# aeroxy/web-bro architecture

> Architecture diagram of the GitHub repository aeroxy/web-bro, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-20). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/aeroxy/web-bro
- Repository: https://github.com/aeroxy/web-bro

## Overview

1. **System shape**
   - This is a **static, browser-only agent workspace**. There is no application backend.
   - The app runs as a Vite-built React SPA, with the heavy work split into **Web Workers** so the UI stays responsive.

2. **Primary UI shell**
   - `src/main.tsx` boots the app into `src/app/App.tsx`.
   - The visible product is composed from feature panels: **chat**, **workspace**, **log**, and **debug**.
   - Shared UI components such as the file tree, markdown rendering, thread sidebar, and capability gating are factored under `src/components`.

3. **Central orchestration boundary**
   - `src/app/store.ts` is the main coordination layer.
   - It holds application state, wires persistence, and orchestrates the agent loop across the UI, the model worker, and the workspace worker.
   - For an architecture diagram, this is the best place to draw the “brain” of the app.

4. **Model execution boundary**
   - `src/workers/llm.worker.ts` is responsible for **loading and running the Gemma 4 E2B-it ONNX model** in-browser via WebGPU.
   - It handles prompt formatting, native tool-call prompting, streamed model output, and cancellation.
   - The model artifacts are fetched from **Hugging Face** on first use and then cached locally by the browser.

5. **Workspace / filesystem boundary**
   - `src/workers/workspace.worker.ts` owns interaction with the user-selected local folder.
   - It performs directory traversal, file reads, text search, writes, and support for restoring overwritten content.
   - This worker is the bridge to the **File System Access API**, so file operations are isolated from the main UI thread.

6. **Agent tool loop**
   - The agent uses a shallow tool loop with four core actions: **`list_dir`**, **`search_text`**, **`read_file`**, and **`write_file`**.
   - The store mediates the turn sequence: user input → model reasoning/tool request → workspace worker execution → updated context → final model answer.
   - The readme note that existing files must be read before overwrite is an important behavioral constraint in this loop.

7. **Persistence model**
   - `src/lib/db.ts` and related code persist data in **IndexedDB** only.
   - Stored locally are chat threads, workspace sessions, settings, and write backups used for undo.
   - This means the app has two local state domains: the selected workspace on disk, and the app’s own durable metadata in browser storage.

8. **Undo and write safety**
   - File writes are not blind mutations: the previous file contents are snapshotted before overwrite.
   - That backup enables the one-click undo flow described in the README and supported by the workspace worker and persistence layer.
   - This is a key architectural boundary between “agent can modify files” and “user can recover prior state.”

9. **Capability and environment gating**
   - `src/components/CapabilityGate.tsx` plus `src/lib/capabilities.ts` guard features that depend on browser support.
   - The product is explicitly **Chromium-first**, requiring a secure context, WebGPU, and the File System Access API.
   - This gating matters architecturally because large parts of the app are unavailable without those browser capabilities.

10. **Shared data contracts and prompt shaping**
   - `src/lib/contracts.ts`, `src/lib/chatml.ts`, and `src/lib/agent-prompt.ts` define the message shapes and prompt format passed between UI, store, and worker.
   - These files are the “schema boundary” that keeps the worker protocol, chat history, and tool-loop messaging consistent.
   - `src/lib/text.ts` and other helpers support parsing and presentation rather than core orchestration.

11. **Observability and diagnostics**
   - The `log` and `debug` feature panels provide runtime visibility into agent behavior, worker activity, and workspace state.
   - This is useful in the diagram as a non-functional side channel off the main orchestration path.

12. **Deployment and delivery**
   - The app is deployed as a **static site**, with `public/_headers` and `public/_redirects` supporting Cloudflare Pages-style hosting.
   - There is no server-side rendering or API backend; all compute is client-side, and all persistence is local to the browser/device.

13. **Testing boundaries**
   - Unit tests use mocked workers, so the normal test suite does not require the real model download.
   - Playwright end-to-end tests cover the browser flow separately.
   - This reinforces the repo’s main architectural split: pure UI/state logic vs. worker-backed runtime behavior.

Main entry points: [`src/app/store.ts`](https://github.com/aeroxy/web-bro/blob/main/src/app/store.ts) (Store), [`src/app/App.tsx`](https://github.com/aeroxy/web-bro/blob/main/src/app/App.tsx) (App shell), [`src/features/chat/ChatPanel.tsx`](https://github.com/aeroxy/web-bro/blob/main/src/features/chat/ChatPanel.tsx) (Chat), [`src/workers/llm.worker.ts`](https://github.com/aeroxy/web-bro/blob/main/src/workers/llm.worker.ts) (LLM worker)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_ui["UI shell"]
  node_main["Main<br/>entrypoint<br/>[main.tsx]"]
  node_app["App shell<br/>react shell<br/>[App.tsx]"]
  node_store{{"Store<br/>orchestrator<br/>[store.ts]"}}
  node_chat["Chat<br/>panel<br/>[ChatPanel.tsx]"]
  node_workspace["Workspace<br/>panel<br/>[WorkspacePanel.tsx]"]
  node_log["Log<br/>panel<br/>[LogPanel.tsx]"]
  node_debug["Debug<br/>panel<br/>[DebugPanel.tsx]"]
  node_thread["Thread list<br/>shared component<br/>[ThreadSidebar.tsx]"]
  node_filetree["File tree<br/>shared component<br/>[FileTree.tsx]"]
  node_markdown["Markdown<br/>shared component"]
  node_gate{{"Capability gate<br/>feature gate<br/>[CapabilityGate.tsx]"}}
end

subgraph group_runtime["Runtime"]
  node_capabilities["Capabilities<br/>browser checks<br/>[capabilities.ts]"]
  node_llm(("LLM worker<br/>web worker<br/>[llm.worker.ts]"))
  node_workspacew(("Workspace worker<br/>web worker"))
  node_runtime["Runtime<br/>service layer<br/>[runtime.ts]"]
  node_chromeai["Chrome AI<br/>runtime adapter"]
  node_contracts["Contracts<br/>message schema<br/>[contracts.ts]"]
  node_chatml["ChatML<br/>prompt format<br/>[chatml.ts]"]
  node_prompt["Agent prompt<br/>prompt template<br/>[agent-prompt.ts]"]
  node_filesystem{{"File System API<br/>browser api"}}
  node_webgpu{{"WebGPU<br/>browser api"}}
end

subgraph group_data["Local data"]
  node_db[("DB<br/>[db.ts]")]
  node_indexeddb[("IndexedDB<br/>browser storage")]
  node_huggingface["Hugging Face<br/>model source"]
  node_cloudflare["Static hosting<br/>deployment target"]
  node_headers["Headers<br/>hosting config"]
  node_redirects["Redirects<br/>hosting config"]
end

node_main -->|"mounts"| node_app
node_app -->|"uses"| node_store
node_app -->|"wraps"| node_gate
node_app -->|"renders"| node_chat
node_app -->|"renders"| node_workspace
node_app -->|"renders"| node_log
node_app -->|"renders"| node_debug
node_chat -->|"uses"| node_thread
node_chat -->|"renders"| node_markdown
node_workspace -->|"uses"| node_filetree
node_gate -->|"checks"| node_capabilities
node_store -->|"orchestrates"| node_llm
node_store -->|"orchestrates"| node_workspacew
node_store -->|"persists"| node_db
node_store -->|"speaks"| node_contracts
node_store -->|"formats"| node_chatml
node_store -->|"templates"| node_prompt
node_store -->|"selects"| node_runtime
node_runtime -->|"adapts"| node_chromeai
node_llm -->|"runs on"| node_webgpu
node_llm -->|"loads from"| node_huggingface
node_workspacew -->|"uses"| node_filesystem
node_workspacew -->|"backs up"| node_db
node_db -->|"stores in"| node_indexeddb
node_filesystem -.->|"separate domain"| node_indexeddb
node_headers -->|"supports"| node_cloudflare
node_redirects -->|"supports"| node_cloudflare

click node_main "https://github.com/aeroxy/web-bro/blob/main/src/main.tsx"
click node_app "https://github.com/aeroxy/web-bro/blob/main/src/app/App.tsx"
click node_store "https://github.com/aeroxy/web-bro/blob/main/src/app/store.ts"
click node_chat "https://github.com/aeroxy/web-bro/blob/main/src/features/chat/ChatPanel.tsx"
click node_workspace "https://github.com/aeroxy/web-bro/blob/main/src/features/workspace/WorkspacePanel.tsx"
click node_log "https://github.com/aeroxy/web-bro/blob/main/src/features/log/LogPanel.tsx"
click node_debug "https://github.com/aeroxy/web-bro/blob/main/src/features/debug/DebugPanel.tsx"
click node_thread "https://github.com/aeroxy/web-bro/blob/main/src/components/ThreadSidebar.tsx"
click node_filetree "https://github.com/aeroxy/web-bro/blob/main/src/components/FileTree.tsx"
click node_markdown "https://github.com/aeroxy/web-bro/blob/main/src/components/MarkdownContent.tsx"
click node_gate "https://github.com/aeroxy/web-bro/blob/main/src/components/CapabilityGate.tsx"
click node_capabilities "https://github.com/aeroxy/web-bro/blob/main/src/lib/capabilities.ts"
click node_llm "https://github.com/aeroxy/web-bro/blob/main/src/workers/llm.worker.ts"
click node_workspacew "https://github.com/aeroxy/web-bro/blob/main/src/workers/workspace.worker.ts"
click node_runtime "https://github.com/aeroxy/web-bro/blob/main/src/services/runtime.ts"
click node_chromeai "https://github.com/aeroxy/web-bro/blob/main/src/services/chrome-ai-runtime.ts"
click node_contracts "https://github.com/aeroxy/web-bro/blob/main/src/lib/contracts.ts"
click node_chatml "https://github.com/aeroxy/web-bro/blob/main/src/lib/chatml.ts"
click node_prompt "https://github.com/aeroxy/web-bro/blob/main/src/lib/agent-prompt.ts"
click node_db "https://github.com/aeroxy/web-bro/blob/main/src/lib/db.ts"
click node_headers "https://github.com/aeroxy/web-bro/tree/main/public/_headers"
click node_redirects "https://github.com/aeroxy/web-bro/tree/main/public/_redirects"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_main,node_app,node_store,node_chat,node_workspace,node_log,node_debug,node_thread,node_filetree,node_markdown,node_gate toneBlue
class node_capabilities,node_llm,node_workspacew,node_runtime,node_chromeai,node_contracts,node_chatml,node_prompt,node_filesystem,node_webgpu toneAmber
class node_db,node_indexeddb,node_huggingface,node_cloudflare,node_headers,node_redirects toneMint
```

## Components

### UI shell

React app entry, shell, and feature panels.

- [Main](https://github.com/aeroxy/web-bro/blob/main/src/main.tsx): entrypoint · Bootstraps the React app. · `src/main.tsx`
- [App shell](https://github.com/aeroxy/web-bro/blob/main/src/app/App.tsx): react shell · Top-level composition of the visible workspace. · `src/app/App.tsx`
- [Store](https://github.com/aeroxy/web-bro/blob/main/src/app/store.ts): orchestrator · Coordinates agent turns, state, persistence, and worker traffic. · `src/app/store.ts`
- [Chat](https://github.com/aeroxy/web-bro/blob/main/src/features/chat/ChatPanel.tsx): panel · Conversation and agent interaction panel. · `src/features/chat/ChatPanel.tsx`
- [Workspace](https://github.com/aeroxy/web-bro/blob/main/src/features/workspace/WorkspacePanel.tsx): panel · Local folder and file-operation panel. · `src/features/workspace/WorkspacePanel.tsx`
- [Log](https://github.com/aeroxy/web-bro/blob/main/src/features/log/LogPanel.tsx): panel · Runtime activity and event visibility. · `src/features/log/LogPanel.tsx`
- [Debug](https://github.com/aeroxy/web-bro/blob/main/src/features/debug/DebugPanel.tsx): panel · Diagnostics and internal state inspection. · `src/features/debug/DebugPanel.tsx`
- [Thread list](https://github.com/aeroxy/web-bro/blob/main/src/components/ThreadSidebar.tsx): shared component · Sidebar for chat thread navigation. · `src/components/ThreadSidebar.tsx`
- [File tree](https://github.com/aeroxy/web-bro/blob/main/src/components/FileTree.tsx): shared component · Browser workspace file navigation. · `src/components/FileTree.tsx`
- [Markdown](https://github.com/aeroxy/web-bro/blob/main/src/components/MarkdownContent.tsx): shared component · Renders assistant and document content. · `src/components/MarkdownContent.tsx`
- [Capability gate](https://github.com/aeroxy/web-bro/blob/main/src/components/CapabilityGate.tsx): feature gate · Blocks unsupported features on incompatible browsers. · `src/components/CapabilityGate.tsx`

### Runtime

Workers and browser-backed execution boundaries.

- [Capabilities](https://github.com/aeroxy/web-bro/blob/main/src/lib/capabilities.ts): browser checks · Detects secure context, WebGPU, and file-system support. · `src/lib/capabilities.ts`
- [LLM worker](https://github.com/aeroxy/web-bro/blob/main/src/workers/llm.worker.ts): web worker · Loads and runs the in-browser Gemma model. · `src/workers/llm.worker.ts`
- [Workspace worker](https://github.com/aeroxy/web-bro/blob/main/src/workers/workspace.worker.ts): web worker · Owns folder traversal, reads, writes, search, and undo backups. · `src/workers/workspace.worker.ts`
- [Runtime](https://github.com/aeroxy/web-bro/blob/main/src/services/runtime.ts): service layer · Selects and adapts the browser AI runtime implementation. · `src/services/runtime.ts`
- [Chrome AI](https://github.com/aeroxy/web-bro/blob/main/src/services/chrome-ai-runtime.ts): runtime adapter · Adapter for browser AI capabilities. · `src/services/chrome-ai-runtime.ts`
- [Contracts](https://github.com/aeroxy/web-bro/blob/main/src/lib/contracts.ts): message schema · Shared message and tool protocol definitions. · `src/lib/contracts.ts`
- [ChatML](https://github.com/aeroxy/web-bro/blob/main/src/lib/chatml.ts): prompt format · Message formatting between UI, store, and model worker. · `src/lib/chatml.ts`
- [Agent prompt](https://github.com/aeroxy/web-bro/blob/main/src/lib/agent-prompt.ts): prompt template · Shapes the agent instructions and tool loop context. · `src/lib/agent-prompt.ts`
- **File System API**: browser api · User-selected local folder access boundary.
- **WebGPU**: browser api · Accelerates in-browser model execution.

### Local data

IndexedDB persistence and external delivery targets.

- [DB](https://github.com/aeroxy/web-bro/blob/main/src/lib/db.ts): indexeddb persistence · Stores threads, sessions, settings, and write backups locally. · `src/lib/db.ts`
- **IndexedDB**: browser storage · Local durable storage used by the app.
- **Hugging Face**: model source · First-use model download source, cached by the browser.
- **Static hosting**: deployment target · Static-site delivery via Cloudflare Pages style hosting.
- [Headers](https://github.com/aeroxy/web-bro/tree/main/public/_headers): hosting config · Response headers for static deployment. · `public/_headers`
- [Redirects](https://github.com/aeroxy/web-bro/tree/main/public/_redirects): hosting config · Routing rules for static deployment. · `public/_redirects`

## Connections

- Main → App shell: mounts · Bootstraps the SPA.
- App shell → Store: uses · App shell is driven by central state.
- App shell → Capability gate: wraps · Feature availability is gated at the shell level.
- App shell → Chat: renders · Visible chat panel.
- App shell → Workspace: renders · Visible workspace panel.
- App shell → Log: renders · Visible log panel.
- App shell → Debug: renders · Visible debug panel.
- Chat → Thread list: uses · Thread navigation is shared UI.
- Chat → Markdown: renders · Assistant content is markdown-rendered.
- Workspace → File tree: uses · Local files are shown in a tree.
- Capability gate → Capabilities: checks · Browser support detection.
- Store → LLM worker: orchestrates · Coordinates model turns and streamed output.
- Store → Workspace worker: orchestrates · Sends tool actions to workspace operations.
- Store → DB: persists · Writes durable app state and backups.
- Store → Contracts: speaks · Uses shared message shapes.
- Store → ChatML: formats · Builds model/chat payloads.
- Store → Agent prompt: templates · Shapes agent instructions and tool loop.
- Store → Runtime: selects · Chooses the browser runtime path.
- Runtime → Chrome AI: adapts · Runtime adapter boundary.
- LLM worker → WebGPU: runs on · Model execution depends on GPU-enabled browser support.
- LLM worker → Hugging Face: loads from · Model artifacts are fetched on first use.
- Workspace worker → File System API: uses · Folder and file access is isolated in the worker.
- Workspace worker → DB: backs up · Write safety depends on stored snapshots.
- DB → IndexedDB: stores in · All durable app data remains local to the browser.
- File System API → IndexedDB: separate domain · Workspace files live on disk; metadata lives in browser storage.
- Headers → Static hosting: supports · Static hosting configuration.
- Redirects → Static hosting: supports · Static hosting routing configuration.
