Skip to content
carakaGUIDEGitHub ↗
ON THIS PAGE8
GUIDE

From installed to working, in the room where the work happens.

Eight chapters in the order you meet them, from what is yours to supply before anything runs, to what to do when Caraka refuses. The last one names the parts of this that have only ever answered a test.

Caraka is unproven: every phase carries shipped code, and no field gate has been answered by anyone but the author. This page teaches what the program does today, and chapter 08 says which parts of it have only ever answered a test.
01

What you supply

Caraka owns no account. It drives the coding agent already installed on your machine and speaks through a bot you create yourself, so four things have to exist before the first command runs, and Caraka can install none of them for you.

$ npx caraka init
asks what it needs, pairs one operator, writes config.yaml
$ npx caraka doctor
names what is missing; --fix repairs what can be repaired alone
$ npx caraka start
stays in the foreground until Ctrl-C
Node 22 or newerThe runtime for the gateway and for npx. init checks it before anything else.
GitYour coding agent works inside the repository you point Caraka at, and init checks that Git is there before it pairs anyone.
A coding agent, signed ininit scans PATH for the seven agent binaries it knows and one of them is enough. Nine presets ship, Claude Code over the official ACP adapter is the shortest route, and five of the nine have completed a turn against a live binary here.
A bot of your ownOn Telegram that means @BotFather and the token it gives you. You paste it into the init wizard in your terminal, never into a chat and never into a file that gets committed.
!The token is stored in a mode-0600 file outside config.yaml. Caraka asks for no model API key, because the agent keeps its own authentication, and it opens no port: Telegram is polled, and both listeners it can start bind 127.0.0.1 unless you say otherwise.
02

Pairing

init prints a link. Whoever opens it first and presses Start becomes the operator, it answers once, and it dies in five minutes — so it is the one thing standing between a stranger and this machine, and forwarding it hands that machine over.

The operatorThe first sender on that channel’s allowlist. A few things are read from that person and nobody else, and the path form in chapter 05 is the one you will meet.
Your own conversation with the botEverything you write there reaches the coding agent. It starts in assisted mode, where a write or a command draws an approval card before it happens.
A group, or a guild channelAdd the bot to the room. The pairing card arrives in your own conversation with the bot rather than in the room, and only if the person who added it is already on the sender allowlist.
What adding a room choosesEveryone who can read the room reads the approval cards, the file paths, the diffs, and the command output. The card says exactly that before you press it.
!Being on the chat allowlist is not permission to write. A room starts read-only, and it stays that way until whoever runs Caraka names it under that channel’s modes in config.yaml on that computer.
03

Topics

Where the chat app has topics, one session is one topic and its answers arrive there. In a Telegram group three conditions decide whether that happens, and two of them are yours rather than Caraka’s.

topics: true in config.yamlThe channel-wide switch init writes. With it off, no session opens a topic anywhere on that channel.
The group is a forumTopics turned on in the group’s own settings, by whoever owns the group. Caraka reads the flag Telegram sends with each message and cannot set it.
Caraka is an admin, with Manage topicsThat right is what lets a bot create, rename, close, and reopen a topic. It arrives on a membership event, so promoting Caraka after it was added is what turns topics on.
What that right costsAn admin bot receives every message in the group, because Telegram stops holding ordinary messages back from it. Chapter 04 is what stands in privacy mode’s place.
!Without all three, sessions run linear behind a workspace and session header and nothing fails. A topic Caraka is refused once marks that container and says so in the room, rather than being retried on every task.
04

Aiming a message

In a room Caraka answers what is aimed at it and leaves everything else alone. That now holds inside a session topic as well, which is the one place it used to not hold: a topic that carries a session is not the same thing as a sentence addressed to Caraka.

·an ordinary line in the room
read, and left alone
@yourbot add a rate limit to the login route
(a reply to any message Caraka wrote) run the tests
/new@yourbot ~/Project/coret Coret
Name itThe mention has to open the message. A mention anywhere else in the line is left where it is, so asking Caraka to fix @yourbot’s parser still says @yourbot.
Reply to one of its messagesAny message Caraka wrote counts, and in a topic it opened there is always one, because it posts progress as soon as the topic exists. A reply to the service message that created the topic does not count.
What answers without being aimed/stop and /lock, so a run can be halted by anyone the allowlist names, and a reply carrying an approval code, because where there are no buttons that code is the only way a decision can arrive.
If Caraka is not an admin hereTelegram delivers only a command that names the bot, a reply to one of its messages, and service messages. An ordinary group message never reaches Caraka at all. That is privacy mode, not a fault.
!In your own conversation with the bot every message is aimed at Caraka by definition, so none of this applies there. There is no setting that turns the gate off in a room.
05

Sessions and folders

A session is one task and its transcript. It begins with an ordinary message where ordinary messages arrive, or with /new anywhere, and it runs in the folder the chat is already stuck to unless you name another.

/new
a fresh session, untitled
/new Coret
a fresh session called Coret
@toko-api fix the checkout 500
picks that workspace, and the chat sticks to it
/new ~/Project/coret Coret
names a folder by its path, and offers to add it
in a group the same line names the bot too — one task, one topic:
/new@kopipagi_bot ~/Project/kopipagi.id Task Kopi Pagi
/new open a new session
@kopipagi_bot which bot, when the group holds more than one
~/Project/… the folder the agent runs in
Task Kopi Pagi what the topic is called
The folder comes firstThe title takes the rest of the line. A first word that is not an absolute path once ~/ is expanded is part of the title, so /new fix the login bug is a session with that name and not a folder called fix.
/wsLists the workspaces and their paths. In a room, a slug is how a folder is named.
The path formRead from the channel’s operator, in any container Caraka serves, and from nobody else. That path becomes the key of a trust window, of a memory scope, and of the directory the agent runs in, so the person who chooses the string is the person who paired.
A path config.yaml does not name yetCaraka offers to add it. The card is drawn in the operator’s own conversation and nowhere else, and the room is told one fixed sentence saying where the answer is given — the same sentence whether that directory exists, is a file, or overlaps something.
What the card’s Yes doesThree things at once: the entry is written to config.yaml and stays until you remove it, the topic appears, and the session opens empty. Nothing has reached the coding agent yet, so the message after it is the actual task. The card expires in ten minutes and takes the waiting task with it.
Where the session is bornIn the room the task came from, not in the conversation where the card was answered.
What is refused before a card existsA path that is not a directory, a last segment that cannot be a slug, a slug or path already taken, and a folder that contains a workspace you already have — approving ~/Project is not meaningfully smaller than approving the disk. A folder inside an existing workspace does get a card, carrying the cost: two scopes over one directory, so /lock on one leaves the other’s trust window open and memory under one does not surface under the other.
One run at a timePer workspace, in the order the messages arrived. A second task in the same workspace is queued and told its number, and workspaces run beside each other rather than behind each other.
!Fourteen commands are registered, so your chat app offers them in its own menu: /new /status /stop /ws /switch /commands /usage /ingat /lupakan /memori /yolo /lock /close /help. Send /help in your own conversation with the bot for what each one does; the answer in a room is a shorter, different one. Those fourteen are all Caraka has. What the coding agent offers is a separate list you read with /commands, and on the ACP route the agent puts its own skills in it — Caraka repeats that list and adds nothing.
06

Approvals

When the agent wants to write a file or run a command, Caraka stops and asks. The question arrives as a card, and what answers it is a single-use secret rather than a word.

Where there are buttonsThe decision travels inside a signed callback bound to the person, the session, and the request. Pressing it once is the whole answer.
Where there are noneThe card carries a code generated on your machine and printed nowhere else, not even in the agent’s own context. Reply ok followed by the code to allow it once, or no followed by the code to refuse.
Ten minutes, and one useA card expires and answers once. Five wrong codes stop Caraka reading codes in that session until the waiting request is decided or its ten minutes are up.
No word approves anythingNot yes, not approve, nothing a prompt injected into a file could produce. A card in a room is read by everyone in it, and only the person it is bound to can answer it.
/yolo 30m, and /lockA trust window auto-approves ordinary actions in one workspace for a stated duration, 60 minutes at most, and /lock closes it. Opening one is confirmed by pressing a button; chat text cannot open one.
!The high-risk list applies before any of this and draws a card whatever the mode says. A trust window covers the whole workspace, including the conversations that were never opted in, which is why /yolo is refused in a read-only room rather than quietly scoped to it.
07

When it refuses

A refusal names what happened and what to do next, and never shows a stack trace. Six of them arrive often enough to be worth reading before you meet one.

This conversation is read-onlyA room starts that way. Whoever runs Caraka adds that container’s id as assisted under the channel’s modes in config.yaml and restarts. Until then Caraka reads the repository and answers questions there.
A path names a workspace only when the operator writes itName the folder by its slug instead, and /ws lists them. Or ask the operator to add it once, after which the slug works for everyone the allowlist names.
That is not a directory Caraka can findThe path is resolved on the machine running Caraka, not on the phone you typed it from. Create it there, or check the spelling, then send the path again.
That path overlaps a workspaceA parent of a workspace is not a smaller grant than the whole disk: one trust window would cover both. Name a directory that holds neither the other, or add it in config.yaml by hand.
That gives no usable nameThe slug is the last part of the path, and it has to be letters, digits, dots, dashes, or underscores. Add the entry in config.yaml with a slug of your own, then restart.
No window opened/yolo sent from a read-only room. Send it from your own conversation with the bot, or opt the room in first.
!Nothing closes a topic on its own. A finished run is renamed with its state glyph and left open, because a run ending is not a session ending — the next message in that topic continues the same session. When you are done, /close marks the session finished, sends a closing line, and closes the topic in that order, so the last thing in the topic explains why the session ended. It refuses while a task is running and names /stop as the way through. Closed, never deleted: the delete call takes the whole transcript with it, while closing is a flag and the history stays readable to every member. In a group the composer is then gone for everyone but an admin with Manage topics, and the next session starts with /new.
08

What is unproven

The instructions above describe code that ships and is tested. Three parts of it have never been answered by a person, and knowing which three is the difference between following a guide and trusting one.

Telegram is the route that has been usedThe Discord path has never touched a real Discord, and no WhatsApp number has ever been linked. Both are shipped code answering a test rather than a person.
Closing and reopening a topicExercised against a stub adapter and against the Bot API documentation, never against a real forum supergroup. If a session ends and its topic stays open, this is the gap it fell through.
Four of the nine agent presetsHave never been run here at all: amp, antigravity, cursor, and gemini. The other five each completed two turns and a resume against their real binary. A YAML file that loads is not an agent that answered, and running one is what breaks its preset — two of the five were wrong until the run found them.
!Where a sentence on this page disagrees with what your own machine does, the machine is right and this page has the bug. docs/troubleshooting.md is the runbook, and the repository takes the report.
Two pages this one leans on.
Install walks the prerequisites and the prompt that hands the work to your coding agent. Docs is the scope: everything Caraka does, and what it deliberately does not.
Install →Docs →