Add embedded web chat client (closes #7) #8

Merged
clawbot merged 22 commits from feature/web-client into main 2026-02-11 03:02:42 +01:00
Collaborator

Implements the embedded web chat client as described in #7.

Changes

  • Migration 003: users, channel_members, messages tables
  • C2S HTTP API: 13 endpoints for registration, channels, messages, DMs, polling
  • Preact SPA: IRC-style UI with tabs, user list, dark theme (~19KB bundle)
  • embed.FS: SPA served at GET / from the single Go binary

See issue #7 for full architecture details and engineering rationale.

Implements the embedded web chat client as described in #7. ## Changes - **Migration 003**: `users`, `channel_members`, `messages` tables - **C2S HTTP API**: 13 endpoints for registration, channels, messages, DMs, polling - **Preact SPA**: IRC-style UI with tabs, user list, dark theme (~19KB bundle) - **embed.FS**: SPA served at `GET /` from the single Go binary See issue #7 for full architecture details and engineering rationale.
sneak was assigned by clawbot 2026-02-10 18:22:55 +01:00
clawbot added 1 commit 2026-02-10 18:22:55 +01:00
- New DB schema: users, channel_members, messages tables (migration 003)
- Full C2S HTTP API: register, channels, messages, DMs, polling
- Preact SPA embedded via embed.FS, served at GET /
- IRC-style UI: tab bar, channel messages, user list, DM tabs, /commands
- Dark theme, responsive, esbuild-bundled (~19KB)
- Polling-based message delivery (1.5s interval)
- Commands: /join, /part, /msg, /nick
clawbot added 4 commits 2026-02-10 19:20:20 +01:00
- HandleState returns user info (id, nick) + joined channels in one response
- HandleGetMessages now serves unified message stream (was HandlePoll)
- HandleSendMessage accepts 'to' field for routing to #channel or nick
- HandleGetHistory supports scrollback for channels and DMs
- Remove separate HandleMe, HandleListChannels, HandleSendDM, HandleGetDMs, HandlePoll
- GET /api/v1/state replaces /me and /channels
- GET/POST /api/v1/messages replaces /poll, /channels/{ch}/messages, /dm/{nick}/messages
- GET /api/v1/history for scrollback
- DELETE /api/v1/channels/{name} replaces /channels/{channel}/part
- Use /state instead of /me for auth check
- Use /messages instead of /poll for message stream
- Use unified POST /messages with 'to' field for all sends
- Update part channel URL to DELETE /channels/{name}
- Document simplified endpoint structure
- Single message stream (GET /messages) for all message types
- Unified send (POST /messages) with 'to' field
- GET /state replaces separate /me and /channels
- GET /history for scrollback
- Update project status
clawbot added 1 commit 2026-02-10 19:21:13 +01:00
clawbot added 1 commit 2026-02-10 19:25:44 +01:00
C2S (7): send, join, part, nick, topic, mode, ping
S2C (12): message, dm, notice, join, part, quit, nick, topic, mode, system, error, pong
S2S (6): relay, link, unlink, sync, ping, pong

Each message type has its own schema file under schema/{c2s,s2c,s2s}/.
schema/README.md provides an index of all types with descriptions.
clawbot added 4 commits 2026-02-10 19:26:59 +01:00
Add JSON Schema definitions for all message types:
- Base message envelope (message.schema.json)
- C2S: PRIVMSG, NOTICE, JOIN, PART, QUIT, NICK, MODE, TOPIC, KICK, PING, PUBKEY
- S2C: named commands + numeric reply codes (001, 002, 322, 353, 366, 372, 375, 376, 401, 403, 433)
- S2S: RELAY, LINK, UNLINK, SYNC, PING, PONG
- Schema index (schema/README.md)

All messages use IRC command names and numeric codes from RFC 1459/2812.
Bodies are always objects or arrays (never raw strings) to support
deterministic canonicalization (RFC 8785 JCS) and message signing.
- Add IRC command/numeric mapping tables (C2S, S2C, S2S)
- Document structured message bodies (array/object, never raw strings)
- Document RFC 8785 JCS canonicalization for deterministic hashing
- Document Ed25519 signing/verification flow with TOFU key distribution
- Document PUBKEY message type for public key announcement
- Update message examples to use IRC command format
- Update curl examples to use command-based messages
- Note web client as convenience UI; primary interface is IRC-style clients
- Add schema/ to project structure
Remove schema/commands/ and schema/message.json, replaced by
the new schema/{c2s,s2c,s2s}/*.schema.json structure.
clawbot added 1 commit 2026-02-10 19:31:29 +01:00
Replace c2s/s2c/s2s taxonomy with IRC-native structure:
- schema/commands/ — IRC command schemas (PRIVMSG, NOTICE, JOIN, PART,
  QUIT, NICK, TOPIC, MODE, KICK, PING, PONG)
- schema/numerics/ — IRC numeric reply codes (001-004, 322-323, 332,
  353, 366, 372-376, 401, 403, 433, 442, 482)
- schema/message.json — base envelope mapping IRC wire format to JSON

Messages use 'command' field with IRC command names or 3-digit numeric
codes. 'body' is a string (IRC trailing parameter), not object/array.
'from'/'to' map to IRC prefix and first parameter.

Federation uses the same IRC commands (no custom RELAY/LINK/SYNC).

Update README message format, command tables, and examples to match.
clawbot added 1 commit 2026-02-10 19:36:06 +01:00
Message bodies are always arrays of strings (text lines) or objects
(structured data like PUBKEY). Never raw strings. This enables:
- Multiline messages without escape sequences
- Deterministic JSON canonicalization (RFC 8785 JCS) for signing
- Structured data where needed

Update all schemas: body fields use array type with string items.
Update message.json envelope: body is oneOf[array, object], id is UUID.
Update README: message envelope table, examples, and canonicalization docs.
Update schema/README.md: field types, examples with array bodies.
clawbot added 1 commit 2026-02-10 19:36:57 +01:00
Dedicated JSON Schema for the PUBKEY command — announces/relays
user signing public keys. Body is a structured object with alg
and key fields. Already documented in README; this adds the
schema file and index entry.
clawbot added 1 commit 2026-02-10 20:51:08 +01:00
Adds cmd/chat-cli/ with:
- tview-based irssi-like TUI (message buffer, status bar, input line)
- IRC-style commands: /connect, /nick, /join, /part, /msg, /query,
  /topic, /names, /list, /window, /quit, /help
- Multi-buffer window model with Alt+N switching and unread indicators
- Background long-poll goroutine for message delivery
- Clean API client wrapper in cmd/chat-cli/api/
- Structured types matching the JSON message protocol
clawbot added 4 commits 2026-02-11 02:53:55 +01:00
All client-to-server commands now go through POST /api/v1/messages
with a 'command' field. The server dispatches by command type:

- PRIVMSG/NOTICE: send message to channel or user
- JOIN: join channel (creates if needed)
- PART: leave channel
- NICK: change nickname
- TOPIC: set channel topic
- PING: keepalive (returns PONG)

Removed separate routes:
- POST /channels/join
- DELETE /channels/{channel}
- POST /register (renamed to POST /session)
- GET /channels/all (moved to GET /channels)

Added DB methods: ChangeNick, SetTopic
- JoinChannel/PartChannel now send via POST /messages with command field
- ListChannels uses /channels instead of /channels/all
- gofmt whitespace fixes
- Session creation uses /session instead of /register
- JOIN/PART via POST /messages with command field
- NICK changes via POST /messages with NICK command
- Messages sent as PRIVMSG commands with body array
- DMs use PRIVMSG command format
- Document all C2S commands with required/optional fields table
- Remove separate join/part/nick/topic endpoint docs
- Update /channels/all to /channels
- Update /register to /session
clawbot added 1 commit 2026-02-11 02:55:00 +01:00
Explains why the protocol is IRC over HTTP (not a new protocol borrowing
IRC names), the four specific changes from IRC (HTTP transport, server-held
sessions, structured bodies, message metadata), and why the C2S command
dispatch resembles but is not JSON-RPC.
clawbot added 1 commit 2026-02-11 02:55:15 +01:00
clawbot added 1 commit 2026-02-11 02:55:18 +01:00
clawbot merged commit df2217a38b into main 2026-02-11 03:02:42 +01:00
Sign in to join this conversation.
No reviewers
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: sneak/chat#8
No description provided.