Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/daemon-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -3109,6 +3109,14 @@ SGLang 等推理服务的扩展字段,官方 OpenAI 接口会拒绝);Respo
该 Provider 的默认协议(ACEModel 为 Responses);切换到其他 Provider 会清除该字段,其他 Provider 显式传入
则返回 `UNSUPPORTED_MODEL_OPTION`,未知协议值返回 `INVALID_API_PROTOCOL`。

Responses 的自动工具选择使用 `tool_choice.type:"allowed_tools"` 和 `mode:"auto"`,
允许列表仅包含本次提供的 ACECode 函数工具;模型仍可直接回答,不会被强制调用工具。
没有工具的请求显式发送 `tool_choice:"none"`,压缩请求已有的禁用工具策略保持不变。
兼容网关须支持该标准字段;拒绝时不会退回不受限制的 `auto`。
网关额外注入的托管生图、搜索等工具不属于 ACECode 本地执行链路;若仍返回未支持的
输出类型(如 `image_generation_call`),会明确报错,不再丢弃结果后显示文字成功。
生图应调用已配置的 `image_generate`,才能走本地成本确认、附件保存和展示流程。

返回包含 `api_key` 原值的模型配置。校验错误使用 `BAD_JSON`、`BAD_REQUEST` 或
`SavedModelEditError` 字符串;持久化失败会回滚内存并返回
`500 PERSIST_FAILED`。
Expand Down
1 change: 1 addition & 0 deletions docs/desktop-agent-office.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Windows 与 macOS Desktop 可开启透明桌面宠物,默认关闭。设置
- 顶部显示跨工作区最近发过消息的五个主会话。顺序只看用户最后发送消息的时间,打开、切换和 agent 输出不会把会话顶到最前面。
- “跟随”默认开启,办公室随主窗口当前会话切换。点击门牌会关闭跟随并固定办公室;再次打开跟随后恢复跟随。查看最近五个之外的当前会话不改变门牌排序。
- 切换会话等待新快照时保留当前办公室的布局、角色和标题,新快照就绪后一起切换,避免中途闪现默认布局。快速连续切换只应用最后一次选择;真实空会话或会话不存在时仍显示空态。
- 最近五个会话从共享索引的只读分片中筛选,只复制返回结果;旧会话缺失用户发言时间时按批次轮转补读,文件签名检查也计入补读预算,避免每次切换遍历磁盘。模型上下文大小在办公室显示后异步补全,不阻塞布局、角色和标题切换;切换与关闭会取消过期补全请求。
- 主 agent 成功完成后留在座位显示 `zzz`,下一轮自动醒来;成功完成的子 agent 立即离座,重新工作时以同样的外观返回。
- 忙碌的 agent 头顶常驻状态气泡:「图标 动作 · 细节」。正在输出时显示「撰写回复」和最新的几个字(打字动画 + 光标),推理时显示思考点和推理尾巴,调用工具时显示动作(读取、运行命令、修改代码…)和调用预览(路径、命令)。默认「用于编程」模式下服务端不发正文进度,桌宠由 token 事件推断。气泡互相避让:先左右错开,再抬高并用引线连回头顶,放不下时只留动作。
- 子 agent 出现时门先打开,人从门槛淡入走进来,先到派活的人桌前领「任务」信封再回工位,坐下后跳一跳、冒星星、说「报到!」;完成后走到派活的人桌前递「回报」信封(派活的人显示「收到…的结果」),说「再见」后快步出门、在门槛淡出;失败或停止的成员直接道别出门。网状协作中 agent 间消息以带「消息 / 新任务 / 回报」标签的信封在工位间飞过。系统开启「减少动态效果」时不走路,交接信封、「报到!」和原地「再见」仍然显示。
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-10-17
31 changes: 31 additions & 0 deletions openspec/changes/adapt-sidebars-to-transcript-width/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
## Context

App 持有全局左栏开关、按工作台保存的右栏开关和全局栏宽;ChatView 持有预览页签、预览隐藏与子对话状态。现有布局求解器允许 transcript 缩到 350 px。动机见 proposal.md。

## Goals / Non-Goals

- 以 transcript 为优先级最高的常规阅读区域,计算窗口、预览、导航与子对话共同产生的占宽。
- 不迁移偏好存储作用域,不改后端,不修改用户已有的手动最大化/演示模式语义。
- 自动隐藏保留组件、页签和草稿;不把临时显示状态写进工作台或全局偏好。

## Decisions

1. 按用户调低折叠阈值的要求,所有字号的阅读下限统一为 350 CSS px。恢复门槛比折叠门槛高 64 px;使用壳体实际宽度、保存栏宽和预览意图预测展开后的 transcript 宽度,避免用收起后变宽的 transcript 直接触发反向展开。
2. 独立纯函数决定左右自动折叠与可停靠能力;React hook 只负责测量、临时状态与外部点击。左栏优先保留,右侧预览和列表作为一组让出空间。子对话打开时,父 transcript 的预算额外考虑子对话宽度。
3. 只由正常布局下的手动开关修改现有偏好。popup 互斥、切工作台清空,窄窗口刷新重新按偏好计算。宽度恢复后,原先开启的栏停靠,原先关闭的栏保持关闭。
4. 左右 popup 保留原组件实例,不用改变 portal 目标的方式搬运内容。通过 React 事件边界识别栏内 portal 菜单,防止操作栏内菜单被误认作外部点击。Escape 尊重内层菜单/对话框的处理。
5. 窄右侧 popup 同时有详情与列表时,以详情为主,列表可临时覆盖详情供选择;不能因两个最小宽度相加而把浮层撑出窗口。临时列表开关也不修改持久化偏好。
6. 现有显式预览最大化/演示模式继续生效;自动折叠只保护常规对话布局,不能把用户主动最大化误当成挤压。
7. Desktop 的原生最小窗口宽度由旧的 1170 降为 480 逻辑像素,低于左栏自动折叠门槛。Windows 继续按 DPI 缩放并受工作区上限约束;macOS 拖动和程序化设置宽度共用此下限。初始窗口大小保持现有设置。原生下限与 transcript 的阅读下限分开,用户主动缩到更窄时由前端使用全部可用空间。
8. 浮层也提供靠 transcript 一侧的拖宽手柄:左浮层拖右边,右浮层拖左边。使用实际渲染宽度作为拖动起点,范围由当前容器和 24 px 外部点击区域计算。浮层手动宽度保存在同一个全局栏宽偏好中的可选 `sidebarPopup` / `rightPanelPopup` 字段,不改正常占位宽度和开关;拖窄不会因此退出浮动或压缩 transcript。默认仍使用现有栏宽,窄视口临时夹取不能覆盖保存值。Pointer capture 保持跨边界拖动,取消、失焦、关闭或卸载均清理监听与拖动光标;键盘方向键沿用原手柄步长。

## Risks / Trade-offs

- 收起后测量反馈环 → 根据未受临时隐藏影响的意图计算,并保留恢复余量。
- popup 关闭导致编辑草稿丢失 → 自动隐藏保留挂载;对既有草稿存储做回归验证。
- 老 WebView 不支持新 CSS → 使用普通绝对定位、现有颜色变量与 rgba 阴影。
- Desktop 运行包可能仍使用旧前端 → 本次验证源码、构建和 Chromium;不把这些证据宣称为已安装 Desktop 已更新。

## Migration Plan

无需存储迁移;已有偏好即为恢复依据。撤回前端变更即可回滚,临时状态不会污染保存数据。
25 changes: 25 additions & 0 deletions openspec/changes/adapt-sidebars-to-transcript-width/proposal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
## Why

窗口缩小时,左右边栏与预览会挤压 transcript,导致最重要的对话内容不可读。需要优先为 transcript 让出空间,并在窄窗口里保留通过 popup 使用边栏的能力。

## What Changes

- 以 transcript 的可用宽度为依据,先自动收起整个右侧工作区,再收起左栏。
- 所有字号统一保留 350 CSS px 阅读宽度,恢复时增加 64 px 余量,避免临界抖动。
- 窄窗口 expand 打开对应侧 popup,栏内正常操作,点击外部、再次点击按钮或 Escape 收起;两侧 popup 互斥。
- 自动折叠与 popup 不修改持久化开关和栏宽;仅恢复用户原先开启的栏。
- 保留预览页签、编辑草稿和子对话状态;窗口极窄时优先让 transcript 使用可用空间。

## Capabilities

### New Capabilities
- `responsive-workbench-layout`: transcript 优先的空间分配、自动折叠、popup 与偏好恢复。

### Modified Capabilities
- `webui-side-panel`: 单会话侧面板不再要求所有窗口宽度下固定占位,支持响应式隐藏与浮层。

## Impact

- Web/Desktop 共用的 App、ChatView、TopBar、布局求解器及独立响应式样式。
- 复用现有全局左栏偏好、工作台右栏偏好与全局栏宽,不改变存储作用域或后端协议。
- 增加纯逻辑与 Chromium 真实组件交互验证;保留当前工作区其他未提交修改。
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
## Purpose

保证 ACECode 单会话工作台在窗口缩放时优先显示可阅读的 transcript,同时保留左右辅助栏的临时访问能力、用户保存的开关选择和栏宽,避免窗口缩放意外改变用户长期布局。

## ADDED Requirements

### Requirement: Transcript-first responsive collapse
系统 SHALL 根据 transcript 可用宽度决定辅助栏是否占位。所有字号阅读下限 SHALL 统一为 350 CSS px;恢复展开 SHALL 额外保留 64 px。右侧导航与预览及打开的子对话占宽 MUST 参与判断。空间不足 SHALL 先收右侧工作区,再收左栏;整个窗口不足阅读下限时 transcript SHALL 使用可用空间而不是撑出视口。显式最大化预览和演示模式 SHALL 保留原行为。

#### Scenario: 连续缩小再拉大
- **WHEN** 用户从足够宽的窗口逐渐缩小并重新拉宽
- **THEN** 右栏先收起、左栏后收起,恢复按左栏优先且 transcript 仍可读的条件进行,临界宽度的小幅抖动不反复切换

#### Scenario: 打开预览造成拥挤
- **WHEN** 窗口宽度不变但预览或子对话占用更多空间
- **THEN** 系统重新判断 transcript 的空间并按相同顺序释放辅助栏占宽

#### Scenario: 统一 350 px 折叠边界
- **WHEN** 不同字号下,正常占位的辅助栏使 transcript 可用宽度逐渐缩至 350 CSS px,再继续变窄
- **THEN** 恰好 350 CSS px 时保持占位,低于该值时按右栏优先的顺序折叠;已折叠栏需满足额外 64 px 余量才能恢复

#### Scenario: 原生窗口允许拖动到单列布局
- **WHEN** 用户拖动 Desktop 窗口边缘缩小宽度
- **THEN** 原生窗口 SHALL 允许缩到 480 逻辑像素,能够触发左右栏自动折叠及单列 transcript,不能以旧多栏布局的最小宽度阻止缩小

### Requirement: Preserve persistent layout intent
系统 SHALL 独立保存用户左右栏开关及栏宽;自动折叠、浮层开关和恢复 SHALL NOT 修改这些偏好。宽度恢复 SHALL 仅恢复之前开启的栏。刷新、重启和切工作台 SHALL 使用既有持久化作用域中的偏好,不能继承其他工作台的临时 popup。

#### Scenario: 原本关闭的栏临时查看
- **WHEN** 原本关闭的栏在窄窗口中通过 popup 打开,随后窗口拉宽或刷新
- **THEN** 该栏仍然关闭,已保存开关与栏宽不变

#### Scenario: 原本开启的栏自动恢复
- **WHEN** 原本开启的栏因空间不足自动收起,随后恢复门槛满足
- **THEN** 该栏恢复正常占位,预览页签与草稿仍然保留

### Requirement: Temporary sidebar popup
在空间不足以正常展开时,expand SHALL 打开对应侧 popup,不改变 transcript 的布局宽度。popup SHALL 限于可用视口,左右互斥;栏内操作和其菜单 SHALL 保持可用;点击栏外、再次点击对应按钮或 Escape SHALL 收起。内层菜单或对话框处理 Escape 时 SHALL 优先关闭内层。

#### Scenario: 点击内部与外部
- **WHEN** 用户在窄窗口打开一个边栏并点击其中的菜单、滚动或选择内容
- **THEN** 栏正常响应且不会因栏内点击被收起;点击栏外时 popup 收起,持久化偏好不变

#### Scenario: 切换两侧与键盘关闭
- **WHEN** 一个 popup 打开时用户打开另一侧或按 Escape
- **THEN** 打开另一侧时关闭当前侧;Escape 关闭当前 popup 并将键盘焦点还给相应展开按钮

#### Scenario: 窄右栏中的详情和文件列表
- **WHEN** 右侧 popup 不能并排容纳详情和导航
- **THEN** 用户仍可在浮层内查看详情和打开导航选择文件,浮层不超出窗口

### Requirement: Resizable sidebar popups
左右 popup SHALL 支持拖动靠 transcript 一侧的边缘调整宽度,并支持手柄上的键盘方向键。调整 SHALL 保持浮动,不改变 transcript 几何和正常占位栏宽或开关;手动浮层宽度 SHALL 独立持久化。浮层 SHALL 保留可点击的外部区域并遵守当前视口边界;窗口临时变窄 SHALL NOT 覆盖保存的浮层宽度。拖动取消、关闭、切会话或失焦后 SHALL 清理拖动状态。

#### Scenario: 拖宽详情浮层
- **WHEN** 用户向左拖动右侧详情浮层的左边缘
- **THEN** 浮层变宽,右边缘保持贴边,transcript 宽度和草稿不变;向右拖动则变窄,过程中不会自动收起或恢复占位

#### Scenario: 保存浮层宽度并适配视口
- **WHEN** 用户调整左栏或右栏浮层宽度后关闭、重开或刷新,再缩小和恢复窗口
- **THEN** 浮层恢复用户选择的宽度,空间不足时仅临时夹取到视口范围;正常栏宽与开关不变

#### Scenario: 跨边界拖动和取消
- **WHEN** 拖动指针移出浮层,随后松开、取消或关闭浮层
- **THEN** 拖动持续到终止事件,终止后不残留拖动光标、监听或意外的宽度更新
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
## MODIFIED Requirements

### Requirement: Side panel layout in single-session view

Web UI 单会话视图 (`view === 'single'`) SHALL 提供右侧导航面板及详情预览,默认导航宽度 280 CSS px,允许使用用户保存的栏宽。是否正常占位 SHALL 服从 transcript 优先的响应式布局与用户保存的开关;窄窗口展开 SHALL 使用 popup。Grid4 / Grid9 视图下 SHALL NOT 显示该面板。

#### Scenario: 单会话视图渲染右侧面板
- **WHEN** 用户进入单会话视图且已开启右侧面板、空间充足
- **THEN** ChatView 右侧按保存宽度显示导航和已打开的详情

#### Scenario: 切到 4 宫格隐藏面板
- **WHEN** 用户从单会话视图切到 4 宫格视图
- **THEN** SidePanel 从单会话布局移除,grid 视图主区按既定布局填满

#### Scenario: tab 切换零延迟
- **WHEN** 用户点击变更导航
- **THEN** 面板立即展示已加载消息聚合的变更数据

#### Scenario: 切 session 时面板状态保留
- **WHEN** 用户选择同一工作区内另一个 session
- **THEN** 既有工作台状态隔离规则继续保留各自文件树缓存、展开目录和页签,不因响应式隐藏而清空

#### Scenario: cwd 真变时整面板 reset
- **WHEN** 用户切换到另一个 cwd
- **THEN** 系统按对应工作台加载导航和预览,不能显示其他 cwd 的残留
40 changes: 40 additions & 0 deletions openspec/changes/adapt-sidebars-to-transcript-width/tasks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
## 1. 响应式决策

- [x] 1.1 实现 transcript 优先的纯布局决策,单测覆盖先右后左、恢复余量、手动关闭、预览和子对话占宽。
- [x] 1.2 接入 App 与 ChatView 的实际宽度和显示意图,验证 resize 不写入持久化开关与栏宽。

## 2. Popup 交互

- [x] 2.1 实现左右互斥 popup、外部点击、按钮切换、Escape 与焦点恢复,浏览器验证栏内 portal 菜单不会误关闭。
- [x] 2.2 处理窄右侧详情与导航、页签草稿保留、极窄布局,浏览器验证实际 transcript 几何和刷新后的偏好恢复。

## 3. 集成验证

- [x] 3.1 执行完整 pnpm test、pnpm build、严格 OpenSpec 校验和 diff 检查,记录实际结果。
- [x] 3.2 Chromium 覆盖 1920×1080、较窄及极窄窗口、深浅主题和开关组合,保存截图并人工检查;注明 Desktop 包是否重建。

## 4. 原生窗口下限补齐

- [x] 4.1 将 Desktop 最小宽度降到 480 逻辑像素,使正常拖动能进入单列 transcript;核对 Windows/macOS 限制入口,验证原生下限与前端折叠阈值的跨层约束。

## 5. 浮层调宽

- [x] 5.1 增加左右浮层拖动与键盘手柄,按视口约束宽度并独立保存;单测验证范围、偏好兼容及不改变停靠判定。
- [x] 5.2 真实 App 验证详情、仅导航、左栏浮层的跨边界拖动、重新打开/刷新、视口夹取、取消及草稿保留;完成 Web 测试、构建与严格校验。

## 6. 降低折叠阈值

- [x] 6.1 将所有字号的 transcript 折叠阈值统一降至 350 CSS px,保留 64 px 恢复缓冲;更新边界与真实页面验证,完成 Web 测试、构建及严格校验。

## 验证记录

- 最终 `pnpm test`、`pnpm build` 均退出 0;构建扫描 4541 个正则,无旧 WebView 不兼容的 lookbehind。`openspec validate adapt-sidebars-to-transcript-width --strict` 与 `git diff --check` 通过。
- `node src/lib/responsiveSidebars.test.js`:通过。覆盖逐像素缩小、自定义左栏宽度、恢复余量、四种开关组合及预览/子对话占宽。
- `node scripts/test-responsive-sidebars.mjs`:通过。使用真实 App、TopBar、Sidebar、ChatView 和存储模块,仅隔离 API 与 WebSocket;覆盖外部点击、按钮切换、Escape、portal 菜单、列表自身收起、四组合刷新恢复、编辑器实例与未保存草稿、显式最大化、子对话占宽、切工作台清理 popup。
- Chromium 截图:1920×1080、1400×1080、1100×1080、800×1080、320×1080;深浅主题,已目视检查。产物目录由脚本输出,文件名包含 `1920-wide.png`、`1400-preview-popup.png`、`light-1920.png`、`dark-800.png` 等。
- Impeccable 对本次修改的 UI 文件检测返回空问题列表。
- 未重建或重启已安装 Desktop。Chromium 中通过 Desktop 编辑模式验证共用前端,不代表运行中的 Desktop 已加载更新。
- 原生下限补验:旧值 1170 在新增跨层用例中无法触发左栏折叠;改为 480 后,左栏宽度 160/270/360 的组合均能进入单列。`responsiveSidebars.test.js`、`singleLayout.test.js`、`framelessResize.test.js` 均通过。Windows 按 DPI 使用共享下限;macOS 拖动和程序化尺寸也使用该值。本轮未编译/启动原生 Desktop,需重建并重新启动后才改变运行中窗口的限制。
- 详情最大化拼接修正:去掉相邻文件栏圆角规则对最大化状态的排除。真实 App 的深浅主题验证均为圆角 0、相邻顶边与分隔位置一致,恢复普通布局后仍保持直角拼接。完整 `pnpm test`、`pnpm build` 通过;目视截图确认缺角消失,未重建 Desktop。
- 浮层调宽补验:纯逻辑覆盖浮层范围、视口临时夹取、旧偏好兼容与停靠判断隔离。`test-responsive-sidebars.mjs --popup-resize-only` 和完整脚本均通过,覆盖左右真实指针拖动、方向键、左栏缩到 160 px 仍保持浮动、从被夹取的实际边缘起拖、仅导航内容跟随宽度、详情编辑器实例与草稿、Escape/pointercancel 清理、关闭重开和刷新记忆。完整 `pnpm test` 与 `pnpm build` 退出 0;样式检测无新问题;已检查 `left-popup-resized.png` 与 `detail-popup-resized.png`。未重建已安装 Desktop。
- 350 px 阈值补验(2026-10-18):纯逻辑验证各字号统一边界;真实 App 在默认栏宽下确认窗口 906/905 px 时右栏保持/折叠、626/625 px 时左栏保持/折叠,保持时 transcript 实测为 350 px;恢复分别在 970/690 px,保留 64 px 缓冲。完整浏览器脚本通过,包含浮层调宽、刷新记忆与草稿保留;`pnpm test`、`pnpm build`、严格 OpenSpec 校验与 diff 检查通过。截图输出目录为 `ace-responsive-sidebars-KoXviV`(系统临时目录)。未重建 Desktop。
2 changes: 2 additions & 0 deletions openspec/changes/fix-acemodel-prompt-cache-key/.openspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-10-18
Loading
Loading