From a3e639f8f598b6103a7e55155fde94adc2992763 Mon Sep 17 00:00:00 2001 From: Jiang Bohan Date: Thu, 5 Feb 2026 03:14:44 +0800 Subject: [PATCH] refactor(cli): make desktop app the default dev target - Change `multica dev` default from gateway+console+web to desktop app - Remove console from dev command options (use embedded Hub in desktop) - Update package.json scripts to reflect new defaults - Update README.md and CLAUDE.md architecture documentation The desktop app has an embedded Hub, so no separate console/gateway is needed for local development. Gateway is now optional, only needed for remote client access. Co-Authored-By: Claude Opus 4.5 --- CLAUDE.md | 29 +++++++++--------- README.md | 55 ++++++++++++++++++++--------------- package.json | 6 ++-- src/agent/cli/commands/dev.ts | 53 ++++++++++++--------------------- 4 files changed, 70 insertions(+), 73 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 32d8a9d7..267369b7 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,13 +4,13 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Project Overview -Super Multica is a distributed AI agent framework with a monorepo architecture. It includes an agent engine with multi-provider LLM support, a WebSocket gateway, a console hub for multi-agent coordination, and frontend apps (Next.js web, Electron desktop). +Super Multica is a distributed AI agent framework with a monorepo architecture. It includes an agent engine with multi-provider LLM support, an Electron desktop app with embedded Hub, a WebSocket gateway for remote access, and a Next.js web app. ## Monorepo Structure -- **`src/`** — Core modules (agent engine, gateway, console, client, shared types) +- **`src/`** — Core modules (agent engine, gateway, hub, shared types) +- **`apps/desktop`** — Electron + Vite + React desktop app (`@multica/desktop`) — **primary development target** - **`apps/web`** — Next.js 16 web app (`@multica/web`, port 3001) -- **`apps/desktop`** — Electron + Vite + React desktop app (`@multica/desktop`) - **`packages/ui`** — Shared UI component library (`@multica/ui`, Shadcn/Tailwind CSS v4) - **`packages/sdk`** — Gateway client SDK (`@multica/sdk`, Socket.io) - **`packages/store`** — Zustand state management (`@multica/store`) @@ -31,15 +31,14 @@ multica profile list # List profiles multica skills list # List skills multica tools list # List tools multica credentials init # Initialize credentials -multica dev # Start all dev services +multica dev # Start desktop app (default) multica help # Show help # Development servers -multica dev # All services (gateway:3000, console:4000, web:3001) -multica dev gateway # WebSocket gateway only -multica dev console # NestJS console with agent +multica dev # Desktop app (default, recommended) +multica dev gateway # WebSocket gateway only (for remote clients) multica dev web # Next.js web app -multica dev desktop # Electron desktop app +multica dev all # Gateway + web app # Build (turbo-orchestrated) pnpm build @@ -56,18 +55,22 @@ pnpm test:coverage # With v8 coverage ## Architecture ``` -Frontend (web:3001 / desktop) +Desktop App (standalone, recommended) + └─ Hub (embedded) + └─ Agent Engine (LLM runner, sessions, skills, tools) + └─ (Optional) Gateway connection for remote access + +Web App (requires Gateway) → @multica/sdk (GatewayClient, Socket.io) → Gateway (NestJS, WebSocket, port 3000) - → Console Hub (multi-agent coordination) - → Agent Engine (LLM runner, sessions, skills, tools) + → Hub + Agent Engine ``` **Agent Engine** (`src/agent/`): Orchestrates LLM interactions with multi-provider support (OpenAI, Anthropic, DeepSeek, Kimi, Groq, Mistral, Google, Together). Features session management (JSONL-based, UUIDv7 IDs), profile system (`~/.super-multica/agent-profiles/`), modular skills with hot-reload, and token-aware context window guards (compaction modes: tokens, count, summary). Unified CLI in `src/agent/cli/index.ts` with subcommands in `src/agent/cli/commands/`. -**Gateway** (`src/gateway/`): NestJS WebSocket server with Socket.io for real-time message passing, RPC request/response, and streaming. +**Hub** (`src/hub/`): Manages agents and communication channels. Embedded in desktop app, or runs standalone for web clients. -**Console** (`src/console/`): NestJS hub for multi-agent coordination with a web dashboard. +**Gateway** (`src/gateway/`): NestJS WebSocket server with Socket.io for remote client access, message routing, and device verification. ## Tech Stack & Config diff --git a/README.md b/README.md index 5aee5c5e..c6fd6d28 100644 --- a/README.md +++ b/README.md @@ -13,18 +13,18 @@ src/ │ ├── skills/ # Modular skill system │ └── tools/ # Agent tools │ └── web/ # Web fetch and search tools -├── gateway/ # WebSocket gateway for distributed communication -├── hub/ # Multi-agent coordination hub -├── client/ # Client library -├── console/ # NestJS console application -└── shared/ # Shared types and gateway SDK - └── gateway-sdk/ # Gateway client SDK +├── gateway/ # WebSocket gateway for remote access +├── hub/ # Agent coordination hub +└── shared/ # Shared types apps/ +├── desktop/ # Electron desktop app (recommended) └── web/ # Next.js web application packages/ -└── sdk/ # SDK package for external use +├── sdk/ # Gateway client SDK +├── store/ # Zustand state management +└── ui/ # Shared UI components skills/ # Bundled skills (commit, code-review) ``` @@ -85,9 +85,8 @@ Example `skills.env.json5` (dynamic keys): Start services directly (no `source .env`): ```bash -multica dev console -multica run "hello" -multica dev gateway +multica dev # Start desktop app +multica run "hello" # Run CLI mode ``` Optional overrides: @@ -194,10 +193,10 @@ multica chat --profile my-agent multica run --thinking high "solve this complex problem" # Development servers -multica dev # Start all services -multica dev gateway # Gateway only (:3000) -multica dev console # Console only (:4000) +multica dev # Start desktop app (default) +multica dev gateway # Gateway only (:3000) - for remote clients multica dev web # Web app only (:3001) +multica dev all # Start gateway + web # Help multica help @@ -383,23 +382,33 @@ web_search({ }) ``` -## Distributed Architecture +## Architecture + +### Desktop App (Recommended) + +The Electron desktop app runs a standalone Hub with embedded Agent Engine: + +- **No Gateway required** for local development +- Direct IPC communication for optimal performance +- QR code pairing for mobile remote access +- Optional Gateway connection for web/remote clients ### Gateway -The WebSocket gateway enables distributed multi-agent communication: +The WebSocket gateway enables remote client access: -- Real-time message passing between agents +- Real-time message routing between clients and Hub - Streaming support for long-running operations - RPC-style request/response patterns +- Device verification and authentication ### Hub -The Hub manages multiple agents and gateway connections: +The Hub manages agents and communication: - Agent lifecycle management -- Communication channel coordination -- Device identification and tracking +- Multi-subscriber event distribution +- Device whitelist and token-based verification ## Scripts @@ -418,11 +427,11 @@ The Hub manages multiple agents and gateway connections: ### Development (shortcuts) -- `pnpm dev` - Run full stack (gateway + console + web) -- `pnpm dev:gateway` - Run gateway only -- `pnpm dev:console` - Run console only -- `pnpm dev:web` - Run web app only +- `pnpm dev` - Run desktop app (default, recommended) - `pnpm dev:desktop` - Run desktop app +- `pnpm dev:gateway` - Run gateway only (for remote clients) +- `pnpm dev:web` - Run web app only +- `pnpm dev:all` - Run gateway + web ### Build & Test diff --git a/package.json b/package.json index 1396639c..38c7ec1a 100644 --- a/package.json +++ b/package.json @@ -12,10 +12,10 @@ "multica": "tsx src/agent/cli/index.ts", "mu": "tsx src/agent/cli/index.ts", "dev": "tsx src/agent/cli/index.ts dev", - "dev:gateway": "tsx src/agent/cli/index.ts dev gateway", - "dev:console": "tsx src/agent/cli/index.ts dev console", - "dev:web": "tsx src/agent/cli/index.ts dev web", "dev:desktop": "tsx src/agent/cli/index.ts dev desktop", + "dev:gateway": "tsx src/agent/cli/index.ts dev gateway", + "dev:web": "tsx src/agent/cli/index.ts dev web", + "dev:all": "tsx src/agent/cli/index.ts dev all", "build": "turbo build", "build:sdk": "pnpm --filter @multica/sdk build", "build:cli": "node scripts/build-cli.js", diff --git a/src/agent/cli/commands/dev.ts b/src/agent/cli/commands/dev.ts index 88d608ca..edd06cd6 100644 --- a/src/agent/cli/commands/dev.ts +++ b/src/agent/cli/commands/dev.ts @@ -2,44 +2,46 @@ * Dev command - Start development servers * * Usage: - * multica dev Start all services (gateway + console + web) - * multica dev gateway Start gateway only (:3000) - * multica dev console Start console only (:4000) + * multica dev Start desktop app (with embedded Hub) + * multica dev gateway Start gateway only (:3000) - for remote clients * multica dev web Start web app only (:3001) - * multica dev desktop Start desktop app + * multica dev all Start all services (gateway + web) */ import { spawn } from "node:child_process"; import { cyan, yellow, green, dim, red } from "../colors.js"; -type Service = "all" | "gateway" | "console" | "web" | "desktop" | "help"; +type Service = "all" | "gateway" | "web" | "desktop" | "help"; function printHelp() { console.log(` ${cyan("Usage:")} multica dev [service] ${cyan("Services:")} - ${yellow("(default)")} Start all services (gateway + console + web) - ${yellow("gateway")} Start Gateway server (:3000) - ${yellow("console")} Start Console server (:4000) + ${yellow("(default)")} Start Desktop app (with embedded Hub) + ${yellow("gateway")} Start Gateway server (:3000) - for remote clients ${yellow("web")} Start Web app (:3001) - ${yellow("desktop")} Start Desktop app + ${yellow("all")} Start all services (gateway + web) ${yellow("help")} Show this help ${cyan("Architecture:")} - Frontend (web:3001 / desktop) + Desktop App (standalone) + └─ Embedded Hub + Agent Engine + └─ (Optional) Gateway connection for remote access + + Web App (requires Gateway) → Gateway (WebSocket, :3000) - → Console Hub (multi-agent coordination, :4000) - → Agent Engine + → Hub + Agent Engine ${cyan("Examples:")} - ${dim("# Start all services")} + ${dim("# Start desktop app (recommended for local development)")} multica dev - ${dim("# Start only the gateway")} + ${dim("# Start desktop with remote Gateway for mobile access")} + GATEWAY_URL=http://localhost:3000 multica dev & multica dev gateway - ${dim("# Start web and gateway separately")} + ${dim("# Start web app with gateway")} multica dev gateway & multica dev web `); @@ -52,7 +54,7 @@ interface DevOptions { function parseArgs(argv: string[]): DevOptions { const args = [...argv]; - let service: Service = "all"; + let service: Service = "desktop"; let watch = true; while (args.length > 0) { @@ -68,7 +70,7 @@ function parseArgs(argv: string[]): DevOptions { } // Service name - if (["gateway", "console", "web", "desktop", "all", "help"].includes(arg)) { + if (["gateway", "web", "desktop", "all", "help"].includes(arg)) { service = arg as Service; } } @@ -105,14 +107,6 @@ async function startGateway(watch: boolean) { }); } -async function startConsole(watch: boolean) { - const watchFlag = watch ? "--watch" : ""; - return runCommand("tsx", [watchFlag, "src/console/main.ts"].filter(Boolean), { - name: "console", - color: "\x1b[33m", // yellow - }); -} - async function startWeb() { return runCommand("pnpm", ["--filter", "@multica/web", "dev"], { name: "web", @@ -130,20 +124,17 @@ async function startDesktop() { async function startAll(watch: boolean) { console.log(`\n${cyan("Starting all services...")}\n`); console.log(` ${"\x1b[34m"}Gateway${"\x1b[0m"} → http://localhost:3000`); - console.log(` ${"\x1b[33m"}Console${"\x1b[0m"} → http://localhost:4000`); console.log(` ${"\x1b[32m"}Web${"\x1b[0m"} → http://localhost:3001`); console.log(""); // Start all services const gateway = await startGateway(watch); - const console_ = await startConsole(watch); const web = await startWeb(); // Handle Ctrl+C const cleanup = () => { console.log(`\n${dim("Stopping all services...")}`); gateway.kill(); - console_.kill(); web.kill(); process.exit(0); }; @@ -154,7 +145,6 @@ async function startAll(watch: boolean) { // Wait for all to exit await Promise.all([ new Promise((resolve) => gateway.on("exit", resolve)), - new Promise((resolve) => console_.on("exit", resolve)), new Promise((resolve) => web.on("exit", resolve)), ]); } @@ -168,11 +158,6 @@ export async function devCommand(args: string[]): Promise { await startGateway(opts.watch); break; - case "console": - console.log(`\n${cyan("Starting Console...")} → http://localhost:4000\n`); - await startConsole(opts.watch); - break; - case "web": console.log(`\n${cyan("Starting Web App...")} → http://localhost:3001\n`); await startWeb();