diff --git a/CLAUDE.md b/CLAUDE.md index e39cc77b..2f070ef2 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,30 +2,18 @@ This file gives coding agents high-signal guidance for this repository. -## 1. Project Snapshot +## 1. Documentation Scope -Super Multica is a pnpm monorepo for a distributed AI agent system: +Documentation in this repo should prioritize: -- Agent engine + Hub: `packages/core` -- Desktop app (primary local runtime): `apps/desktop` -- CLI: `apps/cli` -- Remote access gateway: `apps/gateway` -- Web client: `apps/web` +1. Development workflow +2. Testing methods +3. Operational process -## 2. Monorepo Map +Project-intro and architecture explanations are intentionally minimized. +Treat source code as the architecture source of truth. -```text -apps/ - cli desktop gateway server web mobile - -packages/ - core sdk ui store hooks types utils - -skills/ - skill assets and runtime helper scripts -``` - -## 3. Core Commands +## 2. Core Workflow Commands ```bash pnpm install @@ -40,20 +28,13 @@ pnpm typecheck pnpm test ``` -## 4. Architecture Notes - -- Desktop app embeds Hub + Agent runtime. -- Gateway is optional for local desktop usage, required for remote/web-style access. -- Web app depends on gateway/API setup. -- Sessions are directory-based: `~/.super-multica/sessions//`. - -## 5. Data and Credentials +## 3. Data and Credentials Workflow - Default data dir: `~/.super-multica` (override with `SMC_DATA_DIR`) - Credentials: `~/.super-multica/credentials.json5` (override with `SMC_CREDENTIALS_PATH`) - Initialize credentials via `pnpm multica credentials init` -## 6. Coding Rules +## 4. Coding Rules - TypeScript strict mode is enabled; keep types explicit. - Keep comments in code **English only**. @@ -61,14 +42,14 @@ pnpm test - Avoid broad refactors unless required by the task. - Keep docs concise and aligned with current code behavior. -## 7. Testing Rules +## 5. Testing Rules - Test runner: Vitest. - Mock policy: mock external/third-party dependencies only. - Do not mock internal modules when real integration can be tested. - Prefer temp directories and real file I/O for storage-related tests. -## 8. Commit Rules +## 6. Commit Rules - Use atomic commits grouped by logical intent. - Conventional format: @@ -79,14 +60,14 @@ pnpm test - `test(scope): ...` - `chore(scope): ...` -## 9. Minimum Pre-Push Checks +## 7. Minimum Pre-Push Checks ```bash pnpm typecheck pnpm test ``` -## 10. E2E Docs +## 8. E2E Process Docs - `docs/e2e-testing-guide.md` - `docs/e2e-finance-benchmark.md` diff --git a/README.md b/README.md index 45f01ea4..bf98fbe5 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,15 @@ # Super Multica -Super Multica is a monorepo for a distributed AI agent framework. -It includes a local-first Desktop app, CLI, Gateway/Web access, and reusable core packages. +This repository keeps docs focused on: -## Current Documentation Strategy +1. Development workflow +2. Testing workflow +3. Operational process -The docs set is intentionally **small and high-signal**. -For current status and priorities, see: +Architecture and project-description details are intentionally omitted from docs. +Use source code as the architecture reference. -- `docs/README.md` - -## Monorepo Layout - -```text -apps/ - cli/ @multica/cli Command-line interface - desktop/ @multica/desktop Electron desktop app (primary local runtime) - gateway/ @multica/gateway NestJS WebSocket gateway - server/ @multica/server NestJS REST server - web/ @multica/web Next.js web app - mobile/ @multica/mobile React Native app - -packages/ - core/ @multica/core Agent, Hub, tools, channels, cron, heartbeat - sdk/ @multica/sdk Gateway client SDK - ui/ @multica/ui Shared React UI components - store/ @multica/store Zustand stores - hooks/ @multica/hooks Shared hooks - types/ @multica/types Shared types - utils/ @multica/utils Shared utilities -``` - -## Quick Start +## Quick Start (Workflow) ```bash pnpm install @@ -39,7 +17,7 @@ pnpm multica credentials init pnpm multica ``` -Run desktop app in dev mode: +Run local desktop workflow: ```bash pnpm dev @@ -78,7 +56,7 @@ Related: pnpm dev:local:archive ``` -## Common Commands +## Workflow Commands ```bash # CLI @@ -101,7 +79,27 @@ pnpm typecheck pnpm test ``` -## Runtime Data +## Testing Workflow + +```bash +# Unit/integration +pnpm test +pnpm test:watch +pnpm test:coverage + +# Type safety gate +pnpm typecheck + +# Agent E2E +pnpm multica run --run-log "your test prompt" +``` + +E2E process docs: + +- `docs/e2e-testing-guide.md` +- `docs/e2e-finance-benchmark.md` + +## Runtime Paths By default, runtime data is stored under: @@ -111,12 +109,13 @@ You can isolate environments with: - `SMC_DATA_DIR=~/.super-multica-dev` (or other path) -## Core Docs +## Process Docs -- `CLAUDE.md` (AI coding guidance in this repo) +- `CLAUDE.md` - `docs/development.md` - `docs/cli.md` - `docs/credentials.md` - `docs/skills-and-tools.md` +- `docs/package-management.md` - `docs/e2e-testing-guide.md` - `docs/e2e-finance-benchmark.md` diff --git a/docs/README.md b/docs/README.md index 6f2f74f7..df459a38 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,8 @@ # Documentation Index (Priority-Based) This repo keeps documentation intentionally small to reduce stale AI context. +Only workflow/testing/process documentation should be maintained. +Project-intro and architecture explanation docs are intentionally omitted. ## P0 (Keep Fresh) diff --git a/docs/architecture.drawio b/docs/architecture.drawio deleted file mode 100644 index 6c6f32bc..00000000 --- a/docs/architecture.drawio +++ /dev/null @@ -1,433 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/code-stats-report.html b/docs/code-stats-report.html deleted file mode 100644 index a05799da..00000000 --- a/docs/code-stats-report.html +++ /dev/null @@ -1,347 +0,0 @@ - - - - - - Super Multica 代码贡献统计 - - - -
-

Super Multica 代码贡献统计

-
- -
- -
-

代码量分布(按扩展名)

-
-
- -
-

人员贡献(人工口径)

-
-
- -
-

每日贡献(人工口径)

-
-
- -
-

小时段贡献(人工口径)

-
-
- -
数据来源:git log --numstat 与当前工作树文件统计。人工口径排除 checkpointer / dependabot。
-
- - - - diff --git a/docs/subagent-architecture.html b/docs/subagent-architecture.html deleted file mode 100644 index 6e12c449..00000000 --- a/docs/subagent-architecture.html +++ /dev/null @@ -1,884 +0,0 @@ - - - - - -Subagent Orchestration Architecture - - - -
- -

Subagent Orchestration Architecture

-

Super Multica — Parent-child agent spawning, lifecycle management, and result announcement

- - -

System Architecture

- - -
- - -
-
-
- Agent - Parent Agent (Interactive Session) -
-
- User-facing agent with full tool access. Can spawn child agents via sessions_spawn tool. - Receives announcement messages when child agents complete. -
-
src/agent/runner.ts → tools: sessions_spawn, exec, glob, web_fetch, ...
-
-
- - -
- - - - - - - - - - - - spawn - - - announce - -
- - -
-
-
- Singleton - Hub -
-
- Central coordinator. Creates & manages all agents. Provides createSubagent(), - getAgent(), closeAgent(). Calls registry init on startup, shutdown on exit. -
-
src/hub/hub.ts + hub-singleton.ts
-
- -
-
- Module - Subagent Registry -
-
- In-memory Map + JSON persistence. Tracks run lifecycle (created → started → ended). - Archive sweeper cleans old runs every 60s. Handles crash recovery on restart. -
-
src/agent/subagent/registry.ts
-
-
- - -
- - - - - - - - - - - createSubagent() - - watchChildAgent() - -
- - -
-
-
- Agent - Child AsyncAgent -
-
- Isolated agent with isSubagent: true. Restricted tools (no sessions_spawn). - Custom system prompt: stay focused, no user messaging, no nested spawning. -
-
src/agent/async-agent.ts
-
- -
-
- Flow - Announce Module -
-
- Reads child's last assistant reply from session JSONL. Formats announcement message with findings, duration, status. - Delivers to parent via parentAgent.write(). -
-
src/agent/subagent/announce.ts
-
- -
-
- Store - Registry Store -
-
- JSON file persistence at ~/.super-multica/subagents/runs.json. - Schema: { version: 1, runs: {...} }. Survives process restarts. -
-
src/agent/subagent/registry-store.ts
-
-
- -
- - -

Call Chain — Spawn & Lifecycle

- - -
- -
-
Parent Agent invokes sessions_spawn tool
-
- Agent calls tool with { task, label?, model?, cleanup?, timeoutSeconds? }. - Guard rejects if isSubagent === true. -
-
sessions-spawn.ts → execute()
-
- -
-
Generate IDs & build system prompt
-
- runId = UUIDv7, childSessionId = UUIDv7. - buildSubagentSystemPrompt() creates prompt with task context, rules (no nested spawn, stay focused). -
-
announce.ts → buildSubagentSystemPrompt()
-
- -
-
Hub creates child AsyncAgent
-
- hub.createSubagent(childSessionId, { systemPrompt, model }) - creates an AsyncAgent with isSubagent: true. Not persisted to agent store (ephemeral). -
-
hub.ts → createSubagent()
-
- -
-
Write task to child (non-blocking)
-
- childAgent.write(task) enqueues the task to the serial queue. - This happens before registration so waitForIdle() observes queued work. -
-
async-agent.ts → write() (enqueues to serial queue)
-
- -
-
Register run in registry
-
- registerSubagentRun() saves record to in-memory Map + JSON file. - Sets createdAt, starts archive sweeper. -
-
registry.ts → registerSubagentRun()
-
- -
-
Start lifecycle watcher & return to parent
-
- watchChildAgent() sets startedAt. - Attaches childAgent.waitForIdle() (promise resolves when task queue drained) - and childAgent.onClose() callback. Optionally sets timeout timer. - Tool returns { status: "accepted", childSessionId, runId } immediately. -
-
registry.ts → watchChildAgent() → AsyncAgent.waitForIdle() + onClose()
-
- -
-
Child agent processes task autonomously
-
- Child runs LLM inference with restricted tools. Uses its own session. - May call exec, glob, web_fetch etc. but NOT sessions_spawn. -
-
runner.ts → Agent.run() (within AsyncAgent queue)
-
- -
-
Child completes → waitForIdle() resolves
-
- Task queue drains. Watcher's cleanup callback fires: sets endedAt, outcome: { status: "ok" }. - Persists updated record to JSON. -
-
registry.ts → cleanup() → handleRunCompletion()
-
- -
-
Announce flow: read child reply & deliver to parent
-
- readLatestAssistantReply(childSessionId) reads session JSONL, extracts last assistant text. - formatAnnouncementMessage() builds summary with task, status, findings, runtime. - parentAgent.write(message) delivers to parent. -
-
announce.ts → runSubagentAnnounceFlow() → hub.getAgent(parentId).write()
-
- -
-
Session cleanup & archive
-
- If cleanup === "delete": removes child session directory + closes agent in Hub. - Schedules archive at now + 60min. Sweeper removes from registry after TTL. -
-
registry.ts → deleteChildSession() + sweep()
-
- -
- - -

Sequence Diagram

- - -
- - - - - - Parent Agent - - - sessions_spawn - - - Hub - - - Registry - - - Child Agent - - - - - - - - - - - execute({ task, label }) - - - - createSubagent(id, opts) - - - - new AsyncAgent({ isSubagent: true }) - - - - childAgent.write(task) - - - - registerSubagentRun(params) - - - - waitForIdle() + onClose() - - - - { status: "accepted", runId } - - - - - async (non-blocking) - - - - LLM - inference - - - - idle (resolved) - - - - announce - - - - parentAgent.write(announcement) - - - - deleteChildSession() - - - - archive 60m - - - - - - - - - - - - - - - - - - - - - - - -
- - -

Run State Machine

- - -
-
- - created -
-
- - - - - - - - - startedAt -
-
- - started -
-
- - - - - - - - - endedAt -
-
- - ended -
-
- - - - - - - - - announce -
-
- - cleanup done -
-
- - - - - - - - - 60 min -
-
- - archived -
-
- -
-
Outcome Status Values
-
- ok — Task completed normally (waitForIdle resolved) - error — Child agent threw an error - timeout — Exceeded timeoutSeconds limit - unknown — Process crash or Hub shutdown -
-
- - -

Module Map

- - -
-
-
src/agent/subagent/types.ts
-
Core type definitions
-
- export SubagentRunOutcome
- export SubagentRunRecord
- export RegisterSubagentRunParams
- export SubagentAnnounceParams
- export SubagentSystemPromptParams -
-
- -
-
src/agent/subagent/registry.ts
-
In-memory registry + lifecycle watcher
-
- export initSubagentRegistry()
- export registerSubagentRun()
- export listSubagentRuns()
- export releaseSubagentRun()
- export getSubagentRun()
- export shutdownSubagentRegistry() -
-
- -
-
src/agent/subagent/registry-store.ts
-
JSON file persistence
-
- export loadSubagentRuns()
- export saveSubagentRuns()
- export getSubagentStorePath() -
-
- -
-
src/agent/subagent/announce.ts
-
Result propagation child → parent
-
- export buildSubagentSystemPrompt()
- export readLatestAssistantReply()
- export formatAnnouncementMessage()
- export runSubagentAnnounceFlow() -
-
- -
-
src/agent/tools/sessions-spawn.ts
-
Tool definition for parent agents
-
- export createSessionsSpawnTool()
- schema: { task, label?, model?,
-   cleanup?, timeoutSeconds? } -
-
- -
-
src/hub/hub-singleton.ts
-
Global Hub access for tools & registry
-
- export setHub(hub)
- export getHub()
- export isHubInitialized() -
-
-
- - -

Key Design Decisions

- - -
-
-
waitForIdle() vs stream consumption
-
- Channel is single-reader. Hub.consumeAgent() already reads the stream for forwarding events. - Registry uses waitForIdle() (promise on internal task queue) to detect completion without competing for the stream. -
-
-
-
Singleton Hub access
-
- Tools and registry modules cannot receive Hub via constructor injection (tools are created before Hub exists). - A module-level singleton (setHub/getHub) bridges this gap, with isHubInitialized() guard for test safety. -
-
-
-
Crash recovery
-
- Runs are persisted to JSON after every state change. On restart, initSubagentRegistry() - loads persisted runs: completed-but-unannounced runs trigger announce flow; unfinished runs are marked as - status: "unknown". -
-
-
-
Subagent isolation
-
- Child agents have isSubagent: true which applies tool deny-list (blocks sessions_spawn). - System prompt explicitly forbids nested spawning, direct user communication, and off-topic work. - Sessions are ephemeral — deleted after announce unless cleanup: "keep". -
-
-
- -
- Super Multica — Subagent Orchestration System — Branch: subagent-orchestration -
- -
- -