Commit graph

43 commits

Author SHA1 Message Date
Naiyuan Qing
ef4e57ffdd refactor(sdk): unify message types with pi-ai source of truth
Replace hand-written message/content types in @multica/sdk with
`import type` from @mariozechner/pi-ai and @mariozechner/pi-agent-core.
This ensures compile-time correctness and eliminates type drift between
backend and frontend (e.g. "tool_use" vs "toolCall", "tool_result" vs
"toolResult").

- stream.ts: re-export TextContent, ThinkingContent, ToolCall,
  ImageContent from pi-ai; use AgentEvent from pi-agent-core
- rpc.ts: AgentMessageItem = pi-ai Message (no more manual mirroring)
- connection-store.ts: use SDK types instead of inline hand-written ones
- ContentBlock now includes ImageContent to match backend reality

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 17:13:01 +08:00
Naiyuan Qing
2f5dbcdde9 feat(ui): add QR code scanner to ConnectPrompt
Add browser-based QR scanning as an alternative to paste mode in the
ConnectPrompt component. Mobile users can scan the Desktop QR code
directly instead of manually copying connection codes.

- Add qr-scanner dependency (WebWorker-based decoding, BarcodeDetector support)
- Create use-qr-scanner hook wrapping camera lifecycle and cleanup
- Create QrScannerView component with viewfinder overlay
- ConnectPrompt auto-detects mobile (touch + narrow viewport) and defaults to scan mode
- Lazy-load scanner component for zero initial bundle impact
- Graceful fallback to paste mode on permission denial or no camera

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 15:41:12 +08:00
Naiyuan Qing
24b75d3398 chore: update lockfile after removing sonner from store
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 10:21:38 +08:00
Naiyuan Qing
ff80cf0732 feat(desktop): integrate Chat component into desktop app
Add @multica/store and zustand to desktop dependencies. Replace
placeholder chat page with the shared Chat component. Add Toaster
for toast notifications and remove padding on the chat route.
Change Chat root from h-dvh to h-full for container adaptability.
Add showHeader prop to Chat; desktop passes showHeader={false}
since it has its own layout header.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 20:08:30 +08:00
Naiyuan Qing
a088875118 refactor(ui): move theme toggle from Chat to web app layout
Chat component no longer depends on next-themes, making it safe to use
in the desktop app. Theme toggle is now a fixed button in the web layout.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 20:02:48 +08:00
Jiang Bohan
dafbf856ac merge: resolve conflicts with main branch
- Merge auth-profiles feature from main into runner.ts
- Merge closeCallbacks feature from main into async-agent.ts
- Regenerate pnpm-lock.yaml with new dependencies

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 18:57:05 +08:00
Jiang Bohan
70cee08317 chore(desktop): add dependencies for routing and QR code
- Add react-router-dom for client-side routing
- Add qrcode.react for QR code generation
- Update vite.config.ts with path aliases

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 18:25:52 +08:00
yushen
617ddfbfea refactor(auth-profiles): replace proper-lockfile with custom file lock
Unify locking strategy across the project by using a custom synchronous
file lock (exclusive-create based, with PID stale detection) instead of
the proper-lockfile dependency, matching the pattern in session-write-lock.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 18:05:00 +08:00
yushen
4b10420324 Merge remote-tracking branch 'origin/main' into auth-profile-rotation
# Conflicts:
#	pnpm-lock.yaml
#	src/agent/runner.ts
2026-02-03 17:58:50 +08:00
yushen
a8c5042554 fix(auth-profiles): add file locking, type priority sort, credential filtering
- Add proper-lockfile for concurrent-safe store updates with fallback
- Add "format" to AuthProfileFailureReason
- Two-level round-robin sort: credential type priority (OAuth > API key), then lastUsed
- Filter out profiles with missing/invalid credentials from candidates
- Add preferredProfile option to resolveAuthProfileOrder
- Export coerceStore and ensureAuthStoreFile for testing
- Add store.test.ts with coerceStore, load/save round-trip, corruption handling
- Update order.test.ts mocks for resolver and registry dependencies

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 17:26:09 +08:00
Naiyuan Qing
01c82b296d feat(mobile): 移动端初始化
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 16:39:53 +08:00
Naiyuan Qing
a8143735e9 feat(desktop): initialize electron app with routing and cleanup
Remove template boilerplate (sample SVGs, test IPC message, comments),
add react-router-dom v7 with createHashRouter, scaffold home and chat
pages using @multica/ui components, and add READMEs for desktop, ui,
and store packages documenting import conventions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 14:17:31 +08:00
Naiyuan Qing
a62ac2e075 chore: remove @multica/fetch package
No consumers remain after migrating to pure WebSocket RPC.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:29:27 +08:00
Naiyuan Qing
e491949749 refactor(store): remove @multica/fetch dependency
- Move gatewayUrl into gateway store state with setGatewayUrl action
- layout.tsx uses useGatewayStore.getState().setGatewayUrl() directly
- Remove @multica/fetch from store and web package.json dependencies

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:23:06 +08:00
Naiyuan Qing
3d7b13555f refactor(sdk): unify gateway-sdk into @multica/sdk package
Sync latest code from src/shared/gateway-sdk/ into packages/sdk/,
update all backend imports to use @multica/sdk, and remove the
duplicate src/shared/gateway-sdk/ directory.

- Translate Chinese comments to English in SDK source
- Fix package.json exports with default condition
- Add @multica/sdk as workspace dependency for backend
- Update imports in gateway, test-client, and hub

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 13:43:52 +08:00
Naiyuan Qing
4a7a9800f2 fix(frontend): apply code review fixes across store and UI
- Move setConfig() after imports in layout.tsx
- Add gateway disconnect cleanup in hub-init useEffect
- Replace silent catches with toast error notifications in hub store
- Optimize chat selectors with useMemo and useCallback/getState()
- Remove unused getMessagesByAgent from messages store
- Add clipboard try/catch with error toast
- Add skeleton loading states for hub sidebar and chat header

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 11:52:42 +08:00
Naiyuan Qing
eef26d8675 refactor(frontend): complete migration of all hooks and components to packages
- Create gateway store in @multica/store (WS connection independent of components)
- Gateway auto-connects when hub is ready, messages handled internally
- Move scroll-fade hook to @multica/ui/hooks
- Move Chat component to @multica/ui/components
- Add setConfig() call in web layout for URL injection
- Delete all web-local hooks, components, and lib/config
- Web app is now a pure shell: layout.tsx + page.tsx

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 11:07:57 +08:00
Naiyuan Qing
5275bc55fc refactor(store): migrate device-id hook to @multica/store
- Move useDeviceId from apps/web to packages/store/src/device-id.ts
- Update imports in chat.tsx and use-gateway.ts to use @multica/store
- Add uuid dependency to @multica/store

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 10:45:20 +08:00
Naiyuan Qing
63861d03c6 refactor(frontend): extract shared stores and components into packages
- Create @multica/fetch package for HTTP client and URL config
- Migrate hub store and hub-init hook to @multica/store
- Move HubSidebar component to @multica/ui for web/desktop reuse
- Update web app imports to use shared packages
- Remove counter store example and its component-example usage

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 10:37:17 +08:00
Jiayuan
3ee8946e29 feat(credentials): add JSON5 credential system 2026-02-01 02:28:27 +08:00
Naiyuan Qing
3ef7d5351c feat(web): add @multica/sdk dependency and URL config module
Adds gateway and console URL configuration in app/lib/config.ts,
centralizing endpoint URLs with env var overrides.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:40:43 +08:00
Naiyuan Qing
5f367fb6b7 fix(web): replace Zustand device store with local useDeviceId hook
Move device ID logic from @multica/store (Zustand persist) into a
simple useDeviceId hook in the web app. SSR returns empty string,
client reads/writes localStorage directly — no hydration mismatch,
no suppressHydrationWarning needed.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:16:54 +08:00
Naiyuan Qing
7d326695c1 feat(web): add scroll fade hint effect to chat message list
Use CSS mask-image gradients to hint at scrollable overflow in the chat
area. Adds useScrollFade hook that dynamically applies top/bottom fade
based on scroll position via scroll events and ResizeObserver.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:14:19 +08:00
Naiyuan Qing
10dbacc693 chore: add concurrently to run all services with pnpm dev
`pnpm dev` now starts gateway (3000), console (4000) and web (3001)
in parallel with colored labels.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 21:31:53 +08:00
Naiyuan Qing
88d2e9340b feat(ui): add light/dark theme toggle in sidebar
Add next-themes integration with a ThemeProvider wrapper and a
ThemeToggle dropdown (Light / Dark / System) in the sidebar footer.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 21:21:31 +08:00
Naiyuan Qing
9b87cd789e feat(ui): add Markdown rendering components
Add CodeBlock, Markdown, StreamingMarkdown components with
Shiki syntax highlighting, GFM support, and linkify utility.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 20:40:27 +08:00
Jiayuan
7f25378e4b feat(cli): add binary build support for interactive CLI
Add esbuild-based build script to bundle CLI tools into standalone
binaries that can be run directly with node. The built binaries
externalize dependencies to keep bundle size small and avoid
bundling issues with native modules.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 15:22:53 +08:00
Jiayuan
7215a15e37 chore: set up Vitest testing framework
Add Vitest and @vitest/coverage-v8 for unit testing. Configure
test scripts and add coverage directory to gitignore.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 13:54:34 +08:00
Naiyuan Qing
d7d2861a79 feat(store): add shared Zustand store package with counter example
- Create packages/store with @multica/store package
- Add zustand to pnpm catalog for version consistency
- Add counter store as cross-platform state example
- Integrate counter into ComponentExample for verification
- Add tsconfig path mappings for web and desktop
- Add @multica/store to Next.js transpilePackages
- Add @multica/store dependency to packages/ui

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 11:34:09 +08:00
Naiyuan Qing
141af9e9f1 feat(desktop): integrate @multica/ui shared components
Add @multica/ui workspace dependency with @tailwindcss/vite plugin
for CSS processing. Import globals.css for theme and replace template
UI with shared Button component. Remove unused template CSS files.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 11:34:09 +08:00
Naiyuan Qing
6431829b0c chore: unify shared deps with pnpm catalogs
Add catalog section to pnpm-workspace.yaml for react, react-dom,
@types/react, @types/react-dom, @types/node, and typescript.
Update all package.json files to use catalog: protocol.
Upgrade desktop from React 18 to 19. Rename to @multica/desktop.
Add dev:desktop script to root.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 11:34:09 +08:00
Naiyuan Qing
ff026b122d feat(desktop): scaffold Electron app with Vite
Add initial Electron desktop app using vite-plugin-electron template
with React and TypeScript.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 11:34:09 +08:00
Naiyuan Qing
663a9ec2a7 chore: update lockfile for packages/ui dependencies
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 11:34:05 +08:00
Jiayuan
50ae997ab4
feat(agent): add skills system with profile integration (#21)
* chore(deps): add yaml package for skill parsing

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(agent): add skills system

Implement a skills system inspired by moltbot's approach:

- Skills are markdown files (SKILL.md) with YAML frontmatter
- Multi-source loading with precedence: bundled < user < workspace
- Eligibility filtering based on platform, binaries, and env vars
- Skills are automatically included in agent system prompt
- New AgentOptions: enableSkills, skillsBaseDir, extraSkillDirs

Includes two bundled skills:
- commit: Git commit helper with conventional commit guidelines
- code-review: Code review checklist and best practices

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(skills): use profile-based skills instead of workspace

Change skill loading from workspace-based (.skills/) to profile-based:
- Skills now load from ~/.super-multica/agent-profiles/<profileId>/skills/
- Remove workspace and user skill sources
- Simplify to only bundled and profile sources
- Profile skills have higher precedence than bundled

This is more appropriate for non-coding agents where skills are
associated with agent identity rather than working directory.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 05:21:57 +08:00
Jiayuan
9b3ffd1e90
feat(agent): add web_fetch and web_search tools (#20)
* chore(deps): add web tools dependencies

Add undici, @mozilla/readability, linkedom, and turndown for
web fetching and HTML content extraction capabilities.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(agent): add web_fetch and web_search tools

Port network tools from moltbot with the following features:

web_fetch:
- Fetch and extract readable content from URLs
- Dual extraction mode: readability (smart) or turndown (full page)
- SSRF protection (blocks private IPs, localhost)
- Response caching with TTL
- Redirect handling

web_search:
- Brave Search API for traditional results
- Perplexity API for AI-synthesized answers
- Region/language settings
- Freshness filtering (Brave only)
- Auto-detects provider from available API keys

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(agent): register web_fetch and web_search tools

Add web tools to the agent's tool registry.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 05:09:16 +08:00
Jiayuan
95e6ae439d
feat(agent): add glob tool for file pattern matching (#18)
Add a glob tool that allows agents to find files matching glob patterns.
Features:
- Supports standard glob patterns (e.g., **/*.ts, src/**/*.{js,jsx})
- Results sorted by modification time (most recent first)
- Configurable result limit and ignore patterns
- Default ignores for node_modules, .git, dist, etc.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 04:33:01 +08:00
Jiayuan
1097ef5144 feat(agent): add exec/process tools 2026-01-30 01:52:10 +08:00
Jiayuan
8c2b6563d2 feat(agent): add pi-agent core integration and test CLI 2026-01-30 01:04:39 +08:00
Naiyuan Qing
84fe9d99f5 Add monorepo setup with Turborepo and Web client
- Add pnpm workspace and Turborepo configuration
- Extract Gateway SDK to packages/sdk as independent package
- Add Next.js + shadcn Web client in apps/web
- Update root package.json with turbo scripts

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 16:33:35 +08:00
yushen
dcca9333ab Add Hub Console with agent management and message routing
Implement Hub that auto-connects to Gateway, manages agents via REST API,
and routes WebSocket messages to agents by payload.agentId with echo responses
sent back to the original sender.

- Add Hub with GatewayClient auto-connect, agent CRUD, and message routing
- Add Console (NestJS) with REST API and static pages (management + demo client)
- Switch Gateway registration from explicit event to query-based on connect
- Remove deprecated types (RegisterPayload, metadata, SendMessagePayload)
- Add @nestjs/serve-static for serving console UI

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 16:14:29 +08:00
yushen
2ea7938444 Add Docker support for Gateway and SDK documentation
- Add Dockerfile and build script for Gateway containerization
- Add USAGE.md documenting SDK usage for Client/Agent implementations
- Move socket.io-client to production dependencies (required by SDK)
- Remove redundant timestamp field from RoutedMessage (UUID v7 contains timestamp)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 17:56:22 +08:00
yushen
7d94b40a11 Implement WebSocket Gateway with NestJS and client SDK
- Add NestJS WebSocket Gateway with Socket.IO for real-time communication
- Create client SDK (GatewayClient) supporting both browser and Node.js
- Implement device registration and point-to-point message routing
- Add action types: request/response (RPC), stream (for chat messages)
- Integrate Pino logger for structured logging
- Configure heartbeat detection (pingInterval/pingTimeout)
- Use UUID v7 for time-ordered message IDs

Gateway features:
- Device registration with deviceId and deviceType (client/agent)
- Message routing between devices via Gateway
- HTTP API endpoints (/ping, /broadcast)
- Auto-reconnect support in client SDK

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 16:46:51 +08:00
yushen
6b34ddc3dc Initial project setup with multi-component architecture
- Initialize TypeScript project with pnpm
- Create agent, gateway, client, and shared modules
- Configure ESM with strict TypeScript settings

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 14:08:34 +08:00