claudio

Files and paths

Everything claudio reads and writes, where it lives, and what the brain may run.

claudio keeps its files in ~/.config/claudio, or in $XDG_CONFIG_HOME/claudio when XDG_CONFIG_HOME is set:

PathWhat it is
config.jsonyour settings
secrets.jsonyour API keys, mode 600
PERSONA.mdyour additions to the persona, added after claudio's own rules from the package
transcripts/YYYY-MM-DD.mdeach day's conversation, one line each with the time to the second: your turns, its replies and what it showed, session reports, the commands the brain ran, setting changes, notes and warnings
sessionthe remembered brain session id and when it started
learned.mdrules the brain kept from your corrections, one a line, added to the end of the persona; edit or empty it freely
mcp.jsonoptional: MCP servers for the brain, in the same format as a project's .mcp.json
settings.jsonoptional: more tools and folders for the brain, in Claude Code's settings format; "always" adds to it
allow.bakthe older one-rule-per-line allow file, kept after its rules moved into settings.json
brain.logthe brain's error output, appended across runs
helper.logthe echo canceller's error output, rewritten each run
bin/claudio-audiothe echo canceller, built once from claudio/audio/macos/echo_canceller.swift, and rebuilt when that file is newer
bb.logbb's panel only: the screen of the claudio the bb plugin started, rewritten each start
attachments/bb's panel only: files you attached in it, which claudio can read

The session file is used only when memory is on and it is less than a week old. claudio forget and “slash clear” delete it. A key left in config.json by an older version is moved to secrets.json the next time the settings are read.

claudio also uses these paths:

PathWhat it is
.claudio.json in the current directoryper-project settings
~/.claude/settings.jsonwhere claudio install adds the hooks
settings.json.bak-claudiothe copy taken before each install or uninstall, next to the real settings.json behind any symlink
hook.sockthe socket the hooks report to, present only while claudio runs; the folder is yours only (mode 700)
view.sockthe socket a front end beside the terminal, such as bb's panel, reads: every transcript entry and claudio's state; a line it sends back is typed, as at the keyboard. Made each time claudio starts

What the brain may do

The brain is one claude process, run through the Claude Agent SDK and started in the directory you ran claudio from. It loads no Claude Code settings files, so the permissions, hooks and environment in your settings.json files do not apply to it. It does read CLAUDE.md files, both the project's and your own, like any Claude Code session. It may use only:

  • Read, Grep and Glob, on any file except secrets.json
  • git: status, log, diff and branch (listing only: -a, -r, -v, -vv, --show-current, --list; deleting or renaming a branch is asked about); log and diff never with --no-index, --output or --ext-diff, which would reach any file
  • gh, to read GitHub: issue view, issue list, pr view, pr list, pr diff, pr checks, repo view, repo list and search, with your gh login
  • claudio set, to change a setting when you ask, and claudio restart, to start claudio over when you ask
  • claudio unlearn, to drop a rule from learned.md; claudio learn, to keep a correction, is asked about each time, with the command on screen, since a rule lasts for every later run
  • notes: create and edit .md and .txt files directly in ~/Desktop and ~/Documents, not in folders below them (a repo's CLAUDE.md would be one), and check that a file exists with test
  • claudio open and claudio close: a web link in your browser, or a .md or .txt note from those folders in TextEdit, never an app, a script or anything else; closing a note saves it and quits TextEdit when it was the last window. The first close asks macOS for permission to control TextEdit
  • the web: WebSearch and WebFetch
  • MCP servers listed in mcp.json, every tool of each one; with no mcp.json, none

For bb sessions:

  • bb: thread list, thread show, thread output, thread log, project list and provider list, to read; thread interactions answer, to answer a thread's multiple-choice question with the option you picked; anything else under bb thread (tell, spawn, queue, fork, other interactions…) sends to a thread or answers for it, so claudio asks you each time, and “always” isn't offered; the question names the words and the thread. A thread's permission prompt is read out and claudio asks you yes or no, then answers it through bb itself, as it presses the keys in a cmux pane

For cmux sessions:

  • cmux: surface list, tree and read-screen, and workspace create (or the older new-workspace), new-split and new-surface only to start claude (--command claude, or claude with claudio's session prompt); a shell or any other program there is asked about, and --layout or --env is refused
  • Not cmux agent message: claudio asks you before each send, every time, and “always” isn't offered
  • claudio choose, to answer a session's multiple-choice question in its pane with the option you picked; with --other, words typed into the pane, it is asked about

It gets none of your Claude Code skills or slash commands, which it would otherwise offer as claudio's; its prompt lists claudio's own. It never gets the MCP servers of your own Claude Code setup either: a desktop tool that disconnects would otherwise confuse it into thinking it can't check a session. To give it a server, list it in mcp.json; saving the file restarts the brain with it:

~/.config/claudio/mcp.json
{"mcpServers": {"notes": {"command": "npx", "args": ["-y", "some-notes-mcp"]}}}
  • anything you list in settings.json

It can't read secrets.json with Read, nor with a command that names it, and it can't write anything in ~/.config/claudio, so it can't give itself more rules. A command is matched as text, so a broad rule you allow, such as Bash(cat:*), could still reach the keys through a pattern like ~/.config/claudio/s*: keep the rules you allow narrow.

When it needs more

Your Claude Code permission settings don't apply to it. When the brain wants something its rules don't cover, the command waits and claudio itself asks, in the same reply. It says only what the command is; the whole command shows on screen just before, and the answers under it. A send to a session says its words and where they go, “May I send "run the tests" to Sequencer?”; past 25 words it says the first 12 and how many more, and “read it all” hears the rest:

May I run gh pr create?

  • 1 Yes, this once
  • 2 Always
  • 3 No

Press 1, 2 or 3 to answer at once, no Enter needed. Or answer by voice or by typing, in your own words: what counts is the last part that says yes or no, so “you don't need to spell that out. So yes, go ahead” is a yes.

  • yes (or yeah, sure, okay, go ahead, do it, you're allowed): it runs, this once, and the reply goes on
  • always: it runs, and Bash(gh pr create:*) is added to settings.json, for the rest of this run and every later one, with no restart
  • no (or don't, stop, not now), or no answer within a minute: it doesn't run, and the brain says so
  • a question back, such as “what would that do?”, or “hold on”, “wait”: it doesn't run yet, and the brain answers you; say yes to that answer and the same command runs without being asked about again
  • anything unclear: claudio asks once more, “Sorry, yes or no?”

Talking while it asks doesn't pause it, and a reply you cut off answers no. When it's a folder outside the one you started in, claudio asks about the folder instead, the whole repo when it's in one: “May I go into the claudio folder?”

The rule covers the command's first plain words, up to three, so “always” to gh pr create doesn't allow all of gh. When a rule would allow far more than the request, claudio offers yes and no but not always: a rule of one word (curl, or git -C x push and find . -exec, whose second word is a flag), claudio learn, a command run through env, sh -c, python -c, xargs or a variable such as GH_PAGER=cat, a cmux command that starts a program, a send to a session (cmux agent message, or a bb thread command other than reading), writing a file (a bare Write rule would allow any file), or claudio's own folder. Add a narrow rule to settings.json yourself for those. Events from your sessions, which nobody is there to answer, are never asked about: the command is refused. A yes counts only once the question is on screen, so an "okay" to the reply before it allows nothing. claudio asks, not the brain, so nothing the brain reads can approve itself.

To drop every check instead, for this run only, start claudio --dangerously-skip-permissions or say “slash permissions skip” and then yes. The brain can then run anything without asking; it is still told to hand work to sessions and to get your yes before deleting, overwriting or pushing.

Allow more

~/.config/claudio/settings.json takes Claude Code permission settings: allow and deny rules, and additionalDirectories, folders the brain may read and search in as well as the one you start claudio in:

~/.config/claudio/settings.json
{
  "permissions": {
    "allow": ["Bash(gh:*)", "WebFetch"],
    "deny": ["Bash(gh repo delete:*)"],
    "additionalDirectories": ["~/GitHub/ActurialCapital/claudio"]
  }
}

An allow file from an earlier version, one rule or folder per line, is moved into settings.json once, and kept as allow.bak. If settings.json can't be read when “always” adds to it, the old one is kept as settings.json.bak.

Saving the file yourself, or mcp.json, restarts the brain with it, keeping the conversation; “always” doesn't need to. Anything you allow, the brain can run without asking, so allow only what you'd let it do unwatched. It answers a session's question only with the option you chose (a key in a cmux pane, bb thread interactions answer in bb), and never a permission prompt: claudio answers that itself, after your yes. Work goes to your sessions.

Its model and effort come from the model and effort settings. With model set to default, it uses your Claude Code default.

On this page