Skip to content

feat(session-workspace): 临时会话工作区(顶栏胶囊 + 左侧会话轨道) - #79

Merged
Jaxton07 merged 1 commit into
mainfrom
feat/session-workspace
Sep 29, 2026
Merged

Jaxton07 merged 1 commit into
mainfrom
feat/session-workspace

Conversation

@Jaxton07

Copy link
Copy Markdown
Owner

What does this PR do?

把顶栏胶囊从「置顶表」改造成独立的临时会话工作区,并新增左侧会话轨道。

动机:pinnedSessions 一直被当成会话存储用,于是「打开过的会话」实际是「置顶表」——删除会话它的胶囊就没了、旧会话不在表里就丢、无法重排/命名,配置与调用点还各有一套。现在工作区是独立的有序成员表(只存会话文件路径 + activeFile),跨重启保留、重启只按需加载 activeFile 一条;顶栏胶囊与左侧轨道共用同一份,左栏继续承担全量会话与置顶。

主要改动

  • 契约/主进程:SessionWorkspaceSnapshot{files,activeFile} + UiState.sessionWorkspace / sessionRailEnabled;normalize 负责清洗(trim/去空/去重、activeFile 必须 ∈ files)并在两个显示入口都关掉时强制清空。
  • 工作区 store(新):成员表 + 纯函数(file/sessionId 双键判重、右侧插入、右邻优先接替、失效裁剪、读侧展示集 tabs 优先/目录兜底)+ 合并式单写者持久化(只落最后意图)+ epoch 令牌。
  • 冷启动恢复链(新):目录投影显式等待、按路径解析存在性(不拿 tabs 里的 0 消息计划路径当依据)、失效项裁剪并落盘修复、只按需打开 activeFile 一条;用户在等待期间动过手(切会话/回新会话页/自己开过会话)则不抢焦点、也不继承旧指针。
  • 用户路径:只在用户入口入表(打开/新建转正/fork),打开成功后才入表(失败的 open 不留点不开的假胶囊);迟到结果只入表不抢 activeFile;activeSessionId 订阅单点同步 activeFile(订阅绝不加成员,防 GC 卸载/重建把已移出的会话复活);删除会话顺带移出成员。关会话/GC 卸载不自动移出。
  • 顶栏胶囊:展示集改工作区(GC 卸载后胶囊仍在、未加载成员点击按需打开);× = 移出工作区(右邻/左邻/都没有回新会话页,不调后端 close/delete/unpin);拖拽改工作区顺序;真胶囊形状(rounded-full,与轨道一致)。
  • 左侧会话轨道(新):与顶栏同一份工作区的短线条,悬停/聚焦原地膨胀成胶囊(图钉 + 标题 + ×)、相邻 ±1/±2 波浪;键盘 ↑↓ 移动焦点、Delete/Backspace 移出(焦点落到邻居)且带 aria-keyshortcuts;收起态纯覆盖层不占宽(命中区 24px,窄窗不抢正文点击)。
  • 设置 → 外观:新增「左侧会话轨道」开关(默认关),与「顶栏显示会话」互相独立;两处都关 = 清空工作区并停止采集,但不导航、不关会话、不打断运行中的任务。
  • 让位动画(新):增删成员时其余胶囊/轨道项滑动到位(FLIP,220ms,与拖拽让位同曲线;新项 140ms 淡入;prefers-reduced-motion 跳过)。

How was it tested?

  • npm run lint / npm run typecheck / npm run test:desktop 612 例、backend 559 例 全绿。
  • CDP 真机验收脚本 scripts/shoot-rail.mjs(10+ 模式,断言 fail-fast:失败 exit 1):几何与命中区、波浪档位、组态截图、设置开关独立性与双关清空、prefers-reduced-motion、图钉即时增删、键盘(↑↓/Delete,含焦点落邻居)、未加载胶囊真实拖拽的 DragOverlay 与落盘顺序、GC 卸载后胶囊仍在且按需打开(读 dev 的 [session-gc] unload 日志取证)、三处顺序一致、插入锚点回归、让位动画关键帧、未加载成员离线重命名一致性(重启前后)。
  • 手验:旧用户 ui-state 升级(顶栏开/关两态,置顶不迁移)、脏快照剪枝(幽灵成员被裁且不造空白会话文件)、重启保顺序且只加载一条、窄窗口无横向偷滚、深色主题、Mac drag-region 回归。

已知覆盖缺口

  • 后台运行中的 streaming / 审批 / 频道订阅未做真实模型调用演练(dev 环境无凭证):目前只有「代码层未触碰这些路径 + 状态色与左栏同源(useSessionStatus)」的证据,已与维护者确认接受该缺口。

Checklist

  • npm run lint passes
  • npm run typecheck passes
  • npm run test passes
  • New user-facing strings were added to both zh and en dictionaries
  • No API keys or sensitive data included

把「临时会话工作区」从 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)
@Jaxton07
Jaxton07 merged commit 6fd9662 into main Sep 29, 2026
1 check passed
@Jaxton07
Jaxton07 deleted the feat/session-workspace branch September 29, 2026 01:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant