Commit graph

186 commits

Author SHA1 Message Date
Jiang Bohan
cd0888dc33 docs(tools): add Agent Profile integration section
Add architecture diagram showing Hub-Agent-Client relationship and
document how Profile config.json integrates with tools configuration.
Mark Phase 2 as complete.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 02:25:42 +08:00
Jiang Bohan
37aafe655e docs(profile): add README with config.json documentation
Document the Profile system structure, configuration options,
CLI usage, and programmatic API.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 02:25:42 +08:00
Jiang Bohan
3c0f132ff8 feat(tools): integrate Profile tools config with runner
Add mergeToolsConfig function to combine Profile tools config with
CLI options. Profile config serves as base, CLI options override.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 02:25:42 +08:00
Jiang Bohan
9467ac9fff feat(profile): add config.json support for profile configuration
Add ProfileConfig interface with tools, provider, model, and
thinkingLevel settings. ProfileManager now exposes getToolsConfig()
and getProfileConfig() methods.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 02:25:42 +08:00
Jiang Bohan
11e2564aac docs(tools): add comprehensive README with architecture diagram
Document the 4-layer policy filter system, tool groups, profiles,
and usage examples for both CLI and programmatic interfaces.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 02:25:42 +08:00
Jiang Bohan
e44861b56c fix(tools): resolve exactOptionalPropertyTypes errors
Handle undefined values correctly in optional object properties
for TypeScript strict mode compatibility.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 02:25:42 +08:00
Jiang Bohan
7d04253791 fix(tools): replace replaceAll with replace for ES2020 compatibility
Use regex replace instead of replaceAll to support older target versions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 02:25:42 +08:00
Jiang Bohan
ae6d516952 feat(tools): add tools:cli for inspecting tool configuration
New CLI commands:
- pnpm tools:cli list - list available tools with optional filtering
- pnpm tools:cli groups - show all tool groups
- pnpm tools:cli profiles - show all profiles

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 02:25:42 +08:00
Jiang Bohan
67d54306a1 feat(cli): add tools configuration options
Add --tools-profile, --tools-allow, and --tools-deny CLI options
to configure tool policy from command line.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 02:25:22 +08:00
Jiang Bohan
ab7c0774ba test(tools): add policy system unit tests
Test coverage for:
- Tool group expansion
- Profile policies
- Allow/deny filtering
- Provider-specific rules
- Subagent restrictions
- Combined policy layers

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 02:25:22 +08:00
Jiang Bohan
12a4677107 refactor(tools): integrate policy filtering into resolveTools
- Add ToolsConfig to AgentOptions for policy configuration
- Add isSubagent flag for subagent tool restrictions
- Refactor resolveTools to apply 4-layer policy filtering
- Add createAllTools and getAllToolNames utility functions

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 02:25:22 +08:00
Jiang Bohan
57f31b2f79 feat(tools): add tool policy system with 4-layer filtering
Implement a flexible tool policy system that supports:
- Tool groups (group:fs, group:runtime, group:web)
- Predefined profiles (minimal, coding, web, full)
- Global allow/deny lists
- Provider-specific rules
- Subagent restrictions

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 02:25:22 +08:00
Naiyuan Qing
83ab7ee743
Merge pull request #38 from multica-ai/fix/chat-assistant-message-width
fix(web): remove max-width constraint on assistant messages
2026-01-30 23:54:03 +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
Naiyuan Qing
fd46d7ba9a
Merge pull request #37 from multica-ai/feat/web-v1
Feat/web v1
2026-01-30 23:40:08 +08:00
Naiyuan Qing
716bbceaf4 refactor(chat, hooks): simplify handleSend and update useDeviceId to use useSyncExternalStore
- Simplified handleSend function in Chat component by removing unnecessary useCallback.
- Refactored useDeviceId hook to utilize useSyncExternalStore for better state management and removed useState and useEffect for device ID retrieval.
- Updated useGateway hook to ensure onMessageRef is set correctly on options change.
- Enhanced useScrollFade hook to properly cancel animation frames on cleanup.
2026-01-30 23:38:10 +08:00
Naiyuan Qing
5ee3176d3a docs: restore missing Atomic Commits details in CLAUDE.md
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 23:20:16 +08:00
Naiyuan Qing
403c44f536 refactor(web): unify hub + agent state into single Zustand store
Replace useState-based useHub hook and separate useActiveAgent store
with a single useHubStore (Zustand). This fixes the bug where
HubSidebar and Chat held independent state copies, causing stale data
and duplicate 30s polling. Agent create/delete logic now lives in the
store with automatic activeAgentId management.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 23:15:11 +08:00
Naiyuan Qing
cb28fbecc0 refactor(web): remove agent ID copy button from chat header
Keep only the device ID copy interaction; agent ID is display-only.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 23:12:49 +08:00
Naiyuan Qing
94f32701c7 feat(ui): auto-activate newly created agent
Return the new agent ID from createAgent and set it as active
immediately after creation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 23:05:43 +08:00
Naiyuan Qing
cdd146e31f feat(web): restore device ID display and copy button in chat header
Re-add deviceId (full UUID) with copy-to-clipboard button next to the
SidebarTrigger, matching the original behavior from commit 0975510.
Both deviceId and agentId now have independent copy states.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 23:04:52 +08:00
Naiyuan Qing
d04952da91 feat(web): restore agent ID copy button in chat header
Re-add the copy-to-clipboard button that was lost when chat.tsx was
rewritten for hub/agent support. Clicking copies the full agentId,
shows a checkmark icon for 2s, and triggers a toast confirmation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:55:57 +08:00
Naiyuan Qing
3b1bc5a17f fix(ui): use data-active: syntax and add text color for active agent item
Align with sidebar component library convention: use Tailwind v4 native
data-active: instead of data-[active]:, and add missing
text-sidebar-accent-foreground for active state.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:54:59 +08:00
Naiyuan Qing
78e34a1d63 refactor(ui): unify agent item hover to full row
Replace SidebarMenuButton with a custom flex row div that handles hover
and active states on the entire item, not just the text area. Delete
button uses stopPropagation to avoid triggering selection.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:51:21 +08:00
Naiyuan Qing
da5565adcf fix(ui): wrap agent ID in span for CSS truncate ellipsis
SidebarMenuButton applies truncate via [&>span:last-child]:truncate,
so the text must be in a <span> rather than a bare text node to get
overflow-hidden + text-ellipsis + whitespace-nowrap.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:49:10 +08:00
Naiyuan Qing
f1244f467b refactor(ui): replace absolute-positioned delete with flex layout in HubSidebar
Drop SidebarMenuAction (absolute positioning) in favor of a flex row:
left side (SidebarMenuButton) gets flex-1 min-w-0 for natural truncation,
right side (delete button) sits as a normal flex child with hover reveal.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:48:19 +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
3190be60c3 fix(ui): soften HubSidebar styling and improve UX
Use CSS truncation for agent/hub IDs instead of JS slicing, show delete
button only on hover via showOnHover prop, and reduce contrast on status
dots, labels, and placeholder text for a more subtle appearance.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:44:14 +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
5319991868 feat(web): wire Hub sidebar, real chat messaging, and layout integration
- hub-sidebar: displays Hub connection status, agent list with create/delete
- chat: sends messages via Gateway to Hub, receives agent responses, filters by active agent
- layout: passes HubSidebar as children to AppSidebar, removes static NAV_ITEMS

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:41:03 +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
c5bf56282f feat(web): add gateway, hub, active-agent hooks and real message state
- use-gateway: GatewayClient WebSocket lifecycle with auto-connect/disconnect
- use-hub: REST polling for Hub status and agent CRUD operations
- use-active-agent: Zustand store for cross-component selected agent state
- use-messages: replace mock data with real addUser/addAssistant/clear API

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:40:50 +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
30a1fd02b8 feat(console): enable CORS for cross-origin web app requests
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:40:38 +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
db9d7ab2d7 feat(web): replace default Next.js branding with Multica icon
- Copy brand icon from gateway to web app/icon.png and public/icon.png
- Remove default favicon.ico and placeholder SVGs
- Update metadata title and description

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:31:41 +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
0975510956 feat(web): show full deviceId with copy button and toast feedback
Display full UUID instead of truncated 8-char slice. Add ghost button
with copy icon that writes deviceId to clipboard, switches to checkmark
for 2s, and shows a sonner toast confirmation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:19:57 +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
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
456d9c5429 docs: rewrite CLAUDE.md with project architecture and commands
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 21:50:12 +08:00
Naiyuan Qing
1a1c3ec086 fix: auto-load .env via --env-file flag in all tsx scripts
Eliminates the need to manually `source .env` before running dev
services. This fixes `pnpm dev` where concurrently couldn't source
.env for the console process.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 21:50:07 +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
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
2a1e5f0343 feat(web): add SidebarTrigger to Chat header
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 21:24:47 +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
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
e3643514d4 refactor(web): move sidebar layout shell to layout.tsx
Lift AppSidebar, SidebarInset and SidebarTrigger into the root layout
so page.tsx only contains page-specific content.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 21:09:06 +08:00