2026-09-07 โ Bot Relay, Per-Node Routing & Dark Theme
Today we hardened the scorpiox-bot remote control stack:
- Fixed the iOS "access local network" prompt by enabling relay routing for
.3(nzxt:8151) and.6(lazarus:8152). - Upgraded the architecture from a single global route mode to per-node
RelayMode(direct,relay,auto) stored directly in SQL ServerRuntimeConfig. - Enabled resolving nodes by friendly names and slugs (
node=.3,node=nzxt,node=.6,node=lazarus) in bothrelay.candtools/runtimecfg. - Made the web shell stateless in JSON mode:
/?node=.3&format=jsonqueries and returns the node and its live tmux sessions in one shot. - Fixed dark theme styling on native select and option popups across desktop and mobile Safari.
- Implemented dedicated full-page edge-to-edge terminal endpoint
GET /terminal?id=<session>in pure C (terminal.c). Serves an xterm.js terminal with zero shell clutter, real-time SSE streaming, raw keystroke queue, auto-resizing viewport sync with tmux, 10-second anti-artifact screen refresh, HUD collapsible mode, and multi-node routing (node=.3,node=.6). - Integrated "Full Page" button in the Peek modal inside the shell web for one-click popup into the dedicated fullscreen terminal.
- Built
stats.jsonlive telemetry emission intoclang(sx_statusbar.c,libsxutil/sx_session.c,sx.c). The core engine now serializes full TUI statusbar telemetry (Anthropic cache countdown timerT mm:ss, keepalive stateKA:N, active callbacks[CB:count mm:ss], bash spinner, model, context max, and token metrics) to.scorpiox/sessions/<id>/stats.jsonatomically with 1 Hz throttling and 0ms turn-completion updates. - Released
clangx64 Linux build (0027acf) on .3 todist.scorpiox.netand updated fleet viascorpiox-update. Verifiedstats.jsonemission live in tmux test session. - Updated
scorpiox-bot-api(sessions.c) to read and inlinestats.jsonintoGET /sessionsresponses across.100,.3, and.6. - Upgraded
scorpiox-bot-web(index.c&terminal.c) with bottom statusbar telemetry and Read-Only spectator mode: - In
index.c, placed the.statusbar-paneldirectly UNDER the input box and send button (mirroringsx.c), rendering: - Up to 3 stacked lines of token history (
rsnin purple,Tin bold white,inin gray,Rin green,Win orange,outin cyan, ratelimits, and speed). - Bottom row:
๐ cwd,๐ฟ branch,CTX:250K,โ๏ธ bash,โฑ๏ธ CB, cache TTL timerT mm:ss,KA, and a clickable[๐ข OPERATOR]โ[๐ READONLY]toggle. - In Read-Only mode, input is disabled with spectator placeholder, send button is hidden, and prompts cannot be submitted. URL query
?ro=1automatically locks the view. - In
terminal.c, added cache countdown timer#hudTimerand#btnRoto the HUD bar, blocking keystroke transmission in Read-Only mode.
De-picobot: bot-web + bot-api treat picobot as a regular codebase (22:05 NZST)
User decision: picobot gets zero special cases โ no protected session, no hardcoded paths, no default session.
bot-api (67605c5 + 5d81368):
sessions.c: droppedpicobot->/codebases/picobot/picobot-<name>worktree guessing; cwd = tmux-reported worktree or empty.find_session_dirnow scans ALL session roots and returns(root, id); response gains arootfield.sxcommon.h: newcollect_session_roots()(explicitSCORPIOX_SESSIONS_DIRS, else primary + every/codebases/*/.scorpiox/sessionsthat exists โ 42 roots live) +foreach_session_dir().send.c,infobox.c,conversation.c: resolve tmux-name -> session dir in any root via worktree then bare-name match.conversationalso neededyyjson.o(Makefile fix).- Earlier: DELETE
/sessions403 guard for picobot already removed (4f07a28).
bot-web (cb9bae5):
terminal.c: nopicobotdefault (session: ""in JSON); browser auto-selects first live session from/sessions, falls back to session switcher.startStreamno-ops on empty session.index.cplaceholder, both READMEs,relay.ccomment example de-picoboted.
Left alone (live contracts): PICOBOT_PASSWORD/X-Picobot-Password, RuntimeType PICOBOT, JWT picobot perm, pico_* localStorage compat keys โ fleet + iOS depend on these; rename = migration.
Gotcha hit: .100's make said "up to date" while git log showed the new commit โ stale binaries served old code until make clean && make. Always clean-build on deploy.