aws-runtime-bridge 1.9.185 → 1.9.189

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/CHANGELOG.md +1767 -1640
  2. package/README.md +256 -256
  3. package/dist/adapter/AcodeSdkAdapter.js +3 -3
  4. package/dist/adapter/types.js +1 -1
  5. package/dist/browser/browser-pool.d.ts +2 -0
  6. package/dist/browser/browser-pool.js +1 -1
  7. package/dist/config.d.ts +12 -0
  8. package/dist/config.js +2 -2
  9. package/dist/index.js +1 -1
  10. package/dist/remote-desktop/win32-api.js +1 -1
  11. package/dist/routes/background-tasks.js +4 -4
  12. package/dist/routes/dashboard.js +17 -17
  13. package/dist/routes/file-browser.js +1 -1
  14. package/dist/routes/terminal.js +19 -19
  15. package/dist/services/acode-bg-manager.js +1 -1
  16. package/dist/services/auto-register.js +1 -1
  17. package/dist/services/instance-features.d.ts +9 -0
  18. package/dist/services/instance-features.js +1 -1
  19. package/dist/services/launch-manager.d.ts +33 -0
  20. package/dist/services/launch-manager.js +7 -7
  21. package/dist/services/launch-streams.d.ts +2 -0
  22. package/dist/services/launch-streams.js +4 -4
  23. package/dist/services/panel-auth.d.ts +4 -0
  24. package/dist/services/panel-auth.js +1 -1
  25. package/dist/services/plugin-handler-adapter.js +2 -2
  26. package/dist/services/port-detector.js +5 -5
  27. package/dist/services/workspace-files.d.ts +4 -0
  28. package/dist/services/workspace-files.js +1 -1
  29. package/dist/utils/dynamic-import.d.ts +31 -0
  30. package/dist/utils/dynamic-import.js +2 -0
  31. package/dist/utils/sdk-package-loader.js +1 -1
  32. package/node_modules/playwright/cli.js +0 -0
  33. package/node_modules/playwright-core/bin/reinstall_chrome_beta_linux.sh +0 -0
  34. package/node_modules/playwright-core/bin/reinstall_chrome_beta_mac.sh +0 -0
  35. package/node_modules/playwright-core/bin/reinstall_chrome_stable_linux.sh +0 -0
  36. package/node_modules/playwright-core/bin/reinstall_chrome_stable_mac.sh +0 -0
  37. package/node_modules/playwright-core/bin/reinstall_msedge_beta_linux.sh +0 -0
  38. package/node_modules/playwright-core/bin/reinstall_msedge_beta_mac.sh +0 -0
  39. package/node_modules/playwright-core/bin/reinstall_msedge_dev_linux.sh +0 -0
  40. package/node_modules/playwright-core/bin/reinstall_msedge_dev_mac.sh +0 -0
  41. package/node_modules/playwright-core/bin/reinstall_msedge_stable_linux.sh +0 -0
  42. package/node_modules/playwright-core/bin/reinstall_msedge_stable_mac.sh +0 -0
  43. package/node_modules/playwright-core/cli.js +0 -0
  44. package/node_modules/playwright-core/lib/webp_codec.wasm +0 -0
  45. package/node_modules/playwright-core/lib/xdg-open +0 -0
  46. package/package/acode/dist/await-complete-tool.js +3 -3
  47. package/package/acode/dist/mcpToolNames.js +1 -1
  48. package/package/acode/dist/runtime.d.ts +9 -0
  49. package/package/acode/dist/runtime.js +20 -21
  50. package/package/acode/dist/sub-agent-manager.d.ts +33 -0
  51. package/package/acode/dist/sub-agent-manager.js +9 -1
  52. package/package/acode/dist/sub-agent-tools.d.ts +4 -0
  53. package/package/acode/dist/sub-agent-tools.js +27 -12
  54. package/package/acode/dist/subagent-handback.d.ts +16 -0
  55. package/package/acode/dist/subagent-handback.js +7 -0
  56. package/package/acode/dist/tool-allocation.js +1 -1
  57. package/package/acode/package.json +38 -38
  58. package/package/aws-client-agent-mcp/dist/agent-client.d.ts +14 -5
  59. package/package/aws-client-agent-mcp/dist/agent-client.js +1 -1
  60. package/package/aws-client-agent-mcp/dist/mcp-server.d.ts +31 -1
  61. package/package/aws-client-agent-mcp/dist/mcp-server.js +16 -16
  62. package/package/aws-client-agent-mcp/dist/mcp-tools.d.ts +23 -1
  63. package/package/aws-client-agent-mcp/dist/mcp-tools.js +35 -19
  64. package/package/aws-client-agent-mcp/dist/message-buffer.d.ts +10 -0
  65. package/package/aws-client-agent-mcp/dist/message-buffer.js +1 -1
  66. package/package/aws-client-agent-mcp/dist/status-reporter.js +1 -1
  67. package/package/aws-client-agent-mcp/dist/tool-groups.js +2 -2
  68. package/package/aws-client-agent-mcp/dist/types.d.ts +84 -6
  69. package/package/aws-client-agent-mcp/package.json +53 -53
  70. package/package.json +134 -132
  71. /package/package/acode/dist/grammars/{grammars/tree-sitter-bash.wasm → tree-sitter-bash.wasm} +0 -0
  72. /package/package/acode/dist/grammars/{grammars/tree-sitter-c-sharp.wasm → tree-sitter-c-sharp.wasm} +0 -0
  73. /package/package/acode/dist/grammars/{grammars/tree-sitter-c.wasm → tree-sitter-c.wasm} +0 -0
  74. /package/package/acode/dist/grammars/{grammars/tree-sitter-cpp.wasm → tree-sitter-cpp.wasm} +0 -0
  75. /package/package/acode/dist/grammars/{grammars/tree-sitter-go.wasm → tree-sitter-go.wasm} +0 -0
  76. /package/package/acode/dist/grammars/{grammars/tree-sitter-java.wasm → tree-sitter-java.wasm} +0 -0
  77. /package/package/acode/dist/grammars/{grammars/tree-sitter-javascript.wasm → tree-sitter-javascript.wasm} +0 -0
  78. /package/package/acode/dist/grammars/{grammars/tree-sitter-jsx.wasm → tree-sitter-jsx.wasm} +0 -0
  79. /package/package/acode/dist/grammars/{grammars/tree-sitter-lua.wasm → tree-sitter-lua.wasm} +0 -0
  80. /package/package/acode/dist/grammars/{grammars/tree-sitter-php.wasm → tree-sitter-php.wasm} +0 -0
  81. /package/package/acode/dist/grammars/{grammars/tree-sitter-python.wasm → tree-sitter-python.wasm} +0 -0
  82. /package/package/acode/dist/grammars/{grammars/tree-sitter-ruby.wasm → tree-sitter-ruby.wasm} +0 -0
  83. /package/package/acode/dist/grammars/{grammars/tree-sitter-rust.wasm → tree-sitter-rust.wasm} +0 -0
  84. /package/package/acode/dist/grammars/{grammars/tree-sitter-tsx.wasm → tree-sitter-tsx.wasm} +0 -0
  85. /package/package/acode/dist/grammars/{grammars/tree-sitter-typescript.wasm → tree-sitter-typescript.wasm} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,1640 +1,1767 @@
1
- # Changelog
2
-
3
- 本文件记录 aws-runtime-bridge 各版本的发布说明,随 npm 包一并分发(package.json
4
- files 白名单),供调度中心「查看本次更新内容」弹窗按 `## v<version>` 精确切片
5
- 展示。发布新版本时须在仓库中先写好 `## v<version>` 段(prepack-guard 校验缺段
6
- 即阻断发布);Bridge 自更新成功后的运行时追加仅作为包内缺段时的兜底。
7
-
8
- ## v1.9.185
9
-
10
- _发布日期:2026-11-04_
11
-
12
- ### 修复:已配对机器重启不再自毁配对(面板实例消失的根因)
13
-
14
- 已配对机器(machineToken 自持凭据)优雅关闭时曾无条件调用 `/api/instances/unregister`
15
- 注销实例,而 server 端该路径会整行删除登记行——`machineToken` 的 hash 就存在这一行上,
16
- 行被删掉配对即被永久摧毁:重启后机器凭据注册被拒(invalid or revoked),面板上的实例
17
- 也随之消失。本次两端同修:
18
-
19
- - Bridge:注销时识别机器凭据目标(machineToken / credentialType=MACHINE_TOKEN),
20
- **跳过自删登记行**——配对身份必须跨重启存活;Agent 离线由隧道断开与服务端重启同步兜底,
21
- 真正下线机器请用管理页删除(Bearer 路径,带租户/负责人校验);
22
- - Server:runtime token 自注销路径拒绝删除 MACHINE_TOKEN 行并返回明确错误
23
- (兼容尚未升级的旧版 bridge,防止其重启时再毁配对);token 无效时不提前泄露
24
- 实例的存在性与凭据类型,仍按既有路径走登录态校验。
25
-
26
- ### 修复:票据里填写的实例名写回不再被旧主机名顶掉
27
-
28
- server 配对响应的实例名以票据建议名为权威,但 bridge 写回配置用的是
29
- `target.instanceName = target.instanceName || instanceName`——本机已有同址旧 target
30
- (instanceName 为历史主机名,如此前用 API Key 注册过)时票据名永远写不进本地配置;
31
- 下次注册(配对后立即重注册或重启)机器上报旧主机名,server 又按请求名覆盖登记行,
32
- 用户在票据里填写的实例名就丢了。本次改为**无条件写回 server 响应名**,票据名在
33
- 本地配置与面板登记行之间保持一致。
34
-
35
- ## v1.9.184
36
-
37
- _发布日期:2026-11-03_
38
-
39
- ### 调整:后台命令上限 20 个,满额报错可操作并回显剩余名额
40
-
41
- 后台命令名额此前只有 16 个,且满额报错只有一句「Kill or wait」——agent 不知道还剩多少名额,
42
- 也不知道怎么腾位,本地命令通道因此被整段卡死(只能干等保留期过期)。本次把名额管理做成
43
- 可见、可操作:
44
-
45
- - 单 agent 后台命令上限 16 → 20(运行中与 5 分钟保留期内已完成的命令都占名额);
46
- - 满额时新命令明确失败(status=not_executed,不自动杀任务):报错带 `20/20 slots in use`
47
- 实况与 `kill_background_command` 腾位指引,agent 按指引停止现有命令后重试即可继续;
48
- - `kill_background_command` 停止/清理命令**立即释放名额**(此前须等 5 分钟保留期淘汰),
49
- 「停止现有后台命令来执行新的」当场兑现;对已终态条目即清理占位,终态与输出不改写;
50
- 重复停止同一条目经磁盘记录幂等返回,「重置状态」重试不报错;
51
- - 每次 Bash 命令结果新增 `remainingBackgroundCommandSlots` / `backgroundCommandLimit`
52
- (当前可执行的后台命令数),agent 随时可见剩余名额,提前腾位不再盲跑撞墙。
53
-
54
- ### 修复:休眠唤醒在时间线上始终有「休眠恢复」凭证
55
-
56
- 唤醒时按进度摘要接续上下文的三条路径此前在时间线上完全无卡片——`importTranscript`
57
- 重放失败(降级摘要通道)、旧构建 runtime 不支持重放、休眠时仅存下摘要(无完整记录)。
58
- 用户无法区分「唤醒了」和「全新启动」。本次适配层在带休眠上下文启动但正常重放卡片
59
- 未发出时,自动补发一条「休眠恢复」兜底卡片(`transcript-replay-fallback-*`),
60
- 文案按实际通道区分「重放未完成,已按进度摘要接续」与「已按进度摘要接续」。
61
-
62
- ### 修复:机器级操作伪 agent 归属未登记时自动自愈,「AI 配置选中后立即回弹」
63
-
64
- `machine-*` 伪 agent(机器级管理操作如应用 AI 配置、工具安装)的目录可能早于多租户
65
- 归属改造创建而没有 owner.json,归属校验 fail-closed 会让这类请求永久 403——前端表现为
66
- 「AI 配置选中后立即回弹为未选择」。本次对**归属从未登记**的 `machine-*` 伪 agent 首次
67
- 触达时按当前权威 scope 自动登记(登记后放行);已登记归属(本人或他人)与真实 agent
68
- 实例不适用自愈,他人实例仍 403,归属变更只能走受信入口。
69
-
70
- ### 修复:插件卸载后不再「复活」,并发部署/移除不再互相覆盖
71
-
72
- 共享插件清单此前是整表读-改-写:卸载写在旧快照上会把遗留层同名条目原样带回(卸载的
73
- 插件下次部署对账时复活),并发部署与卸载互相覆盖丢改动。本次清单写入改为合并视图保真:
74
-
75
- - 卸载在遗留只读层仍登记同名条目时写入**移除墓碑**压制复活,展示/运行时链接/对账
76
- 一律走过滤墓碑后的活动视图;重新部署同名插件时整条替换墓碑自然清除;
77
- - 读-改-写持有 manifest 锁,并发部署/移除串行化,墓碑不再在写回时丢失;
78
- - 部署条目 `zipFile` 缺失时按空串消毒,不再抛异常。
79
-
80
- ### 新增:崩溃自动休眠——运行上下文落盘保护,中断后下次启动自动接续
81
-
82
- 运行中实例崩溃(进程死/机器睡/bridge 被杀)此前上下文全丢——对话只存在进程内存里。
83
- 本次为 acode 实例引入休眠 journal(`~/.acode/hibernation/{agentId}.json`,与待办同区):
84
-
85
- - **运行中节流落盘**:每个 turn 结束(≥10s 间隔)+ 长 turn 期间每 30s 由存活看门狗
86
- 补写一次完整对话与 token 用量;崩溃后磁盘上自然留存最近一次现场(可能丢最近几条);
87
- - **启动自动接续**:启动时若 Java 未下发休眠快照且本机 journal 存在,自动重放上下文,
88
- 并在系统块最后注入中断提示(「遇到中断导致你进入了休眠,部分工作状态可能已经丢失,
89
- 请继续工作!」);时间线先落「休眠唤醒中」卡,重放成功后出现「休眠恢复」卡;
90
- - **干净退出收尾**:正常停止/批量停止/bridge 优雅关闭在终止前做一次 clean 完整落盘
91
- (零丢失);`/runtime/stop` 新增 `discardContext` 参数,true 时删除 journal
92
- (用户显式选择「停止(丢弃上下文)」);journal 默认保留 7 天,启动时清扫超期文件。
93
-
94
- ## v1.9.183
95
-
96
- _发布日期:2026-11-02_
97
-
98
- ### 调整:voice 结果新增 protocol,agent 可感知情绪指令是否真的生效
99
-
100
- 云端 TTS 现支持双 OpenAI 兼容协议:`/audio/speech`(CosyVoice2 等,指令级情绪)与
101
- `/chat/completions`(MiMo 等对话式音频输出,协议限制不支持情绪指令——指令会被当正文
102
- 念出来)。两者的差异 agent 此前无法感知,`voice.emotion` 恒回显请求值,容易误以为
103
- 情绪已经传达。
104
-
105
- - 发送工具结果 `voice` 新增 `protocol` 字段:`speech`(指令级情绪生效)/
106
- `chat`(暂不支持情绪指令)/ `local`(本地兜底,仅语速与停顿);
107
- - `voice` 新增 `emotionApplied`:情绪是否真实作用于本条语音的最终事实
108
- (chat 与 local 为 false);
109
- - `voice.emotion` 参数说明改为按 protocol 区分语义,agent 发送后即可判断
110
- 「这条语音到底有没有带上情绪」;
111
- - 会话 profile 注入全局提示词的语音能力说明由服务端按当前配置实时生成
112
- (协议状态、字数上限、emotion 是否生效),agent 会话创建即知道能力边界,
113
- 不依赖工具描述里的静态说明;配置中途变更由逐条发送结果自我校正;
114
- - 语音消息载荷(`voice.protocol`)同步写入,前端/排查可定位音质来源;
115
- - 协议类型由站点「语音合成」配置显式指定(speech/chat),不再按接口路径猜测。
116
-
117
- ## v1.9.182
118
-
119
- _发布日期:2026-11-01_
120
-
121
- ### 新增:配对成功即生效,无需重启 Bridge
122
-
123
- `awsb pair` 成功写盘后,CLI 会调用本机运行中 Bridge 的回环端点
124
- `POST /runtime/pair-applied`,让它立即用磁盘上的最新配置重新注册并重建隧道。
125
- 此前配对只写盘、长期运行的 Bridge 只在启动时注册,不重启就永远显示「隧道未连接」。
126
-
127
- - 端点只认回环来源(与 `/binding/request-token` 同口径),并做单飞防抖:
128
- 上一轮注册未结束时直接复用,不会并发跑两趟 autoRegister;
129
- - 立即应答、注册在后台进行(含重试可能耗时数秒),面板「等待连接」轮询如实反映结果;
130
- - Bridge 未运行(首次安装尚未启动服务)或是旧版本(404)时通知静默失败,
131
- CLI 回落为原有的 `awsb service restart` 提示。
132
-
133
- ### 修复:transcribe_voice 工具有声明无分发
134
-
135
- `aws-client-agent-mcp` 早已声明 `transcribe_voice` 工具,但 `mcp-server` 的分发
136
- 分支漏接,调用一律落到 Unknown tool。ASR 推理在服务端容器执行,这里补上
137
- `callAgentScopedTool` 转发(自动注入 agentId),agent 侧语音复听/转写校验恢复可用。
138
-
139
- ### 调整:voice.emotion 说明对齐云端指令级情绪
140
-
141
- 工具描述从「只影响语速与句间停顿」改为区分链路:云端合成按自然语言指令真正
142
- 改变语气(开心/兴奋/平静/低落/郑重),本地兜底只有语速与句间停顿。
143
-
144
- ## v1.9.181
145
-
146
- _发布日期:2026-11-01_
147
-
148
- ### 修复:插件等用户路由 403(agent-ownership-mismatch)
149
-
150
- `requireUserScope` 的解析优先级纠正:validateToken 已按凭据
151
- (connectionKey / runtime token)解析出的 `req.userScope` 必须原样保留,
152
- 不再被请求头/体无条件覆盖。此前有两个问题:
153
-
154
- 1. 携带合法凭据、但没带 `X-Tenant-Id` / `X-User-Id` 头的服务端调用
155
- (如调度中心的插件代理)会被降级成 binding.json 的本机用户
156
- `{tenantId:"_local"}`,与实例 owner.json 登记的真实归属永不相等,
157
- `requireAgentOwnership` 一律拒绝——表现为插件面板一打开就报 403。
158
- 2. 更严重的是「凭据决定的权威 scope」可被「请求自称的 scope」替换,
159
- 伪造请求头即可跨 target / 跨租户写入别人的用户命名空间。
160
-
161
- 现在头/体身份仅服务于「无 target 凭据」的本机面板 / MCP 子进程链路,
162
- 凭据解析出的 scope 拥有最高优先级。
163
-
164
- 配套调度中心侧:`PluginProxyController` 发往 bridge 的代理请求补注
165
- `X-Tenant-Id` / `X-User-Id`(按 agent owner,与 RuntimeBridgeService
166
- 同口径),本机面板/子进程链路不再缺身份头;插件面板错误提示优先透出
167
- bridge 返回的真实原因,不再被 "Request failed with status code 403"
168
- 之类的 HTTP 概括语吞掉。
169
-
170
- ## v1.9.180
171
-
172
- _发布日期:2026-11-01_
173
-
174
- ### 功能:累计消耗 token(从 Agent 启动起)全链路
175
-
176
- 此前面板只有「当前上下文」口径的输入/输出 token(覆盖式,压缩/清空会回落),
177
- 没有「从启动到此刻一共烧了多少」的累计口径。本次打通 runtime → adapter →
178
- 调度中心的全链路:
179
-
180
- 1. **acode runtime 累计消耗**:新增 `totalInputTokens` / `totalOutputTokens`
181
- 累计字段(Σ 各次请求 provider 真实上报的 prompt/completion tokens,输入含
182
- 缓存命中),跨迭代、跨 turn 只增不减,压缩/清空不影响;与缓存命中计数同
183
- 口径——只累计真实上报值,文本长度兜底不计入,压缩摘要 LLM 请求(独立
184
- fetch)不计入。`turn_complete` / `iteration_usage` 的 usage 覆盖式携带累计
185
- 快照,前端无需自行累加。
186
- 2. **休眠唤醒跨快照延续**:休眠导出的 tokenUsage 快照(含累计与缓存四字段)
187
- 由调度中心落库,唤醒启动时经 `resumeTokenUsage` 回灌,runtime `start()`
188
- 重建 state 时以 `config.initialTokenUsage` 为累计初值——唤醒后继续累计而非
189
- 清零。普通启动缺省从 0 起;旧快照(无累计字段)按无 seed 处理,不阻断启动。
190
- 3. **adapter / 终端路由透传**:`toUsage` 逐字段解析累计值(独立于 0/0 丢弃与
191
- fallback 判定,不参与文本长度兜底);`totalUsage` 字段级 presence 覆盖
192
- (旧版 runtime 不带累计字段时保留现值,不清零不回落);`resolveStatusChangeUsage`
193
- 在 input/output 为 0(如 seed 后、首个请求前)但累计已有值时也照常传出。
194
- `getTotalUsage`(休眠导出通道)一并带出累计与缓存快照。
195
-
196
- 配套调度中心侧:状态回调透传累计字段、AgentContextPanel 新增「累计消耗」区块、
197
- 休眠快照表补列(cache_hit/miss + total_input/output tokens)。
198
-
199
- ### 修复:唤醒请求的累计 token seed 解析
200
-
201
- `parseResumeTokenUsage`(与 `parseResumeTranscript` 同模式)只接受四个累计字段,
202
- 非法/缺失字段丢弃、全部非法返回 undefined(累计从 0 起,不阻断启动),
203
- JSON 文本异常不会让唤醒流程失败。
204
-
205
- ## v1.9.179
206
-
207
- _发布日期:2026-10-27_
208
-
209
- ### 修复:注册成功后立刻拆掉自己的隧道并退出进程
210
-
211
- 现象:日志依次出现「隧道客户端已启动」→「目标已不在配置中,停止旧隧道」→
212
- 「未捕获异常: {}」→ 优雅关闭 → 注销实例。机器明明注册成功却连不上。
213
-
214
- 三个叠加缺陷:
215
-
216
- 1. **`instanceId` 预声明用了对象展开重绑定**(`config = {...config, instanceId}`)。
217
- `autoRegisterAll` 用同一个 `config` 对象数组构造隧道「保留集」,重绑定后外层
218
- 仍持有旧对象,后续补上的 `credentialId` 传不出去。
219
- 2. **`credentialId` 同样只改了局部变量**。于是一边按 `credentialId` 启动隧道、
220
- 一边按 `userKey 指纹` 计算保留集,键不一致 → 刚建的隧道被判定为「已不在配置
221
- 中」而拆除。两处均改为原地写回。
222
- 3. **`teardownConnection` 先 `removeAllListeners()` 再 `close()`**。对仍在
223
- `CONNECTING` 的 socket 调 `close()`,`ws` 会异步 emit `'error'`
224
- ("WebSocket was closed before the connection was established");此时已无任何
225
- error 监听,EventEmitter 把它抛成未捕获异常 → 进程级 `uncaughtException` →
226
- 整个 bridge 优雅关闭。现在保留一个忽略用的 `error` 监听。
227
-
228
- ### 修复:未捕获异常日志只打印 `{}`
229
-
230
- `Error` 的 `message` / `stack` 是非可枚举属性,`JSON.stringify(error)` 只得到
231
- `"{}"`,此前根本看不出崩溃原因。日志格式化现在显式展开
232
- `name [code]: message` 与 `stack`。
233
-
234
- ### 代码质量:lint 全量清零
235
-
236
- `npm run lint`(`eslint src --max-warnings 0`)从 89 error / 34 warning 降到 0 / 0:
237
- 清理未使用导入与变量、修正 `import/order` 与重复导入;测试文件中的非空断言
238
- (`!`)按惯例在 eslint 配置里对 `**/*.test.ts` 放宽,避免为消除告警引入无意义判空。
239
-
240
- ## v1.9.178
241
-
242
- _发布日期:2026-10-27_
243
-
244
- ### 目标身份升级为 `credentialId`:轮换 Key 不再断链
245
-
246
- 上一版用 `serverUrl + userKey 指纹` 作目标身份,解决了同址多账号并行;但**轮换
247
- API Key 会改变指纹**,导致 runtime token、隧道、注册状态、instanceId 全部重新开始
248
- (表现为换 Key 后 agent 找不到实例)。本版把身份锚点换成服务端下发的稳定凭据 ID:
249
-
250
- - `config.json` 的 target 新增 `credentialId` / `credentialType`,注册成功时由
251
- 服务端回填并持久化(与 instanceId 同一条回写路径)。
252
- - `targetKeyOfConfig` 改为 `buildTargetKey(serverUrl, credentialId ?? userKey)`:
253
- 有 credentialId 时身份不随 Key 变化;旧配置无该字段时仍回退 userKey 指纹,平滑迁移。
254
- - runtime token 存储、隧道槽位、注册重试、instanceId 反查统一用
255
- `identityKeyOfConfig(config)`(credentialId 优先)。
256
- - **删除隧道鉴权的 userKey 兜底**:此前取不到 runtime token 时会把 userKey 当
257
- token 发出去,服务端只认 hash 匹配必然 401,却掩盖了「未注册/注册失败」的真实
258
- 原因。现在明确报错并提示重新注册。
259
-
260
- ### 同一调度中心地址支持多账号/多租户并行注册
261
-
262
- (承接 v1.9.177)身份模型继续保证:同一 `serverUrl` 下不同凭据各自独立隧道、
263
- 独立 runtime token、独立 instanceId,互不覆盖。
264
-
265
- ## v1.9.177
266
-
267
- _发布日期:2026-10-26_
268
-
269
- ### 同一调度中心地址支持多账号/多租户并行注册
270
-
271
- 同一用户加入多个组织(租户)时,同一台机器往往需要连接**同一个调度中心地址**、
272
- 但使用**不同的 API Key** 各自注册一个实例。此前桥内以归一化 `serverUrl` 作为唯一
273
- 身份键,同址两行会互相覆盖(隧道被拆、runtime token 串用、instanceId 写乱),
274
- 面板因此直接拒绝保存第二行。
275
-
276
- 本次把桥内身份模型从「地址」升级为「目标身份」= `归一化 serverUrl + userKey 指纹`:
277
-
278
- - 新增 `utils/target-identity`:`buildTargetKey(serverUrl, userKey)`,形如
279
- `http://host:port#a1b2c3d4`(sha256 前 8 位,不落明文;可读、可作 properties 键)。
280
- 地址归一化(尾斜杠/协议大小写/`ws→http`/`localhost→127.0.0.1`/重复端口)抽到
281
- `utils/scheduler-url`,由 `config`、`runtime-binding`、`target-identity` 共用一份实现。
282
- - **runtime token 存储**:`runtime-tokens.properties` 的键由 `md5(serverUrl)` 改为
283
- 目标身份键,同址多账号各存各的 token。旧键自动兼容读取;未指定 `userKey` 且该地址
284
- 只有一个身份时仍可命中(单目标老调用点无需改动),多身份时必须显式指定,避免串用
285
- 别的账号 token 造成「注册成功但回调 401」。新增 `listScopedRuntimeAccessTokens`。
286
- - **隧道**:`tunnels` Map 改按目标身份键控;同址不同账号各自一条隧道并存。
287
- 新增 `stopTunnelClientForTarget(serverUrl, userKey)` 精确停止单个身份;
288
- `stopTunnelClientsExcept` 改为接收身份键集合;`stopTunnelClientForServer` 保留,
289
- 语义改为「停该地址下所有账号」。
290
- - **注册状态**:`registrationState.registrations` 键改为目标身份键,instanceId 互不覆盖;
291
- 新增 `resolveInstanceIdForTarget`。注销只清理本身份的 token/隧道/记录,其余身份保持注册。
292
- - **instanceId 回写**:只回写与本次注册身份匹配的那一行(此前按地址会把所有同址行写成
293
- 同一个 instanceId)。
294
- - **注册重试**:后台重试定时器按身份键去重,同址两个账号各自独立重试。
295
- - **面板去重规则**:由「同址即重复」改为「同址 + 同一 API Key」才是重复;同址不同 Key
296
- 属合法配置。去重校验移到「继承原配置」之后,因为编辑行留空 userKey 时真实身份要等
297
- 继承完成才确定。
298
- - **面板交互**:列表每行显示 API Key 掩码与租户 ID,便于区分同址多行;编辑行新增
299
- `originalTargetKey` 精确指代被编辑的那一行(同址多行时仅靠地址无法定位),两行都留空
300
- userKey 时按写入顺序逐条认领旧身份继承。
301
- - **目标解析**:`resolveSchedulerBaseUrlFrom` 返回值新增 `userKey`;歧义判定改用
302
- 「目标身份数量」而非「去重后 URL 数量」——否则同址多账号会被误判为单目标而静默选中
303
- 其中一个账号。新增 `resolveTargetIdentityFromToken` 按 token 反查身份(含地址与
304
- userKey),供入站回调确定该用哪个账号的凭据。
305
-
306
- > **兼容**:单地址单账号的既有配置行为不变;旧 token 文件(md5 键)继续可读。
307
- > 无需改动 `config.json`。
308
-
309
- ## v1.9.176
310
-
311
- _发布日期:2026-10-25_
312
-
313
- ### 工作区代码导航:语言服务 + 语法索引兜底
314
-
315
- - `/ws/lsp` 从「仅 TypeScript 单进程」升级为多语言模型:按
316
- `工作区 + provider + clientId` 隔离进程,同一会话内跨文件复用;不同浏览器
317
- 标签/面板使用不同 `clientId`(tsserver、pyright 都不支持多客户端共享文档状态)。
318
- 进程池设并发上限(`AWS_LSP_MAX_PROCESSES`,默认 6)并按最久未用淘汰,断连后
319
- 保活 60s 供快速重连复用。
320
- - 新增 provider 注册表(`services/lsp/provider-registry`),覆盖 15 个语言服务:
321
- TypeScript/JavaScript、Vue、Python、JSON、CSS、HTML、YAML、Bash、Dockerfile、
322
- PHP、Java、Go、Rust、clangd、C#、Ruby。按扩展名推断 provider,统一
323
- `languageId` 归并与启动参数拼装;新增 `services/lsp/uri-rewrite` 处理客户端与
324
- 服务端路径形态差异(Windows 盘符大小写、`file://` 编码)。
325
- - 新增 `GET /runtime/lsp/providers`、`POST .../install`、`POST .../uninstall`、
326
- `GET .../task/:id`、`GET /runtime/lsp/processes`:npm provider 按需安装到
327
- `.aws-bridge/lsp-servers`,安装进度可轮询,进程列表供排障。
328
- - 新增工作区语法索引(`services/workspace-index`):以 tree-sitter 抽取声明与
329
- 导入,覆盖 12 种语言(TypeScript/JavaScript、Python、Go、Rust、Java、C、C++、
330
- Ruby、PHP、Lua、Bash),提供定义/引用/符号/大纲查询。LSP 不可用时前端回退到
331
- 该索引,不因语言服务缺失而失去跳转能力。端点挂在
332
- `/api/workspace-index/{status,build,query,drop}`,索引随工作区切换释放。
333
-
334
- > **兼容**:旧前端只带 `file`/`language`(无 `provider`/`clientId`)时按扩展名
335
- > 推断 provider、`clientId` 视为 `default`,行为与历史版本一致。
336
-
337
- ### 桌面控制人工治理:急停与动作审计
338
-
339
- - 新增 `POST /runtime/desktop-control/:agentId/pause`(急停/恢复)与
340
- `GET .../state`(控制状态 + 最近动作审计)。急停后所有 `desktop_*` 工具
341
- 一律拒绝(含读类),并产生 `rejected` 事件而非静默失败。
342
- - 动作事件流:`desktop_*` 调用映射为 `started`/`done`/`error`/`rejected`
343
- 四态事件,按 agent 维护 100 条环形审计缓冲,经远程桌面 WS 实时推送,
344
- 每个 agent 独立自增 `seq` 供前端排序与去重。
345
- - **坐标陈旧性校验**:截图成功后记录「坐标依据」(截图文件 + 时刻 + 可重放参数);
346
- 带坐标的动作执行前,若依据超过 `AWS_DESKTOP_STALE_WARN_MS`(默认 60s),
347
- 用记忆参数重截一次并做内容比对——画面已变则在结果尾部追加警告(不阻断,
348
- LLM 读到后自行重截),未变则静默刷新依据时刻。5s 内结果缓存,连续动作不重复校验;
349
- sharp 不可用/截屏失败时退化为时间戳警告(安全方向)。
350
- - 状态为进程级内存态:Bridge 重启即自动解除急停(重启本身会终止桌面 MCP,
351
- 等效急停,无需持久化)。
352
-
353
- ### 桌面安装包 sidecar 模式
354
-
355
- - 新增 `AWS_BRIDGE_APP_MODE=desktop` 与 `AWS_BRIDGE_LISTEN_HOST`:桌面态只监听
356
- 回环,不暴露局域网;未显式配置注册地址时默认走隧道(回环地址对外不可达)。
357
- - 端口探测改为「探测形态 = listen 形态」:指定 host 时只探测该 host,避免把
358
- 「别的进程占了通配、但 127.0.0.1 仍可绑定」误判为冲突导致端口无谓顺延。
359
- - 未设置这两个变量时行为与既有一致(通配绑定、服务器部署语义不变)。
360
-
361
- ### Bridge 面板
362
-
363
- - 面板 HTML 拆分为独立模块(`routes/dashboard-theme`、`routes/dashboard-icon`),
364
- 主题令牌与图标不再内联在巨型模板字符串里,便于维护与复用。
365
-
366
- ### 子 Agent 与工具组
367
-
368
- - `SubAgentManager` 等待结果时,store 查询失败不再让该项从结果中静默消失:
369
- 超时后按 `settled` 集合补报未终态项,避免「部分子 agent 结果莫名丢失」。
370
- - 工具组:新增命名分组与 `tools/list` 名称对齐校验(`named-group-tool-names-alignment`),
371
- 防止分组配置与实际暴露的工具名漂移。
372
- - `aws-client-agent-mcp` 补齐邮箱工具组(`send_email`/`list_emails`/`read_email`/
373
- `reply_email`/`ack_email`)与 `list_project_members` 的转发分支,全部经
374
- `callAgentScopedTool` 注入 agentId(防越权)。
375
-
376
- ### 发布链路修复
377
-
378
- - **修复 `npm publish` 被自身守卫误拦**:`verify-dist-minified` 原先用
379
- `code.includes("/**")` 判断「未混淆」。但本仓库把 HTML/CSS/内联脚本放在模板
380
- 字符串里(`DASHBOARD_HTML`、`THEME_CSS`),压缩后字符串内的 `/** ... */`
381
- 会原样保留(那是要发给浏览器的页面源码,不是 JSDoc),导致
382
- `dist/routes/dashboard.js` 被误判并直接阻断发布。
383
- 新增 `scripts/source-comments.mjs`,基于 TypeScript AST + 字面量区间排除
384
- 判定「代码区注释」;`minify-dist.mjs` 的 .d.ts 注释剥离同步切到同一口径,
385
- 避免「剥干净了却仍被判为脏」。守卫对真实未压缩文件仍然拦截(已验证)。
386
-
387
- > **验证**:`npm run typecheck` 与 `npm test` 通过(137 files、1915 passed、
388
- > 3 skipped);`npm pack` 端到端通过(780 files / 6.6MB,postpack 正确还原)。
389
- > 新增/覆盖 `workspace-index`、`provider-registry`、`uri-rewrite`、`lsp`、
390
- > `desktop-control`、`desktop-staleness`、`desktop-mode`、`sub-agent-manager`、
391
- > `named-group-tool-names-alignment`、`mcp-tools` 等用例。
392
-
393
- ## v1.9.175
394
-
395
- _发布日期:2026-10-23_
396
-
397
- ### 技术栈自动识别:扫描工作区生成启动项候选
398
-
399
- - 新增端点 `POST /runtime/tech-stack/scan`(body `{ workspacePath }`):只读扫描
400
- 工作区标记文件,返回可直接创建的启动项候选(名称/类型/命令/工作目录/依据)。
401
- - 识别范围:`pom.xml`/`build.gradle(.kts)`(Spring Boot 走 `spring-boot:run`/`bootRun`,
402
- 有 wrapper 优先 `mvnw`/`gradlew`)、`package.json`(按 `pnpm-lock.yaml`/`yarn.lock`/
403
- `bun.lockb` 推断包管理器,脚本按 dev>develop>serve>start 取)、`manage.py`、
404
- `pyproject.toml`/`requirements.txt`(FastAPI 出 `uvicorn main:app --reload`,
405
- uv/poetry 项目自动加 `uv run`/`poetry run` 前缀)、`go.mod`(根 `main.go` 出
406
- `go run .`,否则展开 `cmd/*/main.go`)、`composer.json`(Laravel `php artisan serve`、
407
- Symfony `php -S localhost:8000 -t public`),以及 `Cargo.toml`/`deno.json`/
408
- `docker-compose.yml` 兜底为 generic。
409
- - 遍历全层级且尊重 `.gitignore`(规则引擎抽到 `services/gitignore.ts`,与文件浏览器
410
- 目录树共用同一实现);依赖/构建/版本库目录(`node_modules`/`target`/`dist`/
411
- `.venv`/`.git` 等)恒跳过。目录预算 4000,超限返回 `truncated` 并保留已识别结果。
412
- - 命中标记文件才读内容,单文件读取上限 64KB;候选 id 为「相对目录+技术栈+命令」
413
- 的稳定哈希,重复扫描结果一致。
414
-
415
- > **验证**:bridge `npm run typecheck` 通过;新增 `tech-stack-scanner.test.ts`
416
- > (16 passed)覆盖 Spring Boot/wrapper 平台分支、Maven 回退、Node 包管理器推断、
417
- > monorepo 子包、Django/FastAPI/uv 前缀、Go 单入口与 `cmd/*` 展开、Laravel/Symfony、
418
- > Cargo 可运行 crate 判定与 lib crate 排除、compose 兜底、.gitignore 排除、
419
- > 同目录多栈、id 稳定性。
420
-
421
- ### Git 提交历史分页与快照保留策略
422
-
423
- - `POST /runtime/git/commits` 支持 `skip`/`limit` 分页:新增 `resolveCommitPageLimit`
424
- / `resolveCommitPageSkip` / `sliceCommitPage`,一次抓取多取一条用于判定 `hasMore`,
425
- 避免整段历史一次性返回;保留不传 `skip` 的旧单页响应形状。
426
- - 全分支图按 `--branches --remotes --tags` 收敛引用范围,内部引用(如 cline
427
- checkpoint)不再混入提交图;detached HEAD 通过显式 revision 保留。
428
- - 新增工作区快照保留策略(`snapshot-retention`):默认不清理,面板下发保留天数后
429
- 按 mtime 删除过期快照;与 change-cache 复用同一节流(写缓存时 1h + 24h 兜底扫描),
430
- 配置变更立即执行一次。面板显式下发的值不会被迟到的 `config.json` 覆盖。
431
-
432
- ### 终端与隧道稳定性
433
-
434
- - 隧道请求体分帧:请求体超过单帧上限(2MB WS 文本帧)时,server 改为 `req` 头帧
435
- + `reqchunk` 数据帧 + `reqend` 收尾,bridge 侧按 id 归集拼装后转发本地服务;
436
- 半包请求带 5 分钟空闲超时,连接断开时清理残留缓冲。
437
- - 终端 SDK 作答/取消:新增取消作答链路(含可选原因),与回答共用幂等与回执;
438
- `compaction_summary` 走独立推送通道,不进 `sdkOutputQueueBySession` 串行队列,
439
- 摘要流与主输出流互不阻塞。
440
- - 修复时间线重复卡片:仅刷新用量的 `status-change`(`iteration_usage` 等)不再
441
- 重放上一次 `ai_request` 动作;抽为 `isUsageOnlyStatusChange` 便于单测覆盖。
442
- - 终端「等待输入」判定抽到 `lastOutputLine` + `listWaitingForInput`:只取输出末行
443
- 做启发式匹配,纯读不消费输出游标,供压缩后重建资源快照给出「哪些终端卡在提示符上」。
444
-
445
- ### Bridge 面板
446
-
447
- - 仪表盘时间统一按面板当前语言(中/英)与浏览器本地时区渲染,修复切换语言后
448
- 日期仍按系统语言、以及直接切 ISO 字符串导致显示 UTC 挂钟值的问题。
449
- - 自更新前增加确认弹窗,明确「更新会重启 Bridge、运行中的实例会停止、进行中的
450
- 任务会中断」。
451
-
452
- > **验证**:`npm run typecheck` 与 `npm test` 通过(130 files、1827 passed、
453
- > 6 skipped);`git-commits-page.test.ts`(4 passed)、`tech-stack.test.ts`、
454
- > `snapshot-retention.test.ts`、`tunnel-client.test.ts`、`terminal.sdk-answer.test.ts`
455
- > 均通过。
456
-
457
- ## v1.9.174
458
-
459
- _发布日期:2026-10-21_
460
-
461
- ### 私信附件「存到对方机器」:bridge 临时文件通道
462
-
463
- - 新增 bridge 临时文件通道:上传的文件直接落到**接收方实例所在机器**的
464
- `<系统临时目录>/aw-temp/ATT/YYYYMMDD/{uuid}{扩展名}`,服务端不落盘,
465
- 按天归档并在写入时顺带清理超过 7 天的旧目录。
466
- - 新增端点:`POST /api/bridge-temp-files/upload`(multipart 上传)、
467
- `POST /api/bridge-temp-files/read`(按绝对路径读回字节)、
468
- `POST /api/bridge-temp-files/delete`(删除临时文件)。
469
- - 落盘文件名用 uuid 而非原始文件名(原始名只回传展示,规避文件名注入);
470
- 扩展名由原始名清洗而来,保留原扩展名便于 agent 判断读取方式。
471
- - 回传路径统一为正斜杠:Windows 的 `path.resolve` 接受正斜杠,跨平台一致,
472
- 且正文标记进 JSON 载荷时不会被反斜杠转义弄乱。
473
- - 修正 multipart 文件名在部分代理链路被 latin1 解读导致的中文乱码
474
- (与工作区上传同一口径)。
475
- - 读/删接口做路径越界校验:只允许访问 `aw-temp/ATT` 目录树内的文件,
476
- 越界与不存在统一返回 404,不向调用方泄露目录结构。
477
- - 上传超限(>512MB)返回 413 与明确错误码,不落成 HTML 500。
478
-
479
- > **验证**:bridge `npm run typecheck` 通过;新增 `bridge-temp-files.test.ts`
480
- > (10 passed)覆盖上传落盘/扩展名保留/读回/越界 404/删除/正斜杠跨平台往返。
481
- ## v1.9.173
482
-
483
- _发布日期:2026-10-21_
484
-
485
- ### 上下文压缩后补齐「运行时资源事实」,修复命令失忆
486
-
487
- - 压缩后重建的运行时资源快照新增「当前打开的文档」一类:画布(pencil)、
488
- 绘图(draw)、Office 文档各自登记**面板当前开着的那一份**。此前快照只列
489
- 「存在哪些文档」,压缩后 agent 不知道用户正看着哪份文档,容易重复 open
490
- 或对着已被取代的版本继续改。
491
- - 打开状态由 bridge 侧按 agentId 维护(`open-doc-registry`):依据工具调用流
492
- 登记 / 清除,随会话结束清理;识别直调与收纳态 `call_tool` 中转两种形态。
493
- - 终端快照补「waiting for input」状态:停在 ssh 密码提示等交互提示上的会话
494
- 单独标出(判定只取输出末行,历史输出里的旧提示符不误判)。
495
- - 浏览器条目补 `browserId`:同 agent 可有多个独立 chromium 实例,缺 id 时
496
- agent 无法分辨「已开的那一个」。
497
- - 修复两条漏掉重建快照的路径:`resetContext`(对话还原到启动基线但真实资源
498
- 并未消失)与休眠恢复 `importTranscript`(预压缩同样会丢弃资源事实)。
499
-
500
- - 修复「面板事件顺序与真实运行态相悖」:LLM 同一轮声明 `poll_message` + 兄弟工具
501
- (如 `get_profile`)时,`call_tool` 事件原在**准备阶段**按声明序发出,但 blocking
502
- 工具会被调度器排到**批尾串行**执行 —— 于是 poll_message 的「调用中」卡片先落库、
503
- 实际先跑完的兄弟工具后落库,面板最后一条停在 `get_profile`,而 agent 正阻塞在
504
- poll_message。现改为「工具真正开始执行时」才发 `call_tool`,事件顺序即真实执行顺序。
505
- - poll_message 阻塞期间新增**面板事件矫正**:以 runtime 内部的阻塞型调用计数
506
- (`hasActiveBlockingToolCall`,经 bridge `GET /runtime/sessions/:agentId/current-action`
507
- 暴露)为权威判据。该判据是运行时事实、不经事件流派生,故不会被兄弟工具的完成
508
- 事件覆盖;发现权威状态与本地 tag 不一致时补发一次 poll_message 事件矫正面板,
509
- 并保留 30s 冷却避免刷屏。无法判定(查不到会话/查询失败/无阻塞调用在飞)时一律
510
- 不矫正,宁可保持现状也不凭猜测改写面板。
511
-
512
- > **验证**:bridge `npm run typecheck` 与 `npm test` 通过(123 files、
513
- > 1775 passed、2 skipped);`package/acode` legacy 套件 175 passed / 0 failed、
514
- > vitest 828 passed。事件顺序修复另行验证:`package/acode` 新增
515
- > `call-tool-event-order.test.ts`(3 passed)、`aws-client-agent-mcp` 新增
516
- > 面板矫正用例(mcp-server 162 passed / 0 failed)、bridge `npm test`
517
- > 1775 passed / 0 failed。
518
-
519
- ## v1.9.172
520
-
521
- _发布日期:2026-10-21_
522
-
523
- ### 上下文压缩重构、提问取消作答与消息中心体验收敛
524
-
525
- - ACode 上下文压缩改为「高保真级联」统一策略(完整摘要 → 降级 → 截断),不再由
526
- 前端勾选压缩类别;移除 `compaction-preview` 与「先行压缩」配置弹窗,输入区入口
527
- 直接启用开关,压缩范围由运行时决定。
528
- - 压缩摘要改为流式上报:runtime 逐 chunk 发射 `compaction_summary`,bridge 按
529
- 120 字符 / 120ms 积攒后推送,时间线实时滚动展示;摘要正文不落库(bridge 本地
530
- 环 Buffer、per-agent 事件存储、Java 事件表与运行日志全部跳过),刷新后不复活。
531
- - 修复压缩摘要与思考卡片互相打断、摘要尾部落到压缩结束事件之后、长摘要不跟随
532
- 滚动的问题;压缩摘要使用独立琥珀色卡片样式。
533
- - 修复 token 用量显示:启动/恢复/压缩后的估算值与 provider 真实值用
534
- `usageEstimated` 显式区分,真实 usage 变小时不再被 20% 启发式误判为 fallback;
535
- provider 未上报 input tokens 时不再把上下文清零。
536
- - 修复时间线重复卡片:`iteration_usage` 等 usage-only 状态变更不再重放上一次
537
- `ai_request` 动作;工具结果先于调用到达时不再覆盖已完成的同名工具卡片。
538
- - 支持「取消作答」:提问卡片新增取消入口与可选原因,Java / bridge / ACODE runtime
539
- 全链路解除 Agent 阻塞并把取消结果回传模型;回答与取消共用幂等与回执持久化,
540
- 刷新后展示「已取消」只读态。
541
- - `read_file` 图片 URL 读取:以魔数为权威格式判据(签名 URL 的
542
- `application/octet-stream` 不再被误拒),发送最小浏览器请求头规避图床 403/406,
543
- URL 只保留 origin+path 写调试日志;运行时提示明确「URL 直接读,不要先 curl 落盘」。
544
- - dashboard:消息通知弹层新增提示音开关(Web Audio 合成、首次手势解锁、静音持久化);
545
- 桌面通知权限入口移至消息通知弹层;移动端弹框最小化新增「飞向收纳按钮」动画;
546
- 普通终端打开期间按钮转圈防重复点击;长文本粘贴统一转为 txt 附件;文件引用图标与
547
- 工作区文件树同源;引用图标视觉修正。
548
- - 邮件:新增 `imapInternalHost` / `smtpInternalHost` 等后端内网连接地址(留空回退
549
- 客户端展示地址),配置自检展示实际生效地址;compose 为 James 增加
550
- `mail.<mailDomain>` 网络别名,避免容器经公网/NAT 回环;邮箱别名改用 James
551
- typed alias 路由 `/address/aliases/{目标}/sources/{别名}`,修复旧路由稳定 404。
552
- - 消息协作:`send_dm` 的 `replyToCallId` 未命中调用式消息时降级为普通私信并回传
553
- warning(不再静默丢内容);自动关联 pending call 失败时同样降级发送。
554
- - 修复 `sendOutput` 在 `skipLocalPersist` 路径于 `finally` 中 `return` 吞掉异常,
555
- 导致上层重试队列收不到失败信号的问题。
556
- - 内置 `db_connect_client_mcp` 源码随仓库提交(能力市场包仍以 esbuild 单文件
557
- bundle 发布)。
558
-
559
- > **验证**:bridge `npm run typecheck`、`npm test`(121 files、1747 passed、
560
- > 2 skipped)与 `package/acode`(827 passed)、`package/aws-client-agent-mcp`
561
- > (561 passed)测试通过;Java `mvn test`(2057 passed)通过;dashboard
562
- > `npm run lint`、`npm run type-check` 与全部 `test:*` 脚本通过。
563
-
564
- ## v1.9.171
565
-
566
- _发布日期:2026-10-20_
567
-
568
- ### 消息协作、邮箱别名、同事观察与日志治理
569
-
570
- - 消息中心:发送改为乐观上屏(本地「发送中」→ 服务端 `sent`),网络/5xx/429
571
- 自动退避重试 3 次,失败气泡保留并支持「重试 / 编辑」;WS 回显按发送者+正文+
572
- 时间窗认领本地待发气泡;私信/群聊发送携带客户端幂等键,服务端按
573
- `(sender, clientMessageId)` 去重,HTTP 响应丢失后的自动重试不会产生重复消息。
574
- - 群聊支持 @所有人(后端展开为房间/项目实际成员,提及记录与未读口径一致)、
575
- 结构化引用提醒(回表校验被引用消息作者,拒绝客户端伪造 `senderId`),并补充
576
- 引用提醒系统通知。
577
- - 新增角色实例邮箱「人类只读查看」(收件箱 / 已发送 / 详情,不改变 IMAP 已读
578
- 状态)与邮箱别名设置;别名更新改为「先建新远端映射、再删旧映射」,任一步失败
579
- 不会让旧别名提前失效,失败时补偿恢复远端状态。
580
- - 同事协作:`get_colleague` 增加在线状态、当前动作、工作区路径与邮箱概要;
581
- 新增 `list_colleague_events` 分页查看同事行为时间线(摘要视图,剥离工具输入/
582
- 结果原文),由 `collaboration.agentObserve` 能力开关控制(默认收纳)。
583
- - ACode 收口:AI 配置 / MCP 模板 / 终端 CLI 仅保留 ACode,移除 ClaudeCode、
584
- Codex、OpenCode 的配置入口与文案。
585
- - 修复:`RuntimeBridgeService` / `RuntimeGlobalSettingsService` 保存 MCP 时补回
586
- `instantiate` / `packageUrl` / `packageSha256` 字段,避免包型 MCP 初始化丢失。
587
- - 修复:清空角色实例邮箱别名改为显式 `SET address_alias = NULL`(MyBatis-Plus
588
- `updateById` 会忽略 null 字段);恢复心跳超时后的 Agent 异常离线告警。
589
- - bridge 日志治理:新增统一日志保留策略(lifecycle、MCP 子进程、AI 配置调试
590
- 日志,最长保留 7 天),启动即清理 + 每 6h 周期清理,面板下发值夹取到 1..7 天;
591
- Java Debug 日志清理同步收敛为最长 7 天。
592
- - bridge 启动记忆加载抽为独立服务并复用;provider 请求体非法(确定性 4xx)时
593
- 落盘完整对话上下文快照(去重 + 保留最近 20 份),便于事后复现工具调用配对问题。
594
- - dashboard 接入标签页未读标题 / PWA 应用角标;页面隐藏时按私信、群聊 @、系统
595
- 通知弹桌面通知(同会话 4s 合并、点击跳转会话),权限申请放在个人菜单。
596
-
597
- > **验证**:bridge `npm run typecheck` 与 `npm test` 通过
598
- > (120 files、1724 passed、2 skipped);Java `mvn -q test` 通过;
599
- > dashboard `npm run lint`、`npm run type-check` 与 99 个 `test:*` 脚本
600
- > 全部通过。
601
-
602
- ## v1.9.170
603
-
604
- _发布日期:2026-10-17_
605
-
606
- ### 能力市场与插件运行时落地,并发一致性与调试挂载修复
607
-
608
- - 新增能力市场:Java 侧 `AbilityMarketService` / `AbilityMarketController` 提供
609
- 模板上架、安装、卸载与“我的能力”清单,安装态以 `RuntimeGlobalSettings`
610
- 全局设置持久化;bridge 侧配套能力市场工具与 MCP 包探测、部署链路
611
- (`mcp-package.ts`、`mcp-probe-client.ts`、`ability-market-tools.ts`)。
612
- - bridge 插件体系重构为 manifest / loader / runtime / listener-runner 分层,
613
- 统一插件清单校验、持久化目录部署与监听器生命周期,并补充插件开发指南与
614
- 插件系统设计文档。
615
- - dashboard 新增能力市场管理页与安装弹窗(含环境变量占位符校验)、Agent 状态
616
- 重置与上下文压缩弹窗,会话操作菜单抽取为 `chat-message-actions`。
617
- - 新增调试挂载(debug-mount)能力:会话建立时按需挂载调试资源,会话销毁
618
- (含 SDK 会话清理各出口)统一调用 `clearDebugMounts`,避免残留。
619
- - 修复:`AbilityMarketService` 安装 / 卸载回滚快照在同一写锁内捕获,消除并发
620
- 写下的回滚竞态;`mcp-deploy` 增加名称合法性校验(拒绝 `.`、`..` 与非 basename)
621
- 并改用原子 rename 交换,清单 `fileName` 以实际下载文件名为准。
622
- - 修复:插件部署仅在全部候选迁移成功时才清理旧 `shared/` 目录,legacy
623
- `zipFile` 经 `sanitizeArchiveFileName` 收敛,重命名失败不再误删目标目录;
624
- 插件处理器在启用 shell 且命令含 `{{...}}` 插值时改为 fail-closed 拒绝执行。
625
- - 修复:`package/acode` 运行时 `removeMcpServer` 同步清理 stderr 缓冲;手动
626
- compact 优先级高于自动 `shouldCompact`,避免手动压缩计划被丢弃。
627
-
628
- > **验证**:bridge `tsc --noEmit` 与 `vitest run` 通过(1687 passed;仅
629
- > `src/browser/page-listener-nav.smoke.test.ts` 偶发 hook 超时,重跑通过,该目录
630
- > 未改动);`package/acode` `tsc --noEmit`、`runtime.test.ts` 与 `compaction.test.ts`
631
- > 通过;Java `mvn compile` 通过,`AbilityMarketServiceTest`(31)、
632
- > `RuntimeBridgeServiceTest`(79)通过;dashboard `npm run lint`、`npm run type-check`
633
- > 以及 i18n / ability-market / dialogQueue 相关测试通过。
634
-
635
- ## v1.9.169
636
-
637
- _发布日期:2026-10-12_
638
-
639
- ### 多语言与消息协作增强,环境变量、邮箱与流程线能力整合
640
-
641
- - dashboard 接入 `vue-i18n`,提供简体中文与英文的自动识别、持久化、运行期切换
642
- 和 Element Plus 文案联动,并补充完整开发指南与语言资源测试。
643
- - 消息中心补齐消息复制、引用流、附件下载与反馈队列体验;能力范围、时间线顺序、
644
- 浏览器面板适配和会话分组等交互稳定性同步收敛。
645
- - dashboard 侧接通项目 / 角色 / Agent 三层环境变量配置、能力开关与邮箱管理界面,
646
- 并补充项目关系图导入、流程线交付物下载 / 回放 / 指派标签等能力。
647
- - bridge 启动测试统一跨平台命令进程 PID mock 输出,稳定 Linux CI 端口探测时序,
648
- 避免发布流水线因平台差异产生偶发失败。
649
- - 更新 Docker Compose 与邮箱部署、跨项目角色冲突、环境变量分层等文档。
650
-
651
- > **验证**:dashboard `npm run lint`、`npm run type-check` 与 `npm run build` 通过;
652
- > dashboard 新增 34 个测试脚本全部通过;bridge `npm test` 通过
653
- > (114 files、1621 passed、2 skipped)。
654
-
655
- ## v1.9.168
656
-
657
- _发布日期:2026-10-11_
658
-
659
- ### 发版稳定性:测试兼容、任务通知与连接生命周期修复
660
-
661
- 本版本主要为发版验证中暴露的兼容性与稳定性问题收敛,既有功能契约保持不变:
662
-
663
- - `aws-client-agent-mcp` 的 `initialize` 返回完整工具组清单,能力开关三态
664
- (`disabled` / `collapsed` / `expanded`)契约与 Java 侧保持一致。
665
- - `pipeline_task_assigned` 的 `SYSTEM_NOTIFY` 与持久化任务通知增加强制任务域
666
- hydrate,首次落空时自动重试,避免重启或长轮询窗口内遗漏流程任务。
667
- - `.agentswork` 记忆目录搜索增加项目根与 Git 仓库边界,避免相邻项目目录串用;
668
- `MemoryStore` 增加 domain 写入缓存,修复大量 domain 场景测试超时。
669
- - WebSocket 手动断开与异步 token 刷新重连之间的竞态修复,断开后不再重新排程
670
- 重连,非 CLOSED 连接句柄会被终止。
671
- - `RuntimeBridgeService` 的 SSE 客户端改为首次使用时初始化;同步迁移版本数、
672
- `reply_to` 测试 schema 与 Direct/Group Message 控制器测试签名。
673
- - 测试命令增加 Node 测试进程强制退出兼容项,确保 CI 收尾不被子进程管道句柄
674
- 阻塞。
675
- - 修复 Linux CI 启动项端口探测用例的 shell PID / 命令进程 PID 替换竞态,
676
- 避免发布流水线因平台进程发现时序产生偶发失败。
677
-
678
- > **验证**:Java 后端 `mvn test`(1873 tests)、bridge 根目录测试、ACode 测试与
679
- > `aws-client-agent-mcp` 测试全部通过;`npm run build:all`、`npm run build`
680
- > 和 `npm run typecheck` 均通过。
681
-
682
- ## v1.9.167
683
-
684
- _发布日期:2026-10-07_
685
-
686
- ### Word 格式管控:OOXML 版式底座 + 信任机制(自动备份 / 保护区域 / 报告聚合)
687
-
688
- 面向「生成复杂排版文档并严格把控」这一目标,分两条线补强 office 工具链。
689
- Java 侧新增 3 个 OOXML 助手并扩展 5 个,bridge 侧补齐备份、参数透传与工具契约。
690
-
691
- #### 1. 写盘前自动备份(改坏了能回滚)
692
-
693
- `office_edit` / `office_format(fix)` / `office_apply_profile` / `office_generate_from_template`
694
- 直接改写用户文档,此前改错只能靠事先手动 copy。现在覆盖写盘前自动留一份
695
- `<基名>-backup-<时间戳><扩展名>`,滚动保留最近 5 份;回执透出 `backupPath` + `backupHint`。
696
- **另存到已有文件**同样先备份(等价于覆盖)。备份失败不阻断写盘(磁盘满/权限异常时
697
- 不带该字段);只清理严格匹配时间戳命名的文件,不会误删 `报告-backup-未命名.docx` 这类同名文件。
698
-
699
- #### 2. 保护区域:封面/题注/代码块不被正文规则触碰
700
-
701
- 规则新增 `exclude`(支持 `/body/p[1]-p[14]` 区间简写与 `{path/from/to/style/contains/role}` 对象)
702
- 与 `excludeByRole`,**check 与 fix 同源生效**。`summary.excludedParagraphs` 透出命中段数。
703
- `office_format` 另提供顶层 `exclude` 便捷入口(preset 场景下也能一次排除封面);
704
- 实现上复制 rules 再写入,不原地修改 preset 共享实例(否则会污染后续所有调用)。
705
-
706
- #### 3. 三套规则系统打通:profile 可直接当 rules
707
-
708
- `office_view(mode=profile)` 的产物此前**无法**直接喂给 `office_format`——启发式识别出的
709
- 角色其 `match` 为空对象,`RoleMatcher.matches()` 恒为 false 且不回落到内置判定。
710
- 现空 `match` 回落内置启发式,并新增 `unmatchedRoles`/`unmatchedRolesHint` 显式报出
711
- 「既无 match 又非内置角色名」的规则(此前这类规则静默失效,是「配了规则却没反应」的根因)。
712
- 推荐链路:模板 `view(profile)` → `office_format(rules=profile, exclude=[封面范围], action=check)` → `action=fix`。
713
-
714
- #### 4. 报告可读性:106 条平铺 → 可定位
715
-
716
- - 每条违规新增 `textDigest`(段落文字摘要),不必再按 path 反查原文;
717
- - `summary.byRole`(按角色聚合降序)、`summary.paragraphs`(按段落聚合,含该段问题属性列表)、
718
- `summary.topIssue`(一句话摘要)。
719
- - 阅读顺序:`topIssue` → `byRole` → `paragraphs` → 需要细节时再读 `violations`。
720
-
721
- #### 5. `office_format(action=dryRun)` 与 `office_view(paths=[...])`
722
-
723
- - **dryRun**:按 fix 逻辑算出将改哪些项,返回 `willModify` + `nextStep`,不写盘、不返回字节
724
- (bridge 侧即使服务端意外带回字节也直接丢弃)。注意 dryRun **不产生 `converged`**——
725
- 未真正修正就不能声称收敛。
726
- - **paths**:段落白名单(`/body/p[7]`、区间 `/body/p[5]-p[11]`),仅对 `styles`/`profile`/`selfcheck`
727
- 生效。大文档(几百段)下排查局部时把返回量从整篇压到几段。`profile` 的 `page`/`numbering`
728
- 来自文档级部件仍按整篇提取;`selfcheck` 的 `pageNo` 仍为真实页码。无法解析的 `paths`
729
- 一律回退为「不过滤」,避免空结果误导。
730
-
731
- #### 6. OOXML 版式能力补齐 + 4 个 P0 缺陷修复
732
-
733
- 新增 `DocxLayoutOps`(分栏/页码分区/文档网格/titlePg/分页控制/中文排版开关/动态版心宽)、
734
- `DocxRunFormatExtras`(双删除线/小型大写/字符缩放/复杂文种字号/字体 hint)、
735
- `DocxFootnoteOps`(脚注尾注);扩展 `DocxStyleOps`(样式创建**与改写**、字符样式)、
736
- `DocxNumberingOps`(多级编号/样式绑定/一键编号)、`DocxTableOps`(行高/cantSplit/表格布局/边框)、
737
- `DocxPaths`(`/body/table[T]/row[R]`、`/body/style[ID]`)。
738
-
739
- 修复的 P0:
740
-
741
- | 缺陷 | 影响 | 修复 |
742
- |---|---|---|
743
- | `pageBreakBefore` 进规则但不被下游识别 | 标记 `fixable=true` 却写不进去 → **check 永不收敛** | `applyParagraphExtras` 委托 `DocxLayoutOps.applyParagraphLayout` |
744
- | `applyProfile` 编号硬编码 `numId=2` | 文档已占用 numId=2 时挂错编号定义 | 改用 `createStyleBoundHeadingNumbering` 返回值 |
745
- | bridge 从不读 `outputFile` | 描述承诺「标注版不覆盖原件」落空 | 接上 `outputFile`,缺省自动派生 `<原名>-标注版.docx` |
746
- | `fontSize` 走 `intProp` + `setFontSize(int)` | **10.5pt 被截断为 10pt**(论文图题/表题标准字号) | 按双精度写 `w:sz`+`w:szCs`(半磅精度) |
747
-
748
- 另:`keywordCount`/`refCount` 角色级聚合断言从「只在描述里」补成真实实现
749
- (此前按描述配置会静默零违规);selfcheck 分页识别补齐「显式分页符 + 段前分页 + 分节符」并修正
750
- **文本归属页**(段前分页段的文本此前被算进上一页);标题级别判定兼容中文样式名「标题 N」与纯 `outlineLvl`。
751
-
752
- #### 7. 颜色值序列化:`STHexColor` 联合类型陷阱
753
-
754
- `w:color/@w:val` 的类型是 XMLBeans **联合类型** `STHexColor`——RGB 分支存 3 字节 `byte[]`,
755
- 另一分支存字符串 `"auto"`,因此 `CTColor.getVal()` 返回 `Object`。
756
- `DocxStyleResolver` 直接 `String.valueOf(getVal())`,RGB 被渲染成 `[B@74a239d7`。
757
-
758
- **不只是显示乱码**:`OfficeRuleEngine.compareColor` 拿这个值跟期望值比对,
759
- 任何带 `color` 期望的规则**都不可能收敛**(fix 写完复检仍报违规,`converged` 永远 false)。
760
- 读取改走 `xgetVal().getStringValue()`(两类分支都正确),字节分支兜底手写十六进制。
761
-
762
- 同根因的写入侧缺陷:颜色归一化一律 `toUpperCase()`,把合法的 `auto` 变成非法的 `AUTO`,
763
- 被 XMLBeans 以「union value 'AUTO' does not match any members」拒绝
764
- (传 `color="auto"` 清色直接报错)。归一化统一收敛到 `OfficeArgs.normalizeColor` 单点权威
765
- (命名色表 + `auto` 保留小写),`OfficeDocService` 与 `OfficeRuleEngine` 都委托它;
766
- xlsx/pptx 无 `auto` 概念,走新增的 `rgbColorOf` 显式拒绝并给可读提示。
767
-
768
- 顺带修复 `office_view(outline)` 两处同源缺陷:标题判定只认 `styleId` 以 `heading` 开头
769
- (中文模板「标题 1」与纯 `outlineLvl` 标题全部漏检);表格节点只有行列数,现附加题注文本
770
- (先取表格前一段、再取后一段,按「表 X-Y」文本特征或题注样式判定,都不中则回退)。
771
-
772
- > **升级须知**:本版本无破坏性变更。`office_format` 的 `action` 枚举新增 `dryRun`,
773
- > 旧调用方不受影响;备份文件会在文档同目录产生额外的 `<基名>-backup-*` 文件,
774
- > 若不希望出现在工作区索引中,可在 `.gitignore` 加 `*-backup-????????-??????.*`。
775
-
776
- ## v1.9.166
777
-
778
- _发布日期:2026-10-05_
779
-
780
- ### 修复:submit_task_result 丢参导致循环节点恒被拒绝提交
781
-
782
- `handleSubmitTaskResult` 只向 `agentClient.submitTaskResult` 透传了
783
- `nodeId / outputPayload / changeLog`,而工具 schema 早已声明、服务端也早已消费的
784
- **`handoverNote` 与 `deliverables` 在这一层被静默丢弃**。后果:
785
-
786
- - 位于循环路径(模板 `require_handover=true`)的节点,Agent 即便按描述传入
787
- `handoverNote`,抵达 Java 侧时仍为 null,`validateHandoverNoteIfRequired`
788
- 恒定抛「必须提供交接经验」拒绝提交 —— 表现为「nodeId 能识别、handoverNote 却
789
- 永远缺失」的固定失败,Agent 侧穷尽调用通道与字段命名均无法绕过;
790
- - 结束节点的 `requiredDeliverables` 同理永远收不到交付物,必填项必然判缺。
791
-
792
- 修复内容:
793
-
794
- - **补齐 5 参透传**:`handoverNote`(`getOptionalString`)与 `deliverables` 一并
795
- 下发到 `agentClient.submitTaskResult(nodeId, outputPayload, changeLog,
796
- handoverNote, deliverables)`。
797
- - **新增 `prepareDeliverables`**:逐项归一化交付物,文件类(`path`)复用
798
- `uploadAttachmentFiles` 换取 `url/mediaType/size` 后回传,文本类(`text`)原样
799
- 透传;无 key 项与空数组安全忽略。服务端 `parseDeliverablesArg` 可直接消费。
800
- - **changeLog 放宽形态**:数组(MCP 已解析)与 JSON 字符串两种形态均透传,
801
- 原先只认数组、字符串形态被吞(服务端 `parseChangeLog` 本就两种都支持)。
802
-
803
- ### 错误结构化:errorCode / field 回传给 Agent
804
-
805
- 服务端校验失败原先只回 `{"error":"<纯文本>"}`,Agent 只能从中文长句里猜原因。
806
- 现新增 `McpToolError`(携带 `errorCode` / `field`),`callTool` 抛出时保留,
807
- `McpToolError` 经 MCP 错误响应原样透出:
808
-
809
- ```json
810
- {"error":"该节点位于循环路径…","errorCode":"HANDOVER_REQUIRED","field":"handoverNote"}
811
- ```
812
-
813
- 仅新增字段、不改 `error` 语义,向后兼容;Agent 可据此直接补齐入参重试。
814
-
815
- > **回归锁定**:`mcp-server.test.ts` 的 `submit_task_result` 分发断言原先只校验
816
- > 3 个位置参数(`["node-1","...",undefined]`),恰好把丢参行为固化,导致测试全绿
817
- > 而线上必然失败。现改为 5 参断言,并新增 handoverNote / text 交付物 / file 交付物
818
- > (打桩上传)/ changeLog 字符串形态四条用例。
819
-
820
- > **兼容性**:MCP 工具 schema 未变更,仅修复「声明了却不转发」的实现缺口;
821
- > 新旧服务端均可对接(服务端本就接受这两个可选字段)。
822
-
823
- ## v1.9.165
824
-
825
- _发布日期:2026-10-03_
826
-
827
- ### 浏览器画质档位:原画改为无损 PNG,高清 80 / 流畅 60
828
-
829
- 原先三档都是 JPEG,所谓「原画」实为 JPEG q80;且 tile 差量路径把 CDP 帧解码后
830
- **再按同一质量重编码一次**,同一区域反复变化时有损伪影逐次累积。
831
-
832
- - **档位参数改为格式驱动**(`QUALITY_PRESETS` 新增 `format` 字段):
833
- - `original`:无损 PNG,像素级还原(`quality` 不生效);
834
- - `hd`:JPEG 80;
835
- - `smooth`:JPEG 60。
836
- - **tile 重编码跟随档位格式**(新增 `frame-encode.ts` 统一编码入口):
837
- 无损档位下增量块同样输出 PNG,不再被二次有损压缩;整帧与 tile 两条路径
838
- 共用同一实现,避免只改一半造成「整帧无损、增量有损」的错配。
839
- - **CDP 参数修正**:`Page.startScreencast` 仅在 jpeg 格式下携带 `quality`,
840
- png 格式传 0 会被 CDP 判为非法参数。
841
- - **默认格式由默认档位派生**:原先 `DEFAULT_FORMAT` 写死 `'jpeg'`,与默认档位
842
- `original` 冲突,会让会话初始状态变成「UI 显示原画、实际下发 JPEG q0」。
843
- - **单帧上限 2MB → 6MB**(`WS_DEFAULT_MAX_SEND_BYTES`):1280×720 的无损 PNG
844
- 整帧可达 3.5MB 量级,沿用 2MB 会让高熵内容的整帧被静默丢弃,
845
- 表现为画面冻结并反复 resync。
846
- - **切换档位时丢弃差分参考帧**:格式变化会改变参考帧的编码语义,
847
- 沿用旧基准会把新格式首帧差分成跨格式 tile。
848
-
849
- 前端同步:`createImageBitmap` 不再声明 `image/jpeg`(原画档位是 PNG,
850
- 声明错误的 MIME 会选错解码路径,改由内容嗅探);画质下拉文案标注「原画(无损)」。
851
-
852
- > **兼容性**:帧协议未变更(`createImageBitmap` 按内容嗅探格式),
853
- > 新旧前端均可解码;但旧 bridge + 新前端会失去无损能力(仍为 JPEG)。
854
-
855
- ## v1.9.164
856
-
857
- _发布日期:2026-09-26_
858
-
859
- ### 项目级 / 角色级能力层(inherited 层):bridge 侧落地
860
-
861
- 能力配置由「全局默认 + 实例覆盖」两级升级为**四层逐键覆盖链**
862
- (角色实例 > 角色 > 项目 > 全局默认),本版本承接 bridge 侧全部落地。
863
- 解析权威仍在 Java(`AgentCapabilityService.buildInheritedLayers` 产出「项目 ⊕ 角色」的
864
- 增量层),bridge 只负责存储与逐键取用:
865
-
866
- - **能力布尔(MCP / Skill / 插件)**:per-agent 文件由「平铺 map」升级为
867
- `{ overrides, inherited }` 双子对象;旧平铺文件读作 `overrides`,向后兼容。
868
- 取值链 `overrides > inherited > 共享默认(config) > deployedDefault > false`。
869
- 新增整表替换端点 `POST /runtime/{skills|mcp|plugins}/deployed/inherited`
870
- (`{ agentId, inherited }`,null/缺省 = 清空本层),由 Java fan-out 推送。
871
- - **工具三态(disabled / collapsed / expanded)**:新增内存层
872
- `inheritedFeaturesByAgent`,`getFeatureState` 改为
873
- `实例显式 > inherited > 内置默认` 逐键解析;**分组父门禁**在合并视图上判定
874
- (父主开关 `disabled` 则子能力一律未授权),与 Java `AgentAbilitySwitchService`
875
- 同口径。
876
- - **分层推送互不覆盖**:全局改动只动共享默认、项目/角色改动只推 inherited、
877
- 实例改动只推 overrides —— 因此删掉本层键即可自然露出下层值,
878
- 「恢复跟随上层」得以正确工作。
879
- - `/runtime/start` 与 `POST /instances/:id/features` 同步接收 `inheritedFeatures` /
880
- `capabilitiesInherited` 字段(undefined = 不改动,避免误清空其它实例的推送值)。
881
-
882
- > **升级须知(重要)**:低于本版本的 bridge 不认识 inherited 层,会回退到
883
- > 「缺名 = 启用」的迁移期路径,导致**上层已禁用的能力仍被启用**。因此本版本要求
884
- > bridge 与 Java 端同批升级;环境变量四层链(v1.9.163 起)不涉 bridge 存储,滚动安全。
885
-
886
- ### 工具批次归组:阻塞型通讯工具移出「并行执行工具」
887
-
888
- `poll_message` / `create_meeting` 这类核心阻塞型通讯工具不再进入工具批次:
889
-
890
- - **移出批次**(不进批次根事件、不带 `batchId`、不计入 `tool_batch_metrics` 的
891
- `toolCount`/`traces`),时间线上按普通工具扁平展示;执行本身不变,仍由调度器排到
892
- 批尾串行(`poll_message` 的 while(true) 阻塞等待语义不受影响)。
893
- - 动因:这两者与本批其他工具毫无并行收益,归进「并行执行工具」卡片会造成双重误导——
894
- 卡片名宣称并行、实测 `speedup` 恒为 1.00x;`poll_message` 的阻塞等待也会被错觉为
895
- 批次成员。之前的批调用把 `search_memory` 与 `poll_message` 并列,既无加速、又难看懂。
896
- - 批次成立条件收紧为「**批次成员**数 > 1」:若排除后成员不足 2 个(如
897
- `poll_message` + 单个 `write_file`),则不发根事件与指标,时间线完全扁平。
898
- - 运行时新增 `isMcpBatchExcludedToolName`(`mcpToolNames.ts`)作为批次排除判据;
899
- 与「MCP 超时策略」集合 `isMcpBlockingToolName` 语义分离。
900
-
901
- 配套 Java 侧(同批发布):`ProjectCapabilityOverrideService` 项目层存储(
902
- `project_capability_overrides:{tenant}:{projectId}`)、`AgentCapabilityService`
903
- 四层解析与 source 细化(agent/role/project/bridge)、`AgentAbilitySwitchService`
904
- 三态四层 + 分组门禁、`RuntimeBridgeService` inherited 推送与 fan-out、
905
- 项目/角色能力配置接口与新建项目草稿落库。
906
-
907
- ### 修复:Agent 回到 waiting_input 后长时间"空闲"(每次任务后约 10min 死区)
908
-
909
- 现象:角色实例状态徽章长时间显示"空闲",而时间线最新事件停在"编辑文件";
910
- 期间私信/流程线任务完全不消费,约 10 分钟后才自行恢复。
911
-
912
- 根因(`AcodeSdkAdapter`):`turn_complete` 的"用户消息轮调用了工作工具"分支
913
- (`!autoPollActive && observedAnyTool && !observedPollingTool`)原本只做 `return`——
914
- 既不派发空闲提示词、也放弃了重臂。而 `waiting_input` 下 turn 级看门狗不计时,
915
- 会话遂无任何定时器在看守,只能等 10min 会话存活看门狗兜底。
916
- 且重试轮(`retryFailedRequest`,`autoPollActive=false`)同样命中该分支,
917
- 而该路径不重置观察标记,上一失败轮残留的 `observedAnyTool` 使分支必然成立 →
918
- **每次任务结束都固定触发约 10min 死区**。
919
-
920
- 修复(保留"不立即派发"的节流意图,改为**延迟重臂**):
921
- - 新增 `ACODE_DEFERRED_IDLE_REARM_MS`(默认 3s,env 可覆盖)与
922
- `scheduleDeferredIdleRearm()`:分支 2 不立即派发空闲提示词,但延迟后重臂监听,
923
- 把死区从 10min 压到 3s。刻意走 `scheduleAutoPoll` 而非 `armIdleLoopOrAutoPoll`,
924
- 避免配置了 polling 类 idle 命令时被 `IdlePollLoop`(0ms)架空延迟。
925
- - `armIdleLoopOrAutoPoll` 重臂前清除待触发的延迟定时器(只清 timer、不动退避档位),
926
- 防止延迟重臂与正常重臂双发。
927
- - `retryFailedRequest` 与其它提交入口对齐,重置 `autoPollObserved*` 三标记,
928
- 消除跨轮污染导致的"重试轮被误判为用户消息轮"。
929
-
930
- ## v1.9.163
931
-
932
- _发布日期:2026-09-25_
933
-
934
- ### 三级环境变量(全局 / 项目 / 角色实例)→ 工具子进程 + MCP 配置
935
-
936
- 环境变量由单一「面板全局层」升级为**三级合并**(角色实例 > 项目 > 全局,择近优先),
937
- 合并结果随 `/runtime/start` 下发,作用于 bridge 管理的工具子进程与 MCP stdio 服务器配置。
938
- Java 侧 `EnvVarResolver` 为唯一权威计算点,本版本承接 bridge 侧全部落地:
939
-
940
- - **per-agent 环境变量存储**:`panel-env` 由进程级单例改为按 agentId 键控。此前最后启动的
941
- 实例会覆盖整个 bridge 的环境变量(多实例静默串味);现在各实例独立,桌面工具子进程按
942
- 调用方实例取值,切换实例时经 env 签名检测触发重启应用新值(`ownerAgentId` 记录归属)。
943
- - **MCP stdio spec 注入**:MCP 子进程**不继承 bridge 的 `process.env`**(MCP SDK 的
944
- `StdioClientTransport` 只带 HOME/PATH 等少数键),故新增 `mcp-env-injector` 把有效环境变量
945
- 写入每个 stdio server 的 `env`。优先级:**server 自身 env > 三级合并结果 > SDK 默认继承项**;
946
- 内置 `agents-work-studio` 与 sse/http 服务器跳过。acode(per-instance acode.json 装配)
947
- 与 Claude SDK 两条适配器路径均已接入。
948
- - **`${VAR}` 占位符展开**:stdio spec 的 `env` 值与远程 spec 的 `url` / `headers` 值中的
949
- `${变量名}` 按该实例有效环境变量展开(如 `Authorization: "Bearer ${API_KEY}"`);
950
- 未命中的占位符保持原样,便于在 MCP 启动失败信息中定位拼写错误。
951
- - **子进程 env 安全名单**:新增 `utils/env-safety.ts`,把原 plugin-manager 的
952
- `BLOCKED_ENV_KEYS` 集中为单点权威并新增 `sanitizeEnvForChild`,在面板环境变量入站、
953
- MCP spec 注入、桌面子进程显式覆盖层三处统一把关(挡掉 `NODE_OPTIONS` / `LD_PRELOAD` /
954
- `PATH` 等执行流劫持与宿主关键路径键)。
955
-
956
- 配套 Java 侧(同批发布):`EnvVarResolver` 三级合并与「空串=屏蔽」解析、`t_agent.env_overrides`
957
- 实例层存储、项目级 `project_env_vars:*` 存储与掩码读写、有效值预览接口、三级配置 UI。
958
-
959
- ## v1.9.162
960
-
961
- _发布日期:2026-09-24_
962
-
963
- ### 工具懒加载:browser / desktop 收纳态展开链路打通(关键修复)
964
-
965
- v1.9.153 起 browser / desktop 改为**收纳态不注入会话工具列表**(缓存稳定化的
966
- 前提:LLM 请求的 tools 前缀字节级不变,provider 前缀缓存全程命中),工具定义改由
967
- `expand_tools` 结果下发、执行经 `call_tool` 回传。但回传链路在重构中被删除且未补回,
968
- 导致收纳态(默认档)下:
969
-
970
- - `expand_tools({group:"browser"})` 从本地 `exposedTools` 取 manifests → 收纳态下
971
- 必然为空(工具按设计就没注入),agent 拿到 0 个工具定义;
972
- - `call_tool({name:"browser_navigate"})` 找不到工具名 → 直接报「未知工具」;
973
- - bridge 侧 `POST /sessions/:agentId/capability-tools[/call]` 端点恢复后**没有任何调用方**
974
- (原 MCP Server 中继 `setBridgeCapabilityTools` / `handleExpandTools` 已随重构移除)。
975
-
976
- 本次以**同进程中继**补齐(不改 tools/list 载荷,缓存稳定性不回退):
977
-
978
- - ACode 新增 `CapabilityToolRelay` 契约(`tool-group-manager.ts`)+ 运行时配置
979
- `capabilityToolRelay`(`types.ts`),`expand_tools` / `call_tool` 的桥接组分支经其
980
- 回传;本地组(pencil / draw / office / launch / hire / task / meeting / debug /
981
- fileHistory)路径完全不变。
982
- - 展开:先中继(`setBuiltInCapabilityTools(expand)` 刷新定义缓存并授予调度授权、
983
- 返回 manifests),成功后才置本地展开态 —— 中继失败可重试,不留半展开态;
984
- - `group="all"`:桥接组经中继拉 manifests,`disabled` 静默跳过、单组失败不阻断其余组
985
- (该组 `call_tool` 会被拒并提示重新 expand,自愈);收起时桥接授权全部回收;
986
- - 调度:`findTool` 落空且工具名归 bridge 托管时,按 `call_tool` 三道闸同口径的
987
- 本地预检(`disabled` 拒绝 / 未展开引导 expand)后执行 `callBuiltInCapabilityTool`。
988
- - `AcodeSdkAdapter` 会话启动时注入中继(同进程直连,无 HTTP、无 token 依赖;
989
- HTTP 端点 `capability-tools[/call]` 保留供外部/兼容调用)。无 `agentId` 时不注入,
990
- 退化为本地查找(与启动注入的缺省兜底一致)。
991
-
992
- 配套测试:acode `tool-group-manager.test.ts` 新增「capabilityToolRelay」12 项(展开
993
- manifests 来自中继、幂等、失败不留状态且可重试、disabled 不触中继、group=all 混合
994
- 本地+桥接+disabled、收起回收、调度透传参数/未展开拒绝/disabled 拒绝/错误透传/
995
- 非桥接未知工具不触中继);bridge `AcodeSdkAdapter.test.ts` 新增端到端用例
996
- (启动注入中继 → `expand` 下发 manifests 且不注入 exposedTools → `call` 执行 →
997
- `collapse` 后调度被拒)。bridge 套件 1473 通过 + 4 跳过、acode 743 通过。
998
-
999
- ### 工具组:ACode 短 key ↔ 能力 featureKey 错位修复
1000
-
1001
- `collaboration.*`(流程任务 / 会议 / 调试日志 / 文件变更历史)与 `agentSys.launchItem` /
1002
- `agentSys.hire` 的工具组短 key(`task` / `meeting` / `debug` / `fileHistory` / `launch` /
1003
- `hire`)与完整 featureKey 不一致,ACode 侧把「收纳」误判为「禁用」(实测确认):
1004
- 系统提示词把已授权能力显示为未开启、`expand_tools` 直接拒绝。本次新增
1005
- `GROUP_KEY_TO_FEATURE` 映射与 `resolveGroupFeatureKey()`(`instance-features.ts`),
1006
- `capabilityState` 回调先归一再取三态;同时补齐父门禁级联
1007
- (`collaboration` / `agentSys` 主开关 `disabled` 时其子能力一律 `disabled`),
1008
- 与前端清除子键、Java 门禁传播同口径。
1009
-
1010
- 工具组归属推断同时加固(`tool-group-manager.ts`):不再只认 `key_` 前缀,注册的
1011
- 精确 `toolNames` 先于前缀命中,`listToolManifests` 忽略 MCP 的 `serverName__` 命名空间
1012
- 取裸名匹配 —— `my_task` / `create_meeting` / `query_debug_logs` /
1013
- `query_file_changes_history` 等非前缀命名的 MCP 工具组据此正确归组与下发定义。
1014
-
1015
- ### 协作能力分组:默认收纳 + 父门禁级联
1016
-
1017
- `instance-features.ts` 新增 `collaboration` 主开关与 `collaboration.task` /
1018
- `collaboration.meeting` / `collaboration.debug` / `collaboration.fileHistory` 四个子能力
1019
- (默认收纳),ACode 侧注册同名工具组;四个分组在收纳态下不进 LLM 工具列表,经
1020
- `expand_tools` 展开后由 `call_tool` 调度。
1021
-
1022
- ### 工具并发执行(资源驱动调度)
1023
-
1024
- 新增 `tool-concurrency/` 子系统(`types` / `resource-lock` / `scheduler` /
1025
- `observability`),ACode 一条 LLM 响应返回多个 `tool_calls` 时按**资源冲突关系**
1026
- 并发而非按工具类型分组,并新增运行时配置 `toolConcurrency`
1027
- (`enabled` 默认 true、`maxReadOnly` 默认 8、`maxBash` 默认 0=不限):
1028
-
1029
- - 资源键层级(`file:` / 目录前缀 / `bash:` 等)与祖先-后代判定;区间重叠即冲突;
1030
- - 同资源读写按读写锁串行,写-写互斥;未声明并发策略的工具(如 bridge 注入的
1031
- `browser_` / `desktop_`)默认独占串行 —— 关闭 `enabled` 即退化为旧的串行行为;
1032
- - `ToolTraceRecorder` 记录每个工具的 waiting_resource / running / completed 时序并聚合
1033
- 批次度量(墙钟、并行度、等锁总时长、竞争次数、加速比),`ConcurrencyLimiter` 提供
1034
- 只读 / Bash 并发上限;
1035
- - 文件工具声明资源键(`buildFileResourceKey` / `fileResourceClaim`),读 `read`、
1036
- 写 `write`。
1037
-
1038
- ### 文件写入 stale guard(陈旧写入拒绝)
1039
-
1040
- 新增 `read-file-state.ts`:`read_file` 记录 mtime / size / 内容快照,`edit_file` /
1041
- `write_file` 落盘前比对,文件在上次读取后被外部修改(且内容与快照不匹配)时拒绝写入
1042
- 并提示模型重读,避免并发会话/外部编辑器改动被静默覆盖。运行时开关
1043
- `enableStaleFileGuard`(缺省启用,`false` 关闭比对;状态仅存内存,`stop()` 清空)。
1044
-
1045
- ### 工具权限:新增 `fileModificationOutside` 档位
1046
-
1047
- 「限制操作」新增工作区外文件修改权限(`fileModificationOutside`),
1048
- `resolveAgentToolPermissions` 全 allow 兜底值同步补齐,热推路径显式下发默认值以
1049
- 清除历史限制。
1050
-
1051
- ### 会话启动令牌吊销与运行时钟强化
1052
-
1053
- - `RuntimeGlobalSettingsService` 启动时吊销历史运行令牌,避免重启后旧令牌继续可用。
1054
- - `terminal.ts` 抽出 `isIdleStatusChangeRetryable()`:`waiting_input` 纯状态切换
1055
- (`turn_complete` 仅带 usage、不带 `actionType`)也纳入 idle 串行重试队列,
1056
- 修复该类状态切换漏到零重试路径的问题;原 `!params.actionInfo` 空判改为
1057
- `!params.actionInfo?.actionType`。
1058
-
1059
- ### LTR 临时文件读取端点
1060
-
1061
- `POST /api/ltr/read`:按绝对路径返回 LTR 临时文本内容,安全校验拒绝 `LTR_ROOT`
1062
- 目录树之外的路径(防路径穿越),文件不存在 404、非文件 400、上限 512KB。
1063
-
1064
- ### Agent Todo 重置与 acode-todos 路由
1065
-
1066
- `AgentTodoService` / `routes/acode-todos.ts` 支持重置(清空)会话待办列表,
1067
- 配套 `acode-todos.test.ts` 覆盖重置语义。
1068
-
1069
- ### 空闲监听指令(poll_message)措辞收敛
1070
-
1071
- `MESSAGE_POLLING_IDLE_PROMPT` 改为显式前置条件:「此指令仅在当前没有未完成任务时生效;
1072
- 若仍在处理任务请忽略本指令并继续执行」,仅在确认无进行中/未完成任务时才调用
1073
- `poll_message`,降低任务中途被空闲轮询打断的概率(三个 adapter 的单测改为从
1074
- `prompts.ts` 导入常量,避免文案与断言再次脱节)。
1075
-
1076
- ### 依赖与其它
1077
-
1078
- - `aws-client-agent-mcp` 新增 `temml`(Office 公式渲染)依赖,新增
1079
- `office_format` / `office_apply_profile` / `office_generate_from_template` 三个
1080
- Office 工具及 `office-equation.ts` 公式模块(含测试)。
1081
- - `AcodeSdkAdapter` 恢复 `POST /sessions/:agentId/capability-tools[/call]` 路由,
1082
- `resolveAdapter(providerId)` 按会话 providerId 解析适配器;sessions 测试 29 项通过。
1083
- - 版本号 1.9.157 – 1.9.162 为连续未发布开发周期(npm 上仍为 1.9.153),
1084
- 本次一并发布。
1085
-
1086
- ## v1.9.161
1087
-
1088
- _发布日期:2026-09-18_
1089
-
1090
- ### Office 题注位置与回执提示修复(依据 v4 回归报告 N7/N8)
1091
-
1092
- **N7:`captioned_table` 题注位置对齐中文论文规范**
1093
-
1094
- 中文论文(学位论文)规范要求「图题在下、表题在上」,本项目脚本产物同样如此;
1095
- 此前 `captioned_table` 一律把题注插在表格**下方**,用工具链重做论文逐页比对时会显现差异。
1096
- 现按元素类型区分默认位置:
1097
-
1098
- - `captioned_image`:题注默认在图片**下方**(行为不变)
1099
- - `captioned_table`:题注默认在表格**上方**
1100
- - 新增 `props.captionPosition`(`above`/`below`,兼容 `top`/`before`/`bottom`/`after`)显式覆盖
1101
-
1102
- 实现:新增 `insertParagraphBeforeElement`(表题在上的插入路径);章内序号统计按位置
1103
- (章标题之后、插入点之前)计算,因此「表题在上」不改变编号连续性。
1104
-
1105
- **N8:`office_edit` 回执未透传服务端 warnings**
1106
-
1107
- 服务端(Java)已在 `chapterHeadingStyle=false` 等场景返回 `warnings`,但 bridge 层
1108
- `officeEdit` 组装回执时丢弃了该字段,使用者无法感知「F9 后编号不会按章重启」的风险。
1109
- 现原样透传 `warnings`(服务端未返回时不产生空数组噪音)。
1110
-
1111
- 配套回归测试:`OfficeDocxPrecisionTest` 新增 4 个用例(表题默认在上、图题默认在下、
1112
- captionPosition 显式覆盖、表题在上时序号连续);bridge `mcp-server.test.ts` 新增 2 个
1113
- 用例(warnings 透传、无 warnings 时不含该键)。office 测试总数 179 全通过;
1114
- Word COM F9 实测题注编号稳定(表1-1/表1-2/表2-1、图1-1/图1-2/图2-1)。
1115
-
1116
- ### ACode 模型请求失败重试不再重置上下文
1117
-
1118
- 模型请求超时/网关 5xx/看门狗中止后的重试此前会重新走主动压缩预检:一旦累计或估算
1119
- 用量越过阈值,与上下文大小无关的失败重试也会裁剪+摘要化历史,表现为「重试后上下文
1120
- 被重置」。本次修复:
1121
-
1122
- - **恢复式重试(resume,与失败请求逐字节一致)**:非溢出的普通失败(5xx/超时/看门狗)
1123
- 后,适配器以 `resume: true` 恢复同一轮——不重发 prompt 钩子、不重复 push 用户消息、
1124
- **不回滚轮内进展**(工具结果/部分输出原地保留),基于与失败请求同一份 conversation
1125
- 重建请求:重试请求与上次失败的请求逐字节一致,重试之前的状态不丢失。原先的失败轮
1126
- 锚点回滚(`rollbackFailedTurn`)会把会话截回 turn 开始前、丢弃轮内已成功的迭代,已移除。
1127
- - **轮级跳过压缩**:重试 submit 携带 `skipProactiveCompaction`(resume 隐含),覆盖整轮
1128
- 全部 LLM 迭代,并同时约束 800KB 请求体字节上限截断(`truncateConversationIfNeeded`),
1129
- 旧版 `markSkipNextCompaction()` 单次标记兼容保留;仅 provider 显式溢出信号(错误字段/
1130
- `finish_reason`)触发响应式压缩重建,413 溢出仍正常兜底——上下文改写只属于溢出响应。
1131
- - **结构化溢出判定**:新增 `context-overflow.ts`(cause 链下钻 + 字段级标记 + 精选消息
1132
- 片段),`length`/`max_tokens` 被输出长度标记独占短路,绝不因输出上限触发压缩。
1133
- - **4xx 确定性错误短路重试**:invalid_request 类错误直接 `retry_aborted`(「请求无效」),
1134
- 5xx/超时仍按指数退避+抖动重投。
1135
-
1136
- 配套回归测试:acode `runtime.test.ts` 新增/强化 5 个用例(resume 重试请求体逐字节一致
1137
- 且不重复 push、中途失败保留轮内工具结果后 resume 与失败迭代逐字节一致、整轮跳过主动
1138
- 压缩、legacy 单次标记、重试轮跳过 800KB 字节截断而普通轮照常截断);bridge
1139
- `AcodeSdkAdapter.test.ts` 断言重试提交携带 `resume + skipProactiveCompaction`,并含
1140
- 4xx 短路与重试计数语义用例(套件 82/82 通过)。
1141
-
1142
- ## v1.9.160
1143
-
1144
- _发布日期:2026-09-18_
1145
-
1146
- ### Office 题注编号与格式检查修复(依据 v3 回归报告 N1-N6)
1147
-
1148
- **N1(高):SEQ 域 `\s` 值写成了章号,F9 后含小节的章出现重复编号**
1149
-
1150
- `\s N` 的 N 是**标题级别**(1-9),不是章号。原实现写 `SEQ figure \s <章号>`,导致:
1151
- 含 H2 小节的章在每次小节标题处错误重启(实测 Word F9 后 图2-1 重复出现),
1152
- 第十章还会写出超范围值 `\s 10`。现固定为 `SEQ figure \s 1`(按 1 级标题重启),
1153
- 章号只体现于静态前缀;章内序号改为按「本章范围内、插入点之前」的实际域数量统计
1154
- (`countSeqFieldsBefore`),与 `\s` 值彻底解耦。
1155
-
1156
- **N2(中):题注按章重启依赖章标题具备「标题 1」样式,此前不校验也不提示**
1157
-
1158
- Word 的 `\s 1` 按**样式名为内置「标题 1」**的段落重启(COM 实测:仅补直接格式
1159
- `outlineLvl` 或自定义名样式均无效)。而论文类模板常把章标题写成直排格式(无样式),
1160
- 此时 F9 后编号会跨章累计。修复:
1161
-
1162
- - `captioned_*` 在 `chapterTracker=auto` 时自动为识别出的章标题补「标题 1」样式
1163
- (新增 `DocxStyleOps`:找样式 → 套用并逐项还原差异 → 若仍不等价则回退到工具自建的
1164
- **最少格式「标题 1」样式**,保证可见外观零变化)
1165
- - 新增 `props.chapterHeadingStyle=false` 可关闭自动补样式(回执带 `warnings` 说明风险)
1166
- - `office_edit` 回执新增 `warnings` 字段
1167
-
1168
- **N3(低):`props.heading` 传数字不生效(静默)**
1169
-
1170
- 数字 `1`、字符串 `"1"`、`"Heading1"`、`"标题 1"` 现均可用;非法值(`"abc"`、越界 `4`)
1171
- 改为**显式报错**,不再静默不加样式。
1172
-
1173
- **N5:check 空段落噪音**
1174
-
1175
- `office_format` 默认跳过无文本段落(空段落/纯图片段落)的正文类检查与修正,
1176
- summary 增加 `skippedBlankParagraphs`;`rules.blankParagraphPolicy="report"` 可恢复旧行为。
1177
- 实测重生成论文违规数 421 → 199(其中 222 条为纯空段落噪音)。
1178
-
1179
- **N6:preset 与模板实测口径统一**
1180
-
1181
- - profile 聚合修正「非空众数」偏差:此前 114 段中仅 1 段 `bold=true` 也会输出 `bold=true`
1182
- (回灌 apply_profile 会把全文错误加粗);现按全量多数票取值,未显式设置的属性不输出
1183
- - 新增 `OfficeFormatPresets.merge(base, overrides)` 与 `office_format` 的 `mergePreset=true`:
1184
- 以 preset 为基线、实测 profile 逐键覆盖(page/rules[role].props/roles),
1185
- 解决「preset 期望黑体 vs 模板实测宋体」的系统性差异导致的验收比对失真
1186
- - 合并时归一「首行缩进/悬挂缩进」互斥(OOXML 中两者共存只有悬挂生效,会造成
1187
- check 期望与实际永不收敛);写入端同步加固
1188
-
1189
- **实测验收**:模板实测 profile + preset 合并后,对重生成论文 check→fix→check
1190
- 收敛 219 → 0;对既有论文 179 → 0(此前因缩进互斥存在 12 条不可收敛残留)。
1191
-
1192
- 配套回归测试:`OfficeDocxPrecisionTest` 新增 11 个用例(SEQ 恒定值、同章序号解耦、
1193
- 章标题样式自动补/外观保持/可关闭、heading 数字与非法值、空段落跳过与 report 策略、
1194
- preset 合并与缩进互斥收敛、profile null 噪声);office 测试总数 175 全通过。
1195
-
1196
- ### office 卡片:指定文件强校验 + 预览链接服务端权威化
1197
-
1198
- **背景**:office 卡片的 `card.previewUrl` 此前由 agent 自报、bridge 与 Java 两端均无校验
1199
- (纯透传),前端直接塞进无 sandbox 的 iframe——agent 可拼造任意地址(含站外页面)。
1200
- 同时卡片引用的文件是否真实存在没有任何服务端校验。
1201
-
1202
- **新契约**:office 卡片只能用 `filePath`(工作区路径)或 `docId`(云文档 id)之一指定
1203
- 文件,二者必居其一、不可同时传;`previewUrl` 从入参契约中移除,由服务端生成。
1204
-
1205
- - **bridge(发送前校验,失败即工具调用失败、消息不发送)**:`buildOfficeCardPayload`
1206
- 重写——filePath 经 `packOfficeFile` 统一校验(存在/普通文件/docx-xlsx-pptx/≤16MB)后
1207
- 上传,载荷换成 `{type,name,kind,fileUrl,sizeKb,title,filePath,workspacePath}`;
1208
- docId 路径本机零上传,载荷只带 `{type,docId,title?,description?}`;
1209
- 两者同传 / 都缺 / 只传 fileUrl 均抛错。入参即使携带 `previewUrl` 也被丢弃。
1210
- - **服务端(落库前权威校验)**:`McpToolHandler.toCardJson` 的 office 分支改为委托
1211
- `OfficeToolHandlers.normalizeOfficeCard`——校验 filePath/docId 二选一;filePath 路径
1212
- 按 `fileUrl` 反解存储名并 `loadFile` 确认文件真实存在;docId 路径经
1213
- `OfficeCloudDocService.findDoc` 校验云文档有效(不存在则工具调用失败、消息不落库)
1214
- 并回填 name/kind/fileUrl/sizeKb。
1215
- - **预览由服务端生成**:取权威文件字节 → `OfficeDocService.buildPreviewHtml` →
1216
- `FileStorageService.storeFile("...-preview.html", ...)` → 服务端 `previewUrl` 写入卡片。
1217
- 文件字节无法解析(损坏/伪装扩展名)时发送失败,杜绝「卡片指向不存在的文件」。
1218
- - **工具描述**:`send_group`/`send_private` 的 `card` schema 删除 `previewUrl` 属性,
1219
- `docId`/`filePath` 描述改写为「二选一」口径;`office_preview` 描述改为「返回地址供自检/
1220
- 留档,卡片预览由服务端生成」。
1221
- - **dashboard**:新增 `utils/officeCardUrl.ts` 信任边界(`fileUrl` 只放行本站
1222
- `/api/files/` 地址,`previewUrl` 额外要求 `.html`;伪协议/携带凭据/站外链接一律拦截),
1223
- `ChatPanel.vue` 的预览按钮、点击、下载统一走该校验;预览 iframe 加
1224
- `sandbox="allow-same-origin"` 与 `referrerpolicy="no-referrer"`;卡片带 `docId` 时
1225
- 「面板打开」直接按 docId 打开 Office 面板(跳过工作区路径匹配)。
1226
-
1227
- 配套回归测试:bridge `mcp-server.test.ts` 新增 office 卡片 9 个用例(上传路径/预览地址
1228
- 丢弃/文件不存在/非 Office 扩展名/docId 零上传/二选一冲突/两者都缺/只传 fileUrl/DM 路径),
1229
- `mcp-tools.test.ts` 新增 schema 契约 2 个用例;dashboard `officeCardUrl.test.ts` 7 个用例。
1230
-
1231
- ## v1.9.159
1232
-
1233
- _发布日期:2026-09-17_
1234
-
1235
- ### Office 回归修复(依据 v1/v2 回归报告)
1236
-
1237
- **严重:lineSpacing 提取值错误(会导致排版全毁)**
1238
-
1239
- `office_view(mode=profile)` 提取的 `body_text.lineSpacing` 为 `0.075` 而实际应为 `1.5`——
1240
- `DocxStyleResolver` 已把 twips 转为磅值,profile 聚合时又按 twips 除以 240(等效多除 20)。
1241
- 现改为 `pt / 12` 得到倍数,与规则引擎 `normalizeLineSpacing` 对齐;提取值回灌
1242
- `office_apply_profile` 后行距正确(360 twips = 1.5 倍)。
1243
-
1244
- **chapterTracker 跨章失效**
1245
-
1246
- `captioned_image` / `captioned_table` 在第二章后仍生成「图1-1」。修复:
1247
-
1248
- - 按 `before`/`after`/`index` 解析真实插入落点(而非扫描全篇)
1249
- - 章号判定同时支持 Heading1 样式、大纲级别 0、「第X章」中文数字(`chineseNumeralToInt`)
1250
- - 章内序号按 `SEQ ... \s N` 分组计数,跨章正确重启
1251
-
1252
- **SEQ 域缓存值与静态前缀叠加(显示「图1-1 前台首页1」)**
1253
-
1254
- 题注以 `{seq}` 为界拆分为「静态前缀 run + SEQ 域 + 静态后缀 run」,域缓存值即章内序号,
1255
- Word/WPS 打开即为正确编号,F9 刷新后保持一致。
1256
-
1257
- **heading1 角色漏识别**
1258
-
1259
- `OfficeRoleDetector` 新增大纲级别判据与中文样式名支持(`headingLevelOfStyle`:`Heading 1` /
1260
- `标题 1`),章标题正则放宽空格并补充裸数字章标题兜底。
1261
-
1262
- 配套新增 10 个回归测试;office 测试总数 161 全通过。
1263
-
1264
- ## v1.9.158
1265
-
1266
- _发布日期:2026-09-17_
1267
-
1268
- ### Office 模板对齐类文档生成增强(F1-F6)
1269
-
1270
- 将「参考模板 → 逐项对齐样式 → 一键出稿」的论文类任务能力沉淀为 office 工具链通用能力,
1271
- 仍基于 Apache POI 纯格式层(无 COM、无外部进程)。新增 2 个工具 + 2 个 office_view 模式,
1272
- 扩展 office_edit 两种带题注元素与表格列声明。
1273
-
1274
- **新工具**
1275
-
1276
- - `office_apply_profile`:按样式 Profile 对匹配角色段落规整字体/字号/行距/缩进/对齐 +
1277
- 页面设置 + 标题编号;值稳定(重复应用不回退、不翻倍)。
1278
- - `office_generate_from_template`:`{{var}}` 全文跨 run 替换 + 内容清单注入
1279
- (heading/paragraph/image/table/pageBreak)+ 可选 profile 应用;`outputFile` 指定时保留模板。
1280
-
1281
- **office_view 新 mode**
1282
-
1283
- - `profile`:从模板 docx 提取按角色聚合的样式 Profile(page/roles/rules/numbering),
1284
- 作为 apply_profile 的输入;role 附 `matchSource`/`sampleText`/`paragraphCount` 审计元数据。
1285
- - `selfcheck`:按分页符拆页,逐页 `textDigest` + 标题层级跳跃/图片溢出/宽表 warning,
1286
- 并复用规则引擎补充格式违规检查。
1287
-
1288
- **office_edit 扩展**
1289
-
1290
- - `add type=captioned_image / captioned_table`:一条命令插入图片/表格 + 居中题注段
1291
- (SEQ 域,Word F9 可刷新);`caption`/`captionText` 双字段兼容;`chapterTracker=auto` 自动判章。
1292
- - `add type=table` 新增 `columns: [{widthPt, align}]` 列宽(pt→dxa)与列对齐声明。
1293
-
1294
- **回归修复**
1295
-
1296
- - 修复 `office_create` 漏传 `template` 参数(bridge 侧)。
1297
- - 修复 `captioned_*` 题注未写入(参数名不一致 + 题注段与内容段共用锚点)。
1298
- - 修复 `office_generate_from_template` 的 `outputFile` 不生效(模板被就地污染)。
1299
- - profile 角色识别增强:TOC/附录等辅助样式不再污染正文/标题统计。
1300
-
1301
- 详见 `docs/Office文件操作能力实施方案.md` §12。
1302
-
1303
- ## v1.9.157
1304
-
1305
- _发布日期:2026-09-16_
1306
-
1307
- ### Office 精准操作能力大版本:Word 内核 / Excel / PPT / 公式 / 规则引擎
1308
-
1309
- 对标参考开源实现(WordFormat、学术 skills 等)完成 Office 三件套从「能创建」到
1310
- 「精准操作」的升级:run 级定位、批注修订、公式目录页码、版式占位符、格式规则
1311
- 检查与一键修正。全部基于 Apache POI 5.2.5 纯格式层实现,无 COM/无外部进程。
1312
-
1313
- **Word 精准编辑内核(docx)**
1314
-
1315
- - 路径寻址扩展:`/body/p[N]/run[M]`(run 级)、`/body/table[T]/row[R]/cell[C]`(单元格)、
1316
- `/body/sectPr`(页面)、`/body/header|footer`(页眉页脚)
1317
- - 新增 `DocxStyleResolver`:docDefaults → basedOn 链 → 直接格式的**有效格式解析**
1318
- (含主题字体兑现),支撑 `view styles` 与规则引擎「改得准、查不误报」
1319
- - 新能力:`op=replace`(跨 run 保格式查找替换)、批注(写/读/删,五件套部件)、
1320
- 修订(tracked 编辑 + accept/reject)、目录 TOC 域 + updateFields、PAGE/NUMPAGES/SEQ 域、
1321
- 页码页脚、书签 + 外链/内链超链接、**引用上标 [n] + 锚点内链**、OMML 公式(行内/块级/编号公式三列表)、
1322
- **自定义标题编号**(第%1章模板 + 清除手动编号)、三线表(threeLine 预设)、
1323
- 段落字符单位缩进(firstLineChars)、中英文字体三槽(fontEa/fontAscii/fontHAnsi)
1324
- - `office_create` 支持 `template: cn-thesis`(A4+2.5cm、宋体/黑体样式体系、标题编号、页码)
1325
- - `office_view` 新 mode:`styles`(有效格式)、`comments`、`revisions`、`search`(query 定位)
1326
- - `office_validate` 增加 OOXML 结构检查:批注范围配对、w:del/w:ins 规范、xml:space
1327
-
1328
- **Excel 增强(xlsx)**
1329
-
1330
- - `add chart`(bar/column/line/pie/doughnut/area,XDDF 原生图表)、单元格批注、
1331
- 数据验证(list/whole/decimal/date/textLength/custom)、条件格式(cellIs/containsText/colorScale)、
1332
- 带位移插入/删除行(不覆盖相邻数据)、按范围拆分合并、富文本单元格(runs 数组)、
1333
- 定义名称、页面设置(方向/缩放/打印区域)、自动筛选、行列隐藏
1334
-
1335
- **PowerPoint 增强(pptx)**
1336
-
1337
- - 演讲者备注(`set /slide[N]/notes`,view notes 读取)、**版式感知创建**(add slide + layout/layoutIndex,
1338
- view layouts 清单)、占位符直接赋值(`/slide[N]/placeholder[type|idx]`,保留模板样式)、
1339
- 全 deck 查找替换(可限定单页)、表格单元格写入(`/shape[M]/cell[R][C]`)、
1340
- 形状旋转/z-order(up/down/top/bottom)/超链接、**幻灯片克隆**(op=clone:复制文本/图片/备注/版式,
1341
- 源页隔离,插入位置可控)
1342
-
1343
- **公式链路(bridge)**
1344
-
1345
- - 新建 `src/office/office-equation.ts`:`props.latex` → temml(MIT)LaTeX→MathML →
1346
- 自研 MathML→OMML 转换(覆盖分数/根式/上下标/极限/求和积分/矩阵/括号分组),
1347
- 失败时给出可读错误;`office_edit` 自动预处理 latex → omml 上行 Java 注入
1348
-
1349
- **格式规则引擎(差异化能力)**
1350
-
1351
- - 新工具 `office_format`:`{file, action: check|fix, preset|rulesFile|rules, annotate?, outputFile?}`
1352
- - 角色识别(三层):Word 样式 → 正则启发式(第X章/图题/摘要/参考文献等)→ 显式匹配器
1353
- - 检查:逐角色比对期望格式 → 违规清单(path/role/property/actual/expected/fixable/severity)+ 摘要;
1354
- `annotate:true` 把违规写成 Word 批注生成标注版(不覆盖原件)
1355
- - 修正:确定性项自动改(字体三槽/字号/加粗/对齐/行距/缩进/编号/手动编号清除),判断类只报告
1356
- - 预置:`cn-thesis`(学位论文)、`cn-report`(公文);rulesFile 支持工作区 YAML/JSON
1357
- - 收敛性验证:fix 后复查零违规(加权优先级 + 半磅字号 + 悬挂缩进语义)
1358
-
1359
- **预览增强(docx HTML 预览)**
1360
-
1361
- - 批注标记(含正文悬浮)、修订 ins/del 着色、公式文本化、TOC 占位、
1362
- 域友好占位(〔页码〕)、超链接渲染为可点击 a[href]、上下标
1363
-
1364
- **测试**
1365
-
1366
- - Java:新增 `OfficeDocxPrecisionTest`(25 用例)、`OfficePptxAdvancedTest`(11 用例)、
1367
- `OfficeFormatEngineTest`(9 用例)等,全量 1442 用例通过
1368
- - bridge:新增 `office-equation.test.ts`(17 用例)+ mcp-tools 描述契约测试;
1369
- `tsc` 与本套件通过
1370
- - 前端:`officeTimeline` 支持 office_format 事件刷新,测试补齐
1371
-
1372
- ## v1.9.156
1373
-
1374
- _发布日期:2026-09-13_
1375
-
1376
- ### Office 三件套能力升级:图片、排版、形状
1377
-
1378
- 按照 genoffice 对标,大幅增强 Office 文件引擎和工具描述,agent 现在可以生成含图片、列表、格式化表格的工作级文档。
1379
-
1380
- **Java POI 引擎**(OfficeDocService.java)
1381
-
1382
- - **图片基础设施**:严格 Base64 校验 + 魔数嗅探(PNG/JPEG/GIF/BMP/TIFF,WebP 等明确拒绝)+ ImageIO 像素尺寸读取 + 等比缩放辅助
1383
- - **docx 新增**:`add image`(source 支持工作区路径 / http URL / data URL → bridge 侧解析,Java 无状态接收 imageBase64)、`add pageBreak`、列表(`list: "bullet"|"number"` + `level: 0-2` 惰性初始化 XWPFNumbering)、`set /body header/footer`、段落 `pageBreakBefore`
1384
- - **xlsx 新增**:单元格 `numberFormat`(`0.00%`、`¥#,##0`、`yyyy-mm-dd` 等)、`border`+`borderColor`(thin/medium/thick/dashed/dotted/double)、`wrapText`、`valign`(top/center/bottom)、工作表 `colWidth`(px)、`rowHeight`(pt)、`freeze`(行/列)、`add merge`(range 字符串)、`add image`(anchorCell + 图片字节 → XSSFDrawing)
1385
- - **pptx 新增**:`add image`(fit=contain/cover/stretch,cover 写 srcRect 裁剪)、`add shape`(rect/roundRect/ellipse/triangle/diamond/chevron 等 + fillColor/lineColor/lineWidth + 垂直居中文字)、`add table`(均分列宽行高 + header 加粗)、`set /slide[N] background`(十六进制背景色)、`remove /slide[N]/shape[M]`(含图片/形状)、列表(`list: "bullet"|"number"` + bullet 三级字符差异)
1386
- - **view 升级**:stats 增加 `images` 计数、图片段落/形状标注 `(图片)`
1387
- - **preview 预览**:三格式含图片标注
1388
-
1389
- **bridge 侧**(aws-client-agent-mcp)
1390
-
1391
- - 新建 `src/office/office-image.ts`:`officeResolveImageSource(source)` 支持三种图片来源(data:image URL / http(s) URL / 工作区路径),含魔数校验和严格格式约束;`prepareOfficeImageCommands(commands)` 预处理 office_edit 命令中的 props.source → imageBase64
1392
- - `mcp-server.ts`:`officeEdit` 新增调用 `prepareOfficeImageCommands`,使图片 URL/路径自动解析为 base64 上行 Java 引擎
1393
- - `mcp-tools.ts`:`OFFICE_EDIT_TOOL` 描述重写为三格式完整能力清单 + 图片通用规则 + 使用要点;props schema 补充所有新增字段
1394
- - 测试 `office-image.test.ts`:11 测试全通过
1395
-
1396
- ## v1.9.155
1397
-
1398
- _发布日期:2026-09-13_
1399
-
1400
- - Office 文件能力面板化(与 pencil / draw 画布面板同款体验):Agent 可在 Dashboard
1401
- 面板中实时查看自己创建/编辑的 Word / Excel / PowerPoint 文档。
1402
- - aws-client-agent-mcp:office 工具组新增 3 个面板工具——`office_open_document`
1403
- (校验工作区文件存在并返回 file/kind/sizeKb/workspacePath,驱动前端打开面板)、
1404
- `office_close_document`(收起面板)、`office_list_open`(列出本会话已打开的文件);
1405
- `office_create` / `office_edit` 返回值补充 `kind` 字段,供前端时间线提取器维护
1406
- 文件列表(Agent 行徽标计数);工具描述同步引导「打开面板即可实时看到编辑效果,无需截图」。
1407
- - aws-mcp-server:`OfficeToolHandlers` 注册同款 3 个 handler(open 校验扩展名并归一
1408
- kind;close/list 为轻量信封),`TOOL_NAMES` 扩为 8 个——office 能力门禁
1409
- (`checkAbilityGate`)自动覆盖新工具;新增 `OfficeToolHandlersTest`(8 用例)。
1410
- - aws-dashboard:新增 `OfficePanel.vue`(docx 用 docx-preview、xlsx 用
1411
- @vue-office/excel、pptx 用 pptx-preview 本地渲染,注册 workspace watch 后经
1412
- FILE_CHANGED 事件自动刷新,头部按类型显示 Word/Excel/PPT 彩色徽标);
1413
- `useAgentTimeline` 新增 `extractOfficeDocInfo`(解析逻辑抽为可单测的
1414
- `officeTimeline.ts`,覆盖 call_tool 懒加载包裹形态);index.vue 完成桌面/移动端
1415
- 面板挂载、可拖拽宽度注册(office: 720/480/1200)与 Agent 行 Office 徽标按钮;
1416
- ChatPanel office 卡片新增「面板打开」入口(卡片载荷携带 filePath/workspacePath,
1417
- 同工作区时可直接在面板中打开原文件)。
1418
- - 修复 `writeOfficeFileAtomic` 对非法 Base64 静默解码的存量问题(Node
1419
- `Buffer.from(x,"base64")` 宽容语义),改为严格字符集 + 长度校验后再解码。
1420
-
1421
- ## v1.9.153
1422
-
1423
- _发布日期:2026-09-12_
1424
-
1425
- - 工具集懒加载(Lazy Tool Expansion)全链路接入:受管控的大工具集(pencil / draw 各 15 个、
1426
- 启动项 9 个、招聘、浏览器 / 桌面桥接等)由「开启即全量暴露」升级为三态能力开关——
1427
- disabled(禁用)/ collapsed(收纳:工具不出现在工具列表,需先 expand_tools 展开)/ expanded(展开:工具全量直接可见),
1428
- 降低初始上下文占用。
1429
- - aws-mcp-server:`t_agent_ability_switch` 新增 `ability_state` 列(update.sql v1.30.0 迁移,存量行按
1430
- `enabled` 归一:1→expanded / 0→disabled,既有 agent 行为不变),`AgentAbilitySwitch` 实体 / Mapper /
1431
- Service 三态读写,`enabled` 布尔列写入时同步回填保持旧读取兼容。缺省口径(DB 无行):
1432
- browser / desktop / agentSys.launchItem / agentSys.hire 默认 collapsed(已授权但收纳),其余默认 disabled(显式授权)。
1433
- - aws-client-agent-mcp:新增常驻元工具 `expand_tools` / `call_tool`(不属于任何受控组,收纳组始终有展开与调度入口)。
1434
- ListTools 按三态过滤;展开不再把工具注入 runtime exposedTools、不再推送 tools/list_changed(ListTools
1435
- 载荷字节级稳定,LLM provider 前缀缓存全程命中),改为授予 call_tool 调度授权并把工具定义
1436
- (name/description/inputSchema)随 expand 结果下发,agent 当轮即可 call_tool 调用;执行期纵深防御:
1437
- disabled 拒绝、collapsed 未展开拒绝(同时兜住原生工具名直调的旁路)。配置为 expanded 的组不可在会话中
1438
- 收起(由用户决定)、重复展开按幂等 already-expanded 返回。browser / desktop 桥接能力经 HTTP 回传
1439
- bridge 新端点 `/runtime/sessions/:agentId/capability-tools[/call]`(X-Runtime-Token 鉴权),call 超时
1440
- 55s < runtime mcpToolTimeoutMs 60s。
1441
- - acode runtime:系统提示词注入能力清单(新增 capability-prompt.ts)——agent 知道哪些能力已展开 /
1442
- 已收纳 / 未开启,「我没有绘图工具」类请求会主动提示用户去能力配置开启;启动期 env 兜底改为携带三态值
1443
- (AWS_LAUNCH_CONFIG_TOOLS / AWS_HIRE_TOOLS / AWS_DRAW_TOOLS 等),消除首次 listTools 早于 token 就绪时
1444
- env 兜底把收纳组全量暴露的窗口。
1445
- - aws-dashboard:能力配置弹窗新增三态选择器(新组件 FeatureStatePicker.vue),capability-features.ts
1446
- 升级为三态模型(agentSys 主开关禁用时子能力级联禁用,跨层与 Java / bridge 口径一致)。
1447
- - Provider 请求失败不再默认无限重试:requestRetryCount 缺省由无限改为 0(持续 4xx 等不可恢复错误不再空转),
1448
- 错误信息从响应载荷提取 code + message 直接抛出,不再被静默重试吞掉;需恢复内部重试时在 config 显式配置
1449
- requestRetryCount(有限值或 -1 无限)。
1450
- - 消息中心「完整请求体」JSON 树视图:新增 JsonTreeNode.vue(层级树形展示、逐层懒展开)与 jsonRepair.ts
1451
- (截断 JSON 修复兜底,修复后可解析即以树形呈现),60KB 截断请求体支持全文搜索——输入防抖 200ms、
1452
- 命中计数、回车逐个定位、自动展开命中祖先链并高亮,未解析为 JSON 时回退原始文本。
1453
- - 图片预览缩放:新增 useImageZoom.ts(滚轮 / 双指缩放、拖拽平移、双击还原、缩放工具栏),接入 ChatPanel
1454
- 全屏图片预览与 MessageInput 附件预览。
1455
- - draw 卡片预览自愈:新增 drawCardPreview.ts 幽灵渲染管线——服务端从未渲染的 draw 消息卡片以发送者
1456
- (owner)身份补渲染生成预览,渲染成功事件即时补拉;pencil / draw 卡片渲染图 30s 定时补拉自愈
1457
- (消息离开列表即停止),有图即终态。
1458
- - 杂项:.gitignore 补充审查 / 调试期临时产物(tsc / TAP 输出、一次性统计脚本、本地 AI 助手工作区);
1459
- 修复 draw.ts 头注释在编辑中被截断损坏的问题。
1460
-
1461
- ## v1.9.152
1462
-
1463
- _发布日期:2026-09-10_
1464
-
1465
- - 绘图(draw.io)能力全链路接入:新增「绘图 (draw)」能力开关(默认关闭,显式授权语义,同 desktop/hire/pencil),
1466
- Agent 可创建 / 编辑 / 导出 / 分享 draw.io 绘图文档,Dashboard 以独立面板内嵌官方 draw.io 编辑器。
1467
- - aws-mcp-server:新增 `t_draw_doc`(doc_id 唯一,`doc_xml` 为完整 `<mxfile>` 权威内容)、
1468
- `t_draw_doc_member`(协作权限 read|write)、`t_draw_doc_change`(事务型 Outbox 变更日志,与内容写入同事务
1469
- 落行,每 doc 保留最近 200 版;变更通知只作唤醒信号,丢失/离线时经 `draw_get_changes(sinceVersion)` 追赶);
1470
- `DrawDocController` 暴露 `/api/draw/*`(docs / doc / doc ops / doc render / counts / doc members);
1471
- `DrawDocMapper` 以 `doc_id + version` 乐观锁 CAS 写回,消除 check-then-act 竞态窗口。
1472
- - aws-runtime-bridge:新增 `DRAW_FEATURE_KEY` 能力标识与 `AWS_DRAW_TOOLS` 启动期 env 兜底;
1473
- `aws-client-agent-mcp` 注册 `draw_*` 工具组(create/list/open/close/get_diagram/get_changes/create_cells/
1474
- update_cells/delete_cells/delete_document/rename_document/share_document/revoke_share/export_document),
1475
- ListTools 按开关注实时过滤,服务端 `/mcp/call` 另有权威校验;`draw_export_document` 只回传
1476
- savedTo/sizeKb 等元信息,docXml 不回流 agent 上下文。
1477
- - aws-dashboard:新增 `DrawPanel.vue`(iframe 加载自托管 draw.io,经 embed postMessage 协议 load/autosave/export);
1478
- 会话列表新增绘图徽标(仅 Agent 有绘图文档时显示,附数量角标);文档列表改为工具事件驱动刷新
1479
- (`drawRevision` 信号 + 防抖),取代每 2.5s 高频轮询 `/api/draw/docs`,仅在 WS 断线/未覆盖时低频兜底;
1480
- 面板宽度与收缩优先级纳入 `draw`;移动端新增绘图覆盖层。
1481
- - 自托管编辑器资源置于 `aws-dashboard/public/draw/`(官方 draw.war 解包,v31.4.4,含 README 说明升级与授权注意),
1482
- 并加入 Service Worker `globIgnores` 排除预缓存(app.min.js 9MB+、integrate.min.js 22MB+ 体积超预缓存上限,
1483
- 仅打开绘图面板时按需加载)。
1484
- - 消息卡片:`send_group` / `send_private` 支持附带 `card`(`{type:pencil|draw,docId,title?,description?}`)
1485
- 文档引用卡片,`send_group`/`send_private` 工具描述同步说明。读取模型为「凭 docId 可读」——任何 Agent 拿到 docId
1486
- 即可用 `pencil_get_tree` / `draw_get_diagram` 读取,无需被邀请;写操作仍按 owner / 协作成员权限校验。
1487
- 为此 `PencilDocService` 的读取路径(readDoc / getTree / getRender / getChanges)去掉「非 owner/成员即拒绝」
1488
- 的拦截,`resolvePermission` 返回 null 时读取归一为 read;新增 `validateCardDoc` 供卡片发送前确认文档存在。
1489
- 卡片只读引用不写入 `*_doc_member`,因此不改变协作者列表、shared 标记与文档列表徽标。
1490
- `t_direct_message` / `t_group_message` 新增 `card` 列(LONGTEXT,防富内容截断),
1491
- `GroupMessageService` / `DirectMessageService` 增加带卡片的 8 参重载(原 7 参签名保留并委托,向后兼容),
1492
- 卡片 JSON 落库前校验合法性(非法 JSON / 非对象直接拒绝,解析失败按无卡片降级渲染历史消息)。
1493
- Dashboard 侧 `ChatPanel.vue` 新增消息卡片渲染(仿小程序卡片:有渲染图显示预览、否则占位封面,
1494
- 带类型徽标与标题,点击直接打开对应绘图 / 画布面板)。
1495
- - 消息内容扩容 + 载荷剥离:`t_direct_message` / `t_group_message` / `t_meeting_message` 的 `content`
1496
- 由 TEXT(64KB) 扩为 LONGTEXT——富格式内嵌图片 base64(压缩后数百 KB ~ 数 MB)在 MySQL 非严格模式下会被
1497
- 静默截断到 64KB,Agent 经 `poll_message` 只拿到残缺 JSON、`JSON.parse` 失败,表现为 agent 看不到图
1498
- (`[image omitted]`)。配套在 acode runtime 的 poll 结果中剥离 directMessages/groupMessages 内嵌的
1499
- 图片与附件 base64,仅保留可读文本摘要,避免 base64 以纯文本污染后续上下文。
1500
- Dashboard 发送侧新增 `buildRichAttachmentContent`——图片附件以内嵌 base64 随消息下发(Agent 直接以
1501
- 多模态 data URL 读取,无需 fetch 图片 URL / 落盘再读),非图片附件仍为 URL 描述(语义等价 `[文件: ...]`),
1502
- 这正是 content 必须扩容到 LONGTEXT 的直接原因。
1503
- 新增 `ACODE_IMAGE_DIAG=1` 开启的图片注入诊断日志(默认关闭,异步追加且吞掉 I/O 异常)。
1504
- - 发布前修复:群消息仅卡片(无正文)时 Java 侧校验误拒绝,已与 mcp-server 侧「content/attachments/card
1505
- 至少其一非空」对齐;`draw_export_document` 工具 schema 与实现统一(仅 xml/drawio,svg/png 等渲染
1506
- 待阶段 2 管线,描述不再误导);`DrawPanel` 的 postMessage 接收仅接受同源自托管编辑器消息。
1507
- - 原子写健壮性:`atomicWriteFile` 改用 `renameFileWithRetry`——Windows 下 `fs.rename` 可能因目标被瞬时占用
1508
- (杀毒扫描 / 并发句柄)抛 EPERM/EBUSY/EACCES,按 40ms 递增退避重试 3 次,降低实际运行与测试并发下的假失败。
1509
- - 面板最大化(脱离为弹框):新增 `PanelDetachButton.vue`,终端 / 时间线 / 工作区 / 上下文 / 待办 / 后台任务 /
1510
- 子 Agent / 浏览器 / 画布等侧窗面板可一键脱离为弹框最大化,再点恢复回侧窗;脱离态保留强调色提示,
1511
- 标签栏场景支持右对齐 sticky 固定,移动端隐藏(已是全屏覆盖层)。
1512
- - 桌面工具 origin 判定明确化:`injectRememberedOrigin` 以 `originSet()`(非 null 且非 undefined)替代
1513
- `!= null` 判断,语义等价并消除隐式类型收窄告警。
1514
- - 轮询降频:在线成员列表的断连兜底轮询由 5s 放宽到 30s(`ONLINE_CHANGE` WS 事件已支持增量更新,
1515
- 断连时仅需兜底同步,无需高频拉取);绘图文档列表同样由固定间隔轮询改为工具事件驱动。
1516
- - 测试:vitest 单测超时由 30s 放宽到 90s——本机并行跑完整套件(103 个文件、真实 git/子进程)时 CPU 争用
1517
- 可把单个用例拖慢数倍,避免负载型假失败掩盖真实回归;补齐 `draw_*` 工具、git 路由与 acode runtime 用例。
1518
-
1519
- ## v1.9.151
1520
-
1521
- _发布日期:2026-09-07_
1522
-
1523
- - 工作区 LSP(TypeScript/JavaScript 语言服务)全链路接入:Dashboard 文件编辑器可对实例工作区的
1524
- TS/TSX/JS/JSX 文件提供语义级定义跳转与引用查找,不再依赖字符串搜索。
1525
- - runtime-bridge:新增 `typescript-language-server` 与 `typescript` 运行时依赖;`src/services/lsp-stdio-bridge.ts`
1526
- 封装 LSP stdio 帧编解码(Content-Length 增量解析、畸形流防护)与子进程桥(自动解析 tls 入口、注入
1527
- TSSERVER_PATH 保证 tsserver 可启动);`src/routes/lsp.ts` 暴露 `/ws/lsp` WebSocket——单 workspace 单进程
1528
- 复用、60s 空闲回收、复用进程再次收到 initialize 时重建进程(避免 tsserver 沿用旧文档状态陷入
1529
- "No Project"、跳转恒空)。
1530
- - aws-mcp-server:`WorkspaceLspProxyService` 在 HTTP 侧校验 workspace 归属后签发 5 分钟一次性令牌
1531
- (TTL 放宽覆盖慢建连、消费即失效防重放);`WorkspaceLspWebSocketHandler` 把浏览器 `/ws/workspace-lsp/{token}`
1532
- 双向转发到 bridge `/ws/lsp`,隧道模式经 BridgeTunnelService 虚拟流、直连模式带 X-Runtime-Token 握手头;
1533
- `FileBrowserProxyService.resolveWorkspaceLspBridge` 解析 bridge 目标(保留隧道实例前缀)与鉴权令牌。
1534
- - aws-dashboard:`workspaceLsp.ts` 封装 CodeMirror LSP 会话——同一 bridge+workspace 仅建立一条 WS 与
1535
- 一次 initialize,切换文件仅替换 per-file 句柄(didOpen/didClose),避免重复 initialize 导致跳转失效;
1536
- 补充库未内置的 textDocument/references 与 definition 请求、自定义 transport 占位。`WorkspacePanel.vue`
1537
- 接入 LSP 扩展、Ctrl+点击/快捷键跳转定义与引用查找;对 Windows 盘符修正 file:// 三层斜杠与 URI 归一比较。
1538
- - 确认弹窗交互调整:确认按钮移至取消按钮左侧并作为默认焦点,Enter 键即触发确认,Tab 焦点循环顺序与
1539
- 视觉排布一致(确认左、取消右)。
1540
- - 工作区面板媒体预览:图片 / SVG / 视频预览改为经下载接口生成 object URL 展示,支持 B 站式画面缩放
1541
- (Ctrl+滚轮 / 缩放按钮)与按住空格+拖动平移放大后画面,双击复位;预览状态栏同步显示媒体尺寸与状态。
1542
-
1543
- ## v1.9.150
1544
-
1545
- _发布日期:2026-09-07_
1546
-
1547
- - 长文引用(LTR)全链路化:私信超长文本粘贴不再全文进消息,改为引用上传——MCP 与 bridge
1548
- 新增 `/api/ltr/upload`,把大文本片段落盘到目标机器 `<系统临时目录>/aw-temp/LTR/YYYYMMDD/{uuid}.txt`
1549
- (单篇 ≤512KB,按天归档、写入时顺带清理超 7 天的目录),消息只传 `[bridgeName:绝对路径]` 引用,
1550
- agent 用 read_file 读取全文,避免超长文本撑爆消息表(MySQL TEXT 65535 字节)与 LLM 上下文。
1551
- 前端配套:粘贴转胶囊 token(发送时统一上传 + 进度提示、hover 预览全文、未上传时随草稿保留并在
1552
- 切换会话后恢复);LTR 图标与 capsule 颜色跟随主题。
1553
- - 后台命令僵尸状态根治(L1–L4):读路径对账(面板每次刷新先翻"磁盘 running 但本进程内存不命中"
1554
- 的孤儿为 killed(runtime_crashed) 并原子回写);状态写入事务化(per-agent 串行写链消除并发
1555
- heartbeat/finalize 的丢失更新);生命周期补齐(exit+close 双监听,exit 后 2s 宽限强制 finalize,
1556
- 孙进程持续持有管道不再留下永远 running 的状态;进程退出时落盘 killed(process_exit));running
1557
- 任务心跳节流落盘(5s 或输出增量 64KB 触发)+ 启动时全量扫描所有 agent 目录孤儿。
1558
- 面板改为只展示"真后台/运行中"命令,前台同步执行、从未转后台的命令不再占用面板。
1559
- - open-pencil CLI 多路径探测:pencil_export_document 依次探测 `AWS_OPEN_PENCIL_HOME` →
1560
- `<工作区>/open-pencil` → 仓库相对路径 → 逐级向上回溯,未命中时错误信息列出全部探测路径;
1561
- README 补充生产部署前置(工作区锚点或环境变量二选一,须用仓库构建版 CLI 以支持 GraphSnapshot)。
1562
- - create_meeting 有效性预检:角色占坑席位无可认领实例(如该角色唯一实例就是创建人)、或创建人把
1563
- 自己重复加入受邀成员时直接返回错误,不再进入无谓的等待。
1564
- - 群消息撤回语义修正:发送者本人游标越过已撤回消息仍可撤回;他人游标越过则拒绝撤回(撤回不再
1565
- 被"阅读过即作废"误伤)。两项修复均补齐单测。
1566
- - 输入框编辑体验:自建 undo/redo 栈(浏览器原生撤销对 contenteditable + 手动 DOM 不可靠),
1567
- mention / command / LTR 原子 token 可整体撤销;@mention 输入确认后自动把自由文本原地转换为
1568
- mention 高亮 token(`--cp-mention-highlight-*` 亮暗主题双套);「调用式回复」更名为「强调回复」。
1569
- - 文件下载回源文件名:下载/预览响应 Content-Disposition 改用上传时的原始文件名(URL name 参数),
1570
- 并清洗控制字符、引号、分号与路径分隔符,避免 header 畸形与路径穿越。
1571
- - 消息中心:项目在线成员列表去重(同一 agent 绑定多实例时不再重复头像)。
1572
- - 健壮性:后台命令状态持久化失败仅告警不再崩进程;LTR 上传上游失败统一 502 且不回传内部错误细节。
1573
-
1574
- ## v1.9.149
1575
-
1576
- _发布日期:2026-09-06_
1577
-
1578
- - 项目头像支持裁剪:PNG / JPG / WebP / GIF 位图在选文件或点击现有图标后进入方形裁剪
1579
- (拖动调整位置、滚轮或滑块缩放),以 512×512 输出确认保存;SVG / ICO 等无法用
1580
- canvas 裁剪的格式仍直接按原文上传;favicon 预览复用已下载文件,点击直接进入裁剪,
1581
- 避免二次网络下载。
1582
- - Pencil 嵌入式画布跟随 Dashboard 明暗主题:iframe URL 携带 theme 参数,主题切换时
1583
- 经 pencil:theme 消息同步画布配色,不再固定白底。
1584
- - 修复浅色主题下消息中心 agent 上下文用量 / 待办 / 子代理按钮的选中态样式:选中项
1585
- 不再被浅色覆盖规则盖成深色文字(`:not(--active)` 限定浅色覆盖范围,避开高特异性
1586
- 覆盖选中态)。
1587
- - 「限制操作」入口从输入框左侧常驻盾牌图标移回「+」菜单(撤销 v1.9.148 的常驻盾牌,
1588
- 并移除权限档位拉取与盾牌着色逻辑,简化输入框布局)。
1589
- - 版本升级 1.9.148 → 1.9.149:Bridge 本包无运行时代码改动,随前端 Pencil / 消息中心
1590
- 更新一并发布。
1591
-
1592
- ## v1.9.148
1593
-
1594
- _发布日期:2026-09-06_
1595
-
1596
- - Pencil 导出 savePath 不再限制在工作区内:绝对路径(如 D:\exports\hero.svg 或
1597
- 用户 Downloads)直接使用,相对路径仍基于工作区根解析——导出交付物可落盘到
1598
- 任意位置。
1599
- - Pencil 渲染缓存升级为原始分辨率(最长边 ≤8192 内不缩放,此前 1280),agent
1600
- pencil_export_image 与人工导出拿到原图;导出等待超时 8s→15s;升级规格后对旧
1601
- 低分辨率缓存自动补渲一次。
1602
- - Pencil 画板编辑锁:有写权限时默认锁定只读,点击解锁才可编辑;编辑中画布被
1603
- agent 工具/协作端推进版本时自动回锁并加载最新快照,防止基于旧版编辑整份覆盖
1604
- 他人写入(脏写);写权限被收回时强制回锁。
1605
- - 输入框新增终端式 ↑/↓ 发送历史回溯(按会话隔离,Esc 退出并恢复进入前的草稿);
1606
- 「限制操作」入口从「+」菜单移到输入框左侧盾牌常驻图标,存在授权/禁止档位时
1607
- 显示绿色。
1608
- - 修复:侧板拖拽经过 iframe(画布/终端)宽度冻结且无法结束的问题(拖拽期间禁用
1609
- 容器内 iframe 鼠标事件,窗口失焦自动结束拖拽);全局设置菜单横向滚动两端留白
1610
- 被吞掉的问题;项目头像弹窗标题显示项目名而非 projectId。
1611
- - 更新健壮性:包内 CHANGELOG 缺目标版本段时继续尝试 ~/.aws-bridge 下运行时追加
1612
- 的候选文件;更新成功后的发布说明追加改为 await 在重启前完成,版本号优先取 npm
1613
- 刚落盘的 package.json。
1614
- - 发布护栏:prepack-guard 校验 CHANGELOG.md 必须含当前版本段(缺段阻断发布),
1615
- verify-pack-contents 将 CHANGELOG.md 列为必需 payload。
1616
-
1617
- ## v1.9.147
1618
-
1619
- _发布日期:2026-09-06_
1620
-
1621
- - Pencil 设计画布全栈接入:t_pencil_doc 权威存储(迁移 v1.26.0~v1.26.3)与协作者
1622
- 权限、MCP pencil_* 工具(AWS_PENCIL_TOOLS 兜底可见性过滤)。
1623
- - 桌面自动化增强:nuphus-mcp 0.1.12 的 desktop_window_activate 先还原再激活,修复
1624
- 托盘/最小化窗口无法激活的问题;新增 som.rs 与 UIA 安全增强。
1625
- - acode 新增 runtime-environment;后台命令/文件/图片工具优化,AcodeSdkAdapter 与
1626
- 浏览器池稳定性改进。
1627
- - 修复:CHANGELOG.md 自本版本起随包分发。此前发布说明依赖"执行更新的旧进程"运行
1628
- 时追加,旧版 Bridge(≤1.9.145 无此代码)执行更新会导致新版本弹窗无发布说明可
1629
- 展示,只能回退安装过程日志。
1630
-
1631
- ## v1.9.146
1632
-
1633
- - 新增「本次更新内容」展示:将更新弹窗从安装过程日志(updates.log)切换为版本
1634
- 发布说明(CHANGELOG.md),让用户看到本次版本相对变更的要点,而非 npm 安装
1635
- 过程噪声。
1636
- - 更新成功重启后,由 Bridge 自动在 CHANGELOG.md 顶部追加当前版本段。
1637
- - 当目标版本未找到发布说明时,弹窗自动回退展示 updates.log(安装过程日志)并
1638
- 给出提示。
1639
-
1640
- <!-- append-new-version-above -->
1
+ # Changelog
2
+
3
+ 本文件记录 aws-runtime-bridge 各版本的发布说明,随 npm 包一并分发(package.json
4
+ files 白名单),供调度中心「查看本次更新内容」弹窗按 `## v<version>` 精确切片
5
+ 展示。发布新版本时须在仓库中先写好 `## v<version>` 段(prepack-guard 校验缺段
6
+ 即阻断发布);Bridge 自更新成功后的运行时追加仅作为包内缺段时的兜底。
7
+
8
+ ## v1.9.189
9
+
10
+ _发布日期:2026-11-06_
11
+
12
+ ### 新增:语音表达指南工具组与 voice_guide
13
+
14
+ 新增 `voice` 收纳工具组(能力开关 `collaboration.voice`,默认收纳),组内提供
15
+ `voice_guide` 工具:返回当前生效的 TTS 路由与协议、可用的情感方言(传统枚举 /
16
+ 自然语言风格)及其语法、音色目录及标签、多角色对话与停顿写法、语音转写用法。
17
+ 发送工具 send_private / send_group / transcribe_voice 不受开关影响,仍是常驻
18
+ 核心工具;带语音发送的结果新增 voice 块(合成元数据 / 受理票据 / 失败原因码
19
+ 与当前可用能力),agent 据此换语法重发,不必凭记忆猜方言与音色。
20
+ get_send_status 票据终态统一为 send_completed(原 sent)。
21
+
22
+ ### 新增:桌面壳免登录通道(shell pair 全链路)
23
+
24
+ - 外壳在拉起 sidecar 时注入每次启动随机生成的共享令牌(AWS_BRIDGE_SHELL_TOKEN,
25
+ 仅存在于壳主进程与 sidecar 内存,不落盘);bridge 视图的所有请求凭
26
+ `X-Shell-Token` 头 + 回环来源校验放行,桌面用户不再经过 /login;
27
+ - 新增 GET /runtime/shell/status 与 POST /runtime/shell/pair:壳内工作台页面
28
+ 可查询本机配对状态、凭配对票据直接完成配对(票据兑换 → 写盘 → 防抖重注册),
29
+ 免去重启 Bridge;未注入令牌(服务器部署 / 旧壳)时行为完全不变,仍走面板会话;
30
+ - 面板会话从 24h 改为 30 天滑动过期并持久化到 panel-sessions.json(0600):
31
+ bridge 重启、崩溃自愈、升级换包不再丢登录态。
32
+
33
+ ### 新增:注册客户端指纹(防逆向可观测)
34
+
35
+ bridge 注册时自报 clientVersion 与入口文件 sha256 前 16 位(字节码形态下哈希
36
+ 真实代码 index.jsc)。服务端仅记录不校验:同版本号不同哈希即提示私改构建,
37
+ 供 SQL 审计消费;旧版不上报为 NULL,行为不变。
38
+
39
+ ### 加固:浏览器 launchArgs 剥离调试参数
40
+
41
+ 浏览器会话 launchArgs(LLM 可传)经 sanitizeLaunchArgs 过滤
42
+ --remote-debugging-port/pipe/address、--inspect、--inspect-brk、--debugging-port:
43
+ 防止把 Chromium 调试口开在本地被同机进程 attach。Playwright 自身 CDP 走 pipe,
44
+ 过滤后既有功能零影响。
45
+
46
+ ### 变更:payload 字节码分发兼容(内部)
47
+
48
+ - dist 启动流程从模块顶层 await 收进 bootstrap()(payload 链路需 bundle 成单文件
49
+ CJS,esbuild 不支持入口 TLA),执行顺序与语义不变;
50
+ - 新增 loadDynamicModule 统一动态加载入口:ESM(npm 包)走 import() 与原行为一致;
51
+ payload CJS 字节码产物走 require(含插件 reload 的缓存击穿:CJS 删 require.cache,
52
+ ESM 目标落同目录 nonce 临时副本),运行时 import() 在字节码下不可用的问题就此收敛;
53
+ - koffi(win32 远程桌面)与 archiver(工作区 zip)改为惰性加载,消除 CJS 化后的
54
+ 顶层 await。
55
+
56
+ ## v1.9.187
57
+
58
+ _发布日期:2026-11-05_
59
+
60
+ ### 新增:子 agent 续聊 send_sub_agent_message(上下文保留的后续轮)
61
+
62
+ 终态子 agent 不再只能一次性使用:向已完成的子 agent 注入新消息即可开启新一轮,
63
+ 复用其全部上下文(终态后约 30min 保留窗口内有效),不必带着历史报告重新 spawn:
64
+
65
+ - 新一轮结果照常经 await_complete / poll_message 两条通道投递,result 被新报告
66
+ 覆盖;运行中/已释放(TTL 到期)的子 agent 拒绝续聊并给出明确错误;
67
+ - 子 agent 禁止嵌套管理:send_sub_agent_message 加入管理工具黑名单,
68
+ 不会进入可分配工具目录;
69
+ - await_complete 取代 await_sub_agents 成为统一等待入口:一次 JOIN 等齐子 agent
70
+ (sub_agent_ids)与后台命令(bg_cmd_ids),超时_ms 是整个 JOIN 的总预算——
71
+ 修复了混合等待时两段串行各拿满超时、最坏耗时 2× 的契约偏差;等待定时器
72
+ 用后即清,不再给事件循环留 10min 挂起 timer;
73
+ - 失败不再丢现场:await_complete 对 failed 子 agent 同时渲染 task_error 与
74
+ task_partial_output(失败前已产出的文本),不再二选一吞掉;
75
+ - get_sub_agent_status 的 result 不再截断(完整报告 600 字回归锁定);
76
+ hand-back 框架只作用于 await_complete / poll_message 两条投递通道,
77
+ 不写入 store、不作用于 status 查询——报告全文带「模型输出、非用户消息、
78
+ 不携带用户授权」声明并逐行缩进两格,防子 agent 输出伪造用户指令。
79
+
80
+ ### 新增:通知「已读 ⇒ 已交付」确认协议(邮件通知可靠投递)
81
+
82
+ 系统通知(邮件指针 mail_received 等)的已读语义整个翻转,杜绝「取到但没送到」
83
+ 造成的通知永久丢失:
84
+
85
+ - 交付前不再预标记已读:通知随 poll/get_message 结果真正交付给模型之后,才经
86
+ mark_notification_read 上报确认(fire-and-forget,不阻塞结果返回);确认失败
87
+ 清除本地去重记录,服务端保持未读、下次 poll 重投同一条通知(at-least-once,
88
+ 重复交付无害——通知只是「调用 read_email 读取正文」之类的指针);
89
+ - 邮件指针不受「任务型通知每拍一条」限流:未读邮件全量随拍交付,积压邮件
90
+ 不再按拍逐封挤牙膏;
91
+ - 阻塞中的 poll 被邮件等普通系统通知即时唤醒(独立于会议/任务的唤醒通道),
92
+ 不再等满 30s 节流周期才感知;
93
+ - POLL_MESSAGE_TYPES.md 同步更新:SubAgent 完成事件的 content 形状(hand-back
94
+ 框架、Output 不截断、失败附 Partial output)与续聊协议说明。
95
+
96
+ ### 修复:语音工具描述与实现对齐
97
+
98
+ send_private / send_group 带语音的终态发送结果(已送达/已按文字兜底/失败)
99
+ 本身就是定局、不带 ticket;仅超时受理(pending)才返回 ticket 走
100
+ get_send_status 核销。此前的描述会让 agent 对每条语音多查一次状态。
101
+
102
+ ## v1.9.186
103
+
104
+ _发布日期:2026-11-04_
105
+
106
+ ### 新增:语音消息发送状态查询/等待 get_send_status(私信与群聊通用)
107
+
108
+ send_private / send_group 带语音不再让工具调用阻塞到合成结束:受理即落库、
109
+ 最多同步等待 20s——终态(已送达/已按文字兜底/失败)直接返回完整结果,
110
+ 超时返回 pending + ticket,任务留在后台继续。新增 `get_send_status` 工具凭
111
+ tickets 查询或阻塞等待终态:
112
+
113
+ - 可传 `wait_timeout_ms` 阻塞等待(全部票据到终态立即提前返回;到点未完返回
114
+ 当前快照,不算错误),多条语音一次传齐统一核销;
115
+ - 结果带 state/msgId/fallbackMsgId/error,群聊票据附 roomId/projectId、私信附
116
+ targetId,连发多条也能把结果对回具体消息;
117
+ - 客户端等待上限封顶 270s:Node fetch(undici) 默认 headersTimeout=300s,
118
+ 与服务端 300s 预算贴边必然网络层失败(与 create_meeting 同一道坑);
119
+ - acode 侧该工具归入轮询类(免 60s MCP 超时),适配层归为 idle(等待语音送达),
120
+ 豁免 tool_using 5min 慢超时看门狗——否则 270s 等待会被强制恢复打断。
121
+
122
+ ### 修复:Windows 11 26200 上启动项端口徽标一直为空
123
+
124
+ 部分 Windows 构建对监听 socket 的 State 上报不稳定(node 绑定 ::/127.0.0.1 的
125
+ 监听项 State 为 null),`Get-NetTCPConnection -State Listen` 直接漏掉,vite 等
126
+ 端口徽标永远空。改为全量枚举后按「无对端(RemotePort=0)」客户端过滤监听项。
127
+
128
+ ### 修复:启动项端口徽标错过晚绑定的端口
129
+
130
+ vite/spring-boot 的端口常在 start 返回后数秒才监听,原先只在建连时补探一次
131
+ (固定 2s),错过即永久空。改为 5s 间隔续探(探到 / 进程退出 / 2 分钟窗口超时
132
+ 即停);端口一经探到即缓存,后续状态帧不再把已显示的徽标清空;无订阅者时不再
133
+ 做后台续探。相关:工作区文件搜索/替换支持限定在当前显示目录(rootPath)。
134
+
135
+ ## v1.9.185
136
+
137
+ _发布日期:2026-11-04_
138
+
139
+ ### 修复:已配对机器重启不再自毁配对(面板实例消失的根因)
140
+
141
+ 已配对机器(machineToken 自持凭据)优雅关闭时曾无条件调用 `/api/instances/unregister`
142
+ 注销实例,而 server 端该路径会整行删除登记行——`machineToken` 的 hash 就存在这一行上,
143
+ 行被删掉配对即被永久摧毁:重启后机器凭据注册被拒(invalid or revoked),面板上的实例
144
+ 也随之消失。本次两端同修:
145
+
146
+ - Bridge:注销时识别机器凭据目标(machineToken / credentialType=MACHINE_TOKEN),
147
+ **跳过自删登记行**——配对身份必须跨重启存活;Agent 离线由隧道断开与服务端重启同步兜底,
148
+ 真正下线机器请用管理页删除(Bearer 路径,带租户/负责人校验);
149
+ - Server:runtime token 自注销路径拒绝删除 MACHINE_TOKEN 行并返回明确错误
150
+ (兼容尚未升级的旧版 bridge,防止其重启时再毁配对);token 无效时不提前泄露
151
+ 实例的存在性与凭据类型,仍按既有路径走登录态校验。
152
+
153
+ ### 修复:票据里填写的实例名写回不再被旧主机名顶掉
154
+
155
+ server 配对响应的实例名以票据建议名为权威,但 bridge 写回配置用的是
156
+ `target.instanceName = target.instanceName || instanceName`——本机已有同址旧 target
157
+ (instanceName 为历史主机名,如此前用 API Key 注册过)时票据名永远写不进本地配置;
158
+ 下次注册(配对后立即重注册或重启)机器上报旧主机名,server 又按请求名覆盖登记行,
159
+ 用户在票据里填写的实例名就丢了。本次改为**无条件写回 server 响应名**,票据名在
160
+ 本地配置与面板登记行之间保持一致。
161
+
162
+ ## v1.9.184
163
+
164
+ _发布日期:2026-11-03_
165
+
166
+ ### 调整:后台命令上限 20 个,满额报错可操作并回显剩余名额
167
+
168
+ 后台命令名额此前只有 16 个,且满额报错只有一句「Kill or wait」——agent 不知道还剩多少名额,
169
+ 也不知道怎么腾位,本地命令通道因此被整段卡死(只能干等保留期过期)。本次把名额管理做成
170
+ 可见、可操作:
171
+
172
+ - 单 agent 后台命令上限 16 → 20(运行中与 5 分钟保留期内已完成的命令都占名额);
173
+ - 满额时新命令明确失败(status=not_executed,不自动杀任务):报错带 `20/20 slots in use`
174
+ 实况与 `kill_background_command` 腾位指引,agent 按指引停止现有命令后重试即可继续;
175
+ - `kill_background_command` 停止/清理命令**立即释放名额**(此前须等 5 分钟保留期淘汰),
176
+ 「停止现有后台命令来执行新的」当场兑现;对已终态条目即清理占位,终态与输出不改写;
177
+ 重复停止同一条目经磁盘记录幂等返回,「重置状态」重试不报错;
178
+ - 每次 Bash 命令结果新增 `remainingBackgroundCommandSlots` / `backgroundCommandLimit`
179
+ (当前可执行的后台命令数),agent 随时可见剩余名额,提前腾位不再盲跑撞墙。
180
+
181
+ ### 修复:休眠唤醒在时间线上始终有「休眠恢复」凭证
182
+
183
+ 唤醒时按进度摘要接续上下文的三条路径此前在时间线上完全无卡片——`importTranscript`
184
+ 重放失败(降级摘要通道)、旧构建 runtime 不支持重放、休眠时仅存下摘要(无完整记录)。
185
+ 用户无法区分「唤醒了」和「全新启动」。本次适配层在带休眠上下文启动但正常重放卡片
186
+ 未发出时,自动补发一条「休眠恢复」兜底卡片(`transcript-replay-fallback-*`),
187
+ 文案按实际通道区分「重放未完成,已按进度摘要接续」与「已按进度摘要接续」。
188
+
189
+ ### 修复:机器级操作伪 agent 归属未登记时自动自愈,「AI 配置选中后立即回弹」
190
+
191
+ `machine-*` 伪 agent(机器级管理操作如应用 AI 配置、工具安装)的目录可能早于多租户
192
+ 归属改造创建而没有 owner.json,归属校验 fail-closed 会让这类请求永久 403——前端表现为
193
+ 「AI 配置选中后立即回弹为未选择」。本次对**归属从未登记**的 `machine-*` 伪 agent 首次
194
+ 触达时按当前权威 scope 自动登记(登记后放行);已登记归属(本人或他人)与真实 agent
195
+ 实例不适用自愈,他人实例仍 403,归属变更只能走受信入口。
196
+
197
+ ### 修复:插件卸载后不再「复活」,并发部署/移除不再互相覆盖
198
+
199
+ 共享插件清单此前是整表读-改-写:卸载写在旧快照上会把遗留层同名条目原样带回(卸载的
200
+ 插件下次部署对账时复活),并发部署与卸载互相覆盖丢改动。本次清单写入改为合并视图保真:
201
+
202
+ - 卸载在遗留只读层仍登记同名条目时写入**移除墓碑**压制复活,展示/运行时链接/对账
203
+ 一律走过滤墓碑后的活动视图;重新部署同名插件时整条替换墓碑自然清除;
204
+ - 读-改-写持有 manifest 锁,并发部署/移除串行化,墓碑不再在写回时丢失;
205
+ - 部署条目 `zipFile` 缺失时按空串消毒,不再抛异常。
206
+
207
+ ### 新增:崩溃自动休眠——运行上下文落盘保护,中断后下次启动自动接续
208
+
209
+ 运行中实例崩溃(进程死/机器睡/bridge 被杀)此前上下文全丢——对话只存在进程内存里。
210
+ 本次为 acode 实例引入休眠 journal(`~/.acode/hibernation/{agentId}.json`,与待办同区):
211
+
212
+ - **运行中节流落盘**:每个 turn 结束(≥10s 间隔)+ 长 turn 期间每 30s 由存活看门狗
213
+ 补写一次完整对话与 token 用量;崩溃后磁盘上自然留存最近一次现场(可能丢最近几条);
214
+ - **启动自动接续**:启动时若 Java 未下发休眠快照且本机 journal 存在,自动重放上下文,
215
+ 并在系统块最后注入中断提示(「遇到中断导致你进入了休眠,部分工作状态可能已经丢失,
216
+ 请继续工作!」);时间线先落「休眠唤醒中」卡,重放成功后出现「休眠恢复」卡;
217
+ - **干净退出收尾**:正常停止/批量停止/bridge 优雅关闭在终止前做一次 clean 完整落盘
218
+ (零丢失);`/runtime/stop` 新增 `discardContext` 参数,true 时删除 journal
219
+ (用户显式选择「停止(丢弃上下文)」);journal 默认保留 7 天,启动时清扫超期文件。
220
+
221
+ ## v1.9.183
222
+
223
+ _发布日期:2026-11-02_
224
+
225
+ ### 调整:voice 结果新增 protocol,agent 可感知情绪指令是否真的生效
226
+
227
+ 云端 TTS 现支持双 OpenAI 兼容协议:`/audio/speech`(CosyVoice2 等,指令级情绪)与
228
+ `/chat/completions`(MiMo 等对话式音频输出,协议限制不支持情绪指令——指令会被当正文
229
+ 念出来)。两者的差异 agent 此前无法感知,`voice.emotion` 恒回显请求值,容易误以为
230
+ 情绪已经传达。
231
+
232
+ - 发送工具结果 `voice` 新增 `protocol` 字段:`speech`(指令级情绪生效)/
233
+ `chat`(暂不支持情绪指令)/ `local`(本地兜底,仅语速与停顿);
234
+ - `voice` 新增 `emotionApplied`:情绪是否真实作用于本条语音的最终事实
235
+ (chat 与 local 为 false);
236
+ - `voice.emotion` 参数说明改为按 protocol 区分语义,agent 发送后即可判断
237
+ 「这条语音到底有没有带上情绪」;
238
+ - 会话 profile 注入全局提示词的语音能力说明由服务端按当前配置实时生成
239
+ (协议状态、字数上限、emotion 是否生效),agent 会话创建即知道能力边界,
240
+ 不依赖工具描述里的静态说明;配置中途变更由逐条发送结果自我校正;
241
+ - 语音消息载荷(`voice.protocol`)同步写入,前端/排查可定位音质来源;
242
+ - 协议类型由站点「语音合成」配置显式指定(speech/chat),不再按接口路径猜测。
243
+
244
+ ## v1.9.182
245
+
246
+ _发布日期:2026-11-01_
247
+
248
+ ### 新增:配对成功即生效,无需重启 Bridge
249
+
250
+ `awsb pair` 成功写盘后,CLI 会调用本机运行中 Bridge 的回环端点
251
+ `POST /runtime/pair-applied`,让它立即用磁盘上的最新配置重新注册并重建隧道。
252
+ 此前配对只写盘、长期运行的 Bridge 只在启动时注册,不重启就永远显示「隧道未连接」。
253
+
254
+ - 端点只认回环来源(与 `/binding/request-token` 同口径),并做单飞防抖:
255
+ 上一轮注册未结束时直接复用,不会并发跑两趟 autoRegister;
256
+ - 立即应答、注册在后台进行(含重试可能耗时数秒),面板「等待连接」轮询如实反映结果;
257
+ - Bridge 未运行(首次安装尚未启动服务)或是旧版本(404)时通知静默失败,
258
+ CLI 回落为原有的 `awsb service restart` 提示。
259
+
260
+ ### 修复:transcribe_voice 工具有声明无分发
261
+
262
+ `aws-client-agent-mcp` 早已声明 `transcribe_voice` 工具,但 `mcp-server` 的分发
263
+ 分支漏接,调用一律落到 Unknown tool。ASR 推理在服务端容器执行,这里补上
264
+ `callAgentScopedTool` 转发(自动注入 agentId),agent 侧语音复听/转写校验恢复可用。
265
+
266
+ ### 调整:voice.emotion 说明对齐云端指令级情绪
267
+
268
+ 工具描述从「只影响语速与句间停顿」改为区分链路:云端合成按自然语言指令真正
269
+ 改变语气(开心/兴奋/平静/低落/郑重),本地兜底只有语速与句间停顿。
270
+
271
+ ## v1.9.181
272
+
273
+ _发布日期:2026-11-01_
274
+
275
+ ### 修复:插件等用户路由 403(agent-ownership-mismatch)
276
+
277
+ `requireUserScope` 的解析优先级纠正:validateToken 已按凭据
278
+ (connectionKey / runtime token)解析出的 `req.userScope` 必须原样保留,
279
+ 不再被请求头/体无条件覆盖。此前有两个问题:
280
+
281
+ 1. 携带合法凭据、但没带 `X-Tenant-Id` / `X-User-Id` 头的服务端调用
282
+ (如调度中心的插件代理)会被降级成 binding.json 的本机用户
283
+ `{tenantId:"_local"}`,与实例 owner.json 登记的真实归属永不相等,
284
+ `requireAgentOwnership` 一律拒绝——表现为插件面板一打开就报 403。
285
+ 2. 更严重的是「凭据决定的权威 scope」可被「请求自称的 scope」替换,
286
+ 伪造请求头即可跨 target / 跨租户写入别人的用户命名空间。
287
+
288
+ 现在头/体身份仅服务于「无 target 凭据」的本机面板 / MCP 子进程链路,
289
+ 凭据解析出的 scope 拥有最高优先级。
290
+
291
+ 配套调度中心侧:`PluginProxyController` 发往 bridge 的代理请求补注
292
+ `X-Tenant-Id` / `X-User-Id`(按 agent owner,与 RuntimeBridgeService
293
+ 同口径),本机面板/子进程链路不再缺身份头;插件面板错误提示优先透出
294
+ bridge 返回的真实原因,不再被 "Request failed with status code 403"
295
+ 之类的 HTTP 概括语吞掉。
296
+
297
+ ## v1.9.180
298
+
299
+ _发布日期:2026-11-01_
300
+
301
+ ### 功能:累计消耗 token(从 Agent 启动起)全链路
302
+
303
+ 此前面板只有「当前上下文」口径的输入/输出 token(覆盖式,压缩/清空会回落),
304
+ 没有「从启动到此刻一共烧了多少」的累计口径。本次打通 runtime → adapter →
305
+ 调度中心的全链路:
306
+
307
+ 1. **acode runtime 累计消耗**:新增 `totalInputTokens` / `totalOutputTokens`
308
+ 累计字段(Σ 各次请求 provider 真实上报的 prompt/completion tokens,输入含
309
+ 缓存命中),跨迭代、跨 turn 只增不减,压缩/清空不影响;与缓存命中计数同
310
+ 口径——只累计真实上报值,文本长度兜底不计入,压缩摘要 LLM 请求(独立
311
+ fetch)不计入。`turn_complete` / `iteration_usage` 的 usage 覆盖式携带累计
312
+ 快照,前端无需自行累加。
313
+ 2. **休眠唤醒跨快照延续**:休眠导出的 tokenUsage 快照(含累计与缓存四字段)
314
+ 由调度中心落库,唤醒启动时经 `resumeTokenUsage` 回灌,runtime `start()`
315
+ 重建 state 时以 `config.initialTokenUsage` 为累计初值——唤醒后继续累计而非
316
+ 清零。普通启动缺省从 0 起;旧快照(无累计字段)按无 seed 处理,不阻断启动。
317
+ 3. **adapter / 终端路由透传**:`toUsage` 逐字段解析累计值(独立于 0/0 丢弃与
318
+ fallback 判定,不参与文本长度兜底);`totalUsage` 字段级 presence 覆盖
319
+ (旧版 runtime 不带累计字段时保留现值,不清零不回落);`resolveStatusChangeUsage`
320
+ 在 input/output 为 0(如 seed 后、首个请求前)但累计已有值时也照常传出。
321
+ `getTotalUsage`(休眠导出通道)一并带出累计与缓存快照。
322
+
323
+ 配套调度中心侧:状态回调透传累计字段、AgentContextPanel 新增「累计消耗」区块、
324
+ 休眠快照表补列(cache_hit/miss + total_input/output tokens)。
325
+
326
+ ### 修复:唤醒请求的累计 token seed 解析
327
+
328
+ `parseResumeTokenUsage`(与 `parseResumeTranscript` 同模式)只接受四个累计字段,
329
+ 非法/缺失字段丢弃、全部非法返回 undefined(累计从 0 起,不阻断启动),
330
+ JSON 文本异常不会让唤醒流程失败。
331
+
332
+ ## v1.9.179
333
+
334
+ _发布日期:2026-10-27_
335
+
336
+ ### 修复:注册成功后立刻拆掉自己的隧道并退出进程
337
+
338
+ 现象:日志依次出现「隧道客户端已启动」→「目标已不在配置中,停止旧隧道」→
339
+ 「未捕获异常: {}」→ 优雅关闭 → 注销实例。机器明明注册成功却连不上。
340
+
341
+ 三个叠加缺陷:
342
+
343
+ 1. **`instanceId` 预声明用了对象展开重绑定**(`config = {...config, instanceId}`)。
344
+ `autoRegisterAll` 用同一个 `config` 对象数组构造隧道「保留集」,重绑定后外层
345
+ 仍持有旧对象,后续补上的 `credentialId` 传不出去。
346
+ 2. **`credentialId` 同样只改了局部变量**。于是一边按 `credentialId` 启动隧道、
347
+ 一边按 `userKey 指纹` 计算保留集,键不一致 → 刚建的隧道被判定为「已不在配置
348
+ 中」而拆除。两处均改为原地写回。
349
+ 3. **`teardownConnection` 先 `removeAllListeners()` 再 `close()`**。对仍在
350
+ `CONNECTING` 的 socket 调 `close()`,`ws` 会异步 emit `'error'`
351
+ ("WebSocket was closed before the connection was established");此时已无任何
352
+ error 监听,EventEmitter 把它抛成未捕获异常 → 进程级 `uncaughtException` →
353
+ 整个 bridge 优雅关闭。现在保留一个忽略用的 `error` 监听。
354
+
355
+ ### 修复:未捕获异常日志只打印 `{}`
356
+
357
+ `Error` 的 `message` / `stack` 是非可枚举属性,`JSON.stringify(error)` 只得到
358
+ `"{}"`,此前根本看不出崩溃原因。日志格式化现在显式展开
359
+ `name [code]: message` 与 `stack`。
360
+
361
+ ### 代码质量:lint 全量清零
362
+
363
+ `npm run lint`(`eslint src --max-warnings 0`)从 89 error / 34 warning 降到 0 / 0:
364
+ 清理未使用导入与变量、修正 `import/order` 与重复导入;测试文件中的非空断言
365
+ (`!`)按惯例在 eslint 配置里对 `**/*.test.ts` 放宽,避免为消除告警引入无意义判空。
366
+
367
+ ## v1.9.178
368
+
369
+ _发布日期:2026-10-27_
370
+
371
+ ### 目标身份升级为 `credentialId`:轮换 Key 不再断链
372
+
373
+ 上一版用 `serverUrl + userKey 指纹` 作目标身份,解决了同址多账号并行;但**轮换
374
+ API Key 会改变指纹**,导致 runtime token、隧道、注册状态、instanceId 全部重新开始
375
+ (表现为换 Key 后 agent 找不到实例)。本版把身份锚点换成服务端下发的稳定凭据 ID:
376
+
377
+ - `config.json` 的 target 新增 `credentialId` / `credentialType`,注册成功时由
378
+ 服务端回填并持久化(与 instanceId 同一条回写路径)。
379
+ - `targetKeyOfConfig` 改为 `buildTargetKey(serverUrl, credentialId ?? userKey)`:
380
+ 有 credentialId 时身份不随 Key 变化;旧配置无该字段时仍回退 userKey 指纹,平滑迁移。
381
+ - runtime token 存储、隧道槽位、注册重试、instanceId 反查统一用
382
+ `identityKeyOfConfig(config)`(credentialId 优先)。
383
+ - **删除隧道鉴权的 userKey 兜底**:此前取不到 runtime token 时会把 userKey 当
384
+ token 发出去,服务端只认 hash 匹配必然 401,却掩盖了「未注册/注册失败」的真实
385
+ 原因。现在明确报错并提示重新注册。
386
+
387
+ ### 同一调度中心地址支持多账号/多租户并行注册
388
+
389
+ (承接 v1.9.177)身份模型继续保证:同一 `serverUrl` 下不同凭据各自独立隧道、
390
+ 独立 runtime token、独立 instanceId,互不覆盖。
391
+
392
+ ## v1.9.177
393
+
394
+ _发布日期:2026-10-26_
395
+
396
+ ### 同一调度中心地址支持多账号/多租户并行注册
397
+
398
+ 同一用户加入多个组织(租户)时,同一台机器往往需要连接**同一个调度中心地址**、
399
+ 但使用**不同的 API Key** 各自注册一个实例。此前桥内以归一化 `serverUrl` 作为唯一
400
+ 身份键,同址两行会互相覆盖(隧道被拆、runtime token 串用、instanceId 写乱),
401
+ 面板因此直接拒绝保存第二行。
402
+
403
+ 本次把桥内身份模型从「地址」升级为「目标身份」= `归一化 serverUrl + userKey 指纹`:
404
+
405
+ - 新增 `utils/target-identity`:`buildTargetKey(serverUrl, userKey)`,形如
406
+ `http://host:port#a1b2c3d4`(sha256 前 8 位,不落明文;可读、可作 properties 键)。
407
+ 地址归一化(尾斜杠/协议大小写/`ws→http`/`localhost→127.0.0.1`/重复端口)抽到
408
+ `utils/scheduler-url`,由 `config`、`runtime-binding`、`target-identity` 共用一份实现。
409
+ - **runtime token 存储**:`runtime-tokens.properties` 的键由 `md5(serverUrl)` 改为
410
+ 目标身份键,同址多账号各存各的 token。旧键自动兼容读取;未指定 `userKey` 且该地址
411
+ 只有一个身份时仍可命中(单目标老调用点无需改动),多身份时必须显式指定,避免串用
412
+ 别的账号 token 造成「注册成功但回调 401」。新增 `listScopedRuntimeAccessTokens`。
413
+ - **隧道**:`tunnels` Map 改按目标身份键控;同址不同账号各自一条隧道并存。
414
+ 新增 `stopTunnelClientForTarget(serverUrl, userKey)` 精确停止单个身份;
415
+ `stopTunnelClientsExcept` 改为接收身份键集合;`stopTunnelClientForServer` 保留,
416
+ 语义改为「停该地址下所有账号」。
417
+ - **注册状态**:`registrationState.registrations` 键改为目标身份键,instanceId 互不覆盖;
418
+ 新增 `resolveInstanceIdForTarget`。注销只清理本身份的 token/隧道/记录,其余身份保持注册。
419
+ - **instanceId 回写**:只回写与本次注册身份匹配的那一行(此前按地址会把所有同址行写成
420
+ 同一个 instanceId)。
421
+ - **注册重试**:后台重试定时器按身份键去重,同址两个账号各自独立重试。
422
+ - **面板去重规则**:由「同址即重复」改为「同址 + 同一 API Key」才是重复;同址不同 Key
423
+ 属合法配置。去重校验移到「继承原配置」之后,因为编辑行留空 userKey 时真实身份要等
424
+ 继承完成才确定。
425
+ - **面板交互**:列表每行显示 API Key 掩码与租户 ID,便于区分同址多行;编辑行新增
426
+ `originalTargetKey` 精确指代被编辑的那一行(同址多行时仅靠地址无法定位),两行都留空
427
+ userKey 时按写入顺序逐条认领旧身份继承。
428
+ - **目标解析**:`resolveSchedulerBaseUrlFrom` 返回值新增 `userKey`;歧义判定改用
429
+ 「目标身份数量」而非「去重后 URL 数量」——否则同址多账号会被误判为单目标而静默选中
430
+ 其中一个账号。新增 `resolveTargetIdentityFromToken` 按 token 反查身份(含地址与
431
+ userKey),供入站回调确定该用哪个账号的凭据。
432
+
433
+ > **兼容**:单地址单账号的既有配置行为不变;旧 token 文件(md5 键)继续可读。
434
+ > 无需改动 `config.json`。
435
+
436
+ ## v1.9.176
437
+
438
+ _发布日期:2026-10-25_
439
+
440
+ ### 工作区代码导航:语言服务 + 语法索引兜底
441
+
442
+ - `/ws/lsp` 从「仅 TypeScript 单进程」升级为多语言模型:按
443
+ `工作区 + provider + clientId` 隔离进程,同一会话内跨文件复用;不同浏览器
444
+ 标签/面板使用不同 `clientId`(tsserver、pyright 都不支持多客户端共享文档状态)。
445
+ 进程池设并发上限(`AWS_LSP_MAX_PROCESSES`,默认 6)并按最久未用淘汰,断连后
446
+ 保活 60s 供快速重连复用。
447
+ - 新增 provider 注册表(`services/lsp/provider-registry`),覆盖 15 个语言服务:
448
+ TypeScript/JavaScript、Vue、Python、JSON、CSS、HTML、YAML、Bash、Dockerfile、
449
+ PHP、Java、Go、Rust、clangd、C#、Ruby。按扩展名推断 provider,统一
450
+ `languageId` 归并与启动参数拼装;新增 `services/lsp/uri-rewrite` 处理客户端与
451
+ 服务端路径形态差异(Windows 盘符大小写、`file://` 编码)。
452
+ - 新增 `GET /runtime/lsp/providers`、`POST .../install`、`POST .../uninstall`、
453
+ `GET .../task/:id`、`GET /runtime/lsp/processes`:npm provider 按需安装到
454
+ `.aws-bridge/lsp-servers`,安装进度可轮询,进程列表供排障。
455
+ - 新增工作区语法索引(`services/workspace-index`):以 tree-sitter 抽取声明与
456
+ 导入,覆盖 12 种语言(TypeScript/JavaScript、Python、Go、Rust、Java、C、C++、
457
+ Ruby、PHP、Lua、Bash),提供定义/引用/符号/大纲查询。LSP 不可用时前端回退到
458
+ 该索引,不因语言服务缺失而失去跳转能力。端点挂在
459
+ `/api/workspace-index/{status,build,query,drop}`,索引随工作区切换释放。
460
+
461
+ > **兼容**:旧前端只带 `file`/`language`(无 `provider`/`clientId`)时按扩展名
462
+ > 推断 provider、`clientId` 视为 `default`,行为与历史版本一致。
463
+
464
+ ### 桌面控制人工治理:急停与动作审计
465
+
466
+ - 新增 `POST /runtime/desktop-control/:agentId/pause`(急停/恢复)与
467
+ `GET .../state`(控制状态 + 最近动作审计)。急停后所有 `desktop_*` 工具
468
+ 一律拒绝(含读类),并产生 `rejected` 事件而非静默失败。
469
+ - 动作事件流:`desktop_*` 调用映射为 `started`/`done`/`error`/`rejected`
470
+ 四态事件,按 agent 维护 100 条环形审计缓冲,经远程桌面 WS 实时推送,
471
+ 每个 agent 独立自增 `seq` 供前端排序与去重。
472
+ - **坐标陈旧性校验**:截图成功后记录「坐标依据」(截图文件 + 时刻 + 可重放参数);
473
+ 带坐标的动作执行前,若依据超过 `AWS_DESKTOP_STALE_WARN_MS`(默认 60s),
474
+ 用记忆参数重截一次并做内容比对——画面已变则在结果尾部追加警告(不阻断,
475
+ LLM 读到后自行重截),未变则静默刷新依据时刻。5s 内结果缓存,连续动作不重复校验;
476
+ sharp 不可用/截屏失败时退化为时间戳警告(安全方向)。
477
+ - 状态为进程级内存态:Bridge 重启即自动解除急停(重启本身会终止桌面 MCP,
478
+ 等效急停,无需持久化)。
479
+
480
+ ### 桌面安装包 sidecar 模式
481
+
482
+ - 新增 `AWS_BRIDGE_APP_MODE=desktop` 与 `AWS_BRIDGE_LISTEN_HOST`:桌面态只监听
483
+ 回环,不暴露局域网;未显式配置注册地址时默认走隧道(回环地址对外不可达)。
484
+ - 端口探测改为「探测形态 = listen 形态」:指定 host 时只探测该 host,避免把
485
+ 「别的进程占了通配、但 127.0.0.1 仍可绑定」误判为冲突导致端口无谓顺延。
486
+ - 未设置这两个变量时行为与既有一致(通配绑定、服务器部署语义不变)。
487
+
488
+ ### Bridge 面板
489
+
490
+ - 面板 HTML 拆分为独立模块(`routes/dashboard-theme`、`routes/dashboard-icon`),
491
+ 主题令牌与图标不再内联在巨型模板字符串里,便于维护与复用。
492
+
493
+ ### 子 Agent 与工具组
494
+
495
+ - `SubAgentManager` 等待结果时,store 查询失败不再让该项从结果中静默消失:
496
+ 超时后按 `settled` 集合补报未终态项,避免「部分子 agent 结果莫名丢失」。
497
+ - 工具组:新增命名分组与 `tools/list` 名称对齐校验(`named-group-tool-names-alignment`),
498
+ 防止分组配置与实际暴露的工具名漂移。
499
+ - `aws-client-agent-mcp` 补齐邮箱工具组(`send_email`/`list_emails`/`read_email`/
500
+ `reply_email`/`ack_email`)与 `list_project_members` 的转发分支,全部经
501
+ `callAgentScopedTool` 注入 agentId(防越权)。
502
+
503
+ ### 发布链路修复
504
+
505
+ - **修复 `npm publish` 被自身守卫误拦**:`verify-dist-minified` 原先用
506
+ `code.includes("/**")` 判断「未混淆」。但本仓库把 HTML/CSS/内联脚本放在模板
507
+ 字符串里(`DASHBOARD_HTML`、`THEME_CSS`),压缩后字符串内的 `/** ... */`
508
+ 会原样保留(那是要发给浏览器的页面源码,不是 JSDoc),导致
509
+ `dist/routes/dashboard.js` 被误判并直接阻断发布。
510
+ 新增 `scripts/source-comments.mjs`,基于 TypeScript AST + 字面量区间排除
511
+ 判定「代码区注释」;`minify-dist.mjs` 的 .d.ts 注释剥离同步切到同一口径,
512
+ 避免「剥干净了却仍被判为脏」。守卫对真实未压缩文件仍然拦截(已验证)。
513
+
514
+ > **验证**:`npm run typecheck` 与 `npm test` 通过(137 files、1915 passed、
515
+ > 3 skipped);`npm pack` 端到端通过(780 files / 6.6MB,postpack 正确还原)。
516
+ > 新增/覆盖 `workspace-index`、`provider-registry`、`uri-rewrite`、`lsp`、
517
+ > `desktop-control`、`desktop-staleness`、`desktop-mode`、`sub-agent-manager`、
518
+ > `named-group-tool-names-alignment`、`mcp-tools` 等用例。
519
+
520
+ ## v1.9.175
521
+
522
+ _发布日期:2026-10-23_
523
+
524
+ ### 技术栈自动识别:扫描工作区生成启动项候选
525
+
526
+ - 新增端点 `POST /runtime/tech-stack/scan`(body `{ workspacePath }`):只读扫描
527
+ 工作区标记文件,返回可直接创建的启动项候选(名称/类型/命令/工作目录/依据)。
528
+ - 识别范围:`pom.xml`/`build.gradle(.kts)`(Spring Boot 走 `spring-boot:run`/`bootRun`,
529
+ 有 wrapper 优先 `mvnw`/`gradlew`)、`package.json`(按 `pnpm-lock.yaml`/`yarn.lock`/
530
+ `bun.lockb` 推断包管理器,脚本按 dev>develop>serve>start 取)、`manage.py`、
531
+ `pyproject.toml`/`requirements.txt`(FastAPI 出 `uvicorn main:app --reload`,
532
+ uv/poetry 项目自动加 `uv run`/`poetry run` 前缀)、`go.mod`(根 `main.go` 出
533
+ `go run .`,否则展开 `cmd/*/main.go`)、`composer.json`(Laravel `php artisan serve`、
534
+ Symfony `php -S localhost:8000 -t public`),以及 `Cargo.toml`/`deno.json`/
535
+ `docker-compose.yml` 兜底为 generic。
536
+ - 遍历全层级且尊重 `.gitignore`(规则引擎抽到 `services/gitignore.ts`,与文件浏览器
537
+ 目录树共用同一实现);依赖/构建/版本库目录(`node_modules`/`target`/`dist`/
538
+ `.venv`/`.git` 等)恒跳过。目录预算 4000,超限返回 `truncated` 并保留已识别结果。
539
+ - 命中标记文件才读内容,单文件读取上限 64KB;候选 id 为「相对目录+技术栈+命令」
540
+ 的稳定哈希,重复扫描结果一致。
541
+
542
+ > **验证**:bridge `npm run typecheck` 通过;新增 `tech-stack-scanner.test.ts`
543
+ > (16 passed)覆盖 Spring Boot/wrapper 平台分支、Maven 回退、Node 包管理器推断、
544
+ > monorepo 子包、Django/FastAPI/uv 前缀、Go 单入口与 `cmd/*` 展开、Laravel/Symfony、
545
+ > Cargo 可运行 crate 判定与 lib crate 排除、compose 兜底、.gitignore 排除、
546
+ > 同目录多栈、id 稳定性。
547
+
548
+ ### Git 提交历史分页与快照保留策略
549
+
550
+ - `POST /runtime/git/commits` 支持 `skip`/`limit` 分页:新增 `resolveCommitPageLimit`
551
+ / `resolveCommitPageSkip` / `sliceCommitPage`,一次抓取多取一条用于判定 `hasMore`,
552
+ 避免整段历史一次性返回;保留不传 `skip` 的旧单页响应形状。
553
+ - 全分支图按 `--branches --remotes --tags` 收敛引用范围,内部引用(如 cline
554
+ checkpoint)不再混入提交图;detached HEAD 通过显式 revision 保留。
555
+ - 新增工作区快照保留策略(`snapshot-retention`):默认不清理,面板下发保留天数后
556
+ 按 mtime 删除过期快照;与 change-cache 复用同一节流(写缓存时 1h + 24h 兜底扫描),
557
+ 配置变更立即执行一次。面板显式下发的值不会被迟到的 `config.json` 覆盖。
558
+
559
+ ### 终端与隧道稳定性
560
+
561
+ - 隧道请求体分帧:请求体超过单帧上限(2MB WS 文本帧)时,server 改为 `req` 头帧
562
+ + `reqchunk` 数据帧 + `reqend` 收尾,bridge 侧按 id 归集拼装后转发本地服务;
563
+ 半包请求带 5 分钟空闲超时,连接断开时清理残留缓冲。
564
+ - 终端 SDK 作答/取消:新增取消作答链路(含可选原因),与回答共用幂等与回执;
565
+ `compaction_summary` 走独立推送通道,不进 `sdkOutputQueueBySession` 串行队列,
566
+ 摘要流与主输出流互不阻塞。
567
+ - 修复时间线重复卡片:仅刷新用量的 `status-change`(`iteration_usage` 等)不再
568
+ 重放上一次 `ai_request` 动作;抽为 `isUsageOnlyStatusChange` 便于单测覆盖。
569
+ - 终端「等待输入」判定抽到 `lastOutputLine` + `listWaitingForInput`:只取输出末行
570
+ 做启发式匹配,纯读不消费输出游标,供压缩后重建资源快照给出「哪些终端卡在提示符上」。
571
+
572
+ ### Bridge 面板
573
+
574
+ - 仪表盘时间统一按面板当前语言(中/英)与浏览器本地时区渲染,修复切换语言后
575
+ 日期仍按系统语言、以及直接切 ISO 字符串导致显示 UTC 挂钟值的问题。
576
+ - 自更新前增加确认弹窗,明确「更新会重启 Bridge、运行中的实例会停止、进行中的
577
+ 任务会中断」。
578
+
579
+ > **验证**:`npm run typecheck` 与 `npm test` 通过(130 files、1827 passed、
580
+ > 6 skipped);`git-commits-page.test.ts`(4 passed)、`tech-stack.test.ts`、
581
+ > `snapshot-retention.test.ts`、`tunnel-client.test.ts`、`terminal.sdk-answer.test.ts`
582
+ > 均通过。
583
+
584
+ ## v1.9.174
585
+
586
+ _发布日期:2026-10-21_
587
+
588
+ ### 私信附件「存到对方机器」:bridge 临时文件通道
589
+
590
+ - 新增 bridge 临时文件通道:上传的文件直接落到**接收方实例所在机器**的
591
+ `<系统临时目录>/aw-temp/ATT/YYYYMMDD/{uuid}{扩展名}`,服务端不落盘,
592
+ 按天归档并在写入时顺带清理超过 7 天的旧目录。
593
+ - 新增端点:`POST /api/bridge-temp-files/upload`(multipart 上传)、
594
+ `POST /api/bridge-temp-files/read`(按绝对路径读回字节)、
595
+ `POST /api/bridge-temp-files/delete`(删除临时文件)。
596
+ - 落盘文件名用 uuid 而非原始文件名(原始名只回传展示,规避文件名注入);
597
+ 扩展名由原始名清洗而来,保留原扩展名便于 agent 判断读取方式。
598
+ - 回传路径统一为正斜杠:Windows 的 `path.resolve` 接受正斜杠,跨平台一致,
599
+ 且正文标记进 JSON 载荷时不会被反斜杠转义弄乱。
600
+ - 修正 multipart 文件名在部分代理链路被 latin1 解读导致的中文乱码
601
+ (与工作区上传同一口径)。
602
+ - 读/删接口做路径越界校验:只允许访问 `aw-temp/ATT` 目录树内的文件,
603
+ 越界与不存在统一返回 404,不向调用方泄露目录结构。
604
+ - 上传超限(>512MB)返回 413 与明确错误码,不落成 HTML 500。
605
+
606
+ > **验证**:bridge `npm run typecheck` 通过;新增 `bridge-temp-files.test.ts`
607
+ > (10 passed)覆盖上传落盘/扩展名保留/读回/越界 404/删除/正斜杠跨平台往返。
608
+ ## v1.9.173
609
+
610
+ _发布日期:2026-10-21_
611
+
612
+ ### 上下文压缩后补齐「运行时资源事实」,修复命令失忆
613
+
614
+ - 压缩后重建的运行时资源快照新增「当前打开的文档」一类:画布(pencil)、
615
+ 绘图(draw)、Office 文档各自登记**面板当前开着的那一份**。此前快照只列
616
+ 「存在哪些文档」,压缩后 agent 不知道用户正看着哪份文档,容易重复 open
617
+ 或对着已被取代的版本继续改。
618
+ - 打开状态由 bridge 侧按 agentId 维护(`open-doc-registry`):依据工具调用流
619
+ 登记 / 清除,随会话结束清理;识别直调与收纳态 `call_tool` 中转两种形态。
620
+ - 终端快照补「waiting for input」状态:停在 ssh 密码提示等交互提示上的会话
621
+ 单独标出(判定只取输出末行,历史输出里的旧提示符不误判)。
622
+ - 浏览器条目补 `browserId`:同 agent 可有多个独立 chromium 实例,缺 id 时
623
+ agent 无法分辨「已开的那一个」。
624
+ - 修复两条漏掉重建快照的路径:`resetContext`(对话还原到启动基线但真实资源
625
+ 并未消失)与休眠恢复 `importTranscript`(预压缩同样会丢弃资源事实)。
626
+
627
+ - 修复「面板事件顺序与真实运行态相悖」:LLM 同一轮声明 `poll_message` + 兄弟工具
628
+ (如 `get_profile`)时,`call_tool` 事件原在**准备阶段**按声明序发出,但 blocking
629
+ 工具会被调度器排到**批尾串行**执行 —— 于是 poll_message 的「调用中」卡片先落库、
630
+ 实际先跑完的兄弟工具后落库,面板最后一条停在 `get_profile`,而 agent 正阻塞在
631
+ poll_message。现改为「工具真正开始执行时」才发 `call_tool`,事件顺序即真实执行顺序。
632
+ - poll_message 阻塞期间新增**面板事件矫正**:以 runtime 内部的阻塞型调用计数
633
+ (`hasActiveBlockingToolCall`,经 bridge `GET /runtime/sessions/:agentId/current-action`
634
+ 暴露)为权威判据。该判据是运行时事实、不经事件流派生,故不会被兄弟工具的完成
635
+ 事件覆盖;发现权威状态与本地 tag 不一致时补发一次 poll_message 事件矫正面板,
636
+ 并保留 30s 冷却避免刷屏。无法判定(查不到会话/查询失败/无阻塞调用在飞)时一律
637
+ 不矫正,宁可保持现状也不凭猜测改写面板。
638
+
639
+ > **验证**:bridge `npm run typecheck` 与 `npm test` 通过(123 files、
640
+ > 1775 passed、2 skipped);`package/acode` legacy 套件 175 passed / 0 failed、
641
+ > vitest 828 passed。事件顺序修复另行验证:`package/acode` 新增
642
+ > `call-tool-event-order.test.ts`(3 passed)、`aws-client-agent-mcp` 新增
643
+ > 面板矫正用例(mcp-server 162 passed / 0 failed)、bridge `npm test`
644
+ > 1775 passed / 0 failed。
645
+
646
+ ## v1.9.172
647
+
648
+ _发布日期:2026-10-21_
649
+
650
+ ### 上下文压缩重构、提问取消作答与消息中心体验收敛
651
+
652
+ - ACode 上下文压缩改为「高保真级联」统一策略(完整摘要 → 降级 → 截断),不再由
653
+ 前端勾选压缩类别;移除 `compaction-preview` 与「先行压缩」配置弹窗,输入区入口
654
+ 直接启用开关,压缩范围由运行时决定。
655
+ - 压缩摘要改为流式上报:runtime 逐 chunk 发射 `compaction_summary`,bridge 按
656
+ 120 字符 / 120ms 积攒后推送,时间线实时滚动展示;摘要正文不落库(bridge 本地
657
+ 环 Buffer、per-agent 事件存储、Java 事件表与运行日志全部跳过),刷新后不复活。
658
+ - 修复压缩摘要与思考卡片互相打断、摘要尾部落到压缩结束事件之后、长摘要不跟随
659
+ 滚动的问题;压缩摘要使用独立琥珀色卡片样式。
660
+ - 修复 token 用量显示:启动/恢复/压缩后的估算值与 provider 真实值用
661
+ `usageEstimated` 显式区分,真实 usage 变小时不再被 20% 启发式误判为 fallback;
662
+ provider 未上报 input tokens 时不再把上下文清零。
663
+ - 修复时间线重复卡片:`iteration_usage` 等 usage-only 状态变更不再重放上一次
664
+ `ai_request` 动作;工具结果先于调用到达时不再覆盖已完成的同名工具卡片。
665
+ - 支持「取消作答」:提问卡片新增取消入口与可选原因,Java / bridge / ACODE runtime
666
+ 全链路解除 Agent 阻塞并把取消结果回传模型;回答与取消共用幂等与回执持久化,
667
+ 刷新后展示「已取消」只读态。
668
+ - `read_file` 图片 URL 读取:以魔数为权威格式判据(签名 URL 的
669
+ `application/octet-stream` 不再被误拒),发送最小浏览器请求头规避图床 403/406,
670
+ URL 只保留 origin+path 写调试日志;运行时提示明确「URL 直接读,不要先 curl 落盘」。
671
+ - dashboard:消息通知弹层新增提示音开关(Web Audio 合成、首次手势解锁、静音持久化);
672
+ 桌面通知权限入口移至消息通知弹层;移动端弹框最小化新增「飞向收纳按钮」动画;
673
+ 普通终端打开期间按钮转圈防重复点击;长文本粘贴统一转为 txt 附件;文件引用图标与
674
+ 工作区文件树同源;引用图标视觉修正。
675
+ - 邮件:新增 `imapInternalHost` / `smtpInternalHost` 等后端内网连接地址(留空回退
676
+ 客户端展示地址),配置自检展示实际生效地址;compose 为 James 增加
677
+ `mail.<mailDomain>` 网络别名,避免容器经公网/NAT 回环;邮箱别名改用 James
678
+ typed alias 路由 `/address/aliases/{目标}/sources/{别名}`,修复旧路由稳定 404。
679
+ - 消息协作:`send_dm` 的 `replyToCallId` 未命中调用式消息时降级为普通私信并回传
680
+ warning(不再静默丢内容);自动关联 pending call 失败时同样降级发送。
681
+ - 修复 `sendOutput` 在 `skipLocalPersist` 路径于 `finally` 中 `return` 吞掉异常,
682
+ 导致上层重试队列收不到失败信号的问题。
683
+ - 内置 `db_connect_client_mcp` 源码随仓库提交(能力市场包仍以 esbuild 单文件
684
+ bundle 发布)。
685
+
686
+ > **验证**:bridge `npm run typecheck`、`npm test`(121 files、1747 passed、
687
+ > 2 skipped)与 `package/acode`(827 passed)、`package/aws-client-agent-mcp`
688
+ > (561 passed)测试通过;Java `mvn test`(2057 passed)通过;dashboard
689
+ > `npm run lint`、`npm run type-check` 与全部 `test:*` 脚本通过。
690
+
691
+ ## v1.9.171
692
+
693
+ _发布日期:2026-10-20_
694
+
695
+ ### 消息协作、邮箱别名、同事观察与日志治理
696
+
697
+ - 消息中心:发送改为乐观上屏(本地「发送中」→ 服务端 `sent`),网络/5xx/429
698
+ 自动退避重试 3 次,失败气泡保留并支持「重试 / 编辑」;WS 回显按发送者+正文+
699
+ 时间窗认领本地待发气泡;私信/群聊发送携带客户端幂等键,服务端按
700
+ `(sender, clientMessageId)` 去重,HTTP 响应丢失后的自动重试不会产生重复消息。
701
+ - 群聊支持 @所有人(后端展开为房间/项目实际成员,提及记录与未读口径一致)、
702
+ 结构化引用提醒(回表校验被引用消息作者,拒绝客户端伪造 `senderId`),并补充
703
+ 引用提醒系统通知。
704
+ - 新增角色实例邮箱「人类只读查看」(收件箱 / 已发送 / 详情,不改变 IMAP 已读
705
+ 状态)与邮箱别名设置;别名更新改为「先建新远端映射、再删旧映射」,任一步失败
706
+ 不会让旧别名提前失效,失败时补偿恢复远端状态。
707
+ - 同事协作:`get_colleague` 增加在线状态、当前动作、工作区路径与邮箱概要;
708
+ 新增 `list_colleague_events` 分页查看同事行为时间线(摘要视图,剥离工具输入/
709
+ 结果原文),由 `collaboration.agentObserve` 能力开关控制(默认收纳)。
710
+ - ACode 收口:AI 配置 / MCP 模板 / 终端 CLI 仅保留 ACode,移除 ClaudeCode、
711
+ Codex、OpenCode 的配置入口与文案。
712
+ - 修复:`RuntimeBridgeService` / `RuntimeGlobalSettingsService` 保存 MCP 时补回
713
+ `instantiate` / `packageUrl` / `packageSha256` 字段,避免包型 MCP 初始化丢失。
714
+ - 修复:清空角色实例邮箱别名改为显式 `SET address_alias = NULL`(MyBatis-Plus
715
+ `updateById` 会忽略 null 字段);恢复心跳超时后的 Agent 异常离线告警。
716
+ - bridge 日志治理:新增统一日志保留策略(lifecycle、MCP 子进程、AI 配置调试
717
+ 日志,最长保留 7 天),启动即清理 + 每 6h 周期清理,面板下发值夹取到 1..7 天;
718
+ Java Debug 日志清理同步收敛为最长 7 天。
719
+ - bridge 启动记忆加载抽为独立服务并复用;provider 请求体非法(确定性 4xx)时
720
+ 落盘完整对话上下文快照(去重 + 保留最近 20 份),便于事后复现工具调用配对问题。
721
+ - dashboard 接入标签页未读标题 / PWA 应用角标;页面隐藏时按私信、群聊 @、系统
722
+ 通知弹桌面通知(同会话 4s 合并、点击跳转会话),权限申请放在个人菜单。
723
+
724
+ > **验证**:bridge `npm run typecheck` 与 `npm test` 通过
725
+ > (120 files、1724 passed、2 skipped);Java `mvn -q test` 通过;
726
+ > dashboard `npm run lint`、`npm run type-check` 与 99 个 `test:*` 脚本
727
+ > 全部通过。
728
+
729
+ ## v1.9.170
730
+
731
+ _发布日期:2026-10-17_
732
+
733
+ ### 能力市场与插件运行时落地,并发一致性与调试挂载修复
734
+
735
+ - 新增能力市场:Java 侧 `AbilityMarketService` / `AbilityMarketController` 提供
736
+ 模板上架、安装、卸载与“我的能力”清单,安装态以 `RuntimeGlobalSettings`
737
+ 全局设置持久化;bridge 侧配套能力市场工具与 MCP 包探测、部署链路
738
+ (`mcp-package.ts`、`mcp-probe-client.ts`、`ability-market-tools.ts`)。
739
+ - bridge 插件体系重构为 manifest / loader / runtime / listener-runner 分层,
740
+ 统一插件清单校验、持久化目录部署与监听器生命周期,并补充插件开发指南与
741
+ 插件系统设计文档。
742
+ - dashboard 新增能力市场管理页与安装弹窗(含环境变量占位符校验)、Agent 状态
743
+ 重置与上下文压缩弹窗,会话操作菜单抽取为 `chat-message-actions`。
744
+ - 新增调试挂载(debug-mount)能力:会话建立时按需挂载调试资源,会话销毁
745
+ (含 SDK 会话清理各出口)统一调用 `clearDebugMounts`,避免残留。
746
+ - 修复:`AbilityMarketService` 安装 / 卸载回滚快照在同一写锁内捕获,消除并发
747
+ 写下的回滚竞态;`mcp-deploy` 增加名称合法性校验(拒绝 `.`、`..` 与非 basename)
748
+ 并改用原子 rename 交换,清单 `fileName` 以实际下载文件名为准。
749
+ - 修复:插件部署仅在全部候选迁移成功时才清理旧 `shared/` 目录,legacy
750
+ `zipFile` 经 `sanitizeArchiveFileName` 收敛,重命名失败不再误删目标目录;
751
+ 插件处理器在启用 shell 且命令含 `{{...}}` 插值时改为 fail-closed 拒绝执行。
752
+ - 修复:`package/acode` 运行时 `removeMcpServer` 同步清理 stderr 缓冲;手动
753
+ compact 优先级高于自动 `shouldCompact`,避免手动压缩计划被丢弃。
754
+
755
+ > **验证**:bridge `tsc --noEmit` 与 `vitest run` 通过(1687 passed;仅
756
+ > `src/browser/page-listener-nav.smoke.test.ts` 偶发 hook 超时,重跑通过,该目录
757
+ > 未改动);`package/acode` `tsc --noEmit`、`runtime.test.ts` 与 `compaction.test.ts`
758
+ > 通过;Java `mvn compile` 通过,`AbilityMarketServiceTest`(31)、
759
+ > `RuntimeBridgeServiceTest`(79)通过;dashboard `npm run lint`、`npm run type-check`
760
+ > 以及 i18n / ability-market / dialogQueue 相关测试通过。
761
+
762
+ ## v1.9.169
763
+
764
+ _发布日期:2026-10-12_
765
+
766
+ ### 多语言与消息协作增强,环境变量、邮箱与流程线能力整合
767
+
768
+ - dashboard 接入 `vue-i18n`,提供简体中文与英文的自动识别、持久化、运行期切换
769
+ 和 Element Plus 文案联动,并补充完整开发指南与语言资源测试。
770
+ - 消息中心补齐消息复制、引用流、附件下载与反馈队列体验;能力范围、时间线顺序、
771
+ 浏览器面板适配和会话分组等交互稳定性同步收敛。
772
+ - dashboard 侧接通项目 / 角色 / Agent 三层环境变量配置、能力开关与邮箱管理界面,
773
+ 并补充项目关系图导入、流程线交付物下载 / 回放 / 指派标签等能力。
774
+ - bridge 启动测试统一跨平台命令进程 PID mock 输出,稳定 Linux CI 端口探测时序,
775
+ 避免发布流水线因平台差异产生偶发失败。
776
+ - 更新 Docker Compose 与邮箱部署、跨项目角色冲突、环境变量分层等文档。
777
+
778
+ > **验证**:dashboard `npm run lint`、`npm run type-check` 与 `npm run build` 通过;
779
+ > dashboard 新增 34 个测试脚本全部通过;bridge `npm test` 通过
780
+ > (114 files、1621 passed、2 skipped)。
781
+
782
+ ## v1.9.168
783
+
784
+ _发布日期:2026-10-11_
785
+
786
+ ### 发版稳定性:测试兼容、任务通知与连接生命周期修复
787
+
788
+ 本版本主要为发版验证中暴露的兼容性与稳定性问题收敛,既有功能契约保持不变:
789
+
790
+ - `aws-client-agent-mcp` 的 `initialize` 返回完整工具组清单,能力开关三态
791
+ (`disabled` / `collapsed` / `expanded`)契约与 Java 侧保持一致。
792
+ - `pipeline_task_assigned` 的 `SYSTEM_NOTIFY` 与持久化任务通知增加强制任务域
793
+ hydrate,首次落空时自动重试,避免重启或长轮询窗口内遗漏流程任务。
794
+ - `.agentswork` 记忆目录搜索增加项目根与 Git 仓库边界,避免相邻项目目录串用;
795
+ `MemoryStore` 增加 domain 写入缓存,修复大量 domain 场景测试超时。
796
+ - WebSocket 手动断开与异步 token 刷新重连之间的竞态修复,断开后不再重新排程
797
+ 重连,非 CLOSED 连接句柄会被终止。
798
+ - `RuntimeBridgeService` 的 SSE 客户端改为首次使用时初始化;同步迁移版本数、
799
+ `reply_to` 测试 schema 与 Direct/Group Message 控制器测试签名。
800
+ - 测试命令增加 Node 测试进程强制退出兼容项,确保 CI 收尾不被子进程管道句柄
801
+ 阻塞。
802
+ - 修复 Linux CI 启动项端口探测用例的 shell PID / 命令进程 PID 替换竞态,
803
+ 避免发布流水线因平台进程发现时序产生偶发失败。
804
+
805
+ > **验证**:Java 后端 `mvn test`(1873 tests)、bridge 根目录测试、ACode 测试与
806
+ > `aws-client-agent-mcp` 测试全部通过;`npm run build:all`、`npm run build`
807
+ > 和 `npm run typecheck` 均通过。
808
+
809
+ ## v1.9.167
810
+
811
+ _发布日期:2026-10-07_
812
+
813
+ ### Word 格式管控:OOXML 版式底座 + 信任机制(自动备份 / 保护区域 / 报告聚合)
814
+
815
+ 面向「生成复杂排版文档并严格把控」这一目标,分两条线补强 office 工具链。
816
+ Java 侧新增 3 个 OOXML 助手并扩展 5 个,bridge 侧补齐备份、参数透传与工具契约。
817
+
818
+ #### 1. 写盘前自动备份(改坏了能回滚)
819
+
820
+ `office_edit` / `office_format(fix)` / `office_apply_profile` / `office_generate_from_template`
821
+ 直接改写用户文档,此前改错只能靠事先手动 copy。现在覆盖写盘前自动留一份
822
+ `<基名>-backup-<时间戳><扩展名>`,滚动保留最近 5 份;回执透出 `backupPath` + `backupHint`。
823
+ **另存到已有文件**同样先备份(等价于覆盖)。备份失败不阻断写盘(磁盘满/权限异常时
824
+ 不带该字段);只清理严格匹配时间戳命名的文件,不会误删 `报告-backup-未命名.docx` 这类同名文件。
825
+
826
+ #### 2. 保护区域:封面/题注/代码块不被正文规则触碰
827
+
828
+ 规则新增 `exclude`(支持 `/body/p[1]-p[14]` 区间简写与 `{path/from/to/style/contains/role}` 对象)
829
+ 与 `excludeByRole`,**check 与 fix 同源生效**。`summary.excludedParagraphs` 透出命中段数。
830
+ `office_format` 另提供顶层 `exclude` 便捷入口(preset 场景下也能一次排除封面);
831
+ 实现上复制 rules 再写入,不原地修改 preset 共享实例(否则会污染后续所有调用)。
832
+
833
+ #### 3. 三套规则系统打通:profile 可直接当 rules
834
+
835
+ `office_view(mode=profile)` 的产物此前**无法**直接喂给 `office_format`——启发式识别出的
836
+ 角色其 `match` 为空对象,`RoleMatcher.matches()` 恒为 false 且不回落到内置判定。
837
+ 现空 `match` 回落内置启发式,并新增 `unmatchedRoles`/`unmatchedRolesHint` 显式报出
838
+ 「既无 match 又非内置角色名」的规则(此前这类规则静默失效,是「配了规则却没反应」的根因)。
839
+ 推荐链路:模板 `view(profile)` → `office_format(rules=profile, exclude=[封面范围], action=check)` → `action=fix`。
840
+
841
+ #### 4. 报告可读性:106 条平铺 → 可定位
842
+
843
+ - 每条违规新增 `textDigest`(段落文字摘要),不必再按 path 反查原文;
844
+ - `summary.byRole`(按角色聚合降序)、`summary.paragraphs`(按段落聚合,含该段问题属性列表)、
845
+ `summary.topIssue`(一句话摘要)。
846
+ - 阅读顺序:`topIssue` → `byRole` → `paragraphs` → 需要细节时再读 `violations`。
847
+
848
+ #### 5. `office_format(action=dryRun)` 与 `office_view(paths=[...])`
849
+
850
+ - **dryRun**:按 fix 逻辑算出将改哪些项,返回 `willModify` + `nextStep`,不写盘、不返回字节
851
+ (bridge 侧即使服务端意外带回字节也直接丢弃)。注意 dryRun **不产生 `converged`**——
852
+ 未真正修正就不能声称收敛。
853
+ - **paths**:段落白名单(`/body/p[7]`、区间 `/body/p[5]-p[11]`),仅对 `styles`/`profile`/`selfcheck`
854
+ 生效。大文档(几百段)下排查局部时把返回量从整篇压到几段。`profile` 的 `page`/`numbering`
855
+ 来自文档级部件仍按整篇提取;`selfcheck` 的 `pageNo` 仍为真实页码。无法解析的 `paths`
856
+ 一律回退为「不过滤」,避免空结果误导。
857
+
858
+ #### 6. OOXML 版式能力补齐 + 4 个 P0 缺陷修复
859
+
860
+ 新增 `DocxLayoutOps`(分栏/页码分区/文档网格/titlePg/分页控制/中文排版开关/动态版心宽)、
861
+ `DocxRunFormatExtras`(双删除线/小型大写/字符缩放/复杂文种字号/字体 hint)、
862
+ `DocxFootnoteOps`(脚注尾注);扩展 `DocxStyleOps`(样式创建**与改写**、字符样式)、
863
+ `DocxNumberingOps`(多级编号/样式绑定/一键编号)、`DocxTableOps`(行高/cantSplit/表格布局/边框)、
864
+ `DocxPaths`(`/body/table[T]/row[R]`、`/body/style[ID]`)。
865
+
866
+ 修复的 P0:
867
+
868
+ | 缺陷 | 影响 | 修复 |
869
+ |---|---|---|
870
+ | `pageBreakBefore` 进规则但不被下游识别 | 标记 `fixable=true` 却写不进去 → **check 永不收敛** | `applyParagraphExtras` 委托 `DocxLayoutOps.applyParagraphLayout` |
871
+ | `applyProfile` 编号硬编码 `numId=2` | 文档已占用 numId=2 时挂错编号定义 | 改用 `createStyleBoundHeadingNumbering` 返回值 |
872
+ | bridge 从不读 `outputFile` | 描述承诺「标注版不覆盖原件」落空 | 接上 `outputFile`,缺省自动派生 `<原名>-标注版.docx` |
873
+ | `fontSize` 走 `intProp` + `setFontSize(int)` | **10.5pt 被截断为 10pt**(论文图题/表题标准字号) | 按双精度写 `w:sz`+`w:szCs`(半磅精度) |
874
+
875
+ 另:`keywordCount`/`refCount` 角色级聚合断言从「只在描述里」补成真实实现
876
+ (此前按描述配置会静默零违规);selfcheck 分页识别补齐「显式分页符 + 段前分页 + 分节符」并修正
877
+ **文本归属页**(段前分页段的文本此前被算进上一页);标题级别判定兼容中文样式名「标题 N」与纯 `outlineLvl`。
878
+
879
+ #### 7. 颜色值序列化:`STHexColor` 联合类型陷阱
880
+
881
+ `w:color/@w:val` 的类型是 XMLBeans **联合类型** `STHexColor`——RGB 分支存 3 字节 `byte[]`,
882
+ 另一分支存字符串 `"auto"`,因此 `CTColor.getVal()` 返回 `Object`。
883
+ `DocxStyleResolver` 直接 `String.valueOf(getVal())`,RGB 被渲染成 `[B@74a239d7`。
884
+
885
+ **不只是显示乱码**:`OfficeRuleEngine.compareColor` 拿这个值跟期望值比对,
886
+ 任何带 `color` 期望的规则**都不可能收敛**(fix 写完复检仍报违规,`converged` 永远 false)。
887
+ 读取改走 `xgetVal().getStringValue()`(两类分支都正确),字节分支兜底手写十六进制。
888
+
889
+ 同根因的写入侧缺陷:颜色归一化一律 `toUpperCase()`,把合法的 `auto` 变成非法的 `AUTO`,
890
+ 被 XMLBeans 以「union value 'AUTO' does not match any members」拒绝
891
+ (传 `color="auto"` 清色直接报错)。归一化统一收敛到 `OfficeArgs.normalizeColor` 单点权威
892
+ (命名色表 + `auto` 保留小写),`OfficeDocService` 与 `OfficeRuleEngine` 都委托它;
893
+ xlsx/pptx 无 `auto` 概念,走新增的 `rgbColorOf` 显式拒绝并给可读提示。
894
+
895
+ 顺带修复 `office_view(outline)` 两处同源缺陷:标题判定只认 `styleId` 以 `heading` 开头
896
+ (中文模板「标题 1」与纯 `outlineLvl` 标题全部漏检);表格节点只有行列数,现附加题注文本
897
+ (先取表格前一段、再取后一段,按「表 X-Y」文本特征或题注样式判定,都不中则回退)。
898
+
899
+ > **升级须知**:本版本无破坏性变更。`office_format` 的 `action` 枚举新增 `dryRun`,
900
+ > 旧调用方不受影响;备份文件会在文档同目录产生额外的 `<基名>-backup-*` 文件,
901
+ > 若不希望出现在工作区索引中,可在 `.gitignore` 加 `*-backup-????????-??????.*`。
902
+
903
+ ## v1.9.166
904
+
905
+ _发布日期:2026-10-05_
906
+
907
+ ### 修复:submit_task_result 丢参导致循环节点恒被拒绝提交
908
+
909
+ `handleSubmitTaskResult` 只向 `agentClient.submitTaskResult` 透传了
910
+ `nodeId / outputPayload / changeLog`,而工具 schema 早已声明、服务端也早已消费的
911
+ **`handoverNote` 与 `deliverables` 在这一层被静默丢弃**。后果:
912
+
913
+ - 位于循环路径(模板 `require_handover=true`)的节点,Agent 即便按描述传入
914
+ `handoverNote`,抵达 Java 侧时仍为 null,`validateHandoverNoteIfRequired`
915
+ 恒定抛「必须提供交接经验」拒绝提交 —— 表现为「nodeId 能识别、handoverNote 却
916
+ 永远缺失」的固定失败,Agent 侧穷尽调用通道与字段命名均无法绕过;
917
+ - 结束节点的 `requiredDeliverables` 同理永远收不到交付物,必填项必然判缺。
918
+
919
+ 修复内容:
920
+
921
+ - **补齐 5 参透传**:`handoverNote`(`getOptionalString`)与 `deliverables` 一并
922
+ 下发到 `agentClient.submitTaskResult(nodeId, outputPayload, changeLog,
923
+ handoverNote, deliverables)`。
924
+ - **新增 `prepareDeliverables`**:逐项归一化交付物,文件类(`path`)复用
925
+ `uploadAttachmentFiles` 换取 `url/mediaType/size` 后回传,文本类(`text`)原样
926
+ 透传;无 key 项与空数组安全忽略。服务端 `parseDeliverablesArg` 可直接消费。
927
+ - **changeLog 放宽形态**:数组(MCP 已解析)与 JSON 字符串两种形态均透传,
928
+ 原先只认数组、字符串形态被吞(服务端 `parseChangeLog` 本就两种都支持)。
929
+
930
+ ### 错误结构化:errorCode / field 回传给 Agent
931
+
932
+ 服务端校验失败原先只回 `{"error":"<纯文本>"}`,Agent 只能从中文长句里猜原因。
933
+ 现新增 `McpToolError`(携带 `errorCode` / `field`),`callTool` 抛出时保留,
934
+ `McpToolError` 经 MCP 错误响应原样透出:
935
+
936
+ ```json
937
+ {"error":"该节点位于循环路径…","errorCode":"HANDOVER_REQUIRED","field":"handoverNote"}
938
+ ```
939
+
940
+ 仅新增字段、不改 `error` 语义,向后兼容;Agent 可据此直接补齐入参重试。
941
+
942
+ > **回归锁定**:`mcp-server.test.ts` 的 `submit_task_result` 分发断言原先只校验
943
+ > 3 个位置参数(`["node-1","...",undefined]`),恰好把丢参行为固化,导致测试全绿
944
+ > 而线上必然失败。现改为 5 参断言,并新增 handoverNote / text 交付物 / file 交付物
945
+ > (打桩上传)/ changeLog 字符串形态四条用例。
946
+
947
+ > **兼容性**:MCP 工具 schema 未变更,仅修复「声明了却不转发」的实现缺口;
948
+ > 新旧服务端均可对接(服务端本就接受这两个可选字段)。
949
+
950
+ ## v1.9.165
951
+
952
+ _发布日期:2026-10-03_
953
+
954
+ ### 浏览器画质档位:原画改为无损 PNG,高清 80 / 流畅 60
955
+
956
+ 原先三档都是 JPEG,所谓「原画」实为 JPEG q80;且 tile 差量路径把 CDP 帧解码后
957
+ **再按同一质量重编码一次**,同一区域反复变化时有损伪影逐次累积。
958
+
959
+ - **档位参数改为格式驱动**(`QUALITY_PRESETS` 新增 `format` 字段):
960
+ - `original`:无损 PNG,像素级还原(`quality` 不生效);
961
+ - `hd`:JPEG 80;
962
+ - `smooth`:JPEG 60。
963
+ - **tile 重编码跟随档位格式**(新增 `frame-encode.ts` 统一编码入口):
964
+ 无损档位下增量块同样输出 PNG,不再被二次有损压缩;整帧与 tile 两条路径
965
+ 共用同一实现,避免只改一半造成「整帧无损、增量有损」的错配。
966
+ - **CDP 参数修正**:`Page.startScreencast` 仅在 jpeg 格式下携带 `quality`,
967
+ png 格式传 0 会被 CDP 判为非法参数。
968
+ - **默认格式由默认档位派生**:原先 `DEFAULT_FORMAT` 写死 `'jpeg'`,与默认档位
969
+ `original` 冲突,会让会话初始状态变成「UI 显示原画、实际下发 JPEG q0」。
970
+ - **单帧上限 2MB → 6MB**(`WS_DEFAULT_MAX_SEND_BYTES`):1280×720 的无损 PNG
971
+ 整帧可达 3.5MB 量级,沿用 2MB 会让高熵内容的整帧被静默丢弃,
972
+ 表现为画面冻结并反复 resync。
973
+ - **切换档位时丢弃差分参考帧**:格式变化会改变参考帧的编码语义,
974
+ 沿用旧基准会把新格式首帧差分成跨格式 tile。
975
+
976
+ 前端同步:`createImageBitmap` 不再声明 `image/jpeg`(原画档位是 PNG,
977
+ 声明错误的 MIME 会选错解码路径,改由内容嗅探);画质下拉文案标注「原画(无损)」。
978
+
979
+ > **兼容性**:帧协议未变更(`createImageBitmap` 按内容嗅探格式),
980
+ > 新旧前端均可解码;但旧 bridge + 新前端会失去无损能力(仍为 JPEG)。
981
+
982
+ ## v1.9.164
983
+
984
+ _发布日期:2026-09-26_
985
+
986
+ ### 项目级 / 角色级能力层(inherited 层):bridge 侧落地
987
+
988
+ 能力配置由「全局默认 + 实例覆盖」两级升级为**四层逐键覆盖链**
989
+ (角色实例 > 角色 > 项目 > 全局默认),本版本承接 bridge 侧全部落地。
990
+ 解析权威仍在 Java(`AgentCapabilityService.buildInheritedLayers` 产出「项目 ⊕ 角色」的
991
+ 增量层),bridge 只负责存储与逐键取用:
992
+
993
+ - **能力布尔(MCP / Skill / 插件)**:per-agent 文件由「平铺 map」升级为
994
+ `{ overrides, inherited }` 双子对象;旧平铺文件读作 `overrides`,向后兼容。
995
+ 取值链 `overrides > inherited > 共享默认(config) > deployedDefault > false`。
996
+ 新增整表替换端点 `POST /runtime/{skills|mcp|plugins}/deployed/inherited`
997
+ (`{ agentId, inherited }`,null/缺省 = 清空本层),由 Java fan-out 推送。
998
+ - **工具三态(disabled / collapsed / expanded)**:新增内存层
999
+ `inheritedFeaturesByAgent`,`getFeatureState` 改为
1000
+ `实例显式 > inherited > 内置默认` 逐键解析;**分组父门禁**在合并视图上判定
1001
+ (父主开关 `disabled` 则子能力一律未授权),与 Java `AgentAbilitySwitchService`
1002
+ 同口径。
1003
+ - **分层推送互不覆盖**:全局改动只动共享默认、项目/角色改动只推 inherited、
1004
+ 实例改动只推 overrides —— 因此删掉本层键即可自然露出下层值,
1005
+ 「恢复跟随上层」得以正确工作。
1006
+ - `/runtime/start` 与 `POST /instances/:id/features` 同步接收 `inheritedFeatures` /
1007
+ `capabilitiesInherited` 字段(undefined = 不改动,避免误清空其它实例的推送值)。
1008
+
1009
+ > **升级须知(重要)**:低于本版本的 bridge 不认识 inherited 层,会回退到
1010
+ > 「缺名 = 启用」的迁移期路径,导致**上层已禁用的能力仍被启用**。因此本版本要求
1011
+ > bridge 与 Java 端同批升级;环境变量四层链(v1.9.163 起)不涉 bridge 存储,滚动安全。
1012
+
1013
+ ### 工具批次归组:阻塞型通讯工具移出「并行执行工具」
1014
+
1015
+ `poll_message` / `create_meeting` 这类核心阻塞型通讯工具不再进入工具批次:
1016
+
1017
+ - **移出批次**(不进批次根事件、不带 `batchId`、不计入 `tool_batch_metrics` 的
1018
+ `toolCount`/`traces`),时间线上按普通工具扁平展示;执行本身不变,仍由调度器排到
1019
+ 批尾串行(`poll_message` 的 while(true) 阻塞等待语义不受影响)。
1020
+ - 动因:这两者与本批其他工具毫无并行收益,归进「并行执行工具」卡片会造成双重误导——
1021
+ 卡片名宣称并行、实测 `speedup` 恒为 1.00x;`poll_message` 的阻塞等待也会被错觉为
1022
+ 批次成员。之前的批调用把 `search_memory` 与 `poll_message` 并列,既无加速、又难看懂。
1023
+ - 批次成立条件收紧为「**批次成员**数 > 1」:若排除后成员不足 2 个(如
1024
+ `poll_message` + 单个 `write_file`),则不发根事件与指标,时间线完全扁平。
1025
+ - 运行时新增 `isMcpBatchExcludedToolName`(`mcpToolNames.ts`)作为批次排除判据;
1026
+ 与「MCP 超时策略」集合 `isMcpBlockingToolName` 语义分离。
1027
+
1028
+ 配套 Java 侧(同批发布):`ProjectCapabilityOverrideService` 项目层存储(
1029
+ `project_capability_overrides:{tenant}:{projectId}`)、`AgentCapabilityService`
1030
+ 四层解析与 source 细化(agent/role/project/bridge)、`AgentAbilitySwitchService`
1031
+ 三态四层 + 分组门禁、`RuntimeBridgeService` inherited 推送与 fan-out、
1032
+ 项目/角色能力配置接口与新建项目草稿落库。
1033
+
1034
+ ### 修复:Agent 回到 waiting_input 后长时间"空闲"(每次任务后约 10min 死区)
1035
+
1036
+ 现象:角色实例状态徽章长时间显示"空闲",而时间线最新事件停在"编辑文件";
1037
+ 期间私信/流程线任务完全不消费,约 10 分钟后才自行恢复。
1038
+
1039
+ 根因(`AcodeSdkAdapter`):`turn_complete` 的"用户消息轮调用了工作工具"分支
1040
+ (`!autoPollActive && observedAnyTool && !observedPollingTool`)原本只做 `return`——
1041
+ 既不派发空闲提示词、也放弃了重臂。而 `waiting_input` 下 turn 级看门狗不计时,
1042
+ 会话遂无任何定时器在看守,只能等 10min 会话存活看门狗兜底。
1043
+ 且重试轮(`retryFailedRequest`,`autoPollActive=false`)同样命中该分支,
1044
+ 而该路径不重置观察标记,上一失败轮残留的 `observedAnyTool` 使分支必然成立 →
1045
+ **每次任务结束都固定触发约 10min 死区**。
1046
+
1047
+ 修复(保留"不立即派发"的节流意图,改为**延迟重臂**):
1048
+ - 新增 `ACODE_DEFERRED_IDLE_REARM_MS`(默认 3s,env 可覆盖)与
1049
+ `scheduleDeferredIdleRearm()`:分支 2 不立即派发空闲提示词,但延迟后重臂监听,
1050
+ 把死区从 10min 压到 3s。刻意走 `scheduleAutoPoll` 而非 `armIdleLoopOrAutoPoll`,
1051
+ 避免配置了 polling 类 idle 命令时被 `IdlePollLoop`(0ms)架空延迟。
1052
+ - `armIdleLoopOrAutoPoll` 重臂前清除待触发的延迟定时器(只清 timer、不动退避档位),
1053
+ 防止延迟重臂与正常重臂双发。
1054
+ - `retryFailedRequest` 与其它提交入口对齐,重置 `autoPollObserved*` 三标记,
1055
+ 消除跨轮污染导致的"重试轮被误判为用户消息轮"。
1056
+
1057
+ ## v1.9.163
1058
+
1059
+ _发布日期:2026-09-25_
1060
+
1061
+ ### 三级环境变量(全局 / 项目 / 角色实例)→ 工具子进程 + MCP 配置
1062
+
1063
+ 环境变量由单一「面板全局层」升级为**三级合并**(角色实例 > 项目 > 全局,择近优先),
1064
+ 合并结果随 `/runtime/start` 下发,作用于 bridge 管理的工具子进程与 MCP stdio 服务器配置。
1065
+ Java 侧 `EnvVarResolver` 为唯一权威计算点,本版本承接 bridge 侧全部落地:
1066
+
1067
+ - **per-agent 环境变量存储**:`panel-env` 由进程级单例改为按 agentId 键控。此前最后启动的
1068
+ 实例会覆盖整个 bridge 的环境变量(多实例静默串味);现在各实例独立,桌面工具子进程按
1069
+ 调用方实例取值,切换实例时经 env 签名检测触发重启应用新值(`ownerAgentId` 记录归属)。
1070
+ - **MCP stdio spec 注入**:MCP 子进程**不继承 bridge 的 `process.env`**(MCP SDK 的
1071
+ `StdioClientTransport` 只带 HOME/PATH 等少数键),故新增 `mcp-env-injector` 把有效环境变量
1072
+ 写入每个 stdio server 的 `env`。优先级:**server 自身 env > 三级合并结果 > SDK 默认继承项**;
1073
+ 内置 `agents-work-studio` 与 sse/http 服务器跳过。acode(per-instance acode.json 装配)
1074
+ 与 Claude SDK 两条适配器路径均已接入。
1075
+ - **`${VAR}` 占位符展开**:stdio spec 的 `env` 值与远程 spec 的 `url` / `headers` 值中的
1076
+ `${变量名}` 按该实例有效环境变量展开(如 `Authorization: "Bearer ${API_KEY}"`);
1077
+ 未命中的占位符保持原样,便于在 MCP 启动失败信息中定位拼写错误。
1078
+ - **子进程 env 安全名单**:新增 `utils/env-safety.ts`,把原 plugin-manager 的
1079
+ `BLOCKED_ENV_KEYS` 集中为单点权威并新增 `sanitizeEnvForChild`,在面板环境变量入站、
1080
+ MCP spec 注入、桌面子进程显式覆盖层三处统一把关(挡掉 `NODE_OPTIONS` / `LD_PRELOAD` /
1081
+ `PATH` 等执行流劫持与宿主关键路径键)。
1082
+
1083
+ 配套 Java 侧(同批发布):`EnvVarResolver` 三级合并与「空串=屏蔽」解析、`t_agent.env_overrides`
1084
+ 实例层存储、项目级 `project_env_vars:*` 存储与掩码读写、有效值预览接口、三级配置 UI。
1085
+
1086
+ ## v1.9.162
1087
+
1088
+ _发布日期:2026-09-24_
1089
+
1090
+ ### 工具懒加载:browser / desktop 收纳态展开链路打通(关键修复)
1091
+
1092
+ v1.9.153 起 browser / desktop 改为**收纳态不注入会话工具列表**(缓存稳定化的
1093
+ 前提:LLM 请求的 tools 前缀字节级不变,provider 前缀缓存全程命中),工具定义改由
1094
+ `expand_tools` 结果下发、执行经 `call_tool` 回传。但回传链路在重构中被删除且未补回,
1095
+ 导致收纳态(默认档)下:
1096
+
1097
+ - `expand_tools({group:"browser"})` 从本地 `exposedTools` 取 manifests → 收纳态下
1098
+ 必然为空(工具按设计就没注入),agent 拿到 0 个工具定义;
1099
+ - `call_tool({name:"browser_navigate"})` 找不到工具名 → 直接报「未知工具」;
1100
+ - bridge 侧 `POST /sessions/:agentId/capability-tools[/call]` 端点恢复后**没有任何调用方**
1101
+ (原 MCP Server 中继 `setBridgeCapabilityTools` / `handleExpandTools` 已随重构移除)。
1102
+
1103
+ 本次以**同进程中继**补齐(不改 tools/list 载荷,缓存稳定性不回退):
1104
+
1105
+ - ACode 新增 `CapabilityToolRelay` 契约(`tool-group-manager.ts`)+ 运行时配置
1106
+ `capabilityToolRelay`(`types.ts`),`expand_tools` / `call_tool` 的桥接组分支经其
1107
+ 回传;本地组(pencil / draw / office / launch / hire / task / meeting / debug /
1108
+ fileHistory)路径完全不变。
1109
+ - 展开:先中继(`setBuiltInCapabilityTools(expand)` 刷新定义缓存并授予调度授权、
1110
+ 返回 manifests),成功后才置本地展开态 —— 中继失败可重试,不留半展开态;
1111
+ - `group="all"`:桥接组经中继拉 manifests,`disabled` 静默跳过、单组失败不阻断其余组
1112
+ (该组 `call_tool` 会被拒并提示重新 expand,自愈);收起时桥接授权全部回收;
1113
+ - 调度:`findTool` 落空且工具名归 bridge 托管时,按 `call_tool` 三道闸同口径的
1114
+ 本地预检(`disabled` 拒绝 / 未展开引导 expand)后执行 `callBuiltInCapabilityTool`。
1115
+ - `AcodeSdkAdapter` 会话启动时注入中继(同进程直连,无 HTTP、无 token 依赖;
1116
+ HTTP 端点 `capability-tools[/call]` 保留供外部/兼容调用)。无 `agentId` 时不注入,
1117
+ 退化为本地查找(与启动注入的缺省兜底一致)。
1118
+
1119
+ 配套测试:acode `tool-group-manager.test.ts` 新增「capabilityToolRelay」12 项(展开
1120
+ manifests 来自中继、幂等、失败不留状态且可重试、disabled 不触中继、group=all 混合
1121
+ 本地+桥接+disabled、收起回收、调度透传参数/未展开拒绝/disabled 拒绝/错误透传/
1122
+ 非桥接未知工具不触中继);bridge `AcodeSdkAdapter.test.ts` 新增端到端用例
1123
+ (启动注入中继 → `expand` 下发 manifests 且不注入 exposedTools → `call` 执行 →
1124
+ `collapse` 后调度被拒)。bridge 套件 1473 通过 + 4 跳过、acode 743 通过。
1125
+
1126
+ ### 工具组:ACode 短 key ↔ 能力 featureKey 错位修复
1127
+
1128
+ `collaboration.*`(流程任务 / 会议 / 调试日志 / 文件变更历史)与 `agentSys.launchItem` /
1129
+ `agentSys.hire` 的工具组短 key(`task` / `meeting` / `debug` / `fileHistory` / `launch` /
1130
+ `hire`)与完整 featureKey 不一致,ACode 侧把「收纳」误判为「禁用」(实测确认):
1131
+ 系统提示词把已授权能力显示为未开启、`expand_tools` 直接拒绝。本次新增
1132
+ `GROUP_KEY_TO_FEATURE` 映射与 `resolveGroupFeatureKey()`(`instance-features.ts`),
1133
+ `capabilityState` 回调先归一再取三态;同时补齐父门禁级联
1134
+ (`collaboration` / `agentSys` 主开关 `disabled` 时其子能力一律 `disabled`),
1135
+ 与前端清除子键、Java 门禁传播同口径。
1136
+
1137
+ 工具组归属推断同时加固(`tool-group-manager.ts`):不再只认 `key_` 前缀,注册的
1138
+ 精确 `toolNames` 先于前缀命中,`listToolManifests` 忽略 MCP 的 `serverName__` 命名空间
1139
+ 取裸名匹配 —— `my_task` / `create_meeting` / `query_debug_logs` /
1140
+ `query_file_changes_history` 等非前缀命名的 MCP 工具组据此正确归组与下发定义。
1141
+
1142
+ ### 协作能力分组:默认收纳 + 父门禁级联
1143
+
1144
+ `instance-features.ts` 新增 `collaboration` 主开关与 `collaboration.task` /
1145
+ `collaboration.meeting` / `collaboration.debug` / `collaboration.fileHistory` 四个子能力
1146
+ (默认收纳),ACode 侧注册同名工具组;四个分组在收纳态下不进 LLM 工具列表,经
1147
+ `expand_tools` 展开后由 `call_tool` 调度。
1148
+
1149
+ ### 工具并发执行(资源驱动调度)
1150
+
1151
+ 新增 `tool-concurrency/` 子系统(`types` / `resource-lock` / `scheduler` /
1152
+ `observability`),ACode 一条 LLM 响应返回多个 `tool_calls` 时按**资源冲突关系**
1153
+ 并发而非按工具类型分组,并新增运行时配置 `toolConcurrency`
1154
+ (`enabled` 默认 true、`maxReadOnly` 默认 8、`maxBash` 默认 0=不限):
1155
+
1156
+ - 资源键层级(`file:` / 目录前缀 / `bash:` 等)与祖先-后代判定;区间重叠即冲突;
1157
+ - 同资源读写按读写锁串行,写-写互斥;未声明并发策略的工具(如 bridge 注入的
1158
+ `browser_` / `desktop_`)默认独占串行 —— 关闭 `enabled` 即退化为旧的串行行为;
1159
+ - `ToolTraceRecorder` 记录每个工具的 waiting_resource / running / completed 时序并聚合
1160
+ 批次度量(墙钟、并行度、等锁总时长、竞争次数、加速比),`ConcurrencyLimiter` 提供
1161
+ 只读 / Bash 并发上限;
1162
+ - 文件工具声明资源键(`buildFileResourceKey` / `fileResourceClaim`),读 `read`、
1163
+ 写 `write`。
1164
+
1165
+ ### 文件写入 stale guard(陈旧写入拒绝)
1166
+
1167
+ 新增 `read-file-state.ts`:`read_file` 记录 mtime / size / 内容快照,`edit_file` /
1168
+ `write_file` 落盘前比对,文件在上次读取后被外部修改(且内容与快照不匹配)时拒绝写入
1169
+ 并提示模型重读,避免并发会话/外部编辑器改动被静默覆盖。运行时开关
1170
+ `enableStaleFileGuard`(缺省启用,`false` 关闭比对;状态仅存内存,`stop()` 清空)。
1171
+
1172
+ ### 工具权限:新增 `fileModificationOutside` 档位
1173
+
1174
+ 「限制操作」新增工作区外文件修改权限(`fileModificationOutside`),
1175
+ `resolveAgentToolPermissions` 全 allow 兜底值同步补齐,热推路径显式下发默认值以
1176
+ 清除历史限制。
1177
+
1178
+ ### 会话启动令牌吊销与运行时钟强化
1179
+
1180
+ - `RuntimeGlobalSettingsService` 启动时吊销历史运行令牌,避免重启后旧令牌继续可用。
1181
+ - `terminal.ts` 抽出 `isIdleStatusChangeRetryable()`:`waiting_input` 纯状态切换
1182
+ (`turn_complete` 仅带 usage、不带 `actionType`)也纳入 idle 串行重试队列,
1183
+ 修复该类状态切换漏到零重试路径的问题;原 `!params.actionInfo` 空判改为
1184
+ `!params.actionInfo?.actionType`。
1185
+
1186
+ ### LTR 临时文件读取端点
1187
+
1188
+ `POST /api/ltr/read`:按绝对路径返回 LTR 临时文本内容,安全校验拒绝 `LTR_ROOT`
1189
+ 目录树之外的路径(防路径穿越),文件不存在 404、非文件 400、上限 512KB。
1190
+
1191
+ ### Agent Todo 重置与 acode-todos 路由
1192
+
1193
+ `AgentTodoService` / `routes/acode-todos.ts` 支持重置(清空)会话待办列表,
1194
+ 配套 `acode-todos.test.ts` 覆盖重置语义。
1195
+
1196
+ ### 空闲监听指令(poll_message)措辞收敛
1197
+
1198
+ `MESSAGE_POLLING_IDLE_PROMPT` 改为显式前置条件:「此指令仅在当前没有未完成任务时生效;
1199
+ 若仍在处理任务请忽略本指令并继续执行」,仅在确认无进行中/未完成任务时才调用
1200
+ `poll_message`,降低任务中途被空闲轮询打断的概率(三个 adapter 的单测改为从
1201
+ `prompts.ts` 导入常量,避免文案与断言再次脱节)。
1202
+
1203
+ ### 依赖与其它
1204
+
1205
+ - `aws-client-agent-mcp` 新增 `temml`(Office 公式渲染)依赖,新增
1206
+ `office_format` / `office_apply_profile` / `office_generate_from_template` 三个
1207
+ Office 工具及 `office-equation.ts` 公式模块(含测试)。
1208
+ - `AcodeSdkAdapter` 恢复 `POST /sessions/:agentId/capability-tools[/call]` 路由,
1209
+ `resolveAdapter(providerId)` 按会话 providerId 解析适配器;sessions 测试 29 项通过。
1210
+ - 版本号 1.9.157 – 1.9.162 为连续未发布开发周期(npm 上仍为 1.9.153),
1211
+ 本次一并发布。
1212
+
1213
+ ## v1.9.161
1214
+
1215
+ _发布日期:2026-09-18_
1216
+
1217
+ ### Office 题注位置与回执提示修复(依据 v4 回归报告 N7/N8)
1218
+
1219
+ **N7:`captioned_table` 题注位置对齐中文论文规范**
1220
+
1221
+ 中文论文(学位论文)规范要求「图题在下、表题在上」,本项目脚本产物同样如此;
1222
+ 此前 `captioned_table` 一律把题注插在表格**下方**,用工具链重做论文逐页比对时会显现差异。
1223
+ 现按元素类型区分默认位置:
1224
+
1225
+ - `captioned_image`:题注默认在图片**下方**(行为不变)
1226
+ - `captioned_table`:题注默认在表格**上方**
1227
+ - 新增 `props.captionPosition`(`above`/`below`,兼容 `top`/`before`/`bottom`/`after`)显式覆盖
1228
+
1229
+ 实现:新增 `insertParagraphBeforeElement`(表题在上的插入路径);章内序号统计按位置
1230
+ (章标题之后、插入点之前)计算,因此「表题在上」不改变编号连续性。
1231
+
1232
+ **N8:`office_edit` 回执未透传服务端 warnings**
1233
+
1234
+ 服务端(Java)已在 `chapterHeadingStyle=false` 等场景返回 `warnings`,但 bridge 层
1235
+ `officeEdit` 组装回执时丢弃了该字段,使用者无法感知「F9 后编号不会按章重启」的风险。
1236
+ 现原样透传 `warnings`(服务端未返回时不产生空数组噪音)。
1237
+
1238
+ 配套回归测试:`OfficeDocxPrecisionTest` 新增 4 个用例(表题默认在上、图题默认在下、
1239
+ captionPosition 显式覆盖、表题在上时序号连续);bridge `mcp-server.test.ts` 新增 2 个
1240
+ 用例(warnings 透传、无 warnings 时不含该键)。office 测试总数 179 全通过;
1241
+ Word COM F9 实测题注编号稳定(表1-1/表1-2/表2-1、图1-1/图1-2/图2-1)。
1242
+
1243
+ ### ACode 模型请求失败重试不再重置上下文
1244
+
1245
+ 模型请求超时/网关 5xx/看门狗中止后的重试此前会重新走主动压缩预检:一旦累计或估算
1246
+ 用量越过阈值,与上下文大小无关的失败重试也会裁剪+摘要化历史,表现为「重试后上下文
1247
+ 被重置」。本次修复:
1248
+
1249
+ - **恢复式重试(resume,与失败请求逐字节一致)**:非溢出的普通失败(5xx/超时/看门狗)
1250
+ 后,适配器以 `resume: true` 恢复同一轮——不重发 prompt 钩子、不重复 push 用户消息、
1251
+ **不回滚轮内进展**(工具结果/部分输出原地保留),基于与失败请求同一份 conversation
1252
+ 重建请求:重试请求与上次失败的请求逐字节一致,重试之前的状态不丢失。原先的失败轮
1253
+ 锚点回滚(`rollbackFailedTurn`)会把会话截回 turn 开始前、丢弃轮内已成功的迭代,已移除。
1254
+ - **轮级跳过压缩**:重试 submit 携带 `skipProactiveCompaction`(resume 隐含),覆盖整轮
1255
+ 全部 LLM 迭代,并同时约束 800KB 请求体字节上限截断(`truncateConversationIfNeeded`),
1256
+ 旧版 `markSkipNextCompaction()` 单次标记兼容保留;仅 provider 显式溢出信号(错误字段/
1257
+ `finish_reason`)触发响应式压缩重建,413 溢出仍正常兜底——上下文改写只属于溢出响应。
1258
+ - **结构化溢出判定**:新增 `context-overflow.ts`(cause 链下钻 + 字段级标记 + 精选消息
1259
+ 片段),`length`/`max_tokens` 被输出长度标记独占短路,绝不因输出上限触发压缩。
1260
+ - **4xx 确定性错误短路重试**:invalid_request 类错误直接 `retry_aborted`(「请求无效」),
1261
+ 5xx/超时仍按指数退避+抖动重投。
1262
+
1263
+ 配套回归测试:acode `runtime.test.ts` 新增/强化 5 个用例(resume 重试请求体逐字节一致
1264
+ 且不重复 push、中途失败保留轮内工具结果后 resume 与失败迭代逐字节一致、整轮跳过主动
1265
+ 压缩、legacy 单次标记、重试轮跳过 800KB 字节截断而普通轮照常截断);bridge
1266
+ `AcodeSdkAdapter.test.ts` 断言重试提交携带 `resume + skipProactiveCompaction`,并含
1267
+ 4xx 短路与重试计数语义用例(套件 82/82 通过)。
1268
+
1269
+ ## v1.9.160
1270
+
1271
+ _发布日期:2026-09-18_
1272
+
1273
+ ### Office 题注编号与格式检查修复(依据 v3 回归报告 N1-N6)
1274
+
1275
+ **N1(高):SEQ 域 `\s` 值写成了章号,F9 后含小节的章出现重复编号**
1276
+
1277
+ `\s N` 的 N 是**标题级别**(1-9),不是章号。原实现写 `SEQ figure \s <章号>`,导致:
1278
+ 含 H2 小节的章在每次小节标题处错误重启(实测 Word F9 后 图2-1 重复出现),
1279
+ 第十章还会写出超范围值 `\s 10`。现固定为 `SEQ figure \s 1`(按 1 级标题重启),
1280
+ 章号只体现于静态前缀;章内序号改为按「本章范围内、插入点之前」的实际域数量统计
1281
+ (`countSeqFieldsBefore`),与 `\s` 值彻底解耦。
1282
+
1283
+ **N2(中):题注按章重启依赖章标题具备「标题 1」样式,此前不校验也不提示**
1284
+
1285
+ Word 的 `\s 1` 按**样式名为内置「标题 1」**的段落重启(COM 实测:仅补直接格式
1286
+ `outlineLvl` 或自定义名样式均无效)。而论文类模板常把章标题写成直排格式(无样式),
1287
+ 此时 F9 后编号会跨章累计。修复:
1288
+
1289
+ - `captioned_*` 在 `chapterTracker=auto` 时自动为识别出的章标题补「标题 1」样式
1290
+ (新增 `DocxStyleOps`:找样式 → 套用并逐项还原差异 → 若仍不等价则回退到工具自建的
1291
+ **最少格式「标题 1」样式**,保证可见外观零变化)
1292
+ - 新增 `props.chapterHeadingStyle=false` 可关闭自动补样式(回执带 `warnings` 说明风险)
1293
+ - `office_edit` 回执新增 `warnings` 字段
1294
+
1295
+ **N3(低):`props.heading` 传数字不生效(静默)**
1296
+
1297
+ 数字 `1`、字符串 `"1"`、`"Heading1"`、`"标题 1"` 现均可用;非法值(`"abc"`、越界 `4`)
1298
+ 改为**显式报错**,不再静默不加样式。
1299
+
1300
+ **N5:check 空段落噪音**
1301
+
1302
+ `office_format` 默认跳过无文本段落(空段落/纯图片段落)的正文类检查与修正,
1303
+ summary 增加 `skippedBlankParagraphs`;`rules.blankParagraphPolicy="report"` 可恢复旧行为。
1304
+ 实测重生成论文违规数 421 → 199(其中 222 条为纯空段落噪音)。
1305
+
1306
+ **N6:preset 与模板实测口径统一**
1307
+
1308
+ - profile 聚合修正「非空众数」偏差:此前 114 段中仅 1 段 `bold=true` 也会输出 `bold=true`
1309
+ (回灌 apply_profile 会把全文错误加粗);现按全量多数票取值,未显式设置的属性不输出
1310
+ - 新增 `OfficeFormatPresets.merge(base, overrides)` 与 `office_format` 的 `mergePreset=true`:
1311
+ 以 preset 为基线、实测 profile 逐键覆盖(page/rules[role].props/roles),
1312
+ 解决「preset 期望黑体 vs 模板实测宋体」的系统性差异导致的验收比对失真
1313
+ - 合并时归一「首行缩进/悬挂缩进」互斥(OOXML 中两者共存只有悬挂生效,会造成
1314
+ check 期望与实际永不收敛);写入端同步加固
1315
+
1316
+ **实测验收**:模板实测 profile + preset 合并后,对重生成论文 check→fix→check
1317
+ 收敛 219 → 0;对既有论文 179 → 0(此前因缩进互斥存在 12 条不可收敛残留)。
1318
+
1319
+ 配套回归测试:`OfficeDocxPrecisionTest` 新增 11 个用例(SEQ 恒定值、同章序号解耦、
1320
+ 章标题样式自动补/外观保持/可关闭、heading 数字与非法值、空段落跳过与 report 策略、
1321
+ preset 合并与缩进互斥收敛、profile null 噪声);office 测试总数 175 全通过。
1322
+
1323
+ ### office 卡片:指定文件强校验 + 预览链接服务端权威化
1324
+
1325
+ **背景**:office 卡片的 `card.previewUrl` 此前由 agent 自报、bridge 与 Java 两端均无校验
1326
+ (纯透传),前端直接塞进无 sandbox 的 iframe——agent 可拼造任意地址(含站外页面)。
1327
+ 同时卡片引用的文件是否真实存在没有任何服务端校验。
1328
+
1329
+ **新契约**:office 卡片只能用 `filePath`(工作区路径)或 `docId`(云文档 id)之一指定
1330
+ 文件,二者必居其一、不可同时传;`previewUrl` 从入参契约中移除,由服务端生成。
1331
+
1332
+ - **bridge(发送前校验,失败即工具调用失败、消息不发送)**:`buildOfficeCardPayload`
1333
+ 重写——filePath 经 `packOfficeFile` 统一校验(存在/普通文件/docx-xlsx-pptx/≤16MB)后
1334
+ 上传,载荷换成 `{type,name,kind,fileUrl,sizeKb,title,filePath,workspacePath}`;
1335
+ docId 路径本机零上传,载荷只带 `{type,docId,title?,description?}`;
1336
+ 两者同传 / 都缺 / 只传 fileUrl 均抛错。入参即使携带 `previewUrl` 也被丢弃。
1337
+ - **服务端(落库前权威校验)**:`McpToolHandler.toCardJson` 的 office 分支改为委托
1338
+ `OfficeToolHandlers.normalizeOfficeCard`——校验 filePath/docId 二选一;filePath 路径
1339
+ 按 `fileUrl` 反解存储名并 `loadFile` 确认文件真实存在;docId 路径经
1340
+ `OfficeCloudDocService.findDoc` 校验云文档有效(不存在则工具调用失败、消息不落库)
1341
+ 并回填 name/kind/fileUrl/sizeKb。
1342
+ - **预览由服务端生成**:取权威文件字节 → `OfficeDocService.buildPreviewHtml` →
1343
+ `FileStorageService.storeFile("...-preview.html", ...)` → 服务端 `previewUrl` 写入卡片。
1344
+ 文件字节无法解析(损坏/伪装扩展名)时发送失败,杜绝「卡片指向不存在的文件」。
1345
+ - **工具描述**:`send_group`/`send_private` 的 `card` schema 删除 `previewUrl` 属性,
1346
+ `docId`/`filePath` 描述改写为「二选一」口径;`office_preview` 描述改为「返回地址供自检/
1347
+ 留档,卡片预览由服务端生成」。
1348
+ - **dashboard**:新增 `utils/officeCardUrl.ts` 信任边界(`fileUrl` 只放行本站
1349
+ `/api/files/` 地址,`previewUrl` 额外要求 `.html`;伪协议/携带凭据/站外链接一律拦截),
1350
+ `ChatPanel.vue` 的预览按钮、点击、下载统一走该校验;预览 iframe 加
1351
+ `sandbox="allow-same-origin"` 与 `referrerpolicy="no-referrer"`;卡片带 `docId` 时
1352
+ 「面板打开」直接按 docId 打开 Office 面板(跳过工作区路径匹配)。
1353
+
1354
+ 配套回归测试:bridge `mcp-server.test.ts` 新增 office 卡片 9 个用例(上传路径/预览地址
1355
+ 丢弃/文件不存在/非 Office 扩展名/docId 零上传/二选一冲突/两者都缺/只传 fileUrl/DM 路径),
1356
+ `mcp-tools.test.ts` 新增 schema 契约 2 个用例;dashboard `officeCardUrl.test.ts` 7 个用例。
1357
+
1358
+ ## v1.9.159
1359
+
1360
+ _发布日期:2026-09-17_
1361
+
1362
+ ### Office 回归修复(依据 v1/v2 回归报告)
1363
+
1364
+ **严重:lineSpacing 提取值错误(会导致排版全毁)**
1365
+
1366
+ `office_view(mode=profile)` 提取的 `body_text.lineSpacing` 为 `0.075` 而实际应为 `1.5`——
1367
+ `DocxStyleResolver` 已把 twips 转为磅值,profile 聚合时又按 twips 除以 240(等效多除 20)。
1368
+ 现改为 `pt / 12` 得到倍数,与规则引擎 `normalizeLineSpacing` 对齐;提取值回灌
1369
+ `office_apply_profile` 后行距正确(360 twips = 1.5 倍)。
1370
+
1371
+ **chapterTracker 跨章失效**
1372
+
1373
+ `captioned_image` / `captioned_table` 在第二章后仍生成「图1-1」。修复:
1374
+
1375
+ - 按 `before`/`after`/`index` 解析真实插入落点(而非扫描全篇)
1376
+ - 章号判定同时支持 Heading1 样式、大纲级别 0、「第X章」中文数字(`chineseNumeralToInt`)
1377
+ - 章内序号按 `SEQ ... \s N` 分组计数,跨章正确重启
1378
+
1379
+ **SEQ 域缓存值与静态前缀叠加(显示「图1-1 前台首页1」)**
1380
+
1381
+ 题注以 `{seq}` 为界拆分为「静态前缀 run + SEQ 域 + 静态后缀 run」,域缓存值即章内序号,
1382
+ Word/WPS 打开即为正确编号,F9 刷新后保持一致。
1383
+
1384
+ **heading1 角色漏识别**
1385
+
1386
+ `OfficeRoleDetector` 新增大纲级别判据与中文样式名支持(`headingLevelOfStyle`:`Heading 1` /
1387
+ `标题 1`),章标题正则放宽空格并补充裸数字章标题兜底。
1388
+
1389
+ 配套新增 10 个回归测试;office 测试总数 161 全通过。
1390
+
1391
+ ## v1.9.158
1392
+
1393
+ _发布日期:2026-09-17_
1394
+
1395
+ ### Office 模板对齐类文档生成增强(F1-F6)
1396
+
1397
+ 将「参考模板 → 逐项对齐样式 → 一键出稿」的论文类任务能力沉淀为 office 工具链通用能力,
1398
+ 仍基于 Apache POI 纯格式层(无 COM、无外部进程)。新增 2 个工具 + 2 个 office_view 模式,
1399
+ 扩展 office_edit 两种带题注元素与表格列声明。
1400
+
1401
+ **新工具**
1402
+
1403
+ - `office_apply_profile`:按样式 Profile 对匹配角色段落规整字体/字号/行距/缩进/对齐 +
1404
+ 页面设置 + 标题编号;值稳定(重复应用不回退、不翻倍)。
1405
+ - `office_generate_from_template`:`{{var}}` 全文跨 run 替换 + 内容清单注入
1406
+ (heading/paragraph/image/table/pageBreak)+ 可选 profile 应用;`outputFile` 指定时保留模板。
1407
+
1408
+ **office_view 新 mode**
1409
+
1410
+ - `profile`:从模板 docx 提取按角色聚合的样式 Profile(page/roles/rules/numbering),
1411
+ 作为 apply_profile 的输入;role 附 `matchSource`/`sampleText`/`paragraphCount` 审计元数据。
1412
+ - `selfcheck`:按分页符拆页,逐页 `textDigest` + 标题层级跳跃/图片溢出/宽表 warning,
1413
+ 并复用规则引擎补充格式违规检查。
1414
+
1415
+ **office_edit 扩展**
1416
+
1417
+ - `add type=captioned_image / captioned_table`:一条命令插入图片/表格 + 居中题注段
1418
+ (SEQ 域,Word F9 可刷新);`caption`/`captionText` 双字段兼容;`chapterTracker=auto` 自动判章。
1419
+ - `add type=table` 新增 `columns: [{widthPt, align}]` 列宽(pt→dxa)与列对齐声明。
1420
+
1421
+ **回归修复**
1422
+
1423
+ - 修复 `office_create` 漏传 `template` 参数(bridge 侧)。
1424
+ - 修复 `captioned_*` 题注未写入(参数名不一致 + 题注段与内容段共用锚点)。
1425
+ - 修复 `office_generate_from_template` 的 `outputFile` 不生效(模板被就地污染)。
1426
+ - profile 角色识别增强:TOC/附录等辅助样式不再污染正文/标题统计。
1427
+
1428
+ 详见 `docs/Office文件操作能力实施方案.md` §12。
1429
+
1430
+ ## v1.9.157
1431
+
1432
+ _发布日期:2026-09-16_
1433
+
1434
+ ### Office 精准操作能力大版本:Word 内核 / Excel / PPT / 公式 / 规则引擎
1435
+
1436
+ 对标参考开源实现(WordFormat、学术 skills 等)完成 Office 三件套从「能创建」到
1437
+ 「精准操作」的升级:run 级定位、批注修订、公式目录页码、版式占位符、格式规则
1438
+ 检查与一键修正。全部基于 Apache POI 5.2.5 纯格式层实现,无 COM/无外部进程。
1439
+
1440
+ **Word 精准编辑内核(docx)**
1441
+
1442
+ - 路径寻址扩展:`/body/p[N]/run[M]`(run 级)、`/body/table[T]/row[R]/cell[C]`(单元格)、
1443
+ `/body/sectPr`(页面)、`/body/header|footer`(页眉页脚)
1444
+ - 新增 `DocxStyleResolver`:docDefaults → basedOn 链 → 直接格式的**有效格式解析**
1445
+ (含主题字体兑现),支撑 `view styles` 与规则引擎「改得准、查不误报」
1446
+ - 新能力:`op=replace`(跨 run 保格式查找替换)、批注(写/读/删,五件套部件)、
1447
+ 修订(tracked 编辑 + accept/reject)、目录 TOC 域 + updateFields、PAGE/NUMPAGES/SEQ 域、
1448
+ 页码页脚、书签 + 外链/内链超链接、**引用上标 [n] + 锚点内链**、OMML 公式(行内/块级/编号公式三列表)、
1449
+ **自定义标题编号**(第%1章模板 + 清除手动编号)、三线表(threeLine 预设)、
1450
+ 段落字符单位缩进(firstLineChars)、中英文字体三槽(fontEa/fontAscii/fontHAnsi)
1451
+ - `office_create` 支持 `template: cn-thesis`(A4+2.5cm、宋体/黑体样式体系、标题编号、页码)
1452
+ - `office_view` 新 mode:`styles`(有效格式)、`comments`、`revisions`、`search`(query 定位)
1453
+ - `office_validate` 增加 OOXML 结构检查:批注范围配对、w:del/w:ins 规范、xml:space
1454
+
1455
+ **Excel 增强(xlsx)**
1456
+
1457
+ - `add chart`(bar/column/line/pie/doughnut/area,XDDF 原生图表)、单元格批注、
1458
+ 数据验证(list/whole/decimal/date/textLength/custom)、条件格式(cellIs/containsText/colorScale)、
1459
+ 带位移插入/删除行(不覆盖相邻数据)、按范围拆分合并、富文本单元格(runs 数组)、
1460
+ 定义名称、页面设置(方向/缩放/打印区域)、自动筛选、行列隐藏
1461
+
1462
+ **PowerPoint 增强(pptx)**
1463
+
1464
+ - 演讲者备注(`set /slide[N]/notes`,view notes 读取)、**版式感知创建**(add slide + layout/layoutIndex,
1465
+ view layouts 清单)、占位符直接赋值(`/slide[N]/placeholder[type|idx]`,保留模板样式)、
1466
+ 全 deck 查找替换(可限定单页)、表格单元格写入(`/shape[M]/cell[R][C]`)、
1467
+ 形状旋转/z-order(up/down/top/bottom)/超链接、**幻灯片克隆**(op=clone:复制文本/图片/备注/版式,
1468
+ 源页隔离,插入位置可控)
1469
+
1470
+ **公式链路(bridge)**
1471
+
1472
+ - 新建 `src/office/office-equation.ts`:`props.latex` → temml(MIT)LaTeX→MathML →
1473
+ 自研 MathML→OMML 转换(覆盖分数/根式/上下标/极限/求和积分/矩阵/括号分组),
1474
+ 失败时给出可读错误;`office_edit` 自动预处理 latex → omml 上行 Java 注入
1475
+
1476
+ **格式规则引擎(差异化能力)**
1477
+
1478
+ - 新工具 `office_format`:`{file, action: check|fix, preset|rulesFile|rules, annotate?, outputFile?}`
1479
+ - 角色识别(三层):Word 样式 → 正则启发式(第X章/图题/摘要/参考文献等)→ 显式匹配器
1480
+ - 检查:逐角色比对期望格式 → 违规清单(path/role/property/actual/expected/fixable/severity)+ 摘要;
1481
+ `annotate:true` 把违规写成 Word 批注生成标注版(不覆盖原件)
1482
+ - 修正:确定性项自动改(字体三槽/字号/加粗/对齐/行距/缩进/编号/手动编号清除),判断类只报告
1483
+ - 预置:`cn-thesis`(学位论文)、`cn-report`(公文);rulesFile 支持工作区 YAML/JSON
1484
+ - 收敛性验证:fix 后复查零违规(加权优先级 + 半磅字号 + 悬挂缩进语义)
1485
+
1486
+ **预览增强(docx HTML 预览)**
1487
+
1488
+ - 批注标记(含正文悬浮)、修订 ins/del 着色、公式文本化、TOC 占位、
1489
+ 域友好占位(〔页码〕)、超链接渲染为可点击 a[href]、上下标
1490
+
1491
+ **测试**
1492
+
1493
+ - Java:新增 `OfficeDocxPrecisionTest`(25 用例)、`OfficePptxAdvancedTest`(11 用例)、
1494
+ `OfficeFormatEngineTest`(9 用例)等,全量 1442 用例通过
1495
+ - bridge:新增 `office-equation.test.ts`(17 用例)+ mcp-tools 描述契约测试;
1496
+ `tsc` 与本套件通过
1497
+ - 前端:`officeTimeline` 支持 office_format 事件刷新,测试补齐
1498
+
1499
+ ## v1.9.156
1500
+
1501
+ _发布日期:2026-09-13_
1502
+
1503
+ ### Office 三件套能力升级:图片、排版、形状
1504
+
1505
+ 按照 genoffice 对标,大幅增强 Office 文件引擎和工具描述,agent 现在可以生成含图片、列表、格式化表格的工作级文档。
1506
+
1507
+ **Java POI 引擎**(OfficeDocService.java)
1508
+
1509
+ - **图片基础设施**:严格 Base64 校验 + 魔数嗅探(PNG/JPEG/GIF/BMP/TIFF,WebP 等明确拒绝)+ ImageIO 像素尺寸读取 + 等比缩放辅助
1510
+ - **docx 新增**:`add image`(source 支持工作区路径 / http URL / data URL → bridge 侧解析,Java 无状态接收 imageBase64)、`add pageBreak`、列表(`list: "bullet"|"number"` + `level: 0-2` 惰性初始化 XWPFNumbering)、`set /body header/footer`、段落 `pageBreakBefore`
1511
+ - **xlsx 新增**:单元格 `numberFormat`(`0.00%`、`¥#,##0`、`yyyy-mm-dd` 等)、`border`+`borderColor`(thin/medium/thick/dashed/dotted/double)、`wrapText`、`valign`(top/center/bottom)、工作表 `colWidth`(px)、`rowHeight`(pt)、`freeze`(行/列)、`add merge`(range 字符串)、`add image`(anchorCell + 图片字节 → XSSFDrawing)
1512
+ - **pptx 新增**:`add image`(fit=contain/cover/stretch,cover 写 srcRect 裁剪)、`add shape`(rect/roundRect/ellipse/triangle/diamond/chevron 等 + fillColor/lineColor/lineWidth + 垂直居中文字)、`add table`(均分列宽行高 + header 加粗)、`set /slide[N] background`(十六进制背景色)、`remove /slide[N]/shape[M]`(含图片/形状)、列表(`list: "bullet"|"number"` + bullet 三级字符差异)
1513
+ - **view 升级**:stats 增加 `images` 计数、图片段落/形状标注 `(图片)`
1514
+ - **preview 预览**:三格式含图片标注
1515
+
1516
+ **bridge 侧**(aws-client-agent-mcp)
1517
+
1518
+ - 新建 `src/office/office-image.ts`:`officeResolveImageSource(source)` 支持三种图片来源(data:image URL / http(s) URL / 工作区路径),含魔数校验和严格格式约束;`prepareOfficeImageCommands(commands)` 预处理 office_edit 命令中的 props.source → imageBase64
1519
+ - `mcp-server.ts`:`officeEdit` 新增调用 `prepareOfficeImageCommands`,使图片 URL/路径自动解析为 base64 上行 Java 引擎
1520
+ - `mcp-tools.ts`:`OFFICE_EDIT_TOOL` 描述重写为三格式完整能力清单 + 图片通用规则 + 使用要点;props schema 补充所有新增字段
1521
+ - 测试 `office-image.test.ts`:11 测试全通过
1522
+
1523
+ ## v1.9.155
1524
+
1525
+ _发布日期:2026-09-13_
1526
+
1527
+ - Office 文件能力面板化(与 pencil / draw 画布面板同款体验):Agent 可在 Dashboard
1528
+ 面板中实时查看自己创建/编辑的 Word / Excel / PowerPoint 文档。
1529
+ - aws-client-agent-mcp:office 工具组新增 3 个面板工具——`office_open_document`
1530
+ (校验工作区文件存在并返回 file/kind/sizeKb/workspacePath,驱动前端打开面板)、
1531
+ `office_close_document`(收起面板)、`office_list_open`(列出本会话已打开的文件);
1532
+ `office_create` / `office_edit` 返回值补充 `kind` 字段,供前端时间线提取器维护
1533
+ 文件列表(Agent 行徽标计数);工具描述同步引导「打开面板即可实时看到编辑效果,无需截图」。
1534
+ - aws-mcp-server:`OfficeToolHandlers` 注册同款 3 个 handler(open 校验扩展名并归一
1535
+ kind;close/list 为轻量信封),`TOOL_NAMES` 扩为 8 个——office 能力门禁
1536
+ (`checkAbilityGate`)自动覆盖新工具;新增 `OfficeToolHandlersTest`(8 用例)。
1537
+ - aws-dashboard:新增 `OfficePanel.vue`(docx 用 docx-preview、xlsx 用
1538
+ @vue-office/excel、pptx 用 pptx-preview 本地渲染,注册 workspace watch 后经
1539
+ FILE_CHANGED 事件自动刷新,头部按类型显示 Word/Excel/PPT 彩色徽标);
1540
+ `useAgentTimeline` 新增 `extractOfficeDocInfo`(解析逻辑抽为可单测的
1541
+ `officeTimeline.ts`,覆盖 call_tool 懒加载包裹形态);index.vue 完成桌面/移动端
1542
+ 面板挂载、可拖拽宽度注册(office: 720/480/1200)与 Agent 行 Office 徽标按钮;
1543
+ ChatPanel office 卡片新增「面板打开」入口(卡片载荷携带 filePath/workspacePath,
1544
+ 同工作区时可直接在面板中打开原文件)。
1545
+ - 修复 `writeOfficeFileAtomic` 对非法 Base64 静默解码的存量问题(Node
1546
+ `Buffer.from(x,"base64")` 宽容语义),改为严格字符集 + 长度校验后再解码。
1547
+
1548
+ ## v1.9.153
1549
+
1550
+ _发布日期:2026-09-12_
1551
+
1552
+ - 工具集懒加载(Lazy Tool Expansion)全链路接入:受管控的大工具集(pencil / draw 各 15 个、
1553
+ 启动项 9 个、招聘、浏览器 / 桌面桥接等)由「开启即全量暴露」升级为三态能力开关——
1554
+ disabled(禁用)/ collapsed(收纳:工具不出现在工具列表,需先 expand_tools 展开)/ expanded(展开:工具全量直接可见),
1555
+ 降低初始上下文占用。
1556
+ - aws-mcp-server:`t_agent_ability_switch` 新增 `ability_state` 列(update.sql v1.30.0 迁移,存量行按
1557
+ `enabled` 归一:1→expanded / 0→disabled,既有 agent 行为不变),`AgentAbilitySwitch` 实体 / Mapper /
1558
+ Service 三态读写,`enabled` 布尔列写入时同步回填保持旧读取兼容。缺省口径(DB 无行):
1559
+ browser / desktop / agentSys.launchItem / agentSys.hire 默认 collapsed(已授权但收纳),其余默认 disabled(显式授权)。
1560
+ - aws-client-agent-mcp:新增常驻元工具 `expand_tools` / `call_tool`(不属于任何受控组,收纳组始终有展开与调度入口)。
1561
+ ListTools 按三态过滤;展开不再把工具注入 runtime exposedTools、不再推送 tools/list_changed(ListTools
1562
+ 载荷字节级稳定,LLM provider 前缀缓存全程命中),改为授予 call_tool 调度授权并把工具定义
1563
+ (name/description/inputSchema)随 expand 结果下发,agent 当轮即可 call_tool 调用;执行期纵深防御:
1564
+ disabled 拒绝、collapsed 未展开拒绝(同时兜住原生工具名直调的旁路)。配置为 expanded 的组不可在会话中
1565
+ 收起(由用户决定)、重复展开按幂等 already-expanded 返回。browser / desktop 桥接能力经 HTTP 回传
1566
+ bridge 新端点 `/runtime/sessions/:agentId/capability-tools[/call]`(X-Runtime-Token 鉴权),call 超时
1567
+ 55s < runtime mcpToolTimeoutMs 60s。
1568
+ - acode runtime:系统提示词注入能力清单(新增 capability-prompt.ts)——agent 知道哪些能力已展开 /
1569
+ 已收纳 / 未开启,「我没有绘图工具」类请求会主动提示用户去能力配置开启;启动期 env 兜底改为携带三态值
1570
+ (AWS_LAUNCH_CONFIG_TOOLS / AWS_HIRE_TOOLS / AWS_DRAW_TOOLS 等),消除首次 listTools 早于 token 就绪时
1571
+ env 兜底把收纳组全量暴露的窗口。
1572
+ - aws-dashboard:能力配置弹窗新增三态选择器(新组件 FeatureStatePicker.vue),capability-features.ts
1573
+ 升级为三态模型(agentSys 主开关禁用时子能力级联禁用,跨层与 Java / bridge 口径一致)。
1574
+ - Provider 请求失败不再默认无限重试:requestRetryCount 缺省由无限改为 0(持续 4xx 等不可恢复错误不再空转),
1575
+ 错误信息从响应载荷提取 code + message 直接抛出,不再被静默重试吞掉;需恢复内部重试时在 config 显式配置
1576
+ requestRetryCount(有限值或 -1 无限)。
1577
+ - 消息中心「完整请求体」JSON 树视图:新增 JsonTreeNode.vue(层级树形展示、逐层懒展开)与 jsonRepair.ts
1578
+ (截断 JSON 修复兜底,修复后可解析即以树形呈现),60KB 截断请求体支持全文搜索——输入防抖 200ms、
1579
+ 命中计数、回车逐个定位、自动展开命中祖先链并高亮,未解析为 JSON 时回退原始文本。
1580
+ - 图片预览缩放:新增 useImageZoom.ts(滚轮 / 双指缩放、拖拽平移、双击还原、缩放工具栏),接入 ChatPanel
1581
+ 全屏图片预览与 MessageInput 附件预览。
1582
+ - draw 卡片预览自愈:新增 drawCardPreview.ts 幽灵渲染管线——服务端从未渲染的 draw 消息卡片以发送者
1583
+ (owner)身份补渲染生成预览,渲染成功事件即时补拉;pencil / draw 卡片渲染图 30s 定时补拉自愈
1584
+ (消息离开列表即停止),有图即终态。
1585
+ - 杂项:.gitignore 补充审查 / 调试期临时产物(tsc / TAP 输出、一次性统计脚本、本地 AI 助手工作区);
1586
+ 修复 draw.ts 头注释在编辑中被截断损坏的问题。
1587
+
1588
+ ## v1.9.152
1589
+
1590
+ _发布日期:2026-09-10_
1591
+
1592
+ - 绘图(draw.io)能力全链路接入:新增「绘图 (draw)」能力开关(默认关闭,显式授权语义,同 desktop/hire/pencil),
1593
+ Agent 可创建 / 编辑 / 导出 / 分享 draw.io 绘图文档,Dashboard 以独立面板内嵌官方 draw.io 编辑器。
1594
+ - aws-mcp-server:新增 `t_draw_doc`(doc_id 唯一,`doc_xml` 为完整 `<mxfile>` 权威内容)、
1595
+ `t_draw_doc_member`(协作权限 read|write)、`t_draw_doc_change`(事务型 Outbox 变更日志,与内容写入同事务
1596
+ 落行,每 doc 保留最近 200 版;变更通知只作唤醒信号,丢失/离线时经 `draw_get_changes(sinceVersion)` 追赶);
1597
+ `DrawDocController` 暴露 `/api/draw/*`(docs / doc / doc ops / doc render / counts / doc members);
1598
+ `DrawDocMapper` 以 `doc_id + version` 乐观锁 CAS 写回,消除 check-then-act 竞态窗口。
1599
+ - aws-runtime-bridge:新增 `DRAW_FEATURE_KEY` 能力标识与 `AWS_DRAW_TOOLS` 启动期 env 兜底;
1600
+ `aws-client-agent-mcp` 注册 `draw_*` 工具组(create/list/open/close/get_diagram/get_changes/create_cells/
1601
+ update_cells/delete_cells/delete_document/rename_document/share_document/revoke_share/export_document),
1602
+ ListTools 按开关注实时过滤,服务端 `/mcp/call` 另有权威校验;`draw_export_document` 只回传
1603
+ savedTo/sizeKb 等元信息,docXml 不回流 agent 上下文。
1604
+ - aws-dashboard:新增 `DrawPanel.vue`(iframe 加载自托管 draw.io,经 embed postMessage 协议 load/autosave/export);
1605
+ 会话列表新增绘图徽标(仅 Agent 有绘图文档时显示,附数量角标);文档列表改为工具事件驱动刷新
1606
+ (`drawRevision` 信号 + 防抖),取代每 2.5s 高频轮询 `/api/draw/docs`,仅在 WS 断线/未覆盖时低频兜底;
1607
+ 面板宽度与收缩优先级纳入 `draw`;移动端新增绘图覆盖层。
1608
+ - 自托管编辑器资源置于 `aws-dashboard/public/draw/`(官方 draw.war 解包,v31.4.4,含 README 说明升级与授权注意),
1609
+ 并加入 Service Worker `globIgnores` 排除预缓存(app.min.js 9MB+、integrate.min.js 22MB+ 体积超预缓存上限,
1610
+ 仅打开绘图面板时按需加载)。
1611
+ - 消息卡片:`send_group` / `send_private` 支持附带 `card`(`{type:pencil|draw,docId,title?,description?}`)
1612
+ 文档引用卡片,`send_group`/`send_private` 工具描述同步说明。读取模型为「凭 docId 可读」——任何 Agent 拿到 docId
1613
+ 即可用 `pencil_get_tree` / `draw_get_diagram` 读取,无需被邀请;写操作仍按 owner / 协作成员权限校验。
1614
+ 为此 `PencilDocService` 的读取路径(readDoc / getTree / getRender / getChanges)去掉「非 owner/成员即拒绝」
1615
+ 的拦截,`resolvePermission` 返回 null 时读取归一为 read;新增 `validateCardDoc` 供卡片发送前确认文档存在。
1616
+ 卡片只读引用不写入 `*_doc_member`,因此不改变协作者列表、shared 标记与文档列表徽标。
1617
+ `t_direct_message` / `t_group_message` 新增 `card` 列(LONGTEXT,防富内容截断),
1618
+ `GroupMessageService` / `DirectMessageService` 增加带卡片的 8 参重载(原 7 参签名保留并委托,向后兼容),
1619
+ 卡片 JSON 落库前校验合法性(非法 JSON / 非对象直接拒绝,解析失败按无卡片降级渲染历史消息)。
1620
+ Dashboard 侧 `ChatPanel.vue` 新增消息卡片渲染(仿小程序卡片:有渲染图显示预览、否则占位封面,
1621
+ 带类型徽标与标题,点击直接打开对应绘图 / 画布面板)。
1622
+ - 消息内容扩容 + 载荷剥离:`t_direct_message` / `t_group_message` / `t_meeting_message` 的 `content`
1623
+ 由 TEXT(64KB) 扩为 LONGTEXT——富格式内嵌图片 base64(压缩后数百 KB ~ 数 MB)在 MySQL 非严格模式下会被
1624
+ 静默截断到 64KB,Agent 经 `poll_message` 只拿到残缺 JSON、`JSON.parse` 失败,表现为 agent 看不到图
1625
+ (`[image omitted]`)。配套在 acode runtime 的 poll 结果中剥离 directMessages/groupMessages 内嵌的
1626
+ 图片与附件 base64,仅保留可读文本摘要,避免 base64 以纯文本污染后续上下文。
1627
+ Dashboard 发送侧新增 `buildRichAttachmentContent`——图片附件以内嵌 base64 随消息下发(Agent 直接以
1628
+ 多模态 data URL 读取,无需 fetch 图片 URL / 落盘再读),非图片附件仍为 URL 描述(语义等价 `[文件: ...]`),
1629
+ 这正是 content 必须扩容到 LONGTEXT 的直接原因。
1630
+ 新增 `ACODE_IMAGE_DIAG=1` 开启的图片注入诊断日志(默认关闭,异步追加且吞掉 I/O 异常)。
1631
+ - 发布前修复:群消息仅卡片(无正文)时 Java 侧校验误拒绝,已与 mcp-server 侧「content/attachments/card
1632
+ 至少其一非空」对齐;`draw_export_document` 工具 schema 与实现统一(仅 xml/drawio,svg/png 等渲染
1633
+ 待阶段 2 管线,描述不再误导);`DrawPanel` 的 postMessage 接收仅接受同源自托管编辑器消息。
1634
+ - 原子写健壮性:`atomicWriteFile` 改用 `renameFileWithRetry`——Windows 下 `fs.rename` 可能因目标被瞬时占用
1635
+ (杀毒扫描 / 并发句柄)抛 EPERM/EBUSY/EACCES,按 40ms 递增退避重试 3 次,降低实际运行与测试并发下的假失败。
1636
+ - 面板最大化(脱离为弹框):新增 `PanelDetachButton.vue`,终端 / 时间线 / 工作区 / 上下文 / 待办 / 后台任务 /
1637
+ 子 Agent / 浏览器 / 画布等侧窗面板可一键脱离为弹框最大化,再点恢复回侧窗;脱离态保留强调色提示,
1638
+ 标签栏场景支持右对齐 sticky 固定,移动端隐藏(已是全屏覆盖层)。
1639
+ - 桌面工具 origin 判定明确化:`injectRememberedOrigin` 以 `originSet()`(非 null 且非 undefined)替代
1640
+ `!= null` 判断,语义等价并消除隐式类型收窄告警。
1641
+ - 轮询降频:在线成员列表的断连兜底轮询由 5s 放宽到 30s(`ONLINE_CHANGE` WS 事件已支持增量更新,
1642
+ 断连时仅需兜底同步,无需高频拉取);绘图文档列表同样由固定间隔轮询改为工具事件驱动。
1643
+ - 测试:vitest 单测超时由 30s 放宽到 90s——本机并行跑完整套件(103 个文件、真实 git/子进程)时 CPU 争用
1644
+ 可把单个用例拖慢数倍,避免负载型假失败掩盖真实回归;补齐 `draw_*` 工具、git 路由与 acode runtime 用例。
1645
+
1646
+ ## v1.9.151
1647
+
1648
+ _发布日期:2026-09-07_
1649
+
1650
+ - 工作区 LSP(TypeScript/JavaScript 语言服务)全链路接入:Dashboard 文件编辑器可对实例工作区的
1651
+ TS/TSX/JS/JSX 文件提供语义级定义跳转与引用查找,不再依赖字符串搜索。
1652
+ - runtime-bridge:新增 `typescript-language-server` 与 `typescript` 运行时依赖;`src/services/lsp-stdio-bridge.ts`
1653
+ 封装 LSP stdio 帧编解码(Content-Length 增量解析、畸形流防护)与子进程桥(自动解析 tls 入口、注入
1654
+ TSSERVER_PATH 保证 tsserver 可启动);`src/routes/lsp.ts` 暴露 `/ws/lsp` WebSocket——单 workspace 单进程
1655
+ 复用、60s 空闲回收、复用进程再次收到 initialize 时重建进程(避免 tsserver 沿用旧文档状态陷入
1656
+ "No Project"、跳转恒空)。
1657
+ - aws-mcp-server:`WorkspaceLspProxyService` 在 HTTP 侧校验 workspace 归属后签发 5 分钟一次性令牌
1658
+ (TTL 放宽覆盖慢建连、消费即失效防重放);`WorkspaceLspWebSocketHandler` 把浏览器 `/ws/workspace-lsp/{token}`
1659
+ 双向转发到 bridge `/ws/lsp`,隧道模式经 BridgeTunnelService 虚拟流、直连模式带 X-Runtime-Token 握手头;
1660
+ `FileBrowserProxyService.resolveWorkspaceLspBridge` 解析 bridge 目标(保留隧道实例前缀)与鉴权令牌。
1661
+ - aws-dashboard:`workspaceLsp.ts` 封装 CodeMirror LSP 会话——同一 bridge+workspace 仅建立一条 WS 与
1662
+ 一次 initialize,切换文件仅替换 per-file 句柄(didOpen/didClose),避免重复 initialize 导致跳转失效;
1663
+ 补充库未内置的 textDocument/references 与 definition 请求、自定义 transport 占位。`WorkspacePanel.vue`
1664
+ 接入 LSP 扩展、Ctrl+点击/快捷键跳转定义与引用查找;对 Windows 盘符修正 file:// 三层斜杠与 URI 归一比较。
1665
+ - 确认弹窗交互调整:确认按钮移至取消按钮左侧并作为默认焦点,Enter 键即触发确认,Tab 焦点循环顺序与
1666
+ 视觉排布一致(确认左、取消右)。
1667
+ - 工作区面板媒体预览:图片 / SVG / 视频预览改为经下载接口生成 object URL 展示,支持 B 站式画面缩放
1668
+ (Ctrl+滚轮 / 缩放按钮)与按住空格+拖动平移放大后画面,双击复位;预览状态栏同步显示媒体尺寸与状态。
1669
+
1670
+ ## v1.9.150
1671
+
1672
+ _发布日期:2026-09-07_
1673
+
1674
+ - 长文引用(LTR)全链路化:私信超长文本粘贴不再全文进消息,改为引用上传——MCP 与 bridge
1675
+ 新增 `/api/ltr/upload`,把大文本片段落盘到目标机器 `<系统临时目录>/aw-temp/LTR/YYYYMMDD/{uuid}.txt`
1676
+ (单篇 ≤512KB,按天归档、写入时顺带清理超 7 天的目录),消息只传 `[bridgeName:绝对路径]` 引用,
1677
+ agent 用 read_file 读取全文,避免超长文本撑爆消息表(MySQL TEXT 65535 字节)与 LLM 上下文。
1678
+ 前端配套:粘贴转胶囊 token(发送时统一上传 + 进度提示、hover 预览全文、未上传时随草稿保留并在
1679
+ 切换会话后恢复);LTR 图标与 capsule 颜色跟随主题。
1680
+ - 后台命令僵尸状态根治(L1–L4):读路径对账(面板每次刷新先翻"磁盘 running 但本进程内存不命中"
1681
+ 的孤儿为 killed(runtime_crashed) 并原子回写);状态写入事务化(per-agent 串行写链消除并发
1682
+ heartbeat/finalize 的丢失更新);生命周期补齐(exit+close 双监听,exit 后 2s 宽限强制 finalize,
1683
+ 孙进程持续持有管道不再留下永远 running 的状态;进程退出时落盘 killed(process_exit));running
1684
+ 任务心跳节流落盘(5s 或输出增量 64KB 触发)+ 启动时全量扫描所有 agent 目录孤儿。
1685
+ 面板改为只展示"真后台/运行中"命令,前台同步执行、从未转后台的命令不再占用面板。
1686
+ - open-pencil CLI 多路径探测:pencil_export_document 依次探测 `AWS_OPEN_PENCIL_HOME` →
1687
+ `<工作区>/open-pencil` → 仓库相对路径 → 逐级向上回溯,未命中时错误信息列出全部探测路径;
1688
+ README 补充生产部署前置(工作区锚点或环境变量二选一,须用仓库构建版 CLI 以支持 GraphSnapshot)。
1689
+ - create_meeting 有效性预检:角色占坑席位无可认领实例(如该角色唯一实例就是创建人)、或创建人把
1690
+ 自己重复加入受邀成员时直接返回错误,不再进入无谓的等待。
1691
+ - 群消息撤回语义修正:发送者本人游标越过已撤回消息仍可撤回;他人游标越过则拒绝撤回(撤回不再
1692
+ 被"阅读过即作废"误伤)。两项修复均补齐单测。
1693
+ - 输入框编辑体验:自建 undo/redo 栈(浏览器原生撤销对 contenteditable + 手动 DOM 不可靠),
1694
+ mention / command / LTR 原子 token 可整体撤销;@mention 输入确认后自动把自由文本原地转换为
1695
+ mention 高亮 token(`--cp-mention-highlight-*` 亮暗主题双套);「调用式回复」更名为「强调回复」。
1696
+ - 文件下载回源文件名:下载/预览响应 Content-Disposition 改用上传时的原始文件名(URL name 参数),
1697
+ 并清洗控制字符、引号、分号与路径分隔符,避免 header 畸形与路径穿越。
1698
+ - 消息中心:项目在线成员列表去重(同一 agent 绑定多实例时不再重复头像)。
1699
+ - 健壮性:后台命令状态持久化失败仅告警不再崩进程;LTR 上传上游失败统一 502 且不回传内部错误细节。
1700
+
1701
+ ## v1.9.149
1702
+
1703
+ _发布日期:2026-09-06_
1704
+
1705
+ - 项目头像支持裁剪:PNG / JPG / WebP / GIF 位图在选文件或点击现有图标后进入方形裁剪
1706
+ (拖动调整位置、滚轮或滑块缩放),以 512×512 输出确认保存;SVG / ICO 等无法用
1707
+ canvas 裁剪的格式仍直接按原文上传;favicon 预览复用已下载文件,点击直接进入裁剪,
1708
+ 避免二次网络下载。
1709
+ - Pencil 嵌入式画布跟随 Dashboard 明暗主题:iframe URL 携带 theme 参数,主题切换时
1710
+ 经 pencil:theme 消息同步画布配色,不再固定白底。
1711
+ - 修复浅色主题下消息中心 agent 上下文用量 / 待办 / 子代理按钮的选中态样式:选中项
1712
+ 不再被浅色覆盖规则盖成深色文字(`:not(--active)` 限定浅色覆盖范围,避开高特异性
1713
+ 覆盖选中态)。
1714
+ - 「限制操作」入口从输入框左侧常驻盾牌图标移回「+」菜单(撤销 v1.9.148 的常驻盾牌,
1715
+ 并移除权限档位拉取与盾牌着色逻辑,简化输入框布局)。
1716
+ - 版本升级 1.9.148 → 1.9.149:Bridge 本包无运行时代码改动,随前端 Pencil / 消息中心
1717
+ 更新一并发布。
1718
+
1719
+ ## v1.9.148
1720
+
1721
+ _发布日期:2026-09-06_
1722
+
1723
+ - Pencil 导出 savePath 不再限制在工作区内:绝对路径(如 D:\exports\hero.svg 或
1724
+ 用户 Downloads)直接使用,相对路径仍基于工作区根解析——导出交付物可落盘到
1725
+ 任意位置。
1726
+ - Pencil 渲染缓存升级为原始分辨率(最长边 ≤8192 内不缩放,此前 1280),agent
1727
+ pencil_export_image 与人工导出拿到原图;导出等待超时 8s→15s;升级规格后对旧
1728
+ 低分辨率缓存自动补渲一次。
1729
+ - Pencil 画板编辑锁:有写权限时默认锁定只读,点击解锁才可编辑;编辑中画布被
1730
+ agent 工具/协作端推进版本时自动回锁并加载最新快照,防止基于旧版编辑整份覆盖
1731
+ 他人写入(脏写);写权限被收回时强制回锁。
1732
+ - 输入框新增终端式 ↑/↓ 发送历史回溯(按会话隔离,Esc 退出并恢复进入前的草稿);
1733
+ 「限制操作」入口从「+」菜单移到输入框左侧盾牌常驻图标,存在授权/禁止档位时
1734
+ 显示绿色。
1735
+ - 修复:侧板拖拽经过 iframe(画布/终端)宽度冻结且无法结束的问题(拖拽期间禁用
1736
+ 容器内 iframe 鼠标事件,窗口失焦自动结束拖拽);全局设置菜单横向滚动两端留白
1737
+ 被吞掉的问题;项目头像弹窗标题显示项目名而非 projectId。
1738
+ - 更新健壮性:包内 CHANGELOG 缺目标版本段时继续尝试 ~/.aws-bridge 下运行时追加
1739
+ 的候选文件;更新成功后的发布说明追加改为 await 在重启前完成,版本号优先取 npm
1740
+ 刚落盘的 package.json。
1741
+ - 发布护栏:prepack-guard 校验 CHANGELOG.md 必须含当前版本段(缺段阻断发布),
1742
+ verify-pack-contents 将 CHANGELOG.md 列为必需 payload。
1743
+
1744
+ ## v1.9.147
1745
+
1746
+ _发布日期:2026-09-06_
1747
+
1748
+ - Pencil 设计画布全栈接入:t_pencil_doc 权威存储(迁移 v1.26.0~v1.26.3)与协作者
1749
+ 权限、MCP pencil_* 工具(AWS_PENCIL_TOOLS 兜底可见性过滤)。
1750
+ - 桌面自动化增强:nuphus-mcp 0.1.12 的 desktop_window_activate 先还原再激活,修复
1751
+ 托盘/最小化窗口无法激活的问题;新增 som.rs 与 UIA 安全增强。
1752
+ - acode 新增 runtime-environment;后台命令/文件/图片工具优化,AcodeSdkAdapter 与
1753
+ 浏览器池稳定性改进。
1754
+ - 修复:CHANGELOG.md 自本版本起随包分发。此前发布说明依赖"执行更新的旧进程"运行
1755
+ 时追加,旧版 Bridge(≤1.9.145 无此代码)执行更新会导致新版本弹窗无发布说明可
1756
+ 展示,只能回退安装过程日志。
1757
+
1758
+ ## v1.9.146
1759
+
1760
+ - 新增「本次更新内容」展示:将更新弹窗从安装过程日志(updates.log)切换为版本
1761
+ 发布说明(CHANGELOG.md),让用户看到本次版本相对变更的要点,而非 npm 安装
1762
+ 过程噪声。
1763
+ - 更新成功重启后,由 Bridge 自动在 CHANGELOG.md 顶部追加当前版本段。
1764
+ - 当目标版本未找到发布说明时,弹窗自动回退展示 updates.log(安装过程日志)并
1765
+ 给出提示。
1766
+
1767
+ <!-- append-new-version-above -->