Wednesday, 16 July 2026
Brainstormed and scaffolded rokojori-tunnel — user-based local tunneling service.
New standalone service at C:\rokojori\projects\web-projects\tunnel,
same stack as the rest of the ecosystem (Node.js, Express, ts-node, JSON file
storage, shared JWT verification).
source/server/db.ts — JSON file storage for tunnel configs
(build/data/db/tunnels.json)source/server/middleware/requireAuth.ts — JWT verification,
same pattern as rokojori-authsource/server/relay/TunnelRegistry.ts — in-memory
Map<tunnelId, WebSocket> of active agent connectionssource/server/relay/pending.ts — pending request callbacks
keyed by reqId for matching responses to waiting HTTP connectionssource/server/routes/tunnels.ts — full CRUD plus
GET /api/tunnels/available?purpose= discovery endpointsource/server/routes/agent.ts — WebSocket upgrade handler;
verifies JWT, confirms ownership, registers socket in registrysource/server/routes/proxy.ts — ALL /t/:tunnelId/*
relay; soft auth check for access mode, raw body forwarding, 30s timeoutsource/server/index.ts — Express + HTTP server with manual
WebSocket upgrade routing; JSON middleware applied only to /api
routes so proxy receives raw body streamsscripts/test-agent.ts — standalone Node.js agent for
testing before the Electron app exists; connects via WebSocket and forwards
inbound relay requests to a local port
Registered a tunnel via POST /api/tunnels, started the test agent
forwarding to port 8900 (gemma4-coding-Q4_K_M.gguf running locally),
and sent an OpenAI-compatible /v1/chat/completions request through
the relay. Full round-trip succeeded — request forwarded, response relayed back,
streaming token count confirmed in the response.
New plan document at workspace/outline/tunneling.html covering:
the relay mechanic (three-leg model, minimal inspection, raw byte forwarding),
access modes (private / public / password-protected), tunnel metadata shape and
purpose tags, all three components (relay server, Electron agent app, rokojori-auth
permission), API endpoint reference, Roject LLM provider integration example,
file structure, and phased implementation plan.
Separate service, not part of rokojori-auth. Auth stays focused on identity. tunnel.rokojori.com is its own Express process that verifies the shared JWT but owns all relay logic independently.
HTTP-only for Phase 1. Stable Diffusion (AUTOMATIC1111) and OpenAI-compatible LLMs (Ollama, LM Studio) all speak HTTP with SSE streaming — no WebSocket from the app side needed. Language servers use raw TCP and are out of scope for now.
JSON envelope protocol for Phase 1. Requests and responses are
wrapped as { reqId, method, path, headers, body (base64) } JSON
messages over the agent WebSocket. No raw byte framing needed at this stage;
the JSON envelope is simple enough and sidesteps binary WebSocket complexity.
No express.json() on proxy routes. The JSON middleware is applied
only to /api/tunnels so the proxy handler always receives a raw
readable body stream, regardless of content type.