This document describes the architectural patterns and protocols used in the Agora, specifically focusing on the interaction between components (Server, Bridge) and external systems (Fediverse).
The "Join" flow allows users to self-onboard by adding their Git repositories to the Agora.
settings.ts, overlay.html).agora.py), serving as the public gateway.api/agora.py) running on a private port (default: 5018). It has privileged access to the filesystem and configuration.sequenceDiagram
participant User
participant Browser as Client (Browser)
participant Server as Agora Server (5017)
participant Bridge as Agora Bridge (5018)
participant FS as File System
User->>Browser: Enters Username & Repo URL, clicks "Join"
Browser->>Server: POST /api/join {username, repo_url}
Note over Server: 1. Validate Input<br/>2. Construct target path (garden/user)<br/>3. Resolve Bridge URL (config)
Server->>Bridge: POST /sources {url, target, type='garden', format='git'}
Note over Bridge: 1. Read ~/agora/sources.yaml<br/>2. Check for duplicates<br/>3. Append new source<br/>4. Write sources.yaml
Bridge->>FS: git clone <repo_url> ~/agora/<target>
FS-->>Bridge: (Exit Code / Output)
alt Clone Success
Bridge-->>Server: 201 Created {message: "Source added and cloned"}
Server-->>Browser: 200 OK {message: "Success! You have joined."}
Browser->>User: Displays "Success!" (Green)
else Clone Failure
Bridge-->>Server: 202 Accepted {error: "Git error...", source: ...}
Server-->>Browser: 200 OK {message: "Added, but clone failed. Contact admin."}
Browser->>User: Displays Error/Warning
end
The Agora acts as an ActivityPub instance (anagora.org). It periodically broadcasts new content to its followers.
Agora Server (federate_latest_loop).git_utils.py) to query git history.federated_subnodes, followers).sequenceDiagram
participant Loop as Federation Loop (Thread)
participant Git as Git Utils
participant DB as SQLite
participant AP as ActivityPub Followers
Note over Loop: Runs every 5 minutes (or 10s in debug)
Loop->>Git: get_latest_changes_per_repo()
Git-->>Loop: [User: [Subnode A, Subnode B...], ...]
loop For each Subnode
Loop->>DB: Check is_subnode_federated(uri)
opt Not Federated
Note over Loop: 1. Render Content (or handle Image)<br/>2. Construct 'Create' Activity<br/>3. Load RSA Keys
Loop->>DB: Get Followers of Author (or @agora)
loop For each Follower
Loop->>AP: Resolve Inbox URL (WebFinger/Actor fetch)
Loop->>AP: POST /inbox (Signed 'Create' Activity)
end
Loop->>DB: add_federated_subnode(uri)
end
end
The Agora Bridge provides a RESTful interface for privileged operations.
Base URL: http://localhost:5018 (Internal)
| Endpoint | Method | Payload | Description |
|---|---|---|---|
/ |
GET |
- | Status Page. Returns HTML listing configured sources and database stats. |
/sources |
POST |
url: Git URLtarget: Path slugtype: ‘garden’|’stoa’format: ‘git’ (default) |
Add Source. updates sources.yaml and triggers a synchronous git clone. |