侧栏项目与对话

完整侧栏契约

参考截图规定了置顶/取消置顶、编辑显示名称与图标、自定义分组、显示文件夹、创建持久 worktree、归档项目聊天和移除项目。编辑对话框支持源文件夹。OpenProgram 还提供打开项目设置和创建项目对话。移除项目只隐藏导航入口,保留注册表元数据、会话归属、文件与对话内容。Projects 页面可以恢复隐藏入口,重新打开文件夹也会恢复。默认 home 项目不可移除。

项目排序独立于对话排序。最近活动按项目内任意对话的最新时间戳排序;也支持最早活动和字母顺序。置顶项目显示在 Projects 上方独立的顶层 Pinned 列表。两个列表使用相同的分组标题字体和缩进,独立保存折叠状态,每个项目只出现一次。自定义分组保持为可管理的同级列表;空 Pinned 列表不显示。Projects 即使为空也保留标题以供筛选。拖拽切换为手动排序,并保留全部隐藏项目。对话排序明确区分升序和降序。偏好在重新加载后保留,并在窗口间同步。

侧栏可见性

侧栏仅显示包含可见、未归档对话的项目,置顶项目也遵循此规则。空项目和所有对话均已归档的项目不显示。项目注册、选择、管理、归档内容和已存储顺序保持完整。归档最后一条对话后项目隐藏;恢复对话后项目重新满足显示条件。

实施计划

  1. 实现基于活动的项目排序、对话排序方向和持久项目置顶;保留拖拽。
  2. 通过经过验证的注册表修改实现项目上下文菜单,以及可编辑元数据、图标、分组和源文件夹。
  3. 实现显示文件夹、创建持久 worktree、全部归档和非破坏性移除;整合项目打开操作。
  4. 完成入口测试、规格与质量审查、构建、后台部署和逐项需求核查。

四项全部完成才算完成。仅实现排序选项不足以满足完整侧栏目标。

项目标题支持指针拖放。被拖拽项目组沿垂直方向跟随指针,相邻组平滑移动以预览结果顺序,采用与 Favorite Programs 相同的 Motion 弹簧参数(stiffness 600、damping 40)。不显示插入线或独立项目名称预览。减少动态效果模式禁用弹簧过渡。会话随项目一起移动。Alt+ArrowUp 和 Alt+ArrowDown 支持键盘排序。

向上拖拽项目 B 会使项目 A 下移;松开后保存新顺序。

当前行为与选择

注册表管理归属。projectGroups 关联保留注册表归属,同时应用选定的项目排序和置顶。对话排序仍然独立。拖拽交互参考 Favorite Programs:被拖拽行连续移动,相邻行相应移位。指针捕获、六像素移动阈值和明确的释放/取消处理无需新增依赖;项目拖拽还根据目标位置改变分组和置顶位置。会话归属始终不变。

项目元数据与分组

注册表存储显示名称、纯文本图标或 emoji、描述及附加源文件夹。更新会验证受支持字段、长度和已存在的绝对目录,然后在锁内原子替换注册表。编辑元数据不改变主文件夹或会话归属。主文件夹迁移仍使用现有项目设置操作。聊天没有显式文件夹配置时,附加源文件夹作为默认值;刻意设置为空的聊天级列表仍保持为空。项目更新通知全部已连接窗口。自定义分组和项目位置属于本地视图偏好;移除分组会将其项目返回默认分组。

项目行通过右键和省略号按钮提供相同菜单,由共享菜单组件提供键盘导航。项目设置与侧栏共用元数据编辑器。保存失败时保留表单输入并显示错误。空项目不出现在侧栏;空自定义分组仍可管理。

项目操作

显示文件夹复用现有平台文件管理器操作。永久 worktree 从源 HEAD 创建,使用用户命名的新分支和实际源 Git checkout 之外的绝对目标路径。Git 验证分支与目标。重复请求识别完全匹配的现有 worktree 并注册,不重复创建。源 checkout 与未提交文件保持不变。全部归档先逐一持久化聊天再广播更新,失败时报告已完成 ID。移除仅设置注册表隐藏标志;隐藏项目的归属保持完整,历史仍可通过日期/平铺分组访问。项目筛选使用注册表 ID,因此修改显示名称不破坏筛选。

项目置顶控件

通过右键或选项按钮打开项目上下文菜单,可执行置顶和取消置顶。项目行不显示独立置顶按钮。菜单中的置顶控件使用 animated-icons 中的共享 PinIcon,与其他侧栏图标采用相同的受控 AnimatedNavIconHandle 接口。菜单项在悬停和键盘聚焦时驱动动画,离开或失焦后恢复静止。由于 pqoqubbw/icons 目录没有 Pin 组件,图标采用官方 Lucide Pin 图形,与现有 MonitorIcon 回退方式一致。复用共享 FolderOpenIcon 动画,不编写 SVG 路径或调用方独立旋转。新聊天和选项控件共用 project-action 类:20px 方形目标、5px 圆角、零内边距、居中的 14px 图标及相同中性悬停背景。两个控件组成紧凑组,内部间距 2px;项目名、操作组和折叠箭头间距不变。菜单打开时,边界和图标中心保持对齐。显式像素尺寸避免应用 14px 根字体导致差异。标准 2px 图标描边和中性色保持一致。减少动态效果用户看到静态图标。标签、按下状态、置顶/取消置顶行为、列表位置和持久化不变。

侧栏上下文菜单

桌面项目和对话菜单使用 Electron Menu.popup,提供原生 macOS 外观。菜单坐标取自调用位置的 CSS 像素,再按渲染器缩放系数转换;键盘调用使用当前焦点控件。Web 回退使用同一位置并处理视口边界碰撞。保留现有操作和确认流程。原生桥接仅接受所属 shell frame 发送的受限普通菜单描述,菜单关闭后只返回选定操作 ID。取消、渲染器导航、卸载和窗口销毁都会关闭所属请求并清理临时反馈。原生菜单失败时回退至 Web 菜单。实现遵循 Electron Menu 文档,不根据截图仿制 macOS 外观。

对话菜单反馈

通过选项按钮或右键打开对话菜单后,菜单打开期间,对话行和选项按钮保持现有中性悬停背景,包括指针移入菜单时。关闭菜单清除该临时反馈;已选对话保留正常选中背景。项目选项已经保留菜单打开背景。不增加发光、额外阴影或新选中状态。

项目行反馈

项目标题仅在指针位于该行或上下文菜单打开时显示中性悬停背景。点击、键盘激活、创建草稿及对话变化不会保留项目行选中状态。指针位于行外时关闭菜单,会清除临时背景。折叠、项目归属、拖拽和键盘焦点保持不变。

项目设置交互完善

项目设置编辑器使用应用 Input 和 Textarea 基础组件。聚焦字段显示细强调色边框和轻微外发光,强调色跟随当前主题。对话框使用克制的强调色边缘,图标选项持续显示选中状态。菜单或编辑器打开时,项目选项触发按钮保持可见,不单独发光;整个项目行仅在菜单打开时保留背景。菜单悬停和键盘焦点共享反馈。编辑器标题预览所选图标;文件夹路径换行而不挤动移除控件。打开及交互过渡快速完成,减少动态效果模式禁用新增过渡。

使用现有系统字体与主题 token:深色表面 #191918 和 #252523、亮色文字 #f0efea、主题弱化文字色和配置的强调色。浅色主题使用现有白色表面和深色文字。内容左对齐,标签 13px,字段采用共享 10px 圆角,编辑器通过可滚动正文适配窄屏。验证覆盖真实项目菜单入口、计算后的焦点与选中样式、深浅主题和减少动态效果渲染、取消操作,以及保存 payload 不变。全局对话框内容与遮罩高于窄屏侧栏,确保项目设置和文件夹选择器可见。共享层叠修复保留现有对话框交互。无关表单保持现有外观。

已移动文件夹

项目通过目录中的可移植标识文件保持身份;已知范围内查找与明确定位共用现有会话归属。当前契约及验收状态见 项目位置设计。

状态与边界

现有 recents 视图偏好中的项目 ID 数组在本地保存顺序。忽略未知 ID;新增项目遵循现有回退排序。其他项目移动时,隐藏项目保留顺序。Storage 事件同步窗口。无效持久化数组回退至默认顺序。存储失败时保留当前窗口可见顺序,并提示持久化失败。

验收

在 Projects 侧栏向上或向下拖拽,仅在放下时改变顺序。Escape 或在列表外放下不改变顺序。重新加载保留顺序。折叠、新会话按钮、归属和筛选行为不变。键盘移动保留焦点并播报结果。

实现状态

指针拖拽排序已通过针对性测试与独立审查。完整侧栏契约已实现。活动排序、对话方向和置顶通过针对性测试及两项独立审查;上下文菜单、元数据与源文件夹编辑器及分组也通过两项独立审查。worktree 创建、显示文件夹、全部归档、可逆项目移除和注册表 ID 筛选通过规格与质量审查。集成 Web 单元检查和受影响项目后端检查通过。项目设置焦点、活动菜单状态、图标选择、深浅主题、减少动态效果及窄屏布局通过渲染验收。TypeScript、可访问性、项目选择器、日期分组、WS action 路由和文档链接检查通过。用户明确排除前台 UI 验收;后台事件与集成检查提供获准范围内的验证证据。