* 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> |
||
|---|---|---|
| .github/workflows | ||
| apps/web | ||
| e2e | ||
| scripts | ||
| server | ||
| .env.example | ||
| .gitignore | ||
| .goreleaser.yml | ||
| .npmrc | ||
| AGENTS.md | ||
| CLAUDE.md | ||
| docker-compose.yml | ||
| Dockerfile | ||
| LOCAL_DEVELOPMENT.md | ||
| Makefile | ||
| package.json | ||
| playwright.config.ts | ||
| pnpm-lock.yaml | ||
| pnpm-workspace.yaml | ||
| README.md | ||
| skills-lock.json | ||
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:
.envtypically usesPOSTGRES_DB=multica- each
.env.worktreegets its ownPOSTGRES_DB, such asmultica_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 stringPOSTGRES_DB— Database name for the current checkout or worktreePOSTGRES_PORT— Shared PostgreSQL host port (fixed to5432)PORT— Backend server port (default: 8080)FRONTEND_PORT/FRONTEND_ORIGIN— Frontend port and browser originJWT_SECRET— JWT signing secretMULTICA_APP_URL— Browser origin for CLI login callback (default:http://localhost:3000)MULTICA_DAEMON_ID/MULTICA_DAEMON_DEVICE_NAME— Stable daemon identity for runtime registrationMULTICA_CLAUDE_PATH/MULTICA_CLAUDE_MODEL— Claude Code executable and optional model overrideMULTICA_CODEX_PATH/MULTICA_CODEX_MODEL— Codex executable and optional model overrideMULTICA_WORKSPACES_ROOT— Base directory for agent execution environments (default:~/multica_workspaces)NEXT_PUBLIC_API_URL— Frontend → backend API URLNEXT_PUBLIC_WS_URL— Frontend → backend WebSocket URL
Local Development Notes
make setup,make start,make dev, andmake testnow require an env file. They fail fast if.envor.env.worktreeis missing.make stoponly stops the backend/frontend processes for the current checkout. It does not stop the shared PostgreSQL container.- Use
make db-downonly when you explicitly want to shut down the shared local PostgreSQL instance for every checkout.