Agents & automation
Tools & Skills
Bodega registers 34 built-in tools that the agent calls during a task, ships 12 skills you trigger with slash commands, and handles a set of client-side commands in the app itself. Tools from connected MCP servers are registered on top of that and vary with your configuration. This page covers what each one does, when it fires, and what to watch out for.
How tools and skills differ
Tools are functions the agent calls on its own during a response - reading a file, running a shell command, doing a web search. You see each tool call as a card in the message stream showing what ran and what came back. In Ask mode, every tool call pauses for your approval before executing - unless you turn on auto-approve read-only tools (Settings → Agent, beta.28, off by default), which lets pure reads (search, grep, glob, symbol lookup, Map/memory/knowledge/session queries) skip the prompt while writes, web, and shell still ask. Shell can never auto-approve in Ask mode.
Skills (/commit, /debug, etc.) are structured workflows you trigger explicitly. They load a pre-written policy into the agent's context that shapes how it approaches the task - which tools it's allowed to use, what order to do things in, and when to stop and ask you. You invoke them with a slash command in any AI panel.
Client-side slash commands (/help, /clear, /compact, /mode, /preview, /map, /export) are handled entirely in the app - nothing goes to the LLM.
File and code tools
| Tool | What it does | Key limits |
|---|---|---|
file_system |
Read, write, append, delete, list, mkdir, rename, check existence. Sandboxed to your project workspace. Large files can be read two ways: by character window (offset/length, with a nextOffset return field) or by line window (start_line/line_count, with a nextStartLine return field). Either way the requested window is a maximum, not a promise: a window too big to survive the tool-result limit is shrunk before it is sent, and the returned continuation field points at the first character the agent did not actually receive - so the guard that stops it overwriting a file it has only partly read is never credited with text it never saw. A line-addressed read comes back numbered like cat -n, so the line numbers grep and stack traces give you are the same numbers you can read by; the numbers are added by the tool and are not part of the file. Lines longer than 2000 characters are shown cut short. Jupyter notebooks (.ipynb) are refused with a notice rather than read, because their JSON mixes cell source with base64 image output. Reading an empty file, or reading past the end of one, returns a plain notice saying which of the two happened rather than a blank success. Text reads strip a leading UTF-8 BOM, which otherwise sits at line 1 character 1 and breaks str_replace anchors; line endings are left exactly as they are on disk. |
100MB size limit. Blocked extensions: .exe, .dll, .sh, .bat, .ps1. The agent must read a file before writing it. |
grep |
Regex search across file contents using ripgrep. Returns matching lines with paths and line numbers. | 50 results max, 1MB buffer, 25s timeout. Scoped to workspace. |
glob |
Finds files matching glob patterns, sorted by modification time. | 100 results max. Patterns capped at 200 chars, max 5 ** segments (ReDoS protection). |
str_replace |
Surgical find-and-replace inside a file. Whitespace must match exactly. Use replace_all for multiple occurrences. |
Code Mode only - blocked in Chat Mode. Exact string match required; no fuzzy matching. |
find_symbol |
Looks up where a function, class, or type is defined. Returns file paths and line numbers. Exact matches rank first. | Index is built when your project opens - very large projects may have a brief delay before it's ready. |
code_search |
Semantic code search supporting symbol names, class definitions, and text patterns with file-type filtering. | 500-char query limit. Max 100 results. Shell metacharacters are rejected. |
diff_file |
Shows the git diff for a specific file. Supports staged-only via an optional parameter. | 10s timeout. Requires the project to be a git repo. |
run_tests |
Runs your test suite. Auto-detects Vitest, Jest, pytest, or go test from the project structure. |
120s timeout, 2MB output buffer. Only available in plan, act, code, or debug modes - blocked in Ask mode. |
get_diagnostics |
Pulls the current type errors for a TypeScript/JavaScript file from the bundled language server. Use it before editing already-broken code, instead of running the whole compiler through the shell. Read-only, auto-approves. | Project must be open. Non-TS/JS files return a redirect note. Same bundled server as editor diagnostics - air-gap safe. |
dispatch_scout |
Sends a read-only sub-agent to investigate the codebase and report back a short digest, so the exploration (greps, reads, symbol lookups) doesn't fill the main conversation's context. Good for "how does X work?" or "trace the Z flow." | One scout at a time, 90s cap. The scout can't edit, run commands, or dispatch its own scout. Runs on your primary model. |
Shell tool
The shell tool runs commands in your project directory: git operations, package managers, test runners, compilers, linters - anything you'd run in a terminal. On Windows the shell tool runs commands through cmd.exe, not PowerShell and not bash, and this is separate from the Terminal panel, which prefers PowerShell 7. PowerShell-only syntax ($env:X, cmdlets) and bash-isms (mkdir -p, export, $(...)) do not work; use the file_system tool for files and folders.
Every command is classified into one of three tiers before it runs:
- SAFE (auto-approve in Act mode):
ls,cat,git status, and similar read-only commands. - MODERATE (brief confirmation):
npm install,git commit, and similar. - DANGEROUS (full approval dialog):
rm,chmod,git push,curl, and similar.
In Ask mode, shell commands always show an approval card regardless of tier - there is no auto-approve timeout.
After every execution, output is scanned for 13 credential patterns: SSH private keys, AWS AKIA* keys, GitHub ghp_* PATs, OpenAI sk-* keys, JWTs, and high-entropy strings over 40 chars (scored by actual Shannon entropy, so DNA sequences, hex digests, and UUIDs are not redacted).
Air-gap mode blocks all network-touching shell commands: curl, wget, ssh, git clone/push/pull, npm install, pip install, docker pull.
Web tools
Both web tools are blocked entirely in air-gap mode.
| Tool | What it does | Key limits |
|---|---|---|
web_search |
Searches the web via DuckDuckGo. No API key needed. Returns up to 8 results with title, URL, and snippet. | 20s timeout. |
web_fetch |
Fetches a URL, strips HTML for readability, returns up to 500KB of text. Used to read docs, articles, and API references. | SSRF protection blocks all private IPs (127.x, 10.x, 192.168.x, 172.16–31.x, 169.254.x, localhost, 0.0.0.0). HTTP/HTTPS only. 30s timeout. |
Memory and knowledge tools
| Tool | What it does | Notes |
|---|---|---|
save_memory |
Stores a key-value fact in persistent memory. Facts survive across all sessions and are injected into future context automatically. | 5 writes per session, shared with the agent's own automatic extraction. Overwriting a key you already wrote this session doesn't count again. Say "Remember that..." to trigger it directly. |
query_memory |
Searches your persistent memory across long-term, shared, and project scopes in parallel. Default 10 results, hard cap 20, deduplicated with shared preferred over project over long-term. | 3s timeout. Note scope: 'session' is not session-isolated - in main chat it persists exactly like shared. |
query_knowledge |
Searches your Knowledge Base. Three tiers: hybrid semantic + keyword when RAG embeddings are on, else FTS5 full-text, else LIKE substring. | Default 10 results, capped at 20. 5s timeout. Searches all your knowledge regardless of which project is open. |
query_docs |
Searches Bodega's own bundled, versioned documentation - this docs hub - for questions about how the app itself works (a tool, a setting, a mode, troubleshooting). This is how the agent answers app-behavior questions instead of guessing. | Core tool, visible to every model size including small local models. Purely local - never touches the network. Never reads live settings. If the bundled docs are older than the running build, results carry a staleness note. |
scratchpad |
In-memory notepad for planning multi-step tasks. The agent writes notes, checks them, and clears them as it works. | Session-scoped only - not saved to disk or database. |
query_map |
Asks a natural-language question about your project's codebase and returns a grounded answer with source file citations. Uses semantic search over the codebase index. Never throws if the index hasn't been built yet - it tells you to build the index first. | Requires an embeddings model (Settings → Models → Codebase Embeddings) and the project to be open. 65s timeout. Air-gap: local provider only. |
Cross-model consultation and delegation
Two non-core tools let the agent reach outside its own single-model turn for a hard subproblem. Both are off by default and only visible when their setting is enabled.
| Tool | What it does | Notes |
|---|---|---|
consult_mixture |
Fans a focused subquestion out to a panel of independent reference models in parallel and returns their draft opinions as the tool result - a second opinion, not a decision. The references see only the subquestion you pass (never your files or conversation history) and cannot call any tools or edit anything. | Setting: mixture.consult_tool_enabled (off by default). Slow - each reference can take tens of seconds - and can spend cloud credits if a cloud model is in the reference panel. Disabled entirely in headless/Loops/background runs. Requires at least the minimum reference count to be available (air-gap and single-active-model constraints can drop the panel below that). |
spawn_agent |
Runs a named agent on ONE focused task, on that agent's own provider and model, and returns its final report. The agent starts fresh - it sees the task, never your conversation. Built-ins: delegate (edits inside an isolated worktree; your project's own tests run against the diff in that worktree and it is admitted only if it broke nothing that was passing before the child started - tests that were already red do not block it - and a diff that introduces a new failure is discarded) and researcher (read-only - it can read your project's files and code, not just search the web, and reports rather than edits). Any custom agent you mark spawnable can be named too. |
spawn_agent is a write tool: in Ask mode it pauses for your approval like any other write, even when the child is a read-only researcher. Setting: agent.subagents_enabled (off by default) - once on, local models see spawn_agent in their own tool list too. Per-sub-agent spend cap, opt-in for shell inside a worktree agent. Slow (a full sub-loop), three per turn. Set background: true and the tool returns immediately with started; the report reaches you on a later turn - including a plain question turn with no tool calls of its own - and a strip under the conversation shows the agent working - click its chip to open a panel with the agent's tool calls and, once it finishes, its report. A local VRAM fit check runs before a local child starts: if it fits beside your loaded model it proceeds (a foreground child may cost one swap-out-and-back, logged); a background child that would make the daemon swap models on every request is refused outright rather than thrash. One LOCAL sub-agent runs at a time - two models generating on one GPU is the failure that rule exists to prevent; cloud agents run up to the background-sessions ceiling. Stopping the run cancels its sub-agents within about a second and discards their worktrees. Off by default in headless/Loops/background runs - nobody is watching one, so it is opt-in (agent.subagents_headless, or bodega run --subagents for a single run). Always refused in Sidechat, and always refused inside a sub-agent: sub-agents cannot spawn sub-agents, and no setting relaxes that. A cloud agent is refused under air-gap. Returns done, rejected, no_changes, unavailable or started, with the report, the files changed and what it cost. |
Deferred tool loading - discover_tools and use_tool
When deferred tool loading (agent.deferred_tools, off by default - see the KV-cache section in this page's overview) is turned on, the model's native tool list shrinks to a small core set for KV-cache efficiency, and everything else pages in through two meta-tools instead of being listed up front:
| Tool | What it does |
|---|---|
discover_tools |
Lists the non-core tools available on demand. Called with no arguments, it returns names and one-line descriptions; called with a query or category, it returns full parameter schemas for matching tools. |
use_tool |
Invokes a non-core tool the model just discovered, by passing its exact name and an arguments object matching that tool's schema. An unknown name or invalid arguments return a corrective listing instead of failing outright. |
Both are always part of the core set (so their own schemas never move), but they only matter when deferred tool loading is on - with it off, every registered tool (including consult_mixture and spawn_agent when their own settings are enabled) is listed natively as usual and these two meta-tools go unused.
Session and coordination tools
| Tool | What it does |
|---|---|
query_session |
Searches the current session's message history - lets the agent refer back to earlier in a long conversation. |
link_session |
Creates parent-child, fork, or merge relationships between sessions. Used for cross-session coordination and Fleet Parallel worktree tracking. |
todo_write |
Creates and manages a session-scoped TODO list for multi-step tasks. Every third tool call, the agent gets a reminder of open items to prevent context drift. Session-scoped only. |
Vision and preview tools
open_preview is the simple way to open the Preview tab. With no arguments it auto-detects a running dev server (Vite/Next/CRA/Astro/…) on the common localhost ports and opens the panel to it. If nothing is running but the project has an index.html, it serves that folder locally instead, so plain HTML/JS sites and no-build-step projects are previewable too. Pass url to target a specific localhost address. It only opens the panel - the tool never starts a dev server for you (that's still the shell tool's job; you can also start one yourself with the one-click Start button on the Preview empty state, which runs your project's dev script in a Terminal tab).
preview_interaction lets the agent drive the Preview tab (an embedded browser) once it's open. Actions:
screenshot- captures a PNG and returns animg_XXXXXXXXhandlenavigate- loads a URL. Localhost/loopback always works; a non-localhost origin requires your prior approval and is refused entirely under Air-Gap modeclick- clicks an element by CSS selector (approval-gated by default)type- sets an input/textarea value (no simulated keystrokes) so the agent can fill in a search box, a login form, or any other field. Password and other credential fields are always refused outright - never approvable, never a silent no-op - and every other value is scanned for credential signatures before you're asked to approve it. Everytypeshows you the exact field and value and asks every time; nothing is remembered site-to-site the way navigate/click approval is.submit- submits a form. Asks for your approval on every call, even on an already-approved site, and shows the real field values read from the page rather than what the agent claims it's sending. Clicking a form's submit button after the agent has typed into that form goes through this same real-values approval, not the lighter click approval.getDom- returnsouterHTMLfor a selector (output capped at 8,000 chars)getConsoleErrors- returns sanitized JS console errors
preview_script runs several of those actions in one call - up to 8 steps drawn from navigate, click, getDom and screenshot - so the agent stops spending a whole turn per click while it is finding the right page. It is not a shortcut around anything: each step is executed exactly as if the agent had called preview_interaction for it, so every approval prompt, air-gap refusal and credential scan happens the same way and at the same moment. Two behaviours worth knowing: type and submit can never be part of a batch (if a script asks for one, it stops there and the agent has to request that action on its own, so you always approve typing and submitting against the page as it stands right now), and if any step does not do what it claimed - a selector matched nothing, a site was refused - the rest of the script is abandoned and the agent is told which step failed rather than carrying on against a page it never reached.
vision_query takes an image_id from a prior screenshot and a plain-English question (max 500 chars), sends both to your configured Vision Language Model, and returns a text answer. This is how a text-only loop driver (e.g., Claude) can "see" the screen.
To use vision features: configure a VLM in Settings → Models → Vision Model, and have the Preview tab open with a dev server running.
Can the agent browse the web beyond localhost?
preview_interaction's navigate action always works for localhost/loopback addresses - that's how the agent drives your own dev server in the Preview tab. Navigating to a real, non-localhost website is a separate, off-by-default setting: Settings → Safety → Agent Web Browsing (non-localhost) (browser.widened_enabled, off by default, never available under Air-Gap mode). Turning it on requires confirming a warning dialog, and takes effect on your next new chat or session - not mid-conversation, since the tool's definition is fixed for the life of a running session.
The browser surface is a separate sandboxed view from the Preview tab (it appears in the same area of the window, but the two are not the same thing), created on demand and torn down again when idle. It is intended to be usable by you directly, with its own URL bar, and there is an "Open agent browser" button in the Preview panel to bring it up without waiting for the agent. This part of the feature is still experimental and rough - if a page does not load for you, that is a known limitation being worked on, not something you have configured wrong. Navigating there yourself is entirely separate from the agent's approval path: nothing you do in that URL bar grants the agent access to a site, and nothing the agent is approved for lets it drive pages you load yourself.
By default, every new website needs your approval before the agent navigates there, and a click on an already-approved site is cached - you're asked once per site, not once per click. Approval also governs what the agent may READ: if a link moves the browser onto a site you never approved, the agent is refused when it tries to read that page, even though the page itself loads. Typing needs a site already approved for reading/clicking too - it never opens a new site on its own. Three things always require a SEPARATE confirmation every single time, even on an already-approved site: typing a value into a field, submitting a form, and loading an address whose query string carries data you didn't see in the original approval (the guard against a page quietly appending your data to a link). A password or other credential field is refused outright, before any approval is even asked - there is no way to approve typing into one; type the password yourself instead. Private and local-network addresses (127.0.0.1, your router, your own Bodega services) stay blocked regardless of any approval. Note that some pages submit or send data as soon as a field changes, without you ever seeing a separate submit step - Bodega can't see that happening either, so treat every approved type as something that could reach the site immediately.
This is opt-in with real residual risk - a website's content can still try to manipulate the agent through what it reads (prompt injection is an open problem industry-wide, not something any single safeguard solves), so only approve sites you trust. web_fetch and web_search (fetching a URL's text, searching DuckDuckGo) are unaffected by any of this - those already work today, subject to the SSRF and air-gap rules described elsewhere on this page.
Keeping the agent signed in - persistent browser logins
By default, every widened-browsing session is ephemeral - its cookies and storage are wiped when the browser surface tears down, so the agent is never logged in anywhere across sessions. That stays true unless you deliberately change it.
"Keep the agent signed in" (Settings → Safety) is available, and off until you turn it on. Switching it on asks you to confirm first, because it is a real grant of authority: on a site you approve, the agent acts as you until you revoke it. If you had this setting on in an earlier build it has been reset to off - the earlier switch approved a version of the feature that was never actually wired, so the app asks again rather than assuming the old answer still applies.
With it on, each site you grant gets its own cookie jar, kept separate from every other granted site and from the rest of the app. The grant is per site, requested the first time the agent navigates there, and it covers that site's subdomains.
You stay in control of it: Settings lists every persisted site and lets you revoke one or all of them, a site you decline is remembered so you aren't asked repeatedly (with an Ask again action if you change your mind), and turning on Air-Gap mode wipes every persisted login outright, naming the affected sites before it clears them.
One honest caveat while this is new: signing in to a site that authenticates by redirecting through a third party (a "Sign in with…" flow) will not work - the browser blocks cross-site redirects on purpose, and that restriction is not something to work around.
Document and research tools
| Tool | What it does | Notes |
|---|---|---|
create_document |
Generates a structured Markdown document artifact from a chat turn. Triggered when the agent classifies your request as document intent. | Chat Mode only. 50,000-char output cap. |
deep_research |
Multi-step parallel web research. Runs multiple DuckDuckGo queries in parallel, fetches pages, and synthesizes a structured answer with citations. Progress shown in real time: Planning → Searching → Synthesizing. | Blocked in air-gap mode. Max 10 queries per turn, 45s total timeout. Enable via the Research toggle in the + menu. |
convert_to_markdown |
Converts HTML, CSV, or JSON content that's already IN the conversation to clean Markdown - typically the raw HTML web_fetch just returned. HTML becomes headings/links/lists/tables; CSV becomes a table; JSON becomes a fenced code block. This tool does not open files and does not handle PDFs or Office documents - see "Reading PDFs and Office documents" below for that. |
100KB input / 50KB output limits, 5s timeout. |
Reading PDFs and Office documents
This isn't a tool the agent calls - it's built into the normal file-read path. When the agent (or you, via an attachment) opens a PDF, DOCX, XLSX, PPTX, ODT, ODS, ODP, EPUB, or RTF file, Bodega converts it to Markdown automatically before the content reaches the model. Legacy binary Office formats (.doc, .ppt, .xls) are also supported - .doc conversion is verified against a real fixture, .ppt/.xls use the same underlying parser and are extrapolated from that.
Two entry points, same converter:
- The agent reads the file directly with
file_system- the binary-format detector routes it to the converter instead of returning garbled bytes. - You attach the file in the chat composer - the same converter runs before the content is added to your message.
What it won't do:
- Scanned PDFs are refused. If a PDF's extracted text is near-empty relative to its file size, Bodega assumes it's an image scan and tells you so rather than returning blank content - it does not perform OCR.
- Encrypted/password-protected documents are refused with a clear message.
- 100MB input limit. Anything larger is refused before conversion is attempted.
- 50,000-character output cap on the converted Markdown, with a
truncatedmarker appended when a document is cut off.
Why it's safe on untrusted files: the actual conversion runs in an isolated child process, not in Bodega's main backend. A malformed or hostile document that crashes the parser takes down that one child process - you get a "could not convert this document" refusal, not a backend crash.
Authoring a skill with /learn
The learn_skill tool turns "I keep doing this same workflow" into a reusable skill. Point it at a source - a folder inside your workspace, or a URL - and it has the model draft a spec-conformant skill YAML, validates the draft, and returns it as a preview for you to review.
This first version stops at the preview: it reads, drafts, and validates, but it does not write the skill or change your skill registry yet - the save/approve/reload steps come later. So you can use it today to see exactly what a skill for a given source would look like before anything is committed.
What it needs:
source-directory(a path inside the workspace) orurl.path_or_url- the folder path or the http(s) URL to learn from.skill_name- lowercase letters, numbers, hyphens, or underscores.skill_description- a one-line summary of what the skill does and when to use it.triggers(optional) - comma-separated trigger phrases; defaults to/<skill_name>.
Safety: directory sources go through the workspace sandbox (no escaping your project), URL sources go through the SSRF-protected fetcher, and the source is truncated before authoring. Under air-gap, URL sources are refused with a clear message - directory sources still work. If the model produces invalid YAML, you get an error rather than a malformed skill.
Hallucination auto-correction
When the LLM calls a tool name that doesn't exist, Bodega auto-corrects it against a large alias table (40+ mappings) before the call fails. The correction is logged in the tool call card so you can see what happened.
Examples of what gets redirected:
bash,exec,run,terminal→shellread_file,write_file,list_dir→file_systemsearch,rg,ripgrep,grep_search→grepfind_files,list_files→globstring_replace,edit_file→str_replacebrowse,fetch_url,navigate→web_fetchremember,store_memory→save_memorysearch_knowledge,recall→query_knowledge
One known quirk: the alias code_search in the correction map redirects to grep, not to the code_search tool. If the agent calls code_search by name, it gets grep behavior. The actual code_search tool is only triggered when the LLM uses its exact registered name.
Skills - structured slash command workflows
Skills load a policy into the agent that controls how it approaches the task. Type / in any AI panel to see autocomplete. Twelve ship built in:
| Skill | What it does |
|---|---|
/commit |
Stage changes, generate a conventional commit message (type(scope): description), and commit. Needs the shell tool, and must report the files changed and the commit hash. |
/debug |
Hypothesis-driven bug investigation: read the code, form a hypothesis, test it, apply a minimal fix, verify. |
/decompose |
Turn a large objective into a persistent goal with 3–7 verifiable tasks, then work them in order. Requires todo_write. Also activates on multi-step phrasing ("build X with Y and Z", "migrate A to B"). |
/docs |
Write JSDoc or docstring comments for the current file's exports, classes, and public methods. |
/explain |
Explain what code does: purpose, data flow, key patterns, dependencies. Read-only. |
/generate |
Create a new file from a plain-English description, matching existing project patterns, then verify the build. |
/onboard |
Tour an unfamiliar repository and save the findings as persistent project knowledge. Requires save_memory; shell, web, and str_replace are forbidden to it. |
/perf |
Identify performance hotspots - O(n²) loops, missing memoization, N+1 queries - ranked by impact. Suggests; does not apply changes on its own. |
/refactor |
Structural refactoring, then verify with npx tsc --noEmit --skipLibCheck exiting 0. Blocks on a failed verification rather than reporting success. |
/review |
Code review grouped by severity. This is the only skill that changes shape by mode: in Chat mode it gives conceptual guidance without reading files; in Code mode it scans files and cites file:line. |
/security |
Security audit of the current file: credential patterns, injection, OWASP categories. |
/test |
Generate tests for a file or function - happy path, error path, edge cases - then run them and iterate on failures. |
Skills are not mode-restricted. There is no per-skill "Code Mode only" flag. What is gated is automatic activation: Bodega only matches a skill from your phrasing when you are in Code mode and skills.auto_activation is on. An explicit /trigger works in any panel, in either mode. A skill can still fail for a mundane reason - /commit needs the shell tool, and shell is not available everywhere.
Project skills must be approved before they load
Skills load from three places, and only one of them is gated:
| Source | Path | Gated |
|---|---|---|
| Built-in | ships with the app | no |
| Yours | ~/.bodega/skills/<name>/SKILL.md |
no |
| The project's | <project>/.bodega/skills/<name>/SKILL.md |
yes |
A skill that arrives inside a repo you cloned does not run. It is skipped before its frontmatter is parsed - never registered, never listed to the model, never executed - until you approve it.
Approval is keyed to the SHA-256 of the whole SKILL.md file, frontmatter and body together, paired with that project's resolved path. Two consequences worth knowing:
- Editing an approved skill re-prompts. Any byte change is a new hash. This is deliberate: the body is injected into the agent as instructions, so changing it is as much a change of behaviour as changing the policy fields.
- Approval does not travel. The same skill in a second checkout of the same repo is a separate decision.
Approve at Settings → Skills → Project Skills - the block appears only when the open project actually has skills pending - or from the small approval chip in the corner when you open a project. From a shell, bodega skills trust lists them and bodega skills approve <name> approves one, printing the content hash it approved. There is no "deny" verb; declining is simply never approving. An approval you regret can be revoked: click the Approved label in Settings → Skills → Project Skills and the skill goes back to requiring approval.
The trust record lives in skill-trust.json in your Bodega data directory and fails closed: if that file is missing, corrupt, or unreadable, every project skill is refused rather than allowed. Each record also notes what was approved, when, and from which surface (Settings, CLI, or API). One hard refusal: a .bodega/skills/ entry that is a symlink or junction pointing elsewhere is never loaded and cannot be approved - it shows as Blocked (link) in Settings.
Skills in the CLI
Bodega One Code (the CLI) sees exactly the same skills the app does - it starts the same backend and reads the same registry, and it ships no skill set of its own.
bodega skills/bodega skills list- what's loadedbodega skills trust [--json]- project skills and their approval statebodega skills approve <name>- approve one
One difference worth knowing: the backend's skill listing does not distinguish a skill you wrote from one the project shipped. The CLI works that out itself by checking whether the file exists under the project's .bodega/skills/, and tags it project ⚠ [untrusted] when it isn't approved. The app's Settings list does not make that distinction the same way, so the CLI is the better place to audit what a repo is trying to hand your agent.
Client-side slash commands
These are handled entirely in the app - nothing goes to the LLM.
| Command | What it does | Available in |
|---|---|---|
/clear |
Clears the current input field. Does not clear conversation history. | Any panel |
/help |
Lists the available slash commands in a toast. | Any panel |
/compact |
Summarizes older conversation history to free up context window space. A toast confirms and shows how many messages were summarized. | Any panel (requires an open session) |
/mode ask / /mode plan / /mode act |
Sets the Agent panel permission mode. | Agent panel (Code Mode) |
/export |
Exports the current chat conversation as a Markdown file. Opens a native save dialog pre-filled with the session title. | Chat Mode only |
/preview |
Opens the Preview tab. Bare /preview opens a port picker (common ports: 3000, 5173, 8080, 4200) or re-opens the last URL. /preview localhost:5173 jumps directly. |
Any panel (Code Mode) |
/map |
Opens the Bodega Map codebase visualization panel. Requires Dockview layout - if the map doesn't open, check Settings → Layout. | Any panel (Code Mode) |
Fast Mode - skipping extended thinking
Fast Mode skips the extended-thinking pre-pass on models that do it, so replies start sooner without dropping to a smaller model. Enable it with the Fast toggle in the message composer, next to the reasoning control; it only shows for models that support extended thinking.
The priority order for reasoning control:
- Per-message reasoning pill in the composer (always wins)
- The Fast Mode toggle (
llm.claude_fast_mode, default off) - Global reasoning effort default (Settings → Models)
If you've set a per-message reasoning level in the composer, Fast Mode is ignored for that message. It has no effect on models that don't do extended thinking.
Custom Agents
Custom agents let you define named profiles with a tailored system prompt, an optional pinned model, a tool allowlist, and an iteration cap.
To create a custom agent:
- Go to Settings → Custom Agents
- Fill in: Name (required, max 100 chars), System Prompt (required, max 6,000 chars), and optionally Description, a pinned Model, Tool Allowlist, Read-only filesystem, and Max Iterations (1–50)
- Leave the tool allowlist empty to allow all tools. Add specific tools to restrict what the agent can call.
- Save.
To use a custom agent:
- Open Code Mode and find the Agent panel
- In the Agent panel header, click the profile picker dropdown (robot icon, shows "Default" when none selected). The picker is hidden if you have no custom agents.
- Select a custom agent. The next message you send applies that profile.
- Switch back to Default to remove the profile.
If a selected agent is deleted, the picker falls back to Default automatically. Tool allowlists are validated against the live tool registry - invalid tool names are rejected at create time.
Permission mode (ask/plan/act) and sandbox rules are global settings, not agent-derived.
ACP Agent Server - external agents as Fleet members
The ACP (Agent Client Protocol) server lets external coding agents run as Fleet members inside Bodega. Supported agents: Gemini CLI, Claude Code, Codex, and Cursor.
Configure at Settings → ACP Agents. What each one needs:
- Gemini CLI -
GEMINI_API_KEYand@google/gemini-cliinstalled globally - Claude Code -
ANTHROPIC_API_KEYand@zed-industries/claude-code-acpinstalled - Codex -
OPENAI_API_KEYand@zed-industries/codex-acpinstalled - Cursor -
cursor-agentCLI installed andcursor-agent loginrun once (subscription auth, no API key)
Once configured, ACP agents appear as Fleet session options. Communication is NDJSON-RPC over stdin/stdout - Bodega spawns the agent as a child process and routes prompts through the ACP session protocol.
What ACP agents can and can't do:
- File system and shell access routes through Bodega's own tools - sandbox and air-gap rules still apply
- ACP agents do not go through QEL verification - they show an "external - not QEL-verified" badge
- Blocked entirely in air-gap mode - enabling air-gap kills any running ACP subprocesses
Managed llama.cpp embedding server
When using llama.cpp as your embeddings provider, Bodega can manage the embedding server process automatically - separate from the chat server (port 8080), running on port 8081 by default.
To set it up:
- Install an embedding-capable GGUF first: go to Models → llama.cpp → Discover and download a model such as
nomic-embed-textor abgemodel - Go to Settings → Knowledge → Search & Embeddings (or Settings → Models → Codebase Embeddings)
- Set provider to llama.cpp
- Enable the "Let Bodega manage the embedding server" toggle
- In the GGUF dropdown, select an installed model (the dropdown only shows models from your llama.cpp library)
- Optionally set a custom port (default: 8081)
The embedding server starts with the --embedding flag and is fully independent of the chat server. If you'd rather manage the process yourself, leave the toggle off and type the path manually.
Local code review in the Git panel
The Review button in the Git panel runs an AI code review against your current git diff - the "review before I commit" case. It uses your configured LLM provider, so it works fully locally.
To use it:
- Make changes to your project files (staged, unstaged, or both)
- Open the Git panel in Code Mode (Activity Bar → git icon)
- Click Review (next to the Generate commit message button)
- The review result appears inline as a markdown block in the Git panel
If the working tree is clean, the review falls back to comparing the branch against its base (the PR-scope view). Large diffs are clipped and a truncation note is appended.
Delta-only re-review (beta.28): files unchanged since your last review of the project are skipped - the result notes how many, with a Review everything link for a full pass.
This is separate from the /review skill. The /review skill reads source files and runs a code quality analysis. The Git panel Review button reads the git diff and focuses on what changed.
Keyboard shortcuts
| Keys | Action |
|---|---|
| /commit | Stage, write a commit message, and commit |
| /debug | Hypothesis-driven bug investigation |
| /decompose | Turn an objective into a persistent goal with verifiable tasks |
| /docs | Generate JSDoc/docstring documentation for a file |
| /explain | Explain what code does |
| /generate | Generate a new file from a description |
| /onboard | Tour an unfamiliar repo and save the findings as project knowledge |
| /perf | Analyze code for performance issues |
| /refactor | Refactor with plan-first approval |
| /review | Code quality review with merge-safety assessment |
| /security | Static security audit |
| /test | Generate and run tests for a file |
| /clear | Clear the current input field |
| /compact | Summarize older conversation history |
| /mode ask | Set Agent panel to Ask mode |
| /mode plan | Set Agent panel to Plan mode |
| /mode act | Set Agent panel to Act mode |
| /export | Export current chat as a Markdown file (Chat Mode) |
| /preview | Open the Preview tab browser |
| /map | Open the Bodega Map codebase visualization |
This page mirrors the in-app docs hub for app version 1.0.0-beta.41. Found something unclear or out of date? Tell us on Discord. New here? Download the free beta and follow along.