Feat/dev 112 desktop tauri shell#8
Merged
Merged
Conversation
The post-onboarding home is a simple chatbot; the canvas demotes to a side activity panel. Builds on the shipped orchestration + live-trace backbone (consumed, not modified). specs/chatbot-home.md (#9 + #4). Storage (migration 007_chat_home): chat_sessions, chat_turns, pipeline_templates + a turns index, plus 6 synchronous Store methods (createSession, appendTurn, listSessions, listTurns, getTemplate, upsertTemplate). chat_turns.run_id links an assistant turn to the run that produced it (transcript bubble == activity-tree root). Router pipeline (packages/pipelines/router/): a chat message is a manual scheduler.run("router", {params}) (the EXISTING run path — no new execution). The handler classifies via ctx.complete to one label, maps it through a FIXED ALLOWLIST to a registered handler id, and ctx.spawns it; an unmapped/free-form label produces a clarify turn (no spawn, no dynamic handler id, preserving no-eval). The router merges the target's editable template default_params UNDER the user message, so an edited template configures its runs. Routes + WS: POST /api/chat, GET /api/chat/sessions, GET /api/chat/sessions/:id/turns, GET /api/pipelines, GET|PUT /api/pipelines/:id/template; a chat:<sessionId> WS topic next to the backbone's agent:<runId> (one socket, UUID-guarded). Client: transcript home + demoted activity panel (reuses the runTree render) + a templates screen; prefers-reduced-motion + WCAG-AA honored. Security: a minimal out-of-band approval-token module (vesper-core/src/approval/, CSPRNG single-use) gates PUT /template; POST /api/approval/request mints a code and prints it to the daemon TTY (out-of-band — never in the HTTP response, so a local app can mint but not read it). POST /api/chat is isLocalRequest-only (deliberate parity with the existing run route). No provider SDK. 724 tests / 0 fail; Biome clean; no new tsc errors. No Linear issue (workspace issue-capped) — cycle-log.md + this commit are the record (Rule 11 fallback).
…ices 1-2) Add packages/vesper-desktop — a thin Tauri 2 native window over the existing Bun-hosted Vesper World UI. The host runtime stays Bun; the Rust core holds no business logic. This is the consumer surface (double-click app); the vesper CLI remains the developer surface. Slice 1 — scaffold the Tauri app: window config + entrypoint, generated icons, Rust build verified. Slice 2 — sidecar auto-start: - vesper-ui: startUiServer gains an optional clientAssets dep + a process-wide setEmbeddedClientAssets() fallback + an exported buildClientAssets(). The on-disk read + Bun.build stays as the fallback, so `vesper daemon run` from source is unchanged. - vesper-cli/compiled-entry.ts: embeds the prebuilt client (index.html + app.js) via an import attribute so a `bun build --compile` daemon serves the UI without client source files or a runtime bundler. - scripts/build-daemon.ts (root build:daemon): builds the client assets, then compiles the daemon to src-tauri/binaries/vesper-daemon-<triple>. - Rust core (tauri-plugin-shell): spawns the sidecar, health-waits on 127.0.0.1:4317, opens the window onto it, and stops the sidecar on exit. attach-if-already-running is free via the daemon's single-instance guard. Verified: the compiled daemon serves the full UI headlessly (GET / 200, /app.js, /api/world); cargo build clean; vesper-ui + vesper-cli suites green; biome clean on the changed files. Adds the Rust/cargo toolchain to the repo, scoped to the desktop package; the Hard-rule-14 contract amendment lands with a later slice. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rebuild the Vesper desktop UI as an OpenClaw-style native companion and rebuild "Vesper World" from scratch. Replaces the floating-pill nav over a pixel-art canvas with a real app shell; dark glass is now the default theme (light/hearth opt-in). Shell - Custom draggable titlebar: Cmd+E command search + live status pills (/api/status). - Grouped sidebar + client-side SectionRouter; chrome-only theme system that replaces the canvas-coupled WorldTheme. - 14 sections: Chat, Runtime, Helper CLIs, Permissions, Sandbox, Settings, Diagnostics, About (live data); Pipelines/Channels/Schedule (thin views); Skills/Memory/Voice (honest stubs naming their owning specs). Vesper World rebuild - Chat scoped to "only Vesper": a transcript + a Vesper-only activity rail that follows the conversation's run tree (existing /api/chat + run-trace APIs, no backend rewrite; subscribe-before-backfill + de-dupe preserved). - Machine-wide agent presence moves off the home into Diagnostics. - Retires the pixel-art renderer (sprite/render/world/themes/brand) via controlled git rm (recoverable). Net -890 lines tracked in vesper-ui. Server - New read-only /api/status, /api/presence, /api/runs; /api/world + snapshot removed. Native - macOS overlay titlebar (TitleBarStyle::Overlay + hidden_title, cfg-gated) so the custom titlebar shows with the traffic lights inset; tray + single-instance shell. Specs: specs/desktop-app-shell.md + specs/vesper-world-rebuild.md (Omar-authorized; Linear issue-capped, recorded in cycle-log.md). biome ci clean; vesper-ui 46 / vesper-cli 104 pass; compiled sidecar verified serving the new shell. No provider SDKs.
Left-clicking the Vesper menu-bar icon now toggles a compact dark-glass popover anchored under the icon; clicking away dismisses it. Right-click keeps the existing Show/Quit menu. - Web: panel.ts renders a quick-glance view (daemon status, default CLI, run/chat counts, recent runs, Open Vesper + Quit) at /?panel=1; main.ts branches panel-mode vs the full shell (bootShell). - Native: a hidden borderless always-on-top "panel" window; tray left-click toggles + positions it under the icon (clamped to the monitor work-area); focus-loss hide; open_main / quit_app commands over the Tauri bridge (withGlobalTauri). One UI, two modes (no second front-end); the native actions hide in a plain browser. cargo build clean; biome ci clean; vesper-ui 46 tests pass; compiled sidecar serves /?panel=1. Spec: specs/menubar-app.md.
…listed fetch Add the connections layer (vesper-core/src/connections): a curated, code-reviewed catalog of messaging channels and MCP servers that a pipeline opts into by id, with all egress gated by a deny-by-default host allowlist and every action audited. - catalog: CHANNEL_CATALOG (Telegram + Discord ready; WhatsApp + Signal deferred) and MCP_CATALOG (10 seed servers). The user selects an id, never an arbitrary host; each entry declares allowedHosts + vaultKeys (key names only, never values). - fetch: allowlistedFetch asserts NETWORK_FETCH and refuses any host a descriptor did not declare — Vesper only ever reaches the first-party hosts a catalog entry names, never an LLM provider. - telegram: TelegramHandler long-poll receive loop yields to the event loop each iteration (setTimeout 0) so a cooperative stop() and timers fire — fixes a microtask-starvation hang. - registry + audit (recordConnectionEvent + stripSensitive redaction) + typed ConnectionError + the channel/MCP types. - index: export the connections public surface. bun test: 30 pass (connections). biome ci clean. No provider SDK.
ogarciarevett
added a commit
that referenced
this pull request
Jun 4, 2026
Reconciles the local chatbot-home + editable-pipeline-templates work (dfd01bd) with the desktop dark-glass Tauri shell rebuild merged on origin/main (3a49a16, PR #8). The shared chatbot backend (approval tokens, storage migration 007, pipelines/router handler) is identical on both sides and auto-merged cleanly; only the UI surface and the cycle log diverged. Conflict resolution (4 files): - client/main.ts, client/index.html: took the PR #8 new-shell versions. The old canvas-world + bolted-on chat home is SUPERSEDED by the shell's sections/chat.ts (full chat home over the same /api/chat + chat:<sessionId> socket) and sections/pipelines.ts (template view) + sections/activity-rail.ts ("watch it work"). No chat/template feature is lost. - server/server.ts: kept PR #8's additive clientAssets field (compiled-daemon asset injection) alongside the shared approvalTokens field. - cycle-log.md: kept both the chatbot-home and the desktop-shell-redesign entries. Removed the now-orphaned old-architecture client files (superseded; templates.ts imported the deleted brand/index.ts): client/chat.ts, client/templates.ts. Kept client/chat-types.ts (imported by the new sections) and client/theme-store.ts (imported by shell/themes.ts). Verified: Biome clean (2 known cosmetic warnings); 733 tests / 0 fail; tsc shows 31 pre-existing errors, all byte-identical to origin/main (zero introduced by this merge — CI gate is biome + bun test). No provider SDKs.
ogarciarevett
added a commit
that referenced
this pull request
Jun 5, 2026
… Diagnostics The "Vesper World" rebuild (specs/vesper-world-rebuild.md) already shipped via the dark-glass shell (PR #8). This finishes the spec's leftover (task #4): gate the presence poll server-side and retire the dead /api/world. - /api/presence now detects on demand (only consumer is the Diagnostics section, fetched on mount), bounded by a presencePollMs cache TTL. Removes the always-on 3s background poll and its dead {type:"presence"} WS frame. - The /api/world SceneGraph route was already gone; fixed stale doc-comments. - Drop the now-orphaned presenceSignature (its only consumer was the poll). - The world WS topic stays (run:completed + run:event:lite feed the activity rail); the presence detector + Diagnostics view are unchanged. 917 tests / 0 fail (+1 cache test); Biome clean; no new tsc errors.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The Desktop phase (DEV-112): Vesper becomes a real native desktop app. This PR delivers the native
Tauri shell over the Bun daemon, a from-scratch premium dark-glass UI (replacing the pixel-art "Vesper
World"), a macOS menu-bar popover, the connections layer (messaging channels + MCP), and refreshed
docs/screenshots.
108 files changed, +9,697 / −3,605.What's in it
Native desktop shell — Tauri 2 (
39eaf65, extended in43c5db4/ea8453e)bun build --compile): spawn → health-wait on theUI port → open the window → clean shutdown; attach-if-already-running via the single-instance guard.
instance. Rust holds no business logic; the daemon serves the full UI on
127.0.0.1.specs/tauri-migration.md. Amends Hard rule 14 (Tauri now in-tree, scoped to the shell);the Bun host is unchanged.
Dark-glass desktop shell + "Vesper World" rebuild (
43c5db4)@vesper/uiis now an app shell: a custom draggable titlebar (Cmd+E command search + live statuspills off
/api/status), a grouped sidebar, a client-sideSectionRouter, and a chrome-only themesystem (dark default; light/hearth opt-in) that replaces the canvas-coupled
WorldTheme.(live data) + Pipelines / Channels / Schedule (thin views) + Skills / Memory / Voice (honest stubs).
conversation's run tree via the existing
/api/chat+ run-trace APIs (no backend rewrite;subscribe-before-backfill + de-dupe preserved). The machine-wide agent presence moved off the home into
Diagnostics.
git rm(recoverable). New read-only routes
/api/status,/api/presence,/api/runs;/api/worldremoved.Net −890 lines in vesper-ui.
specs/desktop-app-shell.md+specs/vesper-world-rebuild.md.macOS menu-bar popover (
ea8453e)recent activity, Open Vesper + Quit) anchored under the icon; click-away dismiss. Right-click
keeps the existing Show/Quit menu.
/?panel=1; native actions over the Tauri bridge(
withGlobalTauri). Design record:specs/menubar-app.md.Connections layer (
da2b566)vesper-core/src/connections: a curated, code-reviewed channel + MCP catalog (Telegram + Discordready; WhatsApp + Signal deferred; 10 MCP servers), opted into by id — never an arbitrary host.
allowlistedFetchassertsNETWORK_FETCHand refuses anyhost a descriptor did not declare — first-party hosts only, never an LLM provider).
microtask-starvation hang); registry + audit (with sensitive-value redaction) + typed errors.
Docs (
e2151d3)presenceconfig now points at the Diagnostics section.Verification
biome ciclean.bun test(scoped): vesper-ui 46, vesper-cli 104, connections 30 — all pass.cargo build(desktop shell) clean; the compiled daemon sidecar verified serving the new UI end-to-end.Test plan
cd packages/vesper-desktop && bun run dev→ native window opens on the dark-glass app; sidebar nav,Cmd+E search, theme switch, chat → activity rail streams live.
vesper daemon start+ openhttp://127.0.0.1:4317→ identical UI in the browser.loop does not spin the CPU.
Notes
specs/+cycle-log.md(Rule 11 fallback) — reconcile toDEV-112 when the cap lifts.
panel.tsCSS).da2b566(formatting normalized so CIis green).