feat(session-workspace): 临时会话工作区(顶栏胶囊 + 左侧会话轨道) - #79
Merged
Merged
Conversation
把「临时会话工作区」从 pinnedSessions 里独立出来:pinnedSessions 曾被当成会话存储用,
删除会话即丢、旧会话不在表里就丢、无法重排/命名,配置与调用点各一套。现在工作区是
独立的有序成员表(只存会话文件路径 + activeFile),跨重启保留、重启只按需加载 activeFile
一条;顶栏胶囊与左侧轨道共用同一份,左侧栏继续承担全量会话与置顶。
后端/契约
- shared: SessionWorkspaceSnapshot{files,activeFile} + UiState.sessionWorkspace / sessionRailEnabled
- main ui-state: files 清洗(trim/去空/去重)、activeFile 越界归 null、两个显示入口都关时强制清空
renderer
- stores/session-workspace.ts(新):成员表 + 纯函数(双键判重、右侧插入、右邻优先接替、
失效裁剪、读侧展示集 tabs优先/目录兜底)+ 合并式单写者持久化 + epoch 令牌
+ 插入锚点 anchorFile() = activeFile ?? recentFile(新会话页 activeFile 必为 null,
靠内存态 recentFile 才能把新成员插在「刚看过的会话」右侧)
- stores/session-workspace-restore.ts(新):冷启动恢复链(三个号取在 await 之前、自己读目录判据、
失效项裁剪并落盘修复、只开 activeFile 一条、用户接管时不抢焦点也不继承指针)
- sessions/projects:用户入口成功才入表(失败不留假胶囊)、迟到结果只入表不抢 activeFile、
activeSessionId 订阅单点同步 activeFile(订阅绝不加成员,防 GC 复活已移出会话)、
userIntentSeq 与 activationSeq 分职、adoptCatalog 参与目录 latest-wins
- 顶栏:展示集改工作区(GC 卸载后胶囊仍在、未加载成员点击按需打开)、× = 移出工作区
(右邻/左邻/回新会话页接替)、拖拽改工作区顺序、真胶囊形状(rounded-full,与轨道一致)
- components/session/SessionRail.tsx(新):与顶栏同一份工作区的短线条,悬停/聚焦膨胀成胶囊
(图钉+标题+×)、±1/±2 波浪、键盘 ↑↓ 移动 / Delete·Backspace 移出(焦点落邻居)、
命中区 24px 不抢正文点击
- lib/workspace-actions.ts(新):× 语义唯一一份实现(顶栏与轨道共用)
- lib/use-list-shift.ts(新):增删成员时其余胶囊/轨道的让位动画(FLIP,220ms 与拖拽同曲线)
- 设置 → 外观:顶栏显示会话 / 左侧会话轨道两个独立开关(双关 = 清空工作区并停止采集,不导航)
文档与验收
- docs/INDEX.md、docs/PITFALLS.md 同步(含 HMR 重建 store 模块实例、合成 mouseover 污染命中测试)
- scripts/shoot-rail.mjs(新):measure/wave/states/switches/reduced/pin/keyboard/ghost/gc/matrix/
anchor/anim/rename/assert-rename/assert-state/pill 等 CDP 验收模式,断言 fail-fast(失败 exit 1)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
把顶栏胶囊从「置顶表」改造成独立的临时会话工作区,并新增左侧会话轨道。
动机:
pinnedSessions一直被当成会话存储用,于是「打开过的会话」实际是「置顶表」——删除会话它的胶囊就没了、旧会话不在表里就丢、无法重排/命名,配置与调用点还各有一套。现在工作区是独立的有序成员表(只存会话文件路径 +activeFile),跨重启保留、重启只按需加载activeFile一条;顶栏胶囊与左侧轨道共用同一份,左栏继续承担全量会话与置顶。主要改动
SessionWorkspaceSnapshot{files,activeFile}+UiState.sessionWorkspace/sessionRailEnabled;normalize 负责清洗(trim/去空/去重、activeFile必须 ∈files)并在两个显示入口都关掉时强制清空。epoch令牌。activeFile一条;用户在等待期间动过手(切会话/回新会话页/自己开过会话)则不抢焦点、也不继承旧指针。activeFile;activeSessionId订阅单点同步activeFile(订阅绝不加成员,防 GC 卸载/重建把已移出的会话复活);删除会话顺带移出成员。关会话/GC 卸载不自动移出。rounded-full,与轨道一致)。aria-keyshortcuts;收起态纯覆盖层不占宽(命中区 24px,窄窗不抢正文点击)。prefers-reduced-motion跳过)。How was it tested?
npm run lint/npm run typecheck/npm run test:desktop 612 例、backend 559 例 全绿。scripts/shoot-rail.mjs(10+ 模式,断言 fail-fast:失败exit 1):几何与命中区、波浪档位、组态截图、设置开关独立性与双关清空、prefers-reduced-motion、图钉即时增删、键盘(↑↓/Delete,含焦点落邻居)、未加载胶囊真实拖拽的 DragOverlay 与落盘顺序、GC 卸载后胶囊仍在且按需打开(读 dev 的[session-gc] unload日志取证)、三处顺序一致、插入锚点回归、让位动画关键帧、未加载成员离线重命名一致性(重启前后)。已知覆盖缺口
useSessionStatus)」的证据,已与维护者确认接受该缺口。Checklist
npm run lintpassesnpm run typecheckpassesnpm run testpasseszhandendictionaries