@rainmanhhh/pi-web 0.8.7
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/LICENSE +22 -0
- package/README.md +147 -0
- package/README.zh-CN.md +145 -0
- package/dist/server.mjs +403 -0
- package/dist/static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/dist/static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/dist/static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/dist/static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/dist/static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/dist/static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/dist/static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/dist/static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/dist/static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/dist/static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/dist/static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/dist/static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/dist/static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/dist/static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/dist/static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/dist/static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/dist/static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/dist/static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/dist/static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/dist/static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/dist/static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/dist/static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/dist/static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/dist/static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/dist/static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/dist/static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/dist/static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/dist/static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/dist/static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/dist/static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/dist/static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/dist/static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/dist/static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/dist/static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/dist/static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/dist/static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/dist/static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/dist/static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/dist/static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/dist/static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/dist/static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/dist/static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/dist/static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/dist/static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/dist/static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/dist/static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/dist/static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/dist/static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/dist/static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/dist/static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/dist/static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/dist/static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/dist/static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/dist/static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/dist/static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/dist/static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/dist/static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/dist/static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/dist/static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/dist/static/assets/_baseFor-D6HAxaEF.js +1 -0
- package/dist/static/assets/arc-Cev3HYkO.js +1 -0
- package/dist/static/assets/architecture-YZFGNWBL-DSVeA3Mc.js +1 -0
- package/dist/static/assets/architectureDiagram-Q4EWVU46-BUaFXLue.js +36 -0
- package/dist/static/assets/array-BifhSqXX.js +1 -0
- package/dist/static/assets/blockDiagram-DXYQGD6D-BD7crHZn.js +132 -0
- package/dist/static/assets/c4Diagram-AHTNJAMY-BTvR1Qix.js +10 -0
- package/dist/static/assets/channel-DSbgxqFl.js +1 -0
- package/dist/static/assets/chunk-4BX2VUAB-C9I87hfN.js +1 -0
- package/dist/static/assets/chunk-4TB4RGXK-CYXNKQNe.js +206 -0
- package/dist/static/assets/chunk-55IACEB6-DAYR8bYh.js +1 -0
- package/dist/static/assets/chunk-5FUZZQ4R-BghvyuR7.js +62 -0
- package/dist/static/assets/chunk-5PVQY5BW-CZT35iHI.js +2 -0
- package/dist/static/assets/chunk-BSJP7CBP-BclwT518.js +1 -0
- package/dist/static/assets/chunk-EDXVE4YY-C4TkNvln.js +1 -0
- package/dist/static/assets/chunk-ENJZ2VHE-BNRddB0h.js +10 -0
- package/dist/static/assets/chunk-FMBD7UC4-4iiTC4rp.js +15 -0
- package/dist/static/assets/chunk-ICPOFSXX-BIhiNjvk.js +122 -0
- package/dist/static/assets/chunk-K5T4RW27-FpH_VPgE.js +94 -0
- package/dist/static/assets/chunk-OYMX7WX6-Dg0dFe8H.js +231 -0
- package/dist/static/assets/chunk-QZHKN3VN-DnoLcr4T.js +1 -0
- package/dist/static/assets/chunk-U2HBQHQK-CJqSKuXA.js +70 -0
- package/dist/static/assets/chunk-X2U36JSP-DVXuKdYc.js +1 -0
- package/dist/static/assets/chunk-YZCP3GAM-D4t97aMk.js +1 -0
- package/dist/static/assets/chunk-ZZ45TVLE-D3ALxVxH.js +1 -0
- package/dist/static/assets/classDiagram-6PBFFD2Q-3fKgRhOi.js +1 -0
- package/dist/static/assets/classDiagram-v2-HSJHXN6E-3fKgRhOi.js +1 -0
- package/dist/static/assets/clone-Dgktwry5.js +1 -0
- package/dist/static/assets/cose-bilkent-S5V4N54A-CVHW-V1c.js +1 -0
- package/dist/static/assets/cytoscape.esm-KkXhEuBu.js +321 -0
- package/dist/static/assets/dagre-DANBRJgS.js +1 -0
- package/dist/static/assets/dagre-KV5264BT-RX495Ogs.js +4 -0
- package/dist/static/assets/defaultLocale-BFoDCU3G.js +1 -0
- package/dist/static/assets/diagram-5BDNPKRD-B3TQrwLp.js +10 -0
- package/dist/static/assets/diagram-G4DWMVQ6-DMTfV1fq.js +24 -0
- package/dist/static/assets/diagram-MMDJMWI5-BA8Bf6LU.js +43 -0
- package/dist/static/assets/diagram-TYMM5635-DZgWIMF2.js +24 -0
- package/dist/static/assets/dist-C_yfW-4f.js +1 -0
- package/dist/static/assets/erDiagram-SMLLAGMA-BPjiJgpM.js +85 -0
- package/dist/static/assets/flatten-DYA82rhy.js +1 -0
- package/dist/static/assets/flowDiagram-DWJPFMVM-C8itnDyk.js +162 -0
- package/dist/static/assets/ganttDiagram-T4ZO3ILL-QijQZ_7A.js +292 -0
- package/dist/static/assets/gitGraph-7Q5UKJZL-DUTBJasc.js +1 -0
- package/dist/static/assets/gitGraphDiagram-UUTBAWPF-B4SbXUo2.js +106 -0
- package/dist/static/assets/graphlib-CAZZWEle.js +1 -0
- package/dist/static/assets/highlighted-body-OFNGDK62-B6SZt-Xj.js +1 -0
- package/dist/static/assets/index-BSAN2ZmA.css +1 -0
- package/dist/static/assets/index-CtaBtFPm.js +492 -0
- package/dist/static/assets/info-OMHHGYJF-y8VVrvpT.js +1 -0
- package/dist/static/assets/infoDiagram-42DDH7IO-SEL8m7Hn.js +2 -0
- package/dist/static/assets/init-C-OQMol4.js +1 -0
- package/dist/static/assets/ishikawaDiagram-UXIWVN3A-BiGygTnl.js +70 -0
- package/dist/static/assets/journeyDiagram-VCZTEJTY-x16DmnC7.js +139 -0
- package/dist/static/assets/kanban-definition-6JOO6SKY-B_Vmy_se.js +89 -0
- package/dist/static/assets/katex-9tSoZCUs.js +257 -0
- package/dist/static/assets/line-BXZmYadU.js +1 -0
- package/dist/static/assets/linear-BDsPwGxk.js +1 -0
- package/dist/static/assets/mermaid-GHXKKRXX-CZfowopI.js +1 -0
- package/dist/static/assets/mermaid-parser.core-BdiNtuYK.js +4 -0
- package/dist/static/assets/mermaid.core-Cy3kC-2x.js +42 -0
- package/dist/static/assets/mindmap-definition-QFDTVHPH-DibAS34Z.js +96 -0
- package/dist/static/assets/ordinal-DtR4qwUh.js +1 -0
- package/dist/static/assets/packet-4T2RLAQJ-QWjI5ifX.js +1 -0
- package/dist/static/assets/path-fybaL0A-.js +1 -0
- package/dist/static/assets/pie-ZZUOXDRM-CCpZfmHW.js +1 -0
- package/dist/static/assets/pieDiagram-DEJITSTG-DE3IRdo2.js +30 -0
- package/dist/static/assets/quadrantDiagram-34T5L4WZ-BnFzq8uS.js +7 -0
- package/dist/static/assets/radar-PYXPWWZC-DJRfpCAG.js +1 -0
- package/dist/static/assets/reduce-D9Ymtwj-.js +1 -0
- package/dist/static/assets/requirementDiagram-MS252O5E-4JH5mfMt.js +84 -0
- package/dist/static/assets/rolldown-runtime-C_s2cVnS.js +1 -0
- package/dist/static/assets/rough.esm-Dy-Kn_BL.js +1 -0
- package/dist/static/assets/sankeyDiagram-XADWPNL6-BBM3bCVp.js +10 -0
- package/dist/static/assets/sequenceDiagram-FGHM5R23-Ngkhph4n.js +157 -0
- package/dist/static/assets/src-D3QavEJ4.js +1 -0
- package/dist/static/assets/stateDiagram-FHFEXIEX-B8QHUbFP.js +1 -0
- package/dist/static/assets/stateDiagram-v2-QKLJ7IA2-8s677m33.js +1 -0
- package/dist/static/assets/timeline-definition-GMOUNBTQ-Cj_jCa6v.js +120 -0
- package/dist/static/assets/treeView-SZITEDCU-BYIf12Kb.js +1 -0
- package/dist/static/assets/treemap-W4RFUUIX-ChTAE-ps.js +1 -0
- package/dist/static/assets/vennDiagram-DHZGUBPP-Nv73eNL-.js +34 -0
- package/dist/static/assets/wardley-RL74JXVD-D4JZq5aY.js +1 -0
- package/dist/static/assets/wardleyDiagram-NUSXRM2D-D4_-w6kd.js +20 -0
- package/dist/static/assets/xychartDiagram-5P7HB3ND-BWrW2XAn.js +7 -0
- package/dist/static/icons/apple-touch-icon.png +0 -0
- package/dist/static/icons/icon-192.png +0 -0
- package/dist/static/icons/icon-512.png +0 -0
- package/dist/static/index.html +46 -0
- package/dist/static/manifest.webmanifest +28 -0
- package/dist/static/offline.html +83 -0
- package/dist/static/sw.js +75 -0
- package/package.json +107 -0
- package/public/icons/apple-touch-icon.png +0 -0
- package/public/icons/icon-192.png +0 -0
- package/public/icons/icon-512.png +0 -0
- package/public/manifest.webmanifest +28 -0
- package/public/offline.html +83 -0
- package/public/sw.js +75 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
|
6
|
+
<meta name="theme-color" content="#1a1a1a" />
|
|
7
|
+
<title>Pi Web is offline</title>
|
|
8
|
+
<style>
|
|
9
|
+
:root {
|
|
10
|
+
color-scheme: dark;
|
|
11
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
12
|
+
background: #1a1a1a;
|
|
13
|
+
color: #e8e8e8;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
* {
|
|
17
|
+
box-sizing: border-box;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
body {
|
|
21
|
+
min-height: 100dvh;
|
|
22
|
+
margin: 0;
|
|
23
|
+
display: grid;
|
|
24
|
+
place-items: center;
|
|
25
|
+
padding: 32px;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
main {
|
|
29
|
+
width: min(100%, 420px);
|
|
30
|
+
text-align: center;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
img {
|
|
34
|
+
width: 88px;
|
|
35
|
+
height: 88px;
|
|
36
|
+
margin-bottom: 24px;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
h1 {
|
|
40
|
+
margin: 0 0 10px;
|
|
41
|
+
font-size: 22px;
|
|
42
|
+
font-weight: 650;
|
|
43
|
+
letter-spacing: 0;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
p {
|
|
47
|
+
margin: 0;
|
|
48
|
+
color: #9ca3af;
|
|
49
|
+
font-size: 14px;
|
|
50
|
+
line-height: 1.6;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
button {
|
|
54
|
+
margin-top: 24px;
|
|
55
|
+
min-height: 40px;
|
|
56
|
+
padding: 0 18px;
|
|
57
|
+
border: 1px solid #3a3a3a;
|
|
58
|
+
border-radius: 6px;
|
|
59
|
+
background: #242424;
|
|
60
|
+
color: #e8e8e8;
|
|
61
|
+
font: inherit;
|
|
62
|
+
cursor: pointer;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
button:hover {
|
|
66
|
+
background: #2e2e2e;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
button:focus-visible {
|
|
70
|
+
outline: 2px solid #60a5fa;
|
|
71
|
+
outline-offset: 3px;
|
|
72
|
+
}
|
|
73
|
+
</style>
|
|
74
|
+
</head>
|
|
75
|
+
<body>
|
|
76
|
+
<main>
|
|
77
|
+
<img src="/icons/icon-192.png" alt="" />
|
|
78
|
+
<h1>Pi Web is offline</h1>
|
|
79
|
+
<p>Reconnect to the local Pi Web server, then try again.</p>
|
|
80
|
+
<button type="button" onclick="location.reload()">Try again</button>
|
|
81
|
+
</main>
|
|
82
|
+
</body>
|
|
83
|
+
</html>
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
const CACHE_PREFIX = "pi-web";
|
|
2
|
+
const CACHE_VERSION = new URL(self.location.href).searchParams.get("v") || "dev";
|
|
3
|
+
const STATIC_CACHE = `${CACHE_PREFIX}-static-${CACHE_VERSION}`;
|
|
4
|
+
const OFFLINE_URL = "/offline.html";
|
|
5
|
+
const PRECACHE_URLS = [
|
|
6
|
+
OFFLINE_URL,
|
|
7
|
+
"/manifest.webmanifest",
|
|
8
|
+
"/icons/icon-192.png",
|
|
9
|
+
"/icons/icon-512.png",
|
|
10
|
+
"/icons/apple-touch-icon.png",
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
self.addEventListener("install", (event) => {
|
|
14
|
+
event.waitUntil(
|
|
15
|
+
caches
|
|
16
|
+
.open(STATIC_CACHE)
|
|
17
|
+
.then((cache) => cache.addAll(PRECACHE_URLS))
|
|
18
|
+
.then(() => self.skipWaiting()),
|
|
19
|
+
);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
self.addEventListener("activate", (event) => {
|
|
23
|
+
event.waitUntil(
|
|
24
|
+
caches
|
|
25
|
+
.keys()
|
|
26
|
+
.then((keys) =>
|
|
27
|
+
Promise.all(
|
|
28
|
+
keys
|
|
29
|
+
.filter((key) => key.startsWith(`${CACHE_PREFIX}-`) && key !== STATIC_CACHE)
|
|
30
|
+
.map((key) => caches.delete(key)),
|
|
31
|
+
),
|
|
32
|
+
)
|
|
33
|
+
.then(() => self.clients.claim()),
|
|
34
|
+
);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
self.addEventListener("fetch", (event) => {
|
|
38
|
+
const { request } = event;
|
|
39
|
+
if (request.method !== "GET") return;
|
|
40
|
+
|
|
41
|
+
const url = new URL(request.url);
|
|
42
|
+
if (url.origin !== self.location.origin) return;
|
|
43
|
+
|
|
44
|
+
// Session data and live agent traffic must always come from the local server.
|
|
45
|
+
if (url.pathname.startsWith("/api/") || url.pathname === "/sw.js") return;
|
|
46
|
+
|
|
47
|
+
if (request.mode === "navigate") {
|
|
48
|
+
event.respondWith(
|
|
49
|
+
fetch(request).catch(async () => {
|
|
50
|
+
const fallback = await caches.match(OFFLINE_URL);
|
|
51
|
+
return fallback ?? Response.error();
|
|
52
|
+
}),
|
|
53
|
+
);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const isStaticAsset =
|
|
58
|
+
url.pathname.startsWith("/_next/static/") || PRECACHE_URLS.includes(url.pathname);
|
|
59
|
+
|
|
60
|
+
if (isStaticAsset) {
|
|
61
|
+
event.respondWith(cacheFirst(request));
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
async function cacheFirst(request) {
|
|
66
|
+
const cached = await caches.match(request);
|
|
67
|
+
if (cached) return cached;
|
|
68
|
+
|
|
69
|
+
const response = await fetch(request);
|
|
70
|
+
if (response.ok && response.type === "basic") {
|
|
71
|
+
const cache = await caches.open(STATIC_CACHE);
|
|
72
|
+
await cache.put(request, response.clone());
|
|
73
|
+
}
|
|
74
|
+
return response;
|
|
75
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rainmanhhh/pi-web",
|
|
3
|
+
"version": "0.8.7",
|
|
4
|
+
"description": "Web UI for the pi coding agent (fork of @agegr/pi-web)",
|
|
5
|
+
"homepage": "https://gitee.com/dsxbygzzl/pi-web#readme",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://gitee.com/dsxbygzzl/pi-web.git"
|
|
9
|
+
},
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://gitee.com/dsxbygzzl/pi-web/issues"
|
|
12
|
+
},
|
|
13
|
+
"author": "rainmanhhh",
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public",
|
|
17
|
+
"registry": "https://registry.npmjs.org"
|
|
18
|
+
},
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=22.19.0"
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist",
|
|
24
|
+
"public",
|
|
25
|
+
"package.json"
|
|
26
|
+
],
|
|
27
|
+
"bin": {
|
|
28
|
+
"pi-web": "dist/server.mjs"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@earendil-works/pi-agent-core": "0.84.1",
|
|
32
|
+
"@earendil-works/pi-ai": "0.84.1",
|
|
33
|
+
"@earendil-works/pi-coding-agent": "0.84.1",
|
|
34
|
+
"@earendil-works/pi-tui": "0.84.1",
|
|
35
|
+
"@hono/node-server": "^2.1.0",
|
|
36
|
+
"class-variance-authority": "^0.7.1",
|
|
37
|
+
"clsx": "^2.1.1",
|
|
38
|
+
"hono": "^4.13.1",
|
|
39
|
+
"lucide-react": "^1.31.0",
|
|
40
|
+
"proper-lockfile": "4.1.2",
|
|
41
|
+
"radix-ui": "^1.6.7",
|
|
42
|
+
"react": "^19.2.4",
|
|
43
|
+
"react-dom": "^19.2.4",
|
|
44
|
+
"shadcn": "^4.17.0",
|
|
45
|
+
"streamdown": "2.5.0",
|
|
46
|
+
"tailwind-merge": "^3.6.0",
|
|
47
|
+
"tw-animate-css": "^1.4.0",
|
|
48
|
+
"undici": "8.9.0"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@lobehub/icons": "^5.6.0",
|
|
52
|
+
"@playwright/test": "^1.62.1",
|
|
53
|
+
"@tailwindcss/postcss": "^4.2.2",
|
|
54
|
+
"@testing-library/dom": "^10.4.1",
|
|
55
|
+
"@testing-library/react": "^16.3.2",
|
|
56
|
+
"@types/node": "^25",
|
|
57
|
+
"@types/node-notifier": "^8.0.5",
|
|
58
|
+
"@types/proper-lockfile": "4.1.4",
|
|
59
|
+
"@types/react": "^19",
|
|
60
|
+
"@types/react-dom": "^19",
|
|
61
|
+
"@types/react-syntax-highlighter": "^15.5.13",
|
|
62
|
+
"@vitejs/plugin-react": "^6.0.5",
|
|
63
|
+
"biome": "^0.3.3",
|
|
64
|
+
"commander": "^15.0.0",
|
|
65
|
+
"husky": "^9.1.7",
|
|
66
|
+
"jiti": "^2.7.0",
|
|
67
|
+
"jscpd": "^5.0.14",
|
|
68
|
+
"jsdom": "^30.0.1",
|
|
69
|
+
"katex": "^0.16.47",
|
|
70
|
+
"lint-staged": "^17.3.0",
|
|
71
|
+
"mammoth": "^1.12.0",
|
|
72
|
+
"mermaid": "^11.14.0",
|
|
73
|
+
"node-notifier": "^10.0.1",
|
|
74
|
+
"oxlint": "^1.78.0",
|
|
75
|
+
"postcss": "^8",
|
|
76
|
+
"react-markdown": "^10.1.0",
|
|
77
|
+
"react-syntax-highlighter": "^16.1.1",
|
|
78
|
+
"rehype-katex": "^7.0.1",
|
|
79
|
+
"rehype-raw": "^7.0.0",
|
|
80
|
+
"rehype-sanitize": "^6.0.0",
|
|
81
|
+
"remark-gfm": "^4.0.1",
|
|
82
|
+
"remark-math": "^6.0.0",
|
|
83
|
+
"tailwindcss": "^4.2.2",
|
|
84
|
+
"typescript": "^7.0.2",
|
|
85
|
+
"vite": "^8.2.1",
|
|
86
|
+
"vite-plugin-svgr": "^5.2.0",
|
|
87
|
+
"vitest": "^4.1.10"
|
|
88
|
+
},
|
|
89
|
+
"type": "module",
|
|
90
|
+
"scripts": {
|
|
91
|
+
"dev": "vite",
|
|
92
|
+
"dev:lan": "vite --host 0.0.0.0",
|
|
93
|
+
"mb": "bun run --env-file=.env.manual api",
|
|
94
|
+
"mf": "bun run --env-file=.env.manual dev -- --port 3001",
|
|
95
|
+
"api": "bun run server/main.ts",
|
|
96
|
+
"api:node": "bun run build:server && node dist/server.mjs",
|
|
97
|
+
"build:server": "bun build server/main.ts --target node --outfile dist/server.mjs --minify --external \"@earendil-works/*\" --define \"process.env.PI_WEB_PACKAGED=1\"",
|
|
98
|
+
"e2e:stop": "bun run scripts/e2e-stop.mjs",
|
|
99
|
+
"build": "vite build",
|
|
100
|
+
"lint": "oxlint --fix",
|
|
101
|
+
"jscpd": "jscpd --config .jscpd.json",
|
|
102
|
+
"check": "tsc --noEmit",
|
|
103
|
+
"format": "biome check --write .",
|
|
104
|
+
"test:e2e": "playwright test",
|
|
105
|
+
"test:unit": "vitest run"
|
|
106
|
+
}
|
|
107
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "/",
|
|
3
|
+
"name": "Pi Web",
|
|
4
|
+
"short_name": "Pi Web",
|
|
5
|
+
"description": "Local web interface for the pi coding agent",
|
|
6
|
+
"start_url": "/",
|
|
7
|
+
"scope": "/",
|
|
8
|
+
"display": "standalone",
|
|
9
|
+
"background_color": "#000000",
|
|
10
|
+
"theme_color": "#000000",
|
|
11
|
+
"orientation": "any",
|
|
12
|
+
"categories": ["developer", "productivity"],
|
|
13
|
+
"lang": "en",
|
|
14
|
+
"icons": [
|
|
15
|
+
{
|
|
16
|
+
"src": "/icons/icon-192.png",
|
|
17
|
+
"sizes": "192x192",
|
|
18
|
+
"type": "image/png",
|
|
19
|
+
"purpose": "any"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"src": "/icons/icon-512.png",
|
|
23
|
+
"sizes": "512x512",
|
|
24
|
+
"type": "image/png",
|
|
25
|
+
"purpose": "any"
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
|
6
|
+
<meta name="theme-color" content="#1a1a1a" />
|
|
7
|
+
<title>Pi Web is offline</title>
|
|
8
|
+
<style>
|
|
9
|
+
:root {
|
|
10
|
+
color-scheme: dark;
|
|
11
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
12
|
+
background: #1a1a1a;
|
|
13
|
+
color: #e8e8e8;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
* {
|
|
17
|
+
box-sizing: border-box;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
body {
|
|
21
|
+
min-height: 100dvh;
|
|
22
|
+
margin: 0;
|
|
23
|
+
display: grid;
|
|
24
|
+
place-items: center;
|
|
25
|
+
padding: 32px;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
main {
|
|
29
|
+
width: min(100%, 420px);
|
|
30
|
+
text-align: center;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
img {
|
|
34
|
+
width: 88px;
|
|
35
|
+
height: 88px;
|
|
36
|
+
margin-bottom: 24px;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
h1 {
|
|
40
|
+
margin: 0 0 10px;
|
|
41
|
+
font-size: 22px;
|
|
42
|
+
font-weight: 650;
|
|
43
|
+
letter-spacing: 0;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
p {
|
|
47
|
+
margin: 0;
|
|
48
|
+
color: #9ca3af;
|
|
49
|
+
font-size: 14px;
|
|
50
|
+
line-height: 1.6;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
button {
|
|
54
|
+
margin-top: 24px;
|
|
55
|
+
min-height: 40px;
|
|
56
|
+
padding: 0 18px;
|
|
57
|
+
border: 1px solid #3a3a3a;
|
|
58
|
+
border-radius: 6px;
|
|
59
|
+
background: #242424;
|
|
60
|
+
color: #e8e8e8;
|
|
61
|
+
font: inherit;
|
|
62
|
+
cursor: pointer;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
button:hover {
|
|
66
|
+
background: #2e2e2e;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
button:focus-visible {
|
|
70
|
+
outline: 2px solid #60a5fa;
|
|
71
|
+
outline-offset: 3px;
|
|
72
|
+
}
|
|
73
|
+
</style>
|
|
74
|
+
</head>
|
|
75
|
+
<body>
|
|
76
|
+
<main>
|
|
77
|
+
<img src="/icons/icon-192.png" alt="" />
|
|
78
|
+
<h1>Pi Web is offline</h1>
|
|
79
|
+
<p>Reconnect to the local Pi Web server, then try again.</p>
|
|
80
|
+
<button type="button" onclick="location.reload()">Try again</button>
|
|
81
|
+
</main>
|
|
82
|
+
</body>
|
|
83
|
+
</html>
|
package/public/sw.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
const CACHE_PREFIX = "pi-web";
|
|
2
|
+
const CACHE_VERSION = new URL(self.location.href).searchParams.get("v") || "dev";
|
|
3
|
+
const STATIC_CACHE = `${CACHE_PREFIX}-static-${CACHE_VERSION}`;
|
|
4
|
+
const OFFLINE_URL = "/offline.html";
|
|
5
|
+
const PRECACHE_URLS = [
|
|
6
|
+
OFFLINE_URL,
|
|
7
|
+
"/manifest.webmanifest",
|
|
8
|
+
"/icons/icon-192.png",
|
|
9
|
+
"/icons/icon-512.png",
|
|
10
|
+
"/icons/apple-touch-icon.png",
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
self.addEventListener("install", (event) => {
|
|
14
|
+
event.waitUntil(
|
|
15
|
+
caches
|
|
16
|
+
.open(STATIC_CACHE)
|
|
17
|
+
.then((cache) => cache.addAll(PRECACHE_URLS))
|
|
18
|
+
.then(() => self.skipWaiting()),
|
|
19
|
+
);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
self.addEventListener("activate", (event) => {
|
|
23
|
+
event.waitUntil(
|
|
24
|
+
caches
|
|
25
|
+
.keys()
|
|
26
|
+
.then((keys) =>
|
|
27
|
+
Promise.all(
|
|
28
|
+
keys
|
|
29
|
+
.filter((key) => key.startsWith(`${CACHE_PREFIX}-`) && key !== STATIC_CACHE)
|
|
30
|
+
.map((key) => caches.delete(key)),
|
|
31
|
+
),
|
|
32
|
+
)
|
|
33
|
+
.then(() => self.clients.claim()),
|
|
34
|
+
);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
self.addEventListener("fetch", (event) => {
|
|
38
|
+
const { request } = event;
|
|
39
|
+
if (request.method !== "GET") return;
|
|
40
|
+
|
|
41
|
+
const url = new URL(request.url);
|
|
42
|
+
if (url.origin !== self.location.origin) return;
|
|
43
|
+
|
|
44
|
+
// Session data and live agent traffic must always come from the local server.
|
|
45
|
+
if (url.pathname.startsWith("/api/") || url.pathname === "/sw.js") return;
|
|
46
|
+
|
|
47
|
+
if (request.mode === "navigate") {
|
|
48
|
+
event.respondWith(
|
|
49
|
+
fetch(request).catch(async () => {
|
|
50
|
+
const fallback = await caches.match(OFFLINE_URL);
|
|
51
|
+
return fallback ?? Response.error();
|
|
52
|
+
}),
|
|
53
|
+
);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const isStaticAsset =
|
|
58
|
+
url.pathname.startsWith("/_next/static/") || PRECACHE_URLS.includes(url.pathname);
|
|
59
|
+
|
|
60
|
+
if (isStaticAsset) {
|
|
61
|
+
event.respondWith(cacheFirst(request));
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
async function cacheFirst(request) {
|
|
66
|
+
const cached = await caches.match(request);
|
|
67
|
+
if (cached) return cached;
|
|
68
|
+
|
|
69
|
+
const response = await fetch(request);
|
|
70
|
+
if (response.ok && response.type === "basic") {
|
|
71
|
+
const cache = await caches.open(STATIC_CACHE);
|
|
72
|
+
await cache.put(request, response.clone());
|
|
73
|
+
}
|
|
74
|
+
return response;
|
|
75
|
+
}
|