17-diagrams
17-diagrams
架构与流程图
本文档中的图用 Mermaid 编写,可在支持 Mermaid 的 Markdown 预览器中查看。
1. 总体框架图
flowchart LR
User[Human user] --> Web[apps/web<br/>Next.js]
User --> Desktop[apps/desktop<br/>Electron]
User --> Mobile[apps/mobile<br/>Expo RN]
User --> CLI[server/cmd/multica<br/>CLI]
Web --> Core[packages/core<br/>API/Query/Store]
Desktop --> Core
Mobile -. shares types/pure funcs .-> Core
Web --> Views[packages/views<br/>Shared business UI]
Desktop --> Views
Views --> Core
Views --> UI[packages/ui<br/>Atomic UI]
Core --> API[Go API server<br/>server/cmd/server]
CLI --> API
Desktop --> Daemon[Local daemon<br/>server/internal/daemon]
CLI --> Daemon
API --> DB[(PostgreSQL + pgvector)]
API --> Redis[(Redis optional)]
API --> S3[S3 or local storage]
API --> Cloud[Cloud runtime / billing upstream]
API --> Integrations[Lark / Slack / GitHub / Stripe]
Daemon --> AgentCLI[Agent CLIs<br/>Claude/Codex/OpenCode/etc.]
Daemon --> API
API -- WebSocket events --> Core
API -- daemon WS wakeup --> Daemon
2. Monorepo 分层图
flowchart TB
subgraph Apps
WebApp[apps/web<br/>Next.js routing/platform]
DesktopApp[apps/desktop<br/>Electron routing/IPC]
MobileApp[apps/mobile<br/>Expo independent UI]
DocsApp[apps/docs<br/>Docs site]
end
subgraph Packages
ViewsPkg[packages/views<br/>Business pages/components]
CorePkg[packages/core<br/>API, Query, stores, types]
UIPkg[packages/ui<br/>Atomic components/tokens]
TSCfg[packages/tsconfig]
ESLint[packages/eslint-config]
end
WebApp --> ViewsPkg
DesktopApp --> ViewsPkg
ViewsPkg --> CorePkg
ViewsPkg --> UIPkg
WebApp --> CorePkg
DesktopApp --> CorePkg
MobileApp -. type/pure imports only .-> CorePkg
WebApp --> TSCfg
DesktopApp --> TSCfg
CorePkg --> TSCfg
ViewsPkg --> TSCfg
UIPkg --> TSCfg
3. 后端组件图
flowchart TB
Main[server/cmd/server/main.go] --> Router[NewRouterWithOptions<br/>server/cmd/server/router.go]
Main --> Bus[events.Bus]
Main --> Hub[realtime.Hub]
Main --> DaemonHub[daemonws.Hub]
Main --> Scheduler[scheduler.Manager]
Main --> Sweeper[Runtime sweeper]
Main --> Metrics[metrics server]
Router --> Middleware[Auth / DaemonAuth / Workspace / CORS / RateLimit]
Router --> Handler[handler.Handler]
Handler --> Queries[sqlc Queries]
Handler --> TaskSvc[TaskService]
Handler --> IssueSvc[IssueService]
Handler --> AutopilotSvc[AutopilotService]
Handler --> Storage[Storage S3/local]
Handler --> Channel[Channel engine<br/>Lark/Slack]
Handler --> Bus
TaskSvc --> Queries
IssueSvc --> Queries
AutopilotSvc --> Queries
TaskSvc --> Bus
IssueSvc --> Bus
AutopilotSvc --> Bus
Queries --> DB[(PostgreSQL)]
Bus --> Listeners[server/cmd/server/*_listeners.go]
Listeners --> Hub
Listeners --> Queries
Hub --> WSClients[Web/Desktop WS clients]
DaemonHub --> Daemon[Local daemon]
4. Server 启动流程图
flowchart TD
A[main()] --> B[Init logger and env defaults]
B --> C[Load feature flags]
C --> D[Create pgxpool and ping DB]
D --> E[Create events.Bus + realtime.Hub + daemonws.Hub]
E --> F{REDIS_URL set?}
F -- no --> G[Use in-memory hub single-node mode]
F -- yes --> H[Create Redis clients]
H --> I{REALTIME_RELAY_MODE}
I --> I1[legacy relay]
I --> I2[sharded relay]
I --> I3[dual mirrored relay]
G --> J[register realtime listener]
I1 --> J
I2 --> J
I3 --> J
J --> K[Create analytics, queries, authorizer]
K --> L[Register subscriber/activity/notification listeners]
L --> M[Build metrics registry optional]
M --> N[Create heartbeat scheduler]
N --> O[NewRouterWithOptions]
O --> P[Create TaskService and AutopilotService]
P --> Q[Register autopilot listeners]
Q --> R[Start sweepers, scheduler, channel supervisor]
R --> S[Start HTTP server]
S --> T[Wait SIGINT/SIGTERM]
T --> U[Graceful shutdown HTTP, workers, metrics, relay]
5. HTTP 请求处理时序图
sequenceDiagram
participant UI as Web/Desktop UI
participant Core as packages/core ApiClient
participant Router as Chi Router
participant MW as Auth + Workspace middleware
participant H as Handler
participant S as Service/sqlc
participant DB as PostgreSQL
participant Bus as events.Bus
participant WS as realtime.Hub
UI->>Core: call query/mutation hook
Core->>Router: HTTP request with auth, CSRF, workspace slug, request id
Router->>MW: global + auth + workspace middleware
MW->>H: request with X-User-ID and workspace context
H->>S: validate input, call service or Queries
S->>DB: read/write via sqlc
DB-->>S: rows/results
S-->>H: domain result
H->>Bus: Publish domain event
Bus->>WS: registerListeners broadcasts event
WS-->>UI: WebSocket frame
H-->>Core: JSON response
Core-->>UI: parsed data or ApiError
6. Issue 更新后的事件副作用
flowchart LR
Update[Update issue handler/service] --> DB[(Update DB)]
Update --> Publish[Bus.Publish issue:updated]
Publish --> Sub[registerSubscriberListeners]
Sub --> SubDB[(issue_subscriber)]
Sub --> SubEvent[subscriber:added]
Publish --> Act[registerActivityListeners]
Act --> ActDB[(activity_log)]
Act --> ActEvent[activity:created]
Publish --> Notif[registerNotificationListeners]
Notif --> InboxDB[(inbox_item)]
Notif --> InboxEvent[inbox:new / inbox:batch-*]
Publish --> AP[registerAutopilotListeners]
AP --> APDB[(autopilot_run sync if needed)]
Publish --> RT[registerListeners]
SubEvent --> RT
ActEvent --> RT
InboxEvent --> RT
RT --> WS[Workspace/user WebSocket delivery]
WS --> FE[useRealtimeSync<br/>patch/invalidate Query cache]
7. Realtime 架构图
flowchart TB
Producer[Handler / Service] --> Bus[events.Bus]
Bus --> Listener[registerListeners]
Listener --> Broadcaster{Broadcaster}
Broadcaster -- no Redis --> Hub[realtime.Hub]
Broadcaster -- Redis enabled --> Dual[DualWriteBroadcaster]
Dual --> Hub
Dual --> Relay[Redis relay]
Relay --> Streams[(Redis streams)]
Streams --> RelayReaders[Other API node relay readers]
RelayReaders --> Hub2[Other node realtime.Hub]
Hub --> WS1[Client WS connections]
Hub2 --> WS2[Client WS connections]
WS1 --> Core1[WSClient]
WS2 --> Core2[WSClient]
Core1 --> Sync1[useRealtimeSync]
Core2 --> Sync2[useRealtimeSync]
Sync1 --> Cache1[React Query cache]
Sync2 --> Cache2[React Query cache]
8. Agent 任务执行时序图
sequenceDiagram
participant User as User/UI/Autopilot/Channel
participant API as Go API
participant TaskSvc as TaskService
participant DB as PostgreSQL
participant Wake as daemonws/Redis wakeup
participant D as Local daemon
participant Agent as Agent CLI backend
participant WS as WebSocket clients
User->>API: Create/update issue, comment @agent, chat, or autopilot trigger
API->>TaskSvc: Enqueue task
TaskSvc->>DB: INSERT agent_task_queue status=queued
TaskSvc->>WS: Publish task:queued
TaskSvc->>Wake: NotifyTaskAvailable(runtime_id, task_id)
Wake-->>D: wake runtime poller
D->>API: POST /api/daemon/runtimes/{runtimeId}/tasks/claim
API->>DB: ClaimAgentTask -> dispatched
API-->>D: task payload + context
D->>API: POST /api/daemon/tasks/{taskId}/start
API->>TaskSvc: StartTask -> running
TaskSvc-->>WS: task:running
D->>Agent: Execute(prompt, ExecOptions)
loop streaming
Agent-->>D: message/progress/status/usage
D->>API: ReportTaskMessages / ReportProgress / ReportUsage
API-->>WS: task/chat/message events
end
Agent-->>D: final Result
alt success
D->>API: POST /complete
API->>TaskSvc: CompleteTask
TaskSvc->>DB: status=completed
TaskSvc-->>WS: task:completed
else failure
D->>API: POST /fail
API->>TaskSvc: FailTask
TaskSvc->>DB: status=failed
TaskSvc-->>WS: task:failed
end
9. Frontend Boot 和数据流
flowchart TD
subgraph Web
WRoot[apps/web/app/layout.tsx]
WProviders[WebProviders]
WWorkspace[workspaceSlug layout]
end
subgraph Desktop
DApp[renderer App.tsx]
DesktopCore[CoreProvider]
DRoutes[routes.tsx memory routers]
DDaemon[daemon IPC bridge]
end
subgraph Core
CoreProvider[packages/core CoreProvider]
APIClient[ApiClient singleton]
Auth[Auth store]
Query[QueryProvider / React Query]
WSProvider[WSProvider]
Realtime[useRealtimeSync]
WorkspaceStore[workspace-storage singleton]
end
WRoot --> WProviders --> CoreProvider
WWorkspace --> WorkspaceStore
DApp --> DesktopCore --> CoreProvider
DApp --> DRoutes
DApp --> DDaemon
CoreProvider --> APIClient
CoreProvider --> Auth
CoreProvider --> Query
CoreProvider --> WSProvider
WSProvider --> Realtime
APIClient --> Backend[Go API]
Realtime --> Query
10. Web 与 Desktop 页面复用图
flowchart LR
WebRoute[apps/web page.tsx] --> SharedPage[packages/views/<domain> page]
DesktopRoute[apps/desktop routes.tsx] --> SharedPage
SharedPage --> CoreHooks[packages/core queries/mutations]
SharedPage --> UIComponents[packages/ui components]
CoreHooks --> API[ApiClient]
API --> Backend[Go API]
WebRoute --> WebPlatform[apps/web/platform navigation]
DesktopRoute --> DesktopPlatform[apps/desktop renderer platform navigation]
SharedPage --> NavAdapter[NavigationAdapter]
NavAdapter --> WebPlatform
NavAdapter --> DesktopPlatform
11. 数据关系简图
erDiagram
USER ||--o{ MEMBER : joins
WORKSPACE ||--o{ MEMBER : has
WORKSPACE ||--o{ AGENT : owns
WORKSPACE ||--o{ ISSUE : owns
WORKSPACE ||--o{ PROJECT : owns
WORKSPACE ||--o{ SKILL : owns
WORKSPACE ||--o{ AGENT_RUNTIME : has
WORKSPACE ||--o{ INBOX_ITEM : has
WORKSPACE ||--o{ ACTIVITY_LOG : has
AGENT_RUNTIME ||--o{ AGENT : assigned_to
AGENT ||--o{ AGENT_TASK_QUEUE : runs
ISSUE ||--o{ AGENT_TASK_QUEUE : triggers
ISSUE ||--o{ COMMENT : has
ISSUE ||--o{ ACTIVITY_LOG : logs
ISSUE ||--o{ INBOX_ITEM : notifies
PROJECT ||--o{ ISSUE : groups
SKILL ||--o{ SKILL_FILE : contains
AGENT ||--o{ AGENT_SKILL : uses
SKILL ||--o{ AGENT_SKILL : assigned
CHAT_SESSION ||--o{ CHAT_MESSAGE : has
CHAT_SESSION ||--o{ AGENT_TASK_QUEUE : triggers
AUTOPILOT ||--o{ AUTOPILOT_TRIGGER : has
AUTOPILOT ||--o{ AUTOPILOT_RUN : creates
AUTOPILOT_RUN ||--o| ISSUE : creates
AUTOPILOT_RUN ||--o| AGENT_TASK_QUEUE : runs
SQUAD ||--o{ SQUAD_MEMBER : has
AGENT ||--o{ SQUAD : leads
12. API 分组图
flowchart TB
Root[Chi Router] --> Health[/health, /readyz, /healthz/]
Root --> WS[/ws/]
Root --> AuthPublic[/auth/*/]
Root --> PublicAPI[/api/config, contact-sales/]
Root --> Webhooks[/api/webhooks/*/]
Root --> Daemon[/api/daemon/*<br/>DaemonAuth/]
Root --> AuthGroup[Auth group]
AuthGroup --> UserAPI[/api/me, cli-token, upload-file, invitations, tokens/]
AuthGroup --> Workspaces[/api/workspaces/*/]
AuthGroup --> Billing[/api/cloud-billing/*<br/>human actor only/]
AuthGroup --> WorkspaceGroup[RequireWorkspaceMember]
WorkspaceGroup --> Issues[/api/issues/*/]
WorkspaceGroup --> Projects[/api/projects/*/]
WorkspaceGroup --> Agents[/api/agents/*/]
WorkspaceGroup --> Skills[/api/skills/*/]
WorkspaceGroup --> Runtimes[/api/runtimes/*/]
WorkspaceGroup --> Chat[/api/chat/*/]
WorkspaceGroup --> Inbox[/api/inbox/*/]
WorkspaceGroup --> Autopilots[/api/autopilots/*/]
WorkspaceGroup --> Squads[/api/squads/*/]
WorkspaceGroup --> Dashboard[/api/dashboard/*/]
13. 文档站产品心智模型
flowchart LR
subgraph Collaboration["协作层:Server"]
Workspace[Workspace<br/>工作区]
Issue[Issue<br/>工作项]
Comment[Comment<br/>评论/mention]
Project[Project<br/>项目/资源]
Agent[Agent<br/>智能体配置]
Task[Task Queue<br/>agent_task_queue]
Inbox[Inbox/Activity<br/>通知和时间线]
end
subgraph Execution["执行层:用户本机"]
Daemon[Multica daemon]
Runtime[Runtime<br/>daemon x provider x workspace]
Provider[Provider CLI<br/>Codex/Claude/Cursor/etc.]
Code[Code/API keys/local dirs<br/>留在本机]
end
Workspace --> Issue
Workspace --> Agent
Workspace --> Project
Issue --> Comment
Project --> Issue
Agent --> Task
Issue --> Task
Comment --> Task
Task --> Runtime
Runtime --> Daemon
Daemon --> Provider
Provider --> Code
Task --> Inbox
14. 四种智能体触发方式
flowchart TB
A[把 issue 分配给 agent/squad] --> A1{issue status = backlog?}
A1 -- yes --> A2[只保存 assignee<br/>暂不入队]
A1 -- no --> T[创建 task queued]
B[评论创建,包含 mention://agent 或 mention://squad] --> B1[保存 comment]
B1 --> B2[ParseMentions + 私有/归档/runtime/pending/self-loop 检查]
B2 --> T
C[Chat 发送消息] --> C1[保存 chat_message]
C1 --> C2[创建 chat task<br/>issue_id = null]
C2 --> T
D[Autopilot schedule/manual/webhook] --> D1{execution_mode}
D1 -- create_issue --> D2[创建 issue<br/>origin_type=autopilot]
D2 --> T
D1 -- run_only --> D3[直接创建 autopilot task]
D3 --> T
T --> Wake[发布 task:queued<br/>唤醒 daemon]
15. ACME-42 分配给 CodeSmith 的完整时序
sequenceDiagram
participant Chen as Chen<br/>chen@example.com
participant UI as Web/Desktop UI
participant API as Go API
participant IssueSvc as IssueService
participant TaskSvc as TaskService
participant DB as PostgreSQL
participant WS as WebSocket
participant D as macbook-pro-chen daemon
participant Codex as Codex CLI
Chen->>UI: 创建 ACME-42 并分配给 CodeSmith
UI->>API: POST /api/issues
API->>IssueSvc: Create(workspace=acme-ai, assignee=agt_codesmith)
IssueSvc->>DB: INSERT issue iss_42
IssueSvc->>WS: issue:created
IssueSvc->>TaskSvc: EnqueueTaskForIssue(iss_42)
TaskSvc->>DB: INSERT task_9001 status=queued runtime=rt_mac_01
TaskSvc->>WS: task:queued
TaskSvc-->>D: daemon wakeup
D->>API: claim task for rt_mac_01
API->>DB: task_9001 queued -> dispatched
D->>API: start task_9001
API->>TaskSvc: StartTask
TaskSvc->>DB: task_9001 dispatched -> running
TaskSvc->>WS: task:running
D->>Codex: Execute(prompt + project resources + skills)
Codex-->>D: messages/progress/usage
D->>API: report messages/progress/usage
API->>WS: task/chat/comment events
Codex-->>D: final result
D->>API: complete task_9001
API->>TaskSvc: CompleteTask
TaskSvc->>DB: task_9001 running -> completed
TaskSvc->>WS: task:completed
16. 评论 Mention 触发链路
flowchart TD
Editor[TipTap/RN editor] --> Markdown["[@CodeSmith](mention://agent/agt_codesmith) ..."]
Markdown --> API[POST /api/issues/iss_42/comments]
API --> Save[CreateComment<br/>保存 Markdown 原文]
Save --> Publish[comment:created]
Save --> Trigger[triggerTasksForComment]
Trigger --> Parse[util.ParseMentions]
Parse --> AgentMention{mention type}
AgentMention -- agent --> CheckA[检查 agent 可访问/未归档/有 runtime/无 pending]
AgentMention -- squad --> CheckS[解析 squad leader 并检查 readiness]
AgentMention -- member/issue/all --> NoTask[不创建 agent task]
CheckA --> Enqueue[EnqueueTaskForMention]
CheckS --> Leader[EnqueueTaskForSquadLeader]
Enqueue --> Task[task queued<br/>trigger_comment_id=cmt_501]
Leader --> Task
17. Chat 沙盒链路
sequenceDiagram
participant User as Chen
participant ChatUI as Chat UI
participant API as Handler.SendChatMessage
participant DB as PostgreSQL
participant TaskSvc as TaskService
participant D as Daemon
participant Agent as Provider CLI
User->>ChatUI: 发送私人消息
ChatUI->>API: POST /api/chat/sessions/chat_100/messages
API->>DB: INSERT chat_message(role=user)
API->>TaskSvc: EnqueueChatTask(chat_100)
TaskSvc->>DB: INSERT task(issue_id=null, chat_session_id=chat_100)
TaskSvc-->>D: wake runtime
D->>API: claim chat task
D->>Agent: prompt 只包含 chat 上下文和用户消息
Agent-->>D: assistant reply
D->>API: report/complete
API->>DB: INSERT chat_message(role=assistant)
18. Autopilot Schedule/Webhook 流程
flowchart TB
Schedule[DB scheduler<br/>cron due] --> Dispatch[AutopilotService.DispatchAutopilot]
Manual[POST /api/autopilots/{id}/trigger] --> Dispatch
Webhook[POST /api/webhooks/autopilots/awt_xxx] --> WH[限流/token/body/event filter/delivery]
WH --> Dispatch
Dispatch --> Run[INSERT autopilot_run]
Run --> Mode{execution_mode}
Mode -- create_issue --> Issue[CreateIssueWithOrigin<br/>origin_type=autopilot]
Issue --> Link[run.status=issue_created<br/>run.issue_id=...]
Link --> IssueTask[EnqueueTaskForIssue<br/>或 EnqueueTaskForSquadLeader]
Mode -- run_only --> DirectTask[CreateAutopilotTask<br/>run.task_id=...]
IssueTask --> Daemon[daemon claim and execute]
DirectTask --> Daemon
Daemon --> Sync[SyncRunFromIssue/SyncRunFromTask]
Sync --> Done[autopilot_run completed/failed/skipped]
19. Project Resource 进入执行环境
flowchart TD
Project[Project Web App] --> R1[github_repo<br/>https://github.com/acme/web-app]
Project --> R2[local_directory<br/>/Users/chen/code/web-app<br/>daemon=macbook-pro-chen]
Issue[ACME-42 belongs to Project] --> Claim[Daemon claims task]
Claim --> Match{local_directory matches daemon?}
Match -- yes --> Validate[daemon 校验路径存在/目录/读写/黑名单]
Validate --> Lock[按真实路径加目录锁]
Lock --> LocalWork[WorkDir = 用户本地目录]
Match -- no --> Worktree[WorkDir = 隔离 worktree/envRoot]
R1 --> Context[.multica/project/resources.json<br/>Project Context prompt]
R2 --> Context
LocalWork --> Context
Worktree --> Context
Context --> Agent[Provider CLI 执行]
20. 认证与 Token 使用范围
flowchart LR
Browser[Browser Web UI] --> Cookie[JWT Cookie<br/>multica_auth<br/>30 days]
CLI[CLI / scripts] --> PAT[PAT<br/>mul_...]
Daemon[Daemon] --> MDT[Daemon Token<br/>mdt_...]
Cookie --> UserAPI[/api/user + workspace APIs]
Cookie --> WS[/ws cookie auth]
PAT --> UserAPI
PAT --> DaemonAPI[/api/daemon bootstrap/control]
PAT --> WS2[/ws token auth]
MDT --> DaemonAPI
DaemonAPI --> Limited[注册 runtime<br/>心跳<br/>claim task<br/>上报结果]
UserAPI --> Full[代表完整用户身份]
21. GitHub PR 自动关联
sequenceDiagram
participant GH as GitHub
participant API as /api/webhooks/github
participant DB as PostgreSQL
participant Bus as events.Bus
participant UI as Issue UI
GH->>API: pull_request webhook<br/>branch/title/body contains ACME-42
API->>API: verify X-Hub-Signature-256
API->>DB: upsert github_pull_request
API->>API: extract issue key by workspace prefix
API->>DB: upsert issue_pull_request(iss_42, pr, close_intent?)
alt PR merged/closed and auto-close gate passes
API->>DB: update issue ACME-42 -> done unless cancelled
API->>Bus: issue:updated actor=system
Bus-->>UI: WebSocket update
else PR open/sync
API-->>UI: PR sidebar updates via realtime/cache refresh
end
22. 飞书/Lark Bot 到 Chat/Issue
flowchart TB
LarkMsg[飞书私聊或群 @ Bot] --> Inbound[Lark connector/channel engine]
Inbound --> Bind{飞书身份已绑定<br/>且是 workspace member?}
Bind -- no --> Drop[丢弃或返回绑定卡片<br/>不保存消息内容]
Bind -- yes --> Kind{消息类型}
Kind -- 普通消息 --> Chat[创建/复用 chat_session<br/>写 chat_message]
Chat --> ChatTask[EnqueueChatTask]
ChatTask --> AgentRun[daemon + provider 执行]
AgentRun --> Done[chat:done]
Done --> LarkReply[飞书卡片/文本回复]
Kind -- /issue --> Issue[IssueService.Create]
Issue --> Board[Multica issue 看板]
This post is licensed under CC BY 4.0 by the author.