04. E2E 测试 Plan
翻译说明: 本页是与 英文源规格 一一对应的机器辅助翻译。代码、协议字段和标识符保持原文;如翻译与英文源事实有歧义,以英文版本为准。
范围:MVP 接受场景加上 PI-Desktop 当前发货的产品增量 状态:已接受(protocol/Electron 自动化已激活;完整桌面 Playwright 仍在计划中) 交叉引用:验收标准 · 里程碑 · ai-开发工作流程 · 变更清单
1. 目标
- 记录 MVP 必须验证的每个用户可见和协议可见的行为。
- 提供映射到验收标准 (A–H) 和里程碑 (M1–M6) 的场景目录。
- 作为可追溯性主干:场景 ID ↔ 验收标准 ↔ 规范。
- 为未来的自动化做好准备,无需立即实施。
2. 非目标
- 完全由UI驱动的自动化覆盖;协议和源合同自动化是 仍在计划中,而更广泛的桌面套件仍在计划中。
- 性能/压力测试(后 MVP)。
- 原生 Windows/Linux 发布资格(已发布的工件存在;原生 资格差距仍然记录在案)。
- 市场发行商来源和恶意插件沙箱场景;基本的 browse/install/update 流已成为目录的一部分。
- 远程网关/控制平面场景(后 MVP — ADR 0004 / 基线 #20)。
3. 测试金字塔
╱ E2E ╲ — few, high-value, cross-system
╱ Integration ╲ — IPC/RPC contracts, host↔renderer
╱ Unit ╲ — per-module, fast, isolated| 级别 | 适用范围 | 计数目标 | 工装 |
|---|---|---|---|
| 单位 | 单模块,无 IPC | 很多 | Vitest / Rust#[测试] |
| 整合 | IPC 合约,主机↔渲染器,主机↔sidecar | 中等 | Vitest + IPC 模拟或现场 Electron |
| E2E | 桌面应用程序的完整用户旅程 | 100 多个功能+ US-UI 视觉目录 | 现在协议烟雾 + Electron 探针;后来成为剧作家 |
策略:立即记录所有 E2E 场景;添加或更新 unit/integration 当变更风险需要时,与代码一起进行测试;自动化 E2E 之后 M5。
4. 工具意图
| 工具 | 目的 | 状态 |
|---|---|---|
| 维斯特 | 单元+集成(TS侧) | 活动(pnpm test,共享包) |
| Rust #[测试] | 主机核心单元测试 | 活跃(cargo test -p host-core) |
| 协议烟雾 | 主机 RPC + 工具 + 无头插件 | 有效(test:e2e,20 次检查) |
| Electron 探针 | 启动桥+崩溃监控 | 活跃(test:e2e:boot、test:e2e:supervision) |
| 剧作家 | 完整的 UI 驱动旅程 | 计划(M5 之后) |
决策:立即记录场景;当代码准备好进行 M5 硬化时,选择具体的 E2E 流道。
5. 环境要求
| 要求 | 详情 |
|---|---|
| 平台 | macOS arm64、Windows x64 和 Linux x64 发行目标 (D126) |
| 公司简介 | 干净的 ~/.pi-desktop 配置文件(无需事先配置) |
| 固定装置 | 示例项目目录 (examples/fixtures/sample-project/) |
| 示例插件 | 从本地路径加载 examples/plugins/hello |
| 提供商 | 至少一个拥有有效密钥的提供商(测试帐户) |
| 显示 | 无头功能 Electron 或真实显示 |
6. 场景模板
每个场景都以这种格式记录:
markdown
### E2E-<ID>: <title>
- **Preconditions**: what must be true before steps start
- **Steps**: ordered list of user / system actions
- **Expected**: observable outcome that proves correctness
- **Specs linked**: relevant spec file(s)
- **Acceptance criterion**: which A–H letter(s) this verifies
- **Milestone**: M1–M6 target
- **Status**: Draft | Documented | Partially automated | Automated | Passed7. MVP 场景目录
运行时资源治理
E2E-097:工具爆发受到限制,主机重启后恢复
- 先决条件:主机核心健康;一个会话有一个工作区;的 监督探针可以终止主机进程。
- 步骤:1) 调度比主机工具预算更大的突发,其中包含 读取工具和 shell 命令。 2) 突发运行时观察
app.health。 3) 在活动呼叫期间终止 host-core。 4)等待一位监督者 重新启动。 5) 冲洗持久性发件箱。 - 预期:活动 shell 进程永远不会超过配置的全局和 每个会话的限制。多余的工作返回
HOST_OVERLOADED或在 有界队列。仅运行一个重启循环;过时的一代调用很快就会失败 作为HOST_UNAVAILABLE;无重复ERR_STREAM_DESTROYED持久风暴 被发射。同一突发期间的临时操作系统线程压力不会 通过其 stdio 控制路径终止 host-core;主机仍保留在一台上 发电和容量错误保持结构化。已完成 assistant/tool 恢复后消息将保留一次。 - 链接规格:
03-runtime/06-host-rpc-protocol.md,03-runtime/07-process-model.md、03-runtime/08-error-codes.md、03-runtime/09-logging-and-observability.md、ADR 0051 - 验收:A(运行时运行状况)、C(工具执行和恢复)
- 里程碑:M5
- 状态:已记录;自动化待定
启动和健康检查
E2E-001:应用程序启动并显示主窗口
- 先决条件:macOS arm64;没有先前的
~/.pi-desktop配置文件。对于 开发通道、工作区包构建输出不存在或早于 他们的 TypeScript 来源。 - 步骤:1) 启动 PI-Desktop。在开发通道中,使用
pnpm dev。 2) 观察主窗口出现。 - 预期:开发启动之前会重建所有工作区依赖项 host-core 和 Electron 启动。窗口首先显示品牌启动画面 当 bootstrap 运行时,然后用当前的英文显示主 shell 语言环境目录;没有编译错误、缺少菜单运行时错误或崩溃; 版本信息可见。
- 链接规格:
03-runtime/07-process-model.md、04-ux/01-ui-ia.md - 接受:A(应用程序启动)
- 里程碑:M1
- 状态:部分自动化(
runtime-build-contract.test.mjs涵盖 依赖构建合约; Electron 窗口启动仍处于草案状态)
E2E-002:IPC 桥功能正常
- 前提条件:应用程序正在运行。
- 步骤: 1) 触发调用 preload IPC 的操作(例如版本查询)。 2)观察渲染器中的结果。
- 预期:Main↔渲染器 IPC 返回预期数据;没有错误。
- 链接规格:
03-runtime/01-ipc-protocol.md - 验收:A(桥梁正常)
- 里程碑:M1
- 状态:自动化(
scripts/e2e-electron-boot.mjs— 沙盒 preload 桥 + IPC 往返)
E2E-003:Rust 主机运行状况检查响应
- 前提条件:应用程序正在运行; Rust host-core sidecar 已启动。
- 步骤:1) 使用协议版本 9 进行 Electron 握手。 2) 呼叫主机 健康检查 RPC。 3) 使用不匹配的旧协议和新协议重复启动 固定装置。
- 预期:协议 v9 主机返回
ok并记录握手。 除 v9 之外的所有版本,无论较旧还是较新,都会在 对话界面变为交互式,因此 Plan approval/state 事件和 上下文检查点不能悄无声息地丢失。 - 链接规格:
03-runtime/05-host-core-rust.md、03-runtime/06-host-rpc-protocol.md - 验收:A(桥梁正常)
- 里程碑:M1
- 状态:自动(协议烟雾)
E2E-004:出现首次运行内联检查表
- 先决条件:新鲜的配置文件(无
~/.pi-desktop)。 - 步骤:1) 在新的配置文件上启动应用程序。 2) 遵守新手引导清单。
- 预期:显示内嵌清单; provider/key 项目打开设置 → Agent,可选插件项打开app-shell Plugins 目的地。
- 链接规格:
04-ux/05-onboarding.md - 验收:A(首次运行清单)
- 里程碑:M2
- 状态:自动(协议烟雾:主机加入状态;UI 清单手册)
提供商和密钥
E2E-005:添加提供商并保存 API 密钥
- 前提条件:应用程序运行;没有配置提供商。
- 步骤: 1) 打开设置 → Agent。 2) 打开添加提供商对话框。 3) 输入名称、基础 URL、模型 ID 和 API 密钥。 4)保存。
- 预期:提供商显示为带有秘密徽章的卡片;安全存储密钥(不在明文配置中);英雄摘要计数更新。
- 链接规格:
03-runtime/12-provider-config-schema.md、03-runtime/14-secrets-storage.md - 接受:B(添加提供商,保存密钥)
- 里程碑:M2
- 状态:自动(协议烟雾:提供商创建+秘密,无明文回显)
E2E-006:密钥在重启后仍然存在
- 先决条件:已配置提供商+密钥。
- 步骤:1) 退出应用程序。 2)重新启动。 3) 打开设置 → Agent → 提供商。
- 预期:提供商仍在列表中;密钥可用(无需重新输入)。
- 链接规格:
03-runtime/14-secrets-storage.md - 接受:B(密钥在重新启动后仍然有效)
- 里程碑:M2
- 状态:草案
E2E-007:无提供商阻止提示
- 前提条件:应用程序运行;没有配置提供商。
- 步骤:1) 尝试开始聊天。
- 预期:清除阻止提示,解释必须配置提供程序。
- 链接规格:
04-ux/06-settings-ia.md - 接受:B(阻止提示)
- 里程碑:M2
- 状态:草案
对话流和中止
E2E-008:新会话并发送消息
- 先决条件:已配置提供商。
- 步骤:1) 创建新会话。 2) 输入消息。 3)发送。
- 预期:转录结果立即显示紧凑的本地化
Working…发送后、第一个助手或工具事件之前的状态。它产生 具体的 thinking/tool/answer 反馈,并在回合结束时消失。 - 链接规格:
03-runtime/02-agent-runtime.md、03-runtime/10-session-state-machine.md - 接受:C(新会话,发送消息)
- 里程碑:M2
- 状态:自动化(协议烟雾、实时模型通道;需要 PI_DESKTOP_TEST_API_KEY)
E2E-008a:首轮工具按需加载
- 先决条件:Agent 模式;提供商已配置;
BrowserPreview或 启用插件工具可用;请求捕获可以检查第一个和 后续提供商有效负载。 - 步骤: 1) 创建一个新会话并发送一个简单的提示。 2) 检查 第一个提供商请求的工具列表。 3) 要求代理创建或编辑 HTML 页面并观察工具活动。 4) 之后启动第二个用户提示 预览任务完成。
- 预期:第一个请求仅包含模式核心工具(Agent:
Working…/thinking/tool/answer/03-runtime/02-agent-runtime.md/03-runtime/10-session-state-machine.md;聊天:BrowserPreview/Agent/Agent) 和本地ToolSearch;延迟模式是 仅由有界# On-demand tools目录表示。代理打电话ToolSearch在BrowserPreview之前(或选定的 plugin/ToolSearch工具) 当需要该功能并且匹配模式可用时 下一个模型回合。对于用户可见的 HTML 可交付成果,BrowserPreview是 创建或第一次有意义的视觉编辑后调用一次,然后重复使用 在页面优化时通过实时重新加载。已生成,仅供测试,并且 非可视 HTML 文件不会触发预览调用。加载的集合不 泄漏到下一个提示的第一个请求中。工具激活标记幸存 在不授予主机权限或工作区逃逸的情况下重新加载脚本。 - 链接规格:
03-runtime/02-agent-runtime.md§7.1,03-runtime/03-tools-and-permissions.md§2.1、ADR 0048、08-meta/decisions-log.md(D185) - 验收:C(第一轮和流)+ E(工具执行)
- 里程碑:M5
- 状态:单位覆盖(
agent-runtime延迟工具测试);真人模特 请求捕获和完整的 Electron 旅程待处理
E2E-009:UI 中可见的流式令牌
- 先决条件:会话处于活动状态;消息已发送。
- 步骤:1) 请求包含 Markdown 和 inline/display 的长答案 数学。 2) 观察助理的响应。 3)让答案 完成并检查渲染器控制台。
- 预期:运行时块通过增量逐渐出现 Markdown 渲染器和最终响应完成。渲染器不 启动第二个动画帧打字机循环,引发 React 错误 185,或者 拒绝 CSP 下的 Vite 内联 KaTeX 字体。
- 链接规格:
03-runtime/02-agent-runtime.md,04-ux/08-component-spec.md、04-ux/09-interaction-patterns.md、05-security/01-security.md - 验收:C(流式输出),质量
- 里程碑:M2
- 状态:部分自动化(协议实时模型流加上渲染器
renderer-stream-safety.test.mjs中的源回归;完整的UI观察 仍为草案)
E2E-010:中止生成
- 先决条件:一个会话可以产生故意延迟的第一个 令牌和流响应。
- 步骤: 1) 发送普通文本并在助理文本、思考或之前停止 工具行开始。 2)确认用户行被撤消,文本返回到 输入框。 3)再次发送,等待部分输出,然后停止 流。 4)观察抄本和输入框。
- 预期:未答复的发送将被撤消并恢复其草稿。的 流发送停止,保留部分响应且没有草稿 恢复或重复用户轮流。该会话仍然可用。
- 链接规格:
03-runtime/02-agent-runtime.md - 接受:C(中止)
- 里程碑:M2
- 状态:草案
E2E-011:在项目和临时会话之间切换
- 先决条件:一个保留的项目会话和一个无路径的临时会话 会话存在。两份成绩单都超过一个视口,并且具有不同的最终结果 记录。
- 步骤:1) 从其精确路径侧边栏组打开项目会话。 2) 滚动到较早的记录并确认出现跳转到最新的控件。 3) 打开临时会话并观察其第一个绘制的帧。 4) 开关 快速项目→临时→项目,而前两个成绩单读取 延迟,并观察哪一行响应以及哪个目标提交。 5) Hover/focus 暂时的,再次切换到它来锻炼暖缓存,然后 启用减少运动后重复。 6)观察聊天内容和工作空间 铬。
- 预期:侧边栏不包含最近的聚合;保留项目 范围组和无路径会话仍处于临时状态;每个 成绩单加载正确;选择临时清除项目上下文并 不继承任何工作空间访问权限;两次会议仍然持续进行。每节课 激活在转录本底部绘制其独特的最终记录,而无需 首先暴露记录顶部,前一个会话的滚动位置, 或陈旧的跳转到最新控件。最新点击的行立即响应 并且其转录请求不会等待被取代的读取;只有决赛 project/session/work-panel 元组提交。在 cold/deferred 加载期间 先前的完整视图在薄忙下变暗且非交互 指标;热重新访问会重用有界缓存并重新验证。减少 运动呈现静态进度轨迹并保持相同的稳定 没有生动地穿越历史的目的地。
- 链接规格:
03-runtime/10-session-state-machine.md,04-ux/01-ui-ia.md、04-ux/08-component-spec.md、04-ux/09-interaction-patterns.md - 接受:C(切换会话)
- 里程碑:M2
- 状态:涵盖源级回归;全视觉场景草稿
E2E-011a:新会话,而另一个会话仍在流式传输
- 先决条件:已配置提供商;会话 A 正在流式传输很长的时间 响应(composer 显示 stop/abort 控件)。
- 步骤: 1) 当 A 仍在直播时,单击“新任务”/“新聊天”。 2) 观察新会话的输入框。 3) 输入提示并在 A 时发送 继续在后台播放。 4)让A完成并观察 又是新会议的输入框。
- 预期:新会话立即显示空闲的发送控件 (绝不是卡住的 stop/abort 控件)并且其文本区域已启用;提示 正常发送和流式传输,而 A 继续在后台运行。当A 结束时,其跨会话
agent_end不会更改新会话的 输入框状态,该状态与发送控件保持空闲状态。 - 链接规格:
04-ux/08-component-spec.md(§11.4),04-ux/09-interaction-patterns.md(§1.6,§11) - 接受:C(会话隔离、聊天和流)
- 里程碑:M2
- 状态:单位覆盖(
composer-send-state.test.mjs);完整的 UI 场景草稿
E2E-011b:从保留的项目组创建新会话
- 先决条件:已配置提供商;至少有一个保留项目 在侧边栏中可见;当前对话可能处于空闲或流状态。
- 步骤: 1) 单击项目组的“新建会话”控件。 2) 等待 要加载的项目对话。 3) 键入提示并检查发送控件。 4) 无需再次单击“新建会话”即可发送。
- 预期:项目激活和会话创建作为一个渲染器提交 导航流程。目标输入框可以使用“发送”进行编辑 一旦存在有效的草稿和模型,控制就启用;较早的 项目的后台转动不能使其禁用。提示被接受 第一次发送尝试时。
- 链接规格:
04-ux/09-interaction-patterns.md(§1.6),04-ux/08-component-spec.md(§11.4) - 接受:C(项目会话创建和发送准备)
- 里程碑:M2
- 状态:覆盖源级回归(
app-store-sidebar.test.mjs); 完整的 UI 场景草稿
对话顶部栏
E2E-087:对话顶部栏在聊天路径上呈现
- 先决条件:已配置提供商;至少存在一个会话。
- 步骤: 1) 打开聊天路径。 2) 检查顶部的 46px 栏 交谈区。 3) 确认其显示简洁的 session/task 标题, 模型选择器和新任务/搜索/命令 动作按钮;确认 侧边栏切换仅在侧边栏折叠时出现(展开时, 侧边栏拥有该控件)。 4)切换到Pull requests,Scheduled, 插件或设置路由并检查同一顶部区域。
- 预期:在聊天路径上,对话顶部栏以其 标题、模型选择器和操作;它没有 Agent|Plan|Goal 模式控制。的 左侧输入 Composer 芯片拥有活动会话的 Agent/Plan/Goal 开关。的 任务标题是唯一可见的标题文本,最多 10 个字符 带有省略号;项目范围可通过其工具提示获得。紧凑型 运行时出现状态点。侧边栏 切换仅在折叠状态下存在(没有 侧边栏控件的重复)。在所有其他路线上均采用无框拖曳 band 会改为渲染(没有顶栏控件)。该栏可拖动以移动 窗户;交互式控件不会启动窗口拖动。 macOS 仅在侧边栏打开时为交通灯保留左侧约 76px 的空间 折叠(全屏 8 像素); Windows/Linux 将右侧 112px 留空 本机窗口控件。
- 链接规格:
04-ux/08-component-spec.md(§2 顶栏) - 验收:C (send/UI),质量
- 里程碑:M2
- 状态:草案
E2E-088:Composer Agent/Plan/Goal 芯片更新会话
- 先决条件:聊天路线激活;选定的会话。
- 步骤: 1) 单击左侧输入的 Composer 模式芯片,进入 Plan。 2) 发送通常需要 Write/Edit 的提示并观察行为。 3) 单击同一 Composer 芯片返回 Agent。 4) 开始回合并尝试 在运行中或待处理的 Plan 批准可见时切换模式。
- 预期:Composer 芯片更新活动会话
mode(Plan 和 Goal 硬否认 Write/Edit 和插件工具,而 Bash 遵循所选的 权限模式; Agent 根据权限设置允许其正常工具)。的 当存在轮流或活动待批准时芯片被禁用并重新启用 会话返回 idle/planning 后。不呈现顶栏模式控件。 - 链接规格:
04-ux/08-component-spec.md(§2,§11),03-runtime/03-tools-and-permissions.md(§10),03-runtime/04-data-storage.md(§8) - 验收:C、E
- 里程碑:M2
- 状态:草案
E2E-088a:Composer 配置控件在 project/session 初始化后仍然存在
- 先决条件:已配置提供商;新项目或新会话流程是 当目标
activeSessionId仍在解析时可见。 - 步骤:1) 检查 Composer 模式、Thinking 和权限控制 在 empty/home 转换期间。 2)点击模式控制并确认 前进到下一个模式。 3) 打开Thinking并选择支持的级别。 4)打开权限模式,选择自动。 5) 检查目标会话 导航完成后。
- 预期:没有任何空闲配置触发器被仅仅禁用 因为目的地会话尚未预测。第一个 配置操作创建或重用目标草稿,保留 选择值,并且不需要第二次单击。跑步回合和 待批准仍会禁用控件。
- 链接规格:
04-ux/08-component-spec.md(§11),04-ux/09-interaction-patterns.md(§5A) - 接受:C(新 project/session 输入框)
- 里程碑:M2
- 状态:草案
E2E-089:顶栏模型选择器向下打开并切换模型
- 先决条件:聊天路线激活;提供商已配置。
- 步骤: 1) 单击顶部栏中的模型选择器。 2)确认下拉菜单 从酒吧向下打开。 3) 选择不同的 provider/model。 4)打开 命令面板或应用程序菜单中的设置(顶部栏不再 有一个设置操作按钮)。
- 预期:菜单列出了具有默认模型的已启用的可运行提供程序 并向下打开(固定在顶部栏上);选择更新活动 会话模型;通过命令 palette/menu 打开设置。模型触发器 省略长 ID。
- 链接规格:
04-ux/08-component-spec.md(§2,模型下拉列表),03-runtime/13-model-catalog-and-selection.md - 接受:C
- 里程碑:M2
- 状态:草案
E2E-090:转录底部保留跟踪停靠的输入框高度
- 先决条件:聊天路线激活;会议记录 超出一个视口,因此最后一条消息位于停靠的编辑器附近。
- 步骤: 1) 将脚本滚动到最新消息。 2) 测量 最后一条消息与停靠的编辑器顶部之间的垂直间隙。 3) 在编辑器中输入几行,这样草稿就会变成多行。 4) 重新测量间隙并确认上面最后一条消息仍然完全可见 输入框(不重叠)。 5) 将草稿折叠回一行并 确认差距缩小至约 16 像素储备。
- 预期:最后一条消息位于输入框上方(一个小的, 一致的差距)而不是远远低于它;储备遵循输入框的 通过
--composer-dock-height获得真实高度,因此更高的多线草稿会推动 将成绩单向上而不是覆盖它。跳转到最新按钮和 小地图在每个草稿高度都固定在输入框上方。 - 链接规格:
04-ux/08-component-spec.md(§4.3 MainChat 布局) - 验收:C (send/UI),质量
- 里程碑:M2
- 状态:草案
E2E-091:发送提示使成绩单保持在最新回合
- 先决条件:聊天路线激活;所选会话包含足够的 历史记录溢出记录视口;成绩单是最晚的 消息或已向上滚动。
- 步骤:1) 发送提示。 2)观察第一次发送的记录 通过持久化的用户消息事件和第一个流式传输的行来确定状态。 3) 发送前手动向上滚动后重复此操作。
- 预期:发送立即隐藏跳转控件并重新固定 布局阶段的转录。历史行仅向上移动 添加新回合;视口永远不会闪烁到对话的顶部, 新用户回合以及流式响应仍然在底部可见。
- 链接规格:
04-ux/08-component-spec.md(§4.3,§4.4),04-ux/09-interaction-patterns.md(§9.1,§10.4) - 验收:C (send/UI),质量
- 里程碑:M2
- 状态:草案
工作区打开
E2E-012:打开项目目录
- 前提条件:应用程序运行;没有项目开放。
- 步骤: 1) 通过 UI 打开项目目录。 2) 选择本地文件夹。
- 预期:显示项目路径;工具路径相对于项目根目录进行解析。
- 规格链接:
03-runtime/15-workspace-ignore-rules.md - 接受:D(打开项目,显示路径)
- 里程碑:M3
- 状态:草案
E2E-013:只读工具在项目中工作
- 前提条件:项目目录打开。
- 步骤: 1) 要求代理读取项目中的文件。 2)观察结果。
- 预期:
Read在项目范围内立即返回。在 Agent 模式下, 代理在使用之前通过ToolSearch激活Glob或Grep; Plan 在第一次请求时保持其 read/search 内核可用。所有结果 保持在项目范围内。 - 链接规格:
03-runtime/03-tools-and-permissions.md - 验收:E(Read/Glob/Grep 工作),D(基于项目的工具)
- 里程碑:M3
- 状态:自动化(协议烟雾:示例项目中的 Read + Glob)
权限允许/拒绝/超时
E2E-014:Write/Edit/Bash 触发权限卡
- 先决条件:Agent 模式;项目开放。
- 步骤: 1) 要求代理写入文件。 2)遵守许可卡。
- 预期:许可卡内联显示在原始成绩单中 包含工具名称、工作区、参数预览、倒计时和 allow/deny 选项。它不创建背景或模式,也不覆盖其他会话。
- 链接规格:
04-ux/03-permission-ux.md、03-runtime/03-tools-and-permissions.md - 接受:E(Write/Edit/Bash 触发确认)
- 里程碑:M3
- 状态:草案
E2E-015:拒绝权限阻止执行
- 前提条件:显示许可卡。
- 步骤: 1) 单击权限卡上的“拒绝”。 2) 观察座席反应。
- 预期:工具未执行;代理人收到拒绝结果;没有更改文件。
- 链接规格:
03-runtime/03-tools-and-permissions.md - 接受:E(拒绝→不执行)
- 里程碑:M3
- 状态:草案
E2E-016:允许的权限执行工具
- 前提条件:显示许可卡。
- 步骤: 1) 单击权限卡上的“允许”。 2) 观察代理响应和 UI。
- 预期:工具已执行;结果返回到模型并显示在UI中;文件已修改。
- 链接规格:
03-runtime/03-tools-and-permissions.md - 接受:E(允许→结果返回)
- 里程碑:M3
- 状态:草案
E2E-017:权限超时默认为拒绝
- 前提条件:显示许可卡;没有用户操作。
- 步骤: 1) 等待 120 秒而不响应权限卡。 2)观察结果。
- 预期:超时后自动拒绝权限;工具未执行。
- 链接规格:
03-runtime/03-tools-and-permissions.md - 接受:E(超时→拒绝)
- 里程碑:M3
- 状态:草案
E2E-018:Plan 否认工作区突变和插件工具
- 先决条件:Plan 模式处于活动状态,选择“自动”并注册插件代理工具。
- 步骤: 1) 要求 Agent 调用 Write、Edit 和插件工具。 2)询问 运行创建标记文件的 Bash 命令。 3) 重复 Bash 调用 选择询问并检查许可卡。
- 预期:写入、编辑和插件工具不可见且不直接 尝试返回
WRITE_DISABLED_IN_PLAN、EDIT_DISABLED_IN_PLAN或PLUGIN_DISABLED_IN_PLAN;这些工具不会更改任何文件。重击运行 未经自动确认,可能会发生变异;在“询问”下等待 普通许可卡。不存在聊天模式错误或命令。 - 链接规格:
03-runtime/03-tools-and-permissions.md - 接受:E(Plan 政策)
- 里程碑:M3
- 状态:已记录(M6;未请求 E2E 执行)
E2E-019:工作空间外部路径遵循权限模式
- 先决条件:Agent 或 Plan 模式;项目开放;存在可读文件 在会话项目和暂存根之外。
- 步骤:1) 选择“询问”后,要求客服人员
Read外部文件并 观察内联许可卡。 2) 拒绝一次并确认没有内容 回来了。 3)重复并允许一次;验证工具结果携带root: "external"和规范的绝对路径。 4) 切换到自动和 重复Grep或Glob;验证没有卡片出现以及有界结果 返回。 5) 重复接受编辑;仍然验证外部 read/search 请求许可。 - 预期:在用户可以之前,显式外部路径永远不会发生硬故障 决定。询问并接受编辑请求权限;自动执行。否认, 超时或取消返回
TOOL_DENIED并且不执行任何操作。 - 链接规格:
03-runtime/03-tools-and-permissions.md,03-runtime/15-workspace-ignore-rules.md、04-ux/03-permission-ux.md - 接受:E(工作空间外部权限策略)
- 里程碑:M3
- 状态:自动(host-core protocol/unit 覆盖范围;桌面旅程待定)
E2E-019e:有界搜索参数在平台之间保持可移植性
- 先决条件:Agent 或 Plan 模式;项目开放;主机工具目录是 可在 macOS、Linux 或 Windows 上使用。
- 步骤:1) 延迟时激活 Agent/Plan 并检查其架构。 2) 使用工作区相关的
path、include、headLimit进行搜索outputMode: "filesWithMatches"或"count",首先是一个目录,然后 然后是一个显式文件。 3) 使用目录调用Read并遵循其 结构化的全局建议。 4) 使用平台的本机 shell 重复此操作 选择,而不更改工具参数。 - 预期:模式在每个 平台;
Read声明仅文件输入,Glob声明目录输入,Grep接受文件或目录。filesWithMatches被接受为 规范输出模式。目录读取返回INVALID_ARGUMENTsuggestedTool=Glob和有界参数;更正后的调用成功。搜索 结果使用项目内工作区相对路径和绝对路径 仅适用于经批准的外部地点。没有特定于 shell 的路径语法 所需的和超大的结果仍然有限。 - 链接规格:
03-runtime/03-tools-and-permissions.md,03-runtime/16-tool-result-limits.md、ADR 0057、ADR 0069 - 接受:E(有界跨平台搜索)
- 里程碑:M5
- 状态:单元覆盖(host-core 和代理运行时);多平台直播 协议捕获待处理
E2E-019a:暂存目录写入不在工作区中 (D114)
- 先决条件:Agent 模式;项目开放;会议开始。
- 步骤: 1) 要求代理生成 temporary/intermediate 文件(例如一次性脚本)。 2)观察其书写位置以及是否出现权限卡。 3) 检查
git status和工作面板状态。 4) 删除会话并检查<data_dir>/scratch/。 - 预期:文件在没有权限卡的情况下登陆
<data_dir>/scratch/<sessionId>/下;git status项目保持干净;没有文件或查看工件选项卡打开用于临时写入;删除会话会删除临时目录。 - 链接规格:
03-runtime/03-tools-and-permissions.md §4b、03-runtime/04-data-storage.md - 接受:E(与工作区隔离的临时文件)
- 里程碑:M5
- 状态:部分自动化(host-core 单元测试:双根解析、暂存 write/read、PI_SCRATCH_DIR、扫描)
E2E-019b:划痕遏制与工作空间防御相匹配 (D114)
- 先决条件:Agent 模式;项目开放。
- 步骤:1) 尝试使用
..从头开始遍历进行写入。 2)尝试通过植入内部指向外部的符号链接进行写入。 3) 在 Plan 中尝试相同的写入调用。 - 预期:两次转义均返回
PATH_OUTSIDE_WORKSPACE; Plan 返回WRITE_DISABLED_IN_PLAN在任何临时路径之前都可以使写入可用。 - 链接规格:
03-runtime/03-tools-and-permissions.md §4b - 接受:E(scratch root 无法逃脱)
- 里程碑:M5
- 状态:自动化(host-core 单元测试)
E2E-019c:权限模式管理高风险批准 (D115/D132)
- 先决条件:Agent 模式;项目开放;全局默认
ask。 - 步骤: 1) 使用新继承的会话和全局默认“每次询问”,打开编写器菜单 - 期望“每次询问”都被选中,且没有 global-default/inherit 标签 - 然后要求 Agent 写入工作区文件并期望获得权限卡。 2) 将会话芯片切换为接受编辑;重复一下——预计 Write/Edit 不会出现任何卡,但 Bash 仍然会出现卡。 3) 切换到“自动”——预计 Bash 也不会卡。 4) 在设置中将全局默认值设置为接受编辑后创建另一个继承会话 - 期望输入框芯片和菜单选择直接显示接受编辑并且自动允许 Write/Edit。 5) 将会话切换到 Plan,然后切换到 Goal,并设置自动 — 预计 Write/Edit/plugin 会被拒绝,但 Bash 会允许而无需确认。
- 预期:有效模式=会话覆盖→全局默认→询问; Plan 和 Goal Write/Edit/plugin 硬否认超越每种模式,而他们的 Bash 遵循所选模式;输入框芯片和菜单始终显示有效模式,无需 default/inherit 出处。
- 链接规格:
03-runtime/03-tools-and-permissions.md §6、03-runtime/04-data-storage.md、08-meta/decisions-log.md(D115/D132) - 接受:E(权限模式解析并强制主机端)
- 里程碑:M5
- 状态:部分自动化(host-core 单元测试:评估矩阵、Plan 策略优先级、询问下的会话授权;渲染器源测试:仅有效的输入框选项和选择)
E2E-019d:Bash 工具查看用户的登录 shell 工具链 (D181)
- 先决条件:Agent 模式;项目开放;操作系统用户有一个登录 shell (macOS 上的默认设置)其配置文件至少导出一个不在应用程序上的工具 最小 GUI 路径(例如 nvm/Homebrew)。
- 步骤:1) 要求代理打印
$PATH并运行工具链检查,例如 作为command -v node && node -v。 2) 与新终端的 PATH 进行比较 显示同一用户。 3) 可以选择暂时删除~/.bash_profile并在只有.zshrc初始化工具链的机器上重复。 - 预期:Bash 工具解析用户自己的登录 shell 的工具 即使命令通过 bash 运行,也会导出(nvm、pnpm、Homebrew);的 探测到的登录路径是有效子路径的子集(bash 配置文件可能 prepend/dedupe)。丢失或楔入的用户 shell 会降级到主机 PATH 不会使工具失效。
- 链接规格:
03-runtime/03-tools-and-permissions.md §5、08-meta/decisions-log.md(D181)、ADR 0045 - 接受:E(Bash 工具中可见的用户工具链)
- 里程碑:M5
- 状态:自动化(host-core 单元测试:登录路径探测 + 子路径注入)
会话持续性
E2E-020:会话在重新启动后仍然存在
- 先决条件:存在具有消息历史记录的会话。
- 步骤:1) 退出应用程序。 2)重新启动。 3) 打开会话列表。
- 预期:出现上一个会话;消息可恢复。
- 链接规格:
03-runtime/04-data-storage.md、03-runtime/10-session-state-machine.md - 接受:F(会话在重新启动后仍然存在)
- 里程碑:M2
- 状态:自动(协议烟雾:主机级持久性;完全重启通道手动)
E2E-021:删除会话作品
- 先决条件:会话存在。
- 步骤:1) 删除会话。 2) 观察会话列表。
- 预期:会话已从列表中删除;数据不见了。
- 链接规格:
03-runtime/04-data-storage.md - 接受:F(删除会话)
- 里程碑:M2
- 状态:草案
E2E-036:本地化导入分组开始折叠
- 先决条件:支持的本地代理存储包含跨至少两个项目路径和两个源的可导入会话,包括一个没有项目路径的会话;该应用程序可以使用英语系统区域设置启动一次,也可以使用简体中文系统区域设置启动一次。
- 步骤: 1) 以英文启动并打开“设置”→“导入”。 2) 扫描会话。 3) 检查初始源组。 4) 展开一个组并选择一个会话。 5) 将分组依据更改为项目路径。 6) 切换回源。 7) 使用简体中文系统区域设置启动后重复该流程。
- 预期:来源/来源是初始分组;扫描后以及任一分组更改后,所有组都会折叠;项目路径模式显示准确的项目路径和最终的“无项目/未关联项目组”;一组的扩张导致其他组的崩溃;选定的会话在分组更改中保持选定状态;计数、日期、选择标签、可访问名称和导入结果使用活动区域设置,无需原始键或未解析的双括号占位符。
- 链接规格:
04-ux/01-ui-ia.md、04-ux/02-i18n-english-first.md、04-ux/08-component-spec.md - 接受:F(会话导入审核)
- 里程碑:M2
- 状态:草案
E2E-037:导入创建持久的项目条目
- 前提条件:导入候选者包括两个路径 A 的会话、一个路径 B 的会话和一个没有项目路径的会话;这两个项目都不是活动工作区。
- 步骤:1) 导入所有候选。 2) 打开设置→项目存档。 3) 检查并扩展路径 A 和 B。 4) 返回家中并检查临时会话。 5) 重复导入。
- 预期:项目存档恰好包含 A 的一行和 B 的一行;匹配的导入会话出现在其确切的项目行下;无路径会话仅出现在临时会话下;活动工作区不会改变;重复导入既不会重复会话,也不会重复项目行;磁盘上不会创建丢失的文件系统路径。
- 链接规格:
03-runtime/04-data-storage.md、04-ux/01-ui-ia.md、04-ux/08-component-spec.md - 接受:F(session/project 持久性)
- 里程碑:M2
- 状态:草案
E2E-038:设置拥有项目存档目标
- 先决条件:应用程序运行时至少有一个已配置的提供程序、一个受支持的本地会话存储、一个保留的项目和一个存档的项目。
- 步骤:1) 打开设置。 2) 检查完整的设置导轨。 3) 打开Basics 并使用主题预览卡更改其外观卡中的主题。 4) 打开全局 AI 并检查权限和上下文管理卡。 5) 打开快捷方式并检查键盘快捷方式卡。 6) 打开指令并保存全局指令。 7) 打开模型配置并检查提供商工作室。 8) 按顺序打开“导入”、“项目存档”和“信息”。 9) 搜索设置“项目”或“存档”。 10) 在项目存档中,读取概览计数器并将其与渲染的部分进行比较。 11) 将排序控件从“最近”切换到“名称”。 12) 搜索已知的会话标题,检查其展开的项目行,然后显示八个以上的会话;通过清晰的功能来清除搜索。 13) 打开行菜单,使用 Escape 并按下外部按钮将其关闭。 14) 恢复存档的项目,然后激活它。 15) 返回应用程序外壳并打开插件。
- 预期:该导轨按顺序包含基础知识、全局 AI/AI、快捷方式、说明、模型配置、导入、项目存档和信息,每个都有其语义 Lucide 图标(滑块/火花/键盘/文件文本/机器人/下载/存档/信息);外观和提供商仍合并到其所属的目的地;全局 AI 下的权限和上下文管理;键盘快捷键和全局指令都有自己的目的地;开发者生活在 Info 下;项目存档显示活动、关闭和存档的持久行,无需可见性切换,将它们分组在始终可见的固定/所有项目/存档部分 (D168) 下,并带有每个部分的计数。概览横幅的项目、打开、存档和会话计数器与呈现的行一致;按名称排序会重新排序每个部分内的行,而不隐藏任何行;搜索匹配项目字段和会话标题并报告匹配计数,会话标题结果扩展其所属项目,按最新活动和相对更新时间列出会话,并以八个批次显示历史记录;清除搜索将恢复完整索引。行菜单在 Escape 和外部按下时关闭。恢复使存档保持打开状态,激活返回以与侧栏中保留的恢复项目聊天;主页侧边栏和全局页面结果没有独立的项目目标;设置搜索找到项目存档;插件仍然是一个独立的应用程序外壳目的地。
- 链接规格:
04-ux/06-settings-ia.md、04-ux/01-ui-ia.md、03-runtime/11-provider-model-system.md - 接受:B(模型配置),F(会话导入)
- 里程碑:M4
- 状态:单位覆盖(
settings-project-archive.test.mjs、sidebar-navigation.test.mjs);渲染场景草稿
E2E-091:外观卡通过预览卡选择主题和语言
- 先决条件:应用程序在 macOS 上运行,并具有简体中文系统区域设置。
- 步骤:
- 打开设置→基础。
- 在外观卡中,确认主题行显示三张预览卡 (系统、浅色、深色)首先是系统卡;选择深色并确认 选定的卡会显示一个复选标记,并且 UI 会切换为黑色。
- 选择 Light 并确认 UI 切换为浅色。
- 在语言行中,确认三张预览卡(自动、简体中文、英语); 当操作系统区域设置为中文时,自动卡描述为 “当前:简体中文”并选择自动应用简体中文。 5)选择English并确认UI切换为英文;选择简体中文并 确认它切换回来。
- 预期:主题和语言是卡片网格(不是本机选择),每个网格都有 选定的检查徽章和每个选项的描述;自动语言卡 通过主进程 (
app.getLocale()) 解析操作系统区域设置,并将其传递 安全地通过沙盒 preload 桥,并内联反映它;切换 选项更新实时 UI,无需重新加载。 - 链接规格:
04-ux/06-settings-ia.md、04-ux/02-i18n-english-first.md - 验收:A(核心壳)、H(本地化)
- 里程碑:M4
- 状态:已记录
E2E-039:设置标题栏拖动移动窗口
- 先决条件:应用程序在 macOS 上以窗口方式运行,并且打开“设置”。
- 步骤: 1) 记录窗口位置。 2) 将空的 46 像素带拖动到设置栏上方。 3) 将同一条带拖动到内容窗格上方。 4) 使用后退、搜索、项目存档和导航控件。
- 预期:顶带拖动会移动本机窗口;返回、搜索和导航保持交互,并且从不启动窗口拖动。
- 链接规格:
04-ux/06-settings-ia.md、04-ux/01-ui-ia.md - 验收:质量(关键操作感觉很精致)
- 里程碑:M5
- 状态:草案
E2E-043:设置内容跟随窗口宽度
- 先决条件:应用程序在 macOS 上以窗口方式运行,并且打开“设置”。
- 步骤: 1) 以默认窗口宽度打开Basics,并记录内容卡宽度。 2) 将窗口扩展到 1600px 宽。 3) 打开模型配置、导入和项目存档。 4) 将窗口缩小到支持的最小 1040px。
- 预期:右侧内容卡在每个测试宽度上随可用窗格展开和收缩; 275px 导轨和窗格排水沟保持稳定;控件保持可见,无需剪切或水平页面滚动。
- 链接规格:
04-ux/06-settings-ia.md、04-ux/07-ui-design-system.md - 验收:质量(关键操作感觉很精致)
- 里程碑:M5
- 状态:单位覆盖(
settings-responsive-layout.test.mjs);场景已记录
E2E-040:Codex 风格的工具活动在转录本重新加载后仍然存在
- 先决条件:已配置提供商;项目开放;一个会话可以运行一个 成功的工具和失败或中止的工具。
- 步骤:1) 运行代表性读取、搜索和命令工具。 2) 检查 处于活动状态时折叠的处理标头。 3)等待完成 并扩大加工组。 4) 展开已完成的行并复制其 输出。 5) 单击展开行旁边的垂直线,然后单击键盘焦点 并激活处理组的垂直规则。 6) 重新加载会话并 展开恢复的组。
- 预期:连续调用默认折叠在一个本地化版本下 处理标头更新然后冻结其经过的时间并显示 步数。扩展调用使用透明语义活动行 动作图标、自然语言动词、等宽主要参数和安静 披露。处理组使用完整的辅助列宽度,因此 短标签或有效负载不会将扩展的细节缩小为内容大小 芯片。每个扩展内容垂直规则都是一个指针并且可通过键盘聚焦 对其自身披露的崩溃控制。嵌套扩展显示输出 在夹紧滚动区域中的原始输入之前。实时部分输出更新 地方。重新加载的行保留工具名称、参数、结果和状态。
- 链接规格:
04-ux/01-ui-ia.md,04-ux/07-ui-design-system.md、04-ux/08-component-spec.md、04-ux/09-interaction-patterns.md - 接受:C(聊天流)、E(工具)、F(持久性)
- 里程碑:M3
- 状态:草案
E2E-041:对话小地图导航长记录
- 先决条件:会话包含足够的用户和助理轮流 滚动超出一个视口并密集填充小地图,包括一个 AI 围绕工具活动作为多个辅助片段发出的响应;一个 第二个会话至少有两个符合条件的回合标记,并且仍适合其中一个 视口。
- 步骤: 1) 打开长会话。 2) 滚动浏览文字记录并 观察活动的小地图标记。 3) 将鼠标悬停在标记上并检查其预览。 4) 使用键盘焦点到达另一个标记。 5) 激活标记。 6) 打开一个 少于两个合格回合标记的会话。 7) 打开 仍然适合一个视口的多消息会话。 8) 调整长会话的大小 窗口变高,直到内容不再溢出,然后再次变短。 9) 在一个 窗口高度短,检查并激活窗口附近的第一个和最后一个标记 小地图的垂直边界,包括面向标题栏的一侧。
- 预期:导轨包含每个可见用户回合一个标记和每个可见用户回合一个标记 人工智能响应。两个用户消息之间的多个助手片段共享一个 单个标记和组合有界预览,而仅工具行不会创建 标记并且不拆分响应。靠近上三分之一读数的标记 锚点暴露
aria-current;悬停和焦点显示相同的本地化发件人 和预览;附近的标记水平放大而不移动堆栈; 激活平滑地滚动到该响应中的第一条内容丰富的消息; 当存在少于两个合格标记时,导轨不存在或当 内容不会溢出一个视口;一旦溢出,导轨就会重新出现 调整大小后返回。密集标记保持在无障碍区域的中心 46px 标题栏和停靠的编辑器之间的跨度,均匀压缩,以及 无需进入本机窗口拖动区域即可保持交互。 - 链接规格:
04-ux/08-component-spec.md - 验收:C(聊天流)、质量(键盘和长线程导航)
- 里程碑:M3
- 状态:草案
E2E-042:v7 之前的版本通过中断重置存储档案;记录存在于会话文件中
- 先决条件:夹具数据目录包含一个
pi.sqlite,其PRAGMA user_version介于 1 和 6 之间(D119 之前的内容数据库模式) 具有代表性的行。 - 步骤: 1) 针对灯具启动 host-core。 2)创建一个会话并 通过主机 RPC 附加消息。 3) 停止并重新启动 host-core。 4) 重新加载 通过 RPC 进行会话并检查数据目录。
- 预期:主机核心将旧文件重命名为 1
pi.sqlite.v6.bak,引导一个新的 schema-v7 数据库(仅索引messages),使用会话头行加上sessions/<id>.jsonl来写入 每条消息一行,重新启动后从文件中重新加载记录 具有相同的逻辑结果,并且删除会话会同时删除 索引行和会话文件。没有 Electron 拥有的持久性文件 权威的。 - 链接规格:
03-runtime/04-data-storage.md,03-runtime/06-host-rpc-protocol.md、ADR 0014 - 接受:F(持久性),H(重置失败是可诊断的)
- 里程碑:M2
- 状态:单位覆盖(
db::tests::archives_pre_v7_database_and_starts_fresh,sessions::tests::transcript_survives_reopen_from_file,sessions::tests::delete_session_removes_transcript_files);完整的夹具 场景草稿
插件加载/命令/禁用
E2E-022:加载本地插件
- 前提条件:应用程序运行;本地路径提供示例插件。
- 步骤:1) 从侧边栏页脚插件图标打开扩展。 2) 从标题溢出菜单中选择加载本地插件。 3) 使用行开关启用它。
- 预期:插件加载;清单已验证;捐款登记;该行显示在带有本地标记的“活动”下。
- 链接规格:
07-plugins/01-plugin-system.md、07-plugins/05-plugin-lifecycle.md - 接受:G(加载本地插件)
- 里程碑:M4
- 状态:自动(协议烟雾:plugins.loadDev)
E2E-022A:从模板创建插件
- 前提条件:应用程序运行;一个可用的空文件夹。
- 步骤:1) 打开扩展。 2) 在标题溢出菜单中选择从模板新建插件(或使用空状态按钮)。 3) 依次选择四个模板并阅读其说明。 4) 选择文件夹。 5) 第二次尝试时取消文件夹选取器。
- 预期:选取器准确列出
panel-basic、agent-tool-basic、skill-pack、full-demo,每个值均在活动区域设置中命名和描述;选择一个文件夹写入模板文件,加载插件作为开发插件,刷新列表,然后打开该文件夹作为活动项目 - 应用程序以新文件夹作为工作区进行聊天,它出现在侧边栏项目列表中,并且 toast 上显示“已创建、加载并打开用于开发”;该插件的贡献可以立即使用,并且内置插件开发技能在新工作区中处于活动状态。该技能教授当前全局piAPI(onLoad()加pi.commands.register)和固定window.pluginBridge边界,但不教授已退役的onLoad(pi)/pi.registerCommand形状。取消的文件夹选择器不会改变任何内容,也不会报告任何错误。 - 链接规格:
07-plugins/10-plugin-devex.md、../../plugin-development.md、ADR 0039 - 接受:G(从模板创建插件)
- 里程碑:后 MVP
- 状态:部分自动化(
apps/desktop/test/plugin-template-action.test.mjs:通道、模板 ID 与 devkit 的奇偶校验、区域设置覆盖、取消挑选排序、项目激活); UI 演练已记录
E2E-022B:开发插件热重载
- 先决条件:从本地文件夹加载并启用的插件。
- 步骤: 1) 编辑
main.js以更改命令标题并保存。 2) 一次保存多个文件。 3)引入语法错误并保存。 4) 修正错误并保存。 5) 为manifest.json添加新权限并保存。 6) 单击开发插件卡上的“重新加载”。 7)再次编辑并重新启动应用程序。 - 预期:单次编辑重新加载插件,无需重新选择文件夹,并且命令面板显示新标题;保存突发会产生一次重新加载,而在
dist/或node_modules/下写入不会产生任何结果;语法错误报告重新加载失败,但不会导致应用程序崩溃,并且修复保存会恢复插件;添加的权限拒绝使用PERMISSION_DENIED自动重新加载,而显式重新加载操作会加载已注册的文件夹,刷新权限上限,并报告成功;稍后的编辑使用刷新的上限,并且在重新启动后仍会监视该文件夹。 - 链接规格:
07-plugins/10-plugin-devex.md§7、07-plugins/13-plugin-permissions-matrix.md、ADR 0039、ADR 0075 - 接受:G(热重载),D(未经审查不得扩大权限)
- 里程碑:后 MVP
- 状态:部分自动化(
apps/desktop/test/plugin-hot-reload.test.mjs:反跳、忽略列表、权限上限、恢复、拆卸);手动编辑循环记录
E2E-022C:检查、打包、安装往返
- 先决条件:脚手架插件目录。
- 步骤:1)
pnpm pi-plugin check <dir>。 2) 删除main命名的文件并再次运行check。 3) 恢复它,声明contributes.skills而不声明agent.prompt.inject,然后再次运行check。 4)pnpm pi-plugin pack <dir>。 5) 从插件页面安装生成的.piplug。 6) 要求代理在同一目录上运行PluginCheck和PluginPack。 - 预期:脚手架插件检查干净并报告其文件计数和大小;缺少
main是一个阻止pack的错误; inert-skills 情况是一个不会阻止的警告;pack使用仅存储条目写入dist/<id>-<version>.piplug并打印其 sha256;该软件包通过正常的权限审查进行安装,并显示在“活动”下;代理工具会产生相同的判断并拒绝会话工作区之外的任何目录。 - 链接规格:
07-plugins/10-plugin-devex.md§5–§6、07-plugins/06-plugin-packaging.md、ADR 0039 - 承兑:G(本地包装往返)
- 里程碑:后 MVP
- 状态:部分自动化(
packages/plugin-devkitvitest:脚手架→检查→按模板打包,存储方法标头,每个检查规则);安装步骤已记录
E2E-023:全局搜索中的插件命令并执行
- 前提条件:插件已加载并启用。
- 步骤: 1) 打开全局搜索(Cmd/Ctrl+K 或 Cmd/Ctrl+Shift+P)。 2) 在“命令”部分下找到插件命令。 3)执行。
- 预期:命令出现在全局搜索结果中;执行产生预期结果。
- 链接规格:
07-plugins/09-plugin-command-palette.md - 接受:G(插件命令出现并执行)
- 里程碑:M4
- 状态:草案
E2E-024:插件注册并调用代理工具
- 先决条件:插件已加载;插件声明一个代理工具。
- 步骤: 1) 要求代理使用插件工具。 2) 如果需要,请遵守许可卡。 3)允许。
- 预期:使用强制前缀 (
plugin_<id>_<name>) 注册的工具;调用成功。 - 链接规格:
07-plugins/03-plugin-api.md、07-plugins/13-plugin-permissions-matrix.md - 接受:G(插件代理工具)
- 里程碑:M4
- 状态:自动化(协议烟雾:调度往返主机->运行器->主机;通过PluginRuntime执行应用内JS)
E2E-024G:市场详细信息表显示自述文件、权限、版本
- 先决条件:提供官方市场目录。
- 步骤:1) 打开扩展 → 市场。 2) 打开
demo.workspace-summary的详细信息。 3) 检查自述文件/风险分组权限/版本行。 4) 选择版本并审核权限后安装。 5) 使用 Escape 并单击稀松布来解除纸张。 - 预期:通过
market.getDetail加载详细信息表;自述文件、安全说明和每个风险的权限解释;所选版本驱动粘性安装操作; Escape 和 scrim 都会关闭工作表,但不会关闭下面的权限对话框。 - 规格链接:
07-plugins/07-plugin-marketplace.md - 接受:G(市场详细信息用户体验)
- 状态:已记录
E2E-024F:刷新官方远程市场存储库
- 先决条件:网络可用于 GitHub 原始内容。
- 步骤:1) 打开扩展 → 市场。 2) 使用标题刷新市场操作。 3) 确认源代码行指向
vastsa/pi-desktop-plugins。 - 预期:目录从远程官方存储库刷新;卡片网格更新;如果获取失败,离线回退仍然有效。
- 链接规格:
07-plugins/07-plugin-marketplace.md - 接受:G(远程市场来源)
- 状态:已记录/涵盖 host-core 单元
E2E-024B:带有权限审查的市场安装
- 前提条件:应用程序运行;提供官方市场目录。
- 步骤:1) 打开扩展 → 市场。 2) 安装
demo.workspace-notes。 3) 阅读风险分级权限对话框。 4)接受高风险权限。 - 预期:在下载之前,权限分为高/中/低,并带有简单的语言解释;从市场包安装的插件,校验和已验证,已授予权限,panel/tools可用;安装的选项卡和风险分组行反映了新插件,没有单独的概述卡行。
- 链接规格:
07-plugins/07-plugin-marketplace.md、07-plugins/13-plugin-permissions-matrix.md - 接受:G(市场安装+权限审查)
- 状态:单元测试+协议方法已记录/host-core
E2E-024C:插件包安装和自动更新路径
- 先决条件:市场目录有较新版本或本地
.piplug。 - 步骤:1) 从标题溢出菜单安装包。 2) 从行溢出菜单启用自动更新。 3) 运行检查更新,然后应用自动更新。
- 预期:该行移至“可用更新”,更新横幅报告计数;新版本添加的权限在审阅对话框中被标记为“新建”;仅当权限差异为空或预先授予时才应用自动更新。
- 链接规格:
07-plugins/06-plugin-packaging.md、07-plugins/08-plugin-signing-updates.md - 接受:G(软件包安装+更新策略)
- 状态:已记录
E2E-024H:已安装插件的表面状态、风险和故障
- 前提条件:至少有一个已启用的插件、一个已禁用的插件以及一个加载失败的插件。
- 步骤:1) 打开扩展→已安装。 2) 读取选项卡和组计数。 3) 确认失败的插件位于需要注意及其错误消息下。 4) 按作者和许可进行搜索。 5) 清除搜索。
- 预期:行分组为需要注意/可用更新/活动/已关闭(带计数);
status: "error" | "load_error"内联呈现错误消息而不是静默;每行默认为两行 name/id/version 摘要,而详细信息披露则揭示了带有风险色彩的权限芯片、功能和常驻服务状态;单范围触发器打开解释关闭/此项目/到处选择和项目选择器;行图标操作公开 hover/focus 标签;结果计数反映了过滤的子集,清除会恢复每个组。 - 链接规格:
04-ux/01-ui-ia.md、07-plugins/13-plugin-permissions-matrix.md - 接受:G(已安装插件管理)
- 状态:已记录
E2E-024D:隔离插件面板主桥
- 先决条件:启用
ui.panel的插件。 - 步骤: 1) 打开插件面板。 2) 调用面板桥 API(
ui.showToast、可选的 fs/net(带授权))。 - 预期:面板在沙盒 window/partition 中运行;桥接调用经过许可检查;主机在面板关闭时保持稳定。
- 链接规格:
07-plugins/03-plugin-api.md、07-plugins/04-plugin-security.md - 验收:G(隔离面板)
- 状态:已记录
E2E-024E:高风险插件 API 需要拨款
- 先决条件:使用明确授权安装的 Notes 插件。
- 步骤: 1) 通过插件运行时或面板桥调用
fs.writeText/net.fetch/shell.openExternal。 2) 撤销一项权限并重试。 - 预期:授权调用通过审核成功; revoked/undeclared 调用失败并显示
PERMISSION_DENIED,并且不会使应用程序崩溃。 - 链接规格:
07-plugins/13-plugin-permissions-matrix.md、07-plugins/04-plugin-security.md - 接受:安全+G
- 状态:已记录
E2E-024I:插件技能到达代理并按需加载
- 先决条件:
examples/plugins/hello启用并授予agent.prompt.inject;未经许可的舱单第二份副本;一个工作区是插件目录,另一个工作区不是。 - 步骤: 1) 开始会话并询问客服人员拥有哪些技能。 2) 要求它遵循 Hello 演示技能,以便它调用
Skill工具。 3) 编辑技能文档并重复步骤2。 4) 禁用插件并开始新一轮。 5) 加载不带agent.prompt.inject的变体并重复步骤 1。 6) 声明一个大于每个技能上限的文档。 7) 依次打开两个工作区。 - 预期:目录列出了技能 ID、名称和修剪后的描述,但没有正文,位于内置技能之后、项目指令链之前;仅在请求时才通过
ToolSearch加载Skill架构,并读取已编辑的文件而无需重新启动;禁用插件会重建运行时,因此该技能从下一回合就会消失;未经许可的变种加载正常,无技能贡献;过大的文档会通过审核行跳过,而不是夹在提示中;内置的plugin-development技能在插件工作区中进行编目,而在其他工作区中则不存在,而PluginCheck则在两者的有界按需工具目录中列出。 - 链接规格:
07-plugins/02-plugin-manifest-schema.md、07-plugins/04-plugin-security.md§7.1、07-plugins/10-plugin-devex.md、ADR 0039、ADR 0037、D174 - 接受:G(技能激活)+ E(工具和权限)+ D(高风险权限门控)
- 状态:单元覆盖(
plugin-skills.test.mjs、代理运行时 prompt/digest 测试);面向代理的场景草稿
E2E-024J:插件主题适用并在撤回时回退
- 先决条件:在授予
ui.theme的情况下启用examples/plugins/hello; CSS 使用@import或远程url()可用于拒绝情况的插件。 - 步骤: 1) 打开设置 → 常规 → 主题并选择
Hello Midnight。 2)重新启动应用程序。 3) 禁用提供的插件。 4)重新启用它,然后卸载它。 5) 使用不安全的 CSS 加载插件。 - 预期:插件主题与内置插件一起出现在选择器中并立即应用;该选择在重新启动后仍保留为
plugin:demo.hello:midnight;禁用或卸载提供程序会退回到system而不是无样式的 shell;不安全的 CSS 在加载时被拒绝,并记录了原因,并且没有注入<style>元素。 - 链接规格:
07-plugins/04-plugin-security.md§3.1、04-ux/07-ui-design-system.md、D175 - 接受:G(主题贡献)+安全
- 状态:单位覆盖(
plugin-themes.test.mjs、theme-cssSDK 测试);视觉场景草稿
E2E-024K:插件 MCP 服务器工具到达代理
- 先决条件:针对本地存根声明一个
stdio和一个httpMCP 服务器的插件;已授予mcp.server.local和mcp.server.remote;保存存根凭证的设置密钥。 - 步骤: 1) 启用插件并确认尚未启动服务器进程。 2) 要求代理调用已发现的工具。 3) 检查存根收到的 environment/headers。 4) 使存根调用失败并超时。 5)禁用插件。
- 预期:服务器在首次使用时延迟连接;工具在
risk: "medium"上显示为plugin_demo_*_<serverId>_<tool>,并进行每次调用审核; stdio 子级仅接收声明的env值加上 PATH/temp/locale,从不接收主机提供程序密钥;失败和超时会返回工具错误,而不会导致插件或主机崩溃;禁用会断开两个服务器的连接。 - 链接规格:
07-plugins/02-plugin-manifest-schema.md、07-plugins/04-plugin-security.md§8.1、ADR 0038、D176 - 接受:G(MCP 桥)+ E(工具和权限)+ 安全
- 状态:单位覆盖(
plugin-mcp.test.mjsstdio + HTTP 存根);面向代理的场景草稿
E2E-024L:常驻插件服务受监督且可见
- 先决条件:在授予
background.service的情况下启用examples/plugins/hello。 - 步骤: 1) 打开扩展→已安装并展开插件行上的详细信息以读取
Greeter heartbeat芯片。 2) 杀死插件的实用进程并观察芯片。 3) 反复杀死它超过重启上限。 4) 禁用并重新启用该插件。 5) 撤销background.service并重新加载。 - 预期:详细信息披露暴露了一个在加载后报告
running的芯片; Kill 显示failed,然后再次显示running,并在尝试之间增加重新启动计数和退避;在过去的五次尝试中,插件保持failed状态并停止重试;手动disable/enable取消挂起的定时器并重置计数器;未经许可,服务永远不会启动,并且跳过会被审核。 - 链接规格:
07-plugins/05-plugin-lifecycle.md§3.1、ADR 0040、D177 - 接受:G(居民服务)
- 状态:单位覆盖(
plugin-services.test.mjs监督 + 退避);手动杀掉场景草稿
E2E-024M:总线消息仅按照声明跨插件
- 先决条件:启用两个插件 - 一个发布
demo.*主题,一个订阅demo.**- 并授予bus.publish/bus.subscribe。 - 步骤: 1) 运行发布者的命令并观察订阅者。 2) 发布
contributes.bus.publish中缺少的主题。 3) 订阅contributes.bus.subscribe中缺少的模式。 4) 发布超过 64KB 的负载,并在 10 秒内发布超过 100 次。 5) 卸载订阅者并再次发布。 - 预期:订阅者收到
{ topic, from, payload, at }而发布者永远不会收到自己的消息;未声明的发布和订阅都失败PERMISSION_DENIED,并有一条命名主题的审核行;负载过大且速率突发失败LIMIT_EXCEEDED/RATE_LIMITED;向已离开的订阅者发布成功,扇出较小且没有主机错误。 - 链接规格:
07-plugins/02-plugin-manifest-schema.md§5.1、07-plugins/04-plugin-security.md§5.1、ADR 0040、D178 - 接受:G(消息总线)+安全
- 状态:单位覆盖(
plugin-bus.test.mjs交付、过滤、上限);两个插件手动场景草稿
E2E-024N:扩展页面密度和主题可读操作
- 先决条件:应用程序运行时至少有一个已安装的扩展程序和一个 可用的市场行动;提供深色和浅色主题。
- 步骤:1)在深色主题中打开扩展。 2) 确认标题并 已安装/MCP/技能/子代理/市场选项卡到达内容 没有四卡数字概览带。 3) 确认安装行开始 作为安静的两行摘要,然后展开一行上的详细信息并检查其 功能、服务状态和权限。 4) 使用紧凑范围 控件及其解释的范围菜单、上下文主要操作以及 辅助 update/action 按钮。 5) 切换到浅色主题并重复。 6) 键盘焦点详细信息披露, 范围状态和每个操作。
- 预期:四张数字概览卡不存在;标签计数, 已安装的组计数,并且任何更新警报在其中仍然可用 相关表面。安装的行保持其默认高度较低,而 披露暴露了完整的辅助读数。范围触发器保持不变 与行操作轨对齐,其菜单解释每个状态和图标 操作在静止时保持可见,同时在悬停和焦点时显示标签。 主要和次要按钮保留 可见的语义表面、文本、边框、悬停状态和焦点环 这两个主题和键盘焦点都不依赖于指针悬停。
- 链接规格:
04-ux/01-ui-ia.md、04-ux/07-ui-design-system.md、07-plugins/07-plugin-marketplace.md、ADR 0058、D196 - 接受:G(扩展页面)+质量
- 状态:单位覆盖(
extensions-page.test.mjs,plugins-page-style.test.mjs);视觉场景草稿
E2E-024O:市场隐藏仅供开发的示例插件
- 前提条件:应用程序运行;官方目录包含 开发装置
demo.hello或demo.workspace-summary且至少 一个产品插件。 - 步骤: 1) 打开扩展 → 市场并进行空搜索。 2) 搜索 依次为
Hello、Workspace Notes和Workspace Summary。 3)检查 类别过滤器和结果卡。 4) 打开已安装并验证 已安装的示例仍然易于管理。 - 预期:ID 以
demo.开头的条目永远不会出现在 市场卡、类别或搜索结果;保留产品插件 可发现的。已安装的示例仍列在“已安装”下 它可以被禁用或卸载,而不是成为非托管运行时。 - 链接规格:
07-plugins/07-plugin-marketplace.md,04-ux/01-ui-ia.md - 接受:G(扩展页面)+质量
- 状态:单位覆盖(
extensions-page.test.mjs);视觉场景草稿
E2E-025:禁用插件会删除贡献
- 先决条件:插件已启用并且贡献可见。
- 步骤: 1) 在“扩展”页面上禁用该插件。 2)检查全局搜索和代理工具。
- 预期:命令和工具消失;没有剩余捐款。
- 规格链接:
07-plugins/05-plugin-lifecycle.md - 接受:G(禁用删除贡献)
- 里程碑:M4
- 状态:自动(协议烟雾:禁用清除启用标志;全局搜索删除手动)
E2E-026:插件错误不会导致应用程序崩溃
- 先决条件:已加载插件。
- 步骤:1) 触发插件抛出错误的场景。 2) 观察应用程序行为。
- 预期:应用程序保持运行;捕获并报告错误;没有崩溃。
- 链接规格:
07-plugins/04-plugin-security.md - 接受:G(插件错误→没有崩溃)
- 里程碑:M4
- 状态:草案
安全——无秘密泄露
E2E-027:正常流程的日志中没有秘密
- 先决条件:使用 API 密钥配置的提供程序。
- 步骤:1) 执行聊天会话。 2) 检查日志文件。
- 预期:API 键/令牌不存在于正常流程的任何日志输出中。
- 链接规格:
05-security/01-security.md、03-runtime/09-logging-and-observability.md - 接受:H(不在日志中的秘密)
- 里程碑:M2
- 状态:自动化(协议烟雾:提供商列表不包含秘密材料)
E2E-028:Renderer 没有 Node 集成
- 先决条件:应用程序正在运行。
- 步骤:1) 检查渲染器进程标志。
- 预期:
nodeIntegration: false;contextIsolation: true; preload 是唯一的桥梁。 - 链接规格:
05-security/01-security.md - 接受:安全(渲染器中没有 Node)
- 里程碑:M1
- 状态:草案
E2E-029:无法调用未列入白名单的 IPC
- 先决条件:应用程序正在运行。
- 步骤:1) 尝试从渲染器调用不在白名单中的 IPC 方法。
- 预期:呼叫被阻止;没有返回数据;错误或无响应。
- 链接规格:
03-runtime/01-ipc-protocol.md、05-security/01-security.md - 接受:安全(强制实施 IPC 白名单)
- 里程碑:M1
- 状态:草案
E2E-030:插件无法读取 API 密钥
- 先决条件:插件已加载;提供商已配置。
- 步骤:1) 插件尝试通过任何 API 访问提供商机密。 2)观察结果。
- 预期:访问被拒绝;没有秘密数据返回到插件。
- 链接规格:
07-plugins/04-plugin-security.md、03-runtime/14-secrets-storage.md - 接受:安全(插件无法读取 API 密钥)
- 里程碑:M4
- 状态:草案
E2E-031:错误代码稳定且可读
- 先决条件:通过正常桌面开发启动应用程序 命令;提供商已配置。
- 步骤: 1) 选择或输入提供商拒绝的模型 ID。 2) 发送 提示。 3) 检查助手错误信息及其详细披露。 4) 切换会话并重新加载失败的会话。 5) 重复无效 提供商密钥。
- 预期:运行停止并且转录物包含一个持久的
role=assistant、status=error消息而不是 toast、浮动横幅, 或空白行。它显示了本地化的摘要和稳定的MODEL_NOT_CONFIGURED或PROVIDER_UNAUTHORIZED代码。细节暴露 已编辑的提供商响应加上 provider/model ID,并且可以复制;没有 API 出现密钥或授权值。配置失败链接到 设置,可重试的失败提供重试,输入框再次可用, 并重新加载保留错误消息。开发启动执行 sidecar 从当前运行时源重建。 - 链接规格:
03-runtime/02-agent-runtime.md,03-runtime/07-process-model.md、03-runtime/08-error-codes.md - 接受:C(失败的聊天解决),H(错误暴露稳定代码)
- 里程碑:M2
- 状态:单元已覆盖(代理运行时错误 message/redaction,主机 持久性、桌面脚本合同和预开发构建合同);满 Electron UI 场景草案
硬化 (M5)
E2E-032:后端崩溃触发受监督的重启
- 前提条件:应用程序运行; host-core 和 sidecar 健康。
- 步骤: 1) 从外部终止 host-core(或 sidecar)进程。 2) 观察应用程序行为。
- 预期:运行中的 RPC 快速失败(不会长时间挂起);
hostStatus显示降级然后恢复;孩子以退避方式重新开始;在 2 分钟内 3 次重新启动失败后,应用程序会保持降级状态,并出现明显的致命状态。 - 链接规格:
03-runtime/07-process-model.md - 验收:质量(主路径无崩溃)
- 里程碑:M5
- 状态:自动(
scripts/e2e-supervision.mjs— SIGKILL host-core,断言重新启动 + 正常的 RPC)
E2E-033:重新启动后窗口边界仍然存在
- 先决条件:应用程序以默认窗口大小运行。
- 步骤: 1) Resize/move 将窗口设置为不同的正常边界 A (≥1040×700),在 600 毫秒保存去抖动结束之前最大化,退出并重新启动。 2) 恢复,resize/move 到不同的边界 B,在去抖结束之前退出,然后再次重新启动。
- 预期:每次重新启动都会恢复最新的正常范围(A,然后 B),包括在最大化或等待保存时发生退出。 Maximized/fullscreen 几何图形永远不会存储为法线边界; invalid/tiny 保存的边界回退到默认值 1200×800。
- 链接规格:
04-ux/09-interaction-patterns.md - 验收:质量(关键操作感觉很精致)
- 里程碑:M5
- 状态:已记录
E2E-034:NDJSON 日志文件已写入并经过编辑
- 先决条件:新鲜的个人资料;提供商已配置;一轮聊天结束。
- 步骤:1) 通过工具调用运行提示。 2) 打开
~/.pi-desktop/logs/。 3) 检查app/、host/和agent/下的分类文件。 - 预期:NDJSON 记录与
ts/level/channel/category/message一起存在;工具 start/end 携带 host-core/RPC;没有出现 API 密钥材料;每个类别文件的大小为 5 MB。此外,(D183)host/timing.log对于携带 Maximized/fullscreen/invalid/tiny/04-ux/09-interaction-patterns.md/NDJSON/~/.pi-desktop/logs/的每个工具调用都有一个tool timing记录,并且agent/timing.log具有匹配的[timing] kind=tool和[timing] kind=model行,因此对于同一toolCallId,批准等待、慢速工具主体和慢速提供程序是可区分的。 - 链接规格:
03-runtime/09-logging-and-observability.md - 接受:H(诊断)
- 里程碑:M5
- 状态:已记录
E2E-035:Bash 工具使用有效的目录 shell
- 前提条件:工作区打开;代理模式。
- 步骤:1) 选择可用的目录 shell 并运行
Bash(例如echo ok)。 2) 使持久选择不可用,并在运行下一轮之前检查有效目录。 3) 使用上一回合快照运行。 - 预期:未更改的
Bash协议调用使用选定的目录条目。稍后不可用的持久选择会回退到第一个可用的平台 shell 并标记目录回退;上一个回合的快照被COMMAND_SHELL_CHANGED拒绝为过时的,而不是默默地更改 shell。不会发生部分执行; E2E-113 覆盖过时的身份路径。 - 链接规格:
03-runtime/03-tools-and-permissions.md、03-runtime/06-host-rpc-protocol.md、03-runtime/08-error-codes.md、ADR 0054 - 接受:H(错误暴露稳定代码)
- 里程碑:M5
- 状态:单位覆盖(
tools::shell::tests);场景已记录
E2E-044:开发启动使用 PI-Desktop Dock 品牌
- 先决条件:macOS 开发与规范的
build/icon_1024.png进行检验。 - 步骤:1) 运行
pnpm dev。 2) 检查正在运行的应用程序的 Dock 图标。 - 预期:Dock 显示 PI-Desktop 品牌图标,而不是 Electron 的默认图标;打包版本继续使用
build/icon.icns。 - 链接规格:
06-delivery/06-release-runbook.md - 验收:质量(开发外壳与发布品牌相匹配)
- 里程碑:M5
- 状态:单位覆盖(
development-branding.test.mjs);视觉场景记录
E2E-045:全局文本选择保留编辑和复制
- 先决条件:应用程序运行时包含用户的聊天记录 消息、带有代码块的助理 Markdown 响应以及扩展的 工具结果。
- 步骤:1) 拖动 sidebar/titlebar chrome 和按钮标签。 2) 在 user/assistant 散文、代码和工具输出之间拖动。 3)聚焦 输入框和 settings/search 输入,然后使用
Cmd/Ctrl+A并替换 选定的文本。 4) 复制选定的成绩单和代码文本。 - 预期:Chrome 不会留下意外的文本选择;留言 散文、代码、工具 input/output 和可编辑控件仍然是可选的 可复制;本机编辑快捷方式、焦点可见环和窗口拖动 行为保持不变。
- 链接规格:
04-ux/07-ui-design-system.md,04-ux/09-interaction-patterns.md - 验收:质量(关键操作感觉很精致)
- 里程碑:M5
- 状态:单位覆盖(
user-select.test.mjs);场景已记录
E2E-046:PI-Desktop 渲染器品牌和输入框图标边界
- 先决条件:应用程序在英语和中中文语言环境中运行,并带有 空荡荡的家和可用的停靠成绩单。
- 步骤:1) 检查展开和折叠的侧边栏。 2) 检查 空荡荡的英雄和停靠的输入框。 3) 将鼠标悬停在吉祥物上并确认 继续播放,没有空闲暂停,然后将指针移开并 确认空闲暂停返回。 4)关注页脚设置和插件 图标,然后每个 project/Temporary 会话创建控件。 5)打开设置 和输入框输入。
- 预期:可见 shell 标识为
PI-Desktop;空荡荡的家英雄 渲染 100pxHomeMascotLogo精灵,随机选择一个姿势组 并在固定视口内播放后选择不同的组 无需水平平移吉祥物;指针连续悬停 在离开吉祥物的同时推进小组,恢复较慢的空闲节奏。 expanded/collapsed 侧边栏通过BrandLogo呈现规范的build/icon_1024.png资源 并且停靠的输入框提示行没有前导 品牌图标或保留图标槽及其文本直接与输入对齐 天沟。页脚设置和插件操作是紧凑的图标按钮; 插件紧邻“设置”右侧,并公开本地化的 可访问的名称。每个作用域会话创建控件都使用专用的 带有本地化标签和可访问名称的消息加号图标。Codex仅在以下情况下保持可见 外部导入源标签或非运行时设计参考文本。 - 链接规格:
04-ux/01-ui-ia.md、04-ux/07-ui-design-system.md、04-ux/08-component-spec.md、04-ux/09-interaction-patterns.md、08-meta/decisions-log.md(D094/D160),../../adr/0031-icon-free-composer-prompt-row.md - 验收:质量(品牌一致性和关键操作感觉很精致)
- 里程碑:M5
- 状态:单位覆盖(
renderer-branding.test.mjs);场景已记录
E2E-047:保留、折叠、切换和关闭多个项目选项卡
- 先决条件:项目 A 和 B 各至少有一个持久会议; 两个路径均未存档;还存在临时会话。
- 步骤: 1) 从“设置”→“项目存档”打开项目 A。 2)打开项目B而不关闭 A.3) 单击 A 的 V 形、文件夹、标签和尾随目录行 依次披露击中区域到 collapse/expand 即可;使用 B 的目录行 激活和崩溃B;验证
+和溢出不会切换 B. 4) 悬停并 键盘焦点 A 的项目标题并确认完整路径已公开;打开 A的项目溢出或者右键菜单选择打开文件夹;确认 对话溢出不再提供打开文件夹。 5) 选择A的对话。 6) 关闭 B。 7) 重新启动应用程序。 8) 从“设置”→“项目存档”重新打开 B。 - 预期:A 和 B 在 a 中呈现为单独的精确路径侧边栏组 紧凑的连续列表,每个目录公开时有一个键盘停止; A 行中的每个非操作点仅切换 A,项目操作出现在 hover/focus 不带移位标签,项目标题 hover/focus 路径显示 A 的完整绝对路径,打开文件夹仅是项目菜单操作并打开 A 在系统文件管理器中,崩溃并重新启动后仍然存在; 激活群组或其对话 清除以前可见的记录,更新选定的工作区并 会话绑定,然后仅加载所选项目的会话; 暂时保持分离;关闭 B 仅删除其保留的选项卡,并且 既不删除其项目行也不删除会话;重新打开B恢复相同 会话无需重复。
- 链接规格:
04-ux/01-ui-ia.md、04-ux/08-component-spec.md、04-ux/09-interaction-patterns.md、ADR 0016 - 接受:C(切换会话)、D(工作空间)、F(本地演示) 坚持)
- 里程碑:M5
- 状态:单元覆盖(
sidebar-preferences.test.mjs用于保留路径 和崩溃持久性);完整的 UI 场景草稿
E2E-048:固定、存档、恢复和排序 project/conversation 行
- 先决条件:两个保留的项目包含不同的对话 标题和 created/updated 时间戳;存档视图最初被禁用。
- 步骤:1) 检查静态的会话和项目标题操作。 2) 将鼠标悬停在每个标题上并通过键盘聚焦每个操作来确认控件 无需移动标签即可显示。 3) 检查
Sessions工具栏并验证 该排序出现在新聊天之前。 4) 打开排序并检查其位置, 然后依次选择“最近更新”、“创建日期”、“最早的在前”和“名称”。
- 固定一个项目和一个对话。 6) 归档另一个对话 和项目。 7) 启用显示存档并恢复两者。 8) 重新启动应用程序。
- 通过不同的删除操作删除一次性对话。
- 预期:部分创建和排序控件在休息时视觉上很安静, 在工具栏悬停或键盘焦点上显示;项目
+和溢出操作 遵循相同的规则而不改变标签。排序优先于新聊天 会话工具栏;排序菜单保持内容大小,打开触发器 向右而不向左翻转,并且 session/project/section 主体级菜单使用与 窄视口宽度上限。固定行保持在前面 每个选定的二级订单下未固定的行数;每种排序都会产生 有记录的稳定订单;归档行从默认视图中消失,但 保留 transcripts/project 记录并重新出现在 Show archived 中;恢复 将它们返回到选定的顺序;归档活动行选择一个可见的 非存档后备或创建记录的空后备而不是 留下隐藏的活动上下文; pin/archive/sort 选择在重启后仍有效;仅 删除会删除一次性持久会话。旧版manual首选项 安全加载,不会暴露或暗示拖动重新排序工作流程。 - 链接规格:
03-runtime/04-data-storage.md、04-ux/01-ui-ia.md、04-ux/08-component-spec.md、04-ux/09-interaction-patterns.md - 接受:C(会话组织),F(持久性)
- 里程碑:M5
- 状态:单位覆盖(元数据为
sidebar-preferences.test.mjs, 过滤和排序行为);完整的 UI 场景草稿
E2E-048A:项目会话在最近十行之后列出折叠
- 前提:一个保留项目包含十个以上耐久 具有不同更新时间戳的会话;侧边栏使用默认值 最近更新的排序;另一个保留的项目有十个或更少的会话。
- 步骤:1) 检查大型项目的会话行并对其进行计数。 2) 选择 加载 N 更多... 控件。 3)将排序切换为名称并检查 扩展前的同一组。 4) 重新启动应用程序并检查组 再次。
- 预期:该组默认显示正好十个会话行加上一个 再加载 N 个… 控件(N = 剩余会话数)样式类似于 按时间分组的溢出;这十行是活动排序中的第一行 顺序,因此固定行永远不会被推到未固定行和名称排序后面 按字母顺序折叠前十个之后的所有内容;选择加载更多 展开完整的时间分组列表 (Yesterday/Previous 7 days/Previous 14 days/Older 标头出现(如适用),并且控件消失; 扩展按组进行,并在重新启动时重置(不持久);该项目 十个或更少的会话显示没有折叠控制。
- 链接规格:
04-ux/01-ui-ia.md、04-ux/09-interaction-patterns.md - 接受:C(会议组织)
- 里程碑:M5
- 状态:场景已记录
E2E-049:后台会话保留其原始工作空间
- 前提条件:保留项目A和B;每个都包含一个会话 Agent 模式;两个工作区都包含具有相同内容的不同标记文件 相对名称。
- 步骤:1) 在会话 A 中,开始一轮读取标记并执行 权限控制的长期运行工具。 2)当A运行时,激活项目 B 并打开会话 B。 3) 读取 B 的标记并仅允许 B 中的工具。 4) 等待 两个回合都完成。 5) 打开临时会话并尝试 工作区所需的工具。
- 预期:切换选项卡不会中止任何转动; A的工具cwd/path沙箱 保留项目 A,B 保留项目 B; A 的活动和赠款从来没有 出现在B的transcript/session中;每个侧边栏行报告自己的 running/completed 状态;临时会话不继承任何项目并且 接收
WORKSPACE_REQUIRED;返回 A 恢复 A 的已完成状态 成绩单。 - 链接规格:
02-architecture/01-architecture.md,03-runtime/02-agent-runtime.md、03-runtime/03-tools-and-permissions.md、03-runtime/06-host-rpc-protocol.md,03-runtime/10-session-state-machine.md、ADR 0016 - 接受:C(并行会话)、D(工作区)、E (tool/permission 隔离)、安全(工作空间边界)
- 里程碑:M5
- 状态:单位覆盖(
rpc::tests表示项目绑定、临时和 缺少会话工作区解决方案);完整的多回合UI场景草稿
E2E-050:思考选择器遵循精确的模型功能
- 先决条件:一种编目推理模型,一种非推理模型, 以及一个未知的自由格式模型 ID。
- 步骤: 1) 依次选择每个 provider/model。 2)检查输入框 Agent / Plan / Goal 旁边的控件。 3)打开Thinking触发器并选择多个 支持的级别。 4) 检查未知模型的菜单和提供商设置。
- 预期:推理模型立即显示当前的思维水平 Agent / Plan / Goal 的右侧,仅将其稀疏支持级别公开为 按规范顺序的单列列表,用尾随标记所选行 检查,不公开 inherit/default 行,调整菜单大小以适应其内容,而无需 超过 160px 或可用视口,截断过长标签并关闭 选择后的菜单。非推理模型不显示思维触发器。 每个级别都来自 pi 选择的模型记录。未知模型曝光 既不是思维触发器,也不是启用思维行动,并且提供商 设置不公开 reasoning/level 覆盖。刷新发现的模型 数据无法取代 pi 的已知模型语义或为 pi 发明功能 未知模型。
- 链接规格:
03-runtime/11-provider-model-system.md,03-runtime/12-provider-config-schema.md,03-runtime/13-model-catalog-and-selection.md、ADR 0018、ADR 0027 - 验收:B(模型配置),质量
- 里程碑:M5
- 状态:单元覆盖(
thinking-ui.test.mjs,代理运行时能力测试);完整的 UI 场景草稿
E2E-051:思考水平在会话中持续存在
- 先决条件:具有推理能力的会话空闲。
- 步骤: 1) 选择
high。 2) 改变Plan/Goal/Agent模式而不改变 思维水平。 3) 重新启动应用程序并重新打开会话。 4)切换到 另一个会议然后回来。 - 预期:每次配置更新都会发送完整的会话配置;
high在权限模式更改、会话切换、主机重新加载和 应用程序重新启动。 v2 数据库将相同字段迁移到off,而不会丢失转录本。 - 链接规格:
03-runtime/04-data-storage.md,03-runtime/06-host-rpc-protocol.md、04-ux/08-component-spec.md、ADR 0018 - 接受:F(坚持)
- 里程碑:M5
- 状态:单位覆盖(主机 schema/session 测试、
thinking-ui.test.mjs);完全重启场景草稿
E2E-052:思维水平达到圆周率要求
- 先决条件:具有稀疏性的具有仪器推理能力的提供商 级别设置和请求捕获;一个会话配置在上方和下方的间隙。
- 步骤:1) 选择每个可用级别并运行提示。 2) 种子 不支持的存储级别并再次运行。 3) 用 pi 目录重复 非推理模型。
- 预期:主要使用会话的实际模型 ID 解析功能; Composer、main、sidecar 和 pi 使用相同的 upward-first/downward-second 夹子; pi 接收有效级别,非推理模型接收
off。特定于模型的请求语义,包括自适应思维和off是否可表达,匹配固定的 pi 记录,无需桌面 重写。 - 链接规格:
03-runtime/01-ipc-protocol.md,03-runtime/02-agent-runtime.md、03-runtime/13-model-catalog-and-selection.md、ADR 0018、ADR 0027 - 接受:B(模型配置),C(聊天和流)
- 里程碑:M5
- 状态:单元覆盖(代理运行时 prompt/clamp 测试);集成场景草案
E2E-053:思考与答案分开
- 先决条件:提供商在回答之前和之间发出思考增量 三角洲。
- 步骤:1) 开始交替使用浅色和深色主题。 2) 观察 仅思考阶段。 3)让答案完整。 4)切换披露, 测试键盘焦点、启用减少运动并使用复制答案。
- 预期:在仅思考流媒体期间打开文字记录;一开 思考披露更新,没有空答案泡沫或重复 工作指示器。该披露使用了文字记录表面、主题标记、 Sparkles/chevron 触发器,以及左规则而不是插入卡; 折叠的内容留下焦点遍历,减少运动会禁用闪烁 和过渡。最终答案markdown单独渲染;复制答案 不包含思考文本。
- 链接规格:
03-runtime/01-ipc-protocol.md,04-ux/07-ui-design-system.md、04-ux/08-component-spec.md、ADR 0018 - 验收:C(聊天和直播),质量
- 里程碑:M5
- 状态:单元覆盖(
thinking-ui.test.mjs,代理运行时事件测试);全流场景草稿
E2E-054:存储的思维无损重新加载
- 先决条件:完整的辅助消息包含推理和 最终答案块;另一个仅包含推理。
- 步骤:1) 完成两个回合。 2) 重新启动 host/app。 3)重新打开 会议。 4)检查搜索结果和答案副本。
- 预期:主机返回相同的单独
thinking和contentreload/import/replace 往返后的值;两条消息均保留 可见;搜索和答案副本排除推理。 - 链接规格:
03-runtime/04-data-storage.md,03-runtime/06-host-rpc-protocol.md、04-ux/08-component-spec.md、ADR 0018 - 接受:C(聊天和流),F(持久)
- 里程碑:M5
- 状态:单位覆盖(主机 message/import 测试、
thinking-ui.test.mjs);完全重载场景草稿
E2E-055:不受支持的提供商安全过渡夹
- 先决条件:
max上推理提供商的会议;目标 提供商包括非推理和稀疏级别的变体。 - 步骤:1)切换到非推理提供商。 2)跑一圈。 3)开关 到前一个级别周围的稀疏变体。 4)发送malformed/legacy 有效载荷缺乏能力或思维领域。
- 预期:非推理持续存在并发送
off;稀疏变体选择 到处都是相同的最近水平;失踪的田地安全回落; 畸形思维不会被渲染,也不会污染答案内容。 - 链接规格:
03-runtime/01-ipc-protocol.md,03-runtime/13-model-catalog-and-selection.md、04-ux/08-component-spec.md、ADR 0018 - 验收:B(模型配置)、C(聊天和直播)、质量
- 里程碑:M5
- 状态:单位覆盖(
thinking-ui.test.mjs,主机验证测试);完整的 UI 场景草稿
E2E-056:工作面板外壳对接和持久化
- 先决条件:应用程序在任何工作区状态下运行。
- 步骤: 1) 重新启动并检查标题栏和应用程序菜单;确认 面板开始关闭。按 Cmd/Ctrl+J 并检查空面板标题 和上下文菜单,然后再次按下以确认打开状态是幂等的 并且没有创建任何选项卡。 2)打开两个不同的文件工件,再次打开相同的第一个文件, URL 预览和完整的命令工件。 3)打开header的统一 上下文菜单:验证四个工具以固定顺序出现一次,并且处于活动状态, 打开-非活动和关闭状态,并且出现转录打开的资源 仅在第二部分。 Open/select 每个工具都带有指针和键盘, 重新打开已有 URL 的浏览器并确认 URL 仍然存在,然后执行 具有 ArrowDown/ArrowUp/Home/End 的行(焦点必须跳过关闭按钮),关闭 删除非活动行并确认菜单保持打开状态并将焦点放在 邻居,按 Esc 键并确认焦点返回到触发器,然后关闭 标题中的活动项目。确认正确的操作簇停留在 最短和最长标签的标题右边缘。 4) 关闭活动的中间和边缘项目 并验证邻居选择。 5) 使用唯一的会话窗格折叠控件和 触发另一个神器。 6) 在会话 A 中,让面板保持打开状态,并显示多个 选项卡和浏览器资源;切换到会话 B,创建不同的选项卡集, 然后在A和B之间反复切换并选择一个没有活动的项目 谈话。在不可见会话中生成背景工件。 7) 将左边缘手柄拖动到244px以下和720px以上;验证指针向下 不跳过分隔线,使用 Escape 取消一个手势,然后聚焦 处理并执行 Arrow/Shift+Arrow/Home/End。提交不同的宽度 浏览器处于活动状态。 8) 在有足够工作区域的显示器上,记录MainChat宽度, 本机边界和打开时的
window/setWorkPanelReservation结果, 重复相同的开放目标,提交分隔线宽度,折叠, 重新打开并关闭最终资源。浏览器在 Windows 上处于活动状态时, 一边观察整个无框窗户,一边重复折叠。 9) 带面板 打开,从左右边缘调整本机窗口的大小;之后重复 切换侧边栏。 10) 在太窄的工作区域上重复 open/resize/collapse 提供完整的预订。 11) 最大化时打开或折叠 全屏,然后恢复正常。 12) 在显示之间移动普通窗口 不同的工作区域,更改活动显示的工作区域几何形状,以及 在一个不变的工作区域内执行普通动作;包括过渡 窗口管理器压缩并重新定位外部窗口之前的位置 显示更改回调。 13) 在打开时注入一项被拒绝的预订 以及折叠时的一个,然后重试每个操作。 14) 发送字符串、布尔值、 空、小数和超出范围的预留有效负载。 15) 重新启动。 - 预期:启动时不显示面板、欢迎选择器、固定工具按钮或 titlebar/menu 启动器。 Cmd/Ctrl+J 打开活动会话的面板 无需创建资源选项卡即可提交宽度;重复它是幂等的, 如果没有活动会话或“设置”处于活动状态,则快捷方式不会执行任何操作 打开。每个工件自动打开停靠的第三列并创建或 激活一种资源;文件资源是路径键控且重复的资源 去重复。打开、折叠和 关闭动画面板的 width/flex 分配及其有界 opacity/slide,因此 MainChat 连续重排,无需预动画跳转。 打开面板、折叠面板或调整分隔线大小 更改操作系统窗口大小 - 仅 MainChat 在内部回流 固定客户区 (ADR 0033)。一旦面板打开,一个统一的 上下文触发器会打开一个下拉列表,其中首先以固定的方式列出四种工具 订单,填充加 2px 边缘标记作为活动行,点作为打开 不活动的,每个打开的行在一个 始终保留的尾随槽;第二部分仅出现在分隔线之后 对于转录打开的资源(完整路径工具提示,每个项目关闭),所以没有 条目被列出两次。菜单淡入超过 ≤4px,并且在以下状态下保持静态 减少运动。 Arrow/Home/End 仅跨行移动焦点并跳过关闭 按钮,触发器上的 ArrowDown/ArrowUp 在 active/last 行上打开, Delete/Backspace 关闭焦点行,同时菜单保持打开状态,焦点位于 它的邻居,并且 Escape/Tab/selection 将焦点恢复到触发器。重新开放 已打开的工具会激活它并保留其浏览器 URL。右边的 无论标签如何,操作簇都保持固定在标题的右边缘 长度。打开菜单 暂时隐藏本机浏览器预览,因此它永远不会被遮挡。的 鞋底 折叠控件位于会话窗格的右上角,而不是内容标题中。 主动关闭选择右邻居,然后选择左邻居;关闭最后一个选项卡会隐藏 面板。折叠保留运行时间 选项卡,但隐藏面板,直到另一个工件重新打开它。宽度夹至 固定的
244px–720px范围,将这些 current/minimum/maximum 值暴露给 辅助技术,并支持记录的键盘步骤。 指针向下保留起始宽度,移动跟随指针 连续,只有当宽度改变时release才提交一次。一个 零移动释放、转义或取消保留了先前的 首选宽度和原生保留。浏览器预览不会拦截 活动分隔线拖动。 A 和 B 独立恢复其运行时打开状态、有序选项卡、活动状态 选项卡和浏览器资源;在没有积极对话的情况下选择一个项目 隐藏面板,并且没有相关资源跨越 session/workspace 上下文。 后台工件仅更新其保留的上下文,而不会更改 可见预订。 在退出动作之前,本机浏览器预览会与窗口分离。开 Windows 码头通过其有界的出口幻灯片保持不透明,并折叠 在本机边界时不产生 white/full-pane 闪存或过时的预览帧 返回到基础宽度。 重启后仅恢复{width};每个会话的打开状态、选项卡、 活动选项卡和浏览器资源重置。打开的面板保持在原来的位置 通过原生边缘和侧边栏更改来提交宽度;这些手势调整大小 仅限 MainChat,永远不会重写首选项。正常状态下,打开返回{requested: committedWidth, reserved: committedWidth}和 grows/shifts 本机窗口位于工作区域内,因此 MainChat 宽度保持不变。重复 目标是空操作。分隔符提交更新目标一次。崩溃和 最终关闭返回{requested: 0, reserved: 0}并对称恢复 基边界和 x 位置。在受限工作区域,reserved报告所有requested以下可添加宽度;面板保持固定并且仅 MainChat 弥补了缺口。 Maximized/fullscreen 调用保留最新的 请求的目标而不改变几何形状,然后在返回时协调一次 正常。 Display/work-area 更改使同一目标与当前目标一致 可用宽度并更新本机最小值;一内的普通运动 未更改的工作区域不会重新应用几何体。系统压缩或 显示转换期间的重定位不会覆盖已确认的基数 边界,返回到更宽敞的显示会恢复之前的聊天宽度。 重新启动恢复用户的窗口大小(本机预留始终为0, ADR 0033)。格式错误的预留有效负载失败并显示INVALID_ARGUMENT和 从不强迫。被拒绝的预订保留 最后一次确认的小组演示,直到后来成功请求;一个 被取代的成功不能带来陈旧的表现。没有过渡产生 第二次调整大小或位置漂移。 以前的上下文面板覆盖不再存在。 - 链接规格:
03-runtime/01-ipc-protocol.md、04-ux/01-ui-ia.md、04-ux/07-ui-design-system.md、04-ux/08-component-spec.md、04-ux/09-interaction-patterns.md、ADR 0032、ADR 0068、D163、D207 - 接受:F(坚持),质量
- 里程碑:M5
- 状态:单位覆盖(
work-panel-resize.test.mjs,work-panel-window.test.mjs、work-panel-presentation.test.mjs、work-panel.test.mjs);完整的 UI 场景草稿
E2E-057:消息拥有的审阅历史记录可以安全提交并回滚
- 先决条件:具有可写工作空间的项目绑定 Agent 会话; 不需要 Git 存储库。
- 步骤: 1) 要求活动代理编辑现有文件并创建新文件 在会话 A 中归档。2) 展开活动组并检查每张复习卡 直接在其相应的工具行之后;验证每张卡的启动情况 崩溃,其 added/modified 状态和 +/- 计数在 标头,然后展开它以验证确切的帅哥。 3)提交文件 在应用程序外部,关闭并重新打开“审阅”面板,然后重新加载会话 A。 4)验证相同的卡 计数仍然存在,因为它们来自转录消息。 5)使用 卡的回滚操作并验证创建的文件是否已删除或以前的 文件字节被恢复。 6) 在应用程序外部再次编辑该文件并重试 回滚;检查冲突结果并验证后面的字节是否保留。 7) 切换到会话 B 和后台项目会话,然后返回到 A。8) 重复失败、拒绝和临时写入。
- 预期:每个成功的工作区 Write/Edit 都会创建一个消息拥有的 查看记录和一张相邻的键盘可访问卡;该卡从来都不是 bottom/global 条目。每张评论卡,内联和评论选项卡中,都是 默认折叠并按需扩展。 Review 选项卡列出了 A 按时间顺序记录的更改,独立于 Git 状态、存储库 存在、提交状态、焦点刷新、 或工作空间切换。添加、修改和删除状态加行 当有有限证据可用时,会显示 additions/deletions 和帅哥。 成功回滚会将卡更新为已回滚并在重新启动后仍然有效。 工具后文件更改会返回冲突并且不会覆盖它。失败的, 被拒绝,并且刮擦写入不会创建卡;会话 B 不能继承 A 的会话 记录。二进制或超大快照显示有限元数据并禁用 当先前的字节没有保留时回滚。
- 链接规格:
03-runtime/01-ipc-protocol.md§13a,03-runtime/03-tools-and-permissions.md§4c,04-ux/08-component-spec.md§5、ADR 0043 - 验收:D(工作空间),质量
- 里程碑:M5
- 状态:单位覆盖(
chat-review-entry.test.mjs);完整的 UI 场景草稿
E2E-058:交互式终端会话生命周期
- 前提:工作区已打开;成功完成的命令 神器存在。
- 步骤:1) 激活已完成的命令工件以创建终端, 然后运行
pwd和ls。 2) 切换到另一个工件选项卡并返回。 3) 通过另一个命令工件折叠并重新打开。 4) 拖动调整大小 面板并切换 light/dark 主题。 5) 运行exit。 6) 通过以下方式重新启动 覆盖按钮。 7) 退出应用程序并检查孤立 shell。 - 预期:shell 作为登录名在工作区目录中启动 带有256色TERM的外壳; output/scrollback 保留选项卡开关和 面板关闭(重新连接相同的 PTY);调整列大小而不会出现乱码; 主题切换重新着色终端;
exit显示已结束的会话 重新启动的覆盖层会启动一个新的 shell;应用程序退出会杀死所有 PTY;与 没有工作区,选项卡显示其空状态,并且没有 PTY 生成。 - 链接规格:
03-runtime/01-ipc-protocol.md§13a、ADR 0019 - 验收:D(工作空间),质量
- 里程碑:M5
- 状态:草案(手动)
E2E-059:嵌入式浏览器预览隔离和覆盖
- 前提条件:本地开发服务器正在运行;存在 URL 或 BrowserPreview 工件。
- 步骤: 1) 激活工件,输入
localhost:<port>(不带方案),然后提交。 2) 导航站点链接;使用 back/forward/reload/stop。 3) 触发window.open弹出窗口和权限请求页面(例如通知 提示)。 4) 打开全局搜索,然后打开设置。返回聊天 并触发内联工具权限卡。 5) 切换到另一个面板选项卡 然后回来;关闭面板。 6) 使用开放式外部。 - 预期:无方案输入标准化为 http;导航状态(URL 栏, back/forward 启用、加载微调器)镜像页面。弹出窗口打开于 默认浏览器(绝不在应用程序内);许可请求被拒绝; 非 http(s) 导航被阻止。预览隐藏在每个遮挡下 覆盖并卸载时,随后以正确的边界重新出现。安 内嵌权限卡不会隐藏或重新挂载预览; resize/drag 保持视图与占位符矩形对齐。 Open-external 在默认浏览器中启动当前的 URL。景色 使用隔离的持久分区(应用程序外壳中没有会话流失)。
- 链接规格:
03-runtime/01-ipc-protocol.md§13a、ADR 0019 - 验收:质量、安全
- 里程碑:M5
- 状态:草案(手动)
E2E-060:文件选项卡浏览停留在工作区中
- 先决条件:具有嵌套源文件工件的工作区,大型 (>512KB)、图像和二进制文件。
- 步骤:1) 激活每个文件工件并验证不同的路径键控 标头切换器中的资源;浏览树,展开嵌套文件夹。 2)开源 文件、图像、二进制文件和大文件。 3) 使用在 Finder 中显示。 4) 尝试通过 devtools IPC 进行遍历读取 (
../outside)。 5) 开关 工作区。 - 预期:目录懒惰地列出,文件夹首先,带有
.git/node_modules/ 隐藏构建输出;文本以语法高亮显示 (上限为 5000 行),图像预览内联、二进制和超大文件 显示后备并显示仍然可用。遍历尝试是 被INVALID_ARGUMENT拒绝;无工作空间→空状态;切换 工作区重置树和查看器。 - 链接规格:
03-runtime/01-ipc-protocol.md§13a、ADR 0019、03-runtime/15-workspace-ignore-rules.md - 验收:D(工作空间),安全
- 里程碑:M5
- 状态:单位覆盖(
fs-panel-guard.test.mjs);完整的 UI 场景草稿
E2E-059a:记录消息板遵循 WorkBuddy 密度
- 前提条件:一个会话至少包含一个简短的用户提示,一个 更长的用户提示和完整的助理答案;浅色和深色主题 可用。
- 步骤:1)以深色主题打开会话。 2)检查用户和助手 静止和悬停时的行。 3)启动流媒体助理应答。 4) 开关 点亮主题并重复。 5) 使用键盘聚焦复制控件。
- 预期:用户回合右对齐,主题中性软板封顶 接近 560px,源自每个主题的主要文本墨迹而不是重音 色调,带有微妙的边框;助理答案保持透明全角 720px 内容带中的散文。行间距更密集(~10px)。复制芯片有 静止时隐藏,出现在 hover/focus-within 上,并在下面保持右对齐 用户轮流。流媒体助理的答案显示出轻微的口音左规则,没有 拳击整个答案。两个主题都对用户保持可读性对比 板。
- 链接规格:
04-ux/07-ui-design-system.md,04-ux/08-component-spec.md、04-ux/10-workbuddy-benchmark-ux.md - 验收:C(聊天流),质量
- 里程碑:M5
- 状态:单位覆盖(
transcript-style.test.mjs);全视觉场景草稿
E2E-060b:镀铬中性灰色调
- 先决条件:应用程序在深色和浅色主题中运行;插件页面和 可以使用 Markdown links/blockquotes 聊天。
- 步骤:1) 检查对焦环、主按钮、切换开关、选定的 会话环,插件市场主要 CTA。 2)打开助理答案 链接和块引用。 3)切换主题并重新检查。
- 预期:不再保留蓝色品牌口音。交互式口音、Markdown links/rules,插件主要操作通过中性灰色解析 重音标记(
white/gray深色、深色墨水浅色)。插件 installed/market UI(选项卡、搜索、卡片、权限模式和主要/ 辅助按钮)仅使用--ds-*令牌,在 任一主题;按钮表面和墨水在深色模式下仍然可见。语义学 success/warning/error 颜色保持不变。 - 链接规格:
04-ux/07-ui-design-system.md,04-ux/08-component-spec.md - 验收:质量
- 里程碑:M5
- 状态:单位覆盖(
neutral-accent.test.mjs,plugins-page-style.test.mjs);视觉场景草稿
E2E-060c:辅助 Markdown 散文层次结构和代码 chrome
- 先决条件:完整的助理答案,包含标题、 blockquote,GFM 表,带有语言标签的围栏代码块,内联 代码、任务列表和远程图像链接;提供浅色和深色主题。
- 步骤:1)以深色主题打开会话并滚动答案。 2) 将鼠标悬停在代码块复制控件和表行上。 3)拓展思维 包含降价的披露。 4)切换到浅色主题并重新检查 内联代码、块引用规则和代码卡的对比。
- 预期:答案散文使用
.prose-chat层次结构(h1–h6 斜坡, 带重音的块引用、细线边框内联代码、zebra/hover 表 shell,带有等宽语言标签的插入代码卡)。思考散文留下来 secondary/smaller 并且不会合并到答案中。两个主题都保留 可读对比度;复制仍然复制原始栅栏文本。 - 链接规格:
04-ux/07-ui-design-system.md,04-ux/08-component-spec.md§8.7 - 验收:C(聊天流),质量
- 里程碑:M5
- 状态:单位覆盖(
user-select.test.mjs、thinking-ui.test.mjs); 全视觉场景草稿
E2E-061:用户消息纯文本布局在包装和重新加载中仍然存在
- 先决条件:已配置提供商;输入框可以接受多行输入 通过 Shift+Enter(或禁用 Enter-发送)。
- 步骤:1) 编写一个三行提示符,其中包含两个硬换行符和一个 URL 其编码路径比用户板宽。 2)发送。 3)检查用户 文字记录中出现气泡。 4) 复制用户消息并粘贴到外部 编辑。 5) 重新加载会话。
- 预期:用户板显示三个不同的行(未折叠成 单段)。链接的 URL 包裹在板内,没有水平 溢出,并且每个连续行保持逻辑开始与 第一行而不是居中。复制的文本保留原始内容 换行符。重新加载后,相同的换行符仍然存在。
- 链接规格:
04-ux/08-component-spec.md - 验收:C(聊天流),质量
- 里程碑:M5
- 状态:单位覆盖(
transcript-style.test.mjs);全视觉场景草稿
E2E-060d:助理元芯片、上下文检查器和重试操作
- 前提:完整的辅助消息包含modelId和token 用法;另一条已完成的助理消息有内容但没有用途。
- 步骤: 1) 打开会话。 2) 将鼠标悬停在已完成的辅助回合上 用法,然后使用键盘将其焦点放在上下文检查器触发器上。 3)检查 面板的剩余令牌标题、已用百分比和计量、 pi-ai-resolved 模型上下文窗口大小,精确 input/output/cache/reasoning 故障,报告缓存读取元数据时的缓存命中率,已完成 生成 tokens/s 值、源徽章以及每个 独特工具类型的聚合调用计数和估计的 argument/result 令牌 分配。 4) 滚动文字记录,直到触发器接近顶部、底部和 右视口边缘,并在面板打开时调整窗口大小。 5)点击 空闲时重试该回合。 6) 确认回合不使用仍优惠 重试并忽略检查员。
- 预期:模型徽章和紧凑的上下文检查器出现在已完成的情况下 助手在数据存在时应答;触发器显示剩余容量并且 低空间 warning/error 状态,而悬停和键盘焦点会暴露 相同的完整令牌面板。该小组的确切提供商和估计工具 来源明显区分,其缓存命中率采用缓存提示 令牌除以所有报告的提示令牌(缓存加上未缓存);当 缓存读取元数据不存在,速率被省略而不是推断。其 context-window Total 与代理运行时使用的模型元数据匹配; 工具行按首次看到的顺序显示每种独特的工具类型,重复聚合 呼叫,包括呼叫次数和累积持续时间,并明确标记其 估计。一代人 速率仍然是已完成的回合值,并且在流式传输期间不会更新; 重试重新发送最近的先前用户提示,并在回合时被禁用 正在运行;门户面板在视口中保持完全可见, 从未被文字记录滚动剪辑,并在之后跟随触发器 滚动或调整大小;文案仍然排除思考文本。
- 链接规格:
04-ux/08-component-spec.md,04-ux/10-workbuddy-benchmark-ux.md、03-runtime/01-ipc-protocol.md - 验收:C(聊天流),质量
- 里程碑:M5
- 状态:单位覆盖(
transcript-style.test.mjs,context-usage.test.mjs,运行时使用映射);完整场景草稿
E2E-061a:重新生成替换当前回合
- 前提:一个会话有用户 A → 助理 A → 用户 B → 助理 B。
- 步骤: 1) 将鼠标悬停在助手 A 上,然后单击“重新生成”。 2)等待新的 转动完成。 3) 重新加载会话。
- 预期:脚本截断了助理 A / 用户 B / 助理 B 在重做开始之前;只剩下用户 A 加上新的 assistant/tool 尾部。 重新生成的答案不会留下其上方的旧分支。重新加载保持 仅截断的分支。
- 链接规格:
04-ux/08-component-spec.md,03-runtime/01-ipc-protocol.md、03-runtime/04-data-storage.md - 接受:C(聊天流),F(持久)
- 里程碑:M5
- 状态:单元覆盖(store/main 截断接线测试);完整场景草稿
E2E-062:重新生成历史寻呼机恢复之前的变体
- 先决条件:助理答案至少重新生成一次的会话。
- 步骤: 1) 在完成的辅助回合上单击 Retry/Regenerate。 2) 替换回合开始时观察可见的 root 用户气泡, 完成后。 3) 切换到以前的版本。 4) 向前切换 再次。 5) 重新加载会话。
- 预期:根用户气泡仍然可见并显示 一旦该行悬停或在其操作工具栏中显示
current / total寻呼机 专注;默认情况下,工具栏(包括寻呼机)是隐藏的。重试确实如此 不要移动选择器或将其与气泡分离。切换恢复 已存档 assistant/tool 分支到位。重新加载保留活动变体 以及完整的修订集。 - 链接规格:
04-ux/08-component-spec.md、03-runtime/04-data-storage.md - 接受:C(聊天流),F(持久)
- 里程碑:M5
- 状态:单元覆盖(
sessions::tests::save_and_activate_message_revision,架构 v4 迁移);完整场景草稿
E2E-063:空荡荡的家让主要任务表面保持专注
- 先决条件:应用程序在空聊天主页(无文字记录)上运行 和黑暗主题;窗口大小可以调整为~1200×690 和~900×640。
- 步骤:1)打开空房子。 2)确认英雄包含安静标志, 本地化标题和简短的支持台词。 3)确认没有开发者启动器 渲染卡片或上下文快速操作行。 4) 拒绝新手引导并 再次检查。 5)在另一个主题中重复。 6) 调整为较短的高度并 如果需要,滚动内容区域。
- 预期:默认的空状态使英雄和底部输入框保持不变 视觉锚点,可选的入门作为唯一的附加内容。 忽略检查表不会留下任何空白间隔。输入框仍留在 底部不覆盖英雄或清单,并且短窗口保留了每个 可通过滚动到达内容块。
- 链接规格:
04-ux/01-ui-ia.md、04-ux/07-ui-design-system.md、04-ux/08-component-spec.md、08-meta/decisions-log.md(D111/D131/D204/D206) - 验收:质量(布局完整性)
- 里程碑:M5
- 状态:单位覆盖(
home-empty-layout.test.mjs);完整的 UI 场景草稿
E2E-094:主动回合保持下转录本表面清晰
- 前提:确定性代理可以发出思考,工具start/end, 流式传输应答、许可和终端事件以实现持久会话;一个 第二个会话可以在后台运行。
- 步骤: 1) 在可见会话中开始一轮。 2)观察成绩单 当代理思考、使用工具并传输答案时。 3) 触发 许可请求并检查批准卡。 4)切换到第二个 会议,而第一个会议仍在继续。 5) 之后返回第一个会话 完成。
- 预期:没有一般理解、工作、检查或完成 当回合处于活动状态时,卡片会出现在成绩单下方。助理和 工具行保持内联;只有实际的权限请求才会呈现 可操作的卡。后台活动永远不会改变可见会话, 成绩单、输入框焦点或项目。
- 链接规格:
04-ux/08-component-spec.md,04-ux/09-interaction-patterns.md、03-runtime/10-session-state-machine.md - 验收:C(聊天流)、质量(交互和可访问性)
- 里程碑:M5
- 状态:单位覆盖(
active-turn-surface.test.mjs);完整的 UI 场景草稿
E2E-095:终端故障暴露恢复而没有成功卡
- 先决条件:确定性提供商可以从失败中恢复 目录
Read和Glob,通过工作区编辑完成一圈,然后失败 另一轮出现可重试错误;该会话有一个可见的输入框。 - 步骤: 1) 运行失败-读取然后成功-Glob 恢复轮次并 检查其活动组。 2) 完成工作区编辑回合。 3) 确认 没有出现成功结果卡并检查内联审核卡 紧接在更改工具行之后。 4)展开内联卡并验证 它的帅哥。 5)承诺 编辑好的文件并确认录音卡仍然存在,然后使用回滚 一次。 6) 触发可重试失败。 7) 检查故障卡,然后 选择重试。 8) 启动另一个新提示并检查旧卡。
- 预期:恢复的回合使失败的读取在其自己的行上可见, 将包含组标记为已处理,完成其会话结果,并且 显示无故障卡。完成使用成绩单和内联审核卡 作为其证据,无需添加“任务完成”卡。文件状态、计数、 提交后,帅哥仍保留在相邻卡上,并受保护的回滚 恢复工具前的状态。失败表明现有的工作仍然存在, 公开重试和继续,重试保留最新的提示。新的转机 清除之前的故障卡;中止不会创建失败结果副本。
- 链接规格:
04-ux/08-component-spec.md,04-ux/09-interaction-patterns.md、03-runtime/10-session-state-machine.md、 ADR 0069 - 验收:C(聊天流)、质量(完成和恢复)
- 里程碑:M5
- 状态:单位覆盖(
assistant-turns.test.mjs,interaction-performance.test.mjs、turn-outcome-card.test.mjs);完整的用户界面 场景草稿
E2E-064:持久通知收件箱记录终端任务结果
- 先决条件:存在两个持久会话;确定性提供商可以 完成一回合,失败一回合并出现稳定的错误代码,以及中止一回合 转;通知收件箱开始为空。
- 步骤:1) 聚焦并查看会话 A,然后在 A 中完成一个回合。2) 当 仍然专注于 A,在后台会话 B 中失败。 3) 取消聚焦 窗口并完成 A 中的另一轮。 4) 中止第四轮。 5) 重复每一个 终端 RPC。 6)确认主标题栏没有响铃,然后打开响铃 扩展的侧边栏页脚并在“全部”和“未读”之间切换。 7)标记一 row 读取并确认其会话没有终端侧边栏标记,然后 close/reopen 弹出窗口并重新启动应用程序。 8) 选择其他会话 从其带有终端标记的侧边栏行。 9) 用205生成一个主机装置 符合资格的终端回合。 10) 使用“标记全部已读”,然后“清除”。
- 预期:A 的可见当前完成不会创建任何行。正好两行 存在,最新的优先:未聚焦的 A 完成和背景 B 失败, 带有本地化标签、快照会话标题和 B 的稳定代码。 Abort/repeated 终端调用不创建行。前页脚帮助快捷方式 缺席; 32px 页脚钟形件及其向上开口的弹出框取代了它。 徽章和未读显示确切的未读计数,无需隐式打开 读取行。读取状态和两者 记录在重新启动后仍然有效。行选择标记其已读取并激活其绑定 project/session。该装置准确地保留了最新的 200 行。全部标记 保留零个未读行。选择其他会话会清除其 终端侧边栏标记并标记其任务通知已读;都没有标记 刷新或重启后返回。清除仅清空收件箱并离开 会议、回合和成绩单完好无损。
- 链接规格:
03-runtime/04-data-storage.md,03-runtime/06-host-rpc-protocol.md、03-runtime/01-ipc-protocol.md、04-ux/07-ui-design-system.md、04-ux/08-component-spec.md、08-meta/decisions-log.md(D117/D130) - 验收:C(回合完成)、F(持久)、质量
- 里程碑:M5
- 状态:草案
E2E-065:本机任务通知仅无焦点并激活会话
- 前提:支持原生通知;会议 A 和 B 存在;主窗口可以聚焦、不聚焦、隐藏和最小化。一个 Windows 运行使用 NSIS 安装的应用程序或标准开发命令。
- 步骤:1) 让应用程序专注于 A 并在 A 中完成一个回合。2) 当 仍然专注于 A,在 B 中完成一个回合。3) 在 A 仍然存在时取消应用程序的焦点 当前并完成 A 中的另一回合。 4) 单击 A 的本机通知。 5) 最小化应用程序,再次失败,然后单击其本机通知。 6) 取消应用程序的焦点并中止回合。 7) 重复并抑制本机传递 由操作系统。 8) 在 Windows 上,检查本机通知属性, 通知设置条目、任务栏组、已安装的可执行文件和开始 菜单快捷方式。
- 预期:当前焦点 A 既不创建收件箱行,也不创建本机横幅。 聚焦背景 B 创建一个没有本机横幅的收件箱行。不专心 当前 A 和最小化故障分别创建一个持久行和一个 本地化的本机通知。单击可恢复、显示并聚焦 激活匹配会话之前的主窗口;没有事件打开错误 当前选定的会话。中止不显示两个表面。操作系统抑制确实 不会丢失持久行或出现误导性应用程序错误。每检查一次 Windows系统表面识别
PI-Desktop;无库存 Electron 应用程序 姓名或身份被暴露。 - 链接规格:
03-runtime/01-ipc-protocol.md,04-ux/07-ui-design-system.md、04-ux/09-interaction-patterns.md、08-meta/decisions-log.md(D117/D141) - 验收:C(回合完成),质量
- 里程碑:M5
- 状态:草案
E2E-066:提供程序模型目录在重新启动和离线刷新后仍然存在
- 先决条件:已保存的提供程序已从其返回至少两个模型 发现端点和生成的目录存储在
models中。 - 步骤:1) 退出并重新启动应用程序。 2) 断开提供商端点的连接。 3) 打开顶栏模型选择器。 4)等待后台刷新失败。 5) 使用一个重命名的模型和一个附加模型重新连接端点, 然后更新提供程序配置并重新打开选择器。
- 预期:第一个打开的选择器渲染先前的目录而不启动 来自一个空列表。离线刷新保留每个缓存的条目和 配置模型后备。重新连接后,实时结果更新 渲染器并保留到 Rust 拥有的 SQLite。保留用户定义的模型行 不变,新发现的模型仍然可用 重新启动。
- 链接规格:
03-runtime/04-data-storage.md,03-runtime/12-provider-config-schema.md,03-runtime/13-model-catalog-and-selection.md、04-ux/08-component-spec.md - 验收:B(模型配置)、F(持久性)、质量
- 里程碑:M5
- 状态:单位覆盖(
providers::tests、model-cache.test.mjs);满 restart/offline UI 场景草案
E2E-080:Claude Opus 5 从固定的 pi-ai 目录中解析
- 先决条件:桌面位于
@earendil-works/pi-ai/pi-agent-core^0.82.1+;自定义或与 Anthropic 兼容的提供程序使用 apiStyleanthropic_messages(或与 OpenAI 兼容的chat_completionsanthropic/claude-opus-5)和模型 IDclaude-opus-5。 - 步骤:1) 在顶栏模型选择器中选择
claude-opus-5。 2)打开 思维选择器。 3) 开始一个短回合并检查 sidecar 模型 快照/请求元数据(或单位等效解析路径)。 - 预期:id 映射到固定的 pi 目录记录(1M
contextWindow,适应性思维兼容,已发布的思维水平包括contextWindow/xhigh)。思维控件出现并仅列出这些级别。 提供商设置不能覆盖限制。 pin 中仍然不存在 ID 停留在通用的非推理后备上。 - 链接规格:
02-architecture/02-tech-stack.md,03-runtime/11-provider-model-system.md,03-runtime/13-model-catalog-and-selection.md、ADR 0027、D136 - 验收:B(模型配置)
- 里程碑:M5
- 状态:单位覆盖(
model-capabilities.test.ts);完整的 UI 场景草稿
E2E-067:平台应用程序菜单和窗口镶边
- 先决条件:原生 macOS、Windows 和 Linux 运行程序;内置桌面 应用程序;提供英语和中文语言环境。 Windows/Linux线束可设置
PI_DESKTOP_START_MAXIMIZED=1在启动之前,以便 Main 最大化隐藏 渲染器安装之前的本机窗口。 - 步骤:1) 在 macOS 上,启动
pnpm dev和打包版本。确认 应用程序菜单标题为 PI-Desktop,打开“关于 PI-Desktop”,然后检查 它的名称、版本和图标。然后打开每个系统菜单并调用“新建任务”、“打开” 项目、设置、全局搜索、侧边栏切换、编辑、 zoom/fullscreen、窗口、帮助、日志和检查更新操作。验证 更新状态报告当前夹具版本是最新的。 2) 在 Windows/Linux 上,确认没有出现 File/Edit/View/Window/Help 菜单栏 窗口内部和左侧导航占用了回收的空间 标题栏空间。验证 F10 和 Shift+F10 不被 shell chrome 消耗; 练习新任务、打开项目、设置、关闭窗口、缩放、全屏、 全局搜索(Cmd/Ctrl+K 和 Cmd/Ctrl+Shift+P)、侧边栏和标准编辑快捷方式。调用 从“设置”->“信息”检查更新是否具有相同的状态结果。 3) 关闭macOS窗口,立即调用两个原生菜单 命令,并在替换加载后确认渲染器准备就绪。 验证每个命令的一个窗口和一个传递。 4) 在 Windows/Linux 上,重复 从主聊天、设置和打开的工作面板。与工作面板 打开,确认面板折叠按钮与主面板右侧齐平 分隔线并且不保留 112px 外窗口控制间隙。在 主聊天,发送第一条用户消息并确认其完整的气泡在下面开始 46px 标题栏控制带。打开扩展页面并确认其标题 操作,然后是详细信息表的关闭按钮,也从该区域下方开始, 他们自己点击而不是移动窗口。单击中心加 顶部、底部和 每个右侧控件面向标题栏的边缘可最小化、最大化、 恢复,然后关闭窗口。 5) 开始 当其本机窗口已经最大化时渲染器并检查 初始查询glyph/state。 6) 尝试未知的 menu/window IPC 操作 当窗口存在时以及窗口关闭后。 7) 在其基础上构建每个目标 来自干净的发布主机目录的本机运行器。 - 预期:macOS 开发和打包发布显示 PI-Desktop 作为 本机应用程序标识,并且“关于”面板使用规范 PI-Desktop 图标;两个表面都不会暴露库存 Electron 名称或图标。 macOS 遵循本机菜单约定和加速器。 Windows/Linux 窗口内不显示应用程序菜单;导航和 右侧控件不会与拖动区域、键盘快捷键发生冲突 保持运行状态,并且不存在工作面板启动器。开放式面板 折叠按钮触及主窗格右分隔线,没有插入或 重复的本机对照间隙。检查更新 从 macOS 系统菜单和 设置表面并显示结果的最新状态。更换窗 命令等待渲染器准备就绪,无需 创建重复的窗口或丢失事件。没有主面板、设置面板或工作面板 拖动矩形与保留的控制区域重叠。窗口控件保留 可在其完整的 46 像素高的命中目标上单击,匹配本机状态,并且 有易于理解的名称;第一个用户或助理成绩单行从不 在它们下面绘制,扩展页面标题操作或 插件详细信息表关闭按钮。未知操作失败关闭。每个包装包含 目标本机主机二进制文件(
.exe仅在 Windows 上)。通过这个场景 Windows/Linux 证明 shell 已准备就绪,而不是首次发布资格。 - 链接规格:
03-runtime/01-ipc-protocol.md,04-ux/01-ui-ia.md、04-ux/02-i18n-english-first.md、04-ux/07-ui-design-system.md、04-ux/08-component-spec.md、04-ux/09-interaction-patterns.md、06-delivery/06-release-runbook.md、08-meta/decisions-log.md(D118、D121、D129) - 验收:A(应用程序启动),质量
- 里程碑:macOS 上的 M5; Windows/Linux 上 MVP 后发布资格
- 状态:单位覆盖(
window-menu.test.mjs,development-branding.test.mjs); Electron 引导探针盖 平台桥、本机菜单安装和预渲染最大化 Windows/Linux 上的固定装置;原生视觉场景草稿
E2E-067A:预发行安装发现更新的稳定版本 (D120)
- 先决条件:打包构建,其嵌入式版本是预发布版本,例如 作为
0.2.0-rc.6; GitHub Releases 最新稳定标签较新(例如0.2.2)以及已发布的latest*.yml源。 - 步骤:1) 启动打包的预发行安装。 2) 等待 自动检查或从应用程序菜单调用检查更新/ 设置 → 信息。
- 预期:更新状态报告
available(手动平台)或 通过应用内下载 Windows NSIS / Linux AppImage 取得进展availableVersion等于较新的稳定标签。客户不得举报 最新只是因为没有较新的版本共享相同的rc预发行版 频道。 - 链接规格:
04-ux/09-interaction-patterns.md,05-security/01-security.md、08-meta/decisions-log.md(D120)、 ADR 0022 - 验收:A(应用程序启动),质量
- 里程碑:M5
- 状态:单位覆盖(
auto-update.test.mjs断言allowPrerelease = false);打包发现场景草稿
E2E-067B:双区域设置更新说明和完整变更日志对话框(D164)
- 先决条件:发货的
packages/sharedCHANGELOG 包含对齐的en和zh-CN历史记录稳定;可以切换产品语言。对于 紧凑的更新路径,使用打包或固定更新器状态 编目availableVersion。 - 步骤: 1) 如果没有可用更新,请打开“设置”→“信息”并打开“发布” 笔记。 2) 检查完整的历史记录、当前版本标记、滚动、 以及通过密切控制、逃脱和背景来密切行为。 3)强制或等待 对于更新发现,因此状态为手动
available、应用内downloading, 或downloaded;检查环境横幅和设置更新行,然后 重新打开发行说明。 4)切换UI语言为zh-CN并重新检查,无需 调用新的检查。 5) 在没有版本的情况下重复紧凑更新路径 从目录中。 - 预期:
UpdateState.releaseNotes是普通的多线产品 Main 从双语言环境目录中选择的亮点 - 从来都不是 渲染器提供的 URL。两个表面均显示本地化的“新增内容”块 当注释存在时隐藏它,当注释不存在时隐藏它。区域设置更改刷新笔记 对于相同版本。发行说明操作在每个版本中仍然可用 更新器状态并打开一个本地化的、最新优先的模式,其中包含每个 发布了稳定的条目,并在以下时间确定了当前和可用版本 存在。模态捕获焦点,关闭后恢复焦点,并且不暴露 新的 IPC 域或 Feed 配置。 - 链接规格:
04-ux/06-settings-ia.md、04-ux/09-interaction-patterns.md、05-security/01-security.md、06-delivery/06-release-runbook.md、08-meta/decisions-log.md(D164)、ADR 0022 - 验收:A(应用程序启动),质量
- 里程碑:M5
- 状态:单位覆盖(
auto-update.test.mjs、changelog.test.ts); 打包的UI场景草稿
E2E-068:将对话分叉为独立会话
- 先决条件:空闲项目对话有用户、助理、 思维、工具历史以及至少一种再生变体。一秒钟 源对话正在运行。一个临时对话,两个保留 项目工作区包含不同的同名标记文件。闲置资源 拥有会话范围的工具授权。
- 步骤: 1)用键盘打开空闲对话溢出菜单。 2) 选择创建分支。 3) 附加提示并更改子项的 model/mode。 4)切换可见工作区,返回子工作区,读取标记。 5) 触发先前授予的工具并验证是否请求确认。 6) 重新打开源。 7) 重新启动应用程序并检查两个会话。 8) 打开 正在运行的对话溢出菜单。 9)分叉临时对话 并调用工作区所需的工具。
- 预期:本地化分支标题出现在同一项目组中,并且 以输入框焦点激活。其活性转录物可见且持久 project/provider/model/mode/thinking/permission 配置匹配 源快照,但不存在重新生成寻呼机历史记录。儿童消息和 以后的配置更改不会影响源;两者都可以在重新启动后生存。 正在运行的源操作被禁用。没有回合、通知、工件, 复制权限授予、修订或临时文件。 标记在子项继承的项目下解析;临时孩子 保持无路径并返回
WORKSPACE_REQUIRED。 - 链接规格:
03-runtime/01-ipc-protocol.md,03-runtime/04-data-storage.md、03-runtime/06-host-rpc-protocol.md、04-ux/01-ui-ia.md、04-ux/08-component-spec.md、04-ux/09-interaction-patterns.md - 验收:C(会话)、D(工作空间)、F(持久性)、质量
- 里程碑:M5
- 状态:单位覆盖(
sessions::tests::fork_session_clones_active_transcript_and_configuration,session-fork.test.mjs);完全重启 UI 场景草稿
E2E-071:分叉助理响应而不更改其来源
- 前提条件:一个空闲会话包含两个已完成的 user/assistant 交换,第二个助理响应具有缓存令牌使用元数据。
- 步骤:1) 将鼠标悬停在第一个助理响应上并检查其工具栏。 2) 单击叉子。 3) 确认激活的子项在该响应处结束并附加 提示。 4) 重新打开源并检查它。 5)向孩子附加提示, 重新启动,并检查源和子项。 6) 在源运行时重复此操作。
- 预期:完成的辅助工具栏包含复制、分叉和 仅重新生成 — 不删除也不编辑(D137 将编辑移至用户轮次)。叉子 在源转动期间被禁用。它激活一个单独标题的会话 其历史记录在所选响应处停止;后来的源轮不存在。 源文本、版本历史记录、令牌元数据、后续轮次、运行时和缓存 状态保持不变。继续该孩子仅影响该孩子并且 从它自己的重新映射的转录本中重新播种。
- 链接规格:
03-runtime/01-ipc-protocol.md,03-runtime/04-data-storage.md、03-runtime/06-host-rpc-protocol.md、04-ux/08-component-spec.md、08-meta/decisions-log.md(D134、D137) - 验收:C(聊天 stream/sessions)、F(坚持)、质量
- 里程碑:M5
- 状态:单位覆盖(
sessions::tests::message_scoped_fork_stops_at_selected_assistant_response,session-fork.test.mjs、transcript-style.test.mjs);完全重启 UI 场景草稿
E2E-073:纯图标消息工具栏和编辑用户提示
- 前提条件:一个空闲会话包含两个已完成的 user/assistant 交流;一个用户回合作为斜杠模板调用发送。
- 步骤: 1) 将鼠标悬停在已完成的助手行和用户行上,然后将鼠标悬停在 键盘聚焦每个动作芯片。 2) 在第一个用户提示上选择编辑。 3) 按 Esc 键,重新打开编辑,保存提示不变。 4)重新打开编辑,更改 文本,然后使用 Cmd/Ctrl+Enter 保存。 5)新答案完成后, 使用
current / total寻呼机返回原始交换机并 再次前进。 6) 重新加载会话。 7) 在斜杠命令上选择编辑 转动并检查种子文本。 8) 在回合运行时尝试编辑。 - 预期:每个工具栏芯片仅显示其字形,并带有标签 在悬停和键盘焦点时显示为工具提示;无芯片渲染 标题文本。辅助工具栏提供复制、分叉、重新生成;用户 工具栏提供寻呼机(当存在变体时)、复制、编辑、删除。编辑 用更宽的内联文本区域替换提示气泡;逃脱恢复 气泡不变,并且不变的保存关闭编辑器而不启动 转动。更改后的保存会截断该提示中的文字记录,并传输新的 应答,并在恢复的用户轮上留下
current / total寻呼机 原始提示及其完整答案尾部就位 - 幸存重新加载。 斜杠转为键入的/command表单播种并重新扩展模板 保存。回合运行时编辑被禁用。 - 链接规格:
04-ux/08-component-spec.md,03-runtime/01-ipc-protocol.md、03-runtime/04-data-storage.md、08-meta/decisions-log.md(D137) - 接受:C(聊天流)、F(持久性)、质量
- 里程碑:M5
- 状态:单位覆盖(
transcript-style.test.mjs);完整的 UI 场景草稿
E2E-069:特定于平台的侧边栏标题行为
- 先决条件:PI-Desktop 已打开,并带有扩展的侧边栏和聊天室 会话处于活动状态。
- 步骤: 1) 在 macOS 窗口模式下打开扩展。 2)检查展开的 侧边栏标题栏。 3) 确认没有 PI-Desktop logo/title 可见并搜索 然后折叠侧边栏出现在交通灯的右侧。 4) 输入 全屏并检查同一行。 5) 在Windows/Linux上,确认品牌 仍然可见;用指针激活它,然后用键盘焦点激活它 Enter/Space。
- 预期:macOS 使用一排 46px 的行,左侧带有原生灯光,这是一个可用的 拖动区域,并在右侧单独提供可访问的“搜索”和“折叠”按钮; Logo/Home 品牌在窗口模式和全屏模式下均不存在。 Windows/Linux 在 15px shell 名称旁边渲染规范的 20px 徽标;这 完整的品牌有一个本地化的主页可访问名称,可见 hover/focus 反馈,并返回主窗格进行聊天,而不清除活动的 对话或工作空间。搜索后立即保持折叠状态。的 徽标本身具有主题感知:浅色模式显示
build/icon_1024.png,深色模式 显示build/logo_dark.png,与data-theme实时交换(无需重新加载)。 - 链接规格:
04-ux/01-ui-ia.md、04-ux/07-ui-design-system.md、04-ux/08-component-spec.md - 验收:质量
- 里程碑:M5
- 状态:单位覆盖(
renderer-branding.test.mjs,sidebar-navigation.test.mjs);渲染交互场景草稿
E2E-098:侧边栏折叠和展开动画作为停靠过渡
- 先决条件:PI-Desktop 打开并带有扩展的侧边栏和活动的 聊天会话;
prefers-reduced-motion已关闭。 - 步骤: 1) 单击展开的侧边栏标题中的折叠侧边栏(或按 侧边栏切换快捷方式)。 2)折叠时观察侧边栏。 3) 确认 主窗格展开,折叠的标题栏现在显示展开控件。 4) 从折叠状态再次按下侧边栏切换快捷键:每个 压机必须严格交替折叠和展开,因此第二次压机 重新展开侧边栏(回归:它绝不能重新折叠)。 5)崩溃 并通过快捷方式再次重新展开,然后重复完整的往返行程 使用指针控件。 6) 在 Windows/Linux 上重复。
- 预期:折叠播放
sidebar-out关键帧(不透明度 + ≤8px 幻灯片 加上 width/flex 分配),而旁路保留在树中,然后卸载 动画结束后;主窗格连续填充释放的空间。 Expand 播放sidebar-in关键帧并 控件返回到展开的标题。在 Windows 上,码头保持不透明 退出期间 (sidebar-out-windows),与工作面板停靠行为匹配。否 布局跳转在动画之前,焦点返回到 sidebar/Expand 控制可预测。 - 链接规格:
04-ux/08-component-spec.md、04-ux/07-ui-design-system.md - 验收:质量
- 里程碑:M5
- 状态:单位覆盖(
sidebar-collapse-animation.test.mjs);呈现 交互场景草稿
E2E-070:本机选择菜单在整个应用程序中遵循 Windows 主题
- 先决条件:PI-Desktop 在 Windows 上运行,有光和暗 可用的主题。
- 步骤:1)在浅色主题中,在“设置”→“基础”中打开本机选择, 设置 → 模型配置、设置 → 导入和一项计划任务 形式。 2)以深色主题重复每个表面。 3)之后打开每个列表 无需重新启动应用程序即可切换主题。
- 预期:每个关闭的触发器和打开的本机选项列表都使用 活动主题的可读 foreground/background 配对。没有黑暗主题列表 退回到带有浅色文本的浅色 Windows 表面,没有浅色主题列表 使用深色主题墨水,更改主题会更新后续空缺。的 同样的结果适用于本机选择外部设置。
- 链接规格:
04-ux/06-settings-ia.md,04-ux/07-ui-design-system.md - 接受:质量(跨平台主题可读性)
- 里程碑:M5
- 状态:单位覆盖(
settings-general.test.mjs); Windows 渲染 场景草稿
E2E-072:键盘快捷键映射持续存在并保持冲突安全
- 先决条件:应用程序在 macOS 和一个 Windows/Linux 目标上运行 设置打开;不存储自定义快捷方式覆盖。
- 步骤: 1) 打开设置 → 快捷方式并检查键盘快捷键。 2)改变 搜索未使用的修饰和弦。 3)调用新和弦,然后调用旧和弦 和弦。 4) 尝试将该和弦分配给命令快捷方式(现在通过全局搜索打开)。 5)尝试裸露 字母和保留的编辑和弦。 6) 重新启动应用程序并调用自定义 再次搜索和弦。 7) 恢复搜索,然后选择恢复默认值。 8) 开 macOS 检查相应的本机应用程序菜单加速器 每个 save/reset。 9) 单独按下并释放 Ctrl/Command,确认 IME 候选者,并保持 back/forward 和弦足够长的时间以产生重复。
- 预期:操作分为导航、Agent 和窗口,其中 平台原生关键标签;录制有可见焦点且
Escape取消; 自定义搜索和弦立即生效,替换旧和弦, 重启后仍然有效,并更新 macOS 菜单;重复,无修饰符,并且 保留的分配显示内联错误而不更改任何操作; 单独和全局重置恢复共享默认值;键盘快捷键是 它自己的设置目的地(八项导轨保持不变)。仅修饰符 IME 按键不会发送任何内容,并且保留的历史和弦只会遍历 每次物理按压一次。 - 链接规格:
04-ux/06-settings-ia.md、04-ux/07-ui-design-system.md、03-runtime/01-ipc-protocol.md - 接受:F(设置持久性)、质量(键盘可访问性)
- 里程碑:M5
- 状态:单位覆盖(
keyboard-shortcuts.test.ts,settings-keyboard-shortcuts.test.mjs);渲染场景草稿
E2E-073a:开发者模式控制开发者工具控制台
- 先决条件:应用程序在 macOS 和一个 Windows/Linux 目标上运行; 持久设置和设置 -> 中开发人员模式不存在或为 false 信息已公开。
- 步骤: 1) 通过设置搜索找到开发者卡。 2) 确认 打开控制台操作被禁用并调用 F12 加上辅助平台 捷径。 3) 启用开发者模式并从“设置”中打开控制台。 4)关闭并按F12重新打开;在 Windows/Linux 上重复 Ctrl+Shift+I,然后在 macOS 上检查并调用视图菜单开发人员工具 项目。 5) 重新启动应用程序并调用已启用的入口点。 6) 禁用 控制台打开时的开发人员模式。 7) 直接尝试控制台IPC 禁用时。
- 预期:没有禁用的入口点打开开发人员工具,并且 macOS 省略 查看菜单项。启用持久化开关可解锁本地化 设置操作和适用的平台快捷键;每个切换都相同 重启后的窗口控制台。禁用开关会关闭控制台, 禁用“设置”操作,删除 macOS 菜单项,并使直接 IPC 请求无法关闭。
- 链接规格:
03-runtime/01-ipc-protocol.md,04-ux/06-settings-ia.md、04-ux/08-component-spec.md、04-ux/09-interaction-patterns.md - 验收:F(设置持久性),质量
- 里程碑:M5
- 状态:单位覆盖(
settings-general.test.mjs,window-menu.test.mjs);原生交互场景草稿
E2E-074:并发会话事件和权限永远不会夺走焦点
- 前提条件:会话A和B以Agent模式存在并且可以运行 同时; A 在其编辑器中可见并带有草稿。
- 步骤:1) 开始轮流 A 和 B,然后返回 A。 2) 让 B 发出流式传输 消息、工具活动、完成和权限请求。 3)确认A 保持可见并继续编辑其草稿。 4)触发权限 也在A中请求。 5)显式打开B,只解析B的请求,然后 返回A并解决A的请求。 6) 会话时快速选择 A 然后 B 详细信息以相反的完成顺序加载。 7) 当B加载时,解析A的 Write/Edit 请求,因此其工具完成创建 Review,然后让 B 发出 当 A 可见时,BrowserPreview 伪影。切换回每个会话。
- 预期:B的后台事件仅更新B的行和保留状态; 他们不会更改 A 的活动 session/project/page、记录、草稿、卷轴、 或键盘焦点,并且不会出现全局模式。打开 B 仅显示 B 内联卡及其原始倒计时。两个请求保持独立 可操作,并且解决B并没有清除A。最终的快速选择保持不变 即使 A 的较旧负载稍后完成,也会在 B 上执行。仅明确通知或 会话激活可以导航。 A 的批准后审查仅保留在 A 中 B 中没有瞬态 open/close 闪存; B 的 BrowserPreview 携带 B 的 会话身份,仅更新 B 保留的浏览器资源,并且从不打开, 导航、聚焦或调整 A 的面板大小。明确返回到任一 会话恢复其自己的打开状态、选项卡、活动选项卡和浏览器资源。
- 链接规格:
04-ux/01-ui-ia.md、04-ux/03-permission-ux.md、04-ux/08-component-spec.md、04-ux/09-interaction-patterns.md - 验收:C(会话隔离)、E(权限隔离)、质量
- 里程碑:M5
- 状态:单位覆盖(
permission-inline.test.mjs表示作用域状态, 内嵌渲染契约、绝对倒计时、最新选择守护; 用于会话范围的work-panel.test.mjs和browser-preview-tool.test.mjs工件保留和路由);完整的 UI 场景草稿
E2E-075:侧边栏部分上下文菜单创建会话和项目
- 状态:手动
- 优先级:P1
- 封面:A、C、D / US-UI-57
- 先决条件:应用程序运行时可见扩展的主页侧边栏。
- 步骤:
- 右键单击
Sessions标题标签(不是会话行)。 - 选择单个创建项目。
- 右键单击独立会话列表中的空镶边。
- 右键单击
Projects标题标签。
- 右键单击
- 选择单个创建项目并取消或完成项目选择器。
- 右键单击项目列表中的空镶边(任何项目组之外)。
- 预期:
- 会话上下文菜单 create/reuse 无路径临时会话和焦点 输入框。
- 项目上下文菜单打开与标题相同的文件夹选择器 文件夹加控件。
- 现有的行上下文菜单和标题字形按钮仍然可用;的 部分菜单保持一项且与其他侧边栏菜单主题匹配。
- 部分、会话行和项目行右键菜单在右侧打开 当空间允许时,指针完全保持在视口内 右边缘。
- 退出并外部单击关闭菜单而不创建任何内容。
E2E-076:出现启动画面,然后返回主 shell
- 状态:部分自动化(
startup-splash-motion.test.mjs涵盖启动标记、运动标记、简化运动和目录键;全窗口计时仍为草稿) - 优先级:P1
- 封面:A,品质/US-UI 外壳抛光
- 先决条件:应用程序启动路径可用(开发或打包)。
- 步骤: 1.启动PI-Desktop。 2. 在引导完成之前观察第一个绘制的渲染器表面。 3. 等待 sessions/settings 引导程序完成。 4. 如果可用,请对 OS
prefers-reduced-motion: reduce重复此操作。 - 预期:
- 准备之前:带有品牌标志、外壳名称、标语和可访问的启动状态 (
data-testid="startup-splash") 的全窗口启动画面。- 准备好后:启动画面会短暂淡出(或立即减少运动)退出,并且主外壳(或设置页面)在下面是交互式的。
- 没有简单的无品牌“开始...”居中文本作为唯一的启动 UI。
- Overlay/dialog 输入动作使用共享令牌;减少的运动可以保持状态变化,而无需装饰持续时间。
- 链接规格:
04-ux/07-ui-design-system.md§8、04-ux/02-i18n-english-first.md、决策日志 D146 - 验收:A(应用程序启动),质量
- 里程碑:M5
E2E-099:品牌标志遵循活跃主题
- 状态:草案
- 优先级:P3
- 封面:品质/US-UI 外壳抛光
- 前提条件:应用程序运行;主题可以在浅色和深色(以及系统)之间切换,而无需重新启动。
- 步骤:
- 在轻型模式下,打开应用程序外壳、空的聊天主页和展开的侧边栏 (Windows/Linux) 或启动画面。
- 检查侧边栏和启动画面中渲染的
BrandLogo源, 并检查随机选择的HomeMascotLogo姿势组动画 空荡荡的家英雄。将鼠标悬停在吉祥物上并验证其是否前进 悬停时连续。 - 将主题切换为深色(设置→基础→外观,或系统外观更改)。
- 重新检查相同的表面,无需重新加载。
- 切换回光源并重新检查。
- 预期:
- 明暗模式渲染
build/icon_1024.png/build/logo_dark.png位于侧边栏和启动画面中,无需重新加载窗口。
- 明暗模式渲染
- 空荡荡的英雄渲染 100 像素的吉祥物精灵,选择九个之一 安装上的剩余姿势组,交换固定内的离散帧 视口,并在每次播放后选择不同的组。单帧 小组保持更长时间,完成的小组在之前休息几秒钟 下一个选择。指针悬停绕过那些空闲休息并连续 推进姿势组;在减少运动下当前组的第一个 框架仍然可见。
- 尺寸在主题变化时保持稳定(侧边栏 20 像素、英雄 100 像素、启动栏 64px),标记保持装饰性,无需点击、键盘或焦点 行为。
- 链接规格:
04-ux/08-component-spec.md§3.7、04-ux/07-ui-design-system.md - 验收:质量
- 里程碑:M5
E2E-077:主题感知选择和 CJK 部分标签
- 状态:部分自动化(
user-select.test.mjs、interaction-polish.test.mjs) - 优先级:P2
- 封面:A,品质/US-UI 外壳抛光
- 先决条件:应用程序运行时至少有一个可选择的转录本或输入;语言可以切换为
zh-CN。 - 步骤:
- 选择转录消息或输入框中的文本。
- 检查侧边栏 Sessions/Projects 部分的英文标签。
- 将应用程序语言切换为
zh-CN并重新检查相同的标签。 - 悬停跳转-最新(当可见时)、停止、搜索行和配置文件菜单项。
- 预期:
- 选择突出显示使用中性文本主色(不是浏览器默认的蓝色)。
- Caret/form 强调色保留在单色令牌坡道上。
- 英文部分标签可以使用大写+宽跟踪;
zh-CN标签使用正常跟踪,无需强制大写。 - 列出的 chrome 控件可通过共享运动令牌简化 background/color 更改。
- 链接规格:
04-ux/07-ui-design-system.md、04-ux/08-component-spec.md - 接受:D147
- 里程碑:M5
- 状态详细信息:CSS 合约的源代码级别覆盖范围;视觉选择油漆仍然是手动的。
E2E-078:工作面板和设置光表面抛光
- 状态:部分自动化 (
surface-polish.test.mjs) - 优先级:P2
- 封面:D,品质/US-UI 外壳抛光
- 前提条件:应用程序运行;主题可以切换为浅色;可以打开工作面板选项卡。
- 步骤: 1.切换到浅色主题。 2. 打开“设置”并检查表单字段、切换开关、分段控件和快捷键键帽。 3. 打开聊天会话旁边的工作面板(审阅/文件/浏览器)。 4. 将鼠标悬停在文件树行或 diff 标头上;聚焦浏览器 URL 字段。 5. 打开 confirmation/provider 对话框并检查稀松布。
- 预期:
- 工作面板主体读取为安静的
#fafafa插页纸,带有白色标题带。 - 设置字段、浏览器 URL、分段轨道和快捷键键帽使用浅色嵌入填充;聚焦场通过中性环提升。
- 切换开启状态使白色旋钮保持在近乎黑色的轨道上。
- 悬停可通过共享运动令牌轻松填充 file-tree/diff/resize。
- 工作面板主体读取为安静的
- 浅色对话稀松布比深色 45% 面纱(约 28% 墨水)更柔软。
- 链接规格:
04-ux/07-ui-design-system.md、04-ux/08-component-spec.md - 接受:D148
- 里程碑:M5
- 状态详细信息:CSS 合约的源代码级别覆盖范围;目视表面检查仍然是手动的。
E2E-079:面向用户的英文和中文目录副本
- 状态:部分自动化(
packages/i18n/test/user-facing-copy.test.mjs、catalogs.test.mjs) - 优先级:P2
- 封面:A,质量/US-UI 副本
- 前提条件:应用程序运行;语言可以在英语和中文之间切换。
- 步骤:
- 检查空首页提示、侧边栏临时聊天部分和 status/connection toast。
- 打开设置 → AI 提供商和市场刷新操作。
- 将应用程序语言切换为中文并重新检查相同的界面。
- 预期:
- 文案以简单的产品语言(AI 提供商、项目、市场、connected/limited)而非 host/backend/repo 行话解释结果。
- 英语和中文目录保留相同的键和插值变量。
- 崩溃的 chrome 和空主目录标题在两个区域设置中均保留目录支持。
- 链接规格:
04-ux/02-i18n-english-first.md - 接受:D149
- 里程碑:M5
- 状态详细信息:目录合同的源级覆盖范围;视觉措辞审查仍然是手动的。
E2E-081:发送重新固定脚本并跳转到底部
- 先决条件:溢出一个视口的长脚本;提供商已配置。
- 步骤:
- 从固定底部开始,使用触控板向上滚动 初始运动较小;观察第一个动作和 跳转到最新的控件。
- 在编辑器中键入新提示并发送。
- 在回合开始和流式传输时观察转录位置。
- 在流式传输时再次向上滚动触控板,等待 了解更多内容,然后单击跳转到最新内容。
- 预期:
- 第一次向上运动立即释放跟随模式并保持 稳定;它不会快速返回、反转方向或振荡 待处理的流或调整大小跟随帧完成。
- 新的流媒体内容不会移动手动定位的视口,并且 一旦释放跟随模式,就会出现跳转到最新内容。
- 发送时,记录会重新固定、隐藏跳转到最新内容并跳转到底部,以便新用户消息(和后续流)可见。
- 固定时流媒体继续关注。
- 手动滚动中流暂停并再次显示跳转到最新内容;单击它即可恢复跟随。
- 链接规格:
04-ux/08-component-spec.md、04-ux/09-interaction-patterns.md - 验收:C(聊天流),质量/D151
- 里程碑:M5
- 状态:部分自动化(
apps/desktop/test/transcript-scroll.test.mjs); 完整的触控板交互仍为草稿
E2E-082:新推理会话默认为最大思考
- 先决条件:应用程序默认 provider/model 通过 pi-ai 解析为 具有推理能力并发布稀疏思维水平集;第二个默认值 模型是非推理的。
- 步骤:
- 将具有推理能力的模型设置为应用程序默认模型并创建一个新会话。
- 检查发送到主机的思考触发器和会话配置。
- 选择较低级别或关闭,退出会话,然后重新打开。
- 将非推理模型设置为默认并创建另一个新会话。
- 预期:
- 第一个新会话持续存在并显示最高规范级别 为继承的推理模型发布,即使提供商返回 它的稀疏级别乱了。
- 重新打开第一个会话会保留用户以后的显式选择。
- 非推理会话从
off开始,不渲染任何思考触发器; 丢失的功能元数据也会回退到off。
- 链接规格:
03-runtime/13-model-catalog-and-selection.md,04-ux/08-component-spec.md、ADR 0018、D153 - 验收:B(模型配置)、F(持久性)、质量
- 里程碑:M5
- 状态:部分自动化(
thinking-levels.test.ts,thinking-ui.test.mjs);完整的 UI 场景草稿
E2E-083:长流转使 shell 交互保持响应
- 先决条件:已配置提供商;活动会话有足够的用户, 助手和工具行可溢出多个视口;工作面板可以是 打开;正常和简化运动首选项均可用。
- 步骤:
- 启动长助理响应,发出频繁的流式更新。
- 在流式传输时,将鼠标悬停并聚焦侧边栏行,然后在以下情况下输入输入框: 启用后,open/collapse 工作面板,然后滚动文字记录 并返回到最新的。
- 观察小地图、完成的历史行、composer 表面和 shell 整个流中的镀铬。
- 导航至插件或设置并返回,然后以减少的动作重复。
- 预期:
- 当前助手行逐步显示内容并固定关注 保持在最晚,没有明显的振荡。
- 可替换的 message/tool 部分会合并到下一个油漆,同时 终端、许可、计划和错误状态仍然是即时的。
- 失败的工具行仍然带有错误色调并且可以局部扩展,但永远不会标记 包含的活动组最终失败。小组只报道 处理时间;终端回合样式来自终端代理 结果表面。
- 侧边栏、输入框、已完成的 message/activity 行、工作面板、标题栏、 并且全局覆盖不会明显重绘或丢失 pointer/keyboard 每个令牌更新的响应能力。
- 已完成的历史记录保留在其稳定的渲染边界中,而活动的历史记录保留在其稳定的渲染边界中 尾部变化;历史保持可选择、可复制并锚定在 小地图,无需为每个标记重建为 React 子树。
- 按下和释放标准、图标、侧边栏、发送、停止和消息 动作控制使用一种缓和变换而不是捕捉比例; 活动流标签和加载骨架保留其 shimmer/pulse 循环时间等于或低于 1 秒。
- 小地图溢出和活动标记状态在没有标记的情况下保持正确 流媒体内容改变高度时出现抖动。
- 目的地、面板、焦点、按下、跳转、错误反馈使用一短路 有界过渡;抄本中没有输入框的模糊痕迹。
- 初始 shell 不会急切地评估次要目标模块; 第一个导航可能会显示一个紧凑的本地化加载指示器,然后 本地块解析后保留正常的页面交互。
- 减少运动保留每个状态变化并使用即时编程 以接近零的过渡持续时间进行滚动。
- 链接规格:
04-ux/07-ui-design-system.md,04-ux/08-component-spec.md、04-ux/09-interaction-patterns.md - 验收:C(聊天流),质量
- 里程碑:M5
- 状态:单位覆盖(
interaction-performance.test.mjs);呈现 流媒体场景草稿
E2E-084:长工具循环在提供程序上下文限制之前压缩
- 先决条件:使用已知的 pi-ai context/output 配置的提供程序 限制;夹具可以产生重复的刀具转动和大型带帽刀具 结果没有完成代理运行。自动保护始终开启 并且没有任何设置。
- 步骤:
- 启动一项代理任务,其工具循环超出硬预算。
- 让至少三个
turn_end事件发生在agent_end之前;观察 composer/session 控制、处理行、转录和 toast。 - 继续直至安装检查点,然后完成任务。
- 发送进一步的提示,直到安装第二个检查点。
- 使用多个平行带帽刀具重复硬边界车削结果 压缩范围。
- 重新启动应用程序,重新打开会话,并发送取决于 既总结了旧工作,又保留了最近的用户留言。
- 对返回 Bedrock 的提供商固定装置重复此操作
prompt is too long: N tokens > M maximum一次。 - 运行模型调用远低于硬预算的
new_context的回合。 - 空闲时手动调用
/compact。
- 预期:
- 每个
turn_end在另一个提供商请求之前都会被评估,并且永远不会 标记整体任务空闲; composer/config 控件保持阻塞状态,直到agent_end、error或仅手动的compaction_end。 - 每次成功的压缩都会在记录中添加一个分隔行, 位于检查点覆盖的最后一条消息之后,并且 恰好引发一个警告Toast。两个检查点产生两行, 顺序,并且两行都不会替换或隐藏消息。
new_context调用显示为正常工具活动行,返回 立即,并在下一个回合边界处创建检查点 而不是中途回合。
- 每个
- 在检查点后打开上下文使用检查器显示一行 压缩计数和最新摘要的令牌估计;在任何之前 检查点该线不存在。
- 在硬边界,在下一个模型之前创建持久检查点 请求。完整的可见记录没有改变,并且继续 任务保持低于模型感知的安全预算。
- 在检查点之后,下一个提供商请求不包含助手或工具 来自边界之前的消息 - 仅摘要和最近的用户 消息,其中最旧的可能携带检查点截断标记 - 并且不包含没有结果的工具调用。扩展原来的 转录本行仍然显示其完整的持久结果。
- 重新启动可恢复摘要+保留的用户消息以及每个更早的消息 压实行仍被绘制。检查点之前的 regenerate/fork 具体记录的边界滴;以生存为基础的记录 消息为 preserved/remapped。
- 确切的提供程序溢出仅从模型中删除失败的助手 上下文,压缩后重试一次,并且不会在第二次循环 溢出。
- 如果自动摘要生成失败,则持久保留尾部回退 附加检查点,运行保持活动状态,并有一个警告解释 旧模型上下文被减少;如果后备持久性或安全 预算保护失败,
CONTEXT_COMPACTION_FAILED被发出一次。 - 如果后续检查时最新的检查点已经是转录本叶子 提示超出硬预算,运行时会重建较小的尾部 完整的成绩单并向前推进现有的摘要,而不是 报告称没有新的上下文需要压缩。
- 每个检查点窗口的预算提醒最多出现一次,从不 在记录中,而不是在持久的系统提示中。
- 空闲
/compact成功并在顶部显示其自己的信息 toast 压缩警告,因为用户要求它。压实失败 通过CONTEXT_COMPACTION_FAILED表面一次,没有重复错误 干杯。 - 设置不包含上下文管理卡,并且设置搜索不返回任何内容 压实行。
- 链接规格:
03-runtime/01-ipc-protocol.md,03-runtime/02-agent-runtime.md、03-runtime/03-tools-and-permissions.md、03-runtime/04-data-storage.md、03-runtime/06-host-rpc-protocol.md、04-ux/06-settings-ia.md、04-ux/08-component-spec.md、04-ux/09-interaction-patterns.md、ADR 0030、ADR 0049、ADR 0061、ADR 0064、 D158、D203 - 验收:C (chat/stream)、F(持久性)、质量
- 里程碑:M5
- 状态:部分自动化(
runtime.test.ts,context-compaction.test.mjs、assistant-turns.test.mjs、host-core transcript/session 单元测试);完整的 provider/UI 旅程草稿
E2E-AGENTS-001:项目指令链配置代理会话
- 先决条件:项目包含根
AGENTS.md,嵌套packages/api/AGENTS.md,并且配置了提供程序。 - 步骤:
- 启动Agent模式对话并提交root覆盖的任务 指示。
- 让代理读取或编辑
packages/api/handler.ts。 - 添加
packages/api/AGENTS.override.md,然后让代理访问另一个 该目录中的文件。 - 在会话空闲时编辑 root 指令,然后提交 后续任务。
- 预期:初始运行时接收根链。文件之前 工具执行时,嵌套指令将附加在其根源之后,并且 因此优先。在一个目录中,
AGENTS.override.md胜出AGENTS.md;CLAUDE.md和.claude/CLAUDE.md是后备名称。闲着的 后续使用更改的根内容而不是重用之前的运行时。 空的、不可读的、过大的和超出根的指令文件不会阻塞 转牌圈;组合的 UTF-8 内容上限为 32 KiB。如果路径特定 分辨率超过其两秒期限或主机不可用,则 文件工具继续使用基础链并且不保留同级链 目录的规则。同一目录中的重复文件工具一次 提示重用一种路径解析声明;下一个提示再次解决,所以 观察到更改的指令文件。解析器使用会话绑定 项目根在运行时启动时传递,并且不发出每个文件session.getRPC。 - 链接规格:
03-runtime/02-agent-runtime.md - 接受:C (chat/stream),F(持久)
- 里程碑:M5
- 状态:部分自动化(
project-instructions.test.ts,runtime.test.ts);满 provider/UI 旅程草案
E2E-AGENTS-002:全局设置和项目菜单管理指令文件
- 先决条件:PI-Desktop 正在运行;可以打开一个项目。
- 步骤:
- 在没有活动项目的情况下打开设置 -> 说明并保存全局 内容。
- 启动新的代理会话并验证其指令上下文包括 全球来源。
- 打开项目视图并使用项目的更多菜单来编辑和保存其 显示
AGENTS.md。 - 在新会话或空闲会话中提交提示。
- 预期:全局编辑器仅针对
~/.pi/agent/AGENTS.md。的 项目编辑器只能从已知项目的项目中使用 - 查看更多 菜单并仅针对该项目的根AGENTS.md。两位编辑均显示 他们解析的路径,保留键入的文本,并通过专用的保存 IPC 而不是一般文件写入 API。全球内容先于项目 下一个运行时的内容;保存的项目内容跟随它并采取 冲突的优先顺序。项目编辑器是一个视口级对话框。 - 链接规格:
03-runtime/02-agent-runtime.md、ADR 0037 - 接受:C (chat/stream)、D(工作空间)、F(持久性)
- 里程碑:M5
- 状态:单位覆盖(
project-instructions.test.ts); UI 之旅草案
E2E-085:扩展的侧边栏排版使列表内容保持紧凑
- 前提:展开的侧边栏至少包含一个独立的 会话、一个带有会话的保留项目和一个空项目组; 有浅色和深色主题可供选择。
- 步骤:
- 以默认窗口宽度打开应用程序并检查会话标题, project/group 标题、空状态副本、节标签和页脚 设置、插件和通知图标。
- 在浅色和深色主题之间切换,然后将窗口缩小到 支持的最小扩展侧边栏宽度。
- 将侧边栏层次结构与 14px 聊天正文文本进行比较并检查长 session/project 名称。
- 预期:
- 页脚操作图标使用共享的 32px 命中目标和紧凑的 14px 图标 尺寸;插件位于“设置”的右侧。
- 会话标题、project/group 标题和空状态副本使用
--text-md(13 像素);部分标签和辅助元数据保留在--text-sm(12px)。 - 两个主题中的层次结构都保持可读性,行距保持紧凑 大约 28–32px,长标签会在没有外壳回流的情况下截断。
- 链接规格:
04-ux/07-ui-design-system.md,04-ux/08-component-spec.md,D161 - 验收:质量
- 里程碑:M5
- 状态:单位覆盖(
sidebar-navigation.test.mjs);视觉呈现 场景草稿
E2E-086:助理美人鱼栅栏安全渲染而不会阻塞流
- 先决条件:提供商可以流式传输包含以下内容的助理答案: 有效的 Mermaid 流程图、无效的 Mermaid 栅栏和普通栅栏代码; 有浅色和深色主题可供选择。
- 步骤:
- 缓慢流式传输有效的
mermaid栅栏,并在栅栏前后观察它 关闭栅栏到达。 - 将完成的图表滚动到视图中,切换源,复制源, 并在浅色和深色主题之间切换。
- 向上滚动,以便暂停转录记录,然后带来另一个已完成的记录 视口附近的图表。
- 渲染无效且超过 20,000 个字符的美人鱼源以及负载 尝试 HTML 标签、外部图像、链接或 Mermaid 配置覆盖。
- 扩展包含
mermaid栅栏的思维内容。
- 缓慢流式传输有效的
- 预期:
- 部分流仍然是正常的源代码块;只有完整的 答案栅栏开始渲染,并且仅在视口附近。普通代码 栅栏和思考 美人鱼栅栏保留了其来源演示。
- 该图使用有界卡镶边,保持在转录本宽度内, 切换主题而不使用陈旧的颜色,并公开键盘可访问的 diagram/source 和复制控件。复制返回原始栅栏源。
- 图表高度变化将固定的记录保留在底部,但永远不会 用户向上滚动后恢复关注。
- 无效、过大或不安全的输入不会导致助手转动、执行失败 链接、加载嵌入媒体、添加外部 HTML 或削弱严格设置; 当渲染不可用时,它会回退到可读的可复制源。
- 链接规格:
04-ux/08-component-spec.md§8.7,04-ux/09-interaction-patterns.md§2、05-security/01-security.md§2、D165 - 验收:C(聊天和直播)、安全性、质量
- 里程碑:M5
- 状态:单位覆盖(
mermaid-rendering.test.mjs);提供安全性和 视觉场景草稿
E2E-092:打包的运行时是独立的,没有重复的依赖项
- 先决条件:本机 macOS arm64、Windows x64 和 Linux x64 软件包 从干净的发布主机目录构建;干净的应用程序配置文件; 提供英语和中文版本;可以禁用外部网络访问 环回仍然可用;与 OpenAI 兼容的确定性环回 夹具提供程序返回代码、KaTeX、Mermaid 和终端命令。
- 步骤:
- 记录每个压缩工件格式以及解压的应用程序, 每个本机上的 ASAR、Electron 运行时、区域设置和解压本机大小 跑步者。
- 检查 sidecar、主机、生产的 ASAR 和资源库存 模块、源映射、tests/examples/declarations、Chromium 语言环境以及 本机预构建目标。
- 配置环回装置提供程序,禁用外部出口,然后 从干净的配置文件启动。英文和简体切换 中文,要求确定性响应,渲染通用 JavaScript/TypeScript、Python、Rust、shell、Mermaid 和未知语言 栅栏加上 KaTeX 和美人鱼图,打开终端并验证主机 和代理边车健康状况。
- 预期:该软件包仅包含一个捆绑代理 sidecar,即 目标本机 Rust 主机和
node-pty,并且仅配置了 Chromium 区域设置 包。 Renderer 依赖关系通过 Vite 输出存在,而不是重复 原始node_modules;依赖源映射、测试、示例、声明、 第二个代理运行时树,以及可靠的排他性非目标本机资产 缺席。精心策划的 Shiki 语法在未知的栅栏中突出显示本地 保持纯文本可读。离线 shell 启动并且所有装置 功能使用本地打包资产; provider/update 网络故障会导致 不阻止启动。 - 链接规格:
02-architecture/01-architecture.md,02-architecture/02-tech-stack.md、03-runtime/07-process-model.md、04-ux/02-i18n-english-first.md、05-security/01-security.md、06-delivery/06-release-runbook.md,D008 - 验收:A(应用程序启动),质量
- 里程碑:M5
- 状态:单位覆盖(
packaging-footprint.test.mjs验证静态 依赖项和构建器配置);原生库存并离线打包 启动草稿
E2E-093:变异工具序列化并从过时的编辑上下文中恢复
- 先决条件:项目绑定的 Agent 会话具有可写工作区; 提供商装置可以在一个中发出两个相同会话的 Agent/
Write调用 工具批次;第二次编辑可能会变得过时或不明确old_string背景; Bash 命令可以返回带有诊断信息的非零退出代码。 - 步骤:
- 启动一个任务,为同一会话发出两个突变,同时还 发出独立的 read/search 调用。
- 在第一个突变运行时检查工具计时和转录本。
- 强制第二个
Edit使用不再存在的上下文,然后 允许代理重新读取文件并从当前内容重试。 - 运行以非零值退出的 Bash 命令并检查其工具结果 内联状态。
- 对出现在两个位置的
old_string重复此操作。 - 如果任务使用广告工作区之外的专用工作树, 验证其受保护的 Bash 编辑和生成的
git diff。
- 预期:
- Read/search 调用可能会重叠,但一次只执行一个 Agent/
Write一次会话;排队的突变不会消耗另一个全局变量 等待时的变异槽。 - 陈旧且不明确的编辑会在不更改文件的情况下失败并返回
TOOL_FAILED消息指示代理重新读取并提供 独特的当前背景。 - 非零 Bash 命令被标记为失败,同时保留其退出代码, 用于代理和诊断的 stdout 和 stderr。
- Read/search 调用可能会重叠,但一次只执行一个 Agent/
- 重试执行一次新读取并对当前文件进行操作;一个 第二个相同路径不匹配或失败的 shell patch 命令返回 终止工具结果,停止变异工作流程,并且不 重复修改旧的补丁工件或其块标头。
- 最终文件准确包含预期的更改以及 diff/review 数据 不包含部分或交错突变。
- 链接规格:
03-runtime/03-tools-and-permissions.md,03-runtime/06-host-rpc-protocol.md、03-runtime/08-error-codes.md - 验收:E(工具和权限)、质量
- 里程碑:M5
- 状态:单位覆盖(
tool_budget.rs、tools/mod.rs、agent-runtime/runtime.test.ts);完整的 provider/UI 旅程草稿
E2E-096:就地恢复一个临时提供程序流终止
- 先决条件:项目绑定的 Agent 会话使用确定性 发出部分辅助流的提供商装置,终止一次, 然后下一个请求成功;第二场比赛可以终止两次; 计时日志已启用。
- 步骤:
- 使用单端接夹具开始 Agent 转动,并观察 部分助理回应。
- 等待有界重试并检查成绩单、会话状态和 恢复后的模型计时日志。
- 对两端夹具重复并检查端子错误 message/event 及其诊断详细信息。
- 重新加载会话并验证是否只有已完成的响应或 单终端故障助手依然耐用。
- 预期:
terminated被分类为STREAM_FAILED。- 第一个流后瞬态故障等待一个可中止的界限 退避,从模型上下文中删除失败的助手,并重试一次 没有重复的助手气泡或终端错误通知。
- 恢复的回合发出一个终端生命周期并保持相同的可见性 助理消息 ID。时序日志记录
outcome=retry和最终的 结果。 - 第二次故障发出一个终端
STREAM_FAILED辅助错误并且 生命周期事件。可用的详细信息包括阶段、流计时、提供商 状态和retryAttempt,无需凭据或不受限制的提供商 身体。 - 身份验证、模型选择、上下文和格式错误的请求失败 不进入该同轮流重播路径。
- 链接规格:
03-runtime/01-ipc-protocol.md,03-runtime/02-agent-runtime.md、03-runtime/08-error-codes.md、08-meta/decisions-log.md(D186)、ADR 0050 - 接受:C(聊天和直播)、F(持久性)、H(诊断)、质量
- 里程碑:M5
- 状态:单位覆盖(
agent-errors.test.ts、runtime.test.ts);满 provider/UI 旅程草案
7A。 M6 Plan 和 shell 场景
E2E-104:旧合约值迁移到架构 v11
- 先决条件:Schema-v8 固定装置包含会话、应用程序默认值和 具有旧版
chat值以及成绩单和权限的预定记录; schema-v7 和 schema-v9 固定装置覆盖两个受保护的入口路径。 - 步骤:1) 启动 host-core 并允许受保护的迁移(首先是 v7) 达到 v8)。 2) 检查会话、设置、计划模式、
plan_approvalsfields/indexes,以及精确可读的 v8/v9 备份。 3) 重新启动并检查相同的记录。 4) 对格式错误的应用程序设置重复此操作, 格式错误的计划配置、无效的顶级操作模式以及未知的 或错误的平台默认 shell。 5)重复平台有效的持久化 shell 标记为暂时不可用并嵌套扩展mode字段。 - 预期:每个旧模式都是
plan,Agent 仍然是新会话,并且 新任务默认,transcripts/permissions 存活,plan_approvals保留 批准数据并具有 artifact/execution 字段,v8→v11 是一个原子 在其 WAL 检查点和 v8 备份、v9 和 v10 创建之后的事务 可读备份,迁移失败会离开源架构 权威的。每个畸形或 无效的固定装置在架构升级之前无法关闭。暂时的 不可用的平台有效 shell 仍保留用于运行时回退,并且 嵌套扩展模式保持不变。 - 链接规格:
00-baseline.md、03-runtime/04-data-storage.md、03-runtime/01-ipc-protocol.md、04-ux/06-settings-ia.md、ADR 0053 - 接受:F(持续),H(诊断)
- 里程碑:M6
- 状态:自动(2026-08-05通过):host-core 139/139,包括 15 个 专注于数据库测试,涵盖 schema-v7→v8→v11、v8→v11、v9→v11 和 v10→v11 守卫的路径, 精确可读的备份、故障关闭回滚、重新启动、转录、设置、 计划模式、批准字段和索引测试
E2E-105:Plan 策略仍然具有主机权威
- 先决条件:项目绑定会话在 Plan 和 BrowserPreview 中处于空闲状态, 一个插件工具和一个伪造的
requestedMode = "agent"夹具。 - 步骤:1) 检查可见的 Plan 工具。 2) 使用 Read/Glob/Grep 和 BrowserPreview。 3) 尝试编写、编辑、插入和 各种权限模式下通过主机的未知工具。 4) 在下面运行 Bash 询问、接受编辑和自动。
- 预期:Plan 拒绝 Write/Edit/plugin/unknown 工具,无论 伪造模式、补助金或自动; Bash 遵循所选的权限模式。的 运行时仍为 1 pi Agent 并且所有拒绝都会经过审核。
- 链接规格:
03-runtime/02-agent-runtime.md,03-runtime/03-tools-and-permissions.md、03-runtime/05-host-core-rust.md、03-runtime/06-host-rpc-protocol.md、05-security/01-security.md、ADR 0053 - 接受:E(工具和权限)、安全
- 里程碑:M6
- 状态:自动(2026-08-04 通过):
test:e2e:plan加 host-core permission/policy 和代理运行时工具组合测试
E2E-106:SubmitPlan 拒绝进入可编辑计划并重新提交新工件
- 先决条件:项目绑定会话在 Plan 中与提供商处于空闲状态;
.pi/plan/不存在或为空,并且工作区允许主机工件 创造。 - 步骤: 1) 让 Agent 使用固定标题、Markdown 和 问题。 2) 逐字节检查新的
.pi/plan/*.md文件和plan_approvals行。 3)检查卡牌的标题和神器开启者;确认 question/description、validity/deadline 和状态不存在且仅 提供批准和拒绝。 4) 打开审批模式菜单,选择自动, 并验证下一个批准默认为自动。 5) 拒绝 提案。 6) 确认持久模式为Plan,实时状态为可编辑planning, 批准门已清除,并接受稍后的提示。 7)让 Agent 在新回合中修改并调用SubmitPlan一次,并带有完整的 快照。 8) 使用记住的自动模式批准第二个提案。 - 预期:主机将准确提交的 Markdown 字节保留在新的文件中 独特的神器,记录其相关的 path/hash/size 与结构化 title/question,并且绝不让渲染器或 sidecar 写入或替换它。 标题衍生的工件文件名可以从标题中识别出来,包括 非 ASCII 标题字符。卡牌显示标题,打开神器; 它不需要内联 question/Markdown/hash/size 或 validity/deadline 指标。选择的审批方式会被本地记住,以便下次使用 批准。 第一行的拒绝是终止的,离开持久模式 Plan,并返回 实时状态到可编辑规划。后来的 prompt/resubmission 创建了一个 第二个完整的 Markdown 快照和不同的
.pi/plan/*.md工件; 第一个工件字节保持不变。批准第二项提案 记住的自动模式仍然将相同的 Agent 更改为 Agent 并排队执行。 - 链接规格:
03-runtime/01-ipc-protocol.md,03-runtime/02-agent-runtime.md、03-runtime/04-data-storage.md、03-runtime/06-host-rpc-protocol.md、04-ux/03-permission-ux.md、04-ux/08-component-spec.md、05-security/01-security.md、ADR 0053 - 接受:C (conversation/stream)、E(权限)、F(持久性)
- 里程碑:M6
- 状态:自动(2026-08-05 通过):
test:e2e:plan验证主机 artifact/approval 生命周期。可选的实时test:e2e:plan-ui案例 需要环境提供的 OpenAI 兼容提供程序;授权运行 模型gpt-5.6-luna通过了 6/6,控制台诊断为零。它使用了 真正控制Composer和Send,现场Agent调用EnterPlanModeSubmitPlan,正常呈现 通过 preload/Main 请求批准解决, 批准的执行会发出精确的耐用标记,并且私人 env-gate WeakMap 检查之前证明了相同的DesktopAgentRuntime对象 并在批准后。 Main/Host/sidecar PID 保持稳定;凭据从不 输入 CDP 或输出。默认无钥匙运行仍为 5/5 与现场案例 明确跳过。
E2E-107:Plan 批准使用一个绝对 30 分钟到期时间
- 先决条件:存在带有可控时钟的待处理 Plan 请求。
- 步骤: 1) 记录
createdAt和expiresAt。 2)重新加载渲染器并 重新请求。 3)将时间提前到最后期限而不解决。 4) 到期后尝试批准。 - 预期:Renderer 重新加载仅重新水化仍待处理的行,而 主机仍然存活,显示的倒计时保留原来的绝对值 截止日期;拒绝、过期、approved/completed 和中断终端 卡不属于重新装水的一部分。过期记录
expired,留下 会话 Plan,返回PLAN_APPROVAL_TIMEOUT,并拒绝迟到的响应 无需更改模式或许可。 - 链接规格:
03-runtime/06-host-rpc-protocol.md,03-runtime/08-error-codes.md、03-runtime/10-session-state-machine.md、04-ux/03-permission-ux.md、ADR 0053 - 接受:E(权限)、H(诊断)、安全
- 里程碑:M6
- 状态:自动(2026-08-04 通过):
test:e2e:plan-ui涵盖待定 渲染器重新加载;test:e2e:plan和确定性 host-core 延迟到期 测试涵盖绝对期限、超时持久性和失败关闭 分辨率。没有声称终端卡重新加载水合。
E2E-108:启动栅栏中断待处理的 Plan 工作
- 先决条件:Plan 请求正在等待实时审批服务员,并且 运行计划回合;主机和渲染器可以独立重启。
- 步骤:1) 重新加载渲染器并列出实时请求。 2)重新启动 决议前的 host/app。 3) 检查
plan_approvals行,转动并 启动后的会话。 4) 提交重启前响应。 - 预期:Renderer 在主机保持活动状态时重新加载,保留 仍然悬而未决的行和原始截止日期。以事务方式完全重启 Host/app 标记待处理行并在 RPC 服务之前转动 interrupted/aborted,离开 会话 Plan,并为旧响应返回
PLAN_APPROVAL_STALE。不 可操作的陈旧卡或执行已恢复,并且 UI 不需要 重启后呈现中断的终端快照。无进程纪元 字段被保留或发送。 - 链接规格:
03-runtime/04-data-storage.md,03-runtime/06-host-rpc-protocol.md、03-runtime/07-process-model.md、03-runtime/10-session-state-machine.md、04-ux/08-component-spec.md、ADR 0053 - 接受:F(持久性)、H(诊断)、安全性
- 里程碑:M6
- 状态:自动(2026-08-04 通过):
test:e2e:plan执行真实操作 主机重启和host-core恢复测试验证中断的持久状态; 待处理的渲染器重新加载断言由 E2E-107 UI 通道覆盖。
E2E-109:重新启动后不会重播已批准的 Plan 执行
- 先决条件:Plan 请求已通过 Ask 获得批准并被捕获 一次处于
queued状态,一次处于running状态。 - 步骤: 1) 在每个状态期间重新启动主机。 2) 检查
plan_approvals.execution_state并在启动后转记录。 3)观察 provider/tool 调用和会话模式。 4) 开始新的用户回合 明确地。 - 预期:Queued/running 执行字段变为
interrupted, 关联的转向中止,没有重播 provider/tool 调用,并且会话 仍为 Agent,因为批准已提交。仅接受新回合 用户启动后;没有中断的终端卡或过时的操作 重启后需要。 - 链接规格:
03-runtime/04-data-storage.md,03-runtime/06-host-rpc-protocol.md、03-runtime/07-process-model.md、03-runtime/10-session-state-machine.md、ADR 0053 - 接受:C (conversation/stream)、F(持久性)、H(诊断)、安全性
- 里程碑:M6
- 状态:自动(2026-08-04 通过):
test:e2e:plan重新启动实际排队 并声明执行并验证没有重播以及 Agent 保留
E2E-110:计划的 Plan 在任何工作之前被拒绝
- 先决条件:计划任务是 Plan,无人值守运行程序是 可用;可以观察提供商、工件和队列写入。
- 步骤: 1) 通过无人值守路径触发任务。 2) 检查 提供程序跟踪、
.pi/plan/和plan_approvals表。 3) 切换 task/session 显式更改为 Agent 并再次运行。 - 预期:Plan 在提供商、工件、批准或队列之前被拒绝 与
PLAN_REQUIRES_INTERACTIVE_SESSION合作;无后台自动批准 发生。显式 Agent 选择允许正常的无人值守策略。 - 链接规格:
03-runtime/04-data-storage.md,03-runtime/08-error-codes.md、04-ux/01-ui-ia.md、ADR 0053 - 接受:F(持久性)、H(诊断)、安全性
- 里程碑:M6
- 状态:自动(2026-08-04 通过):
test:e2e:plan验证 Plan 副作用之前的拒绝和显式 Agent 执行独立于 全局默认值
E2E-111:强制执行主动转向、待批准和配置边界
- 先决条件:一个会话有一个活动的 Agent 回合,并且另一个会话处于活动状态 闲置的; Plan 运行可以变为 pending/queued/running。
- 步骤:1) 尝试第二个提示,mode/provider/model/permission/shell 配置更改,以及活动轮期间的第二次 Plan 提交。 2) 让轮流变为等待批准并重复提示和配置 尝试。 3) 拒绝批准。 4) 提交稍后提示并让 Agent 创建修订后的 Plan 快照。 5) 会话结束后重复配置 可编辑的规划。
- 预期:Active-turn/configuration 更改、提示和第二个 Plan 当回合或活动待决时,提交失败并显示 pending/queued/running/Plan 存在批准;仅阻止原始会话。拒绝返回 Plan 的持久会话和规划的实时状态,清除大门,以及 允许后来的 prompt/new 工件。终端提案快照不 禁用输入、Composer 模式芯片或当前期间的模型选择 渲染器的生命周期。 Idle/planning配置成功且无跨会话 事件或工作区根泄漏。
- 链接规格:
03-runtime/01-ipc-protocol.md,03-runtime/02-agent-runtime.md、03-runtime/06-host-rpc-protocol.md、03-runtime/10-session-state-machine.md、04-ux/08-component-spec.md、ADR 0053 - 验收:C (conversation/stream)、E(权限)、质量
- 里程碑:M6
- 状态:自动(2026-08-04 通过):
test:e2e:plan验证主机 边界和test:e2e:plan-ui验证仅待处理的门控以及可编辑 当前渲染器生命周期内的 rejected/terminal 状态
E2E-112:可选择的 shell 目录保留默认值
- 前提:主机有一个可用的平台目录条目,一个固定装置可以 使持久选择不可用,并且项目绑定的 Agent 会话是 闲置。 Windows 通道练习多选排序。
- 步骤:1) 检查目录中的平台有效 ID
windows-powershell、cmd、git-bash和bash。 2) 验证设置 拒绝不可用或错误的平台 ID。 3)选择可用的shell 并坚持defaultCommandShell。 4)使坚持的选择不可用, 重新启动,并验证目录选择第一个可用的平台 shell 与fallback: true。 5) 执行未更改的Bash工具。 - 预期:设置仅保留有效的稳定 shell ID;不可用 条目在指导下仍然不可用,并且稍后仍然不可用 选择有意使用第一个可用的后备。主机调用 有效 shell,同时 tool/protocol 名称保留为
Bash,并且 shell 选择遵循空闲配置边界。 - 链接规格:
03-runtime/01-ipc-protocol.md,03-runtime/03-tools-and-permissions.md、03-runtime/06-host-rpc-protocol.md、04-ux/06-settings-ia.md、04-ux/08-component-spec.md、ADR 0054 - 接受:B (model/config)、E (tools/permissions)、F(持久)
- 里程碑:M6
- 状态:自动(2026-08-04 通过):
test:e2e:plan验证目录, 验证、持久化和重启;确定性 host-core 目录 当存储的 shell 不可用时,测试验证第一个可用的回退
E2E-113:过时的 shell 身份无法关闭
- 先决条件:Bash 回合具有固定的有效外壳 ID/dialect;这 固定装置可以在生成之前更改有效目录选择。
- 步骤: 1) 更改有效的 shell ID 或方言。 2) 执行 Bash 旧的预期 ID。 3) 检查流程创建、回退尝试、审核、 和用户界面错误。 4) 启动新一轮并重试。
- 预期:第一次调用返回
COMMAND_SHELL_CHANGED,开始没有 工艺,且转销后不换壳。审计记录了 选择的 ID 和方言。稍后运行需要新的回合快照。 - 链接规格:
03-runtime/03-tools-and-permissions.md,03-runtime/05-host-core-rust.md、03-runtime/06-host-rpc-protocol.md、03-runtime/08-error-codes.md、05-security/01-security.md、ADR 0054 - 接受:E (tools/permissions)、H(诊断)、安全
- 里程碑:M6
- 状态:自动(2026-08-04 通过):
test:e2e:plan验证过时 创建标记之前的方言拒绝加上 host-core 过时的 ID/dialect 测试
E2E-114:Bash 独立流 stdout 和 stderr
- 先决条件:选定的 shell 可用且确定性命令 写入交错的 stdout 和 stderr 块。
- 步骤: 1) 通过
Bash执行命令。 2)观察host/RPC/UI 输出事件。 3) 检查最终的有界结果和成绩单行。 - 预期:stdout 和 stderr 保持独立,按工具调用排序,并且 进程运行时可见。最终输出保留截断元数据; 没有跨会话或回合的块,并且 Bash 协议名称未更改。
- 链接规格:
03-runtime/06-host-rpc-protocol.md,03-runtime/09-logging-and-observability.md,03-runtime/16-tool-result-limits.md、04-ux/09-interaction-patterns.md、ADR 0054 - 验收:C(流)、E(工具)、质量
- 里程碑:M6
- 状态:自动(2026-08-04 通过):
test:e2e:plan验证不同的 stdout/stderr 通知和最终工具身份; host/runtime 流测试 涵盖有界累积和会话隔离
E2E-115:Bash 超时使用 60 秒和有界覆盖
- 前提条件:选定的 shell 可以运行超过 60 秒的命令; 主机时钟是可观察的。
- 步骤:1) 在没有超时覆盖的情况下运行。 2) 观察60秒 截止日期。 3) 以范围内超驰运行。 4) 提交零、负数和 超过 300 秒的覆盖。
- 预期:缺少超时正好使用 60 秒并返回 进程树关闭后的
TOOL_TIMEOUT。范围内的值起作用 1–300 秒;超出范围的值将无法验证并且永远不会生成。 - 链接规格:
03-runtime/03-tools-and-permissions.md,03-runtime/06-host-rpc-protocol.md、03-runtime/08-error-codes.md、03-runtime/16-tool-result-limits.md、05-security/01-security.md、ADR 0054 - 验收:E(工具)、H(诊断)、安全
- 里程碑:M6
- 状态:自动(2026-08-04 通过):长时间超时
test:e2e:plan测量无覆盖超时为 60,024 毫秒,并验证在范围内 没有延迟标记写入的无效边界
E2E-116:Bash 中止关闭整个进程树
- 先决条件:Bash 命令启动发出信号的子级和孙级 延迟输出;原始会话正在运行。
- 步骤: 1) 启动命令。 2) 中止当前回合。 3)检查过程 后代、输出事件、审核以及关闭宽限后的状态。
- 预期:进程 group/job 树终止,没有后代保留, 没有后续输出到达,本轮返回
TURN_ABORTED,工作空间为 不会自动回滚。 - 链接规格:
03-runtime/03-tools-and-permissions.md,03-runtime/07-process-model.md、03-runtime/08-error-codes.md、03-runtime/16-tool-result-limits.md、05-security/01-security.md、ADR 0054 - 接受:C(中止)、E(工具)、H(诊断)、安全
- 里程碑:M6
- 状态:自动(2026-08-04 通过):
test:e2e:plan中止真实的 后代进程树并验证没有迟到的 marker/output; host-core 测试 验证取消注册表清理
E2E-117:Agent/Plan/Goal UX 和区域设置不包含聊天控件
- 先决条件:应用程序可以在空闲会话下以英语和中文运行, Plan 工件夹具、外壳设置和命令选项板可用。
- 步骤:1) 检查 Agent/Plan/Goal、权限、工件批准和 shell 英文控制。 2) 输入Plan并检查planning/approval/queue/ 渲染器保持活动状态时处于终端状态。 3) 批准和拒绝 提案,确认主办后批准面消失 确认。 4) 使用命令面板和
/plan-mode//agent-mode斜杠别名用于切换活动空闲会话,确认 Composer 芯片 立即改变。在同一草稿中的任一别名后键入提示,然后 发送;确认模式更改并且提示仍为可见用户 转。单独发送别名并确认它仍然是本地模式开关,无需 创建一个空的转录回合。如果提示发送失败,请确认 完整的草稿仍然可以编辑。 5) 终端提议后重新加载并检查 会话,同时断言 Electron 主进程和主机进程身份已执行 不改变。 6) 在 zh-CN 中重复。 7) 搜索已删除的可见命令 聊天模式和请求更改控件。 Host/app重启恢复是 由E2E-108和E2E-109分别执行。 - 预期:Agent 是默认值;输入左侧的 Composer 芯片是 唯一的活动会话 Agent/Plan/Goal 控制; Plan 和 Goal 展示 Ask/Accept edits/Auto,提交的标题,工件开启器, 记住批准模式,仅限 approve/reject,shell catalog/fallback 状态, 和局部失败关闭状态。否 聊天模式,
/chat-mode,请求更改操作,内联 Markdown/hash/size 要求,或暴露过时的可操作队列;终端检查站 元数据可能仅在当前渲染器生命周期内保持不可操作, 而输入框认可面则在主持人确认后被移除 分辨率。 Renderer 重新加载不会重新水合被拒绝、过期、approved/completed 或 终端卡中断。 Host/app 重新启动不会重播工作或恢复 陈旧的操作,并且 UI 不需要呈现中断的终端 快照;page = "chat"仍然是内部路由。 - 链接规格:
01-product/01-product-scope.md、04-ux/01-ui-ia.md、04-ux/04-builtin-commands.md、04-ux/03-permission-ux.md、04-ux/06-settings-ia.md、04-ux/08-component-spec.md、04-ux/02-i18n-english-first.md、ADR 0053、ADR 0054 - 验收:C(对话),质量
- 里程碑:M6
- 状态:自动化(2026年8月4日通过):raw-CDP
test:e2e:plan-ui针对现有的 Electron Main 探针使用环境门控 主机,断言稳定的 Electron/Host PID,涵盖挂起的恢复、实时终端 控制、拒绝和 approved/completed 终端卡缺席后 渲染器重新加载、EN/zh-CN 和 1280×800 / 900×700 渲染。 E2E-108/E2E-109 涵盖主机重启中断、陈旧动作拒绝和无重放。
E2E-118:重新生成的回合在分支存档后保留其最终答案
- 先决条件:项目绑定的 Agent 会话,其成绩单已包含 一个完整的交换,一个提供足够长的多工具轮流的提供商 最后的助理消息通过持久性发件箱登陆,以及 对
<data_dir>/sessions/<id>.jsonl的读取访问权限,<id>.revisions.jsonl和messages索引。 - 步骤: 1) 重新生成助手答案,以便 root 用户轮流携带
revisionCount/activeRevision和修订版 1 已存档。 2)让 重新运行完成一个回合,以工具调用结束,然后是最后的助手 消息。 3) 紧接着agent_end之后,检查转录文件,messages行,以及存档的修订有效负载。 4) 重新加载会话。 5) 将根气泡翻页至修订版 1,然后再次前进。 - 预期:最终的助理消息出现在转录文件中, 在索引中,并作为存档分支的最后一条消息。每一条消息 转牌保留其所属的
turn_id。根带有revisionCount = 2和activeRevision = 2,重新加载显示完整回合,分页恢复每个 枝全。没有对session.replaceMessages进行调用 回合完成路径。 - 链接规格:
03-runtime/04-data-storage.md§4.9/§7,03-runtime/06-host-rpc-protocol.md§4、ADR 0041、ADR 0060 - 接受:C(对话)、F(持久)、H(诊断)、质量
- 里程碑:M6
- 状态:由 host-core 单元测试覆盖(2026-08-06):
save_active_branch_revision_keeps_a_message_appended_after_its_read档案 在读取后附加一条消息并断言转录本, 存档的有效负载和索引(seq, turn_id)行;replace_messages_preserves_owning_turn_ids涵盖了剩余的重写 来电者。 UI 分页仍然是手动的。
E2E-119:并行子代理在不进入父级上下文的情况下报告
- 先决条件:项目绑定的 Agent 会话,其工作区包含
.pi/agents/scout.md(只读,无tools键)、.pi/agents/fixer.md(tools: Read, Edit)、.pi/agents/pinned.md(model:命名第二个 配置的提供程序)和.pi/agents/broken.md(缺少name);提供商 可以驱动其流在一条辅助消息中发出两个Task调用; 权限模式ask,因此代表的Edit被门控;读取访问权限<data_dir>/sessions/<id>.jsonl和messages索引。 - 步骤:
- 提示一个回合,其中助手发出两个
Task呼叫 —scout和pinned— 在一条消息中。观察代表团卡,同时运行和 各自安顿下来后;折叠它,然后展开每个节点。 - 提示轮流,其中两个
fixer代表各自编辑不同的文件,并且 仅回答第一张许可卡。 - 回答第二张牌,然后提示第三回合,其中有两个
fixer代表们编辑相同文件。 - 当一张卡出现在屏幕上而另一张卡出现时,启动扇出并按停止。 排队。
- 提示
Task调用命名为broken,然后调用一个不命名的代理 存在,则其定义固定未配置的提供商。 - 将会话切换到 Plan,然后切换到 Goal,并检查工具目录。
- 重新加载会话并重新展开委托卡和每个
Task节点。
- 预期:
- 步骤 1 中的两个代表同时运行,并且
pinned单独进行流式传输 provider/model,而父级保留会话的。 - 步骤 1 中的两个
Task调用形成一张全角委托卡。同时 活动时,它打开一次,其标题会更新子代理和已结算的计数; 结算后保留用户的扩展选择并汇总报告 成功、警告或问题状态加上经过的时间。单个Task仍然 使用紧凑的单行。 - 扩展卡显示一个连接到
scout的主代理根,并且pinned按父行顺序排列,代表之间没有发明的边缘。每个 节点显示其代理、简短描述、明确结果、持续时间和步骤 计数。展开节点会显示摘要、报告一次,并且status/turns/toolCalls。委托行仅出现在该节点内部, 绝不在回合流或小地图中。 - 家长的下一个请求包含报告和无委托消息或 工具排;这些行仍然存在于转录文件中并且 索引为
meta.parentToolCallId和meta.agentName。 - 仅渲染头部许可卡;它命名了请求代表并 后面等待的号码。回答它会显示下一张牌,并且都不会 答案解决了另一个请求。
scout根本无法调用Edit或Write;fixer可以。相同文件编辑 步骤 3 按定义的顺序应用,并且不会丢失对方的写入。- Stop 拒绝显示的请求和排队的请求,并且两个委托都结束
aborted位于其自己的Task节点内的文本和图标中 — 父轮 结束一次,聚合卡结算并发出警告。 broken不在带有启动诊断和会话的目录中 保留其他三名代表;未知的代理和无法解析的模型 每个引脚都会失败,因为Task工具错误指出了原因,没有回退到 会话提供商并且没有转向失败。Task不在 Plan 和 Goal 的目录中。- 充值后卡片默认折叠;重新扩展保留节点 顺序、归因、结果和嵌套内容与出现的完全相同 住。
- 步骤 1 中的两个代表同时运行,并且
- 链接规格:
03-runtime/02-agent-runtime.md§5f/§7.2b/§8,03-runtime/03-tools-and-permissions.md§10.2,03-runtime/04-data-storage.md§4.7a、04-ux/03-permission-ux.md§6a、04-ux/08-component-spec.md§9.9,ADR 0062,决策日志 D201 - 接受:C(对话)、E(工具和权限)、F(持久性)、 安全、品质
- 里程碑:M6
- 状态:由单元测试覆盖(2026-08-06):
packages/sharedsubagent-definition.test.ts和packages/agent-runtimesubagent-definitions.test.ts(frontmatter、工具过滤、上限、格式错误 文档、项目阴影内置);subagent.test.ts(报告边界,转 上限、中止、事件归因、提示框架)和path-lock.test.ts(同路径排序、并发上限);桌面permission-inline.test.mjs(队列顺序、ID 匹配删除、工具调用删除、中止拒绝队列、 卡副本),subagent-wiring.test.mjs(主进程发现和模型引脚) 和subagent-transcript.test.mjs+assistant-turns.test.mjs(嵌套, 单一报告打印、记忆),加上subagent-topology.test.mjs(委托检测、结构化结果和汇总计数)。满 多提供商扇出和渲染拓扑交互仍然是手动的。
E2E-097:工具结果读取为结构化块,从不 JSON
- 先决条件:项目绑定的 Agent 会话,具有允许的权限 转牌圈;安装了结果为任意记录的插件工具;的 工作空间包含一个足够大的文件,足以导致主机截断。
- 步骤:
- 运行一轮读取源文件、glob 目录、greps 令牌, 再次使用
outputMode: filesWithMatches和count进行 grep,编辑 工作区文件,编辑临时根文件,运行失败的 shell 命令, 并调用插件工具。 - 检查每个折叠的活动行,然后展开每一行 黑暗。
- 单击 Glob 路径和 Grep 命中标题。 4、触发高危工具,出现内嵌权限卡。
- 读取截断的文件并复制每个块。
- 运行一轮读取源文件、glob 目录、greps 令牌, 再次使用
- 预期:
- 没有扩展行显示转义的 JSON,并且没有有效负载出现两次。
- Read/Write 显示突出显示的内容; Bash 显示命令、输出和 错误色调的 stderr 作为单独的块,省略了空通道;全球演出 路径列表; Grep 显示按文件分组的匹配结果以及
content中的行号 模式、filesWithMatches中的路径列表以及count中的每个文件总计;的 失败的命令携带exit 1芯片。 - 工作区编辑不显示内联差异(其 ReviewChangeCard 拥有它);的 暂存编辑显示了紧凑的差异和
scratch芯片。 - 插件结果呈现 label/value 字段和标记块,而不是斑点。
- 单击路径在工作面板中将其打开;工作空间根目录之外的路径 不可点击。
- 权限卡的参数预览使用相同的块。
- 主机截断标记保持可见,出现
truncated芯片,主机notice在其限定的块下呈现为中性音符,上限 列表报告隐藏的剩余部分,复制产生完整的有效负载。
- 链接规格:
04-ux/08-component-spec.md§9、§10.2、08-meta/decisions-log.md(D192) - 验收:C(聊天和直播)、E(工具和权限)、质量
- 里程碑:M5
- 状态:单位覆盖(
tool-presentation.test.mjs,transcript-style.test.mjs);完整的 UI 旅程草稿
E2E-098:不产生可见文本的回合重新运行一次
- 先决条件:项目绑定的 Agent 会话使用确定性提供程序 在没有工具调用和没有文本的情况下结束一圈的夹具 - 一次带有推理 内容呈现,曾经什么也没有;第二场比赛结束 第一个回合,然后以同样的方式重新运行;计时日志已启用。
- 步骤:
- 使用仅推理夹具启动 Agent 回合并观察 运行时恢复时的转录。
- 随后检查脚本、会话状态和模型计时日志。
- 对无任何装置重复上述步骤。
- 对两次静音的夹具重复此操作并检查终端错误消息, 其详细信息披露及其操作按钮。
- 单击错误的重试操作。
- 重新加载会话并验证哪些内容保持持久。
- 预期:
- 恢复的回合保留相同的可见助手消息 ID,发出一个 终端生命周期,并且没有显示错误。用户只能看到答案。
- 在重新运行之前,空助手会从模型上下文中删除,因此 提供商从来不会连续收到两条辅助消息,而且也永远不会 附加到持久的成绩单中。
- 计时日志记录
outcome=silent且thinkingOnly为 true 仅推理固定装置,对于无任何固定装置为 false,则 重新运行自己的结果。 - 第二次静音发出一个终端可重试
EMPTY_MODEL_RESPONSE辅助错误和生命周期事件;该消息命名了两次尝试,并且 重试操作会重新发送最后一个提示。 - 由于请求工具而文本为空的回合未受影响,因此 是一个中止或已经失败的回合。
- 每个提示仅发生一次重新运行,包括在上下文溢出之后 在同一提示内恢复。
- 链接规格:
03-runtime/02-agent-runtime.md§5e、§7、03-runtime/08-error-codes.md§3.2、08-meta/decisions-log.md(D193) - 接受:C(聊天和直播)、F(持久性)、H(诊断)、质量
- 里程碑:M5
- 状态:单位覆盖(
runtime.test.ts);完整的 provider/UI 旅程草稿
E2E-099:范围搜索保持在预算范围内,特工讲述
- 先决条件:项目绑定的 Agent 会话;工作区包含一个 多兆字节源文件,一个带有
.map同级的缩小包(一行, 兆字节长)、二进制文件和.gitignore排除的依赖树。 - 步骤:
- 检查
tools.list中的Read、Glob和Grep。 2.读取多兆文件,然后从上报的next处再次读取 抵消。 - Grep 命中缩小包及其
.map的令牌。 - 使用
path查找相同的标记,指向被忽略的依赖树, 然后用include缩小到一个扩展,然后用outputMode: filesWithMatches和count。 - Glob 一个广泛的模式,并使用
path和limit进行 Glob。 - 读取二进制文件。
- 运行一个 shell 命令,在标准输出上打印远远超过 shell 预算的内容,然后 在 stderr 上打印进度噪音并打开溢出后失败的一个 每个标记中命名的文件。 8.提出一个需要多个工具批次的问题,并观看成绩单 批次之间。
- 检查
- 预期:
- 每个描述都带有其参数和实际限制数。
- 没有任何一个工具结果超出其预算:Read/Glob/Grep 为 48 KB,96 KB 对于巴什。读取报告
offset、lineCount、fileBytes和下一个偏移量notice;第二次读取继续,没有重叠,并报告totalLines一旦到达终点。 - 任何文件大小都不会被拒绝。来自捆绑包和
.map的行到达 剪辑为 2000 个字符,并且剪辑计数出现在notice中,因此一行 无法消耗结果。 - 显式
path到达被忽略的树;没有它同样的搜索 从那里没有返回任何内容。include、outputMode和headLimit各一个 缩小有效负载,结果按最新修改的顺序排列。
- 二进制读取失败并显示
TOOL_BINARY_CONTENT,并且没有二进制文件到达 模型; Grep 默默地跳过它。- Bash stdout 保留其头部,stderr 保留其尾部,两个标记均命名为哪个 结束幸存和溢出路径,并且每个溢出文件以更完整的方式打开 输出。
- 代理以用户编写的语言回答,位于每个工具之前 批处理用一个关于它正在做什么的句子,永远不会留下多个 批处理没有新的可见文本,并以独立的结果结束。
- 链接规格:
03-runtime/16-tool-result-limits.md,03-runtime/02-agent-runtime.md§7、08-meta/decisions-log.md(D194) - 验收:C(聊天和直播)、E(工具和权限)、质量
- 里程碑:M5
- 状态:单位覆盖(host-core
tools测试,runtime.test.ts提示 断言);完整的 provider/UI 旅程草稿
E2E-100:粘贴的 MCP 服务器仅在其作用域内运行
- 先决条件:磁盘上有两个项目,
~/work/api和~/personal/site。 PATH 上可用的本地 stdio MCP 服务器。每个项目一个 Agent 会话。 - 步骤:
- 扩展 → MCP → 从 JSON 导入。粘贴
mcpServers文档持有 三台服务器:一个有效的 stdio 条目,一个带有url的远程条目,没有type,以及一个没有command的 stdio 条目。 2.确认导入,然后打开导入的stdio服务器并按Test 连接。 - 将服务器留在Everywhere,并要求每个项目中的代理 列出其可用的工具。
- 将服务器设置为这些项目,仅选择
~/work/api。 - 在每个项目中再次询问。
- 在已经打开的
~/personal/site会话中 — 在服务器时组装 是全局的——要求代理按名称调用服务器工具之一。 7、编辑服务器的env并保存;再次在~/work/api中询问。 - 重命名服务器并重新调整范围;再问一次。
- 将服务器的命令指向不存在的二进制文件,保存并打开 一个新的会话。
- 扩展 → MCP → 从 JSON 导入。粘贴
- 预期:
- 导入两台服务器;第三个被列为跳过“stdio 服务器 需要指挥”。远程条目以
http身份登陆,其 url 完好无损。 - 与其找到的工具名称以及行的字形相关的测试报告 从连接状态变为就绪状态。
- 虽然是全局的,但两个会话都会看到
mcp_<serverId>_<tool>名称。 - 缩小范围后,只有
~/work/api会话才能看到它们;总结芯片 读取“1 个项目”并为其命名。 - 第 6 步中的过时调用失败,并显示
TOOL_NOT_FOUND和“not active for 本次会议”——范围在调度时有效,而不仅仅是在目录中。 env编辑会断开连接:下一个程序集重新握手,并且 该工具的行为反映了新的值。第 8 步中的重命名不会 重新连接任何东西。- 损坏的命令记录
failed并带有一条消息,不提供任何工具, 并且不会在下一次会议上重拨;压制测试 重试。
- 导入两台服务器;第三个被列为跳过“stdio 服务器 需要指挥”。远程条目以
- 链接规格:
07-plugins/01-plugin-system.md§12,03-runtime/01-ipc-protocol.md§12a、08-meta/decisions-log.md(D192、D193) - 验收:E(工具和权限)、质量
- 里程碑:M5
- 状态:单位覆盖(
apps/desktop/test/user-mcp.test.mjs,packages/shared/src/mcp-import.test.ts、host-coremcp_servers测试);满 UI 之旅草案
E2E-101:用户技能编写一次并限定每个项目的范围
- 先决条件:磁盘上有两个项目。每个中都有一个 Agent 会话。
- 步骤: 1.扩展→技能→新增。使用空描述保存。 2. 填写描述,编写正文,然后保存。 3. 要求每个项目中的代理按名称使用该技能。 4. 将技能设置为这些项目,仅选择第一个项目, 然后将其关闭并返回到这些项目。 5. 在每个项目中再次询问。 6. 在第一个项目的会话中,将技能范围缩小到第二个项目 并立即要求代理调用它。 7. 粘贴超过 128 KB 的正文。 8. 将应用程序语言切换为中文并重新访问上面的每个表面。
- 预期:
- 没有描述的保存将被拒绝,并显示一条消息命名该字段: 描述是进入提示的唯一部分。
- 基本提示包含技能的 ID、名称和精简的描述以及 不是它的身体;主体仅通过
Skill工具到达。- 切换“关闭”和“返回”可恢复所选项目,而无需重新选择它。
- 缩小范围后,只有范围内的项目的会话可以调用它;另一个 得到“未启用此项目”。
- 步骤 6 在已经打开的会话中也失败了——当 正文已加载,但不受列出它的目录的信任。
- 字节计数器在 128 KB 上限之前发出警告,超过该上限则拒绝保存。
- 每个标签、空状态、错误和计数均以中文呈现,并带有计数 自然地阅读0、1和许多。
- 链接规格:
07-plugins/01-plugin-system.md§12.3,03-runtime/01-ipc-protocol.md§12b、08-meta/decisions-log.md(D174、D192、 D194) - 验收:E(工具和权限)、质量
- 里程碑:M5
- 状态:单位覆盖(host-core
user_skills测试,apps/desktop/test/extensions-page.test.mjs);完整的 UI 旅程草稿
E2E-102:Composer 文件和图像粘贴成为会话草稿参考
- 先决条件:应用程序正在项目中使用 Agent 会话运行,并且 可用的家庭输入框。操作系统剪贴板包含一个文本片段,一个或 更多本地文件(包括带空格的文件名)和图像 单独的粘贴尝试。记录应用程序数据目录和会话 ID。
- 步骤:
- 仅将文本粘贴到编辑器中,并确认文本是由编辑器插入的 本机文本区域路径。
- 粘贴一个本地文件,然后粘贴包含空格名称的多个文件。
- 粘贴来自操作系统 screenshot/clipboard 提供程序的图像。 4.发送前检查草稿:确认每个物化项目都是 可移动的叶名芯片和无划痕的绝对路径占用 文本区域。 Hover/focus 芯片检查其完整路径,删除一个,然后 发送提示并检查会话消息。
- 检查
<data_dir>/scratch/<sessionId>/pasted/并比较保存的 源 files/image 的字节。检查项目git status。 6.删除会话,然后确认其临时目录和粘贴的文件 被删除。
- 预期:
- 纯文本粘贴保持本机状态,不会通过文件桥进行路由。
- 每个 file/image 都使用经过清理、UUID 支持的唯一名称保存在 会话暂存根,而其芯片仅显示已清理的原始根 叶名。重复的叶名称仍然是单独的引用。
- 分派的提示和持久的用户消息包含剩余的 带空格引用的完整路径,而不是标签或二进制字节,并且 代理可以使用其普通文件工具来读取物化文件。
- 家庭粘贴在写入之前创建或重用持久会话。的 工作区保持干净,并且不会创建任何工作区工件行。
- 删除会话会删除粘贴的文件以及其余的内容。
- 链接规格:
04-ux/08-component-spec.md§11.7–11.8,03-runtime/01-ipc-protocol.md§13c,03-runtime/03-tools-and-permissions.md§4b,03-runtime/04-data-storage.md、08-meta/decisions-log.md(D197、D209)、 ADR 0059、ADR 0070 - 接受:C(对话和流),E(工具和权限), F(坚持),品质
- 里程碑:M5
- 状态:单位覆盖(
apps/desktop/test/composer-paste-files.test.mjs); 完整的 UI 旅程草案(除非明确要求,否则不要在本地运行 E2E)
E2E-102a:Composer 文件引用结果使用紧凑的叶名称
- 先决条件:应用程序正在工作区中使用 Agent 会话运行 包含嵌套文件、不同目录中的重复叶名称,以及 名称包含空格的目录。
- 步骤: 1) 键入
@并过滤出嵌套和重复的条目。 2) 检查可见行,然后将鼠标悬停在完整路径工具提示上并检查其 可访问的名称。 3) 接受文件并确认叶名芯片出现,同时 文本区域省略其路径。接受目录结果并继续 子文件。 4) 发送完整的引用并检查持久化的用户 消息。 - 预期:
- 每个结果持久地仅呈现其叶名称;目录保留一个 尾随
/,并且没有父路径消耗水平行空间。 - 工具提示和可访问名称保留完整的相对路径,以便 重复的叶子名称仍然可以区分。
- 文件接受保留芯片后面原始完整的
entry.path; 目录接受保留文字路径延续。发货时 发送并保留的提示包含现有的每个完整路径 空格引用,代理可以正常读取两个选定的文件。
- 每个结果持久地仅呈现其叶名称;目录保留一个 尾随
- 链接规格:
04-ux/08-component-spec.md§11.8,04-ux/09-interaction-patterns.md§8a、03-runtime/01-ipc-protocol.md§13c、08-meta/decisions-log.md(D124、D209)、ADR 0024、ADR 0070 - 接受:C(对话和直播),质量
- 里程碑:M5
- 状态:单位覆盖 (
apps/desktop/test/composer-file-reference-display.test.mjs);完整的用户界面 旅程草稿(除非明确要求,否则不要在本地运行 E2E)
E2E-102b:未答复的停止恢复紧凑的文件参考草稿
- 先决条件:Agent 会话可以延迟其第一个辅助事件。的 草稿包含普通文本、一个工作区参考、两个粘贴参考 具有重复的叶子名称和包含空格的规范路径。
- 步骤:1)发送混合草稿并在助理发短信之前停下来,思考, 或任何工具行开始。 2) 检查修复后的输入框和抄本。 3) 再次发送恢复的草稿并检查保留的用户消息。 4) 重复,允许部分辅助输出开始,然后停止。
- 预期:
- Unanswered Stop 删除刚刚发送的用户行并恢复原始 普通文本加上稳定顺序的叶子名称芯片。
- 相对路径和临时绝对路径永远不会出现在恢复的文本区域中; 重复的标签仍然是不同的参考。
- 重新发送将每个精确的规范路径与现有的路径序列化一次 空白引用。
- 回复开始后停止保留部分中止的记录并执行 不恢复或复制文本或碎片。
- 临时字节保留在现有会话生命周期内。
- 链接规格:
04-ux/08-component-spec.md§11.5/§11.8,04-ux/09-interaction-patterns.md§3.2/§8a.2,03-runtime/10-session-state-machine.md、08-meta/decisions-log.md(D209)、 ADR 0070 - 接受:C(对话和直播)、F(持久)、质量
- 里程碑:M5
- 状态:单位覆盖 (
composer-file-reference-display.test.mjs,transcript-style.test.mjs); 完整的 UI 旅程草案(除非明确要求,否则不要在本地运行 E2E)
E2E-103:在 UI 中编写的子代理到达任务、范围和影子
- 先决条件:应用程序正在运行,并注册了两个项目 A 和 B, 以及每个中可用的 Agent 会话。这两个项目都没有
.pi/agents/目录。记录应用程序数据目录。 - 步骤:
- 扩展 → 子代理 → 新建。将其命名为
log-reader,编写描述并 主体,授予Read, Grep, Bash,然后保存。确认该行显示Task(log-reader)处理并将Bash着色为突变授权。 - 在项目 A 的会话中(无需重新启动应用程序),要求客服人员 委托给
log-reader并确认Task接受该名称。
- 扩展 → 子代理 → 新建。将其命名为
- 将行的范围设置为仅项目 B。开始新的项目 A 并 确认
Task不再提供log-reader并且该行报告它不是 在这里活跃;在项目 B 中重复并确认该项目已提供。 - 将范围恢复为全局。在只读列表中,将
explorer复制为您的 自己定义,保存不变,并确认出现注册表副本 而explorer不再作为内置项出现 — 副本就是Task会跑。重命名副本并确认两个条目均已列出。 - 使用不同的描述写入
<project A>/.pi/agents/log-reader.md。 重新打开选项卡并确认注册表行将项目文档报告为 获胜者,并且只读列表显示项目定义。 6.从注册表中删除log-reader并确认<data>/agents/不再存在 在项目文档仍在加载时保留其文档。
- 预期:
- 创建、编辑、确定范围和删除定义绝不会写入 项目;除了文件之外,两个项目中的
git status都保持干净 在步骤 5 中手写。 - 保存的编辑将在下一个提示时生效,无需重新启动,因为 每次启动都会重新读取目录。
- 使用
SUBAGENT_INVALID拒绝重复的名称,而不是默默地拒绝 后缀,并且注册表不能超过 16 个定义。 - 内置和项目行不提供启用开关和范围控制;他们的 唯一的操作是显示(仅限项目)和复制。
- 优先级是项目 > 用户注册表 > 内置的所有报告。
- 创建、编辑、确定范围和删除定义绝不会写入 项目;除了文件之外,两个项目中的
- 链接规格:
03-runtime/01-ipc-protocol.md§12c–§12d,03-runtime/02-agent-runtime.md§5f、04-ux/01-ui-ia.md§3.5、08-meta/decisions-log.md(D192、D201、D202)、ADR 0062、ADR 0063 - 接受:E(工具和权限)、F(持久性)、质量
- 里程碑:M6
- 状态:部分自动化(
scripts/e2e-subagents.mjs— 注册表 real host-core RPC,则其文件通过真实加载器:scope 双向过滤,16 个上限,项目 > 用户 > 内置优先级,以及 格式错误的文档降级为诊断)加上单元覆盖范围(host-coreuser_subagents测试、packages/agent-runtime子代理定义测试、apps/desktop/test/extensions-page.test.mjs,apps/desktop/test/subagent-wiring.test.mjs);Task的 UI 之旅 保持草稿状态(除非明确请求,否则不要在本地运行 E2E)
E2E-120:全局插件启动、下一回合编辑和停止吞吐量
- 前提:安装并启用中文显示的面板插件 名称是
无限画布。配置一个流传输速度足够慢以停止的提供程序 部分答案。在 macOS 上运行一次,在 Windows 上运行一次。 - 步骤:
- 在 PI-Desktop 未聚焦的情况下,在 macOS 上按 Option+Space 或在 Windows,而另一个应用程序拥有前台窗口。确认一个 居中的启动器出现在指针的显示屏上,没有本机关闭, 最小化、最大化、调整大小或任务栏控件,并且 Windows 不显示 活动应用程序的系统菜单。
- 分别搜索
无限、wuxianhuabu和wxhb。使用 Up/Down 和 输入一次运行,然后单击进行另一次运行;确认现有插件面板 打开。确认中文输入法候选输入不打开结果。 - 开始 Agent 回答。当它流式传输时,输入下一个草稿并进行更改 思考,权限模式,以及Agent/Plan/Goal。确认每个选择都是 可编辑,停止仍然存在,并且发送无法调度。
- 部分输出后停止。确认部分答案仍然存在,排队的 配置只有在终止后才变得持久,并且下一回合 使用最终选择而不是任何中间选择。
- 检查停止的答案的对话统计信息,重新加载会话, 并再次检查。
- 预期:
- 启动器搜索仅返回启用的、准备好的面板插件和每个 调用以空的、集中的查询开始。逃避和失焦隐藏 它无需关闭主应用程序。
- 没有运行回合观察到分阶段的 mode/model/thinking/permission 变化, 并且不能同时发送第二个提示。
- 重新加载之前和之后都存在吞吐量停止的情况。它使用精确的输出 提供商提供时的使用情况;否则 UI 会标记持久化 四码点估计为近似值。
- 链接规格:
03-runtime/01-ipc-protocol.md,03-runtime/02-agent-runtime.md§5b/§9,04-ux/07-ui-design-system.md§8.2–8.3,04-ux/08-component-spec.md§11,04-ux/09-interaction-patterns.md§1/§3、D211、D212、ADR 0072、ADR 0073 - 接受:C(对话和流)、F(持久)、G(插件)、 品质
- 里程碑:M6
- 状态:Unit/source-contract 已覆盖;完整的跨平台 UI 之旅草案 (除非明确请求,否则不要在本地运行 E2E)
E2E-121:Goal 批准恢复自主验收标准执行
- 先决条件:项目绑定的会话具有已配置的提供程序并且是 在 Agent 模式下空闲;工作区允许创建主机工件并且没有 先前的测试目标工件。
- 步骤: 1) 将会话切换到 Goal 并让 Agent 调用
EnterGoalMode,然后是SubmitGoal(title, markdown, question)。 2) 检查 新.pi/goal/*.md工件中的确切 Markdown 字节以及匹配的plan_approvals行。 3) 确认共享审批卡仅公开 Approve/Reject 和 Goal 否认 Write/Edit/plugin 工具,而 Bash 紧随其后 所选的权限模式。 4) 通过询问进行批准并遵守相同的 Agent 在 Agent 模式下恢复。 5)逐个标准检查最终响应 验证或显式边界,然后重新加载会话。 - 预期:Goal 使用 Plan 审批管道,无需第二个规划者; 该工件是不可变的,行记录
kind = goal、路径、哈希、 大小和执行状态。批准是一个单独的用户决定,转换 会话到Agent,并在批准后才开始自主工作。的 重新加载后,成绩单仍可审阅,并且没有 scheduled/unattended Goal run 可以绕过审批边界。 - 链接规格:
03-runtime/02-agent-runtime.md,03-runtime/03-tools-and-permissions.md、03-runtime/04-data-storage.md、03-runtime/06-host-rpc-protocol.md、03-runtime/10-session-state-machine.md、04-ux/01-ui-ia.md、04-ux/08-component-spec.md、D198 - 接受:C(对话和流),E(工具和权限), F(持久性)、H(诊断)、安全性
- 里程碑:M6+
- 状态:Unit/source-contract 已覆盖(
packages/agent-runtime和 host-core Goal 测试);完整的 UI 旅程草案(不要在本地运行 E2E,除非 明确要求)
E2E-122:插件请求并传递本机通知
- 先决条件:已安装的插件声明并被授予
notify;的 桌面平台支持Electron原生通知;操作系统通知 许可处于初始或先前被拒绝的状态。 - 步骤:1)从插件进程中,调用
getNotificationPermission()。 2) 调用requestNotificationPermission()并 观察本机 permission/probe 结果。 3) 打电话showNativeNotification({ title, body })。 4) 对缺少的插件重复此操作notify,并且在不支持本机通知的平台上。 - 预期:第一个状态为
unknown、denied或unsupported;请求 返回尽力而为的granted、denied或unsupported结果;理所当然的 插件接收{ shown: true, permission: "granted" }以进行本机交付, 而 denied/unsupported 传递返回shown: false且不会导致 插件。缺少notify将失败并显示PERMISSION_DENIED。原生插件 通知不会添加持久任务收件箱行或激活聊天会话。 - 链接规格:
07-plugins/01-plugin-system.md,07-plugins/03-plugin-api.md、07-plugins/13-plugin-permissions-matrix.md、 ADR 0074 - 接受:E(工具和权限)、G(插件)、安全性、质量
- 里程碑:M6+
- 状态:Unit/source-contract 已覆盖;完整的跨平台操作系统权限 旅程草稿(除非明确要求,否则不要在本地运行 E2E)
8. 可追溯性矩阵
| 验收 | 应用场景 |
|---|---|
| A — 应用程序启动 | E2E-001、E2E-002、E2E-003、E2E-004、E2E-067、E2E-076、E2E-079、E2E-092、E2E-097 |
| B——模型配置 | E2E-005、E2E-006、E2E-007、E2E-038、E2E-050、E2E-052、E2E-055、E2E-066、E2E-080、E2E-082 |
| C — 对话和直播 | E2E-008、E2E-008a、E2E-009、E2E-010、E2E-011、E2E-011a、E2E-011b、E2E-031、E2E-040、E2E-047、E2E-048、E2E-048A、E2E-049、E2E-052、 E2E-053、E2E-054、E2E-055、E2E-059、E2E-059a、E2E-060c、E2E-060d、E2E-061、E2E-061a、E2E-062、E2E-064、E2E-065、E2E-068、E2E-071、 E2E-073、E2E-074、E2E-075、E2E-081、E2E-083、E2E-084、E2E-086、E2E-087、E2E-088、E2E-089、E2E-090、E2E-094、E2E-095、E2E-096、 E2E-097、E2E-098、E2E-099、E2E-102、E2E-102a、E2E-102b、E2E-106、E2E-109、E2E-111、E2E-114、E2E-116、E2E-117、E2E-118、E2E-119、 E2E-120、E2E-121、E2E-代理-001 |
| D——工作区 | E2E-012、E2E-013、E2E-022B、E2E-024I、E2E-047、E2E-049、E2E-057、E2E-058、E2E-060、E2E-068、E2E-075、E2E-078 |
| E——工具和权限 | E2E-008a、E2E-014、E2E-015、E2E-016、E2E-017、E2E-018、E2E-019、E2E-024I、E2E-024K、E2E-040、E2E-049、E2E-074、E2E-093、E2E-097、 E2E-099、E2E-100、E2E-101、E2E-102、E2E-103、E2E-105、E2E-106、E2E-107、E2E-111、E2E-112、E2E-113、E2E-114、E2E-115、E2E-116、 E2E-119、E2E-121、E2E-122 |
| F——坚持 | E2E-020、E2E-021、E2E-036、E2E-037、E2E-038、E2E-040、E2E-042、E2E-047、E2E-048、E2E-051、E2E-054、E2E-056、E2E-061、E2E-062、 E2E-064、E2E-066、E2E-068、E2E-071、E2E-072、E2E-073、E2E-082、E2E-084、E2E-096、E2E-098、E2E-102、E2E-102b、E2E-103、E2E-代理-001、 E2E-061a、E2E-073a、E2E-104、E2E-106、E2E-107、E2E-108、E2E-109、E2E-110、E2E-112、E2E-118、E2E-119、E2E-120、E2E-121 |
| G——插件 | E2E-022、E2E-022A、E2E-022B、E2E-022C、E2E-023、E2E-024、E2E-024B、E2E-024C、E2E-024D、E2E-024E、E2E-024F、E2E-024G、E2E-024H、 E2E-024I、E2E-024J、E2E-024K、E2E-024L、E2E-024M、E2E-024N、E2E-024O、E2E-025、E2E-026、E2E-105、E2E-117、E2E-120、E2E-122 |
| H——诊断 | E2E-027、E2E-031、E2E-034、E2E-042、E2E-096、E2E-098、E2E-104、E2E-107、E2E-108、E2E-109、E2E-110、E2E-113、E2E-115、E2E-116、 E2E-118、E2E-121 |
| 安全性 | E2E-028、E2E-029、E2E-030、E2E-024J、E2E-024K、E2E-024M、E2E-049、E2E-068、E2E-086、E2E-105、E2E-106、E2E-107、E2E-108、E2E-109、 E2E-110、E2E-112、E2E-113、E2E-115、E2E-116、E2E-117、E2E-119、E2E-121、E2E-122 |
| 品质 | E2E-032、E2E-033、E2E-039、E2E-043、E2E-044、E2E-045、E2E-046、E2E-047、E2E-048、E2E-048A、E2E-049、E2E-050、E2E-053、E2E-055、 E2E-056、E2E-057、E2E-058、E2E-059、E2E-060、E2E-061、E2E-062、E2E-063、E2E-064、E2E-065、E2E-066、E2E-067、E2E-068、E2E-069、 E2E-070、E2E-071、E2E-072、E2E-073、E2E-074、E2E-075、E2E-076、E2E-077、E2E-078、E2E-079、E2E-080、E2E-081、E2E-082、E2E-083、 E2E-084、E2E-085、E2E-086、E2E-092、E2E-093、E2E-094、E2E-095、E2E-096、E2E-097、E2E-098、E2E-099、E2E-100、E2E-101、E2E-102、 E2E-102a、E2E-102b、E2E-103、E2E-AGENTS-001、E2E-024N、E2E-024O、E2E-059a、E2E-060b、E2E-060c、E2E-060d、E2E-061a、E2E-073a、E2E-111、 E2E-114、E2E-117、E2E-118、E2E-119、E2E-120、E2E-122 |
| 里程碑 | 应用场景 |
|---|---|
| M1 | E2E-001、E2E-002、E2E-003、E2E-028、E2E-029 |
| M2 | E2E-004、E2E-005、E2E-006、E2E-007、E2E-008、E2E-009、E2E-010、E2E-011、E2E-011a、E2E-011b、E2E-020、E2E-021、E2E-027、E2E-031、 E2E-036、E2E-037、E2E-042、E2E-087、E2E-088、E2E-089、E2E-090 |
| M3 | E2E-012、E2E-013、E2E-014、E2E-015、E2E-016、E2E-017、E2E-018、E2E-019、E2E-040 |
| M4 | E2E-022、E2E-023、E2E-024、E2E-025、E2E-026、E2E-030、E2E-038 |
| M5 | E2E-008a、E2E-032、E2E-033、E2E-034、E2E-039、E2E-043、E2E-044、E2E-045、E2E-046、E2E-047、E2E-048、E2E-048A、E2E-049、E2E-050、 E2E-051、E2E-052、E2E-053、E2E-054、E2E-055、E2E-056、E2E-057、E2E-058、E2E-059、E2E-060、E2E-061、E2E-062、E2E-063、E2E-064、 E2E-065、E2E-066、E2E-067、E2E-068、E2E-069、E2E-070、E2E-071、E2E-072、E2E-073、E2E-074、E2E-075、E2E-076、E2E-077、E2E-078、 E2E-079、E2E-080、E2E-081、E2E-082、E2E-083、E2E-084、E2E-085、E2E-086、E2E-092、E2E-093、E2E-096、E2E-097、E2E-098、E2E-099、 E2E-100、E2E-101、E2E-102、E2E-102a、E2E-102b、E2E-AGENTS-001、E2E-059a、E2E-060b、E2E-060c、E2E-061a、E2E-073a、E2E-094、E2E-095 |
| M6 | E2E-104、E2E-105、E2E-106、E2E-107、E2E-108、E2E-109、E2E-110、E2E-111、E2E-112、E2E-113、E2E-114、E2E-115、E2E-116、E2E-117、 E2E-118、E2E-119、E2E-120、E2E-103 |
| M6+ | E2E-121, E2E-122 |
| 后MVP | E2E-022A、E2E-022B、E2E-022C、E2E-024I、E2E-024J、E2E-024K、E2E-024L、E2E-024M(插件路线图 R2/R3/R6) |
US-UI-* 视觉场景(§UI shell 视觉场景)追踪到 决策日志 §D 中的法典平价决策 而不是 A-H 标准;他们的黄金来源是捕获套件。
9. AI 必须如何更新本文档
添加或更改影响用户可见或协议可见行为的功能时:
- 使用第 6 节中的模板添加新场景。分配下一个可用 ID (
E2E-<N>)。 - 将其链接至相关验收标准 (A–H) 和里程碑 (M1–M6 或 M6+ 用于当前产品增量)。
- 将状态设置为
Draft,除非已存在自动测试。 - 更新第 8 节中的可追溯性矩阵。
- 提交更新作为更改的一部分(根据 ai-development-workflow R3)。
10. 未来自动化地图
当实施 E2E 自动化时(M5 之后):
- 每个
Draft场景→剧作家测试文件。 - 场景 ID 变为测试用例名称:
e2e-001-app-launches。 tests/e2e/fixtures/目录中定义的夹具和测试数据路径。- CI 门:所有 E2E 场景必须通过才能发布。
当工具决策最终确定时,自动化部分将在未来的 ADR 中扩展。
11. 验收标准
该测试计划规范在以下情况下被接受:
- [ ] 所有 MVP 验收标准 (A–H) 至少有一种 E2E 场景。
- [ ] 所有安全验收项至少有一个 E2E 场景。
- [ ] 每个场景至少链接到一个规范文档。
- [ ] 可追溯性矩阵已完成(场景 ↔ 验收 ↔ 里程碑)。
- [ ] 场景模板已定义,所有条目均遵循该模板。
- [ ] AI 更新规则已记录并与工作流程规范交叉链接。
- [ ] 环境要求符合基线(macOS arm64,干净的配置文件)。
UI shell 视觉场景
US-UI-01 符合 Codex 的外壳镀铬
- 在 macOS 深色主题上打开桌面应用程序。
- 预计木炭主表面(
#181818),左侧边栏包含当前项目 和临时会话组,以及浮底输入框 配有 mode/model 控件,无工作区导轨。 - 预计不会有蓝石营销镀铬;主要发送控件是一个圆形倒置按钮。
US-UI-02 空线程英雄
- 打开或创建零消息的线程。
- 期待居中的英雄文案“我能帮你建造什么?”,一个简短的静音 支持线,没有开发者入门卡。可选的项目名称 当工作区打开时,仍然是点下划线操作。
US-UI-03 侧边栏目的地
- 预计扩展的主页侧边栏将显示会话和项目,而无需 独立插件、拉取请求或计划行。
- 单击侧栏页脚右侧的插件图标 设置,并期望它用专用页面取代主窗格。
- 打开设置→项目存档并使用它来打开、切换和关闭本地 文件夹工作区。
US-UI-04 没有工作区上下文的 Composer
- 打开 git 工作区时,composer 不显示项目、本地或分支 提示表面上方的标签。
- 操作模式选择器在 Agent、Plan 和 Goal 之间切换;双方签订合同 模式保留了权限模式芯片并解释了它们的 Bash 权衡。
US-UI-05 区域设置 chrome
- 在 zh-CN 系统语言环境中,侧边栏标签以中文呈现(项目/临时会话), 没有拉取请求或已安排条目。页脚插件图标显示 本地化的可访问名称插件。
- 空线英雄和辅助线均为汉化汉化副本;项目 当工作区打开时,名称仍然是点下划线操作。
- Composer 省略本地工作区标签并显示 Agent/Plan/Goal 以及 活动模型 ID;这两个区域设置都会公开 Plan 和 Goal 批准副本。
US-UI-06 会话自动标题
- 创建一个新任务并发送第一个提示,例如“同步代码”。
- 期望其项目或临时会话行标题成为截断形式 该提示而不是保留“新任务”。
US-UI-08 仅快捷方式目的地历史记录
- 导航设置 → 项目存档 → 项目会话 → 插件。
- 扩展侧边栏或主标题栏中不会有 back/forward 按钮。
- 按
Cmd/Ctrl+[和Cmd/Ctrl+];期望他们能够穿越那段历史。
US-UI-09 分组会话标题回填
- 打开先前显示“新任务”/“新聊天”但有第一条用户消息的旧会话。
- 期望其范围侧边栏行显示截断的第一用户消息标题 会话列表加载后。
US-UI-11 空草稿重用
- 单击“新任务”两次。
- 预计当前项目或临时项目中只有一份空的“新任务”草稿 团体和主场英雄仍然可见。另一个范围内的空草稿是 不被重复使用。
US-UI-12 Composer 不带工作区导轨
- 在空主目录、项目主目录和线程中,预计没有项目/本地/ 输入框上方的分支上下文栏。
- 提示外壳保持一个不间断的圆角表面,无保留 导轨高度、附加顶唇、导轨阴影、底部接缝或分隔符。
US-UI-13 Light 主题 shell 平价
- 在浅色 macOS 外观上将主题设置为 system/light。
- 预计侧边栏
#f3f3f3、主#ffffff、文本#1a1c1f、白色浮动输入框和带有项目下划线的主页英雄。 - 侧边栏 project/session 标签、页脚 Settings/Plugins/notification 图标、当前项目标识、线程标题和输入框控件必须保留 可读明暗对比 (≥4.5:1)。永远不要 white/translucent 文字亮起 侧边栏。
- macOS 交通灯行使搜索和折叠侧边栏在 就在浅铬上,不渲染 Logo/Home 品牌。
US-UI-14 语义 chrome 标记
- 切换主题系统→浅色→深色,无需重新启动。
- Shell chrome(侧边栏项目、Composer 运行时控件、图标按钮) 两个主题中均遵循语义
--ds-text-*/--ds-bg-*标记;不 浅色表面上的硬编码白色 (gray-0) 文本。
US-UI-15 法典密度 + 海拔
- 侧边栏行使用紧凑的约 28–32 像素间距,层次结构为 12–14 像素 US-UI-69 和 8px 水平填充(Codex
radius-token-row10px)。 - 浮动输入框使用 Codex 高度突出:0.5 像素笔画 + 柔和的 3px/20px 阴影(不是沉重的 10–30 像素下降)。
- 空英雄标题的行高为 28px / 34px,粗细为 400。
- 如果 Stage Manager 折叠窗口,窗口将恢复 ≥1000×700(目标 1200×800)。
US-UI-16 侧边栏页脚实用布局
- 在 light/dark home shell 上,侧边栏页脚是一个透明实用程序 带没有分隔符。设置、插件和通知操作 分组在左侧,而 build/version 芯片则右对齐。
- 通知铃声在左侧操作组中仍然可见,其 未读徽章并打开页脚上方的收件箱;主标题栏没有 复制贝尔。
- 单击 build/version 芯片会检查当前更新或打开 设置 → 可用更新时的信息。
- Codex
{x:16,y:16}上的交通灯带有 46 像素的工具栏;扩展的 macOS 侧边栏将搜索加折叠侧边栏放在右侧相同的位置 行,没有 Logo/Home 品牌或 back/forward 按钮。
US-UI-17 PI-Desktop 家庭英雄标志
- 在空聊天主页上,100px
HomeMascotLogo使用以下方式在标题上方呈现 剩下的九个姿势组(50个透明吉祥物框架)编译自 提供的docs/ip纸。 - 每个空置坐骑随机选择一组并仅播放其可见的组 阿特拉斯细胞。当一组完成后,另一组被随机分配,没有 闲置几秒后立即重复;单帧组休息 更长。悬停吉祥物绕过空闲休息并不断前进 通过姿势组。精灵保持其原生像素艺术颜色 减少的运动保留当前组的第一帧。
- 标题为 28px / 粗细为 400;活动项目名称使用点下划线(1 像素,偏移 4 像素)。
- Composer 不会在有效负载之前渲染附件或 appshot 控件 首尾相连达到 pi。
US-UI-18 Composer 没有惰性操作
- 在聊天主页和停靠线程上,检查每个输入框控件。
- 当这些有效负载存在时,预计没有文件、照片或应用程序快照控件 pi 运行时不支持。具有精确推理能力的模型揭示了 当前思维级别紧邻 Agent / Plan / Goal 右侧;不支持的 模型显示没有触发器。未知的兼容模型可以显式启用 从模型菜单思考,更改更新持久会话。
- 预计 Composer 中没有项目、本地或分支上下文标签。
- 每个可见的 Composer 控件都会更改活动会话、打开其菜单,或者 submits/aborts 当前回合。
US-UI-19 永久舞台管理器边界恢复
- 在使用 Stage Manager 的 macOS 上,缩小或取消聚焦 PI 窗口,直到宽度 < 1040 或高度 < 700。
- 预计外壳会重新声明类似 Codex 的足迹(~1200×800,最小 1040×700)并在仍然折叠的情况下继续恢复(不仅在发射后的前 20 秒内)。
US-UI-20 深色浮动编辑框
- 在聊天主页切换到深色主题。
- 预计主
#181818、侧边栏#000000以及位于高架主要位置的浮动输入框板(#212121f5/ 灰色-800 96%),具有高程突出笔画 + 软升力,以便盒子在主表面上读取。
US-UI-21 顶栏模型菜单配置 pi
- 与提供商 A/model A 创建会话,然后打开顶栏模型菜单。
- 期望启用、可运行 provider/default-model 对和 Agent 条目。的 模型触发器仅显示模型 ID;能力门控思维触发器是 放置在 Agent / Plan / Goal 旁边,而不是嵌套在模型菜单中。
- 选择提供商 B/model B,发送提示,并期望 main-to-sidecar
agent.prompt负载和 pi 运行时使用 B 进行该会话。 - 切换离开和返回;期望 B 继续被选中。当回合运行时,预计 模型控制被禁用。
US-UI-22 配置文件页脚菜单
- 在侧边栏页脚上,单击
Custom/Local profile触发器。 - 预计页脚上方 8 像素处有一个 280 像素的不透明升高菜单。重复本地的 非交互式标题中的标识,然后显示分隔符和设置, 按顺序记录日志和主题操作。
- 方向键贯穿三个动作; Home/End 跳转到边界。 Escape 关闭菜单并恢复触发焦点。外部指针按下 关闭它而不窃取目标焦点。
- 设置导航到设置页面,日志打开本地日志,主题 关闭菜单后循环当前主题。
US-UI-23 项目档案索引
- 打开设置 → 项目存档。
- 预期设置标题“项目存档”加上三个堆叠带 (D168): 带有一个意图句子的概述横幅,主要的“添加项目”,以及 四个计数器(项目、开放、存档、会话);带有搜索功能的工具栏 字段、清晰的可供性、实时匹配计数以及最近/姓名排序分段 控制;以及按“固定”、“所有项目”、“存档位置”顺序排列的分组索引 当前的每个部分都显示其标签和行数。完全没有项目的情况下 分组索引被一张具有其自己的主要操作的空状态卡所取代。
- 期望每一行都带有一个彩色字形,即项目名称及其活动/ 打开/固定/存档标签,一条带有缩短的等宽字体的元行 路径、分支和会话计数、相对最后活动时间以及 悬停显示新任务和行菜单操作。已归档的行保持列出状态并且 软化而不是隐藏。
- 展开一个非活动项目并打开其中一个会话;期望该应用程序 在选择会话之前激活该项目,因此工作区工具和 会话范围使用相同的项目。
- 将排序切换为名称并期望行在每个部分内重新排序 没有隐藏行;清除搜索并期望返回完整的索引。
US-UI-24 设置全页 shell
- 打开设置(页脚配置文件 → 设置)。
- 预计全页 Codex 设置(无应用程序 sidebar/nav)。左导轨有后部 到应用程序、搜索和确切的基础知识/全局AI/快捷方式/模型配置/ 按顺序导入/项目存档/信息;内容窗格显示部分标题和 目的地的设置或存档内容。
- 返回应用程序外壳并期望插件保持独立 侧边栏页脚目的地。
- 将空的 46 像素顶带拖到导轨或内容窗格上;本地人 窗口移动,而“后退”、“搜索”和“导航”仍然可单击。
US-UI-27 深色目标页面
- 强制使用深色主题并打开插件和设置 → 项目存档。
- 预计黑色侧边栏、主
#181818和目标 cards/rows 在升高的暗板(不是平面同灰色)上可读。
US-UI-28 主页空输入框协会
- 在空的聊天主页(浅色+深色)中,期待英雄,可选的入门 清单和家庭输入框在一个可滚动的垂直流中(D111/D204/D206), 没有大的空白间隙或起始卡层。
- 组合器仍然是一个独立的板,没有附加的工作区导轨。
- 开始转录会恢复底部停靠的输入框并带有淡入淡出的面纱。
US-UI-29 Light Composer 板易读性
- 在浅色主题的空屋中,白色输入框外壳使用统一的实体 填充没有内部渐变或背景图像。
- 外壳仍然通过细细的笔触读作一个升高的盒子,
#ffffff主表面上的受限软阴影。 - 工具栏控件和占位符保持清晰(不是纯白底白字)。
US-UI-30 Composer 占位符副本
- 空输入框显示 PI-Desktop 占位符副本:EN
Ask PI-Desktop to do anything、zh-CN向 PI-Desktop 下达任意指令。 - 占位符墨水在浅色和深色浮动板上清晰可见。
US-UI-31 Home 空垂直堆栈 (D111/D204/D206)
- 给定空聊天主页,当窗口为~1200×690时,英雄和可选 入门清单呈现在上方居中的可滚动内容堆栈中 底部保留的家庭输入框(不是双增长绝对门户区域)。
- 不存在起始卡或绝对覆盖;新手引导清单 仍然可操作,并且可以直接与输入框联系。
US-UI-32 深色浮动框标高
- 给定黑暗主题空置家庭,当绘制输入框外壳时,它在
#181818上使用升高的主#212121,并具有与光相同的高度突出笔划+提升(没有较重的自定义深色阴影)。
US-UI-33 范围侧边栏会话组
- 主侧边栏没有最近的聚合。
- 它为每个保留的项目路径显示一个独立的可折叠标题 嵌套会话和一个
Temporary sessions/临时会话标头 无路径会话。 - 项目和临时标头公开紧凑的特定于范围的
+控件; project/session 溢出菜单公开 pin/archive 操作;导航行间距 保持约 32 像素,会话行间距约 28-31 像素。
US-UI-34 Home 没有开发者入门卡 (D206)
- 在空的聊天主页(浅色+深色)上,没有开发人员入门网格、卡片或 上下文快速操作行在英雄和输入框之间呈现。
- 任务条目直接从底部编辑器开始,而可选的 新手引导清单在存在时仍然可操作。
US-UI-35 空作曲器板密度
- 空屋输入框结构紧凑,内容驱动,带有空行或一行 草稿;它不保留以前固定的~148px空板。
US-UI-36 Hero Y + 夜间箱仰角
- 在 ~1200×690 灯光下,英雄形成一个居中的方块;家 滚动条不会剪裁其顶部或与底部合成器重叠,并且没有启动器 网格被渲染。
- 深色家庭输入框板读取为升高的主要
#212121f5,并相对于#181818具有高度突出(不是平坦的同一表面)。 - 灯光合成器渲染为一个不间断的实体表面,没有上下文 轨道或独立顶立面。
- 模型芯片显示当前模型ID;它的菜单仅包含可运行的 provider/model 选择和 Agent。
- 占位符和批准芯片在浅色和深色板上仍然清晰可见。
US-UI-39 主标记 + 英雄标题光学
- 空置 PI-Desktop 标记可见(并非几乎不可见);笔划密度保持可读,没有装饰性重影效果。
- 项目的空主标题使用可读的项目标签范围(短基本名称可能显示为
PI-Desktop以实现光学奇偶校验)。
US-UI-40 主页内容宽度与 rem root
- 在 1200×690 光空的家里,输入框板外部宽度为〜744–760px(不是〜640px)。
- 主页建议网格与输入框板跨越相同的内容列。
US-UI-41 黑暗英雄 + 夜间框可读性
- 深色空家庭英雄标题墨水是浅色深色(
--ds-text-primary/接近白色),而不是硬编码的#1a1c1f。 - 夜间输入框板位于主
#181818上,主#212121f5升高,高度突出;浅色主题不强行给夜盘填充。
US-UI-42 Light范围会话创建chrome
- 在轻型侧边栏上,会话和项目范围的创建控件仍然存在 仅图标,带有语义悬停清洗;不会呈现独立的新任务行。
US-UI-43 空本垒板 Y + 夜间高架-初级
- 以 ~1200×690 浅色主题打开空荡荡的家。
- Composer 板底部对齐且内容驱动:空行或一行 草稿使用紧凑的外壳,而不是固定的最小 ~140px;表面 保持均匀的固体,没有装饰性的洗涤。
- 切换深色主题:夜盘为高架-主色(
#212121f5/ 灰色-800 96%)具有相同的约束标高并且没有内部梯度。
US-UI-44 设置紧凑目录+合并部分
- 打开设置灯光主题~1200×690。
- 全页外壳:
#f3f3f3上的轨道 ~260px,主#fff;返回应用程序;搜索药丸;带有图标的基础活性药丸。 - 铁路订单完全是基础知识、全局 AI/AI、快捷方式、说明、模型 配置、导入、项目存档和信息; 没有 Personal/Integrations/Coding 组标题、插件重复、 或占位符目的地。
- 基本内容:大标题和一张带有工作信息的外观卡 system/light/dark 控件和 默认 卡。 全局AI持有权限 上下文管理;快捷键包含键盘快捷键卡。 文件打开目标、语言 覆盖、菜单栏行为和底部面板行为不存在,直到 存在主机支持的实现。
- 模型配置包含提供商工作室英雄,默认mode/model,回车发送 交换机,以及带有添加提供商对话框的基于卡的提供商管理。
- 插件 load/enable/disable/uninstall 仍然可以从应用程序 shell 中使用 独立的扩展目的地。
- 深色:铁路
#000、主线#181818、卡高架#212121。
US-UI-38 Composer 工作区上下文被省略
- 在空置的家、项目家以及开始转录后,输入框 从不渲染项目/本地/分支胶囊。
- 工作区身份通过主页英雄或侧边栏仍然可见 而不是在提示符上方重复。
US-UI-37 空草稿行 + 调整大小
- 空的输入框提示行不显示领先品牌图标并保留可见 占位符墨水(不是空白的 white/night 孔)。
- 自动调整大小永远不会折叠低于 ~28px 的空文本区域。
- 禁用的发送控制是一个亮着的灰色实心芯片(
#8e8e90),完全不透明,带有白色箭头。 - 暗夜板保持升高的主
#212121f5,并在#181818上突出可读的升高。
US-UI-31b(已取代)
- 被 US-UI-31 家用空垂直堆栈 (D111) 取代。
US-UI-46 Home-with-project Composer chrome
- 在空荡荡的家里打开一个项目(没有成绩单)。
- 预计板上没有连接工作区控件;没有遗留草案 标记,占位符使用 PI-Desktop 副本。
- 模型芯片显示当前模型ID;页脚使用循环本地用户 字形、两行自定义/本地配置文件标识、披露 V 形符号和 单独的“帮助”→“设置信息”控件。
US-UI-47 项目指数平价
- 打开设置 → 项目存档。
- 期望设置部分标题、搜索药丸、添加项目按钮和 完整的持久项目列表,包括存档行。
- 行扩展以显示最近的任务;激活项目或其会话之一 使用
setProject而不通过对话框重新选择并保留 session/workspace 上下文同步。侧边栏 pin/archive/close 元数据保留在本地 渲染器并且从不隐藏或删除持久的项目存档行。
US-UI-48 Home starter 字形和标签缺失 (D206)
- 在空置的房屋中,没有开发人员入门图标板、title/description 或 入门卡字形以浅色或深色主题呈现。
- 英雄、可选的入门清单和底层输入框仍然是唯一的 空置的任务输入表面。
US-UI-49 范围侧边栏行镀铬
- 将鼠标悬停或选择项目或临时会话行。
- 预期标题行具有 active/hover 背景且紧凑 pin/archive 的溢出操作(不是最近聚合)。
- 多个保留的项目组可能会同时可见;剩余会话数 在精确路径组下,而封闭项目会议仍然可用 设置 → 项目存档。
US-UI-50 目的地标题比例
- 打开设置 → 项目存档和插件。
- 预计大节标题 (~28px) 与 Codex destination/index 页面一致。
- 黑暗家庭范围内的会话创建控件保持安静的图标操作,无需 独立的新任务行。
US-UI-52 设置金铬指标 (D070)
- 打开“设置”灯“基本”,分辨率约为 1200×690。
- 预计约 275 像素
#f4f4f4导轨,单个活性基础药丸,后退 + 搜索。 - 期望工作主题选择器没有惰性切换或开放目标行。
- 期待权限+基础+外观提升卡; Agent, 导入和信息仍然是唯一的其他目的地。
- 在 1040 像素、1200 像素和 1600 像素宽度之间调整大小;内容卡填充 每种尺寸都可用右窗格,无需更换导轨或引入 水平滚动。
US-UI-53 设置暗壳 (D070)
- 深色主题设置基础:黑色导轨、提升卡、蓝色开关、返回聊天。
- 行描述使用主题感知辅助文本并保持清晰可读
#212121卡面;它们不能退回到低对比度的柔和墨水。
US-UI-54 Toast 变体 + 生命周期 (D085)
- 触发成功(保存提供程序)、错误(使用无效密钥运行)和 来自测试插件的信息 toast。
- 预计顶部中心堆叠在高架板上,带有有色变体图标(绿色✓/红色!/信息)和每张卡的X消除;最新的牌进入顶部中心的锚点并将旧牌推下。
- Success/info 自动关闭约 4 秒,错误持续约 8 秒;将鼠标悬停在卡片上会暂停倒计时; X 立即将其删除。
- 当堆栈与无框标题栏带重叠时,悬停仍然会暂停 倒计时和每个 X 仍然可点击,而不是拖动窗口。
- 重复相同的操作会重新启动现有的Toast,而不是堆叠重复的Toast;堆栈永远不会超过 4。
- 捕获装备场景
pi-toasts-light/pi-toasts-dark显示两个主题中的堆栈。
US-UI-55 Composer 文本区域增长 (D089)
- 在家庭输入框和线程对接输入框中,空草稿或单行草稿 显示一根可见的文本行。
- 输入或粘贴两到七条视线;文本区域随着 无需手动调整大小即可包装内容。
- 添加第八条视线;文本区域保持在七行可见的位置 内部滚动而不是进一步发展输入框。
- 删除回一行或提交草稿;文本区域收缩到它的 默认一行。
US-UI-56 Codex 转录工具活动
- 在浅色和深色主题中,工具调用使用透明紧凑的活动行, 不是高架卡片或彩色成功轨道。
- 连续调用出现在一个默认折叠的处理组内。其 活动标头显示
Processing · {elapsed}且其完整标头显示Processed for {elapsed},加上本地步数。 - 该行显示语义 15–16px 图标、progressive/past-tense 操作、 椭圆形等宽参数提示、安静披露 V 形和本地化 running/error/denied 状态。
- Fork 系列工具显示 GitFork 分支图标而不是通用工具 字形。
- 展开已完成的调用会在输入之前显示输出。两个部分都是 可独立复制并带有内部滚动功能。
- 重新加载会话会保留操作标签和参数提示,而不是 将该行降级为通用
Tool。 - 运行一个回合,发出辅助文本,调用多个工具,然后继续 更多辅助文本。在流式传输期间和会话重新加载后,预计会出现一个 整个用户回合的辅助文章,其中包含片段和活动 原始订单,但只有一个尾随 model/usage 行和一个 Copy/Fork/Retry 工具栏。副本按顺序包含所有辅助文本片段。
US-UI-57 多项目侧边栏组
- 打开项目 A 和 B,但不关闭其中任何一个。
- 预计
Sessions标题高于Projects,包含无路径 对话加上新会话和排序操作。拥有五个以上 独立对话,期望有一个五行高的列表,可以滚动到每个 剩余行不再进一步增长。 - 右键单击
Sessions标题或空白独立列表 chrome 并期望 一个单项创建菜单,用于 creates/reuses 无路径临时会话。 - 期望以下
Projects标题保留其新项目文件夹 操作、每个保留项目一个路径键控组以及一个活动状态标记 恰好在一个组上。它的列表消耗剩余的高度并滚动 独立。相邻的项目组被视为紧凑的连续树 无分离卡间距。 - 右键单击
Projects标题或空项目列表镶边并期待 一项创建菜单,打开与文件夹加相同的项目选择器 行动。 - 期望项目和会话列表在侧边栏主体内滚动,而无需 在页脚后面剪裁;侧边栏 Search/Collapse 保留在侧边栏中 标头。当工作面板打开时,预期其唯一的折叠控制位于 会话窗格右上角而不是工作面板内容标题,与 主窗格右边缘的分隔线。
- 通过单击目录标签折叠 A,将其从 V 形区域展开, 然后激活B并返回A。只有A的子行折叠;项目
+并且溢出操作不会切换它;的 活动项目、顶栏路径和脚本一起切换;输入框 仍然不受工作区身份镀铬的影响。 - 关闭 B 并从“设置”→“项目存档”重新打开它。关闭仅删除侧边栏选项卡; 持久的 project/session 行仍然可用。
US-UI-58 侧边栏组织操作
- 打开项目和对话溢出菜单。
- 需要本地化的 Pin/Unpin、Archive/Restore 和(对于对话)删除 具有键盘可访问的菜单语义的操作。
- 从独立的
Sessions标题打开排序菜单,第一个引脚 project/session,并选择每个面向用户的排序模式(最近更新, 创建日期,最早的在前,名称)。固定的行保留在第一位。 - 存档一行,验证默认情况下不存在,启用显示存档,然后 恢复它。成绩单和项目绑定保持不变。
- 传统的
manual首选项加载时不会出现拖动重新排序 可供性。
US-UI-59 基于会话的后台工具
- 在项目 A 中启动可见轮次,在项目 B 运行时切换到项目 B,并且 检查两个侧边栏状态指示器。
- 期望轮到 A 在后台继续,B 的 composer/context 显示 仅 B,并且来自 A 的工具 output/artifacts 保持扎根于 A,无需 打开或激活 B 上的工作面板选项卡。
- 打开临时会话并调用工作区所需的工具;期望 正常的
WORKSPACE_REQUIRED结果而不是从 B 继承。
US-UI-60 WorkBuddy 成绩单板 (D101)
- 打开浅色和深色主题的混合成绩单。
- 期望右对齐紧凑的用户板,透明的全角助手 散文,更密集的行间距,以及每轮下仅悬停的复制芯片。
- 当助理回答时,请注意左口音规则,而不是 一个盒装框架。
US-UI-60b 助理 Markdown 散文重新设计
- 打开带有标题、表格、代码栏、块引用和任务列表的助理答案。
- 预计两个主题中都会有精致的
.prose-chat层次结构和嵌入代码镶边。 - 扩展思维标记并确认它在视觉上保持从属于答案。
US-UI-61 助理上下文检查器 + 重试(D103、D184)
- 完成报告使用情况的助理回合。
- 答案下方会有模型徽章和紧凑的上下文检查器。的 触发器显示剩余上下文百分比;悬停或键盘焦点显示 used/remaining/window 代币,确切的 input/output/cache/reasoning 用法, 生成 tokens/s,以及每个独特工具类型的聚合调用计数, argument/result 足迹、份额和持续时间。面板标签提供商 报告的总计和估计的工具行。
- 将触发器移动到每个视口边缘附近,并在面板滚动或调整大小时 已开放;期望车身水平覆盖层翻转、夹紧并完全保持 可见,而不是被脚本滚动容器剪切。
- 将鼠标悬停在操作行并单击“重试”;最近的前面的用户提示是 重新发送。
US-UI-62 就地再生 (D105)
- 在多轮成绩单上,重新生成较早的助理答案。
- 期望后面的轮次消失并且所选用户提示重新运行 放置,而不堆叠提示的第二个副本。
US-UI-63 重新生成历史寻呼机 (D109)
- 重新生成助手答案两次。
- 每次重试后,将鼠标悬停或聚焦于根用户气泡并期待其操作 工具栏以公开
1/N寻呼机以恢复早期变体。
US-UI-64 空荡荡的家,没有输入框重叠 (D111/D204/D206)
- 在〜1200×690和较低的高度(〜900×640)打开空的家。
- 在可滚动内容中期待英雄和可选的入门清单 区域,主输入框明显保留在底部,没有启动器 卡片。
- 短窗口滚动内容区域而不是堆叠输入框 检查表;当清单不存在时,不存在空的垫片。
US-UI-65 持久通知收件箱 (D117/D130)
- 验证当前焦点完成是否使收件箱保持不变,然后 通过 background/unfocused 已完成和失败的任务行填充它, 包括一个很长的会议标题。检查展开的侧边栏页脚并 light/dark 主题中的弹出窗口默认宽度和窄支持宽度。
- 预计没有标题栏响铃,在前帮助位置有一个稳定的 32px 页脚响铃, 不重叠的
1–99/99+徽章, 密集的 360 像素或更窄的列表、本地化的 kind/session/time/error 内容,以及 独特的 text/icon/unread-dot 语义,无需嵌套卡片或剪切文本。 - 切换All/Unread;使用 Tab 键、箭头键、Home/End、Enter/Space、Escape 和 外部点击。焦点顺序保持可预测,行激活打开 正确的会话,然后 Escape 将焦点恢复到铃声上。
- 标记所有已读并清除公开图标 tooltips/accessible 名称、禁用和 空状态仍然是可以理解的,并且减少运动模式改变了 立即弹出,无需抑制焦点或未读状态。
US-UI-66 应用程序更新通知布局
- 在与停靠的输入框的对话中可见,练习手册
available、应用内downloading和downloaded在灯光下更新灯具 以及默认和最小支持窗口大小的深色主题。种植 输入框草稿到其最大可见高度。 - 预计主窗格标题栏下方会出现一个紧凑的更新通知 右上角的安全区域。它永远不会与输入框相交,包括当 草案增加,并且它没有覆盖开放的工作面板。
- 期待 icon/title/message 层次结构的稳定更新,确定进度
downloading,适用的查看版本或重新启动以更新操作,以及 24px 使用可访问的名称解除控件。取消一个状态阶段 不会抑制同一版本的后续阶段。 - 当灯具包含
releaseNotes时,预计会在下面出现“新增功能”部分 横幅和设置 → 信息更新行上的状态消息,使用 产品 UI 区域设置(EN 或 zh-CN)。没有注释的夹具省略了 部分。切换语言会重新解析相同版本的注释,而无需 新支票。
US-UI-67 独特的侧边栏任务状态指示器 (D135)
- 在浅色和深色主题中,在会话 A 进行时保持会话 B 处于选中状态 通过正在进行、已完成、新的正在进行的转向、失败和中止 州。启用减少运动后重复并检查键盘焦点。
- 预计 A 在进行过程中会显示橙色呼吸点,绿色勾号 完成,失败时出现红色圆圈警报。开始新回合清除 A 较早的终止标记;中止不会留下已完成或失败的标记。
- 预计选定的空闲 B 将显示静态重音蓝色轮廓环和活动环 行背景。如果选择的 B 开始工作,其橙色的进行中点将显示 优先,直到回合结束;其最新的最终结果仍然隐藏 选择时位于所选环后面。
- 每个指标都公开本地化的“进行中”/“已选择”/“已完成”/“失败” 通过其可访问的名称和工具提示来显示文本。减少运动使橙色 点静态而不改变其颜色或含义。行高、标题截断、 图钉图标、悬停操作和对焦环在两个主题中保持稳定。
- 打开带有已完成或失败标记的对话并期望该终端 当其持久任务通知被读取时,标记为立即清除。 刷新通知并重新启动应用程序;认可的商标不得 返回。标记为从收件箱中读取的终端通知同样会产生 无侧边栏端子标记。
US-UI-68 会话范围的内联权限和工件 (D138/D142)
- 同时运行两个会话,并在 B 到达工具时保持 A 可见 批准请求。检查默认宽度和窄宽度的 light/dark 主题。
- 没有背景、模态、page/session 开关、工作面板隐藏、转录 A 中的替换或输入框焦点更改。B 保留其挂起状态。
- 明确打开 B 并期望在 B 最新的之后有一张内联权限卡 活动,具有可读的风险、参数、工作区、倒计时和包装操作 控制。切换回来可以保留绝对期限。
- 将A和B一起挂起,各自独立解决,并且都不确认 操作删除或更改另一张卡。
- 解析A的Write/Edit权限,完成前切换到B。预计不会 B 中的瞬态检查面板且无 panel/window 闪烁;返回A恢复 A 生成的“审阅”选项卡和之前的面板选择,而 B 的选项卡和浏览器 资源保持不变。
US-UI-69 侧边栏类型平衡 (D144/D161)
- 在默认和最小值下打开浅色和深色主题的扩展侧边栏 支持至少一个会话、一个项目组和本地的宽度 个人资料页脚可见。
- 期望插件、页脚配置文件名称和配置文件菜单操作呈现在 机身镀铬尺寸 (
--text-base/ 14px)。 - 预计 session/thread 标题、project/group 标题和空状态副本位于
--text-md/ 13px,带有大写部分标签 (SESSIONS/PROJECTS) 位于--text-sm/ 12px — 主列表内容永远不会低于--text-md。 - 确认行间距保持紧凑(约 28–32 像素),标题仍然截断干净, 折叠的图标栏控件无需回流外壳即可保持清晰。
US-UI-70 禁用可编辑字段的文本更正 (D145)
- 打开空的主页,停靠的成绩单,设置搜索,插件市场搜索, 项目存档搜索、全局搜索(现在包括命令)、提供商模型组合、 消息编辑文本区域,以及工作面板浏览器 URL 栏(浅色和深色)。
- 期望每个文本 Write/Edit/panel/window 都暴露
spellcheck="false"(ReactspellCheck={false}) 加上autocorrect="off"和autocapitalize="off"。 - 输入类似代码的标记、路径、模型时不要出现红色拼写下划线 ID 或 URL;复选框和非文本控件保持不变。
US-UI-71 Composer 运行时芯片下降器 (D150)
- 打开空的 home 和一个带有包含下降器的模型 ID 的停靠线程 (例如
gpt、gemini或任何具有g/y/p/q/j的 ID)。 - 检查 Agent/Plan/Goal、思考(如果存在)、权限模式和 明暗模型芯片。
- 期望每个芯片标签都显示完整的字形墨水 —
gpt/gemini/g的底部则不然 被 28px 胶囊剪切——而长模型 ID 仍然水平椭圆。 - 链接规格:
04-ux/07-ui-design-system.md§8.2、04-ux/08-component-spec.md§11.5、决策日志 D150 - 里程碑:M5
- 状态:部分自动化(渲染器源测试:芯片行高+无前导-无)
US-UI-72 受 Apple 启发的全局角落层次结构 (D210)
- 打开空的家,填充的成绩单,设置,插件,项目 默认支持的桌面大小的存档、菜单和对话框 和黑暗主题。
- 预计固定角点将遵循全局 4/6/8/10/12/14/16/18/20/24px 梯子,视觉上更大或更高的表面接收更大的 半径。
- 标准紧凑型和中型按钮和字段保持圆角矩形, 不是胶囊。药丸、分段选择、状态标签、进度轨迹、 开关、等宽圆形图标控件和点保留其明确的 胶囊或圆形。
- 当一个圆形的孩子坐在一个圆形的父角上时,期望半径 与中间的插图同心阅读。全宽侧边栏, 标题栏和工作面板边缘保持方形而不是浮动 牌。
- 调整到支持的最小窗口大小并检查每个窗口附近的 menus/dialogs 边缘。圆形表面不得剪切文本、对焦环、操作或可滚动内容 内容。
- 链接规格:
04-ux/07-ui-design-system.md§6.2、ADR 0071 - 里程碑:M5
- 状态:部分自动化(radius 令牌和共享控制源测试)
US-UI-73 Composer 模式选择器具有稳定的宽度
- 以英语和中文打开空的主页和停靠的线程。
- 通过Agent/Plan/Goal多次切换Composer模式芯片。
- 期望模式芯片为最长的内置保持一个固定的宽度尺寸 标签(英文“Agent”/zh-CN“智能体”);相邻的思维和 权限控件、发送按钮和 Composer shell 不会移动或调整大小。
- 链接规格:
04-ux/08-component-spec.md§11.3 - 里程碑:M5
- 状态:部分自动化(渲染器 style/source 合约)
E2E-123:asktool 收集多个答案并返回跳过的占位符
- 先决条件:Agent、Plan 或 Goal 模式;已配置的提供商;一个 与活动转录本的会话。
- 步骤:1) 要求客服人员致电
asktool,并提出单选问题, 一个多选问题,每个问题都有一个选项列表。 2)确认每张卡 显示固定的自定义输入选择。 3)回答第一个问题,点击 接下来,在多选问题上选择两个答案。 4)跳过决赛 问题无需输入文字。 5) 检查完成的工具行和 下一个模型响应。 - 预期:一次可见一个问题;小指标显示 输入框批准区域中已回答、当前和跳过的状态 Plan 和 Goal 批准使用的停靠位置相同。请求没有 倒计时。工具输出排序为
question:answer,使用、多个答案之间和问题之间的\n---\n之间,并保持question:用于跳过的问题。拒绝所有产生空 每个问题的占位符,仍然完成工具调用。 - 链接规格:
03-runtime/17-asktool-questions.md,04-ux/11-asktool-question-card.md、ADR 0077 - 验收:E(交互式工具输出)、C(内联卡)
- 里程碑:M5
- 状态:草案(单位覆盖范围有效;桌面旅程待定)
E2E-124:最小化隐藏跨平台托盘中的窗口
- 先决条件:在 macOS、Windows 和 Linux 上构建桌面应用程序;英语 和 zh-CN 语言环境可用;正常的主窗口打开。
- 步骤:1)从平台的窗口控制最小化(macOS流量 光或 Windows/Linux 渲染器控制)。 2) 确认主窗口是 当应用程序进程保持驻留时隐藏。 3) 单击或双击 托盘图标并确认同一窗口已恢复并聚焦。 4) 打开 托盘菜单并选择“显示”,然后重复“退出”。 5) 在 zh-CN 中重复并 在窗口隐藏时调用 macOS 应用程序激活。
- 预期:所有最小化路径都隐藏到一个托盘图标,而不是退出或 留下任务栏最小化的窗口。 Show/click/double-click/app 激活 恢复现有窗口;本地化菜单包含 Show PI-Desktop 并退出 PI-Desktop。 Quit 运行正常的关闭顺序,并且不留下任何内容 孤立主机、sidecar 或托盘进程。关闭窗口仍然是明确的 放弃行动。
- 链接规格:
03-runtime/07-process-model.md,04-ux/09-interaction-patterns.md、08-meta/decisions-log.md(D216)、 ADR 0078 - 验收:A(应用程序生命周期),质量
- 里程碑:M6+
- 状态:Unit/source-contract 已覆盖;原生跨平台托盘之旅 草稿(除非明确要求,否则不要运行本地 E2E)
E2E-125:完整的双语 VitePress 文档仍然可用
- 先决条件:已安装文档依赖项并提供 VitePress 预览版 服务器正在从存储库运行。
- 步骤:1)以1440×900打开
/并验证英文登陆页面, 系统地图、按意图阅读的旅程、参考书架、全局搜索、 Guide/Specs/ADRs 导航和语言选择器。 2) 切换到/zh-CN/并验证翻译后的英雄、镜像主题图、中文规范 链接。 3)打开/spec/03-runtime/01-ipc-protocol,切换语言, 验证/zh-CN/spec/03-runtime/01-ipc-protocol是否包含翻译的散文, 保留的代码标识符,以及返回英文源的链接。 4) 搜索 在每个区域设置中并打开匹配结果。 5)重复主页和长 明暗模式下的桌面规格为 390×844。 - 预期:两个语言环境入口点和每个 English/Chinese 规范 对渲染没有损坏的链接或页面级水平溢出。登陆 阅读栏在其可用布局中视觉上居中;的 移动英雄在系统视觉之前呈现文本。搜索返回本地 结果。移动导航打开和关闭不会移动或遮挡 页面。代码块和表格通过包含的滚动保持可读, 主题对比清晰,每个中文规范都标识英文 页面作为其规范来源。直接刷新
/zh-CN/spec/README,/zh-CN/spec/03-runtime/01-ipc-protocol、/zh-CN/adr/、/spec/README和 Vercel 上的/adr/README;每条路线都通过记录的解析cleanUrls配置而不是返回 404。 - 链接规格:
02-architecture/04-documentation-site.md、ADR 0079 - 验收:质量、文档可发现性、响应式布局
- 里程碑:M6+
- 状态:浏览器渲染的 desktop/mobile 验证已获得授权 本文档重新设计;远程部署刷新检查仍处于草稿状态。