feat: Cude Claw, agent modes, checkpoints and MCP - #20
Open
Emrevrg wants to merge 7 commits into
Open
Conversation
… files A mode is a system prompt plus a tool budget. The budget is the part that matters: "answer questions about this codebase" should not be able to write to it, and a restriction that lives only in the system prompt is not a restriction. Modes: code (everything), architect (reads anything, writes only Markdown), ask (read-only), debug, orchestrator. The allow-list is applied twice — once when building the tool list handed to the model, and again in the agent loop before each call, so a model asking for a tool it was never offered is refused rather than obeyed. Architect's "writes only Markdown" claim is enforced by a path pattern, not just asserted in its description. Project rules: AGENTS.md, CUDE.md, .cuderules and .cude/rules/*.md are discovered from the filesystem root down to the workspace root — so a monorepo rule applies to packages inside it and the closest file wins — and appended to every agent system prompt, capped so a rule file cannot crowd out the task. cude run "task" --mode architect cude modes list | cude modes show ask cude rules Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The workspace boundary stops the agent writing where it shouldn't; it does nothing about a wrong edit inside the boundary. Before every mutating tool call the prior state of the target is now recorded, so a bad run can be put back. - Whole prior file contents are snapshotted — wasteful for large files and completely reliable, which is the right trade for an undo path. Files over 5MB are recorded as uncaptured rather than silently appearing restorable. - A file the agent created is deleted on restore, not left behind; move_file captures both ends. - Works without git, and never touches git if present: an agent run is not a commit. - AgentResult exposes runId; `cude run` prints the undo command when the run changed anything. cude checkpoint list | show <id> | restore <id> | restore-run <id> | clear Old checkpoints are pruned to the last 20 runs at the start of each run. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Written against the protocol rather than the official SDK, because the client half of MCP is four JSON-RPC calls and Cude ships no runtime dependency it does not need. - Two transports: stdio (a local server run as a child process, newline-framed JSON-RPC) and HTTP (one POST per request, accepting a JSON body or an SSE stream). - Tools are namespaced mcp__<server>__<tool>, so a server cannot shadow a built-in tool and the model can see where a capability came from. They dispatch through executeTool, so mode budgets, checkpoints and the agent loop treat them like any other tool. - Servers are independent: one that fails to start is reported and skipped rather than taking the run down. Requests time out instead of hanging, and every server is stopped when the run ends — a stdio child would otherwise hold the CLI open. - Modes that promise read-only do not receive arbitrary external tools (allowMcp is false for ask and architect). - ~/.cude/mcp.json uses the same "mcpServers" shape as other MCP clients, so an existing configuration copies across unchanged. cude mcp list | test | add <name> --command … | --url … | remove | disable `mcp add` connects and lists the server's tools before saving, so a typo is caught at configuration time rather than mid-run. Tests drive a real stdio MCP server (test/helpers/mcp-stub-server.mjs) rather than a mock, which is how two Windows spawn bugs and a namespacing bug in this commit were caught. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Cude Claw keeps context between turns, where `cude run` starts from nothing each time. The difference that matters is not the prompt — it is that the user is present, so every edit can be shown and approved before it happens, the mode and model can change mid-conversation, and cost is visible as it accumulates. - Edits are previewed as a diff and approved individually: yes / no / always / stop. A declined edit tells the model not to retry it, and stopping mid-turn still answers every tool call the model made — leaving one unanswered would make the next request malformed, which the F2 invariant rejects. - Read-only tools are not put through the approval prompt. - @path in a message attaches that file's contents, so naming a file does not cost a tool round-trip. - Slash commands: /mode /model /tools /mcp /rules /cost /undo /checkpoints /auto /clear /exit. Mode changes take effect immediately, including taking the write tools away when switching to ask. - Every applied edit is checkpointed under the session id, so /undo reverts the whole session. Input goes through one readline interface with a queue in front of it. A short-lived interface per question drops whatever the terminal had already buffered, which left the nested approval prompt waiting for a line that had already been read — caught by driving the real CLI end-to-end, not by the unit tests. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The bottom notch was drawn with the group's round line cap, so each leg bulged half a stroke-width (21 units) past its end point. That nearly doubled their visible length — 11% of the mark's height against the artwork's 5.8% — and made them read as two feet hanging off the mark rather than a split through its bottom vertex. The legs now use butt caps. The CLI block art and the README screenshot had both drifted from the artwork: - tools/generate-logo.mjs rendered the SVG in Chromium, which CI deliberately never downloads and which cannot be installed here at all, so the art could not be regenerated. The mark is three stroked polylines with round joins, so its inked region is a closed form — tools/mark-raster.mjs samples it directly, no browser needed. - --write had never worked on Windows: it anchored its regex on "\n" and a Windows checkout has CRLF, so it always reported that it could not find LOGO_ART. That is why the art could go stale unnoticed. - The bounding box was hand-measured in a comment. It is now computed, because changing a cap changes the box and getting it wrong shifts the whole mark. - assets/cude-cli.png was a hand-captured screenshot showing the old mark, feet and all. It is now assets/cude-cli.svg, generated from the same LOGO_ART the CLI prints, with the art drawn as rectangles so a viewer whose monospace font lacks quadrant blocks does not see tofu. Publishes the new banner (assets/cude-banner.png) and keeps the reference artwork (assets/cude-mark.png) so the SVG can be checked against it. test/brand.test.mjs asserts the CLI art equals what the SVG reduces to, that the legs use butt caps and keep the artwork's proportions, that the mark stays open on its right side, and that every image the README points at exists. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Builds Cude into an agent platform rather than a one-shot task runner: an interactive session, modes with real permission boundaries, undo, and MCP.
No new runtime dependencies. MCP is implemented against the protocol directly; the REPL is
readlineandchalk.claw.test.mjs— 15modes.test.mjs— 10modes.test.mjscheckpoints.test.mjs— 8mcp.test.mjs— 17Cude Claw —
cude clawcude runstarts from nothing every time. Claw keeps the conversation, and — the part that actually matters — the user is present, so every edit can be shown before it happens.validateTurnSequencerejects; there is a test asserting the invariant holds after an abort.read_fileis noise.@path/to/fileattaches a file's contents to your message, so naming a file doesn't cost a tool round-trip./mode/model/tools/mcp/rules/cost/undo/checkpoints/auto/clear/exit. Mode and model changes apply mid-conversation.One bug worth calling out, because it only appeared when driving the real CLI end-to-end and no unit test would have found it: input originally used a short-lived
readlineinterface per question, the wayrun.tsdoes. That drops whatever the terminal had already buffered, so the nested approval prompt waited forever for a line that had already been read. It is now one interface for the session with a queue in front of it, which behaves identically whether input is typed or piped.Agent modes —
--mode,cude modesA mode is a system prompt plus a tool budget. The budget is the point: "answer questions about this codebase" should not be able to write to it, and a restriction that exists only in the system prompt is not a restriction.
codearchitectaskdebugorchestratorEnforced twice: when the tool list is built for the model, and again in the agent loop before each call — so a model asking for a tool it was never offered is refused rather than obeyed. There's a regression test for exactly that, driving a stub that requests
write_fileinaskmode and asserting the file does not appear.Architect's "writes only Markdown" is a path pattern checked at call time, not a claim in its description. Every other route to a source file (
replace_in_file,apply_patch,move_file,delete_file,run_command) is closed off by the tool budget, and that's asserted too.Project rules —
cude rulesAGENTS.md,CUDE.md,.cuderules,.cude/rules/*.md. Discovered from the filesystem root down to the workspace root, so a monorepo-wide rule applies to a package inside it and the nearest file lands last in the prompt.AGENTS.mdis deliberately first in the list — it's the convention other agent tools already read, so a repo that has one gets the behaviour for free. Capped at 32K chars so a rule file cannot crowd out the actual task.Checkpoints —
cude checkpoint#19's workspace boundary stops the agent writing where it shouldn't. It does nothing about a wrong edit inside the boundary.
Before every mutating tool call, the prior state of the target is recorded.
move_filecaptures both ends.cude runprints the undo command when the run changed anything. Pruned to the last 20 runs.There's a test asserting every tool that writes files is in the checkpoint map — a mutating tool missing from it produces an unreversible edit, silently.
MCP —
cude mcpModel Context Protocol servers, over stdio and HTTP.
mcp__<server>__<tool>so a server cannot shadow a built-in, and dispatch throughexecuteTool— so mode budgets, checkpoints and the agent loop treat them like any other tool, for free.mcp addconnects and lists the server's tools before saving, so a typo is caught at configuration time rather than mid-run.allowMcpis false foraskandarchitect) — a third-party server's tools are unknown, so handing them to a read-only mode would make its promise false.~/.cude/mcp.jsonuses the samemcpServersshape as other MCP clients, so an existing configuration copies across unchanged.Tests drive a real stdio MCP server (
test/helpers/mcp-stub-server.mjs) rather than a mock. That caught three bugs that a mock would have sailed past:shell: trueon Windows with an unquoted command path —C:\Program Files\nodejs\node.exesplit at the space.shell: true(Node's DEP0190) — nothing escapes it.mcp__rather than__, producingmcp__probemcp__echo.Verification
Claw was also driven end-to-end through the real CLI against a scripted server: the edit is previewed, approved, applied, the session exits 0, and stderr stays clean.
Not included
Deliberately left out rather than half-built — each needs its own design pass:
orchestratormode currently works through sub-tasks in one context. Spawning isolated child agents is a different thing and needs a context-passing story first.chatWithToolsacross 13 providers..cude/modes/*.md. The built-in five cover the common shapes; user modes need a permission-declaration format that can't be used to handaskmode write access by accident.🤖 Generated with Claude Code