From 09b32ffb52d4260a64a5b1ac8feb2c6496a7cfa7 Mon Sep 17 00:00:00 2001 From: SakuraRed <86900315+SakuraRed@users.noreply.github.com> Date: Sun, 13 Sep 2026 05:11:39 +0800 Subject: [PATCH 1/2] feat: align workbench navigation and reference browsing --- CONTEXT.md | 59 +++++ README.md | 36 ++-- docs/ARCHITECTURE.md | 35 +++ docs/AUDIT-2026-09-11.md | 70 ++++++ docs/CURRENT-STATE.md | 39 ++++ docs/DDD-PLAN.md | 24 +++ docs/DECISIONS.md | 22 ++ docs/EXECUTION-PLAN.md | 14 ++ docs/EXECUTION-PROGRESS.md | 9 + docs/IMPLEMENTATION-ORDER.md | 10 + docs/LEGACY-PRD-COVERAGE.md | 120 +++++++++++ docs/REVIEW-SUMMARY.md | 12 ++ docs/UIUX-DIRECTION.md | 28 +++ docs/VERIFICATION-2026-09-12.md | 180 ++++++++++++++++ docs/WORKBENCH-ACCEPTANCE.md | 63 ++++++ docs/academic.md | 20 +- docs/assets/workbench/archive-125.jpg | Bin 0 -> 92399 bytes docs/assets/workbench/dark.jpg | Bin 0 -> 89860 bytes docs/assets/workbench/reference-action.jpg | Bin 0 -> 100675 bytes docs/assets/workbench/writing.jpg | Bin 0 -> 118038 bytes docs/creative.md | 18 +- docs/diff-merge.md | 13 +- docs/editor.md | 14 +- docs/export.md | 13 +- docs/git.md | 17 +- docs/github.md | 6 +- docs/graph.md | 9 +- docs/index.md | 16 +- docs/links.md | 24 ++- docs/math.md | 7 +- docs/modes.md | 14 +- docs/projects.md | 2 + docs/reading.md | 23 +- docs/shortcuts.md | 17 +- docs/simple-mode.md | 4 +- docs/specs/AUTOMATION.md | 31 ++- docs/specs/workbench-ux.feature | 57 +++++ docs/update.md | 10 +- docs/writing.md | 8 +- scripts/acceptance/bindings.mjs | 9 +- scripts/acceptance/workbench-bindings.mjs | 50 +++++ specs/01-workbench.spec.md | 65 +++--- specs/03-live-preview-ime.spec.md | 46 ++-- specs/README.md | 5 + src/academic/useReferenceLibrary.test.tsx | 49 +++++ src/academic/useReferenceLibrary.ts | 57 +++++ src/components/projects/ProjectRail.test.tsx | 30 +++ src/components/projects/ProjectRail.tsx | 21 +- src/components/settings/settingsSections.tsx | 19 +- src/components/workbench/CentralArea.tsx | 23 +- src/components/workbench/EditorTabs.test.tsx | 203 +++++++++++++++--- src/components/workbench/EditorTabs.tsx | 123 +++++------ src/components/workbench/ModeIndicator.tsx | 27 ++- src/components/workbench/OutlinePanel.tsx | 9 +- src/components/workbench/PanelTabs.test.tsx | 177 +++++++++++++++ src/components/workbench/PanelTabs.tsx | 37 +++- src/components/workbench/ProjectOverview.tsx | 30 +++ .../workbench/ProjectVersions.test.tsx | 36 ++++ src/components/workbench/ProjectVersions.tsx | 32 +++ src/components/workbench/RightPanel.test.tsx | 12 ++ src/components/workbench/RightPanel.tsx | 12 +- src/components/workbench/Sidebar.tsx | 6 +- src/components/workbench/StatusBar.tsx | 1 - src/components/workbench/WorkbenchLayout.tsx | 2 + .../workbench/Workspace.integration.test.tsx | 60 ++++++ .../workbench/WorkspaceNavigation.test.tsx | 47 ++++ .../workbench/WorkspaceNavigation.tsx | 39 ++++ .../workbench/ZoteroLibraryPanel.test.tsx | 9 +- .../workbench/ZoteroLibraryPanel.tsx | 173 +++++---------- src/components/workbench/layoutPatch.test.ts | 7 +- src/components/workbench/workbench.css | 67 ++++++ src/editor/academicActions.ts | 5 +- src/editor/fileOpenFlow.ts | 3 + src/stores/effectiveCentralView.ts | 2 +- src/stores/useWorkbenchStore.ts | 3 + src/styles/base.css | 11 +- src/styles/material.css | 26 ++- src/styles/theme.css | 48 +++-- src/styles/theme.test.ts | 6 +- src/types/workbench.ts | 6 +- 80 files changed, 2181 insertions(+), 456 deletions(-) create mode 100644 CONTEXT.md create mode 100644 docs/ARCHITECTURE.md create mode 100644 docs/AUDIT-2026-09-11.md create mode 100644 docs/CURRENT-STATE.md create mode 100644 docs/DDD-PLAN.md create mode 100644 docs/DECISIONS.md create mode 100644 docs/EXECUTION-PLAN.md create mode 100644 docs/EXECUTION-PROGRESS.md create mode 100644 docs/IMPLEMENTATION-ORDER.md create mode 100644 docs/LEGACY-PRD-COVERAGE.md create mode 100644 docs/REVIEW-SUMMARY.md create mode 100644 docs/UIUX-DIRECTION.md create mode 100644 docs/VERIFICATION-2026-09-12.md create mode 100644 docs/WORKBENCH-ACCEPTANCE.md create mode 100644 docs/assets/workbench/archive-125.jpg create mode 100644 docs/assets/workbench/dark.jpg create mode 100644 docs/assets/workbench/reference-action.jpg create mode 100644 docs/assets/workbench/writing.jpg create mode 100644 docs/specs/workbench-ux.feature create mode 100644 scripts/acceptance/workbench-bindings.mjs create mode 100644 specs/README.md create mode 100644 src/academic/useReferenceLibrary.test.tsx create mode 100644 src/academic/useReferenceLibrary.ts create mode 100644 src/components/projects/ProjectRail.test.tsx create mode 100644 src/components/workbench/PanelTabs.test.tsx create mode 100644 src/components/workbench/ProjectOverview.tsx create mode 100644 src/components/workbench/ProjectVersions.test.tsx create mode 100644 src/components/workbench/ProjectVersions.tsx create mode 100644 src/components/workbench/Workspace.integration.test.tsx create mode 100644 src/components/workbench/WorkspaceNavigation.test.tsx create mode 100644 src/components/workbench/WorkspaceNavigation.tsx diff --git a/CONTEXT.md b/CONTEXT.md new file mode 100644 index 0000000..25e75f5 --- /dev/null +++ b/CONTEXT.md @@ -0,0 +1,59 @@ +# InkStream 领域用语 + +InkStream 面向日常、学术与长篇创作。以下词汇描述内容及其工作状态。 + +## 写作与项目 + +**项目档案(项目)**:关联一个本地内容目录,拥有名称、封面、收藏与独立会话的写作项目。 +_避免_:把项目、最近目录和 Git 仓库当作同一概念。 + +**内容目录(工作区 / Vault)**:一个项目关联的文件夹及其中的文件;可以不是 Git 仓库。 + +**项目会话**:项目的已打开文档、恢复正文、选区、滚动位置、写作模式和面板布局记录。 + +**独立草稿会话**:不归属于某个项目的文稿集合及恢复状态。 + +**文档**:一份正在编辑或阅读的内容,可以是文件或未指定保存位置的草稿。 + +**草稿**:尚未指定磁盘保存位置的文档。 +_避免_:与章节完成程度中的“草稿”混用。 + +**文档标签**:访问当前会话内一份已打开文档的入口。 + +**未保存**:文稿包含尚未成功写入目标文件的修改。 + +**未提交**:磁盘修改尚未进入 Git 历史,与未保存是不同状态。 + +**外部冲突**:未保存文稿与外部程序修改的磁盘版本需要裁决的状态。 + +## 工作台 + +**项目轨**:常态显示项目快捷入口及工作台控制的窄栏。 + +**项目档案浮层**:用于检索、切换和管理项目的临时覆盖区域。 + +**工作区视图**:用户在项目内选择的工作目的地,包括概览、文稿、文献与版本。 +_避免_:把工作区视图当作文档标签或写作模式。 + +**项目内导航**:当前项目文件、章节或资料的组织入口。 + +**上下文工具**:围绕当前文稿显示的大纲、反链、引用、预览、角色资料或场景概要。 + +**写作模式**:通用、学术、创作三种工具与布局预设,不改变或限制文档格式。 + +**简易模式**:收起高级能力、保留基础编辑和阅读的选择,与写作模式独立。 + +## 资料与关联 + +**文献库**:具有明确身份的参考文献集合;离线副本仍属于该库。 + +**选中文献**:当前正在查看详情的文献条目;选中本身不代表已插入文稿。 + +**引用**:文稿对某个文献条目的引用标记及解析结果。 + +**Codex**:项目中的角色、地点与设定资料集合。 +_避免_:与开发 InkStream 的 Codex 工具混用。 + +**双向链接**:文档引用其他文档、标题或文本块,并可从目标反查来源的关系。 + +**索引**:从源文件派生的可重建检索资料,不是正文的权威副本。 diff --git a/README.md b/README.md index c03532c..9beb991 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ --- -**InkStream(墨流)** 是一款基于 Tauri 2 的桌面写作应用。它只用一个 CodeMirror 6 编辑器,提供 Standard(通用)、Academic(学术)、Creative(长篇创作)三种模式;git 版本管理、双向链接、Zotero 引用和 Typst / LaTeX / KaTeX 数学渲染都内置在应用里,而不是交给一堆插件。 +**InkStream(墨流)** 是一款基于 Tauri 2 的桌面写作应用。它以 CodeMirror 6 承载主文档编辑,提供 Standard(通用)、Academic(学术)、Creative(长篇创作)三种模式;git 版本管理、双向链接、Zotero 引用和 Typst / LaTeX / KaTeX 数学渲染都内置在应用里,而不是交给一堆插件。 如果要一句话概括,它想成为文本编辑器里的 IntelliJ:纯文本的简单,配上 IDE 级的工具。 @@ -55,26 +55,26 @@ ## 特性 -- **单一内核编辑器**:整个应用就一个 CodeMirror 6 实例,纯文本始终是文档的依据。Source 和 Live Preview 随时切换,光标所在行自动展开源码,支持 11 种语言高亮。 +- **单一内核编辑器**:主文档共用一个 CodeMirror 6 编辑视图,纯文本始终是文档的依据。Source 和 Live Preview 可切换,光标所在行展开源码;大文档默认进入基础编辑,可手动启用完整排版。表格单元格、公式和只读比较按需使用独立视图。 - **本机项目档案**:`Ctrl+Alt+P` 打开左侧档案,管理名称、封面、收藏和内容目录。每个项目记住标签、光标与布局;独立草稿也会暂存在本机。切换前保存失败会留在原项目。详见[项目与恢复](docs/projects.md)。 - **三类数学块**:math 走 KaTeX,typst 走 typst.ts(wasm 实时 SVG),latex 走 MathJax。都是懒加载,首屏不碰 wasm 和字体。 - **双向链接知识网络**:`[[wiki-link]]` 支持别名、标题与块定位,SQLite FTS5 索引保存在本机应用数据目录,并支持一至两个字符的短词查找;反链面板列出有上下文的未链接提及。 - **知识图谱**:`Ctrl+G` 打开全库 Graph View,d3-force 力导加 Canvas2D 自绘,布局放到 Worker 里跑。可缩放、拖拽、点击跳转、邻域高亮;右栏能看当前文件的局部图谱。 -- **git 原生**:基于 libgit2 的完整命令集,自绘三栏 git-graph(图谱、提交详情、文件 diff)。支持远程 clone / fetch / push / pull 和 SSH 签名提交。 +- **git 版本管理**:本地操作结合 libgit2 与系统 Git,自绘三栏 git-graph(图谱、提交详情、文件 diff)。提供克隆对话框、fetch / push / pull、本地变基、暂存记录管理和分支完整正文比较,提交支持 SSH 签名。 - **句级 diff 与三向合并**:中英混排按句子比较,看的是「哪句话改了」而不是「哪行变了」。合并冲突可以逐句采纳本方或对方。 - **Zotero 集成**:CAYW 一键插入 `[@citekey]`,Web API 离线缓存,GB/T 7714 / APA / Vancouver 参考文献,引用与 Typst / LaTeX 联动。 -- **GitHub 集成**:PAT 或 gh CLI 登录(token 存进系统钥匙串,不进前端),浏览、评论、创建 Issue 和 PR,内嵌 diff 审阅。 +- **GitHub 集成**:PAT、现有 gh CLI 凭据或配置了 Client ID 的设备授权登录(token 存进系统凭据库,不进前端),浏览、评论、创建 Issue 和 PR,内嵌 diff 审阅与讨论回复。 - **创作模式**:章节场景树(带状态色点和字数)、`Codex/` 角色与设定卡(别名提及高亮、悬停预览)、Focus Mode、今日字数目标、场景概要。 - **写作辅助**:打字机模式让光标行居中,专注模式淡化其余段落,写作 HUD 记码字速度、码字时间和番茄钟。默认都关着,只存在内存里。 - **文件导出**:一键把当前文档导出成 HTML、PDF、DOCX,全本地转换;可加一行自定义水印(默认关)。装了 pandoc 还能导出 ODT、LaTeX、EPUB 等。 -- **沉浸阅读模式**:打开 txt、docx、epub、pdf 全屏阅读,自动认出小说还是文献并换排版,三套配色护眼。PDF 逐页懒渲染,编辑器不卸载,随时切回来。 +- **沉浸阅读模式**:txt、Markdown、docx、epub、pdf 可进入阅读视图;文本阅读提供文体识别、排版、目录、书签与续读,PDF 逐页懒渲染。书架可按设置启用,编辑器不卸载,随时切回来。 - **应用内自动更新**:启动时静默检查新版本,一键下载并重启升级,更新包经签名验证。 - **简易模式**:一键收起高级功能并关闭索引,保留写作、项目档案和草稿恢复。所有模式都不向内容目录写入新的项目元数据或索引库。 -- **中文优先**:中文输入法全程不被预览打断,中英混合字数统计,中文模糊搜索。 +- **中文优先**:组合输入期间暂停会干扰输入的预览更新,提供中英混合字数统计和中文模糊搜索;物理输入法的候选窗与连续上屏仍按[真机回归清单](specs/03-live-preview-ime.spec.md)验收。 ## 下载安装 -前往 **[Releases](https://github.com/KRPCT/InkStream/releases/latest)** 下载对应平台安装包: +**[2.0.0 已公开发布](https://github.com/KRPCT/InkStream/releases/tag/v2.0.0)**。前往 **[Releases](https://github.com/KRPCT/InkStream/releases/latest)** 下载对应平台安装包: | 平台 | 安装包 | |------|--------| @@ -88,11 +88,13 @@ 三模式 = UI 布局预设 + 默认功能集 + 状态栏指标。不限制文件内容、不绑定文件格式,随时切换不丢数据。 -| 模式 | 定位 | 强调色 | 特色 | -|------|------|--------|------| -| Standard | 通用文本编辑 | 石墨灰 | 文件树、大纲 / 反链 / 局部图谱、Live Preview | -| Academic | 学术写作 | 学院深蓝 | Zotero 文献库、Citation Panel、Typst 预览、学术工具栏 | -| Creative | 长篇创作 | 朱砂红 | 章节导航树、Codex、Focus Mode、字数目标进度 | +| 模式 | 定位 | 特色 | +|------|------|------| +| Standard | 通用文本编辑 | 文件树、大纲 / 反链 / 局部图谱、Live Preview | +| Academic | 学术写作 | Zotero 文献库、引用面板、Typst 预览、学术工具栏 | +| Creative | 长篇创作 | 章节导航树、Codex、专注模式、字数目标进度 | + +多栏分支统一采用纸白、石墨灰和低饱和灰绿,提供概览/文稿/文献/版本导航、多个项目快捷入口,以及先看详情再明确插入的引用流程。发布与验证范围见[当前状态](docs/CURRENT-STATE.md),真实窗口观察见 [ComputerUse 验收](docs/WORKBENCH-ACCEPTANCE.md)。 ## 技术栈 @@ -115,18 +117,20 @@ ```bash corepack enable -pnpm install # 精确版本锁定 +pnpm install --frozen-lockfile pnpm tauri dev # 开发模式启动桌面应用 pnpm tauri build # 打包本平台安装包(产物在 src-tauri/target/release/bundle/) ``` -本地检查:`pnpm typecheck`、`pnpm lint`、`pnpm test:ci`、`pnpm build`。`test:ci` 串行执行全部前端测试,保留每项测试的原有时限,记录进程清理与结果,避免大文档测试和其他 jsdom 实例争用资源。原生测试运行 `node scripts/acceptance/run-rust.mjs`。Linux 构建需先安装 webkit2gtk 等系统依赖(清单见 [.github/workflows/ci.yml](./.github/workflows/ci.yml));三平台安装包经 [.github/workflows/release.yml](./.github/workflows/release.yml) 在 CI 同时构建。 +本地检查:`pnpm typecheck`、`pnpm lint`、`pnpm test:ci`、`pnpm build`。`test:ci` 将功能测试与两份大文档性能测试分阶段串行执行,保留测试自身时限,记录结果与进程清理。原生入口 `node scripts/acceptance/run-rust.mjs` 执行 `cargo test --locked --manifest-path src-tauri/Cargo.toml --all-targets -- --test-threads=1`,覆盖库与应用二进制的编译和测试;CI 不再单独执行 `cargo check`。Unix 权限负控通过独立 runner 执行。 + +`pnpm test:acceptance` 只运行人工映射的 Vitest 检查,不解释 Gherkin,不能据此宣称全部 BDD 场景通过。执行范围、硬超时和证据边界见 [BDD 自动化绑定状态](docs/specs/AUTOMATION.md)。Linux 系统依赖和三平台检查步骤见 [CI 配置](./.github/workflows/ci.yml)。[Release 工作流](./.github/workflows/release.yml)负责打包;标签发布在更新包签名与 `latest.json` 聚合完成后公开,手动触发仅上传构建产物,不创建公开 Release。打包成功不代替产品验收。 ## 路线图 -v1 的 12 个阶段已经全部做完:三模式 Workbench、CM6 单内核与多语言高亮、Live Preview、FTS5 索引与双向链接、三类数学块、git 与 git-graph、句级 diff、Zotero 与学术模式、创作模式、知识图谱、GitHub 集成,以及三向合并和跨平台打包发布。 +2.0.0 已包含三模式工作台、本机项目与草稿恢复、编辑与索引、Git/GitHub、学术与创作、阅读与导出等功能。实现状态和发布状态分别记录;历史阶段的实现结束不表示所有验收结束。 -v1.1 之后又陆续加了简易模式、写作模式升级(打字机 / 专注 / 写作 HUD)、文件导出(含 pandoc 多格式)、沉浸阅读模式,还有应用内自动更新。 +2.0.0 对应 PR #40 已合并到 `main`(`ca4c214`),合并前 CI、main CI 与 Release 工作流均成功。外部真实账号、物理 IME、跨平台完整视觉与性能验证仍有开放事项,见 [Issues](https://github.com/KRPCT/InkStream/issues)及[验收边界](docs/specs/AUTOMATION.md)。 还想做的: diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md new file mode 100644 index 0000000..3230cff --- /dev/null +++ b/docs/ARCHITECTURE.md @@ -0,0 +1,35 @@ +# 架构现状与工作台边界 + +基线:2.0.0 / main `ca4c214`,2026-09-13。发布与验收状态统一见 [CURRENT-STATE](CURRENT-STATE.md)。 + +| 职责 | 实现入口 | 权威边界 | +| --- | --- | --- | +| 文档编辑 | `src/editor/documentSession.ts`、`editorState.ts`、`useCodeMirror.ts` | 主 EditorView 与文档缓存持有正文、选区、撤销;标签 store 是镜像 | +| 保存/文件身份 | `src/stores/autosave.ts`、编辑 flows、`src-tauri/src/files/` | 按身份和修订承认写入;失败保留文稿,旧结果不清新修改 | +| 项目会话 | `src/projects/session.ts`、`src-tauri/src/projects/` | 协调保存、快照、打开和恢复,每窗口一个活动项目 | +| 项目操作 | `src/projects/actions.ts`、`src/ipc/projects.ts` | UI 经既有入口添加、切换、改名、重新定位及恢复 | +| 工作台 | `useWorkbenchStore`、`effectiveCentralView`、`WorkbenchLayout` | 视图、模式、布局与能力降级,不拥有正文或保存裁决 | +| 索引/关系 | `src/ipc/index*`、`src-tauri/src/index*`、`src/graph/` | 本机可重建派生数据,查询带项目/工作区归属 | +| Git | `src-tauri/src/git/`、Git flows/stores | 仓库状态、操作与恢复,Git 根独立于内容目录 | +| 文献 | `src/academic/useReferenceLibrary.ts`、`src/ipc/zotero.ts`、引用/CSL | 库身份和游标隔离;选择条目只看资料,明确插入才改正文 | +| 创作 | Codex、章节树、场景概要、写作指标 | 用户文件为资料源,经既有文档入口编辑 | + +## 编辑器与多栏 + +主编辑器持续挂载。切换工作区视图可隐藏它,但不重新创建正文实例;摘录/表格辅助视图不是另一份正文权威。新工作台复用现有文档、项目、Git 和引用入口。 + +项目浮层阻止后台编辑并保留纸面几何。常态项目轨直接切换也遵循保存/会话协议,失败需要让错误可见。导航、文档标签、模式分别表达目的地、文档身份和工具预设。 + +## 持久化与恢复 + +项目名称、封面、收藏、会话和索引已位于本机应用数据目录。内容目录保留用户文件,历史 `.inkstream` 未知内容原样保留。会话记录恢复正文、选区、滚动、模式、各模式布局及活动工具;重启不重放撤销历史。 + +项目协调器负责接受目标会话。布局写回只接受用户调整,拒绝启动恢复、项目切换和缩放产生的中间测量。UI 不直接改写这些协议。 + +## 本轮 DDD 切面 + +工作台统一表达概览、文稿、文献和版本,不为相同状态另建平行权威。资料选择与正文插入分离;库切换、失败和过期响应不能串库或误插入。 + +继续使用 React、CSS token 与 Tauri WebView。窄视口改变呈现,保存的宽度不因临时缩放被覆盖。行为规格先于实现,测试后通过 ComputerUse 操作真实窗口验收。 + +工作台实现由 `WorkspaceNavigation` 选择目的地,`CentralArea` 组合概览、文献、版本和保活正文。`ProjectVersions` 复用现有 Git 快照,只将复杂操作交给原全宽版本管理。资料浏览 hook 管理库修订和请求代次,插入仍经过可见可写正文命令边界,并形成独立撤销步骤。右栏始终派生可用工具,处理简易模式双向切换;收起的栏保持实例但退出焦点导航。 diff --git a/docs/AUDIT-2026-09-11.md b/docs/AUDIT-2026-09-11.md new file mode 100644 index 0000000..73c7f93 --- /dev/null +++ b/docs/AUDIT-2026-09-11.md @@ -0,0 +1,70 @@ +# 历史记录:AUDIT-2026-09-11.md + +此文件保留原日期、原工作树与当时证据。2.0.0 的实现/合并/发布现状见 [CURRENT-STATE](CURRENT-STATE.md);下面“尚未实施/未推送/草稿 PR”等文字是历史状态,不作为当前指令。 + +
+查看原始历史记录 + +# InkStream 1.3.0 功能与架构审计 + +核对日期:2026-09-11;基线 `02e0afa3aab27bf91ce35d0270e8815672d4efde`,已 fetch,开始时与 origin/main 无差异。此次没有修复生产功能,没有变更用户工作区、凭据或系统运行时。 + +结论:现有技术栈可以继续用于 UIUX 探索,但文档生命周期、工作区和派生数据缺少一致的身份与完成规则。先登记缺陷、明确项目模型和行为,再重做界面。 + +## 验证证据 + +- CodeGraph 使用本轮从 npm 核验并隔离安装的 `@colbymchenry/codegraph@1.6.0`,未升级全局配置。完整重建覆盖 521 文件、5,478 节点、17,334 条边。旧索引只有 112 文件、1,025 条未解析引用,不能继续作为完整证据。新原型不属于上述产品基线。 +- 基线 TypeScript 检查通过。 +- 全套 Vitest 串行执行:现有 162 个测试文件、1,366 项测试通过;额外两项临时集成复现失败。总结果为 163 文件中 1 个失败、1,368 项中 2 项失败。临时检查使用真实 EditorTabs、CodeMirror 状态及 autosave,仅替换文件 I/O;已从产品测试目录移出并保留审计证据。 +- 第一轮全套测试的 90 秒上限不足,已回收该进程树;随后在 300 秒硬上限内完成,耗时约 257 秒。不能将第一次超时误记为测试通过。 +- 当前提交的三平台 CI 均失败于两处剪贴板直接导入违规,后续步骤被阻断。[该提交 CI](https://github.com/KRPCT/InkStream/actions/runs/28985293456) +- 未运行真实磁盘故障注入、真实账户/远程攻击、Rust 测试、三平台桌面构建或原生 IME 验收。除明确注明的两项临时集成复现外,其余缺陷证据来自完整静态调用链。代码证据不等同于真机故障录像。 + +## 已登记缺陷与改进 + +P1 为可能破坏文档正确性、跨工作区数据隔离或凭据范围的优先项;P2 为恢复、功能与规范不符合项。每个 issue 有触发条件、证据边界与验收条件;本轮不自动实施。 + +| 级别 | 问题与影响 | 主要代码证据 | GitHub | +|---|---|---|---| +| P1 | 关闭活动标签后正文仍属于旧文档,保存对象却换成新文档;已动态复现身份失配 | `EditorTabs.tsx:33`、`useEditorStore.ts:75`、`editorState.ts:231` | [关闭活动文档一致性](https://github.com/KRPCT/InkStream/issues/2) | +| P1 | 保存失败/冻结仍关闭;冲突失败误清状态;在途保存误清新修订 dirty;已动态复现失败关闭丢缓冲 | `autosave.ts:118`、`EditorTabs.tsx:45`、`ExternalChangeBar.tsx:52` | [保存结果与修订](https://github.com/KRPCT/InkStream/issues/3) | +| P1 | 干净后台文档外部更新后仍用旧缓存,可能把磁盘新版本回退 | `externalChange.ts:78`、`editorState.ts:190` | [后台缓存失效](https://github.com/KRPCT/InkStream/issues/4) | +| P1 | 重命名/移动/删除未同步标签、缓存与写入位置,旧文件可能复活 | `fileTreeOps.ts:95`、`autosave.ts:123` | [文件身份迁移](https://github.com/KRPCT/InkStream/issues/5) | +| P1 | 乱序切库可混合根/树/查询;失败没有恢复旧 watcher | `vaultFlow.ts:50`、`:114` | [工作区会话](https://github.com/KRPCT/InkStream/issues/6) | +| P1 | 普通 A→简易→B→普通后保存 B,可把 B 正文写进 A 索引 | `index.rs:34`、`indexService.ts:40`、`useSettingsStore.ts:126` | [索引会话与启停](https://github.com/KRPCT/InkStream/issues/7) | +| P2 | 关闭高级能力后 overlay 和正文均隐藏,中央区空白 | `WorkbenchLayout.tsx:69`、`CentralArea.tsx:12` | [有效导航](https://github.com/KRPCT/InkStream/issues/8) | +| P1 | GitHub PAT 可作为第三方 HTTPS Git 认证凭据 | `git/remote.rs:18`、`:123` | [凭据主机范围](https://github.com/KRPCT/InkStream/issues/9) | +| P2 | Zotero 换账户仍共用旧数据与 library_version | `zotero_sync.rs:99`、`:115`、`:166` | [文献库分区](https://github.com/KRPCT/InkStream/issues/10) | +| P2 | 删除同步失败/分页版本改变仍推进 Zotero 游标 | `zotero_sync.rs:208`、`:228` | [同步提交](https://github.com/KRPCT/InkStream/issues/11) | +| P2 | Unix 原子写 temp+rename 未保留目标权限 | `files.rs:61` | [文件权限](https://github.com/KRPCT/InkStream/issues/12) | +| P2 | 代码示例中的 wiki-link 被计入知识网络 | `index.rs:368`、`livepreview/wikiLink.ts:27` | [链接上下文契约](https://github.com/KRPCT/InkStream/issues/13) | +| P2 | >1MB Channel 声明未落实,最高 100MB 二进制可整块 invoke;未声称测得 OOM | `files.rs:20`、`:136`、`src/ipc/README.md` | [传输与响应性](https://github.com/KRPCT/InkStream/issues/14) | +| P2 | 编辑命令及测试直接导入 Tauri clipboard,违反现行 IPC 规则 | `editCommands.ts:3`、`editCommands.test.ts:4` | [恢复 CI](https://github.com/KRPCT/InkStream/issues/15) | +| P2 | 前端放行 Markdown 阅读,Rust 字节读取白名单拒绝 md/markdown | `reading/openReading.ts:14`、`reading/loadContent.ts:37`、`files.rs:148` | [Markdown 阅读契约](https://github.com/KRPCT/InkStream/issues/20) | +| P2 | Git 远程模式与自定义服务器设置只持久化,执行路径未读取 | `settingsSections.tsx:276`、`useSettingsStore.ts:124` 与远程执行引用核对 | [远程设置生效](https://github.com/KRPCT/InkStream/issues/21) | +| P2 | 同名候选丢失路径身份;标题/块标记未用于精确定位 | `wikiLinkComplete.ts:32`、`wikiTarget.ts:16` | [精确链接目标](https://github.com/KRPCT/InkStream/issues/23) | +| P2 | 关系面板不随索引提交刷新,查询失败可显示为空结果 | `BacklinksPanel.tsx:58`、`indexService.ts` 查询失败路径 | [关系结果的新鲜度与错误](https://github.com/KRPCT/InkStream/issues/24) | + +## 设计漂移与尚未裁定事项 + +旧 PRD 为 v0.2 草案,当前代码为 1.3.0。ORACLE、UI-SPEC、ROADMAP 的旧根引用已失效;Octokit/Device Flow、完整 git2 命令集与现实现不同。rebase 缺失、clone 未有前端入口、反链缺段落上下文,均需要决定“补齐或调整范围”,不能擅自全部列为必须新建的功能。 + +“全应用一个 CodeMirror 实例”与已有摘录/表格辅助编辑视图不符。应先确认文档内容权威与回写规则,不能用实例数量证明不会丢数据。最近 20 个目录路径也不等于永久、海量的项目档案系统。 + +系统 git/pandoc 缺应用级超时/取消是需进一步实验的恢复改进;连接句柄长期占用、特定输入法与材质帧率未在本轮得到运行证据,不列为已复现事故。 + +## 重构前的架构判断 + +优先深化 DocumentSession,把正文身份、修订、保存结果、关闭与外部冲突放到同一可验收 interface。其次是 WorkspaceSession,协调切换目标、监听与索引生命周期;再收敛 WorkbenchNavigation 的有效视图。全部是待讨论候选,不是已经批准的新接口。 + +React/Tauri/CodeMirror 暂时保留,CSS 为材质原型的起点。真正折射、虚拟化数量、三平台帧率与可访问性预算需要后续明确指标;本轮视觉样例只回答布局与材料方向。 + +## 决策入口 + +[UIUX 重构决策地图](https://github.com/KRPCT/InkStream/issues/16) 使用原生子 issue;[文档与开发范围确认](https://github.com/KRPCT/InkStream/issues/19) 原生依赖于[项目含义](https://github.com/KRPCT/InkStream/issues/17)和[原型布局比较](https://github.com/KRPCT/InkStream/issues/18)。未获得用户回答的票据保持开放。 + +第一轮已完成项目含义裁定;会话、记录位置与后续轮次保存在[项目切换与记录位置](https://github.com/KRPCT/InkStream/issues/22)。用户进一步要求先补齐旧 PRD 的全部 v1 用户功能并验收,之后才正式重构 UI;覆盖表见 [LEGACY-PRD-COVERAGE.md](LEGACY-PRD-COVERAGE.md)。18 个缺陷/改进票据不替代全部旧功能的验收清单。 + +用户已整体确认记录并进入DDD/BDD计划,相关方向决策票已关闭;[旧v1功能验收](https://github.com/KRPCT/InkStream/issues/25)与缺陷/功能票仍开放。[光学技术验证](https://github.com/KRPCT/InkStream/issues/39)由旧v1验收阻塞,尚未执行。当前原型类型检查与专用构建通过;浏览器检查了三布局、项目搜索/切换、低透明和档案浮层,浮层前后正文几何一致,浏览器未报告脚本错误。以上不是生产保存、真实折射或原生平台验收。 + +
diff --git a/docs/CURRENT-STATE.md b/docs/CURRENT-STATE.md new file mode 100644 index 0000000..28b1b17 --- /dev/null +++ b/docs/CURRENT-STATE.md @@ -0,0 +1,39 @@ +# 当前状态与证据 + +核对日期:2026-09-13。已发布基线为 [InkStream 2.0.0](https://github.com/KRPCT/InkStream/releases/tag/v2.0.0),main 提交 `ca4c214a4d045c4c23da21d0f1fba1a43abdcd58`。分支 `codex/workbench-ux-v2` 已实现多栏对齐,本分支改动尚未发布。 + +## 已完成并发布 + +- [PR 40](https://github.com/KRPCT/InkStream/pull/40) 已合并。项目档案、独立会话/草稿、本机索引及文稿/Git/学术流程修复已进入 2.0.0。 +- 图标采用用户选定的双层竖板与墨带 SVG。项目 popup 使用纸白、石墨灰、灰绿,已清理两处装饰英文。 +- 「视图」菜单实时勾选反馈打字机和专注模式,应用内更新公告包含 2.0.0。 +- [合并前 CI](https://github.com/KRPCT/InkStream/actions/runs/34709938076)、[main CI](https://github.com/KRPCT/InkStream/actions/runs/34710877435)、[Release](https://github.com/KRPCT/InkStream/actions/runs/34710891782) 均通过。 +- Windows x64、macOS Apple Silicon、Linux x64 安装包及自动更新清单已发布。自动更新载荷签名不等于操作系统发行者代码签名。 + +## 尚需专项验收 + +24 个等待合并的实现票已关闭。以下 11 个专项票仍开放,发布或 CI 通过不取代其验收。 + +| 范围 | 入口 | 尚需证据 | +| --- | --- | --- | +| 大文档 | [响应性契约](https://github.com/KRPCT/InkStream/issues/14) | 代表性输入的端到端耗时与峰值内存 | +| 整体 v1 | [逐项验收](https://github.com/KRPCT/InkStream/issues/25) | 组合流程、原生输入与平台矩阵 | +| Typst | [编译与预览](https://github.com/KRPCT/InkStream/issues/26) | 连续编辑、切文档、失败修正的真实渲染 | +| 文献 | [格式与联动](https://github.com/KRPCT/InkStream/issues/29) | 类型/缺字段矩阵、真实库联动 | +| 真实账户 | [Device Flow](https://github.com/KRPCT/InkStream/issues/36)、[评论线程](https://github.com/KRPCT/InkStream/issues/37) | OAuth/keyring、真实权限和获授权的发送 | +| 主题 | [导入与回退](https://github.com/KRPCT/InkStream/issues/38) | 真实主题与新工作台可读性 | +| 光学与平台 | [CSS/WebGL 与降级](https://github.com/KRPCT/InkStream/issues/39) | 原生 WebView、GPU、缩放及长时表现 | +| UI | [原型差距](https://github.com/KRPCT/InkStream/issues/41) | 本轮多栏已实现并完成 Windows ComputerUse;严格并排对照和密集项目矩阵继续保留 | +| 图标/popup | [SVG 图标](https://github.com/KRPCT/InkStream/issues/42)、[项目弹窗](https://github.com/KRPCT/InkStream/issues/43) | 已补 Windows 亮暗工作台/浮层证据;安装图标与完整弹窗矩阵继续保留 | + +## 本轮顺序与证据 + +[任务地图](https://github.com/KRPCT/InkStream/issues/45):文档/issues 同步 → DDD/BDD 多栏实现 → 自动测试 → ComputerUse 用户验收。用户已要求实施;旧“仅规划”“全部外部验收后才做 UI”已被后续指令覆盖。 + +历史审计、旧计划和旧验证文件只代表各自日期。原型的示例数字与假数据不构成产品事实。Vitest、原生测试、浏览器和 ComputerUse 分别说明边界;ComputerUse 不自动证明物理 IME 或其它系统已通过。 + +实施工作树为 `D:/Github/InkStream-workbench-v2`;`D:/Github/InkStream` 保留用户测试分支的未提交代码。 + +## 多栏分支完成状态 + +已实现项目轨、概览/文稿/文献/版本目的地、文献详情与明确插入、键盘标签导航、布局和显示收敛。1910 项前端断言、41 项显式绑定、类型/Lint/前端/原生构建通过;三轮 ComputerUse 已完成并清理进程。实际截图、发现与修复、证据限制见 [验收记录](WORKBENCH-ACCEPTANCE.md)。此结果属于当前分支,main 和公开 Release 仍为上述 2.0.0 基线。 diff --git a/docs/DDD-PLAN.md b/docs/DDD-PLAN.md new file mode 100644 index 0000000..487d36d --- /dev/null +++ b/docs/DDD-PLAN.md @@ -0,0 +1,24 @@ +# DDD 工作台演进计划 + +2026-09-13。2.0.0 的文档会话、项目会话、索引与 Git 修复已合并。本计划描述其后的多栏工作,不把已实现项目档案重新列为未来实体。 + +## 职责与边界 + +术语唯一来源为 [CONTEXT](../CONTEXT.md),代码职责见 [ARCHITECTURE](ARCHITECTURE.md)。主编辑器拥有正文,项目协调器拥有切换与恢复,工作台只管理目的地和布局,文献浏览管理只读库快照与资料选择。正文和项目身份不复制到页面私有模型中。 + +## 纵向切片 + +| 切片 | 用户结果 | 复用边界 | +| --- | --- | --- | +| 项目轨与导航 | 快速选择真实项目,失败保留文稿并可理解原因 | 项目 actions/session,工作台状态 | +| 概览/文稿/版本 | 查看真实项目资料与 Git 历史,再返回原文稿 | 现有文档与 Git stores/flows | +| 文献详情 | 选中只浏览,明确插入才改当前文稿 | Zotero 库身份与已有引用编辑入口 | +| 布局与键盘 | 栏宽、折叠、Tab/方向键和窄视口保持可用 | 现有布局恢复/写回及能力降级 | + +每个切片用 Given/When/Then 说明可观察行为,先证明失败,再完成实现。规格与自动检查逐项映射,ComputerUse 是独立用户层验收。未绑定或未执行的场景不能被其它测试通过覆盖。 + +## 约束 + +主 EditorView 常驻;视图切换不释放正文或清 dirty。项目切换继续先保存与快照,失败停留。库切换使过期查询和选择失效。缩放不覆盖保存的栏宽。保持当前文件格式与元数据版本,本轮不引入通用 DDD 框架或新的正文数据库。 + +实施与完成状态统一见 [EXECUTION-PROGRESS](EXECUTION-PROGRESS.md)。原 2026-09-11 计划保存在本地审计源,不作为当前待实施清单。 diff --git a/docs/DECISIONS.md b/docs/DECISIONS.md new file mode 100644 index 0000000..8daf9f4 --- /dev/null +++ b/docs/DECISIONS.md @@ -0,0 +1,22 @@ +# 已确认决定与当前范围 + +截至 2026-09-13。词汇见 [CONTEXT](../CONTEXT.md),实现状态见 [CURRENT-STATE](CURRENT-STATE.md)。 + +| 决定 | 当前约束 | 来源 | +| --- | --- | --- | +| B+A+C | B 日常写作、A 左侧档案浮层、C 学术资料与正文相邻的工具布局 | [原型选择](https://github.com/KRPCT/InkStream/issues/18) | +| 项目 | 独立身份关联内容目录,Git 根单独识别,无 Git 可写作 | [项目定义](https://github.com/KRPCT/InkStream/issues/17) | +| 切换 | 先保存/暂存草稿,失败停留,成功恢复独立会话;每窗口一个活动项目 | [项目会话](https://github.com/KRPCT/InkStream/issues/22) | +| 数据位置 | 元数据、会话和索引在本机应用数据目录,正文留在内容目录 | 同上 | +| 材料/配色 | 正文安静纸面;导航/工具可有材料层次;纸白、石墨灰、低饱和灰绿 | 原方向及用户 2026-09-13 选择 | +| 图标 | 用户最终选择双层竖板与墨带,SVG 路径/渐变重绘 | [图标任务](https://github.com/KRPCT/InkStream/issues/42) | +| popup | 背景独立重做、清理英文;“仅图标拟物”限定新增拟物改动,不自动撤销整个工作台材料目标 | [弹窗任务](https://github.com/KRPCT/InkStream/issues/43) | +| 顺序 | 用户已允许先完成本地实现与 UI,真实账号验收独立保留 | 后续交接与发布指令 | +| 2.0.0 | 已完成合并 main、推送标签和公开发布 | [PR 40](https://github.com/KRPCT/InkStream/pull/40)、[Release](https://github.com/KRPCT/InkStream/releases/tag/v2.0.0) | +| 本轮 | 先更新文档/issues,按 DDD/BDD 对齐多栏,测试后 ComputerUse 验收 | 当前请求、[任务地图](https://github.com/KRPCT/InkStream/issues/45) | + +原型累计字数、目标进度、文献与版本记录是演示数据;产品展示真实状态或明确的空/失败状态。 + +当前按单一主编辑器与多个工具栏推进。“对齐现有多栏”不自动增加多个文稿同时编辑;新的正文权威或焦点模型需要明确需求。 + +本轮实现选择:日常版本时间线保留项目导航,高级分支/差异/远端操作仍使用全宽版本管理。新会话采用 220/260px 两侧默认宽度,既有项目记忆不改写。模式菜单使用独立弹出层以兼容状态栏横向滚动;文献详情可滚动,插入操作常驻底部。原生发现与修复见 [验收记录](WORKBENCH-ACCEPTANCE.md)。 diff --git a/docs/EXECUTION-PLAN.md b/docs/EXECUTION-PLAN.md new file mode 100644 index 0000000..f907413 --- /dev/null +++ b/docs/EXECUTION-PLAN.md @@ -0,0 +1,14 @@ +# 多栏工作台执行计划 + +基线 main / 2.0.0 / ca4c214。工作入口为[任务地图](https://github.com/KRPCT/InkStream/issues/45)。 + +| 顺序 | 产出 | 完成判据 | +| --- | --- | --- | +| 1 | 产品文档、领域词汇、架构、覆盖矩阵与 issues | 逐份审计、过时状态清理、链接有效,保留未验收边界 | +| 2 | 工作台行为规格与失败测试 | 用户意图、失败恢复和数据不变条件可追溯 | +| 3 | 多栏导航/概览/文献/版本及布局实现 | 用户动作可到达真实功能,状态与文稿归属一致 | +| 4 | 自动验证 | 相关测试、类型、lint/build及必要回归真实通过 | +| 5 | ComputerUse | 实际窗口中完成写作/资料/版本/布局流程,保存截图、结果与限制 | +| 6 | 文档/issues 收尾 | 只把实际达到判据的任务标记完成,列明未验证项 | + +进程盘点、硬超时、串行重任务与回收沿用现有 acceptance runner。用户原测试工作树保留,当前实现位于 InkStream-workbench-v2。新版本合并发布不属于本轮自动步骤。 diff --git a/docs/EXECUTION-PROGRESS.md b/docs/EXECUTION-PROGRESS.md new file mode 100644 index 0000000..2112372 --- /dev/null +++ b/docs/EXECUTION-PROGRESS.md @@ -0,0 +1,9 @@ +# 当前执行进度 + +2026-09-13。2.0.0 已发布,PR 40 已合并;发布与专项验收边界见 [CURRENT-STATE](CURRENT-STATE.md)。 + +本轮[多栏工作台对齐](https://github.com/KRPCT/InkStream/issues/45)已完成文档/issue 同步、DDD/BDD 实现、自动测试与三轮 ComputerUse 验收。共审阅 42 份文档,保留 102 条旧需求索引,并逐项同步既有 issues。最终 1910 项前端断言、41 项显式绑定及类型/Lint/前端/原生构建通过。 + +ComputerUse 发现并修复模式菜单裁剪、退出简易模式的工具空白、窄文献详情操作被挤出视口等问题。最终截图、真实文件回读与进程清理见 [验收记录](WORKBENCH-ACCEPTANCE.md)。物理 IME、真实账号和完整跨平台矩阵仍由原专项票推进,未标成整体 BDD 完成。 + +当前工作树:D:/Github/InkStream-workbench-v2;分支 codex/workbench-ux-v2。D:/Github/InkStream 保留用户原测试代码与未提交修改;本轮不自动合并 main 或发布新版本。 diff --git a/docs/IMPLEMENTATION-ORDER.md b/docs/IMPLEMENTATION-ORDER.md new file mode 100644 index 0000000..30eea13 --- /dev/null +++ b/docs/IMPLEMENTATION-ORDER.md @@ -0,0 +1,10 @@ +# 当前实施顺序 + +2026-09-13:2.0.0 已合并发布,旧缺陷实现阶段不再列为未开始。发布与未验收边界见 [CURRENT-STATE](CURRENT-STATE.md)。 + +1. 完成[文档与 issue 同步](https://github.com/KRPCT/InkStream/issues/46),清理过时事实并保留历史证据。 +2. 完成[多栏 DDD/BDD 实现](https://github.com/KRPCT/InkStream/issues/47):明确导航/文档/工具职责,以用户行为场景和失败测试驱动。 +3. 运行与改动相称的自动检查,按真实失败修复。 +4. 通过 [ComputerUse 用户验收](https://github.com/KRPCT/InkStream/issues/48),记录实际点击、键盘、拖动与写作结果。 + +真实账户、物理 IME 与跨平台完整矩阵由专项票据推进。当前指令已授权本地 UX 实现,不再以所有外部验收为前置。 diff --git a/docs/LEGACY-PRD-COVERAGE.md b/docs/LEGACY-PRD-COVERAGE.md new file mode 100644 index 0000000..6c5d1ed --- /dev/null +++ b/docs/LEGACY-PRD-COVERAGE.md @@ -0,0 +1,120 @@ +# 旧 PRD 功能覆盖与验收索引 + +更新于 2026-09-13,基线 2.0.0。旧审计中的“缺少 rebase/clone/Codex/项目会话”等实现缺口已经合并发布,不能继续当作当前待开发项。原始用户要求的编号与内容保留在下表;状态区分实现与专项验收,不声称 v1 总验收已完成。 + +| 编号 | 原承诺 | 当前状态与后续 | +| --- | --- | --- | +| US-S1 | 新建默认 `.md`,立即输入并 Live Preview | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| US-S2 | 输入 `[[` 出现 vault 模糊候选,选择插入文件名 | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| US-S3 | Ctrl+点击 wiki-link 跳转,不存在则提示创建 | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| US-S4 | 反链显示来源文件及引用段落 | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| US-S5 | Ctrl+G 查看全库链接网络 | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| US-A1 | Ctrl+Shift+Z 通过 BBT picker 插入 `[@citekey]` | 已有发布实现;真实账户/文献矩阵见 [文献](https://github.com/KRPCT/InkStream/issues/29)、[登录](https://github.com/KRPCT/InkStream/issues/36)、[评论](https://github.com/KRPCT/InkStream/issues/37)。 | +| US-A2 | Citation Panel 汇总当前引用,未解析标红 | 已有发布实现;真实账户/文献矩阵见 [文献](https://github.com/KRPCT/InkStream/issues/29)、[登录](https://github.com/KRPCT/InkStream/issues/36)、[评论](https://github.com/KRPCT/InkStream/issues/37)。 | +| US-A3 | `:::typst` 块实时 SVG,位于块右侧 | 两种 Typst 块、预览和状态已有实现;[真实渲染验收](https://github.com/KRPCT/InkStream/issues/26)保留。 | +| US-A4 | Insert Bibliography 插入 ``,展开 GB/T 7714/APA/Vancouver | 已有发布实现;真实账户/文献矩阵见 [文献](https://github.com/KRPCT/InkStream/issues/29)、[登录](https://github.com/KRPCT/InkStream/issues/36)、[评论](https://github.com/KRPCT/InkStream/issues/37)。 | +| US-A5 | 设置 Web API key 后离线阅读文献缓存 | 已有发布实现;真实账户/文献矩阵见 [文献](https://github.com/KRPCT/InkStream/issues/29)、[登录](https://github.com/KRPCT/InkStream/issues/36)、[评论](https://github.com/KRPCT/InkStream/issues/37)。 | +| US-C1 | 打开项目自动显示章→场景树,带字数及三种状态 | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| US-C2 | F11 Focus Mode 淡化非当前段落 | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| US-C3 | 设置今日目标 2000,状态栏实时进度 | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| US-C4 | 在 Codex 添加角色,提及时高亮并悬停角色卡 | 补全实现已随 2.0.0 合并,对应实现票已关闭;组合用户流程继续归[总验收](https://github.com/KRPCT/InkStream/issues/25)。 | +| US-C5 | Git Graph 比较两个 draft 分支并看句级差异 | 补全实现已随 2.0.0 合并,对应实现票已关闭;组合用户流程继续归[总验收](https://github.com/KRPCT/InkStream/issues/25)。 | +| US-F1 | `/math` 插入块并实时显示 KaTeX | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| US-F2 | typst fenced block 公式实时 SVG | 两种 Typst 块、预览和状态已有实现;[真实渲染验收](https://github.com/KRPCT/InkStream/issues/26)保留。 | +| US-F3 | LaTeX 公式 Live Preview,并导出 PDF 片段 | 补全实现已随 2.0.0 合并,对应实现票已关闭;组合用户流程继续归[总验收](https://github.com/KRPCT/InkStream/issues/25)。 | +| MODE-01 | Standard/Academic/Creative 随时切换;布局、工具及指标预设;不绑定格式、不丢数据 | 已有发布功能;本轮对齐多栏呈现和交互,[工作台任务](https://github.com/KRPCT/InkStream/issues/47)记录新增证据。 | +| STD-01 | 按 Git 根展示工作区文件树 | 已有发布功能;本轮对齐多栏呈现和交互,[工作台任务](https://github.com/KRPCT/InkStream/issues/47)记录新增证据。 | +| STD-02 | 右栏 Outline/Backlinks/Local Graph 三 tab | 已有发布功能;本轮对齐多栏呈现和交互,[工作台任务](https://github.com/KRPCT/InkStream/issues/47)记录新增证据。 | +| STD-03 | 状态栏显示路径、Git 分支、字数、光标、渲染模式 | 补全实现已随 2.0.0 合并,对应实现票已关闭;组合用户流程继续归[总验收](https://github.com/KRPCT/InkStream/issues/25)。 | +| ACA-01 | 左栏上方 Zotero 同步状态,下方文件树 | 已有发布功能;本轮对齐多栏呈现和交互,[工作台任务](https://github.com/KRPCT/InkStream/issues/47)记录新增证据。 | +| ACA-02 | 右栏 Citation/Typst Preview/Outline | 两种 Typst 块、预览和状态已有实现;[真实渲染验收](https://github.com/KRPCT/InkStream/issues/26)保留。 | +| ACA-03 | 学术工具栏:引用、脚注、参考文献、公式编号 | 补全实现已随 2.0.0 合并,对应实现票已关闭;组合用户流程继续归[总验收](https://github.com/KRPCT/InkStream/issues/25)。 | +| ACA-04 | 状态栏:引用数、未解析提示、Typst 编译状态 | 两种 Typst 块、预览和状态已有实现;[真实渲染验收](https://github.com/KRPCT/InkStream/issues/26)保留。 | +| CRE-01 | 左栏章→场景树含字数/状态 | 已有发布功能;本轮对齐多栏呈现和交互,[工作台任务](https://github.com/KRPCT/InkStream/issues/47)记录新增证据。 | +| CRE-02 | 右栏 Codex 角色/地点/设定及场景概要 | 补全实现已随 2.0.0 合并,对应实现票已关闭;组合用户流程继续归[总验收](https://github.com/KRPCT/InkStream/issues/25)。 | +| CRE-03 | 编辑器顶部可折叠场景概要卡及 Focus Mode | 已有发布功能;本轮对齐多栏呈现和交互,[工作台任务](https://github.com/KRPCT/InkStream/issues/47)记录新增证据。 | +| CRE-04 | 状态栏今日字数/目标、章节场景计数、定稿色点 | 补全实现已随 2.0.0 合并,对应实现票已关闭;组合用户流程继续归[总验收](https://github.com/KRPCT/InkStream/issues/25)。 | +| EDIT-01 | 纯文本为权威,渲染不偷换内容 | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| EDIT-02 | Source/Live Preview 运行时切换,命令与状态栏一致 | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| EDIT-03 | 标题、粗体、列表、链接、fenced、wiki-link、citation 最终样式 | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| EDIT-04 | 光标所在行展开源代码 | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| LANG-01 | Markdown/Obsidian 变体 | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| LANG-02 | LaTeX | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| LANG-03 | Typst | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| LANG-04 | JavaScript / TypeScript | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| LANG-05 | Python | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| LANG-06 | Rust | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| LANG-07 | JSON | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| LANG-08 | YAML | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| LANG-09 | HTML | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| LANG-10 | CSS | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| LANG-11 | Shell | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| FMT-01 | 新建默认 `.md` + UTF-8 | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| FMT-02 | frontmatter `language: markdown/latex/typst/richtext` 整体切语言 | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| FMT-03 | richtext 简化 Markdown,B/I/U/链接工具栏,物理仍 Markdown | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| `git_status` | `src-tauri/src/git/status.rs`、`src/ipc/git.ts`、`SidebarGitPanel.tsx` | 补全实现已随 2.0.0 合并,对应实现票已关闭;组合用户流程继续归[总验收](https://github.com/KRPCT/InkStream/issues/25)。 | +| `git_branch_list` | `src-tauri/src/git/branch.rs`、`BranchManager.tsx` | 补全实现已随 2.0.0 合并,对应实现票已关闭;组合用户流程继续归[总验收](https://github.com/KRPCT/InkStream/issues/25)。 | +| `git_log` | `src-tauri/src/git/log.rs`、`graph/CommitGraphList.tsx` | 补全实现已随 2.0.0 合并,对应实现票已关闭;组合用户流程继续归[总验收](https://github.com/KRPCT/InkStream/issues/25)。 | +| `git_diff` | `src-tauri/src/git/diff.rs`、`FileDiffPanel.tsx` | 补全实现已随 2.0.0 合并,对应实现票已关闭;组合用户流程继续归[总验收](https://github.com/KRPCT/InkStream/issues/25)。 | +| `git_commit` | `src-tauri/src/git/commit.rs` 的系统 `git commit -S`、`src/editor/gitActions.ts` | 补全实现已随 2.0.0 合并,对应实现票已关闭;组合用户流程继续归[总验收](https://github.com/KRPCT/InkStream/issues/25)。 | +| `git_checkout` | `src-tauri/src/git/refops.rs`、`BranchManager.tsx`、`GitContextMenu.tsx` | 补全实现已随 2.0.0 合并,对应实现票已关闭;组合用户流程继续归[总验收](https://github.com/KRPCT/InkStream/issues/25)。 | +| `git_merge` | `src-tauri/src/git/commit.rs`、`MergeResolver.tsx` | 补全实现已随 2.0.0 合并,对应实现票已关闭;组合用户流程继续归[总验收](https://github.com/KRPCT/InkStream/issues/25)。 | +| `git_rebase` | `src/types/ipc.ts`、`src-tauri/src/lib.rs` 与 `src-tauri/src/git/` 未见本地 rebase command | 补全实现已随 2.0.0 合并,对应实现票已关闭;组合用户流程继续归[总验收](https://github.com/KRPCT/InkStream/issues/25)。 | +| `git_cherry_pick` | `src-tauri/src/git/commit.rs`、`GitContextMenu.tsx` | 补全实现已随 2.0.0 合并,对应实现票已关闭;组合用户流程继续归[总验收](https://github.com/KRPCT/InkStream/issues/25)。 | +| `git_stash` | `src-tauri/src/git/stash.rs` 提供 save/list/pop/drop,`gitActions.ts` 有 stash 动作 | 补全实现已随 2.0.0 合并,对应实现票已关闭;组合用户流程继续归[总验收](https://github.com/KRPCT/InkStream/issues/25)。 | +| `git_tag` | `src-tauri/src/git/refops.rs` create/delete、`GitContextMenu.tsx` | 补全实现已随 2.0.0 合并,对应实现票已关闭;组合用户流程继续归[总验收](https://github.com/KRPCT/InkStream/issues/25)。 | +| `git_reset` | `src-tauri/src/git/refops.rs` soft/mixed/hard、`GitContextMenu.tsx` | 补全实现已随 2.0.0 合并,对应实现票已关闭;组合用户流程继续归[总验收](https://github.com/KRPCT/InkStream/issues/25)。 | +| `git_clone` | `src-tauri/src/git/remote.rs`、`src/ipc/git.ts:gitClone`;`docs/git.md` 明示无应用内克隆对话框 | 补全实现已随 2.0.0 合并,对应实现票已关闭;组合用户流程继续归[总验收](https://github.com/KRPCT/InkStream/issues/25)。 | +| `git_push` | `src-tauri/src/git/remote.rs`、`src/editor/gitActions.ts` | 补全实现已随 2.0.0 合并,对应实现票已关闭;组合用户流程继续归[总验收](https://github.com/KRPCT/InkStream/issues/25)。 | +| `git_pull` | `src-tauri/src/git/remote.rs` fetch + ff-only merge | 补全实现已随 2.0.0 合并,对应实现票已关闭;组合用户流程继续归[总验收](https://github.com/KRPCT/InkStream/issues/25)。 | +| `git_fetch` | `src-tauri/src/git/remote.rs`、Git 工具条/侧栏 | 补全实现已随 2.0.0 合并,对应实现票已关闭;组合用户流程继续归[总验收](https://github.com/KRPCT/InkStream/issues/25)。 | +| GRAPH-GIT-01 | 图谱/提交详情/文件 diff 三栏 | 已有发布功能;本轮对齐多栏呈现和交互,[工作台任务](https://github.com/KRPCT/InkStream/issues/47)记录新增证据。 | +| GRAPH-GIT-02 | 右键菜单驱动所有操作 | 已有发布功能;本轮对齐多栏呈现和交互,[工作台任务](https://github.com/KRPCT/InkStream/issues/47)记录新增证据。 | +| GRAPH-GIT-03 | Find Widget | 已有发布功能;本轮对齐多栏呈现和交互,[工作台任务](https://github.com/KRPCT/InkStream/issues/47)记录新增证据。 | +| GRAPH-GIT-04 | Filter Branches | 已有发布功能;本轮对齐多栏呈现和交互,[工作台任务](https://github.com/KRPCT/InkStream/issues/47)记录新增证据。 | +| GRAPH-GIT-05 | Repository Settings | 已有发布功能;本轮对齐多栏呈现和交互,[工作台任务](https://github.com/KRPCT/InkStream/issues/47)记录新增证据。 | +| GRAPH-GIT-06 | 点击 commit 在编辑器右侧自动打开 diff | 已有发布功能;本轮对齐多栏呈现和交互,[工作台任务](https://github.com/KRPCT/InkStream/issues/47)记录新增证据。 | +| GRAPH-GIT-07 | 菜单 View→Git Graph 与 Ctrl+Shift+G | 已有发布功能;本轮对齐多栏呈现和交互,[工作台任务](https://github.com/KRPCT/InkStream/issues/47)记录新增证据。 | +| GH-01 | OAuth Device Flow 登录 | 已有发布实现;真实账户/文献矩阵见 [文献](https://github.com/KRPCT/InkStream/issues/29)、[登录](https://github.com/KRPCT/InkStream/issues/36)、[评论](https://github.com/KRPCT/InkStream/issues/37)。 | +| GH-02 | PAT 备用登录 | 已有发布实现;真实账户/文献矩阵见 [文献](https://github.com/KRPCT/InkStream/issues/29)、[登录](https://github.com/KRPCT/InkStream/issues/36)、[评论](https://github.com/KRPCT/InkStream/issues/37)。 | +| GH-03 | 已登录 gh CLI 备用登录 | 已有发布实现;真实账户/文献矩阵见 [文献](https://github.com/KRPCT/InkStream/issues/29)、[登录](https://github.com/KRPCT/InkStream/issues/36)、[评论](https://github.com/KRPCT/InkStream/issues/37)。 | +| GH-04 | Issue 浏览、评论、创建 | 已有发布实现;真实账户/文献矩阵见 [文献](https://github.com/KRPCT/InkStream/issues/29)、[登录](https://github.com/KRPCT/InkStream/issues/36)、[评论](https://github.com/KRPCT/InkStream/issues/37)。 | +| GH-05 | PR 浏览、评论、创建 | 已有发布实现;真实账户/文献矩阵见 [文献](https://github.com/KRPCT/InkStream/issues/29)、[登录](https://github.com/KRPCT/InkStream/issues/36)、[评论](https://github.com/KRPCT/InkStream/issues/37)。 | +| GH-06 | PR diff 内嵌编辑器 | 已有发布实现;真实账户/文献矩阵见 [文献](https://github.com/KRPCT/InkStream/issues/29)、[登录](https://github.com/KRPCT/InkStream/issues/36)、[评论](https://github.com/KRPCT/InkStream/issues/37)。 | +| GH-07 | PR review 评论回复 | 已有发布实现;真实账户/文献矩阵见 [文献](https://github.com/KRPCT/InkStream/issues/29)、[登录](https://github.com/KRPCT/InkStream/issues/36)、[评论](https://github.com/KRPCT/InkStream/issues/37)。 | +| DIFF-01 | 中英句级分词→LCS→段落对齐→语义高亮 | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| DIFF-02 | prose-aware 三向冲突解决器 | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| LINK-01 | wiki-link 基础目标及 alias | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| LINK-02 | `#heading` 链接定位 | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| LINK-03 | `^block-id` 链接定位 | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| LINK-04 | SQLite FTS5 全库索引 | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| LINK-05 | 编辑增量索引 | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| LINK-06 | 反链含未链接提及 | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| LINK-07 | 全库图谱 | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| LINK-08 | 当前文档 Local Graph | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| ZOT-01 | 本地 CAYW HTTP 主路,需 Zotero+BBT | 已有发布实现;真实账户/文献矩阵见 [文献](https://github.com/KRPCT/InkStream/issues/29)、[登录](https://github.com/KRPCT/InkStream/issues/36)、[评论](https://github.com/KRPCT/InkStream/issues/37)。 | +| ZOT-02 | Web API 增量、离线 SQLite 缓存 | 已有发布实现;真实账户/文献矩阵见 [文献](https://github.com/KRPCT/InkStream/issues/29)、[登录](https://github.com/KRPCT/InkStream/issues/36)、[评论](https://github.com/KRPCT/InkStream/issues/37)。 | +| ZOT-03 | 命令面板 Cite from Zotero + 引用面板 + Insert Bibliography | 已有发布实现;真实账户/文献矩阵见 [文献](https://github.com/KRPCT/InkStream/issues/29)、[登录](https://github.com/KRPCT/InkStream/issues/36)、[评论](https://github.com/KRPCT/InkStream/issues/37)。 | +| ZOT-04 | Typst `#cite()` / LaTeX `\cite{}` 自动联动 | 已有发布实现;真实账户/文献矩阵见 [文献](https://github.com/KRPCT/InkStream/issues/29)、[登录](https://github.com/KRPCT/InkStream/issues/36)、[评论](https://github.com/KRPCT/InkStream/issues/37)。 | +| USER-01 | §1:研究者可在一 App 完成引用、公式、Git 多稿及 Prose Diff | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| USER-02 | §1:创作者章节、Codex、专注及多稿合并 | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| USER-03 | §1/§9:Obsidian 主题导入即用、兼容主题 | 主题变量导入已发布;[真实主题矩阵](https://github.com/KRPCT/InkStream/issues/38)保留,非任意 CSS 兼容声明。 | +| USER-04 | §1:混合 Markdown 与多语言代码写作 | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| REL-01 | §2/§3:切模式/操作不丢纯文本 | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| REL-02 | §4/§5:工作区身份与索引正确 | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| REL-03 | §4:Git 认证和远程动作可信 | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| REL-04 | 桌面编辑的文件属性与大文件响应 | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| REL-05 | 旧开发标准所需可执行验证基线 | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | +| REL-06 | 后续已加入的功能不得因补旧 PRD 回归 | 已有发布实现或保持的行为约束;完整平台/组合场景仍由[总验收](https://github.com/KRPCT/InkStream/issues/25)逐项收口。 | + +## 技术约束的当前解释 + +- 保留主 CodeMirror、纯文本权威与文档身份/保存/恢复边界;辅助视图不是独立正文权威。 +- 配色按当前用户确认的纸白、石墨灰、灰绿;旧固定模式色不阻止 UX 收敛,语法/错误等有功能的颜色仍保留。 +- 保留当前 Tauri/React/Zustand、类型约束与 CSS token;版本从实际配置读取。 +- Git 由 git2 与受管系统 git 共同承担;GitHub REST/Device Flow 使用现有原生实现,不要求旧指定 SDK。 +- GSD 与已缺失旧 ORACLE/UI-SPEC 的历史引用不再是当前强制入口。当前遵循 wayfinder、DDD/BDD 与明确用户要求。 + +## 旧范围边界 + +原路线图的云协作、插件市场、多项目后台并行等未来设想不因发布号为 2.0.0 而自动实现或纳入本轮。已出现的阅读/书架/终端/导出/主题/更新能力按现有产品文档维护。完整原始审计保存在本地 governance-originals,旧失败与旧未验证记录不被改写为通过。 diff --git a/docs/REVIEW-SUMMARY.md b/docs/REVIEW-SUMMARY.md new file mode 100644 index 0000000..57ef24e --- /dev/null +++ b/docs/REVIEW-SUMMARY.md @@ -0,0 +1,12 @@ +# 当前文档审阅入口 + +2.0.0 已发布;本轮已获授权更新文档和 issues,并按 DDD/BDD 完成原型多栏对齐及 ComputerUse 验收。 + +- 当前事实与证据:[CURRENT-STATE](CURRENT-STATE.md)。 +- 产品要求:本地 `PRD.md`(遵守既有忽略规则,不随源码发布);词汇:[CONTEXT](../CONTEXT.md)。 +- 职责与规则:[ARCHITECTURE](ARCHITECTURE.md)、[DECISIONS](DECISIONS.md)。 +- UX 方向:[UIUX-DIRECTION](UIUX-DIRECTION.md)。 +- 执行:[DDD-PLAN](DDD-PLAN.md)、[EXECUTION-PLAN](EXECUTION-PLAN.md)、[EXECUTION-PROGRESS](EXECUTION-PROGRESS.md)。 +- 旧承诺:[LEGACY-PRD-COVERAGE](LEGACY-PRD-COVERAGE.md);行为自动化边界:[AUTOMATION](specs/AUTOMATION.md)。 + +历史审计保留其原日期,不把旧未实施/草稿 PR 状态作为当前指令。 diff --git a/docs/UIUX-DIRECTION.md b/docs/UIUX-DIRECTION.md new file mode 100644 index 0000000..ef9afed --- /dev/null +++ b/docs/UIUX-DIRECTION.md @@ -0,0 +1,28 @@ +# UIUX 方向与当前对齐范围 + +截至 2026-09-13,B+A+C 方向已确认并部分实现于 2.0.0。本轮继续对齐多栏 UX 与功能;发布/验收状态见 [CURRENT-STATE](CURRENT-STATE.md)。 + +## 已确认方向 + +B 是日常写作界面:项目轨、项目内导航、大面积文稿和上下文工具。A 是点击或 Ctrl+Alt+P 展开的项目浮层,不推挤正文。C 让学术材料/引用与文稿相邻。三模式同等,默认通用写作。 + +项目有独立名称、封面、收藏及会话;关联一个内容目录,Git 根独立。切换先保存与快照,失败停留,成功恢复目标会话;这些已发布的约束继续保持。 + +## 后续用户修订 + +- 采用最终双层竖板与流动墨带 SVG,原型品牌图和早期波浪档案图标已退役。 +- 配色方向为中性纸白、石墨灰、低饱和灰绿。 +- popup 背景另行设计,2.0.0 已去掉斜纹/模糊底板及两处英文装饰。本轮不把“只调整图标拟物”误读为删除工作台全部既有材料。 +- 先完成本地实现与 UI,真实账号验收独立保留;旧 v1 全验收不再阻塞本轮 UI。 + +## 本轮对齐 + +工作区视图、文档标签、模式的职责要清楚;原型的概览/文稿/文献/版本入口应由真实功能承接。项目轨可见多个真实项目。文献先选中看详情,再明确插入。去除重复控件和无用英文,保留有意义的术语与状态。正文的字体、留白及工具密度按原型节奏收敛。 + +原型中的假字数、进度、文献与提交记录不直接移植。当前 SVG/popup 方向保留,具体差距和通过情况由行为测试及 ComputerUse 记录。 + +## 验收条件 + +覆盖长名称、多个项目、空/加载/失败、三模式、键盘焦点、面板拖动/折叠、缩放和 reduced 偏好。视图切换不丢正文、选区与撤销;项目切换继续受保存协议保护。 + +参考源为用户提供的 inkstream-uiux.html,以及本地 codex/prototype-uiux-direction 分支的原型源码;它们是讨论与对照材料,不是额外用户指令。原型图片或浏览器桩不等同原生/真实账号/物理 IME 验收。 diff --git a/docs/VERIFICATION-2026-09-12.md b/docs/VERIFICATION-2026-09-12.md new file mode 100644 index 0000000..e21119e --- /dev/null +++ b/docs/VERIFICATION-2026-09-12.md @@ -0,0 +1,180 @@ +# 历史记录:VERIFICATION-2026-09-12.md + +此文件保留原日期、原工作树与当时证据。2.0.0 的实现/合并/发布现状见 [CURRENT-STATE](CURRENT-STATE.md);下面“尚未实施/未推送/草稿 PR”等文字是历史状态,不作为当前指令。 + +
+查看原始历史记录 + +# 2026-09-12 续接验证与旧 v1 验收索引 + +本报告记录当前 `codex/con-repair-v1` 的未提交工作区。原分支未改变;没有推送或触发 GitHub Actions。 + +**旧 v1 总验收 #25 仍开放;正式 UIUX、新项目档案与持久草稿尚未开始。** 测试文件关联只用于定位证据,不表示一整行用户需求已经验收。 + +## 已核验结果 + +| 检查 | 结果 | 本机证据 | +|---|---|---| +| typecheck | 通过 | [报告](../coverage/acceptance/ci-typecheck-win32-1789192346084-58100/ci-summary.json) | +| lint | 通过 | [报告](../coverage/acceptance/ci-lint-win32-1789192465348-46236/ci-summary.json) | +| test | 1707/1707,无失败、跳过或超时 | [报告](../coverage/acceptance/ci-test-win32-1789192674321-41828/ci-summary.json) | +| build | 通过 | [报告](../coverage/acceptance/ci-build-win32-1789192471654-55828/ci-summary.json) | +| Windows Rust | 208 通过;1 个进程 helper 由其他测试调用;复用最近一次原生报告 | [报告](../coverage/acceptance/rust-win32-1789187386473-59604/rust-summary.json) | +| Windows 原生学术流程 | 22 个检查点通过;使用合成 BBT 与模拟 composition 事件 | [记录](../coverage/acceptance/native-academic-20260912-135519/academic-checks.json) | +| Windows 原生分支比较 | 15 个已通过检查点;复用此前实际 WebView 证据 | [记录](../coverage/acceptance/native-compare-20260912-114656/browser-checks.json) | + +新增修复:实时预览只隐藏 Markdown 转义前缀,保留 `[1]`、`[J]` 等字面标点;活动行、源码模式、代码块、IME 与撤销保持原文。先复现 4 项失败,再通过 100 项相关回归,最后重建并以原生截图核验。 + +[修复后原生截图](../coverage/acceptance/native-academic-20260912-135519/academic-bibliography.png)。最终源文件校验值与进程/端口结果见[工作区汇总](../coverage/acceptance/continuation-20260912/summary.json)和[源码哈希](../coverage/acceptance/continuation-20260912/source-sha256.json)。 + +生产 `dist` 已检查,不含测试桥接入口。两次本轮原生测试的 HEAD、index、工作树快照一致;其子进程已回收,1420/9229/23119 端口关闭。 + +## 仍未满足的进入条件 + +Linux:本机 WSL 列出 Ubuntu 24.04,但实例启动返回 `Wsl/Service/CreateInstance/CreateVm/HCS/HCS_E_SERVICE_NOT_AVAILABLE`。仅作只读诊断,没有启用系统功能或修改虚拟化服务。macOS:Darwin 进程回收修复仍无该平台执行证据。 + +外部服务:构建环境未提供 `INKSTREAM_GITHUB_CLIENT_ID`。真实 GitHub OAuth、系统钥匙串、Zotero/BBT 与 Web API、授权远程 clone/Git/PR 回复仍未验收;本地合成服务不能替代。此前已提出配置依赖,本轮没有重复索取凭据,也没有发送远程评论。 + +本地完整场景:基础写作、索引/真实 watcher、长篇创作、全部 Git 入口、主题导入与既有能力的贯通流程仍需逐行核对或归档。`scripts/acceptance/bindings.mjs` 中原有 partial/pending 没有被批量改成完成。 + +## 证据组与剩余场景 + +| 组 | 范围 | 相关检查(不等于完整覆盖) | 尚缺证据 | +|---|---|---|---| +| DOC | 文档保存与生命周期 | [document-session.integration.test.tsx](../src/test/document-session.integration.test.tsx)、[documentFileMutations.test.ts](../src/editor/documentFileMutations.test.ts)、[exitGuard.test.ts](../src/editor/exitGuard.test.ts) | DOC-01–08 的完整场景与磁盘往返证据仍须逐条归档。 | +| WIKI | 链接补全与定位 | [wikiLinkComplete.test.ts](../src/editor/livepreview/wikiLinkComplete.test.ts)、[wikiNavigation.test.ts](../src/editor/livepreview/wikiNavigation.test.ts)、[wikiAnchor.test.ts](../src/editor/livepreview/wikiAnchor.test.ts) | 组合输入、补全产物到真实点击、原生可见落点仍须贯通核对。 | +| INDEX | 索引与关系查询 | [indexLifecycle.test.ts](../src/ipc/indexLifecycle.test.ts)、[indexRefresh.test.ts](../src/ipc/indexRefresh.test.ts)、[BacklinksPanel.paragraph.test.tsx](../src/components/workbench/BacklinksPanel.paragraph.test.tsx)、[render.test.ts](../src/graph/render.test.ts) | WS-01–08 的真实 watcher、跨库索引及面板联动仍须归档。 | +| CITE | 引用与学术命令 | [academicActions.integration.test.ts](../src/editor/academicActions.integration.test.ts)、[academicActions.test.ts](../src/editor/academicActions.test.ts)、[citations.test.ts](../src/editor/citations.test.ts) | 22 个原生检查使用本地合成 BBT;真实 Zotero/BBT picker 与引用面板全场景待验收。 | +| BIB | 参考文献与转义显示 | [bibliography.integration.test.ts](../src/editor/bibliography.integration.test.ts)、[cslFormat.standard.test.ts](../src/editor/cslFormat.standard.test.ts)、[escapePreview.test.ts](../src/editor/livepreview/escapePreview.test.ts) | 真实文献库、多文献类型与三种样式的端到端符合性仍须核验。 | +| ZOT | 文献库账户与离线同步 | [ZoteroLibraryPanel.account.test.tsx](../src/components/workbench/ZoteroLibraryPanel.account.test.tsx)、[ZoteroLibraryPanel.test.tsx](../src/components/workbench/ZoteroLibraryPanel.test.tsx) | 真实 Web API 同步、断网重启、系统凭据库待验收;合成 HTTP/SQLite 不替代真实账户。 | +| TYP | Typst 预览与首次加载 | [TypstFlow.test.tsx](../src/components/workbench/TypstFlow.test.tsx)、[languages.typst.test.ts](../src/editor/languages.typst.test.ts)、[typstClient.lifecycle.test.ts](../src/editor/livepreview/typst/typstClient.lifecycle.test.ts) | 首次 .typ 原生语法树已有证据;完整双语法、多修订、故障恢复场景仍须逐条归档。 | +| EQ | 公式、编号与导出 | [equationNumbering.flow.test.tsx](../src/editor/equationNumbering.flow.test.tsx)、[equationPdf.flow.test.tsx](../src/editor/export/equationPdf.flow.test.tsx)、[slashCommand.test.ts](../src/editor/livepreview/slashCommand.test.ts) | 公式导出核心已有历史实机证据;原生保存对话框、重开与各编号场景仍须归档。 | +| CRE | 长篇创作 | [chapterTree.test.ts](../src/editor/chapterTree.test.ts)、[writingMetrics.test.ts](../src/editor/writingMetrics.test.ts)、[CodexPanel.lifecycle.test.tsx](../src/components/workbench/CodexPanel.lifecycle.test.tsx)、[focusMode.test.ts](../src/editor/livepreview/focusMode.test.ts) | 章节→Codex→目标→比较/合并→保存重开及物理中文 IME 的贯通验收未完成。 | +| CMP | 完整分支比较 | [BranchCompareView.test.tsx](../src/components/git/BranchCompareView.test.tsx)、[branchComparisonClient.test.ts](../src/editor/branchComparisonClient.test.ts)、[comparisonView.test.ts](../src/editor/comparisonView.test.ts)、[compareText.test.ts](../src/diff/compareText.test.ts) | Windows 双分支、长文、增删改名、分页与未保存缓冲场景已有原生证据;跨平台仍未验证。 | +| SHELL | 模式与工作区入口 | [totalAssembly.test.ts](../src/modes/totalAssembly.test.ts)、[WorkbenchLayout.test.tsx](../src/components/workbench/WorkbenchLayout.test.tsx)、[StatusBar.document.test.tsx](../src/components/workbench/StatusBar.document.test.tsx)、[FileTree.test.tsx](../src/components/workbench/FileTree.test.tsx) | 三模式长会话、能力关闭后继续编辑及全部入口仍须贯通核对。 | +| MD | Markdown 与实时预览 | [inlinePlugin.test.ts](../src/editor/livepreview/inlinePlugin.test.ts)、[escapePreview.test.ts](../src/editor/livepreview/escapePreview.test.ts)、[editorState.renderMode.test.ts](../src/editor/editorState.renderMode.test.ts)、[Toolbar.test.tsx](../src/editor/richtext/Toolbar.test.tsx) | 转义显示已有原生复验;其余语法与模式往返需按旧矩阵逐项归档。 | +| LANG | 多语言与文件格式 | [languages.test.ts](../src/editor/languages.test.ts)、[codeLanguages.test.ts](../src/editor/livepreview/codeLanguages.test.ts)、[frontmatter.test.ts](../src/editor/frontmatter.test.ts) | 各语言真实文件的首次打开、混合写作、保存重开与错误路径仍待逐项验收。 | +| GIT | 本地 Git 生命周期 | [gitActions.test.ts](../src/editor/gitActions.test.ts)、[gitWorktreeMutation.test.ts](../src/editor/gitWorktreeMutation.test.ts) | status/log/branch/diff 有真实 Rust 证据;全部菜单、右键、merge/cherry-pick/tag/reset 的完整生命周期仍需核验。 | +| REB | 本地 rebase | [BranchManager.rebase.test.tsx](../src/components/git/BranchManager.rebase.test.tsx)、[RebaseControls.test.tsx](../src/components/git/RebaseControls.test.tsx)、[gitWorktreeMutation.test.ts](../src/editor/gitWorktreeMutation.test.ts) | Windows Rust 成功/冲突/签名失败恢复通过;Linux/macOS 进程回收与原生入口全流程待验收。 | +| STA | Stash 管理 | [gitStashActions.test.ts](../src/editor/gitStashActions.test.ts)、[StashEntry.test.tsx](../src/components/git/StashEntry.test.tsx) | Rust 临时仓库恢复/冲突/身份通过;真实应用完整保存/恢复/删除手势链待归档。 | +| CLONE | 克隆与打开工作区 | [GitCloneDialog.test.tsx](../src/components/git/GitCloneDialog.test.tsx)、[CloneEntry.test.tsx](../src/components/workbench/CloneEntry.test.tsx) | 本地 Git 克隆与排他发布通过;授权远程、原生进度/取消/成功打开仍需验收。 | +| REMOTE | 远程 Git 与凭据目标 | [git.remote.test.ts](../src/ipc/git.remote.test.ts)、[gitCredential.test.ts](../src/ipc/gitCredential.test.ts)、[gitActions.test.ts](../src/editor/gitActions.test.ts) | 真实授权远程 Git、PAT/gh 与系统凭据链待验收;不代替用户注册或授权。 | +| GITUI | Git 图谱交互 | [layoutGraph.test.ts](../src/components/git/graph/layoutGraph.test.ts)、[builtins.test.ts](../src/commands/builtins.test.ts)、[menuConfig.test.ts](../src/components/workbench/menuConfig.test.ts) | Find、Filter Branches、仓库设置及各入口组合仍需逐项实际操作验收。 | +| AUTH | GitHub Device Flow | [GithubDeviceFlow.test.tsx](../src/components/settings/GithubDeviceFlow.test.tsx) | 需要 InkStream 自有公开 Client ID、真实授权与钥匙串读回;当前环境未配置该变量。 | +| PR | Issue / PR / review | [PrReply.test.tsx](../src/components/git/PrReply.test.tsx)、[CommentThread.scope.test.tsx](../src/components/git/CommentThread.scope.test.tsx) | 授权仓库真实读取、回复后读回、分页权限待验收;远程发送还需明确授权。 | +| MERGE | 三向冲突 | [parseConflicts.test.ts](../src/diff/parseConflicts.test.ts)、[MergeResolver.scope.test.tsx](../src/components/git/MergeResolver.scope.test.tsx) | base/ours/theirs 与全部非冲突上下文的原生合并/取消/保存重开链待验收。 | +| THEME | 主题导入兼容 | [themeImport.test.ts](../src/styles/themeImport.test.ts)、[ImportedTheme.test.tsx](../src/components/settings/ImportedTheme.test.tsx) | 代表性第三方主题、重启保持、取消及失败回退的原生证据仍需逐项归档。 | +| QUALITY | 传输、权限与检查基线 | [documentBudget.integration.test.tsx](../src/editor/documentBudget.integration.test.tsx)、[files.streaming.test.ts](../src/ipc/files.streaming.test.ts)、[files.writing.test.ts](../src/ipc/files.writing.test.ts) | Windows 检查与 Raw 传输已有证据;Unix 文件属性和 macOS 清理未验证,旧 CI 不替代验收。 | +| EXISTING | 后续既有能力 | [HtmlReader.transfer.test.tsx](../src/components/reading/HtmlReader.transfer.test.tsx)、[TerminalPanel.test.tsx](../src/components/terminal/TerminalPanel.test.tsx)、[replaceAll.test.ts](../src/editor/multibuffer/replaceAll.test.ts)、[useUpdaterStore.test.ts](../src/stores/useUpdaterStore.test.ts) | 简易模式、阅读/书架、终端、更新、multibuffer、缩放的完整组合仍需回归归档。 | +| E2E | 跨领域用户流程 | 须复用各子流程并实际贯通 | 前置子流程与真实外部依赖仍开放;不能由测试总数替代完整用户故事。 | + +## 原矩阵逐行索引 + +共 102 行,覆盖原矩阵第 1–7 节全部功能编号;第 8 节技术条款与第 9 节非目标维持原裁定。每行完整接受仍为 false,不能由本表关联自动关闭 #25。详细机器记录见 [legacy-v1-rows.json](../coverage/acceptance/continuation-20260912/legacy-v1-rows.json)。 + +| 原编号 | 证据组 | 完整场景验收 | +|---|---|---| +| US-S1 | DOC | 待完整核验;缺口见对应组 | +| US-S2 | WIKI | 待完整核验;缺口见对应组 | +| US-S3 | WIKI | 待完整核验;缺口见对应组 | +| US-S4 | INDEX | 待完整核验;缺口见对应组 | +| US-S5 | INDEX | 待完整核验;缺口见对应组 | +| US-A1 | CITE | 待完整核验;缺口见对应组 | +| US-A2 | CITE | 待完整核验;缺口见对应组 | +| US-A3 | TYP | 待完整核验;缺口见对应组 | +| US-A4 | BIB | 待完整核验;缺口见对应组 | +| US-A5 | ZOT | 待完整核验;缺口见对应组 | +| US-C1 | CRE | 待完整核验;缺口见对应组 | +| US-C2 | CRE | 待完整核验;缺口见对应组 | +| US-C3 | CRE | 待完整核验;缺口见对应组 | +| US-C4 | CRE | 待完整核验;缺口见对应组 | +| US-C5 | CMP | 待完整核验;缺口见对应组 | +| US-F1 | EQ | 待完整核验;缺口见对应组 | +| US-F2 | TYP | 待完整核验;缺口见对应组 | +| US-F3 | EQ | 待完整核验;缺口见对应组 | +| MODE-01 | SHELL | 待完整核验;缺口见对应组 | +| STD-01 | SHELL | 待完整核验;缺口见对应组 | +| STD-02 | SHELL | 待完整核验;缺口见对应组 | +| STD-03 | SHELL | 待完整核验;缺口见对应组 | +| ACA-01 | ZOT | 待完整核验;缺口见对应组 | +| ACA-02 | TYP | 待完整核验;缺口见对应组 | +| ACA-03 | EQ | 待完整核验;缺口见对应组 | +| ACA-04 | TYP | 待完整核验;缺口见对应组 | +| CRE-01 | CRE | 待完整核验;缺口见对应组 | +| CRE-02 | CRE | 待完整核验;缺口见对应组 | +| CRE-03 | CRE | 待完整核验;缺口见对应组 | +| CRE-04 | CRE | 待完整核验;缺口见对应组 | +| EDIT-01 | DOC | 待完整核验;缺口见对应组 | +| EDIT-02 | MD | 待完整核验;缺口见对应组 | +| EDIT-03 | MD | 待完整核验;缺口见对应组 | +| EDIT-04 | MD | 待完整核验;缺口见对应组 | +| LANG-01 | MD | 待完整核验;缺口见对应组 | +| LANG-02 | LANG | 待完整核验;缺口见对应组 | +| LANG-03 | TYP | 待完整核验;缺口见对应组 | +| LANG-04 | LANG | 待完整核验;缺口见对应组 | +| LANG-05 | LANG | 待完整核验;缺口见对应组 | +| LANG-06 | LANG | 待完整核验;缺口见对应组 | +| LANG-07 | LANG | 待完整核验;缺口见对应组 | +| LANG-08 | LANG | 待完整核验;缺口见对应组 | +| LANG-09 | LANG | 待完整核验;缺口见对应组 | +| LANG-10 | LANG | 待完整核验;缺口见对应组 | +| LANG-11 | LANG | 待完整核验;缺口见对应组 | +| FMT-01 | DOC | 待完整核验;缺口见对应组 | +| FMT-02 | LANG | 待完整核验;缺口见对应组 | +| FMT-03 | MD | 待完整核验;缺口见对应组 | +| git_status | GIT | 待完整核验;缺口见对应组 | +| git_branch_list | GIT | 待完整核验;缺口见对应组 | +| git_log | GIT | 待完整核验;缺口见对应组 | +| git_diff | GIT | 待完整核验;缺口见对应组 | +| git_commit | GIT | 待完整核验;缺口见对应组 | +| git_checkout | GIT | 待完整核验;缺口见对应组 | +| git_merge | GIT | 待完整核验;缺口见对应组 | +| git_rebase | REB | 待完整核验;缺口见对应组 | +| git_cherry_pick | GIT | 待完整核验;缺口见对应组 | +| git_stash | STA | 待完整核验;缺口见对应组 | +| git_tag | GIT | 待完整核验;缺口见对应组 | +| git_reset | GIT | 待完整核验;缺口见对应组 | +| git_clone | CLONE | 待完整核验;缺口见对应组 | +| git_push | REMOTE | 待完整核验;缺口见对应组 | +| git_pull | REMOTE | 待完整核验;缺口见对应组 | +| git_fetch | REMOTE | 待完整核验;缺口见对应组 | +| GRAPH-GIT-01 | GITUI | 待完整核验;缺口见对应组 | +| GRAPH-GIT-02 | GIT | 待完整核验;缺口见对应组 | +| GRAPH-GIT-03 | GITUI | 待完整核验;缺口见对应组 | +| GRAPH-GIT-04 | GITUI | 待完整核验;缺口见对应组 | +| GRAPH-GIT-05 | REMOTE | 待完整核验;缺口见对应组 | +| GRAPH-GIT-06 | CMP | 待完整核验;缺口见对应组 | +| GRAPH-GIT-07 | GITUI | 待完整核验;缺口见对应组 | +| GH-01 | AUTH | 待完整核验;缺口见对应组 | +| GH-02 | REMOTE | 待完整核验;缺口见对应组 | +| GH-03 | REMOTE | 待完整核验;缺口见对应组 | +| GH-04 | PR | 待完整核验;缺口见对应组 | +| GH-05 | PR | 待完整核验;缺口见对应组 | +| GH-06 | PR | 待完整核验;缺口见对应组 | +| GH-07 | PR | 待完整核验;缺口见对应组 | +| DIFF-01 | CMP | 待完整核验;缺口见对应组 | +| DIFF-02 | MERGE | 待完整核验;缺口见对应组 | +| LINK-01 | WIKI | 待完整核验;缺口见对应组 | +| LINK-02 | WIKI | 待完整核验;缺口见对应组 | +| LINK-03 | WIKI | 待完整核验;缺口见对应组 | +| LINK-04 | INDEX | 待完整核验;缺口见对应组 | +| LINK-05 | INDEX | 待完整核验;缺口见对应组 | +| LINK-06 | INDEX | 待完整核验;缺口见对应组 | +| LINK-07 | INDEX | 待完整核验;缺口见对应组 | +| LINK-08 | INDEX | 待完整核验;缺口见对应组 | +| ZOT-01 | CITE | 待完整核验;缺口见对应组 | +| ZOT-02 | ZOT | 待完整核验;缺口见对应组 | +| ZOT-03 | CITE | 待完整核验;缺口见对应组 | +| ZOT-04 | CITE | 待完整核验;缺口见对应组 | +| USER-01 | E2E | 待完整核验;缺口见对应组 | +| USER-02 | E2E | 待完整核验;缺口见对应组 | +| USER-03 | THEME | 待完整核验;缺口见对应组 | +| USER-04 | LANG | 待完整核验;缺口见对应组 | +| REL-01 | DOC | 待完整核验;缺口见对应组 | +| REL-02 | INDEX | 待完整核验;缺口见对应组 | +| REL-03 | REMOTE | 待完整核验;缺口见对应组 | +| REL-04 | QUALITY | 待完整核验;缺口见对应组 | +| REL-05 | QUALITY | 待完整核验;缺口见对应组 | +| REL-06 | EXISTING | 待完整核验;缺口见对应组 | + +
diff --git a/docs/WORKBENCH-ACCEPTANCE.md b/docs/WORKBENCH-ACCEPTANCE.md new file mode 100644 index 0000000..1eee40e --- /dev/null +++ b/docs/WORKBENCH-ACCEPTANCE.md @@ -0,0 +1,63 @@ +# 多栏工作台验收记录 + +2026-09-13,实施分支 `codex/workbench-ux-v2`,发布基线 `v2.0.0 / ca4c214`。本轮记录对应[地图 45](https://github.com/KRPCT/InkStream/issues/45)、[实现 47](https://github.com/KRPCT/InkStream/issues/47)、[ComputerUse 48](https://github.com/KRPCT/InkStream/issues/48)。本分支尚未发布。 + +## 方法和边界 + +先写 [WB-01 至 WB-08](specs/workbench-ux.feature) 行为规格,再用真实 React、CodeMirror、项目会话与受控 IPC 边界验证。首个失败测试证明旧列表点击会立即插入;原生验收发现问题后继续补回归、修复和复验。 + +ComputerUse 使用 Windows 的 `@oai/sky`,实际操作普通 Tauri 构建的窗口、系统目录选择器、菜单、键盘和分隔线。此层没有 DOM 查询、页面脚本、store 注入或应用内自动化桥。独立应用标识为 `com.krpct.inkstream.workbenchcheck20260913`,不使用用户正式配置。 + +两个项目和文稿为本次创建的真实目录,Git 时间线读取测试仓库实际提交。文献经原生 HTTP/IPC 读取本机受控 BBT 响应,用于核对界面到插入的完整通路;不是 Zotero 真实账号验收。中文通过 ComputerUse 文本输入接口输入,不声称物理拼音输入法已验收。没有执行真实远端评论、推送或账号授权。 + +## 逐项观察 + +| 场景 | 实际观察 | 自动与原生证据边界 | +| --- | --- | --- | +| WB-01 概览与正文 | 项目文件数 3、已开文稿数随会话变化;概览往返保留正文选区和滚动,返回正文后可撤销;重启保留已保存内容与标签 | 实例身份由集成测试验证;原生观察见 03–07、26 | +| WB-02 项目切换 | 项目轨显示两个项目,长名称省略但完整名称可读;切回恢复两份标签和写入内容 | 38–39;保存失败由项目会话测试验证 | +| WB-02 目标不可用 | 暂时移动本次测试目录后,从项目轨打开它会显示错误,原项目仍为当前项目;关闭提示后可继续输入和保存 | 40–41;目录随后恢复,实际文件回读包含两段验收文字 | +| WB-03 文献 | 选择条目显示作者、年份、引用键、DOI 和摘要,正文计数不变;明确插入返回原文稿,引用落到原光标;一次撤销只移除该引用 | 08–11、29–30、48–49;最终窄栏插入按钮无需滚动即可使用,所用文献明确标为验收样本 | +| WB-04 库身份 | 旧列表与详情的迟到响应不能覆盖新库或形成插入目标 | 自动竞争时序测试;原生已验空库/失败呈现(50–51),错误后旧插入入口消失;不替代账号切换 | +| WB-05 键盘 | Home/方向键改变工作区焦点;文档方向键实际切换文稿;工具方向键实际显示反链内容 | 13、15–16;关闭的保存/冲突规则由相应集成测试覆盖 | +| WB-06 简易模式 | 在版本页启用简易模式后回到原文稿,文献/版本入口隐藏,正文保留 | 33–34;关闭简易模式后 Codex 工具恢复选中并显示内容,最终复验见 44–45 | +| WB-07 栏宽与缩放 | 文件栏拖宽后,两侧折叠互不影响;缩放复原保持拖过的宽度;放大后工具转为抽屉,收起即可继续输入 | 17–24、54–58,覆盖 100%、125%、130%、150%;临时几何不写回的来源判定另有自动回归 | +| WB-08 版本 | 实际提交信息与本地仓库一致;日常版本页保留两侧导航 | 12、33;无仓库空态与过期仓库过滤另有自动回归 | +| 三模式与主题 | 通用、学术、创作提供各自工具;暗色及减少动效、减少透明度设置可操作 | 28–36、42、54、56;54 明确显示减少效果开关开启;完整跨平台、GPU/长时与第三方主题矩阵不在这些观察中 | + +## 原生验收发现并修复 + +1. 状态栏滚动容器裁剪模式菜单。菜单改为锚定到按钮的独立弹出层;缩放/滚动/项目阻塞时关闭。150% 放大后的原生复验已显示完整菜单(27)。 +2. 简易模式退出后,创作工具仍记着不再可用的大纲,导致空白。右栏先派生当前可用目标,再收敛保存的活动工具;已复现 RED 并加入 WB-06 回归。 +3. 长文献详情会把插入按钮推到窄侧栏底部之外。资料独立滚动,明确插入操作留在固定的底部区域。 +4. 折叠面板退出键盘与辅助功能访问;设置开关补充名称。暗色采用原生暗色滚动条,并提升应用内 SVG 标记对比度;SVG 母版和桌面资源保持用户确认的版本。 + +## 最后验证状态 + +最终检查通过:243 份功能测试文件的 1908 项断言,加两份独立性能文件,共 1910 项,零失败、零跳过。41 项显式 BDD 绑定全部通过;Gherkin 未被解释执行,旧专项场景仍按各自证据保留 partial/pending。 + +最终 TypeScript、ESLint、Vite 与 Tauri 原生构建均通过。三轮 ComputerUse 已完成,最后一轮复验确认工具回退、常驻插入操作、暗色滚动条/标记、文献错误/空态和 125% 浮层。新母版未替换:仓库 SVG SHA-256 仍为 `58ffe1787e8802565d9ac5e5112e270a488954e00b1ecbc37ce11385a4d2510a`。 + +三轮应用进程 PID 分别为 50188、60288、61500,均经应用退出并完成所属 Job 清理;本次 WebView 子进程和本地 23119 监听均已回收。回读测试文件确认两段验收文字只写入原项目,另一项目不含它们,撤销后的引用也未留在文件中。 + +本地完整记录位于实施工作树的 `coverage/acceptance/workbench-v2/`:有界命令、进程盘点、三轮原生进程退出记录,以及 `cua/<序号>-<观察>.json/.jpg`。只将少量代表截图收入产品文档,原始日志、测试配置、测试项目和原生包留在忽略目录。 + +## 仍独立保留的验收 + +[41](https://github.com/KRPCT/InkStream/issues/41) 的严格同内容并排对照、密集项目矩阵,[42](https://github.com/KRPCT/InkStream/issues/42) 的安装图标/系统缓存,[43](https://github.com/KRPCT/InkStream/issues/43) 的完整弹窗矩阵,以及真实账户、跨平台和物理 IME 验收不能由本轮有限的 Windows 操作代替。相关票按已补证和剩余项继续管理。 + +## 最终构建截图 + +文稿、文献详情与大纲同时可见;插入操作保持在窄侧栏底部。 + +![最终多栏写作界面](assets/workbench/writing.jpg) + +暗色主题及可识别的 SVG 标记: + +![暗色工作台](assets/workbench/dark.jpg) + +125% 缩放、减少效果开启时的项目浮层,保留长项目名称: + +![项目档案](assets/workbench/archive-125.jpg) + +另见[暗色文献详情与常驻插入操作](assets/workbench/reference-action.jpg)。图片均来自真实窗口,文献内容是明确标示的验收样本。 diff --git a/docs/academic.md b/docs/academic.md index 3224fef..a557bd2 100644 --- a/docs/academic.md +++ b/docs/academic.md @@ -7,14 +7,16 @@ Academic(学术)模式把 Zotero 文献库、引用插入、参考文献编 InkStream 有三种写作模式(Standard / Academic / Creative),切换不会改变文件格式,只是调整界面布局与功能集。 - 按 `Ctrl+Shift+P` 打开命令面板,输入「学术」或「Academic」,选择「模式:切换到 Academic(学术)」。 -- 切换后,三处界面会随之变化:左侧边栏顶部出现「Zotero 文献库」,编辑器上方出现学术工具栏,右侧面板自动切到「引用」标签页。 +- 切换后,三处界面会随之变化:左侧分类可切换到「文献」,编辑器上方出现学术工具栏,右侧面板自动切到「引用」标签页。 ## 学术工具栏 -进入学术模式后,编辑器正上方常驻一条工具栏,按钮从左到右为: +进入学术模式后,编辑器上方的工具栏提供: - **引用**:等同于 `Ctrl+Shift+Z`,触发 Zotero 选择器插入引用。 - **脚注**:在光标处插入脚注标记 `[^N]`,并在文末追加对应的脚注定义行,光标自动移到定义处等你填写(编号自动取文档内未用过的最小数字)。 +- **公式编号**:为 Markdown 块公式启用编号并补充稳定标签。 +- **公式 PDF**:导出当前 LaTeX 围栏中的公式片段,范围与限制见[公式编号与引用](./equations.md)。 - **参考文献**:下拉菜单,含「插入 / 刷新(默认 GB/T 7714)」以及 GB/T 7714、APA、Vancouver 三种样式(详见下文)。 - **公式**:插入数学公式块。 @@ -38,11 +40,11 @@ InkStream 有三种写作模式(Standard / Academic / Creative),切换不 ## 从侧边栏文献库插入 -学术模式下左侧边栏顶部的「Zotero 文献库」直接列出 Zotero 库中的条目: +可从正文上方的「文献」进入完整文献工作区,也可在学术模式左侧分类选择「文献」,在正文旁查阅: -- 顶部输入框可按标题、作者或 citekey 过滤。 -- 点击任意一条,即在编辑器光标处插入对应的 `[@citekey]`(同样会按文档语言自动适配格式),无需再弹选择器。 -- 右上角的刷新按钮可重新拉取文献库。 +- 顶部输入框可按标题、作者、年份或 citekey 过滤。 +- 点击条目只选择并显示标题、作者、年份、引用键,以及可取得的出版物、DOI、摘要。按「插入所选引用」才在原文稿的当前选区插入,格式随语言适配;完整工作区会自动回到文稿。一次撤销只撤掉这次插入。长详情单独滚动,插入按钮保留在详情区底部。没有打开文稿时插入按钮不可用。 +- 右上角刷新重新读取文献库并清除旧选择。库身份变化会使在途结果失效,不能把旧库条目插入新会话。 - 当 Zotero 未运行时,若已配置过 Web API 同步,面板会自动改读本地离线缓存,并在标题旁显示一个离线小图标。 ## 引用面板与未解析标红 @@ -83,8 +85,12 @@ InkStream 有三种写作模式(Standard / Academic / Creative),切换不 注意事项: -- API Key 仅保存在本机操作系统的凭据库,不会上传,也不会回显到界面。 +- API Key 保存在本机操作系统的凭据库,仅用于向 Zotero API 认证,不回显到界面。 - 同步是增量的:每次只拉取上次同步以来的改动。 +- 缓存按 Zotero 用户库隔离。切换账户后读取各自缓存;旧版离线数据保留,需要为当前账户重新同步。 +- 同步期间库版本持续变化或下载失败时,不以不完整结果推进缓存与游标,按提示稍后重试。 - 离线时为「在线优先、离线回退」:先尝试连 Zotero,连不上再读缓存;缓存也为空时才报错。 +当前实现包含本地模块及协议回归;真实 Zotero/BBT 选择器、真实账户同步和跨平台排版仍需各自验证,不因 2.0 发布或 CI 成功而自动完成。 + ← 返回 [功能文档总览](./index.md) diff --git a/docs/assets/workbench/archive-125.jpg b/docs/assets/workbench/archive-125.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ca4ca9b4b1f603c15d22d24c57b8fc4e03d58a43 GIT binary patch literal 92399 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 D!x?y` literal 0 HcmV?d00001 diff --git a/docs/assets/workbench/dark.jpg b/docs/assets/workbench/dark.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bc61d66d839b03affa52867e207043619964660d GIT binary patch literal 89860 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 AA^-pY literal 0 HcmV?d00001 diff --git a/docs/assets/workbench/reference-action.jpg b/docs/assets/workbench/reference-action.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1c65f5b88659fb92e51b48d1c85e1e78013fdccf GIT binary patch literal 100675 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%0Aa08Bq-H2i#&pW)~ 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

`d{@*L6392xU4?*b;!D!b!+s- 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

Y=w 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 / DOCX 的核心属性),这是不可见的元信息,不影响正文。 +「文件 → 导出为 → 公式 PDF 片段…」另用于当前 LaTeX 公式,输出范围与整篇文档的「PDF…」不同;支持范围见[公式 PDF 片段](./equations.md#导出-latex-公式-pdf-片段)。 + ← 返回 [功能文档总览](./index.md) diff --git a/docs/git.md b/docs/git.md index 6042896..62b986f 100644 --- a/docs/git.md +++ b/docs/git.md @@ -1,6 +1,6 @@ # Git 版本管理 -InkStream 内置了 git。打开一个 git 仓库文件夹,就能在应用内提交、看历史、切分支、合并、推拉远程,不用切到终端。提交默认带 SSH 签名。 +InkStream 提供 Git 界面,结合 libgit2 与系统 Git 完成本地和远程操作。打开仓库文件夹后,可在应用内提交、看历史、切分支、合并、变基和推拉远程。产生提交的操作使用系统 Git 签名配置,需先准备可用的签名密钥。 ## 让工作区成为 git 工作区 @@ -10,7 +10,7 @@ git 功能只在「当前工作区是一个 git 仓库」时出现,否则相 - 如果你打开的子目录处在某个 git 仓库内部,顶部会出现引导条,询问「打开仓库根 还是 仅此文件夹」。选「打开仓库根」,整个仓库就会进入版本管理。 - 识别成功后,左下角状态栏会显示当前分支名;有未提交改动时分支名旁会亮一个小圆点。 -注意:当前版本不在应用内提供「克隆远程仓库」的对话框。请先用 git 把远程仓库克隆/初始化到本地,再用「打开文件夹」打开它。 +也可从「文件 → 克隆仓库…」或命令面板「克隆仓库…」开始:填写仓库 URL,选择父目录与新目录名。已有同名目录时不会开始克隆。对话框显示进度,支持取消和重试;完成后点击「打开工作区」才切换当前项目。克隆过程需要系统 Git,认证方式受下方远程设置约束。 ## 左侧栏:源代码管理(日常提交) @@ -31,7 +31,7 @@ git 功能只在「当前工作区是一个 git 仓库」时出现,否则相 Git Graph 是中央区的整页视图,分三栏: -- 左栏:提交图谱。顶部可切换「图谱 / 分支 / PR / Issues」四个标签。 +- 左栏:提交图谱。顶部可切换「图谱 / 分支 / 分支比较 / 暂存记录 / PR / Issues」六个标签。 - 中栏:选中提交的详情(信息、作者、时间、父提交、变更文件列表)。 - 右栏:选中文件的 diff,右上角可切换「行」diff 与「句」(句级 prose)diff。 @@ -51,11 +51,14 @@ Git Graph 是中央区的整页视图,分三栏: - 分组显示「当前分支 / 本地分支 / 远程分支」;当前分支卡片显示是否跟踪远程、领先/落后远程的提交数(↑/↓)。 - 右上角「新建」在当前提交创建分支并切过去。 - 把鼠标移到某分支上会出现操作按钮:切换到此分支、合并到当前分支、删除分支(远程分支不显示删除)。 +- 「将当前分支变基到此分支」或命令面板「本地变基…」启动本地变基。状态区提供继续、跳过当前提交、中止及停止正在执行的任务;停止进程不等同于中止整个变基序列。冲突解决后按提示继续,签名失败留下待提交结果时可「提交暂存结果并继续」。 - 切换分支时若有未提交改动导致失败,应用会询问是否「丢弃改动并强制切换」(此操作不可恢复,会再次确认)。 合并:在分支列表点某分支的「合并到当前分支」。产生冲突时会弹出警告,点提示可打开三向解决器逐处采纳本方/对方,或在解决器内中止本次合并。 -暂存(stash):工具条「暂存改动」会把当前改动(含未跟踪文件)暂存起来,可填一句备注。 +暂存(stash):工具条「暂存改动」会把当前改动(含未跟踪文件)暂存起来,可填一句备注。「暂存记录」页提供刷新、恢复并移除、删除记录。恢复失败或发生冲突时保留记录供后续处理;删除记录需要确认。 + +分支比较:打开「分支比较」标签可选择两个分支,固定提交后查看两侧完整正文,不切换工作树。操作说明见[Prose Diff 与合并冲突](./diff-merge.md)。 ## 提交右键菜单 @@ -85,14 +88,14 @@ Git Graph 是中央区的整页视图,分三栏: - 仅本地:只在本机做版本管理,不连任何远程。 - SSH:用 SSH 密钥与远程同步(推荐,支持 ed25519)。需先把公钥加入 GitHub 或你的服务器。 -- GitHub 登录:在「账户」分区填入 GitHub 个人访问令牌(PAT,需含 repo 权限),登录后 HTTPS 远程会自动带上令牌。若本机已安装并登录了 gh CLI,也可以直接用它登录。令牌只存在本机 OS 凭据库,不会上传。 -- 自定义服务器:填写自建或第三方 git 服务器地址。 +- GitHub 登录:在「账户」分区用 PAT、现有 gh CLI 凭据,或已配置 Client ID 的设备授权登录。凭据保存在本机 OS 凭据库,只向通过准入检查的 GitHub HTTPS 目标提供认证;私有仓库需相应权限。详见[GitHub 集成](./github.md)。 +- 自定义服务器:填写自建或第三方 git 服务器地址,只用于本次远程操作,不改写仓库的 remote 配置,也不向自定义地址发送 GitHub 令牌。 「账户」分区底部有「查看多设备同步教程」链接,提供图文同步指引。 ## SSH 签名(Verified) -InkStream 产生新提交的操作(提交、合并、cherry-pick、revert)默认带 SSH 签名,提交在 GitHub 上会显示为 Verified。 +InkStream 的提交、合并、cherry-pick、revert 使用系统 Git 的 `-S` 签名,遵循本机签名配置。GitHub 是否显示 Verified 还取决于签名密钥、账户关联和服务端校验,不能仅凭本地提交成功判定。 - 请确保本机已配置 SSH 签名密钥,并把对应公钥作为「签名密钥」加入 GitHub。 - 配好之后,应用内提交和你在终端手动签名的提交效果一样,不用再做别的设置。 diff --git a/docs/github.md b/docs/github.md index cb0668a..be4175b 100644 --- a/docs/github.md +++ b/docs/github.md @@ -32,7 +32,7 @@ GitHub 的 PR / Issues 视图位于 Git Graph 页面内。 - 按 `Ctrl+Shift+G` 打开 Git Graph,或从命令面板执行「Git Graph」。 - 仅在当前工作区是 git 仓库时可用;否则会提示「当前工作区不是 git 仓库」。 -Git Graph 顶部可切换图谱、分支、暂存记录、PR 与 Issues。点「PR」或「Issues」即可进入对应视图。 +Git Graph 顶部可切换图谱、分支、分支比较、暂存记录、PR 与 Issues。点「PR」或「Issues」即可进入对应视图。 提示:`Ctrl+G` 打开的是知识图谱(双向链接网络),与 Git Graph 不是同一个功能,请勿混用。 @@ -44,6 +44,7 @@ Git Graph 顶部可切换图谱、分支、暂存记录、PR 与 Issues。点「 - 点标题进入 PR 详情(中栏),同时右栏会载入该 PR 的逐文件 diff 供审阅。 - 点条目右侧的外链图标可在浏览器打开该 PR。 - 点顶部「刷新」重新拉取列表。 +- 列表按页加载,使用分页控件查看后续 PR;一页结果不是全部仓库记录。 新建 PR: @@ -77,6 +78,7 @@ PR 详情中的“代码审阅讨论”按文件位置列出原评论和回复 - 顶部有「开放 / 已关闭 / 全部」三个筛选按钮,切换查看不同状态的 Issue。 - 列表每条显示标题、编号、作者与评论数。 - 点「刷新」重新拉取列表。 +- 列表按页加载,筛选或切换仓库时重新读取对应结果。 新建 Issue: @@ -92,4 +94,6 @@ Issue 详情页与 PR 详情页底部都有共用的评论线程: - 上方按顺序列出已有评论,每条显示作者与内容。 - 在底部文本框写下内容,点「评论」即可发表。 +以上是 2.0 已实现的入口与处理流程。真实账户授权、令牌刷新及线上读写仍需对应账号验收;本地替身测试、CI 与 Release 成功不替代这些验证,当前状态见[验收边界](./specs/AUTOMATION.md)。 + ← 返回 [功能文档总览](./index.md) diff --git a/docs/graph.md b/docs/graph.md index aa707ce..f578e7f 100644 --- a/docs/graph.md +++ b/docs/graph.md @@ -4,8 +4,8 @@ ## 这是什么 -- **节点**:工作区内的每一个 `.md` 文件(一个圆点代表一篇笔记)。 -- **连线**:笔记之间的 wiki 链接(`[[目标笔记]]`)。一条链接画一条线。 +- **节点**:工作区内已索引的 `.md` / `.markdown` 文件(扩展名不区分大小写,一个圆点代表一篇笔记)。 +- **连线**:笔记之间唯一解析的 wiki 链接(`[[目标笔记]]`);同一来源到同一目标的重复链接合并,自链接与未解析链接不画线。 - **节点大小**:连接越多的笔记,圆点越大,便于找到中心笔记。 - **没有任何链接的笔记**也会作为孤立圆点出现,提醒你它还没有接入知识网络。 @@ -47,9 +47,10 @@ ## 注意事项 -- 图谱依赖工作区索引:只有被索引到的 `.md` 文件和已解析的链接才会出现。打开新笔记或修改链接后,如果图谱没及时反映,点「重新加载」即可。 -- 当工作区还没有可索引的文件、或尚未建立任何链接时,全库图谱会提示「工作区暂无可索引的文件,或尚未建立链接。」。 +- 图谱依赖本机项目索引:只有已索引的 Markdown 文件和唯一解析的链接才会出现;同名歧义链接不会猜选连线。打开新笔记或修改链接后,如果图谱没及时反映,点「重新加载」即可。 +- 没有已索引的 Markdown 文件时提示「工作区暂无可索引的 Markdown 文件。」;有笔记但没有连线时仍显示孤立节点。 - 局部图谱在没有打开文件、或当前文件还没有任何链接时,会显示空状态提示,请先打开一篇笔记并为它建立 `[[链接]]`。 +- 索引准备中或查询失败时分别显示状态与重试提示,不能把失败当作空图。简易模式会隐藏全库与局部图谱。 - 拖拽时即使经过节点也不会误触发打开,只有真正的点击才会打开笔记。 ← 返回 [功能文档总览](./index.md) diff --git a/docs/index.md b/docs/index.md index 89b382c..bc7a829 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,5 +1,7 @@ # InkStream 功能文档 +开发与验收的当前状态见 [CURRENT-STATE](CURRENT-STATE.md);领域词汇见 [CONTEXT](../CONTEXT.md),本轮多栏工作见 [执行计划](EXECUTION-PLAN.md)。 + InkStream(墨流)各功能的使用指南。每篇都从用户视角讲怎么用:打开方式、操作步骤、快捷键和注意事项。 > 下载安装与项目概览见 [仓库 README](../README.md)。 @@ -11,10 +13,12 @@ InkStream(墨流)各功能的使用指南。每篇都从用户视角讲怎 - [项目与恢复](./projects.md):本机项目档案、每项目会话、独立草稿、备份恢复与材质设置 - [快捷键与命令面板](./shortcuts.md):Ctrl+Shift+P 命令面板、快捷键表、F11 Focus Mode - [简易模式](./simple-mode.md):精简界面与高级功能开关 +- [导入主题](./themes.md):本地 CSS 预览、兼容报告、应用与恢复内置主题 ## 写作能力 - [数学公式块](./math.md):math (KaTeX) / typst / latex (MathJax)、`/` 触发器、行内与块公式 +- [公式编号与引用](./equations.md):稳定标签、文内跳转、导出编号与 LaTeX 公式 PDF 片段 - [双向链接与知识网络](./links.md):`[[wiki-link]]` 语法、`[[` 补全与跳转、反链面板、全库索引、Ctrl+P 快速打开 - [知识图谱](./graph.md):Ctrl+G 全库 Graph View、邻域高亮、局部图谱 - [学术模式与 Zotero](./academic.md):CAYW 插入引用、Citation Panel、参考文献(GB/T 7714 / APA / Vancouver)、Zotero 同步 @@ -24,15 +28,23 @@ InkStream(墨流)各功能的使用指南。每篇都从用户视角讲怎 ## 导出与阅读 - [文件导出](./export.md):导出当前文档为 HTML / PDF / DOCX(系统装 pandoc 后再加 ODT/RTF/LaTeX/EPUB/Typst/Org)、可定制水印、数学与链接处理 -- [阅读模式](./reading.md):txt / docx / epub / pdf 沉浸阅读、小说 vs 文献自动识别、亮 / 护眼 / 夜间配色 +- [阅读模式](./reading.md):txt / Markdown / docx / epub / pdf 阅读、目录与书签、续读和可选书架 ## 版本与协作 -- [Git 版本管理](./git.md):git-graph 三栏、提交 / 分支 / 合并 / stash、远程同步、SSH 签名 +- [Git 版本管理](./git.md):克隆入口、git-graph 三栏、提交 / 分支 / 本地变基 / stash 管理、远程同步与 SSH 签名 - [Prose Diff 与合并冲突](./diff-merge.md):句级语义 diff、prose 三向合并解决器 - [GitHub 集成](./github.md):PAT / gh CLI 登录、Issue / PR / review、内嵌 diff 审阅 - [自动更新](./update.md):启动静默检查、下载后重启升级、签名验签、手动检查更新 +## 验收与维护 + +- [BDD 自动化绑定状态](./specs/AUTOMATION.md):人工映射 Vitest、CI / Rust 执行范围和仍开放的验证事项 +- [工作台验收清单](../specs/01-workbench.spec.md):当前 2.0 工作台行为及自动、真机验证分工 +- [中文 IME 真机回归清单](../specs/03-live-preview-ime.spec.md):物理输入法矩阵,自动桩与发布结果不能代替签核 + --- ← 返回 [README](../README.md) + +多栏分支的已实现行为、测试与真实窗口观察见 [ComputerUse 验收记录](WORKBENCH-ACCEPTANCE.md)。 diff --git a/docs/links.md b/docs/links.md index 42f8aec..703b45b 100644 --- a/docs/links.md +++ b/docs/links.md @@ -1,6 +1,6 @@ # 双向链接与知识网络 -用 `[[ ]]` 在笔记之间建立链接。支持自动补全和点击跳转,链接目标不存在时会顺手建好;反链面板和全库索引则用来查看哪些笔记引用了当前文件。 +用 `[[ ]]` 在笔记之间建立链接。支持自动补全、定位跳转和确认后创建缺失目标;反链面板和全库索引用来查看哪些笔记引用了当前文件。 ## 什么是 wiki-link @@ -12,12 +12,13 @@ wiki-link 是用双方括号包住目标的链接写法,让一篇笔记指向 [[目标#标题^块|别名]] ``` -其中只有目标是必填的,后面三段都可选,可任意组合或省略: +跨文件链接指定目标,别名、标题与块标识按需填写;同一文档内的标题或块定位可省略文件名: - `[[目标]]`:最简形式,链接到名为「目标」的笔记。 - `|别名`:链接显示成别名,但实际指向「目标」。例如 `[[2024-总结|去年回顾]]` 在正文中显示为「去年回顾」。 - `#标题`:指向目标笔记中的某个标题段落,例如 `[[方法论#实验设计]]`。 - `^块`:指向目标笔记中的某个文本块,例如 `[[读书笔记^p3]]`。 +- 当前文档定位:`[[#实验设计]]`、`[[#^p3]]`;公式标签引用另见[公式编号与引用](./equations.md)。 注意事项: @@ -31,15 +32,15 @@ wiki-link 是用双方括号包住目标的链接写法,让一篇笔记指向 - 列表按文件名相关度排序,单次最多展示 50 个候选。 - 候选项的副标题会显示该文件的相对路径,便于区分同名文件。 -- 选中某项后会插入 `[[文件名]]`(自动去掉 `.md` 后缀,光标落在 `]]` 之后)。 +- 选中某项后保留它的工作区相对路径,避免同名文件丢失身份。例如选择 `资料/笔记.md` 会插入 `[[资料/笔记|笔记]]`,光标落在 `]]` 之后。 -## 点击跳转与「不存在即建」 +## 点击跳转与创建缺失目标 按住 `Ctrl`(macOS 上为 `Cmd`)点击一个 wiki-link 即可跳转: -1. 先在工作区内按精确相对路径查找目标,找不到再按文件名匹配(裸名 `[[笔记名]]` 即可命中,多个同名时取第一个)。 -2. 命中目标时,在当前编辑器内直接打开它。 -3. 目标笔记不存在时,会自动新建 `目标.md`、打开它、刷新文件树,并弹出提示「『目标.md』不存在,已新建并打开。」 +1. 优先匹配精确相对路径;裸文件名可以匹配唯一同名目标。多个同名时提示补全目录路径,不猜选第一个;显式路径不会降级跳到别处的同名文件。 +2. 唯一命中时打开文件,并按标题或块标识定位。定位不存在或不唯一时提示原因,保留文档当前位置。 +3. 目标不存在时弹出「创建链接目标」确认,选择「创建并打开」后才创建空白 Markdown 文档。取消不写文件;父目录缺失等创建失败会提示原因。 补充说明: @@ -54,13 +55,14 @@ wiki-link 是用双方括号包住目标的链接写法,让一篇笔记指向 - 内容随当前打开的文档自动更新,分为两组: - **反向链接**:用 `[[ ]]` 明确链接到当前文件的其他笔记。 - **未链接提及**:正文里提到了当前文件名、但还没有建立 `[[ ]]` 链接的笔记。可据此把零散提及补成正式链接。 -- 每组标题后带数量统计;点击任意一行即可在编辑器中打开对应笔记。 +- 每组标题后带数量统计。反向链接显示来源段落,点击按当前正文重新定位该引用;未链接提及点击打开来源笔记。 - 当前文件没有任何反链与提及时,面板显示「暂无反向链接」的空态提示。 注意事项: -- 「未链接提及」依赖全文索引的三元组匹配,文件名少于 3 个字时不会进行提及检索。 +- 「未链接提及」支持一至两个字符的短词查询,代码、已有链接与公式中的文字会被排除。 - 反链结果会排除文件自身,「未链接提及」也会自动剔除已经建立链接的笔记,避免重复。 +- 索引准备中、关闭或查询失败会分别显示状态,失败不显示成「没有关系」,可按提示重试。 ## 全库索引与重建 @@ -78,4 +80,8 @@ wiki-link 是用双方括号包住目标的链接写法,让一篇笔记指向 - 结果行标题为文件名,副标题为相对路径,便于区分不同目录下的同名文件。 - 选中某项后会在编辑器中打开它。 +## 全库搜索替换 + +按 `Ctrl+Shift+F`,或执行「视图:全库搜索替换」,在项目索引中搜索正文并查看命中片段。此入口依赖完整模式与当前项目索引;切换项目后,旧查询结果不能继续用于新项目的替换。 + ← 返回 [功能文档总览](./index.md) diff --git a/docs/math.md b/docs/math.md index a010b22..6b70dce 100644 --- a/docs/math.md +++ b/docs/math.md @@ -20,6 +20,8 @@ E = mc^2 把光标移出块外,公式即自动渲染;把光标移回块内,块会还原成可编辑的源码。 +Typst 还支持 `:::typst` 容器写法,以单独一行 `:::` 结束,与 Typst 围栏共用公式编辑和编号流程。 + ## 用 /math 触发器插入 在编辑器的空白处或空格后键入 `/`,会弹出补全菜单,可快速插入公式块: @@ -45,11 +47,12 @@ E = mc^2 ## 就地编辑与悬浮工具栏 -公式渲染后,把鼠标移到公式上会出现一个悬浮工具栏,提供三个按钮: +块公式渲染后,把鼠标移到公式上会出现 SVG 图标工具栏,基础操作为: - 编辑(双栏预览):打开一个左右分栏面板,左侧编辑源码、右侧实时预览。 - 复制源码:把该公式的源码复制到剪贴板。 - 删除公式块:移除整个公式块。 +- LaTeX 块额外提供「导出公式 PDF」,用于导出当前公式矢量片段,详见[公式编号与引用](./equations.md)。 进入编辑的方式有两种:点击已渲染的公式,或点工具栏的「编辑」按钮。双栏面板里编辑完成后,点「完成」按钮或按 `Esc` 即退出,恢复就地渲染。 @@ -63,4 +66,6 @@ E = mc^2 注意:Typst 引擎相对较重(首次加载需要拉取较大的 wasm 模块),首个 Typst 块出现时可能会有短暂的「编译中」占位,属正常现象。 +大文档基础编辑档暂停实时预览与完整编号扫描;需显式启用完整排版后使用相关编辑入口。公式编号、标签引用与片段导出不等于完整 TeX 文档或任意宏包编译。 + ← 返回 [功能文档总览](./index.md) diff --git a/docs/modes.md b/docs/modes.md index 5e5f996..26821e9 100644 --- a/docs/modes.md +++ b/docs/modes.md @@ -14,18 +14,20 @@ InkStream 用同一个编辑器内核提供 Standard(通用)、Academic( - 点击窗口右下角状态栏的**模式指示器**(带圆点的模式名),在弹出菜单中选择目标模式,当前模式行尾会有勾选标记。 - 或打开命令面板(Ctrl+Shift+P),执行「模式:切换到 Standard / Academic / Creative」。 +- 或从标题栏「视图 → 模式」选择目标模式。 -模式没有占用全局快捷键,切换一律通过上面两种入口完成。 +模式没有占用全局快捷键。简易模式会隐藏模式切换入口。 ## 布局与面板 -界面分为三栏:左侧边栏(文件树等)、中央编辑区、右侧面板。 +当前分支在 2.0.0 的项目浮层基础上增加常态多项目轨、文件侧栏、概览/文稿/文献/版本四个工作区入口及右侧上下文工具。主编辑器持续挂载。宽度不超过 1100px 时右栏成为抽屉,不超过 760px 时文件栏也成为抽屉。新会话默认导航宽 220px、工具宽 260px;已保存的项目布局保持原值。此变更尚未发布,发布基线见 [CURRENT-STATE](CURRENT-STATE.md)。 - **每种模式各自记忆布局**:你在某个模式下调整的栏宽与折叠状态,会单独保存到该模式;切回来时恢复原样。 -- 切换左侧边栏:Ctrl+\(也可点编辑器标签栏最左侧的面板按钮)。 -- 切换右侧面板:Ctrl+Alt+B(也可点标签栏最右侧的面板按钮)。 +- 切换左侧边栏:Ctrl+\(也可点项目轨底部的文件导航按钮)。 +- 切换右侧面板:Ctrl+Alt+B(也可点项目轨底部的工具面板按钮)。 - 重置当前模式布局:命令面板执行「视图:重置当前模式布局」。 -- 右侧面板顶部按模式列出对应的标签,点击标签切换;当前没有内容时显示该标签的空态提示。 +- 右侧面板顶部按模式列出对应标签。工作区、文稿和工具标签均可用方向键及 Home/End 切换,Tab 只进入一个活动标签。退出简易模式时,右栏自动选中当前模式的可用工具。项目轨的两栏按钮标明展开状态,切换一侧不影响另一侧;空内容显示明确提示。 +- 「视图」菜单的打字机和专注模式带实时勾选标记;状态栏模式选择菜单标出当前写作模式。按钮图标使用 SVG,含项目导航、侧栏切换和模式勾选等入口。 ## 打开文件夹作工作区 @@ -35,7 +37,7 @@ InkStream 以一个文件夹为工作区(同一窗口同时只有一个工作 2. 在弹出的系统目录对话框中选择文件夹,确认后该文件夹即成为当前工作区,文件树随之载入。 3. 侧边栏空态还会列出**最近打开**的工作区,点击任一项即可直接重开。 -切换到另一个工作区时,若当前工作区是 git 仓库且有未提交更改,会先提示「直接切换 / 提交并切换 / 取消」。切换工作区不会动到磁盘上的文件,已打开的文件仍保留在原处。 +切换内容文件夹走项目会话流程:先保存当前已修改文件及草稿、会话,再打开目标项目并恢复它自己的标签和布局。保存、会话快照或目标读取失败时保留原项目;Git 写入或远程操作进行中不能切换。Git 尚未提交的更改与尚未保存的正文是不同状态,详见[项目与恢复](./projects.md)。 ## 文件树操作 diff --git a/docs/projects.md b/docs/projects.md index 5abd259..3f75dc7 100644 --- a/docs/projects.md +++ b/docs/projects.md @@ -1,5 +1,7 @@ # 项目与恢复 +当前分支的项目轨显示多个本机项目及封面,收藏优先、最近打开靠前。直接点击封面走同一保存与恢复入口;切换失败保持原项目并打开档案展示错误。项目概览展示实际文件数、已开文稿和待保存数量,版本页展示真实提交;高级分支、差异和远端操作从「打开版本管理」进入。本轮功能状态及验收见 [CURRENT-STATE](CURRENT-STATE.md)。 + 点击左侧「项目」或按 `Ctrl+Alt+P` 打开项目档案。选择一个内容文件夹后,InkStream 为它建立本机项目记录。内容目录可以不是 Git 仓库,也可以位于某个仓库的子目录中。 项目名称、封面、收藏、文档会话和搜索索引保存在应用数据目录。你的文件仍留在原内容目录;旧目录中已有的 `.inkstream` 或其他未知文件会保留。 diff --git a/docs/reading.md b/docs/reading.md index 87b3ab2..f4dc210 100644 --- a/docs/reading.md +++ b/docs/reading.md @@ -1,10 +1,11 @@ # 阅读模式 -InkStream 除了写作,也能当阅读器用。打开 txt、Word(docx)、EPUB 电子书或 PDF,它会切到一个全屏阅读界面:盖住编辑器和两侧面板,隐藏与阅读无关的功能,只留下正文和一条简单的工具栏。 +InkStream 可阅读 txt、Markdown、Word(docx)、EPUB 电子书和 PDF。阅读视图覆盖工作区中的编辑器与两侧面板,保留正文和阅读工具栏,不切换操作系统全屏。 ## 支持的格式 - **txt**:纯文本 +- **md / markdown**:Markdown 文档的阅读视图 - **docx**:Word 文档(转换为排版后的正文) - **epub**:电子书(按章节顺序连续呈现) - **pdf**:逐页渲染、滚动阅读 @@ -12,15 +13,19 @@ InkStream 除了写作,也能当阅读器用。打开 txt、Word(docx)、E ## 怎么进入 - **docx / epub / pdf**:直接打开即自动进入阅读模式(它们不可编辑)。打开方式包括:文件菜单 → 打开文件、把文件拖进窗口、或在系统里用 InkStream「打开方式」。 -- **txt**:默认仍在编辑器里打开(txt 可编辑);想换成阅读视图时,用命令面板(`Ctrl+Shift+P`)→「视图:阅读模式」把当前 txt 切过去。 +- **txt / md / markdown**:默认在编辑器中打开;通过「视图 → 阅读模式」或命令面板(`Ctrl+Shift+P`)→「视图:阅读模式」进入阅读。阅读视图读取磁盘文件,未保存的正文请先保存;未命名草稿需先另存为文件。 ## 工具栏 阅读界面顶部的工具栏只有几个按钮: - **文体切换**(小说 / 文献):见下节。 -- **字号** −/+:调节正文大小。 -- **配色**:在 亮色 / 护眼(米黄)/ 夜间 三种配色间循环切换,长时间阅读时换护眼或夜间会舒服一些。 +- **排版设置**:文本阅读可调整字体、字号、版心宽度与页边距;PDF 不显示这些文本重排控件。 +- **配色**:用「亮 / 护眼 / 夜间」分段按钮选择,当前项高亮。 +- **目录**:文本提取到标题后显示,点击可定位到对应段落。 +- **书签**:文本阅读可添加当前位置、跳转或删除书签;PDF 当前不提供这个块级书签入口。 +- **上一章 / 下一章**:从书架打开有章节结构的书籍时显示。 +- **加入书架**:启用书架后,对尚未上架的 txt / docx / epub / pdf 显示;Markdown 不加入书架。 - **关闭**:回到编辑器。 ## 自动识别小说 vs 文献 @@ -34,8 +39,14 @@ InkStream 除了写作,也能当阅读器用。打开 txt、Word(docx)、E ## 沉浸与退出 -进入阅读模式后,编辑器、侧边栏、右侧面板都被盖住,相关的编辑功能也就用不到了,状态栏折叠成「阅读模式 · 文件名」。底层编辑器并没有卸载,点关闭(或退出阅读)就回到原来的编辑状态,光标和内容都还在。 +进入阅读模式后,编辑器、侧边栏、右侧面板都被盖住,状态栏折叠成「阅读模式 · 文件名」。底层编辑器没有卸载,关闭阅读后回到原编辑状态。书架已启用且当前文件尚未上架时,关闭前会提示是否加入,可选「暂不」。 -> 提示:阅读模式会把文件一次性读进内存,超大文档(约 100MB 以上)会被拒绝,以免影响性能。 +## 书架与续读 + +在「设置 → 通用」启用书架后,标题栏出现「书架」菜单,可导入书籍文件或文件夹。文件夹支持「书 → 卷 → 章」结构,书卡显示进度,点击可续读。移除书卡只移除书架记录,不删除原文件。 + +文本按正文块记录位置,PDF 按页记录;启用书架持久化后,书籍记录、进度与文本书签保存在本机,关闭书架开关不清除已有数据。阅读配色和排版偏好是本次应用会话状态。 + +单文件读取上限为 100MiB。原生读取使用分块传输,随后仍需在内存解析;PDF 按视口逐页绘制。文件大小上限不代表全部格式和设备已通过相同的性能验收。 ← 返回 [功能文档总览](./index.md) diff --git a/docs/shortcuts.md b/docs/shortcuts.md index 7c34f8b..c4773b8 100644 --- a/docs/shortcuts.md +++ b/docs/shortcuts.md @@ -1,6 +1,6 @@ # 快捷键与命令面板 -InkStream 的命令都能通过命令面板搜索执行,常用的也有键盘快捷键,不必去翻菜单。 +InkStream 的已注册命令可通过命令面板搜索执行,常用操作也有键盘快捷键。简易模式、书架设置和 pandoc 可用性会影响显示的命令。 ## 命令面板 @@ -31,13 +31,14 @@ InkStream 的命令都能通过命令面板搜索执行,常用的也有键盘 ## 全局快捷键 -以下快捷键在应用任意位置均可使用。 +以下为应用级快捷键;弹窗、组合输入、项目切换和功能开关会限制可用范围。表中按 Windows / Linux 的 Ctrl 标法列出;全局命令解析尚未统一提供 macOS Cmd 等价映射,不能将所有 Ctrl 直接替换为 Cmd。 | 快捷键 | 功能 | |--------|------| | `Ctrl+Shift+P` | 命令面板 | | `Ctrl+P` | 快速打开文件 | | `Ctrl+,` | 打开设置 | +| `Ctrl+Alt+P` | 项目档案 | | `Ctrl+\` | 切换侧边栏 | | `Ctrl+Alt+B` | 切换右侧面板 | | `Ctrl+N` | 新建文档(未命名草稿,保存时另存为转正) | @@ -48,17 +49,22 @@ InkStream 的命令都能通过命令面板搜索执行,常用的也有键盘 | `Ctrl+E` | 切换渲染模式(源码 / 实时预览) | | `Ctrl+G` | 打开知识图谱 | | `Ctrl+Shift+G` | 打开 Git Graph | +| `Ctrl+Shift+F` | 全库搜索替换(需完整模式与项目索引) | +| `` Ctrl+` `` | 内置终端(先在设置中启用) | +| `Ctrl+=` / `Ctrl+-` | 放大 / 缩小界面 | +| `Ctrl+0` | 重置界面缩放;Markdown 编辑器聚焦时由「设为正文」优先处理 | | `Ctrl+Shift+Z` | 插入引用(Zotero) | -| `F11` | 切换专注模式(Focus Mode) | +| `F11` | 编辑器聚焦时切换专注模式(Focus Mode) | ## 渲染模式切换(Ctrl+E) - `Ctrl+E` 在「源码」与「实时预览」之间热切换。 - 仅对 Markdown 家族文档生效;其他类型的文档按下后无变化。 +- 大文档处于基础编辑时不会通过此快捷键启用实时排版,需先点击「启用完整排版(可能较慢)」。 ## 专注模式(F11) -- 按 `F11` 开关专注模式。 +- 编辑器聚焦时按 `F11` 开关专注模式,也可从「视图」菜单或命令面板执行。 - 开启后只有光标所在段落是清晰的,其余段落会淡化。移动光标时清晰的那段会跟着换。 - 再次按 `F11` 关闭,恢复全文正常显示。 @@ -114,9 +120,10 @@ InkStream 的命令都能通过命令面板搜索执行,常用的也有键盘 ## 注意事项 -- 中文输入法(IME)正在组合输入时,回车和快捷键不会误触发命令。 +- 命令分发对 IME 组合状态及 `keyCode 229` 做短路处理;真实候选窗和物理输入法表现仍需[真机回归](../specs/03-live-preview-ime.spec.md)。 - 段落与格式类命令只对 Markdown 家族文档起作用,对其他语言的文档不会有变化。 - `Ctrl+\` 用于切换侧边栏(让位于 `Ctrl+B` 加粗);`Ctrl+O` 打开文件、`Ctrl+Shift+O` 打开文件夹,二者勿混。 - 没有列出快捷键的命令(如插入脚注、插入参考文献、切换文档语言、关于、使用教程等)均可在命令面板中搜索执行。 +- 「视图」菜单中的打字机模式和专注模式会显示当前勾选状态;通过快捷键或命令面板改变后,菜单同步更新。 ← 返回 [功能文档总览](./index.md) diff --git a/docs/simple-mode.md b/docs/simple-mode.md index 088fc51..357ac22 100644 --- a/docs/simple-mode.md +++ b/docs/simple-mode.md @@ -16,7 +16,7 @@ - 侧边栏:隐藏全文搜索、Git 面板、Zotero 文献库、章节-场景树,只保留文件树。 - 右侧面板:只保留大纲,反链与局部图谱隐藏。 -- 状态栏:只留文件路径、光标位置、渲染模式,隐藏 Git 分支、字数目标、引用、模式切换。 +- 状态栏:保留文件路径、光标位置、渲染模式和会话暂存反馈,隐藏 Git 分支、文档字数/目标、引用、模式切换;已处于 Creative 时的写作 HUD 入口仍可用。 - 命令面板 / 菜单 / 快捷键:知识图谱(Ctrl+G)、Git Graph、模式切换、插入引用、切换文档语言等高级命令一并隐藏,即使按对应快捷键也不会触发。 **关闭索引**:简易模式下打开或切换项目不启动索引,反链、未链接提及和图谱工具隐藏。 @@ -25,7 +25,7 @@ ## 随时可逆 -关闭简易模式后,高级功能会恢复;下次打开工作区时索引库会自动重建。简易模式只是一个显示和行为上的开关,不会改动你的文档。 +关闭简易模式后,高级功能会恢复,当前项目按索引会话流程重新打开/刷新索引;切换项目时仍按各项目隔离。简易模式不会改动你的正文。书架由自己的设置开关控制,与简易模式独立。 旧工作区已有的 `.inkstream/` 文件夹会保留;应用使用新的本机项目索引,不自动删除旧目录或其中的未知文件。 diff --git a/docs/specs/AUTOMATION.md b/docs/specs/AUTOMATION.md index 8e40d57..149b3e5 100644 --- a/docs/specs/AUTOMATION.md +++ b/docs/specs/AUTOMATION.md @@ -8,7 +8,9 @@ pnpm test:acceptance 命令只选择映射中的具体测试名,串行运行,测试进程硬上限 300 秒;盘点/终止辅助命令各有 10 秒上限。检查测试文件与场景名称是否仍存在,并解析当次新生成的 Vitest JSON:每个选择项必须恰好出现一次且状态为 `passed`;报告缺失、测试未发现、skip/todo、失败、超时或清理未确认都不会被当作通过。未绑定场景不因同文件其它测试绿色而改变状态。 -当前命令选择五个文件中的 24 项检查:DocumentSession、WorkspaceSession、文件身份迁移、Wiki 实际导航,以及一项同名候选补全检查。既有完整 `pnpm test` 与 CI 的完整 Vitest 步骤保留,不按这份有限映射排除任何测试;CI 不重复运行同一批 Vitest,只新增原生 Rust 验证。 +当前命令选择 14 个文件中的 41 项检查:原有 DocumentSession、WorkspaceSession、文件身份迁移、Wiki 导航与补全共 24 项,以及新增多栏工作台 17 项。工作台映射见 [workbench-bindings.mjs](../../scripts/acceptance/workbench-bindings.mjs),覆盖 WB-01 至 WB-08 的已绑定行为;真实窗口观察见 [ComputerUse 验收](../WORKBENCH-ACCEPTANCE.md)。已校正三条过时的工作区测试名,缺失名称仍会使 runner 失败。`pnpm test` 是直接 `vitest run`;CI 使用 `pnpm test:ci` 的有界 runner,不按本有限映射排除其他测试,也不另行调用 `test:acceptance` 重跑这些选择项。 + +`test:ci` 先串行运行功能测试(排除两份性能文件,进程上限 780 秒),再单独运行 `blockField.performance.test.ts` 与 `perf.test.ts`(fork 进程、显式 GC,进程上限 60 秒)。两阶段均使用单 worker、关闭文件并行,不提高测试自身的时限;阶段结果和清理记录合并后才形成完整前端检查结论。性能文件必须被发现、有实际断言且全部通过,不能用跳过文件换取绿色结果。 这些集成测试使用真实应用模块、状态、CodeMirror 或工作区流程;边界替身按各测试声明使用。它们不能代替原生 WebView/IME、真实磁盘故障、OS watcher 或外部服务验收。运行后只报告“选择的检查通过”,`bddCompletion` 固定为 `false`;全部 BDD 完成仍须逐项补齐下表。 @@ -41,13 +43,13 @@ Save As、删除脏文档、目录移动撤销、旧路径在途写、文件操 ## Unix 权限:负控与生产断言分开 -CI 保留 `cargo check`,并在 Windows、Linux、macOS 实际执行: +Windows、Linux、macOS CI 调用 `node scripts/acceptance/run-rust.mjs`,实际执行: ```text -cargo test --locked --manifest-path src-tauri/Cargo.toml --lib -- --test-threads=1 +cargo test --locked --manifest-path src-tauri/Cargo.toml --all-targets -- --test-threads=1 ``` -[原生 runner](../../scripts/acceptance/run-rust.mjs)给该命令 20 分钟硬上限,并在 Unix 输出中要求观察到正式 `files::tests::write_file_atomic_preserves_existing_unix_permissions` 的通过记录。该正式测试保持原有断言,验证生产 `files.rs` 的写入结果;Windows 的 `cfg(unix)` 排除明确记为未执行,不算权限验证。 +[原生 runner](../../scripts/acceptance/run-rust.mjs)给该命令 20 分钟硬上限。`--all-targets` 同时编译库、测试及应用二进制目标;CI 不再单独跑 `cargo check`,也不缩为 `--lib`。Unix 输出必须出现正式 `files::tests::write_file_atomic_preserves_existing_unix_permissions` 的通过记录。该测试验证生产写入路径;Windows 的 `cfg(unix)` 排除明确记为未执行,不算权限验证。 [独立负控](../../scripts/acceptance/unix-permission-negative.rs)只用 Rust 标准库,在本次新建的临时目录重现旧 `File::create → write → sync → rename` 成功写入策略。它不运行旧应用二进制、不包含旧应用其它组件,也不替换正式测试。它记录 `0600` 与 `0751` 的目标权限和实际权限;至少一个权限谓词被违反时输出确认标记并以专用退出码 `42` 退出。 @@ -61,7 +63,24 @@ cargo test --locked --manifest-path src-tauri/Cargo.toml --lib -- --test-threads - `*-before/after.json`:OS 进程盘点,包含盘点探针自身命令/PID/时间/10 秒上限。OS 没提供的工作目录保留为 unknown,不臆测。 - `*-idle-*.json`:连续 60 秒无输出时的进程诊断。 - `*-after-cleanup.json`:发现属于本次进程组/可追溯父子链的残留后,记录清理复查;既有或归属不明进程不终止。 -- `vitest.json` 与 `acceptance-summary.json`:原始测试结果及逐项匹配,保留 partial/pending 状态。 +- 有限映射 runner 的 `vitest.json` 与 `acceptance-summary.json`:原始测试结果及逐项匹配,保留 partial/pending 状态。 +- 完整前端 runner 的 `functional.json`、`performance.json`、合并 `vitest.json` 与 `tests-summary.json`:分阶段结果、发现的断言和清理结论。 - `rust-summary.json` 与 `negative-control-summary.json`:生产 Rust 结果和隔离旧策略负控各自的证据边界。 -正常退出、失败、超时及中断均检查可观察的所属进程树;Windows 用明确 PID 的 `taskkill /T`,Unix 用该次新建的进程组。主动脱离父子链/进程组的未知进程不被推定为本次所有,相关限制写入记录。此设施尚需主 Agent 实际运行审查;文件存在不构成运行通过声明。 +正常退出、失败、超时及中断均检查可观察的所属进程树;Windows 用明确 PID 的 `taskkill /T`,Unix 用该次新建的进程组。主动脱离父子链/进程组的未知进程不被推定为本次所有,相关限制写入记录。文件存在本身不构成运行通过声明,必须读取对应执行的报告。 + +## 2.0.0 发布记录与剩余验收 + +截至 2026-09-13 已复核的发布基线为 `main` / `v2.0.0` / `ca4c214`,[PR #40](https://github.com/KRPCT/InkStream/pull/40) 已合并,[2.0.0 Release](https://github.com/KRPCT/InkStream/releases/tag/v2.0.0) 已公开: + +| 执行 | 结果 | 证据范围 | +|---|---|---| +| [合并前 CI 34709938076](https://github.com/KRPCT/InkStream/actions/runs/34709938076) | success | 对应提交的三平台 CI 步骤 | +| [main CI 34710877435](https://github.com/KRPCT/InkStream/actions/runs/34710877435) | success | 合并后 main 的三平台 CI 步骤 | +| [Release 34710891782](https://github.com/KRPCT/InkStream/actions/runs/34710891782) | success | 安装包、更新签名条目与清单聚合发布 | + +[CI 工作流](../../.github/workflows/ci.yml)执行锁文件安装、类型检查、lint、`test:ci`、前端 build、独立 Unix 负控与 Rust 全目标测试。[Release 工作流](../../.github/workflows/release.yml)执行打包与发布,不单独承担完整测试或真实用户验收。标签发布先保留草稿,三平台更新签名与 `latest.json` 就绪后公开;手动触发仅上传 run artifacts,不创建公开 Release。 + +24 张已实现票已关闭;仍开放的 validation 票为 [#14](https://github.com/KRPCT/InkStream/issues/14)、[#25](https://github.com/KRPCT/InkStream/issues/25)、[#26](https://github.com/KRPCT/InkStream/issues/26)、[#29](https://github.com/KRPCT/InkStream/issues/29)、[#36](https://github.com/KRPCT/InkStream/issues/36)、[#37](https://github.com/KRPCT/InkStream/issues/37)、[#38](https://github.com/KRPCT/InkStream/issues/38)、[#39](https://github.com/KRPCT/InkStream/issues/39)、[#41](https://github.com/KRPCT/InkStream/issues/41)、[#42](https://github.com/KRPCT/InkStream/issues/42)、[#43](https://github.com/KRPCT/InkStream/issues/43)。实现票关闭不改变本表的 BDD partial/pending 状态。 + +外部真实账号、物理 IME、跨平台完整视觉/性能和安装升级体验需要各自的实际证据。CI success 与公开发布都不能作为这些事项已完成的依据;本规范不将任何未执行的 Gherkin 或真机清单勾为通过。 diff --git a/docs/specs/workbench-ux.feature b/docs/specs/workbench-ux.feature new file mode 100644 index 0000000..766570c --- /dev/null +++ b/docs/specs/workbench-ux.feature @@ -0,0 +1,57 @@ +Feature: 多栏工作台 + 用户在同一项目内组织文稿、查阅资料和查看版本,同时保留当前写作内容。 + + Scenario: WB-01 在概览与文稿之间往返保留写作状态 + Given 当前文稿包含未保存修改和一个选区 + When 用户查看项目概览后返回文稿 + Then 正文、文档身份、选区和撤销历史仍属于原文稿 + And 概览展示真实项目和文档信息 + + Scenario: WB-02 项目轨的快捷切换遵循保存结果 + Given 用户有多个项目且当前文稿未保存 + When 用户从项目轨选择另一个项目 + Then 切换通过现有项目会话入口执行 + And 保存失败时保留原项目并显示错误 + + Scenario: WB-03 文献选择与插入分离 + Given 当前文稿可编辑且文献库有可选条目 + When 用户选择一条文献 + Then 显示该条目的标题作者年份和可用详情 + And 正文不发生变化 + When 用户明确插入所选引用 + Then 引用写入原文稿的当前选区 + + Scenario: WB-04 文献库变化拒绝过期选择 + Given 用户已选择旧库中的条目且一次查询尚未完成 + When 文献库身份发生变化 + Then 清除旧选择并显示当前库状态 + And 旧响应不能覆盖新库或触发正文插入 + + Scenario: WB-05 工具与文档标签可用键盘切换 + Given 用户通过键盘聚焦当前标签 + When 用户按方向键或 Home End + Then 焦点和活动标签按可用项目切换 + And 关闭文档仍遵循原保存和冲突规则 + + Scenario: WB-06 简易模式使高级目的地回到文稿 + Given 用户正在查看文献或版本 + When 用户启用简易模式 + Then 返回仍然存在的文稿 + And 高级入口不再触发隐藏操作 + When 用户关闭简易模式 + Then 当前模式的可用工具重新显示且至少一个工具处于选中状态 + + Scenario: WB-07 面板和缩放保留用户布局 + Given 用户已调整导航和工具栏宽度 + When 用户折叠一侧或调整窗口缩放 + Then 另一侧状态不被翻转 + And 临时窄视口不覆盖保存的栏宽 + And 用户可回到文稿并继续输入 + + Scenario: WB-08 版本视图保留项目导航 + Given 当前项目存在文档与版本记录或明确的无仓库状态 + When 用户查看版本 + Then 当前项目导航仍可见 + And 版本内容使用真实仓库数据或明确的空状态 + When 用户返回文稿 + Then 当前编辑内容仍被保留 diff --git a/docs/update.md b/docs/update.md index 9e949a3..3491e81 100644 --- a/docs/update.md +++ b/docs/update.md @@ -2,6 +2,8 @@ InkStream 内置应用内自动更新。启动时会在后台检查新版本,有更新时弹一个不打扰的提示,点一下下载、重启就升级好了,不用再自己去下载页。 +[2.0.0 已公开发布](https://github.com/KRPCT/InkStream/releases/tag/v2.0.0)。发布成功表示对应发布流水线完成,实际安装、升级和平台交互仍按各自验收记录确认。 + ## 怎么用 - **自动检查**:每次启动后台静默检查最新版本。有更新时弹出对话框「InkStream X 现已可用」,可选「现在更新」或「稍后」;无更新或离线时不打扰。 @@ -16,8 +18,14 @@ InkStream 内置应用内自动更新。启动时会在后台检查新版本, ## 注意 -- 自动更新仅在正式安装版中生效,开发版不检查(不会报错)。 +- 自动更新面向正式安装版;启动仍会调用检查入口,开发/未打包环境或网络失败时静默处理。手动检查失败会给出提示,不能写成开发版完全不调用更新器。 - 从 **v1.1.2 起**的安装版才内置更新器;更早版本需手动下载一次新版,此后即可自动更新。 - macOS / Windows 安装包未做系统代码签名,首次安装可能有「未知开发者」提示,属正常。 +## 发布与更新清单 + +标签 `v*` 触发的发布先建立草稿,构建 Windows x64、Linux x64、macOS Apple Silicon 安装包及更新载荷,校验各平台更新签名条目并生成 `latest.json` 后才公开。手动触发 Release 工作流只提供构建产物下载,不创建公开版本。更新载荷签名与 Windows Authenticode/macOS 公证是不同步骤,不能互相替代。 + +CI 的类型检查、前端测试、Rust 全目标测试与 Release 打包各有执行范围;BDD 人工映射、物理 IME、真实账户和跨平台视觉/性能的剩余工作见[自动化绑定与验收边界](./specs/AUTOMATION.md)。 + ← 返回 [功能文档总览](./index.md) diff --git a/docs/writing.md b/docs/writing.md index 1eb84c5..3fdce97 100644 --- a/docs/writing.md +++ b/docs/writing.md @@ -6,14 +6,14 @@ 开启后,光标所在的行会滚动到视口垂直居中,视线固定在屏幕中央,不必随着越写越往下而低头。文首与文末也能居中(编辑器上下留出半屏空白)。 -- 开启:命令面板(`Ctrl+Shift+P`)→「视图:打字机模式」,再执行一次关闭。 -- 中文输入安全:合成中文时不滚动,不会打断输入法(与编辑器其余部分共用同一套 IME 保护)。 +- 开启:「视图 → 打字机模式(光标行居中)」,或命令面板(`Ctrl+Shift+P`)→「视图:打字机模式」,再执行一次关闭。菜单勾选与当前状态同步。 +- 中文组合输入期间暂停居中滚动,组合结束后再更新;真实输入法效果仍按 IME 回归清单验证。 ## 专注模式 开启后,光标所在段落以外的行会被淡化,只有正在写的这一段保持清晰,并随光标移动。 -- 开启:`F11`,或命令面板 →「视图:专注模式」。 +- 开启:编辑器内 `F11`、「视图 → 专注模式(淡化其他段落)」,或命令面板 →「视图:专注模式」。菜单勾选会随这些入口同步。 - 可以和打字机模式叠加使用,居中加淡化。 ## 写作 HUD @@ -25,6 +25,8 @@ - Creative(长篇创作)模式下,状态栏右侧有一个「写作 HUD」入口,点一下即开。 - 命令面板 →「写作:写作 HUD(码字速度 / 时间 / 番茄钟)」。 +状态栏入口会反映 HUD 是否开启;HUD 内的番茄钟按钮按运行状态显示「开始」或「暂停」。 + 面板内容: - **码字速度**:最近 60 秒内敲下的字数(即「字/分」),停笔后自动衰减。粘贴、插入参考文献等程序化写入不计入,中文输入合成期也不计入,统计的是实际手敲的量。 diff --git a/scripts/acceptance/bindings.mjs b/scripts/acceptance/bindings.mjs index 00a644a..30d50fd 100644 --- a/scripts/acceptance/bindings.mjs +++ b/scripts/acceptance/bindings.mjs @@ -1,5 +1,7 @@ // Human-reviewed links to named Vitest checks. This file does not parse or execute Gherkin. +import { workbenchGroups, workbenchScenarios } from './workbench-bindings.mjs'; export const groups = [ + ...workbenchGroups, { file: 'src/test/document-session.integration.test.tsx', tests: [ ['doc-close', 'FE-01: closing active A must activate B content before B can be saved'], ['doc-failed-save', 'FE-02: a failed close-save must preserve the dirty background A buffer and tab'], @@ -9,9 +11,9 @@ export const groups = [ ['doc-save-as', 'Save As retains edits made while the chosen file is being written'], ] }, { file: 'src/editor/workspaceSession.integration.test.ts', tests: [ - ['workspace-missing', 'an inaccessible target leaves the original workspace and its watcher operational'], - ['workspace-order', 'prepares the complete target before publishing, and later requests finish consistently'], - ['workspace-watch', 'does not publish a target whose watcher cannot start'], + ['workspace-missing', '目标目录无法打开时保留原文档与监听'], + ['workspace-order', '完整准备目标后才发布,后续切换请求按同一会话队列完成'], + ['workspace-watch', '目标监听启动失败会恢复旧监听和旧编辑会话,失败不伪装成功'], ] }, { file: 'src/editor/documentFileMutations.test.ts', tests: [ ['file-rename', '重命名后活动身份、显示名、缓存和未保存正文一致,后续只写新路径'], @@ -40,6 +42,7 @@ const document = 'docs/specs/document-session.feature'; const workspace = 'docs/specs/workspace-session.feature'; // A passed related check never changes partial/pending into complete. Gaps require additional evidence. export const scenarios = [ + ...workbenchScenarios, { id: 'DOC-01', file: document, name: '关闭活动 A 后继续编辑的是 B', status: 'partial', checks: ['doc-close'], gap: '补充输入后的 B 保存、A 磁盘不变及真实文件往返仍需对应证据。' }, { id: 'DOC-02', file: document, name: '未成功保存时关闭请求保留正文', status: 'partial', checks: ['doc-failed-save'], gap: '仅磁盘失败回归;外部冲突 Examples 行、明确反馈断言仍待绑定。' }, { id: 'DOC-03', file: document, name: '保留我的内容写入失败后仍可继续裁决冲突', status: 'partial', checks: ['doc-conflict'], gap: '绑定冲突提示/冻结/正文;再次裁决和自动保存不得越权的完整流程待绑定。' }, diff --git a/scripts/acceptance/workbench-bindings.mjs b/scripts/acceptance/workbench-bindings.mjs new file mode 100644 index 0000000..ed17b57 --- /dev/null +++ b/scripts/acceptance/workbench-bindings.mjs @@ -0,0 +1,50 @@ +// Named user-behavior checks for the workbench. Gherkin remains a reviewed specification. +export const workbenchGroups = [ + { file: 'src/components/workbench/RightPanel.test.tsx', tests: [ + ['wb-simple-return', 'WB-06 从简易模式返回创作后,选中可用工具并显示内容'], + ] }, + { file: 'src/components/workbench/Workspace.integration.test.tsx', tests: [ + ['wb-overview', 'WB-01 概览往返不卸载真实编辑器,保留修改、选区、撤销;概览数据来自会话'], + ['wb-file-navigation', 'WB-01 从概览使用文件导航会显示所开文稿,复用同一编辑器'], + ['wb-insert', 'WB-03 文献工作区先查看,再明确插入到原文稿选区;撤销可恢复正文'], + ] }, + { file: 'src/components/projects/ProjectRail.test.tsx', tests: [ + ['wb-project-switch', 'WB-02 项目轨使用完整切换入口,失败保持当前项目并展示档案中的错误'], + ['wb-pane-feedback', 'WB-07 两栏开关独立,选中反馈跟随实际折叠状态'], + ] }, + { file: 'src/projects/session.test.ts', tests: [ + ['wb-save-failure', '文件保存失败保留当前完整正文、dirty与所有者,未触碰目标/索引/监听'], + ] }, + { file: 'src/academic/useReferenceLibrary.test.tsx', tests: [ + ['wb-library-detail', 'WB-04 切换库立即清空旧选择,迟到详情不能进入新库或成为插入目标'], + ['wb-library-list', 'WB-04 迟到列表不能覆盖当前库,卸载释放订阅'], + ] }, + { file: 'src/components/workbench/PanelTabs.test.tsx', tests: [ + ['wb-tool-keys', 'WB-05:Tab 只进入活动工具,方向键切换后 Tab 离开标签栏'], + ['wb-tool-content', 'WB-05:键盘切换同时显示对应工具内容,隐藏原内容并保留已挂载面板'], + ] }, + { file: 'src/components/workbench/EditorTabs.test.tsx', tests: [ + ['wb-document-keys', 'WB-05:Tab 只进入活动文档及其可见关闭按钮,然后离开文档栏'], + ['wb-close-guard', 'WB-05:键盘关闭脏草稿仍可取消丢弃,且不调用落盘'], + ] }, + { file: 'src/components/workbench/WorkspaceNavigation.test.tsx', tests: [ + ['wb-simple-references', 'WB-06 简易模式使文献目的地退回原文稿并隐藏高级入口'], + ['wb-simple-versions', 'WB-06 简易模式使版本目的地退回原文稿并隐藏高级入口'], + ] }, + { file: 'src/components/workbench/ProjectVersions.test.tsx', tests: [ + ['wb-versions-empty', 'WB-08 版本空态保留两侧导航及编辑器,返回文稿仍是原视图'], + ['wb-versions-owner', 'WB-08 版本列表只展示当前仓库的数据,切换后不显示旧项目的提交'], + ] }, +]; +const file = 'docs/specs/workbench-ux.feature'; +export const workbenchScenarios = [ + ['WB-01', '在概览与文稿之间往返保留写作状态', ['wb-overview', 'wb-file-navigation']], + ['WB-02', '项目轨的快捷切换遵循保存结果', ['wb-project-switch', 'wb-save-failure']], + ['WB-03', '文献选择与插入分离', ['wb-insert']], + ['WB-04', '文献库变化拒绝过期选择', ['wb-library-detail', 'wb-library-list']], + ['WB-05', '工具与文档标签可用键盘切换', ['wb-tool-keys', 'wb-tool-content', 'wb-document-keys', 'wb-close-guard']], + ['WB-06', '简易模式使高级目的地回到文稿', ['wb-simple-references', 'wb-simple-versions', 'wb-simple-return']], + ['WB-07', '面板和缩放保留用户布局', ['wb-pane-feedback']], + ['WB-08', '版本视图保留项目导航', ['wb-versions-empty', 'wb-versions-owner']], +].map(([id, name, checks]) => ({ id, name: `${id} ${name}`, file, checks, status: 'partial', + gap: '自动检查范围见对应测试。真实窗口、缩放及本轮 ComputerUse 观察另见 docs/WORKBENCH-ACCEPTANCE.md;不代表真实 Zotero 账户或物理 IME 验收。' })); diff --git a/specs/01-workbench.spec.md b/specs/01-workbench.spec.md index a6624e1..7318b6d 100644 --- a/specs/01-workbench.spec.md +++ b/specs/01-workbench.spec.md @@ -1,28 +1,33 @@ -# 01 应用骨架与三模式 Workbench 验收规范 +# 01 三模式 Workbench 验收规范(2.0 基线与多栏分支) > 用户视角 ATDD 验收清单。每项标注验证方式: -> **自动** = 对应单元/组件测试文件(`pnpm test` 全绿即覆盖);**人工** = 真实窗口操作步骤。 -> 本规范是阶段验收的唯一对照表,后续阶段的回归核验也以此为基线。 +> **自动** = 指定测试文件中对应行为的断言,需核对实际发现、执行与结果;**人工** = 真实窗口操作步骤。 +> `pnpm test` / `test:ci` 通过不等于每条验收或全部 BDD 完成;jsdom 不能证明真实 WebView、物理 IME、跨平台视觉与性能通过。 +> 本清单在 `v2.0.0` / `ca4c214` 基线上更新到多栏分支行为,勾选须附对应提交证据。它与 [工作台行为规格](../docs/specs/workbench-ux.feature)、[BDD 绑定状态](../docs/specs/AUTOMATION.md)和 [ComputerUse 记录](../docs/WORKBENCH-ACCEPTANCE.md)共同使用;发布范围以 CURRENT-STATE 为准。 -## 1. 启动与五插槽布局 +## 1. 启动、项目导航与布局 -- [ ] 启动桌面应用后,一屏内可见全部五个插槽:TitleBar(顶部自绘标题栏)/ Sidebar(左侧栏)/ EditorArea(中央编辑区)/ RightPanel(右侧面板)/ StatusBar(底部状态栏)。 - - 验证:自动 `src/components/workbench/WorkbenchLayout.test.tsx`;人工 `pnpm tauri dev` 启动目视核对。 +- [ ] 桌面工作台包含顶部标题栏与菜单、左侧项目导航、文件侧栏、中央编辑区、右侧工具和底部状态栏。项目档案作为浮层打开,不推挤正文;面板按当前模式的折叠状态显示,不要求所有区域始终可见。 + - 验证:自动 `src/components/workbench/WorkbenchLayout.test.tsx`、`src/components/workbench/WorkbenchProjects.test.tsx`;人工用桌面窗口核对。 +- [ ] `Ctrl+Alt+P`、项目导航按钮及「文件 → 项目档案…」打开同一档案入口;归档层打开或项目切换中,背景编辑区不会继续接受输入。 + - 验证:自动 `src/components/projects/ProjectArchive.test.tsx`、`src/components/workbench/WorkbenchProjects.test.tsx`;人工逐入口核对。 - [ ] 拖拽 Sidebar 与 RightPanel 的分隔条可调整面板宽度,宽度在合法区间内(Sidebar 200-480px,RightPanel 240-560px)。 - - 验证:自动 `src/stores/useWorkbenchStore.test.ts`(钳制断言);人工拖拽到极限位置确认不破版。 + - 验证:自动 `src/stores/useWorkbenchStore.test.ts`、`src/components/workbench/WorkbenchLayoutPersistence.test.tsx`、`src/components/workbench/layoutPatch.test.ts`;人工宽窗口拖拽核对。窗口不超过 1100px 时两侧改用抽屉,抽屉几何不得覆盖已记忆栏宽。 - [ ] Sidebar / RightPanel 可折叠与展开,折叠状态不影响其余插槽布局。 - - 验证:自动 `src/stores/useWorkbenchStore.test.ts`;人工 Ctrl+B / Ctrl+Alt+B 往返切换。 -- [ ] EditorArea 在无文档时显示欢迎页(应用名 + 快捷键提示表),无任何乱码或占位英文。 - - 验证:人工目视核对(文案为简体中文)。 + - 验证:自动 `src/stores/useWorkbenchStore.test.ts`;人工 `Ctrl+\` / `Ctrl+Alt+B` 往返切换;`Ctrl+B` 保留为 Markdown 加粗。 +- [ ] 无项目且无标签时显示新建文档/打开文件夹入口;已有项目但无活动文件时显示未打开文件空态;独立草稿打开后可继续编辑。 + - 验证:自动 `src/components/workbench/EditorArea.test.tsx`;人工目视核对可操作入口和简体中文文案。 +- [ ] 项目导航使用 `inkstream-icon.svg`,工具及菜单勾选使用 SVG 图标;图标入口有可识别名称,亮暗主题下清晰。 + - 验证:静态核对 `ProjectRail.tsx`、`Menu.tsx`、`ModeIndicator.tsx`;人工在桌面窗口核对显示与交互,不以资源存在证明视觉验收。 ## 2. 三模式运行时切换 -- [ ] 打开命令面板,执行「模式:切换到 Academic(学术)」,布局预设(面板可见性、RightPanel tab 集)与强调色立即变为学院深蓝;「模式:切换到 Creative(长篇创作)」变为朱砂红;「模式:切换到 Standard(通用)」回到石墨灰。 +- [ ] 打开命令面板,执行「模式:切换到 Academic(学术)」,布局预设(面板可见性、RightPanel tab 集)立即更新;三个模式均沿用纸白、石墨灰与低饱和灰绿配色,身份由模式名称与当前勾选标记表达。 - 验证:自动 `src/modes/presets.test.ts`、`src/commands/builtins.test.ts`;人工依次执行三命令目视核对。 - [ ] 模式切换不重建窗口、不丢失任何已打开内容:切换前在 EditorArea 区域的状态(含面板宽度调整)切换后仍保留各自模式记忆。 - - 验证:自动 `src/components/workbench/WorkbenchLayout.test.tsx`(EditorArea 不卸载断言);人工调宽后往返切换核对。 + - 验证:自动 `src/components/workbench/WorkbenchLayoutPersistence.test.tsx`;人工编辑、调宽后往返切换,核对正文、选区与模式布局。 - [ ] StatusBar 模式指示器实时显示当前模式名,与实际布局一致。 - - 验证:自动 `src/components/workbench/ModeIndicator.test.tsx`;人工切换时目视核对。 + - 验证:自动 `src/components/workbench/ModeIndicator.test.tsx`;人工核对状态栏右侧入口、当前模式勾选,以及「视图 → 模式」和命令面板入口。 - [ ] RightPanel 的 tab 集随模式变化:Standard(大纲/反链/局部图谱)、Academic(引用/Typst 预览/大纲)、Creative(Codex/场景概要),各 tab 空态文案为简体中文。 - 验证:自动 `src/components/workbench/RightPanel.test.tsx`;人工逐模式目视核对。 @@ -30,13 +35,13 @@ - [ ] 主题三态可用:命令面板执行「主题:亮色」「主题:暗色」「主题:跟随系统」三条命令,界面即时响应;跟随系统时随操作系统主题实时变化。 - 验证:自动 `src/stores/useSettingsStore.test.ts`;人工切换系统主题观察跟随。 -- [ ] 3 模式 x 2 亮暗 = 6 组合的强调色与主题变量值全部正确(CSS 变量层,Obsidian 命名习惯,Atom one-dark/one-light 取值)。 +- [ ] 3 模式 x 2 亮暗 = 6 组合的强调色与主题变量值全部正确(CSS 语义变量;当前灰绿强调色见 theme.css,语法高亮保留独立语义色)。 - 验证:自动 `src/styles/theme.test.ts`(6 组合变量断言)。 -- [ ] 右侧标签栏 active 态对比度达标:标签文本 4.5:1 门、accent 指示条 3:1 门(非文本组件),8 项检查全部通过: +- [ ] 内置主题右侧标签栏 active 态对比度达标:标签文本 4.5:1 门、accent 指示条 3:1 门(非文本组件)。以下 8 项计算检查不能代替导入主题、透明材质与真实平台的完整视觉核验: | 检查项 | 门槛 | 验证 | |--------|------|------| - | active tab 标签文本(亮,全模式同值) | 4.5:1 | 自动 `src/styles/contrast.test.ts` | + | active tab 标签文本(亮,全模式同值) | 4.5:1 | 自动 `src/styles/theme.test.ts`(比例计算另见 `contrast.test.ts`) | | active tab 标签文本(暗,全模式同值) | 4.5:1 | 同上 | | Standard 亮 accent 指示条 | 3:1 | 同上 | | Academic 亮 accent 指示条 | 3:1 | 同上 | @@ -60,12 +65,14 @@ - 验证:自动 `src/commands/mru.test.ts`;人工执行后重开面板核对。 - [ ] 命令注册表为统一入口:注册/注销/执行行为正确,重复注册有防御。 - 验证:自动 `src/commands/registry.test.ts`。 -- [ ] 已注册命令全集(12 条)可在面板中检索到:模式 x3、主题 x3、视图 x4(切换侧边栏/切换右侧面板/重置当前模式布局/命令面板)、应用:退出、帮助:关于 InkStream,显示名为「类别:动作」命名法简体中文。 - - 验证:自动 `src/commands/builtins.test.ts`;人工滚动面板全列表核对。 +- [ ] 命令面板按注册表及功能开关展示当前可用命令,包括项目、文件、编辑、视图、Git、学术与帮助入口;不再以早期的 12 条骨架命令作为全集。简易模式、pandoc 可用性和书架开关与菜单使用同一过滤规则。 + - 验证:自动 `src/commands/builtins.test.ts`、`src/components/workbench/menuConfig.test.ts`;人工切换开关后核对命令面板和菜单。 +- [ ] 「视图」菜单的打字机模式、专注模式显示实时勾选;从命令面板或编辑器 `F11` 改变专注状态后,菜单同步更新。写作 HUD 的状态栏入口反映其开启状态。 + - 验证:核对 `MenuBar.tsx` / `menuConfig.tsx` 与对应组件检查、`src/components/workbench/HudHintIndicator.test.tsx`;人工通过各入口往返核对。 ## 5. 中文 IME 防御 -- [ ] 拼音组合输入过程中按 Ctrl+B 等快捷键不触发命令分发(含旧引擎/WebView 的 keyCode 229 路径)。 +- [ ] 拼音组合输入过程中按 `Ctrl+\`、`Ctrl+B` 等快捷键不触发命令分发(含旧引擎/WebView 的 keyCode 229 路径)。 - 验证:自动 `src/commands/keymap.test.ts`(isComposing 与 keyCode 229 短路用例)。 - [ ] 命令面板输入框中,IME 组合上屏的 Enter 不执行选中命令,仅完成组合。 - 验证:自动 `src/components/palette/CommandPalette.test.tsx`(isComposing Enter 与 keyCode 229 Enter 用例);人工以中文输入法在面板内输入并上屏核对。 @@ -73,20 +80,22 @@ ## 6. 持久化与恢复 - [ ] 重启应用后原样恢复:主题三态、上次模式、三模式各自布局(面板宽度/折叠)、命令 MRU 顺序。 - - 验证:自动 `src/stores/persistSettings.test.ts`;人工「改状态 → 重启 → 核对」。 -- [ ] 手写损坏的 settings.json(非法枚举、超界宽度、异型结构)后启动:应用回落默认配置正常可用,并出现错误 toast「无法读取上次的布局配置,已恢复默认布局。」 - - 验证:自动 `src/stores/validateSettings.test.ts`(投毒输入收敛用例);人工手改配置文件后重启核对。 + - 验证:自动 `src/stores/persistSettings.test.ts`、`src/projects/session.test.ts`;人工「改状态 → 重启 → 核对」。项目会话恢复时应用该项目自己的模式与布局,不把全局上次模式当作所有项目的状态。 +- [ ] 设置中的非法枚举、超界宽度或异型结构经校验回落合法值;读取/解析失败时回落默认配置,并提示「无法读取上次的布局配置,已恢复默认布局。」 + - 验证:自动 `src/stores/validateSettings.test.ts` 与 `src/stores/persistSettings.test.ts`;人工仅在专用测试配置副本上核对两类失败,不修改用户实际配置。 - [ ] 配置写盘失败时出现警告 toast「布局配置保存失败,本次更改在重启后可能丢失。」,UI 不中断。 - 验证:自动 `src/stores/persistSettings.test.ts`(写失败路径文案逐字断言)。 - [ ] 频繁调整布局不产生高频磁盘写入(500ms 防抖合并落盘)。 - 验证:自动 `src/stores/persistSettings.test.ts`(防抖窗口内多次变更单次落盘断言)。 +- [ ] 项目档案、封面、会话恢复正文与索引使用本机应用数据目录,内容目录中的既有 `.inkstream` 保留;切换前保存/快照失败时原项目与正文保留。独立草稿、缺失文件恢复副本和「恢复前编辑」按[项目与恢复](../docs/projects.md)处理。 + - 验证:自动 `src/projects/session.test.ts`、`src/projects/session.recovery.test.ts` 和 `src-tauri/src/projects/tests.rs`;人工用测试创建的内容目录核对切换、重启、备份和故障提示。自动替身不代替真实磁盘故障验收。 ## 7. IPC 与 Channel 红线(立约条目) - [ ] 全项目仅 `src/ipc/` 目录触达 `@tauri-apps/api` 与 Tauri 插件 API,其余模块经类型化封装调用。 - - 验证:自动 ESLint `no-restricted-imports` 规则(`pnpm lint` 全绿即覆盖)。 -- [ ] **红线**:单次 invoke 负载 > 1MB(序列化后 1,048,576 字节)必须改走 Channel(`invokeStreamed`),禁止单条 JSON 消息直传。判定与机理见 `src/ipc/README.md`。 - - 验证:code review 引用条目——后续任何引入大负载 IPC 的变更,评审时对照本条与 `src/ipc/README.md`;运行时断言在出现首个真实大负载的阶段落地。 + - 验证:ESLint `no-restricted-imports` 规则只证明导入边界,不证明具体 IPC 行为或整体验收。 +- [ ] 单次 JSON invoke 不超过 1MiB;文件读取走 Channel Raw 分块,写入走 begin / append / commit 会话、逐块确认。数据块最大 256KiB,只有真实提交成功才能清除未保存状态,失败/取消不得误报保存成功。 + - 验证:对照 [IPC 协议](../src/ipc/README.md)、`src/ipc/fileStream.ts`、`src/ipc/fileWrite.ts` 与原生读写测试;真实 WebView 响应性另测。该实现已经存在,不再列作未来大负载阶段的待实现断言。 ## 8. 平台行为 @@ -94,10 +103,10 @@ - 验证:自动 `src/components/workbench/TitleBar.test.tsx`、`src/ipc/window.test.ts`(控制调用断言);人工真窗口逐项操作。 - [ ] 窗口几何持久化且离屏兜底:拔掉外接显示器后启动,窗口自动回到主屏中央而非停留在不可见区域(含负坐标位置)。 - 验证:自动 `src-tauri/src/window_guard.rs` 单元测试(`cargo test`,含负坐标用例);人工改写窗口位置到离屏坐标后启动核对。 -- [ ] 三平台构建冒烟:ubuntu / windows / macos 三平台 CI 上 install → typecheck → lint → test → build → cargo check 全绿。 - - 验证:自动 `.github/workflows/ci.yml`(GitHub Actions matrix 运行结果)。 +- [ ] 三平台 CI 完成锁文件安装 → typecheck → lint → `test:ci` → build → 独立 Unix 负控(仅 Unix)→ `run-rust.mjs` 全目标生产测试。 + - 验证:`.github/workflows/ci.yml` 与对应运行报告。原生实际命令为 `cargo test --locked --manifest-path src-tauri/Cargo.toml --all-targets -- --test-threads=1`,不另跑 `cargo check`;发布记录见 [AUTOMATION.md](../docs/specs/AUTOMATION.md)。三平台 CI 与 Release success 不自动勾选人工或性能项。 ## 9. 已知偏差 - [ ] **macOS Cmd(Meta)修饰键映射推迟**:本阶段快捷键解析仅覆盖 Ctrl / Alt / Shift 修饰键,macOS 上以 Cmd 为主修饰键的等价映射(如 Cmd+Shift+P)暂未实现,待 macOS 实机交互测试阶段补齐后回收本条。代码标记:`src/commands/keymap.ts` 内 `DEVIATION(D-05)` 注释。 - - 验证:存在性核对——`grep "DEVIATION(D-05)" src/commands/keymap.ts` 命中即偏差仍在登记;补齐实现并删除标记后,本条改为常规快捷键验收项。 + - 验证:`rg -n 'DEVIATION\(D-05\)|metaKey|MODIFIER_ORDER' src/commands/keymap.ts` 核对实现;保留偏差直到全局 Cmd 映射与 macOS 真机检查均有证据。编辑器或链接局部支持 Cmd 不代表全局命令已经映射。 diff --git a/specs/03-live-preview-ime.spec.md b/specs/03-live-preview-ime.spec.md index f3be29e..51b24c9 100644 --- a/specs/03-live-preview-ime.spec.md +++ b/specs/03-live-preview-ime.spec.md @@ -1,22 +1,24 @@ -# Phase 3 中文 IME 手测清单(永久回归门 D-13) +# 中文 IME 真机回归清单(2.0 基线,永久回归门 D-13) > **本清单是 EDIT-06 永久回归门。** 它是全项目最高风险件(`view.composing` 冻结纪律)的护栏: > 一旦冻结回退即吞字 / 候选窗跳位 / 上屏错乱。 > -> **本阶段及 Phase 4 / 5 / 8 / 9 的所有装饰类变更,合并前必须逐项勾验通过。** 任何触及 +> **所有触及装饰层的变更,合并前必须逐项勾验通过。** 任何触及 > CodeMirror 装饰层(块级 StateField / 行内 ViewPlugin / atomicRanges)的改动都要重跑本清单。 > > 与 `specs/01-workbench.spec.md` 同构:入库公开可审计、人工逐项勾验。在力所能及范围内已补 > Vitest 模拟 `CompositionEvent` 的自动回归桩以减人工负担,但**人工清单始终是硬门**—— > 自动桩无法复现真实候选窗行为,不可替代真机逐项勾验。 +> +> `v2.0.0` / `ca4c214` 已公开发布,相关 CI 与 Release 成功不代表本矩阵已完成。没有对应提交、平台、输入法版本和实测结果的格子保持未勾选;[开放验证事项](../docs/specs/AUTOMATION.md)继续保留。 ## 0. 范围与平台门 -- **Windows 为本阶段硬门**:下方 4 输入法 × 4 场景类矩阵在 Windows 真机逐项勾验通过,方可合并装饰类变更。 +- **Windows 物理输入法仍是回归硬门**:下方 4 输入法 × 4 场景类矩阵需在 Windows 真机逐项勾验。 - **表格就地编辑(方案 B 子编辑器)IME 专项**:见 §1 专项框 + §4.5——子编辑器是独立 IME 宿主,须单独逐项勾验 (上屏不跳末尾 B1 / 撤销不跳顶 B2 / 跨格续写 / 对齐列编辑 / 空行高),触及 tableCellEditor / TableWidget / blockField 的改动须重跑。 -- **macOS(注音 / 拼音)、Linux(fcitx / ibus)留 Phase 12 打包阶段补测**——本阶段不阻断,届时以同结构矩阵回归。 -- 执行时机:Live Preview 链接 / 装饰落地后(Wave 2 之后)逐项执行;jsdom 无法复现真实候选窗行为,故全部为真机手测。 +- **macOS(注音 / 拼音)、Linux(fcitx / ibus)的物理输入法仍需同结构矩阵**;不能因打包阶段或跨平台 CI 已完成而记为通过。 +- 执行时机:触及主编辑器、表格子编辑器、公式源码或组合输入相关装饰后。需实际启用 OS 输入法并观察候选窗;jsdom 合成事件、直接注入文本或普通自动点击不能代替这一证据。 ## 1. 通用判据(每格勾验四项,全部满足才算通过) @@ -37,7 +39,7 @@ > **表格单元格子编辑器专项(方案 B,TABLE-WYSIWYG / commit 0b451b3)**:表格就地编辑用嵌套子 EditorView > 承载单元格——它是与主编辑器**并存的独立 IME 宿主**(独立 contentDOM、子组合事件经 `stopBubblingToMain` -> 不上达主门、组合期**每个 compositionupdate 即时 commit 回写主 doc**)。此路径不走主编辑器组合门,第 1 节 +> 不上达主门)。当前 `commitSub` 会检查主编辑器和子编辑器的组合状态,组合期间延后回写,不能按“每次 compositionupdate 即时提交”验收。第 1 节 > 四判据之外**额外**须满足(缺一即失败): > 1. **上屏后光标停插入点**:在单元格已有文字**中部**用拼音输入、按空格确认上屏后,光标停在刚上屏文字之后, > **不弹到单元格末尾**(B1 真因:commit 重建子编辑器 + focusSub 落 doc.length;已修为复用子实例 + 保选区)。 @@ -53,7 +55,7 @@ | 代号 | 输入法 | 选取理由 | |------|--------|----------| | IME-A | 微软拼音 | 系统内置基准,最常见路径 | -| IME-B | 搜狗拼音 | 市占第一,第三方候选窗行为差异大 | +| IME-B | 搜狗拼音 | 常见第三方输入法,候选窗行为需独立覆盖 | | IME-C | 双拼模式 | 码长 / 上屏时序与全拼不同 | | IME-D | 手写 / 语音面板 | 非标准一次性上屏路径,绕常规组合事件序列 | @@ -109,39 +111,36 @@ - [ ] 对齐列编辑一致:把某列设居中 / 右对齐后进入该列单元格输入中文,编辑中文字即跟随对齐,空格确认上屏后与同列非活动格渲染一致。(Wave2/3 A) - [ ] 空单元格行高一致:工具条「插入行」后在新空行单元格输入中文上屏,空行高度自始至终与内容行一致(不偏矮)。(Wave2/3 B) -### 4.6 Fenced 公式块源码编辑专项(Phase 5,```math / ```latex / ```typst;至少 IME-A 微软拼音 + IME-B 搜狗) +### 4.6 公式块源码编辑专项(math / latex / typst 围栏及 :::typst 容器;至少 IME-A 微软拼音 + IME-B 搜狗) > 光标进公式块即还原源码(块级 replace 装饰 skip,**主编辑器**直接编辑源码——非子编辑器,走主组合门,与表格子编辑器 > 路径不同)。在源码内输入中文(typst `#text[中文]` / latex `\text{中文}` / 注释等),对照第 1 节四判据 **+** 下列专项: -- [ ] 块内源码输中文不吞字:进 ```typst / ```latex / ```math 块,在源码内连续输入中文(多字词 + 组合中途删改),无吞字、上屏无错乱。 +> 点击公式进入双栏编辑时使用独立源码输入区,须另验该入口的组合输入、完成/Esc 退出与正文回写;不能只验主编辑器中的围栏源码就判定双栏路径通过。 + +- [ ] 块内源码输中文不吞字:进 ```typst / ```latex / ```math 块或 :::typst 容器,在源码内连续输入中文(多字词 + 组合中途删改),无吞字、上屏无错乱。 - [ ] 组合期块不闪渲染:块内输中文组合期间,该块**保持源码态不闪回渲染**(blockField `isComposingTr` 映射旧装饰不重建);`compositionend` 后才刷新。 - [ ] 进/出块切换不被组合打断:光标在「块外渲染 ↔ 块内源码」间移动时,边界重建走 `isComposingTr` 门,组合期不撕装饰吞字。 - [ ] typst 异步编译不干扰输入:typst 块内输中文(200ms 防抖编译)期间输入流畅、无吞字(编译在 Worker,不阻塞主线程 IME)。 - [ ] `/math` `/latex` `/typst` 触发器插块后续输中文:补全 apply 插块 + 光标落空行后直接输中文,无吞字、光标不弹位(apply 零 `view.focus`)。 +- [ ] 双栏公式编辑:在独立源码输入区连续中文组合上屏,完成或 Esc 退出后正文与公式一致,无吞字、重复提交或光标错位。 ## 5. 自动回归桩(减负,非硬门) - [ ] 模拟 `compositionstart` → 输入 → `compositionend` 的 Vitest 桩存在并通过:断言组合期装饰暂停**语法树重算**、 组合期 docChanged 时旧装饰经 `tr.changes` **映射跟随位移**(非返回未映射旧集)、`compositionend` 后推迟一个 微任务统一刷新一次(覆盖 `view.composing` / `isFrozen` 双判 + CM6 原生 `input.type.compose` userEvent 路径)。 - - 验证:自动(对应 CM 装饰扩展的配对测试,`pnpm test` 全绿即覆盖)。 + - 验证:核对 `src/editor/composition.test.ts`、`src/editor/composition.regression.test.ts` 与对应装饰配对测试的实际断言和执行结果;`pnpm test:ci` 汇总绿色不能代替本项逐条证据。 - 说明:此桩仅减少人工负担,**不替代**第 4 节真机矩阵;自动桩绿不构成回归门通过。 - [ ] 表格子编辑器(方案 B)配对桩存在并通过:`tableCellEditor.test.ts` 组合期门桩(组合中子→主不 commit、 end 后落 doc)+ B1/B2 回归桩(连续 commit 复用同一子编辑器实例不重建 / 本地优先撤销 undo(sub) 先撤本格 / 进格锚主选区落表内 / 活动格跟随列对齐)。 - - 验证:自动(`pnpm test` 全绿即覆盖)。 + - 验证:核对 `src/editor/livepreview/tableCellEditor.test.ts` 的具体断言及实际运行结果;这些是组合门、选区和撤销契约的证据。 - 说明:同样**不替代** §4.5 真机专项——jsdom 不驱动子 view 真实组合与「空格确认上屏」时序。 -> **真因结论(2026-06-12,WebView2 平台限制,非装饰层)**:经真机 CDP 直连确证,中文 IME 仅在**真实指针进入 -> 编辑器**时才武装 OS IME/TSF;任何 programmatic 路径(`view.focus()` / 原生 `ICoreWebView2Controller::MoveFocus` / -> EditContext)都不武装 → 打开文件后**首次**程序化聚焦的中文组合丢字。装饰层(freeze/map、Option 2 活动行纯源码) -> 经 CDP 证实**无辜**——IME 一旦工作,装饰层不打断它(即第 5 节自动桩断言的契约成立)。故对策为**不程序化抢焦点** -> (去 auto-focus,由用户点击编辑器自然落焦);该 WebView2 限制记入 `.planning/CONSTRAINTS.md §8`,深层 click-free -> IME 健壮性并入 UX 重做里程碑。 +> **历史排障线索(2026-06-12)**:此前在特定 Windows / WebView2 环境观察到首次程序化聚焦与物理点击进入编辑器的 IME 表现不同,并据此调整聚焦路径。这是旧环境的排障记录,不足以证明所有 WebView2 版本都存在同一限制,也不能排除后续装饰变更的影响。当前回归应分别覆盖首次打开、真实点击聚焦、切换标签和恢复项目后的中文输入。 > -> **诊断脚手架已移除**:定位期间曾加的 DEV-ONLY `[IME-TRACE]` 追踪器(前端 console + Rust `ime_trace_append` 落盘)、 -> 原生 `arm_webview_ime` 武装、程序化 auto-focus 三者在结论确定后一并移除(仓库纯净硬约束)。需复诊按 git 历史还原即可。 +> **当前诊断入口**:`src/App.tsx` 仍按 `import.meta.env.DEV` 挂载 `ImeProbe`。历史 `[IME-TRACE]` 等工具的变迁以 Git 历史为准,不能笼统写成当前没有任何诊断脚手架;开发探针存在或其测试通过也不构成正式安装版 IME 验收。 > **⚠️ 真机为 EDIT-06 唯一验收门(jsdom 无法复现 composition,这正是本 bug 曾经带病上线的原因)。** > jsdom 的 `CompositionEvent` 桩**不驱动**浏览器真实 IME 组合状态机:它无法复现「合成中文本节点」、 @@ -159,14 +158,15 @@ 1. 定位回退点:多为组合期未短路装饰重建(`view.composing` / `isComposing` 漏判)或 `compositionend` 刷新破坏盒模型; 表格子编辑器路径(§4.5)多为子→主 commit 触发重建未保子实例/选区,或撤销委派/锚选区回退。 2. 修复后**重跑整张矩阵**(不可只补失败格——冻结纪律是全局不变量)。 -3. 修复与重验结论记入对应阶段 SUMMARY 的偏差 / 验证小节。 +3. 将修复提交、失败格、平台/输入法版本及重验结果记入对应验证 issue 与下方签核表。 ## 7. 验收签核记录(每次跑矩阵填一行,留审计轨迹) -> 第 4 节 16 格 + §4.5 专项每全过一轮,在此记一行。结果列填「全过」或「失败:<格号/项>」。 +> 第 4 节 16 格 + §4.5 及适用的 §4.6 专项每执行一轮,在此记一行。结果列填「全过」或「失败:<格号/项>」;未执行保持待填。 > 装饰类变更合并前须有一行覆盖该提交且结果为「全过」。 | 日期 | 验证提交(SHA) | 平台 / WebView2 | 输入法 + 版本 | 结果 | 备注 | |------|---------------|-----------------|---------------|------|------| -| (待填) | | Windows / 148 Fixed Runtime | 微软拼音 / 搜狗 | | | -| (待填,Phase 5)| 8849568 / 3286eb7 / 21d33b7 | Windows / 148 Fixed Runtime | 微软拼音 / 搜狗 | | §4.6 fenced 公式块(math/latex/typst)源码 IME 待真机逐项 | +| (待实测) | | Windows / 实际 WebView2 版本 | 实际输入法与版本 | 未执行 | 16 格及表格/公式专项 | +| (待实测) | | macOS / 实际 WebView 版本 | 注音/拼音与版本 | 未执行 | 同结构平台矩阵 | +| (待实测) | | Linux / 实际 WebKit 版本 | fcitx/ibus 与版本 | 未执行 | 同结构平台矩阵 | diff --git a/specs/README.md b/specs/README.md new file mode 100644 index 0000000..3e1402e --- /dev/null +++ b/specs/README.md @@ -0,0 +1,5 @@ +# 行为规格入口 + +当前基线为已发布的 2.0.0。本目录的工作台与 IME 规格按各自证据验收,不因 pnpm test 通过就自动覆盖人工条目。 + +DDD/BDD 本轮顺序见 [执行计划](../docs/EXECUTION-PLAN.md)。会话 Gherkin 及其人工 Vitest 映射见 [自动化说明](../docs/specs/AUTOMATION.md),不能把人工映射称为执行了 Gherkin。多栏场景的自动检查和 ComputerUse 观察见 [验收记录](../docs/WORKBENCH-ACCEPTANCE.md)。 diff --git a/src/academic/useReferenceLibrary.test.tsx b/src/academic/useReferenceLibrary.test.tsx new file mode 100644 index 0000000..6f5193b --- /dev/null +++ b/src/academic/useReferenceLibrary.test.tsx @@ -0,0 +1,49 @@ +import { act, renderHook, waitFor } from '@testing-library/react'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; +import type { CslItem, ZoteroItem } from '../types/zotero'; + +const api = vi.hoisted(() => ({ revision: 0, listeners: new Set<() => void>(), items: vi.fn(), detail: vi.fn() })); +vi.mock('../ipc/zotero', () => ({ + currentZoteroLibraryRevision: () => api.revision, + onZoteroLibraryChanged: (listener: () => void) => { api.listeners.add(listener); return () => api.listeners.delete(listener); }, + zoteroItemsResilient: api.items, zoteroCslResilient: api.detail, +})); +import { useReferenceLibrary } from './useReferenceLibrary'; +const a: ZoteroItem = { citekey: 'A', title: '甲库文献', authors: '甲', year: '2025' }; +const b: ZoteroItem = { citekey: 'B', title: '乙库文献', authors: '乙', year: '2026' }; +function deferred() { let resolve!: (value: T) => void; const promise = new Promise((done) => { resolve = done; }); return { promise, resolve }; } +beforeEach(() => { api.revision = 0; api.listeners.clear(); api.items.mockReset().mockResolvedValue({ items: [a], offline: false }); api.detail.mockReset().mockResolvedValue([]); }); + +describe('文献浏览会话', () => { + it('WB-04 切换库立即清空旧选择,迟到详情不能进入新库或成为插入目标', async () => { + const pending = deferred(); api.detail.mockReturnValue(pending.promise); + const { result } = renderHook(useReferenceLibrary); + await waitFor(() => expect(result.current.items).toEqual([a])); + act(() => { void result.current.select(a); }); + expect(result.current.selectedKey()).toBe('A'); + api.items.mockResolvedValue({ items: [b], offline: true }); + await act(async () => { api.revision++; api.listeners.forEach((listener) => listener()); }); + expect(result.current.selected).toBeNull(); expect(result.current.selectedKey()).toBeNull(); + await act(async () => pending.resolve([{ id: 'A', DOI: 'old-library' }])); + expect(result.current.detail).toBeNull(); expect(result.current.items).toEqual([b]); expect(result.current.offline).toBe(true); + }); + it('WB-04 迟到列表不能覆盖当前库,卸载释放订阅', async () => { + const pending = deferred<{ items: ZoteroItem[]; offline: boolean }>(); api.items.mockReturnValueOnce(pending.promise); + const { result, unmount } = renderHook(useReferenceLibrary); + api.items.mockResolvedValue({ items: [b], offline: false }); + await act(async () => { api.revision++; api.listeners.forEach((listener) => listener()); }); + await act(async () => pending.resolve({ items: [a], offline: false })); + expect(result.current.items).toEqual([b]); + unmount(); expect(api.listeners.size).toBe(0); + }); + it('快速改选时详情始终属于最后选中的文献', async () => { + api.items.mockResolvedValue({ items: [a, b], offline: false }); + const pending = deferred(); api.detail.mockReturnValueOnce(pending.promise).mockResolvedValueOnce([{ id: 'B', DOI: 'new' }]); + const { result } = renderHook(useReferenceLibrary); + await waitFor(() => expect(result.current.items).toHaveLength(2)); + act(() => { void result.current.select(a); }); + await act(async () => result.current.select(b)); + await act(async () => pending.resolve([{ id: 'A', DOI: 'old' }])); + expect(result.current.selectedKey()).toBe('B'); expect(result.current.detail?.DOI).toBe('new'); + }); +}); diff --git a/src/academic/useReferenceLibrary.ts b/src/academic/useReferenceLibrary.ts new file mode 100644 index 0000000..95eadbd --- /dev/null +++ b/src/academic/useReferenceLibrary.ts @@ -0,0 +1,57 @@ +import { useCallback, useEffect, useRef, useState } from 'react'; +import { currentZoteroLibraryRevision, onZoteroLibraryChanged, zoteroCslResilient, zoteroItemsResilient } from '../ipc/zotero'; +import type { CslItem, ZoteroItem } from '../types/zotero'; + +const message = (error: unknown) => error instanceof Error ? error.message : String(error); + +/** 文献浏览会话。库身份、列表与所选详情作为同一生命周期失效;选择不写入文档。 */ +export function useReferenceLibrary() { + const [items, setItems] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + const [offline, setOffline] = useState(false); + const [selected, setSelected] = useState(null); + const [detail, setDetail] = useState(null); + const [detailLoading, setDetailLoading] = useState(false); + const [detailError, setDetailError] = useState(null); + const listRequest = useRef(0); + const detailRequest = useRef(0); + const libraryRevision = useRef(currentZoteroLibraryRevision()); + const clearSelection = useCallback(() => { + detailRequest.current += 1; + setSelected(null); setDetail(null); setDetailError(null); setDetailLoading(false); + }, []); + const load = useCallback(async () => { + const request = ++listRequest.current; + const revision = currentZoteroLibraryRevision(); + libraryRevision.current = revision; + clearSelection(); setItems([]); setLoading(true); setError(null); setOffline(false); + const current = () => request === listRequest.current && revision === currentZoteroLibraryRevision(); + try { + const result = await zoteroItemsResilient(); + if (current()) { setItems(result.items); setOffline(result.offline); } + } catch (failure) { if (current()) setError(message(failure)); } + finally { if (current()) setLoading(false); } + }, [clearSelection]); + useEffect(() => { + const unsubscribe = onZoteroLibraryChanged(() => { void load(); }); + void load(); + return () => { listRequest.current += 1; detailRequest.current += 1; unsubscribe(); }; + }, [load]); + + const select = async (item: ZoteroItem) => { + if (libraryRevision.current !== currentZoteroLibraryRevision() || !items.includes(item)) return; + const request = ++detailRequest.current; + const revision = libraryRevision.current; + setSelected(item); setDetail(null); setDetailError(null); setDetailLoading(true); + const current = () => request === detailRequest.current && revision === currentZoteroLibraryRevision(); + try { + const result = await zoteroCslResilient([item.citekey]); + if (current()) setDetail(result.find((entry) => + String(entry.id) === item.citekey || entry['citation-key'] === item.citekey || entry.citekey === item.citekey) ?? null); + } catch (failure) { if (current()) setDetailError(message(failure)); } + finally { if (current()) setDetailLoading(false); } + }; + const selectedKey = () => libraryRevision.current === currentZoteroLibraryRevision() ? selected?.citekey ?? null : null; + return { items, loading, error, offline, selected, detail, detailLoading, detailError, load, select, selectedKey }; +} diff --git a/src/components/projects/ProjectRail.test.tsx b/src/components/projects/ProjectRail.test.tsx new file mode 100644 index 0000000..e745ed3 --- /dev/null +++ b/src/components/projects/ProjectRail.test.tsx @@ -0,0 +1,30 @@ +import { act, fireEvent, render, screen } from '@testing-library/react'; +import { beforeEach, expect, it, vi } from 'vitest'; +import { useProjectStore } from '../../stores/useProjectStore'; +import { useWorkbenchStore } from '../../stores/useWorkbenchStore'; +import type { ProjectRecord } from '../../types/projects'; +const open = vi.hoisted(() => vi.fn()); +vi.mock('../../projects/actions', () => ({ openProject: open })); +import ProjectRail from './ProjectRail'; +const project = (id: string): ProjectRecord => ({ id, name: `项目${id}`, root: `D:/${id}`, favorite: false, cover: null, removed: false, createdAt: 1, lastOpenedAt: 1 }); +beforeEach(() => { + useProjectStore.setState({ phase: 'idle', archiveOpen: false, activeId: 'A', catalog: { version: 1, activeId: 'A', projects: [project('A'), project('B')] } }); + useWorkbenchStore.setState(useWorkbenchStore.getInitialState(), true); + open.mockReset().mockResolvedValue(false); +}); +it('WB-02 项目轨使用完整切换入口,失败保持当前项目并展示档案中的错误', async () => { + render(); + await act(async () => fireEvent.click(screen.getByRole('button', { name: '打开项目:项目B' }))); + expect(open).toHaveBeenCalledWith('B'); + expect(useProjectStore.getState().activeId).toBe('A'); expect(useProjectStore.getState().archiveOpen).toBe(true); + expect(screen.getByRole('button', { name: '打开项目:项目A' })).toHaveAttribute('aria-current', 'true'); +}); +it('WB-07 两栏开关独立,选中反馈跟随实际折叠状态', () => { + render(); + const left = screen.getByRole('button', { name: '展开或收起文件导航' }); + const right = screen.getByRole('button', { name: '展开或收起工具面板' }); + fireEvent.click(left); + expect(left).toHaveAttribute('aria-pressed', 'false'); expect(right).toHaveAttribute('aria-pressed', 'true'); + fireEvent.click(right); fireEvent.click(left); + expect(left).toHaveAttribute('aria-pressed', 'true'); expect(right).toHaveAttribute('aria-pressed', 'false'); +}); diff --git a/src/components/projects/ProjectRail.tsx b/src/components/projects/ProjectRail.tsx index 9536361..aa6b2da 100644 --- a/src/components/projects/ProjectRail.tsx +++ b/src/components/projects/ProjectRail.tsx @@ -2,25 +2,32 @@ import { Archive, PanelLeft, PanelRight, Settings } from 'lucide-react'; import { execute } from '../../commands/registry'; import { useProjectStore } from '../../stores/useProjectStore'; import { useWorkbenchStore } from '../../stores/useWorkbenchStore'; +import { openProject } from '../../projects/actions'; +import ProjectCover from './ProjectCover'; export default function ProjectRail() { const catalog = useProjectStore((state) => state.catalog); const activeId = useProjectStore((state) => state.activeId); const archiveOpen = useProjectStore((state) => state.archiveOpen); const phase = useProjectStore((state) => state.phase); - const project = catalog.projects.find((item) => item.id === activeId && !item.removed); - const count = catalog.projects.filter((item) => !item.removed).length; + const layout = useWorkbenchStore((state) => state.layouts[state.mode]); + const projects = catalog.projects.filter((item) => !item.removed).sort((a, b) => Number(b.favorite) - Number(a.favorite) || b.lastOpenedAt - a.lastOpenedAt); return

; diff --git a/src/components/settings/settingsSections.tsx b/src/components/settings/settingsSections.tsx index 051d4d8..c0f79ca 100644 --- a/src/components/settings/settingsSections.tsx +++ b/src/components/settings/settingsSections.tsx @@ -41,11 +41,12 @@ function SettingRow({ ); } -function Toggle({ checked, onChange }: { checked: boolean; onChange: (v: boolean) => void }) { +function Toggle({ label, checked, onChange }: { label: string; checked: boolean; onChange: (v: boolean) => void }) { return ( ); + + const activeTab = screen.getByRole('tab', { name: /b\.md/ }); + expect(activeTab).toHaveAttribute('tabindex', '0'); + expect(screen.getByRole('tab', { name: /a\.md/ })).toHaveAttribute('tabindex', '-1'); + expect(screen.getByRole('button', { name: '关闭 a.md' })).toHaveAttribute('tabindex', '-1'); + await user.tab(); + expect(activeTab).toHaveFocus(); + + const closeButton = screen.getByRole('button', { name: '关闭 b.md' }); + expect(closeButton).toBeVisible(); + await user.tab(); + expect(closeButton).toHaveFocus(); + await user.tab(); + expect(screen.getByRole('button', { name: '后续内容' })).toHaveFocus(); + await user.tab({ shift: true }); + expect(closeButton).toHaveFocus(); + expect(closeButton).toBeVisible(); + await user.tab({ shift: true }); + expect(activeTab).toHaveFocus(); + }); + + it.each([ + ['{ArrowRight}', 'b.md'], + ['{ArrowLeft}', 'c.md'], + ['{End}', 'c.md'], + ['{ArrowRight}{Home}', 'a.md'], + ['{End}{ArrowRight}', 'a.md'], + ['{End}{ArrowLeft}', 'b.md'], + ])('WB-05:按 %s 后焦点和活动文档切换到 %s,首尾循环', async (keys, name) => { + const user = userEvent.setup(); + useEditorStore.getState().openTab({ path: 'c.md', name: 'c.md' }); + render(); + await user.tab(); + await user.keyboard(keys); + + const selected = screen.getByRole('tab', { selected: true }); + expect(selected).toHaveTextContent(name); + expect(selected).toHaveFocus(); + expect(selected).toHaveAttribute('tabindex', '0'); + for (const tab of screen.getAllByRole('tab', { selected: false })) { + expect(tab).toHaveAttribute('tabindex', '-1'); + } + expect(useEditorStore.getState().activePath).toBe(name); + expect(switchTab).toHaveBeenLastCalledWith(name); + expect(flushAutosave).not.toHaveBeenCalled(); + }); + + it.each(['{Enter}', ' '])('WB-05:按 %s 激活已聚焦的文档入口', async (key) => { + const user = userEvent.setup(); + render(); + const tab = screen.getByRole('tab', { name: /b\.md/ }); + act(() => tab.focus()); + await user.keyboard(key); + expect(tab).toHaveFocus(); + expect(tab).toHaveAttribute('aria-selected', 'true'); + expect(tab).toHaveAttribute('tabindex', '0'); + expect(switchTab).toHaveBeenCalledTimes(1); + expect(switchTab).toHaveBeenCalledWith('b.md'); + }); + + it('WB-05:关闭按钮上的方向键不切文档,回车只执行关闭请求', async () => { + const user = userEvent.setup(); + flushAutosave.mockResolvedValue({ kind: 'failed' }); + render(); + await user.tab(); + await user.tab(); + const closeButton = screen.getByRole('button', { name: '关闭 a.md' }); + expect(closeButton).toHaveFocus(); + await user.keyboard('{ArrowRight}{Home}{End}'); + expect(closeButton).toHaveFocus(); + await user.keyboard('{Enter}'); + expect(flushAutosave).toHaveBeenCalledTimes(1); + expect(flushAutosave).toHaveBeenCalledWith('a.md'); + expect(switchTab).not.toHaveBeenCalled(); + expect(screen.getByRole('tab', { name: /a\.md/ })).toHaveAttribute('aria-selected', 'true'); + }); + + it.each<{ label: string; outcome: SaveOutcome }>([ + { label: '保存失败', outcome: { kind: 'failed' } }, + { label: '外部冲突', outcome: { kind: 'blocked', reason: 'conflict' } }, + { label: '保存期间修订改变', outcome: { kind: 'changed' } }, + { label: '保存返回后仍有新修改', outcome: { kind: 'saved' } }, + ])('WB-05:键盘关闭遇到$label时保留文档、脏标记及关闭焦点', async ({ outcome }) => { + const user = userEvent.setup(); + useEditorStore.getState().markDirty('a.md'); + if (outcome.kind === 'blocked') { + useEditorStore.getState().freezeAutosave('a.md'); + useEditorStore.getState().markExternalChange('a.md'); + } + flushAutosave.mockResolvedValue(outcome); + render(); + await user.tab(); + await user.tab(); + const closeButton = screen.getByRole('button', { name: '关闭 a.md' }); + expect(closeButton).toHaveFocus(); + expect(closeButton).toBeVisible(); + await user.keyboard('{Enter}'); + + expect(screen.getByRole('tab', { name: /a\.md/ })).toHaveAttribute('aria-selected', 'true'); + expect(screen.getByTestId('dirty-dot-a.md')).toBeInTheDocument(); + expect(closeButton).toHaveFocus(); + expect(disposeStateSpy).not.toHaveBeenCalled(); + expect(useEditorStore.getState().dirty['a.md']).toBe(true); + if (outcome.kind === 'blocked') { + expect(useEditorStore.getState().frozen['a.md']).toBe(true); + expect(useEditorStore.getState().externalChanged['a.md']).toBe(true); + } + }); - it('渲染两端贴边面板开关,默认展开态 aria-pressed=true', () => { + it('WB-05:键盘关闭脏文档在保存成功清除脏标记后才移除标签', async () => { + const user = userEvent.setup(); + useEditorStore.getState().markDirty('a.md'); + flushAutosave.mockImplementationOnce(async (path) => { + useEditorStore.getState().clearDirty(path); + return { kind: 'saved' }; + }); render(); - const left = screen.getByRole('button', { name: /侧边栏/ }); - const right = screen.getByRole('button', { name: /右侧面板/ }); - // DEFAULT_LAYOUT 两侧均展开(collapsed=false)→ pressed=true - expect(left).toHaveAttribute('aria-pressed', 'true'); - expect(right).toHaveAttribute('aria-pressed', 'true'); + await user.tab(); + await user.tab(); + await user.keyboard(' '); + + await waitFor(() => expect(screen.queryByRole('tab', { name: /a\.md/ })).not.toBeInTheDocument()); + expect(flushAutosave).toHaveBeenCalledWith('a.md'); + expect(screen.getByRole('tab', { name: /b\.md/ })).toHaveAttribute('aria-selected', 'true'); + expect(switchTab).not.toHaveBeenCalled(); }); - it('点左开关走 view.toggle-sidebar 命令、右开关走 view.toggle-right-panel', () => { - const exec = vi.spyOn(registry, 'execute').mockResolvedValue(undefined); + it('WB-05:键盘关闭脏草稿仍可取消丢弃,且不调用落盘', async () => { + const user = userEvent.setup(); + useEditorStore.getState().openTab({ path: 'draft://1', name: '未命名-1' }); + useEditorStore.getState().markDirty('draft://1'); render(); - fireEvent.click(screen.getByRole('button', { name: /侧边栏/ })); - fireEvent.click(screen.getByRole('button', { name: /右侧面板/ })); - expect(exec).toHaveBeenCalledWith('view.toggle-sidebar'); - expect(exec).toHaveBeenCalledWith('view.toggle-right-panel'); - exec.mockRestore(); + await user.tab(); + await user.keyboard('{End}'); + await user.tab(); + await user.keyboard('{Enter}'); + + expect(confirmDestructive).toHaveBeenCalledTimes(1); + expect(flushAutosave).not.toHaveBeenCalled(); + expect(screen.getByRole('tab', { name: /未命名-1/ })).toHaveAttribute('aria-selected', 'true'); + expect(screen.getByRole('button', { name: '关闭 未命名-1' })).toHaveFocus(); + expect(useEditorStore.getState().dirty['draft://1']).toBe(true); + expect(disposeStateSpy).not.toHaveBeenCalled(); }); - it('折叠态 → aria-pressed=false 且 aria-label/标题切到“展开”', () => { - useWorkbenchStore.getState().toggleSidebar(); + it('WB-05:键盘可到达外部文档,保留非工作区标记并按原绝对路径关闭', async () => { + const user = userEvent.setup(); + const path = 'D:/outside/reference.md'; + useEditorStore.getState().openTab({ path, name: 'reference.md', external: true }); render(); - const left = screen.getByRole('button', { name: /展开侧边栏/ }); - expect(left).toHaveAttribute('aria-pressed', 'false'); + await user.tab(); + await user.keyboard('{End}'); + const tab = screen.getByRole('tab', { name: /reference\.md/ }); + expect(tab).toHaveFocus(); + expect(tab).toHaveAttribute('aria-selected', 'true'); + expect(within(tab).getByLabelText('非工作区文件')).toBeInTheDocument(); + expect(within(tab).getByText('reference.md')).toHaveAttribute('title', `非工作区文件:${path}`); + await user.tab(); + await user.keyboard('{Enter}'); + await waitFor(() => expect(screen.queryByRole('tab', { name: /reference\.md/ })).not.toBeInTheDocument()); + expect(flushAutosave).toHaveBeenCalledWith(path); + expect(disposeStateSpy).toHaveBeenCalledWith(path); }); }); diff --git a/src/components/workbench/EditorTabs.tsx b/src/components/workbench/EditorTabs.tsx index 668a23b..3e4b597 100644 --- a/src/components/workbench/EditorTabs.tsx +++ b/src/components/workbench/EditorTabs.tsx @@ -1,24 +1,15 @@ -import { - ExternalLink, - PanelLeft, - PanelLeftClose, - PanelRight, - PanelRightClose, - X, - type LucideIcon, -} from 'lucide-react'; -import { execute } from '../../commands/registry'; +import { ExternalLink, X } from 'lucide-react'; +import { useRef } from 'react'; import { closeDocument } from '../../editor/documentSession'; import { switchToTab } from '../../editor/editorState'; import { useEditorStore } from '../../stores/useEditorStore'; -import { useWorkbenchStore } from '../../stores/useWorkbenchStore'; /** * 编辑器 tab 栏(D-01 标签页模型):tab 并存、可关闭、带脏标记。 * * 切 tab 经 switchToTab(path)——单内核 view.setState 换装 + 快照 + 滚动还原(D-03)全在 * editorState 内完成,组件不重复实现。关闭统一交给 documentSession 保存并释放。 - * 高 36 / 内边距 12 / active 2px 底 accent 指示条 + 600 字重;脏态 6px 圆点 ↔ hover 变 x。 + * 高 36 / 内边距 12 / active 2px 底 accent 指示条 + 600 字重;脏态圆点在 hover / focus-within 时变 x。 */ /** @@ -30,74 +21,66 @@ import { useWorkbenchStore } from '../../stores/useWorkbenchStore'; */ const closeTabFlow = closeDocument; -/** - * tab 栏贴边面板开关(R4 §3.2):复用 Sidebar HeaderAction 几何(32px 命中区 / 16px 图标 / - * strokeWidth 1.75 / rounded-[4px])。图标随开关态切换给视觉反馈,面板已开时高亮(aria-pressed)。 - * onClick 走既有 view.toggle-sidebar / view.toggle-right-panel 命令(零新命令,R4 §3.2 接线)。 - */ -function PanelToggle({ - icon: Icon, - label, - commandId, - pressed, -}: { - icon: LucideIcon; - label: string; - commandId: string; - pressed: boolean; -}) { - return ( - - ); -} - export default function EditorTabs() { const tabs = useEditorStore((s) => s.tabs); const activePath = useEditorStore((s) => s.activePath); const dirty = useEditorStore((s) => s.dirty); - const sidebarCollapsed = useWorkbenchStore((s) => s.layouts[s.mode].sidebarCollapsed); - const rightPanelCollapsed = useWorkbenchStore((s) => s.layouts[s.mode].rightPanelCollapsed); + const tabRefs = useRef(new Map()); + const tabbablePath = tabs.some((tab) => tab.path === activePath) ? activePath : tabs[0]?.path; if (tabs.length === 0) return null; return (
- {/* 左端贴边:切换左侧栏(图标随开关态 PanelLeft↔PanelLeftClose) */} -
- -
- {tabs.map((tab) => { + {tabs.map((tab, index) => { const active = tab.path === activePath; const isDirty = dirty[tab.path] === true; return (
{ + if (element) tabRefs.current.set(tab.path, element); + else tabRefs.current.delete(tab.path); + }} role="tab" aria-selected={active} - tabIndex={0} - onClick={() => switchToTab(tab.path)} + tabIndex={tab.path === tabbablePath ? 0 : -1} + onClick={(e) => { + e.currentTarget.focus(); + void switchToTab(tab.path); + }} onKeyDown={(e) => { - if (e.key === 'Enter' || e.key === ' ') switchToTab(tab.path); + // 关闭按钮保留原生键盘行为,不让冒泡事件变成标签切换。 + if (e.target !== e.currentTarget || e.altKey || e.ctrlKey || e.metaKey || e.nativeEvent.isComposing || e.keyCode === 229) return; + let nextIndex: number; + switch (e.key) { + case 'ArrowLeft': + nextIndex = (index - 1 + tabs.length) % tabs.length; + break; + case 'ArrowRight': + nextIndex = (index + 1) % tabs.length; + break; + case 'Home': + nextIndex = 0; + break; + case 'End': + nextIndex = tabs.length - 1; + break; + case 'Enter': + case ' ': + nextIndex = index; + break; + default: + return; + } + e.preventDefault(); + const nextTab = tabs[nextIndex]; + tabRefs.current.get(nextTab.path)?.focus(); + void switchToTab(nextTab.path); }} className={ 'group flex shrink-0 cursor-pointer items-center gap-2 border-b-2 px-3 text-[13px] ' + @@ -121,25 +104,28 @@ export default function EditorTabs() { > {tab.name} - {/* 脏态 6px 圆点 ↔ hover 变 x:圆点常显于脏态、hover 时让位关闭按钮 */} + {/* 鼠标悬停或键盘焦点进入标签时,脏圆点让位给可操作的关闭按钮。 */} {isDirty ? ( ) : null}
); })} - {/* 右端贴边:ml-auto 把开关推到 tab 组之后、靠窗口右上(不随 tab 横向滚动消失) */} -
- -
); } diff --git a/src/components/workbench/ModeIndicator.tsx b/src/components/workbench/ModeIndicator.tsx index e6c662a..bab9be8 100644 --- a/src/components/workbench/ModeIndicator.tsx +++ b/src/components/workbench/ModeIndicator.tsx @@ -1,8 +1,10 @@ import { Check } from 'lucide-react'; -import { useRef, useState } from 'react'; +import { useEffect, useRef, useState, type CSSProperties } from 'react'; +import { createPortal } from 'react-dom'; import { execute } from '../../commands/registry'; import { MODE_PRESETS } from '../../modes/presets'; import { useWorkbenchStore } from '../../stores/useWorkbenchStore'; +import { useProjectStore } from '../../stores/useProjectStore'; import type { AppMode } from '../../types/workbench'; import Menu, { type MenuEntry } from '../common/Menu'; @@ -16,7 +18,17 @@ const MODES: AppMode[] = ['standard', 'academic', 'creative']; export default function ModeIndicator() { const mode = useWorkbenchStore((s) => s.mode); const [open, setOpen] = useState(false); + const [position, setPosition] = useState({}); const anchorRef = useRef(null); + const blocked = useProjectStore((s) => s.archiveOpen || s.phase !== 'idle'); + useEffect(() => { + if (!open) return; + const close = () => setOpen(false); + window.addEventListener('resize', close); + window.addEventListener('scroll', close, true); + const unsubscribe = useProjectStore.subscribe((state) => { if (state.archiveOpen || state.phase !== 'idle') close(); }); + return () => { window.removeEventListener('resize', close); window.removeEventListener('scroll', close, true); unsubscribe(); }; + }, [open]); const items: MenuEntry[] = MODES.map((m) => ({ id: m, @@ -49,7 +61,11 @@ export default function ModeIndicator() { data-testid="mode-indicator" aria-haspopup="menu" aria-expanded={open} - onClick={() => setOpen((v) => !v)} + onClick={() => { + const rect = anchorRef.current?.getBoundingClientRect(); + if (rect) setPosition({ right: Math.max(8, window.innerWidth - rect.right), bottom: window.innerHeight - rect.top + 4 }); + setOpen((v) => !v); + }} className={`flex h-full items-center gap-1.5 px-2 text-[12px] font-normal transition-colors duration-[var(--duration-fast)] hover:bg-[var(--background-modifier-hover)] hover:text-[var(--text-normal)] ${ open ? 'bg-[var(--background-modifier-active)] text-[var(--text-normal)]' @@ -59,14 +75,15 @@ export default function ModeIndicator() {