Commit Graph

44 Commits

Author SHA1 Message Date
Naiyuan Qing
ec1589f7b6 fix(deps): add eslint phantom dep detection + fix existing violations (MUL-2654) (#3249)
* fix(deps): add eslint phantom dep detection + fix existing violations (MUL-2654)

Introduce eslint-plugin-import-x/no-extraneous-dependencies rule to
prevent phantom deps from causing production build splits when pnpm
creates peer-dep variants. Fix all existing phantom deps across the
monorepo, unify catalog references, and enable desktop smoke CI on PRs.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>

* revert(ci): remove desktop smoke PR trigger per user feedback

The existing smoke workflow only verifies packaging completes — it does
not actually start the app or check rendering. This means it wouldn't
have caught the white-screen bug (which was a runtime issue, not a build
failure). Adding it to PRs would slow CI without providing meaningful
protection. The ESLint no-extraneous-dependencies rule is the actual
prevention mechanism.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>

* fix(deps): sync pnpm-lock.yaml for rehype-sanitize dep classification

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>

* fix(ui): move rehype-sanitize to deps + declare eslint-config (MUL-2654)

- Move rehype-sanitize from devDependencies to dependencies (used in
  production Markdown.tsx)
- Add @multica/eslint-config to devDependencies (imported by
  eslint.config.mjs but previously undeclared)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-05-26 09:42:29 +08:00
Naiyuan Qing
5f1f08e466 feat(web): add use-cases content pipeline with welcome page (MUL-2349) (#2795)
* feat(web): add use-cases content pipeline with welcome page (MUL-2349)

Wire fumadocs-mdx into apps/web with an independent collection rooted at
content/use-cases/. Add the first page at /use-cases/welcome (header + H1 +
prose + screenshot + footer) using the about-page visual shell.

- source.config.ts + lib/use-cases-source.ts (separate from apps/docs)
- features/landing/components/mdx/screenshot.tsx wraps next/image
- public/use-cases/welcome/screenshot-1.png placeholder (55KB)
- next.config.ts wraps NextConfig with createMDX()
- .gitignore + eslint ignore .source/

Co-authored-by: multica-agent <github@multica.ai>

* feat(web): bilingual db-boy use case with cookie locale (MUL-2349)

Extends the use-cases pipeline into the first real article.

- ZH + EN MDX (auto-data-analysis.{zh,en}.mdx) sharing three real
  screenshots; sensitive fields on db-boy-profile.png (RDS host, DB
  name, password) are blurred in-place.
- Cookie-based locale: /use-cases/<slug> reads multica-locale
  server-side via lib/use-cases-i18n.ts (mirrors LandingLayout's
  cookie + Accept-Language fallback). Same URL serves either language;
  no [lang] segment so all other landing routes stay unchanged.
- Frontmatter schema (source.config.ts): z.looseObject with declared
  hero_image / updated_at (required) / category (optional); a
  preprocess converts YAML-auto-parsed Date back to a YYYY-MM-DD string.
- MDX components factory createMdxComponents(locale) routes the
  secondary CTA to /docs/zh (ZH) or /docs (EN); internal MDX links
  use <Link> for SPA nav; full-width and half-width colons both
  trigger [CTA: ...] / [占位图: ...] markers; 副 and Secondary
  both work as the secondary CTA prefix.
- Index page localizes hero / subtitle / card CTA / metadata; sort
  fallback uses an epoch placeholder so undefined-order disappears.
- Landing header + footer surface use-cases entry in both locales.
- Detail route: sticky header, right-rail TOC with anchor jumps,
  scroll-mt-[100px] on H2/H3 so anchor jumps don't slip under the
  sticky header.
- Drop welcome demo page.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(web): resolve code review blockers on use-cases PR

- Add `use-cases` to reserved_slugs.json + regenerate TS (P1: prevent
  future workspace slug collision)
- Fix dead links in both MDX files: /features/* → /docs/* (P2)
- Remove duplicate brand suffix in page title metadata (nit)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>

* fix(web): align usecases locale routing

* chore: refresh web mdx lockfile

* fix(web): type mdx next config adapter

* fix(web): wrap settings route page

---------

Co-authored-by: multica-agent <github@multica.ai>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 10:05:17 +08:00
Kagura
d43961ed7a MUL-2284 fix(deps): bump Next.js to patch CVE-2026-44578 (#2690)
* fix(deps): bump Next.js to patch CVE-2026-44578

Bump minimum Next.js versions to the first patched releases:
- apps/docs: ^15.3.3 → ^15.5.16
- apps/web: ^16.2.3 → ^16.2.5

Advisory: https://github.com/advisories/GHSA-c4j6-fc7j-m34r

Closes #2676

* chore: regenerate lockfile for Next.js bump
2026-05-15 19:59:25 +08:00
Bohan Jiang
5def4b62e0 fix(web): upgrade Next.js to ^16.2.3 for CVE-2026-23869 (#706)
High-severity DoS vulnerability (CVSS 7.5) in App Router — specially
crafted requests to RSC endpoints cause excessive CPU consumption.
Patched in Next.js 16.2.3.

Ref: https://github.com/multica-ai/multica/issues/701
2026-04-11 18:23:13 +08:00
Jiayuan Zhang
2d4b959407 fix(docker): remove COPY for non-existent tsconfig/node_modules (#661)
* fix(docker): remove COPY for non-existent tsconfig/node_modules

The @multica/tsconfig package has zero dependencies, so pnpm install
never creates a node_modules directory for it. The COPY --from=deps
instruction fails with "not found" during docker compose build.

Closes #658

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(docker): add dotenv as explicit dependency for web app

next.config.ts imports dotenv to load .env for REMOTE_API_URL, but
dotenv was never declared as a dependency. It worked locally as a
hoisted transitive dep but fails in Docker's stricter module resolution.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: fix daemon setup instructions for local Docker deployments

The daemon setup section in SELF_HOSTING.md had production URLs as the
active example and local Docker URLs commented out. Since this is a
self-hosting guide, local Docker should be the primary example.

Key changes:
- Make local Docker URLs the default in daemon setup examples
- Add explicit warning that CLI defaults to hosted service
- Add 'multica config set' instructions for persistent setup
- Add link from Quick Start to daemon setup section
- Clarify that daemon runs on host machine, not inside Docker
- Update CLI_AND_DAEMON.md self-hosted section similarly

Closes #660

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 20:58:32 +08:00
Naiyuan Qing
b067eee487 chore: set up test infrastructure for shared packages
Add vitest configs to packages/core and packages/views. Test deps
added to pnpm catalog for unified versioning. Web test deps migrated
to catalog references. pnpm test now discovers all packages.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 10:34:03 +08:00
Naiyuan Qing
ba32f3a187 chore: add shared ESLint config + enforce strict tsconfig across packages
- Add @multica/eslint-config package (base, react, next configs)
- Replace `next lint` (removed in Next.js 16) with `eslint .`
- Add lint scripts to all packages and desktop app
- Add noUnusedLocals, noUnusedParameters, noImplicitReturns to base tsconfig
- Fix all resulting TS/ESLint errors (unused imports, missing returns,
  stale eslint-disable comments from legacy eslint-config-next)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 08:27:29 +08:00
Naiyuan Qing
f41a0cf423 feat(views): extract packages/views — shared business UI + navigation adapter
- Create NavigationAdapter interface (push, replace, back, pathname, searchParams)
- Create AppLink component replacing next/link in 4 files
- Replace useRouter → useNavigation in 3 files (issue-detail, create-issue, create-workspace)
- Create WebNavigationProvider wrapping Next.js useRouter/usePathname/useSearchParams
- Move ~85 feature UI files (issues, editor, modals, my-issues, skills, runtimes) to packages/views/
- Add store singleton registration pattern (registerAuthStore, registerWorkspaceStore)
- Create data-aware wrappers in packages/views/common/ (ActorAvatar, Markdown)
- Update all app-layer imports to @multica/views/*
- Add @source directive for Tailwind to scan views package
- packages/views/ has zero next/* imports

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 11:49:55 +08:00
Naiyuan Qing
35828492d5 feat(ui): extract packages/ui — shared atomic UI layer
- Move 55 shadcn components → packages/ui/components/ui/
- Move lib/utils.ts (cn function) → packages/ui/lib/
- Move 3 DOM hooks (auto-scroll, mobile, scroll-fade) → packages/ui/hooks/
- Extract CSS design tokens (@theme + :root + .dark) → packages/ui/styles/tokens.css
- Refactor 3 common components to pure-props (actor-avatar, mention-hover-card, reaction-bar)
- Move 6 markdown components with renderMention slot for IssueMentionCard decoupling
- Create wrapper components in apps/web/ for data-aware ActorAvatar and Markdown
- Update 116 import paths across apps/web/
- Add @source directives for Tailwind to scan packages

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 10:44:31 +08:00
Naiyuan Qing
e1e7f68330 feat: extract packages/core — Turborepo infrastructure + headless business logic
Phase 1: Monorepo infrastructure
- Add Turborepo with turbo.json pipeline (build, dev, typecheck, test)
- Update pnpm-workspace.yaml to include packages/*
- Create shared TypeScript config (packages/tsconfig)

Phase 2: Extract packages/core (zero react-dom, all-platform reuse)
- Move domain types, API client, logger, utils → packages/core/
- Move TanStack Query modules (issues, inbox, workspace, runtimes)
- Move Zustand stores (auth, workspace, issues, navigation, modals)
- Move realtime sync (WSProvider, hooks, ws-updaters)
- Refactor auth/workspace stores to factory pattern for DI
- Refactor ApiClient with onUnauthorized callback
- Refactor useWorkspaceId to React Context (WorkspaceIdProvider)
- Refactor WSProvider to accept wsUrl + store props
- Create apps/web/platform/ bridge layer (api singleton, store instances)
- Update 91 import paths across apps/web/
- Fix 3 test files for new import paths

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 10:20:00 +08:00
Naiyuan Qing
2be9f6cd2f feat(web): add TanStack Query infrastructure (Phase 0)
- Install @tanstack/react-query v5 + devtools
- Create core/query-client.ts with WS-optimized defaults (staleTime: Infinity)
- Create QueryProvider and wire into root layout
- Add @core/* path alias to tsconfig + vitest
- Add useWorkspaceId() bridge hook for query key scoping

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 14:43:51 +08:00
Naiyuan Qing
27e58d91af refactor(editor): unify editor into features/editor with single markdown pipeline
Replace three divergent data paths (Marked HTML loading, regex post-processing
saving, separate paste parsing) with one symmetric path through @tiptap/markdown.

Key changes:
- Create features/editor/ module with ContentEditor (unified edit+readonly)
  and TitleEditor, replacing components/common/ editor files
- Load content via contentType: 'markdown' instead of markdownToHtml() hack
- Save content via editor.getMarkdown() directly, no post-processing
- Merge RichTextEditor + ReadonlyEditor into single ContentEditor with
  editable prop
- Extract extensions into separate modules (mention, file-upload,
  markdown-paste, submit-shortcut, code-block-view)
- Extract shared preprocessMentionShortcodes to components/markdown/mentions.ts
- Add copyMarkdown utility for clipboard operations
- Upgrade all @tiptap packages from 3.20.5 to 3.22.1 (lexer isolation fix,
  HTML entity roundtrip fix, table alignment support)
- Delete markdownToHtml.ts, readonly-editor.tsx, and 10 old component files

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 10:28:29 +08:00
Naiyuan Qing
097630c733 fix(editor): reliable markdown rendering via marked HTML pipeline
Replace @tiptap/markdown's beta contentType: "markdown" parser with a
dedicated marked-based HTML pipeline for loading markdown content.

The @tiptap/markdown parser silently drops content in complex documents
(tables, nested lists, mentions). Instead, we now:

1. Pre-convert mention links to <span data-type="mention"> HTML
2. Render markdown to HTML via a dedicated Marked instance with a custom
   renderer that wraps table cell content in <p> tags (required by
   Tiptap's TableCell block+ content spec)
3. Load as HTML — Tiptap's ProseMirror HTML parser handles everything
4. Keep @tiptap/markdown extension only for getMarkdown() serialization

Also adds Table extension support and aligns CSS with the old Markdown
component's minimal mode styling.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 19:24:33 +08:00
Naiyuan Qing
9a37af4ca1 feat(ui): editor UX improvements — lowlight, upload, emoji, comment editing
- New QuickEmojiPicker: shared SmilePlus + 8 quick emojis + full picker
- New FileUploadButton: reusable Paperclip upload trigger
- New CodeBlockView: React NodeView with language label + copy button
- CodeBlockLowlight: syntax highlighting in editor (replaces plain codeBlock)
- ReactionBar: brand-tinted pill styles, hideAddButton prop
- Comment header: emoji picker + three-dot menu in top-right
- Comment edit: inline editing with brand border, blur-to-save, Escape-to-cancel
- RichTextEditor: add onBlur prop, markdown paste extension
- Create issue: upload button in footer
- Issue detail: upload button next to reaction bar
- Comment/reply: use FileUploadButton, loading spinners, no optimistic updates

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 18:37:53 +08:00
Naiyuan Qing
8fae493f01 merge: resolve conflicts with main (file upload support)
- Merge main's file upload (Image extension, Paperclip, useFileUpload)
- Keep our mention/markdown/TitleEditor changes
- Apply RichTextEditor edit/display to main's Collapsible CommentCard layout

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 16:07:45 +08:00
yushen
1e22633301 Merge remote-tracking branch 'origin/main' into feature/file-upload-cloudfront
# Conflicts:
#	apps/web/components/common/rich-text-editor.tsx
#	apps/web/features/issues/components/comment-card.tsx
#	apps/web/package.json
#	pnpm-lock.yaml
2026-03-31 15:59:46 +08:00
yushen
423aa38888 feat(upload): add file upload UI — avatar, editor paste/drop, attachments
- Add uploadFile method to ApiClient (FormData + 401 handling)
- Add useFileUpload hook with client-side validation
- ActorAvatar renders actual avatar images with fallback to initials
- Account settings: replace URL input with clickable avatar upload
- RichTextEditor: add Image extension, paste/drop/insertFile support
- Markdown renderer: add img component for uploaded images
- CommentInput & ReplyInput: add paperclip button for file attachments
- Issue description: paste/drop file upload support

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 15:17:54 +08:00
Naiyuan Qing
b4bbc16521 fix(issues): use floating-ui for mention popup viewport-aware positioning
Replace hardcoded bottom positioning with @floating-ui/dom computePosition
so the @ mention popup flips above the cursor when near the viewport bottom.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 14:39:48 +08:00
Jiayuan
7c1aabbe3a feat(reactions): add emoji reactions for comments and issue descriptions
Add Slack-style emoji reactions to comments and issue descriptions with
full-stack support: database tables, REST API endpoints, real-time
WebSocket sync, optimistic UI updates, and inbox notifications.

- New `comment_reaction` and `issue_reaction` tables with migrations
- POST/DELETE endpoints for adding/removing reactions on both comments
  and issue descriptions
- Real-time WS events (reaction:added/removed, issue_reaction:added/removed)
- Shared ReactionBar component with quick emoji picker and full emoji-mart
  picker (lazy-loaded)
- Optimistic add/remove with rollback on failure
- Inbox notifications for comment author and issue creator when reacted to
- Reactions included in timeline, comment list, and issue detail responses
2026-03-30 22:37:59 +08:00
Naiyuan Qing
4052017c7a feat: settings redesign, rich text mentions, inbox listeners, and UI polish
- Refactor settings page into tabbed components (general, workspace, members, tokens, account)
- Move settings link from dropdown to sidebar nav
- Add @mention suggestions in rich text editor
- Expand inbox listeners with enhanced event handling
- Improve board column, issue detail, and create issue modal UX
- Update markdown rendering and code block styling
- Polish skills page layout

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 19:17:14 +08:00
Naiyuan Qing
2cf088ddf6 feat: resizable sidebar, issue detail rewrite, package consolidation
- Add drag-to-resize sidebar with localStorage persistence
- Rewrite issue detail page with Tiptap rich text editor, due date picker, acceptance criteria
- Redesign create-issue modal with pill-based property toolbar and expand/collapse
- Consolidate @multica/sdk and @multica/types into apps/web/shared/
- Simplify auth: remove verification codes, PATs, email service (dev-only login)
- Add 401 unauthorized handler to redirect expired sessions to login
- Fix due date format to send full RFC3339 timestamps
- Increase description editor debounce to 1500ms
- Remove arbitrary Tailwind values in create-issue modal
- Renumber migrations (inbox_actor 012→009), remove unused migrations
- UI polish across agents, settings, inbox, knowledge-base pages

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 16:47:04 +08:00
Naiyuan Qing
0629eb9d79 fix(web): add missing linkify-it dependency and types
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 18:24:30 +08:00
Naiyuan Qing
bf7ea14092 fix(web): add missing markdown dependencies (react-markdown, rehype-raw, remark-gfm, shiki)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 18:21:24 +08:00
Naiyuan Qing
66e99136c2 refactor(web): self-contained shadcn UI with base-nova style and design tokens
Migrate all shadcn components into apps/web/components/ui/ so the web app
is fully independent from packages/ui for its UI layer. Update to the
latest shadcn base-nova style. Add missing semantic color variables
(success, warning, info, canvas), font-mono mapping, scrollbar styling,
and wrap Select items in SelectGroup for proper padding.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 18:19:26 +08:00
Naiyuan Qing
a2d7501d57 refactor(web): restructure to feature-based architecture with zustand stores
- Remove tab system entirely (tab-store, tab-bar, tab-link)
- Split monolithic AuthContext into zustand auth + workspace stores
- Move issue components/config to features/issues/
- Move WebSocket provider to features/realtime/
- Move api.ts to shared/
- Migrate all consumers from useAuth() to direct store imports
- Simplify sidebar: replace hand-built dropdown with shadcn DropdownMenu,
  replace custom layout wrapper with SidebarInset
- Remove unused @multica/store and @multica/hooks dependencies
- Add @/ path alias and zustand dependency
- Update CLAUDE.md with feature-based architecture conventions

Net change: +293 / -2435 lines

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:08:36 +08:00
Jiayuan Zhang
81e64e9fce Add workspace management and isolated worktree environments 2026-03-23 18:12:11 +08:00
Jiayuan Zhang
6dfc61fa86 test: add comprehensive test suite (Go unit/integration, Vitest, Playwright E2E)
- Add JWT middleware unit tests (8 tests covering all auth edge cases)
- Add WebSocket hub tests (5 tests for client lifecycle and broadcast)
- Add full HTTP integration tests (12 tests through real Chi router with DB)
- Add frontend component tests for login, issues, and issue detail pages
- Add auth context unit tests (9 tests for login/logout/name resolution)
- Add Playwright E2E tests for auth, issues, comments, and navigation
- Configure Vitest with jsdom, React plugin, and path aliases

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 11:50:25 +08:00
Jiayuan Zhang
332a9b6bcc chore(web): add @dnd-kit for drag-and-drop support
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 14:27:15 +08:00
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
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
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
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
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
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
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
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
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
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
4375a6662b chore(web): set dev port to 3001 to avoid gateway conflict
Gateway occupies port 3000, so the Next.js dev server now
runs on port 3001.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 21:20:06 +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
5c240ab363 refactor(web): update imports to use @multica/ui package
Replace local UI component and utility imports with @multica/ui
subpath imports. Remove old components/ui/ directory, lib/utils.ts,
and globals.css. Configure postcss, next.config, and tsconfig for
monorepo UI package consumption.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 11:34:05 +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