Add a dedicated "sending" activity indicator kind (warning color) so a
session uploading attachments is visually distinct from server activity.
Server activity propagates up to workspace/machine rows; client-side
sending does not, and the different color signals that to users.
Also extract sessionRowActivityKind as a pure, exported helper so the
"sending takes precedence, archived/cached-new never show" logic is unit
tested without rendering.
isSendingPrompt was a single global flag, so an in-flight upload showed
the "Sending…" dock on whatever session/machine the user switched to.
Replace it with sendingPrompts, a Record<sessionId, true> keyed like
sessionStatuses/sessionActivities. The controller sets/clears the entry
for the originating session (captured before the await), the chat dock
reads only the selected session's entry, and the session list now shows
the activity dot for a session that is uploading so progress is visible
after switching away. Machine switches clear the record like other
per-session state; deselecting a session no longer cancels its indicator.
The paste/drop/file capture logic (supported-type filtering, unnamed-file
extension fallback, per-file error collection) lived inside PromptEditor,
mixing browser side effects with branching that had no tests.
Move it into a pure promptAttachmentCapture module with the byte reader
injected, so the FileReader side effect stays at the component boundary
and the orchestration is unit-tested. Also removes a duplicated mime->ext
fallback in favour of the shared extensionForImageMimeType helper.
Replace the composer-local "Sending…" indicator with a single, consistent
state surfaced by the existing chat activity dock. The session controller
now owns the full attachment send lifecycle (including the folder-mode
upload + reference rewrite) and toggles an isSendingPrompt flag around it,
which the chat dock renders as "Sending your message…" until the real
server activity supersedes it.
This covers the pre-receipt dead zone (upload, server-side image resize,
first-session open) with one indicator instead of two, and keeps plain
text sends fire-and-forget.
Messages with image attachments could take a moment to appear (large
base64 upload, server-side resize, first-session open) while the composer
cleared instantly, making it look like nothing happened.
Await the send for attachment messages and surface a "Sending…" button
label plus a "Sending your files…" / "Saving your files…" hint, disabling
the composer until the message lands. Plain text messages stay
fire-and-forget so the input frees up instantly.
Support pasting (Ctrl/Cmd+V), drag-and-drop, and an Attach button to add
PNG/JPEG/GIF/WebP images to a message, with thumbnail previews and
multi-image support.
Attachments are delivered to the session using pi's native ImageContent
format and are run through pi's own resizeImage so they match pi's inline
image limits exactly. Image content now renders inline in the transcript.
A per-message delivery toggle also lets users save attachments into the
workspace `.pi-web/paste` folder and reference them so the agent reads
them with its own tools.
The accepted HTTP upload size is configurable via PI_WEB_MAX_UPLOAD_BYTES
or the maxUploadBytes config value (default 64 MB).
Closes#13
Run Linux restart commands inside a detached transient systemd user
service (systemd-run --user) so the restart survives the launching
terminal being killed and its logs can be inspected via journalctl.
Make the Updates panel actionable: every command has Copy and Run,
a single recommended all-in-one command is shown at the top, and the
rest are grouped as optional additional commands.
Drive-qualify resolved paths in fixtures and assert against normalized cwds
so route tests match the values normalizeRequestCwd produces. Skip the
POSIX-shell TerminalService suite on native Windows, where the terminal
feature is unsupported.
Sessions outside the server's launch directory were invisible and returned
404 on open, leaving the model picker empty. List without the SDK's
process-cwd filter and normalize working directories at the API boundary and
when reading stored session data, tolerating separator/normalization
differences (including Windows backslash vs forward slash). Requires Pi
coding agent SDK 0.78.0 or newer.
Running the suggested restart command from a PI WEB terminal kills the
command when sessiond restarts, so services listed after sessiond were
never restarted. Restart web/UI first in both the updates plugin's
suggested command and `pi-web restart` (systemd and launchd).
Use viewport-constrained positioning for sidebar action menus and keep the auth warning test isolated from local models.json config so pre-commit verification is deterministic.