The open-source managed agents platform. Turn coding agents into real teammates — assign tasks, track progress, compound skills. https://multica.ai
Find a file
LinYushen 961de18c97
feat(agents): reply as thread instead of top-level comment (#205)
* feat(agents): reply as thread instead of top-level comment

When an agent responds to a user comment, the reply is now nested under
the triggering comment (parent_id) instead of appearing as a separate
top-level comment. Also enables on_comment trigger by default for newly
created agents.

- Add trigger_comment_id column to agent_task_queue (migration 028)
- Pass triggering comment ID through EnqueueTaskForIssue → task → createAgentComment
- Include parent_id in WebSocket broadcast for agent comments
- Default agent creation includes both on_assign and on_comment triggers

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(cli): add --parent flag to comment add for threaded replies

The agent posts comments via the CLI, so the correct fix is giving it a
--parent flag rather than wiring trigger_comment_id through the task
infrastructure. The agent reads the comment list, decides which comment
to reply to, and passes --parent <comment-id>.

- Add --parent flag to `multica issue comment add`
- Update agent runtime instructions to explain --parent usage

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(daemon): pass trigger_comment_id to agent execution context

The agent now knows which comment triggered its task and gets an explicit
instruction to reply to it using --parent. The trigger_comment_id flows
from the DB through the claim response, daemon Task struct, and into
issue_context.md where the agent sees it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(comments): agent replies to thread root, matching frontend behavior

When the triggering comment is itself a reply (has parent_id), resolve
to the thread root so the agent's reply stays in the same flat thread.
This matches the frontend where all replies share the top-level parent.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(cli): show parent_id and full IDs in comment list

The table output now includes a PARENT column and shows full comment IDs
(not truncated) so agents can see thread structure and use --parent.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(daemon): instruct agents to always use --output json

Agents now see explicit guidance to use --output json for all read
commands, ensuring they get structured data with full IDs and parent_id
for proper threading.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(daemon): differentiate comment-trigger vs assign-trigger context

When triggered by a comment, the agent now gets clear instructions:
- Primary goal is to read and respond to the comment
- Do NOT change issue status just because you replied
- Only change status if explicitly requested

This prevents the agent from seeing "In Review" and stopping, since
it now understands the task is to reply, not to re-evaluate the issue.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(daemon): split workflow by trigger type in CLAUDE.md/AGENTS.md

The Workflow section in the agent's runtime config now shows a
comment-reply workflow when triggered by a comment (read comments,
find trigger, reply, don't change status) vs the full assignment
workflow (set in_progress, do work, set in_review).

Previously the agent always saw the assignment workflow, causing it
to check the issue status, see "In Review", and stop without reading
or replying to the triggering comment.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor(daemon): remove duplicate workflow from issue_context.md

Workflow instructions now live only in CLAUDE.md/AGENTS.md (runtime_config.go).
issue_context.md keeps just the task data: issue ID, trigger type, and
triggering comment ID.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(task): skip duplicate comment on completion for comment-triggered tasks

When triggered by a comment, the agent posts its own reply via CLI
with --parent. The task completion path was also creating a comment
from the agent's stdout output, resulting in duplicates. Now only
assignment-triggered tasks auto-post output as a comment. Error
messages from FailTask are still posted regardless of trigger type.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 13:48:39 +08:00
.github/workflows fix(ci): replace turbo commands with direct pnpm calls 2026-03-26 18:01:24 +08:00
apps/web feat(agents): reply as thread instead of top-level comment (#205) 2026-03-31 13:48:39 +08:00
e2e fix: resolve merge conflicts with main, preserve PAT functionality 2026-03-26 17:19:24 +08:00
scripts Improve local CLI auth and skills UX 2026-03-27 18:32:56 +08:00
server feat(agents): reply as thread instead of top-level comment (#205) 2026-03-31 13:48:39 +08:00
.env.example feat(auth): email verification login and personal access tokens 2026-03-26 14:32:30 +08:00
.gitignore fix(activity): address code review feedback and improve timeline UX 2026-03-29 00:21:46 +08:00
.goreleaser.yml chore: rename super-multica references to multica 2026-03-25 21:01:39 +08:00
.npmrc refactor: restructure to monorepo architecture 2026-02-10 18:00:23 +08:00
AGENTS.md refactor: decouple task lifecycle from issue status (#151) 2026-03-27 18:30:21 +08:00
CLAUDE.md docs: update CLAUDE.md with logging, CI, and CLI details 2026-03-27 12:33:38 +08:00
docker-compose.yml chore: rename super-multica references to multica 2026-03-25 21:01:39 +08:00
Dockerfile chore: add Dockerfile for Go backend 2026-03-30 15:41:42 +08:00
LOCAL_DEVELOPMENT.md chore: rename super-multica references to multica 2026-03-25 21:01:39 +08:00
Makefile Improve local CLI auth and skills UX 2026-03-27 18:32:56 +08:00
package.json refactor: remove unused monorepo tooling 2026-03-26 17:57:11 +08:00
playwright.config.ts Add workspace management and isolated worktree environments 2026-03-23 18:12:11 +08:00
pnpm-lock.yaml feat(reactions): add emoji reactions for comments and issue descriptions 2026-03-30 22:37:59 +08:00
pnpm-workspace.yaml refactor: remove unused monorepo tooling 2026-03-26 17:57:11 +08:00
README.md feat(cli): restructure CLI commands for better UX 2026-03-29 01:43:45 +08:00
skills-lock.json feat: add Claude Code skills for UI/UX development 2026-03-27 00:40:16 +08:00

Multica

AI-native task management platform — like Linear, but with AI agents as first-class citizens.

For the full local development workflow, see Local Development Guide.

Prerequisites

Quick Start

# 1. Install dependencies
pnpm install

# 2. Copy environment variables for the shared main environment
cp .env.example .env

# 3. One-time setup: ensure shared PostgreSQL, create the app DB, run migrations
make setup

# 4. Start backend + frontend
make start

Open your configured FRONTEND_ORIGIN in the browser. By default that is http://localhost:3000.

Main checkout uses .env. A Git worktree should generate its own .env.worktree and use the explicit worktree targets:

make worktree-env
make setup-worktree
make start-worktree

Every checkout shares the same PostgreSQL container on localhost:5432. Isolation now happens at the database level:

  • .env typically uses POSTGRES_DB=multica
  • each .env.worktree gets its own POSTGRES_DB, such as multica_my_feature_702
  • backend/frontend ports still stay unique per worktree

That keeps one Docker container and one volume, while still isolating schema and data per worktree.

Project Structure

├── server/             # Go backend (Chi + sqlc + gorilla/websocket)
│   ├── cmd/            # server, daemon, migrate
│   ├── internal/       # Core business logic
│   ├── migrations/     # SQL migrations
│   └── sqlc.yaml       # sqlc config
├── apps/
│   └── web/            # Next.js 16 frontend
├── packages/           # Shared TypeScript packages
│   ├── ui/             # Component library (shadcn/ui + Radix)
│   ├── types/          # Shared type definitions
│   ├── sdk/            # API client SDK
│   ├── store/          # State management
│   ├── hooks/          # Shared React hooks
│   └── utils/          # Utility functions
├── Makefile            # Backend commands
├── docker-compose.yml  # PostgreSQL + pgvector
└── .env.example        # Environment variable template

Commands

Frontend

Command Description
pnpm dev:web Start Next.js dev server (uses FRONTEND_PORT, default 3000)
pnpm build Build all TypeScript packages
pnpm typecheck Run TypeScript type checking
pnpm test Run TypeScript tests

Backend

Command Description
make dev Run Go server (uses PORT, default 8080)
make daemon Run local agent daemon
make multica ARGS="version" Run the local multica CLI without installing it
make test Run Go tests
make build Build server & daemon binaries
make sqlc Regenerate sqlc code from SQL

Database

Command Description
make db-up Start the shared PostgreSQL container
make db-down Stop the shared PostgreSQL container
make migrate-up Ensure the current DB exists, then run migrations
make migrate-down Rollback database migrations for the current DB
make worktree-env Generate an isolated .env.worktree for the current worktree
make setup-main / make start-main Force use of the shared main .env
make setup-worktree / make start-worktree Force use of isolated .env.worktree

CLI (multica)

The CLI manages authentication, workspace configuration, and the local agent daemon.

Install

brew tap multica-ai/tap
brew install multica-cli

Or build from source:

make build
cp server/bin/multica /usr/local/bin/multica   # or ~/.local/bin/multica

For local development, you can also run the CLI directly from the repo:

make multica ARGS="version"
make multica ARGS="auth status"

For browser-based auth from source, make sure the local frontend is running at FRONTEND_ORIGIN first, for example with make start, make start-main, or make start-worktree.

Authentication

multica login               # Authenticate and auto-watch your workspaces
multica auth login          # Legacy auth-only flow
multica auth login --token  # Legacy token-only auth flow
multica auth status         # Show current auth status
multica auth logout         # Remove stored token

Credentials are saved to ~/.multica/config.json.

Workspaces

multica workspace list      # List all workspaces you belong to
multica workspace get       # Show the current workspace details/context

Daemon Watch List

The daemon monitors one or more workspaces for tasks. Manage which workspaces are watched:

multica workspace watch <workspace-id>    # Add a workspace to the watch list
multica workspace unwatch <workspace-id>  # Remove a workspace from the watch list
multica workspace list                    # Show all workspaces (watched ones marked with *)

The watch list is stored in ~/.multica/config.json. Changes are picked up by a running daemon within 5 seconds (hot-reload).

Local Agent Daemon

The daemon polls watched workspaces for tasks and executes them using locally installed AI agents (Claude Code, Codex).

# 1. Authenticate
multica login

# 2. Add workspaces to watch
multica workspace watch <workspace-id>

# 3. Start the daemon
multica daemon start

The daemon auto-detects available agent CLIs (claude, codex) on your PATH. When a task is claimed, it creates an isolated execution environment, runs the agent, and reports results back to the server.

Other Commands

multica agent list          # List agents in the current workspace
multica daemon status       # Show local daemon status
multica config              # Show CLI configuration
multica config show         # Compatibility alias for config display
multica version             # Show CLI version

Environment Variables

See .env.example for all available variables:

  • DATABASE_URL — PostgreSQL connection string
  • POSTGRES_DB — Database name for the current checkout or worktree
  • POSTGRES_PORT — Shared PostgreSQL host port (fixed to 5432)
  • PORT — Backend server port (default: 8080)
  • FRONTEND_PORT / FRONTEND_ORIGIN — Frontend port and browser origin
  • JWT_SECRET — JWT signing secret
  • MULTICA_APP_URL — Browser origin for CLI login callback (default: http://localhost:3000)
  • MULTICA_DAEMON_ID / MULTICA_DAEMON_DEVICE_NAME — Stable daemon identity for runtime registration
  • MULTICA_CLAUDE_PATH / MULTICA_CLAUDE_MODEL — Claude Code executable and optional model override
  • MULTICA_CODEX_PATH / MULTICA_CODEX_MODEL — Codex executable and optional model override
  • MULTICA_WORKSPACES_ROOT — Base directory for agent execution environments (default: ~/multica_workspaces)
  • NEXT_PUBLIC_API_URL — Frontend → backend API URL
  • NEXT_PUBLIC_WS_URL — Frontend → backend WebSocket URL

Local Development Notes

  • make setup, make start, make dev, and make test now require an env file. They fail fast if .env or .env.worktree is missing.
  • make stop only stops the backend/frontend processes for the current checkout. It does not stop the shared PostgreSQL container.
  • Use make db-down only when you explicitly want to shut down the shared local PostgreSQL instance for every checkout.