feat: unify execution and add workspace file imports

Remove Ask/Execute modes and general product tool approvals so requests use the selected runtime, enabled capabilities, and execution account permissions. Migrate retired application metadata while preserving user content.

Retire the Results page while retaining conversation images and stored artifacts. Add local and remote workspace file imports, timestamps and sorting, improve image discovery and saving, and refine workspace navigation and supervision responsiveness. Include the accompanying web-search changes, tests, probes, and product documentation.

Remote imports require an updated Agent. Existing artifacts are not automatically copied into project directories. Validation evidence and outstanding failures remain documented in feature progress files; no full test suite or real-model calls were rerun for this commit.

Release note: Run requests without switching work modes, import files into a selected local or remote workspace folder, sort workspace files by date, and keep using conversation images after removal of the Results page.
This commit is contained in:
mesalogo
2026-10-04 20:02:59 +08:00
parent 0cd5da33f4
commit 56ebd40bd8
374 changed files with 7075 additions and 6224 deletions
+4 -1
View File
@@ -1,6 +1,7 @@
# 助手工作栏
助手工作栏统一承载本机与远程执行空间、Task、成果、文件、浏览器、终端和笔记等持续工作界面。
助手工作栏统一承载本机与远程执行空间、Task、文件、浏览器、终端和笔记等持续工作界面。
成果页已移除;项目文件统一在工作区查看和导入,会话图片继续由消息引用读取。
“笔记”为应用级、可关闭的单实例 Tab,新布局默认不打开。它提供搜索、浏览和快速追加文字,
与主页面魔法笔记共用存储;会话采集、来源跳转与草稿规则由
@@ -16,10 +17,12 @@
| [浏览器多实例技术设计](./browser-tabs-technical-design.md) | 浏览器 Tab 身份、Conversation 绑定、IPC、BrowserService 和 MCP 路由 |
| [实现与验证进度](./progress.md) | 工作区与 Runtime 相关改动的实现事实、验证证据与剩余阻塞 |
| [执行记录存储与升级回收](./execution-history-storage.md) | 子任务差量存储、远程去重、旧库转换、会话置顶、摘要与完整历史按需读取、内存引用释放 |
| [工作区文件导入与时间](./workspace-files.md) | 真实文件来源、导入操作、排序、图片存储边界及本机和远程实现 |
| [Runtime 交互边界](./runtime-interactions.md) | 原生权限、结构化问答、后台拒绝、终端交互、并行与输出、消息请求状态及资源生命周期规则 |
| [Runtime 进程复用技术设计](./runtime-process-reuse-technical-design.md) | 跨 Runtime 资源调研、锁定协议证据、进程与会话拆分、远端模型桥、实施顺序和性能验收 |
| [Runtime 原生客户端启动方案](./runtime-native-client-proposal.md) | Local terminal/DS Web shortcut requirements, startup rules, current integration, validation boundaries and remaining remote/resource work |
| [Runtime 执行清单技术设计](./runtime-checklist-technical-design.md) | OC/CN 原生清单提取、远程 Agent 传递复用、消息恢复与真实部署验收;尚未实现 |
| [移除 Ask / Execute 工作模式](../unified-execution/README.md) | 跨入口统一执行、历史字段迁移及清除数据入口;主要源码已落地,定向 UI/Host 通过,完整验收待完成 |
当前尚未拆出独立 User Stories、功能逻辑和 UI 设计文档;产品场景与验收保留在现有 PRD,
Runtime 资源状态规则由交互边界文档维护。浏览器多实例和 Runtime 进程复用涉及不同的
@@ -7,7 +7,7 @@
子任务仍实时显示完整的文字、思考、工具过程和最终结果。运行时间较长、工具输出较多时,
数据库不再为每个流式更新重复保存此前的整份过程;本机和托管 SSH OpenCode 使用相同
的桌面存储机制。此修复不关闭子任务、不截短已有过程,也不增加 Execute 权限门槛。
的桌面存储机制。此修复不关闭子任务、不截短已有过程,也不增加工具审批。
已有数据库在首次升级时自动处理。启动页铺满窗口,显示处理数量、全宽进度条和近期
处理速度;处理时间取决于历史数据量与磁盘速度,不承诺固定几分钟。用户可以退出,
+36 -58
View File
@@ -13,7 +13,7 @@
## 1. 背景
GoodBuddy 已经在聊天右侧提供任务中心、工作区、浏览器和成果面板,也已经具备
GoodBuddy 已经在聊天右侧提供任务中心、工作区和浏览器面板,也已经具备
Runtime 事件、Git 变更、文件预览、成果存储、受控浏览器和专家执行等基础能力。后续还
计划增加:
@@ -37,14 +37,14 @@ Runtime 统一抽象为“执行空间”。
助手工作栏是 GoodBuddy 中始终可访问的应用级工具容器。它提供稳定能力目录,用户从中
查看任务中心,并按需打开一个或多个监督、Runtime、终端、进程、工作区、浏览器、资源监控、
成果和文档面板实例。稳定的是能力的可发现性,不是十个同时占据界面的固定面板。
文档面板实例。成果页已移除,项目文件由工作区统一展示;会话图片保留在消息中。
工作栏不是:
- 只在编程项目中出现的 IDE 面板。
- 当前聊天消息的附属详情框。
- 根据能力探测结果自动增删入口的动态菜单。
- 绕过 Main、Preload、Ask/Execute 或审批边界的控制台。
- 绕过 Main、Preload、能力范围或用户数据边界的控制台。
- 全系统进程管理器、任意文件浏览器或无边界远程管理工具。
### 2.2 执行空间
@@ -84,7 +84,6 @@ Runtime
工作区
浏览器
资源监控
成果
文档
笔记
```
@@ -115,7 +114,7 @@ Runtime
- 终端创建时固定到当前项目执行空间,由项目配置自动决定本机或托管 SSH;没有当前项目时
使用本机 Home。
- 工作区默认显示当前项目目录,用户可以打开其他本机目录或远程目录。
- 成果默认使用当前范围,用户可以切换到项目、全局或其他允许范围。
- 项目文件统一使用工作区范围,会话图片按原消息引用读取。
- 文档创建时固定到用户明确打开的文件和 ShareServer 编辑会话,不提供跟随模式。
- 下一次请求的附件和知识库由当前 Composer 展示与管理,不作为工作栏能力。历史执行上下文
随关联 Task 查看;记忆功能实现后也归入任务中心,而不是新增独立上下文面板。
@@ -177,7 +176,7 @@ Runtime
- 建立统一范围、执行空间、生命周期、成果和控制契约。
- 复用现有 Project、Conversation、Task、Artifact、Activity 和 Approval 数据。
- 保持 Renderer 无任意文件、进程、PTY、SSH 或 Electron API 能力。
- 保持 Ask 只读、Execute 账号完整授权、取消、超时、输出边界和活动审计。
- 使用当前账号权限,保留能力范围、取消、超时、输出边界和活动审计。
- 为本机与远程能力提供一致 UI,同时准确表达能力差异。
## 5. 非目标
@@ -232,8 +231,8 @@ Runtime
- 每个实例显示稳定实例 ID、能力名称、跟随或固定状态与当前目标;同能力多实例不能只靠位置区分。
从当前聊天右栏迁移时,Task Center 和工作区作为默认打开、单实例且不可关闭的基础应用保留;
浏览器保留一个默认打开实例,但注册为可关闭的多实例应用;成果保持默认打开、单实例且可
关闭;终端不默认打开,由用户通过“+”创建,并从首期开始支持多实例。Tab 必须单行横向滚动,
浏览器保留一个默认打开实例,但注册为可关闭的多实例应用;成果入口移除;
终端不默认打开,由用户通过“+”创建,并从首期开始支持多实例。Tab 必须单行横向滚动,
不能自动隐藏或缩写到不可辨认。“+”固定在滚动区外的行末,溢出时页签区两端提供固定滚动箭头,箭头不覆盖“+”。Task Center 继续作为 Task 的现有
入口;审批定位到所属 Task 或 Runtime。智能心跳不作为工作栏页签,其报告、建议、历史和
完整配置统一归属“智能心跳”菜单入口。当前阶段不新增独立自动化中心。
@@ -265,10 +264,10 @@ Task Center 保留为工作栏中的稳定入口,并在现有基础上适度
- 只索引 Task;每个 Task 只关联一条 Conversation,一条 Conversation 可以关联多个 Task。
- 顶部显示当前会话消息总数和 Agent 累计回复时间;列表显示本项目任务的名称、关联 Conversation、
所属项目、Ask/Execute、状态、最近进展、真实活动时间、累计执行时间和需要关注信息。
所属项目、状态、最近进展、真实活动时间、累计执行时间和需要关注信息。
- 点击 Task 打开其关联 Conversation 并定位 Task。
- 完整消息留在 Conversation;工具、Subagent、审批、错误和成果按 Task 关联到 Runtime、
活动记录和成果查看器中,不在窄栏复制,也不呈现 Job/Run 树。
活动记录、会话消息和工作区中,不在窄栏复制,也不呈现 Job/Run 树。
- 智能心跳的报告、建议、历史和配置不进入任务中心。
任务中心是应用级单例,默认存在且不可关闭。当前项目是唯一范围,标题明确显示项目;切换
@@ -282,8 +281,8 @@ Task Center 保留为工作栏中的稳定入口,并在现有基础上适度
主侧栏最近会话为关联 Task 提供轻量入口:父会话行只显示行首展开按钮,Task 子项使用
任务图标和本地化摘要,展开层级只到 Task;点击 Task 子项打开同一 Conversation 并定位。
新建定制任务使用共享 Modal,默认立即执行和当前 Conversation,可选本项目其他可用会话或
新会话,以及单次定时、每日或每周。内容必填,名称可留空从内容生成;工作模式使用关联
会话的执行时配置,未设置时使用项目默认值,不在创建表单另设模式。
新会话,以及单次定时、每日或每周。内容必填,名称可留空从内容生成;使用关联
会话的执行时配置,不在项目、会话或创建表单保存工作模式。
详细产品边界以 [Task Center PRD](../task-and-job/task-center-prd.md) 和
[Task 与 Job 统一领域模型](../task-and-job/task-and-job-model.md) 为准。
@@ -308,7 +307,7 @@ Task Center 保留为工作栏中的稳定入口,并在现有基础上适度
- 未解决、已查看、已解决、忽略和误报状态。
- “带入输入框”“查看证据”“追问”“停止当前回复”等用户介入操作。
“采纳”只生成可编辑草稿或显式会话操作,不自动发送、执行、切换 Execute 或批准工具。
“采纳”只生成可编辑草稿或显式会话操作,不自动发送、执行或批准工具。
### 7.3 Runtime
@@ -543,37 +542,16 @@ type BrowserToolbarState = {
指标缺失时保留面板入口并显示不可用原因。资源监控入口、采样频率、数据契约与验收由
[应用导航与系统工具入口](../application-tool-navigation/README.md)定义。
### 7.9 成果
### 7.9 工作区文件与会话图片
成果面板统一显示全局、项目、Conversation、Task 执行和监督显式产生的独立成果:
- Markdown、纯文本和 JSON。
- 图片和图表。
- HTML 安全预览。
- 后续的 PDF、Office、表格和其他受支持格式。
普通聊天回复只保留在会话消息流中,不自动复制为成果。只有 Runtime 或受管工具显式声明的
Artifact、自动化和监督生成的独立输出,以及用户手动导入或明确保存的内容进入成果面板。
升级前已经自动保存的普通对话 Markdown 可以从成果列表中隐藏,但不应通过升级迁移物理
删除用户数据库内容。
用户可以切换范围、搜索、预览、查看来源、导出或打开关联对象。成果必须保留项目、
Conversation、Task、内部 Run、创建者、MIME、大小、校验值和时间等可用归属;界面按
Task 呈现来源,不把 Run 作为导航对象。
#### HTML 即时预览
- Runtime 或受管工具通过显式 Artifact 事件声明成果,不能让 Renderer 猜测任意路径。
- Main 验证成果属于当前授权执行空间,限制大小、类型和读取范围后再持久化。
- HTML 使用 `iframe sandbox=""` 和严格 CSP 进行脚本关闭、网络关闭的静态预览。
- 清理脚本、事件属性、嵌套 frame、object、embed、base、link、meta refresh、表单和活动 URL。
- 提供“预览 / 源码”切换,并持续标注“静态安全预览,脚本和网络已禁用”。
- 不使用 `dangerouslySetInnerHTML`,不启用 Electron `webviewTag`。
- 外部打开是明确的用户操作,并说明外部浏览器可能执行脚本或联网。
成果页面已移除。FR-WF1~FR-WF3、导入与排序场景以及图片保留边界统一见
[工作区文件导入与时间](./workspace-files.md)。实际文件使用项目目录作为唯一来源;会话图片
继续使用已有消息引用和 artifact 存储。HTML 会话预览由
[会话 HTML 渲染](../conversation-html-rendering/README.md)维护。
### 7.10 文档
文档是可创建多个实例的工作栏应用。用户从工作区、成果或会话文件引用打开受支持的 Office
文档是可创建多个实例的工作栏应用。用户从工作区或会话文件引用打开受支持的 Office
文件时新增文档 Tab;每个实例固定到一个 ShareServer 编辑会话,不随当前 Conversation 或
Project 切换。Tab 使用文档文件名,同名实例增加序号,完整来源通过 Tooltip 和页签内信息
显示。编辑器、保存、冲突、AI 选区修改和关闭行为以
@@ -686,7 +664,7 @@ SSH/远程项目操作;已有 Host、项目和凭据保持不变。若当前
连接信息、认证前 Host Key 核对、密码/系统 SSH Agent 认证和平台/架构/Shell/Home 有界
探针,全部成功后才原子保存主机、加密凭据和完整 Host Key。认证失败可在弹窗内修改凭据
重试;取消或失败不保留新主机。Key 变化显示旧/新指纹并要求显式高风险确认。项目创建和
设置现可选择托管 SSH、已保存 Host、远端工作目录、OpenCode 和 Ask/Execute,不要求
设置现可选择托管 SSH、已保存 Host、远端工作目录和 Runtime,不要求
额外 trust tier 或 consent checklist。候选完成签名 Agent/Runtime、Workspace、ACP、模型桥
和文本模型 profile 验证后原子提交。私钥导入仍未开放。旧流程已保存但
没有成功探针记录的主机继续读取,但在完成新向导前显示为“需要重新验证”。
@@ -727,7 +705,7 @@ digest。当前 registry、连接或 capability 无效时项目保持未切换
匹配 manifest 元数据,不重新验签或哈希完整 Agent payload。项目切换器立即提交本地选择,
不展示远程激活进度;完整进度和取消只属于新建或显式保存项目。
项目只持久化 Host ID、规范远端路径、Runtime 选择和默认工作模式。新建和保存验证当前
项目只持久化 Host ID、规范远端路径和 Runtime 选择。新建和保存验证当前
Workspace/Runtime,但不写入组件 identity;普通切换不做远程验证。未就绪或版本过旧时,
实际 Workspace/Runtime 操作显示错误。桌面更新造成组件版本变化时,用户先在 Host 管理中
准备环境;项目切换本身不连接、不下载、不扫描、不安装,也不改写项目。
@@ -802,8 +780,8 @@ Runtime 会话失效。产品不维护 T1/T2/T3 等附加信任层级。
- Main 保持可信控制面,远程 GoodBuddy Agent 只接受有范围、有期限的请求。
- GoodBuddy 控制协议负责 Agent、Workspace、Git、Process、Blob 和 Runtime supervision;
Runtime Session、stream、tool、permission、usage 和取消优先复用 ACP。
- Ask 的只读限制在远程 GoodBuddy Agent 和 Runtime 适配层共同强制。
- Execute 是用户对所选 SSH 账号完整权限的授权,直接以该账号可用的文件、进程、网络和
- GoodBuddy Agent 与 Runtime 适配层均不保留产品模式字段或只读名单。
- 请求直接以所选 SSH 账号可用的文件、进程、网络和
工具能力运行,不要求逐工具审批或第二个“受控执行”模式。取消、超时、输出上限和活动
记录继续保留。
- GoodBuddy 模型凭据和 Provider URL 必须留在 Main。远程 Runtime 只获得不含凭据的模型
@@ -901,7 +879,7 @@ remote_operations
- 应用重启后先通过远程 Daemon 的 journal、lease、boot identity 和 event cursor 核对活动
终端、进程与 Runtime;无法确认时标记 `interrupted` 或 `outcome_unknown`。
- 日志使用有界环形缓冲或分页持久化,不能无限写入 SQLite。
- Artifact 继续作为成果的权威实体,不把完整成果复制进工作栏状态。
- 工作区目录是文件的权威来源;会话图片继续使用 Artifact 引用,不复制进工作栏状态。
- 运行记录由 Main SQLite 持久化,Renderer 只保留当前内存视图。升级时迁移旧
`localStorage` 记录;若旧缓存达到原数量、详情或总大小边界,页面持续说明更早记录或
部分详情可能已经丢失。新记录不再按固定活动数或详情字符数丢弃,长列表只做可继续展开的
@@ -916,7 +894,7 @@ Renderer 只通过显式方法访问:
- 终端创建、输入、调整大小、关闭和有界输出订阅。
- 受管进程列表、日志和允许的控制动作。
- Runtime Inspector 快照、事件和允许的控制动作。
- 工作区、成果、浏览器和监督的既有或扩展服务,以及有界的本机资源快照。
- 工作区、会话图片、浏览器和监督的既有或扩展服务,以及有界的本机资源快照。
每个 Main Handler 都必须验证可信发送者、Zod 输入、对象归属和当前状态。不得暴露 raw
Electron、ChildProcess、PTY、SSH Client、Socket 或文件句柄。
@@ -924,8 +902,8 @@ Electron、ChildProcess、PTY、SSH Client、Socket 或文件句柄。
## 12. 安全边界
1. 工作栏能力目录项和面板实例不授予任何能力;权限只由 Main 中的范围和控制契约产生。
2. Ask 在本机和远程 Runtime 边界保持只读。
3. Execute 使用当前执行账号的完整权限,不另加目录或逐工具审批;工作栏不能绕过 Main、Preload 与用户数据边界。
2. 本机和远程 Runtime 按实际注册目录、启用与分配设置提供能力。
3. 使用当前执行账号权限,不另加目录或逐工具审批;工作栏不能绕过 Main、Preload 与用户数据边界。
4. 用户终端和 Agent 工具执行使用不同身份和事件来源。
5. 进程面板只控制 GoodBuddy 受管对象,不接受任意 PID。
6. 本机和远程路径分别在对应文件系统上 canonicalize 并验证符号链接边界。
@@ -1030,7 +1008,7 @@ Escape 收起并返回按钮;点击外部或焦点移出也收起。实时区
- **FR-RR2**:仅查看被动状态不启动重型 Runtime。显式连接测试、原生清单和执行请求
复用兼容的已启动实例;尚未握手时不能显示为已经验证连接。
- **FR-RR3**:共享进程仍保持各会话的目录、历史、模型用量、工具、权限和业务问答归属。
同一会话顺序执行,不同会话并行;Ask 保持只读,Execute 不增加第二层审批。
同一会话顺序执行,不同会话并行;统一执行不增加一般工具审批。
- **FR-RR4**:请求结束、会话释放与进程退出分别处理。取消一个普通请求、关闭工作栏
或释放一个会话不得误停其他健康会话;无会话的空闲重型实例及时释放。正常续聊保留
原生上下文,应用退出、配置替换和真实进程故障仍有明确的终态与有界回收。
@@ -1067,7 +1045,7 @@ Escape 收起并返回按钮;点击外部或焦点移出也收起。实时区
## 16. 分阶段实施
本节只表示内部依赖顺序,不表示可以发布临时架构。SSH 远程执行只使用用户级 Daemon,
不发布连接期 stdio Agent。OpenCode Ask、OpenCode Execute 和后续 Runtime 分别通过自身的
不发布连接期 stdio Agent。OpenCode、Continue 和后续 Runtime 分别通过自身的
安装、权限、取消和重连门槛后开放,未完成的能力继续显示不可用。
### 阶段 0:应用级工作栏壳层
@@ -1075,7 +1053,7 @@ Escape 收起并返回按钮;点击外部或焦点移出也收起。实时区
- 将当前聊天专属右栏提升为应用级壳层。
- 建立稳定能力目录和用户打开、关闭、排序、停靠的面板实例模型。
- 建立实例级跟随、固定和失效目标语义。
- 保留现有任务中心、工作区、浏览器和成果行为;附件与知识库继续由 Composer 管理。
- 保留现有任务中心、工作区和浏览器行为;成果页移除,附件与知识库继续由 Composer 管理。
- 将 Task Center 明确为 Task 的单例索引,并补齐范围、状态、最近进展、需要关注和直接打开 Conversation。
- 审批在所属任务或 Runtime 中持续可见;任务中心只为未关联任务的审批保留按需显示的处理
区域,具体规则见 [Task Center 交互](../task-and-job/task-center-prd.md#5-交互)。
@@ -1085,7 +1063,7 @@ Escape 收起并返回按钮;点击外部或焦点移出也收起。实时区
- 本机 CPU、内存、磁盘 IO 和 GoodBuddy 桌面进程摘要的按需资源监控。
- 通用 Artifact Event。
- HTML 工作区和成果的静态即时预览。
- HTML 工作区和会话内容的静态即时预览。
- Runtime Inspector Snapshot 与事件。
- OpenCode 会话、子会话、Todo、工具、用量和取消;本地与托管 SSH 的原生 Task 调用在
Conversation 中统一显示为可追踪的 Subagent 状态,而不是普通工具参数卡。
@@ -1115,8 +1093,8 @@ Escape 收起并返回按钮;点击外部或焦点移出也收起。实时区
- 签名、side-by-side GoodBuddy Agent 安装和按需 detached Daemon。
- SSH connection pool、固定 attach relay、Agent 控制协议、Agent 本地 ACP 日志和断线重连同步。
- 远程工作区、Git、终端和受管进程。
- 当前签名 OpenCode bundle 的 Ask/Execute 均直接启动,Ask 在工具边界保持只读,
Execute 使用账号完整权限;官方 ACP channel、Agent 本地模型网关、取消、超时和活动记录
- 当前源码直接启动 OpenCode bundle,使用账号权限和已接入能力;配套签名包须按 runtime/acp 6 重建。
官方 ACP channel、Agent 本地模型网关、取消、超时和活动记录
以[远程主机技术设计](../remote-host/technical-design.md)为准。
- OpenCode 闭环稳定后,Continue 与 DeepSeek Harness 复用相同面板和通道契约逐个接入。
- 新增或重新验证 Host 时只保存并探测 Agent/Runtime,不自动安装。用户在 Host 卡片用
@@ -1132,7 +1110,7 @@ Escape 收起并返回按钮;点击外部或焦点移出也收起。实时区
Workspace/Runtime 时直接使用新的 current 环境,无需刷新项目绑定。应用启动和项目切换
本身都不连接 Host,也不下载或安装组件。
- SSH、Main、Daemon、Runtime 和远端重启后的核对、恢复与 `outcome_unknown`。
- 支持平台的安装、Ask、Execute、取消和重连冒烟测试通过后开放对应 OpenCode 能力。
- 支持平台的安装、无模式工具执行、取消和重连冒烟测试通过后开放对应 OpenCode 能力。
### 阶段 5:开放后的扩展
@@ -1156,7 +1134,7 @@ Escape 收起并返回按钮;点击外部或焦点移出也收起。实时区
### 17.2 通用使用
- [ ] 没有项目时仍可创建终端、选择工作区、打开浏览器和查看成果。
- [ ] 没有项目时仍可创建终端、选择工作区和打开浏览器。
- [ ] 监督可以作用于普通 Conversation、Task 和后续实验对象,不假设编程语境。
- [ ] 工作区不是 Git 仓库时仍可浏览文件。
- [ ] Runtime 不支持某项原生能力时仍可从目录打开面板并获得准确说明。
@@ -1168,9 +1146,9 @@ Escape 收起并返回按钮;点击外部或焦点移出也收起。实时区
- [ ] Renderer 没有任意文件、Shell、进程、PTY、SSH 或 Electron API。
- [ ] Agent 不能未经授权向用户终端注入命令。
- [ ] 进程面板不能枚举或终止任意系统进程。
- [ ] Ask 在本机和远程执行空间均无法调用写入或外部副作用工具。
- [ ] 本机和远程按已启用能力执行,不保留模式限制或一般工具审批。
- [ ] HTML 预览无法执行脚本、联网、打开窗口、提交表单或访问 Electron API。
- [ ] Supervisor 不能自动发送消息、批准工具、切换工作模式或扩大范围。
- [ ] Supervisor 不能自动发送消息、批准工具或扩大范围。
- [ ] SSH 首次连接和 Host Key 变化均经过明确验证流程。
- [ ] 凭据不进入 Renderer、日志、SQLite 明文或命令参数。
- [ ] Host 地址、用户或 Host Key 变化会关闭旧连接,并使旧 Workspace 和 Runtime 会话失效。
@@ -1,5 +1,50 @@
# 工作栏实现与验证进度
## 2026-10-04:移除成果页,工作区导入与文件时间
对应 [FR-WF1~FR-WF3、US-WF1~US-WF3](./workspace-files.md)。成果 Tab、目录注册及独立导入
界面已移除,旧布局过滤成果实例。工作区显示实际文件的修改时间与可用创建时间,支持同级排序,
向所选目录导入原件。本机及远程共用分块管理动作,同名文件不覆盖,失败项独立反馈并清理部分文件。
来源检查确认:`AssistantDatabase.createImageArtifact` 把图片保存为 `artifacts.inline_content`
数据 URL,消息通过 `artifactIds` 引用;上传源图还可通过 `imageSourceArtifactIds` 引用。
这些数据不是工作区文件。本次未改数据库 schema、删除或迁移 artifact,也未自动复制附件。
生成图片继续保留在消息,需要项目文件时由既有 `save_image` 显式保存。
验证证据:
- 最终定向验证:16 个文件,252 项通过、2 项跳过。覆盖 WorkspaceAccess、导入服务、文件管理、
时间传递、布局恢复、工作区排序和虚拟列表、Sidebar、WorkbarShell、ChatTimeline、图片服务及
ProtocolRemoteWorkspaceTransport。命令使用 `npm test --` 加对应文件;新测试入口为
`src/main/workspace/workspace-import.test.ts` 和 `tests/workspace-import.electron.test.ts`。
- `src/main/ipc.test.ts -t "resolves the project root and validates file requests"`:1 项通过,验证
原生选择取消、真实文件导入、路径校验以及已有目录读取。
- App 的成果入口相关测试修正后复跑:2 项通过。真实 Electron 从完整 App 的工作区按钮进入
生产 preload、IPC 和本机文件系统,导入 700,001 字节二进制文件,逐字节核对,同名项不覆盖,
取消无写入;原生文件选择器以固定路径替代人工操作。历史会话图片在 Renderer 重载后仍能解码,
SQLite artifact 数量保持 1,项目根目录只有显式创建的 `selected` 目录。
- `tests/workspace-files-layout.electron.test.ts`:16 个场景通过,包含 Git/非 Git、浅深主题、
四种窗口尺寸、原生滚轮与点击、隐藏/恢复位置,窄栏横向滚动不撑宽 Sidebar。
`tests/workbar-settings-layout.electron.test.ts`:80 项工作栏观察及 12 项设置观察通过,
中英文、浅深主题及原生键盘操作继续可用。
- Linux x64 共享 Host:`scripts/workspace-import-host-probe.ts` 将当前源码打包后,通过现有
pinned SSH 连接运行。Desktop `RemoteWorkspaceAccess` 经 SSH stdio 测试桥调用真实
`createWorkspaceProtocolMethods`、`WorkspaceRegistry` 和 `manageWorkspace`;上传二进制
700,001 字节及空文件成功,Host 核对每个字节、目录归属、mtime/birthtime,同名重传失败且
原文件不变。临时工作区在 `/root/tmp` 下并在结束时清理。模型调用 0 次。
此探针未经过安装版 daemon 的完整二进制帧/attach 路径;该传输契约的本地回归通过,未替换
已安装 Agent。生产远程导入需要部署包含新增 `importFile` 动作的 Agent,旧 Agent 不支持。
- `npm run typecheck`、`npm run lint` 通过。新工作区文档经 `deai-writing` 扫描无阻断项;
两个复核项属于布局偏好字段列举及明确的旧 Agent 支持边界,保留事实说明。
全仓 `npm test` 运行 852.36 秒:505 文件通过、6 文件失败、14 文件跳过;5,974 项通过、
8 项失败、86 项跳过。此次改动对应的 4 项旧断言(App 2 项、虚拟列表缩进 1 项、工作栏
默认 Tab 数量 1 项)已修正,定向复跑通过。其余失败为 `assistant-storage-worker.test.ts`
2 项升级失败、`supervisor-layout.electron.test.ts` 等待 inline error 超时、
`opencode-runtime.test.ts` 的 cleanup-timeout 断言失败。存储升级 2 项单独复跑仍失败;
OpenCode 用例单独复跑通过;监督者布局未重复运行。未改动这些非本次范围的实现,未将
全仓测试记为通过。未提交、发布或打发行包。
## 2026-10-01:自定义 MCP 失败中断回复
已修复共用网关将单个上游发现失败升级为整轮失败的问题,行为见
@@ -1,13 +1,13 @@
# Runtime 交互边界
本文定义当前原生交互的适配范围,不增加工作模式或第二层 Execute 审批。
本文定义当前原生交互的适配范围,不增加产品工作模式或一般工具审批。
| Runtime | 权限确认 | 业务问答 |
| --- | --- | --- |
| 本机 GoodBuddy 管理的 OpenCode | 内部默认配置允许权限;每个 Ask 请求仍使用 deny-all 与显式只读能力。Execute 自动回复属于当前请求的父、子孙会话权限事件,不处理其他并行请求 | 通过 `question.asked` 转交父、子孙会话问题,支持原生单选、多选、yes/no、自由文本及跳过;使用公开 ID 回传 `question.reply/reject` |
| 托管 SSH OpenCode | Agent 按已接受 Prompt 的 Ask/Execute 模式处理 ACP 权限,规则见远程主机技术设计 | 当前 Agent 插件转交原生父、子孙会话 `question.asked`;前台使用同一问答队列,回答和跳过经认证 Agent 控制通道回传,已知 Task 关联显示子任务归属 |
| Continue | Execute 启动传入 `--auto`,剩余原生权限请求按当前模式自动答复 | 对接 `1.5.47` QuizService 的扁平 `pendingQuestion`,其中 `question` 是字符串。选项回答与自定义文本分别回传正确的 `isCustomAnswer`;跳过发送拒绝回答的文本 |
| DeepSeek Harness | 固定 Host 的 Execute 文件与命令工具不询问目录权限;若收到 ACP 权限请求,活跃 Execute 直接选一次性允许,缺少该选项时使用 Runtime 提供的允许选项,Ask 拒绝,不等待额外 authorizer | 固定 Host 当前未提供通用原生业务问答服务,不把普通模型正文误识别成待答协议。模型以普通回复提问时,用户通过下一条消息回答 |
| 本机 GoodBuddy 管理的 OpenCode | 自动回复属于当前请求的父、子孙会话权限事件,不处理其他并行请求;无产品模式名单 | 通过 `question.asked` 转交父、子孙会话问题,支持原生单选、多选、yes/no、自由文本及跳过;使用公开 ID 回传 `question.reply/reject` |
| 托管 SSH OpenCode | Agent 按已接受 Prompt 的归属和实际能力处理 ACP 权限,规则见远程主机技术设计 | 当前 Agent 插件转交原生父、子孙会话 `question.asked`;前台使用同一问答队列,回答和跳过经认证 Agent 控制通道回传,已知 Task 关联显示子任务归属 |
| Continue | 启动使用原生 agent 与 `--auto`,剩余原生权限请求自动答复 | 对接 `1.5.47` QuizService 的扁平 `pendingQuestion`,其中 `question` 是字符串。选项回答与自定义文本分别回传正确的 `isCustomAnswer`;跳过发送拒绝回答的文本 |
| DeepSeek Harness | 固定 Host 文件与命令工具不询问目录权限;活跃请求优先选择一次性允许,缺少时使用 Runtime 提供的允许选项,保留取消和未知请求拒绝 | 固定 Host 当前未提供通用原生业务问答服务,不把普通模型正文误识别成待答协议。模型以普通回复提问时,用户通过下一条消息回答 |
托管 SSH OpenCode 的权限、原生问题事件与回复链路由
[远程主机技术设计](../remote-host/technical-design.md)定义。该远端业务问答基线需要
@@ -177,10 +177,10 @@ Markdown 或名称含 `list` 的工具。子会话清单不覆盖父请求顶部
不变量:
1. 一条请求始终使用接受时的 execution space、工作模式、配置和归属;不能读取后来
1. 一条请求始终使用接受时的 execution space、配置和归属;不能读取后来
切换的 UI 选择,也不以进程 cwd 表示所有会话的 cwd。
2. 同一会话串行,跨会话不增加全局 Prompt 队列。权限、子代理、问题、用量和最终清理
必须沿同一 Session/请求归属,不因共享进程放宽 Ask 或限制 Execute。
必须沿同一 Session/请求归属,不因共享进程改变能力范围。
3. owner 的退出条件依据所有使用者,不依据某个 adapter 的空闲状态。
未启动对象的 dispose 不产生冷启动;一个等待者取消不取消其他等待者的初始化。
4. 正常会话仍持有原生上下文时,不用任意 TTL 清掉它来声称“空闲内存已回收”。
@@ -94,7 +94,7 @@ Skills/MCP 承接、取消和产品生命周期仍待实现与验证。此次可
| FR-2 | 按项目执行空间启动 | 本地使用本地目录,SSH 使用绑定 Host 与远端目录;目录失效时说明原因 |
| FR-3 | 注入点击时选定模型 | 客户端首轮直接使用该模型,无需重复输入供应商密钥 |
| FR-4 | 创建独立客户端会话 | 不修改原聊天历史,不把打开操作伪装成当前聊天的续接 |
| FR-5 | 保持所选工作模式的执行边界 | Ask 的 AI 工具路径只读;Execute 使用相应账号已有权限 |
| FR-5 | 沿用统一执行与能力范围 | AI 工具路径使用已接入能力和相应账号已有权限,无产品模式 |
| FR-6 | 管理启动、重开和关闭 | 不因收起工作栏或切换项目中断;关闭对应客户端资源时释放其桥接 |
| FR-7 | 保留可处理的失败信息 | 启动、模型和远程错误可区分,允许修正后重试,不清空聊天草稿 |
| FR-8 | 明确原生能力与 GoodBuddy 能力差异 | 已分配的 Skills、MCP 等逐项接入并验证;未接入项有明确说明 |
@@ -105,7 +105,7 @@ Task 关联恢复或客户端历史导入。原生客户端产生的历史由对
活动记录中显示为已经同步的聊天内容。
FR-8 的实施清单须区分原生工具、GoodBuddy 分配的 Skills、自定义 MCP、内置 MCP、知识工具
以及遵循当前工作模式授权的配置工具。配置应用不再额外要求 GoodBuddy 原生确认,Ask 仍只读。
以及按当前请求资源范围提供的配置工具。配置应用不再额外要求 GoodBuddy 原生确认。
支持情况以真实调用为准;现有 DS 宿主插件能力不能
直接算作 DS Web 能力。发现现有分配无法承接时,在实施评审中明确差异和处理方式,不能默默忽略。
@@ -121,18 +121,18 @@ FR-8 的实施清单须区分原生工具、GoodBuddy 分配的 Skills、自定
| US-4 | 启动期间连续点击 | 同一启动只创建一次;按钮显示启动中 | FR-6 |
| US-5 | 已打开客户端后切换项目或模式 | 旧客户端保持原项目和启动模式;新操作使用新选择 | FR-5、6 |
| US-6 | 启动失败或模型请求失败 | 保留原因与可操作的重试方式;聊天内容和草稿不变 | FR-7 |
| US-7 | Ask 下从原生界面请求写文件、执行写命令或使用写入 MCP | AI 执行边界拒绝写入,不能通过客户端模式开关绕过 | FR-5、8 |
| US-7 | 从原生界面请求写测试文件、执行命令或使用已分配 MCP | 工具正常执行,无产品模式拒绝;未启用能力不可调用 | FR-5、8 |
| US-8 | 关闭终端、停止 DS 服务或退出 GoodBuddy | 对应进程和桥接释放,其他会话不受影响;原生历史保留 | FR-4、6 |
### 4.2 行为决策
启动参数按点击时的项目、执行空间、Runtime、模型和工作模式确定。界面后续切换不修改已运行
启动参数按点击时的项目、执行空间、Runtime、模型和能力配置确定。界面后续切换不修改已运行
客户端。这里只需保留进程运行所需的内存记录,不增加持久启动快照、恢复日志或数据库迁移。
Continue 和 OpenCode 启动成功后,每次新的点击创建独立终端。启动中的重复点击合并到同一
进行中操作。终端会话数量沿用现有管理器规则,不新增一套数量控制。
DS 按项目、模型配置及工作模式匹配运行服务。配置相同且服务可用时重新打开原服务;配置变更后
DS 按项目、模型及能力配置匹配运行服务。配置相同且服务可用时重新打开原服务;配置变更后
新建匹配实例,保留原实例直到用户停止或应用退出,避免在已有页面中静默改变模型和权限。
同一匹配项并发启动只执行一次。服务已退出则清除内存记录,下一次点击重新启动。
@@ -148,16 +148,13 @@ DS 按项目、模型配置及工作模式匹配运行服务。配置相同且
| 系统浏览器打开失败 | 保留可重开的就绪服务,通知用户重试;不复制含令牌地址到普通日志 | US-6 |
| 服务启动失败 | 清理本次创建的临时资源,再允许重试;不删除用户原生历史 | US-6 |
Ask 沿用现有 Runtime 按工具命令名判断的只读规则,不改变用户手动终端的已有权限。
DS 后台的 `read` 和原生 `skill` 可在 Ask 执行;`write`、`edit`、`pwsh`/`bash`
在 Ask 拒绝,在 Execute 放行,代理工具沿用现有分类。工具出现在模型请求目录中不等于
获准执行,判断仍在 `tools/execute` 路径。Web 接入复用这些规则,不增加 Shell 文本分析、
目录围栏、逐工具二次确认或新的权限等级。Execute 使用当前账号已有的文件、进程和网络权限。
原生客户端使用实际注册工具和已分配能力,不注入产品模式插件、只读名单或逐工具确认。
Main 代理保留请求身份、启用与分配和参数校验。工具使用当前账号已有的文件、进程和网络权限,
用户手动终端的 OS 权限不变。
官方 `dsh-plan-mode@0.1.7-rc.2` 的 Plan 只改变规划提示和状态,工具目录不随之变化;
权限预设由另外的 sandbox/approval 组件处理。因此不能把 Plan 名称当成 Ask 实现,
也不能把官方默认“工作区内修改”当成 GoodBuddy Execute。接入时将启动模式接到现有
工具名规则,原生页面的模式选择保持同一语义。
权限预设由另外的 sandbox/approval 组件处理,不能与已移除的 GoodBuddy 工作模式混同。
保留原生 full-access/approval 适配,不恢复 GoodBuddy 模式钩子。
这些规则覆盖普通启动、使用、关闭和已知失败。尚需技术验证的项目见第 7 节;它们不构成新增
授权层级或通用恢复框架的理由。
@@ -184,7 +181,7 @@ DS 服务运行后,打开入口仍显示“打开DSH Web”,旁边显示“
### 6.1 进程职责
Renderer 仅提交当前会话或项目标识及选择标识。Main 重新解析项目、模型配置、工作模式与
Renderer 仅提交当前会话或项目标识及选择标识。Main 重新解析项目、模型配置与
程序路径,通过共享 Zod 契约和显式 preload 方法完成调用。保留已有可信发送方校验,供应商
密钥留在 Main 加密设置和模型请求路径中。
@@ -282,7 +279,7 @@ Runtime。远端配置与模型桥需要客户端生命周期,不能直接复
| 阶段 | 工作与应提交证据 | 通过条件 |
| --- | --- | --- |
| P1 原生配置验证 | 固定三个客户端版本;保存脱敏命令、环境与程序路径;隔离已有全局配置 | Continue/OpenCode 使用指定模型;DS 自动选中目标项目 |
| P2 模型与模式 | 每个客户端发送最小真实请求;验证流式、取消、Ask 写入拒绝及 Execute 专用目录写入 | 请求确实经过 GoodBuddy 模型桥;客户端模式切换不能破坏 Ask 边界 |
| P2 模型与工具 | 每个客户端发送最小真实请求;验证流式、取消及专用目录写入 | 请求确实经过 GoodBuddy 模型桥,工具沿用已接入能力 |
| P3 生命周期接入 | 配置、PTY、DS 进程和模型桥接入现有管理路径 | 重开、失败重试、关闭及退出能释放对应资源,原生历史保留 |
| P4 远程验证 | 在共享 Host 部署当前代码,验证 Continue/OpenCode 的 SSH PTY 与模型桥 | 启动、请求、取消、断开和重试均有真实 Host 证据 |
| P5 UI 与交付资源 | 接入按钮、通知、停止 DS 服务;完善平台资源与文档 | 从真实按钮到客户端完成对话,无手动补依赖步骤 |
@@ -290,7 +287,7 @@ Runtime。远端配置与模型桥需要客户端生命周期,不能直接复
P1、P2 是实施前段的实验任务,完成后继续交付完整入口,不将实验程序或不可用按钮作为最终功能。
DS 单项目工作区选中和当前模型桥协议已通过本轮验证。后续优先接入三个客户端的既有
Ask/Execute 工具规则、Skills/MCP 配置及客户端生命周期,再完成快捷入口和交付资源。
统一执行规则、Skills/MCP 配置及客户端生命周期,再完成快捷入口和交付资源。
官方 DS 首次预览声明保留原生“继续”流程,模型配置提前准备。
## 8. 验收计划
@@ -299,11 +296,11 @@ Ask/Execute 工具规则、Skills/MCP 配置及客户端生命周期,再完成
| --- | --- | --- |
| 实际使用 | 每个本地客户端从 GoodBuddy 按钮进入当前项目,使用当前模型完成一轮真实对话 | FR-1~4、US-1、2 |
| 配置隔离 | 预置另一套全局模型后,仍使用当前选择;两个项目不串目录或配置 | FR-2、3、US-5 |
| 工作模式 | Ask 尝试文件写入、Shell 写入和 MCP 写入均不执行;Execute 在专用测试目录成功写入 | FR-5、8、US-7 |
| 工具能力 | 在专用测试目录验证文件、Shell 和已分配 MCP 写入;关闭能力后不可调用,无模式限制 | FR-5、8、US-7 |
| 能力复用 | 为声明支持的 Skills、MCP 各验证实际加载及最小调用;列出未承接能力 | FR-8 |
| 生命周期 | 连点启动、切项目、隐藏工作栏、关闭页签、重开 DS、停止服务及退出 | FR-6、US-4、5、8 |
| 已知失败 | Node/原生依赖缺失、失效目录、模型错误、浏览器打开失败、SSH 中断 | FR-7、9、US-6 |
| 远程 | 当前源码在共享 Linux x64 Host 上完成 Continue/OpenCode 的 Ask/Execute、模型和断开场景 | FR-2、3、5、US-3 |
| 远程 | 快捷入口接通后,须在共享 Linux x64 Host 验证 Continue/OpenCode 工具、模型和断开场景;普通远程 Runtime 验证不替代原生客户端入口 | FR-2、3、5、US-3 |
| UI | 浅深色、键盘操作、窄输入区、无压缩按钮、空对话、200% 文字缩放 | FR-1、US-1、2 |
| 平台资源 | 对实际交付的 Windows、macOS、Linux 架构逐项验证 Node、PTY、CLI 和 DS 原生依赖 | FR-9 |
@@ -325,6 +322,9 @@ The DS Web backend implementation and its focused validation are recorded below.
### 9.1 DS Web Backend, 2026-09-26
本节保留 2026-09-26 的接口与测试记录,其中 `workMode` 和 Ask/Execute 限制已由
[统一执行](../unified-execution/README.md)替代;不作为当前接口或工具权限规范。
`src/main/agent/native-dsh-web-client.ts` exports `NativeDshWebClientService`.
Construct it with `rootDirectory`, an async `resolveLaunchEnvironment` returning
`{ nodeExecutablePath, environment }`, and `resourcesPath` in packaged builds.
@@ -380,20 +380,20 @@ launch paths are unchanged because this service supports local DS Web only.
The production coordinator resolves the saved conversation/project and current
settings for both `get` and `open`. Matching includes the selected model profile
and credentials, work mode, capability assignments, knowledge scope, Obsidian
and credentials, capability assignments, knowledge scope, Obsidian
settings and local Node selection. Ready services keep their MCP gateway after an
OS browser-open error and can be reopened or explicitly stopped by their owner.
The coordinator passes its configuration key into the service's existing match
hash, so the inner DS reuse decision also observes updated skill digests and
launch settings even when directory paths are unchanged.
For DS Ask, the built-in gateway's existing read grant supplies the allowed raw
tool names; the Web adapter maps these through the official MCP naming contract.
Custom MCP is exposed in Execute, matching the existing Runtime behavior; custom
`readOnlyHint` annotations do not introduce a separate Ask permission rule.
The gateway supplies enabled and assigned tools; the Web adapter maps these
through the official MCP naming contract. Custom MCP follows the same assignment
rules, without product-mode filtering or approval policy. `readOnlyHint` describes
tool behavior and does not filter the catalog.
Assigned skill directories containing `SKILL.md` load through the official skill
plugin. Continue/OpenCode native Ask now retain Main-bound endpoints and map the
granted read-tool names through both native permissions and execution hooks.
plugin. Continue/OpenCode retain Main-bound endpoints and map the registered
tool names through native configuration without GoodBuddy mode hooks.
OpenCode prefixes names with the bound MCP server name; Continue uses raw names.
Story Graph additionally rechecks Supervisor enablement on every call.
@@ -145,9 +145,9 @@ SelectedRuntimeManager
混用会引入另一项真实风险。不同 profile ID 不通过比较或序列化明文 API Key 来合并;
密钥、Header 和插件配置更新通过现有设置失效路径使旧 owner 退役。
调研基线的 SSH launch profile 把 workMode 写入原生启动配置。当前实现把工作模式
放入 Session/当前 Prompt 路由,并设置原生 Session 工具规则,详见 §6.1;
不能仅从兼容键中删除 workMode,也不向用户增加逐工具审批。
调研基线的 SSH launch profile 曾把 workMode 写入原生启动配置。当前源码已从启动、
Session 和 Prompt 路由删除产品模式,按实际能力和请求归属接入工具,详见 §6.1;
不向用户增加逐工具审批。
## 4. 本机 OpenCode
@@ -220,7 +220,7 @@ OpenCode 1.18.x 的 `mcp.add` 在服务端独立执行:客户端超时或取
不依赖 Windows 大小写字符串猜测,也不取消路径存在性校验。
- 保留一个本地 Filesystem、Subprocess 和平台 Shell Provider。Session 使用原生 cwd
路由;非 Session 的清单查询显式传入查询工作区,不能回退到第一个项目。
- 保留 `setup(agentCtx)` 注册 Skill 和工具视图、每 Session 的 Ask definition 身份校验、
- 保留 `setup(agentCtx)` 注册 Skill 和工具视图、每 Session 的请求归属校验、
`sessionId + requestId` 准备及事件路由。Main 的 Web/MCP callback 按对应请求找
ToolProvider,不挂到某个最先创建的 adapter 上。
- 第一轮保持同 profile、图片能力和插件组合共享,`queueUsage` 的模型配置因此仍一致。
@@ -229,7 +229,7 @@ OpenCode 1.18.x 的 `mcp.add` 在服务端独立执行:客户端超时或取
第三方插件的初始化可能依赖配置中的路径,不能因为内置工具支持 cwd 就声称所有插件
天然多工作区安全。已启用插件组合属于进程配置;对实际产品支持的插件验证它使用
Agent scope/Session cwd。若某插件确实有项目级初始化状态,将该状态显式作为不兼容
启动配置,而不是默认给所有工作区各起一套 Provider 或禁止 Execute 工具。
启动配置,不默认给所有工作区各起一套 Provider 或禁用工具。
### 5.2 状态与取消
@@ -282,8 +282,8 @@ Agent 当前 Runtime installation + 兼容配置
- 同一 PID 的多个 binding 不代表同一权限或同一 operation。Host/installation identity
变化仍使用已有失效和退役规则,不把不同 Host、账号或 Runtime generation 合并。
原生 `chat.message` 在模型请求前设置该 Session 的工具规则:Execute 允许工具;
Ask 只开放原生只读、搜索和读取网络内容的工具,不开放 Shell/编辑/写入。
原生 `chat.message` 在模型请求前设置该 Session 的工具与模型路由,不再按产品模式
过滤 Shell、编辑或写入;请求级端点与子会话归属仍独立。
OpenCode 1.18.29 的 ACP 不转发未注册子 Session 的权限请求,且原生子代理只继承父
Session 的拒绝规则、不继承允许规则,因此子 Session 也按根 Prompt 设置规则,再
保留原生子代理的显式限制。不能只把进程启动配置统一设成 `ask`,否则子代理工具会等待。
@@ -382,7 +382,7 @@ token、global dir、活动 Session 或权限/问题队列。设置替换及窗
| --- | --- | --- |
| V1 | FR-RR1、FR-RR2 | 全新 profile 仅查看状态、切换设置,OpenCode/DSH 重型启动次数为 0;已有 Host 时刷新不新建;清单与首个真实请求并发只有一次初始化 |
| V2 | FR-RR1、FR-RR3 | 同一有效模型连接,两个独立项目各两会话同时自然开发,OpenCode/DSH 各一重型进程;各项目同名不同内容文件、命令 cwd、Git/测试结果都正确 |
| V3 | FR-RR3 | 第二轮复用同一批会话;Ask/Execute 混合,Ask 写入被边界拒绝,Execute 不增审批;Skill、MCP、图片能力、用量和业务问答不串归属 |
| V3 | FR-RR3 | 第二轮复用同一批会话;不同能力分配不串用,无产品模式或一般审批;Skill、MCP、图片能力、用量和业务问答不串归属 |
| V4 | FR-RR3、FR-RR4 | 一会话取消真实长工具/子代理时另外三会话完成并通过独立项目测试;分别检查请求 abort、SSE、问题映射和工具句柄释放 |
| V5 | FR-RR4 | 关闭面板不取消工作;释放一个会话不关闭共享进程;无会话 owner 空闲后退出;App 退出后本机受管进程无残留,远端按已有 detach 规则保留 Agent-owned 工作 |
| V6 | FR-RR1、FR-RR4 | 等价默认/显式选择复用;不同实际连接/插件配置不串用;配置更新期间旧请求完成,旧 generation 不永久积累;超过八个项目不因轻量 adapter 报重型容量满 |
@@ -24,11 +24,11 @@
[通用助手工作栏与执行空间 PRD](./prd.md)
继续负责工作栏的应用级位置、稳定能力目录、执行空间、范围绑定和总体产品边界。本文不重新
定义 Host Key、凭据、Agent 安装、Ask/Execute Runtime 或项目持久化契约。
定义 Host Key、凭据、Agent 安装、Runtime 执行或项目持久化契约。
## 2. 背景与当前问题
当前工作栏在聊天页面右侧固定显示“任务中心、工作区、浏览器、成果”四个 Tab。用户不能:
最初的聊天右栏固定显示“任务中心、工作区、浏览器、成果”四个 Tab。当时用户不能:
- 通过统一入口按需打开新的工作栏应用。
- 按应用策略关闭并重新打开可关闭的工作栏应用。
@@ -43,7 +43,7 @@ SSH 连接池,但尚不存在工作栏应用实例模型、终端 IPC、终端
### 3.1 工作栏应用
工作栏应用是可以在助手工作栏中打开的一个能力,例如任务中心、工作区、浏览器、成果或
工作栏应用是可以在助手工作栏中打开的一个能力,例如任务中心、工作区、浏览器或
终端、笔记。每项应用通过统一注册表声明:
- 稳定应用 ID。
@@ -77,14 +77,14 @@ SSH 连接池,但尚不存在工作栏应用实例模型、终端 IPC、终端
`defaultOpen`、`required` 和 `closable` 不互相推导。例如浏览器默认打开但不是必需实例;任务
中心和工作区既默认打开又必须存在。`required` 不表示锁定顺序,顺序只由 `reorderable` 控制。
当前六个应用的 `visibleAcrossContextSwitches` 均为 `true`。该属性记录应用目录的显示策略,
当前五个应用的 `visibleAcrossContextSwitches` 均为 `true`。该属性记录应用目录的显示策略,
不改变内容归属,也不授予其他会话的 MCP 访问权限;当前没有使用 `false` 的应用,尚未实现
按上下文隐藏 Tab 的策略。
浏览器在创建时绑定当前 Conversation;切换会话后仍保留原 Tab、选中状态和页面,导航操作
继续使用原 `targetRef.conversationId`。此时新建浏览器才绑定新会话。默认或旧布局中尚未绑定
的浏览器在首次使用时绑定活动会话,此后不再随会话切换改绑。终端同样保留创建时执行目标;
任务中心、工作区和成果的内容继续跟随当前项目。笔记使用应用级范围,选择与草稿不随项目或
任务中心和工作区的内容继续跟随当前项目。笔记使用应用级范围,选择与草稿不随项目或
会话切换,不接受 `targetRef`;重启仅恢复工作栏 Tab 描述,不恢复笔记选择和草稿。
### 3.2 工作栏 Tab 实例
@@ -119,8 +119,8 @@ stdio fallback。首期远程终端随 SSH Channel 结束,不提供跨 SSH 或
6. 多实例应用每次选择都创建新实例。
7. 终端从首期开始就是多实例应用。
8. 任务中心和工作区保持单实例、默认打开且不可关闭,分别固定在第一、第二位,`reorderable` 为 `false`。恢复旧布局时也按此规则修正顺序,其余 Tab 保持相对顺序。
9. 浏览器注册为可关闭的多实例应用,升级后保留一个默认实例;成果保持单实例、默认打开且
可关闭。
9. 浏览器注册为可关闭的多实例应用,升级后保留一个默认实例。成果应用已移除,旧布局过滤
其实例,其他 Tab 及偏好保留。
10. 用户关闭可关闭实例、切换或重排应用 Tab 后,“+”仍保持可见。
11. 选择“终端”后不再显示第二层目标选择器。存在当前项目时直接绑定该项目,由 Main
根据项目执行空间自动打开本机或托管 SSH Shell;没有当前项目时打开本机 Home Shell。
@@ -128,7 +128,7 @@ stdio fallback。首期远程终端随 SSH Channel 结束,不提供跨 SSH 或
Shell,不伪装为恢复旧进程。
13. 工作栏收起、切换主页面或切换 Tab 不终止终端;显式关闭终端 Tab 才终止对应 Shell。
14. 应用重启不自动启动 Shell。恢复的终端 Tab 显示“会话已结束”,由用户显式重新连接。
15. 终端是用户交互表面。Ask/Execute 继续约束 Agent Runtime,不把用户键盘操作误判为
15. 终端是用户交互表面。Agent Runtime 沿用能力与资源范围,不把用户键盘操作误判为
Agent 工具调用;Agent、自动化和模型不得未经明确用户操作向终端注入输入。
16. 工作栏继续按上位 PRD 提升为应用级容器;切换聊天、知识、魔法笔记或活动记录等主页面
不销毁 Tab 实例或终端 Session。
@@ -185,7 +185,7 @@ stdio fallback。首期远程终端随 SSH Channel 结束,不提供跨 SSH 或
- 标签全部可见时移除左右滚动按钮及其占位;溢出时左右箭头在滚动视口两侧各占独立的 28px 宽度,不覆盖标签、关闭按钮或“+”。鼠标移入标签栏时显示可滚动方向的箭头,移出后隐藏;键盘聚焦箭头时显示,无悬停能力的设备保持可滚动方向的箭头可见。悬停箭头时显示轻微底色。点击滚动约一屏,边界方向禁用并隐藏;溢出期间隐藏和禁用均保留占位,避免布局跳动。切换或新增激活标签时将整个标签(含关闭按钮)滚入可见区域。未激活标签使用低对比度灰蓝底色和细边框,激活标签保留亮底与强调色顶线。
- 终端 Tab 默认使用递增标题,例如“终端 1”“终端 2”;状态栏持续显示项目、Host、
工作目录和 Shell。用户可以重命名终端。
- 任务中心、工作区、成果及新建终端的默认标题随界面语言切换,恢复布局时也使用当前语言。
- 任务中心、工作区及新建终端的默认标题随界面语言切换,恢复布局时也使用当前语言。
终端自定义名称保持原文;旧布局中的终端名称保持原值,即使看起来像“终端 1”。浏览器
标题沿用现有行为,不在本次标题国际化范围内。
- 当前 Tab 同时使用连续内容表面、选中边框、顶部强调线、图标和较高字重,不能只靠文字颜色。
@@ -218,7 +218,6 @@ stdio fallback。首期远程终端随 SSH Channel 结束,不提供跨 SSH 或
| 任务中心 | `single` | 当前项目 | 是 | 是 | 否 | 否 | 聚焦已有 Tab |
| 工作区 | `single` | 当前项目 | 是 | 是 | 否 | 否 | 聚焦已有 Tab |
| 浏览器 | `multiple` | 当前 Conversation | 是,一个实例 | 否 | 是 | 是 | 每次创建新 Tab |
| 成果 | `single` | 当前项目 | 是 | 否 | 是 | 是 | 聚焦已有 Tab |
| 终端 | `multiple` | 当前项目 | 否 | 否 | 是 | 是 | 每次创建新 Tab |
| 笔记 | `single` | 应用级 | 否 | 否 | 是 | 是 | 聚焦已有 Tab |
@@ -334,7 +333,7 @@ type TerminalSessionState =
```ts
type WorkbarAppDefinition = {
id: 'tasks' | 'workspace' | 'browser' | 'results' | 'terminal'
id: 'tasks' | 'workspace' | 'browser' | 'notes' | 'terminal'
label: string
icon: WorkbarAppDefinition['id']
description: string
@@ -463,8 +462,8 @@ Sidebar 在渲染时按当前语言派生应用和默认终端标题,再交给
## 13. 权限与边界
- 用户终端以当前本机账号或所选 SSH 账号的正常权限运行,不增加额外虚构的 trust tier。
- Ask/Execute 是 Agent Runtime 模式,不自动改变用户直接操作终端的 OS 权限。
- UI 必须持续将其标注为“用户终端”,避免被理解为 Ask Runtime 的只读输出。
- Agent Runtime 配置不自动改变用户直接操作终端的 OS 权限。
- UI 必须持续将其标注为“用户终端”,避免被理解为 Runtime 的只读输出。
- Agent、模型、监督器和自动化不能调用终端 write,也不能把指令注入已有 Session。
- 终端输出不会自动进入对话上下文、模型 Prompt、成果或活动记录。
- Renderer 只能引用项目和 Session 的公开 ID;Main 从权威 store 解析目录、Host、凭据和
@@ -569,7 +568,7 @@ Schema、假数据终端或不可用入口的中间产品。
- [x] 关闭可关闭的活动 Tab 后激活正确的相邻 Tab 并恢复焦点。
- [x] 当前 Tab 的背景、边框、顶部指示和字重清晰可辨;关闭按钮仅在悬停、焦点或无悬停
设备上出现,且不引发布局位移。
- [x] 升级后任务中心、工作区、一个浏览器实例和成果按默认布局打开;布局恢复会补回缺失的
- [x] 升级后任务中心、工作区和一个浏览器实例按默认布局打开;布局恢复会补回缺失的
任务中心与工作区。
- [ ] 在所有主要页面都能打开工作栏;切换主要页面不会销毁 Tab 实例或终端 Session。
@@ -0,0 +1,56 @@
# 工作区文件导入与时间
## 产品与交互
FR-WF1:工作区展示当前项目执行目录内的实际文件。成果页、工作栏注册项和独立成果导入入口
已移除。旧布局只过滤 `results` 实例,保留其他实例、目标、展开状态和宽度;若活动实例被移除,
按现有布局规则选择第一个保留实例。
FR-WF2:文件页提供“导入文件”。初始目标为项目根目录;点击树中的目录后以该目录为目标,
点击文件后以其父目录为目标,“浏览此目录”同时更新目标。目标路径常显,打开选择器后固定
本次项目与目标,不因切换会话或项目改变写入位置。本机从选定文件复制字节,远程上传到所选
Host 的项目目录。支持二进制和空文件,不调用文档解析器,也不创建 artifact 数据库记录。
同名文件不覆盖。批次逐项处理,失败后继续其余文件;成功数量、目标和失败原因通过应用通知
显示。写入失败时尝试移除本次新建的部分文件,清理失败则报告残留路径。取消文件选择不写入,
导入期间禁用重复提交。完成后刷新目录。当前不提供传输中取消或进度百分比。
FR-WF3:名称默认升序。名称、修改时间和有可用数据时的创建时间列均可点击切换排序;首次
选择时间列按最新优先。每一级目录独立排序且目录优先,缺失时间放在同类条目末尾,显示 `-`。
每目录沿用最多 500 条的读取上限,排序只覆盖已读取条目,截断提示保留。窄栏横向滚动仅发生在
文件视口,工具栏保持可见。
US-WF1:选中子目录后导入二进制及空文件,目录刷新后可见,原文件不变。同名项失败而已有
内容保留;成功项仍落在所选目录。
US-WF2:切换排序后文件按真实文件系统时间显示;不支持创建时间的文件系统不显示创建时间列,
混合数据中缺失值保留为空。Linux 的 inode 状态变更时间不冒充创建时间。
US-WF3:升级前会话图片在聊天和重新打开应用后仍可读取;打开工作区不会把会话图片或附件复制
到项目目录。生成的普通文件由 Runtime 文件工具写入工作区并出现在同一目录列表。
## 存储与实现
`WorkspaceFilesPanel` → preload `workspace.importFiles(projectId, path)` → Main
`workspace:import-files` 验证发送方与共享路径契约,固定项目执行空间并打开原生文件选择器。
`importWorkspaceFiles` 使用已有 `WorkspaceAccess.manage`,先独占创建目标,再以 256 KiB
块读取和写入;每次写入检查目标大小与偏移。内存不随文件总大小增长。文件大小受磁盘和权限
约束,不沿用旧成果导入的预览类型与大小限制。
远程复用 `RemoteWorkspaceAccess`、`ProtocolRemoteWorkspaceTransport` 和 Agent
`workspace/manage`。新增 `importFile` 动作的 Base64 块受共享 schema 限制,完整请求低于
1 MiB 控制帧上限。该动作需要含本次源码的新 Agent;旧 Agent 会拒绝新动作并报告失败,
不能声称旧版已支持上传。文件读取和既有管理操作仍走原通路。
本机目录按条目读取 `lstat`,远程复用 Agent 已有目录元数据;两端传递 `mtime` 和有效正值
`birthtime`。缺失 birthtime 时省略 `createdAt`,从不回退为 `ctime`。Renderer 不逐文件发 IPC。
现有 `artifacts` 表包含 `createImageArtifact` 保存的内联图片、会话上传源图引用以及旧导入
内容,并非项目文件索引。移除成果页不迁移、不删除这些记录;`artifacts.get/list`、消息
`artifactIds`、图片恢复与编辑读取保留。图片生成结果继续作为会话图片保存;需要实际图片文件
时由 `save_image` 使用会话图片 ID 显式保存到 Runtime 主机的指定路径,远程项目写到远程 Host,
不需要成果页。引用发现与保存契约见[图片保存工具](../conversation-media-generation/technical-design.md#图片保存工具)。
不会自动给旧图片批量创建文件,也不会把聊天附件
复制到项目。图片工具仍接受其既有路径契约,本次未修改生成或保存工具的运行权限。
验收命令与实际验证边界记录在[进度](./progress.md)。