A Windows-first, Cursor-like desktop editor workbench with a drivable browser and multi-tab streaming chat, built as a Tauri v2 app with a Rust core and a SolidJS UI.
vibbi is a polished, Windows-first code-editor substrate: a Cursor-styled workbench whose Explorer, Search, editor groups, terminal, embedded browser, and AI chat are all resizable dock regions joined by draggable sashes. The core is written in Rust and rendered as a web UI through Tauri v2 and WebView2, so you get a native window whose contents are fast HTML/CSS and whose logic is safe, unwrap-free Rust.
It carries no autonomous agent. It supplies the surfaces an agent would later drive: a real editor, a real terminal, a programmatically controllable browser, and a streaming chat panel. Think of it as the workbench, ready for the robots. 🦀
- 🧩 Dockable workbench - one
dockviewgrid where every region (side bar, editor groups, bottom panel, chat) resizes and relocates; only the activity bar is fixed chrome. Layout persists and restores across restarts. - 📝 CodeMirror 6 editor - syntax highlighting across TypeScript, JavaScript, JSON, Rust, HTML, CSS, Markdown, Python, and a real plaintext fallback, with multi-tab groups, in-file search, a minimap, rainbow brackets, rulers, and snippet completion.
- 🗂️ Multi-root workspace - open many folders at once; every path is canonicalized and contained inside a permitted root before any read or write, so a path that escapes the roots is rejected, never touched.
- 🔎 ripgrep-grade search - a gitignore-aware parallel walk with literal or regex queries, case sensitivity, include/exclude globs, binary skipping, and a bounded match cap.
- 💻 Real terminal - a
portable-ptyshell (ConPTY on Windows) streaming output to the UI, with the ConPTY cursor-report handshake handled so output actually flows. - 🌐 Drivable embedded browser - a native WebView2 child webview (not an iframe) you can navigate, evaluate JS in, snapshot the DOM of, click, type into, and screenshot over the Chrome DevTools Protocol.
- 💬 Streaming AI chat - a right-docked, multi-tab chat panel, one conversation per tab, streaming replies token by token from the Anthropic Messages API and rendering sanitized Markdown live.
- 🔀 Git aware - editor gutter change bars and a source-control view backed by
libgit2. - 🎨 Cursor "Dark Anysphere" theme - a frameless window with a custom titlebar, delivered on a design-token layer with a toggleable light theme, JetBrains Mono for code, and Shiki-highlighted chat code.
- 🔐 Isolated by construction - untrusted browser webviews can invoke zero backend commands. See Safety and security.
vibbi splits into a Rust backend and a SolidJS frontend joined by a single typed IPC surface that tauri-specta generates into ui/src/bindings.ts. A committed drift test fails CI if those bindings go stale, so the Rust surface and the TypeScript client can never silently disagree.
flowchart LR
subgraph frontend [SolidJS UI in WebView2 - label main]
Shell["Dockview workbench"]
Editor["CodeMirror 6"]
Term["xterm.js terminal"]
Chat["Multi-tab chat"]
Bindings["bindings.ts - typed client"]
end
subgraph ipc [Typed IPC - tauri-specta]
Commands["commands: Result T, String"]
Events["events: fs-change, nav-state, terminal-data, chat-delta"]
end
subgraph backend [Rust core - Cargo workspace]
App["vibbi-app - Tauri binary"]
Core["vibbi-core - types + errors"]
Fs["vibbi-fs - workspace, search, persistence"]
Pty["vibbi-pty - terminal host"]
Browser["vibbi-browser - CDP logic"]
ChatCrate["vibbi-chat - Anthropic client"]
end
BrowserView["browser child webview - untrusted, no permissions"]
Shell --> Bindings --> Commands --> App
App --> Events --> Bindings
App --> Core
App --> Fs
App --> Pty
App --> Browser
App --> ChatCrate
App -.->|"CDP over COM, isolated"| BrowserView
BrowserView -.->|"reaches zero commands"| Commands
A six-member Cargo workspace under crates/, namespaced vibbi-* so it can later fold into a larger workspace as a move rather than a rewrite:
vibbi-app- the Tauri binary. Holdstauri.conf.json,build.rs, the capability manifest, and the thin command layer for the filesystem, browser, terminal, and chat.vibbi-core- shared types, settings, and the#[non_exhaustive]error enum.vibbi-fs- the workspace boundary, read/write, the file watcher, the search engine, and layout/settings/chat-model persistence.vibbi-pty- the terminal host: sessions, shell resolution, and the ConPTY handshake.vibbi-browser- GUI-free browser logic: CDP message building/parsing, address-bar resolution, and history.vibbi-chat- a network-thin Anthropic streaming client: aProvidertrait, the request builder, and the server-sent-event framer, all unit-testable in isolation.
- 🦀 Backend: Rust (edition 2021, rustc 1.77+), Tauri v2,
tokio,tauri-specta+spectafor typed bindings,git2(libgit2),portable-pty,ignore+grep+regex(ripgrep crates),notify,reqwest+futures-utilfor streaming,webview2-com+windowsfor CDP over COM. - ⚡ Frontend: SolidJS + Vite,
dockview-core, CodeMirror 6,@xterm/xterm, Shiki +streaming-markdown+markdown-it+ DOMPurify for chat,material-icon-themeand@vscode/codiconsfor icons, JetBrains Mono for code.
- Rust (stable, 1.77 or newer) with
cargo. - Node.js (18+) with
npm. - Windows with the WebView2 runtime (bundled with recent Windows; installable otherwise). vibbi is Windows-only today by design.
- The Tauri CLI:
cargo install tauri-cli(invoked ascargo tauri).
# 1. Install the frontend dependencies
npm --prefix ui install
# 2. (Optional) enable the AI chat panel by exporting your Anthropic key
setx ANTHROPIC_API_KEY "sk-ant-..." # or set it for the current shell
# 3. Launch the app (starts the Vite dev server and the Tauri window)
cargo tauri devThe chat panel resolves ANTHROPIC_API_KEY from the environment at call time. The key is never logged, persisted, or returned to the frontend. Without it, the rest of the workbench runs fine; only chat reports a missing-key error.
# Produce a release bundle (NSIS + MSI installers on Windows)
cargo tauri buildThe release profile in Cargo.toml is tuned for a shipped desktop binary: size-biased optimization (opt-level = "s"), full LTO, a single codegen unit, and stripped symbols. The bundle emits signed updater artifacts for the Tauri updater plugin.
vibbi/
├─ Cargo.toml # workspace: shared deps, release profile, lints
├─ design-vibbi.md # the full design spec and rationale
├─ cursor-parity.md # the copy-Cursor UI contract
├─ images/ # README assets
├─ crates/
│ ├─ vibbi-app/ # Tauri binary: commands, capabilities, build.rs
│ ├─ vibbi-core/ # shared types, settings, error enum
│ ├─ vibbi-fs/ # workspace, search, watcher, persistence
│ ├─ vibbi-pty/ # terminal host (ConPTY)
│ ├─ vibbi-browser/ # CDP + address + history logic
│ └─ vibbi-chat/ # Anthropic streaming client
└─ ui/ # SolidJS frontend (Vite)
└─ src/
├─ shell/ # Dockview workbench, titlebar, activity bar
├─ editor/ # CodeMirror setup, theme, git gutter
├─ explorer/ search/ # file tree and global search views
├─ terminal/ browser/ # panel content renderers
├─ chat/ # streaming, markdown hardening, follow logic
├─ scm/ services/ # git view and typed service wrappers
└─ bindings.ts # generated typed IPC client
vibbi treats the embedded browser as hostile territory and isolates it in three independent places:
- One capability, scoped to
main. The trusted UI webview is labeledmain; browser webviews are labeledbrowser:<panel_id>and belong to no capability, so they hold no permission. - Every command gated.
build.rsmints anallow-<command>permission for each command; only themaincapability grants them. A browser webview therefore reaches zero commands, not the filesystem, not the terminal, not chat. - A real Content-Security-Policy. The trusted webview loads scripts and fonts only from its own bundled origin, runs no inline script, and connects only over the Tauri IPC channel, so even the chat client's HTTPS traffic must originate in the Rust core.
On top of that: every #[tauri::command] returns Result<T, String> so no panic crosses the IPC boundary, the workspace denies unsafe_code, unwrap, and expect (the single COM module is the one audited exception), and model-authored chat text becomes DOM through one hardened, incremental Markdown boundary with a DOMPurify finalize check.
- Language intelligence (deferred). A CodeMirror LSP client talking to language servers (rust-analyzer, typescript-language-server) over stdio for real completion, diagnostics, and hover is planned but not yet built. Today's autocomplete is keyword-and-document-word scaffolding. Adding the LSP client is additive: a new crate, new commands/events on the existing typed surface, and a CodeMirror client extension.
Licensed under either of
- MIT license
- Apache License, Version 2.0
at your option.
