██████╗██╗ █████╗ ██╗ ██╗██████╗ ██╗ ██████╗
██╔════╝██║ ██╔══██╗██║ ██║██╔══██╗██║██╔═══██╗
██║ ██║ ███████║██║ ██║██║ ██║██║██║ ██║
██║ ██║ ██╔══██║██║ ██║██║ ██║██║██║ ██║
╚██████╗███████╗██║ ██║╚██████╔╝██████╔╝██║╚██████╔╝
╚═════╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═════╝
Configure everything in Lua · Parallel multi-agent teams · Vim-grade TUI · Single Go binary
Quick Start · Install · Features · Why Claudio? · Docs
Claudio is to AI coding what Neovim is to text editing.
The binary ships with sensible defaults and a complete feature set. Everything else — keymaps, colorschemes, providers, tools, commands, hooks, sidebar widgets — is configured in ~/.claudio/init.lua. No flags, no JSON soup, no recompiling. Your config lives in one file and travels with you.
-- ~/.claudio/init.lua — the only config file you need
claudio.colorscheme("tokyonight")
claudio.config.set("model", "claude-opus-4-6")
claudio.register_provider({
name = "groq", type = "openai",
base_url = "https://api.groq.com/openai/v1",
api_key = "$GROQ_API_KEY",
routes = { "llama-*" },
})
claudio.register_keymap({ mode = "normal", key = "K", action = "docs",
handler = function() claudio.notify("docs") end })|
|
Real agent parallelism — not just sub-agents. |
|
Full modal state machine — normal, insert, visual, operator-pending — with registers, text objects, counts, and |
Build reusable multi-agent architectures with |
|
Three-scope facts-based memory (project / global / agent). Background extraction after every session. |
Cheap executor (Haiku) does the work; expensive advisor (Opus) consults at PLAN and REVIEW — at most twice per task. Senior judgment at a fraction of the cost. Configurable per-agent in team templates. |
|
Prompt caching, microcompaction, disk offload for large results, duplicate read dedup, image compression, output filtering (38 built-in commands), Lua filter engine, source-code filter, message merging, deferred tool schemas, snippet expansion. |
Promote any session into a reusable agent persona with its own memory, tools, and standing instructions. Crystallized agents carry accumulated memory into every team run — no cold-start rebuilding. |
|
Community plugins live in |
|
|
Cron-style recurring agent jobs: |
Pure Go, zero runtime dependencies. |
# 1. Install
go install github.com/Abraxas-365/claudio/cmd/claudio@latest
# 2. Authenticate
claudio auth login # Anthropic OAuth — or set ANTHROPIC_API_KEY
# 3. Bootstrap your project
cd your-project
claudio # launches the TUI
/init # AI-guided project setup: CLAUDIO.md + skills + hooks
# 4. Start buildingTip:
claudio --resumepicks up your last session.claudio "fix the failing test"runs a one-shot prompt.
-- ~/.claudio/init.lua
claudio.register_provider({
name = "groq",
type = "openai",
base_url = "https://api.groq.com/openai/v1",
api_key = "$GROQ_API_KEY",
routes = { "llama-*" },
})
claudio.register_provider({
name = "ollama",
type = "ollama",
base_url = "http://localhost:11434",
routes = { "qwen*" },
})
claudio.config.set("model", "llama-3.3-70b-versatile")claudio --model gpt-4o # OpenAI
claudio --model llama-3.3-70b-versatile # Groq
claudio --model qwen2.5-coder # Local OllamaOr switch live: :set model llama-3.3-70b-versatile
claudio
/agent ← pick your principal agent (orchestrator / PM)
/team ← pick a team template (worker roster)
"Build the OAuth module with JWT tokens"
Lead agent:
→ Explores codebase, creates plan, asks one clarifying question
→ TaskCreate × 3 (service layer, migrations, tests)
→ SpawnTeammate (backend-mid) (parallel, isolated worktree)
→ SpawnTeammate (backend-jr) (parallel, isolated worktree)
→ SpawnTeammate (backend-senior) (parallel, isolated worktree)
→ Merges branches, runs build, reports back
Claudio is built ground-up in Go for engineers who want more control, more agents, and fewer dependencies.
| Claudio | Claude Code | |
|---|---|---|
| 🏗️ Runtime | Single Go binary — zero runtime deps | Node.js / TypeScript |
| 🔌 Extensibility | Full Lua runtime — tools, keymaps, themes, providers, hooks from init.lua. No recompile. |
Extension API in beta |
| 🤝 Multi-agent teams | Parallel workers in isolated worktrees, mailbox messaging, /harness patterns + split-pane TUI sessions |
❌ |
| 💎 Session-as-agent | Crystallize sessions into reusable personas with accumulated memory | ❌ |
| 🧠 Memory | Scoped (project/agent/global), facts-based, Recall semantic search, /dream consolidation, cache-safe |
Single directory |
| 🗜️ Token efficiency | 11-layer optimization stack | Basic prompt caching |
| 📦 Plugins | Lua plugins via ~/.claudio/plugins/ — full claudio.* API |
❌ |
| ✂️ Snippet expansion | ~name(args) → full boilerplate; zero extra AI tokens |
❌ |
| 🧑💼 Two-Brain Advisor | Cheap executor + expensive advisor at PLAN/REVIEW only | ❌ |
| ⏰ Cron tasks | @every 1h, @daily, HH:MM — inline or background |
Feature-gated |
| 🌐 Web / Mobile UI | comandcenter — WhatsApp-style PWA, push notifications |
❌ |
| 🌉 Cross-session comms | Unix-socket bridge for parallel worktrees | ❌ |
| ⌨️ Vim mode | Full state machine + registers + : command line (like Neovim) |
Basic vi-mode |
| 💾 Persistence | SQLite + file-based | File-based only |
| 🔭 LSP integration | Config-driven language servers — go-to-definition, find-refs, hover | ❌ |
| Go | 1.26+ (for building from source) |
| OS | macOS, Linux (Windows experimental) |
| Auth | Anthropic API key or OAuth — Groq, OpenAI, Ollama also supported |
| Git | Required for project root detection and worktrees |
Optional: $EDITOR for external editing · Language servers (gopls, pyright, …) for LSP · MCP servers for extended tools.
# CLI / TUI
go install github.com/Abraxas-365/claudio/cmd/claudio@latest
# Command Center server (optional — for the web/mobile UI)
go install github.com/Abraxas-365/claudio/cmd/comandcenter@latestMake sure $GOPATH/bin (or $HOME/go/bin) is on your $PATH.
git clone https://github.com/Abraxas-365/claudio
cd claudio
make build # injects version via ldflags
sudo mv claudio /usr/local/bin/
go build -o comandcenter ./cmd/comandcenter
sudo mv comandcenter /usr/local/bin/claudio --help
claudio --versionclaudio # interactive TUI (default)
claudio "explain this codebase" # one-shot prompt
echo "fix the bug in main.go" | claudio # pipe mode
claudio --resume # resume last session
claudio --headless # headless one-shot (no TUI)
# Command Center — browser/mobile UI + remote sessions
comandcenter --password mysecret --port 8080
claudio --attach http://localhost:8080 --name "my-session" --master- The Philosophy
- Why Claudio?
- Requirements
- Installation
- Quick Start
- Lua Configuration
- Project Setup
- CLI Flags
- Interactive Commands
- Keybindings
- Vim Mode &
:Command Line - Context Management
- Token Efficiency
- Memory System
- Tools
- Agents
- Orchestrator & Multi-Agent Teams
- Harness — Agent Team Architecture
- Security
- Hooks
- Scheduled Tasks (Cron)
- Session Sharing
- Plugins
- Model Configuration
- Output Styles
- Snippet Expansion
- Keybinding Customization
- Per-Turn Diff Tracking
- Command Center (Web / Mobile UI)
- Headless Mode
- Filesystem Layout
- Architecture
- License
Claudio embeds a Lua runtime (gopher-lua — pure Go, no CGO) that gives you full control over every aspect of your setup without recompiling. The philosophy is the same as Neovim: the binary ships compiled defaults, and your ~/.claudio/init.lua overrides everything on top.
-- ~/.claudio/init.lua
-- ── Model & settings ──────────────────────────────────────────
claudio.config.set("model", "claude-opus-4-6")
claudio.config.set("caveman", true)
claudio.config.set("compactMode", "strategic")
-- ── Theme ─────────────────────────────────────────────────────
claudio.colorscheme("tokyonight")
-- or fine-grained:
claudio.ui.set_color("primary", "#7aa2f7")
claudio.ui.set_border("rounded")
-- ── Keymaps ───────────────────────────────────────────────────
claudio.register_keymap({ mode = "normal", key = "K", action = "show_docs",
handler = function() claudio.notify("docs") end })
-- ── Providers ─────────────────────────────────────────────────
claudio.register_provider({
name = "groq",
type = "openai",
base_url = "https://api.groq.com/openai/v1",
api_key = "$GROQ_API_KEY",
routes = { "llama-*" },
})
claudio.register_provider({
name = "ollama",
type = "ollama",
base_url = "http://localhost:11434",
routes = { "qwen*" },
})
-- ── Hooks ─────────────────────────────────────────────────────
claudio.subscribe("tool.executed", function(e)
if e.tool_name == "Bash" then
claudio.log("[audit] " .. tostring(e.input))
end
end)
-- ── Commands ──────────────────────────────────────────────────
claudio.register_command({
name = "standup",
description = "Print git log for standup",
execute = function(args)
return "run: git log --oneline --since=yesterday"
end,
})
-- ── Capabilities ──────────────────────────────────────────────
claudio.register_capability("database", {
tools = { "SQLQuery", "SchemaInspect", "MigrationRun" }
})
-- ── Sidebar panel ─────────────────────────────────────────────
local panel = claudio.win.new_panel({ position = "right", width = 40 })
panel:add_section({
id = "git-status",
title = "Git",
priority = 10,
render = function(w, h) return claudio.cmd("git status --short") end,
})1. internal/lua/defaults.lua ← embedded binary defaults (Gruvbox theme, keymaps, sidebar)
2. ~/.claudio/init.lua ← your personal config
3. ~/.claudio/plugins/*/ ← community plugins
4. .claudio/init.lua ← project overrides (per-repo, wins over personal)
Each layer overrides the one before. Project config wins over personal; personal wins over defaults.
A fully-annotated reference config lives at examples/init.lua — copy it to ~/.claudio/init.lua as a starting point. It includes Gruvbox, Tokyo Night, and Catppuccin Mocha themes as drop-in alternatives, plus examples for every API surface (sidebar blocks, keymaps, providers, hooks, plugins).
Lua plugin examples live in examples/lua-plugins/.
Community plugins are directories under ~/.claudio/plugins/, each with an init.lua:
~/.claudio/plugins/
claudio-jira/
init.lua
claudio-database/
init.lua
Install via CLI:
claudio plugin install https://github.com/someone/claudio-jira
claudio plugin list
claudio plugin remove claudio-jira
claudio plugin info claudio-jiraA plugin's init.lua receives the same claudio.* API — it can register tools, skills, commands, providers, keymaps, capabilities, and hooks exactly like your personal init.lua.
-- Notifications
claudio.notify("message") -- info level
claudio.notify("oops", "error") -- "info" | "warn" | "error"
claudio.log("debug message") -- logs to debug output only
-- Execute any colon command
claudio.cmd("colorscheme tokyonight")
claudio.cmd("set model=claude-sonnet-4-6")
-- Register a custom AI tool (exposed to the agent)
claudio.register_tool({
name = "my_tool",
description = "Does something useful",
schema = { type = "object", properties = { path = { type = "string" } }, required = {"path"} },
execute = function(input)
return "result: " .. input.path
end,
})
-- Register a skill (slash-command for the agent)
claudio.register_skill({
name = "deploy",
description = "Deploy the current project",
content = "Run: make deploy && notify me when done",
capabilities = { "bash" },
})
-- Register a hook (pre/post tool execution)
claudio.register_hook("before_tool", "bash", function(ctx)
claudio.notify("About to run: " .. ctx.command)
end)
-- Register a colon :command
claudio.register_command({
name = "reload",
description = "Reload Lua config",
aliases = { "rl" },
execute = function(args)
claudio.notify("Reloading...")
return nil
end,
})
-- Register a custom AI provider
claudio.register_provider({
name = "my-llm",
type = "openai_compat",
base_url = "https://my-llm.example.com/v1",
api_key = os.getenv("MY_LLM_KEY"),
models = { "my-model-7b" },
context_window = 32000,
})
-- Register a named capability (set of tools for agents)
claudio.register_capability("web_tools", { "fetch", "search" })
-- Event bus
claudio.subscribe("session.start", function(evt)
claudio.notify("New session: " .. (evt.session_id or ""))
end)
claudio.publish("my.event", { key = "value" })
-- Per-plugin config (namespaced, survives restarts)
claudio.set_config("auto_format", true)
local enabled = claudio.get_config("auto_format")-- Read / write Claudio settings at runtime
claudio.config.set("model", "claude-opus-4-6")
claudio.config.set("caveman", true) -- ultra-terse responses
claudio.config.set("permissionMode", "auto") -- "default" | "auto" | "plan"
claudio.config.set("compactMode", true)
claudio.config.set("compactKeepN", 5)
claudio.config.set("outputStyle", "minimal")
claudio.config.set("autoMemoryExtract", true)
local model = claudio.config.get("model")Available keys: model, smallModel, permissionMode, compactMode, compactKeepN, sessionPersist, hookProfile, autoCompact, caveman, outputStyle, outputFilter, autoMemoryExtract, memorySelection
-- Map a <Space>-prefixed leader sequence to a built-in action
claudio.keymap.map("<space>ww", "window.cycle")
claudio.keymap.map("<space>gs", "session.search")
-- Map to a custom Lua function
claudio.keymap.map("<space>nn", function(evt)
claudio.notify("hello from keymap!")
end, { desc = "Say hello" })
-- Remove a leader binding
claudio.keymap.unmap("<space>ww")
-- Delete a raw vim-mode binding
claudio.keymap.del("normal", "gd")
-- List all bindings for a mode
local maps = claudio.keymap.list("normal")
for _, m in ipairs(maps) do
print(m.key, m.action)
end
-- Register insert/normal/visual mode bindings (legacy)
claudio.register_keymap({
mode = "insert",
key = "<C-f>",
action = "format.selection",
handler = function() claudio.cmd("format") end,
})Built-in action IDs available via claudio.actions.list().
-- Full theme override (any subset works)
claudio.ui.set_theme({
primary = "#7aa2f7",
secondary = "#bb9af7",
success = "#9ece6a",
warning = "#e0af68",
error = "#f7768e",
muted = "#565f89",
surface = "#1a1b26",
surface_alt = "#24283b",
text = "#c0caf5",
dim = "#9aa5ce",
subtle = "#414868",
orange = "#ff9e64",
aqua = "#73daca",
})
-- Change border style: "rounded" | "sharp" | "block" | "none"
claudio.ui.set_border("sharp")
-- Custom statusline (returned string is displayed)
claudio.ui.set_statusline(function(ctx)
return string.format(" %s │ %s ", ctx.model or "?", ctx.session_title or "no session")
end)
-- Floating popup
claudio.ui.popup({
title = "My Plugin",
content = "Hello from Lua!",
width = 60,
height = 10,
})
-- Add an entry to the command palette (<Space><Space>)
claudio.ui.register_palette_entry({
name = "Open scratchpad",
description = "Opens the scratch buffer",
handler = function()
claudio.cmd("win scratch")
end,
})
-- Interactive picker (vim.ui.select equivalent)
claudio.ui.pick(
{ { value = "foo", display = "Option A" }, { value = "bar", display = "Option B" } },
{
title = "Choose",
on_select = function(item) claudio.notify("picked: " .. item.value) end,
on_cancel = function() claudio.notify("cancelled") end,
}
)Built-in colorschemes: tokyonight, gruvbox, catppuccin, nord, dracula
-- Create a live-updating buffer
local buf = claudio.buf.new({
name = "my-panel",
render = function(width, height)
return "Live content at " .. os.time()
end,
})
-- Register as a named window (opens with :win my-panel)
claudio.ui.register_window({
name = "my-panel",
buffer = buf,
layout = "right", -- "left" | "right" | "float"
title = "My Panel",
})
-- OR create a full sidebar panel with sections
local panel = claudio.win.new_panel({ position = "right", width = 40 })
panel:add_section({
id = "status",
title = "Status",
priority = 10,
render = function(w, h)
return "Running: " .. (claudio.agent.current() or "none")
end,
})
-- Open a new agent pane (split view) — keybinding: <Space>wn
claudio.win.open_agent({}) -- new pane, default agent
claudio.win.open_agent({ agent = "jj" }) -- new pane with jj persona-- Set placeholder text shown in empty prompt
claudio.prompt.set_placeholder("Ask anything...")
-- Switch prompt editing mode: "vim" | "simple"
claudio.prompt.set_mode("vim")
-- Hook fired before submission — return false to cancel, return string to transform
claudio.prompt.on_submit(function(text)
if text:sub(1,1) == "!" then
-- reroute to shell
claudio.cmd("bash " .. text:sub(2))
return false -- cancel normal submission
end
return text
end)-- Query current agent
local name = claudio.agent.current() -- nil when no agent active
-- React to agent changes
claudio.agent.on_change(function(new_agent, old_agent)
claudio.notify("switched to: " .. (new_agent or "none"))
end)
-- Inject extra context into every prompt
claudio.agent.add_context("Always reply in Portuguese.")
-- Dynamic prompt suffix per agent
claudio.agent.set_prompt_suffix(function(agent_name)
if agent_name == "researcher" then
return "\nCite all sources."
end
return ""
end)
-- List all running agents
local agents = claudio.agent.list()
-- each: { id, name, status, team, has_window }
-- Programmatically spawn a sub-agent
claudio.agent.spawn({
prompt = "Summarise the latest commit",
model = "claude-haiku-4-5-20251001",
max_turns = 5,
tools = { "bash", "read" },
}, function(result, err)
if err then claudio.notify(err, "error") return end
claudio.ui.popup({ title = "Summary", content = result, width = 80, height = 20 })
end)local id = claudio.session.id()
local title = claudio.session.title()
claudio.session.on_start(function(session_id, session_title)
claudio.notify("started: " .. session_title)
end)
claudio.session.on_end(function(session_id)
claudio.log("session ended: " .. session_id)
end)
claudio.session.on_message(function(role, content)
if role == "assistant" then
-- react to every assistant reply
end
end)
-- Read recent messages
local msgs = claudio.session.messages(10)
for _, m in ipairs(msgs) do
print(m.role, m.content)
endlocal all = claudio.sessions.list() -- up to 50 most-recent
local recent = claudio.sessions.list(10)
local found = claudio.sessions.search("authentication", 20)
-- each item: { id, title, project_dir, model, created_at, updated_at }-- Inspect branch tree
local cur = claudio.branch.current() -- { id, title, parent_id, depth, ... }
local parent = claudio.branch.parent()
local children = claudio.branch.children()
local root = claudio.branch.root()
-- Create a new branch from the current message
local branch, err = claudio.branch.create()
if err then claudio.notify(err, "error") end
-- Switch to a branch
local ok, err = claudio.branch.switch(branch.id)
-- Read another branch's messages
local msgs = claudio.branch.messages(branch.id)
-- Hook: fires whenever a branch is created
claudio.branch.on_branch(function(branch_id, parent_id, message_id)
claudio.notify("new branch from message " .. message_id)
end)local team_names = claudio.teams.list()
-- e.g. { "backend-team", "frontend-team" }
local members = claudio.teams.members("backend-team")
-- each: { id, name, role, status }
for _, m in ipairs(members) do
print(m.name, m.status) -- status: "idle" | "running" | "done" | "error"
end-- One-shot LLM call (runs in background, callback on completion)
claudio.ai.run({
system = "You are a terse code reviewer.",
user = "Review: " .. vim.fn.getreg('"'),
model = "claude-haiku-4-5-20251001",
}, function(result, err)
if err then claudio.notify(err, "error") return end
claudio.ui.popup({ title = "Review", content = result, width = 80, height = 30 })
end)-- Register a named output filter applied to bash commands
claudio.filter.register("clean-go-test", {
match_command = "^go test",
strip_ansi = true,
strip_lines_matching = "^=== RUN",
keep_lines_matching = "FAIL|PASS|panic",
head_lines = 0,
tail_lines = 50,
max_lines = 200,
transform = function(output) return output:gsub("%s+$", "") end,
})
claudio.filter.unregister("clean-go-test")
local filters = claudio.filter.list()-- Open a built-in picker
claudio.picker.buffers() -- recent sessions
claudio.picker.agents() -- running agents
claudio.picker.commands() -- colon commands
claudio.picker.skills() -- available skills
-- Open a custom picker with a static list
local finder = claudio.finder.from_table({
{ value = "alpha", display = "Alpha" },
{ value = "beta", display = "Beta" },
})
claudio.picker.open({
title = "Pick one",
finder = finder,
layout = "center",
on_select = function(entry)
claudio.notify("selected: " .. entry.value)
end,
})
-- Dynamic/async finder (items stream in)
local finder = claudio.finder.from_fn(function(query, emit, done)
for _, item in ipairs(my_search(query)) do
emit({ value = item, display = item })
end
done()
end)-- Register a language server for given file extensions
claudio.lsp.register_server({
name = "gopls",
command = "gopls",
args = { "serve" },
extensions = { ".go" },
})
-- Start / stop a server (rootDir defaults to cwd)
claudio.lsp.enable("gopls")
claudio.lsp.enable("gopls", "/path/to/project")
claudio.lsp.disable("gopls")
-- Query running servers
local servers = claudio.lsp.list()
-- each: { name, status, root_dir }
-- Code-intelligence queries (all blocking, return result or nil)
local info = claudio.lsp.hover({ file = vim.fn.expand("%:p"), line = 10, col = 5 })
local loc = claudio.lsp.go_to_definition({ file = "main.go", line = 42, col = 8 })
local refs = claudio.lsp.find_references({ file = "main.go", line = 42, col = 8 })
local syms = claudio.lsp.document_symbols("main.go")claudio.models.*, claudio.commands.*, claudio.skills.*, claudio.windows.*, claudio.actions.* — introspection
-- List everything available at runtime
local models = claudio.models.list() -- { id, name, provider, context_window }
local commands = claudio.commands.list() -- { name, description, aliases }
local skills = claudio.skills.list() -- { name, description }
local windows = claudio.windows.list() -- { name, title, layout }
local actions = claudio.actions.list() -- array of action ID strings
-- Read a window's current rendered content
local text = claudio.windows.read("agent://researcher")Press :checkhealth (or :health) in the TUI for a diagnostics report:
Lua Plugins
✓ claudio-jira (loaded)
✗ claudio-broken (error: attempt to index a nil value)
Capabilities
design (4 factories)
database (3 factories)
Config
model: claude-opus-4-6
permissionMode: default
compactMode: strategic
LSP
gopls go, gomod
Recommended: Run
/initinside the TUI rather thanclaudio init. The TUI version is AI-powered — it surveys your codebase, interviews you, and generates a tailoredCLAUDIO.md, skills, and hooks.
claudio # start the TUI
/init # run the init skill
The /init skill walks through several phases:
- Asks setup questions (scope, branch conventions, gotchas)
- Surveys the codebase with a sub-agent
- Writes
CLAUDIO.mdand optionallyCLAUDIO.local.md(gitignored personal overrides) - Creates project skills under
.claudio/skills/ - Suggests hooks and GitHub CLI integrations
CLI fallback: claudio init creates the .claudio/ scaffold without the interactive interview.
.claudio/
settings.json # Project-specific settings (overrides global)
rules/ # Project-specific rules
project.md
skills/ # Project-specific skills
agents/ # Project-specific agent definitions
memory/ # Project-scoped memories
.gitignore
CLAUDIO.md # Project instructions for the AI
Settings are resolved with priority (highest first):
Environment variables CLAUDIO_MODEL, CLAUDIO_API_BASE_URL, …
|
.claudio/init.lua Project Lua config (per-repo, committed)
|
~/.claudio/plugins/*/init.lua Community plugins
|
~/.claudio/init.lua Personal Lua config — keymaps, theme, providers
|
internal/lua/defaults.lua Embedded defaults (compiled into binary)
|
~/.claudio/state.json Machine-written state only
Human config lives in init.lua, not JSON. Everything intentional goes in ~/.claudio/init.lua. state.json is machine-written and you never touch it.
Scalar values (model, permissionMode) are overridden by higher priority. Lists (denyTools, denyPaths) are appended across layers.
Open with <Space>ic:
- P badge = setting from project scope
- G badge = setting from global scope
tabto switch scope,enterto toggle/cycle (saved immediately)
{
"model": "claude-sonnet-4-6",
"smallModel": "claude-haiku-4-5-20251001",
"thinkingMode": "",
"budgetTokens": 0,
"effortLevel": "medium",
"permissionMode": "default",
"autoCompact": false,
"compactMode": "strategic",
"sessionPersist": true,
"hookProfile": "standard",
"autoMemoryExtract": false,
"memorySelection": "ai",
"outputStyle": "normal",
"cavemanMode": "",
"costConfirmThreshold": 0,
"apiBaseUrl": "https://api.anthropic.com",
"maxBudget": 0,
"denyPaths": [],
"allowPaths": [],
"denyTools": [],
"permissionRules": [],
"mcpServers": {}
}| Setting | Values | Description |
|---|---|---|
model |
any model ID | Default AI model |
thinkingMode |
"", adaptive, enabled, disabled |
Extended thinking mode |
budgetTokens |
token count | Thinking budget when mode is enabled |
effortLevel |
low, medium, high |
Reasoning depth |
permissionMode |
default, auto, plan |
Tool approval behavior |
permissionRules |
array of rules | Content-pattern rules |
autoMemoryExtract |
true/false |
Auto-extract memories after each turn |
memorySelection |
ai, keyword, none |
How memories are selected for system prompt |
outputStyle |
normal, concise, verbose, markdown |
Response formatting |
costConfirmThreshold |
USD amount, 0 = disabled | Pause at this cost |
denyTools |
list of tool names | Disable specific tools |
compactMode |
auto, manual, strategic |
When to compact history |
compactKeepN |
integer (default 10) |
Messages kept after compaction |
maxBudget |
USD, 0 = unlimited | Session spend limit |
outputFilter |
true/false |
RTK-style command output filtering |
cavemanMode |
"", lite, full, ultra |
Compressed output mode |
toolModels |
map[string]string |
Per-tool model override |
publicUrl |
string | Public base URL for bundle share links |
Place a CLAUDIO.md or CLAUDE.md in your project root. Searched paths (first match wins per directory):
./CLAUDIO.md./CLAUDE.md./.claudio/CLAUDE.md
Subdirectory discovery: Claudio walks from your cwd up to the git root, loading files at each level.
@imports: Include other markdown files:
# My Project
@docs/conventions.md
@docs/architecture.md{
"permissionRules": [
{"tool": "Bash", "pattern": "git *", "behavior": "allow"},
{"tool": "Bash", "pattern": "rm -rf *", "behavior": "deny"},
{"tool": "Write", "pattern": "*.test.*", "behavior": "allow"},
{"tool": "*", "pattern": "*.env", "behavior": "deny"}
]
}Rules are evaluated in order; first match wins. Behaviors: allow (skip approval), deny (block), ask (show dialog).
| Flag | Short | Description |
|---|---|---|
--model |
AI model override | |
--version |
-v |
Print version and exit |
--resume |
-r |
Resume last session |
--session |
-s |
Resume session by ID |
--headless |
One-shot without TUI | |
--no-persist |
Disable session persistence | |
--attach |
Attach to a ComandCenter server | |
--name |
Session name (for attach) | |
--master |
Mark as master session (for attach) | |
--permission |
-p |
Permission mode: default, auto, plan |
--cwd |
Working directory override |
Press : in normal vim mode — exactly like Neovim:
| Command | Description |
|---|---|
:lua <code> |
Execute Lua live — :lua claudio.notify("hi"), :lua claudio.ui.set_color(...) |
:set <key> [value] |
Read or write any config — :set model, :set caveman true |
:colorscheme <name> |
Switch theme — tokyonight, gruvbox, catppuccin, nord, dracula |
:checkhealth |
Diagnose plugins, capabilities, config, LSP |
:health |
Alias for :checkhealth |
:<command> |
Any /command also works as a :command |
Plugins can register new : commands with claudio.register_command().
| Command | Aliases | Description |
|---|---|---|
/help |
h, ? |
Show available commands |
/model |
m |
Show or change the AI model |
/compact [instruction] |
Compact conversation history | |
/cost |
Show session cost and token usage | |
/memory extract |
mem |
Manually extract memories |
/session |
sessions |
List or manage sessions |
/resume [id] |
Resume a previous session | |
/new |
Start a new session | |
/rename [title] |
Rename the current session | |
/config |
settings |
View/edit configuration |
/commit |
Create a git commit with AI-generated message | |
/diff [args] |
Show git diff | |
/status |
Show git status | |
/share [path] |
Export session for sharing | |
/teleport <path> |
Import a shared session file | |
/plugins |
List installed plugins | |
/gain |
Show token savings from output filters | |
/discover |
Show commands that ran without a filter | |
/output-style [style] |
Show or set output style | |
/caveman [lite|full|ultra|off] |
Toggle compressed output mode | |
/keybindings |
Open keybindings.json in $EDITOR |
|
/vim |
Toggle vim keybindings | |
/skills |
List available skills | |
/tasks |
Show background tasks and team status | |
/agent |
Pick an agent persona for this session | |
/team |
Pick a team template | |
/dream |
Consolidate and clean up memories | |
/audit |
Show recent tool audit log | |
/export [format] |
Export conversation (markdown, json, txt) | |
/undo |
Undo the last exchange | |
/doctor |
Diagnose environment issues | |
/mcp |
Manage MCP servers | |
/harness <description> |
Build a reusable multi-agent architecture | |
/exit |
quit, q |
Exit Claudio |
| Key | Action |
|---|---|
Ctrl+C |
Cancel streaming / quit |
Ctrl+G |
Open prompt in $EDITOR |
Ctrl+V |
Paste image from clipboard |
Shift+Tab |
Cycle permission mode |
Esc |
Dismiss overlays / cancel streaming |
Enter with <Space>wk or (in vim normal mode with empty prompt) scroll with j/k:
| Key | Action |
|---|---|
j / k |
Navigate between message sections |
Ctrl+D / Ctrl+U |
Jump 5 sections down/up |
g / G |
Jump to top/bottom |
/ |
Search messages |
p |
Pin/unpin message (pinned = survives compaction) |
Enter / Ctrl+O |
Toggle tool group expansion |
i / q / Esc |
Return to prompt |
| Sequence | Action |
|---|---|
<Space>wk |
Focus viewport |
<Space>wj |
Focus prompt |
<Space>bn / <Space>bp |
Next / previous session |
<Space>bc |
Create new session |
<Space>bk |
Delete current session |
<Space>. |
Open session picker (telescope-style) |
<Space>,<Enter> |
Switch to alternate session |
| Sequence | Action |
|---|---|
<Space>wn |
Open new agent pane (split) |
<Space>wN |
Cycle to previous pane |
<Space>wx |
Close current pane |
Active pane shown with ● indicator. Each pane has its own session, engine, message history, and scroll state.
| Key | Panel | Description |
|---|---|---|
c |
Configuration | View/edit settings with scope badges |
m |
Memory | Browse, search, edit, add, delete memories |
k |
Skills | Browse available skills |
a |
Analytics | Session statistics and cache metrics |
t |
Tasks | Background tasks and team agent status — press / to filter by title |
Toggle vim mode with /vim. Full modal state machine:
- Normal mode (
Esc):hjkl,w/b/eword motion,f/F/t/Tchar search,.repeat,d/c/yoperators, text objects (iw,i",i(, …), registers ("aprefix), counts (3dw),%bracket matching - Insert mode (
i): standard editing - Visual mode (
v): character/line selection with operators - Operator-pending mode: after
d/c/y
Press : in normal mode to open the command line — a live Lua REPL and config interface. Press Tab for wildmenu completion on commands and arguments.
Customize in ~/.claudio/keybindings.json or via Lua:
-- ~/.claudio/init.lua
claudio.keymap.set("normal", "<leader>gr", "git_refs", function()
claudio.cmd("git log --oneline -20")
end)Or via the /keybindings command to open the JSON in your editor.
[████████░░] 72%
Colors: green (< 70%), yellow (70–90%), red (> 90%). Auto-compaction at 95%.
Press p in viewport mode to pin messages. Pinned messages survive compaction.
Tiered as context fills:
- 70%: partial compact (clear old tool results)
- 90%: suggest full compaction
- 95%: force compact (summarize old messages, keep last N + pinned)
Manual: /compact [instruction] — optional instruction guides what the summary focuses on.
An 11-layer optimization stack to minimize cost and keep long sessions within the context window.
Every request marks the last system prompt block with cache_control: {type: "ephemeral"}. Cached input tokens cost ~10× less. In practice the system prompt (instructions, memories, tool descriptions) is only paid for in full once per session.
After every tool-execution turn, MicroCompact clears read-heavy tool results older than the last 6 and larger than 2 KB. Affected tools: Bash, Read, Glob, Grep, WebFetch, WebSearch, LSP, ToolSearch. Runs continuously without any threshold.
Results larger than 50 KB are written to disk and replaced with a compact placeholder. Cleaned up when the session ends.
When "outputFilter": true, Bash outputs pass through three filter layers before entering context:
- Lua filters — registered via
claudio.filter.register()in yourinit.lua; highest priority - 38 built-in filters — Go, Rust, JS/TS, Python, JVM, .NET, Swift, DevOps, Docker, and more
- Generic filters — ANSI stripping, blank line collapse, duplicate line dedup, progress bar removal, long-line truncation
Custom filters live in .claudio/init.lua alongside the rest of your config:
-- .claudio/init.lua
claudio.filter.register("my-tool", {
match_command = "^my-tool$",
strip_ansi = true,
max_lines = 50,
on_empty = "my-tool: ok",
strip_lines_matching = { "^Downloading", "^Resolving" },
-- optional: full control via transform function
transform = function(output)
return output:gsub("^Progress:%s*%d+%%\n", "")
end,
})Declarative fields (all optional):
| Field | Type | Effect |
|---|---|---|
match_command |
regex string | Only apply to commands matching this pattern |
strip_ansi |
bool | Strip ANSI escape codes |
replace |
{pattern, replacement}[] |
Regex replacements applied in order |
strip_lines_matching |
string[] | Remove lines matching any pattern |
keep_lines_matching |
string[] | Remove lines not matching any pattern |
truncate_lines_at |
int | Truncate lines longer than N chars |
head_lines |
int | Keep only first N lines |
tail_lines |
int | Keep only last N lines |
max_lines |
int | Alias for tail_lines |
on_empty |
string | Return this string if output becomes empty |
transform |
function | Called with final output string; return value replaces it |
Manage registered filters at runtime:
claudio.filter.list() -- returns table of registered filter names
claudio.filter.unregister("my-tool")Legacy:
.claudio/filters.tomlis still loaded and respected, but Lua filters take priority. New projects should useinit.lua.
Set CLAUDIO_NO_FILTER=1 to bypass all filters, CLAUDIO_FILTER_DEBUG=1 to log which filter matched.
{ "codeFilterLevel": "minimal" }| Level | Effect |
|---|---|
none |
Raw file content |
minimal |
Strips comments, preserves doc comments, collapses blanks |
aggressive |
Function/type signatures + imports only; bodies replaced with // ... |
Only applies to full-file reads of files > 500 lines.
Reduces output tokens by ~65–75% via terse communication rules:
{ "cavemanMode": "full" }| Mode | Style |
|---|---|
lite |
No filler/hedging, keeps full sentences |
full |
Drops articles, fragments OK, [thing] [action] [reason] |
ultra |
Maximum compression — abbreviations, arrows for causality, one word when one word is enough |
Code blocks and security warnings are always written with full clarity regardless of mode.
| Technique | Typical saving |
|---|---|
| Prompt caching | ~90% discount on system tokens per turn |
| Microcompaction | Continuous reduction of old tool result bulk |
| Tool result disk offload | Caps single-result payload at 50 KB |
| Duplicate read cache | Eliminates redundant file read tokens |
| Image compression | Reduces image payloads to ≤500 KB |
| Output filtering (38 commands) | 60–90% reduction on noisy command outputs |
| Lua filter engine | User-customizable via init.lua, supports transform functions |
| Source-code filter | Strips comments from large files |
| Deferred tool schemas | Saves full schema cost for unused tools |
| Snippet expansion | Reduces AI output tokens for repetitive boilerplate |
| CavemanMode | 65–75% reduction in assistant text tokens |
Three-scope, facts-based memory. Cache-safe — never breaks prompt caching.
| Scope | Path | Purpose |
|---|---|---|
| Project | ~/.claudio/projects/<project-slug>/memory/ |
Repo conventions, decisions, architecture |
| Global | ~/.claudio/memory/ |
Cross-project preferences and personal style |
| Agent | ~/.claudio/agents/<name>/memory/ |
Per-crystallized-agent knowledge |
Resolution priority: Agent > Project > Global.
Scope decision rule: "Would this be true in a completely different project?"
- Yes →
global· No →project· Persona-specific →agent
---
name: jwt-config
description: JWT token configuration for this API
type: project
scope: project
tags: [auth, jwt, token]
facts:
- JWT tokens expire in 24h
- Refresh threshold is 20h — issue new token if TTL < 4h
- Secret stored in .env.local under JWT_SECRET
- Signing algorithm is RS256
concepts:
- token-lifecycle
- session-management
---A lean memory index is injected into the first human turn (not the system prompt — cache is never broken):
## Your Memory Index
### Project Memories
- jwt-config [auth,jwt]: JWT configuration — "Expires in 24h" | "RS256 signing"
- no-orm [db,sql]: DB rules — "Never use GORM" | "Raw SQL via modernc.org/sqlite"
The agent then calls:
Memory(action="read", name="...")— load full facts for a specific entryRecall(context="...")— semantic search across all scopesMemory(action="append", name="...", fact="...")— add one fact (no full rewrite)Memory(action="save", ...)— create a new entry
Background memory extraction is disabled by default. Enable with "autoMemoryExtract": true.
/dream runs a consolidation agent that:
- Lists all existing memories
- Detects contradictions and deletes stale facts
- Appends new facts to existing entries
- Creates new memories for new learnings
- Promotes project-scope entries to global when they reflect universal preferences
Run /dream at the end of a productive session to keep memory accurate.
| Key | Action |
|---|---|
j / k |
Navigate |
d |
Delete selected memory |
e |
Edit in $EDITOR |
a |
Add new memory |
r |
Refresh list |
tab |
Switch Memories/Rules tabs |
Stored in ~/.claudio/instincts.json. Confidence-scored patterns that decay after 30 days. Categories: debugging, workflow, convention, workaround.
Core tools are always loaded; deferred tools load on-demand via ToolSearch.
| Tool | Description |
|---|---|
| Bash | Execute shell commands |
| Read | Read files (images, PDFs, notebooks) |
| Write | Create or overwrite files |
| Edit | Exact string replacement |
| Glob | Find files by pattern |
| Grep | Search file contents (ripgrep) |
| Agent | Spawn sub-agents |
| ToolSearch | Discover deferred tools |
| Tool | Description |
|---|---|
| Memory | Search, list, read persistent memories |
| Recall | Semantic memory search |
| WebSearch / WebFetch | Web search and URL fetching |
| LSP | Language server operations |
| NotebookEdit | Jupyter notebook editing |
| TaskCreate/List/Get/Update | Task management |
| EnterPlanMode / ExitPlanMode | Planning workflow |
| EnterWorktree / ExitWorktree | Git worktree isolation |
| TaskStop / TaskOutput | Background task control |
| TeamCreate / SpawnTeammate / SendMessage | Multi-agent teams |
| InstantiateTeam | Restore a saved team template |
| CronCreate / CronDelete / CronList | Scheduled recurring tasks |
| AskUser | Ask user structured questions |
Disable any tool: "denyTools": ["ToolName"] in settings.
Config-driven — no servers are built-in. Configure via settings:
{
"lspServers": {
"gopls": {
"command": "gopls",
"args": ["serve"],
"extensions": [".go", ".mod"]
},
"typescript": {
"command": "typescript-language-server",
"args": ["--stdio"],
"extensions": [".ts", ".tsx", ".js", ".jsx"]
}
}
}Or drop a *.lsp.json file in ~/.claudio/plugins/. Servers start lazily on first use and shut down after 5 minutes of inactivity.
Operations: goToDefinition, findReferences, hover, documentSymbol, workspaceSymbol, goToImplementation, prepareCallHierarchy, incomingCalls, outgoingCalls.
| Type | Model | Description |
|---|---|---|
general-purpose |
inherit | Multi-step tasks, code search, research |
Explore |
haiku | Fast read-only codebase exploration |
Plan |
inherit | Design implementation plans (read-only) |
verification |
inherit | Validate implementations, run tests |
Flat file — ~/.claudio/agents/<name>.md:
---
description: Expert Go backend developer
tools: "*"
model: opus
---
You are an expert Go backend developer...Directory form — ~/.claudio/agents/<name>/ (preferred when you need agent-specific plugins or skills):
agents/
my-agent/
AGENT.md ← same front-matter + body as flat form
plugins/ ← executables loaded only for this agent
skills/ ← skills loaded only for this agent
my-skill/
SKILL.md
| Field | Type | Description |
|---|---|---|
name |
string | Display name |
description |
string | When-to-use guidance shown in agent selector |
model |
string | haiku, sonnet, or opus |
tools |
string or list | "*" for all tools, or an explicit allow-list |
disallowedTools |
list | Tool names to block even when tools: "*" |
capabilities |
list | Opt-in feature sets (e.g. design) |
autoLoadSkills |
list | Skills pre-loaded at spawn — no model invocation needed |
maxTurns |
int | Max agentic turns before stopping |
Crystallize a session's knowledge into a reusable agent persona with its own memory directory. Crystallized agents carry accumulated memory into every team run — no cold-start rebuilding.
Real parallelism — not just sequential sub-agents. Workers run simultaneously in isolated git worktrees.
┌───────────────┐ TeamCreate ┌─────────┐
│ Principal │─────────────────▶│ Manager │
│ Agent (lead) │ └─────────┘
│ │ SpawnTeammate ┌──────────────────────────┐
│ │─────────────────▶│ TeammateRunner │
│ │ │ [backend-mid] worker │──┐ each runs its own
│ │ │ [backend-jr] worker │ │ LLM loop + worktree
│ │ │ [backend-senior] worker │ │ in parallel
│ │ └──────────────────────────┘ │
│ │ on completion: │
│ │◀──────────── Mailbox (file JSON + flock) ◀──────┘
└───────────────┘
- Team creation — creates a team config and inbox directory under
~/.claudio/teams/{name}/ - Spawning — each teammate launches as a goroutine running a full
query.Enginewith its own git worktree branch - Worktree isolation — parallel agents never conflict on the filesystem; lead merges when agents complete
- Messaging — file-based JSON inboxes with
flock. Direct messages, broadcasts, structured control messages. - Completion — teammate sends completion message to lead's mailbox; lead picks it up on next turn
- Task tracking —
TaskCreatetasks auto-complete when the agent finishes; persisted to SQLite
| Tool | Description |
|---|---|
TeamCreate |
Create a new team (caller becomes lead) |
SpawnTeammate |
Spawn a named teammate from a crystallized agent persona |
SendMessage |
Direct or broadcast messages between agents |
InstantiateTeam |
Re-create a team from a saved template |
TaskCreate / TaskUpdate |
Create and track tasks |
PurgeTeammates |
Remove done/idle teammates to keep context clean |
/agent ← Step 1: pick your principal agent (the one you'll talk to)
/team ← Step 2: pick a team template (the workers it can spawn)
"Build the OAuth module with JWT tokens"
The principal agent:
- Clarifies scope (one question if ambiguous)
- Explores codebase with a
code-investigatorworker - Presents plan and waits for confirmation
- Creates tasks, spawns workers in parallel
- Monitors via mailbox, merges worktrees, runs build
- Reports back to you
Key rules:
/agentselects your principal (lead / orchestrator). Any agent type can be the principal — pick one whose expertise fits the session./teamselects the worker roster the principal can draw from. The principal decides which workers to spawn and when.- You interact only with the principal. Workers report back to it, not to you.
A team template is a saved roster of agent types. Save it once, reuse it across any session forever. The names you give workers inside a team are just labels — what matters is which agent type each worker uses.
InstantiateTeam("my-backend-team")
# → creates team + pre-registers all members with their subagent_typeBuilt-in templates:
| Template | Workers |
|---|---|
backend-team |
backend-senior (opus), backend-mid (sonnet), backend-jr (haiku), devops, qa, code-investigator |
frontend-team |
frontend-senior (opus), frontend-mid (sonnet), frontend-jr (haiku), qa, code-investigator |
fullstack-team |
backend senior + mid + jr, frontend senior + mid + jr, devops, qa, investigator |
go-fullstack-team |
backend senior + mid + jr, go-htmx-frontend senior + mid + jr, devops, qa, investigator |
efficient-team |
all workers on Haiku with Opus advisors at PLAN/REVIEW only (maximum throughput at minimum cost) |
Pick interactively with /team — opens a fuzzy picker showing all saved templates. You can also define your own templates in ~/.claudio/team-templates/.
| Mode | Behaviour | Use when |
|---|---|---|
run_in_background: false (default) |
Lead blocks until agent completes | You need the result before the next step |
run_in_background: true |
Lead continues; completion arrives via mailbox | Parallel fire-and-forget tasks |
Background agents auto-open the Agents panel so you can watch live progress.
Splits cognitive work into two roles:
| Role | Model | Job |
|---|---|---|
| Executor | Cheap (e.g. Haiku) | Reads files, runs tools, writes code |
| Advisor | Expensive (e.g. Opus) | Strategic thinking at PLAN and REVIEW only — never touches files |
The advisor is consulted at most twice per task: once before writing code (PLAN), once when done (REVIEW).
advisor(
mode: "plan",
orientation_summary: "Codebase uses repository pattern…",
proposed_approach: "Add JWT middleware: 1) parse token 2) inject claims 3) gate routes",
decision_needed: "Middleware at router level or per-handler?"
)
advisor(
mode: "review",
original_plan: "Add JWT middleware at router level…",
execution_summary: "Added JWTMiddleware, wired in router.go, added 3 tests",
confidence: "high — tests pass, all routes protected"
)
REVIEW returns exactly one verdict: PASS, NEEDS_FIX <what>, or INCOMPLETE <what>.
{
"advisor": {
"subagentType": "advisor-sr",
"model": "claude-opus-4-6",
"maxUses": 6
}
}{
"name": "efficient-team",
"members": [
{
"name": "worker-1",
"subagent_type": "backend-mid",
"model": "claude-haiku-4-5-20251001",
"advisor": {
"subagent_type": "advisor-sr",
"model": "claude-opus-4-6",
"max_uses": 4
}
}
]
}Cost profile of efficient-team: every task costs at most 2 Opus calls (plan + review). All other turns run on Haiku. Dramatically cheaper than senior-on-Opus, better than junior-without-guidance.
A harness is a reusable multi-agent architecture for a specific domain. Build it once with /harness, invoke it forever with a single slash command.
.claudio/
agents/
analyst.md ← specialist role definitions
implementer.md
reviewer.md
skills/
feature-harness/
skill.md ← orchestrator skill
CLAUDIO.md ← harness invocation docs
Sequential stages — each stage's output feeds the next.
[Analyze] → [Design] → [Implement] → [Verify]
Use when each stage depends strongly on the prior one.
Parallel specialists work the same input; an integrator merges results.
┌→ [Specialist A] ─┐
[Dispatcher] →├→ [Specialist B] ─┼→ [Integrator]
└→ [Specialist C] ─┘
Use when the task benefits from multiple independent perspectives.
A router calls only the expert relevant to each task.
[Router] → { Security Expert | Performance Expert | Architecture Expert }
Use when input type varies and each type needs different handling.
A producer creates output; a reviewer validates it and triggers rework if needed.
[Producer] → [Reviewer] → (issues found) → [Producer] retry
→ (approved) → done
Use when output quality must be verifiable. Always cap retries at 2–3 rounds.
A coordinator tracks progress and dynamically assigns work.
┌→ [Worker A]
[Supervisor] ─┼→ [Worker B] ← dynamically reassigns
└→ [Worker C]
Use when the total workload is unknown upfront or optimal assignment requires runtime info.
Lead agents decompose the problem and delegate sub-problems to their own specialists.
[Director] → [Lead A] → [Worker A1]
→ [Worker A2]
→ [Lead B] → [Worker B1]
Use when the problem decomposes naturally into distinct sub-domains.
| Composite | Example |
|---|---|
| Fan-out + Producer-Reviewer | Multi-language translation — 4 parallel translators, each with native-speaker reviewer |
| Pipeline + Fan-out | Analysis (sequential) → parallel implementation by subsystem → integration test |
| Supervisor + Expert Pool | Support queue — supervisor routes tickets to domain experts dynamically |
/harness full-stack feature implementation
/harness security audit pipeline
/harness research and report generation
The /harness skill runs 11 phases automatically:
- Audit — inventories existing harnesses and crystallized agents; decides create vs extend vs repair
- Clarify — asks what the harness covers, what it outputs, who uses it
- Explore — scans project for languages, frameworks, conventions
- Select pattern — picks the best-fit architecture with an ASCII diagram; asks approval
- Design roster — checks existing crystallized agents first (reuse brings memory); creates only what's missing
- Write agent files —
.claudio/agents/<name>.mdwith trigger-rich descriptions and QA protocols - Write orchestrator —
.claudio/skills/<harness-name>/skill.mdwith QA cross-validation built in - Register in CLAUDIO.md — adds invocation docs
- Validate — checks for placeholder text, verifies agent name consistency, does a dry-run walkthrough
- Set up evolution — adds changelog table for incremental extension
- Report — summary, roster, 3 example invocations, next steps
/feature-harness add user notification preferences
The orchestrator creates _workspace/feature-harness/, builds the task backlog, spawns the team, and synthesizes final output.
| Feature | Description |
|---|---|
| Permission modes | default (ask), auto (allow all), plan (read-only) |
| Permission rules | Content-pattern matching — allow: Bash(git *), deny: Write(*.env) |
| Cost thresholds | Configurable cost confirmation dialog |
| Trust system | Projects with hooks/MCP require explicit trust |
| Audit trail | All tool executions logged to SQLite (/audit) |
| Secret scanning | Tool output scanned and redacted for API keys/tokens |
| Path safety | denyPaths / allowPaths / denyTools in settings |
19 lifecycle events for automation and custom workflows. Configure in settings.json under "hooks":
{
"hooks": {
"PreToolUse": [{"matcher": "Bash", "hooks": [{"type": "command", "command": "echo $CLAUDIO_TOOL_NAME"}]}],
"PostCompact": [{"matcher": "*", "hooks": [{"type": "command", "command": "notify-send 'Compacted'"}]}]
}
}| Event | When it fires |
|---|---|
PreToolUse / PostToolUse / PostToolUseFailure |
Before/after tool execution |
PreCompact / PostCompact |
Before/after compaction |
SessionStart / SessionEnd |
Session lifecycle |
Stop |
After AI finishes responding |
UserPromptSubmit |
Before processing user input |
SubagentStart / SubagentStop |
Sub-agent lifecycle |
TaskCreated / TaskCompleted |
Task lifecycle |
WorktreeCreate / WorktreeRemove |
Git worktree lifecycle |
ConfigChange |
Setting changed |
CwdChanged |
Working directory changed |
FileChanged |
Watched file modified |
Notification |
System notification |
Environment variables available in hooks: CLAUDIO_EVENT, CLAUDIO_TOOL_NAME, CLAUDIO_SESSION_ID, CLAUDIO_MODEL, CLAUDIO_TASK_ID, CLAUDIO_WORKTREE_PATH, CLAUDIO_CONFIG_KEY, CLAUDIO_FILE_PATH.
Exit code 1 from a PreToolUse hook blocks the action.
Recurring agent jobs. Tasks stored in ~/.claudio/cron.json, polled every 60 seconds.
CronCreate:
schedule: "@every 1h"
prompt: "Check for failing tests and open a GitHub issue if any"
type: "background"
Supported schedules: @every <duration>, @hourly, @daily, HH:MM.
| Mode | How it runs |
|---|---|
| inline | Injects prompt as user message into the target session |
| background | Spawns isolated engine; result stored in session history |
Manage with CronCreate, CronList, CronDelete. When running with comandcenter, crons are shared across all attached sessions.
# Export current session
/share my-session.json
# Import on another machine
/teleport my-session.jsonThe shared file contains messages, model, summary, and metadata.
claudio plugin install https://github.com/someone/claudio-jira
claudio plugin list
claudio plugin remove claudio-jiraFull claudio.* API available in every plugin's init.lua.
Executables in ~/.claudio/plugins/ are auto-discovered and exposed as tools:
echo '#!/bin/bash
echo "Hello from plugin!"' > ~/.claudio/plugins/greet.sh
chmod +x ~/.claudio/plugins/greet.shBinary plugins receive env vars: CLAUDIO_SESSION_ID, CLAUDIO_MODEL, CLAUDIO_CWD. Use --describe to provide a description.
claudio-codex (Go, tree-sitter) builds a structural index of your codebase and exposes it as a deferred tool. Symbol lookups cost ~50 tokens instead of thousands.
curl -fsSL https://raw.githubusercontent.com/Abraxas-365/claudio-codex/main/install.sh | sh
cd your-project && claudio-codex index| Command | Description |
|---|---|
search <query> |
Find symbols by name |
refs <symbol> |
All call sites referencing a symbol |
context <symbol> |
Definition + source + callers + callees |
impact <symbol> [depth] |
Transitive callers (blast radius) |
outline <file> |
All symbols in a file |
structure |
High-level codebase overview |
hotspots [limit] |
Most-referenced symbols |
-- ~/.claudio/init.lua
claudio.register_provider({
name = "groq", type = "openai",
base_url = "https://api.groq.com/openai/v1",
api_key = "$GROQ_API_KEY",
routes = { "llama-*", "mixtral-*" },
})
claudio.register_provider({
name = "openai", type = "openai",
base_url = "https://api.openai.com/v1",
api_key = "$OPENAI_API_KEY",
routes = { "gpt-*", "o1*" },
})
claudio.register_provider({
name = "ollama", type = "ollama",
base_url = "http://localhost:11434",
routes = { "qwen*", "llama3*" },
})Models without a matching route use the default Anthropic backend. Thinking, effort, and prompt caching are Anthropic-only.
| Mode | Setting | Description |
|---|---|---|
| Auto | "" |
Adaptive thinking for supported models |
| Adaptive | "adaptive" |
Model decides when and how much |
| Enabled | "enabled" |
Always think with budgetTokens budget |
| Disabled | "disabled" |
No extended thinking |
low / medium (default) / high — controls reasoning depth independently from thinking.
| Style | Description |
|---|---|
normal |
Default behavior |
concise |
Brief, direct. Skip preamble and summaries. |
verbose |
Detailed explanations with reasoning and examples. |
markdown |
Well-structured Markdown with headers, code blocks, tables. |
Switch with /output-style [style] or :set outputStyle concise.
Write shorthand that expands to full boilerplate — zero extra AI tokens:
{
"snippets": {
"enabled": true,
"snippets": [
{
"name": "errw",
"params": ["call", "msg"],
"lang": "go",
"template": "{{.result}}, err := {{.call}}\nif err != nil {\n\treturn {{.ReturnZeros}}, fmt.Errorf(\"{{.msg}}: %w\", err)\n}"
}
]
}
}~errw(db.QueryRow(ctx, id), "query user") inside func GetUser(id int) (*User, error) expands to:
result, err := db.QueryRow(ctx, id)
if err != nil {
return nil, fmt.Errorf("query user: %w", err)
}{{.ReturnZeros}} is resolved from the enclosing function's return types via go/ast. For Python, TypeScript, JavaScript, and Rust, regex-based resolution is used.
Context variables resolved automatically:
| Variable | Description | Languages |
|---|---|---|
{{.ReturnZeros}} |
Zero values for the enclosing function's return types | Go |
{{.FuncName}} |
Enclosing function name | Go, Python, TS/JS, Rust |
{{.ReturnType}} |
Return type annotation | Python, TS/JS, Rust |
After each AI turn, Claudio snapshots any changed files and stores the per-turn diff in the session database. View with /diff turn N. This lets you see exactly what changed in each turn of a long session — or undo a specific turn without reverting everything.
comandcenter is a WhatsApp-style browser PWA for managing Claudio sessions remotely.
# Start the server
comandcenter --password mysecret --port 8080
# Connect a Claudio session
claudio --attach http://localhost:8080 --name "my-session" --masterFeatures:
- Multi-session management with a sidebar session list
- Real-time WebSocket streaming of agent responses
- File uploads and image attachments
- Push notifications (iOS, Android, desktop via Web Push)
- Sub-agent status tracking with live progress cards
- Message deletion
- Cron task integration
Install PWA — open in Safari/Chrome, use "Add to Home Screen" for standalone mode with push notifications.
One-shot execution without a TUI — useful for scripts, CI, and automation:
# Run a single prompt and exit
claudio --headless "fix the failing test in main_test.go"
# With model override
claudio --headless --model claude-haiku-4-5-20251001 "summarize the git log"
# Pipe mode
echo "what does this function do?" | claudioOutput is streamed to stdout. Exit code 0 on success, non-zero on error.
~/.claudio/
init.lua ← your personal Lua config
settings.json ← global settings (JSON)
state.json ← machine-written state
keybindings.json ← custom key bindings
cron.json ← scheduled tasks
instincts.json ← learned instincts
memory/ ← global-scope memories
agents/ ← built-in agent types (principal or worker)
backend-senior/
backend-mid/
frontend-senior/
… ← add your own custom agents here
team-templates/ ← reusable team templates
backend-team.json
frontend-team.json
… ← define your own team compositions here
plugins/ ← Lua plugins + binary plugins
claudio-jira/init.lua
claudio-codex
projects/
<project-slug>/
memory/ ← project-scoped memories
designs/ ← design session outputs
.claudio/ ← per-project (committed to git)
init.lua ← project Lua config overrides
settings.json ← project settings
CLAUDE.md ← project instructions (alt location)
agents/ ← project-specific agents
skills/ ← project-specific skills
rules/ ← project rules
filters.toml ← legacy output filter overrides (prefer init.lua)
.gitignore
CLAUDIO.md ← project instructions for the AI
cmd/
claudio/ ← CLI entry point (calls cli.Execute())
comandcenter/ ← Web server entry point
internal/
cli/ ← Cobra commands; Version injected via ldflags
app/ ← Dependency injection / wiring
tools/ ← All tool implementations
tui/ ← BubbleTea TUI (~18K LOC, 15+ subpackages)
web/ ← html/template web UI + Tailwind CSS
storage/ ← SQLite; 22+ versioned migrations in db.go
services/ ← 12 focused services (memory, compact, lsp, mcp, …)
agents/ ← Agent orchestration & spawning
teams/ ← Multi-agent team management
bus/ ← Event bus — decoupled inter-component messaging
config/ ← Hierarchical settings; encrypted token storage
security/ ← Path/command validation, audit logging
hooks/ ← Hook system (pre/post tool events)
permissions/ ← Permission enforcement
lua/ ← Lua runtime (gopher-lua), API bindings
capabilities/ ← Dynamic capability registry
snippets/ ← Snippet expansion engine
query/ ← LLM conversation engine + turn lifecycle
Key constraints:
- No CGO — pure Go (
modernc.org/sqlitefor SQLite) - Single binary — no runtime dependencies on external processes
- BubbleTea TUI:
Model → Update → View— side effects only inCmdreturns - Event bus for cross-component communication — prefer bus over direct calls
GNU Affero General Public License v3.0 — see LICENSE.
Free software under a strong copyleft license. You may use, modify, and distribute Claudio, including for commercial purposes, provided that derivative works are released under the same license. If you run a modified version on a network server, you must make the corresponding source available to its users.
Built with Go · Powered by Claude · Inspired by Neovim
GitHub · Issues · Discussions