diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index dc9c7f9..d776c2a 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -14,6 +14,7 @@ jobs:
runs-on: ubuntu-latest
outputs:
should_release: ${{ steps.changes.outputs.src_changed == 'true' && steps.check_release.outputs.exists == 'false' }}
+ release_exists: ${{ steps.check_release.outputs.exists }}
version: ${{ steps.version.outputs.version }}
tag: ${{ steps.version.outputs.tag }}
steps:
@@ -34,7 +35,6 @@ jobs:
fi
- name: Read version
- if: steps.changes.outputs.src_changed == 'true'
id: version
run: |
VERSION=$(grep -oP '(?<=)[^<]+' src/Directory.Build.props)
@@ -42,7 +42,6 @@ jobs:
echo "tag=v$VERSION" >> "$GITHUB_OUTPUT"
- name: Check if release exists
- if: steps.changes.outputs.src_changed == 'true'
id: check_release
run: |
if gh release view "${{ steps.version.outputs.tag }}" &>/dev/null; then
@@ -57,7 +56,7 @@ jobs:
if: steps.changes.outputs.src_changed == 'true' && steps.check_release.outputs.exists == 'false'
uses: actions/setup-dotnet@v4
with:
- dotnet-version: '10.0.x'
+ dotnet-version: "10.0.x"
- name: Publish Server win-x64
if: steps.changes.outputs.src_changed == 'true' && steps.check_release.outputs.exists == 'false'
@@ -165,17 +164,32 @@ jobs:
choco:
name: Publish to Chocolatey
needs: release
- if: needs.release.outputs.should_release == 'true'
+ if: needs.release.outputs.release_exists == 'true' || needs.release.outputs.should_release == 'true'
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
+ - name: Check if version already published
+ id: choco_check
+ shell: pwsh
+ run: |
+ $version = "${{ needs.release.outputs.version }}"
+ $result = choco search echohub --version $version --exact --source https://community.chocolatey.org/api/v2/ 2>&1
+ if ($result -match "echohub $version") {
+ echo "exists=true" >> $env:GITHUB_OUTPUT
+ Write-Host "Chocolatey package echohub $version already published — skipping."
+ } else {
+ echo "exists=false" >> $env:GITHUB_OUTPUT
+ }
+
- name: Download release asset
+ if: steps.choco_check.outputs.exists == 'false'
run: gh release download "v${{ needs.release.outputs.version }}" --pattern "EchoHub-Client-win-x64.zip"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Pack and push
+ if: steps.choco_check.outputs.exists == 'false'
shell: pwsh
run: |
$version = "${{ needs.release.outputs.version }}"
diff --git a/README.md b/README.md
index 0f24a3a..49868ad 100644
--- a/README.md
+++ b/README.md
@@ -27,12 +27,14 @@
+
+
+
+
-
-
-
-
+
+
---
@@ -76,10 +78,12 @@ graph TD
### Server
- **Self-hostable** — your server, your rules, your data
+- **Docker ready** — `docker compose up -d` and you're done
- **Real-time messaging** via SignalR WebSockets
- **IRC gateway** — native IRC clients connect alongside TUI users, full cross-protocol messaging
- **JWT auth** with short-lived access tokens and 30-day refresh tokens
- **Channels** — create, set topics, delete (no 47-step permission wizard required)
+- **Moderation** — ban, mute (timed or permanent), kick, role assignment
- **File & image uploads** with actual validation (magic bytes, not just trusting the extension)
- **Image-to-ASCII** — because images in a terminal is objectively cool
- **Presence tracking** — online/away/DND/invisible with custom status messages
@@ -94,34 +98,55 @@ graph TD
- **13 built-in themes** — including `hacker` for when you want to feel like you're in a movie
- **Slash commands** — `/join`, `/send`, `/status`, `/theme`, etc.
- **Colored nicknames** — pick your hex color, express yourself
+- **Clickable everything** — usernames, @mentions, #channels — just press Enter
- **File/image sharing** — local files or URLs
- **Multi-server** — save and switch between servers
- **Auto-reconnect** — drops happen, it rejoins your channels automatically
+- **Auto-updater** — updates in-place with automatic rollback if something goes wrong
- **Message history** on join — you won't miss context
## Getting Started
-### Download
+### Install the Client
-Grab a self-contained binary from [Releases](../../releases) — no runtime needed, just run it.
+**Windows (Chocolatey):**
-### Prerequisites (for development)
+```bash
+choco install echohub
+```
-- [.NET 10 SDK](https://dotnet.microsoft.com/download)
+**Linux / macOS:**
-### Run the Server
+```bash
+curl -sSfL https://raw.githubusercontent.com/HueByte/EchoHub/master/scripts/install.sh | sh
+```
+
+**Manual download:** grab a self-contained binary from [Releases](../../releases) — no runtime needed, just run it.
+
+### Host a Server
+
+**Docker (recommended):**
+
+```bash
+cp .env.example .env
+docker compose up -d
+```
+
+Pre-built images on [GHCR](https://github.com/HueByte/EchoHub/pkgs/container/echohub-server) — `linux/amd64` and `linux/arm64`.
+
+**From source:**
```bash
dotnet run --project src/EchoHub.Server
```
-First run does everything for you:
+Requires [.NET 10 SDK](https://dotnet.microsoft.com/download). First run does everything for you:
1. Creates `appsettings.json` from the example config
2. Generates a secure JWT secret
3. Creates the database with a `#general` channel
-### Run the Client
+### Run the Client (from source)
```bash
dotnet run --project src/EchoHub.Client
@@ -165,7 +190,7 @@ irssi -c your-server.com -p 6667 -w -n
/connect echohub
```
-IRC users must have an existing EchoHub account (no registration via IRC). Auth works via `PASS`/`NICK`/`USER` or SASL PLAIN.
+Auth works via `PASS`/`NICK`/`USER` or SASL PLAIN. New usernames are auto-registered on first connect — no separate signup needed.
### What Works
diff --git a/docs/articles/configuration.md b/docs/articles/configuration.md
new file mode 100644
index 0000000..ab860f4
--- /dev/null
+++ b/docs/articles/configuration.md
@@ -0,0 +1,152 @@
+# Configuration
+
+EchoHub Server generates an `appsettings.json` with sensible defaults on first run (including a random JWT secret), so you can launch and start chatting immediately. Tweak things later when you feel like it.
+
+> [!NOTE]
+> Under the hood, EchoHub Server is built on ASP.NET Core, so it inherits the standard .NET configuration system. If you're familiar with that, everything works exactly as you'd expect. If not — no worries, this page covers everything you need.
+
+## How It Works
+
+EchoHub Server loads settings from multiple sources. Each source **overrides** the previous one, so you can layer defaults with environment-specific values:
+
+```text
+1. appsettings.json (base defaults)
+2. appsettings.{Environment}.json (e.g. appsettings.Production.json)
+3. Environment variables (great for Docker / CI)
+4. Command-line arguments (highest priority)
+```
+
+The last one wins. If `appsettings.json` says `"Irc:Port": 6667` but you pass `--Irc:Port=7000` on the command line, port 7000 is what you get.
+
+In practice this means you can leave `appsettings.json` alone and override just the settings you care about using environment variables or CLI flags — no need to edit JSON files if that's not your thing.
+
+### Environment Variable Mapping
+
+Environment variables use **double underscores** (`__`) in place of the JSON nesting. The rule is simple — replace every `:` (or each level of JSON nesting) with `__`:
+
+| appsettings.json path | Environment variable |
+| --- | --- |
+| `Server:Name` | `Server__Name` |
+| `Irc:Enabled` | `Irc__Enabled` |
+| `Jwt:Secret` | `Jwt__Secret` |
+| `Serilog:MinimumLevel:Default` | `Serilog__MinimumLevel__Default` |
+| `ConnectionStrings:DefaultConnection` | `ConnectionStrings__DefaultConnection` |
+
+Arrays use numeric indices: `Server:Admins:0` becomes `Server__Admins__0`, `Server:Admins:1` becomes `Server__Admins__1`, and so on.
+
+This is why the Docker `.env` file uses `Server__Name=My Server` instead of JSON — Docker passes these as environment variables, and the server picks them up automatically.
+
+### Examples
+
+All three of these achieve the same thing — use whichever fits your setup.
+
+**appsettings.json** (direct editing):
+
+```json
+{
+ "Server": {
+ "Name": "My EchoHub Server",
+ "PublicServer": true
+ }
+}
+```
+
+**Environment variables** (Docker, systemd, shell export):
+
+```bash
+export Server__Name="My EchoHub Server"
+export Server__PublicServer=true
+```
+
+**Command-line arguments** (quick overrides, highest priority):
+
+```bash
+./EchoHub.Server --Server:Name="My EchoHub Server" --Irc:Enabled=true
+```
+
+## Configuration Reference
+
+The full `appsettings.json` is auto-generated on first run from the [example config](https://github.com/HueByte/EchoHub/blob/master/src/EchoHub.Server/appsettings.example.json). Here's every option:
+
+### General
+
+| Key | Default | Description |
+| --- | --- | --- |
+| `Urls` | `http://0.0.0.0:5000` | Listen address and port |
+| `AllowedHosts` | `*` | Allowed host headers (leave `*` unless you need host filtering) |
+
+### Database
+
+| Key | Default | Description |
+| --- | --- | --- |
+| `ConnectionStrings:DefaultConnection` | *(empty)* | SQLite connection string. Empty = `echohub.db` in the app directory |
+
+### Authentication
+
+| Key | Default | Description |
+| --- | --- | --- |
+| `Jwt:Secret` | *(auto-generated)* | Signing key (min 32 chars). Auto-generated on first run |
+| `Jwt:Issuer` | `EchoHub.Server` | JWT issuer claim |
+| `Jwt:Audience` | `EchoHub.Client` | JWT audience claim |
+
+Access tokens expire after 15 minutes, refresh tokens after 30 days with rotation on each use.
+
+### Server Identity
+
+| Key | Default | Description |
+| --- | --- | --- |
+| `Server:Name` | `My EchoHub Server` | Display name shown to clients |
+| `Server:Description` | `A self-hosted EchoHub chat server` | Server description |
+| `Server:PublicServer` | `false` | Register on the [public directory](https://echohub.voidcube.cloud/servers) |
+| `Server:PublicHost` | *(empty)* | Public hostname for the directory listing (e.g. `chat.example.com:5000`) |
+| `Server:Admins` | `[]` | Array of admin usernames (e.g. `["alice", "bob"]`) |
+
+### Encryption
+
+| Key | Default | Description |
+| --- | --- | --- |
+| `Encryption:Key` | *(auto-generated)* | AES key for message encryption in transit |
+| `Encryption:EncryptDatabase` | `false` | Also encrypt message content at rest in SQLite |
+
+### Storage
+
+| Key | Default | Description |
+| --- | --- | --- |
+| `Storage:CleanupIntervalHours` | `1` | How often the cleanup job runs (hours) |
+| `Storage:RetentionDays` | `30` | Days to keep uploaded files before cleanup |
+
+### IRC Gateway
+
+| Key | Default | Description |
+| --- | --- | --- |
+| `Irc:Enabled` | `false` | Enable the IRC protocol gateway |
+| `Irc:Port` | `6667` | IRC plain-text listen port |
+| `Irc:TlsEnabled` | `false` | Enable TLS termination for IRC |
+| `Irc:TlsPort` | `6697` | IRC TLS listen port |
+| `Irc:TlsCertPath` | *(empty)* | Path to a PKCS#12 (`.pfx`) certificate |
+| `Irc:TlsCertPassword` | *(empty)* | Password for the certificate file |
+| `Irc:ServerName` | `echohub` | IRC server name in protocol messages |
+| `Irc:Motd` | `Welcome to EchoHub IRC Gateway!` | Message of the day |
+
+### Logging
+
+EchoHub uses [Serilog](https://serilog.net/) for structured logging — console output + daily rolling files with 14-day retention by default.
+
+| Key | Default | Description |
+| --- | --- | --- |
+| `Serilog:MinimumLevel:Default` | `Information` | Global log level (`Debug`, `Information`, `Warning`, `Error`) |
+| `Serilog:MinimumLevel:Override:Microsoft` | `Warning` | Suppress noisy framework logs |
+| `Serilog:MinimumLevel:Override:Microsoft.AspNetCore` | `Warning` | Suppress request pipeline logs |
+| `Serilog:MinimumLevel:Override:Microsoft.EntityFrameworkCore` | `Warning` | Suppress database query logs |
+
+Log files are written to `logs/echohub-server-YYYY-MM-DD.log`. To change the path or retention, edit the `Serilog:WriteTo` section in `appsettings.json`.
+
+Want more verbose output for debugging? Set the minimum level to `Debug`:
+
+```bash
+# via environment variable
+export Serilog__MinimumLevel__Default=Debug
+
+# or command line
+./EchoHub.Server --Serilog:MinimumLevel:Default=Debug
+```
diff --git a/docs/articles/docker.md b/docs/articles/docker.md
index dd60837..a159a35 100644
--- a/docs/articles/docker.md
+++ b/docs/articles/docker.md
@@ -24,26 +24,17 @@ services:
## Configuration
-All settings are configured through the `.env` file. These are ASP.NET Core environment variables that override `appsettings.json`.
+All settings are configured through the `.env` file. These are environment variables that override `appsettings.json` — the `__` (double underscore) maps to JSON nesting levels. For example, `Server__Name` overrides the `Server:Name` key in `appsettings.json`.
+
+See the [Configuration](configuration.md) guide for the full reference of all available settings and how the override hierarchy works.
+
+Common Docker-relevant variables:
| Variable | Default | Description |
| --- | --- | --- |
| `Server__Name` | My EchoHub Server | Display name for your server |
-| `Server__Description` | A self-hosted EchoHub chat server | Server description |
-| `Server__PublicServer` | `false` | List on the [public directory](https://echohub.voidcube.cloud/servers) |
-| `Server__PublicHost` | *(empty)* | Public address for the directory listing |
| `Server__Admins__0` | *(empty)* | Admin username (use `__1`, `__2` for more) |
-| `Jwt__Secret` | *(auto-generated)* | JWT signing key. Auto-generated on first run |
-| `Encryption__Key` | *(auto-generated)* | AES encryption key. Auto-generated on first run |
-| `Encryption__EncryptDatabase` | `false` | Encrypt message content in the database |
-| `Storage__CleanupIntervalHours` | `1` | How often to clean expired uploads |
-| `Storage__RetentionDays` | `30` | Days to keep uploaded files |
| `Irc__Enabled` | `false` | Enable the IRC gateway |
-| `Irc__Port` | `6667` | IRC plain-text port |
-| `Irc__TlsEnabled` | `false` | Enable IRC over TLS |
-| `Irc__TlsPort` | `6697` | IRC TLS port |
-| `Irc__ServerName` | `echohub` | IRC server name shown to clients |
-| `Irc__Motd` | Welcome to EchoHub IRC Gateway! | Message of the day |
| `Serilog__MinimumLevel__Default` | `Information` | Log level (`Debug`, `Warning`, etc.) |
## Persistent Data
diff --git a/docs/articles/getting-started.md b/docs/articles/getting-started.md
index 86ebd87..c248c1e 100644
--- a/docs/articles/getting-started.md
+++ b/docs/articles/getting-started.md
@@ -84,9 +84,9 @@ See the [Architecture](architecture.md) page for details on how the IRC gateway
## Configuration
-Server configuration is in `appsettings.json` (auto-generated on first run). See the [example config](https://github.com/HueByte/EchoHub/blob/master/src/EchoHub.Server/appsettings.example.json) for all available options.
+Server configuration is in `appsettings.json` (auto-generated on first run). You can also use environment variables or command-line arguments to override settings.
-To list your server on the [public directory](https://echohub.voidcube.cloud/servers), set `Server:PublicServer` to `true` and `Server:PublicHost` to your server's public address.
+See the [Configuration](configuration.md) guide for the full reference and how it all works.
## Build from Source
diff --git a/docs/articles/toc.yml b/docs/articles/toc.yml
index b371d95..73b66f1 100644
--- a/docs/articles/toc.yml
+++ b/docs/articles/toc.yml
@@ -1,10 +1,16 @@
-- name: Getting Started
- href: getting-started.md
-- name: Docker
- href: docker.md
-- name: Architecture
- href: architecture.md
-- name: Encryption
- href: encryption.md
-- name: Notification Sounds
- href: notification-sounds.md
+- name: Guides
+ items:
+ - name: Getting Started
+ href: getting-started.md
+ - name: Docker
+ href: docker.md
+ - name: Architecture
+ href: architecture.md
+ - name: Configuration
+ href: configuration.md
+ - name: Encryption
+ href: encryption.md
+ - name: Notification Sounds
+ href: notification-sounds.md
+- name: Flows
+ href: ../flows/toc.yml
diff --git a/docs/docfx.json b/docs/docfx.json
index 52df4c8..7608b47 100644
--- a/docs/docfx.json
+++ b/docs/docfx.json
@@ -85,7 +85,7 @@
"_appTitle": "EchoHub Documentation",
"_appLogoPath": "images/hue_icon.svg",
"_appFaviconPath": "images/hue_icon.svg",
- "_appFooter": "",
+ "_appFooter": "",
"_enableSearch": true,
"_disableContribution": false,
"_gitContribute": {
diff --git a/docs/flows/authentication.md b/docs/flows/authentication.md
index 036aaab..4f520e0 100644
--- a/docs/flows/authentication.md
+++ b/docs/flows/authentication.md
@@ -37,19 +37,6 @@ sequenceDiagram
CM->>CM: Continue to connection setup (see Connection Flow)
```
-**Code references:**
-
-| Step | File | Location |
-|------|------|----------|
-| Dialog UI | `src/EchoHub.Client/UI/Dialogs/ConnectDialog.cs` | Lines 251-268 (register handler) |
-| Orchestrator entry | `src/EchoHub.Client/AppOrchestrator.cs` | Lines 550-592 (`HandleConnect`) |
-| ConnectionManager auth | `src/EchoHub.Client/Services/ConnectionManager.cs` | Lines 74-76 (register branch) |
-| ApiClient register | `src/EchoHub.Client/Services/ApiClient.cs` | Lines 32-43 (`RegisterAsync`) |
-| AuthController register | `src/EchoHub.Server/Controllers/AuthController.cs` | Lines 28-49 |
-| UserService register | `src/EchoHub.Server/Services/UserService.cs` | Lines 20-59 (`RegisterUserAsync`) |
-| JWT generation | `src/EchoHub.Server/Auth/JwtTokenService.cs` | Lines 30-53 (access), 80-86 (refresh) |
-| Token persistence | `src/EchoHub.Client/AppOrchestrator.cs` | Lines 1039-1053 (`SaveServerToConfig`) |
-
---
## User Login
@@ -85,18 +72,6 @@ sequenceDiagram
API->>API: SetTokens()
```
-**Code references:**
-
-| Step | File | Location |
-|------|------|----------|
-| Login button handler | `src/EchoHub.Client/UI/Dialogs/ConnectDialog.cs` | Lines 214-249 |
-| Saved token branch | `src/EchoHub.Client/Services/ConnectionManager.cs` | Lines 69-71 |
-| Password branch | `src/EchoHub.Client/Services/ConnectionManager.cs` | Lines 78-80 |
-| ApiClient login | `src/EchoHub.Client/Services/ApiClient.cs` | Lines 45-56 (`LoginAsync`) |
-| AuthController login | `src/EchoHub.Server/Controllers/AuthController.cs` | Lines 51-72 |
-| AuthController refresh | `src/EchoHub.Server/Controllers/AuthController.cs` | Lines 74-108 |
-| UserService authenticate | `src/EchoHub.Server/Services/UserService.cs` | Lines 61-83 |
-
---
## Token Refresh
@@ -128,15 +103,3 @@ sequenceDiagram
API-->>Config: Persist new refresh token (if Remember Me)
API->>SR: Retry original request with new token
```
-
-**Code references:**
-
-| Step | File | Location |
-|------|------|----------|
-| Proactive check | `src/EchoHub.Client/Services/ApiClient.cs` | Lines 110-129 (`GetValidTokenAsync`) |
-| Reactive 401 retry (GET) | `src/EchoHub.Client/Services/ApiClient.cs` | Lines 338-358 (`AuthenticatedGetAsync`) |
-| Reactive 401 retry (POST/PUT/DELETE) | `src/EchoHub.Client/Services/ApiClient.cs` | Lines 364-384 (`AuthenticatedRequestAsync`) |
-| Refresh HTTP call | `src/EchoHub.Client/Services/ApiClient.cs` | Lines 58-71 (`RefreshTokenAsync`) |
-| SignalR token provider | `src/EchoHub.Client/Services/EchoHubConnection.cs` | Line 37 (`AccessTokenProvider`) |
-| Server-side rotation | `src/EchoHub.Server/Controllers/AuthController.cs` | Lines 74-108 |
-| Token persistence callback | `src/EchoHub.Client/Services/ConnectionManager.cs` | Lines 253-264 |
diff --git a/docs/flows/channels.md b/docs/flows/channels.md
index 278efab..3b2f267 100644
--- a/docs/flows/channels.md
+++ b/docs/flows/channels.md
@@ -33,14 +33,6 @@ sequenceDiagram
CC-->>Client: 201 Created (ChannelDto)
```
-**Code references:**
-
-| Step | File | Location |
-|------|------|----------|
-| Controller endpoint | `src/EchoHub.Server/Controllers/ChannelsController.cs` | Lines 60-76 |
-| Channel service create | `src/EchoHub.Server/Services/ChannelService.cs` | Lines 50-90 |
-| Broadcast updated | `src/EchoHub.Server/Services/ChatService.cs` | Lines 308-309 |
-
---
## Channel Deletion
@@ -65,13 +57,6 @@ sequenceDiagram
CC-->>Client: 204 No Content
```
-**Code references:**
-
-| Step | File | Location |
-|------|------|----------|
-| Controller endpoint | `src/EchoHub.Server/Controllers/ChannelsController.cs` | Lines 94-106 |
-| Channel service delete | `src/EchoHub.Server/Services/ChannelService.cs` | Lines 119-144 |
-
---
## Joining a Channel
@@ -114,17 +99,6 @@ sequenceDiagram
Entry-->>Client: History messages
```
-**Code references:**
-
-| Step | File | Location |
-|------|------|----------|
-| SignalR hub join | `src/EchoHub.Server/Hubs/ChatHub.cs` | Lines 59-81 |
-| IRC join | `src/EchoHub.Server.Irc/IrcCommandHandler.cs` | Lines 361-414 |
-| ChatService join | `src/EchoHub.Server/Services/ChatService.cs` | Lines 96-135 |
-| Presence join | `src/EchoHub.Server/Services/PresenceTracker.cs` | Lines 58-70 |
-| SignalR broadcast | `src/EchoHub.Server/Services/SignalRBroadcaster.cs` | Lines 26-32 |
-| IRC broadcast | `src/EchoHub.Server.Irc/IrcBroadcaster.cs` | Lines 34-41 |
-
---
## Leaving a Channel
@@ -148,12 +122,3 @@ sequenceDiagram
CS->>IRCB: SendUserLeftAsync(channel, username)
end
```
-
-**Code references:**
-
-| Step | File | Location |
-|------|------|----------|
-| SignalR hub leave | `src/EchoHub.Server/Hubs/ChatHub.cs` | Lines 83-96 |
-| IRC part | `src/EchoHub.Server.Irc/IrcCommandHandler.cs` | Lines 416-435 |
-| ChatService leave | `src/EchoHub.Server/Services/ChatService.cs` | Lines 137-143 |
-| Presence leave | `src/EchoHub.Server/Services/PresenceTracker.cs` | Lines 72-81 |
diff --git a/docs/flows/connection.md b/docs/flows/connection.md
index ff4ccaa..eb5d3e3 100644
--- a/docs/flows/connection.md
+++ b/docs/flows/connection.md
@@ -34,19 +34,6 @@ sequenceDiagram
EHC-->>CM: Decrypted history
```
-**Code references:**
-
-| Step | File | Location |
-|------|------|----------|
-| Connection orchestration | `src/EchoHub.Client/Services/ConnectionManager.cs` | Lines 58-140 (`ConnectAsync`) |
-| EchoHubConnection setup | `src/EchoHub.Client/Services/EchoHubConnection.cs` | Lines 29-62 (constructor) |
-| Handler registration | `src/EchoHub.Client/Services/EchoHubConnection.cs` | Lines 64-122 (`RegisterHandlers`) |
-| Hub OnConnected | `src/EchoHub.Server/Hubs/ChatHub.cs` | Lines 31-43 |
-| ChatService connected | `src/EchoHub.Server/Services/ChatService.cs` | Lines 41-57 |
-| PresenceTracker connect | `src/EchoHub.Server/Services/PresenceTracker.cs` | Lines 13-29 |
-| Join channel (hub) | `src/EchoHub.Server/Hubs/ChatHub.cs` | Lines 59-81 |
-| Join channel (service) | `src/EchoHub.Server/Services/ChatService.cs` | Lines 96-135 |
-
---
## IRC Client Connection
@@ -96,18 +83,6 @@ sequenceDiagram
Note over IRC,CH: Client is now ready for JOIN/PART/PRIVMSG
```
-**Code references:**
-
-| Step | File | Location |
-|------|------|----------|
-| TCP listener | `src/EchoHub.Server.Irc/IrcGatewayService.cs` | Lines 45-90 (`ExecuteAsync`) |
-| Client handler | `src/EchoHub.Server.Irc/IrcGatewayService.cs` | Lines 92-154 (`HandleClientAsync`) |
-| Command read loop | `src/EchoHub.Server.Irc/IrcCommandHandler.cs` | Lines 40-98 (`RunAsync`) |
-| SASL auth | `src/EchoHub.Server.Irc/IrcCommandHandler.cs` | Lines 136-207 (`HandleAuthenticateAsync`) |
-| PASS/NICK/USER | `src/EchoHub.Server.Irc/IrcCommandHandler.cs` | Lines 209-267 |
-| Registration completion | `src/EchoHub.Server.Irc/IrcCommandHandler.cs` | Lines 268-315 (`TryCompleteRegistrationAsync`) |
-| Cleanup on disconnect | `src/EchoHub.Server.Irc/IrcGatewayService.cs` | Lines 136-153 |
-
---
## User Disconnect & Presence
@@ -139,12 +114,3 @@ sequenceDiagram
end
end
```
-
-**Code references:**
-
-| Step | File | Location |
-|------|------|----------|
-| SignalR disconnect | `src/EchoHub.Server/Hubs/ChatHub.cs` | Lines 45-57 |
-| IRC cleanup | `src/EchoHub.Server.Irc/IrcGatewayService.cs` | Lines 136-153 |
-| ChatService disconnect | `src/EchoHub.Server/Services/ChatService.cs` | Lines 59-94 |
-| Presence disconnect | `src/EchoHub.Server/Services/PresenceTracker.cs` | Lines 31-53 |
diff --git a/docs/flows/media.md b/docs/flows/media.md
index f76d27b..637b55b 100644
--- a/docs/flows/media.md
+++ b/docs/flows/media.md
@@ -28,15 +28,6 @@ sequenceDiagram
CS->>CS: BroadcastToAllAsync → fan out to clients
```
-**Code references:**
-
-| Step | File | Location |
-|------|------|----------|
-| Upload endpoint | `src/EchoHub.Server/Controllers/ChannelsController.cs` | Lines 108-200 |
-| File validation | `src/EchoHub.Server/Services/FileValidationHelper.cs` | Lines 15-82 |
-| File storage | `src/EchoHub.Server/Services/FileStorageService.cs` | Lines 1-47 |
-| File download | `src/EchoHub.Server/Controllers/FilesController.cs` | Lines 22-53 |
-
---
## Link Embed Resolution
@@ -67,17 +58,6 @@ sequenceDiagram
Note over CS: Attached to MessageDto before broadcast
```
-**Code references:**
-
-| Step | File | Location |
-|------|------|----------|
-| Entry point | `src/EchoHub.Server/Services/LinkEmbedService.cs` | Lines 28-51 (`TryGetEmbedsAsync`) |
-| URL extraction | `src/EchoHub.Server/Services/LinkEmbedService.cs` | Lines 145-160 |
-| Private IP blocking | `src/EchoHub.Server/Services/LinkEmbedService.cs` | Lines 162-181 |
-| OG tag parsing | `src/EchoHub.Server/Services/LinkEmbedService.cs` | Lines 187-210 |
-| Theme color parsing | `src/EchoHub.Server/Services/LinkEmbedService.cs` | Lines 117-143 |
-| ChatService integration | `src/EchoHub.Server/Services/ChatService.cs` | Lines 194-201 |
-
---
## Server Directory Registration
@@ -107,12 +87,3 @@ sequenceDiagram
Note over SDS,Dir: Exponential backoff on disconnect (2s → 30s max)
```
-
-**Code references:**
-
-| Step | File | Location |
-|------|------|----------|
-| Service lifecycle | `src/EchoHub.Server/Services/ServerDirectoryService.cs` | Lines 29-122 |
-| Registration | `src/EchoHub.Server/Services/ServerDirectoryService.cs` | Lines 195-212 |
-| User count polling | `src/EchoHub.Server/Services/ServerDirectoryService.cs` | Lines 154-187 |
-| Reconnection backoff | `src/EchoHub.Server/Services/ServerDirectoryService.cs` | Lines 77-82, 191 |
diff --git a/docs/flows/messaging.md b/docs/flows/messaging.md
index 1811e5d..1b68a81 100644
--- a/docs/flows/messaging.md
+++ b/docs/flows/messaging.md
@@ -45,22 +45,6 @@ sequenceDiagram
end
```
-**Code references:**
-
-| Step | File | Location |
-|------|------|----------|
-| Input handler | `src/EchoHub.Client/UI/MainWindow.cs` | Lines 428-449 (`OnInputKeyDown`) |
-| Orchestrator dispatch | `src/EchoHub.Client/AppOrchestrator.cs` | Lines 631-661 (`HandleMessageSubmitted`) |
-| Client encrypt + send | `src/EchoHub.Client/Services/EchoHubConnection.cs` | Lines 148-153 (`SendMessageAsync`) |
-| Hub receive | `src/EchoHub.Server/Hubs/ChatHub.cs` | Lines 98-111 (`SendMessage`) |
-| ChatService process | `src/EchoHub.Server/Services/ChatService.cs` | Lines 145-241 (`SendMessageAsync`) |
-| Mute check | `src/EchoHub.Server/Services/ChatService.cs` | Lines 177-190 |
-| Link embeds | `src/EchoHub.Server/Services/LinkEmbedService.cs` | Lines 28-51 (`TryGetEmbedsAsync`) |
-| DB insert | `src/EchoHub.Server/Services/ChatService.cs` | Lines 208-221 |
-| Broadcast fan-out | `src/EchoHub.Server/Services/ChatService.cs` | Lines 311-324 (`BroadcastToAllAsync`) |
-| SignalR broadcast | `src/EchoHub.Server/Services/SignalRBroadcaster.cs` | Lines 23-24 |
-| IRC broadcast | `src/EchoHub.Server.Irc/IrcBroadcaster.cs` | Lines 17-32 |
-
---
## Sending a Message (IRC)
@@ -94,15 +78,6 @@ sequenceDiagram
end
```
-**Code references:**
-
-| Step | File | Location |
-|------|------|----------|
-| PRIVMSG handler | `src/EchoHub.Server.Irc/IrcCommandHandler.cs` | Lines 437-469 |
-| Channel name conversion | `src/EchoHub.Server.Irc/IrcCommandHandler.cs` | Line 680 (`IrcToEchoHubChannel`) |
-| ChatService (shared path) | `src/EchoHub.Server/Services/ChatService.cs` | Lines 145-241 |
-| IRC echo suppression | `src/EchoHub.Server.Irc/IrcBroadcaster.cs` | Lines 25-26 |
-
---
## Receiving a Message (TUI Client)
@@ -129,14 +104,6 @@ sequenceDiagram
end
```
-**Code references:**
-
-| Step | File | Location |
-|------|------|----------|
-| SignalR handler | `src/EchoHub.Client/Services/EchoHubConnection.cs` | Lines 64-71 |
-| Orchestrator receive | `src/EchoHub.Client/AppOrchestrator.cs` | Lines 372-383 |
-| @mention detection | `src/EchoHub.Client/AppOrchestrator.cs` | Lines 378-382 |
-
---
## Command Execution
@@ -199,12 +166,3 @@ sequenceDiagram
| `/users` | Local | Show userlist |
| `/help` | Local | Show help text |
| `/quit` | Local | Exit application |
-
-**Code references:**
-
-| Step | File | Location |
-|------|------|----------|
-| Command detection | `src/EchoHub.Client/AppOrchestrator.cs` | Lines 639-655 |
-| Command dispatch | `src/EchoHub.Client/Commands/CommandHandler.cs` | Lines 34-69 (`HandleAsync`) |
-| Command handlers wired | `src/EchoHub.Client/AppOrchestrator.cs` | Lines 97-117 |
-| Individual handlers | `src/EchoHub.Client/AppOrchestrator.cs` | Lines 122-350 |
diff --git a/docs/flows/moderation.md b/docs/flows/moderation.md
index 692fbd1..282eb22 100644
--- a/docs/flows/moderation.md
+++ b/docs/flows/moderation.md
@@ -36,15 +36,3 @@ sequenceDiagram
CS->>IRCB: ForceDisconnectUserAsync(connectionIds, reason)
CS->>DB: Set Status=Invisible, LastSeenAt=now
```
-
-**Code references:**
-
-| Step | File | Location |
-|------|------|----------|
-| Kick endpoint | `src/EchoHub.Server/Controllers/ModerationController.cs` | Lines 62-87 |
-| Ban endpoint | `src/EchoHub.Server/Controllers/ModerationController.cs` | Lines 89-112 |
-| Mute endpoint | `src/EchoHub.Server/Controllers/ModerationController.cs` | Lines 130-151 |
-| Force disconnect | `src/EchoHub.Server/Controllers/ModerationController.cs` | Lines 232-256 |
-| Mute expiration | `src/EchoHub.Server/Services/MuteExpirationService.cs` | Lines 22-62 |
-| Mute enforcement | `src/EchoHub.Server/Services/ChatService.cs` | Lines 177-190 |
-| Presence force remove | `src/EchoHub.Server/Services/PresenceTracker.cs` | Lines 161-178 |
diff --git a/docs/templates/echohub/public/main.css b/docs/templates/echohub/public/main.css
index ffcce11..abc2acf 100644
--- a/docs/templates/echohub/public/main.css
+++ b/docs/templates/echohub/public/main.css
@@ -49,6 +49,7 @@ header.top-navbar {
.navbar .navbar-brand svg {
height: 28px;
width: auto;
+ margin-right: 0.5em;
}
.navbar .nav-link {
@@ -320,19 +321,6 @@ footer {
color: #E6C06E;
}
-.footer-credit {
- color: #484f58;
- font-size: 0.85em;
-}
-
-.footer-credit a {
- color: #6e7681;
-}
-
-.footer-credit a:hover {
- color: #E6C06E;
-}
-
/* --- Scrollbar --- */
::-webkit-scrollbar {
width: 8px;
diff --git a/docs/toc.yml b/docs/toc.yml
index 7682921..c93ba17 100644
--- a/docs/toc.yml
+++ b/docs/toc.yml
@@ -1,9 +1,6 @@
- name: Articles
href: articles/
homepage: articles/getting-started.md
-- name: Flows
- href: flows/
- homepage: flows/flows.md
- name: Changelog
href: changelog/
homepage: changelog/index.md