res.statusText is always empty under HTTP/2, causing "Gateway error: "
with no detail. Now reads the JSON response body to surface the
server's actual error message and always includes the status code.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Track .env.development and .env.production for desktop app
- Add MAIN_VITE_API_URL to all env files
- Remove hardcoded GATEWAY_URL from dev scripts (now in .env.development)
- Update .env.example with full documentation of all env vars
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Read API host from import.meta.env.RENDERER_VITE_API_URL instead of
hardcoding it, so staging/dev builds point to the correct backend.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
In packaged Electron builds, @multica/core is externalized and .env
files are excluded. Bridge import.meta.env.MAIN_VITE_API_URL (injected
at build time by electron-vite) to process.env.MULTICA_API_URL so that
getApiBaseUrl() reads the correct value in staging/test environments.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Extract useQRToken and useCountdown hooks to qr-hooks.ts so qr-code.tsx
only exports components (fixes react-refresh/only-export-components)
- Remove unused useRef import from connect-step.tsx
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
DeviceConfirmDialog only exists in the main Layout, so verify
requests were timing out during onboarding. Since the user is
actively generating the QR code, auto-approve and show a success
state instead.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove the user-facing ability to create custom Telegram bots via BotFather.
Non-technical users should only need to message @multica_bot on Telegram.
- Disable telegramChannel plugin registration in initChannels()
- Remove ConnectStep from onboarding flow (Privacy → Provider → Start)
- Replace TelegramCard with simple text pointing to @multica_bot
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix publish repo from "multica" to "super-multica"
- Add zip to mac targets (required for electron-updater auto-updates)
- Enable hardenedRuntime (required for notarization)
- Add notarize config with teamId placeholder
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 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>
Add WebkitAppRegion drag to login page background areas so the window
can be dragged on macOS. Mark the sign-in button as no-drag to keep it
clickable.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Keep LocalChat mounted at the Layout level with CSS visibility toggle
instead of unmounting on route change, preserving messages, streaming
state, and IPC subscriptions when switching sidebar tabs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move auth callback listener setup before async operations
- Add unique ID to welcome toast to prevent duplicates
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 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>
Add fetch wrapper for desktop renderer to call Multica backend REST API.
Attaches sid, device-id, and os-type headers automatically using
useAuthStore and electronAPI.auth.getDeviceIdHeader().
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Change from storing raw UUID to storing encrypted format
- Consistent with devv-sdk and Web implementation
- Auto-migrate old UUID format to new encrypted format
- Validate device ID format (40 hex characters)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Generate UUID-based Device ID on first launch
- Store deviceId in auth.json (persists across logins/logouts)
- Add double SHA-256 encryption (consistent with Web)
- Expose getDeviceId and getDeviceIdHeader IPC methods
- Fix callback path to only accept /callback (prevent duplicate toasts)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 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>
- Add tagline and animation to login page
- Add toast notification on login success
- Add toast notification on logout
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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>
- Add auth IPC handlers (main process)
- Add auth store with Zustand (renderer)
- Add login page with branded UI
- Add AuthGuard for protected routes
- Add user dropdown menu in sidebar footer
- Support deep link (multica://) for production
- Support local HTTP callback for development
Reference: https://github.com/CapSoftware/Cap
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
electron-builder detects CI and implicitly triggers publishing to GitHub
Releases, which fails without GH_TOKEN. Adding --publish never to the
build script so CI only builds without attempting to publish.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Clarify that local dev needs no .env (GATEWAY_URL set in package.json)
- Document GATEWAY_URL override for local gateway testing
- Add detailed explanation of both URLs (Gateway vs API Server)
- List dev/prod values for each environment variable
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 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>
`pnpm dev` now connects to dev gateway by default. Support runtime
GATEWAY_URL env var to override, so no per-worktree .env setup needed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Refactor QR code component with extracted hooks (useQRToken, useCountdown, useCopyToClipboard)
- Extract reusable sub-components (QRCodeFrame, ExpiryTimer, CopyLinkButton)
- Extract QRCodeCard and DevicesCard components in clients page
- Add GatewayStatus indicator for connection state
- Minor styling fix for empty device list state
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The listStates IPC handler now waits for any "starting" status to
settle (max 3.5s) before returning, ensuring the UI always gets the
final status (running/error) instead of the transient "starting" state.
Also fixes unused variable lint warning in profile page.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 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>