The dashboard
The dashboard is a React app the daemon serves from beside itself, on the same port as everything else:
http://127.0.0.1:18254/dashboard/It is the operator’s interface for anything an agent owns. It is not a lesser copy of the CLI —
the setup wizard and nouride setup run the same code, and the Skills page writes the same file
nouride skills on|off does.
The map
Interact Chat talk to any agent, with its tool steps live as it works
Monitor Overview daemon health · approvals waiting on you · today's spend Schedule every cron job, filtered by active / paused / failing Webhooks endpoints that run a job when called, rather than on a clock System Logs the daemon's own log, the audit trail, scheduler runs, background commands
Configure Agents the list, and the pairing switch above it └ <agent> Files IDENTITY.md, SOUL.md, config.toml… with a Markdown preview Model which provider profile and model this agent runs on Connections the bots and numbers it answers on Access who is allowed to message it Skills every skill in the pool, and which of them this agent carries MCP external tool servers declared for this agent Skills the Workshop: the pool, the drafts queue, who has what Memories what the agents have written down People names and notes for the humans they talk to Models provider profiles: endpoint, wire format, credential (admin)
Account My Account username, name, password Users accounts and roles (admin)Admin-only pages are absent from the sidebar for anyone who cannot use them, rather than present and refusing.
An agent is the module
This is the one structural decision worth explaining. Everything about one agent — its files, its model, its bots, who may reach it, what it carries — is under that agent, not spread across four top-level pages joined by hand.
It also makes a failure mode unrepresentable. A connection is created from an agent’s own page, so the form has nothing to ask about ownership, and there is no longer any way to produce a gateway that belongs to nobody. That used to silently drop every group message.
Model versus Models
A real distinction, not a naming accident. A profile is infrastructure — an endpoint, a wire format, a credential — defined once under Models and shared. A model is one agent’s choice within it, under that agent’s Model tab. Keeping them apart is what lets one agent move to a different deployment without touching the others.
Files
The persona pack, edited in the browser, with a Markdown preview beside it.
The preview builds React elements and there is no raw HTML rendering anywhere in the app. An agent
can write its own SOUL.md and create its own skills; rendering that as HTML would turn “the model
emitted a script tag” into a script running in an admin’s browser, same origin, with a session
cookie.
The two queues that are not the same queue
Confusing these once cost an operator an hour, and the wording is chosen so it cannot happen again.
| Where | What it means | |
|---|---|---|
| Approvals | Overview, top, only when non-empty | An agent has stopped mid-turn wanting to run something |
| Access | Per agent | A person is asking to be let in at all |
| Skill drafts | Skills Workshop, top, only when non-empty | An agent has proposed a skill and wants your call |
An approval is a turn stopped mid-flight with a timer on it. A draft is a suggestion about a turn that finished twenty minutes ago, blocks nothing, and never expires. Putting them in one queue would give one of them the wrong lifecycle.
Approvals sit first on the page and disappear when empty, because an agent is waiting — a queue nobody can find is a turn that times out.
Skills is top-level and a tab
Both are load-bearing. A skill is not owned by an agent — there is one pool and every agent is
offered all of it — so “who has this, and does this box have the dot it needs?” has no agent to
live under. That is the Workshop. The agent tab answers the other direction: what does this one
carry.
Two views of one switch, which is why the Workshop’s rows carry a badge per agent rather than five links away.
A row expands to its SKILL.md in place, fetched only when opened. Deciding whether an agent should
carry something and reading what it says belong on one screen.
Things the UI will always do
Not style preferences — each one is a bug that was written, or one the code’s shape now prevents.
Destructive actions ask, and say what will happen. Which item, how many agents it affects, and that nothing undoes it. The button carries the verb — “Delete”, never “OK”.
Credentials are write-only. A token field on an existing connection is empty, and empty means leave it alone, never clear it. Nothing reads a credential back, so the UI cannot show a masked placeholder for someone to select and overwrite.
A saved gateway is not a running gateway. Adapters are built at boot, so every gateway change reports that a restart is required and offers the button.
It says which state is which. A connection that exists but never started shows as “not started”, not “disconnected” — labelling it as disconnected sends somebody to debug a network problem that does not exist.
Nobody can lock the instance out. A person cannot change their own role or delete their own account, so the last admin cannot demote themselves out of account management.
Chat
The dashboard has a full chat, with each turn’s tool steps expanding live as the agent works. It is the fastest way to see why an answer took the shape it did.
Slash commands work here exactly as they do on Telegram — see talking to an agent.