@narumitw/pi-webui 0.21.0 โ 0.25.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/README.md +59 -27
- package/package.json +3 -1
- package/src/attachments.ts +715 -0
- package/src/conversation.ts +23 -6
- package/src/drafts.ts +226 -0
- package/src/image-limits.ts +36 -0
- package/src/image-pipeline.ts +325 -0
- package/src/images.ts +182 -140
- package/src/pi-settings.ts +11 -6
- package/src/runtime.ts +138 -34
- package/src/sent-images.ts +279 -0
- package/src/server.ts +490 -30
- package/src/settings.ts +102 -7
- package/src/vendor.d.ts +30 -0
- package/src/web/app.js +558 -100
- package/src/web/image-drag.js +86 -0
- package/src/web/index.html +25 -2
- package/src/web/state.js +178 -8
- package/src/web/styles.css +176 -11
- package/src/web/transcript.js +66 -9
package/README.md
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
# ๐ pi-webui โ Current-session Web Companion for Pi
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/@narumitw/pi-webui) [](./LICENSE)
|
|
3
|
+
[](https://www.npmjs.com/package/@narumitw/pi-webui) [](https://pi.dev) [](./LICENSE)
|
|
4
4
|
|
|
5
5
|
`@narumitw/pi-webui` adds a private, lightweight browser companion to the current terminal-owned [Pi Coding Agent](https://pi.dev) session. It displays Pi's semantic conversation and tool activity as they happen and can send text or sanitized images back into that same session.
|
|
6
6
|
|
|
7
7
|
This package is intentionally different from the broader, separately maintained `@narumitw/pi-web` application. WebUI has one current-session chat page and no session manager, shell, file browser, git UI, control room, or task board.
|
|
8
8
|
|
|
9
|
-
## Features
|
|
9
|
+
## โจ Features
|
|
10
10
|
|
|
11
11
|
- Streams current-branch user and assistant messages, assistant text updates, tool activity/results, errors, and busy/idle state over Server-Sent Events.
|
|
12
12
|
- Renders a safe Markdown subset for headings, lists, emphasis, code, blockquotes, and HTTP(S) links without executing model-provided HTML.
|
|
13
13
|
- Preserves open tool/thinking disclosures during keyed streaming updates and offers **Jump to latest** when new activity arrives while you read earlier messages.
|
|
14
14
|
- Sends immediately while Pi is idle and automatically queues **Queue next** as a follow-up while Pi is busy.
|
|
15
15
|
- Provides a separate **Steer** action while Pi is working; steering is never the default submit action.
|
|
16
|
-
- Accepts pasted, dropped, or selected PNG, JPEG, WebP, and
|
|
16
|
+
- Accepts pasted, dropped, or selected PNG, JPEG, WebP, GIF, BMP, TIFF, HEIC/HEIF, and AVIF images, strips metadata server-side, applies Pi-compatible size limits, and provides ordered thumbnails plus an enlarged preview.
|
|
17
17
|
- Reconnects from an ordered event cursor and replaces state from an authoritative snapshot after a gap.
|
|
18
18
|
- Keeps a failed browser draft and prevents rapid duplicate submission with request IDs.
|
|
19
19
|
- Uses no frontend framework, build step, browser storage, remote service, or automatically launched browser.
|
|
20
20
|
|
|
21
|
-
## Install
|
|
21
|
+
## ๐ฆ Install
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
24
|
pi install npm:@narumitw/pi-webui
|
|
@@ -34,7 +34,7 @@ just try webui
|
|
|
34
34
|
|
|
35
35
|
The package targets the latest Pi release.
|
|
36
36
|
|
|
37
|
-
## Usage
|
|
37
|
+
## ๐ Usage
|
|
38
38
|
|
|
39
39
|
1. Start Pi in a terminal and run `/webui`.
|
|
40
40
|
2. Open the one-time `http://127.0.0.1:<port>/bootstrap?...` link shown by Pi. The extension does not open a browser itself.
|
|
@@ -44,7 +44,7 @@ The package targets the latest Pi release.
|
|
|
44
44
|
|
|
45
45
|
If another installed extension also registers `/webui`, Pi assigns numeric command suffixes according to extension load order. Check Pi's command provenance and invoke the WebUI entry.
|
|
46
46
|
|
|
47
|
-
## Commands
|
|
47
|
+
## ๐ฌ Commands
|
|
48
48
|
|
|
49
49
|
| Command | Behavior |
|
|
50
50
|
| --- | --- |
|
|
@@ -56,7 +56,7 @@ If another installed extension also registers `/webui`, Pi assigns numeric comma
|
|
|
56
56
|
|
|
57
57
|
Argument completion is available for all subcommands. Bare `/webui` remains the direct browser-link action.
|
|
58
58
|
|
|
59
|
-
## Settings
|
|
59
|
+
## โ๏ธ Settings
|
|
60
60
|
|
|
61
61
|
WebUI has one optional, **global-only** JSON settings file:
|
|
62
62
|
|
|
@@ -68,77 +68,109 @@ The normal default path is `~/.pi/agent/pi-webui.json`. Pi installations that us
|
|
|
68
68
|
|
|
69
69
|
```json
|
|
70
70
|
{
|
|
71
|
-
"startOnSessionStart": false
|
|
71
|
+
"startOnSessionStart": false,
|
|
72
|
+
"retainSentImages": false,
|
|
73
|
+
"maxRetainedImages": 32,
|
|
74
|
+
"maxRetainedBytes": 134217728,
|
|
75
|
+
"maxImages": 8,
|
|
76
|
+
"maxImageBytes": 10485760,
|
|
77
|
+
"maxBatchBytes": 41943040,
|
|
78
|
+
"maxImagePixels": 50000000
|
|
72
79
|
}
|
|
73
80
|
```
|
|
74
81
|
|
|
75
82
|
| Setting | Default | Behavior |
|
|
76
83
|
| --- | --- | --- |
|
|
77
84
|
| `startOnSessionStart` | `false` | Start WebUI and display a fresh one-time link after every Pi session initialization, including startup, reload, new, resume, and fork. It never opens a browser. |
|
|
85
|
+
| `retainSentImages` | `false` | Opt in to bounded, session-only retention of sanitized images after Pi accepts their browser message. |
|
|
86
|
+
| `maxRetainedImages` | `32` | FIFO retained-image count ceiling. Positive integers up to the hard ceiling of 128 are accepted. |
|
|
87
|
+
| `maxRetainedBytes` | `134217728` (128 MiB) | FIFO retained provider-ready byte ceiling. Positive integers up to the hard ceiling of 536870912 (512 MiB) are accepted. |
|
|
88
|
+
| `maxImages` | `8` | Images in one active draft; hard ceiling 32. |
|
|
89
|
+
| `maxImageBytes` | `10485760` (10 MiB) | Source bytes per image; hard ceiling 52428800 (50 MiB). Must not exceed `maxBatchBytes`. |
|
|
90
|
+
| `maxBatchBytes` | `41943040` (40 MiB) | Combined source/processed draft bytes; hard ceiling 209715200 (200 MiB). |
|
|
91
|
+
| `maxImagePixels` | `50000000` | Decoded pixels per image; hard ceiling 100000000. Animated-image frame area participates in this limit. |
|
|
78
92
|
|
|
79
|
-
A missing file uses defaults. The file must contain a top-level JSON object
|
|
93
|
+
A missing file uses defaults. The file must contain a top-level JSON object; recognized booleans and positive integer limits must have the documented types and remain within their hard ceilings. Malformed JSON or an invalid recognized value causes the file to be ignored with a warning and leaves it untouched. Unknown fields are accepted and preserved by the settings screen for forward compatibility. The settings screen exposes only the frequent startup toggle; there is not yet user-testing evidence that `maxImages` is adjusted often enough to justify another routine row. Retention and image-limit fields remain in Advanced JSON at the reported path.
|
|
94
|
+
|
|
95
|
+
### Advanced image limits
|
|
96
|
+
|
|
97
|
+
Omitting all four image-limit fields exactly reproduces the original 8 image / 10 MiB per image / 40 MiB batch / 50 megapixel behavior. Values are byte counts, not Base64 character counts. Raising any image limit above its safe default emits one concise session-start warning and can materially increase Pi-process memory, decoder work, and denial-of-service exposure; use the smallest value that solves the current workflow. Any non-integer, non-positive, above-ceiling, or cross-field-invalid recognized value rejects the whole file and safely restores all defaults without rewriting it. `/webui status` reports the effective limits and whether they came from defaults or the settings file.
|
|
80
98
|
|
|
81
99
|
Settings are reloaded on every `session_start`. Changes made in `/webui settings` are saved atomically and update the in-memory preference immediately, but they intentionally do not start or stop the server in the current session; they take effect at the next session initialization or `/reload`. `/webui init` creates formatted defaults once and refuses to overwrite valid or invalid existing content.
|
|
82
100
|
|
|
83
101
|
In print, JSON, and RPC modes, `/webui settings` does not open custom TUI or write protocol-breaking output. Use `/webui status`, `/webui help`, or edit the reported path manually.
|
|
84
102
|
|
|
85
|
-
## What synchronization means
|
|
103
|
+
## ๐ What synchronization means
|
|
86
104
|
|
|
87
105
|
WebUI mirrors Pi's semantic session events, not terminal pixels. It displays conversation content, streaming assistant state, tool calls/results, errors, and activity using browser-native presentation. It does not reproduce ANSI colors, terminal wrapping, footer/widgets, built-in dialogs, arbitrary custom TUI components, or unsent terminal editor text.
|
|
88
106
|
|
|
89
|
-
The initial transcript comes from the active session branch.
|
|
107
|
+
The initial transcript comes from the active session branch. Unsent browser message text and ordered attachment references are authoritative in the live Pi process, so refresh, reconnect, and active-tab takeover restore the same draft without creating a second transcript or altering Pi's session tree. Text edits are revisioned and saved with bounded, deduplicated mutations; stale or delayed responses cannot overwrite newer typing.
|
|
90
108
|
|
|
91
|
-
## Images
|
|
109
|
+
## ๐ผ๏ธ Images
|
|
92
110
|
|
|
93
111
|
| Input | Provider-ready output |
|
|
94
112
|
| --- | --- |
|
|
95
113
|
| PNG | PNG |
|
|
96
114
|
| JPEG | JPEG |
|
|
97
115
|
| WebP | WebP |
|
|
98
|
-
| GIF | GIF |
|
|
116
|
+
| GIF, including animation | GIF |
|
|
117
|
+
| BMP | PNG |
|
|
118
|
+
| TIFF | PNG |
|
|
119
|
+
| HEIC/HEIF | PNG |
|
|
120
|
+
| AVIF | PNG |
|
|
121
|
+
|
|
122
|
+
The server checks file signatures instead of trusting browser MIME types or filename extensions. It rejects corrupt/unknown formats and applies the effective `maxImages`, `maxImageBytes`, `maxBatchBytes`, and `maxImagePixels` settings at browser admission, streamed upload, processing, draft accounting, send preflight, and Attach again. Pi's approximately 4.5 MB inline Base64 constraint and 2,000-pixel provider-ready dimension constraint remain fixed and cannot be raised in WebUI settings. Images over 2,000 pixels on either side are resized when Pi's `images.autoResize` setting is enabled and rejected when it is disabled.
|
|
123
|
+
|
|
124
|
+
Choosing, pasting, or dropping images first reserves an ordered server-side batch, uploads each source as a bounded raw request, and processes it before Send becomes available. Each thumbnail reports Uploading, Processing, Ready, or Needs attention; upload progress is shown when the browser reports a byte total. A failed item can be retried without reselecting successful siblings, and every item can be removed independently. Refreshing the active tab restores the authoritative staged batch, while another tab taking the editing lease cancels in-flight work safely.
|
|
125
|
+
|
|
126
|
+
When a draft has two or more images, each card shows its order and can be dragged into place; keyboard users can focus a card and press `Alt+โ` or `Alt+โ`. A single image omits meaningless ordering interaction. Remove images individually with each card's trash button, or use the confirmed **Clear attachments** action when a draft contains several images. The collection summary shows the attached count against the effective maximum and states the metadata-removal guarantee once, while each card keeps its own upload/processing/ready/error state and any conversion or resize summary. Processing applies image orientation, re-encodes provider-ready output, strips EXIF and other private metadata, preserves ICC color profiles and animated GIF timing where supported, and releases each source after successful sanitation. Failed processing retains only that bounded source for Retry; Ready provider bytes remain in the Pi process until accepted send, removal, clear, lease/session teardown, or failed-send retry. Image bytes are never embedded in the message JSON protocol.
|
|
99
127
|
|
|
100
|
-
|
|
128
|
+
Pi's effective global and trusted-project `images.autoResize` and `images.blockImages` settings plus the current model's image capability and authentication are checked again at send time. A failed send leaves the exact Ready batch available for an idempotent retry. BMP and HEIC use bounded portable decoders because the prebuilt `sharp`/libvips distribution does not decode those inputs consistently across supported platforms.
|
|
101
129
|
|
|
102
|
-
|
|
130
|
+
When `retainSentImages` is enabled, only provider-ready sanitized bytes transfer into a separate session-memory store after Pi accepts the matching browser message. Content-identical sanitized images share one opaque session reference. Oldest entries are evicted first when either retention ceiling is exceeded. WebUI also reconciles retained, current-draft, and conservative in-flight processing bytes against one aggregate resident-image budget (the larger of the configured retention byte ceiling and the staging store's maximum working set), evicting sent entries before that aggregate can grow. Eligible transcript image chips offer **Attach again** and **Forget**; evicted or forgotten references read **Expired**, and terminal-origin images never gain those actions. Attach again clones the retained bytes into the current authoritative draft, reuses normal count/byte admission, and never mutates the earlier message. Refresh and active-tab takeover recover eligibility from Pi-process state; session replacement, reload, shutdown, or process exit releases all retained bytes.
|
|
103
131
|
|
|
104
|
-
## Security and privacy
|
|
132
|
+
## ๐ Security and privacy
|
|
105
133
|
|
|
106
134
|
- The server binds only to a random `127.0.0.1` port and is owned by one live Pi session.
|
|
107
135
|
- A rotating bootstrap token is exchanged once for a per-server HttpOnly, `SameSite=Strict` cookie and removed from the URL.
|
|
108
136
|
- Every endpoint requires the cookie. Mutations also require exact Host and Origin values plus the active browser-tab lease.
|
|
109
137
|
- Responses use no-store, no-referrer, MIME-sniffing, frame-denial, same-origin resource, and restrictive Content Security Policy headers.
|
|
110
|
-
- Transcript projection retains at most the newest 500 messages and 500 tool records, event replay keeps 256 updates, and request-id records keep 128 sends.
|
|
138
|
+
- Transcript projection retains at most the newest 500 messages and 500 tool records, event replay keeps 256 updates, and request-id records keep 128 sends. Unsent message text, ordered attachment references, staged image bytes, and opt-in sanitized sent-image bytes live only in bounded Pi-process memory under their documented lifecycles; the page uses no localStorage, sessionStorage, IndexedDB, script-readable cookies, or image/transcript cache.
|
|
111
139
|
- Tool arguments/results, paths, images, and model thinking can be sensitive. Thinking is collapsed by default; only open a link issued by a Pi process you trust.
|
|
112
140
|
- Reload, session replacement/fork, or Pi shutdown closes sockets, invalidates old callbacks, ends the page, and releases in-memory state.
|
|
113
141
|
|
|
114
142
|
A loopback page is local to the operating-system network namespace. WebUI does not support LAN/public binding or a cloud relay. For SSH, containers, or devcontainers, forward the exact printed port and preserve the `127.0.0.1:<port>` Host value.
|
|
115
143
|
|
|
116
|
-
## Accessibility and browsers
|
|
144
|
+
## โฟ Accessibility and browsers
|
|
117
145
|
|
|
118
|
-
The page uses semantic headings, native disclosure/dialog controls, concise status/alert live regions,
|
|
146
|
+
The page uses semantic headings, native disclosure/dialog controls, concise status/alert live regions, accessible labels, visible keyboard focus, at least 44 px controls, keyboard image preview/removal/reordering, `Ctrl/Command+Enter` submission, reduced-motion handling, dark mode, and responsive reflow. It targets current stable desktop Chrome, Edge, Firefox, and Safari.
|
|
119
147
|
|
|
120
|
-
## Limitations
|
|
148
|
+
## ๐ง Limitations
|
|
121
149
|
|
|
122
150
|
- One active Pi session and one active browser editing tab only.
|
|
123
|
-
- No persistent browser transcript, sent-image history, remote access, PTY/terminal control, model/settings controls, or session switching.
|
|
124
|
-
- No SVG,
|
|
151
|
+
- No persistent browser transcript, permanent sent-image gallery, cross-session image history, remote access, PTY/terminal control, model/settings controls, or session switching.
|
|
152
|
+
- No SVG, remote image URL, OCR, annotation, or directory upload support.
|
|
125
153
|
- Browser acknowledgment means Pi accepted or queued the message. Provider failures follow Pi's normal session/retry behavior.
|
|
126
154
|
- Built-in TUI commands and dialogs are not reimplemented in the browser.
|
|
127
155
|
|
|
128
|
-
## Package layout
|
|
156
|
+
## ๐๏ธ Package layout
|
|
129
157
|
|
|
130
158
|
```text
|
|
131
159
|
src/webui.ts Pi extension entrypoint
|
|
132
160
|
src/runtime.ts Pi lifecycle, commands, event projection, and browser message routing
|
|
133
161
|
src/settings.ts global WebUI settings validation and atomic persistence
|
|
134
162
|
src/conversation.ts bounded transcript snapshot and ordered event replay
|
|
135
|
-
src/
|
|
163
|
+
src/drafts.ts authoritative in-memory text and attachment-reference revisions
|
|
164
|
+
src/attachments.ts revisioned staged-image state, processing queue, and byte ownership
|
|
165
|
+
src/sent-images.ts opt-in bounded sanitized sent-image retention
|
|
166
|
+
src/server.ts authenticated loopback HTTP/SSE server and raw attachment protocol
|
|
167
|
+
src/image-limits.ts shared configurable defaults, ceilings, and provider constraints
|
|
136
168
|
src/images.ts bounded provider-ready image processing
|
|
137
169
|
src/pi-settings.ts effective Pi image settings reader
|
|
138
170
|
src/web/ framework-free browser page
|
|
139
171
|
```
|
|
140
172
|
|
|
141
|
-
## Development
|
|
173
|
+
## ๐งช Development
|
|
142
174
|
|
|
143
175
|
From the repository root:
|
|
144
176
|
|
|
@@ -151,10 +183,10 @@ just pack webui
|
|
|
151
183
|
|
|
152
184
|
The package preview must contain its manifest, license, README, TypeScript source, and static web assets, but no tests, fixtures, cache, or `node_modules`.
|
|
153
185
|
|
|
154
|
-
## Keywords
|
|
186
|
+
## ๐ Keywords
|
|
155
187
|
|
|
156
188
|
Pi extension, Pi Coding Agent, browser companion, local web chat, terminal session sync, Server-Sent Events, image prompt, tool activity, local-first AI coding agent.
|
|
157
189
|
|
|
158
|
-
## License
|
|
190
|
+
## ๐ License
|
|
159
191
|
|
|
160
192
|
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@narumitw/pi-webui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.25.0",
|
|
4
4
|
"description": "Lightweight local web companion for the current Pi terminal session.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -29,6 +29,8 @@
|
|
|
29
29
|
"typecheck": "tsc --noEmit"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
+
"bmp-js": "^0.1.0",
|
|
33
|
+
"heic-decode": "^2.1.0",
|
|
32
34
|
"sharp": "^0.35.3"
|
|
33
35
|
},
|
|
34
36
|
"peerDependencies": {
|