09. 交互模式
翻译说明: 本页是与 英文源规格 一一对应的机器辅助翻译。代码、协议字段和标识符保持原文;如翻译与英文源事实有歧义,以英文版本为准。
设计系统令牌:07-ui-design-system.md 组件剖析:08-component-spec.md 权限UX:03-permission-ux.md 命令面板:04-builtin-commands.md
1. 键盘快捷键基线
1. 1 全局快捷键
| 快捷方式 | 行动 | 背景 |
|---|---|---|
Option + Space (macOS) / Alt + Space (Windows/Linux) | 打开插件启动器 | 应用程序启动后操作系统全局;可定制 |
Cmd/Ctrl + Shift + P | 打开命令面板 | 全球 (D014) |
Cmd/Ctrl + N | 新 chat/session | 全球 |
Cmd/Ctrl + O | 打开项目 | 全球 |
Alt + Shift + W | 呼出或隐藏窗口(切换) | 系统级全局(D439);隐藏到托盘,绝不退出 |
Cmd/Ctrl + , | 打开设置 | 全球 |
Cmd/Ctrl + B | 切换侧边栏 | 全球 |
Cmd/Ctrl + J | 打开工作面板 | 全球;活动会话 |
Cmd/Ctrl + [ | 之前的目的地 | 全球 |
Cmd/Ctrl + ] | 下一个目的地 | 全球 |
Cmd/Ctrl + . | 中止主动回合 | 全局(与中止按钮相同) |
Cmd/Ctrl + K | 打开命令面板 | 全球 |
1. 2 对话上下文快捷方式
| 快捷方式 | 行动 | 背景 |
|---|---|---|
Enter | 开启回车发送时发送;关闭后换行 | 以输入框为中心 |
Cmd/Ctrl + Enter | 关闭回车发送时发送 | 以输入框为中心 |
Shift + Enter | 换行符 | 以输入框为中心 |
Alt + Enter(macOS 为 Option + Enter) | 向当前回合补充指令;空闲时正常发送 | 输入框聚焦,且不在输入法组词过程中 |
Escape | 清晰输入/模糊编辑器 | 以输入框为中心 |
Cmd/Ctrl + ↑ | 滚动到文字记录顶部 | 注重成绩单 |
Cmd/Ctrl + ↓ | 滚动到文字记录底部 | 注重成绩单 |
1. 3 命令面板快捷键(面板内)
| 快捷方式 | 行动 | 背景 |
|---|---|---|
↑ / ↓ | 导航结果 | 调色板打开 |
Enter | 执行选定的命令 | 调色板打开 |
Escape | 关闭调色板 | 调色板打开 |
1. 4 快捷键规则
- macOS 应用程序菜单快捷方式可通过系统菜单发现 加速器。 Windows/Linux 快捷方式仍然可用,无需渲染 应用程序菜单栏;仅命令快捷方式可通过命令发现 调色板搜索(关键字“快捷方式”或“键绑定”)。
- 快捷方式不得与 macOS 系统快捷方式或常见浏览器快捷方式冲突
- 切勿覆盖
Cmd/Ctrl + C、Cmd/Ctrl + V、Cmd/Ctrl + A、Cmd/Ctrl + S - macOS (Cmd) 和 Windows/Linux (Ctrl) 之间的快捷键是一致的
- 缺少快捷键覆盖时使用共享的平台默认值;合法字符串使用自定义绑定;明确的
null表示“未绑定”,不会触发命令,也不与其他绑定冲突。 - 仅修饰符按键和 IME composition/229 按键永远不会调度 命令。重复的按键事件不会重复遍历目的地历史;每个 back/forward 和弦每次 物理按下最多前进一次。
- 仅命令快捷方式更改需要更新命令面板元数据; 本机角色和可见的应用程序菜单加速器仍然由菜单拥有
- 插件启动器通过 Electron 的本机全局快捷方式注册 API。 Windows' 保留的默认值
Alt + Space另外使用 host-core 低级键盘钩子,消耗系统菜单和弦并发出 Electron 主机通知,因此它可以在另一个应用程序运行时工作 专注。如果钩子无法被安装,聚焦窗口后备仍然可用。未绑定时会同时关闭钩子和 聚焦窗口后备。自定义绑定继续使用 Electron 的全局快捷方式 API。 启动器始终在最靠近指针的显示屏上打开。 - 窗口可见性只有一个开关键(
Alt + Shift + W):可见且在前台的窗口隐藏到托盘, 其余情况 —— 已隐藏、已最小化或被其它应用挡在后面 —— 显示并获得焦点。隐藏 不走关闭路径,因此不会弹出关闭行为询问、不会销毁窗口,也绝不会退出应用。 该键是系统级全局注册,因此刻意避开Cmd/Ctrl + W—— macOS 把它用于自己的 关闭窗口命令,应用一旦占用就会从所有应用程序手里把它抢走。已弃用的Cmd/Ctrl + Shift + W呼出组合键同样不再注册;读取配置映射时,已存储的closeWindow/summonWindow覆盖项会并入该开关键(D438、D439)。
1. 5 插件启动器快捷方式
| 快捷方式 | 行动 | 背景 |
|---|---|---|
↑ / ↓ | 循环匹配插件 | 专注于启动器 |
Enter | 打开选定的插件面板 | 专注于启动器,而不是撰写 IME 文本 |
Escape | 关闭启动器 | 专注于启动器 |
1. 5 平台应用菜单
- macOS 应用程序菜单加速器调度相同的白名单 shell 作为渲染器控件的命令。保留本机 Edit/View/Window 角色 平台文本编辑、缩放、全屏、隐藏和退出行为。
- Windows/Linux 在窗口中不呈现应用程序菜单。他们的无框 标题栏将侧边栏操作保留在左边缘,将本机窗口控件保留在 右边缘。当工作面板打开时,其唯一的折叠控制位于 在会话窗格右上角这些窗口控件之前,而不是在 工作面板内容标题。目的地历史记录没有可见的 back/forward 控制并通过渲染器快捷方式保持可用。第一个 转录行从 46px 标题栏控制带下方开始,因此用户和 助理内容不能与最小化、maximize/restore 或关闭重叠 目标。目标页面和插件详细信息表的开头相同 带,因此页眉操作和工作表关闭控件永远不会堆叠在 这些目标。 F10 和 Shift+F10 不会被 shell chrome 消耗。
- Windows/Linux 保留新任务、打开项目、设置、关闭窗口、 缩放、全屏、搜索、命令面板、侧边栏和工作面板快捷方式 通过渲染器键处理。标准编辑快捷方式仍然是原生的 网络内容行为。
- 开发者工具是可选的。启用开发者模式后,Main 会处理 F12 每个平台以及 Windows/Linux 上的 Ctrl+Shift+I; macOS 暴露其原生 View 中的开发人员工具角色。禁用该模式后,这些产品条目 点仍然不可用,禁用它会关闭打开的控制台。
- 主队列本机命令,直到渲染器确认其菜单 事件订阅在 macOS 上处于活动状态。关闭并重新创建窗口 重置本次握手。
- 无框最小化、maximize/restore 和关闭控件保留在范围之外 拖动区域。最大化状态在挂载时查询并从本机更新 窗口事件,因此恢复可供性永远不仅仅取决于乐观 渲染器状态。
- 最小化在每个平台上都把窗口隐藏进常驻托盘(D216,§1.5.1)。 Windows/Linux 的关闭行为由用户配置(ADR 0090):尚未设置的偏好通过原生 提示只问一次(取消 / 关闭到托盘 / 退出);
tray把窗口隐藏到同一个托盘 图标之下,点击它即可恢复窗口;quit退出应用。关闭行为从不创建或销毁 托盘 —— 图标归 D216 所有,两种选择下都常驻。这个选择会被持久化、可在 设置 → 通用中回访,并且关闭按钮和关闭快捷键都遵循它。macOS 保持原生 Dock 生命周期(关闭后应用留在 Dock 中,激活时重建窗口)。边界看门狗 永远不会恢复一个最小化或隐藏到托盘的窗口。
1. 5.1 托盘驻留最小化
- 最小化意味着 macOS、Windows 和 Linux 上隐藏到托盘。渲染器的 Windows/Linux 最小化按钮、macOS 交通灯最小化按钮,以及 macOS 窗口 → 最小化角色共享此行为。
- 隐藏将从 taskbar/dock 窗口列表中删除主窗口,而 Electron 进程和后台工作仍然有效。它不坚持 最小化几何形状或处置 host/sidecar。
- Double-clicking the tray icon (or single-clicking on Windows/Linux), choosing Open, or activating the macOS Dock restores/focuses the existing window or creates a new one if it was closed. macOS single-click opens the menu.
- The localized tray includes Open, bounded session groups, and Quit. Quit keeps confirmation and ordered shutdown. Close behavior remains user-owned on Windows/Linux (ADR 0090), and macOS retains its Dock lifecycle.
1.5.2 Tray session navigation (issue #293)
- The native menu shows Running, Unread, and Pinned in that order, at most nine sessions in total. Every non-empty group keeps up to three rows; the share smaller groups leave unused goes to the groups that still overflow, in priority order, so one busy group can fill all nine while the others are empty. Membership is assigned before applying limits; higher-priority overflow never spills into a lower group.
- Empty groups are hidden. Archived sessions/projects and deleted sessions are excluded. Running/Pinned follow sidebar sorting; Unread follows the latest unread result per session, newest first, including failed results.
- Long titles use one line capped at 32 display columns including the ellipsis; an East Asian wide or emoji code point counts as two, so a CJK row stays as wide as a Latin one. An overflowing group offers View more to restore the window and expand session navigation. A session row restores/focuses its exact conversation, activating its project through the existing selection flow.
- macOS single-click opens the menu without restoring/focusing a conversation or marking it read. Entering a conversation uses normal acknowledgement. Open and double-click restore the window; Quit keeps its confirmation and ordered shutdown. Group/action labels follow the active shipped locale.
- Start/finish, read, pin, rename, archive, delete, and backend restart update the menu. The menu remains available when the main window is hidden or closed, without creating another window until an explicit activation.
- macOS 不监听托盘 mouse-enter:该事件会替换原生 status item 并让菜单栏图标消失。 Windows/Linux 仍可在悬停/右键时重试失败的 Host 读取;macOS 改由下一次会话或收件箱事件刷新。
1. 6 侧边栏项目和对话组织
侧边栏是主持人拥有的项目和会话的路径键控演示。 Sessions 标题首先出现,包含无路径对话以及 他们的创建和排序控件。它的有界列表使独立工作保持可见 而不消耗整个侧边栏。以下 Projects 部分标题 在保留的项目组上方公开项目选择器。多个项目组 当只有一个工作空间提供可见的 shell 上下文时,可能会被保留。
项目选项卡生命周期
- 打开 — 从“设置”→“项目存档”中选择一个项目,或者选择器添加其项目 保留集的标准化路径并激活它。现有选项卡保留。
- 激活 — 选择不同的组调用现有的
project.set桥。然后,它的路径驱动顶栏标识、活动工作区状态,以及 新任务范围。 - 折叠 — 披露状态属于每个项目路径。崩溃 仅隐藏儿童;它既不更改选定的会话,也不停止 跑。目录行是一个全角公开目标,包含其 V 形、文件夹和标签:选择非活动目录将其激活 首先,每次目录行单击都会切换该组的子级,而无需 改变任何其他组的状态。项目操作是独立的兄弟项目 控制并且从不切换目录。
- 关闭 — 关闭仅删除保留的选项卡。如果它处于活动状态,则 选择最后一个剩余选项卡或清除可见工作区。耐用 项目、会议和成绩单仍然保留。
组织行动
- 编辑项目 — 侧边栏和项目存档中的项目溢出菜单打开同一个项目编辑器。 编辑器可以调整项目名称和文件夹列表;Primary 文件夹保持在首位且不能移除, 其他文件夹可以通过原生多选文件夹选择器添加,也可以单独移除。保存时由 host 持久化逻辑项目组,同时保留规范化路径、工作区身份、会话、转录和磁盘文件夹。 已有聊天记录的文件夹不能直接移除。
- Pin 切换演示优先级。出现固定的 projects/conversations 在所选二级订单中取消固定的行之前。
- 存档是非破坏性的。默认情况下,存档的行是隐藏的, 可通过显示已存档且可恢复。存档不会取消 转动或删除成绩单。
- 删除会永久移除会话或项目,并且需要点击两次:第一次点击武装该溢出菜单项并改写其 标签(
nav.deleteTaskConfirm/project.deleteMenuConfirm),只有第二次点击才会移除 该行。武装会在几秒后自行失效,因此一行永远不会停留在“再点一次就永久删除”的状态,磁盘 上的文件夹也永远不会被触碰。仍有运行中轮次的项目依然会打开确认对话框,由它指明这些会话 并先将其停止;空闲的项目在第二次点击时即被移除。 - 创建分支快照空闲对话的完整活动状态 转录到同一 project/Temporary 范围内的独立会话中。 当源运行时该命令被禁用。成功选择了孩子 聚焦输入框;失败使源可见且未改变。
- 归档可见的 conversation/project 首先移动可见上下文 给一个未存档的兄弟姐妹。没有兄弟姐妹,谈话就会变得新鲜 同一范围内的草稿和项目清除了可见的工作空间;该应用程序 永远不会将隐藏的归档行保留为活动上下文。
- 排序优惠最近更新 (
recent)、创建日期 (created)、 最旧的在前 (oldest),以及名称 (name)。 Missing/invalid 值回落 至recent。按住项目标题并移动 8px,或聚焦标题后按ArrowUp/ArrowDown,会切换到manual项目排序,并按规范化路径持久化连续顺序。 归档和置顶优先级仍高于手动顺序;尚未分配顺序的项目暂按稳定路径顺序排列。 - 每个项目组显示活动排序顺序中最新的十行 默认情况下;剩余的会话折叠在 加载 N 更多… 控件后面 (与时间分组溢出相同的可供性)。选择它展开 完整的时间分组列表,并且扩展状态是每个组的,对于 仅当前会话,不持久。
- 尽力保存演示文稿更改。存储故障不得阻塞 项目激活、会话选择或代理执行。
跨选项卡的会话隔离
- 选择一行会立即将该目的地标记为已选择。 120毫秒 指针悬停或键盘焦点可以预取其记录;重复读取 共享一个正在进行的请求,渲染器最多保留五个最近的请求 转录快照。
- 若一次记录窗口读取对侧边栏计为有历史的会话返回零条消息,该结果按“无法读取” 而不是“空会话”处理(D615,issue #795):选择流程会再读一次,随后保留用户已有的 快照,否则显示
chat.sessionTranscriptEmpty,而不是提交一份空记录。这类空页绝不会 写入缓存,因此悬停预取不会在之后每次打开时反复提供空内容。 - 脚本加载开始,无需等待旧的被取代的选择。 当会话摘要元数据可用时,项目 activation/clearing 和 转录IO并行运行。单调导航生成仅允许 用于投影可见工作区、脚本、运行状态的最新选择, 导航历史记录和工作面板上下文。
- 聊天表面为每个会话保留一个面板,按会话 ID 键控,上限为三个 (可见面板加上最近的两个)。隐藏的面板保持挂载且惰性——
visibility: hidden加content-visibility: hidden,绝不用display: none,那会丢弃它们的滚动偏移——并且每个面板在其整个 生命周期内保持自己的滚动位置。切换到仍然有面板的会话(热)会 立即以其保留的内容和位置揭示它:没有任何内容被调暗、不出现 骨架屏、没有转录重新挂载,重新验证的快照落回同一个面板, 没有可见变化。若目标仍在运行,或仍持有持久化页尚未赶上的已完成 回复,有界持久化页按时间顺序缝到实时快照上:早于该页的实时行留 在前面,乐观、流式或尚未刷入的尾巴留在后面;实时独有行不得追加 到该页之后,否则最新回合会掉出尾部挂载窗口(D317 / D261 / D324)。 只有当该页已包含每一条实时行时才清掉实时来源标记。 - 切换到没有保留面板的会话(冷)会让可见面板停留在它自己的会话上, 直到目标提交。只有一条细进度轨道和
aria-busy标记这段等待, 输入框保持非交互,因此提示无法发往正在离开的会话,并且目标会话 ID 永远不会与另一个会话的消息配对。随后目标在它最后的记录处 被揭示,没有历史顶部或空首页的闪光。被逐出的会话与首次访问 没有区别。 - 新建任务不是冷切换。创建会话时第一帧就露出空首页(在
session.create之前清掉上一场对话和保留面板)。复用该组最新空会话时, 同一帧提交空转录,不等待session.get。持久行来自session.create摘要;发送和粘贴会等待这次进行中的创建,而不是再开一个槽位(ADR 0154)。 - 首次打开的会话在其最新回合处落定。重新访问的面板回到用户离开的 偏移,而仍然固定在底部的面板重新锚定到底部;对于重新访问,激活 不再重置手动滚动状态(ADR 0137)。历史续接(D269)不会把塌缩的 滚动容器、或
scrollTop被重置为 0 的已钉住溢出记录当成「在顶部」 去翻更早的页;落在近顶部带内的真实手势仍会继续载入历史。空的首帧 不会消耗首次提交的水合门闩,因此随后到达的长记录仍会被限制挂载, 并在布局阶段、浏览器绘制之前重新吸底。 - 选择项目范围的对话会激活其项目作为 商店自有精选交易。选择临时对话将清除 可见的工作空间。项目范围内的新会话操作通过了目标 同一家商店交易的路径;侧边栏和项目索引处理程序执行以下操作 在会话创建或选择之前不执行第二个项目导航。
- 运行状态、权限授予和流式事件由会话 ID 键入。 project/tab 开关不会中止后台轮次或将其事件复制到 可见的转录本。背景消息、工具、完成和权限 事件永远不会激活其会话、更改可见的 project/page 或移动 焦点。创建一个新会话或切换到未运行的会话返回 输入框立即进入空闲发送状态:轮流仍在 先前选择的会话永远不会离开目标会话的发送按钮 卡在 Abort/stop 状态,并且该后台回合稍后完成 不改变目标输入框。他们的工作面板工件和 浏览器资源仅更新 原始会话保留的渲染器上下文,并且不显示或调整大小 可见面板。仅显式 session/notification 激活才能导航 并投影目标会话的保留面板上下文。
- 输入框草稿同样按会话保留在渲染器内存中(D301):缓存比任意一次 Composer 挂载更长寿,因此切换会话、空首页 ↔ 停靠、聊天 ↔ 其他页面、或操作系统窗口时, 都会保存/恢复来源文本和文件引用。未缓存的目标从空开始,首页输入框有自己的 草稿槽位。创建新会话不会复制其他槽位。完成的发送只清除提交该请求的会话草稿, 即使请求进行中用户切换了会话;已删除的会话不能保留草稿。
- 每个工具调用都会从原始持久性解析
workspaceRoot会话,而不是来自当前选定的项目选项卡。后台完成 刷新匹配行而不重定向活动对话。
焦点和语义
- 项目目录行公开
aria-expanded和aria-controls; new-project/new-session 控件具有特定于范围的可访问名称,并且 sort/archive 菜单选项公开其选中状态。活动会话行 保留aria-current。 - 切换披露或菜单操作可将焦点集中在其控制上。选择一个 加载后,project/session 将焦点返回给输入框。
- 保留排序、存档、恢复、固定、创建分支和关闭操作 可通过键盘操作; 它们不能仅仅作为指针悬停功能而存在。
- 从工具栏或行触发器打开的侧边栏主体级菜单仍然存在 内容大小并使用与右键菜单相同的固定规则:打开4px 锚点在右侧而不向左翻转。它们的表面宽度为 为窄视口设置了上限。这包括会话排序菜单, session/project 溢出菜单和部分创建菜单。
1. 6 本地个人资料页脚
44px配置文件触发器切换菜单;它的V字形和aria-expanded状态一起改变。280px菜单在透明页脚带上方打开8px。打开它 将焦点移至非交互式标识之后的第一个可操作行 标头和分隔符。ArrowDown/ArrowUp包含在设置、日志和主题之间。Home和End移动到第一个和最后一个操作。Escape关闭菜单并将焦点恢复到配置文件触发器。一个指针 按外侧可将其关闭,而不会窃取指针目标的焦点。- 在执行操作之前选择“设置”、“日志”或“主题”会关闭菜单 行动。主题应用下一个主题值,无需重新打开菜单。
- 单独的
32px帮助按钮绕过配置文件菜单并导航 直接进入设置 → 信息。 - 折叠侧边栏会关闭菜单并恢复折叠的栏杆 正常导航状态。
1. 7 通知收件箱(D117/D350)
事件到表面的流
- Renderer 将当前聊天的会话 ID 报告给 Electron Main;导航 离开清除它。 Main 将此提示与其自己的窗口可见性结合起来, 当转动达到
completed或error时的焦点状态。 - 如果确切的整理会话已在焦点窗口中可见,
session.endTurn关闭回合而不插入通知。任意 后台会话或 unfocused/hidden 窗口创建持久记录。aborted回合永远不会创建一个。 - Electron 向每个实时渲染器发出
notification.changed,以便响铃 徽章和当前打开的收件箱刷新。 - 对于终端任务结果,本机通知仅在主窗口未聚焦时出现。聚焦背景会话的完成 仍会创建持久行,但不会出现本机横幅。asktool、工具权限和 Plan 审批询问 使用带有
kind: "interactive"的同一个 Electron 表面:确切的聚焦当前 会话保持静默,而聚焦于其他会话时可以收到横幅。在 Windows 上,每个横幅 都归因于与 NSIS 包和任务栏标识共享的规范 PI-Desktop AppUserModelID。 - 单击本机通知 shows/restores 并聚焦于主通知 窗口,然后发出
notification.activated { sessionId }。 - Renderer 激活选择绑定项目(如果存在),加载 会话,并使用与收件箱相同的路径聚焦 transcript/composer 行点击。本机激活和应用内激活不得不同。
交互询问横幅是仅本机的恢复表面,不会创建持久任务收件箱行;用户返回会话后, 行内 ask、权限或 Plan 卡片仍是事实来源。
弹出窗口行为
- 列表只显示
task.failed行,铃铛徽章也只统计未读的失败。task.completed记录仍会持久保存,并继续驱动侧边栏结果徽标和原生通知,但收件箱隐藏它们, 避免失败被例行的顺利完成淹没(D295)。 - 单击铃声可切换非模式弹出窗口;第二次单击、Esc 键或外部 按将其关闭。 Escape 将焦点恢复到铃声上。
- 打开时保留最近选择的
All/Unread过滤器 当前渲染器生命周期并且从不标记隐式读取的行。 - 箭头键在禁用换行的情况下在行中移动;
Home/End跳转到 first/last 行; Enter/Space 标记该行已读取并激活其会话。 - 标记一个主机事务中每个未读行的所有读取更新。清除 删除一个主机事务中的所有收件箱行。两个操作都是 幂等,刷新确切的未读计数,并保持 sessions/turns 不变。
- 渲染器不会从流事件中合成通知记录。 Host-core 独特的
turn_id是重复的一次边界 终端更新、渲染器重新加载和进程重新启动。 - 所有可见事件标签和本机 title/body 字符串均在 结构化字段的表示边界;持久化的行从不包含 本地化的散文。
1. 8 工作面板条目和资源(D128、D142、D154、D173、D179、D207)
- shell 启动时没有可见的工作面板。
Cmd/Ctrl + J打开 活动会话的保留面板上下文,无需创建资源选项卡;它 当面板已经打开时是幂等的,并且是无操作的 活动会话或当“设置”是活动页面时。小组的背景 然后触发器可以创建浏览器或当前范围内的插件视图。 - 工件触发器自动创建或重用其资源,激活它, 并打开面板。背景工件永远不会打开可见面板。
- 文件资源使用规范化路径作为标识。浏览器和插件视图是单例的;重复 触发器保留资源顺序并激活现有资源。
- 打开后,面板标题是可横向滚动的
tablist,紧邻固定的+入口。 每个标签拥有活动状态和关闭按钮,活动标签会滚动到可见范围。新建菜单只有 Tools & panels 分组,包含宿主 Review 以及当前范围内所有插件视图,Files 和 Browser 保持数据驱动(D173)。 - 标签焦点使用 roving
tabIndex:ArrowLeft/ArrowRight/Home/End 在标签间移动, Delete/Backspace 关闭聚焦标签,中键关闭标签;关闭活动标签后按右邻居、左邻居 选择下一个。+菜单使用 Arrow/Home/End、Escape 和 Tab,并在关闭时把焦点 返回+。只有真实存在的绑定才显示快捷键标签。 - 激活已打开的工具会激活其现有资源 替换它,因此浏览器保留其 URL 和文件的选择 (D173)。
- 每个资源都可以从对应标签中关闭。关闭活动资源选择右邻居,再选择左邻居;关闭 最后一个选项卡会保持面板打开并显示 New 启动器。会话窗格右上角的面板折叠控件 只隐藏面板,不删除选项卡。
- 在每个平台上,打开可见面板都要求本机宽度等于 它的承诺宽度。折叠并最终关闭回收预订,并且 提交的分隔符调整大小会更新它。本机窗口边缘拖动更改 仅 MainChat,从不面板宽度(D163,ADR 0032)。
- 任何工具结果都不会创建或激活工作面板标签页。Review 只由用户的 主动操作打开——
+启动器的 Review 行,或视口固定开关与Cmd/Ctrl + J显示的会话保留上下文——因此成功的工作区 Write/Edit 永远不会抢走用户正在阅读的面板。失败和临时写入同样如此。后台会话 事件仅更新其保留的上下文,并且从不打开、激活、调整大小、聚焦, 或更改可见面板。 - 每个成功的工作区 Write/Edit 工具结果都会进行一次持久审查 快照。其紧凑的 InlineReviewCard 在同一个 Activity 中呈现 披露,紧随其工具行之后;它永远不会移动到 转录底部并且从未与其他会话共享。它的状态徽章 涵盖添加、修改和删除的更改,同时计数和可扩展 hunk 来自该消息的结果,而不是当前的 Git diff。
- 成绩单卡和复习会消耗活动会话的持续时间 消息历史记录。提交、工作区焦点更改或外部 Git 状态 更改无法删除或重写旧卡。评论是按时间顺序排列的 快照历史记录和每个可逆卡都会暴露主机保护的回滚; 报告冲突而不替换以后的编辑。划痕,失败, 被拒绝,非结构化结果不会呈现卡片。背景 会话的卡片保留其自己的成绩单并且仅变得可见 选择该会话后;它的事件永远不会呈现在当前 可见会话。成功的工作空间工件不会创建或激活单例“审阅”选项卡; 它只在用户打开后出现。
- 每个会话在渲染器中保留
{open, tabs, activeTabId, browserResource}记忆。选择另一个会话会自动交换可见上下文, 切换回来可以恢复它;选择没有活动的工作区 对话隐藏面板。 Session/workspace 身份仍附加到 每个相关资源,防止跨上下文重新解释。 - 重新启动会丢弃每个会话上下文,包括浏览器资源;仅 承诺的首选面板宽度仍然存在。存储本机窗口状态 独立于正常范围,包括当应用程序关闭时 最大化或在待处理的边界保存去抖完成之前。面板宽度 保持固定而不是被响应地夹紧。
1. 9 应用程序更新 (D120)
- Electron Main 在打包应用程序后 15 秒检查固定发布源 启动后以及之后每 6 小时一次。开发版本仍然被禁用。 检查器始终跟踪 GitHub 的最新稳定版本 (
allowPrerelease = false),因此安装仍带有预发行版 诸如0.2.0-rc.6之类的版本提供了较新的稳定标签,而不是 保持固定在同一个预发布频道上。 - 设置 → 信息和应用程序菜单检查共享一种类型的更新状态。 手动检查公开最新或错误反馈;自动故障不会 打开 Toast 或环境横幅。
- 手动交付(非 AppImage Linux、Windows ZIP,以及带有
PORTABLE_EXECUTABLE_FILE的旧 Windows 便携版运行)在available停止,并提供固定的 GitHub 发布页面。应用内交付(打包的 macOS、Windows NSIS 和 Linux AppImage)自动推进downloading到稳定的downloaded状态。 downloaded保持可操作状态,直至重新启动更新或正常应用退出; 稍后的 scheduled/manual 检查不会将其替换为checking。- 紧凑的更新通知仅出现在主窗格的右上角安全区域中 适用于手动
available、应用内downloading或downloaded。它保持清晰 每个受支持的窗口大小和草稿高度的底部编辑器。的 通知使用稳定的 icon/title/message 层次结构,显示确定的下载 可用时取得进展,并将相关操作保持在同一状态 表面。解雇会抑制当前版本和状态阶段;稍后downloaded等阶段再次出现。 - 当 Main 附加发现版本的本地化产品说明时 (
UpdateState.releaseNotes,D164),通知和设置→信息更新 行在状态消息下显示紧凑的“新增内容”列表。笔记来了 从产品 UI 选择的已发货语言变更日志目录中获取 — 绝不来自渲染器提供的 提要或远程 URL。缺少目录条目省略了该部分;区域设置更改重新解析注释, 无需新的检查。 - 设置 → 信息在每个更新程序中保留可用的发行说明操作 状态。它在“设置”上打开一个模式,具有完整的本地稳定 变更日志按最新到先的顺序,从同一共享目录本地化。 当前版本和发现的可用版本标识为 紧凑的徽章。列表独立滚动,通过其关闭控制关闭, 转义或背景,并将焦点恢复到调用控件。
- D126 标签版本发布所有平台清单和安装程序。打包的 macOS、Windows NSIS 和 Linux AppImage 使用应用内通道;Linux deb/rpm 和 Windows ZIP 保持通知和链接传递模式。
2. 流消息行为
2. 1 Token渲染
- 令牌在到达时附加到当前助手 MessageBubble 中
- Renderer直接显示运行时流块;它不会排队 第二个 requestAnimationFrame 驱动的打字机状态循环
- 渲染使用增量降价解析 - 不要在每个标记上重新渲染整个消息
- 成绩单核对将完整的历史记录保留在记忆的历史边界中; 令牌更新不会协调 React 中的每个历史行,同时保留 选择、复制、小地图锚点和可访问性的完整历史记录。
- 在当前助手回合内,不含 Task 委派且内容未变化的活动组,也应在文本更新时 保持其记忆化渲染边界。工具消息发生变化时仍须渲染;Task 组仍须接收同一 回合后续生命周期消息带来的状态和完成耗时更新。
- 未完成的
mermaid栅栏仍然是源代码块。其关闭后 栅栏到达,回答散文加载并仅在它出现时渲染图表 接近视口;思维披露总是保留美人鱼的来源。 - 图表渲染失败或保持 20,000 个字符/500 个边的安全限制 源可见且可复制,而不是让助理轮不到。
- 光标指示器:流内容末尾的微妙脉冲重音点或线
- 在第一个助手或工具事件之前,活动回合显示一个紧凑的 具有经过时间的本地化
Working…状态。当运行时报告一段安静 间隔时,同一行会标明:正在开始、等待模型、准备下一次请求、 压缩上下文、补救空回复、重试,或等待委托工作(并带上每个 仍在运行的 Subagent 的粗粒度动作)。已有思考、工具或回答不会隐藏 该行,输出暂停时仍保留底部状态。等待权限、提问或计划/目标批准时 隐藏;回合结束和历史阅读窗口不显示实时状态。 - 当流完成时:光标指示器被成功状态取代(2秒淡出)
2. 2 自动滚动
- 首次打开会话会重置跟随模式,并在浏览器绘制其面板之前把转录 放在它最后一条记录处。揭示一个被保留的面板则改为恢复该面板 自己的跟随状态和偏移:仍然固定的重新锚定到底部,向上滚动过的 回到同一个偏移。两条路径都不会通过历史记录动画,任何面板都 不得暴露转录顶部或另一个会话的滚动位置。
- 首次打开的会话若历史超过初始挂载预算,会在一层不透明的骨架 遮罩下落定(D287)。遮罩与有界首次绘制处于同一次提交,覆盖滚动 区域但不覆盖输入框;只有当滚动区域的
scrollHeight和clientHeight连续三帧读数相同,或达到 600ms 上限时才会揭开。 每个采样帧都会把仍然固定的转录重新贴底,因此遮罩揭开的那一帧 已经位于最新回合。小地图和跳转控件在遮罩揭开后才挂载。短转录 不会显示遮罩。 - 自动滚动到每个新令牌组的底部(限制:每 100 毫秒检查一次,而不是每个令牌)
- 第一次向上手动滚动运动会立即暂停自动滚动,并且 取消任何待处理的跟随帧;小触控板三角洲不得弹回 底部
- 发送新提示、重试或重新生成始终会重新固定跟随模式并在继续转动之前跳转到底部,即使用户已向上滚动
- 手动向上滚动时立即出现“滚动到底部”浮动按钮 释放跟随模式
- 单击“滚动到底部”按钮:恢复自动滚动并捕捉到底部
- 流完成:如果用户自动滚动,则保持在底部;如果是手动,则停留在该位置
- 异步完成的图表高度更新遵循相同的规则: ResizeObserver 在底部保留固定的记录,而拥有 向上滚动保持在其阅读位置。
2. 4 主动回合表面
- 主动转动可保持转录本下表面清晰。直播助手 工具行与记录保持一致;没有通用的理解, 工作卡或检查卡呈现在它们下方。运行中的回合保留一行紧凑底部状态: 优先显示具体运行时阶段,否则显示规划/目标或工作中。已有文字和工具 不会隐藏提示;等待用户操作时隐藏。
- 仅当代理被阻止时,权限卡才保持可见 明确批准。这是可操作的中断,而不是进度状态 卡。
- 后台会话继续,而不将进度镶边添加到可见内容中 会话或移动焦点。因此减少运动没有进度卡 过渡以保存。
2. 5 回合结果结束
- 失败的可见回合会在回合结束后呈现一张会话范围的恢复卡 转录内容。它基于终端代理事件,而不是超时 或猜测的旋转器状态。完成回合不会添加成功卡;他们的 现有的成绩单和消息范围的审查卡仍待完成 证据。
- 失败文案表明现有工作仍然可用。恢复卡只提供一个“继续”操作, 不提供“重新生成”。点击“继续”会把当前语言的继续指令 (
Continue the user's unfinished task./继续用户未完成的任务) 追加到同一会话并开始新一轮,不会截断失败轮次或已完成工作。 - 中止的回合不会呈现失败卡。开始新的回合会清除 上一张卡和后台会话结果保持范围,直到该卡 会话已选择。
2. 3 流中断
- 如果连接中途中断:在部分消息上显示错误状态
- 保留部分消息 - 不删除
- 用户看到“流中断”并带有重试选项
3. 中止正在运行的代理
3. 1 触发方法
- 顶部栏中止按钮(在运行状态下可见)
- 键盘快捷键:
Cmd/Ctrl + .
3. 2 中止行为
- 立即取消当前代理轮次
- 取消任何待处理的权限请求(根据 03-permission-ux.md §7)
- 如果没有开始辅助文本、思考或工具行,则删除刚刚发送的 用户行并恢复其预序列化输入框草稿
- 恢复后的草稿将普通文本和文件参考芯片分开 状态;序列化的规范路径永远不会占用文本区域
- 如果回复已开始,则保留用户回合和部分 assistant/tool 行 处于中止状态并且不恢复任何草稿。保留测量的流 持续时间和使用提供商输出使用情况(如果可用);否则存储一个 明显估计的输出计数,因此对话仍然显示吞吐量
- Composer重新激活(解锁)
- 中止是幂等的——当已经中止时按中止不会执行任何操作
3. 3 中止用户体验
- 中止按钮短暂更改为“正在中止...”(100 毫秒),然后消失
- 没有中止确认对话框——它总是立即发生
- 部分中止的消息会获得静音的“(中止)”后缀。只有 未应答的智能停止分支会删除其刚刚发送的用户行。
3.5 向当前回合补充指令
- Host 入队尚未返回持久化 id 时,排队行操作保持禁用,五个操作均提示正在保存, 立即发送按钮也显示正在保存;编辑和删除不会改变条目或 输入框草稿,确认完成后恢复普通等待行的操作。
- 运行中普通发送和回车发送仍将 follow-up 加入 Host 持久 FIFO。
Alt+Enter将可见 草稿立即提交到当前回合,macOS 对应Option+Enter。开启或关闭回车发送均可使用, 且优先于已打开的自动完成菜单;空闲时正常发送。 Shift+Enter和Alt+Shift+Enter换行。用于确认输入法候选词的 Enter (isComposing或键码 229)从不发送或提交补充指令。- 补充指令作为用户消息出现在当前转录中,立即清空草稿,在当前回复和工具批次完成后 进入下一次模型请求。它不创建 FIFO 行,也不中断工具。
- 提交时捕获会话和当前回合标识。如果目标结束、拒绝输入或正在等待审批,草稿恢复到 原会话并显示简短错误。提交后新输入的文本优先于草稿恢复;当前运行不会被标记失败。
- 文件和图像芯片复用现有附件检查及当前模型能力。排队的配置变更只作用于下一次普通 回合;补充指令保留当前配置,斜杠文本按字面发送,不触发本地模式或扩展命令。
- Stop 保留所有已接收的补充输入。Smart Stop 不移除最新 steering 行,也不会用最初 的提示覆盖它;渲染器重载后仍然如此。持久消息标记是判断依据,渲染器不另存一份 steering 登记状态。
- 发送按钮提示区分 follow-up,并按平台显示补充指令快捷键(macOS 为
⌥+Enter)。 保留现有单个 Send/Stop 按钮位置及 Host 拥有的 follow-up 列表。
3A。上下文检查点生命周期
turn_end标记一个已完成的 model/tool 回合,之后可能会进行另一回合 提供商请求。它永远不会重新启用输入框或会话配置。- 自动上下文保护在每个
turn_end后进行评估并运行 inline:用户等待。该模型也可以通过提前要求new_context,落在同一边界。 compaction_start保持会话运行。阈值和溢出compaction_end事件保留在活动运行中;仅agent_end或error解决了这个问题。仅手动检查点位于compaction_end。- 每次成功的压缩都会显示一个警告提示:早期的细节消失了, 开始新的会话是只有用户才能做出的决定。三个 更具体的 toast 保留在其之上 - 成功的手册
/compact结果、溢出重试之前的警告以及下面的回退警告。 - 如果自动摘要生成失败,但保留尾部检查点 持续存在,
compaction_end.fallback = "retained_tail"显示一个警告 祝酒和积极的运行继续减少历史背景。 - 手动失败显示一个错误 toast。自动 hard/overflow 失败不会 不要用祝酒词重复助理错误;终端错误仍然存在 附加到失败的回合。
- 压缩永远不会删除可见的转录消息。检查点影响 仅未来模型上下文并在会话 switching/restart 中保留。
- 每次压缩都会在记录中添加一个分隔行,紧接在 它涵盖的最后一条消息,读取会话已压缩的次数以及 摘要的估计代币成本(或者没有生成摘要)。行 没有任何操作且不可选择。
- 上下文使用检查器为最新的检查点保留一条静音线, 在面板打开时显示;计数和摘要成本位于紧凑的模型/工具摘要下方, 不再添加解释性文案。
4. 长内容折叠/展开
4. 1 崩溃阈值
| 内容类型 | 默认状态 | 崩溃阈值 | 扩大限制 |
|---|---|---|---|
| 助理降价消息 | 扩展 | 50 行 → 折叠至 20 行可见 | 满 |
| 工具活动输入 | 行倒塌 | 始终落后于披露 | 220px 滚动区域 |
| 工具活动输出 | 行倒塌 | 始终落后于披露 | 220px 滚动区域(根据 D033 主机上限) |
| bash 输出 | 行倒塌 | 始终落后于披露 | 220px 滚动区域 |
| 错误信息 | 扩展 | 不塌陷 | — |
4. 2 折叠指示器
- 工具活动以轻量的收起条目开始。失败和被拒调用在行标题中保留问题状态,载荷不会 自动展开。
- 两种模式都为每个已加载的助手回合提供一个整体过程披露,其中包含思考、工具、托管 搜索和中间进度文字;末尾回答、助手错误和中止后的末尾文字位于过程之外。
- 连续活动片段仅在当前模式下至少有两个可见项时获得组披露。进度文字结束该片段, 单项活动直接使用自身披露,紧凑模式隐藏的思考不会制造多余组;Task 拓扑保持独立。
- 详细模式下,活动中和已完成的整体过程默认展开。活动普通组默认展开,完成时仅在用户 未操作的情况下收起;其他已完成组默认收起。紧凑模式下过程与组默认收起,但活动回合 只要记录过失败或被拒工具,未接管的外层过程会在恢复期间保持展开,并在完成后收起。
- 详细模式仅在最后一个活动组的字面最后一项是符合条件的工具调用或托管搜索时自动 展开该叶子。失败/被拒项保持收起;最后一项是思考时不会向前查找工具。紧凑模式保持 所有条目载荷关闭,隐藏推理正文与摘要,只保留活动思考指示器。
- 激活过程、组或条目标题只切换该层级。收起父级会保留子级状态,重新展开时恢复, 同级组彼此独立;展开父级不是“全部展开”。
- 手动操作条目会把所属组和过程标记为用户接管,但不会切换祖先。流式更新和完成不会 重新打开手动收起,也不会收起包含用户已展开、聚焦或选中内容的容器。只要保留会话 窗格仍存在,选择就跨模式切换、单项变组和重新挂载保留。
- 搜索和导航只打开拥有目标消息的过程与活动组,每个显示请求仅应用一次;条目级精确定位不在本次范围内。紧凑模式中的推理需要显式切换到详细;关闭搜索不会收起已显示路径。
- 待处理权限、提问、计划/目标审批及其他操作卡位于隐藏过程之外,始终可达。
- 每个披露使用独立按钮、
aria-expanded和aria-controls;收起的后代离开 Tab 与 无障碍遍历顺序。减少动态效果会禁用非必要标记和 V 形动画。
4. 3 工具结果截断
- 根据 D306 / D194:预算按工具类别计算(见 16-tool-result-limits)。搜索/读取结果上限为 128KB / 4000 行;Bash stdout/stderr 上限为 96KB / 4000 行并带溢出文件。
- Read/Glob/Grep 仅在本次结果被切断时报告
truncated: true(预算、被剪行,或 Grep/Glob 还有剩余命中)。填满的 Read 窗口即使文件更长也不算截断;notice写出下一个偏移。 - Bash 标记标明哪一端幸存以及溢出路径,例如
[truncated: kept the first 4000 of 51234 lines; limit 4000 lines / 96KB. …]。 - 截断的内容永远不会被默默地省略——总是被标记
- 披露扩展不会加载超出主机强制上限的内容
- 折叠行的
truncated芯片跟随details.truncated
5. 权限中断流程
5. 1 流程顺序
Agent calls a permission-gated tool (including Plan/Goal Bash under Ask or Accept edits)
→ PermissionCard inserted inline in transcript
→ Composer disabled (cannot send new prompt)
→ Countdown starts (120s)
→ User responds: Allow once / Allow session / Deny
→ Card transitions to resolved state
→ Composer re-enabled
→ Agent continues or receives denial result5. 2 多个待处理权限
- 每个会话最多有一张活动权限卡,因为该代理会循环 已暂停;多个会话可以独立等待。
- 中止仅取消活动会话的待处理权限。
- 超时(从原始接收开始 120 秒)仅自动拒绝匹配的请求; 切换会话永远不会重置截止日期。
5. 3 权限期间的焦点管理
- 通过
aria-live公布可见的权限卡,无需强制 焦点。后台会话的卡未安装并且无法移动焦点。 - 卡片内的操作按钮可通过选项卡访问
- 解决后:焦点返回到输入框
- 完整规范:03-permission-ux.md
5A。 Plan 和 Goal 工作流程
- 用户在会话空闲时选择 Plan 或 Goal,或相同的 Agent 调用
EnterPlanMode/EnterGoalMode;主机 persists/validates 匹配合约模式和渲染器项目planning。 - Agent 使用选定的合约工具集进行调查。 Read/Glob/Grep 和 允许使用 BrowserPreview; Bash 遵循可见权限模式。一个 Contract-mode Bash 命令可能会在 Auto 下发生变化,因此模式芯片仍然可见。 该回合处于实时
planning时,Composer 模式芯片脉冲,紧凑的规划行占用与 Working 相同的预留底部位置,直到回合结束或等待用户操作。具体运行时阶段优先,工具和回答不会隐藏运行提示。 - Agent 在其工具批次中单独调用
SubmitPlan或SubmitGoal。 Host-core 将准确的 Markdown 字节保留在新的不可变中.pi/plan/*.md或.pi/goal/*.md工件,记录其 path/hash/size 并结构化 title/question,渲染器显示共享合同审批卡 只有标题和神器开启器;问题仍然是主机端合同数据。 打开器在该视图可启动时把这一路径交给内置文件视图,否则交给宿主机文件标签, 因此工件会在对话旁、与用户其它项目文件相同的视图中打开(D452)。 - 批准需要询问/接受编辑/自动选择。渲染器会记住 该设备上最后选择的模式并将其用作下一个批准的模式 默认。 Host-core提交批准,
mode = agent,权限模式, 和queued原子状态;同样的 Agent 继续新的回合 Agent 工具。 5.拒绝停止挂起的运行并将持久会话保留在其合同中 模式。实时状态恢复为可编辑规划;修订是新的SubmitPlan/SubmitGoal使用新的完整 Markdown 快照和新工件进行调用。早期快照 保持不变;没有请求更改操作。 - 过期、中止、持久性失败、renderer/host/sidecar 崩溃或过时 响应呈现失败关闭状态。主机重启中断挂起, 排队、运行且无需重播的工作;已经批准的中断 将会话保留在 Agent 中。
批准卡是会话范围的。后台会话可能会保留待处理的 plan_approvals 中批准或 queued/running 执行状态,但打开 另一场会议从未涵盖它或转移焦点;回到原点 会话恢复渲染器生命周期快照;当宿主还活着的时候, plans.pending 可以对仍待处理的行进行补充。审批卡没有 公开 validity/deadline 概念。 Mode/provider/model/permission/shell 配置和新提示仍然存在 当存在有效的 pending 批准或轮次时禁用。待处理期间 批准现有草案保留在文本区域中,但为只读;仅 批准和拒绝在批准界面上保持启用状态。拒绝、过期或 中断可以重新启用它们;终端提案快照不保留门 关闭。渲染器保留每个会话的最新 checkpoint/execution 状态 仅适用于其当前生命周期,因此被拒绝、过期、中断、批准, 排队,并且运行结果可能在会话切换期间保持可见。一个 渲染器重新加载仅重新水化挂起的行;终端卡掉落并且 没有恢复。主机重启会中断之前的工作而不会重播或过时 动作,并且UI不需要呈现被中断的终端 快照。 Composer 左侧的 Agent/Plan/Goal 芯片是唯一的活动会话模式 控制。
在项目或会话初始化期间,家庭输入框可以在之前渲染 预计 activeSessionId。空闲模式、思考和许可 控制装置在该时间间隔内仍然可用;他们的第一个配置操作 保留在未持久化的草稿上,并在第一条消息创建会话时应用 (D220)。因此,新任务在包含输入之前不会添加侧边栏历史记录行。跑步 轮流和待批准继续限制控制。
6. Toast 与内联错误
6. 1 Toast 通知(用于)
| 场景 | Toast类型 | 持续时间 | 基本原理 |
|---|---|---|---|
| 提供商连接测试结果 | Success/Error | 4s/8s | 瞬时反馈,不阻塞工作流程 |
| 插件load/unload成功 | 成功 | 4秒 | 确认后台操作 |
| 设置已保存 | 成功 | 4秒 | 快速确认 |
| 手动菜单更新检查失败 | 错误 | 8秒 | 对明确命令的直接反馈 |
| 上下文检查点已完成 | 信息(溢出重试前警告) | 4s/8s | 确认后台上下文转换而不更改转录本行 |
| 手动上下文检查点失败 | 错误 | 8秒 | 直接反馈明确的 /compact;自动终端故障保持内联 |
6. 2 内联错误(用于)
| 场景 | 内联放置 | 基本原理 |
|---|---|---|
| 工具调用失败 | ToolCallCard 上的错误状态 | 上下文相关,用户需要查看哪个工具失败了 |
| 拒绝许可 | PermissionCard 上的已解决状态 | 已经内联,对话流程的一部分 |
| 串流中断 | MessageBubble 上的错误状态 | 属于失败的消息 |
| Provider/model 回合失败 | 抄本中的助理错误消息 | 保留失败回合的摘要、稳定代码、经过编辑的详细信息和恢复操作 |
| 提供商配置验证错误 | 内联设置表单 | 用户需要查看哪个字段是错误的 |
| 应用程序更新 status/error | 设置 → 信息更新行 | 保留最新的 Main-owned 状态而不中断背景检查 |
| 输入框验证(无模型) | 禁用状态+发送按钮上的工具提示 | 直接上下文 |
6. 3 规则
- 切勿对与特定消息或工具调用相关的错误使用 toast
- 助手错误详细信息使用键盘可操作的披露
aria-expanded/aria-controls;它在第一次渲染时打开,因此提供商 响应可立即发现,并支持复制编辑文本 - 切勿将内联错误用于瞬态后台操作(插件加载、连接测试)
- Toast 垂直堆叠,最新的位于顶部中央
- 错误 toast 需要手动关闭或超时 8 秒(比成功长)
- 成功祝酒在 4 秒后自动关闭
7. 焦点管理
7. 1 将流程聚焦于页面加载
- Composer 文本区域在主聊天视图中获得初始焦点
- 设置页面:第一个交互元素获得焦点 3.命令面板:搜索输入获得焦点打开
7. 2 操作后的焦点流程
| 行动 | 聚焦目标 |
|---|---|
| 新会话已创建 | 输入框文本区域 |
| 会话已切换 | 输入框文本区域 |
| 消息已发送 | 输入框文本区域(已清除,准备下一步) |
| 直播已完成 | Composer 文本区域(重新启用) |
| 权限已解决 | 输入框文本区域 |
| 中止完成 | 输入框文本区域 |
| 命令面板关闭 | 先前聚焦的元素 |
| 对话框关闭 | 先前聚焦的元素 |
| 使用 Escape 关闭通知弹出窗口 | 通知铃声 |
| 通知 row/native 通知已激活 | 加载脚本后激活会话编辑器 |
7. 3 焦点陷阱
- 命令调色板:打开时焦点被困在调色板内
- 设置模式:焦点被困
- 逃脱总是关闭被困表面并返回焦点
7. 4 对焦环规则
- 仅在
focus-visible(键盘焦点)上显示对焦环,在 click/mouse 焦点上不显示对焦环 - 聚焦环:2px 强调色边框,距元素边缘 2px 偏移
- 根据 07-ui-design-system.md §6.4
- 切勿全局移除对焦环 - 可访问性要求
7. 5 文本选择
- 默认情况下,应用程序镶边是不可选择的,以防止意外 单击或拖动外壳时进行选择。
- 可编辑控件(
input、textarea、select和[contenteditable]) 保留正常文本编辑和Cmd/Ctrl+A/C/V行为。 - 转录散文、渲染的 Markdown、代码块和工具 input/output 保持文本可选择以供检查和复制。
- 保留嵌套在可选内容内的交互式控件 不可选择,并且必须保持其单击和键盘行为。
- 选择规则不得禁用
focus-visible反馈或本机窗口 拖动区域。
8. 拖/放
8. 1 MVP 状态
工作面板宽度调整是在 MVP 中实现的:
10px 左边缘分隔符锚定到按下位置和起始宽度,然后跟随指针 delta 而不跳转。向左拖动会持续增长面板,直到共享预算耗尽;MainChat 到达 450px 下限时展开的左栏立即收起。向右拖动把空间还给 MainChat。
分隔线目标钳制在三栏共享预算内(
客户端宽度 − 450px − 展开的左栏宽度,无固定像素上限)。指针移动是帧合并的。指针释放持续一提交 首选宽度;转义、指针取消和丢失捕获都会回滚。
打开和关闭码头的
width和flex-basis以及 有界 opacity/transform 反馈,因此 MainChat 不断回流 而不是在第一个运动帧之前更改宽度。渲染器始终请求本机预留宽度为 0,因此操作系统窗口 永不扩展 (ADR 0033)。打开、折叠和最终关闭仅改变 承诺的首选宽度。重复目标是幂等的。
当面板弹性分配打开时,MainChat 会持续回流或 关闭,然后保持在设定的客户端宽度;窗口没有变化。 在支持的固定窗口范围内,MainChat 保持 450px 硬下限;展开的左栏会在 阈值处让位,而不会把聊天压到该下限以下。
本机窗口和侧边栏调整大小不会夹紧或重写面板。原生边缘和角落仅通过 回流调整 MainChat 的大小。操作系统保留原生命中区域所有权;恢复逻辑会 等待 300ms 的稳定边界窗口,状态持久化会在最后一次调整大小/移动事件 后等待 600ms,因此不会干扰慢速边缘拖动或保存中间矩形。
Maximized/fullscreen 不受影响; display/work-area 更改协调 窗口边界正常。在一个不变的工作区域内进行普通移动不会 不重新应用几何图形。持久的基边界是用户的窗口大小 (预订始终为 0)。
后台会话工件永远不会更新可见面板。
Preview mode unmounts MainChat and fills the client area beside the sidebar. The 46px chrome row keeps shell/native controls but declares neither drag nor no-drag across the panel and passes pointer events through outside controls. The panel header alone owns dragging in the preview pane; its border box excludes shell actions plus an 8px gap in both sidebar states on all platforms. The left inset is 8px except collapsed-sidebar windowed macOS (88px through
--ds-window-lead-inset: the 76px native cluster edge from@pi-desktop/sharedplus a 12px gap). Native clicks must operate controls and empty-header drags must move the window; DOM/CDP clicks alone are not native hit-test proof.
展开侧边栏固定为 275px。折叠/展开只改变列是否存在;历史上的调整大小手柄 会隐藏,旧的宽度偏好不会继续持久化。
保留的项目组支持项目排序。没有重排手柄。按住项目标题并移动 8px 开始拖动,因此单击仍会激活并切换折叠,菜单和嵌套会话行保持原有点击行为。根据指针位于目标上半部还是下半部,放置会插入目标之前或之后,并持久化结果。
- 文件拖入输入框仍未处理;剪贴板 file/image 粘贴 使用下面的会话临时参考流程
8. 2 项目拖放合同
项目拖放遵循以下模式:
- 项目标题是重排控件:按住并移动 8px 开始拖动
- 没有足够移动的单击仍会选中并切换折叠
- 触摸不会开始重排,以便列表可以滚动
- 强调色插入线标出前/后放置位置
- 使用 Esc 键取消拖动
- 拖动反馈:源上不透明度 0.5
- 聚焦标题后按
ArrowUp/ArrowDown可移动项目并持久化相同的手动顺序
8a。输入框自动完成和剪贴板文件(D123–D125、D197、D209、D262、D362、ADR 0131)
8a.1 触发器
/仅当它是输入的第一个字符时才打开命令模式 并且光标仍在第一个标记内(尚未输入空格)。 命令名称后的空格关闭菜单;参数是自由文本。- 当包含光标的标记以
@开头时,@打开文件模式@之前的字符是输入开始、空格或其中之一 pi 分隔符("、'、=)。查询是@和 光标;包含/的查询跨路径段匹配。引用了一个 代币 (@"…) 在收盘报价之前被视为一种代币。 - 粘贴文本永远不会打开菜单,除非插入符号落在有效的区域内 触发令牌。
- 文件结果通过仅渲染叶名称(带有 目录尾随
/)。完整的相对路径仍然可用 行工具提示和可访问的名称。接受文件(Enter/Tab/点击) 会把@标记替换为光标处的行内哨兵叶名芯片,由完整的entry.path支持;该确认不会发送。接受目录保留 草稿中的完整文字路径,以便可以继续进行更深入的补全。
8a.2 参考芯片和剪贴板文件
- 仅当全部文件都是无原生路径的
image/*副本时,非空白text/plain正文优先(Word 文本选择)。真实文件、任意非图片文件、纯图片及空白文字加 图片的粘贴仍走附件流程。只复用已有 preload 文件路径解析,不重新读取系统剪贴板。 - 选中的正文不超过持久化的
largePasteThreshold(默认 600)时保持可编辑; 超过阈值时转为会话临时文件引用。短多行文本保留空行、末尾换行、前后正文、 光标及原生撤销;CRLF/CR 转为编辑器 LF。HTML 字面量仍为文本,只插入经过 转义的正文和生成的换行。 - 传输字节时,文本区域是只读的并公开
aria-busy="true";发送和自动完成控件被禁用。 - Electron main 在原始会话的暂存下保存有界字节 root 并返回唯一的绝对路径以及经过清理的原始叶名称。 输入框保持可见文本不变,附加叶子名称参考 按剪贴板顺序排列,然后恢复文本区域选择和焦点。
- 对于超过阈值的纯文本粘贴,渲染器通过相同的会话桥发送准确的 UTF-8
text/plain字节,在原始选择处插入由哨兵支持的pasted-text-*.txt芯片,并在草稿中 保存标记到规范路径的映射。点击芯片或按 Enter/Space 会读取有界文本文件,在原位置 以可编辑文本替换哨兵、移除引用并将插入符号放在内容末尾;读取失败或不支持时保留 芯片。在草稿中间粘贴时,前缀和后缀都保持不变。 - 如果家庭输入框没有活动会话,它会创建或重用之前的会话 写作。失败会使现有草稿保持不变并显示错误 正常的Toast表面。
- 芯片删除按钮仅删除草稿参考并恢复文本区域 焦点;它不会急切地删除会话临时字节。退格键 空文本区域会删除最近的活动引用。
text/plain或.txt芯片公开按钮语义,并在点击或按 Enter/Space 时展开。 读取遵循现有fsRead有界策略;二进制、图像、过大或读取失败时显示普通错误 提示并保留芯片。- 仅供参考的草稿启用发送。在发送之前,有效的参考文献是 附加在可见文本之后并使用规范相对或序列化 绝对路径和现有的空白引用。成功发送清除 两者;失败或拒绝的派送保留两者。内联大段粘贴引用会在可见草稿中解析,而不会 追加或作为重复附件发送。引用是会话范围的;只要所属会话仍可用,临时引用可以 跨工作区切换保留。工作区
@芯片相对于产生它们的项目,切换工作区时会从草稿中移除(含哨兵)。 - 接受的调度保留内存中的 session/turn-scoped 副本 仅在未答复时显示可见文本和结构化参考 智能停止可以 撤消发送。该撤消操作将恢复原始芯片顺序和标签;它 从不解析序列化的
@path文本。一旦回复内容开始,中止就会继续 部分抄本,不恢复草稿。 - 发送成功后,用户气泡仅把这些序列化的
@path标记解析回与输入框一致的叶子名芯片用于展示。持久化消息和模型上下文仍是规范@path文本。点击芯片先经pi-desktop/fs/resolveRef补全引用——该通道搜索整个打开的项目,按项目组自身的文件夹顺序、主文件夹优先(ADR 0263)——再按解析结果打开:项目文件在随应用打包的pi.file-manager工作面板视图中打开(该视图不可用时退回宿主file:选项卡),会话临时目录或附件文件在宿主file:选项卡中打开,项目主文件夹中的.html/.htm页面仍在侧边浏览器中打开,因为侧边浏览器本就以该文件夹为根。交给工作面板的地址跟随应答的文件夹:主文件夹中的文件按项目内相对路径传递,同一项目的同级文件夹中的文件按绝对路径传递,与会话临时目录或附件文件一致。什么都没匹配到的芯片不打开任何东西,而是自己报告出来;系统默认应用不再由这次点击触发,该动作仍可从文件视图自己的右键菜单使用。
8a.3 打开时的键盘
- ↑/↓ 以环绕方式移动突出显示; Home/End 留在文本区域。
- Enter / Tab 接受突出显示的项目;Alt+Enter 提交当前回合补充指令。菜单有高亮项时 Enter 和 Cmd/Ctrl+Enter 都不发送 (该规则先于回车发送设置)。 否则保持其行为)。
- Escape 仅关闭菜单 - 它优先于输入框的菜单 “清除输入或模糊”转义并且不得传播到覆盖处理程序。
- 任何其他适当的打字重新过滤器;零匹配表现为闭合。
8a.4 IME(第一规范IME规则)
- 所有自动完成按键处理均位于标准防护装置后面 (
isComposing || keyCode === 229)。 - 在主动合成期间,触发检测器既不打开、更新, 也不关闭菜单;状态重新评估
compositionend。 - 输入确认 IME 候选者从不发送且从不接受菜单 项目;候选导航期间的 ↑/↓ 属于 IME。
8a.5 关闭和聚焦规则
- 关闭:鼠标按下之外、文本区域模糊、删除过去的触发器 字符、会话或工作区切换,接受项目(
@dir/除外) 延续,这使菜单在更深层次的查询上保持打开状态)。 - 在菜单的整个生命周期中焦点保持在文本区域(输入保留 覆盖);菜单永远不会成为焦点陷阱,也不会抢走插入符号。
9. 滚动行为
9. 1 脚本滚动
- 默认:固定时在流中自动滚动到新内容的底部
- 第一次向上滚动会暂停自动滚动并显示 “↓滚动到底部”按钮;排队流或调整大小跟随工作不得 扭转该运动
- 固定的转录在内容或视口尺寸变化的同一帧内重新贴底,绝不延后一帧。 这包括输入框因多行草稿而变高:底部预留是转录内容上的 padding, 因此按 border-box 观察内容,让最新回合随输入框一起上移,而不是 滑到输入框后面(D287)。
- 手动切换整个过程、活动组、工具/搜索/思考条目、委派摘要或错误详情时,由所属滚动器 保持阅读位置(issue #324)。只有发起切换的层级声明滚动锚点;把祖先标记为用户接管 不会同时声明祖先位置。状态变化前先把标题交给滚动器,并在高度变化的每一帧恢复其 视口偏移。嵌套滚动器(委派运行停靠区,D302)保持自身位置,并因外层内容同时增长而 向外传递保持。
- 收起父级不会重置已保留子级的披露或阅读状态。搜索显示会展开所需祖先,并以精确目标
- 收起父级不会重置已保留子级的披露或阅读状态。搜索显示会按消息级精度展开所需祖先,并以该目标 新回合或导航释放保持前,转录停留在用户阅读位置并显示“回到最新”(D430)。
- 用户发送/重试/重新生成:重新固定,隐藏跳转控件,并将最新内容放置在布局阶段,以便新的回合可见,而无需历史记录顶部的闪烁;后续的持久化行和流式传输行继续遵循底部
- 滚动到底部按钮:位置固定在转录区域的右下角,偏移 12px
- 向上滚动释放跟随模式后按钮立即出现
- 单击按钮:滚动到底部,恢复自动滚动
- 按钮在底部时消失
- 展开后的委托运行过程的
.subagent-run-rows滚动区独立使用同一契约(D302): 展开时钉在最新输出,钉住时新的嵌套行把视口留在底部;第一次向上手势暂停跟随 并显示嵌套的「回到最新」控件;布局夹持或程序性的 followscrollTo不会解除 跟随。该滚动区关闭原生 overflow anchoring。
9. 1a 侧边栏项目路径和打开文件夹
- 悬停或聚焦保留的项目标题会显示完整的绝对路径。
- 截断的项目名称在行中仍然可见;完整路径是 仅 tooltip/accessible-description 并且从不强制水平滚动。
- 右键单击项目行或打开其溢出菜单会显示 Open 文件夹作为项目操作。对话溢出不再带有该内容 行动。
- 选择打开文件夹打开系统文件中的项目目录 管理器而不更改活动会话记录。
9.1c 侧边栏行状态与操作
- 项目标题与项目、置顶、独立会话行共享整行悬停背景、圆角和过渡。 标题按钮透明,不叠加内层背景;已选中会话在悬停时保持选中背景。
- 当前工作区仅通过项目圆点表达,不再使用另一份选中背景。折叠选中会话 的分组、离开聊天页或没有选中会话,都不会让项目标题成为选中导航项。
- 键盘焦点保留独立轮廓;新建和更多操作按钮保留局部悬停反馈;拖拽目标 提示优先于普通悬停背景。
- 窗口失焦时释放悬停背景和操作显露,不清除当前会话选中背景。
9. 2 侧边栏滚动
- 独立的会话主体有五个紧凑的行和卷轴 当存在附加会话时在内部。
- 保留的项目组占据剩余的侧边栏高度并滚动 单独的区域。这两个区域都独立于页脚和主要区域 导航。
- 侧边栏没有水平滚动
- 滚动指示器使用平台的微妙覆盖处理,无需 改变任一区域的宽度。
9. 3 设置滚动
- 设置内容在主区域内独立滚动
- 左侧导航(设置部分)是粘性的,不滚动
10. 减少运动
10. 1 政策
所有动画都必须遵循 prefers-reduced-motion: reduce:
- **抑制:**流脉冲、expand/collapse 转换、下拉幻灯片、悬停颜色转换
- **保持(即时):**状态变化仍然发生(卡状态变化,加载→完成)但没有过渡持续时间
- 切勿移除: 对焦环、状态颜色、布局定位 - 这些是结构性的,而不是装饰性的
10. 2 实施
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}这并不能阻止状态改变——它使状态改变变得即时。
10. 3 本文档中受影响的模式
| 图案 | 正常 | 减少运动 |
|---|---|---|
| 流脉冲 | 左边框上的重音脉冲 | 静态重音边框(无脉冲) |
| 工具卡 expand/collapse | 200ms 过渡 | 即时切换 |
| 悬停状态转换 | 150ms背景变化 | 瞬间变色 |
| 启动水花 | 品牌启动 + 进度,最短停留时间然后淡出 | 即时静态飞溅,无条形运动,即时显示 |
| 对话框/搜索输入 | 通过运动令牌覆盖-in + 表面-in | 接近零持续时间输入 |
| 滚动到底部按钮淡入 | 150ms 不透明度 | 即时出现 |
| Toast滑入式 | 200毫秒幻灯片 | 即时出现 |
| Modal/dialog 输入 | 300ms 淡入淡出+缩放 | 即时出现 |
| 通知弹出框输入 | menu-scale/fade 代币 | 即时出现 |
10. 4 编程滚动
- 会话激活使用立即布局阶段底部位置,因此 第一个可见帧已经稳定在最新记录。
- 跳转到最新和小地图导航仅在操作系统时才使用平滑滚动 没有请求减少运动。
- 启动跟随使用立即布局阶段更新,然后 帧合并即时跟随;它不会开始重叠平滑滚动 令牌组的动画。
- 手动向上移动会先取消排队的固定跟随帧 恢复之前的底部位置。关注跨内容发布的内容 增长,直到视口向下滚动到底部或底部 48px 以内 显式的启动/跳转到最新操作会重新固定它。
- Resize 观察者绝不在回调中同步测量每一行转录。回调里唯一允许的 同步动作是对固定且可见的转录做一次贴底(单个
scrollTo),因为 在回调中申请的帧会落在当前帧之后,而当前帧已经把变高的内容以未 贴底的状态绘制出来了(D287)。
11. 验收标准
- §1中的所有键盘快捷键均有效且不与系统快捷键冲突
- 开启回车发送时 Enter 发送;关闭后 Cmd/Ctrl+Enter 发送,Enter/Shift+Enter 在输入框中插入换行符
- Abort 立即取消正在运行的回合和挂起的权限,无需确认对话框 4.长内容(>50行消息,>10行参数,>20行结果)默认通过展开链接折叠
- 被切断的工具结果按 D306 显示截断标记或芯片;更长文件上已填满的 Read 窗口不显示 6.权限中断插入内联卡,禁用composer,显示倒计时,解决后重新启用
- 用于短暂后台操作的Toast;用于特定于上下文的失败的内联错误
- 会话切换、消息发送、权限解析、中止后焦点返回到composer 9.后台消息、工具、完成、权限事件永不改变 活动的 session/project/page 或键盘焦点;并发许可 请求在其原始记录中保持独立可操作性, 和后台工件仅更新其会话保留的工作面板 上下文 9a.创建新会话或切换到非运行会话返回 即使另一个会话仍然处于空闲状态,composer 也会恢复到其空闲发送状态 流式传输;目标会话自己的运行状态单独决定 send/abort 按钮
- 聚焦环仅在
focus-visible上可见,2px 重音偏移 2px 11.命令面板捕获焦点;逃脱回到之前的焦点 - 所有动画均遵循
prefers-reduced-motion: reduce— 状态变化是即时的,没有装饰性动作 13.Project/session行支持无损pin/archive,独立 项目折叠、项目拖动/手动重排,以及记录的面向用户的排序模式 - Shell chrome 不会创建意外的文本选择,同时可编辑 控件和 transcript/code/tool 内容保持可选择和可复制
- 保留的项目选项卡在重启后仍然有效;激活其中一项会更改所选内容 不重定向后台会话工具根的 shell 工作区
- 项目组可通过拖动标题或标题上的
ArrowUp/ArrowDown重排; 规范化路径顺序会跨渲染器重启保留,且不会改变主机工作区身份 - 已完成和失败的回合在持久收件箱中仅出现一次; 中止的回合永远不会出现
- All/Unread、标记为全读、清除、行激活、Escape/focus 恢复以及 arrow/Home/End 键盘导航的行为如 §1.7 中所述
- 本机任务通知仅在主窗口未聚焦。交互询问通知只抑制聚焦的当前会话, 可以为聚焦的其他会话出现;激活通知会聚焦窗口并打开相应的会话
- 流式消息更新保持在聊天渲染边界内;外壳 导航、编辑器、已完成的行和工作面板内容不会重新呈现 仅仅因为当前助手消息附加了内容
- 本机窗口边缘调整大小通过回流更改 MainChat,而不压缩 固定工作面板;分隔符提交更新提交的首选宽度, 而分隔线取消恢复之前的宽度(ADR 0033)