Agents
One key hands a task to your coding agent: in the right place, in the repository's clone, already told what there is to do.
a on a task, or from a shell:
aki agent web!916
The reference is what the board shows: web!916, notes#12, PROJ-7, a ticket key the change names, or its URL. --dry-run prints where it would open and the brief, without opening anything.
The brief
The agent's first message is written from the task: where the work is, why it is listed, and what each reason asks for, most pressing first.
This comes from my board of things to do. Typed errors for the key store https://gitlab.example/acme/api/-/merge_requests/889 api!889 on gitlab. I am a reviewer; the author is @ana. Ticket: PROJ-440 (high). What there is to do, most pressing first: 1. Re-review: the author replied, new commits. I already reviewed it. Look at what changed since: the commits pushed after my review and the answers to my comments. Tell me whether each of my points was addressed. If they all were and nothing new is wrong, say it is ready to approve. Start here: https://gitlab.example/acme/api/-/merge_requests/889#note_7 2. Resolve threads: 2 answered threads to check and resolve. … Start by reading it where it lives, with the forge's or the tracker's own tools. Then tell me what you found and what you propose. Do not post, approve, merge or push anything before I say so.
Every rule has its own request: a review asks for a review, a red pipeline asks to be fixed, a branch behind its target asks for a rebase. instructions adds your own closing words to every brief.
Set it up
[agent]
command = "claude {prompt}"
instructions = "Answer in French."
workspace = "{repo}"
tab = "{ticket} {ref}"
focus = true| Key | Meaning |
|---|---|
command | The agent's command. {prompt} is where the brief goes, as one argument; without it the brief is the last argument. A list works too: ["codex", "--full-auto", "{prompt}"]. |
instructions | Added at the end of every brief. |
workspace, tab | The names of where the agent opens. See Names. |
focus | Whether opening an agent takes you to it. |
Where it opens
launcher chooses. "auto", the default, takes the multiplexer aki runs inside (Herdr, TUIOS or tmux), else the terminal aki runs in, else a Claude conversation.
In a multiplexer, a place per repository holds a terminal per piece of work, both named from your templates and created when missing. A place or a terminal is reused only when it bears exactly that name, and a terminal that is already open is never doubled:
- an agent runs in it: the new brief is pasted into its prompt and sent;
- the agent is gone: it is started again in that terminal, on the brief;
- the terminal runs something else: nothing is typed, and aki says so.
[agent] launcher = "herdr"
One workspace per repository, one tab per piece of work. Herdr reports what each agent is doing.
herdr_session = "work" opens agents in a named Herdr session instead of the current one.
[agent] launcher = "tmux"
One session per repository, one window per piece of work. Inside tmux, opening an agent switches your client to its session; outside, the session is created detached and tmux attach -t web takes you there.
tmux does not report agent states: the board shows that the window is open. A dot or a colon in a repository's name becomes an underscore in the session's.
[agent] launcher = "tuios"
One workspace per repository, one named window per piece of work. A repository takes the first workspace that is empty and unnamed, and gives it its name; when the nine are taken, aki says so. TUIOS reports what each agent is doing.
tuios_session = "work" opens agents in a named TUIOS session instead of the one aki runs in.
[agent] launcher = "terminal"
A new window or tab of Ghostty, WezTerm, kitty, iTerm or Terminal, whichever aki runs in. For another terminal, give your own command:
[agent]
terminal = ["alacritty", "--title", "{title}", "-e", "{command}"]{command} is what to run, {title} its name, {directory} where it starts. A plain terminal cannot tell whether a tab is already open, nor what the agent is doing.
[agent]
launcher = "claude"
chat_url = "https://claude.ai/new?q={prompt}"No terminal: a new Claude conversation opens with the brief as its first message. For the desktop app, try chat_url = "claude://claude.ai/new?q={prompt}". This is what an assistant uses when asked to start on a task.
Names
The names come from the task, never from what you already have open.
| Placeholder | Value |
|---|---|
{repo} | The repository's own name: web. |
{path} | Its full path: acme/platform/web. |
{ref} | The reference: !916, #12, PROJ-7. |
{short} | Both: web!916. |
{ticket} | The first ticket the change names; empty when there is none. |
{kind} | The rule that lists the task: review_requested. |
{source} | Where it comes from: gitlab. |
The clone
The agent starts in the repository's local clone, found by its git remote under the folders where you keep your code. Without your word, aki looks in ~/code, ~/src, ~/dev, ~/projects, ~/work, ~/repos, ~/git, ~/Developer and ~/Desktop.
[agent] roots = ["~/code"] [agent.repos] "group/project" = "~/elsewhere/project"
Without a clone the agent still opens, and the brief carries the link. The agent is started by your own login shell, so it finds the same PATH as at your prompt.
What the agent is doing
Once an agent is open on a task, the board shows its state beside the task, read from the launcher every two seconds.
| Mark | State | Filter |
|---|---|---|
◐ | Working. | agent:working |
? | Waiting for you. | agent:blocked |
✓ | Done, not looked at yet. | agent:done |
· | Idle. | agent:idle |
○ | Its terminal is open; what runs in it is not known. | agent:open |
Herdr and TUIOS report states; tmux shows ○. A pane filtered on agent:blocked gathers the agents that wait for you.