e2f4a22030 feat: steer a running agent from the normal composer, per recipient (MUL-7631) (#8760)
* feat(server): steer running turns from ordinary comments (MUL-7631)

A comment can now name recipients whose running turn should receive it
(`steer_agent_ids` on POST /issues/:id/comments). Each named recipient
with a running, steer-capable turn gets the comment bound to that turn
instead of a follow-up run; any other recipient keeps its normal
queued / coalesced / deferred trigger, so losing a race never drops input.

- One comment can steer several turns: receipts are keyed by
  (comment_id, task_id) and returned as `supplements` on comments and
  timeline entries. The single supplement_* fields mirror the first
  receipt for older clients.
- Completion reconciliation skips a steered comment only for the agent
  it steered, so the same comment still reaches recipients that were
  addressed without steering.
- Delivery claims match the (comment, run) pair.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>

* feat(issues): choose per recipient how a message reaches a running agent (MUL-7631)

Steering moves from a separate "Add message" box on the run row into the
normal reply and comment composers. Recipients keep the existing trigger
rules; each recipient's current run on the issue decides what the message
can do:

- running (and steer-capable): add to the current run (default in that
  run's own thread), start after this run, stop and start over, or skip
- queued: include when it starts, or skip
- idle: start on send, or skip

Receipts follow the message ("Waiting for Lambda to read it" → "Read by
Lambda · after step N"), a failed delivery offers retry or sending it as
a new run, and the run's step list marks where it read the message.
A draft whose recipient finished meanwhile stays in place and says it
will start a new run; a message with files is handled after the run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>

* fix(server): steer only the chosen turn, and make a retried steer idempotent (MUL-7631)

- Steering names the exact running turns the author chose
  (`steer_task_ids`). A chosen turn that ended before the send arrives is
  never swapped for a later turn of the same agent; that recipient keeps
  its normal trigger.
- A steering send carries `client_request_id`. A retry after a lost
  response returns the original comment (200) instead of creating a second
  comment and a second delivery; a concurrent twin binding the same request
  is treated as already steered.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>

* fix(issues): guard steering sends against stale previews and broad resends (MUL-7631)

- "Stop and start over" never stops a run while the trigger preview is
  still catching up with an edited @mention: the stop is dropped unless the
  preview answers the submitted text.
- Steering sends the chosen turns' task ids and one request id per draft
  text, reused on retries of the same text.
- "Send as a new run" on a failed receipt reaches only that receipt's
  agent: every other current recipient is suppressed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>

* fix(issues): keep the reply box placeholder neutral (MUL-7631)

The empty reply box cannot know who a reply goes to: the author may
@ someone else or only talk to a teammate. The recipient chip already
says what Send will do once there is text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>

* test(issues): give steering composer tests room for the preview debounce (MUL-7631)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>

* feat(issues): choose the default reply to a running agent (MUL-7631)

Preferences > Comments gains "When replying to a running agent":
"Add to current run" (default) or "Start after this run". It only
changes what a reply does without a per-message choice; the recipient
chip still offers both, and replies that never steered by default
(another thread, an idle or queued agent) are unaffected. Saved on this
device next to the sticky comment bar.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>

* fix(server): save one comment per send and honor "don't start" on replay (MUL-7631)

Idempotency now lives on the comment, not the delivery receipt. A send's
client_request_id is stored on the comment behind a partial unique index
(migrations 550/551), so a retry, or a concurrent twin, returns the saved
comment (200) whether the send steered a running turn or fell back to a
normal trigger. Before, a twin could save a second comment, and a send whose
turn had ended kept no receipt to find.

The agents an author chose not to start are stored on the comment too, and
completion replay skips them. "Send as a new run" for one missed recipient,
and "Won't start this time", no longer wake the other agent once its current
run completes. An edit re-records the choice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>

* fix(issues): repeat the original steering request on retry (MUL-7631)

Until a send is settled, retrying the same text sends its first steering
request unchanged, even after the chosen turn ended. The server then returns
the comment the first attempt saved instead of posting it again as new input.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>

* fix(migrations): fail fast on locks in 549 and 550 (MUL-7631)

Both take an ACCESS EXCLUSIVE lock on a table the product touches
continuously: comment for every read and write, task_supplement for every
daemon claim. Bound lock acquisition and execution, as 483 does for issue,
so a long transaction makes the migration fail and retry on the next run
instead of queueing all traffic behind it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>

* fix(server): steer at most one turn per comment during rollout (MUL-7631)

Steering is live, and servers from before per-run receipts claim every
receipt of a comment at once. While they still serve daemons during a
rollout, a comment bound to two turns could have the second copy marked in
flight and never delivered. Until every server claims per (comment, run),
a comment steers the first chosen turn only; later recipients keep their
normal trigger. A follow-up lifts the limit after this ships.

Also covers a steer_task_ids entry that names another issue's turn.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>

* fix(server): finish a saved send on retry; keep an edit's choices with its text (MUL-7631)

A send's comment was saved before its agents were started or steered, and
deduplication treated the saved comment as the whole send. A dropped
connection cancelled the request between the two, and the retry only
returned the comment, so no agent ever received it.

- Attempts of one logical send now run one at a time under a transaction
  advisory lock, held on its own connection: a twin waits for the attempt in
  progress (up to 30s, then 409) instead of racing it, and a process that
  dies releases it.
- After the comment is saved, dispatch runs on a non-cancelable context, and
  comment.client_request_dispatched_at (migration 552) records that it
  finished. A retry that finds a saved but undispatched comment finishes the
  dispatch with the comment's recorded choices.

An edit's "don't start" choices were written by a separate statement after
the text, so interleaved edits could leave an older edit's choice. They are
now part of UpdateComment, under the same revision check as the text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>

* fix(issues): offer one steered recipient per message during rollout (MUL-7631)

The server steers at most one turn per comment until #8800, but the
composer showed "Add to current run" for every running recipient and the
server quietly queued the rest. Now only one recipient steers: the one the
author picked, otherwise the first that would by default. The others show
"Start after this run", and picking "Add to current run" on one of them
moves the steer there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>

* fix(server): claim a send before dispatching it; drop the request lock (MUL-7631)

The previous recovery marked a send dispatched only after reaching its
agents, so a failure after dispatch made a retry reach them all again. It
also held a pooled connection per send for an advisory lock while the send
needed more from the same pool, which could wait on itself until timeout.

A send's comment now holds a dispatch claim instead
(comment.client_request_dispatched_at, one conditional update): only the
attempt whose claim takes effect publishes the comment and reaches its
agents. A failed claim writes nothing else and returns 500 for the client
to retry; a retry that finds an unclaimed comment claims and dispatches
it; a claimed one is only returned. Concurrent attempts no longer wait on
each other, and post-save dispatch keeps a 30s bound of its own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>

* feat(server): let one comment steer several running turns (MUL-7631)

Lifts the rollout limit from #8760. Every server now claims receipts per
(comment, run), so a comment can be bound to each running turn its author
chose, and each recipient receives it in its own run.

Merge only after #8760 is deployed everywhere.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>

* feat(issues): steer every running recipient a message addresses (MUL-7631)

The client side of lifting the rollout limit: each running recipient can
take the message in its current turn again, instead of only one per
message.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>

* refactor(issues): drop send-retry idempotency and two display extras (MUL-7631)

A steering send now behaves like any other comment when its response is
lost: a retry posts it again. The machinery that tried to make that retry
return the saved comment grew with every edge it met, and ordinary comments
never had it:

- Remove comment.client_request_id, its unique index, and the dispatch
  claim (migrations 551/552, and 550 reduced to suppressed_agent_ids).
- Remove the replay/resume path in CreateComment, the post-save
  non-cancelable dispatch context, and the client's sticky request id.
  Steering sends only `steer_task_ids`; each binding uses the comment id
  as its receipt request id.

Two display extras go too, since the UI already shows the same thing:

- The "run ended while you were writing" notice: the recipient chip
  already switches from "Add to current run" to its new action.
- "after step N" on a read receipt: the run trace already places the
  message at the step where it was read.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>

* fix(issues): space agent names in Chinese copy; neutral recipients header (MUL-7631)

- The steer badge joined names with Intl.ListFormat, which gives
  "Lambda和Orion" in Chinese. Latin names are now spaced from the Chinese
  joiner ("Lambda 和 Orion"), per the zh copy conventions; the enumeration
  comma stays unspaced.
- The multi-recipient popover was still titled "Will start when sent" and
  its tooltip said "choose who runs", though each row now picks how that
  agent handles the message. Title it "Recipients" and reword the tooltip.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>

* fix(issues): translate the recipient source labels in Chinese (MUL-7631)

"assignee" and "@mention" were left in English in zh-Hans; the recipient
menu header shows them. Use 负责人 (per the zh conventions) and @提及.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-09-25 04:42:26 +08:00

Multica

Multica

Agents that show up on the board.

Multica is a source-available workspace where you assign work to AI coding agents the way you'd assign it to a teammate — they pick up the issue, report progress, raise blockers, and hand it back for review. Self-hostable, works with 26 agent CLIs, no lock-in.

CI Release GitHub stars Discord

Star History Rank GitHub Trending Repository of the Day

Website · Docs · Quickstart · Download · Vision · Self-Hosting · Discord · X

English | 简体中文

A Multica board where six agents and their human teammates are moving work across columns

Your next 10 hires won't be human.


What is Multica?

You already run Claude Code, Codex, and three other agents. Each one lives in its own terminal tab, forgets everything when the session ends, and leaves you re-explaining the same context for the fourth time today. The more agents you add, the more of your day goes to babysitting them.

Multica puts those agents and your teammates in one workspace. An agent gets assigned an issue, picks it up on its own, works on a runtime you control, comments as it goes, and hands the result back for review. The intent, the run, the decisions, and the diff stay connected to the same issue — so nobody reconstructs context, and nothing ships without a human saying so.


Build the team.

Claude Code, Codex, Cursor, Kimi — you don't pick one. You hire them all.

  • 26 agent CLIs → Claude Code, Codex, Cursor, Copilot, Kimi, OpenCode, and more.
  • Agents as teammates → Give each one a name, a provider, and a runtime — they show up on the board like anyone else.
  • Squads → Put agents and people on one team; the leader routes the work.
  • Skills → Turn a solved problem into a playbook every agent reuses.
  • Your own runtime → Their desk is your machine — a daemon on your laptop or cloud box. Code never leaves it.

Hand off the work.

It starts as three rough sentences in an issue. It ends as a pull request.

  • Assign an issue → Pick an agent as assignee the way you'd pick a colleague — it takes the work from there.
  • Autopilots → Run standups, audits, and reports on a cron — nobody to remind.
  • Chat → Ask your workspace a question, or start work without filing anything.
  • Projects → Group work and attach the repos and docs agents need as context.

Stay in the loop.

Which agent touched this? What did it run? What did it cost? Open the run.

  • Execution log → Replay every tool call, command, and error, timestamped.
  • Token usage → See what each run cost, per agent and per issue.
  • Review gates → Work lands in review, not in main. You decide what ships.
  • Inbox → Get pinged when an agent needs a call, not for every step.
  • Retries and timeouts → Failed runs retry on their own, or stop and tell you why.

Make it yours.

Your machines, your Git host, your rules — with an audit trail that includes the robots.


Get started

No terminal required: sign up at multica.ai, or download Multica Desktop for macOS, Windows, and Linux — it connects the computer it runs on as a runtime automatically.

The one prerequisite: the machine that will run agents needs at least one supported agent CLI installed and signed in — Claude Code, Codex, Cursor, and friends. Multica drives them; it doesn't ship them.

Self-hosting the whole thing
curl -fsSL https://raw.githubusercontent.com/multica-ai/multica/main/scripts/install.sh | bash -s -- --with-server
multica setup self-host

On Windows, set $env:MULTICA_MODE="with-server", then run the PowerShell installer: irm https://raw.githubusercontent.com/multica-ai/multica/main/scripts/install.ps1 | iex.

This pulls the official images from GHCR and requires Docker. See the Self-Hosting Guide; if the selected GHCR tag has not been published yet, fall back to make selfhost-build from a checkout.


Your first agent in five minutes

1. Sign in. multica.ai in the browser, or open Multica Desktop.

2. Connect a computer. A runtime is any machine agents can work on — your laptop, or a cloud box. Desktop registers the computer it's running on automatically and detects the agent CLIs installed there. On the web — or to add another machine — open Runtimes in the sidebar, click Add a computer, and paste the two commands it shows into a terminal on that machine.

3. Create an agent. Open Agents in the sidebar and click New agent. Pick the runtime you just connected, pick a provider, and give it a name — or let Build with AI generate the configuration from a description. That name is how it shows up on the board and in comments.

4. Assign it something. File an issue and set the agent as assignee. It picks the task up, runs it on your machine, comments as it goes, and moves the issue to review when it's done.

Full walkthrough: Quickstart · Tutorial


Runtimes

Multica does not ship a model. It drives the agent CLIs you already have installed and authenticated, so switching providers is a dropdown, not a migration.

Provider CLI Provider CLI
Claude Code claude OpenAI Codex codex
Cursor Agent cursor-agent GitHub Copilot CLI copilot
OpenCode opencode OpenClaw openclaw
Hermes hermes Pi pi
Antigravity agy CodeBuddy codebuddy
DevEco Code deveco Grok grok
Kimi kimi Kiro CLI kiro-cli
Qoder CLI qodercli Qoder CN qoderclicn
Qwen Code qwen QwenPaw qwenpaw
Reasonix reasonix Trae CLI traecli
DeepSeek Harness dsh Oh-My-Pi omp
MiniMax Code mcode Dim dim
Huawei Cloud CodeArts codearts — —

Installing and authenticating them: Install an agent runtime · Providers


Documentation

I want to… Start here
Get an agent doing something today Quickstart · Tutorial
Understand how the pieces fit Core concepts · How Multica works
Create and configure agents Agents · Create an agent · Skills
Get work to an agent Triggering agents · Assigning issues · Mentions
Connect my machines Daemon and runtimes · Install an agent runtime
Connect Git and chat tools GitHub · Self-hosted Git · Channels
Run it on my own infrastructure Self-hosting · Security model · Environment variables
Script it CLI reference · CLI and daemon guide · Auth tokens
Drive Multica from Codex, Claude Code, or Cursor Multica CLI skill
Work out why an agent is stuck Tasks · Troubleshooting

Architecture

        Web  ·  Desktop (macOS/Windows/Linux)  ·  iOS
                          │
                          ▼
   ┌──────────────┐   ┌──────────────┐   ┌──────────────────┐
   │   Next.js    │──>│  Go backend  │──>│   PostgreSQL     │
   │   frontend   │<──│  (Chi + WS)  │<──│   (17)           │
   └──────────────┘   └──────┬───────┘   └──────────────────┘
                             │  tasks over WebSocket
                      ┌──────┴───────┐
                      │ Agent daemon │  runs on your machine, next to your code
                      └──────┬───────┘
                             │  spawns
                      ┌──────┴───────────────────────────────┐
                      │  Claude Code · Codex · Cursor · …    │
                      │  (any of the 26 runtimes above)      │
                      └──────────────────────────────────────┘
Layer Stack
Web Next.js 16 (App Router)
Desktop Electron, sharing the web UI packages
Mobile Expo / React Native (iOS)
Backend Go (Chi router, sqlc, gorilla/websocket)
Database PostgreSQL 17 (pgcrypto + pg_trgm)
Agent runtime Local daemon executing any of the 26 agent CLIs above

Development

Contributors: start with the Contributing Guide.

Prerequisites: Node.js 22, pnpm 10.28.2, Go 1.26.6, Docker

make dev

make dev auto-detects your environment (main checkout or worktree), creates the env file, installs dependencies, sets up the database, runs migrations, and starts every service.

See CONTRIBUTING.md for the full workflow, worktree support, testing, and troubleshooting. The iOS client lives in apps/mobile/ — its README covers building it onto your own iPhone.

We release most weekdays, so main moves quickly — pull often.


Why "Multica"?

Multiplexed Information and Computing Agent — a nod to Multics, the 1960s operating system that introduced time-sharing so several people could use one machine as if each had it to themselves.

Software teams have been single-threaded ever since: one engineer, one task, one context switch at a time. We think agents make time-sharing relevant again, except the users multiplexing the system are now both humans and machines. A small team shouldn't feel small.

The longer argument, and where we think this goes: VISION.md.


License

Multica License — the complete Apache License 2.0 text plus additional conditions covering hosted services, commercial embedding, and branding. Self-host it, modify it, build on it; the exact terms are in the LICENSE, attribution notices in NOTICE.

S
Description
No description provided
Readme Apache-2.0
840 MiB
Languages
Go 56%
TypeScript 38%
MDX 4.5%
PLpgSQL 0.4%
Shell 0.4%
Other 0.6%