Vobuda
Download Hoe het werktClaude Codevs CodexVergelijk Over ons Contact

The command line, as a product

Every button, key and menu item runs an action by name, and the same names are reachable from a shell. What the window shows is readable as JSON, and what changes in it is a stream a script can follow.

No socket, no port, no service

A command is a file written into the settings folder, and the window sees the change. Nothing listens on a network address and nothing runs in the background of its own. That is also why the interface checks drive the whole program through this command line: what it does for a script is what the buttons do for a hand.

The command line is installed with the program at ~/.config/vobuda/bin/vobuda. Link it into /usr/local/bin or call it by its path. VOBUDA_CONFIG points it at another settings folder, and every command then affects only the window on that folder, which is how a check drives its own instance without touching a working window. vobuda mcp offers the same commands to an agent as MCP tools.

Reading the window

Four commands that only look. Nothing here changes the window.

CommandWhat it givesExample
vobuda stateThe window as JSON: tabs, the block tree, what runs in each block, its folder, its listening ports, the prompt marks, the copy of the project it sits in, the open panel, the theme, the agents' numbers. Per block: id, view, running, agent, tree, cwd, ports, prompts, copy. Per tab: id, title, signalvobuda state | jq '.tabs[0].blocks[] | {id, running, ports, cwd}'
vobuda events [--since N] [--no-follow]What changes, one JSON line each, as it happens. Every line has seq (a number that only grows), at (epoch milliseconds), window and kind, then the fields of that kind. --since N prints what came after line N first, then follows; --no-follow stops after that backlogvobuda events | jq -c 'select(.kind=="signal" and .signal=="waiting")'
vobuda log [lines]The core's and the interface's log, the last lines of it (40 by default). Errors from the web view land here toovobuda log 100
vobuda whereThe path of the settings foldervobuda where

The event log is events.jsonl beside the settings, trimmed from the front once it passes two megabytes. The follower watches the path, so the trim loses it nothing.

The event stream

What a script can wait for, without polling and without guessing a number of seconds.

KindFieldsWhen
tab.open, tab.closetab, titleA tab appears or goes
block.open, block.closeblock, tab, view, byA block appears or goes. by says what closed it: a cross, an action (a key or the command line), the still-running question, a finished vobuda run, a moved page, its tab, a restore, or unknown
signaltab, title, signalA tab is marked done or waiting
block.start, block.finishblock, tab, program, afterA program starts or ends in a block
block.cwdblock, cwdThe block's folder moved
portsblock, portsThe block's listening ports changed
command.exitblock, codeA command ended, read from the shell's prompt marks
run.exitblock, run, codeA vobuda run ended
guard.refusedtool, kind, what, cwdThe fence stopped the agent: a delete, a write outside the project, or a key
copy.open, copy.removed, copy.keptpath, branch, root, ahead, dirtyA copy of the project made, removed, or kept because it holds work
review.accept, review.put-back, review.tell, review.commit, review.merge, review.prpath, hunk, root, hash, branch, urlThe decisions of a review
snapshot.taken, snapshot.restoredcwd, prompt, at, filesA snapshot of the project, and one put back
project.publish, project.github, project.packedfolder, pathThe project handed on

Driving the window

One dictionary of actions is behind the keys, the buttons, the menus, Cmd+K and this command line. An unknown action is refused, not ignored, and the refusal is in the log.

CommandWhat it doesExample
vobuda do <action>Any action by name. An argument follows a colon. The full list is the right-hand side of the shortcuts file plus the command list (Cmd+K in the window)vobuda do "tab.new:/path/to/project"
vobuda send <text>Types into the active block. A trailing \n is the return key; only \n and \t are unescaped, the rest is the shell's businessvobuda send 'npm test\n'
vobuda run <command>Runs the command in a block of its own beside the active one, waits, and exits with its code. The header shows running, then the exit code; a block that succeeded closes after a moment unless kept, a failed one stays. For a command that should run where a person can watchvobuda run cargo test && echo green
vobuda button <id>Presses a dock button by its id, as if with the mousevobuda button files
vobuda uiEverything on the screen a hand could use, as JSON: an id that stays the same in every language, a name, a kind (button, field, toggle, tab, row, item, link), its state, why it is greyed if it is, the block it stands in, its content if it is a field. A control behind a closed menu is not listed, because a hand could not press it eithervobuda ui | jq '.[] | select(.kind == "row") | .name'
vobuda press <id|name> [--block N]Calls the control's own click, the same event a hand makes. Two things answering to one name refuse the press and list both by id, with a non-zero code; --block settles it. The answer says what appeared, what went and what turned on or off. Nothing here moves the pointervobuda press block.close --block 2
vobuda type <name> <text>, vobuda key <name> <key>Text into a named field, or one key: Enter, Escape, Tab, the arrows, Backspace, a letter, with modifiers in front (shift+Enter, cmd+Left, ctrl+c). Both go through the events the interface listens for, so a search filters and a rename savesvobuda type search quiet
vobuda click <name> <col,row>A click on one cell of a terminal, counted from zero at the top left: the press and the release a hand makes therevobuda click "Terminal input" 8,3
vobuda shot [--block] [--element <name>]A picture of the whole window, and the path to it. --block takes the block that has the keyboard, --element one control by name. Every picture is a file of its own, named by the time it was takenvobuda shot
vobuda wait <key> <value>, vobuda wait --control <name>Waits until the window says so, instead of sleeping. The key is a path into vobuda state. A wait that runs out says what the key stayed instead and returns non-zero. Thirty seconds unless --timeout says otherwisevobuda wait agentBusy false
vobuda signal done|waiting|clearMarks the active tab: a badge, a sound, a notice. It is what the agents' hooks call; any program in a block can do the same with printf '\e]9;done\a'vobuda signal waiting
vobuda workspace list|open <name>|new|delete <name>A workspace is a separate project window with its own tabsvobuda workspace open shop

Settings, and the rest of the toolbox

Every setting is a file in the settings folder, and the window follows the file. A pinpoint edit writes the value with its own type and leaves the rest of the file valid.

CommandWhat it doesExample
vobuda set <file> <key> <value>A nested key in a settings file, typedvobuda set settings.json signals.quiet.enabled true
vobuda theme, vobuda skin, vobuda dockThe theme by name, the monitor skin, the side of the dockvobuda theme dark
vobuda edit <file>The file in your $EDITORvobuda edit settings.json
vobuda backup [file.zip], vobuda restore <file.zip>The whole settings folder as one file, and backvobuda backup
vobuda pack [folder]The project as one archive for a developer, beside the project, with a readme on top: what it is, how it runs, what changed last, that the keys were left out. node_modules, .git, builds and every .env are not in it. Prints the archive's pathvobuda pack

For the agents' hooks

These are what the window writes into Claude Code's and Codex's settings. A person or a script can call them too.

CommandWhat it is for
vobuda askWhere should this page open? Here, a new tab, its own window, or the browser
vobuda note <kind>Notes beside the agent's numbers: compacting, compacted, helper on, helper off, folder, edited, failed
vobuda briefThe window's brief for the agent at the start of a session
vobuda snapshotThe project folder as it is, before the turn; a key in the request stopped
vobuda guardBefore a tool runs: the fence, never delete, keys, the last tool recorded

What each of these writes, where, and how to take it out again is on the page about what vobuda does with your machine.

Two examples

The first is a script that opens a project the way a person likes it and then listens. The second is what an agent does from its own block.

A script
#!/bin/shvobuda do "tab.new:$HOME/work/shop"vobuda do block.splitvobuda do agent.claudevobuda do block.prevvobuda send 'npm run dev\n'# and, in another script, say so when an agent is waitingvobuda events | jq -c 'select(.kind=="signal" and .signal=="waiting")' | while read -r line; do say "the agent is waiting"; done
opens a project, then waits for the agent
An agent
# read the windowvobuda state | jq '.tabs[0].blocks[] | {id, running, ports}'# run a command where the person can watch, and get its exit codevobuda run cargo test# wait for the window instead of sleepingvobuda wait agentBusy false# change a setting by writing the filevobuda set settings.json monitor.every 5
from its own block, with the same commands

What this is not

Not a protocol with a version: the files are the interface, and they are the same files a person edits. Not a way to talk to a chosen window among several: addressing a window is the workspace's business. Not a way to start or supervise the program: a command is a note left for a running window.

Try it from your own shell

The command line comes with the program, and a settings folder of its own is one variable away.

curl -fsSL https://vobuda.com/install.sh | sh