@qt4798/pi-web 0.9.17-beta.2 → 0.9.17-beta.3

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 (99) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +4 -4
  3. package/.next/build-manifest.json +2 -2
  4. package/.next/required-server-files.js +1 -1
  5. package/.next/required-server-files.json +1 -1
  6. package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  7. package/.next/server/app/_global-error.html +1 -1
  8. package/.next/server/app/_global-error.rsc +1 -1
  9. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  10. package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  11. package/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  12. package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  13. package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  14. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  15. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  16. package/.next/server/app/_not-found.html +1 -1
  17. package/.next/server/app/_not-found.rsc +2 -2
  18. package/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  19. package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  20. package/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  21. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  22. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  23. package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  24. package/.next/server/app/api/agent/[id]/events/route.js +2 -2
  25. package/.next/server/app/api/agent/[id]/events/route.js.nft.json +1 -1
  26. package/.next/server/app/api/agent/[id]/route.js +1 -1
  27. package/.next/server/app/api/agent/[id]/route.js.nft.json +1 -1
  28. package/.next/server/app/api/agent/new/route.js +1 -1
  29. package/.next/server/app/api/agent/new/route.js.nft.json +1 -1
  30. package/.next/server/app/api/agent/running/route.js +1 -1
  31. package/.next/server/app/api/agent/running/route.js.nft.json +1 -1
  32. package/.next/server/app/api/features/route.js +1 -1
  33. package/.next/server/app/api/features/route.js.nft.json +1 -1
  34. package/.next/server/app/api/models/route.js +1 -1
  35. package/.next/server/app/api/models/route.js.nft.json +1 -1
  36. package/.next/server/app/api/models-config/builtin/route.js +1 -1
  37. package/.next/server/app/api/models-config/test/route.js.nft.json +1 -1
  38. package/.next/server/app/api/modes/route.js +1 -1
  39. package/.next/server/app/api/modes/route.js.nft.json +1 -1
  40. package/.next/server/app/api/project-trust/route.js +1 -1
  41. package/.next/server/app/api/project-trust/route.js.nft.json +1 -1
  42. package/.next/server/app/api/sessions/[id]/auto-name/route.js +3 -3
  43. package/.next/server/app/api/sessions/[id]/auto-name/route.js.nft.json +1 -1
  44. package/.next/server/app/api/sessions/[id]/queue-recovery/route.js +1 -1
  45. package/.next/server/app/api/sessions/[id]/queue-recovery/route.js.nft.json +1 -1
  46. package/.next/server/app/api/sessions/[id]/route.js +1 -1
  47. package/.next/server/app/api/sessions/[id]/route.js.nft.json +1 -1
  48. package/.next/server/app/api/sessions/[id]/state/route.js +1 -1
  49. package/.next/server/app/api/sessions/[id]/state/route.js.nft.json +1 -1
  50. package/.next/server/app/api/sessions/route.js +1 -1
  51. package/.next/server/app/api/sessions/route.js.nft.json +1 -1
  52. package/.next/server/app/api/settings/title-model/route.js +1 -1
  53. package/.next/server/app/api/settings/title-model/route.js.nft.json +1 -1
  54. package/.next/server/app/api/tasks/[id]/[action]/route.js +1 -1
  55. package/.next/server/app/api/tasks/[id]/[action]/route.js.nft.json +1 -1
  56. package/.next/server/app/api/tasks/[id]/route.js +1 -1
  57. package/.next/server/app/api/tasks/[id]/route.js.nft.json +1 -1
  58. package/.next/server/app/api/tasks/batch/route.js +1 -1
  59. package/.next/server/app/api/tasks/batch/route.js.nft.json +1 -1
  60. package/.next/server/app/api/tasks/events/route.js +2 -2
  61. package/.next/server/app/api/tasks/events/route.js.nft.json +1 -1
  62. package/.next/server/app/api/tasks/route.js +1 -1
  63. package/.next/server/app/api/tasks/route.js.nft.json +1 -1
  64. package/.next/server/app/api/tasks/settings/route.js +1 -1
  65. package/.next/server/app/api/tasks/settings/route.js.nft.json +1 -1
  66. package/.next/server/app/index.html +1 -1
  67. package/.next/server/app/index.rsc +4 -4
  68. package/.next/server/app/index.segments/__PAGE__.segment.rsc +3 -3
  69. package/.next/server/app/index.segments/_full.segment.rsc +4 -4
  70. package/.next/server/app/index.segments/_head.segment.rsc +1 -1
  71. package/.next/server/app/index.segments/_index.segment.rsc +2 -2
  72. package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  73. package/.next/server/app/page.js +12 -12
  74. package/.next/server/app/page_client-reference-manifest.js +1 -1
  75. package/.next/server/app-paths-manifest.json +4 -4
  76. package/.next/server/chunks/4253.js +2 -2
  77. package/.next/server/chunks/4735.js +1 -0
  78. package/.next/server/chunks/5582.js +1 -1
  79. package/.next/server/chunks/6429.js +1 -1
  80. package/.next/server/chunks/7915.js +1 -1
  81. package/.next/server/instrumentation.js +1 -1
  82. package/.next/server/middleware-build-manifest.js +1 -1
  83. package/.next/server/pages/404.html +1 -1
  84. package/.next/server/pages/500.html +1 -1
  85. package/.next/static/chunks/6274-04455fad317a49e9.js +1 -0
  86. package/.next/static/chunks/app/page-35b0daa73a11f364.js +50 -0
  87. package/.next/static/css/288bff2da3ab1a4d.css +1 -0
  88. package/.next/trace +8 -9
  89. package/.next/trace-build +1 -1
  90. package/README.en.md +37 -1
  91. package/README.md +29 -5
  92. package/bin/fix-pi-agent-undici.js +58 -43
  93. package/bin/pi-web.js +11 -0
  94. package/package.json +10 -12
  95. package/.next/static/chunks/3878-d79ef6662348a2e2.js +0 -1
  96. package/.next/static/chunks/app/page-ddcad605657cfba0.js +0 -50
  97. package/.next/static/css/26cede2ceec5c771.css +0 -1
  98. /package/.next/static/{d97gg7mRKGwB8zja1Q4TZ → lVkhyX-XEcFgvfYtDvmwH}/_buildManifest.js +0 -0
  99. /package/.next/static/{d97gg7mRKGwB8zja1Q4TZ → lVkhyX-XEcFgvfYtDvmwH}/_ssgManifest.js +0 -0
package/.next/trace-build CHANGED
@@ -1 +1 @@
1
- [{"name":"run-webpack","duration":34859916,"timestamp":360383651829,"id":14,"parentId":1,"tags":{},"startTime":1786034404554,"traceId":"99e44986e4051211"},{"name":"run-typescript","duration":5475260,"timestamp":360418513086,"id":1004,"parentId":1,"tags":{},"startTime":1786034439416,"traceId":"99e44986e4051211"},{"name":"static-check","duration":1109111,"timestamp":360424000225,"id":1007,"parentId":1,"tags":{},"startTime":1786034444903,"traceId":"99e44986e4051211"},{"name":"static-generation","duration":1615248,"timestamp":360425415761,"id":1155,"parentId":1,"tags":{},"startTime":1786034446318,"traceId":"99e44986e4051211"},{"name":"collect-build-traces","duration":14322945,"timestamp":360425110965,"id":1152,"parentId":1,"tags":{},"startTime":1786034446014,"traceId":"99e44986e4051211"},{"name":"telemetry-flush","duration":12,"timestamp":360439439908,"id":1164,"parentId":1,"tags":{},"startTime":1786034460342,"traceId":"99e44986e4051211"},{"name":"next-build","duration":55903327,"timestamp":360383536596,"id":1,"tags":{"buildMode":"default","version":"16.2.12","bundler":"webpack","has-custom-webpack-config":"false","use-build-worker":"true"},"startTime":1786034404439,"traceId":"99e44986e4051211"}]
1
+ [{"name":"run-webpack","duration":89174945,"timestamp":400130066892,"id":14,"parentId":1,"tags":{},"startTime":1786074151025,"traceId":"93144e710d7dc818"},{"name":"run-typescript","duration":16338980,"timestamp":400219244807,"id":926,"parentId":1,"tags":{},"startTime":1786074240205,"traceId":"93144e710d7dc818"},{"name":"static-check","duration":4724559,"timestamp":400235612204,"id":929,"parentId":1,"tags":{},"startTime":1786074256572,"traceId":"93144e710d7dc818"},{"name":"static-generation","duration":4626174,"timestamp":400241391475,"id":1077,"parentId":1,"tags":{},"startTime":1786074262352,"traceId":"93144e710d7dc818"},{"name":"collect-build-traces","duration":36861527,"timestamp":400240343225,"id":1074,"parentId":1,"tags":{},"startTime":1786074261303,"traceId":"93144e710d7dc818"},{"name":"telemetry-flush","duration":36,"timestamp":400277216062,"id":1086,"parentId":1,"tags":{},"startTime":1786074298177,"traceId":"93144e710d7dc818"},{"name":"next-build","duration":147687381,"timestamp":400129528723,"id":1,"tags":{"buildMode":"default","version":"16.2.12","bundler":"webpack","has-custom-webpack-config":"false","use-build-worker":"true"},"startTime":1786074150487,"traceId":"93144e710d7dc818"}]
package/README.en.md CHANGED
@@ -65,7 +65,18 @@ The board's own **Task settings** button configures per-project execution (separ
65
65
  - The engine is a single server process (exclusive lock); interrupted tasks are recovered on restart (marked failed/interrupted, retryable).
66
66
  - Beta: desktop only; the mobile UI does not show the board.
67
67
 
68
- ## Latest changes (2026-08-06 · v0.9.17-beta.2)
68
+ ## Latest changes (2026-08-07 · v0.9.17-beta.3)
69
+
70
+ - **Zero install-time warnings**: provider icons are now inlined components, so `@lobehub/icons` is gone and npm no longer auto-installs the `@lobehub/ui` / `antd` / `@emoji-mart/react` chain — no more `ERESOLVE overriding peer dependency` and `deprecated intersection-observer` warnings during install (see "npm 11 install notes").
71
+ - **undici fix now runs at runtime**: the `postinstall` hook is gone; `pi-web` applies the undici CVE fix at startup and `dev`/`start` scripts apply it before launching, so installing no longer requires approving install scripts.
72
+ - **Title generation no longer times out (524)**: generating a title while the session is still running waits at most 10s for idle then snapshots the current conversation; the model call timeout is tightened to 80s, keeping the total comfortably under the Cloudflare 100s gateway timeout.
73
+ - **Default mode is now Normal**: new chats default to Normal task mode instead of inheriting Plan.
74
+ - **Task board toggle takes effect immediately**: turning the task board on/off in Settings > Features syncs the toolbar entry and board view without a page refresh.
75
+ - **settings.json concurrency protection**: the modes, features, and title-model modules now share one file lock (proper-lockfile + atomic writes), so concurrent saves can no longer overwrite each other and drop config.
76
+ - **Default mode settings UI**: Settings > Features can now set the default task mode (Normal / Plan / Goal), token profile (Lite / Balanced / Delivery, default Balanced) and tool approval (Ask / Auto / Yolo); already-open chats apply the changes immediately and new chats inherit them.
77
+ - **SPA navigation robustness**: switching projects via the address bar (`?session=` ↔ `?cwd=`) is honored without a full reload; a brand-new project folder with no sessions yet stays in the project list; created sessions appear in the sidebar promptly.
78
+
79
+ ## Previous changes (2026-08-06 · v0.9.17-beta.2)
69
80
 
70
81
  - **Chat mode system** (ported from Reasonix): the composer toolbar gains three mode controls — task mode (Normal / Plan / Goal), token profile (Lite / Balanced / Delivery) and tool approval (Ask / Auto / Yolo). Plan mode produces a read-only plan then shows a confirm card (Execute / Suggest / Exit); Goal mode auto-continues with a turn budget and stall detection; Lite narrows the toolset to save tokens; Delivery injects a verify-first instruction.
71
82
  - **Tool-call approval (real interception)**: in Ask mode, write-class tool calls are suspended before execution and a shelf card appears above the composer — allow, deny, or deny with a reason; parallel batches resolve one by one; 120s timeout auto-denies. Rules (deny > ask > allow) support `ToolName` / `ToolName(glob)` / `Bash(command:*)` and persist to `~/.pi/agent/settings.json`.
@@ -100,6 +111,31 @@ The board's own **Task settings** button configures per-project execution (separ
100
111
  - The mobile composer is now 52px high. It keeps a 16px input font to prevent iOS Safari zoom, while tighter line height and letter spacing make the text read smaller.
101
112
  - Production serving no longer relies on Turbopack development chunks, and quoteable Markdown table rows render with valid table DOM.
102
113
 
114
+ ## npm 11 install notes
115
+
116
+ Since **v0.9.17-beta.3** the `ERESOLVE overriding peer dependency` and `deprecated intersection-observer` warnings are gone: provider icons are inlined (no more `@lobehub/icons`, so npm no longer auto-installs the `@lobehub/ui` / `antd` / `@emoji-mart/react` chain). Two **informational** warnings may remain — both harmless:
117
+
118
+ - `deprecated node-domexception`: pulled in transitively by `@google/genai` → `google-auth-library` → `fetch-blob`. It is a polyfill for older Node versions; Node ≥ 18 ships `DOMException` natively, so it is unused at runtime. It cannot be removed from the package side until the upstream fix lands.
119
+
120
+ - `allow-scripts`: npm ≥ 11.16's install-script approval notice (`@google/genai` / `protobufjs` / `sharp` etc. transitive lifecycle scripts). Current versions only warn (scripts still run); future versions may block by default. To clear the notice in your project:
121
+
122
+ ```bash
123
+ npm approve-scripts --allow-scripts-pending # view pending list first
124
+ npm approve-scripts @google/genai protobufjs sharp # approve and write to your package.json
125
+ ```
126
+
127
+ Or declare in your project `package.json`:
128
+
129
+ ```json
130
+ "allowScripts": {
131
+ "@google/genai@1.52.0": true,
132
+ "protobufjs@7.6.5": true,
133
+ "sharp@0.34.5": true
134
+ }
135
+ ```
136
+
137
+ Note this field matches `package@exact-version`; update it after version bumps.
138
+
103
139
  ## Requirements
104
140
 
105
141
  - Node.js **22.19.0 or newer**
package/README.md CHANGED
@@ -87,7 +87,18 @@
87
87
  - 引擎由服务器进程持有(单实例锁),重启后自动恢复中断的任务(标记为失败/中断,可重试)。
88
88
  - Beta 阶段:仅在桌面端显示入口;移动端不可用。
89
89
 
90
- ## 最新更新(2026-08-06 · v0.9.17-beta.2)
90
+ ## 最新更新(2026-08-07 · v0.9.17-beta.3)
91
+
92
+ - **生成标题不再超时(524)**:会话运行中点「生成标题」最多等待空闲 10 秒后直接用当前对话快照生成,模型调用超时收紧到 80 秒,总时长稳在 Cloudflare 100 秒网关超时内。
93
+ - **默认任务模式改为常规**:新对话默认不再继承「计划」。
94
+ - **任务看板开关实时生效**:设置-功能里关闭/打开任务看板立即同步顶部入口与看板视图,无需刷新页面。
95
+ - **settings.json 并发写保护**:模式、功能开关、标题模型共用同一文件锁(proper-lockfile + 原子写),并发保存不再互相覆盖丢配置。
96
+ - **设置-功能页新增模式默认项**:可配置默认任务模式(常规 / 计划 / 目标)、默认运行档位(轻量 / 均衡 / 交付,默认均衡)、默认工具权限(批准 / 自动 / Yolo),已打开的对话立即生效、新对话自动继承。
97
+ - **SPA 导航修复**:地址栏 `?session=` ↔ `?cwd=` 切换项目无需整页刷新;全新项目(尚无会话)仍保留在项目列表;新会话创建后立即出现在侧栏。
98
+ - **安装提示清零**:供应商图标改为内置组件,移除 `@lobehub/icons` 依赖,不再被 npm 自动安装 `@lobehub/ui` / `antd` / `@emoji-mart/react` 整条链——安装时不再出现 `ERESOLVE overriding peer dependency` 与 `deprecated intersection-observer` 警告(详情见「安装提示(npm 11)」)。
99
+ - **undici 修复改为运行时执行**:移除 `postinstall` 钩子,`pi-web` 启动与 dev/start 脚本执行前自动应用 undici CVE 修复,安装不再要求审批安装脚本。
100
+
101
+ ## 历史更新(2026-08-06 · v0.9.17-beta.2)
91
102
 
92
103
  - **对话框模式系统**(移植自 Reasonix):输入框工具栏新增三组模式控件——任务模式(常规 / 计划 / 目标)、运行档位(轻量 / 均衡 / 交付)、工具权限(批准 / 自动 / Yolo)。计划模式只读产出计划后弹出确认卡(开始执行 / 提出建议 / 退出);目标模式输入目标后自动持续推进,带轮次预算与无进展检测;轻量档位收窄工具集省 token,交付档位强制验收指令。
93
104
  - **工具调用审批(真拦截)**:权限为「批准」时,agent 的写类工具调用在真正执行前挂起,输入框上方弹出审批卡,可允许 / 拒绝 / 附理由拒绝;规则(deny > ask > allow)支持 `ToolName` / `ToolName(glob)` / `Bash(command:*)`,持久化到 settings.json。
@@ -138,15 +149,28 @@
138
149
 
139
150
  ## 安装提示(npm 11)
140
151
 
141
- 使用 npm ≥ 11 安装本包时可能出现两类提示,均为**提示性警告,不影响安装与运行**:
152
+ 自 **v0.9.17-beta.3 起**,`ERESOLVE overriding peer dependency` 与 `deprecated intersection-observer` 两类提示已消除:供应商图标改为内置(不再依赖 `@lobehub/icons`,从而不再被 npm 自动安装 `@lobehub/ui` / `antd` / `@emoji-mart/react` 整条链)。新装本包时仅剩以下两类**提示性警告,均不影响安装与运行**:
153
+
154
+ - `deprecated node-domexception`:来自 `@google/genai` → `google-auth-library` 的传递依赖 `fetch-blob`。它只是旧版 Node 的 polyfill,Node ≥ 18 原生自带 `DOMException`,运行时完全用不到。上游未修复前无法从包侧移除。
155
+
156
+ - `allow-scripts`:npm ≥ 11.16 新增的安装脚本审批提示(`@google/genai` / `protobufjs` / `sharp` 等传递依赖的 preinstall/postinstall/install 脚本)。当前版本**只提示、不拦截**(脚本照常执行),未来版本可能改为默认拦截。想消除提示可在你的项目执行:
157
+
158
+ ```bash
159
+ npm approve-scripts --allow-scripts-pending # 先查看待审批清单
160
+ npm approve-scripts @google/genai protobufjs sharp # 逐个批准并写入你的 package.json
161
+ ```
142
162
 
143
- - `ERESOLVE overriding peer dependency`:上游 `@lobehub/ui` 依赖的 `@emoji-mart/react@1.1.1` 的 peer 声明仅到 React 18,而本包使用 React 19。npm 会自动 override 并继续安装(实际兼容)。如需彻底消除,可在你的项目 `package.json` 添加:
163
+ 或在项目 `package.json` 声明:
144
164
 
145
165
  ```json
146
- "overrides": { "@emoji-mart/react": { "react": "$react" } }
166
+ "allowScripts": {
167
+ "@google/genai@1.52.0": true,
168
+ "protobufjs@7.6.5": true,
169
+ "sharp@0.34.5": true
170
+ }
147
171
  ```
148
172
 
149
- - `allow-scripts`:npm 11 新增的安装脚本审批提示(sharp / protobufjs / @google/genai 等)。本项目已在包内声明 `allowScripts`,若你的 npm 仍提示,可执行 `npm approve-scripts --all` 审批,或在安装命令加 `--allow-scripts=sharp,protobufjs,@google/genai`。
173
+ 注意该字段按 `包名@精确版本` 匹配,版本升级后需同步更新。
150
174
 
151
175
  ## 历史更新(2026-08-03)
152
176
 
@@ -9,54 +9,69 @@
9
9
  // Note: npm audit will still report undici CVEs because the lockfile
10
10
  // references the old version. This is a cosmetic false positive — the
11
11
  // code loaded at runtime is undici@^8.10.0.
12
+ //
13
+ // The fix used to run as a `postinstall` hook. It now runs lazily at
14
+ // `pi-web` startup (bin/pi-web.js) and before the repo's dev/start scripts.
15
+ // Moving it out of postinstall keeps `npm install` output quiet under
16
+ // npm >= 11.16's allow-scripts policy and guarantees the fix applies even on
17
+ // installs where lifecycle scripts are blocked or skipped.
12
18
 
13
19
  const fs = require("fs");
14
20
  const path = require("path");
15
21
 
16
- const root = path.join(__dirname, "..");
17
- const agentDir = path.join(
18
- root,
19
- "node_modules",
20
- "@earendil-works",
21
- "pi-coding-agent",
22
- );
23
- const shrinkwrap = path.join(agentDir, "npm-shrinkwrap.json");
24
- const nestedUndici = path.join(agentDir, "node_modules", "undici");
25
- const topUndici = path.join(root, "node_modules", "undici");
26
-
27
- // 1. Remove shrinkwrap
28
- if (fs.existsSync(shrinkwrap)) {
29
- console.log("[pi-web] Removing pi-coding-agent shrinkwrap…");
30
- fs.rmSync(shrinkwrap);
31
- }
22
+ function applyUndiciFix(rootDir = path.join(__dirname, "..")) {
23
+ const agentDir = path.join(
24
+ rootDir,
25
+ "node_modules",
26
+ "@earendil-works",
27
+ "pi-coding-agent",
28
+ );
29
+ if (!fs.existsSync(agentDir)) return; // not installed here — nothing to fix
30
+
31
+ const shrinkwrap = path.join(agentDir, "npm-shrinkwrap.json");
32
+ const nestedUndici = path.join(agentDir, "node_modules", "undici");
33
+ const topUndici = path.join(rootDir, "node_modules", "undici");
34
+
35
+ // 1. Remove shrinkwrap
36
+ if (fs.existsSync(shrinkwrap)) {
37
+ console.log("[pi-web] Removing pi-coding-agent shrinkwrap…");
38
+ fs.rmSync(shrinkwrap);
39
+ }
32
40
 
33
- // 2. Replace nested undici@8.5.0 with symlink to top-level undici@^8.10.0
34
- if (
35
- fs.existsSync(topUndici) &&
36
- fs.existsSync(nestedUndici) &&
37
- // Only replace if it's a real directory, not already a symlink
38
- fs.lstatSync(nestedUndici).isDirectory() &&
39
- !fs.lstatSync(nestedUndici).isSymbolicLink()
40
- ) {
41
- try {
42
- const nestedVersion = require(path.join(nestedUndici, "package.json")).version;
43
- const topVersion = require(path.join(topUndici, "package.json")).version;
44
-
45
- if (nestedVersion !== topVersion) {
46
- console.log(
47
- `[pi-web] Replacing pi-coding-agent's undici@${nestedVersion} ` +
48
- `→ symlink to undici@${topVersion}`,
49
- );
50
- fs.rmSync(nestedUndici, { recursive: true, force: true });
51
-
52
- const rel = path.relative(path.dirname(nestedUndici), topUndici);
53
- fs.symlinkSync(
54
- rel,
55
- nestedUndici,
56
- process.platform === "win32" ? "junction" : "dir",
57
- );
41
+ // 2. Replace nested undici@8.5.0 with symlink to top-level undici@^8.10.0
42
+ if (
43
+ fs.existsSync(topUndici) &&
44
+ fs.existsSync(nestedUndici) &&
45
+ // Only replace if it's a real directory, not already a symlink
46
+ fs.lstatSync(nestedUndici).isDirectory() &&
47
+ !fs.lstatSync(nestedUndici).isSymbolicLink()
48
+ ) {
49
+ try {
50
+ const nestedVersion = require(path.join(nestedUndici, "package.json")).version;
51
+ const topVersion = require(path.join(topUndici, "package.json")).version;
52
+
53
+ if (nestedVersion !== topVersion) {
54
+ console.log(
55
+ `[pi-web] Replacing pi-coding-agent's undici@${nestedVersion} ` +
56
+ `→ symlink to undici@${topVersion}`,
57
+ );
58
+ fs.rmSync(nestedUndici, { recursive: true, force: true });
59
+
60
+ const rel = path.relative(path.dirname(nestedUndici), topUndici);
61
+ fs.symlinkSync(
62
+ rel,
63
+ nestedUndici,
64
+ process.platform === "win32" ? "junction" : "dir",
65
+ );
66
+ }
67
+ } catch (err) {
68
+ console.warn("[pi-web] Symlink fix skipped:", err.message);
58
69
  }
59
- } catch (err) {
60
- console.warn("[pi-web] Symlink fix skipped:", err.message);
61
70
  }
62
71
  }
72
+
73
+ module.exports = { applyUndiciFix };
74
+
75
+ if (require.main === module) {
76
+ applyUndiciFix();
77
+ }
package/bin/pi-web.js CHANGED
@@ -10,6 +10,17 @@ const fs = require("fs");
10
10
  // eslint-disable-next-line @typescript-eslint/no-require-imports
11
11
  const { parseLaunchOptions } = require("./pi-web-options");
12
12
 
13
+ // Apply the undici CVE fix (formerly a postinstall hook). Running it here —
14
+ // before the pi agent's undici can be loaded — keeps installs quiet under
15
+ // npm >= 11.16's allow-scripts policy and survives installs that skip scripts.
16
+ try {
17
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
18
+ require("./fix-pi-agent-undici").applyUndiciFix();
19
+ } catch {
20
+ // Best-effort; the app still starts with the shrinkwrapped undici if the
21
+ // fix cannot be applied.
22
+ }
23
+
13
24
  const pkgDir = path.join(__dirname, "..");
14
25
  const nextDir = path.join(pkgDir, ".next");
15
26
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qt4798/pi-web",
3
- "version": "0.9.17-beta.2",
3
+ "version": "0.9.17-beta.3",
4
4
  "description": "Web workspace for the pi coding agent",
5
5
  "homepage": "https://github.com/t479842598/pi-web-QT#readme",
6
6
  "repository": {
@@ -28,14 +28,13 @@
28
28
  "package.json"
29
29
  ],
30
30
  "scripts": {
31
- "dev": "next dev -H 127.0.0.1 -p 0 --turbopack",
32
- "dev:lan": "next dev -H 0.0.0.0 -p 0 --turbopack",
31
+ "dev": "node bin/fix-pi-agent-undici.js && next dev -H 127.0.0.1 -p 0 --turbopack",
32
+ "dev:lan": "node bin/fix-pi-agent-undici.js && next dev -H 0.0.0.0 -p 0 --turbopack",
33
33
  "build": "env -u TURBOPACK next build --webpack",
34
- "start": "next start -H 127.0.0.1 -p 0",
35
- "start:lan": "next start -H 0.0.0.0 -p 0",
34
+ "start": "node bin/fix-pi-agent-undici.js && next start -H 127.0.0.1 -p 0",
35
+ "start:lan": "node bin/fix-pi-agent-undici.js && next start -H 0.0.0.0 -p 0",
36
36
  "lint": "eslint .",
37
37
  "release": "npm version patch --no-git-tag-version && npm run build && npm publish --access public",
38
- "postinstall": "node bin/fix-pi-agent-undici.js",
39
38
  "test": "node --experimental-strip-types --test $(find app components hooks lib -name '*.test.mjs' -print)"
40
39
  },
41
40
  "dependencies": {
@@ -45,7 +44,6 @@
45
44
  "@earendil-works/pi-tui": "0.83.0",
46
45
  "@fontsource/ia-writer-quattro": "^5.3.0",
47
46
  "@fontsource/lilex": "^5.3.0",
48
- "@lobehub/icons": "^5.6.0",
49
47
  "@phosphor-icons/react": "^2.1.10",
50
48
  "@types/react-syntax-highlighter": "^15.5.13",
51
49
  "adm-zip": "^0.6.0",
@@ -67,18 +65,17 @@
67
65
  },
68
66
  "overrides": {
69
67
  "undici": "^8.10.0",
70
- "@emoji-mart/react": {
71
- "react": "$react"
72
- },
73
68
  "@earendil-works/pi-coding-agent": {
74
69
  "undici": "^8.10.0"
75
- }
70
+ },
71
+ "node-domexception": "npm:@profoundlogic/node-domexception@1.0.2",
72
+ "intersection-observer": "npm:noop2@2.0.0"
76
73
  },
77
74
  "allowScripts": {
78
75
  "@google/genai@1.52.0": true,
79
76
  "protobufjs@7.6.5": true,
80
77
  "sharp@0.34.5": true,
81
- "unrs-resolver@1.11.1": true
78
+ "unrs-resolver@1.12.2": true
82
79
  },
83
80
  "devDependencies": {
84
81
  "@resvg/resvg-js": "^2.6.2",
@@ -90,6 +87,7 @@
90
87
  "eslint": "^9.39.5",
91
88
  "eslint-config-next": "16.2.12",
92
89
  "jiti": "^2.7.0",
90
+ "lightningcss": "^1.33.0",
93
91
  "postcss": "^8",
94
92
  "tailwindcss": "^4.2.2",
95
93
  "to-ico": "^1.1.5",