Detailed reference
Every panel, in order.
Each section below explains what a feature does, where it lives in the
client, and the steps to use it. At the bottom of every section, the
Details → button opens the live client so you can try it.
🔑
Reserve an alias Header · identity panel
An alias is your seat in the Agora. A free alias exists only while your
browser is connected. A reserved alias is stored on the
router: messages sent to it wait for you, and nobody else can take the name.
- Type a name into your alias in the header (≥3 characters).
- Press Set Alias. If the name is free, you're in with a plain identity.
- To lock it down, press 🔒 Reserve and enter a secret word (≥4 characters).
- Confirm. The header shows
YourAlias* 🔒 — the asterisk and lock mean the reservation succeeded.
On a later visit, your browser auto-fills your alias. If your secret isn't
remembered, type it into the secret to view messages field and press
🔑 View.
Write the secret down. The router stores only
SHA-256(secret). There is no recovery. If you lose it, the
alias stays reserved but you can no longer read its messages.
To log out, press Logout. That clears your alias and secret
from the browser. The reservation on the router stays. Type the alias and
secret again on any device to come back.
💻
Write and test code Chat · code block → Code Executor
The Code Executor is a group member like any other. You
hand it a fenced code block; it runs on the router and returns the result
to the thread — as an image, an HTML preview, an audio clip, a file, or
plain text.
- Write a fenced block in the composer:
```python
print("hello from the router")
```
- Select Code Executor as a recipient in the sidebar.
- Send. The executor runs the code on the server and posts the output back into the thread.
You can also run code blocks already in the log: any ``` block
in a message shows a ▶ Run button in its header. That
sends the block to the executor without retyping.
The result window is a draggable, resizable output panel. HTML renders live,
images display inline, text is preserved. The same content is also archived
as an attachment in the message log.
🛰️
Host your router from home (bore) Header · BORE button
The client tries three transports in order — bore → local → wss
— and uses whichever opens first. To expose a router behind a home
firewall, run bore on that server and hand the port to the client.
- On the home server: start
routerE2E.js as usual. Confirm curl http://127.0.0.1:9387/health answers ok.
- Install
bore: cargo install bore-cli (or a prebuilt release binary).
- Start the tunnel:
bore local 9387 --to bore.pub. It prints a public port, e.g. bore.pub:46213.
- In the client, click BORE in the header. Type the port and press 🔌 Save & reconnect.
- Hover the transport dots in the header. The active URL should read
ws://bore.pub:46213.
For a permanent home node, run bore under systemd
so it restarts on failure. Ask for a stable port with
--port 46213 so the browser's stored hint keeps working.
Anyone who knows the port can reach the router. Set a
ROUTER_KEY_HEX in routerE2E.js before exposing it.
The router's own encryption gate is what protects it. Add your home server (router) to the global Agora, or estblish your private group.
📋
Context panel Sidebar · CONTEXT section
A context is a named snapshot of the whole message log.
Save one, start a fresh conversation, then load the snapshot back later —
long-running work becomes resumable.
- Press ✨ New at the top of the chat. The client sends
save_context to the router, which writes a file named
ctx_YYYY-MM-DD_HH-MM-SS.json and clears the log.
- Click any entry in the CONTEXT panel to load it back. The router merges
it with whatever is in the current log.
- Useful when a thread is getting long: snapshot, start fresh, keep the
old thread one click away.
Contexts live on the router, so anyone in the group can list and load them.
The client refreshes the list on reconnect.
👁️
View panel Sidebar · VIEW section
The VIEW panel lists every sender you've received messages from, with a
message count. Tick one or more to filter the inbox; leave all unticked to
see everything.
- Tick a sender's checkbox to include only that sender in the message list.
- The chat header shows 📤 SenderName (N msgs) so you know the filter is active.
- Press ✕ in the section header to reset — clears all ticks and shows the full inbox again.
- Press + to re-apply whatever is currently ticked.
Filters are local. Everyone sees the whole group's traffic in the log; the
VIEW filter only changes what you are looking at right now.
📱
Applications menu Sidebar · APPLICATIONS section
Any script, HTML page, or tool on the router can join the room as a
group member. Add it once; anyone can launch it with a
checkbox.
- Click + in the APPLICATIONS header. A modal opens.
- Choose a file from the server's available list. Supported extensions:
.sh, .py, .js, .html.
- Give it an alias (the name that appears in the sidebar).
- Press Add. The app now appears in the sidebar.
- Tick its checkbox to launch it. The router spawns the process and
returns a PID, which lands in the chat as a System message.
Launching an app is a sensitive operation — if a router
key is set, the launch message must arrive encrypted. The exit message
(when the process ends) also lands in the chat, so you always know when an
app has finished.
📌
Fixed prompts Sidebar · FIXED PROMPTS section
A fixed prompt is a reusable line of text you can fire into
the conversation, append to the composer, or edit. Prompts are shared
across the room — what one person pins, everyone can reuse.
- Capture: click a message bubble (or a model reply) to
highlight it, then press + in the FIXED PROMPTS header.
The selected text becomes a prompt.
- From the input: type something in the composer and
click the hint line 💡 Click a message…. The input becomes a prompt.
- Send: click a prompt's ✎ icon to open the editor, then
press 📤 Send. It posts as a normal message to whoever is
currently selected.
- Append: press ➕ Append to Input to
merge the prompt into whatever you're already typing.
- Edit: press ✎ on any prompt to change it; ✕ to delete it.
In the fully-wired setup the list comes from the router's prompt library,
not from your browser's local storage — so the group's best prompts are
available to everyone next time.
🔐
Encryption Header · 🔑 button
With a shared AES-256 key, the router enforces encrypted channels on every
sensitive operation — AI calls, file writes, process launches,
private history, model-contact mutations. Ordinary human-to-human chat stays
open by default.
- Click the 🔑 button in the header. A popup asks for a
64-hex-character key.
- Paste or type the key. The counter shows
64 / 64 and the
status shows ✓ valid key.
- Press 🔓 Encryption OFF to toggle it to 🔒 Encryption ON.
- Everyone you want to talk to must use the same key.
When encryption is on, incoming sender names render green
if the frame was genuinely encrypted and red
if it arrived in plaintext. That's a visible trust signal, not decoration.
The key never leaves your machine. It is imported into the
browser's WebCrypto API and used locally. Only encrypted ciphertext is sent.
🧠
AI models Sidebar · AI-MODELS section
Models come from the router's inventory — local Ollama models
(ol.*), Hugging Face models (hf.*), and the Code
Executor. You can add any of them to your contacts and route messages to
them exactly like a person.
- Tick a model's checkbox in the AI-MODELS list to add it to your
contacts. Untick to remove it.
- Press 🔀 Aliases to toggle between raw IDs and friendly
aliases. When showing aliases, only models your group has prioritised
appear in the contact list.
- Press the ? icon on any model to open its details
(provider, capabilities, use cases).
Once added, a model shows up in the 👥 WEB contact list with a status dot
(online / offline). Tick it as a recipient on any message and the router
will route your text to it.
📎
Attachments Composer · 📎 strip
Files you attach travel with the message and are archived alongside it.
Images render inline, audio and video play in place, code and text display
in a scrollable pre-block, and PDFs render in an embed. Every attachment is
hashed on the router and stored once.
- Click the 📎 strip above the composer, or drop files directly onto it.
- Each file appears as a tag with name, type, and size. Press × to remove it.
- Send the message. Attachments arrive with it and are archived in the
asset store.
- Click any inline image to open it in a larger output window. Click any
file tag to download the original.
The 10 MB per-file limit applies in the browser. Generated images from
models come back into the thread the same way — as attachments you can
click, save, and reuse.