Commit graph

111 commits

Author SHA1 Message Date
Naiyuan Qing
430f2c177e refactor(ui): move LoadingIndicator into MessageList
- Move LoadingIndicator from ChatView into MessageList for consistent padding
- Add isLoading and hasPendingApprovals props to MessageList
- Adjust message spacing (my-1 → my-2) for better visual balance

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-15 11:03:59 +08:00
Naiyuan Qing
deb747a859 refactor(ui): unify loading indicator component
- Create LoadingIndicator component with "generating" and "streaming" variants
- Remove inline loading indicator from StreamingMarkdown (empty content returns empty fragment)
- Use unified LoadingIndicator in ChatView with consistent positioning
- Eliminates layout shift between different loading states

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-15 10:52:46 +08:00
Naiyuan Qing
c6ca5f3270 refactor(ui): unify container layout and adjust spacing
- Use container utility class consistently across chat components
- Change container max-width from 5xl to 4xl for better readability
- Adjust message bubble padding (p-3 -> p-2)
- Fix logout dropdown alignment and add destructive variant

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-15 10:47:59 +08:00
Naiyuan Qing
0c5de3c5f4 fix(ui): preserve newlines in chat input multiline text
- Use TipTap's getText({ blockSeparator: '\n' }) instead of doc.textContent
  to preserve newlines between paragraphs when submitting messages
- Add whitespace-pre-wrap CSS to user message bubbles to render newlines
- Add className prop support to StreamingMarkdown component

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-15 10:32:58 +08:00
Jiayuan Zhang
058af56d47
fix(ui): show generating indicator while agent is processing (#191)
When the user sends a message and the agent hasn't started streaming
yet, the chat area showed no visual feedback. Now a "Generating..."
spinner appears between message send and the first streaming content,
matching the existing indicator style used in StreamingMarkdown.

Closes MUL-224

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 03:13:18 +08:00
Naiyuan Qing
e0f80b0054 merge: resolve conflict with main (keep both auth and subagents handlers) 2026-02-13 14:41:15 +08:00
Jiang Bohan
499c573544 feat(desktop): add subagent dashboard with real-time status tracking
Adds a status bar and slide-out dashboard panel to the chat view that
shows subagent progress in real-time. Polls at 2s when active, 10s when
idle. Completed runs auto-hide after 5 minutes. Includes dismiss button
and 30s auto-dismiss for the status bar.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 13:46:58 +08:00
Naiyuan Qing
ca1c260735 feat(ui): add size prop to MulticaIcon bordered variant
Supports sm, md, lg sizes for flexible usage in different contexts.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-13 12:24:48 +08:00
Naiyuan Qing
374ce68b84 fix(ui): remove math plugins and disable single-tilde strikethrough
- Remove remarkMath and rehypeKatex plugins that caused text wrapping
  issues by interpreting $ signs as LaTeX delimiters
- Configure remarkGfm with singleTilde: false to prevent single ~ from
  being parsed as strikethrough (e.g., ~1000 should not become <del>)
- Only double tilde ~~text~~ now renders as strikethrough

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-13 08:33:56 +08:00
Naiyuan Qing
8199dde1b6 feat(core): add message source tracking and persistence
- Add MessageSource type to track where user messages originate (local, gateway, channel)
- Broadcast inbound messages from all channels to local Desktop UI via Hub.onInboundMessage()
- Persist source field in JSONL session storage so it survives page refresh
- Display source icon (Monitor/Smartphone/Send) with tooltip for non-local user messages

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-12 18:45:15 +08:00
LinYushen
8bc36a9cc9
Merge pull request #136 from multica-ai/fix/agent-compaction
fix(agent): prevent context window overflow with 3-layer compaction defense
2026-02-12 17:23:12 +08:00
Naiyuan Qing
bad4d05c15
Merge pull request #138 from multica-ai/refactor/desktop-page-restructure
refactor(desktop): restructure pages and add dev reset scripts
2026-02-12 16:45:07 +08:00
yushen
8f4e894370 feat(ui): show in-chat system message when context compaction occurs
Add CompactionItem component that renders a subtle inline notification
in the chat stream when the agent compacts its context window. Extends
Message type with "system" role and handles compaction_end events in
useChat's handleStream.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 16:10:19 +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
Jiang Bohan
ece00cac2b merge: resolve conflict with main (lucide-react migration)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 14:47:00 +08:00
Jiang Bohan
a33df19bef feat(desktop): add chat abort support with partial content preservation
Add stop button to interrupt agent generation mid-stream. The send button
toggles to a stop icon during loading. Abort propagates from UI through
IPC to the Agent layer (PiAgentCore.abort()), preserving all partial
content in the agent's context so users can follow up immediately.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 14:33:06 +08:00
Naiyuan Qing
b310b57ce9 merge: integrate origin/main into feat/onboarding-check
Resolved conflicts:
- Keep Lucide icons (replaced Hugeicons) in desktop and ui
- Keep new Sidebar layout design
- Merge new dependencies (electron-updater, lucide-react, katex)
- Add new 'data' tool with Lucide BarChart3 icon
- Keep UpdateNotification component (not integrated into UI yet)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-12 11:16:49 +08:00
Naiyuan Qing
eb4e1f57b1 feat(desktop): persist onboarding state to file system
- Add AppState module in core for managing app state persistence
- Add app-state IPC handlers for reading/writing onboarding state
- Hydrate onboarding state from file system on app startup
- Prevent flash by showing blank screen during hydration
- Update onboarding store to sync with file system
- Improve MulticaIcon with enhanced animation states
- Minor UI fixes in chat and device list components

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-12 10:53:04 +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
b718b95da7 fix(ui): improve chat input scroll behavior
- Scroll cursor into view on content changes (e.g., Shift+Enter)
- Add scroll threshold and margin for better edge handling

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-12 09:39:16 +08:00
Naiyuan Qing
d1d3cd0a9f feat(ui): add collapsible component
Add Radix-based collapsible component for accordion-style UI sections.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-12 09:38:56 +08:00
Jiayuan Zhang
953041efa0 feat(ui): add LaTeX math rendering support to chat markdown
Add remark-math + rehype-katex plugins to render inline ($...$) and
display ($$...$$) math expressions. Includes dark mode CSS overrides,
streaming block splitting for math fences, and math range exclusion
in link preprocessing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 20:57:52 +08:00
Naiyuan Qing
bbf2a16f39 style(ui): soften dark mode background color
Increase lightness from 0.141 to 0.155 for a less harsh dark theme.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-11 18:51:10 +08:00
Naiyuan Qing
573d803d71 fix(ui): update component styles for Tailwind v4 compatibility
- Replace ring-[3px] with ring-3 in button and input
- Use data-horizontal/data-vertical in separator
- Fix sidebar data attributes and RTL support
- Simplify tooltip provider nesting

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-11 18:51:05 +08:00
Naiyuan Qing
b825c6b3d8 feat(ui): improve MulticaIcon animation behavior
- Separate entrance animation from hover animation
- Use state to track entrance completion
- Hover spin only activates after entrance is done
- Shorten entrance animation to 0.6s

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-11 17:47:35 +08:00
Naiyuan Qing
437dc05db0 feat(desktop): improve setup step with radio indicators
- Add radio button style indicators for provider selection
- Add HoverCard component for provider setup help
- Add Link component for external URLs
- Add Popover component (dependency for HoverCard)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-11 17:46:17 +08:00
Jiayuan Zhang
4e5c99a97f feat(ui): show task context for sessions_spawn in chat UI
Display the label (or truncated task) as subtitle for SpawnSession tool
calls, so users can see what each spawned session is working on.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 16:59:16 +08:00
Jiayuan Zhang
5a3dc6c1e1 feat(ui): add data tool display config in chat UI
Add chart icon, smart subtitle (shows action + ticker, e.g. "price_snapshot AAPL"),
and running state label for the data tool in the tool call UI component.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 16:54:42 +08:00
Naiyuan Qing
54bc00ce3f feat(desktop): redesign privacy step with single column layout
- Simplify permissions step to single centered column
- Replace per-item switches with single "I understand" checkbox
- Add capabilities info card with clean dividers
- Add trust note section for privacy messaging
- Rename step from "Permissions" to "Privacy" for clarity
- Add fade-in animation for step transitions
- Add shadcn checkbox component

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-11 16:09:42 +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
22db61876b feat(desktop): add welcome page to onboarding flow
- Add Welcome step before the 4-step onboarding flow
- Welcome page introduces Multica with brand title (Playfair Display font)
- Display three core principles: Your AI, Your Machine, Your Control
- Add entrance spin animation to MulticaIcon component
- Welcome page has no stepper, only shown after clicking "Start Exploring"

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-11 13:46:21 +08:00
Jiayuan Zhang
1b252c1cf9 chore(ui): switch primary color to shadcn default
Change primary from custom purple oklch(0.51 0.23 277) to shadcn
default neutral near-black/near-white. Also reset chart and sidebar
primary colors to shadcn defaults.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 22:16:57 +08:00
Naiyuan Qing
24c3af1185 fix(ui): handle possibly undefined values in strict mode 2026-02-10 18:19:41 +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
c27f4e66b5 docs(channels): update README with route queue pattern and ack lifecycle
Document the new channel system design: FIFO pendingRoutes queue,
activeRoute/activeAcks state, agent_start/agent_end lifecycle,
InboundDebouncer, typing/reaction lifecycle, and UI metadata stripping.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 18:27:06 +08:00
Naiyuan Qing
ec67dd6706 fix(ui): strip channel metadata prefixes from user messages in display
Add stripUserMetadata() to remove timestamp envelopes and media type
labels ([Voice Message] Transcript:, [Image] Description:, etc.) that
are injected for LLM context but should not appear in the desktop UI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 18:27:06 +08:00
Naiyuan Qing
0895d42d3b Merge remote-tracking branch 'origin/main' into feat/telegram-channel
# Conflicts:
#	apps/desktop/src/hooks/use-local-chat.ts
#	packages/sdk/src/actions/stream.ts
#	packages/ui/src/components/chat-view.tsx
#	src/agent/async-agent.ts
#	src/agent/events.ts
2026-02-09 14:28:06 +08:00
Bohan Jiang
b7085b2bf5
Merge pull request #107 from multica-ai/fix/new-user-onboarding
fix(desktop): new user onboarding — show errors and configure dialog in Chat
2026-02-09 13:54:48 +08:00
Jiang Bohan
ed681a96bf feat(desktop): add Configure button in chat error banner
When the agent fails due to missing API key, the error banner now
shows a "Configure" button that opens the same ApiKeyDialog (or
OAuthDialog) used on the home page. After successful configuration
the error clears and the user can immediately start chatting.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 13:51:55 +08:00
Naiyuan Qing
23905daaa1 Merge remote-tracking branch 'origin/main' into feat/telegram-channel
# Conflicts:
#	apps/desktop/electron/electron-env.d.ts
#	apps/desktop/electron/ipc/index.ts
#	apps/desktop/electron/preload.ts
#	apps/desktop/src/App.tsx
#	apps/desktop/src/pages/layout.tsx
#	src/agent/async-agent.ts
#	src/agent/runner.ts
#	src/hub/hub.ts
2026-02-09 13:44:08 +08:00
Naiyuan Qing
6a02fd29be fix(ui): adjust chat input padding, icon, and button size
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 11:43:49 +08:00
Naiyuan Qing
54b3ebe9e9 feat(ui): render error messages with Markdown
Use MemoizedMarkdown for error messages so links are clickable
instead of plain text.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 08:04:19 +08:00
Jiang Bohan
0e383f51ab feat(desktop): display agent errors in Chat UI instead of hanging
When the agent encounters an error (e.g. no API key configured),
the Chat UI now shows an error banner instead of silently hanging.
The user can still type and retry after fixing their configuration.

- Add AgentErrorEvent to SDK stream types
- Forward agent_error events through IPC to renderer
- Handle error events in useLocalChat hook
- Keep chat input enabled for AGENT_ERROR (retriable)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 22:23:53 +08:00
yushen
6ecdbc5783 fix(exec-approval): treat expiresAtMs=-1 as non-expiring 2026-02-06 18:09:01 +08:00
Naiyuan Qing
1e6da205df feat(ui): spin MulticaIcon on hover
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 20:22:29 +08:00
Naiyuan Qing
5e174b8fef fix(ui): responsive horizontal padding on message list
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 20:15:19 +08:00
Naiyuan Qing
21312abd01 feat: chat input padding 2026-02-05 19:02:38 +08:00
Naiyuan Qing
65c2fea1b6 feat(chat): add message history pagination with scroll-up loading
Return latest messages by default instead of oldest. Support paginated
loading of older messages when scrolling up via IntersectionObserver,
with scrollHeight compensation to preserve scroll position.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 18:40:15 +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
7a21686505 refactor(hooks,ui): extract useGatewayChat hook and update shared components
Move gateway-specific chat logic into dedicated useGatewayChat hook.
useChat remains a pure state hook with no IO. Update ChatView props,
remove legacy chat.tsx and connect-prompt.tsx.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 17:50:47 +08:00