kolu under any chat app
The coding agent has moved into the chat. kolu is the open, model-agnostic terminal/file foundation any chat app integrates — running claude, codex, or opencode on infrastructure you control. XS integrates kolu; the first proof is an XS bot that runs kolu's own development inside chat, in the open.
A read of Anthropic’s Claude Tag (Claude joins the team chat as a tagged teammate) and AI researcher Andrej Karpathy’s framing of it as “the 3rd major redesign of LLM UIUX,” held against what kolu is. Throughout, XS stands for any chat app (a Slack-style team chat where the agents already live), and pesu (Tamil பேசு, “to speak”) is a minimal XS bot — the first thing to run kolu’s own development inside chat.
The shift: the agent moved into the chat
Karpathy isn’t describing a chatbot you ask questions. He’s describing a coworker: a persistent agent that lives where the team already works, holds the org’s tools and context, and runs tasks on its own while you do something else. You @-tag it, walk away, and it pings you when it needs you. Anthropic shipped this shape as Claude Tag — one shared Claude per channel, tasks it pursues “over hours or days,” an audit log of every task and who asked for it. The proof-point is blunt: “65% of our product team’s code is created by our internal version.” The work moves into chat, and the human’s job shifts from driving keystrokes to managing agents.
In that world the terminal specializes. Chat keeps gaining richer rendering — diffs, highlighting, even little editors — but it stays async text over request and response. It is not a live process you can step into. The terminal is where you drop to a shell, answer an interactive prompt, watch raw output, drive a debugger. Chat owns the breadth; the terminal owns the depth — and kolu is what makes the depth real.
kolu in one picture
At its core kolu does two things: it runs real terminals on computers you control, and watches what’s happening inside them. That core is three parts:
- kaval owns each live terminal — start an agent, type into it, resize it, kill it. It is also the single point that serializes writes: when input arrives, last one wins.
- pulam watches every terminal without touching them, folding the raw noise into a simple, read-only board: which agent is working, which is blocked, who needs you.
@kolu/surfaceis the typed wire that carries both over any connection — a local socket, ssh to another machine, or an Incus host (a sandboxed box).
Two things sit either side of kolu, and the relationship with each is different:
- XS is independent. It already runs without kolu. Integrating kolu is simply what lets a chat thread reach into a real terminal — XS gains the depth, kolu gains a front door. Everything social stays in XS.
- The machine is wherever kolu runs. kolu runs headlessly on any box — your laptop, a server, or a remote sandboxed host. Remote sandboxes (an Incus cluster, another team’s project) are something it naturally supports: a remote host is just another place to dial the same surface.
So the picture is not a tower of dependencies. XS integrates kolu; kolu runs on whatever machine you choose. The arrow is integration one way and execution the other.
The moat: model-agnostic, open, yours
kolu and a chat app divide cleanly. kolu owns the live process, the files, and the durable session. XS owns identity, login, presence, and who-may-write. A foundation that reaches up and grows chat stops being a neutral base any chat app can integrate and becomes one more single-vendor app. Holding that line isn’t caution — it’s the moat.
The seam: observe out, act in
XS integrates kolu through one seam — the same @kolu/surface wire kolu already has —
split into two halves: observe flows out, act flows in. kolu authenticates
nothing: the connection is the trust — an owner-only socket locally, an ssh link to a
remote host — so identity, login, and presence stay in XS, and kolu just serializes
whatever its one trusted client sends.
| Verb | Half | Reuses | Status |
|---|---|---|---|
observe |
out | pulam awareness + activity + read-only fs/git | ships |
attach |
out | kaval’s screen stream (+ a re-resolvable cursor marking where you reattached) | ships |
getSession |
out | the saved session key + resume path — never transcript content | to build |
submit |
in | kaval.spawn |
to build |
write |
in | kaval.write (covers the y⏎ approve) |
partial |
kill |
in | kaval.kill |
to build |
resize |
in | kaval.resize — one terminal has one size; pairing needs it |
to build |
wake / wakeAndSend |
in | reopen a parked session, optionally inject one question (kolu stores none of it) | to build |
On these verbs — with no new auth in kolu — XS builds the who-needs-me board (observe),
pairing on one terminal (attach + write + resize), a forward-facing punchlist pinned
to durable terminals, and later review-interrogation: reopen the exact agent that did
the work and ask it why (getSession + wakeAndSend) — kolu keeps the session key and
a resume path, the agent keeps its own transcript, and kolu never parses the bytes.
The first proof: an XS bot
pesu is a small XS bot that bridges one XS thread to one kolu terminal: it streams the
terminal into the thread (attach + observe) and relays the thread’s one floor-holder
back as keystrokes (write). It rides XS’s own identity, presence, and login, and needs
no auth in kolu — just the connection. The bot is the near-term path; closer, native XS
integration follows.
The milestone is concrete: run kolu’s own development inside XS. Today kolu is built by agents on a personal headless Linux box. The bot moves that work into an XS thread so the team can watch the agents run — observe first, not steer. Querying and writing from chat come once it’s more than one personal host. What the bot proves is the act-in verbs over the surface, driven to a live agent — not a static view any already-shipping read could render.
kolu — make session export a lightweight chat log: a picker for Chat log / Full transcript / Both, plain HTML, no hidden tool payloads. Open a PR.kolu·e7f2. Streaming the live session here./be review gauntlet caught + fixed a stored XSS in the shared export (raw HTML passthrough) — escaped, test added.master. Terminal kolu·e7f2 parked — reopen any time.The target user story, end to end — here replaying a real merged change, PR #1544, which made session export a lightweight chat log: start an agent from a thread, watch it work, get screenshot evidence, jump into the live terminal to try it, then take the PR to green and merge — all without leaving chat. The first milestone lights up the observe half (the stream and the evidence); attaching to test and merging from chat ride the act-in verbs that follow.