Usage
Keep daily TUI work moving: send messages, read tool cards, recover sessions, and steer long tasks. Chord runs either as the local TUI or as the chord headless control plane; most of this page is about the TUI.
How to use this page
Section titled “How to use this page”You do not need to read this page from top to bottom:
- First task: TUI basics covers sending, tool cards, and approvals; set rules in Permissions & Safety before the first edit.
- Long tasks:
/loopkeeps implement, test, and fix moving without nudging. - Parallel work: Worktrees puts each task in its own checkout while sessions stay shared per repository; resume, fork, and import live under Sessions.
Chord has two main usage paths:
- Local terminal interface: the default mode for sending tasks, inspecting results, and handling approvals
- Headless mode: use
chord headlessto control Chord from a script, gateway, or chat bot
Most personal development workflows should start with the local TUI.
TUI basics
Section titled “TUI basics”After startup, the input box is focused by default. Type a message and press Enter to send.
Tool cards show terminal-safe previews. File paths inside the session working directory are displayed as relative paths; external paths remain absolute. Tool path arguments accept ~/... prefixes, which expand against the home directory. Collapsible cards start compact, keeping only key facts such as ranges, counts, command intent, and terminal status; full output, diagnostics, truncation details, and artifact references appear when expanded. A ▸ / ▾ beside the terminal-state marker means the card folds: focus it and press Space, Enter, or o.
write, edit, apply_patch, todo_write, delete and handoff cards are always expanded, so their body (file content, diff, todo list, error detail or plan path) is what you see, and they carry no disclosure marker. read, grep, glob, successful shell output and generic tool calls fold. yy copies the complete card content either way.
When Chord is running in the background, the terminal title shows a one-shot ✅ completion marker when the focused agent transitions from busy to idle. Focusing the terminal clears the marker; ordinary tab/window focus changes do not re-add it unless new background work later completes.
Common keys:
Esc: switch to Normal mode; pressingEscagain in the running main view cancels the current turni: return to insert/input modej/k: move between message cardsgg/G: jump to top / bottom/: search messagesCtrl+T: open the message directoryCtrl+P: switch the main role model poolCtrl+O: open the MCP server selectorCtrl+E: open the error panel (view the errors recorded so far)Ctrl+G: export a diagnostics bundleq: press twice to quitCtrl+C: press twice to quit
Error panel
Section titled “Error panel”Press Ctrl+E in normal mode to open the error panel, which lists the errors encountered so far. This includes:
- Intermediate retry errors: API errors that triggered a key rotation, model fallback, or stream retry (e.g., 429 rate limits, 503 service unavailable, context length exceeded, timeouts). These are recorded silently and only appear in the error panel, keeping the conversation flow clean. Switching to a different fallback model is the exception: the notification appears as soon as the fallback starts, naming the reason and the target model, and the status bar keeps showing that target, reason, and elapsed time while the new model is being reached.
- Final errors: errors that exhausted all retries and appear as red error blocks in the conversation.
Each error record shows:
- Timestamp (HH:MM:SS)
- Provider and model (e.g.,
Anthropic/claude-opus-5) - Masked API key label (e.g.,
key=sk-a...xyz9, showing a short prefix and suffix for safe identification) - HTTP status code (when available)
- Error code and type (when provided by the API)
- Error message (wrapped to panel width)
Example error entry:
14:25:38 Anthropic/claude-opus-5 key=sk-a...xyz9 HTTP 503 code=model_not_found No available channel for model sample/model under group defaultNavigation:
j/k: scroll one lineCtrl+F/Ctrl+B: page down / upg/G: jump to top / bottomEsc: close the panel
The error panel keeps the most recent 80 errors in a ring buffer (newest first), and the buffer lives in process memory: it starts empty when Chord launches and clears when you start or resume a session; a forked session keeps the records it inherits. Use it to diagnose why a model fallback occurred or which keys are hitting rate limits.
Info panel
Section titled “Info panel”USAGE block
Section titled “USAGE block”Contextshows the input-side token burden of the most recent model request, as reported by the provider. A≈prefix marks the single estimate used when that response omitted usage; a session that has not had a measured response yet shows0.BytesandMessagesdescribe the conversation context that will be sent to the model. After request-level context reduction runs,Bytesshows the current request’s post-reduction context byte count followed by↓and the percentage saved relative to that request’s unreduced context:(bytes before reduction - bytes after reduction) / bytes before reduction. This is not a cumulative value across requests; savings from frozen reduced summaries still count whenever those summaries are used in the current request. When a session is restored, Chord precomputes the same reduction for display, soBytesstarts at the post-reduction estimate instead of dropping after the next request; before any request surface can be prepared, it falls back to the current durable context estimate.Bytescounts the installed system prompt, message content, image payloads, and tool names/descriptions. It excludes JSON escaping overhead, tool-call argument JSON, thinking metadata, and request parameters such as stream settings or thinking budgets.- These reductions are not persistent compaction: older tool results are usually replaced with shorter placeholder summaries for the request, while durable session history remains intact.
/compact, automatic compaction, tool-output growth, and system prompt or tool-definition changes update the fallback durable estimate; new request preparation refreshes the actual sent request size, including while loop mode is active. - When
Cache Rshows a percentage, it is cache-read tokens divided by input-side prompt tokens plus separately reported cache-write tokens. Output tokens are excluded because prompt caching applies only to the input side. Thinkappears only when the provider reports reasoning/thinking tokens. These tokens are already included in output-token billing; the line is a visibility breakdown, not an additional token bucket.Callscounts the real LLM requests issued by the focused agent (main agent, running SubAgent, or parked task). It comes from the persisted usage ledger, so it survives session restore and is not reset by context compaction.
TIME block
Section titled “TIME block”TIME reports cumulative wall-clock durations for the focused agent: Model (LLM streaming), Tools (tool execution), Cooldown (key/model cooldown waits), and User wait (waits for your confirmations or answers). These are sums of operation intervals, not exclusive slices of elapsed session time; parallel operations can therefore contribute to more than one bucket at once. Each bucket’s percentage uses the sum of the displayed buckets as its denominator.
- Buckets under one second are hidden, including from the percentage split; if every bucket is sub-second the whole section is hidden.
Modelincludes time spent streaming compaction drafts. When a confirmation dialog, Question prompt, or Handoff selector is pending, tool cards show execution time only: confirmation, answer, and handoff-decision waits are recorded underUser wait, never underTools.- The section follows the focused agent (main agent, running SubAgent, or parked task) and is rebuilt from the session’s usage ledger after restore or resume.
Background jobs
Section titled “Background jobs”Some work outlives the turn that started it: long shell commands, including the ones SubAgents launch. While such a command is running or stopping, Chord tracks it as a job, and the turn can finish without stopping it.
JOBS block
Section titled “JOBS block”Whenever at least one job is running or stopping, the info panel gains a JOBS block. Each job takes one line, indented two columns, with a label (the job description, or the command when there is no description), the elapsed time, and a trailing x. Jobs started by SubAgents are listed right alongside your own.
With nothing running or stopping, the block is omitted entirely.
Narrow terminals
Section titled “Narrow terminals”When the terminal is too narrow for the info panel, the status bar carries a plain-text counter pill instead, such as 2 agents · 1 job. It shows both counts while there is room; when space runs short, Chord drops the agents half first and then hides the pill. Click the pill to open the JOBS list overlay; with the info panel visible, the same list is already on screen. With no jobs to show, Chord tells you so instead of opening an empty overlay.
The pill and the x are click targets, so a terminal without mouse reporting cannot reach them. ctrl+j opens the same list from Normal mode at any width; inside it, j / k (or the mouse wheel) move the selection and Enter opens the confirmation for the selected row.
Stopping a job
Section titled “Stopping a job”Click a job’s trailing x to open a confirmation dialog. It lists the job id, label, command, owner, status, elapsed time, the time of the last output, and the most recent output lines; when output was discarded, it also reports how many bytes were dropped and the path to the full log.
Only y confirms. n and esc cancel, and Enter is not bound. After you confirm, that line switches to stopping and its x disappears.
Stopping a job yourself does not raise a toast. When the job ends, its owner still receives the result, stating plainly that you stopped it; a job that had outlived the turn that started it arrives as a JOB RESULT card.
Esc and Ctrl+C do not stop a background job, including one still running inside the current turn: a long command that outran the foreground budget has already become a job. Confirming the stop dialog (reached by clicking x, or with ctrl+j then j / k and Enter) is the only way to stop one. Jobs do not outlive Chord itself: quitting or switching sessions terminates all of them.
Cancelling a turn does not mute the jobs it left behind either. When one finishes later, its result still arrives and opens a new turn — Chord wakes the main agent for every delivery rather than dropping a result nobody asked for — so a cancelled turn can be followed by a short result turn per job that completes. Stop those jobs, or quit Chord, if you want the session to stay quiet.
Terminal title
Section titled “Terminal title”The terminal title spinner keeps turning while only background jobs are running. With the window unfocused, that spinner is the only sign of life.
File mentions (@path)
Section titled “File mentions (@path)”Type @ in the composer at the start of a line or after a space to open file completion.
- Bare
@uses a cached workspace index of text files. That index includes tracked files and untracked non-ignored files, but skips Git-ignored paths, hidden directories, binary extensions, and common noise directories. - Once you start typing a root-level filename prefix such as
@A, Chord also checks the session working directory directly. This allows root files such asAGENTS.mdto complete even when they were excluded from the cached index by.gitignoreor local Git excludes. - If the query already looks like a path, such as
@docs/,@./,@~/, or@.config/, Chord switches to direct filesystem completion for that directory instead of staying on the cached index. This path-mode completion can surface ignored paths when you explicitly type toward them. - Hidden entries stay hidden by default. To see them, make the query itself explicit, for example
@.,@.env,@./., or@.config/. - Add a 1-based line suffix to include only part of a text file:
@path:42injects line 42, and@path:10-20injects lines 10 through 20. Completion replaces only the path segment, so a suffix you typed is preserved when accepting a file match. If a real filename contains the numeric colon suffix, such asnote:12, the filename takes precedence over line-range parsing. - Completion is only input assistance. When you send the message, Chord reparses the final
@pathtext; if you removed the mention before sending, that file is not attached.
Sessions
Section titled “Sessions”Chord keeps persistent sessions for the current project.
Common workflows:
chord: create a new sessionchord --continue: resume the most recent non-empty session for this projectchord --resume <session-id>: resume a specific session of the current projectchord resume <session-id>: resume a session by ID from any directory. It auto-locates the chord-managed worktree the session belongs to and switches into it; add--fork-history[=N]to resume a fork at a compaction boundary instead (default: latest applied boundary; the fork reproduces that generation with its compaction archives and starts usage and runtime state fresh)chord import <source> [file]: import an external session into Chord’s session store/new: create a new session in the TUI/resume: pick a historical session in the TUI/rename <title>: set the current session’s display title; bare/renameclears it
When exiting, if the current session can be resumed, Chord prints the corresponding resume command.
Usage statistics use the current usage.jsonl ledger format. Session restore and summaries do not migrate older usage schemas; an invalid or stale usage-summary.json is rebuilt from the ledger.
/new resets session state such as conversation history, todos, and usage. Runtime preferences such as the current model pool, service tier, and MCP state stay active until the process exits.
Custom titles are shown in the session picker and terminal title. They are metadata only: /rename does not change the session ID, directory, transcript, or resume command.
Editing after resuming a session
Section titled “Editing after resuming a session”When you resume a session, Chord rebuilds only the safety state needed to allow later edits. It does not re-read files or reload their contents into the conversation. If you edit a file that was changed on disk since the session ended, or whose read history was not durable, the next edit / apply_patch on that file may be blocked and the agent will re-read it first. This is intentional: it keeps edits from being applied against stale file contents.
Importing external sessions
Section titled “Importing external sessions”Chord can import an external agent session into a resumable Chord session.
Currently supported sources:
opencode: JSON fromopencode export <sessionID>codex: Codex rollout JSONL (typically under~/.codex/sessions/**/rollout-*.jsonl)claude: Claude Code transcript JSONL (typically under~/.claude/projects/**/<sessionId>.jsonl)
Example (OpenCode):
# OpenCodeopencode export <sessionID> > export.jsonchord import opencode export.jsonchord resume <sid>
# Codex (direct file)chord import codex ~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl
# Codex (by session id)chord import codex --id <session-id> [--root ~/.codex/sessions]
# Claude Code (direct file)chord import claude ~/.claude/projects/**/<sessionId>.jsonl
# Claude Code (by session id)chord import claude --id <session-id> [--root ~/.claude/projects]Notes:
- Recognized external tool calls become readable Chord tool cards. Unsupported records remain visible as fallback text instead of being silently dropped.
- Imported tool cards represent history only. Re-run
readbefore editing a file when you need current contents and stale-change protection. - Signed Anthropic thinking is preserved. Other reasoning is omitted by default; use
--reasoning visibleto import it as plain text. - Claude sidechain/sub-agent entries are excluded from the main session. Import warnings, skipped records, and conversion statistics are written to
import-report.json.
Common flags:
--project <path>: which project to write into (default: current directory)--sid <id>: specify session id (default: auto-generated)--id <session-id>: import by the source tool’s own session id instead of file path; for Codex this is the idcodex resumeprints (supported forcodexandclaude)--root <path>: root directory for--idlookup--reasoning off|visible|strict: reasoning import policy (default:strict)--dry-run: parse and report only, no writes--json: machine-readable output--force: overwrite an existing--sid
Worktrees
Section titled “Worktrees”For working on multiple tasks in parallel without crosstalk, Chord can create and run inside dedicated git worktrees:
chord --worktree: create or enter a chord-managed worktree (auto-named when no name is given)chord --worktree feat-auth/chord worktree feat-auth: create or enter the worktree namedfeat-auth(branchchord/feat-auth); combine with--continueor--resumeto keep working on the repository’s latest session with the worktree as the working directorychord headless -d <repo> --worktree feat-auth: same in headless mode; thereadyevent payload includes the worktree’sname,branch,path, andrepo_rootchord worktree list: list chord-managed worktrees of the current repositorychord worktree remove <name>: delete the worktree and its runtime cache; the branch and the repository’s session history are preserved. Pass--delete-branchto delete the branch only-if-merged or--forceto force-remove a dirty worktree and its branch.chord worktree finish <name>: update the worktree from the target branch, squash its result back as one commit, then remove the worktree and branch. Use--onto <branch>to choose the target or--checkfor a non-mutating conflict check. On conflict, the target branch stays unchanged and the worktree is left ready for you to resolve the merge and rerunfinish.
Creating or entering a worktree changes the directory Chord runs in. You can do that either with chord --worktree <name> or with chord worktree <name>. The worktree subcommand also owns management operations such as list, remove, and finish. These commands are the normal way to start a worktree session.
The in-session worktree_enter, worktree_exit, and worktree_list tools are available only to a session that is already running in a Chord-managed worktree, or to a subagent explicitly placed in one. They are not included in ordinary sessions, which keeps the default tool surface small. Start the session with chord worktree <name> when the task needs those controls. Once a session has the tools, they stay available for the rest of that conversation after it leaves the worktree; /new, /resume, and restarts decide again from the checkout the session runs in.
Worktree tools and commands need git on PATH. When Chord cannot find it, the worktree tools are hidden from the tool list, and creating or entering a worktree, list, remove, and finish refuse with a message that names the missing git binary instead of reporting a repository error. A session that recorded a checkout can still be resumed: Chord reports that it cannot verify the checkout, resumes in the repository checkout it resolved, and keeps the record, so a later resume switches back once git is available.
Where they live. By default, worktrees land under <state-dir>/worktrees/<repo-id>/<slug>, outside the repository. worktree.root moves them: a relative value resolves against the main repository root, so root: .chord/worktrees puts checkouts at <repo>/.chord/worktrees/<slug>. When the directory is inside the repository, Chord keeps a .gitignore containing * there so the checkouts never show up as untracked files; that file only keeps git status clean, and chord’s own grep / glob skip that root. Other tools are not aware of it: an in-repo checkout is a second copy of the tree on disk, so index- or scan-based tools (LSP indexing, a docker build context, test runners that sweep the repository) may pick it up too. Leaving the default location avoids that.
How the status bar shows it. A session working in a managed worktree shows the checkout as <repo> · <worktree> in the status bar instead of a path: the checkout lives outside the repository, so a shortened path would hide the repository name or imply a location that does not exist. The full path is in the info panel’s GIT section as Worktree Path, and double-clicking the status bar region copies the checkout path.
What a worktree contains. Only tracked files. Uncommitted changes in the main checkout are not copied, and neither is gitignored content: a local AGENTS.md, .chord/config.yaml, agents, skills, plans, and memory stay in the main checkout, and a session in a worktree reads them from there. The exceptions are AGENTS.md and project skills: when the checkout carries its own copies, those win, so a branch can ship its own instructions and skills. Everything else behaves as it does in the main checkout — same sub-agents, same memory. To copy specific gitignored files, such as local env files or machine-specific config, list their patterns in a repository-root .worktreeinclude (gitignore syntax): Chord copies the matching gitignored files on creation and never overwrites a tracked file. Without that file, .env* is copied. Copying happens once, at creation: later edits are not synced in either direction, and since .env* is copied by default a local credential can end up in every checkout, so keep the patterns to what a worktree actually needs.
Sessions are shared per repository. All checkouts of a repository share one session store, so a session you started in a worktree shows up and can continue from the main checkout, and the other way around. Runtime cache stays per checkout, and exports follow their sessions. A session records the checkout it was working in, and /resume marks it on that session’s row, so the list stays searchable by checkout name: chord resume <id>, chord --resume <id>, and chord --continue switch back to it, and a session that continues in a worktree records it. When the recorded worktree is gone they warn: chord resume continues in the main checkout, while --resume and --continue continue in the checkout Chord was started from. chord worktree remove and chord worktree finish never delete the repository’s session history.
A checkout is not exclusive. Creating or entering a worktree reuses the same directory whenever it already exists, and nothing prevents two sessions from working in one checkout: both see the same uncommitted changes, and either can overwrite the other’s files. Run one worktree per task that proceeds in parallel, and treat a checkout as a single writer’s directory while it has uncommitted work.
Permissions follow the session, not the checkout. Permission rules apply to every checkout of a repository: a rule such as write src/**: allow in the main checkout also allows writes to <worktree>/src/, and you cannot write a rule that allows a single checkout only. Chord evaluates repository paths through their repository-relative spelling, so an absolute path rule never matches them; worktrees are for parallel work, not for narrowing permissions. Hooks, agent configuration, permission rules, and worktree creation settings are read when a session starts, from the main checkout, and entering or leaving a worktree inside a session does not change them — to pick up config edited on a worktree branch, start a new session in that checkout.
The in-session worktree tools follow your rules. worktree_enter, worktree_exit, and worktree_list are gated by the same permission rules as any other tool, and a worktree_exit rule can name the action: worktree_exit: {remove: deny} blocks deleting a checkout while leaving it (keep) stays allowed, and a removal that passes discard_changes: true is covered by the same rule. See Permissions & Safety.
Local slash commands
Section titled “Local slash commands”These commands are handled by the local runtime and are not sent to the model as-is. In the TUI, type / to open completion. Tab completes the highlighted command without running it. Enter completes it when the input is not already that command, then runs or sends it in the same keypress. Narrowing the list by typing keeps the highlighted row: Enter runs that command, not the first match:
/new: create a new session/resume: resume a session/rename <title>: set the current session’s display title; bare/renameclears it without changing the session ID/models: view pool status or switch the current view’s model pool (mainview = current main role;SubAgentview = that agent)/models --agent <name> <pool>: directly set a named agent’s pool/role: open a role-picker dialog and switch the active main agent (builder, planner, and custom main-mode roles), the dialog form ofShift+Tab;/role <name>switches directly without the dialog, and/role statusprints the current role and the available roles/mcp: open the MCP server selector;/mcp statusprints status;/mcp enable|disable <server>toggles manual servers. Runtime changes take effect for the next LLM request, not the currently in-flight request./skill <name> [args]: load a skill explicitly, including one kept out of the model’s catalog bydisable-model-invocation; bare/skillopens the skill selector. See Skills: Explicit loads./compact: manually trigger context compaction to summarize the current conversation as a structured archive; while the agent is busy withcontext.compaction.model_drivenenabled, the model is also asked to checkpoint immediately and its checkpoint can replace the runtime result; see Context management: Compaction/tier standard|fast|slow: set the service tier for subsequent model requests (including later retry rounds that have not started yet). Bare/tieris not a status command; use the sidebar/status display for the current effective tier. If you enter a tier that the current provider/model does not support, Chord leaves the current tier unchanged and shows an error./yolo on|off: temporarily bypass the main agent’s permission checks for ordinary tools. While YOLO is on, file edits, shell commands, and similar calls run directly:askrules do not raise a confirmation anddenyrules do not block. The bypass is one-way: it only widens permissions, so a tool that works with YOLO off keeps working with YOLO on, and switching YOLO off restores the original permissions.handoff,delegate, andcancelkeep following their configured rules:allowstays allowed,denykeeps rejecting, anaskrule passes without raising the confirmation dialog, and wildcard defaults behave exactly as they do with YOLO off.doneandcompact_contextkeep their dedicated semantics. YOLO can be toggled while the agent is running; the execution-time change applies immediately to later tool calls, while the LLM-visible tool descriptions and permission prompt are refreshed on the next request. SubAgents inherit the mode while it is on: theiraskdecisions (ordinary tools and mechanism tools alike) stop prompting too, while theirdenyrules keep rejecting. Toggling YOLO applies to a SubAgent’s later calls immediately./help: toggle the in-app cheatsheet overlay (same as pressing?in Normal mode)
When a non-standard tier is active, the sidebar shows it. If a model switch makes the selected tier unavailable, it appears dimmed and struck through. Ctrl+R cycles only through tiers supported by the current provider and model.
The following commands have more interactive detail, expanded below.
Project Memory
Section titled “Project Memory”Chord’s optional cross-session project memory (stable preferences, project facts, and reusable workflows) has its own page: Project Memory. It covers what gets stored, how the summary loads into a session, how to enable automatic extraction, and how to review or remove entries. There is no slash command for memory.
MCP selector
Section titled “MCP selector”Press Ctrl+O to open the MCP server selector. It lists configured MCP servers, their connection state, and whether manual servers are currently enabled or disabled. Use j / k to move, Enter to toggle the selected manual server, e to enable, d to disable, and Esc to close.
The selector can be opened while the agent is running so you can inspect MCP state without waiting for the current turn to finish. Enable/disable actions are also allowed while running, but they are deferred: the current in-flight request keeps the MCP tool surface and prompt it started with, and the changed MCP state is reflected in the next LLM request. Auto-start MCP servers are always read-only in this selector; only servers configured with manual: true can be changed at runtime.
When you ask the agent which MCP tools it can use, its answer describes the tools visible to its current role, not every connected server. Use the selector or /mcp status for connection state.
External files, web pages, command output, images, and MCP descriptions/results are reference data, not authorization to change the task or execute commands. Agent instructions preserve that distinction, including for delegated workers, but they are not a security sandbox: configure tool permissions conservatively and review sensitive operations.
/export: export the current session
Section titled “/export: export the current session”Export the current session as Markdown (default) or JSON.
/export # default: export as Markdown into the session artifacts directory/export ~/out.md # specify an output path/export --json # export as JSON/export ~/out.json # a .json path auto-selects JSONThe export includes every conversation message plus the current session usage statistics. On success, the TUI displays the saved path.
/stats: usage statistics overlay
Section titled “/stats: usage statistics overlay”Opens an overlay to browse usage data along two axes:
- Scope:
Session(current session) orProject(aggregate project stats). Presssto toggle. - View:
Overview,Models(per-model breakdown),Agents(per-agent breakdown). Project scope additionally supportsDates(per-day breakdown). PressTab/Shift+Tabto switch views.
Session Overview shows: LLM calls, input/output tokens, cache read/write tokens, reasoning tokens, estimated cost, and, once any context compaction has run, its lifecycle counts (for example applied, skipped/model_driven). Models and Agents views display detailed per-dimension tables.
Project statistics are auto-aggregated from local sessions directories, with five time ranges: today, 7d, 30d, 90d, all. Switching to Project may briefly show “loading” before data appears.
Any active search is automatically cleared when the overlay opens. Press Esc to close. You can also open it directly via the $ key in Normal mode.
/rules: permission rule manager
Section titled “/rules: permission rule manager”Opens an overlay for remembered permission rules. It opens even when no rules have been added yet, so you can add one manually.
a: add a rule manually↑/↓orj/k: move cursord: delete the current ruleo: open the rule’s backing config file in the OS editorEsc/q: close
When adding a rule manually, enter the tool name and pattern, then use Ctrl+S to cycle scope (session / project / global) and Ctrl+A to cycle action (allow / ask / deny). Tool and pattern are required. Patterns that do not match future tool calls are accepted but have no effect until they match.
Each rule shows its scope (session / project / global) and on-disk file path. session rules apply only to the current session; project rules are written to the current project’s .chord/agents/<role>.yaml; global rules are written to the user config directory’s agents/<role>.yaml (default: ~/.config/chord/agents/<role>.yaml). These rules directly update the target agent’s permission config, and deleting a rule removes it from the same agent config file.
The confirmation popup also supports adding a remembered rule with M. In the rule picker, press E to edit the suggested pattern before saving. Delete confirmations suggest reusable parent-directory rules rather than exact-file rules, ranking directories that cover more paths still needing approval first. A global * catch-all is always available. When every requested path lies inside the repository, the picker also keeps a ** option for follow-up deletes anywhere in the repository (or under the working directory when no repository resolves). The broad ** and * options are never preselected.
/loop: continuous execution mode
Section titled “/loop: continuous execution mode”Continuous execution mode keeps the agent working after each round without you having to nudge it. Suitable for one-shot instructions like “implement feature X”: you send one message and the agent iterates, verifies, and pushes through until the work is done, genuinely blocked, or you explicitly confirm exit.
/loop is available only when the current MainAgent role can use the done tool: that is, done is registered and no rule denies it. A wildcard-only "*": deny does not deny it: mounting done is what entering loop mode does, so the loop itself is the authorization. Write done: deny to keep a role out of loop mode; /loop on is then refused with a toast.
Enabling:
/loop on # enable; agent will try to finish all remaining tasks in the session/loop on implement user auth # enable with a specific task target/loop off # return to normal mode/loop # show current stateThe text after /loop on is the task target sent to the agent. When omitted, it defaults to “Continue and finish all remaining tasks in the current session.” Each enable defaults to 10 max iterations; exceeding that stops automatically.
How it works: after /loop on, send a task instruction (e.g. “implement user auth”). The agent follows this cycle:
- executing: carrying out the task, calling tools to do real work
- assessing: evaluating current progress, deciding the next step
- verifying: running checks (tests, lint, etc.)
- continue or request exit: if more work remains, the agent keeps going; if it believes the loop can stop, it must request exit through the
donetool
When the agent asks to finish, Chord checks the loop exit conditions and shows a local confirmation containing the completion report. Confirm to stop, or reject to keep the loop running. YOLO mode does not bypass this confirmation or the done permission.
The done tool is mounted only while a loop is running. Outside a loop it is absent from the tool surface entirely, so ordinary sessions do not carry its definition and the model is never asked to choose between answering directly and calling a completion tool; in normal mode the agent simply finishes with a regular assistant response. Enabling /loop on mounts it: on models that support Chord’s request-only dynamic tool mounts (Responses-family models and Kimi dynamic tools) it is late-mounted for the next request at no prompt-cache cost, and everywhere else the tool surface is rebuilt once, which breaks prompt-cache reuse for that one request. Chord skips the mount when done is already present, so it never injects a duplicate. Loop mode then uses the current runtime’s tool-call requirements and continuation instructions to make done the explicit exit request. Running /loop off takes done back off the surface, returns subsequent work to normal response behavior, and cancels any loop continuation that had not yet been sent to the model.
Loop mode also detects repeated identical tool calls. It interrupts a stalled sequence and, after repeated interceptions, asks whether to stop or continue.
A good pattern is:
- turn on loop with a concrete target (
/loop on implement feature X with tests) - give one complete instruction with success criteria
- let the agent continue through edits, test failures, and follow-up fixes
- only confirm the final
donerequest when the work is actually complete
This reduces manual prompts such as “continue” or “run the tests too.” Do not use /loop just to keep the model running: normal mode is easier to control when the task is exploratory, ambiguous, or likely to need product decisions.
If the task is genuinely blocked, the agent can still report <blocked>category: reason</blocked>. You can always press Esc to cancel the current iteration.
Status bar: when enabled, the TUI status bar shows a [↻] marker.
When to use: multi-step tasks (generate code → write tests → debug → refine), iterative development. Not suitable for: one-shot queries or pure Q&A.
You can also define custom slash commands (per project or globally). See Customization: Custom slash commands.
Multi-agent focus switching
Section titled “Multi-agent focus switching”Chord supports cooperation between MainAgent and SubAgents.
Shift+Tab: in Insert mode, cycle the main agent mode (role) shown in the status bar (main view only); in Normal mode, cycle the focused agent view between the main agent and subagents
In a SubAgent view, you can inspect that agent’s context and output and submit new input. Completed, failed, and cancelled states describe the previous turn; they do not make the view read-only.
Card numbers are local to the viewed agent: the main transcript and every SubAgent transcript each start at #1 and advance independently. Switching agent views rebuilds that agent’s complete available history, including earlier instances of a rehydrated delegated task, so Ctrl+B / PgUp, gg, search, and the message directory can navigate earlier cards instead of exposing only a live tail.
After resuming a session, every restored agent is idle rather than pretending work from the previous process is still active. Any previous SubAgent state (including waiting, completed, failed, and cancelled) can be continued manually: focus that SubAgent and submit an empty input to continue from its existing context, or submit text to start a follow-up turn. Chord first reacquires a SubAgent concurrency slot and marks it running. An empty input starts a new turn without appending a synthetic user message. Mailboxes restored from the session remain queued while idle and are delivered only as part of this explicit manual continue or input action; mailbox events produced during normal live execution are dispatched immediately to the owning agent.
When todo_write is enabled, the todo list may contain multiple in_progress items while the agent is genuinely switching between distinct active workstreams. Each active item must use a unique active_form; delegated tasks should map to separate live workstreams. Do not mark work as in_progress when it is only planned, blocked on prerequisites, or merely waiting to start.
Images and PDFs
Section titled “Images and PDFs”Currently supported:
- Attach images and PDFs from the system clipboard with
Ctrl+VorAlt+V - Attach image and PDF files to the currently focused agent’s message when the active model supports that input type
- View images directly in supported terminals; PDFs are sent to the model and shown as file chips in the transcript, but are not previewed inline
- Edit historical user messages that contain images or PDFs; tail messages reopen in the current session, while earlier messages fork a new session, and path-restored attachments are reloaded when the edited message is sent again
- Let the model use the built-in
view_imagetool to load a local PNG/JPEG/WebP/GIF/BMP/TIFF image into context (normalized to PNG or JPEG, scaled down to 2000px on the longest edge, first frame for animated WebP/GIF/TIFF) when the tool is permitted, the first model in the effective model pool supports image input, and that first model does not use the OpenAI Chat Completions API. The tool uses the same local-path permission handling asread.
view_image availability follows the first model in the effective pool. For OpenAI models, use the Responses API when tools need to return images or files; Chat Completions accepts images in user messages but not in tool results. After an image/PDF tool result enters the conversation, Chord skips fallback models that cannot replay it safely.
Common actions:
Ctrl+VorAlt+Vin the main composer: asynchronously read an image or PDF from the system clipboard. PNG/JPEG are accepted directly; WebP/GIF/BMP/TIFF are normalized to PNG or JPEG and scaled down to 2000px on the longest edge (animated WebP/GIF/TIFF use their first frame; HEIC/HEIF/AVIF/SVG are rejected with a conversion hint). Images get an inline placeholder such as[image1.png]; PDFs are added as file attachments. Pressing Enter while the read is pending asks you to wait, so an immediate submit cannot lose the attachment. UseAlt+Vin Windows Terminal and WSL sessions hosted by it.Cmd+V, right-click paste, menu paste, and other terminal paste events: paste text only and never inspect clipboard attachments.Cmd+Vin confirmation-dialog text fields: paste text only.- Inline image attachments are capped at 5 per composer message
- Typing literal placeholder text such as
[image1]does not attach an image by itself; only Chord-inserted inline image placeholders are attachment-backed @file completion includes image/PDF files only when the current model supports that input type. Manually typed image/PDF@references are still accepted as attachments; unsupported attachments are ignored at send time with a warning.- To attach an image or PDF by path, enter the path in the composer and configure a custom
insert_attach_filekey binding - PDFs that appear to be encrypted are marked with a warning; Chord still allows sending them because provider-side parsing is authoritative.
Enter/o/Space: open the image in the current user message or tool result in Normal mode
Copying text
Section titled “Copying text”- Drag in the transcript to select text inside the TUI
yycopies the focused message card; tool cards are copied as Markdown with# Tool call,## Arguments,## Result, and## Diffsections (editcards use## old_string/## new_stringfor the replaced text instead, plus## replace_allonly when it is enabled). Done rejection reasons are copied in a separate## Rejection reasonsection.Cmd+C: copy the current transcript selection in macOS terminals that forward the key to Chord; when a confirmation dialog input is focused, copies that input insteadCtrl+C: remains reserved for cancel / quit and is not used for transcript copy
Headless
Section titled “Headless”chord headless is useful for:
- bot / gateway integration
- automation scripts
- external control-plane access without a local TUI
It uses:
- stdin: one JSON command per line
- stdout: one JSON event per line
See Headless for details.
Model editing tools
Section titled “Model editing tools”Chord picks the file-editing tool per active model: gpt-5-and-later family names (gpt-5, gpt-5-mini, gpt-5-nano, gpt-5-codex, any gpt-5.* name, and later majors like gpt-6-astra) and codex-auto-review use apply_patch, everything else defaults to edit; see Edit tools for the full matrix and the rationale. On compatible Responses endpoints, patch-native models additionally receive apply_patch as a freeform custom tool instead of a JSON function tool.
When a model name or gateway behaves differently from the inference, override it per provider or model with compat.apply_patch.enabled (tool surface) and compat.apply_patch.freeform (wire shape). Both keys are three-state: omitted means infer from the model name and endpoint, so you only set the knob you need to change. The authoritative field reference is in Configuration & Auth.