Skip to content

Latest commit

 

History

History
419 lines (346 loc) · 22.4 KB

README.md

File metadata and controls

419 lines (346 loc) · 22.4 KB

Peritus WebUI

Folder guide

Svelte browser client and its build/static assets. The Rust gateway is peritus-web; the daemon owns agent execution.

Use AGENTS.md for file-level responsibilities, child modules, parent context, and nearby implementation owners.

Local files

File Role
COMMANDS.md Document: Command and capability routing.
DAEMON-INVESTIGATION.md Document: Local daemon investigation — 2026-09-12.
README.md Human guide and operating/background notes for this folder; AGENTS.md provides the local navigation map.
SECURITY.md Document: Experimental WebUI security boundaries.
THIRD-PARTY.md Document: Frontend third-party notices.
index.html Browser HTML mount document loaded by the frontend entrypoint.
package-lock.json Locked dependency resolution for the neighboring package manifest.
package.json Node package metadata, dependencies and scripts for peritus-webui.
svelte.config.js Svelte compiler/preprocessor configuration for the browser client.
tsconfig.json TypeScript compiler and source-inclusion settings for the browser client.
vite.config.ts Vite build/dev-server configuration and API proxy routing to the Rust gateway.

Subfolders

Folder Role / next waypoint
public/ Static files copied into the browser build, including source-controlled notices and other public assets.
scripts/ Frontend inspection utility for observing the real browser interface and retaining screenshots/interaction observations.
src/ Browser UI entrypoint, application composition, and client-side modules.

A conversation-first, local browser workspace for Peritus. The Svelte client is served by the peritus-web Rust gateway; the existing Peritus daemon owns agent execution. Multiple projects and nested sessions stay in one browser tab.

Status: optional and experimental. This source-built interface is not part of the native installers and does not replace the CLI/TUI. Linux/Chromium has focused local coverage; other platforms, browsers, and assistive technologies still need qualification. Read the security boundaries before connecting projects or exposing the service through other software.

The interface uses the user-selected Nixie laboratory control-panel system: recessed displays, cathode counters, physical keys, mechanical transitions, and an optional click sound. See DESIGN.md for the visual system and COMMANDS.md for exact native/CLI capability routing.

Build and start

Prerequisites:

  • The Rust toolchain pinned in rust-toolchain.toml.
  • Node matching package.json and npm, for frontend development/build only.
  • Git and an installed, compatible peritus/peritusd for harness workflows. See source installation.

Run from the repository root:

npm --prefix webui ci
npm --prefix webui run build
cargo build -p peritus-web -p peritus-cli -p peritus-daemon -j 2
./target/debug/peritus-web --root "/absolute/path/to/project"

Open http://127.0.0.1:4173. The gateway binds only to IPv4 loopback. Stop it with Ctrl+C. No Node process or Vite server is needed to run the built UI.

For a distributable build, use cargo build --release -p peritus-web -j 2, ship the resulting binary with webui/dist, and pass --assets explicitly:

./peritus-web --assets "/path/to/webui/dist" --root "/path/to/project"

The development default for --assets points into the checkout at compile time. The static files are not embedded in the binary, and the WebUI is not yet integrated into the existing native installers. Distribute the complete asset directory, including licenses/; see third-party notices for bundled fonts and libraries.

First project setup

  1. Open the project's Set up project action or Harness console. This launches the installed peritus open <project-root> in a real PTY.
  2. Complete the existing provider/workspace setup. Provider login and workspace trust use Peritus's own interactive flows.
  3. Return to the browser and use Reconnect (/reconnect) to reload provider, workspace, and connection observations.
  4. Select Chat, Design, Plan, Review, or Build, choose role models if needed, and send a message. The status distinguishes daemon-received input from input observed as incorporated into a provider request.

Choose Design something or enter /design for a conversational design interview. Answer in your own words, choose a suggested answer, or ask to change an earlier decision. Show draft displays the saved Markdown; Revise draft prepares a change message. Closing a tab or restarting the daemon preserves the saved draft and next question. Start implementation explicitly sends the design to the existing build pipeline. Drafting itself does not change project files or execute commands.

Use Focus conversation beside the session title for a larger reading area. It hides workspace side panels and extra navigation, compacts the composer, and keeps the conversation and its controls available. Show workspace panels restores the full workspace. The choice survives a browser reload. Laptop-height windows also use a shorter header by default.

Adding a browser project does not register or trust a daemon workspace. The setup banner remains until a matching canonical root or selected repository is found in the daemon's workspace catalog. The native composer uses its own run identity; the advanced CLI console has its own visible conversation selection.

Development

Run the Rust gateway on port 4173, then, in another terminal:

npm --prefix webui run dev

Open the Vite URL at http://127.0.0.1:5173. Its /api proxy targets the gateway. Use the gateway URL to inspect the production build.

Everyday operation

  • Projects: use the project rail to switch or add project directories. Paths refer to the machine running the gateway. Each project has an X; /close-project closes the selected project too. Closing works for missing folders and retains sessions and daemon work. Reopen the same directory with Open project, or reopen a saved session from Session library.
  • Sessions: create siblings or nested children, drag a session onto another session, or use Organize session to rename/reparent with the keyboard. Cross-root nesting and cycles are rejected server-side. Arrow keys navigate session tab rows. Each tab has an X to close it, including when its project directory has been deleted. Closing preserves its conversation and work; reopen it from Session library.
  • Files: click an explorer entry to open a session-local file sub-tab. Hidden, ignored, and untracked entries are included. Load more retrieves the next 250 entries. Code, UTF-8 text, sanitized Markdown, PDFs, images, and audio have dedicated viewers. Viewing a file does not attach it to model context.
  • PDFs: open read-only in the browser's built-in PDF viewer, with its native page, zoom, search, and print controls. No PDF-rendering dependency is bundled. Open PDF in new tab and Download remain available outside the frame. Browsers without enabled inline PDF support show an explicit fallback; malformed, encrypted, or unsupported documents may require a PDF application.
  • Quick editing: text files open in View. Choose Edit for small Markdown/configuration/source tweaks; use Save (Ctrl/Cmd+S), Revert / reload, literal find/replace (Ctrl/Cmd+F), bounded undo/redo, wrapping, and line/column navigation. Tab moves focus. Drafts survive switching file/session tabs in the current page; leaving the page warns about unsaved changes. File drafts are not crash-persistent. Saves preserve UTF-8 BOM, LF/CRLF, and file permissions, and reject a changed disk revision. Mixed line endings and symbolic/hard-linked files require an external editor. This is not an IDE; no editor dependency, language server, or additional npm package is used.
  • Attach: drag an explorer file into the session, or choose Attach to next message in its file-actions menu. A saved UTF-8 snapshot is queued only for that native session; remove it before sending if unwanted. Native chat's current protocol accepts text, not image/audio payloads: 48 KiB per file, at most 16 files, and 8 KiB for the complete durable input. Oversized input is rejected, never truncated. These context limits are separate from preview size. Non-text media remain view/download-only here; the separate Workbench console has its own attachment selection. Snapshot bytes and hashes are stored beside the gateway state, with a 256 MiB aggregate cache bound.
  • Git: select Source control, then configure the repository directory if necessary. It may be an existing directory anywhere inside the project root, including one without .git. Git actions become usable once that location resolves to a working repository inside the project. Stage, unstage, inspect diffs, commit, pull, and push use actual Git. Pull is fast-forward-only. Branches provides create/switch, remote tracking, rename, and confirmed merged-branch deletion. Remotes provides add, edit fetch/push URL, rename, remove, fetch/prune, and publish with upstream tracking. No force push, forced checkout, or deletion of unmerged branches is exposed.
  • Ignore: use an explorer entry's context menu to preview a literal, root-anchored .gitignore rule. Applying it preserves existing content; already tracked files remain tracked.
  • Commands: press Ctrl/Cmd+K, click Commands, or enter /help. The mouse directory and composer slash commands call the same dispatcher.

Default shortcuts

Shortcut Action
Ctrl/Cmd+K Command directory
Ctrl/Cmd+Shift+E File explorer
Ctrl/Cmd+Shift+G Source control
Ctrl/Cmd+Alt+N New sibling session
Ctrl/Cmd+, Console configuration
Enter in the composer Send message or run command
Shift+Enter in the composer New line
Escape Close the active dialog

Slash arguments support quoted paths and text. They are parsed as argument vectors, not shell expressions; $VARIABLE, pipes, and substitutions are not expanded. Examples:

/open "/home/me/Work Projects/example"
/nest
/plan Inspect the current architecture
/git add "src/my module.ts"
/git commit -m "Explain the change"
/cli status

/git commit commits the selected ordinary repository. /commit is the separate Peritus candidate workflow, with the exact run passed to the installed CLI.

Persistent configuration

Console configuration provides visual controls and a TOML editor with import/export. Save applies validated settings; Reset to defaults restores defaults. Editing the file externally takes effect on reload or /reconnect.

Platform Configuration root State root
Linux/other Unix $XDG_CONFIG_HOME/peritus, otherwise ~/.config/peritus $XDG_STATE_HOME/peritus, otherwise ~/.local/state/peritus
macOS ~/Library/Application Support/Peritus/Config ~/Library/Application Support/Peritus/State
Windows %APPDATA%\Peritus %LOCALAPPDATA%\Peritus\State

The preferences file is <configuration-root>/webui.toml. Project/repository bindings, session organization, and original operation records are in <state-root>/webui/workspace.json. Active tabs, file tabs, modes, and unsent drafts are browser-local, under peritus:layout:v1; changing browser origin or clearing site data gives that browser a fresh presentation state. Daemon-owned conversations remain in Peritus's storage.

Example dotfile (aliases and color overrides here are optional customizations):

theme = "nixie"                 # nixie | daylight | blueprint
density = "comfortable"         # comfortable | compact
motion = true                   # OS reduced-motion preference still wins
sound = false
font_size = 14                  # positive pixels
font_family = "Barlow, sans-serif"
mono_family = "Iosevka, monospace"
explorer_width = 248            # positive pixels
controls_visible = true
explorer_visible = true
word_wrap = true
markdown_preview = true

[shortcuts]
commands = "Mod+k"
files = "Mod+Shift+e"
git = "Mod+Shift+g"
new = "Mod+Alt+n"
settings = "Mod+,"

[aliases]
branch = "/nest"
changes = "/git diff"

[tokens]
accent = "#efa466"

Mod means Ctrl or Command. Shortcut keys name dispatcher commands, with commands reserved for the directory. Alias names use lowercase letters and hyphens; values must be single-line slash commands. Alias and shortcut counts are not capped; alias recursion remains bounded. Missing top-level fields use defaults; supplied maps replace their default map. Unknown top-level fields and invalid settings are rejected. Color override roles are background, panel, display, text, muted, accent, and line, using #RGB or #RRGGBB. Custom palettes should retain readable contrast.

Barlow, Barlow Condensed, and Rajdhani are bundled locally. Other configured fonts, such as Iosevka, use the system installation or their fallback stack.

Gateway options

Option Meaning
--root PATH Initial project when the workspace state is empty; defaults to the current directory
--port N Loopback HTTP port; default 4173
--assets PATH Built static frontend directory
--config PATH WebUI TOML preferences file
--state PATH WebUI workspace/operation JSON file
--daemon-config PATH Exact generated Peritus daemon configuration; default discovers the latest native generation
--product-state DIR Peritus product-state generation directory; defaults to the native state root's product-state
--endpoint PATH Explicit daemon socket/named-pipe endpoint; otherwise derived from daemon configuration
--cli PATH Installed Peritus executable; default $PERITUS_BIN, sibling peritus, then peritus on PATH

Overriding WebUI configuration/state files does not redirect daemon discovery. For an isolated daemon, supply its daemon configuration, endpoint, and product-state directory explicitly.

Model, effort, and provider choices are saved per session in the workspace state. Provider routes are chosen before the first message and retained by the daemon. Changing models on an existing conversation uses the daemon's model-update API, so the browser and an exact-run CLI console observe the same selection. Run history can reopen interactive conversations started by either client.

Use a CLI built from this checkout: session consoles require peritus open PATH --run ID. The gateway prefers a sibling CLI; --cli and PERITUS_BIN override it.

Execution and recovery

The browser is a presentation client. Native conversations use the existing negotiated application client over the daemon's local socket. The gateway does not contain another agent, provider runner, or policy engine.

Mutations receive an original operation ID recorded before dispatch. Reusing an ID with different input is rejected; a repeated identical request returns its original outcome. On connection failure the client queries that operation instead of blindly resending. If an outcome remains uncertain, inspect the named run or repository before submitting a new action. These gateway records complement the daemon's own receipts; they cannot turn an interrupted Git or CLI process into a known successful result. Git commands keep mutation custody after an HTTP disconnect and have an explicit cancellation action. Recovery observes the original process binding; elapsed time does not authorize replay.

Explorer edits, ordinary Git actions, and retained CLI processes are explicit local-user operations under the gateway account's OS permissions. They are not agent tool calls and do not pass through the daemon's agent approval/sandbox pipeline. Daemon workspace trust gates native agent execution, not these local controls. This distinction is part of the experimental interface's security model.

Connected is not the same as ready: structured daemon readiness and local Doctor checks must confirm the workspace/provider route before sending. No provider authentication/network probe is run implicitly. A read-only or draining daemon remains visible but cannot accept new messages.

The gateway durably retains the prepared conversation, workspace, run, provider, model, mode, and exact message text before the first mutating daemon request. A message then uses the daemon-owned create, queue, and start operations. Each stage has a stable operation identity and an authoritative receipt query. After a disconnect, the recovery banner reconciles those exact stages and retransmits only an unchanged domain-idempotent command whose receipt is authoritatively absent. Unresolved effects remain held for inspection; acknowledgement clears the hold without resending or claiming success. Reconnection renews a rotated gateway token automatically.

CLI consoles retain processes while their panel is closed and can be reopened with /consoles, including after a browser reload. Titles, session bindings, exit status, and output are rediscovered from the gateway. Terminate console ends the exact selected process owner. Output is spooled to disk with saved process bindings and byte offsets, and remains inspectable after gateway restart. Ended processes release their live observers; there is no console-count gate. A reopened saved console does not claim a new live input attachment: open a new console when interactive input is unavailable. Closing a browser session tab does not cancel daemon-owned work.

File reads reject canonical paths outside the selected project, including outward symlinks. Text previews read version-bound UTF-8 byte ranges directly; directory continuations use a stable cached inventory, with explicit refresh. Downloads and browser media use raw streaming with byte-range support. Unsupported media has a download route. The gateway uses loopback host/origin checks, same-site cookies, a per-process API token, and a content security policy for the local single-user deployment.

PDF previews bypass UTF-8 decoding. A small header check gates the PDF-only inline response, which forces application/pdf and permits same-origin framing. The browser's PDF engine performs document parsing; the header check is not a malware scanner or complete format validation. Other raw files retain their sandbox policy. All routes retain authentication, canonical path confinement, nosniff, and byte-range delivery. Keep the browser updated for PDF-engine fixes.

Large text previews use bounded plain-text pages, with complete file access; they do not create a highlighted/Markdown DOM for the entire file. Editing files over 2 MiB requires a visible performance confirmation, not a reduced preview limit. Full-file editing and the text-save endpoint accept up to 50 MiB separately from the normal 4 MiB action-body limit, and journals hashes rather than file bodies.

Real behavioral work

Use the project real-testing policy with the built browser client and Rust gateway. Work against a disposable project/state directory, observe the interface before and after each action, and inspect actual files, Git state, daemon events, and recovery results. The retained campaigns and replay resources identify earlier defects and their scope. The browser map links UI state, API calls, presentation, and the native gateway.

The former frontend unit/e2e suites, webui.yml workflow, and xtask workflow checker have been retired. They are not current setup or acceptance instructions. Build/start instructions above still describe the actual interface.

Historical implementation observations

The following observations describe the original Linux/Chromium implementation campaign, not fresh evidence for this checkout. Later campaign reports are retained separately under docs/testing.

Verified locally on Linux/Chromium:

  • Gateway Rust checks, including bounded binary-safe PDF identification, canonical path/nesting constraints, exact 50 MiB preview boundaries, safe saves, real Git workflows, immutable text attachments, read-only readiness, and lost-response/restart recovery against a negotiated socket fixture with exact native targets and revisions.
  • Frontend unit and integration/browser checks covering command routing, text formats, project isolation, original operation outcomes, real Git round trips, editing/conflicts, drag/drop attachments, gateway restart, .gitignore, file tabs, drafts, configuration, and a real CLI PTY invocation. PDF checks cover readable native rendering, unsupported-browser fallback, invalid-header recovery, switching away from pending text, and delivery security.
  • Svelte/TypeScript check without errors or warnings; desktop/phone captures without page errors, horizontal overflow, or automated axe WCAG 2.0 A/AA violations.

Live model inference, provider login, every advanced workbench flow, screen readers, Firefox/Safari, and non-Linux gateway execution have not been verified in this implementation pass. The automated accessibility results do not alone establish WCAG conformance. Full native-panel parity is not claimed: advanced capabilities run in the embedded real CLI as documented in COMMANDS.md.

Code map

Start with the recursive browser waypoint; the concise roles below connect its main areas.

  • src/App.svelte, src/app.css: console composition and responsive visual system.
  • src/lib/components/: viewers, explorer, Git, models, settings, terminal, and dialogs.
  • src/lib/workspace.svelte.ts: reactive presentation state and shared dispatcher.
  • src/lib/commands/: command registry and side-effect-free slash parser.
  • src/lib/api.ts: HTTP transport and original-operation reconciliation.
  • ../crates/app/peritus-web/src/: HTTP, state, files, Git, daemon adapter, and PTY modules.
  • tests/: focused parser and integration coverage.

Add commands through the registry and dispatcher, then implement their native gateway route or an explicit CLI handoff. Keep viewing separate from context attachment, and preserve project/session/run identities across every route.