Cairn / Docs / Agent Workspace

Agent Workspace

Cairn ships a built-in stateful coding agent and a terminal workspace for external CLI agents. Both are accessible from the Agent view (⌘5) and integrate directly with your board tasks and notes.

Two agent modes

The Agent view supports two ways of working:

ModeHow it worksBest for
Cairn Agent Cairn's own built-in agent engine — no binary required. The agent calls tools, streams output to a chat UI, and updates your board and notes as it works. Coding tasks scoped to your project, where you want the agent to stay in sync with your Cairn board
External binary Spawn Claude Code, OpenCode, Aider, or any CLI tool in a live xterm.js terminal alongside the file tree, editor, and diff viewer. Agents with their own TUI, or workflows that require an interactive shell

Cairn Agent

The Cairn Agent is a stateful multi-turn coding agent built directly into the app. It uses the same AI endpoint you configure in Settings → AI — no extra setup. The agent runs a tool-call loop: it can read and write files, run shell commands, search your codebase, and read and update your Cairn board and notes. All tool activity streams to the chat as live chips.

Chat, coding sessions and automations all run on the same built-in agent engine, so approvals, subagents, compaction and session history behave the same everywhere. Every session is saved as an append-only log on disk, so you can close Cairn and resume exactly where you left off, and sessions can be popped out into their own window. History recorded by earlier versions is imported the first time you open it.

Starting a Cairn Agent session

There are two ways to start a session:

Before spawning, set a code directory on the project Overview page — this is the root folder the agent reads and writes. If it hasn't been set, the spawn modal will prompt you to enter one.

Tool chips

Every tool call the agent makes appears as a chip inside the message bubble. While the tool is running, the chip shows a spinner and the tool label. When it completes, the chip updates to a check or cross, and write-tool chips show an expandable output block with the result. Read-only tools (file reads, searches, list calls) suppress their output to keep the chat clean. Shell chips render the command's captured output with an exit-status pill, and connector (MCP and HTTP service) calls show the connector's logo, name and what the call did.

Chips for Cairn write tools (ensure_note, create_task, update_tasks, etc.) include a clickable reference link — clicking it navigates to the created or updated item in the Notes or Board view.

Plan mode

Type /plan to put a coding session in plan mode (and /plan off to leave it). In plan mode everything the agent can do is read-only — it investigates the code and your project, writes a plan with a task checklist, and presents it for your review with the exit_plan_mode tool. Writes and commands are blocked until you approve the plan and switch back to normal execution.

Todo list

For work with three or more steps the agent keeps a live todo list with its todo_write tool (pending, in progress, completed, cancelled, one in progress at a time). A collapsible dock above the input shows a compact [2/5 todos · current task] summary that expands to the full checklist. Todos are saved per session and restored when you resume it.

Approvals

A permission picker under the input, next to the model picker, controls how much the agent asks before acting. You can change it before the first message or between turns; it applies from the next turn.

When approval is needed, the tool chip shows an approval card with the exact command or a preview of the change, and the session pauses until you answer. Some things always ask regardless of the picker: touching protected paths such as .env files, private keys, .npmrc, shell config, .git or CI workflow files, and a command that needs to leave the shell sandbox. If the agent issues the same tool call with identical arguments three times in a row, it pauses and asks whether to continue instead of looping. Automations keep their own approval setting — see Automations.

Shell sandbox

Shell commands, background jobs and persistent terminals run inside an OS sandbox: on macOS (seatbelt) and Linux (bubblewrap) the agent can write only inside the working directory and temp/cache folders, while reads and the network stay open so builds, git and package managers keep working. If a command genuinely needs more access, the agent can request to run it unsandboxed. That request gets its own approval card with the agent's reason, offers only Allow once or Deny, and asks every time — it can never be remembered or covered by an Always allow rule. Toggle the sandbox in Settings → AI → Coding Agents → Sandbox shell commands; it applies to new sessions. Windows has no sandbox, so commands run in PowerShell without confinement there.

Subagents & workflows

The Cairn Agent can hand work to focused child agents. subagent starts a fresh agent for a self-contained task (several can run in parallel) and returns its final report; delegate starts one that is shown the conversation so far. Delegated agents stay around as conversations — the parent can follow up with send_message, check on them with list_agents, or stop a stuck one with interrupt_agent. Subagents appear as collapsible inline blocks in the chat with their own streamed tool chips and context usage; the header has a subagent catalog where you can see each child's activity and message it yourself. Children use the parent's approval mode and ask through the parent, so you answer in one place.

For larger jobs the workflow tool runs a short JavaScript program that orchestrates many subagents (one at a time or in parallel), and ralph works on one task in repeated rounds, each in a fresh subagent, until a round reports it finished.

Goals

Give a session a standing objective with /goal (set, show, pause, resume, complete or clear), or let the agent manage it with get_goal, create_goal and update_goal. A goal chip above the input shows the objective, its phase and the round count, and expands to show the blocker if the goal is blocked.

Background jobs & persistent terminals

Long-running commands can run in the background. A jobs dock above the input shows each job's status, elapsed time and outcome with a Stop button; the agent reads output with job_output. For REPLs and long builds the agent can open persistent shells with the terminal_open, terminal_send, terminal_read, terminal_signal, terminal_close and terminal_list tools, so state survives across tool calls. Those shells appear as read-only Agent tabs in the bottom terminal so you can watch them; closing the tab only hides it.

Session reminders

Optionally (Settings → AI → Coding Agents → Session reminders, off by default, needs a restart) the agent can set session-local reminders with schedule_create, schedule_list and schedule_cancel. A small alarm pill in the chat header shows the active count. This is separate from Cairn's background Automations.

Command hooks

If you already use Claude Code or Codex hooks, Cairn can run them too. Put a claude-code.json or codex.json file in ~/.config/cairn/hooks/ and the UserPromptSubmit, PreToolUse, PostToolUse and Stop hooks in it run around the agent loop. A hook can block a prompt or tool call, ask for approval, or add context for the model. Hooks are opt-in — nothing runs unless the file exists.

Context usage ring & compaction

A small ring in the agent chat header shows how much of the model's context window the current session is using. The ring fills as the conversation grows and turns red when usage is high. The context window size is detected automatically from the models.dev catalog, or set manually in Settings → AI → Coding Agents → Context window (presets 8k, 32k, 128k and 200k tokens).

When usage reaches 80% of the space left for the conversation (the context window minus the room reserved for the reply), the agent automatically compacts the context. It summarises the older part of the conversation with a background model call and keeps the most recent messages verbatim, and old bulky tool output is pruned. The full conversation history is always preserved in the session log; only what is sent to the model is trimmed.

Type /compact in the chat input to trigger compaction on demand at any time — useful before starting a large task to free up context space.

Automatic retry

Transient API errors — rate limits, overloaded responses, and server errors — are retried automatically without ending the session. The agent retries up to five times with exponential backoff (starting at half a second and capped at ten seconds) and shows the retry in the status bar. Clicking the stop button cancels any in-progress retry immediately.

Mandatory workflow

The Cairn Agent follows a built-in project workflow on every session:

  1. Orient — reads the active project context and moves the linked task card to In Progress
  2. Document as you go — uses ensure_note to create or update a session note with findings and decisions (idempotent — no duplicate notes)
  3. Capture out-of-scope tasks — anything discovered but not actioned is added as a board task for later
  4. Wrap up — writes a session summary note and moves the task card to Review or Done

Available tools

ToolWhat it does
read, read_imageRead a file (or view an image) from the code directory
writeWrite or overwrite a file
editReplace an exact string in a file (surgical, not full-file rewrite); returns a unified diff of the change
bashRun a shell command in the code directory (sandboxed; optionally in the background)
grep, globSearch file contents by regex, and list files matching a glob pattern
lspCode navigation — definition, references, implementation and hover — for TypeScript/JavaScript when a language server is on your PATH
web_fetchFetch a public web page as text (content is treated as untrusted; asks each time unless allowed)
todo_writeMaintain the session todo list
skillLoad a skill's full instructions
subagent, delegate, send_message, list_agents, interrupt_agentStart and manage child agents
workflow, ralphOrchestrate many subagents with a script, or iterate on one task in rounds
get_goal, create_goal, update_goalManage the session goal
search_sessions, read_sessionSearch and read earlier chats and coding sessions in this workspace
job_output, job_killRead or stop background jobs
terminal_*Open and drive persistent shell sessions
exit_plan_modePresent a plan for review (plan mode)
Cairn workspace toolsRead and write notes, tasks, projects, Idea Flow and the knowledge graph (the same consolidated set as the MCP server), plus the codebase index tools
Connected toolsAny external MCP servers and HTTP services attached to the project

All tools cap their output and append a pagination hint when truncated — the agent can use offset/limit parameters to page through large results.

Skills

Skills are reusable instruction sets — stored as SKILL.md files — that teach the Cairn Agent specialised workflows without bloating the system prompt. Metadata (name and description) is always visible to the agent; the full instructions are only loaded when the agent determines the skill is relevant to the current task.

How the agent uses skills

  1. At session start, Cairn scans for skill files and injects a compact <available_skills> list into the system prompt — name and one-line description only.
  2. When the agent recognises a skill matches the task, it calls the skill tool with the skill name.
  3. The full SKILL.md body is injected into context. Bundled resources (docs, templates, scripts) in the skill directory are listed and accessible via the read tool.

Where to put skill files

Cairn walks from the code directory up to the git root at session start, checking each ancestor for the following subdirectories (first match per skill name wins):

DirectoryScope
.cairn/skills/<name>/SKILL.mdProject — Cairn-native
.opencode/skills/<name>/SKILL.mdProject — OpenCode compatible
.cline/skills/<name>/SKILL.mdProject — Cline compatible
.claude/skills/<name>/SKILL.mdProject — Claude Code compatible
.agents/skills/<name>/SKILL.mdProject — agent-agnostic
~/.config/cairn/skills/<name>/SKILL.mdGlobal — all projects
~/.opencode/skills/<name>/SKILL.mdGlobal — OpenCode compatible

Because Cairn walks up to the git root, skills placed at the repository root are always discovered even when the code directory is set to a subdirectory such as packages/web/.

SKILL.md format

Each skill is a directory containing a SKILL.md file with a YAML frontmatter header followed by the instruction body in plain Markdown:

---
name: git-release          # required · kebab-case · matches directory name
description: "Draft release notes and bump the version."  # required · shown to agent always
license: MIT               # optional
compatibility: cairn       # optional (cairn | opencode | cline)
metadata:
  audience: maintainers    # optional string map
---

## What I do

Walk through `CHANGELOG.md`, propose a semver bump, and draft
the release notes in the project's established style.

## Steps
1. Run `git log --oneline` since the last tag.
2. Group commits by type …

The directory name must match the name field and follow kebab-case (^[a-z0-9]+(-[a-z0-9]+)*$, 1–64 characters). You can co-locate supporting files alongside SKILL.md:

.cairn/skills/git-release/
  SKILL.md
  docs/release-checklist.md
  templates/release-notes.md
  scripts/bump-version.sh

The agent is shown the relative paths of files in docs/, templates/, and scripts/ subdirectories and can read them via the read tool.

Previewing discovered skills

Go to Settings → AI → Coding Agents → Skills & System Prompt to see which skills were discovered for your workspace, their file paths, and the full assembled system prompt the agent will receive. The system prompt can be copied to the clipboard from this panel.

Compatibility

Cairn uses the same SKILL.md convention as OpenCode and Cline. Skills authored for either of those agents work in Cairn without modification — same directory layout, same frontmatter schema, same skill tool invocation contract.

Security

All file reads and writes are validated against the registered code directory. The agent cannot read, write, or list files outside that path. Shell commands run with the code directory as the working directory, inside the shell sandbox. Secret-bearing files such as .env and private keys always ask for approval; env templates like .env.example stay readable.

External agent workspace

The external agent workspace is a three-pane layout for running CLI tools in a live terminal:

Panes resize by dragging the dividers. Sessions survive navigation — switching to Notes or Board and back does not kill a running process.

Agent workspace showing file tree, editor, and terminal panes
The external agent workspace: file tree on the left, multi-file editor in the centre, terminal sessions on the right.

Setting up a code directory

Each project has a code directory — the root folder the file tree and agent sessions operate in. Set it from the project Overview page: click the terminal-icon row below the project header, type or paste the path, and press Enter. On macOS and Windows you can also click Browse to pick a folder.

The code directory is validated before any agent spawns. All file I/O from the agent workspace is confined to paths within registered code directories — the app will not read or write outside them.

Registering a coding agent

Go to Settings → AI → Coding Agents and click Add agent. Each agent has four fields:

FieldDescription
NameDisplay name shown in the spawn modal and terminal tab
Binary pathAbsolute path to the CLI binary (e.g. /usr/local/bin/opencode)
ArgsArguments passed to the binary (see Prompt delivery below)
DefaultPre-selected in the spawn modal

Prompt delivery and the {prompt} placeholder

The Args field controls how the spawn-time prompt reaches the agent binary. Use the {prompt} placeholder anywhere in the args string — it is replaced with the prompt text at spawn time.

Args valueWhat runsUse case
(empty)binaryInteractive TUI — no prompt injected
{prompt}binary 'prompt text'OpenCode first-positional pre-fill
--prompt {prompt}binary --prompt 'prompt text'OpenCode explicit flag
--message {prompt}binary --message 'prompt text'Claude Code / Aider style
--flag={prompt}binary --flag='prompt text'Inline flag syntax

Prompts are delivered via exec sh -c '…' with single-quote escaping — safe for any length, newlines, colons, or special characters.

Spawning a session

There are two ways to start a session:

On spawn, a new terminal tab opens immediately and the agent process starts. The tab shows the agent name and a live status dot — green while running, grey on exit.

Terminal

Each session runs in a full xterm.js terminal. You can type directly into the terminal to interact with the agent or send follow-up instructions. The terminal preserves full scroll history — switch tabs and back without losing output.

Terminal pane showing an active agent session
Terminal sessions with a live status dot, exit code badge, and full scroll history.

Closing a tab sends a kill signal to the process and removes it. The terminal font size tracks your Cairn font scale setting automatically.

File tree

The left pane shows the code directory as a lazily-expanding tree. Folders expand on click; files open in the editor. Only .git and .DS_Store are hidden, so dotfiles like .env and .gitignore can be opened and edited. The tree is scoped to the registered code directory — it cannot navigate above it. Press ⌘⇧F to activate a filename search input at the top of the file tree.

Editor

The centre pane hosts a multi-file CodeMirror 6 editor. Click any file in the tree to open it in a tab. Multiple files can be open simultaneously — switching tabs is instant with no reload, and scroll position and undo history are preserved per file.

Git diff viewer

The Diff tab in the editor pane polls git diff HEAD every 5 seconds and shows all uncommitted changes in the code directory, including untracked files.

Git diff viewer showing file changes with syntax highlighting
The Diff tab: collapsible file sections with unified, split, and changes-only view modes.

Three view modes are available:

File sections are collapsible. A Copy patch button copies the raw diff to the clipboard. A manual Refresh button is available in the toolbar alongside the last-refreshed timestamp.

Keyboard shortcuts

Security

All file reads and writes from the agent workspace are validated against the registered code directories. The app will refuse to read, write, or list files outside those paths. Binary paths are also validated before any process is spawned.