Commit graph

27 commits

Author SHA1 Message Date
Naiyuan Qing
86d00bb134 feat(ui): render AI messages with streaming markdown
Messages store gains streamingIds set and startStream/appendStream/
endStream actions. Gateway store routes stream action payloads to
these new actions. Chat component switches to StreamingMarkdown
for in-progress messages, providing incremental block-level rendering.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 17:18:35 +08:00
Naiyuan Qing
a1c28b3d04 feat(ui): add auto-scroll to bottom for chat messages
- Add useAutoScroll hook using ResizeObserver + MutationObserver
- Observes content children for size changes (streaming, images)
- Watches for new DOM nodes (new messages, history load)
- Respects user scroll position: no force-scroll when reading above
- Integrate in Chat component alongside existing useScrollFade

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:14:18 +08:00
Naiyuan Qing
3622f82a7b feat(gateway): add auto-connect, hub discovery via list-devices
- Add LIST_DEVICES event and "hub" device type to SDK
- Add listDevices() method to GatewayClient
- Add handleListDevices handler in Gateway
- Change Hub deviceType from "client" to "hub"
- Refactor gateway store: auto-connect WS, separate hubId selection
- Hub-init: auto-connect on mount, discover hubs on registered
- Hub-sidebar: show discovered hubs list with connect/disconnect UI

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:13:40 +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
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
Naiyuan Qing
bcaf14464a fix(ui): improve disabled state cursor and no-agent empty state
- Add cursor-not-allowed and reduced opacity to ChatInput when disabled
- Show user icon in empty state when no agent is selected
- Pass contextual placeholder text based on agent selection

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:45:53 +08:00
Naiyuan Qing
7e5bc7b7ae fix(ui): prevent chat submit during IME composition
Check e.nativeEvent.isComposing so pressing Enter to confirm
CJK input does not accidentally submit the message.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:42:54 +08:00
Naiyuan Qing
4ff227685e feat(ui): add onSubmit/disabled props to ChatInput, convert AppSidebar to children slot
ChatInput now accepts onSubmit callback and disabled state.
AppSidebar uses children instead of items prop for flexible content injection.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:40:56 +08:00
Naiyuan Qing
cdcce47141 feat(ui): add brand icon and artistic font to sidebar header
- Display Multica icon alongside brand name in sidebar header
- Use Playfair Display serif font for an artistic brand feel
- Expose --font-brand CSS variable from layout

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:35:48 +08:00
Naiyuan Qing
8018290fba fix(ui): add semantic colors to sonner toast icons
success → emerald-500, info → blue-500, warning → amber-500,
error → red-500, loading → muted-foreground.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:22:27 +08:00
Naiyuan Qing
9af889a9bb fix(web): import toast from @multica/ui instead of bare sonner
sonner is a dependency of @multica/ui, not web. Re-export toast from
the ui sonner module and update the import path in chat.tsx.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:21:24 +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
047de2b431 fix(web): suppress deviceId hydration mismatch warning
Zustand persist generates a new deviceId on the server (no localStorage),
then hydrates a different value from localStorage on the client. Add
suppressHydrationWarning to the deviceId span since this mismatch is expected.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:04:57 +08:00
Naiyuan Qing
905e8c8ae3 fix(ui): remove Shiki span background-color causing unwanted highlights
The dual-theme CSS applied background-color to .shiki span elements,
which picked up token-level bg variables from github-dark/light themes
and created visible purple/blue highlights on code lines.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 21:48:29 +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
ffaed12048 feat(ui): add global scrollbar styling with light/dark support
Thin 6px scrollbars with transparent tracks and themed thumbs using
CSS standard properties + WebKit pseudo-elements for max compatibility.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 21:09:05 +08:00
Naiyuan Qing
f348d91c18 feat(ui): add Spinner component from multica
Port the SpinKit Grid 3x3 spinner as a shared UI component.
Uses currentColor and em sizing for flexible theming and scaling.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 21:01:48 +08:00
Naiyuan Qing
01790a57d2 refactor(ui): extract AppSidebar into shared UI component
Move sidebar markup from page.tsx into a reusable AppSidebar component
in packages/ui for cross-app reuse.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 20:57:57 +08:00
Naiyuan Qing
4036463d6c feat(web): add sidebar layout
Wrap layout in SidebarProvider, restructure page into left
sidebar navigation + right SidebarInset content area.
Add use-mobile hook via shadcn for responsive behavior.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 20:40:35 +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
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
eb5c388a80 refactor(ui): reorganize components into ui/ subdirectory and share layout
- Move shadcn components from src/components/ to src/components/ui/
- Move component-example and example from apps/web to packages/ui
- Update package.json exports with separate components/* and components/ui/* paths
- Update components.json ui alias in both packages/ui and apps/web
- Add missing @import "shadcn/tailwind.css" to globals.css
- Add new UI components: sheet, sidebar, skeleton, switch
- Update apps/web and apps/desktop to use shared ComponentExample

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 11:34:09 +08:00
Naiyuan Qing
c1129ff37d feat(ui): extract components, utils, and styles from apps/web
Move 13 shadcn UI components, cn() utility, and theme CSS variables
to packages/ui for cross-platform reuse. Add @source directives for
Tailwind v4 content scanning.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 11:34:05 +08:00
Naiyuan Qing
e1443720eb feat(ui): create @multica/ui package skeleton
Shared UI package for web, electron, and mobile. Uses subpath exports
following the official shadcn monorepo template pattern.

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