@liguoshuai/pi-web-chat 2.14.12 → 2.15.4

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.
package/docs/CHANGELOG.md DELETED
@@ -1,990 +0,0 @@
1
- # Changelog
2
-
3
- All notable changes to this project will be documented in this file.
4
-
5
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
-
8
-
9
-
10
- ## [2.14.12] - 2026-09-05
11
-
12
- ### Fixed
13
- - **修复 HarmonyOS `versionCode` 位数与数值回退**:将 `clients/harmony/AppScope/app.json5` 的 `versionCode` 从错误的三位缩短格式(`21411`)恢复为标准的七位格式(`2141200`),并统一全仓版本号至 2.14.12。修正自 2.14.7 起 `versionCode` 由 `2140600` 误缩为 `21407` 造成的数值回退,避免 HarmonyOS 应用商店因版本号非单调递增而拒绝上架。
14
-
15
- ## [2.14.11] - 2026-09-05
16
-
17
- ### Fixed
18
- - **固化服务端与测试进程生命周期回收**:在 `createServer().close()` 中增加 `httpServer.closeAllConnections()` 及 `wss.clients` 强制 terminate 机制,杜绝单元测试及异常退出时因 TCP Keep-Alive 或 WebSocket 连接残留导致 `server.close()` 阻塞挂死。
19
-
20
- ## [2.14.10] - 2026-09-05
21
-
22
- ### Fixed
23
- - **兼容 Node 18+ 原生测试参数**:移除 `node --test` 中 Node 18 不支持的 `--test-timeout` 选项,统一在异步测试内部通过标准 `setTimeout` + `try ... finally` 进行跨版本超时控制与资源清理。
24
-
25
- ## [2.14.9] - 2026-09-05
26
-
27
- ### Fixed
28
- - **修复 CI 依赖安装与 Lockfile 同步**:补全 `clients/web/package.json` 中的依赖声明并同步 `pnpm-lock.yaml`,修复 GitHub Actions 流水线中 `pnpm install --frozen-lockfile` 报错。
29
-
30
- ## [2.14.8] - 2026-09-05
31
-
32
- ### Fixed
33
- - **修复移动端(Android & HarmonyOS)新会话无法正常拉起且卡在“思考中…”的关键 Bug**:
34
- - **反序列化强类型报错丢包修复**:`GenericServerMessage` 中 `message`、`code`、`id`、`content` 等多态字段由 `String?` 调整为 `JsonElement?`。修复 Pi 发送 `message_start` / `message_end`(`message` 为 JSON 对象)及 `pi_exit`(`code` 为数字)时抛出 `JsonDecodingException: Expected string, but had BEGIN_OBJECT/0` 导致事件被静默丢弃、会话状态无法流转的问题。
35
- - **Prompt 失败响应与错误透传闭环**:服务端在 `activeAgent.send(prompt)` 发生预检失败或 Agent 进程死亡时立即回传 `success: false` 响应;移动端(Android `ChatRepository` 与鸿蒙 `ChatViewModel`)补充 `response.command === "prompt"` 失败处理分支,立即重置 `isStreaming = false` 并展示错误卡片,杜绝无响应时永久卡在“思考中…”。
36
- - **新建会话状态全链路同步**:移动端在触发 `new_session` 成功后,自动重置流式状态并向服务端重新请求 `get_state` 与 `get_available_models`,同时将当前已选模型及思考级别重新应用到新会话 Agent 实例中。
37
- - **模型报错与异常 UI 渲染完善**:补充 `message_end` 中 `stopReason === "error"` 及 `MessageStatus.ERROR` 的多端错误占位与提示渲染,避免异常时产生空白或假死气泡。
38
- - **单元测试防挂死与超时保护**:为全仓 Node 测试命令增加 `--test-timeout=30000` 超时保护,网关 WebSocket 单元测试增加显式超时 reject 与 `try ... finally` 资源安全释放,防止异常未捕获导致测试进程永久挂起阻塞流水线。
39
-
40
- ## [2.14.7] - 2026-09-05
41
-
42
- ### Fixed
43
- - **修复僵死任务问题**:服务端 `send()` 对 `prompt`/`steer`/`client_send` 等长运行命令增加可配置超时(默认 10 分钟,环境变量 `LONG_RUNNING_TIMEOUT_MS`),超时后清理 pending entry、重置 streaming 状态并广播 error 事件,防止 pi 子进程挂起时 agent 成为不可回收的僵尸。
44
- - **前端 `tool_execution_end` 清理 activeToolCalls**:工具执行完成时从 `activeToolCalls` Map 中删除该 entry,避免 stale 条目累积。此前仅在 `finalizeStreamingMsg`/`clearChat` 等批量清空,若 `tool_execution_end` 事件丢失则工具永远卡在"执行中…"。
45
- - **WebSocket 断线时标记 stale 工具为"已中断"**:`ws.onclose` 中遍历 `activeToolCalls`,将仍为"执行中…"状态的 tool block 标记为"已中断"并停止计时,防止断线后残留僵尸工具块。
46
- - **`backfill_end` 后清理 stale 工具**:重连回放结束后,若服务端表示 `!streaming`,将所有仍为"执行中…"的 tool block 标记为"已中断",处理 buffer 溢出丢失 `tool_execution_end` 事件的场景。
47
-
48
- ## [2.14.6] - 2026-09-05
49
-
50
- ### Docs
51
- - 在 `AGENTS.md` 新增「⚡ 效率、专注与职业化准则」章节,从效率(并行执行、合并命令、禁止冗余读取、最小路径)、专注(单一目标、范围控制、先澄清后动手、一次到位)、职业化(诚实不作假、先诊断后修复、最小改动、透明收尾)三个维度规范 AI 智能体行为,提升交付效率与专业度。
52
-
53
- ## [2.14.5] - 2026-09-05
54
-
55
- ### Fixed
56
- - 修复 CI `publish-npm` 与 `publish-release` 的依赖判定:将 `!cancelled()` 改为 `success()`,测试失败时不会发布 NPM 包与 GitHub Release。
57
- - 修正 README、各客户端 README、UED 原型、架构文档中残留的旧版本号(2.12.7 / 2.12.9 / 2.13.0),并同步全仓版本至 2.14.5。
58
-
59
- ### Docs
60
- - 精简 `CLAUDE.md`,明确以 `AGENTS.md` 为唯一权威来源,补齐铁律四(CI 绿勾闭环)。
61
-
62
- ## [2.14.4] - 2026-09-05
63
-
64
- ### Performance
65
- - **添加 HTTP gzip 压缩中间件**:使用 Node.js 内置 `zlib` 实现(零外部依赖),对 `app.js` (123KB→~30KB)、`style.css` (46KB→~10KB) 等文本资源自动 gzip,传输体积减少约 70%。
66
- - **添加静态资源 Cache-Control 头**:常规资源缓存 1 天,带哈希文件名的资源缓存 1 年(immutable),减少浏览器重复拉取。
67
-
68
- ### Refactor
69
- - **提取路径遍历安全校验为 `validateSessionFile()` helper**:`routes.js` 中 GET /api/session 和 DELETE /api/session 的重复安全校验逻辑(~30 行 × 2)合并为一处,降低维护风险。
70
- - **提取环境变量数值解析为 `parseEnvNum()` helper**:`config.js` 中 4 处重复的 IIFE 模式合并为一个带 `{ integer }` 选项的 helper 函数。
71
-
72
- ### Fixed
73
- - 修复 `agent.js` `saveTimingData()` 中注释与代码不一致:注释写 "Keep last 200 turns" 但实际保留 1000 条。
74
-
75
- ## [2.14.0] - 2026-09-04
76
-
77
- ### Changed
78
- - 全端版本号统一递增至 2.14.0(Monorepo Lockstep:Root / Protocol / Server / Web / Android / HarmonyOS)。
79
- - 触发 CI 发布流程,产出全平台交付物(NPM 包 / HarmonyOS 包 / Android APK / GitHub Release)。
80
-
81
- ## [2.13.1] - 2026-09-04
82
-
83
- ### Fixed
84
- - **修复 Android `ChatRepository.changeCwd()` 永久破坏 Repository 的关键 Bug**:
85
- - `disconnect()` 原先调用 `wsClient.shutdown()` + `scope.cancel()`,会关闭 OkHttp 线程池并永久取消协程作用域;
86
- - `changeCwd()` 调用 `disconnect()` 后再调用 `connect()`,但 OkHttp 已关闭无法创建新连接,`scope` 已取消导致 `init{}` 中的 `connectionState` 和 `incomingMessages` 两个 collector 永久死亡;
87
- - 用户切换工作目录后,Repository 永久失聪 — WebSocket 消息无法处理,连接状态无法更新,所有 `scope.launch{}` 静默失效;
88
- - 修复:`disconnect()` 改为仅调用 `wsClient.disconnect()`(只关闭当前 WebSocket),`close()` 改为 `wsClient.shutdown()` + `scope.cancel()`(完整清理),`onCleared()` 改为调用 `close()`。
89
- - **修复 Android 真机无法连接局域网网关服务器的问题**:
90
- - `network_security_config.xml` 原先仅允许 `10.0.2.2`(模拟器环回)、`localhost`、`127.0.0.1` 三个地址的明文 HTTP 流量;
91
- - 真机连接局域网服务器(如 `http://192.168.1.x:3000`)时,Android 系统会静默拦截明文请求,导致 WebSocket 握手失败、App 显示"连接失败";
92
- - 改为 `<base-config cleartextTrafficPermitted="true" />`,允许所有域名的明文 HTTP,因为 Pi Gateway 是局域网/本地开发工具,设计上只跑纯 HTTP(无 TLS),要求用户配置证书不现实。
93
-
94
- ## [2.13.0] - 2026-09-04
95
-
96
- ### Added
97
- - **新增 UED 界面原型样例 (`docs/ued/`)**:
98
- - 为网页 WEB、手机 WEB、手机 APP 三端创建 HTML 交互原型(代码级 Mockup),可浏览器直接打开预览;
99
- - `index.html`:UED 总览页,含术语说明(UED/UX/UI/IXD)、业界原型绘制方式对比表、设计规范摘要;
100
- - `desktop-web.html`:桌面网页端原型,双栏布局(侧边栏+主聊天区),含会话列表、消息流、代码块、输入栏;
101
- - `mobile-web.html`:手机网页端原型,单栏布局+左滑抽屉,含 iPhone 设备框架、触控优化输入栏;
102
- - `mobile-app.html`:手机 APP 端原型,含聊天页(气泡式消息)和设置页(模型/连接/界面配置),Android/HarmonyOS 通用风格;
103
- - `README.md`:UED 设计说明文档,含三端布局差异对比表、配色规范、间距圆角规范。
104
-
105
- ### Changed
106
- - 全端版本号统一递增至 2.13.0(Monorepo Lockstep:Root / Protocol / Server / Web / Android / HarmonyOS)。
107
-
108
- ## [2.12.11] - 2026-09-04
109
-
110
- ### Added
111
- - **AI Agent 规范升级:新增铁律四(GitHub Actions CI 全绿保障闭环)(`AGENTS.md`)**:
112
- - 将《Pi-Chat AI Coding Agent 工作指南》核心原则升级为“四大强制原则”;
113
- - 正式确立“铁律四:推送后必监控并保证 GitHub Actions CI 全绿”,要求智能体在每次 push 后通过 `gh run list` / `gh run watch` 跟踪 CI 流水线状态,若发生故障必须立即闭环修复至 100% 成功,保证主干代码时刻健康。
114
-
115
- ### Changed
116
- - 全端版本号统一递增至 2.12.11(Monorepo Lockstep:Root / Protocol / Server / Web / Android / HarmonyOS)。
117
-
118
- ## [2.12.10] - 2026-09-04
119
-
120
- ### Fixed
121
- - **修复 GitHub Actions CI 的 Android 构建失败 (`clients/android/app/build.gradle.kts`)**:Kotlin DSL 脚本中 `java.util.Properties()` 因 `java` 标识符被 Java 插件扩展遮蔽而解析失败,导致 `./gradlew assembleDebug` 编译报错 `Unresolved reference: util`。改为脚本顶部显式 `import java.util.Properties` 并引用 `Properties()`,恢复 Android Debug APK 产物构建。
122
-
123
- ### Changed
124
- - 全端版本号统一递增至 2.12.10(Monorepo Lockstep:Root / Protocol / Server / Web / Android / HarmonyOS)。
125
-
126
- ---
127
- ---
128
-
129
- ## [2.12.9] - 2026-09-04
130
-
131
- ### Fixed
132
- - **用户旅途文档修正与补充 (`docs/USER_JOURNEY.md`)**:基于 5 个代码探索子代理的完整分析结果,修正并补充文档内容:
133
- - 修正痛点 #7:会话搜索功能仅 HarmonyOS 缺失(Web 和 Android 已有),原误标为"全端"问题。
134
- - 新增痛点 #9-#13:HarmonyOS 端无 Token 输入 UI、错误信息不可见、无删除会话、无模型选择 UI;Android/HarmonyOS 端错误提示 UI 薄弱。
135
- - 功能对齐矩阵补充 7 行:空状态引导芯片、键盘快捷键、消息发送失败重试、离开页面警告、图片 Lightbox、代码块复制按钮、错误提示方式。
136
- - 三端交互差异对比补充 8 行:空状态引导、键盘快捷键、离开警告、发送失败重试、图片大图查看、明文 HTTP 限制、流式看门狗超时。
137
- - 改进建议从 8 条扩展至 9 条,新增移动端错误提示增强建议。
138
- - 文档末尾补充分析方法说明与子代理交叉验证过程。
139
-
140
- ### Changed
141
- - 全端版本号统一递增至 2.12.9(Monorepo Lockstep:Root / Protocol / Server / Web / Android / HarmonyOS)。
142
-
143
- ---
144
- ---
145
-
146
- ## [2.12.8] - 2026-09-04
147
-
148
- ### Added
149
- - **用户旅途全景分析文档 (`docs/USER_JOURNEY.md`)**:新增面向终端使用者的 Customer Journey Map 文档,深度分析代码库后从用户视角梳理完整用户旅途,覆盖六大阶段(发现获取 → 配置连接 → 核心对话 → 会话管理 → 高级功能 → 异常恢复),包含产品定位与用户画像、系统拓扑与触点、三端功能对齐矩阵、交互模式差异对比、用户痛点与改进建议、协议消息全景附录。
150
-
151
- ### Changed
152
- - 全端版本号统一递增至 2.12.8(Monorepo Lockstep:Root / Protocol / Server / Web / Android / HarmonyOS)。
153
-
154
- ---
155
- ---
156
-
157
- ## [2.12.7] - 2026-09-04
158
-
159
- ### Fixed
160
- - **全仓文档版本号漂移清理 (`README.md`, `clients/harmony/README.md`, `clients/android/README.md`)**:修复多处残留的旧版本号(`version-2.10.0` 徽章、HarmonyOS / Android 页首标题与工程目录注释中的 `v2.11.3`、`2.10.0`),统一对齐至当前版本 2.12.7。
161
- - **Web 客户端仓库地址更新 (`clients/web/package.json`, `clients/web/README.md`)**:`repository` / `bugs` / `homepage` 及克隆地址由已废弃的 `pi-web-chat` 仓库更正为 Monorepo 主仓 `pi-chat`。
162
- - **环境变量文档补齐与默认值修正 (`.env.example`, `server/.env.example`, `clients/web/README.md`, `clients/web/docs/ARCHITECTURE.md`)**:补充缺失的 `PI_AUTH_TOKEN`、`MAX_AGENT_LIFETIME_MS`、`EVENT_BUFFER_SIZE`、`IDLE_DROP_HEAP`、`HOST`、`ALLOWED_ORIGINS` 说明;修正 `MAX_AGENT_LIFETIME_MS`(默认 `0` 禁用)与 `EVENT_BUFFER_SIZE`(默认 `5000`)两处过时默认值。
163
- - **Android 构建产物命名文档同步 (`README.md`, `clients/android/README.md`, `docs/ARCHITECTURE.md`)**:将过时的 `app-debug.apk` 引用更正为构建脚本实际产出的 `pi-chat-v{version}-debug.apk` 命名。
164
-
165
- ### Changed
166
- - 全端版本号统一递增至 2.12.7(Monorepo Lockstep:Root / Protocol / Server / Web / Android / HarmonyOS)。
167
-
168
- ---
169
-
170
- ## [2.12.6] - 2026-09-04
171
-
172
- ### Fixed
173
- - **服务端代码深度扫描修复(`server/src/*`)**:
174
- - `auth.js`:Token 校验改用 `crypto.timingSafeEqual` 恒定时间比较,消除计时侧信道攻击风险,并对非字符串输入做安全归一化。
175
- - `ws.js`:修复 WebSocket 鉴权失败/容量拒绝时错误消息的 `id` 被错误放入 `details` 字段的问题,改为顶层 `id`,保证客户端可按请求 id 正确关联错误响应。
176
- - `ws.js`:移除 `verifyClient` 中残留的空操作死代码(仅注释无逻辑的判断块)。
177
- - `agent.js`:修复 `replayBufferedSse` 在非流式状态下回放后未清空事件缓冲区的问题(与 `replayBufferedWs` 行为对齐),避免旧事件向新连接的 SSE 客户端重复回放。
178
- - `routes.js`:`/api/log-error` 端点新增字段长度截断(每字段上限 2048 字符),防止恶意/异常客户端写入超大内容刷屏服务端日志。
179
-
180
- ---
181
-
182
- ## [2.12.5] - 2026-09-04
183
-
184
- ### Improved
185
- - **CI NPM 发布支持动态 OTP 验证与 Automation Token 配置 (`.github/workflows/ci.yml`)**:
186
- - 在 `workflow_dispatch` 触发器中新增可选的 `npm_otp` 参数,允许在缺少 Automation Token 时通过手动输入 2FA 一次性验证码完成 NPM 发布;
187
- - 完善发布环境的 Token 传递与错误提示。
188
-
189
- ### Changed
190
- - 全端版本号统一递增至 2.12.5(Monorepo Lockstep:Root / Protocol / Server / Web / Android / HarmonyOS)。
191
-
192
- ## [2.12.4] - 2026-09-04
193
-
194
- ### Added
195
- - **GitHub Actions CI 自动发布至 NPM Registry (`.github/workflows/ci.yml`)**:
196
- - 新增 `publish-npm` 任务,集成 GitHub 仓库配置的 `NPM_TOKEN` Secret 与 `actions/setup-node` 注册表认证;
197
- - 支持在推送版本 Tag(如 `v2.12.4`)或手动触发 `workflow_dispatch`(勾选 `publish_npm: true`)时,自动将全套 Monorepo 包(`@liguoshuai/pi-chat-protocol`、`@liguoshuai/pi-chat-server`、`@liguoshuai/pi-web-chat`)安全发布至 NPM Registry。
198
-
199
- ### Changed
200
- - 全端版本号统一递增至 2.12.4(Monorepo Lockstep:Root / Protocol / Server / Web / Android / HarmonyOS)。
201
-
202
- ## [2.12.3] - 2026-09-04
203
-
204
- ### Fixed
205
- - **Android 端 Compose `Modifier.padding` 参数签名编译错误 (`clients/android/app/src/main/java/com/pichat/android/ui/screen/ChatScreen.kt`)**:修复输入栏容器 `Column` 中非法混用 `horizontal` 与 `top` / `bottom` 命名参数导致 Kotlin 编译报错(`None of the following candidates is applicable`)的问题,规范化为四向命名参数(`start`, `top`, `end`, `bottom`)。
206
- - **GitHub Actions CI 升级 (`.github/workflows/ci.yml`)**:将 `actions/setup-java` 从 v4 升级至官方推荐的 v5。
207
-
208
- ### Changed
209
- - 全端版本号统一递增至 2.12.3(Monorepo Lockstep:Root / Protocol / Server / Web / Android / HarmonyOS)。
210
-
211
- ## [2.12.2] - 2026-09-04
212
-
213
- ### Fixed
214
- - **Web 端发送消息后输入框锁死并误显“正在中止…” (`clients/web/public/app.js`)**:`submitPrompt` 发送成功后调用 `setComposerAborting(true)`(现已更名为 `setComposerStreaming`),其内部误将 `state.aborting` 置为 `true`,导致 `updateComposerUI` 进入“中止中”分支:输入框占位符显示“正在中止当前任务…”,发送按钮变成 `⏳` 并置为 `disabled`,UI 锁死直至任务结束。同时 `agent_start` / `backfill_end` / `updateState` 三处进入流式状态的路径也存在同样的误用。现将语义统一为 `setComposerStreaming`:进入流式状态时始终将 `state.aborting` 清理为 `false`,仅刷新 `updateComposerUI` 与 `renderModelPill`;而“中止”仅由用户点击中止时通过 `abortGeneration` 单独置位,彻底解决发送消息后对话框锁死、误显“中止…”的问题。
215
-
216
- ### Changed
217
- - 全端版本号统一递增至 2.12.2(Monorepo Lockstep:Root / Protocol / Server / Web / Android / HarmonyOS)。
218
-
219
- ## [2.12.1] - 2026-09-04
220
-
221
- ### Improved
222
- - **耗时时长格式化进位与边界修复 (`packages/protocol`, `clients/web/public/app.js`)**:
223
- - 重构 `formatDuration` 算法,避免毫秒数在接近整分边界(例如 `59950ms`、`119950ms`)时因浮点数取模四舍五入导致输出 `"0m 60s"` 或 `"1m 60s"` 异常格式,统一进位并补齐单元测试。
224
- - **会话列表排序时间戳健壮性增强 (`server/src/routes.js`)**:
225
- - 在 `/api/sessions` 排序中加入严格的 `Number.isFinite` 与 `Date.parse` 解析校验,防止无效或非标准日期字符串导致 `NaN` 比较破坏 JavaScript 引擎排序稳定性。
226
- - **流式事件回放与请求 ID 边界保护 (`server/src/agent.js`)**:
227
- - 优化 WebSocket / SSE 缓冲区回放遍历逻辑,精准依据缓冲区环形溢出状态重放事件,过滤潜在空槽位;
228
- - 改进 `PiAgent.send` 在子进程异常终止时对于数字 `0` 作为请求 ID 的正确保留与响应返回。
229
- - **Android 客户端协程生命周期防御 (`clients/android/.../ChatRepository.kt`)**:
230
- - 仓库层使用 `SupervisorJob()` 配合 `Dispatchers.IO`,避免子协程失败导致整个仓库层作用域被级联取消。
231
-
232
- ### Changed
233
- - 全端版本号统一递增至 2.12.1(Monorepo Lockstep:Root / Protocol / Server / Web / Android / HarmonyOS)。
234
-
235
- ## [2.12.0] - 2026-09-04
236
-
237
- ### Added
238
- - **Android 构建产物自定义重命名与 Release 加固配置 (`clients/android/app/build.gradle.kts`, `proguard-rules.pro`)**:
239
- - 构建产物根据版本号和构建类型重命名为语义化规范格式:`pi-chat-v{versionName}-debug.apk` 与 `pi-chat-v{versionName}-release.apk`。
240
- - 启用 Release 版本的混淆加固与代码资源缩减(`isMinifyEnabled = true`, `isShrinkResources = true`),配置完整的 ProGuard / R8 保护规则(数据模型、Kotlinx Serialization、OkHttp、Compose 与协程)。
241
- - 配置默认签名回退支持,使 Release APK 可开箱即用构建。
242
- - **Android 会话删除功能 (`clients/android/.../ApiService.kt`, `ChatRepository.kt`, `ChatViewModel.kt`, `ChatScreen.kt`)**:
243
- - 新增 `DELETE /api/session?file=...` 网络请求与仓库层方法,并在侧边栏每个会话项右侧提供删除按钮及二次确认弹窗。
244
-
245
- ### Improved
246
- - **Android 侧边栏抽屉界面优化与对齐 Web 体验 (`clients/android/.../ChatScreen.kt`)**:
247
- - 抽屉宽度适配调整为 `280dp`,改善手机端视觉比例;
248
- - 会话项展示信息全面对齐 Web:新增格式化时间戳(如 `9月4日 15:30`)、消息条数展示(`· N 条`)与流式任务运行中微动徽标(`运行中`);
249
- - 选中会话样式重构:高亮背景(`BgHover`)+ 左侧强调色指示条(`Accent`),会话行间距与内边距紧凑精致化;
250
- - 搜索框高度重构为紧凑式 `34dp`,包含搜索图标与一键清空按钮;
251
- - 侧边栏底部补齐 `pi.dev` 与 `pi-web-chat` 外部链接跳转,统一展示版本信息。
252
- - **Android 顶栏排版与信息层级重构 (`clients/android/.../ChatScreen.kt`)**:
253
- - 顶部导航栏高度规整至 `56dp`,居中展示当前对话主标题,并在下方紧凑排列工作目录(CWD)、模型名称(含 `★ 默认` 徽标)和思考推理等级胶囊;
254
- - 左右两侧合理布局抽屉按钮、分享导出按钮及设置按钮,排版清晰美观不拥挤,彻底解决信息遮挡与丢失问题。
255
- - **Android 底部输入框体验与样式重构 (`clients/android/.../ChatScreen.kt`)**:
256
- - 输入框整体采用 Web 端 ChatGPT 风格圆角胶囊卡片(`RoundedCornerShape(22.dp)`),内边距与高度严格贴合文本行高;
257
- - 采用 `BasicTextField` 配合优雅的占位符提示,支持多行平滑自适应扩展;
258
- - 发送按钮、指导指令按钮及中止按钮尺寸规整(32dp 圆形/胶囊),并对齐底部安全区。
259
-
260
- ### Changed
261
- - 全端版本号统一递增至 2.12.0(Monorepo Lockstep:Root / Protocol / Server / Web / Android / HarmonyOS)。
262
-
263
- ## [2.11.3] - 2026-09-03
264
-
265
- ### Fixed
266
- - **HarmonyOS 端配置持久化与初始加载缺失 (`clients/harmony/...`)**:`PreferencesHelper` 虽然实现了服务端 URL 的存储与获取,但未在 App 启动/初始化流程中实际调用。现已在 `Index.ets` 的 `aboutToAppear()` 中调用 `PreferencesHelper.getServerUrl()` 动态读取已保存的 URL 进行初始化,并在“保存并重连”时调用 `PreferencesHelper.setServerUrl()` 写入持久化存储,解决应用重启后配置丢失问题。
267
- - **HarmonyOS 端 UI 界面版本号硬编码滞后 (`clients/harmony/.../Index.ets`)**:侧边栏抽屉底部硬编码展示旧版本号 `v2.10.1`,现已更新为当前全仓最新的 `v2.11.3`,与 Monorepo 版本数严格对齐。
268
-
269
- ### Changed
270
- - 全端版本号统一递增至 2.11.3(Monorepo Lockstep:Root / Protocol / Server / Web / Android / HarmonyOS)。
271
-
272
- ## [2.11.2] - 2026-09-03
273
-
274
- ### Fixed
275
- - **Web 端 `submitSteer` 发送失败静默丢弃 (`clients/web/public/app.js`)**:`sendWs` 返回值未检查,WebSocket 在检查与发送之间断开时,指导指令被静默丢弃但 UI 已显示"已插入指导指令"。现先检查 `sendWs` 返回值,失败时提示用户并触发重连,不再乐观更新 UI。
276
- - **Web 端 `abortGeneration` 发送失败导致 UI 锁死 (`clients/web/public/app.js`)**:`sendWs({ type: "abort" })` 返回值未检查,发送失败时 `state.aborting` 永久为 `true`,UI 锁定在中止状态。现检查返回值,失败时回退 `state.aborting` 并提示用户。
277
- - **Web 端 `submitPrompt` 失败回退遗漏定时器清理 (`clients/web/public/app.js`)**:发送失败回退时未调用 `stopStreamingTimer()` 且未重置 `turnStartedAt` / `streamingMsgDurationEl`,导致 100ms 定时器持续向已分离 DOM 节点写入。现已补充清理。
278
- - **Android `sendSteer` / `abort` / `switchSession` 发送返回值未检查 (`clients/android/.../ChatRepository.kt`)**:`sendRaw` 返回的 `Boolean` 被忽略。`abort` 无条件设置 `_isStreaming = false` 即使中止未送达服务端;`switchSession` 在发送前清空消息列表,发送失败时导致状态不同步。现均检查返回值并在失败时回退。
279
- - **HarmonyOS `abort` / `newSession` / `switchSession` 发送返回值未检查 (`clients/harmony/.../ChatViewModel.ets`)**:与 Android 同类问题。`abort` 无条件重置 `isStreaming`;`newSession` / `switchSession` 在发送前清空消息,发送失败时导致状态不同步。现均检查 `wsManager.send()` 返回值并在失败时回退。
280
- - **HarmonyOS `remote_user_prompt` 消息重复 (`clients/harmony/.../ChatViewModel.ets`)**:本地已发送的用户消息与服务端 `remote_user_prompt` 回声重复添加。现增加去重检查,若倒数第二条用户消息内容相同则跳过。
281
- - **HarmonyOS `init()` 未重置流式状态 (`clients/harmony/.../ChatViewModel.ets`)**:切换服务器 URL 重新初始化时,残留的 `isStreaming = true` 导致孤立流式气泡。现 `init()` 中重置 `isStreaming = false`。
282
- - **Android 编译失败修复 (`clients/android/.../ChatScreen.kt`)**:补充 `SmartToy` 与 `Psychology` 图标的 `import` 声明,修复替顶部胶囊换用 Material 图标后因缺失导入导致的 `Unresolved reference`,`assembleDebug` 可正常产出 APK。
283
- - **服务端单元测试 CI 挂起修复 (`server/test/server.test.js` + `server/fixtures/pi-stub.mjs`)**:CI runner 未安装 `pi` CLI,`PiAgent.start()` 执行 `spawn("pi")` 时报 `ENOENT`,导致 `WebSocket gateway NEW_SESSION` 断言失败、HTTP 服务未关闭,最终使 `node --test` 进程长时间挂起。现引入无操作长驻 stub 并重写 `config.piBin`,使网关单测自包含、不再依赖外部 `pi` 二进制。
284
-
285
- ### Changed
286
- - 全端版本号统一递增至 2.11.2(Monorepo Lockstep:Root / Protocol / Server / Web / Android / HarmonyOS)。
287
-
288
- ---
289
-
290
- ## [2.11.1] - 2026-09-03
291
-
292
- ### Fixed
293
- - **Android 构建失败修复 (`clients/android/.../ChatRepository.kt`)**:修复 `connect` 函数声明被写坏导致的语法错误(`fun connectcwd: String = ...` → `fun connect(cwd: String = ..., sessionPath: String? = null)`),该错误导致 `compileDebugKotlin` 失败、APK 无法产出,并连带触发 `ChatViewModel` 中多处 `Unresolved reference 'connect'`。修复后 Android Debug APK 可正常构建。
294
-
295
- ### Changed
296
- - 全端版本号统一递增至 2.11.1(Monorepo Lockstep:Root / Protocol / Server / Web / Android / HarmonyOS)。
297
-
298
- ---
299
-
300
- ## [2.11.0] - 2026-09-03
301
-
302
- ### Changed & Beautified (Android)
303
- - **应用图标焕新 (`clients/android`)**:弃用系统默认图标,新增基于 π 品牌图形与翡翠绿渐变的 **自适应启动图标 (Adaptive Icon)**,包含背景渐变、白色圆角 π 字形与点缀色,支持普通与圆形图标形态。
304
- - **顶部胶囊图标美化 (TopBar Pills)**:将模型选择 (🤖) 与思考级别 (🧠) 的简单 Emoji 替换为 **彩色圆形徽章 + Material 图标**(`SmartToy` 机器人 / `Psychology` 大脑),并同步美化工作目录胶囊图标,视觉更加精致统一。
305
- - **对话框气泡美化 (Message Bubbles)**:
306
- - 用户消息气泡升级为 **翡翠绿渐变背景 + 护色描边**,圆角更柔和、内边距更舒适。
307
- - 助手头像由扁平半透明圆形升级为 **彩色渐变圆形徽章**(白色 π),辨识度与质感更佳。
308
- - **样例提示词间距优化 (Suggestion Chips)**:解决提示词芯片过于紧凑的问题,引入图标 + 标签的卡片式芯片,并增大水平与垂直间距、内边距,视觉更舒展。
309
-
310
- ### Changed
311
- - 全端版本号统一递增至 2.11.0(Monorepo Lockstep:Root / Protocol / Server / Web / Android / HarmonyOS)。
312
-
313
- ---
314
-
315
- ## [2.10.1] - 2026-09-03
316
-
317
- ### Fixed
318
- - **HarmonyOS 监听器泄漏修复 (`clients/harmony/.../ChatViewModel.ets`)**:`init()` 每次调用都新增 WebSocket 状态与消息监听器但不移除旧的,导致重复调用时监听器堆积、消息被重复处理。现已保存监听器引用并在重新初始化时先移除旧监听器。
319
- - **HarmonyOS WebSocket 重连竞争修复 (`clients/harmony/.../WebSocketManager.ets`)**:`connect()` 替换已有连接时,旧 socket 的异步 `on('close')` 回调仍会触发 `scheduleReconnect()`,导致连接抖动。现已通过捕获 ws 实例引用,在陈旧回调中跳过重连逻辑。
320
- - **Android WebSocket 连接泄漏修复 (`clients/android/.../WebSocketClient.kt`)**:`connect()` 未关闭已有 WebSocket 连接,在重连场景下旧连接资源泄漏。现已在 `connect()` 开头主动关闭并清理旧连接。
321
- - **Android 协程作用域泄漏修复 (`clients/android/.../ChatRepository.kt` / `ChatViewModel.kt`)**:`reconnect()` 创建新 `ChatRepository` 但未取消旧实例的协程作用域,导致协程泄漏。现已新增 `close()` 方法并在重连时调用。
322
- - **协议层冗余代码清理 (`packages/protocol/src/index.js`)**:`formatDuration` 函数前两个条件分支完全相同,移除冗余的 `ms < 1000` 分支。
323
- - **HarmonyOS 冗余代码清理 (`clients/harmony/.../Index.ets`)**:同步移除 `formatDuration` 中相同的冗余分支。
324
- - **Web 端 Token 泄漏防护 (`clients/web/public/app.js`)**:从 URL 提取 auth token 后立即使用 `history.replaceState` 清除 URL 中的 token 参数,防止通过 Referer 头、截图或分享链接泄漏。
325
- - **Web 端代码围栏匹配修复 (`clients/web/public/app.js`)**:`renderMarkdown` 中 ```` 围栏匹配改为仅在行首匹配,避免将行内三反引号误判为代码围栏。
326
- - **Web 端 SVG 元素命名空间修复 (`clients/web/public/app.js`)**:DOM 辅助函数 `el()` 对 SVG 标签使用 `createElementNS` 创建,修复 SVG 图标渲染问题。
327
- - **Web 端发送失败处理增强 (`clients/web/public/app.js`)**:`sendWs` 返回布尔值,`submitPrompt` 在 WebSocket 断开时回退流式状态并提示用户,`setComposerAborting(true)` 正确设置 `state.aborting`。
328
- - **Android API 基址规范化 (`clients/android/.../ApiService.kt`)**:构造函数中自动去除 `baseUrl` 尾部斜杠,避免拼接出双斜杠 URL。
329
-
330
- ### Changed
331
- - 全端版本号统一递增至 2.10.1(Monorepo Lockstep:Root / Protocol / Server / Web / Android / HarmonyOS)。
332
- ---
333
-
334
- ## [2.10.0] - 2026-09-02
335
-
336
- ### Added & Aligned
337
- - **Android 原生客户端与移动 Web 端全要素对齐 (`clients/android`)**:
338
- - **顶部栏元素完整对齐 (TopBar Alignment)**:
339
- - 新增 **工作目录胶囊按钮 (CWD Pill)**:展示当前工作目录,点击弹出工作目录切换对话框(包含路径输入与 `~`, `~/.pi`, `/tmp` 快捷芯片)。
340
- - 新增 **模型选择胶囊按钮 (Model Pill)**:展示当前模型名称与 `★ 默认` 徽章,点击弹出支持搜索、厂商归类、能力标签(🧠 推理、👁️ 视觉、🛠️ 工具)的模型选择对话框。
341
- - 新增 **深度思考级别胶囊按钮 (Thinking Pill)**:展示当前思考深度,点击弹出 `Off`、`Minimal`、`Low`、`Medium`、`High`、`Max` 等推理级别选择对话框。
342
- - 新增 **会话导出按钮 (Export Chat)**:一键将完整对话导出为标准 Markdown 格式并唤起系统分享。
343
- - **设置入口单点统一**:移除侧边抽屉顶部多余的重复设置按钮,保留顶部栏统一单一设置入口,避免操作歧义。
344
- - **空白引导页全要素对齐 (Empty State Alignment)**:
345
- - 引入 `π` 经典头像与提示文案。
346
- - 引入 **当前模型信息横幅 (Empty Model Banner)**:展示当前模型名称、默认徽章、🧠 思考 / 👁️ 视觉 / 🛠️ 工具能力标签及“切换模型”快捷按钮。
347
- - 引入 **快捷指令芯片 (Suggestion Chips)**:提供“列出当前目录文件”、“总结这个项目”、“代码审查”等一键触发指令。
348
- - **底部输入区域与富文本展示对齐 (Composer & Message Bubbles)**:
349
- - 增加待发送附件预览栏(带缩略图与删除 `✕` 按钮)。
350
- - 增加图片全屏查看画廊模式 (Image Lightbox Modal)。
351
- - 助手回复内容 Markdown 解析优化,代码块增加语言标签与“复制代码”独立按钮。
352
- - 增加底部操作提示文案:“pi 会执行命令与读写你的文件 —— 请注意操作内容。”
353
-
354
- ### Changed
355
- - 全端版本号统一递增至 2.10.0(Monorepo Lockstep:Root / Protocol / Server / Web / Android / HarmonyOS)。
356
-
357
- ---
358
-
359
- ## [2.9.1] - 2026-09-02
360
-
361
- ### Fixed & Optimized
362
- - **网关路由健壮性增强 (`server/src/routes.js`)**:修复 `/api/sessions` 历史会话列表中若存在数值格式时间戳导致 `localeCompare` 抛错的问题,优化为安全兼容数字与 ISO 字符串的多格式时间戳倒序排列。
363
- - **Web 前端异常流式保护 (`clients/web/public/app.js`)**:在 WebSocket 消息处理中补充对 `error` 与 `pi_exit` 事件的完备响应,遇到异常时自动终结流式状态、解除输入框锁定并提示用户。
364
- - **Android 原生端异常退出流式重置 (`clients/android`)**:`ChatRepository.kt` 补充对 `error` 和 `pi_exit` 事件的处理,避免在子进程异常退出时状态滞留在流式中。
365
- - **HarmonyOS 原生端异常流式重置 (`clients/harmony`)**:`ChatViewModel.ets` 补充对 `error` 和 `pi_exit` 事件的处理,确保鸿蒙界面在异常中断时能正常完成并释放输入。
366
- - **跨端通信协议 Schema 完备性更新 (`packages/protocol/src/schema.json`)**:补充 `remote_user_steer` 与 `extension_ui_request` 到服务端消息类型枚举定义。
367
-
368
- ### Changed
369
- - 全端版本号统一递增至 2.9.1(Monorepo Lockstep:Root / Protocol / Server / Web / Android / HarmonyOS)。
370
-
371
- ---
372
-
373
- ## [2.9.0] - 2026-09-02
374
-
375
- ### Added
376
- - **思考耗时与执行耗时多端展示特性 (Thinking & Execution Duration Display)**:
377
- - **Web 端 (`clients/web`)**:
378
- - 思考过程块 (`.thinking-block`):流式思考进行中实时显示动态耗时(例如 `3.2s`),思考完成显示完整用时徽章(例如 `用时 3.2s`)。
379
- - 工具执行块 (`.tool-block`):执行中显示动态计时(例如 `执行中 · 1.2s`),执行完毕显示最终耗时(例如 `完成 · 1.2s` 或 `错误 · 0.8s`)。
380
- - 助手回复消息头部 (`.role-tag`):实时显示本次回答生成总耗时,并在生成完成后展示总耗时(例如 `耗时 4.5s`)。
381
- - 历史会话加载 (`reconstructFromEntries`):支持自动从历史日志计算各工具调用耗时与助手生成总耗时并渲染。
382
- - **Android 原生端 (`clients/android`)**:
383
- - `ChatMessage` 与 `ToolCall` 模型扩充思考用时 (`thinkingDurationMs`) 与执行耗时 (`durationMs`, `turnDurationMs`) 属性。
384
- - Compose 界面中的 `ThinkingBlock`、`ToolCallBlock` 以及 `MessageBubble` 均支持清晰展示思考耗时、工具执行耗时与回答生成总用时。
385
- - 历史会话加载支持还原思考与工具执行耗时。
386
- - **HarmonyOS 鸿蒙原生端 (`clients/harmony`)**:
387
- - `ChatMessage` 增加 `thinkingDuration` 与 `turnDuration` 属性支持。
388
- - `Index.ets` 在思考过程与助手回复头部优雅展示思考耗时与执行总耗时。
389
- - **跨端协议与公共库 (`@liguoshuai/pi-chat-protocol`)**:
390
- - 新增跨端标准耗时格式化函数 `formatDuration(ms)` 与单元测试。
391
-
392
- ### Changed
393
- - 全端版本号统一升级至 2.9.0(Monorepo Lockstep:Root / Protocol / Server / Web / Android / HarmonyOS)。
394
-
395
- ---
396
-
397
- ## [2.8.0] - 2026-09-02
398
-
399
- ### Added
400
- - 前端思考过程与工具调用块时间戳显示:在思考过程块和工具调用块中添加时间戳,格式为当天 HH:mm,跨天 MM-dd HH:mm。
401
-
402
- ## [2.7.0] - 2026-09-01
403
-
404
- ### Added
405
- - **网关 REST CORS 跨域支持与预检支持 (`server`)**:
406
- - 在 Express 网关服务中增加标准 CORS 拦截器,支持自定义 `ALLOWED_ORIGINS` 配置与通配放行,支持 `OPTIONS` preflight 预检请求与相关请求头(`Authorization`, `Content-Type`, `x-api-token`)。
407
- - **服务端环境变量自动检测与多宿主兼容 (`server`)**:
408
- - 服务端配置模块增加自动检测并读取根目录或包内 `.env` 文件的能力。
409
- - 完善 Windows 宿主机上的 `pi` 执行文件解析(`.cmd` / `.exe`)与 `spawn` 平台兼容性。
410
- - **Web 端 PWA (Progressive Web App) 支持 (`clients/web`)**:
411
- - 新增 `manifest.webmanifest` 与高清矢量 `icon.svg`,支持在手机与桌面浏览器中一键“添加到主屏幕”,享受沉浸式应用体验。
412
- - **移动端指数退避断线重连 (`clients/android` & `clients/harmony`)**:
413
- - Android 原生端 (`WebSocketClient.kt`) 与 HarmonyOS 鸿蒙原生端 (`WebSocketManager.ets`) 统一引入 Exponential Backoff + Jitter(指数退避与随机抖动重连算法),有效防止服务端重启或网络抖动时的瞬时并发重连风暴。
414
- - **CI 工作流强化 (`.github/workflows/ci.yml`)**:
415
- - 在 GitHub Actions 中增加 Android 原生端自动化构建与依赖检查(`gradlew assembleDebug`)。
416
-
417
- ### Changed
418
- - 全端版本号统一升级至 2.7.0(Monorepo Lockstep:Root / Protocol / Server / Web / Android / HarmonyOS)。
419
-
420
- ---
421
-
422
- ## [2.6.0] - 2026-09-01
423
-
424
- ### Added
425
- - **跨端协议增强与强类型声明 (`@liguoshuai/pi-chat-protocol`)**:
426
- - 新增 `createBackfillStartMessage` 与 `createBackfillEndMessage` 协议消息构造器,支持在断线重连回放中透传 `overflowed` 标志。
427
- - 新增 `ToolCallPayload` 与 `ToolResultPayload` 强类型接口,增强跨端工具调用的类型安全性。
428
- - 在 Android (`PiChatProtocol.kt`) 与 HarmonyOS (`PiProtocol.ets`) 客户端协议模型中同步补齐 `overflowed` 等字段。
429
- - **网关断线溢出检测与客户端自愈补偿 (`server` & `clients/web`)**:
430
- - 网关 `PiAgent` 增加事件环形缓冲区溢出状态跟踪(`hasBufferOverflowed`),在客户端重连事件回放结束(`backfill_end`)时明确通知客户端。
431
- - Web 客户端侦测到 `overflowed: true` 时,自动在后台触发增量/完整历史记录无感同步(`syncSessionHistory`),彻底杜绝网络严重抖动或长时间离线导致的消息截断。
432
- - **Web 前端流式渲染性能与快捷键体验优化 (`clients/web`)**:
433
- - 流式更新渲染全面统一采用 `requestAnimationFrame` 防抖批量刷新(`refreshStreamingContentDebounced`),消除高频 token 吐出时的页面重排重绘瓶颈。
434
- - 新增 `Cmd/Ctrl + Shift + O` 快捷新建会话别名,适配主流 AI 交互习惯。
435
-
436
- ### Changed
437
- - 全端版本号统一升级至 2.6.0(Monorepo Lockstep:Root / Protocol / Server / Web / Android / HarmonyOS)。
438
-
439
- ---
440
-
441
- ## [2.5.1] - 2026-09-01
442
-
443
- ### Added
444
- - **AI Coding Agent 工作指南与工程规范 (`AGENTS.md` & `CLAUDE.md`)**:
445
- - 确立三大强制铁律:工作前必拉取远端主干(`git pull origin main`)、任何修改必递增 SemVer 语义化版本号并在 Web 与各客户端正确呈现、任务完成必通过全量测试并提交推送至远端。
446
- - 制定 Monorepo 全仓版本同步清单(Lockstep)与多端版本呈现规范。
447
- - **客户端版本号呈现强化**:
448
- - Android 原生端:启用 `buildConfig = true`,在侧边栏抽屉底部及后端配置对话框中通过 `BuildConfig.VERSION_NAME` 实时展示客户端版本号(`v2.5.1`)。
449
- - HarmonyOS 鸿蒙原生端:在侧边栏底部展示应用版本号(`v2.5.1`)。
450
- - Web 端:通过网关 `/api/config` 动态获取并在侧边栏底部 `#appVersion` 区域正确展示当前版本号(`v2.5.1`)。
451
-
452
- ### Changed
453
- - 全端版本号统一升级至 2.5.1(Root / Protocol / Server / Web / Android / HarmonyOS)。
454
-
455
- ---
456
-
457
- ## [2.5.0] - 2026-09-01
458
-
459
- ### Added
460
- - Android 端聊天消息、思考过程与工具执行块均显示时间戳(当天 `HH:mm`,跨天 `MM-dd HH:mm`)。
461
- - Android 端新增工具执行渲染(`tool_execution_start/update/end`):展示工具名、参数、结果与执行状态(执行中/完成/错误)。
462
- - 用户消息头部显示 `user`,助手消息头部显示 `pi`。
463
-
464
- ### Changed
465
- - Android 端会话列表在新建会话、`agent_start`/`agent_settled`、切换会话及服务端返回 `sessionFile` 时即时刷新,新会话更快出现在侧边栏。
466
- - 全端版本号统一升级至 2.5.0。
467
-
468
- ## [2.4.1] - 2026-09-01
469
-
470
- ### Fixed
471
- - **彻底解决新建对话中断已有后台任务的问题**:
472
- - 修复了 `startNewSession` 在已有活动 WebSocket 连接上直接发送 `new_session` RPC 指令导致原有会话子进程被重置与中断的问题。新建会话时安全断开当前连接(原会话保持后台运行),并为新会话连接独立的无状态 Agent。
473
- - 服务端网关 `NEW_SESSION` 与 `SWITCH_SESSION` 消息处理器增加安全解绑(detach)逻辑,避免跨会话指令误触或覆盖已有活跃 Agent 进程。
474
- - **精准修复老会话误判为“运行中”的状态异常**:
475
- - 严格区分进程资源防回收判定(`isBusy`,包含 pending 异步请求)与真实 AI 流式生成状态(`isStreaming`,严格对应 `state === 'streaming'`)。
476
- - 服务端 `/api/sessions` 接口与 `backfill_end` 状态同步均修正为读取 `isStreaming`,彻底杜绝老会话连接时因 `get_state`/`get_available_models` 临时 pending 导致误判为“运行中”的问题。
477
- - 优化了事件环形缓存机制:会话生成结束收敛(`agent_settled`)后彻底清空缓冲区,且仅在流式生成期间缓存事件,避免非流式 RPC 响应污染回放缓冲区导致前端误进入流式状态。
478
- - 前端 `updateState` 及侧边栏会话路径比对增加统一路径规范化匹配(`sameSession`),避免路径形式差异导致草稿会话残留或状态错乱。
479
-
480
- ---
481
-
482
- ## [2.4.0] - 2026-08-31
483
-
484
- ### Fixed & Improved
485
- - **后台异步长任务稳定性与持久化机制全面强化 (Background Async Persistence & Lifetime Fix)**:
486
- - **移除 30 分钟无条件强杀定时器**:将 `MAX_AGENT_LIFETIME_MS` 默认设为 `0`(禁用硬超时杀进程)。若用户配置了正数生命周期上限,也会严格判断 `isBusy`(正在生成/执行工具中)与 `hasListeners`(仍有客户端监听),任务执行期间绝不强杀子进程。
487
- - **扩大离线事件环形缓冲区**:将 `EVENT_BUFFER_SIZE` 默认容量从 2000 提升至 5000,保障长时间后台离线输出不丢帧。
488
- - **Web 端平滑多任务切换与静默转入后台 (Seamless Background Session Switch)**:
489
- - 移除了在生成过程中新建会话(`startNewSession`)或侧边栏切换会话(`loadSession`)时的强制中断(`abortGeneration()`)逻辑。
490
- - 切换或新建会话时,原会话平滑转入后台静默继续执行,并弹出轻提示告知用户。
491
- - 修复了断线重连(`ws.onopen`)与离线事件增量回放(Backfill)之间的 DOM 渲染竞态条件,避免流式内容被意外清除。
492
- - **侧边栏会话后台执行状态感知 (Sidebar Background Execution Indicator)**:
493
- - 服务端 `/api/sessions` 接口扩展返回 `isStreaming` 状态字段,精准反馈每个会话对应的后台 Agent 是否正在忙碌。
494
- - Web 端侧边栏为正在后台生成中的会话实时展示 `⚡ 运行中` 呼吸动画状态徽标。
495
- - 页面可见性恢复(`visibilitychange`)及定时后台状态轮询自动刷新各会话状态。
496
-
497
- ---
498
-
499
- ## [2.2.0] - 2026-08-30
500
-
501
- ### Fixed & Improved
502
- - **服务端会话路径解析与遍历安全加固 (Session Path Resolution & Security)**:
503
- - 修复了 `/api/session`(GET 与 DELETE)在处理会话相对路径时由于错误相对路径基准导致的误拦截(403 Forbidden),增强为相对于 `config.sessionsDir` 的安全解析并保留严格的路径越界校验与符号链接真实路径防穿透防护。
504
- - 会话扫描增强为多层级安全目录递归遍历(`listAllSessionFiles`),支持更深的会话目录结构与符号链接解析。
505
- - 为服务端 `sessionMetadataCache` 增加 LRU/最大条目上限限制(5000条),防止长期运行内存泄漏。
506
- - **服务端网关稳健性与跨平台优化 (Gateway Robustness & Cross-Platform)**:
507
- - 完善了 WebSocket 握手鉴权响应对请求 `id` 的透传关联,优化了 `PING`/`heartbeat` 的 ID 支持。
508
- - 规范了 `PROMPT` 消息中的 `message` 字符串与 `images` 数组格式,防止向 Pi 进程传递 `undefined`。
509
- - 改进了 SSE 客户端异常断开时的错误捕获与失效监听器及时清理。
510
- - 增强了 `resolvePiBin` 的跨平台检测路径,支持 macOS Homebrew、Linux `~/.local/bin`、`~/.cargo/bin` 等常见环境。
511
- - **Web 端多端同步与渲染优化 (Web UI & Markdown Rendering)**:
512
- - 修复了 `remote_user_prompt` 事件未同步呈现多端上传的 `images` 附件的问题。
513
- - 修复了 Markdown 解析器中 URL 包含查询参数时因多次转义造成的双重转义(Double Escaping)问题,并支持 `mailto:` 链接解析。
514
- - **协议库与 TypeScript 类型定义完善 (`@liguoshuai/pi-chat-protocol`)**:
515
- - 新增 `createSetSessionNameMessage`、`createGetEntriesMessage`、`createGetStateMessage`、`createGetAvailableModelsMessage`、`createExtensionUiResponseMessage` 辅助构造方法。
516
- - 增强了 `SET_SESSION_NAME` 与 `SET_THINKING_LEVEL` 的数据校验与 TypeScript 类型声明。
517
-
518
- ---
519
-
520
- ## [2.1.0] - 2026-08-30
521
-
522
- ### Fixed & Improved
523
- - **移动端流式打字与思考过程实时渲染修复 (Mobile Streaming & Thinking Render Fix)**:
524
- - 在 `@liguoshuai/pi-chat-protocol`、Android 和 HarmonyOS 原生客户端中完善了 `assistantMessageEvent` 结构解析,修复了移动端在 AI 回复生成期间无法接收 `text_delta` 与 `thinking_delta` 流式打字效果的问题。
525
- - **移动端历史会话转录加载修复 (Mobile Session History Restore)**:
526
- - 在 Android (`ApiService`) 与 HarmonyOS (`HttpService`) 中新增了 `/api/session?file=...` 接口调用,在切换会话时自动还原历史聊天气泡。
527
- - **Web 端 401 鉴权重连修复 (Web Re-Auth Fix)**:
528
- - 修复了 `app.js` 中弹窗输入 Token 后调用未定义 `initWebSocket` 导致 `ReferenceError` 的异常,改为正确调用 `connectWs`。
529
- - **服务端网关 RPC ID 保持与进程管理增强 (Gateway RPC ID & Lifecycle Improvements)**:
530
- - 修复了网关转发指令时丢失客户端 `id` 的问题,确保 RPC 请求响应精确关联。
531
- - 增强了 IPv6 Localhost 跨域兼容性支持与死连接自动清理。
532
- - 补充了 `@liguoshuai/pi-chat-protocol` 中的 `createSetThinkingLevelMessage` 与 `createCycleThinkingLevelMessage` 辅助方法。
533
-
534
- ---
535
-
536
- ## [2.0.0] - 2026-08-30
537
-
538
- ### Major Architecture Refactoring (Monorepo & Multi-Client Ecosystem)
539
- - **Monorepo 多端大仓库架构升级**:
540
- - 项目重构为 `pi-chat` Monorepo,采用 pnpm Workspaces 进行多包统一管理。
541
- - 核心架构拆分为 `clients/web`、`clients/android`、`clients/harmony`、`server`(VPS 网关)与 `packages/protocol`(跨端共享协议)。
542
- - **服务端网关统一解耦与单真源设计 (`@pi-chat/server`)**:
543
- - 提取 `@pi-chat/server` 为统一后端网关核心,支持全双工 WebSocket、SSE 打字机增量推送(`/api/stream`)、多端统一 Token 鉴权(`AUTH_TOKEN`)、30s 心跳保活与空闲进程内存自动回收。
544
- - `clients/web/server.js` 瘦身为极简适配层,保持对 `@liguoshuai/pi-web-chat` npm 发行版及 `pi-web-chat` 全局 CLI 的 100% 独立向后兼容。
545
- - **Android 原生端应用骨架 (`clients/android`)**:
546
- - 基于 Kotlin + Jetpack Compose + Material 3 + OkHttp WebSocket + Coroutines/StateFlow 搭建,支持生成 APK 安装包。
547
- - **华为鸿蒙 OS 原生端应用骨架 (`clients/harmony`)**:
548
- - 基于 ArkTS + 声明式 ArkUI (Stage 模型,API 12+) + `@ohos.net.webSocket` 搭建,支持生成 HAP 安装包。
549
- - **跨端标准通信协议 (`@pi-chat/protocol`)**:
550
- - 统一 JSON Schema 标准、TypeScript 定义与自动容错校验器,三端交互格式完全对齐。
551
-
552
- ---
553
-
554
- ### Added & Published
555
- - **NPM 官方包发布与全局命令行安装支持 (Official NPM Package & Global CLI)**:
556
- - 正式发布软件包至 npm 官方注册表([`@liguoshuai/pi-web-chat`](https://www.npmjs.com/package/@liguoshuai/pi-web-chat)),支持通过 `npm i -g @liguoshuai/pi-web-chat` 或 `pnpm add -g @liguoshuai/pi-web-chat` 全局安装并随时随地使用 `pi-web-chat` 命令启动。
557
- - 支持通过 `npx @liguoshuai/pi-web-chat` 免安装即时启动,并在 README 中完善了全局安装、npx 启动与源码安装三种模式的快速指引。
558
-
559
- ### Fixed & Improved
560
- - **移动端附件导入功能全面重构与修复 (Mobile Attachment Import Fix)**:
561
- - **移动端文件选择器唤起修复**:将上传触发器重构为标准可访问的 `<label for="imageFileInput">` 并配合 CSS `.sr-only-file-input`,彻底解决 iOS Safari、Android Chrome、移动端 WebView 及微信内置浏览器中因 `display: none` 导致异步 JS `.click()` 被浏览器安全策略拦截而无法调起系统相册/文件选择器的问题。
562
- - **移动端格式与相机照片兼容性**:扩展对 iOS HEIC/HEIF 相机原图、AVIF、ICO、SVG 及大写扩展名的识别与支持。
563
- - **移动端高清原图智能压缩降采样 (Client-side Downscale)**:针对手机拍摄的超高分辨率照片(12MP~48MP),自动使用 Canvas 进行等比下采样(最大 2048px)与高质量编码压缩,防止超大 Base64 数据挤爆移动端内存或造成 WebSocket 通信中断,同时确保所有主流大模型 Vision API 稳定解析。
564
- - **文本与源码文件附件导入支持 (Text & Code Attachment Parsing)**:支持通过附件按钮、拖拽或剪贴板直接导入 `.py`、`.js`、`.json`、`.md`、`.txt`、`.log` 等各类代码和文本附件,自动提取并按对应语言 Markdown 代码块注入输入框。
565
- - **预览交互与触控体验优化 (Touch UX & Preview Lightbox)**:输入框待发送图片缩略图支持点击直接弹出 Lightbox 大图预览,加大移动端单张删除按钮的触控热区(22px)与操作反馈。
566
-
567
- ---
568
-
569
- ## [1.10.2] - 2026-08-30
570
-
571
- ### Fixed & Improved
572
- - **移动端顶栏排版与信息密度重构 (Mobile Topbar UX)**:
573
- - 在移动端隐藏多余的会话名截断占位,隐藏导出按钮文字标签仅保留操作图标,为工作目录与模型选择胶囊腾出充足显示空间。
574
- - 优化移动端触控胶囊布局与间距,杜绝文字极端挤压和残缺问题。
575
- - **欢迎区与模型卡片响应式布局优化 (Empty State & Model Banner)**:
576
- - 优化欢迎引导文案,兼容移动端抽屉式侧边栏交互。
577
- - 为 `★ 默认模型` 徽标增加专用样式并强制单行禁止折行,彻底消除断词分行问题。
578
- - 修复模型卡片在移动端下的左右对齐与视觉比例,“切换模型”按钮平滑对齐。
579
- - 优化快捷推荐指令标签(Suggestions Chips),支持移动端优雅折行排版。
580
- - **移动端输入框与占位提示适配 (Composer Mobile Adaptation)**:
581
- - 移动端自动使用精简的 Placeholder 提示文案,彻底解决长提示在窄屏单行输入框下文字被腰斩截断的问题。
582
- - 增强底部操作区全面屏手势安全区(`safe-area-inset-bottom`)适配。
583
-
584
- ---
585
-
586
- ## [1.10.1] - 2026-08-30
587
-
588
- ### Improved
589
- - **附件上传图标与交互优化 (Attachment Icon & UX)**:
590
- - 将输入框上传图标更换为美观清晰的标准曲别针附件矢量图标(Paperclip 📎)。
591
- - 优化按钮尺寸(`32px × 32px` 标准圆形)、对称内边距与悬停/按压交互动效。
592
- - **文件与拖拽兼容性增强 (Upload Compatibility)**:
593
- - 完善文件类型扩展(支持 `image/*` 及 `.png, .jpg, .jpeg, .webp, .gif, .bmp, .svg, .ico, .avif`)。
594
- - 增强 MIME 类型缺失时的扩展名自动推断与回退处理机制。
595
- - 增加全局 Drag & Drop 默认事件拦截,防止图片拖拽偏离输入框时误触浏览器页面跳转。
596
-
597
- ---
598
-
599
- ## [1.10.0] - 2026-08-30
600
-
601
- ### Security
602
- - **WebSocket 跨站劫持 (CSWSH) 防护与 Origin 校验**:
603
- - 在 `server.js` 增加 `verifyClient` 来源校验,严格拦截非授权外部网页发起的跨域 WebSocket 连接,防御针对本地服务与命令执行的 CSWSH 攻击。
604
- - 支持同源、`localhost`、`127.0.0.1` 及通过 `ALLOWED_ORIGINS` 环境变量配置的反向代理域名白名单。
605
- - **路径与系统配置写入加固**:
606
- - 加固 `/api/set-default-model` 接口,严格校验客户端传入的目标工作目录,防止任意路径操作。
607
- - **Markdown 链接协议与属性逃逸 XSS 防护**:
608
- - 增强链接协议校验(仅允许 `http:`、`https:`、`mailto:`),修复 URL 包含特定引号实体时在属性反转义下的 XSS 逃逸隐患。
609
-
610
- ### Added
611
- - **多模态图片输入与预览支持 (Multimodal Image Attachments & Lightbox)**:
612
- - 输入框支持截图粘贴(`Ctrl+V` / `Cmd+V`)、本地图片文件拖拽(Drag & Drop)以及附件图标上传。
613
- - 输入框上方显示待发送图片缩略图胶囊,支持单张移除。
614
- - 消息气泡中支持渲染用户上传的多张图片缩略图,点击可弹出全屏大图预览(Lightbox)。
615
- - 加载历史会话记录时自动提取并渲染历史消息中的图片附件。
616
- - **对话导出为 Markdown 功能 (Export Chat as Markdown)**:
617
- - 顶栏新增“导出”按钮,一键将当前会话(包含会话名称、模型信息、工作目录、思考过程、工具调用与对话正文)导出为标准 Markdown(`.md`)文件下载。
618
- - **全局快捷键扩充 (Keyboard Shortcuts)**:
619
- - `Ctrl/Cmd + Shift + N`:快速新建会话。
620
- - `Ctrl/Cmd + K` 或 `Ctrl + /`:快速聚焦侧边栏搜索框。
621
- - `Ctrl/Cmd + B`:快速切换侧边栏展开/折叠。
622
- - `Escape`:支持快速关闭大图预览、搜索框失焦、关闭菜单及模态框。
623
- - **侧边栏搜索体验优化**:
624
- - 搜索结果为空时展示“未找到匹配的会话”空提示。
625
- - 会话列表刷新时自动保持当前搜索过滤词。
626
- - **自动化单元测试套件**:
627
- - 新增基于 `node --test` 的单元测试,覆盖安全规则、Origin 校验与路径穿越检查。
628
-
629
- ### Changed
630
- - **段落排版与换行优化**:Markdown 段落内单换行符自动转为 `<br>`,优化 AI 输出文本的行间结构与排版体验。
631
- - **跨平台工程化优化**:优化 `package.json` 中的 `prepare` 脚本,避免 Windows 下执行 `chmod` 报错;将 `rpctest.mjs` 整理归入 `scripts/` 目录。
632
-
633
- ---
634
-
635
- ## [1.9.1] - 2026-08-29
636
-
637
- ### Added
638
- - **侧边栏底部开源项目跳转链接 (Repository Link in Sidebar Bottom)**:
639
- - 在侧边栏底部元信息区域增加 `pi-web-chat` 项目开源仓库链接(`https://github.com/liguoshuai-1990/pi-web-chat`),方便用户快速跳转与查阅源码。
640
-
641
- ---
642
-
643
- ## [1.9.0] - 2026-08-29
644
-
645
- ### Added
646
- - **历史对话删除功能 (Session Deletion & Auto Process Cleanup)**:
647
- - 后端新增 `DELETE /api/session` 接口,支持通过文件路径删除历史 JSONL 会话记录,并带有严格的会话目录越界与路径穿越安全校验。
648
- - 删除会话时自动清理后端内存元数据缓存,并自动停止与回收当前会话所绑定的常驻后台 Pi 代理子进程。
649
- - 前端侧边栏会话列表新增垃圾桶删除按钮(桌面端 Hover 显示,移动端常驻展示),点击后带有确认拦截提示,防止误删。
650
- - 删除当前正在查看/进行的会话时,自动重置为空白新会话并清理 URL 参数与流式状态;删除其他会话时无感刷新会话列表。
651
- - **左侧栏拖拽缩放宽度特性 (Resizable Sidebar with Dragging)**:
652
- - 左侧边栏新增右侧边缘拖拽把手(`#sidebarResizer`),支持鼠标及触控指针拖拽自由调节侧边栏宽度(180px - 自适应上限)。
653
- - 基于 Pointer Capture API 与 `--sidebar-width` 动态 CSS 变量实现 60fps 丝滑拖拽缩放体验,并消除文本误选与拖动延迟。
654
- - 侧边栏折叠与展开动画完全自适应动态设置的侧边栏宽度,避免折叠时发生截断或残留。
655
- - 支持双击拖拽把手快速重置回默认宽度(260px),并通过 `localStorage` 自动持久化保存用户自定宽度偏好。
656
- - 优化移动端响应式,移动端抽屉侧栏下自动禁用并隐藏桌面端拖拽把手。
657
-
658
- ---
659
-
660
- ## [1.8.9] - 2026-08-29
661
-
662
- ### Fixed
663
- - **Markdown 下划线变量与标识符渲染保护 (Markdown Identifier & Underscore Parsing Protection)**:
664
- - 优化行内 Markdown 解析器,限定下划线 `_` 仅在非单词边界(空格/标点包裹)时触发斜体,防止编程标识符与文件名(如 `user_id_list`、`process.env.NODE_ENV`)被误切分解析为斜体。
665
- - 优化加粗与嵌套斜体(`**bold and *italic***`)的非贪婪匹配规则。
666
- - **移动端模型选择菜单支持“设为默认” (Mobile Model Selector 'Set Default' Accessibility)**:
667
- - 在移动端媒体查询下保持 `.btn-set-default` 可见(`opacity: 1`),修复手机端因缺少 hover 无法将模型设为全局默认的问题。
668
- - **工具调用头部与顶栏弹性布局溢出保护 (Tool Block & Topbar Flex Overflow Protection)**:
669
- - 给 `.tool-head .args` 增加 `min-width: 0`,防止长命令/长文件路径将右侧“复制”按钮与“执行状态”标签挤出卡片。
670
- - 给桌面端 `.topbar .session-name` 增加 `min-width: 0`,防止窄屏下超长会话标题破坏顶栏胶囊布局。
671
-
672
- ---
673
-
674
- ## [1.8.8] - 2026-08-29
675
-
676
- ### Fixed
677
- - **消息发送框确认按钮上下居中与正圆对齐优化 (Composer Send Button Alignment & Circular Sizing)**:
678
- - 修复默认单行输入状态下,发送按钮因与 `textarea` 存在高度差并在 `flex-end` 布局下导致严重偏下、没有垂直居中的问题。
679
- - 精准对齐单行 `textarea` 高度(32px)与按钮高度(32px),使单行状态下发送/确认按钮在输入框内绝对垂直居中,多行输入时依然平滑吸底。
680
- - 将桌面端发送按钮修正为标准正圆(`32px × 32px`,`border-radius: 50%`),并补充字号与行高约束,确保图标居中且不影响手机侧及响应式体验。
681
-
682
- ---
683
-
684
- ## [1.8.5] - 2026-08-23
685
-
686
- ### Fixed
687
- - **中止/终止生成按钮逻辑修复 (Abort Button Logic & UX Fix)**:
688
- - 修复生成过程中点击终止按钮(`■`)时,因输入框为空触发提前返回(`if (!text) return`)导致无法发出 `abort` 信号的问题。
689
- - 抽离独立的 `abortGeneration()` 统一处理中断生成流程,确保点击停止按钮无条件触发任务终止。
690
- - 修复输入框有草稿时点击停止按钮误触发 `steer`(插入指令)的问题,明确区分停止按钮与插入指令按钮职责。
691
- - 新增中止中即时视觉反馈(按钮变为等待状态 `⏳`,输入框边缘高亮变红,提示文字变更为“中止当前任务中…”),并在底层 `agent_settled` 或 `abort` 响应后安全恢复。
692
- - 支持在生成过程中按 `Escape` 键快速中止当前任务(模态框或菜单打开时除外)。
693
- - 在新建会话及切换会话时,若当前任务正在运行中,自动先行中断当前流式任务以避免后台状态错乱。
694
-
695
- ---
696
-
697
- ## [1.8.4] - 2026-07-26
698
-
699
- ### Added
700
- - **Markdown 渲染能力增强 (Markdown Enhancements: HR, Strikethrough & Task Checkboxes)**:
701
- - 支持标准 Markdown 水平分割线(`---`、`***`、`___`)渲染为 `<hr>` 标签。
702
- - 支持删除线语法(`~~strikethrough~~`)渲染为 `<del>` 标签。
703
- - 支持任务列表复选框(`- [ ]` 与 `- [x]`)及加号无序列表(`+ item`)。
704
- - 为 `h4`、`h5`、`h6`、`hr`、`del` 及任务复选框补充了精细的暗色主题 CSS 样式。
705
-
706
- ### Fixed
707
- - **移动端息屏/切出恢复后历史消息自动同步 (Mobile Reconnect Session Auto-Sync)**:
708
- - 修复手机端在后台挂起或息屏后切回页面时,未能及时同步后台已生成完毕的最新回复内容的问题。
709
- - 增加 `syncSessionHistory` 历史同步机制,并在 `ws.onopen`、`visibilitychange` 与 `pageshow` 事件中自动拉取磁盘最新消息渲染至对话区。
710
- - 优化 `backfill_start` / `backfill_end` 流式状态重置,保障后台生成途中切回时无缝追平实时生成内容。
711
- - **未绑定会话孤儿子进程即时回收 (Immediate Cleanup of Unkeyed Idle Agents)**:当客户端打开新建会话页面但未发送消息即关闭或切换时,后端未分配 Session Key 的孤立 `PiAgent` 进程在连接断开后立即释放,避免占用 5 分钟闲置内存。
712
- - **切换与加载历史会话时工作目录自动同步 (Session CWD Auto-Sync)**:点击侧边栏或通过 URL 参数(`?session=...`)打开会话时,自动将 `state.cwd` 同步为会话真实的 `data.header.cwd`,确保 Agent 执行环境与会话一致。
713
- - **工作目录变更后项目级默认配置实时重载 (Project Settings Live Reload on CWD Change)**:切换工作目录时重新获取 `/api/config?cwd=...`,确保项目根目录下的 `.pi/settings.json` 模型配置即时生效。
714
- - **波浪号路径解析规范化 (Tilde `~` Path Resolution Normalization)**:服务端引入统一的 `normalizePath`,确保会话参数与路径校验中包含的 `~` 家目录前缀能被正确展开并绝对化。
715
- - **历史错误消息展示保护 (Error Notice on Historical Failed Messages)**:修复历史会话中若生成中途报错中断时未能渲染失败提示条的问题。
716
- - **Package.json 发布字段补充 (Scripts Directory Inclusion)**:在 `package.json` 的 `files` 字段中加入 `scripts/` 目录,确保 Systemd 服务脚本正常打包发布。
717
-
718
- ---
719
-
720
- ## [1.8.3] - 2026-07-26
721
-
722
- ### Fixed
723
- - **移动端工作目录切换弹窗按钮溢出修复 (CWD Modal Mobile Overflow & Input Sizing)**:
724
- - 修复手机端切换工作目录弹窗中“确定切换”按钮超出卡片右侧边框的问题。
725
- - 为 `.input-group input` 添加 `min-width: 0` 和 `box-sizing: border-box`,消除原生 input 元素的内在最小宽度导致的 Flexbox 溢出。
726
- - 适配移动端弹窗内边距与间距(padding 降至 16px),并在 `<= 380px` 窄屏设备上自适应将按钮折行全宽呈现,防止水平溢出。
727
-
728
- ---
729
-
730
- ## [1.8.2] - 2026-07-26
731
-
732
- ### Fixed
733
- - **移动端顶栏空间挤压与思考胶囊截断修复 (Mobile Topbar Layout & Thinking Pill Overflow)**:
734
- - 移除移动端 `.model-pill-container` 的固定 `max-width: 130px` 宽度限制,修复深度思考胶囊被挤压截断、只显示一半图标的问题。
735
- - 优化移动端顶栏各元素间距与自适应弹性缩放:侧边栏菜单按钮调整为 36px,工作目录胶囊最大宽度限制为 75px,模型胶囊适度收敛文字并隐藏默认徽章,思考胶囊保留完整图标与级别文本。
736
- - 增加对 `<= 360px` 极窄小屏设备的精细化响应式适配规则,保障全尺寸移动端设备顶部操作栏整齐美观且不换行、不溢出。
737
-
738
- ---
739
-
740
- ## [1.8.1] - 2026-07-26
741
-
742
- ### Fixed
743
- - **模型切换系统通知未定义函数报错修复 (Missing appendSystemNotice ReferenceError)**:补充前端 `appendSystemNotice` 函数实现,使用 `.system-notice-divider` 与 `.system-notice-text` 渲染模型变更系统提示,解决切换模型时触发 `ReferenceError` 的问题。
744
- - **思考深度循环切换响应数据字段适配 (cycle_thinking_level Response Handling)**:兼容 Pi RPC 响应中返回的 `data.level` 字段,避免因字段名不匹配导致思考深度未能及时更新。
745
- - **会话自定义命名解析与侧边栏即时呈现 (Session Name & session_info Extraction)**:服务端 `/api/sessions` 与 `/api/session` 增加对 `session_info` 记录的解析,支持读取用户通过 `set_session_name` 设置的会话名称并在侧边栏和顶栏直观显示。
746
- - **默认模型设为已启用模型列表防回退保护 (enabledModels Sync on Set Default)**:在写入 `defaultModel` 时同步检查并加入 `enabledModels` 列表,防止 Pi core 启动时回退至 `enabledModels[0]`。
747
- - **会话历史加载异常容错与提示 (Session Load Error Handling)**:`loadSession` 增加网络及文件读取异常判断与 Toast 友好提示,避免读取异常会话文件时界面卡死。
748
- - **Systemd User 单元文件权限沙箱配置优化 (Systemd Unit Workspace Access)**:移除 `ProtectHome=read-only`,确保作为用户级服务启动时 Pi Agent 可以正常读写和编辑工作区项目文件。
749
-
750
- ---
751
-
752
- ## [1.8.0] - 2026-07-26
753
-
754
- ### Added
755
- - **默认模型确认与展示体系 (Default Model Identification & Visual Indicators)**:
756
- - 后端 `/api/config` 自动读取并整合项目配置 `<cwd>/.pi/settings.json` 与全局配置 `~/.pi/agent/settings.json` 中的 `defaultProvider`、`defaultModel` 及 `defaultThinkingLevel`。
757
- - 顶部模型胶囊 (Model Pill) 自动识别并展示 `★ 默认` 或 `★ 项目默认` 徽章,悬停提示详细配置来源。
758
- - 新建对话欢迎面板 (Empty State) 增加当前会话模型展示卡片,直观呈现模型名称、默认状态及特性标签。
759
- - **深度思考 (Thinking / Reasoning) 联动选择器**:
760
- - 当模型支持推理思考(`reasoning: true`)时,顶栏自动浮现 `🧠 High` / `🧠 Medium` 等深度思考胶囊。
761
- - 支持快捷弹出思考深度菜单(Off / Minimal / Low / Medium / High / Max),即时调节思考预算;非思考模型自动隐藏。
762
- - **一键持久化设为默认模型 (Set as Default Model)**:
763
- - 新增后端接口 `POST /api/set-default-model`,模型列表项右侧支持一键将当前选中的模型设为全局/项目默认模型。
764
- - **模型快捷置顶与特性标签 (Pinned, Recents & Capabilities)**:
765
- - 模型下拉面板置顶呈现 `🌟 默认与常用` 分组,自动基于 `localStorage` 缓存并置顶最近使用的模型。
766
- - 模型项展示 `🧠 Thinking`(深度思考)、`👁️ Vision`(多模态识图)、`★ 默认` 等能力标签。
767
- - **全键盘极客操作与快捷键 (Keyboard Navigation & Shortcut)**:
768
- - 支持全局快捷键 `Ctrl + M` / `Cmd + M` 快速呼出/收起模型选择面板。
769
- - 搜索框支持 `↑` / `↓` 移动高亮、`Enter` 快速切换、`Esc` 退出。
770
- - **会话流模型切换历史标记**:
771
- - 会话中途切换模型时,在消息流中自动插入系统分割通知(`── 已切换模型至 Provider / ModelName ──`)。
772
-
773
- ---
774
-
775
- ## [1.7.6] - 2026-07-26
776
-
777
- ### Security
778
- - **Markdown 渲染 HTML 属性逃逸注入安全漏洞修复 (HTML Attribute Breakout XSS Vulnerability)**:升级 `public/app.js` 中的 `escapeHtml` 严密性,将原有对 `&`、`<`、`>` 的处理,扩展至双引号 `"` (`&quot;`) 与单引号 `'` (`&#39;`),阻断由于模型生成恶意链接等引起的 `href` 属性逃逸与任意 HTML 属性/事件(XSS)注入风险。
779
-
780
- ### Fixed
781
- - **多设备与多标签页流式事件同步及中途连入追平优化 (Multi-device/Multi-tab Live Event Streaming Sync)**:
782
- - 优化 `PiAgent` 事件录制范围:只要处于流式生成(Busy/Streaming)状态,即便当前已有在线浏览器连接,也会向 `eventBuffer` 持续录制。
783
- - 优化缓存释放策略:若 Agent 仍处于 busy 生成状态,新连入的客户端消费完 `eventBuffer` 后不再立即清空 Buffer。
784
- - 优化重连/中途断开录制:若最后一个客户端在 streaming 途中断开连接,只要生成任务仍在运行中,即不销毁当前的缓存。
785
- - 以上多项优化完美实现了多台设备(例如手机、电脑)、多个浏览器 Tab 随时刷新或中途连入正在运行中的流式会话时,能够无缝重播已生成的上半段内容并追平后续实时流,极大地增强了多端多 Tab 的协同可靠性。
786
-
787
- ---
788
-
789
- ## [1.7.5] - 2026-07-26
790
-
791
- ### Fixed
792
- - **初始化 CWD 配置加载与 WebSocket 建立竞态修复 (Async CWD Init Race Condition)**:
793
- - 前端 `init()` 声明为异步函数,优先 `await loadServerConfig()` 完成服务器配置(`serverCwd` / `homeDir`)与本地缓存读取后,再发起 WebSocket 连接或加载会话,彻底消除首次加载时 agent 子进程工作目录与前端显示不一致的问题。
794
- - 服务端 `normalizeCwd(dir)` 在 `dir` 为空时默认使用 `process.cwd()`(服务启动目录),保证前后端默认工作目录始终精确统一。
795
- - **错误信息二次 HTML 转义修复 (Double Escape on Error Messages)**:移除 `message_end` 中冗余的 `escapeHtml()` 调用,避免错误信息包含特殊符号时被 Markdown 渲染器二次转义显示为实体编码字符。
796
- - **CLI 参数解析健壮性增强 (CLI Arguments Validation)**:`bin/pi-web-chat.js` 增加对 `-p/--port` 与 `-c/--cwd` 选项值的合法性检验与防越界保护,避免 `NaN` 或 `undefined`。
797
- - **输入法合成事件优化 (IME Keycode Handling)**:输入框 `keydown` 事件追加 `e.keyCode !== 229` 判断,进一步增强各平台中文输入法选词回车时的兼容性。
798
- - **Systemd 安装脚本优化 (Systemd Absolute ExecStart Path)**:`scripts/install-service.sh` 生成 unit 文件时将 `ExecStart` 明确为绝对路径 `$NODE_BIN "$PROJECT_DIR/server.js"`。
799
-
800
- ---
801
-
802
- ## [1.7.4] - 2026-07-26
803
-
804
- ### Added
805
- - **模型菜单实时搜索与过滤 (Model Search & Instant Filter)**:
806
- - 顶栏模型下拉菜单增加置顶固定的搜索过滤输入框,支持根据 Provider 提供商名称、模型名称、模型 ID 进行多维度实时模糊过滤。
807
- - 打开模型下拉框时自动聚焦并全选搜索框,支持一键清空(`×`)、按 `Escape` 快捷关闭、按 `Enter` 快捷选中。
808
- - 优化模型列表项布局,同时展示友好显示名与底层 Model ID,解决模型列表过长时翻找困难的问题。
809
- - 移动端与桌面端自适应滚动与粘性搜索栏布局。
810
-
811
- ---
812
-
813
- ## [1.7.3] - 2026-07-26
814
-
815
- ### Fixed
816
- - **新建会话即时绑定会话文件与 URL (Instant Session Binding)**:在 `public/app.js` 中自动捕获 RPC 消息中的 `sessionFile`,新建会话发送第一条 Prompt 后立即更新浏览器 URL、当前状态与侧边栏高亮,防止页面刷新丢失当前对话。
817
- - **服务端历史文本提取空指针保护 (Null Safety in extractText)**:在 `server.js` 的 `extractText` 增加对分片项为 null/undefined 的防守式过滤,避免异常历史记录导致元数据读取崩溃。
818
- - **移动端侧边栏底部连接状态与版本号显示修复 (Mobile Sidebar Bottom & Safe Area)**:修复手机端侧边栏 `100vh` 溢出导致底部“已连接/版本号”不可见的问题;增加 `100dvh`、`min-height: 0`、`flex-shrink: 0` 及全面屏 `safe-area-inset-bottom` 适配。
819
-
820
-
821
- ---
822
-
823
- ## [1.7.0] - 2026-07-26
824
-
825
- ### Added
826
- - **前端流式渲染防抖节流 (rAF UI Throttling)**:使用 `requestAnimationFrame` 节流高频 Token/Delta 事件,消除倒水式输出时的 DOM 频繁销毁与全量重塑,大幅提升高频打字时的流畅帧率,显著降低 CPU 和发热消耗。
827
- - **后端 Session 列表 mtime 内存缓存 (Session Metadata Caching)**:`/api/sessions` 引入基于文件修改时间(`mtimeMs`)的元数据内存缓存。对无改动的历史 Session 文件跳过磁盘读取与全量 JSON 逐行解析,大幅提升侧边栏列表加载响应速度。
828
- - **离线事件 Buffer 算法优化 (Ring Buffer O(1) Push)**:将 `PiAgent.bufferEvent` 从 $O(N)$ 复杂度的 `Array.shift()` 改为 $O(1)$ 的指针环形队列,消除无客户端连接时的数组平移消耗。
829
- - **WebSocket 垃圾连接自动回收 (Dead Socket Cleanup)**:在 `wsSend` 广播消息时动态检测并自动剔除已处于关闭状态(`CLOSING`/`CLOSED`)的垃圾 Socket 引用,避免泄露。
830
-
831
- ---
832
-
833
- ## [1.6.0] - 2026-07-26
834
-
835
- ### Added
836
- - **后台任务继续运行 (Background Task Persistence)**:
837
- - 关闭浏览器/标签页不再强制中止正在生成的 pi 任务:后台 pi RPC 子进程保持**跑完当前这一轮**;重连后可看到完整结果。
838
- - `PiAgent` 跟踪 `state`(`idle`/`streaming`)与 `pending` 请求。只有在“**无 WebSocket 且真正空闲**”(无 streaming 也无未响应请求)时才启动空闲回收计时。
839
- - 时长型缓冲区:在后台期间渲染器产出的事件会被**离线缓存**到 `EVENT_BUFFER_SIZE`(默认 2000 条)的环形 buffer。新连接上来时自动 **回放**为 `backfill_start` → N 条原始事件 → `backfill_end` 三个阶段包裹的消息,便于前端精确“追到哪儿”。
840
- - 新增 REST 端点 `GET /api/agents`:查看所有存活后台 pi 代理(`state`, `alive`, `busy`, `hasClients`, `uptimeMs`, `bufferedEvents`, 最近一条用户提示等)。常驻 npm 下载、上传、调试或后台 面板都可以利用。
841
- - 新增环境变量:`MAX_AGENT_LIFETIME_MS`(默认 1800000 = 30分钟,硬上限超出强制 `SIGTERM`;设为 0 禁用)。防止后台代理失控常驻。
842
-
843
- ### Changed
844
- - **`IDLE_TIMEOUT_MS` 语义重要变更**:从“**断开后多久**杀进程”变为“**真正空闲后多久**才回收”(默认还是 5min)。如果断开后还在 streaming 或有余未完成的 RPC 请求,定时器不会触发,任务不会被中断。
845
- - 首页顶栏重连后会同步服务器状态:收到 `backfill_end` 后会自动滚动到底,并恢复 `streaming` 状态(如仍在后台继续)。
846
- - 首页增加优雅关闭:`SIGINT`/`SIGTERM` 会“逐个停止所有后台 pi 进程”后再退出,防止 server 重启时留下 zombie 进程。
847
- - 不再支持“`IDLE_TIMEOUT_MS=0` 断开即杀”告诉——该环境变量现在表示“**禁用空闲回收**”。需要立刻释放内存,请改为正数(如 `5000`)或重启 server。
848
-
849
- ### 技术说明
850
- - `PiAgent` 生命周期事件:`agent_start → state=streaming`;`agent_end/agent_settled → state=idle`;`pi_exit → state=idle`。这是“背景继续跑完”的关键开关。
851
-
852
- ---
853
-
854
- ## [1.5.0] - 2026-07-26
855
-
856
- ### Added
857
- - **Idle timeout & concurrency control (内存保护增强)**:
858
- - 新增 `IDLE_TIMEOUT_MS` 环境变量,可配置浏览器断开后保留 pi RPC 子进程的时间(默认 300000ms = 5 分钟,设为 0 即关闭自动清理)。
859
- - 新增 `MAX_CONCURRENT_AGENTS` 环境变量,限制并发 pi 代理进程数(默认 0 = 无限制)。超限时新 WebSocket 连接返回 1013 (capacity) 并在控制台警告,防止多标签页把小内存机器挤爆。
860
- - 新增 `IDLE_DROP_HEAP=1` 环境变量,空闲时尝试调用 `global.gc()` 主动释放 V8 堆,配合 `--expose-gc` 让内存更快回收到 OS,而非被动 swap。
861
-
862
- ### Changed
863
- - `bin/pi-web-chat.js` 启动 server 时加入 `--expose-gc` 标志,支持上述主动内存释放。
864
-
865
- ---
866
-
867
- ## [1.4.2] - 2026-07-26
868
-
869
- ### Fixed
870
- - **移动端顶栏常驻与布局优化 (Sticky Topbar & Mobile Layout)**:
871
- - 顶栏 `.topbar` 设置 `position: sticky; top: 0; flex-shrink: 0; z-index: 20;`,确保在手机端滚动聊天、弹起软键盘或屏高变化时**始终常驻固定在屏幕最上方**,绝不随聊天区域滚动或被挤压。
872
- - 采用 Dynamic Viewport Height(`100dvh`),解决 iOS Safari 与 Android 移动浏览器地址栏/底部导航栏显示隐藏时的页面抖动与错位。
873
- - 优化移动端工作目录胶囊(CWD Pill)、模型胶囊(Model Pill)与会话标题的宽度挤压与弹性截断(`text-overflow: ellipsis`),小屏手机下依然精致美观。
874
-
875
- ---
876
-
877
- ## [1.4.1] - 2026-07-26
878
-
879
- ### Fixed
880
- - **切换/加载历史会话模型精准显示**:
881
- - 修复加载历史会话时由于后台进程启动时与 `get_state` 异步竞态导致右上角模型 Pill 显示不准确的问题。
882
- - REST `/api/session` 接口现在自动从该会话的 JSONL 历史链中精确提取最后使用的模型 (`model`)。
883
- - 切换会话时,前端能够零延迟(Instant)同步并渲染该会话对应的正确模型,同时支持 `model_select` 事件实时联动。
884
-
885
- ---
886
-
887
- ## [1.4.0] - 2026-07-26
888
-
889
- ### Added
890
- - **多端与多浏览器同步协同 (Multi-Device & Multi-Browser Session Sharing)**:
891
- - **WebSocket 多连接池**:服务端 `PiAgent` 进程升级为多连接池(`Set<WebSocket>`),电脑、手机、平板可同时挂载到同一个正在运行的会话,所有端实时同步接收 AI 流式回答。
892
- - **多端消息双向广播**:手机端发送 Prompt 或插入指导指令(Steer)时,电脑端无需刷新即可实时呈现用户消息并同步流式输出 AI 答复。
893
- - **URL 参数关联与一键分享**:选择会话时自动更新浏览器 URL 参数(`?session=...`),分享 URL 或在手机侧边栏选中同个会话即可直接加入同一会话同步协同。
894
-
895
- ---
896
-
897
- ## [1.3.0] - 2026-07-26
898
-
899
- ### Added
900
- - **运行时实时插入/拦截指令 (Steer Instructions During Agent Turns)**:
901
- - AI 正在思考、读取文件或执行命令(`streaming`)时,可以在输入框输入补充或修正要求。
902
- - 输入框右侧会自动展示 **`🧭 插入指令`** 按钮,按 Enter 或点击按钮可实时将指令发送给 `pi` 代理进程(发送 `steer` 消息)。
903
- - 聊天界面中插入的指令会展示带 **`🧭 指导指令`** 徽章的突出气泡,`pi` 接收后能在当前轮次中即时调整执行方向。
904
- - 未输入内容时,按钮保持原有的 `■` 停止按钮功能。
905
-
906
- ---
907
-
908
- ## [1.2.0] - 2026-07-26
909
-
910
- ### Added
911
- - **断线自动重连 (Auto Reconnect with Exponential Backoff)**:网页连接断开后前端启动指数退避自动重连(1s ~ 15s),并在侧边栏底部指示灯实时显示重连状态(`重连中 (x)`)。重连成功弹出“网络连接已恢复”提示。
912
- - **双向心跳检测 (Heartbeat Ping/Pong)**:服务端每 30 秒发送 WS Protocol Ping 清理僵尸连接,前端每 15 秒发送应用层 Ping,超时 45 秒无响应自动切断重连。
913
- - **重连会话状态同步 (State Restoration)**:重连后自动向服务端获取 `isStreaming` 状态。若生成已在后台完成则载入最新对话历史,若仍生成中则自动平滑接续流式输出。
914
- - **一键复制功能 (Copy Buttons)**:
915
- - **代码块/命令复制**:所有 Markdown 渲染的代码块顶部增加语言标签与“复制”按钮。
916
- - **工具调用指令复制**:在工具调用(如 `bash` 命令执行)卡片标题栏增加“复制”按钮,方便快速复制命令。
917
- - **回答全文复制**:在 `pi` 角色标签右侧新增“复制全文”按钮。
918
-
919
- ---
920
-
921
- ## [1.1.0] - 2026-07-26
922
-
923
- ### Added
924
- - **后台进程持久化 (Process Persistence)**:刷新或暂时离开 Web 页面时,`pi` Agent 进程继续在后台运行,重新打开/刷新网页会自动重挂载 (re-attach) 正在运行的进程,任务不会中断。
925
- - **历史工具输出归折 (Clean Tool Results Rendering)**:从历史记录恢复会话时,将离散的 `toolResult` 输出与对应 `toolCall` 绑定,整洁收纳于工具调用的 `⚙` 折叠卡片内,避免原始日志/代码平铺乱穿于聊天框中。
926
-
927
- ### Fixed
928
- - **历史会话加载异常**:修复 `/api/session` 接口中局部变量名遮蔽 Node.js `path` 模块导致的无法弹出会话历史问题。
929
-
930
- ---
931
-
932
- ## [1.0.1] - 2026-07-20
933
-
934
- ### Fixed
935
- - **空内容 pi 气泡**:`message_start` 原本不区分角色,用户消息回显也建了一个空 pi 气泡 — 现在只对 `role:assistant` 开 streaming 块。
936
- - **重复文本渲染**:pi 在 `message_start` 就带完整 content、随后又用 `text_delta` 发同一文本 — 改用 `text_end.content` 覆盖累加结果,避免出现 `WS_OKWS_OK`。
937
- - **模型出错时空白回复**:当模型返回 `stopReason=error` 又无内容时(如选了不可用模型),现在显示明确的“生成失败 / 请换模型”提示。
938
- - **侧边栏漏掉 Web 新建的会话**:`server.js` 传给 pi 的 `--session-dir` 导致新 session 被直接放在 sessions 根目录而非 cwd 子目录中;`listAllSessionFiles` 原仅扫子目录,于是 11 条 Web 创建的会话一个都列不出来 — 现在同时扫根目录下的 `.jsonl`。
939
- - **新建会话非手动刷新不可见**:根因是上一条 — 侧边栏根本扫不到新文件。现在 `agent_settled` 后列表实时反映新会话,无需刷新页面。
940
- - **初始化时模型 pill 永远空白**:`init()` 里 `// pull current state once:\n setTimeout(...)` 把 `\n` 当成字面字符写进了单行注释,`get_state` / `get_available_models` 永不发出 — 改为真实换行后两调用均发出。
941
- - **工具调用参数显示不全**:新增 `toolcall_delta` / `toolcall_end` 处理,用 `toolcall_end` 的最终 `toolCall.arguments` 刷新头部 args 显示。
942
- - **同一 agent 多轮 agent message 互相污染**:`message_start`(assistant) 重置本块的 text/thinking 累加器,避免上一轮工具调用与下一轮文本串到一起。
943
-
944
- ---
945
-
946
- ## [0.2.0] - 2026-07-19
947
-
948
- ### Added
949
- - **新建会话流程修复**:`btnNew` 点击后刷新侧边栏、清理流式状态、生成新 ws 代次。
950
- - **WebSocket 代次机制**:`wsGen` 防止旧 socket 消息污染新上下文。
951
- - **输入框红边提示**:ws 未连时提交会有 350ms 红色 flash。
952
- - **连接状态文本动态更新**:「连接中…」→「已连接」/「已断开」。
953
- - **提交**:`5a8f036` "Fix new-session flow: ws generation guard + sidebar refresh + drop input"
954
-
955
- ### Fixed
956
- - 新建会话后左侧不出现(缺 `refreshSessions()`)
957
- - 快速切换会话导致 prompt 被当作 abort(旧 socket stragglers)
958
-
959
- ---
960
-
961
- ## [0.1.0] - 2026-07-19
962
-
963
- ### Added
964
- - 项目初始化:`server.js` (Express + ws) + `public/` (HTML/JS/CSS)
965
- - REST API:
966
- - `GET /api/sessions?cwd=` — 列出该 cwd 下所有 session(标题、时间、消息数)
967
- - `GET /api/session?file=` — 重建会话的根→叶对话线
968
- - WebSocket `/ws?cwd=&session=` — 1:1 桥接 `pi --mode rpc`
969
- - 前端 UI:
970
- - 左侧栏:搜索、历史列表、点击切换
971
- - 右侧:空状态建议、流式对话、Markdown 渲染
972
- - 底部:textarea + 发送/停止按钮
973
- - 顶栏:会话名、模型选择 pill
974
- - 流式渲染:文本打字光标、thinking 块、工具折叠块
975
- - 会话历史持久化:复用 pi 原生 `~/.pi/agent/sessions/*.jsonl`
976
- - 多模型切换(pi 配置的所有 provider/model)
977
- - 响应式深色主题(ChatGPT/Gemini 风格)
978
-
979
- ---
980
-
981
- ## Legend
982
-
983
- | 标记 | 含义 |
984
- |------|------|
985
- | **Added** | 新功能 |
986
- | **Changed** | 现有功能变更 |
987
- | **Deprecated** | 即将移除 |
988
- | **Removed** | 已移除 |
989
- | **Fixed** | Bug 修复 |
990
- | **Security** | 安全相关修复 |