pi-web-ui 0.11.0 → 0.11.2
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/bin/pi-web-ui.mjs +29 -5
- package/package.json +86 -85
- package/web/dist/icon.ico +0 -0
- package/web/public/favicon.svg +8 -0
- package/web/public/icon.ico +0 -0
package/bin/pi-web-ui.mjs
CHANGED
|
@@ -26,6 +26,7 @@ import { spawnSync } from "node:child_process";
|
|
|
26
26
|
import { get as httpGet } from "node:http";
|
|
27
27
|
import {
|
|
28
28
|
chmodSync,
|
|
29
|
+
copyFileSync,
|
|
29
30
|
existsSync,
|
|
30
31
|
mkdirSync,
|
|
31
32
|
realpathSync,
|
|
@@ -292,10 +293,21 @@ function winTaskExists(name) {
|
|
|
292
293
|
// 桌面快捷方式(server shortcut)
|
|
293
294
|
// ---------------------------------------------------------------------------
|
|
294
295
|
|
|
295
|
-
const SHORTCUT_LNK_NAME = "pi-web-ui
|
|
296
|
-
const SHORTCUT_MAC_NAME = "pi-web-ui
|
|
296
|
+
const SHORTCUT_LNK_NAME = "pi-web-ui.lnk"; // Windows 桌面快捷方式
|
|
297
|
+
const SHORTCUT_MAC_NAME = "pi-web-ui.command"; // macOS 双击启动器
|
|
297
298
|
const SHORTCUT_LINUX_NAME = "pi-web-ui.desktop"; // Linux 桌面图标
|
|
298
299
|
|
|
300
|
+
/** 快捷方式图标(品牌 .ico,随包发布;.lnk / .desktop 指向它)。 */
|
|
301
|
+
const APP_ICO_NAME = "pi-web-ui.ico"; // 复制到用户目录后的稳定文件名
|
|
302
|
+
const APP_ICO_SOURCE = join(BIN_DIR, "..", "web", "public", "icon.ico"); // 包内品牌图标源文件
|
|
303
|
+
/** Branded SVG logo (source of truth: web/public/favicon.svg) — used on Linux. */
|
|
304
|
+
const APP_SVG_PACKAGE = join(BIN_DIR, "..", "web", "public", "favicon.svg");
|
|
305
|
+
|
|
306
|
+
/** Windows: per-user copy of the branded .ico (stable path for the .lnk icon). */
|
|
307
|
+
function winIcoPath() {
|
|
308
|
+
return join(winServiceDir(), APP_ICO_NAME);
|
|
309
|
+
}
|
|
310
|
+
|
|
299
311
|
/** Full path to Windows PowerShell 5.1. */
|
|
300
312
|
function winPowershell() {
|
|
301
313
|
return join(
|
|
@@ -442,7 +454,12 @@ function installWinShortcut(opts) {
|
|
|
442
454
|
}
|
|
443
455
|
mkdirSync(dirname(ps1Path), { recursive: true });
|
|
444
456
|
writeFileSync(ps1Path, "\uFEFF" + ps1, "utf8"); // PS 5.1 需要 BOM
|
|
445
|
-
|
|
457
|
+
// 把品牌图标准备好:复制到用户目录(.lnk 图标指向稳定路径)
|
|
458
|
+
if (existsSync(APP_ICO_SOURCE)) {
|
|
459
|
+
copyFileSync(APP_ICO_SOURCE, winIcoPath());
|
|
460
|
+
} else {
|
|
461
|
+
console.log(`⚠ 未找到品牌图标 ${APP_ICO_SOURCE},快捷方式将使用默认图标`);
|
|
462
|
+
}
|
|
446
463
|
const powershell = winPowershell();
|
|
447
464
|
const ps = [
|
|
448
465
|
"$ErrorActionPreference = 'Stop'",
|
|
@@ -453,7 +470,7 @@ function installWinShortcut(opts) {
|
|
|
453
470
|
`$lnk.Arguments = '-NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File ' + ${psQuote('"' + ps1Path + '"')}`,
|
|
454
471
|
`$lnk.WorkingDirectory = ${psQuote(cwd)}`,
|
|
455
472
|
"$lnk.Description = 'pi-web-ui — 双击启动服务并打开浏览器'",
|
|
456
|
-
`$lnk.IconLocation = ${psQuote(
|
|
473
|
+
`$lnk.IconLocation = ${psQuote(winIcoPath())} + ',0'`,
|
|
457
474
|
"$lnk.Save()",
|
|
458
475
|
`Write-Output (Join-Path $desktop ${psQuote(SHORTCUT_LNK_NAME)})`,
|
|
459
476
|
].join("\r\n");
|
|
@@ -584,13 +601,17 @@ function installLinuxShortcut(opts) {
|
|
|
584
601
|
const scriptDir = join(homedir(), ".local", "share", "pi-web-ui");
|
|
585
602
|
const scriptPath = join(scriptDir, `${name}-start.sh`);
|
|
586
603
|
const desktopPath = join(homedir(), "Desktop", SHORTCUT_LINUX_NAME);
|
|
604
|
+
const icoPath = join(scriptDir, APP_ICO_NAME); // 备用;优先 SVG
|
|
605
|
+
const svgPath = join(scriptDir, "pi-web-ui.svg");
|
|
587
606
|
const script = buildLinuxStartScript(name, url);
|
|
607
|
+
const desktopIcon = existsSync(APP_SVG_PACKAGE) ? svgPath : APP_ICO_NAME;
|
|
588
608
|
const desktop = `[Desktop Entry]
|
|
589
609
|
Version=1.0
|
|
590
610
|
Type=Application
|
|
591
611
|
Name=pi-web-ui
|
|
592
612
|
Comment=启动 pi-web-ui 服务并打开浏览器
|
|
593
613
|
Exec=${shQuote(scriptPath)}
|
|
614
|
+
Icon=${shQuote(desktopIcon)}
|
|
594
615
|
Terminal=false
|
|
595
616
|
Categories=Network;WebBrowser;
|
|
596
617
|
`;
|
|
@@ -600,6 +621,9 @@ Categories=Network;WebBrowser;
|
|
|
600
621
|
return;
|
|
601
622
|
}
|
|
602
623
|
mkdirSync(scriptDir, { recursive: true });
|
|
624
|
+
// 品牌图标(缺失时跳过,桌面自动回退默认图标)
|
|
625
|
+
if (existsSync(APP_SVG_PACKAGE)) copyFileSync(APP_SVG_PACKAGE, svgPath);
|
|
626
|
+
else if (existsSync(APP_ICO_SOURCE)) copyFileSync(APP_ICO_SOURCE, icoPath);
|
|
603
627
|
writeFileSync(scriptPath, script);
|
|
604
628
|
chmodSync(scriptPath, 0o755);
|
|
605
629
|
writeFileSync(desktopPath, desktop);
|
|
@@ -618,7 +642,7 @@ Categories=Network;WebBrowser;
|
|
|
618
642
|
/** Remove desktop shortcut artifacts created by `server shortcut`. */
|
|
619
643
|
function removeShortcut(name) {
|
|
620
644
|
if (isWin) {
|
|
621
|
-
for (const f of [winShortcutPs1Path(name), winPidFilePath(name)]) {
|
|
645
|
+
for (const f of [winShortcutPs1Path(name), winPidFilePath(name), winIcoPath()]) {
|
|
622
646
|
if (existsSync(f)) rmSync(f);
|
|
623
647
|
}
|
|
624
648
|
spawnSync(
|
package/package.json
CHANGED
|
@@ -1,85 +1,86 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "pi-web-ui",
|
|
3
|
-
"version": "0.11.
|
|
4
|
-
"description": "Web chat interface for the pi coding agent, powered by the pi SDK (@earendil-works/pi-coding-agent) — one-command run, Docker/systemd/launchd deployable",
|
|
5
|
-
"license": "MIT",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"bin": {
|
|
8
|
-
"pi-web-ui": "bin/pi-web-ui.mjs"
|
|
9
|
-
},
|
|
10
|
-
"main": "dist/server/index.js",
|
|
11
|
-
"files": [
|
|
12
|
-
"bin/",
|
|
13
|
-
"dist/",
|
|
14
|
-
"web/dist/",
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
"pi
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
"
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
"
|
|
45
|
-
"dev
|
|
46
|
-
"dev:
|
|
47
|
-
"
|
|
48
|
-
"build
|
|
49
|
-
"build:
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
"@
|
|
57
|
-
"@xterm/
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"react
|
|
63
|
-
"react-
|
|
64
|
-
"react-
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
"@types/
|
|
72
|
-
"@types/
|
|
73
|
-
"@types/react
|
|
74
|
-
"@types/
|
|
75
|
-
"@
|
|
76
|
-
"
|
|
77
|
-
"
|
|
78
|
-
"
|
|
79
|
-
"
|
|
80
|
-
"
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "pi-web-ui",
|
|
3
|
+
"version": "0.11.2",
|
|
4
|
+
"description": "Web chat interface for the pi coding agent, powered by the pi SDK (@earendil-works/pi-coding-agent) — one-command run, Docker/systemd/launchd deployable",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"pi-web-ui": "bin/pi-web-ui.mjs"
|
|
9
|
+
},
|
|
10
|
+
"main": "dist/server/index.js",
|
|
11
|
+
"files": [
|
|
12
|
+
"bin/",
|
|
13
|
+
"dist/",
|
|
14
|
+
"web/dist/",
|
|
15
|
+
"web/public/",
|
|
16
|
+
"deploy/",
|
|
17
|
+
"extensions/",
|
|
18
|
+
"README.md",
|
|
19
|
+
"LICENSE"
|
|
20
|
+
],
|
|
21
|
+
"keywords": [
|
|
22
|
+
"pi",
|
|
23
|
+
"pi-package",
|
|
24
|
+
"coding-agent",
|
|
25
|
+
"ai",
|
|
26
|
+
"chat",
|
|
27
|
+
"web-ui",
|
|
28
|
+
"terminal",
|
|
29
|
+
"llm"
|
|
30
|
+
],
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "git+https://github.com/xing-shuyin/pi-web-ui.git"
|
|
34
|
+
},
|
|
35
|
+
"pi": {
|
|
36
|
+
"extensions": [
|
|
37
|
+
"./extensions"
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
"engines": {
|
|
41
|
+
"node": ">=22.19.0"
|
|
42
|
+
},
|
|
43
|
+
"scripts": {
|
|
44
|
+
"prepublishOnly": "npm run build",
|
|
45
|
+
"dev": "concurrently -k -n server,web -c blue,green \"npm:dev:server\" \"npm:dev:web\"",
|
|
46
|
+
"dev:server": "node --watch --import tsx server/index.ts",
|
|
47
|
+
"dev:web": "vite --config web/vite.config.ts",
|
|
48
|
+
"build": "npm run build:web && npm run build:server",
|
|
49
|
+
"build:web": "vite build --config web/vite.config.ts",
|
|
50
|
+
"build:server": "tsc -p tsconfig.server.json",
|
|
51
|
+
"typecheck": "tsc -p tsconfig.server.json --noEmit && tsc -p web/tsconfig.json --noEmit",
|
|
52
|
+
"test:freeze": "node freeze-test.mjs",
|
|
53
|
+
"start": "node dist/server/index.js"
|
|
54
|
+
},
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"@earendil-works/pi-coding-agent": "^0.83.0",
|
|
57
|
+
"@xterm/addon-fit": "^0.11.0",
|
|
58
|
+
"@xterm/xterm": "^6.0.0",
|
|
59
|
+
"express": "^4.21.2",
|
|
60
|
+
"highlight.js": "^11.10.0",
|
|
61
|
+
"node-pty": "^1.1.0",
|
|
62
|
+
"react": "^18.3.1",
|
|
63
|
+
"react-dom": "^18.3.1",
|
|
64
|
+
"react-icons": "^5.7.0",
|
|
65
|
+
"react-markdown": "^9.0.1",
|
|
66
|
+
"rehype-highlight": "^7.0.1",
|
|
67
|
+
"remark-gfm": "^4.0.0",
|
|
68
|
+
"ws": "^8.18.0"
|
|
69
|
+
},
|
|
70
|
+
"devDependencies": {
|
|
71
|
+
"@types/express": "^4.17.21",
|
|
72
|
+
"@types/node": "^22.10.0",
|
|
73
|
+
"@types/react": "^18.3.12",
|
|
74
|
+
"@types/react-dom": "^18.3.1",
|
|
75
|
+
"@types/ws": "^8.5.13",
|
|
76
|
+
"@vitejs/plugin-react": "^4.3.4",
|
|
77
|
+
"concurrently": "^9.1.0",
|
|
78
|
+
"playwright-core": "^1.62.1",
|
|
79
|
+
"tsx": "^4.19.2",
|
|
80
|
+
"typescript": "^5.7.2",
|
|
81
|
+
"vite": "^6.0.3"
|
|
82
|
+
},
|
|
83
|
+
"allowScripts": {
|
|
84
|
+
"node-pty@1.1.0": true
|
|
85
|
+
}
|
|
86
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
|
2
|
+
<!-- pi symbol favicon: violet rounded square + white π (drawn as paths,
|
|
3
|
+
no font dependency) -->
|
|
4
|
+
<rect width="64" height="64" rx="14" fill="#8b5cf6"/>
|
|
5
|
+
<rect x="14" y="17" width="36" height="6.5" rx="3.25" fill="#ffffff"/>
|
|
6
|
+
<rect x="17.5" y="23.5" width="6.5" height="25" rx="3.25" fill="#ffffff"/>
|
|
7
|
+
<rect x="40" y="23.5" width="6.5" height="25" rx="3.25" fill="#ffffff"/>
|
|
8
|
+
</svg>
|
|
Binary file
|