Commit graph

86 commits

Author SHA1 Message Date
Jiayuan Zhang
d4f5c5b16f
feat: pivot to AI-native task management platform (#232)
Replace the agent framework codebase with a new monorepo structure
for an AI-native Linear-like product where agents are first-class citizens.

New architecture:
- server/ — Go backend (Chi + gorilla/websocket + sqlc)
  - API server with REST routes for issues, agents, inbox, workspaces
  - WebSocket hub for real-time updates
  - Local daemon entry point for agent runtime connection
  - PostgreSQL migration with 13 tables (issue, agent, inbox, etc.)
  - WebSocket protocol types for server<->daemon communication
- apps/web/ — Next.js 16 frontend
  - Dashboard layout with sidebar navigation
  - Route skeleton: inbox, issues, agents, board, settings
- packages/ui/ — Preserved shadcn/ui design system (26+ components)
- packages/types/ — Full API contract types (Issue, Agent, Workspace, Inbox, Events)
- packages/sdk/ — REST ApiClient + WebSocket WSClient
- packages/store/ — Zustand stores (issue, agent, inbox, auth)
- packages/hooks/ — React hooks (useIssues, useAgents, useInbox, useRealtime)
- packages/utils/ — Shared utilities

Removed: apps/cli, apps/desktop, apps/mobile, apps/gateway,
packages/core, skills/, and all agent-framework code.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 17:55:49 +08:00
Naiyuan Qing
78543d7187 fix(web): remove API proxy, use direct backend requests
- Remove Next.js rewrites proxy configuration
- Use NEXT_PUBLIC_API_URL for direct API requests
- Fixes ECONNRESET errors from proxy failures

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-26 15:35:53 +08:00
Jiayuan Zhang
e622b8c6ba refactor(core-sdk): enforce conversation-only client protocol 2026-02-17 09:41:37 +08:00
Jiayuan Zhang
754e604a40 refactor(protocol): add conversationId compatibility across hub/client 2026-02-17 09:39:24 +08:00
Jiayuan Zhang
ecb0cd392e chore(docs): remove non-e2e documentation 2026-02-17 00:46:36 +08:00
yushen
276e9a5b25 fix(web): defer MULTICA_API_URL check to runtime in next.config
Move the env var read into the rewrites function so `next build`
succeeds without MULTICA_API_URL set (it is only needed at runtime).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 06:42:30 +08:00
yushen
4dba1cfdf0 refactor: unify API URL env var to MULTICA_API_URL
Replace scattered API_URL, MAIN_VITE_API_URL, and RENDERER_VITE_API_URL
with a single MULTICA_API_URL across all apps and packages.

- Desktop: use envPrefix to expose MULTICA_* to main process, rename
  RENDERER_VITE_API_URL → RENDERER_VITE_MULTICA_API_URL, remove
  MAIN_VITE_API_URL (now read directly via MULTICA_API_URL)
- Web: add .env.development with MULTICA_API_URL, enforce required check
  in next.config.ts, update .gitignore to allow .env.development
- Core: make MULTICA_API_URL required in api-client (no silent fallback)
- Scripts: pass MULTICA_API_URL in dev-local.sh for web process
- Turbo: update globalEnv from API_URL to MULTICA_API_URL
- Docs: update references to the new env var name

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 06:31:00 +08:00
Jiang Bohan
a86709a4cd chore: switch API host from api-dev.copilothub.ai to api.multica.ai
Update all backend API base URLs to use the production multica.ai domain.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 23:25:00 +08:00
Naiyuan Qing
4b6f42cc21
Merge pull request #169 from multica-ai/fix/google-oauth-client-id
fix(web): update Google OAuth Client ID
2026-02-13 18:39:05 +08:00
Naiyuan Qing
7b581b4e39 fix(web): update Google OAuth Client ID
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-13 18:38:12 +08:00
Naiyuan Qing
242be23876 feat(utils): unify encrypted Device ID across all platforms
- Add common generateEncryptedId() utility in @multica/utils
- All Device IDs now use same encryption algorithm (40 hex chars)
- Web: store encrypted format directly in localStorage
- Desktop: use shared utility, accept encrypted ID from Web
- Hub: use shared utility for hub-id generation
- Telegram: use shared utility for device ID generation
- Gateway hook: use encrypted format for client connections

Algorithm: sha256(sha256(uuid).slice(0,32)).slice(0,8) + sha256(uuid).slice(0,32)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-13 17:34:23 +08:00
Naiyuan Qing
003bde460d fix(web): remove auth guard from home page
Home page (QR code scanning) does not require authentication.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-13 16:53:22 +08:00
Naiyuan Qing
f13509e12a feat(auth): pass encrypted Device ID from Web to Desktop
- Web stores raw UUID, encrypts when transmitting (consistent with copilot-search)
- Desktop receives encrypted Device ID from Web login callback
- Desktop stores encrypted 40-char format in auth.json
- Update IPC types to include deviceId in auth callback

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-13 16:53:13 +08:00
Naiyuan Qing
f0c9c43678 feat(web): add desktop callback API route
Server-side redirect to deep link for production builds.
More reliable than client-side window.location.href.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-13 15:37:08 +08:00
Naiyuan Qing
a2cabb550f refactor(ui): unify login page styling across web and desktop
- Use bordered icon with consistent size on both platforms
- Adjust font size to match icon proportions
- Simplify desktop tagline for cleaner presentation
- Streamline web login header to [icon] Sign In format

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-13 14:56:16 +08:00
Naiyuan Qing
09562776d4 fix(web): avoid setState in useEffect in AuthGuard 2026-02-13 14:43:52 +08:00
Naiyuan Qing
ae86bba599 feat(web): add client-side auth with session storage and route protection
- Add lib/auth.ts for cookie-based session storage
- Add AuthGuard component for route protection
- Update request.ts to include sid in Authorization header
- Update login-form.tsx to save session and redirect if authenticated
- Wrap ChatPage with AuthGuard

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-13 14:31:02 +08:00
Naiyuan Qing
683182e3ac fix(web): fix login page prerender error
Split login page into Server Component + Client Form to properly
handle useSearchParams with force-dynamic rendering.

Reference: CAP project pattern

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-13 14:25:38 +08:00
Naiyuan Qing
31c8b1babc refactor(web): replace devd proxy with Next.js rewrites
- Add rewrites in next.config.ts to proxy /api/* to api-dev.copilothub.ai
- Update docs to reflect new local dev workflow (no devd needed)
- Fix web port number in CLAUDE.md (3001 → 3000)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-13 13:25:08 +08:00
Naiyuan Qing
108cf7ffb0 feat(web): add login page for desktop auth callback
- Add email/code login with verification
- Add Google OAuth login
- Add desktop callback API route
- Add request service with device ID handling

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-13 12:25:03 +08:00
Naiyuan Qing
bc9b7d6fc5 refactor(desktop): restructure pages and consolidate UI components
- Rename channels.tsx to clients.tsx
- Remove standalone skills.tsx and tools.tsx pages
- Add agent/ directory for agent-related pages
- Update layout and navigation structure
- Add tabs component to ui package
- Update fonts and global styles

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-12 15:49:52 +08:00
Naiyuan Qing
6037be2efa refactor: migrate from Hugeicons to Lucide icons
- Replace @hugeicons/react with lucide-react across all packages
- Update all components to use Lucide icon components
- Add silent option to store refresh methods to control toast display
- Simplify icon usage with direct component imports

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-12 10:12:56 +08:00
Naiyuan Qing
54d84abc8b feat(ui): unify font loading and add design system documentation
Font unification:
- Add @fontsource packages for Geist Sans, Geist Mono, Playfair Display
- Create fonts.ts for centralized font imports
- Import fonts in both web (layout.tsx) and desktop (main.tsx)
- Register --font-brand in Tailwind @theme inline block
- Fix font-brand class usage (replace arbitrary value syntax)

Design system documentation:
- Add comprehensive design philosophy comments to globals.css
- Document typography choices (why Geist, why Playfair for brand)
- Document color system approach (neutral grays, semantic colors only)
- Explain component library customizations

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-11 14:50:19 +08:00
Naiyuan Qing
6ef58a0cab refactor: restructure to monorepo architecture
- Move core agent engine to packages/core/
- Add packages/types/ for shared TypeScript types
- Add packages/utils/ for utility functions
- Add apps/cli/ for command-line interface
- Add apps/gateway/ for NestJS WebSocket gateway
- Add apps/server/ for REST API server
- Restructure desktop app (electron/ → src/main/, src/preload/)
- Update pnpm workspace configuration
- Remove legacy src/ directory

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-10 18:00:23 +08:00
Naiyuan Qing
9bcb0993b1 Merge remote-tracking branch 'origin/main' into exec-approvals
# Conflicts:
#	apps/desktop/src/hooks/use-local-chat.ts
2026-02-05 17:54:19 +08:00
Naiyuan Qing
bece8f0545 refactor(web): adapt chat page for extracted shared hooks
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 17:51:12 +08:00
Naiyuan Qing
53c350ea33 refactor(ui,hooks): extract shared ChatView and DevicePairing to packages
- Extract ChatView from web chat-page into packages/ui as a prop-driven
  component (accepts UseChatReturn shape, no transport dependency)
- Move DevicePairing from apps/web to packages/ui with locally defined
  ConnectionIdentity type (no @multica/hooks dependency)
- Create @multica/hooks package with useGatewayConnection and useChat
  (moved from apps/web/hooks)
- Add isLoadingHistory state to useChat with skeleton loading in ChatView
- Add MulticaIcon (pure CSS asterisk via clip-path, adapts to theme)
- Slim web chat-page.tsx from 188 to 65 lines (just wires hooks to UI)

Desktop can now reuse ChatView and DevicePairing directly.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 15:28:44 +08:00
Naiyuan Qing
f5c6f05295 fix(web): replace PWA icons with full-bleed versions to fix iOS white border
The original icon PNGs had pre-baked rounded corners and transparent
backgrounds. When iOS applies its own superellipse mask on Add to Home
Screen, the transparent corners were filled with white, creating a
visible white border around the icon.

Changes:
- Regenerate all icon PNGs as full-bleed (no rounded corners, opaque
  background filling entire canvas) from the existing logo SVG
- Add dedicated apple-touch-icon.png at 180x180 (iOS standard size)
- Add favicon.ico for universal browser fallback
- Replace oversized app/icon.png (540x540) with 192x192 full-bleed
- Update layout.tsx to reference apple-touch-icon.png
- Add explicit purpose: "any" to 192x192 manifest entry

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 14:46:30 +08:00
Naiyuan Qing
7cb9788bed feat(web): add ChatPage with DevicePairing and ChatView
New page architecture: ChatPage composes useGatewayConnection + DevicePairing
(QR scan/paste with connection status) + ChatView (messages, error banner,
input). Decoupled from Zustand stores, fully props-driven.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 14:43:59 +08:00
Naiyuan Qing
178d71524f feat(web): add useGatewayConnection and useChat hooks
Replace Zustand global stores with hook-local state for the web app.
useGatewayConnection handles client lifecycle, identity persistence,
reconnection, and keyed reset. useChat handles message history, streaming
events, tool execution, Hub error action, and exec approval requests.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 14:43:53 +08:00
Naiyuan Qing
22c957ee76 chore(web): enable experimental HTTPS and fix scanner active states
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 10:44:29 +08:00
Naiyuan Qing
21efbf943a chore(web): update PWA logo assets
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 09:23:41 +08:00
Naiyuan Qing
39f2683b35 chore(web): gitignore self-signed HTTPS certificates
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 15:41:17 +08:00
Naiyuan Qing
986b08be48 chore(web): replace old icons with company logo
- Add logo.svg as the new brand logo
- Generate logo-192x192.png and logo-512x512.png from SVG for PWA
- Update app-header, manifest, and layout to reference new logo files
- Remove old icon.png, icon-192x192.png, icon-512x512.png

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 10:20:02 +08:00
Naiyuan Qing
972c887b43 refactor(apps): simplify layout components to pure navigation shells
- desktop layout.tsx: remove connection logic, keep header + tabs + outlet
- web app-header.tsx: remove connection logic, keep logo + theme toggle

Connection lifecycle is now owned by the shared Chat component.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 10:12:57 +08:00
Naiyuan Qing
dacbfa9e3d refactor(ui): purify Chat component and move header to app layouts
- Remove all props from Chat (showHeader, headerActions) making it a
  zero-config pure chat component with only connection input, messages,
  and send functionality
- Create AppHeader client component for web app with brand, theme
  toggle, disconnect button, and useHubInit
- Add disconnect button to desktop layout header
- Add reset() action to hub store to eliminate duplicated state reset
- Remove unused token field from gateway store
- Remove dead code: connection-bar.tsx
- Guard handleConnect against empty deviceId race condition

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 20:31:24 +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
Naiyuan Qing
6add5fc9c3 refactor(ui): remove sidebar, integrate connection flow into Chat
- Remove ConnectionBar sidebar from layout
- Chat component now handles connection code input inline (centered)
- Header: Multica branding left, Disconnect button right (when connected)
- Chat input disabled until connected

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 19:01:48 +08:00
Naiyuan Qing
e7521b4cb0 feat(web): replace sidebar with connection code flow
- Add connection code parsing (JSON + base64) with localStorage persistence
- Add connectWithCode() to gateway store for code-driven connections
- Replace Sidebar with simple ConnectionBar (paste code / status / disconnect)
- Simplify Chat component by removing header clutter
- Auto-restore connection on page refresh from saved code

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 18:53:49 +08:00
Naiyuan Qing
2d83c91ea1 fix(web): split maskable icon into separate entries for type safety
Next.js MetadataRoute.Manifest types only accept single-value purpose
fields, not space-separated combinations like "any maskable".

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 14:49:28 +08:00
Naiyuan Qing
ba1a90cd8d feat(web): add PWA support for installability and offline fallback
Enable the web app to be installed as a standalone PWA on mobile and
desktop. Uses Next.js built-in Metadata API for manifest generation,
a lightweight service worker for navigation offline fallback, and
proper Apple Web App metadata for iOS support.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 14:43:58 +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
150c87a496 refactor(frontend): replace HTTP API with pure WebSocket RPC
- gateway store: add hubId state and request() RPC method
- hub store: replace consoleApi calls with gateway.request() RPC
- hub-init: simplify to react on gwState === "registered"
- hub-sidebar: add hub-id input + connect/disconnect flow
- chat: use gateway hubId for message routing
- layout: remove consoleUrl config (no longer needed)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 15:27:07 +08:00
Naiyuan Qing
3548c91488 docs(web): add development guidelines README
Document thin-shell architecture, package responsibilities, Zustand
best practices, import conventions, and new feature checklist.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 11:52:47 +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
97fce5b113 refactor(store): migrate messages hook to Zustand store
- Move useMessages from apps/web to packages/store/src/messages.ts
- Convert useState to Zustand store for global message persistence
- Add reserved interfaces: updateMessage, loadMessages, getMessagesByAgent
- Update chat.tsx imports to use @multica/store

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 10:49:52 +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
Naiyuan Qing
86a8c91c9b fix(web): remove max-width constraint on assistant messages
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 23:52:11 +08:00