# Bolt Console A desktop app for Bolt, in the style of Claude Code (with a terminal version too). You type, Bolt answers, and when he needs to look at or change something on this machine you see each step as it happens: reading files, listing folders, editing, writing, running commands. Changes wait for your **Allow** on the step itself, and edits show a diff first. It talks to the same Bolt server as Bolt-Pet, the Discord bot and the phone app, so it has the same brain, memory, tools and persona. What it drops is the desktop pet around it: no sprite, no wake word, no microphone, no speech, no screen reading. The window is PySide6 with its own dark theme. Header: working folder (click to change) and an **Ask first / Auto** switch. Below that: the conversation, with each tool call as a card that you can click to expand, and a composer at the bottom (Enter sends, Shift+Enter adds a new line, Ctrl+L clears, Ctrl+O picks a folder). **Chats** (Ctrl+K) lists every conversation you've had with Bolt, from any device (console, pet, phone), newest first. Open one to continue it. **New chat** (Ctrl+N, or the button in the Chats dialog) asks the server for a fresh chat: new conversation history, but Bolt still remembers you, because his memory belongs to you, not to a chat. Switching clears the window's transcript, since the server has no endpoint for an old chat's messages, although Bolt still has them. The current chat is remembered across restarts. The terminal version has `/chats`, `/chat ` and `/new`. **Dictation:** the mic button next to Send (or Ctrl+M) records you and types what you say into the box as you talk. Click again or pause for 3 seconds to stop, and Esc cancels. The text isn't sent until you press Enter, so you can fix it first. It uses the same speech-to-text as Bolt-Pet: the Bolt server's `/desk/stt` relay to Deepgram, so you don't need a Deepgram account. The server does count it against your credits like a chat turn. `MIC_DEVICE` in `.env` picks the microphone. The terminal version (`run-cli.bat` / `./run.sh --cli`) looks like this: ``` > what's taking up space in this repo? ● List(C:\work\site, recursive) ⎿ assets/ assets/hero.mp4 48211332B ... +212 lines ● Shell(du -sh assets/* | sort -h | tail -5) Run this command? [y]es / [n]o / [a]lways this session y ⎿ 48M assets/hero.mp4 ... ● Most of it is one file: assets/hero.mp4 at 48 MB. ... ``` ## Setup ```bash cp .env.example .env # set BOLT_SERVER_URL and DESK_API_KEY run.bat # Windows: the window run-cli.bat # Windows: the terminal version ./run.sh [--cli] # macOS/Linux ``` The launchers create `.venv` on first run. Dependencies: `requests`, plus `PySide6` for the window (the terminal version doesn't import Qt). Bolt works in the directory you **launch from**, so you can put the launcher on your PATH and start it inside whatever project you want him to work on. ```bash run.bat --auto # don't ask before commands, writes and edits run-cli.bat -p "summarise README.md" # one message, print the reply, exit run-cli.bat --doctor [--deep] # check the install (--deep contacts the server) ``` ## Using the terminal version | Input | What it does | |---|---| | any text | sent to Bolt | | `!` | runs a shell command yourself. Nothing is sent to Bolt | | `/cd `, `/pwd` | change or show the working directory | | `/ask`, `/auto` | turn approval prompts on or off for this session | | `/status` | server, session, approval mode, working directory | | `/files` | download anything Bolt has queued for you | | `/new` | start a fresh chat (same as New chat in the window) | | `/chats`, `/chat ` | list your chats from every device; switch to number n (or a session id) | | `/clear` | clear the screen. Bolt's memory lives on the server and is kept | | `/help`, `/exit` | | | line ending in `\` | keep typing on the next line | Ctrl+C stops the spinner and gives the prompt back. The server may still finish that turn on its side. At an approval prompt, Ctrl+C means no. ## How Bolt reaches this machine The desk API has one tool channel: the server sends back a `command` string, the client runs it and posts the output to `/desk/tool_result`, and this repeats until a final reply. The console decides what each string means (`bolt_console/tools.py`): - **`filectl {json}`**: list, read, write or edit a file (`file_ops.py`). This is what makes file editing reliable, because the model never has to hand-quote a shell heredoc. Edits must match exactly once. Common JSON slips, such as a raw `C:\Users\...` path, are repaired and the model is told about the repair. - **`petctl …` / `dialoguectl …`**: the pet's body and voice. These are not run. Bolt is told there's no pet here. - **anything else**: a real shell command, run in the working directory, with a `COMMAND_TIMEOUT_SECONDS` limit (default 120s). Reads and listings never ask. Shell commands, writes and edits ask first in `ask` mode (the default). Edits show a diff before you answer. ## Security Anything you approve runs as your user, with your permissions. In `auto` mode that means anything the server asks for. Keep `DESK_API_KEY` private and don't expose the desk API to the open internet. Each message includes your working directory and OS name (`CONSOLE_CONTEXT=false` to stop that). ## Development ```bash QT_QPA_PLATFORM=offscreen .venv/bin/pytest tests/ # Windows: .venv\Scripts\pytest tests ``` `tests/test_gui.py` drives turns through the real window and its worker thread against the same loopback server. `tests/test_console.py` runs whole turns against a real HTTP server on a loopback port. Only the keyboard is faked. Everything else takes its collaborators as arguments, so no test needs a real terminal or server. This project started as a copy of Bolt-Pet. See that repo for the voice/desktop-pet version.