Skip to content
Skip to content
Product / CritiqueCode11 min read

CritiqueCode Leaves the Terminal Without Leaving Your Machine

The author agent still implements, then survives forced review. The surface can now be a localhost browser instead of a TUI.

Repath Khan

Leave the TUI

Keep the kernel on the machine.

critique.sh

Direct answer

CritiqueCode now has a local web UI. Run critique-code web in the repository you mean to change. It binds 127.0.0.1, opens a browser, and drives the same author kernel as the TTY: Pi createAgentSession, CAS writes, user-gated critique_run, /review / /repair / /ship with the author transcript withheld. It is not OpenCode’s web app, not the Critique CLI sidecar, and not a cloud session.

The useful coding agents of 2026 live in a directory. Claude Code, Codex CLI, OpenCode, Aider, Gemini CLI, CritiqueCode: you cd into the repo and you talk. The surface has almost always been a TUI. That is a fine surface if you like it. It is a bad reason to skip independent review.

People keep asking for a browser. Not because HTML is morally superior to ANSI, but because a TUI is a tax. You cannot select a tool card with a mouse. You cannot keep a review panel beside the chat without splitting tmux. You cannot sit on a couch with a laptop lid half-closed and still see what the agent wrote. OpenCode already shipped that split: opencode web talks to a local server. Codex published the same lesson as an app-server. The mistake would have been to steal their product instead of their architecture.

CritiqueCode’s contract is not “looks like Claude Code in a terminal.” The contract is: the model implements, then the controller forces review and verified repair. Author checks are not Evidence. Slash lines are never sent to the model. none_promoted is not a correctness proof. That contract is easy to lose the moment you wrap someone else’s agent UI.

OpenCode’s web UI is a SolidJS client of OpenCode’s Hono server. It assumes OpenCode sessions, shell, LSP, MCP, share, fork, /tui remote control. CritiqueCode imports the Pi coding agent library. It does not spawn pi. It does not spawn OpenCode. Pointing OpenCode’s packages/app at this harness would mean faking their protocol, then deleting most of it, then looking like OpenCode anyway. The sidecar CLI already embeds OpenCode. Mixing the two products is how you ship a rename nobody asked for.

Pi has a web-ui package too. It is built for an Agent that runs in the browser with IndexedDB keys. That is the wrong runtime. CritiqueCode’s tools are projected on the Node side: CAS file writes, named checks that cannot become Evidence, critique_run that does nothing until you click Approve. The tab can close. The process has to keep going.

Same split as OpenCode and Codex. Different backend.
TUI and web are peers. Neither is the kernel.
LayerOpenCodeCritiqueCode
Processopencode serve / opencode web on loopbackcritique-code web on 127.0.0.1
Author runtimeOpenCode sessions and toolsPi createAgentSession, projected tools
ReviewAgent-owned, optional in the productController-owned /review, transcript withheld
ExecShell as a first-class toolcritique_run only after you approve
ListenCan bind LAN with a passwordLoopback only. 0.0.0.0 is rejected

We copied the split. The TTY was already a client of runLocalCritiqueCodeAuthor. The web UI is a second client of that loop: a line hub instead of readline, SSE instead of stderr chrome, a modal instead of a pi-tui select list for critique_run. Commands still parse through parseAuthorCommand. Unknown /foo is still rejected. It is still not chat.

You get a dark page with the repo name, the model, a transcript, changed paths, last review, command chips, and a composer. Enter sends. Shift+Enter is a newline. /review, /review all, /repair, /ship, /skills, /login, /exit are buttons because those lines were never supposed to be typed from muscle memory. A critique_run request opens a modal with purpose and preview. Approve runs it. Deny finishes the tool with a denial. Output is still not Evidence.

APIs sit behind a per-process token. The HTML page injects it. Snapshot and prompt without the token return 401. A foreign Origin on POST returns 403. The server will not listen on 0.0.0.0. That is the whole security story for v1: this is a control surface for a process that can write your tree. It should not be a LAN toy.

Start it in the repo you mean to edit
Same cwd rule as the TTY. The kernel stays in this process.

Published binary

cd /path/to/your-project
critique-code web

Opens http://127.0.0.1:<port> when it can.

Pick a port

critique-code web --port 7734

0 means ephemeral. Default is an ephemeral bind if you pass --port 0.

critique-code with no subcommand is still the interactive author session. Voice mode still needs a microphone and, today, still lives on the TTY path. Settings pickers still have a terminal UI. We did not wrap Electron. We did not add a file tree, an LSP, or an unrestricted terminal. Those are how a “web coding agent” quietly becomes a different product.

If you want OpenCode, run OpenCode. If you want a sidecar reviewer for the agent you already use, that is @critiquedotsh/cli. If you want Critique to author the change and then be forced through review, that is @critiquedotsh/harness. The web UI is for the last of those, for people who do not want to live inside a TUI to get the contract.

Open the author in a browser
Install @critiquedotsh/harness, cd into the repo, run critique-code web. Review is still /review. none_promoted is still not a proof.