@firstpick/pi-package-webui 0.1.1 → 0.1.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/README.md +33 -13
- package/bin/pi-webui.mjs +457 -15
- package/index.ts +304 -4
- package/package.json +7 -2
- package/public/app.js +644 -40
- package/public/apple-touch-icon.png +0 -0
- package/public/icon-192.png +0 -0
- package/public/icon-512.png +0 -0
- package/public/index.html +48 -22
- package/public/manifest.webmanifest +40 -0
- package/public/service-worker.js +46 -0
- package/public/styles.css +704 -26
- package/tests/mobile-static.test.mjs +170 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/public/index.html
CHANGED
|
@@ -2,9 +2,16 @@
|
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover, interactive-widget=resizes-content" />
|
|
6
6
|
<title>Pi Web UI</title>
|
|
7
|
+
<meta name="theme-color" content="#11111b" />
|
|
8
|
+
<meta name="mobile-web-app-capable" content="yes" />
|
|
9
|
+
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
10
|
+
<meta name="apple-mobile-web-app-title" content="Pi Web" />
|
|
11
|
+
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
|
12
|
+
<link rel="manifest" href="/manifest.webmanifest" />
|
|
7
13
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
14
|
+
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
|
8
15
|
<link rel="stylesheet" href="/styles.css" />
|
|
9
16
|
</head>
|
|
10
17
|
<body>
|
|
@@ -18,11 +25,14 @@
|
|
|
18
25
|
<main class="layout">
|
|
19
26
|
<section class="chat-panel">
|
|
20
27
|
<header class="terminal-tabs-shell">
|
|
21
|
-
<
|
|
22
|
-
<
|
|
28
|
+
<button id="terminalTabsToggleButton" class="terminal-tabs-toggle-button" type="button" aria-controls="tabBar" aria-expanded="false">Tabs</button>
|
|
29
|
+
<div id="tabBar" class="terminal-tabs" role="tablist" aria-label="Pi terminal tabs">
|
|
30
|
+
<button id="newTabButton" class="terminal-new-tab-button" type="button" title="Start a separate isolated Pi terminal">+ Tab</button>
|
|
31
|
+
</div>
|
|
23
32
|
</header>
|
|
24
33
|
<div id="widgetArea" class="widget-area"></div>
|
|
25
34
|
<div id="chat" class="chat" aria-live="polite"></div>
|
|
35
|
+
<button id="jumpToLatestButton" class="jump-to-latest-button" type="button" hidden>Latest ↓</button>
|
|
26
36
|
<div id="statusBar" class="statusbar" aria-live="polite"></div>
|
|
27
37
|
<section id="gitWorkflowPanel" class="git-workflow-panel" aria-live="polite" hidden>
|
|
28
38
|
<div class="git-workflow-header">
|
|
@@ -38,34 +48,50 @@
|
|
|
38
48
|
<div id="gitWorkflowActions" class="git-workflow-actions"></div>
|
|
39
49
|
</section>
|
|
40
50
|
<form id="composer" class="composer">
|
|
41
|
-
<textarea id="promptInput" rows="
|
|
51
|
+
<textarea id="promptInput" rows="1" enterkeyhint="enter" placeholder="Ask Pi…"></textarea>
|
|
42
52
|
<div id="commandSuggest" class="command-suggest" role="listbox" aria-label="Command suggestions" hidden></div>
|
|
43
53
|
<div class="composer-row">
|
|
44
|
-
<
|
|
45
|
-
|
|
46
|
-
<
|
|
47
|
-
|
|
48
|
-
<
|
|
49
|
-
|
|
50
|
-
|
|
54
|
+
<button id="composerActionsButton" class="composer-actions-button" type="button" aria-controls="composerActionsPanel" aria-expanded="false">Actions</button>
|
|
55
|
+
<div id="composerActionsPanel" class="composer-actions-panel" aria-label="Composer actions">
|
|
56
|
+
<label>
|
|
57
|
+
Busy prompt behavior
|
|
58
|
+
<select id="busyBehavior">
|
|
59
|
+
<option value="followUp">follow-up</option>
|
|
60
|
+
<option value="steer">steer</option>
|
|
61
|
+
</select>
|
|
62
|
+
</label>
|
|
63
|
+
<button id="newSessionButton" class="composer-new-button" type="button">New</button>
|
|
64
|
+
<button id="compactButton" class="composer-compact-button" type="button" title="Compact the current Pi session context">Compact</button>
|
|
65
|
+
<button
|
|
66
|
+
id="gitWorkflowButton"
|
|
67
|
+
class="composer-git-button"
|
|
68
|
+
type="button"
|
|
69
|
+
title="Guided Git workflow: git add ., /git-staged-msg, preview messages, commit short/long, git push. Cancel is available at each step."
|
|
70
|
+
aria-label="Start guided Git workflow: git add dot, run git-staged-msg, preview messages, commit short or long, then git push. Cancel is available at each step."
|
|
71
|
+
data-tooltip="Guided Git workflow: 1. Run git add . 2. Run /git-staged-msg 3. Preview short + long messages 4. Commit with short or long message 5. Run git push Cancel is available at each step."
|
|
72
|
+
>Git workflow</button>
|
|
73
|
+
</div>
|
|
51
74
|
<div class="spacer"></div>
|
|
52
|
-
<button id="newSessionButton" class="composer-new-button" type="button">New</button>
|
|
53
|
-
<button id="compactButton" class="composer-compact-button" type="button" title="Compact the current Pi session context">Compact</button>
|
|
54
75
|
<button
|
|
55
|
-
id="
|
|
56
|
-
|
|
76
|
+
id="steerButton"
|
|
77
|
+
type="button"
|
|
78
|
+
title="Type your message first, then tap Steer to guide the active Pi run without sending a normal prompt. Use it for corrections or direction changes while Pi is working."
|
|
79
|
+
aria-label="Steer: type your message first, then tap this button to guide the active Pi run."
|
|
80
|
+
data-tooltip="Steer usage: 1. Type your steering message in the textarea. 2. Tap Steer to guide the active Pi run. Use for corrections or direction changes while Pi is working."
|
|
81
|
+
>Steer</button>
|
|
82
|
+
<button
|
|
83
|
+
id="followUpButton"
|
|
57
84
|
type="button"
|
|
58
|
-
title="
|
|
59
|
-
aria-label="
|
|
60
|
-
data-tooltip="
|
|
61
|
-
>
|
|
62
|
-
<button id="
|
|
63
|
-
<button id="followUpButton" type="button">Follow-up</button>
|
|
64
|
-
<button type="submit" class="primary">Send</button>
|
|
85
|
+
title="Type your message first, then tap Follow-up to send it as a follow-up instead of a normal prompt. Use it to add extra context or the next request."
|
|
86
|
+
aria-label="Follow-up: type your message first, then tap this button to send it as a follow-up."
|
|
87
|
+
data-tooltip="Follow-up usage: 1. Type your message in the textarea. 2. Tap Follow-up to send it as a follow-up. Use for extra context or the next request."
|
|
88
|
+
>Follow-up</button>
|
|
89
|
+
<button id="sendButton" type="submit" class="primary">Send</button>
|
|
65
90
|
</div>
|
|
66
91
|
</form>
|
|
67
92
|
</section>
|
|
68
93
|
|
|
94
|
+
<button id="sidePanelBackdrop" class="side-panel-backdrop" type="button" aria-label="Close side panel" hidden></button>
|
|
69
95
|
<aside id="sidePanel" class="side-panel">
|
|
70
96
|
<div class="side-panel-header">
|
|
71
97
|
<div>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "/",
|
|
3
|
+
"name": "Pi Web UI",
|
|
4
|
+
"short_name": "Pi Web",
|
|
5
|
+
"description": "Mobile-friendly web interface for Pi coding agent sessions.",
|
|
6
|
+
"start_url": "/",
|
|
7
|
+
"scope": "/",
|
|
8
|
+
"display": "standalone",
|
|
9
|
+
"display_override": ["window-controls-overlay", "standalone", "minimal-ui", "browser"],
|
|
10
|
+
"background_color": "#11111b",
|
|
11
|
+
"theme_color": "#11111b",
|
|
12
|
+
"orientation": "any",
|
|
13
|
+
"categories": ["developer", "productivity", "utilities"],
|
|
14
|
+
"icons": [
|
|
15
|
+
{
|
|
16
|
+
"src": "/favicon.svg",
|
|
17
|
+
"sizes": "any",
|
|
18
|
+
"type": "image/svg+xml",
|
|
19
|
+
"purpose": "any"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"src": "/apple-touch-icon.png",
|
|
23
|
+
"sizes": "180x180",
|
|
24
|
+
"type": "image/png",
|
|
25
|
+
"purpose": "any"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"src": "/icon-192.png",
|
|
29
|
+
"sizes": "192x192",
|
|
30
|
+
"type": "image/png",
|
|
31
|
+
"purpose": "any maskable"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"src": "/icon-512.png",
|
|
35
|
+
"sizes": "512x512",
|
|
36
|
+
"type": "image/png",
|
|
37
|
+
"purpose": "any maskable"
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const CACHE_NAME = "pi-webui-pwa-v1";
|
|
2
|
+
const APP_SHELL = [
|
|
3
|
+
"/",
|
|
4
|
+
"/index.html",
|
|
5
|
+
"/styles.css",
|
|
6
|
+
"/app.js",
|
|
7
|
+
"/favicon.svg",
|
|
8
|
+
"/apple-touch-icon.png",
|
|
9
|
+
"/icon-192.png",
|
|
10
|
+
"/icon-512.png",
|
|
11
|
+
"/manifest.webmanifest",
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
self.addEventListener("install", (event) => {
|
|
15
|
+
event.waitUntil(caches.open(CACHE_NAME).then((cache) => cache.addAll(APP_SHELL)).then(() => self.skipWaiting()));
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
self.addEventListener("activate", (event) => {
|
|
19
|
+
event.waitUntil(
|
|
20
|
+
caches.keys()
|
|
21
|
+
.then((keys) => Promise.all(keys.filter((key) => key !== CACHE_NAME).map((key) => caches.delete(key))))
|
|
22
|
+
.then(() => self.clients.claim()),
|
|
23
|
+
);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
self.addEventListener("fetch", (event) => {
|
|
27
|
+
const { request } = event;
|
|
28
|
+
if (request.method !== "GET") return;
|
|
29
|
+
|
|
30
|
+
const url = new URL(request.url);
|
|
31
|
+
if (url.origin !== self.location.origin || url.pathname.startsWith("/api/")) return;
|
|
32
|
+
|
|
33
|
+
if (request.mode === "navigate") {
|
|
34
|
+
event.respondWith(fetch(request).catch(() => caches.match("/index.html")));
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (!APP_SHELL.includes(url.pathname)) return;
|
|
39
|
+
event.respondWith(
|
|
40
|
+
caches.match(request).then((cached) => cached || fetch(request).then((response) => {
|
|
41
|
+
const copy = response.clone();
|
|
42
|
+
caches.open(CACHE_NAME).then((cache) => cache.put(request, copy));
|
|
43
|
+
return response;
|
|
44
|
+
})),
|
|
45
|
+
);
|
|
46
|
+
});
|