pi-web-ui 0.80.2 → 0.83.0
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/CHANGELOG.md +167 -2
- package/README.md +112 -97
- package/README.zh-CN.md +86 -66
- package/dist/server/agent-service.js +385 -13
- package/dist/server/attachments.js +36 -0
- package/dist/server/index.js +5 -0
- package/dist/server/mcp-bridge.js +132 -23
- package/dist/server/plugins.js +23 -2
- package/dist/server/subagent-templates.js +30 -2
- package/dist/server/subagents.js +25 -15
- package/dist/server/tool-manager.js +7 -1
- package/dist/server/webui-context.js +28 -4
- package/package.json +4 -2
- package/plugins/catalog.json +9 -0
- package/themes/cyberpunk.css +1 -0
- package/themes/dazzle.css +1 -0
- package/themes/md-preview.css +1 -0
- package/themes/mist.css +1 -0
- package/themes/paper.css +1 -0
- package/themes/sakura.css +1 -0
- package/themes/white.css +1 -0
- package/web/dist/assets/{TerminalPanel-CeruoZjh.js → TerminalPanel-BF99sld0.js} +1 -1
- package/web/dist/assets/index-B1XPfcM0.css +10 -0
- package/web/dist/assets/index-D__1RagK.js +348 -0
- package/web/dist/index.html +2 -2
- package/web/dist/assets/index-BduNm7_u.css +0 -10
- package/web/dist/assets/index-DtBJSe33.js +0 -347
package/CHANGELOG.md
CHANGED
|
@@ -10,7 +10,154 @@
|
|
|
10
10
|
|
|
11
11
|
## [Unreleased]
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
暂无其他未发布内容。
|
|
14
|
+
|
|
15
|
+
## [0.83.0] — 2026-09-13
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- **子代理模板可以固定思考强度了**(issue #130)——模板原来只能固定模型、提示词与白名单:`explore` 想跑快点、`review` / `oracle` 想往深处想,只能跟主对话共用一个档位;更隐蔽的是子代理原本一律吃 SDK 默认档(medium),主对话调到 `xhigh` 也传不过去。现在模板编辑器里多了一个**思考强度**下拉(off / minimal / low / medium / high / xhigh / max,与顶栏那个下拉共用同一份档位与文案):
|
|
20
|
+
- **留空 = 跟随主对话当前强度**(与「模型留空 = 跟随主对话当前模型」同语义);指定了就用该档位 —— 于是「角色 + 模型 + 强度」能配成一套固定组合。
|
|
21
|
+
- **模型不支持的档位自动收敛**(SDK 行为:非推理模型只能 `off`,`xhigh` / `max` 需要模型声明 `thinkingLevelMap`),收敛不报错、不影响派发。唯一行为变化:子代理默认强度从「SDK 默认档」变成「跟随主对话」。
|
|
22
|
+
- AI 侧的 `subagent_templates` 清单里每个模板都报出模型与思考强度(没配的写「跟随主对话…」),派单时不用猜。
|
|
23
|
+
- 脏数据宽容:老 `subagent-templates.json` 没这个字段 → 空(跟随主对话);值写错(如 `ultra`)当未配置处理,不报错也不猜。
|
|
24
|
+
- 回归:单测(字段归一 / 只认七档 / 内置模板不预设强度 / 工具输出报出强度)、协议冒烟 `subagent-template-test.mjs`(wire 透传 + 非法值归一 + 落盘)、新增零 token 端到端 `subagent-thinking-test.mjs`(mock provider + reasoning 模型:模板 `high` → high、留空 → 跟随主对话的 `low`、模板 `max` → 收敛成 high;改动前这三条全是 medium)。
|
|
25
|
+
|
|
26
|
+
- **「浏览器操作」面板支持把已授权页面一键引用到对话** —— 之前要让模型操作某个页面,得在话里手打网址。现在:只授权了**一个**页面时,顶栏按钮直接变成那个页面的标题(点主体就把引用放进输入框,右侧 ▾ 仍是状态面板);多个页面时,面板里每项都有「引用到对话」,可连续引用多个。
|
|
27
|
+
- 引用进输入框的是 `🌐 页面标题` 的附件 chip(与「引用文件」同一套:可删、可多条、可和文件附件混搭),**不自动发送** —— 你补一句「把前十条读出来」再发;编辑重问时照旧恢复。
|
|
28
|
+
- 发送时服务端把附件渲染成给模型的一句话(`<browser-page url title>`):**这个页面已授权、用 `browser_page`、`target=` 该 origin** —— 模型不必从自然语言里猜网址,也不会跑去抓网页。
|
|
29
|
+
- 回归:`browser-control.test.ts`(单页紧凑态判定 / 引用附件形状)、`attachments.test.ts`(不读文件 + target 提示 + 属性转义)、`question-attachments.test.ts`(重问恢复),以及 `browser-cite-test.mjs` E2E(单页按钮、点击引用、去重、chip 删除、多页面板引用)。
|
|
30
|
+
|
|
31
|
+
- **`browser_page` 支持截图(`op:"shot"`):模型终于“看得见”页面** —— 之前它只能靠 `read` 读 DOM 文本,「这页看起来对不对」这类问题答不了。截图支持整屏或指定元素(按 rect 裁剪,元素几乎不在视口里时不截,而不是给一张碎图),长边默认 1280 / 上限 1568(JPEG)。
|
|
32
|
+
- **主模型能识图就直接给图**(当轮可见);**纯文本模型自动走视觉桥转写**(与用户粘贴图片同一套逻辑与提示词,设置里开着就生效,无需额外配置)。注意:`deliverAs:"nextTurn"` 的附件通道要等下一次用户发言才注入,所以截图**不能**走那条路——必须在工具结果里给图或转写文本。
|
|
33
|
+
- **两个必须知道的代价**(选项页与 README 都写明):① 浏览器的 `captureVisibleTab` 只认 `<all_urls>` 或「点图标那一刻的 activeTab」,普通 host 授权不够 —— 所以打开「允许截图」会弹一次「读取您在所有网站上的数据」,不给就保持关闭(模型仍能用 `read`);② 截图只能截当前活动标签页,扩展会先把目标页切到前台、**截完立刻切回**(失败也切回)。
|
|
34
|
+
- 开关:「允许截图」默认开(但要先授一次权限),关掉后 `shot` 直接被拒并说明去哪开。
|
|
35
|
+
- 回归:`page-picker-bridge.test.ts` 的 shot 用例(切页顺序、失败也切回、按 rect 裁剪、没权限时明确拒绝、开关关闭)、`browser-page-tool.test.ts` 的结果组装(给 image block 且 data 是纯 base64 / 走视觉桥带 `<vision-bridge>` / 桥不可用时说明原因 / 老替身不炸)、`page-picker-ai-ops.test.ts` 的 `metrics`,以及真扩展 E2E(截图开关与权限门控的文案)。真扩展 E2E 还抓到一个真 bug:`captureVisibleTab` 的 `quality` 必须是 **0-100 的整数**,传 0.72 会报 `expected integer`。
|
|
36
|
+
|
|
37
|
+
- **「AI 操作浏览器页面」在 pi-web-ui 侧终于有入口了**(顶栏「浏览器操作」按钮 + 状态面板)。上一版把能力做完了(`browser_page` 工具 + 扩展授权表),但之前**用户那边一片空白**:不知道有这个能力、不知道去哪开通、不知道能说什么。现在:
|
|
38
|
+
- 顶栏按钮显示状态(授权了几个页面),需要你动手时(未授权 / 总开关关)变成醒目色;
|
|
39
|
+
- 面板里报「扩展在不在 / 已授权的页面(标题 + 地址 + 开没开)/ 两个总开关」、给出授权三步、两句可照拄的例子;
|
|
40
|
+
- **「打开扩展设置页」按钮**:网页不能自己导航到 `chrome-extension://`(浏览器会拦),所以这一步由扩展代劳(新动作 `openOptions`);状态查询走新动作 `status`。
|
|
41
|
+
- **AI 在页面上动手时,那个页面会闪一条提示**:「AI 正在操作本页 · click #submit」(右下角、挂 shadow DOM、只报信不拦截、2.2s 淡出、不堆叠、卸桥时一并清掉)—— 否则用户会以为页面自己在动。
|
|
42
|
+
- 回归:`tests/unit/browser-control.test.ts`(状态查询与开设置页的四种失败/成功路径)、`page-picker-ai-ops.test.ts` 的提示条用例、`tests/page-picker-edge-ext-test.mjs` 里真扩展下的 `status` / `openOptions`(真的开出一个设置页)。
|
|
43
|
+
|
|
44
|
+
- **模型多了一个 `browser_page` 工具:直接操作你在浏览器里授权的页面**(需要 pi-web-ui 0.83.0+ 与 page-picker 扩展 0.4.0+)。以前人只能把页面“描述”给 AI(拾取元素→粘上下文),现在模型可以在对话里直接读那个页面、点它的按钮、填表单、滚动、跳转,必要时在它里跑一段脚本。
|
|
45
|
+
- **链路**:模型调工具 → 服务端把请求推给浏览器里那个 pi-web-ui 页面(新协议消息 `page_request`)→ 页面经宿主桥 `window.__piWebUiHost.pageCall()` 转给扩展 → 扩展在授权页面上执行 → 结果原路回到模型(`page_response`)。所以**那个 pi-web-ui 标签页得开着**(与拾取投递同一个取舍)。
|
|
46
|
+
- **只需授权被操作的那个页面**:另一端固定是 pi-web-ui 页面,不用像页面桥那样配两端。授权在扩展选项页点一次(顺带申请 host 权限),可随时收回。
|
|
47
|
+
- **八个动作**:`pages` / `read`(文本/HTML/title/url/元素查询)/ `click` / `type`(走原生 setter + 补发 input/change,React 受控组件也认;`submit` 发回车)/ `scroll` / `goto`(先回结果再跳)/ `wait`(等元素或文案)/ `eval`。
|
|
48
|
+
- **三层开关**:pi-web-ui 设置→工具里的 `browser_page`、扩展选项页的「允许 AI 操作页面」总开关、以及单独一项 **`eval`(默认关)** —— eval 等于把页面交给模型写的脚本,要用得手动打开。
|
|
49
|
+
- **安全边界**:授权列表是唯一凭据(未授权页面一个字节都不注入);只有“浏览器里那个已绑服务地址的 pi-web-ui 页面”能发起(用 `sender.tab.url` 判定);动作名过白名单(其它一律拒)。
|
|
50
|
+
- **失败都说人话**:没授权去选项页授权 / 页面没打开 / 多个页面要指定 target / 选择器没匹上 / wait 超时返回 `found:null` / 页面 CSP 禁了 eval 时提示换动作 / 浏览器里没开 pi-web-ui 页面时提前退出。
|
|
51
|
+
- 已知边界(写进 README 与选项页):eval 受目标页面 CSP 约束;桥只在顶层帧,跨源 iframe 拿不到;`chrome://`/扩展页/商店页/`file://` 不能授权;页面里的第三方脚本也能看到注入的 `window.__piBridge`(与页面桥同一个边界)。
|
|
52
|
+
- 回归:`tests/unit/browser-page-tool.test.ts`(工具 schema、args 组装、超时归一、`pageCall` 超时/迟到响应/无前端/中止)、`tests/unit/page-picker-ai-ops.test.ts`(八个动作的真 jsdom 行为)、`page-picker-bridge.test.ts` 的 AI 路由(宿主/授权页/配对页三角色、总开关与 eval 开关、白名单、`pages` 由 worker 直答)、`tests/unit/plugin-host-page-call.test.ts`(宿主桥 pageCall 的三条纪律)、`tests/page-picker-bridge-test.mjs` 与 `tests/page-picker-edge-ext-test.mjs`(**真浏览器**:宿主读授权页标题、真点击、eval 开关、宿主页面不走配对表)。
|
|
53
|
+
|
|
54
|
+
- **page-picker 扩展:页面桥 —— 两个配对过的页面可以互相读写**(跨源、跨标签页、跨窗口)。拾取是单向的(网页 → pi-web-ui 输入框),这块把另一个方向也打开:对端页面 `window.__piBridge.on("orders", () => …)` 注册能力,这边 `await window.__piBridge.call({ op: "orders" })` 拿到数据,或者调 `highlight` 去操作对端的 DOM。浏览器里只有扩展能做到这件事(跨源 `postMessage` 要 `window.open` 的句柄且对方配合,`BroadcastChannel` / `localStorage` 只限同源)。
|
|
55
|
+
- **默认关闭,只认配对**:选项页「页面桥」里填两个 origin → 点「授权并添加配对」(权限申请必须在扩展自己的页面上点,网页上的按钮给不了浏览器要的手势)。没配对的页面一个字节都不注入。
|
|
56
|
+
- **地址不用手打**:在要配对的两个页面里各点一次扩展图标,它们就进了候选下拉(点过图标那一刻有 `activeTab`,url 与标题都可读;不为此多要 host/`tabs` 权限);开发页的拾取浮条上还有「与另一页配对…」按钮,点一下把本页预填好并直接打开设置页的配对面板。
|
|
57
|
+
- **准入只看 `sender.tab.url`**:消息体里自称是对端也不作数 —— 否则 A 页面可以冒充 B,把 B 的数据全拿走。停用的配对同样拒绝,且与「没配对」分开报原因(一个是去启用、一个是去添加)。
|
|
58
|
+
- **失败都说人话**:对端没打开、对端没注册那个 op(报错里列出它注册了什么)、结果过大(参数 ≤ 256KB / 结果 ≤ 512KB)、返回值不可克隆(循环引用)、对端 handler 抛错、超时(默认 5s,页面侧自己兜底,Promise 不会悬着)。对端刚导航完(桥还没装上)会自动补装一次再重试。
|
|
59
|
+
- **注入时机**:SW 启动、配对表变更、页面导航完成时协调;删配对/停用会把页面上的桥卸下。
|
|
60
|
+
- 已知边界(写在选项页与 README 里,不藏):桥在页面**主世界**,所以被配对页面里的任何脚本(含第三方广告/统计)都摸得到 `window.__piBridge` —— 只对你信任的页面开桥;`chrome://`、扩展页、商店页、`file://` 不能配对;桥装在顶层帧。
|
|
61
|
+
- 回归:`tests/unit/page-picker-bridge.test.ts`(准入/路由/体积/页面侧函数的自包含性/配对候选)、`page-picker-options.test.ts` 的配对管理单测(加/删/停用真的落盘并通知 worker、候选下拉与 `?pair=` 深链预填)、`tests/page-picker-bridge-test.mjs` 浏览器 E2E(**两个真实 origin + 真实 `dist/bridge.js` + 真实 background 逻辑**:A 读 B 的数据、B 改 A 的 DOM、没配对的页面调不动任何人、删配对后桥真的被卸下),以及 `tests/page-picker-edge-ext-test.mjs` 的**真扩展**场景(真 `executeScript` 注入 MAIN world + 真 `storage.local` 喂候选下拉)。
|
|
62
|
+
|
|
63
|
+
- **page-picker 扩展:六个预设与「发送什么」的逐项勾选,在拾取页面上就能改** —— 原来只有扩展选项页能改(为了改一个勾选得去开 `chrome://extensions`),而「这次只要源码位置」「这次只排查样式」这种判断,恰恰是站在页面上看着元素时才有的。现在点完元素后,**底部确认条里就有一排预设 chip**(精简 / 标准 / 完整 / 改对地方 / 样式 / 文案),右边「调整项 ▾」可展开 8 项逐项勾选(与选项页等价,默认收起);拾取阶段的信息条上常显当前预设,`Alt+1~6` 是同一个入口(键盘也能把整套流程走完)。
|
|
64
|
+
- 改完**立刻按新档位重新采集已经选好的元素**:快照是点击那一刻取的,不重采就会出现「浮条上写着精简、发出去的还是完整档」;元素已被页面换掉(SPA 重渲染)时保留原快照,不影响投递。
|
|
65
|
+
- 选择会**写回扩展设置**(选项页同步可见、下次拾取沿用;只写 `detail` + `sections` 两个键,不碰服务地址与口令)。后台没响应时在**摘要行尾**说明「没同步到扩展设置(这次的选择只在本页生效)」—— 不用 toast,因为确认条正开着,盖住它反而看不清。
|
|
66
|
+
- **不允许勾到一项不剩**(空列表在契约里会回落标准组合,那会让人以为「我全取消了它还发」):取消最后一项直接拒绝并提示。
|
|
67
|
+
- 回归:预设短名 / `applySectionToggle` / 热键解析单测,浮条控件单测(jsdom 真点击:点 chip 回调、逐项勾选、拒绝清空、折叠面板、告警文案),service worker 写回单测(脏数据回落 / 只写两个键 / 写失败报错),E2E 页面上切预设后落盘 + 已选元素重采 + 发出去的 Markdown 真的变瘦。
|
|
68
|
+
|
|
69
|
+
- **图片工具插件适配手机端**:三栏硬布局(队列 236px + 舞台 + 参数栏 320px,一条 media query 都没有)在手机上必定挤爆 —— 现在视口 ≤ 640px 时改成上下堆叠:队列变成顶部横向缩略图带(只留缩略图与删除,名字/尺寸在手机宽度里全是省略号),参数栏变成底部抽屉(默认半开;顶上那条手柄一点就收起,只剩 tab 行 + 动作行,舞台立刻高一倍以上;抽屉收着时点任意 tab 会自动展开),舞台独占剩余高度,各区块自己滚,不会把宿主的 `.plugin-view` 顶出外层滚动条。
|
|
70
|
+
- 窄屏下按钮不再折行(中文按钮被压窄会变成竖排的「适应」),状态条改横向滚、不再换行把舞台越顶越小;弹窗 / 工作区列表贴边,行高按能点中做。
|
|
71
|
+
- 触屏(`pointer: coarse`)裁剪把手 11px → 20px、滑杆与勾选框同步加高;裁剪拖动本来就吃 `touch-action: none`,不会和页面滚动打架。
|
|
72
|
+
- 宽屏三栏布局与尺寸未动(回归里仍断言桌面三栏宽度与总高度)。
|
|
73
|
+
- 回归:`image-toolkit-view-test.mjs` 新增手机端一段(真 Chrome 390×780 + `isMobile`/`hasTouch`:堆叠方向、横向缩略图带、自下而上顺序、无横向溢出、抽屉收起与点 tab 展开、收起后舞台变高、触屏把手尺寸),并给测试页补上与宿主一致的 `<meta name="viewport">`(缺了它 `isMobile` 模拟下布局宽度是 980,断点根本不命中)。
|
|
74
|
+
|
|
75
|
+
### Fixed
|
|
76
|
+
|
|
77
|
+
- **右栏扩展区不再是一块「浅色主题下的深灰块」**:那块 widget 容器写死了 `background: rgba(0, 0, 0, 0.15)` —— 深色主题下正好,浅色 / 暖纸 / 雾蓝 / 樱粉主题下就是一块压在浅底上的深灰。现改成主题 token `--sunken-bg`(深色 = 15% 黑;浅色系按各自色调给 4%~5% 低透),`make-light-theme.mjs` 的 LIGHT_DERIVED / PAPER / MIST / SAKURA 各补一条、7 个内置主题由生成器同步重出。
|
|
78
|
+
- 语义写进 token 注释:**布局里禁止写死 `rgba(0,0,0,…)`**,凹陷内容面(比所在底板低一层的区域)一律引用 `--sunken-bg` —— 与上一版那批幽灵 token 同一条纪律。
|
|
79
|
+
|
|
80
|
+
- **goalbar / 问卷面板的背景不再比聊天区差一档**(PR #131 的观感跟进)——上一版把 goalbar 的幽灵 token 修好之后,它(和问卷面板)成了一块带底色的卡片;而它们所在的那一段(消息区与输入区之间)**只有卡片自己有底色**,卡片四周与列外区域的间隙露的是裸页面背景 —— 浅色与壁纸主题下就是**一条比聊天区更暗、一直横到面板两侧的带子**(深色主题差得少一点,同样能看出来)。
|
|
81
|
+
- 玻璃底上移到容器:`.main` 整块聊天面板统一涂 `--msgs-bg`(消息区 + goalbar / 问卷面板那一段 + 输入区),`.messages-wrap` 与 `.inputbar` 不再各涂一层 —— 叠加两层反而比 goalbar 区亮一档,会换一条新的横向色阶。
|
|
82
|
+
- goalbar 与问卷面板**不再自带底色**(即 0.82.0 的观感):背景 = 聊天背景,活动态靠琥珀边框、问卷靠强调色边框 + 投影区分;折叠态的小 pill 仍是控件底(`--chip-bg`),选项预览块(`.question-preview`)与问卷底部 sticky 条保持原样。
|
|
83
|
+
|
|
84
|
+
- **修掉一批「幽灵 CSS 变量」:goalbar、问卷面板、插件按钮在浅色主题下不再是深色块**(PR #131)—— 引用一个**全史从未定义**的自定义属性,按 CSS 规范是 guaranteed-invalid:**整条声明在计算值阶段失效**。`--bg-elev1`(正确名是 `--bg-elev`)从引入它的那笔提交起就是笔误,后果是:goalbar 全家**没有填充**(看着像故意画个框)、输入框丢掉整条 `box-shadow`(连聚焦光环一起没)、插件里带 fallback 的写法则静默用硬编码 `#16161d` → 白色 / 雾蓝 / 暖纸 / 樱粉主题下是深色块。同批还修了 `--glow-inset`(全史未定义)与 `--text-2`(全史未定义,`color` 回落 inherit → 比预期亮)。
|
|
85
|
+
- 按语义改回已定义变量(与 13be9ab 那批改名同方向):菜单内说明块 / 按钮 / 徽章 → `--bg-elev`;消息头悬停 → `--bg-elev2`(用 elev 的话白色主题下等于卡片色,悬停看不见);`--glow-inset` → `--glow-05`(`--glow-*` 家族最小的高光,各主题已有对应浅色值);`--text-2` → `--text-dim`;webmail / demo-mailbox 的 `--bg-elev1` / `--bg-elev0` → `--bg-elev` / `--bg`(保留原 fallback)。
|
|
86
|
+
- **goalbar 与问卷面板改走壁纸体系**:`.goalbar` → `--card-bg`、`.goalbar-hint` → `--chip-bg`、`.goalbar-active` 的 8% 琥珀叠色同步换底;`.dialog-inline`(扩展弹窗 / 提问对话框)与 `.question-preview` → `--card-bg` —— 它们本来就是列内卡片(与消息列同宽),原来写死 `--bg-elev2` 在壁纸 / 半透明主题下与四周玻璃面板有明显色阶差。问卷的 sticky 底栏保持实色(它的职责是遮住从下面滚过的正文,半透会让正文透出来)。
|
|
87
|
+
- 顺手删掉 `.goalbar-hint` 里那句被同规则后句覆盖的 `background: transparent`(正是它让「没有填充」看起来像有意为之)。
|
|
88
|
+
- 新增静态体检 `tests/unit/css-tokens.test.ts`:扫 `web/src` + `plugins` + `themes` + `web/index.html` 里每个 `var()` 引用,要求全仓某处有 `--x:` 声明(带 fallback 的也查);豁免运行时注入(`--fp-zoom` / `--left-w` / `--right-w` / `--rail-gap` / `--msgs-gutter`)、刻意的中性兜底(`--bg-input` / `--border-subtle` / `--muted` / `--warning`)与 vendored 的 `--vscode-*`。改前跑它报 14 + 5 处(styles.css 14 处无 fallback,插件 5 处带 fallback),改后归零 —— prettier / oxlint / 浏览器 E2E 都拦不住这种静默退化,所以让它进 CI。
|
|
89
|
+
|
|
90
|
+
- **MCP 桥的子进程崩溃后不再永久失效(自动重启,不用重启服务)**(PR #129)——外部 MCP 服务器被 OOM 杀掉、被外部 kill、或自己崩了之后,桥原来只把在途请求报错、把子进程句柄置空,**之后所有工具调用都写进空气**:挂满 60 秒报一句 `tools/call 超时`,而且**每次都是**这样,只有重启服务才能恢复。现在下一次工具调用会**先惰性重启**(重新 spawn + `initialize` 握手 + `tools/list`)再发;重启失败就直接抛「服务器进程已退出且自动重启失败:<根因>」,不再干等 60 秒。惰性而非退出即重启是刻意的:配置写错的服务器只在真被调用时试一次,不会空转拉进程。
|
|
91
|
+
- 三条生命周期不变量:显式关闭后**永久停用**(不复活)、重启过程中被关闭会回收刚起的进程**不留孤儿**、**并发调用共享同一次重连**(先判 `starting` 再判 `child`,否则第二个调用会抢在 `initialize` 应答前发 `tools/call`)。顺手修掉 spawn/握手失败漏子进程、退出后写 stdin 的 EPIPE(可能触发未捕获异常)两个隐患。
|
|
92
|
+
- 回归:单测 5 例(在途调用立即报「进程退出」而非挂超时 → 下一次调用自动重启成功、启动即退出的服务器快速报错、`close()` 后不再重启、崩溃后经 `PluginAgentTool.execute` 真实转发路径恢复);夹具新增 `crash` 自杀工具(工具数 8→9,冒烟同步),并开始按真 MCP 语义**在 `initialize` 应答写出前拒绝 `tools/call`(-32002)** —— 并发抢跑会因此变成可见失败。
|
|
93
|
+
|
|
94
|
+
- **page-picker 扩展:拾取时顶部信息条不再被挤成「竖排文字」** —— 它一直是 `left:50% + translateX(-50%)`(没有 `right`),也就是可用宽度只有 `50vw`,`max-width: 92vw` 实际从没生效;窗口一窄或提示一多,里面的字就被压成一行一个字。改成 `width: fit-content; margin: 0 auto`(居中效果不变)并允许**整项**换行;底部的提示条(toast)同一处理。
|
|
95
|
+
|
|
96
|
+
- **子代理会话里的扩展不再因为调用新 UI API 崩溃,也不会卡在无人应答的弹窗上**(PR #128)——子代理原来只拿到 `{ theme, setStatus, setWidget, notify }` 四个方法的 mock,扩展一旦调用 `ExtensionUIContext` 上的其他方法(`setWorkingVisible` / `setToolsExpanded` / `setTheme` …)就 TypeError,浏览器上还多一条 error toast;补成完整 `WebUIContext` 之后换了个坑:那个上下文没有浏览器面板,`select / confirm / input` 照旧挂 Promise,第一个在子代理里问用户问题的扩展会**永久 await**(只有 20 分钟的工具看门狗兜底)。现在子代理用 `WebUIContext.headless()`:方法面与主对话完全一致,但 UI 输出全部丢弃(不会与主对话的 widget/status 串台)、widget 组件工厂不调用(不留下没人 dispose 的组件)、弹窗立即按「取消」返回。
|
|
97
|
+
- 回归:`tests/unit/webui-context.test.ts`(弹窗立即取消 / 输出丢弃 / 不构造组件)+ `tests/subagent-ui-context-test.mjs`(零 token 端到端:探针扩展把 21 个新 UI 方法都调一遍,再断言子代理侧 `confirm=null`、主对话侧仍是「没人答」;改动前这两条分别挂 4 项与 1 项)。
|
|
98
|
+
|
|
99
|
+
暂无其他未发布内容。
|
|
100
|
+
|
|
101
|
+
<!-- auto-i18n:start -->
|
|
102
|
+
### i18n
|
|
103
|
+
|
|
104
|
+
- 前端新增 key(28):`browserPageEnabledDesc`、`browserPageOffHint`、`browserControl`、`browserControlTip`、`browserControlChecking`、`browserControlOffline`、`browserControlEmpty`、`browserControlDisabled`、`browserControlPages`、`browserControlPageOpen`、`browserControlPageClosed`、`browserControlExamples`、`browserControlExample1`、`browserControlExample2`、`browserControlOpenOptions`、`browserControlRefresh`、`browserControlCite`、`browserControlCiteTip`、`browserControlCiteNote`、`browserControlCited`、`browserControlCiteFailed`、`browserControlOpenPanel`、`browserControlSingleTip`、`attachPage`、`attachPageShort`、`tplThinkingLabel`、`tplThinkingFollowMain`、`tplThinkingHint`
|
|
105
|
+
- 前端中文变更(2):`settingsSubagentTemplatesDesc`、`noSubagentTemplates`
|
|
106
|
+
- 前端英文变更(2):`settingsSubagentTemplatesDesc`、`noSubagentTemplates`
|
|
107
|
+
<!-- auto-i18n:end -->
|
|
108
|
+
|
|
109
|
+
## [0.82.0] — 2026-09-13
|
|
110
|
+
|
|
111
|
+
### Added
|
|
112
|
+
|
|
113
|
+
- **page-picker 扩展:「发送什么」改成逐项多选(另配 6 个预设)**——原来只有三档详细度(精简/标准/完整),要么一起多、要么一起少;实际用起来常是「这次只要源码位置」「这次只要样式,别的别发」。现在设置页可以逐项勾:页面上下文 / 定位信息(选择器+尺寸)/ XPath 与 DOM 路径 / 源码位置(React/Vue 文件:行号 + 组件链)/ 文本 / 命中的 CSS 规则 / 计算样式 / HTML 骨架(元素截图仍是单独一项)。**没勾的在采集层就不采**,不只是渲染时丢掉——生成 HTML 骨架、读 CSSOM 这些本身就有开销,顺手也把这点省掉。预设覆盖常见组合:精简 / 标准(默认)/ 完整 / 只要能改对地方(选择器+源码)/ 只排查样式(命中 CSS+计算样式)/ 只看文案结构(文本+骨架),一键勾好之后还可以手动增减(预设同时决定采集深浅:文本长度、骨架深度、选择器深度)。老设置(只有 `detail`)升级后按原档位预勾,行为不变。
|
|
114
|
+
- 回归:`sectionsForDepth`/`normalizeSections`/`presetForSections` 单测、采集层「没勾就不采」单测(jsdom)、渲染层「只输出勾选项」单测、设置页多选 UI 单测(勾选真的落盘 / 预设联动 / 全不勾会提示并回落标准组合)、E2E 用自定义组合真投递一遍。
|
|
115
|
+
|
|
116
|
+
暂无其他未发布内容。
|
|
117
|
+
|
|
118
|
+
## [0.81.2] — 2026-09-13
|
|
119
|
+
|
|
120
|
+
### Fixed
|
|
121
|
+
|
|
122
|
+
- **page-picker 扩展:修「pi-web-ui 页面明明开着,却报『没找到打开的 pi-web-ui 页面』」**——0.2.0 查找目标标签页时传的过滤条件是 `["<地址>/*", "<地址>"]`,而**裸地址(没有路径的 origin)不是合法 match pattern**:真 Chrome/Edge 的 `chrome.tabs.query` 会直接抛 `Invalid url pattern 'http://localhost:8787'`,那个异常被 catch 成了「没找到页面」,于是拾取结果只能退化成「复制到剪贴板」(选项页「测试连接」里的同名查询也一并修)。现在查询只用 origin 级模式(`http://localhost:8787/*`),路径前缀仍由 `tabMatchesBase` 严格复核(子路径反代、前缀相似的站点都不受影响)。
|
|
123
|
+
- 这个 bug 能活着发布,是因为单测/E2E 用的是**假 chrome**,它不校验 match pattern:现在假 chrome 也按真 Chrome 的规则校验入参(`isValidMatchPattern`),这类坑会直接挂在单测上。
|
|
124
|
+
- 另加一条**装真扩展**的 E2E(`tests/page-picker-edge-ext-test.mjs`):实测 Edge(152,headless)仍接受 `--load-extension`,所以能在真 `chrome.*` 上把「拾取 → 投递 → Markdown 真的落进 pi-web-ui 输入框」跑一遍(没装 Edge 自动 SKIP)。
|
|
125
|
+
- **page-picker 扩展:修「在 pi-web-ui 页面上点图标没任何反应」**——绑定浮条原来完全依赖 background 的 MAIN world 探测(`__piWebUiHost` / `/api/health`),那个注入一旦被 CSP/权限/环境挡住,就会静默回落到拾取器,用户看到的就是「新功能没出现」。现在:探测不可用时也照旧注入浮条,**浮条自己再认一次页面**(同源 `/api/health` + 标题/输入框 DOM 兵形),认出是 pi-web-ui 就正常问「要不要绑成服务地址」,不是就自己退场并请 worker 补注入拾取器——**「点了图标什么都没发生」在三条路上都不可能发生**;路由决策同时打进 service worker 控制台,方便排障。
|
|
126
|
+
|
|
127
|
+
暂无其他未发布内容。
|
|
128
|
+
|
|
129
|
+
## [0.81.1] — 2026-09-13
|
|
130
|
+
|
|
131
|
+
### Added
|
|
132
|
+
|
|
133
|
+
- **page-picker 扩展:在 pi-web-ui 页面上点一下图标就能绑定服务地址**——远程/局域网部署时地址是 `http://39.99.235.208:8787` 这种、端口也不固定,原来只能去选项页手打地址再点「授权该地址」。现在点扩展图标会**先认当前页**:页面上有宿主动作桥 `__piWebUiHost` 即认定,老版本则退一步探一次同源 `/api/health`(`{ok, piVersion}` 才算数,所以任何「所有路径都回 200」的站点都不会被误认);认出是 pi-web-ui 就在页面底部弹浮条问「要不要把它设为拾取服务地址」,点一下即可(地址/端口/子路径全部按当前页面算,`?token=`、hash、尾斜杠都会归一掉),已经是当前地址时只说明现状不再多问,浮条上另有「在本页拾取元素」(开发 pi-web-ui 自己时用得上)。缺那一个 origin 的授权时,浮条会提示并给一个「打开设置页授权」按钮 —— `chrome.permissions.request` 必须在扩展自己的页面里点(网页上的按钮给不了浏览器要的手势),那个页面带 `?bind=` 预填地址、一键授权 + 绑定。**普通页面点图标的行为一点没变**(仍是进入拾取模式),也**绝不静默改地址**(改前一定在页面上问一次)。回归:`detectPiWebUi`/`bindView` 单测 + service worker 分流单测 + `?bind=` 面板单测(真 options.html)+ E2E(真 pi-web-ui 页 / 真夹具页各自认定 + 浮条绑定后照常投递)。
|
|
134
|
+
|
|
135
|
+
## [0.81.0] — 2026-09-12
|
|
136
|
+
|
|
137
|
+
### Added
|
|
138
|
+
|
|
139
|
+
- **宿主动作桥新增 `compose()`:把内容放进输入框草稿(宿主 API v1 → v2)**——`startChat()` 是「新建对话并把一段话直接发出去」(脚本化,`prompt` 立刻发),但「元素拾取」这类场景需要的是**人在环中**:内容先落进输入框,用户补一句「这三处间距不一致」再自己发。现在 `window.__piWebUiHost.compose({ text?, attachments? })` 干这件事,与 `startChat` 的差别是**不要求连接就绪**(草稿是本地状态,断线也能先攒着)且输入框没挂载时明确拒收(返回 false,不静默丢)。合并语义复用「撤回消息放回输入框」的同一个纯函数(空则填入、非空追加、**绝不覆盖用户正在打的内容**);附件按 path+mode+行区间去重,与手动 attach 的口径一致。定义见 `web/src/plugin-host.ts` + `web/src/composer-bridge.ts`(草稿在 ChatInput、附件在 App,两处各自注册自己那一半)。
|
|
140
|
+
- **浏览器扩展「网页元素拾取」(`plugins/page-picker`)**:在开发中的网页上点选元素,整理成 AI 能直接动手的上下文,一键注入 pi-web-ui 输入框(`Alt+Shift+P` / 扩展图标 → hover 高亮 → 点击拾取,`Shift`+点击多选,`Esc` 退出,`Ctrl+Enter` 直接发送)。采集的不是截图而是**能让 AI 一次改对**的东西:React fiber 里的组件源码位置(`Card.tsx:18:5` + 调用链)、Vue SFC 文件、命中的 CSS 规则**源文件与行号**(Vite dev 的 `<style data-vite-dev-id>` 的 textContent 与源文件逐字对应,行号可精确反推)、计算样式里**只保留与默认值/继承值不同的项**(现场造同 tag 空元素当探针比对,一个真实卡片通常只剩 3~5 行而不是 300 个属性)、短且唯一的定位串(`#card` > `section.card` > 兜底全 `:nth-of-type`,兄弟冲突会在父级内补 `:nth-of-type` 收窄)、HTML 骨架、可选元素截图(走对话附件,不是把 base64 塞进正文)。详细度三档(精简/标准/完整)在**采集层**就生效。失败一律有兜底:没开 pi-web-ui 页面 / 版本过旧 / 输入框未就绪 / 截屏失败,都会把 Markdown 复制到剪贴板并说明原因,**绝不出现「点了添加什么都没发生」**。
|
|
141
|
+
- 装法:下载 [`page-picker-extension.zip`](https://github.com/xing-shuyin/pi-web-ui/releases/latest/download/page-picker-extension.zip)(打 tag 由 `.github/workflows/extension-release.yml` 自动出包,含 CRC 自校验;zip 打包器是自写的零依赖实现,Windows 上也能出同样的包)→ 解压 → `chrome://extensions` 开发者模式「加载已解压的扩展程序」。也可以从源码 `npm run build:extension` 后加载 `plugins/page-picker/extension/`。远程/局域网部署只需在选项页多点一下「授权该地址」。
|
|
142
|
+
- **`pi-web-ui` 命令行/插件市场不适用于浏览器扩展**:那条通道装的是**服务端插件**(`<dataDir>/plugins/<id>/`),装不了浏览器扩展 —— 这一点在根 README 与插件 README 里都写明了,免得有人对着 `pi-web-ui install` 找半天。
|
|
143
|
+
|
|
144
|
+
- **legado-web 插件:阅读页章末导航(读到底就能翻章)**——阅读页原来只有顶部工具栏有「上一章 / 下一章」,正文读到页面底部什么也没有,这一章看完想接着读必须滚回顶部。现在正文末尾多一条「← 上一章 / 目录 / 下一章 →」(跟在正文下面,带《书名》· 第 n/总 章),换章后自动回到页面顶部;第一章「上一章」、最后一章「下一章」置灰并写明「已是最后一章」(顶栏同名按钮同规则,不再点了没反应),章末「目录」展开目录并回到顶部。回归:`tests/unit/legado-chapnav.test.ts`(禁用态与文案边界:首章/中间章/末章/单章/空目录)+ `tests/legado-web-reader-test.mjs`(真浏览器 + 3 章假书源,钉住导航条长在正文末尾、换章回顶、末章置灰、目录展开)。
|
|
145
|
+
|
|
146
|
+
### Fixed
|
|
147
|
+
|
|
148
|
+
- **输入框里自动折行的长草稿,按 `↑` 会误触历史回溯、打断正在进行的编辑**(issue #127)——历史回溯的边界判定原先只看**逻辑行**(value 里有没有 `\n`),可输入框是按宽度自动折行的:一段没有换行符的长草稿在界面上明明是多行,却被当成「只有一行」,光标停在第三行按 `↑` 也直接切到上一条历史(`↓` 能切回来、草稿没丢,但编辑被打断,想改上一行只能动鼠标)。现在改按**视觉行**判定:新增 `web/src/caret-visual-line.ts`,把与折行相关的样式(字体 / 行高 / 字距 / `white-space` / `overflow-wrap`)拷到一个隐藏镜像 div 上,塞入「光标前的文本 + 一个零宽标记」,量标记的 `offsetTop` —— 与 textarea 自身的折行规则一致(`pre-wrap` + `break-word`),于是「光标上方 / 下方还有没有可见行」直接比像素:首视觉行 ⇔ 标记贴顶,末视觉行 ⇔ 与文末标记同高。拿不到布局的宿主(SSR / jsdom / 未挂载 / `display:none`)回落到旧的逻辑行判定,宁可少一次精确判定也不误判成「可以翻历史」;有选区、输入法组合中一律不碰历史。功能本身没退化:光标真的走到首 / 末视觉行后照旧翻历史,`Esc` / `↓` 仍能回到草稿。回归:`tests/unit/caret-visual-line.test.ts`(像素折算 + 无布局回落 + 选区 / 空输入框边界)+ `tests/composer-history-test.mjs`(真浏览器:折成 4 行的无换行草稿要按满 4 次 `↑` 才切历史、前 3 次逐行上移且内容不变、`↓` 切回草稿、换行草稿与单行草稿的老边界行为不变、测量节点不残留草稿正文)。
|
|
149
|
+
|
|
150
|
+
- **MCP 桥把非文本内容块静默丢掉:截图 / 图像生成 / 图表类工具一律返回空串**——`server/mcp-bridge.ts` 的 `McpClient.call()` 以前只拼 `type === "text"` 的块,`image` 与 `resource` 块被直接丢弃,模型既不报错也拿不到任何东西,工具形同虚设(同一 `browser_screenshot` 调用:桥内得到 `""`,桥外直连 stdio 是 22840 字符的 `image/png`)。现在按块类型保序映射:`image` 原样透传成 SDK 的 `ImageContent`(`{type,data,mimeType}`,进会话后由 SDK 的 `normalizeToolResultImages` 统一缩放,超大图不会再让 provider 整段报错);**文本型 `resource`(`resource.text`)当文本透传**——MCP 的 `EmbeddedResource` 分 TextResourceContents 与 BlobResourceContents 两种,前者是真实正文(filesystem 类 MCP 的 read_text_file 就走这条),退化成「已跳过」等于把文件内容吞掉;PDF 这类 blob 与 audio 退化为「mimeType + 约 N 字节,无法内联」的提示(SDK 内容联合只有 text/image/thinking/toolCall,没有 blob 载体);纯文本结果仍返回拼接字符串(老形状不变,不破坏既有调用方)。回归:`tests/unit/mcp-bridge.test.ts`(image 逐字保真 / 文本资源不丢正文 / blob 退化提示 / 混合保序)+ `tests/mcp-bridge-test.mjs`(e2e 握手 8 tools)。限定:Web UI 的工具卡按既有行为只渲染文本(工具结果里的图片在序列化时是 `[image result]`),图片会进**模型上下文**但不在 tool 卡里显示。
|
|
151
|
+
|
|
152
|
+
- **命令行 `pi-web-ui install <插件> --force` 之后插件一直「不存在」**:CLI 装插件是先整目录删掉再拷新的(`install --force` 的 rm→cp 窗口),撞上这个窗口期的一次插件扫描会把插件当成「已卸载」反激活;而反激活时没把插件从 `attempted` 集合里摘掉,目录回来后永远不会再激活——插件的 HTTP 路由(如 legado-web 的 `/plugins-api/legado-web/proxy`)与 AI 工具在本进程内彻底消失,前端只报「代理请求失败 404 <url>」,CLI 承诺的「服务运行中刷新浏览器即可加载」失效,必须重启服务才恢复。现在反激活会摘掉 `attempted` 并推进 epoch(重新 `import` 拿到磁盘上的新代码、浏览器也重拉插件 client bundle),刷新浏览器即自愈。回归:`tests/unit/plugin-manager.test.ts`(目录消失→回来必须重新激活且用新代码)+ `tests/plugin-test.mjs`(真实 HTTP 路由的 rm→cp 窗口自愈)。
|
|
153
|
+
|
|
154
|
+
<!-- auto-i18n:start -->
|
|
155
|
+
|
|
156
|
+
### i18n
|
|
157
|
+
|
|
158
|
+
- 本版无文案增量(相对 v0.80.2,已核查)。
|
|
159
|
+
|
|
160
|
+
<!-- auto-i18n:end -->
|
|
14
161
|
|
|
15
162
|
## [0.80.2] — 2026-09-12
|
|
16
163
|
|
|
@@ -31,9 +178,11 @@
|
|
|
31
178
|
- nginx 子路径示例配置删掉 `favicon-streaming.svg` 的那条 `location`:该图标早已不存在,留着只会让人以为得额外补一个文件。
|
|
32
179
|
|
|
33
180
|
<!-- auto-i18n:start -->
|
|
181
|
+
|
|
34
182
|
### i18n
|
|
35
183
|
|
|
36
184
|
- 本版无文案增量(相对 v0.80.1,已核查)。
|
|
185
|
+
|
|
37
186
|
<!-- auto-i18n:end -->
|
|
38
187
|
|
|
39
188
|
## [0.80.1] — 2026-09-12
|
|
@@ -47,10 +196,12 @@
|
|
|
47
196
|
- **终端接管 bash 修复:没有尾部管道的命令不再报 `Cannot read properties of null (reading 'segment')`(issue #121)**:`date`、`ls | head -5` 这类命令没有「尾部限输出管道」,`detectTrailingLimiter()` 返回 `null`,而 #91 v2 的取值重构把原本的可选链写成了非空断言 `limiter!.segment` —— 结果几乎每条一次性 bash 命令都在取值处直接 TypeError(只有以 `| tail` / `| less` / `| more` / `| cat` 结尾的命令能跑)。现已改回可选链(这几个值只在真的拆掉管道时才被取用)。回归:`tests/unit/terminal-bash-limiter.test.ts`(桩终端钉住取值路径,CI 必跑);`tests/terminal-bash-test.mjs` 同步恢复可跑(动态导入走 `pathToFileURL`,Windows 上也跑得起来;提示文案断言钉死中文;一次性终端退出改为轮询而非固定等待)。
|
|
48
197
|
|
|
49
198
|
<!-- auto-i18n:start -->
|
|
199
|
+
|
|
50
200
|
### i18n
|
|
51
201
|
|
|
52
202
|
- 前端新增 key(3):`restartService`、`restartingService`、`restartServiceTip`
|
|
53
203
|
- 服务端新增 key(2):`terminals.headtail.omitted.below`、`terminals.headtail.omitted.above`
|
|
204
|
+
|
|
54
205
|
<!-- auto-i18n:end -->
|
|
55
206
|
|
|
56
207
|
## [0.80.0] — 2026-09-12
|
|
@@ -79,9 +230,11 @@
|
|
|
79
230
|
- `db-client` 插件跟随亮色主题:同上,文件树/主区/表头/弹窗输入框底色引用的 `--bg-elev0/1` 改走 `--bg/--bg-elev`(该插件无自绘深色组件,一次变量映射即完整跟随)。
|
|
80
231
|
|
|
81
232
|
<!-- auto-i18n:start -->
|
|
233
|
+
|
|
82
234
|
### i18n
|
|
83
235
|
|
|
84
236
|
- 前端新增 key(1):`queueRecallTip`
|
|
237
|
+
|
|
85
238
|
<!-- auto-i18n:end -->
|
|
86
239
|
|
|
87
240
|
## [0.78.0] — 2026-09-11
|
|
@@ -104,9 +257,11 @@
|
|
|
104
257
|
- `docs/architecture-attachments.md` 的文件预览协议补一节「HTML 渲染走目录映射的 HTTP」(沙箱策略与相对引用语义)。
|
|
105
258
|
|
|
106
259
|
<!-- auto-i18n:start -->
|
|
260
|
+
|
|
107
261
|
### i18n
|
|
108
262
|
|
|
109
263
|
- 前端新增 key(8):`showHtmlSource`、`showHtmlPreview`、`htmlJsOff`、`htmlJsOffTip`、`htmlJsOn`、`htmlJsOnTip`、`htmlEnableJs`、`htmlDisableJs`
|
|
264
|
+
|
|
110
265
|
<!-- auto-i18n:end -->
|
|
111
266
|
|
|
112
267
|
## [0.77.0] — 2026-09-11
|
|
@@ -134,10 +289,12 @@
|
|
|
134
289
|
- 问卷(`ask_user_question`)不再被工具挂死看门狗剁掉:以前它跟普通工具一样被算作「一个工具跑了 20 分钟」(`PI_WEB_TOOL_TIMEOUT_MS`),到点就 abort 整轮对话并弹「工具执行超过…已自动终止」——把还在思考的用户连对话一起终止。现在按工具名豁免:问卷等的是人类回答,不是挂死的工具,收场只走用户回答/取消与会话 dispose,**不限时**。同理,问卷挂着也不再算「失联」(stall 告警默认 180s 无 SDK 事件,对该对话跳过)。同时补上「刷新/重连后问卷对话框不再消失」:`question_pending` 是即时通道,只推给提问那一刻在线的连接,刷新页面/新标签页都拿不到那条历史消息,而服务端还在阻塞等人回答;现在待答问卷同时挂在快照(`UiState.pendingQuestion`,标准引擎只带当前对话的那张,切回原对话会重推快照)上,两个引擎(标准 pi / DSH)重连后都会把面板恢复出来,由快照恢复的面板也能被快照收起(另一标签页答完/服务端取消),但即时通道弹出的面板不会被在途旧快照闪掉,已答过的问卷也不会被在途旧快照重新弹出。回归 `tests/question-bridge-test.mjs`(零 token,本地假模型驱动整条链路)+ `tests/unit/pending-question.test.ts`。
|
|
135
290
|
|
|
136
291
|
<!-- auto-i18n:start -->
|
|
292
|
+
|
|
137
293
|
### i18n
|
|
138
294
|
|
|
139
295
|
- 前端新增 key(28):`placeholderStreamingQueued`、`steerTip`、`settingsTools`、`toolsSectionTerminal`、`toolsSectionSubagent`、`toolsSectionOther`、`toolsSubagentDepHint`、`delegateTaskEnabledDesc`、`delegateTaskOffHint`、`todoListEnabledDesc`、`todoListOffHint`、`toolDescSubagentSpawn`、`toolDescSubagentGetResult`、`toolDescSubagentSteer`、`toolDescSubagentList`、`toolDescSubagentStop`、`toolDescSubagentWaitAll`、`toolDescSubagentTemplates`、`skillFullTextLabel`、`skillFullTextDesc`、`skillFullTextShort`、`delegateOpenSubagent`、`delegateSecTask`、`delegateSecExpected`、`delegateSecTools`、`delegateSecMustDo`、`delegateSecMustNotDo`、`delegateSecContext`
|
|
140
296
|
- 服务端新增 key(3):`delegate.validate.agent`、`delegate.validate.short`、`delegate.started`
|
|
297
|
+
|
|
141
298
|
<!-- auto-i18n:end -->
|
|
142
299
|
|
|
143
300
|
## [0.76.0] — 2026-09-11
|
|
@@ -153,11 +310,13 @@
|
|
|
153
310
|
- 修掉「只有第一次弹、之后怎么都不弹」:通知带固定 `tag` 时,Windows 把同 tag 的新通知当成**替掉旧条目**,而且是静默的 —— 没有横幅、没有提示音,只要系统通知中心里还躺着一条 pi-web-ui 通知,后续每一条都会被无声替换(页面上看 `showNotification` 明明成功了)。现在干脆不用 tag(也不依赖 `renotify` —— 实测它在 Windows toast 这层不起作用),每条都是全新 toast;代价是通知中心里会累积几条。
|
|
154
311
|
|
|
155
312
|
<!-- auto-i18n:start -->
|
|
313
|
+
|
|
156
314
|
### i18n
|
|
157
315
|
|
|
158
316
|
- 前端新增 key(9):`notifyTest`、`notifyTestBody`、`notifyTestSent`、`notifyTestFailed`、`notifyTestState`、`notifyTestHeld`、`notifyTestDropped`、`notifyTestGateSuppressed`、`notifyTestGateOpen`
|
|
159
317
|
- 前端中文变更(1):`notifyEnableDesc`
|
|
160
318
|
- 前端英文变更(1):`notifyEnableDesc`
|
|
319
|
+
|
|
161
320
|
<!-- auto-i18n:end -->
|
|
162
321
|
|
|
163
322
|
## [0.75.0] — 2026-09-11
|
|
@@ -186,11 +345,13 @@
|
|
|
186
345
|
- 提示词模板选择器与编辑弹窗改为「头尾固定、中段滚动」:模板多、字段区高时标题与操作按钮不再被滚走。
|
|
187
346
|
|
|
188
347
|
<!-- auto-i18n:start -->
|
|
348
|
+
|
|
189
349
|
### i18n
|
|
190
350
|
|
|
191
351
|
- 前端新增 key(2):`notifyInsecure`、`notifyWindowsHint`
|
|
192
352
|
- 前端中文变更(2):`notifyEnableDesc`、`notifyDenied`
|
|
193
353
|
- 前端英文变更(2):`notifyEnableDesc`、`notifyDenied`
|
|
354
|
+
|
|
194
355
|
<!-- auto-i18n:end -->
|
|
195
356
|
|
|
196
357
|
## [0.74.0] — 2026-09-10
|
|
@@ -233,6 +394,7 @@
|
|
|
233
394
|
- 对话框内边距与粘性头(sticky)偏移微调。
|
|
234
395
|
|
|
235
396
|
<!-- auto-i18n:start -->
|
|
397
|
+
|
|
236
398
|
### i18n
|
|
237
399
|
|
|
238
400
|
- 前端新增 key(13):`dismissFinishedSubagents`、`dismissFinishedSubagentsScoped`、`dismissConversationWithSubagents`、`dismissConversationWithSubagentsMixed`、`dismissStreamingConfirm`、`dismissFinishedOnly`、`dismissForceAll`、`forceDismissTitle`、`forceDismissConversation`、`forceDismissConfirm`、`noFinishedSubagents`、`reloadModelsConfig`、`reloadModelsHint`
|
|
@@ -254,11 +416,13 @@
|
|
|
254
416
|
- 设置「消息显示」改名「对话」(中英 + 8 语言包同步)。
|
|
255
417
|
|
|
256
418
|
<!-- auto-i18n:start -->
|
|
419
|
+
|
|
257
420
|
### i18n
|
|
258
421
|
|
|
259
422
|
- 前端新增 key(4):`modelRetryAttempts`、`modelRetryHint`、`retryNow`、`retryLastTip`
|
|
260
423
|
- 前端中文变更(1):`settingsMessageDisplay`
|
|
261
424
|
- 前端英文变更(1):`settingsMessageDisplay`
|
|
425
|
+
|
|
262
426
|
<!-- auto-i18n:end -->
|
|
263
427
|
|
|
264
428
|
## [0.71.0] — 2026-09-09
|
|
@@ -522,7 +686,8 @@
|
|
|
522
686
|
- 0.35.1(2026-08-27):编辑重问保留附件(#18)+ 全窗口拖放(#19)。
|
|
523
687
|
- 0.29.0(2026-08-23):全局搜索弹窗(Ctrl+K)+ 消息列表惰性窗口化。
|
|
524
688
|
|
|
525
|
-
[Unreleased]: https://github.com/xing-shuyin/pi-web-ui/compare/v0.
|
|
689
|
+
[Unreleased]: https://github.com/xing-shuyin/pi-web-ui/compare/v0.83.0...main
|
|
690
|
+
[0.83.0]: https://github.com/xing-shuyin/pi-web-ui/releases/tag/v0.83.0
|
|
526
691
|
[0.80.1]: https://github.com/xing-shuyin/pi-web-ui/releases/tag/v0.80.1
|
|
527
692
|
[0.80.0]: https://github.com/xing-shuyin/pi-web-ui/releases/tag/v0.80.0
|
|
528
693
|
[0.79.0]: https://github.com/xing-shuyin/pi-web-ui/releases/tag/v0.79.0
|