amira/ARCHITECTURE.md
2026-02-10 16:09:09 -05:00

225 lines
6.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Hydra Browser Architecture
This document explains the Hydra Browser architecture for a developer who knows Python but is new to frontend and Electron. It focuses on how the app is structured, how data flows, and how the main features work.
## 1. What This App Is
Hydra is a **desktop app** (Electron) that renders **web pages inside a canvas of linked windows**. Each window is a React Flow node. Links can open new windows and form a graph of browsing paths.
Key ideas:
- **Electron** runs a desktop window using Chromium.
- The **renderer** is a React app (frontend UI).
- A **local proxy server** fetches web pages and injects scripts to intercept clicks.
- **Zustand store** holds all app state (nodes, edges, UI state).
## 2. High-Level Architecture
```mermaid
flowchart LR
subgraph Electron App
Main[Main Process
src/main/index.js]
Renderer[Renderer Process
React UI]
end
Renderer -->|HTTP| Proxy[Local Proxy Server
src/server/proxy.js]
Renderer <-->|IPC| Main
Proxy -->|Fetch| Internet[Websites]
```
### Roles
- **Main Process**: bootstraps Electron and starts the proxy server.
- **Renderer**: React UI + state. Renders the canvas and windows.
- **Proxy Server**: fetches web content, injects scripts, returns HTML to iframes.
## 3. Key Modules
### 3.1 Main Process (Electron)
**File:** `src/main/index.js`
Responsibilities:
- Create the Electron window.
- Start the local proxy server (port 3001).
- Provide IPC handlers for file-based session save/load.
### 3.2 Proxy Server
**File:** `src/server/proxy.js`
Responsibilities:
- Fetch remote pages (via Axios).
- Inject a script into HTML to:
- intercept clicks
- intercept form submissions
- intercept programmatic navigations
- send `postMessage` events back to the renderer
- provide page text for summaries/chat
### 3.3 Renderer
**Root:** `src/renderer`
Key pieces:
- `components/ReactFlowCanvas.tsx`: canvas and node types
- `components/BrowserWindowNode.tsx`: web window node
- `components/NoteWindowNode.tsx`: notes
- `components/SummaryWindowNode.tsx`: AI summary output
- `components/ChatWindowNode.tsx`: AI chat window
- `store/hydraStore.ts`: Zustand store (all app state)
## 4. Data Flow: Opening a Page
```mermaid
sequenceDiagram
participant UI as BrowserWindowNode
participant Store as Hydra Store
participant Proxy as Proxy Server
participant Web as Website
UI->>Store: addBrowserWindow(url)
Store->>UI: node created (BrowserWindowNode)
UI->>Proxy: GET /fetch?url=...
Proxy->>Web: fetch page
Web->>Proxy: HTML response
Proxy->>Proxy: inject link interception script
Proxy->>UI: HTML (blob URL)
UI->>UI: iframe loads blob
```
## 5. How Link Expansion Works
When the injected script sees a link click or navigation, it sends:
```js
window.parent.postMessage({
type: 'HYDRA_LINK_CLICK',
url: 'https://example.com',
openInNewWindow: true|false
}, '*')
```
The renderer listens for these messages and either:
- opens a new node and connects it with an edge, or
- navigates within the same node
```mermaid
flowchart TD
Click[User clicks link] --> Script[Injected script]
Script -->|postMessage| Renderer
Renderer -->|openInNewWindow| StoreAdd[addBrowserWindow]
Renderer -->|same window| StoreNav[navigateBrowserWindow]
```
## 6. State Management (Zustand)
**File:** `src/renderer/store/hydraStore.ts`
The store keeps:
- **nodes**: all windows on the canvas
- **edges**: relationships between windows
- **theme**: dark/light
- **AI settings**: provider, API key, model
- **session info**: file path + name
### Example: Creating a Browser Window Node
```ts
addBrowserWindow(url, parentId?)
```
- Creates a new React Flow node
- Optionally creates an edge from the parent
- Re-layouts the graph so windows align
## 7. Layout Engine
**File:** `src/renderer/store/hydraStore.ts`
A custom layout function positions nodes:
- Root nodes are stacked vertically
- Children appear to the right of their parent
- Subtrees never overlap
```mermaid
graph LR
A[Root 1] --> B[Child 1]
A --> C[Child 2]
D[Root 2] --> E[Child]
```
## 8. Node Types
| Type | Purpose | File |
|------|---------|------|
| browserWindow | Render a web page | `BrowserWindowNode.tsx` |
| noteWindow | Editable note | `NoteWindowNode.tsx` |
| summaryWindow | AI summary output | `SummaryWindowNode.tsx` |
| chatWindow | AI chat UI | `ChatWindowNode.tsx` |
## 9. AI Features
### 9.1 Summaries
- Renderer requests page text via `postMessage`.
- Sends request to `/summarize` on the proxy.
- Proxy calls OpenAI/Anthropic API.
- Summary text displayed in a Summary node.
```mermaid
sequenceDiagram
participant UI as BrowserWindowNode
participant Proxy as Proxy Server
participant LLM as AI Provider
UI->>Proxy: POST /summarize {text, url}
Proxy->>LLM: summarize
LLM->>Proxy: summary
Proxy->>UI: summary
```
### 9.2 Chat
- Chat node sends messages to `/chat` on proxy.
- Proxy adds context text and calls LLM API.
## 10. Session Files (File-Based)
Sessions are saved to disk using file dialogs. No in-app storage.
- **Save**: user chooses a `.hydra` file.
- **Load**: user selects a `.hydra` file.
Flow:
```mermaid
flowchart LR
UI -->|IPC| Main
Main -->|showSaveDialog/openDialog| OS
OS --> Main
Main -->|read/write file| FileSystem
```
## 11. Important Constraints
- Some sites block iframes (`X-Frame-Options`, `CSP frame-ancestors`).
- JavaScript-driven navigation can bypass the proxy if not intercepted.
- Removing `allow-same-origin` increases safety but prevents direct DOM access.
## 12. Mental Model (Python Developer Friendly)
Think of it as:
- **Electron Main** = Python `if __name__ == '__main__':` boot process
- **Renderer** = GUI app logic (like a web app)
- **Proxy Server** = a local Flask server that fetches and rewrites HTML
- **Zustand Store** = a global state dictionary
- **React Flow** = a canvas + graph UI library
## 13. Where to Start Reading
Recommended order:
1. `src/main/index.js` app bootstrap
2. `src/server/proxy.js` page fetching and injection
3. `src/renderer/store/hydraStore.ts` core data model
4. `src/renderer/components/ReactFlowCanvas.tsx` node registration
5. `src/renderer/components/BrowserWindowNode.tsx` core window node
---
If you want a deeper walkthrough of any module, ask and Ill expand that section.