A Discord-first, agentic web dev bot in Doc Sportello’s voice. It builds pages, features, and small apps into src/, pushes to GitHub Pages, and exposes an in-browser GUI to observe tool calls, file edits, and agent loops in real time.
Live site: https://bot.inference-arcade.com/
Repo: https://github.com/milwrite/javabot/
What it does
- Generates new pages/features and ships them to
src/with mobile-first styling. - Fixes and edits existing files by invoking repo tools via OpenRouter tool-calling.
- Runs a 4‑agent content pipeline (Architect → Builder → Tester → Scribe) for bigger builds.
- Commits/pushes to GitHub (auto-deploy to Pages) and logs everything to a local GUI.
Design system
- Theme: Noir Terminal (sky blue
#7ec8e3, red#ff0000, cyan#00ffff, near‑black#0a0a0a). - Type:
Courier Primemonospace via Google Fonts. - Shared CSS:
page-theme.css(home-link, components, mobile controls patterns). - Optional starfield: include
../stars.json a page to render a twinkling sky.
- Node 18+ recommended
- Copy
.env.example→.envand set:DISCORD_TOKEN— Bot tokenDISCORD_CLIENT_ID— Application client IDGITHUB_TOKEN— PAT withreposcopeGITHUB_REPO_OWNER— e.g.,milwriteGITHUB_REPO_NAME— e.g.,javabotGITHUB_REPO_URL— repo HTTPS URL (used in embeds)OPENROUTER_API_KEY— OpenRouter keyCHANNEL_ID— optional, comma‑separated channel IDs to restrict handlingGUI_PORT— optional, GUI port (default3001)NO_GUI— set totrueto disable the GUIDATABASE_URL— PostgreSQL connection string for long-term logging (Railway)
Install and run:
npm installnpm start(ornpm run devwith nodemon)- Optional launcher with log preservation:
./run-bot.sh [--no-gui] [--gui-port 3002]
Top‑level
index.js— Discord orchestrator, tool implementations, agent loop, command handlers, git and OpenRouter wiring.services/— integrations + pipeline orchestrators:llmClient.js— OpenRouter client + role prompts (Architect/Builder/Tester/Scribe)gamePipeline.js— plans → builds → tests → docs (returns files + live URL)buildLogs.js— structured logs per build; summarizes recurrent issuesrequestClassifier.js— LLM classifier (create vs fix vs edit vs read‑only)postgres.js— PostgreSQL logging service (events, tool calls, errors)
agents/— role prompts and logic wrappers used by the pipelinegameArchitect.js,gameBuilder.js,gameTester.js,gameScribe.js
gui-server.js+gui/— Express + Socket.IO dashboard with panels for logs, tool calls, file changes, agent loops- Frontend site:
index.htmlhub renders fromprojectmetadata.jsonsrc/pages and demos;page-theme.cssshared theme;stars.jsoptional effectgenerateSiteInventory.jsbuildsSITE_INVENTORY.md(auto‑runs onDEVLOG.mdchanges)
Data & memory
projectmetadata.json— canonical page list + collections powering the homepage.agents.md— rolling memory: summary of older chat + last ~15 messages.build-logs/*.json— per‑build pipeline logs (used for pattern summaries).responses/— full text for outputs > 2,000 chars (Discord limit safe‑keeping).
Slash commands
client.once('clientReady', ...)registers commands (guild‑scoped ifCHANNEL_IDset, else global).interactionCreatedispatches to handlers (e.g.,handleBuildGame,handleCommit).- Some flows show confirmation buttons (e.g., commit) using message components.
@ Mentions
messageCreatetracks history and routes mentions tohandleMentionAsync.requestClassifiercalls OpenRouter to decide the path:- CREATE_NEW →
runGamePipeline(...)(Architect → Builder → Tester → Scribe). - FUNCTIONALITY_FIX or SIMPLE_EDIT → normal agent loop with repo tools.
- READ_ONLY → direct LLM answer (no file edits).
- CREATE_NEW →
- Long answers are truncated in Discord and saved fully to
responses/.
Content pipeline (services/gamePipeline.js)
- Architect: classify type, produce plan (files, slug, features, collection).
- Builder: generate complete HTML/JS with required mobile/UX constraints.
- Tester: automated checks + LLM validation, produce score and issues.
- Scribe: documentation + metadata; updates
projectmetadata.json. - Caller commits/pushes; live page at
https://.../src/<slug>.html.
Available to the LLM via OpenRouter function‑calling; implemented in index.js:
list_files(path | paths[])— list directory contents.search_files(pattern, path | paths[], options)— grep‑like search across files.read_file(path | paths[])— read one or many files (size‑capped).write_file(path, content)— create/overwrite a file.edit_file(path, old_string?, new_string?, instructions?)— prefer exact replace; fall back to instruction‑based edit.delete_file(path)— delete a file from repository.move_file(old_path, new_path)— move or rename a file.commit_changes(message, files='.')— stage/commit/push.get_repo_status()— branch and changed files, plus live site link.git_log(count?, file?, oneline?)— view commit history.web_search(query)— callsperplexity/sonarvia OpenRouter for sources.deep_research(query)— comprehensive research with citations (1-3 min).set_model(model)— switch model preset.
Agent loop details:
- Tool loop runs up to 6 iterations; logs each iteration to the GUI.
- After a “primary action” (create/edit/commit/build), the bot requests one last natural text reply with
tool_choice: 'none'and exits.
- Discord:
discord.jsv14 (slash commands, buttons, embeds; intents include Guilds, Messages, Reactions, Message Content). - OpenRouter:
chat/completionswith model presets (GLM/Kimi/DeepSeek/Qwen/MiMo/Minimax); axios‑retry, timeouts, structured tool calls. - GitHub:
simple-gitfor add/commit/push; GitHub Pages deploys frommain. Remote URL is set with a tokenized HTTPS on push. - Perplexity:
perplexity/sonarmodel via OpenRouter for web search. - GUI: Express + Socket.IO server at
http://localhost:${GUI_PORT||3001}(disable withNO_GUI=true).
/commit <message> [files]— staged commit with confirm buttons; pushes tomain./status— branch and changed files summary + live URL./search <query>— web search via Perplexity (saved toresponses/if long)./set-model <model>—glm|kimi|deepseek|qwen|mimo|minimax./poll <question>— quick yes/no reactions./deep-research <query>— comprehensive research with citations (1-3 min)./logs <recent|errors|stats>— query PostgreSQL logs (requires DATABASE_URL).
Note: Content creation (pages, games, features) is done via @mentions using write_file tool, not slash commands.
index.htmlrenders collections and links fromprojectmetadata.json.- Pages live at
https://bot.inference-arcade.com/src/<page>.html. - Include the back/home link:
<a href="../index.html" class="home-link">← HOME</a>. - Use
page-theme.cssclasses/components; follow mobile‑first guidance. generateSiteInventory.jswritesSITE_INVENTORY.md; a watcher updates it wheneverDEVLOG.mdchanges.
- URL
https://bot.inference-arcade.com/src/filename.htmlmaps to filesrc/filename.html. - The edit loop extracts filenames from URLs and edits
src/accordingly.
- GUI Dashboard:
http://localhost:3001(orGUI_PORT); panels for logs, tool calls, file changes, agent loops. - Build logs:
build-logs/<id>.jsonwith stage-by-stage entries; summaries inform the architect prompt. - Long outputs: written under
responses/and linked from Discord. - Memory file:
agents.md(recent messages + optional summary).
- The bot sets the remote URL with a tokenized HTTPS string to push. Consider a GitHub App or ephemeral credential helpers for tighter security (see ARCHITECTURE_REVIEW.md).
- Restrict channels via
CHANNEL_IDto avoid unintended triggers.
- Start with GUI:
npm start(or./run-bot.sh). - Disable GUI:
NO_GUI=true npm start. - Test the GUI standalone:
node test-gui.js. - New pages/features appear on the live site after GitHub Pages deploys (usually 1–2 minutes).
javabot/
├── index.js # Discord orchestrator, tools, agent loop
├── services/ # OpenRouter + pipeline + logs + classifier
├── agents/ # Architect/Builder/Tester/Scribe wrappers
├── gui-server.js, gui/ # Local dashboard (logs/tools/files/loops)
├── index.html # Hub rendering from projectmetadata.json
├── page-theme.css, stars.js # Shared styling and optional background
├── src/ # All shipped pages and demos
├── projectmetadata.json # Canonical metadata used by the hub
├── generateSiteInventory.js # Builds SITE_INVENTORY.md on DEVLOG changes
├── build-logs/, responses/ # Pipeline logs and long outputs
└── agents.md # Rolling memory for context
- Commands not visible: Ensure slash commands registered (check bot logs after
clientReady) and the bot has the correct scopes in your server. - No edits happening: Confirm
OPENROUTER_API_KEYand model availability; check GUI Tool Calls panel. - Push/auth errors: verify
GITHUB_TOKENscope and that origin remote is updated; see logs. - Live page 404: wait 1–2 minutes for GitHub Pages; confirm URL has
/src/segment.
—
See ARCHITECTURE_REVIEW.md for current issues and suggested improvements.