π Dashboard
Goal: Amy should expose one canonical Discord embed dashboard for state, options, feedback, context, model/provider, usage, queue, and health. Slash commands and interactive buttons should render the same state snapshot β no duplicate truth, no stale status, no Markdown pretending to be UI.
π·οΈ Naming β Ompcord vs Amy. Ompcord is the ompβDiscord bridge (product/plugin); Amy is the bot persona it runs. You install Ompcord; Amy is who answers. Rename phases 1β5 are complete at docs/command/runtime/package level: package name
ompcord, wrapper runtimeompcordd.mjs/ompcordd.service, and compatibility foramyd.mjs,/amy,/pi-discord-remote, legacy config, and~/.omp/amy-sessions/. Repo directory stayspi-discord-amyuntil final filesystem cutover. See the naming direction.*
Rocket launch channel pattern
The channel-level entry point is deliberately reaction-gated:
β¦
This gives the launch channel a visible **outside powerpanel** while the real run happens inside the thread. The current v1 mode is only `π` = normal run. Future reactions may map to `plan`, `debug`, or `review`.
The outside dashboard is not a separate source of truth: it is a mirror of the same `Dashboard` state used in the thread.
Quick-start: [Amy Rocket Launch Channels](./rocket-launch).
---
## Core doctrine
Amy needs a **single state snapshot** and multiple renderers, not scattered status strings.
```text
β¦
Everything user-visible should come from `StatusSnapshot`:
- `/amy status`
β¦
If the value is not in the snapshot, it is not part of the dashboard truth.
---
## StatusSnapshot contract
```js
β¦
**Important:** model/provider/context/usage must be honest.
| Field | Source | Rule |
β¦
---
## Embed layout: status as a dashboard
Use fields as the SSOT surface. Avoid giant prose. Keep every field scannable.
```text
β¦
### Field contract
| Field | Example value |
β¦
### Color rules
| State | Color |
β¦
---
## Slash command design
Implemented commands:
| Command | Status | Behavior |
β¦
Future commands:
| Command | Purpose |
β¦
**ACK rule:** every slash command that may touch Discord/network/process state must `deferReply({ flags: MessageFlags.Ephemeral })` before doing work. `status`/`health` reply immediately because they read an in-memory snapshot only.
---
## Interactive dashboard components
Use components as dashboard actions, not decoration.
```text
β¦
| Component | Behavior |
β¦
Future controls:
| Component | Behavior |
β¦
**Do not** let a refresh button call the model. Dashboard interactions are control-plane operations only.
---
## Options, stats, feedback model
The dashboard should make Amy feel alive without spamming the thread.
| Category | What to show | What not to fake |
β¦
When usage is unknown, say exactly:
```text
β¦
That is better than false precision.
---
## Event capture: one feed, many views
Every run should update the same snapshot:
```text
β¦
This gives:
- dashboard embed fields
β¦
---
## Implementation status
Implemented:
1. `status.mjs`:
β¦
Next:
1. Add queue policy state beyond the current `reject`/single-depth hint.
β¦
---
## Acceptance bar
- [x] `/amy status` shows gateway, active thread, cwd, session, model, provider status, usage status, queue, last error, uptime, pid.
β¦
---
## Related docs
- [Discord Responsive Interview Embed](./responsive-interviews)
- [Ompcord β Always-on Discord Bridge](./)
[β¦179ln elided; re-read needed ranges, e.g. /home/usr/funday/dev/docs/content/omp/harnesses/ompcord/ssot-dashboard.md:22-26,41-43]