146 lines
3.9 KiB
Markdown
146 lines
3.9 KiB
Markdown
# Yonexus.Server
|
|
|
|
Yonexus.Server is the central hub plugin for a Yonexus network.
|
|
|
|
It runs on the main OpenClaw instance and is responsible for:
|
|
|
|
- accepting WebSocket connections from follower instances
|
|
- enforcing the `followerIdentifiers` allowlist
|
|
- driving pairing and authenticated reconnects
|
|
- tracking heartbeat/liveness state
|
|
- rewriting inbound client rule messages before dispatch
|
|
- sending pairing notifications to the human admin via Discord DM
|
|
|
|
## Status
|
|
|
|
Current state: **core runtime MVP with Discord DM transport wired via REST API**
|
|
|
|
Implemented in this repository today:
|
|
|
|
- config validation
|
|
- runtime lifecycle wiring
|
|
- JSON persistence for durable trust records
|
|
- WebSocket transport and single-active-connection promotion model
|
|
- pairing session creation
|
|
- auth proof validation flow
|
|
- heartbeat receive + liveness sweep
|
|
- rule registry + send-to-client APIs
|
|
- Discord DM pairing notifications via Discord REST API (`notifyBotToken` + `adminUserId`)
|
|
|
|
Still pending before production use:
|
|
|
|
- broader lifecycle integration with real OpenClaw plugin hooks
|
|
- more operator-facing hardening / troubleshooting polish
|
|
- expanded edge-case and live-environment validation beyond the current automated suite
|
|
|
|
## Install Layout
|
|
|
|
This repo expects the shared protocol repo to be available at:
|
|
|
|
```text
|
|
protocol/
|
|
```
|
|
|
|
In the umbrella repo this is managed as a submodule.
|
|
|
|
## Configuration
|
|
|
|
Required config shape:
|
|
|
|
```json
|
|
{
|
|
"followerIdentifiers": ["client-a", "client-b"],
|
|
"notifyBotToken": "<discord-bot-token>",
|
|
"adminUserId": "123456789012345678",
|
|
"listenHost": "0.0.0.0",
|
|
"listenPort": 8787,
|
|
"publicWsUrl": "wss://example.com/yonexus"
|
|
}
|
|
```
|
|
|
|
### Field notes
|
|
|
|
- `followerIdentifiers`: allowlisted client identifiers
|
|
- `notifyBotToken`: bot token used for pairing notifications
|
|
- `adminUserId`: Discord user that receives pairing DMs
|
|
- `listenHost`: optional bind host, defaults to local runtime handling
|
|
- `listenPort`: required WebSocket listen port
|
|
- `publicWsUrl`: optional public endpoint to document/share with clients
|
|
|
|
## Runtime Overview
|
|
|
|
Startup flow:
|
|
|
|
1. validate config
|
|
2. load persisted trust records
|
|
3. ensure allowlisted identifiers have base records
|
|
4. start WebSocket transport
|
|
5. start liveness sweep timer
|
|
|
|
Connection flow:
|
|
|
|
1. unauthenticated socket connects
|
|
2. client sends `hello`
|
|
3. server decides `pair_required`, `waiting_pair_confirm`, or `auth_required`
|
|
4. if needed, server creates a pending pairing request and notifies admin out-of-band
|
|
5. client confirms pairing or authenticates with signed proof
|
|
6. authenticated connection is promoted to the active session for that identifier
|
|
|
|
## Public API Surface
|
|
|
|
Exported runtime helpers currently include:
|
|
|
|
```ts
|
|
sendMessageToClient(identifier: string, message: string): Promise<boolean>
|
|
sendRuleMessageToClient(identifier: string, ruleIdentifier: string, content: string): Promise<boolean>
|
|
registerRule(rule: string, processor: (message: string) => unknown): void
|
|
```
|
|
|
|
Rules:
|
|
|
|
- `builtin` is reserved and cannot be registered
|
|
- server-side dispatch expects rewritten client-originated messages in the form:
|
|
|
|
```text
|
|
${rule_identifier}::${sender_identifier}::${message_content}
|
|
```
|
|
|
|
## Persistence
|
|
|
|
Durable state is stored as JSON and includes at least:
|
|
|
|
- identifier
|
|
- pairing status
|
|
- public key
|
|
- secret
|
|
- pairing metadata
|
|
- heartbeat / auth timestamps
|
|
- last known liveness status
|
|
|
|
Rolling nonce and handshake windows are intentionally rebuilt on restart in v1.
|
|
|
|
## Development
|
|
|
|
Install dependencies and run type checks:
|
|
|
|
```bash
|
|
npm install
|
|
npm run check
|
|
```
|
|
|
|
## Limitations
|
|
|
|
Current known limitations:
|
|
|
|
- DM delivery depends on Discord bot permissions and the target user's DM settings
|
|
- no offline message queueing
|
|
- no multi-server topology
|
|
- no management UI
|
|
- transport is covered mainly by automated tests rather than live Discord end-to-end validation
|
|
|
|
## Related Repos
|
|
|
|
- Umbrella: `../`
|
|
- Shared protocol: `../Yonexus.Protocol`
|
|
- Client plugin: `../Yonexus.Client`
|