Skip to content

Architecture

refact-planner edited this page Jun 7, 2026 · 1 revision

Architecture

Refact is a three-layer system: IDE plugins speak to a React GUI, the GUI talks to the Rust refact-lsp engine over HTTP/SSE, and the engine orchestrates chat, tools, providers, indexes, and integrations.

flowchart LR
  subgraph IDE[IDE plugins]
    VS[VSCode]
    JB[JetBrains]
  end

  subgraph GUI[GUI webview]
    R[React GUI]
  end

  subgraph ENG[refact-lsp engine]
    G[GlobalContext]
    C[Chat / tools]
    A[AST + VecDB + knowledge]
    S[Scheduler + background tasks]
  end

  subgraph EXT[External systems]
    P[LLM providers]
    L[Local indexes]
    I[Integrations]
  end

  VS <-- postMessage --> R
  JB <-- postMessage --> R
  R <-- HTTP REST + SSE :8001 --> G
  G --> C
  G --> A
  G --> S
  C <---> P
  A <---> L
  C <---> I
Loading

Components

refact-lsp Rust engine

The engine is the backend process in refact-agent/engine/. It is an Axum HTTP server and a tower-lsp server in the same binary, with the entry point in src/main.rs and shared state centered in GlobalContext.

GlobalContext owns the shared runtime state used by HTTP handlers, LSP handlers, chat, tools, integrations, providers, AST/VecDB services, and background services. It also carries the configured cache/config directories and the shutdown flag.

React GUI

The GUI in refact-agent/gui/ is a React 18 + TypeScript application that renders the chat experience inside a webview. It uses Redux Toolkit / RTK Query, subscribes to engine SSE streams, sends chat commands over HTTP, and exchanges IDE bridge events through postMessage.

IDE plugins

The VSCode and JetBrains plugins host the GUI webview and provide the IDE bridge. They pass IDE context to the GUI and receive actions back from the GUI through the same postMessage channel.

Communication

  • Engine ↔ GUI: HTTP REST plus SSE streaming on :8001. The GUI posts chat commands to POST /v1/chats/{chat_id}/commands and subscribes to GET /v1/chats/subscribe?chat_id={id} for monotonic seq events.
  • Engine ↔ IDE: LSP protocol for editor features such as completions and code-lens, with HTTP also used for chat and tool endpoints.
  • IDE ↔ GUI: postMessage bridge between the host and the webview. In VSCode this is acquireVsCodeApi; in JetBrains it is the plugin bridge used by the GUI event layer.

GlobalContext + background tasks

GlobalContext is the engine’s shared state hub: Arc<ARwLock<GlobalContext>> is referenced by both the HTTP server and the LSP server. The struct stores runtime flags, clients, paths, caches, provider state, workspace state, chat sessions, integrations, knowledge index, and event senders.

The engine starts background services through start_background_tasks(); the repo docs describe this as roughly 12 tokio tasks, including AST indexing, VecDB work, git shadow cleanup, knowledge graph maintenance, trajectory memo handling, agent monitoring, and OAuth refresh.

Local state & config locations

  • <project>/.refact/ — project-scoped trajectories, knowledge, tasks, and integrations.
  • ~/.config/refact/ — user config such as privacy and provider YAML files.
  • ~/.cache/refact/ — caches, logs, shadow repos, telemetry, and integration runtime data.

GlobalContext is initialized with explicit config_dir and cache_dir paths, and the engine’s config loading code reads from these locations unless command-line overrides are supplied.

Where to go next

For implementation details, read the engine AGENTS.md and the GUI AGENTS.md, then trace the flow from chat commands through SSE events into the GUI reducers and selectors.

Clone this wiki locally