pi-web-ui 0.95.0 → 0.96.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 +42 -1
- package/bin/pi-web-ui.mjs +159 -31
- package/dist/server/agent-service.js +880 -240
- package/dist/server/approval-rules.js +56 -10
- package/dist/server/attachment-store.js +21 -4
- package/dist/server/attachments.js +30 -3
- package/dist/server/bg-servers.js +45 -7
- package/dist/server/claim-files-tool.js +4 -8
- package/dist/server/claim-store.js +4 -2
- package/dist/server/client-state.js +63 -14
- package/dist/server/compact-context-tool.js +6 -5
- package/dist/server/composer-drafts.js +9 -0
- package/dist/server/control-socket.js +57 -28
- package/dist/server/conversation-read-tool.js +7 -17
- package/dist/server/dangling-tools.js +72 -5
- package/dist/server/delegate-task.js +25 -28
- package/dist/server/dsh/dsh-agent-service.js +19 -6
- package/dist/server/edit-soft-tool.js +14 -11
- package/dist/server/eval-tool.js +67 -14
- package/dist/server/file-archives.js +16 -5
- package/dist/server/files-service.js +30 -11
- package/dist/server/goal-service.js +141 -19
- package/dist/server/hashline-engine.js +59 -21
- package/dist/server/host-guard.js +94 -0
- package/dist/server/i18n.js +3 -3
- package/dist/server/index.js +306 -78
- package/dist/server/lsp-tool.js +752 -60
- package/dist/server/mcp-bridge.js +47 -3
- package/dist/server/model-admin.js +94 -34
- package/dist/server/office-parse.js +96 -30
- package/dist/server/patch-tool.js +9 -15
- package/dist/server/permission-preset.js +25 -0
- package/dist/server/plan-manager.js +11 -1
- package/dist/server/plugin-catalog-sync.js +36 -19
- package/dist/server/plugin-catalog.js +11 -4
- package/dist/server/plugin-facilities.js +92 -21
- package/dist/server/plugin-llm.js +71 -65
- package/dist/server/plugin-project.js +70 -2
- package/dist/server/plugin-updater.js +115 -12
- package/dist/server/plugins.js +205 -44
- package/dist/server/present-files-tool.js +9 -12
- package/dist/server/process-utils.js +4 -0
- package/dist/server/prompt-composer.js +9 -0
- package/dist/server/protocol-version.js +1 -1
- package/dist/server/read-tool.js +69 -30
- package/dist/server/resolve-global-sdk.js +30 -16
- package/dist/server/schedule-agent-tool.js +12 -15
- package/dist/server/sdk-origin.js +18 -2
- package/dist/server/serialize.js +108 -21
- package/dist/server/settings-service.js +4 -2
- package/dist/server/skill-tool.js +5 -7
- package/dist/server/subagent-templates.js +51 -0
- package/dist/server/subagents.js +48 -72
- package/dist/server/terminals.js +181 -69
- package/dist/server/tool-manager.js +24 -7
- package/dist/server/tool-overrides.js +59 -0
- package/dist/server/update-check.js +28 -1
- package/dist/server/uploads.js +17 -2
- package/dist/server/wait-subscription-scan.js +18 -21
- package/dist/server/ws-client-id.js +29 -0
- package/dist/server/ws-pending-queue.js +60 -0
- package/extensions/webui.ts +60 -2
- package/package.json +4 -2
- package/plugins/catalog.json +20 -0
- package/themes/aetheris.css +457 -0
- package/themes/zhupi-dark.css +658 -0
- package/themes/zhupi.css +711 -0
- package/web/dist/assets/{TerminalPanel-DlGBF2MD.js → TerminalPanel-DDChcYOh.js} +1 -1
- package/web/dist/assets/index-Do9RgJC3.js +366 -0
- package/web/dist/assets/index-DryOsILO.css +1 -0
- package/web/dist/assets/{markdown-eUQn_o9D.js → markdown-DXwnfD9T.js} +1 -1
- package/web/dist/index.html +3 -3
- package/web/dist/assets/index-BXnCQL9p.js +0 -364
- package/web/dist/assets/index-RpIGFyi_.css +0 -1
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Host 白名单守卫(防 DNS rebinding,审查跟踪 issue #352)。
|
|
3
|
+
*
|
|
4
|
+
* 此前 Host/Origin 校验只覆盖 WS 升级,HTTP 路由完全不校验 Host;而
|
|
5
|
+
* originAllowed 的「Origin 与 Host 自比」在 rebinding 下必然相等——恶意网页
|
|
6
|
+
* 让自己的域名解析到 127.0.0.1(或私网 IP)后,浏览器发出的请求 Host 就是
|
|
7
|
+
* 攻击者域名,无 token 默认部署即可获得与本地用户等价的 API 面。
|
|
8
|
+
*
|
|
9
|
+
* 规则(纯函数,便于单测):
|
|
10
|
+
* - `hasAuthToken` 为真 → 直接放行(token 本身就是鉴权,rebinding 拿不到口令);
|
|
11
|
+
* - 显式白名单 PI_WEB_ALLOW_HOSTS 非空 → 严格模式,只认白名单(与 WS 侧
|
|
12
|
+
* 旧行为一致,回环/私网兜底不再生效);
|
|
13
|
+
* - Host 是回环(localhost / 127.0.0.0-127.255.255.255 / [::1])→ 放行;
|
|
14
|
+
* - Host 是私网/链路本地(10/8、172.16/12、192.168/16、169.254/16、
|
|
15
|
+
* ::ffff: 映射的上述段、fe80::/10、fc00::/7)→ 放行,保留「局域网用 IP
|
|
16
|
+
* 直接访问」的既有用法(rebinding 的 Host 是公网域名,不会命中这些段);
|
|
17
|
+
* - 其余(公网域名等)→ 拒绝。
|
|
18
|
+
*/
|
|
19
|
+
/** 拆掉 Host 头里的端口与 IPv6 方括号,返回小写 hostname。 */
|
|
20
|
+
export function hostWithoutPort(authority) {
|
|
21
|
+
let a = authority.trim().toLowerCase();
|
|
22
|
+
if (a.startsWith("[")) {
|
|
23
|
+
const end = a.indexOf("]");
|
|
24
|
+
if (end === -1)
|
|
25
|
+
return "";
|
|
26
|
+
return a.slice(1, end);
|
|
27
|
+
}
|
|
28
|
+
// IPv6 裸形式(无方括号的 Host 头不合规,但容忍):含多个冒号时整体当 hostname。
|
|
29
|
+
const colon = a.lastIndexOf(":");
|
|
30
|
+
if (colon !== -1 && a.indexOf(":") === colon)
|
|
31
|
+
a = a.slice(0, colon);
|
|
32
|
+
return a;
|
|
33
|
+
}
|
|
34
|
+
function isIpv4Literal(host) {
|
|
35
|
+
const parts = host.split(".");
|
|
36
|
+
if (parts.length !== 4)
|
|
37
|
+
return null;
|
|
38
|
+
const octets = [];
|
|
39
|
+
for (const p of parts) {
|
|
40
|
+
if (!/^\d{1,3}$/.test(p))
|
|
41
|
+
return null;
|
|
42
|
+
const n = Number(p);
|
|
43
|
+
if (n > 255)
|
|
44
|
+
return null;
|
|
45
|
+
octets.push(n);
|
|
46
|
+
}
|
|
47
|
+
return octets;
|
|
48
|
+
}
|
|
49
|
+
/** 归一 IPv4-mapped IPv6(::ffff:a.b.c.d)为点分 IPv4,便于按段判断。 */
|
|
50
|
+
function unwrapIpv4Mapped(host) {
|
|
51
|
+
const m = /^::ffff:(\d{1,3}(?:\.\d{1,3}){3})$/.exec(host);
|
|
52
|
+
return m ? m[1] : host;
|
|
53
|
+
}
|
|
54
|
+
export function isLoopbackHost(host) {
|
|
55
|
+
if (host === "localhost" || host.endsWith(".localhost"))
|
|
56
|
+
return true;
|
|
57
|
+
const h = unwrapIpv4Mapped(host);
|
|
58
|
+
if (h.includes(":"))
|
|
59
|
+
return h === "::1";
|
|
60
|
+
const o = isIpv4Literal(h);
|
|
61
|
+
return o !== null && o[0] === 127;
|
|
62
|
+
}
|
|
63
|
+
export function isPrivateLanHost(host) {
|
|
64
|
+
const h = unwrapIpv4Mapped(host);
|
|
65
|
+
if (h.includes(":")) {
|
|
66
|
+
// fe80::/10 链路本地;fc00::/7 (fc/fd 开头) ULA 私网。
|
|
67
|
+
return /^fe[89ab]/.test(h) || /^f[cd]/.test(h);
|
|
68
|
+
}
|
|
69
|
+
const o = isIpv4Literal(h);
|
|
70
|
+
if (!o)
|
|
71
|
+
return false;
|
|
72
|
+
const [a, b] = o;
|
|
73
|
+
if (a === 10)
|
|
74
|
+
return true;
|
|
75
|
+
if (a === 172 && b >= 16 && b <= 31)
|
|
76
|
+
return true;
|
|
77
|
+
if (a === 192 && b === 168)
|
|
78
|
+
return true;
|
|
79
|
+
if (a === 169 && b === 254)
|
|
80
|
+
return true;
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
export function httpHostAllowed(hostHeader, opts) {
|
|
84
|
+
if (opts.hasAuthToken)
|
|
85
|
+
return true;
|
|
86
|
+
const host = hostWithoutPort(hostHeader);
|
|
87
|
+
if (!host)
|
|
88
|
+
return false;
|
|
89
|
+
// PI_WEB_ALLOW_HOSTS 是文档化的「严格模式」:设置了就只认白名单(与 WS
|
|
90
|
+
// 侧旧行为一致),回环/私网兜底仅在未设置时生效。
|
|
91
|
+
if (opts.allowHosts.length > 0)
|
|
92
|
+
return opts.allowHosts.includes(host);
|
|
93
|
+
return isLoopbackHost(host) || isPrivateLanHost(host);
|
|
94
|
+
}
|
package/dist/server/i18n.js
CHANGED
|
@@ -17,9 +17,9 @@
|
|
|
17
17
|
* Keys must be globally unique (module prefix guarantees it).
|
|
18
18
|
* - `getServerBlock(lang, key, zhLines, enLines)` — multi-line blocks
|
|
19
19
|
* (guidance arrays, prompt sections); tables store one `\n`-joined string.
|
|
20
|
-
* - `bilingual(en, zh)` —
|
|
21
|
-
*
|
|
22
|
-
*
|
|
20
|
+
* - `bilingual(en, zh)` — now used only for user-facing relay strings (error
|
|
21
|
+
* messages etc.). Tool DEFINITIONS (description/promptSnippet/promptGuidelines)
|
|
22
|
+
* are concise English-only. No keys needed.
|
|
23
23
|
* - Template DATA (subagent_templates content, user overrides) stays zh/en
|
|
24
24
|
* fields — it is user-editable config, not code copy.
|
|
25
25
|
*
|