Packaged renderer was bundling two copies of @tanstack/react-query because
apps/desktop imported it without declaring the dep, so Node resolution fell
through to the hoisted root variant (react@19.2.0, pulled in by apps/mobile),
while packages/core resolved to the catalog variant (react@19.2.3). Two physical
paths → two QueryClientContexts → "No QueryClient set" white screen on launch.
- Declare @tanstack/react-query, lucide-react, zustand as direct deps via catalog:
so apps/desktop resolves to the same peer variant as packages/core/views.
- Add @tanstack/react-query to renderer dedupe as a defense-in-depth bound
against future peer drift.
Verified: realpaths under apps/desktop, packages/core, packages/views all point
to @tanstack+react-query@5.96.2_react@19.2.3; production renderer bundle now
contains exactly one "use QueryClientProvider to set one" string (was 2) and
no useQueryClient\$1 suffix.
Co-authored-by: multica-agent <github@multica.ai>
* feat(desktop): brand dev build as Multica Canary with bundled icon
pnpm dev:desktop ran under the stock Electron name and default icon,
making it indistinguishable from any other Electron dev app in the dock.
Set a Canary app name + userData path and point the macOS dock icon and
BrowserWindow icon at the bundled resources/icon.png so the dev build is
visually branded.
* feat(desktop): allow overriding renderer port via DESKTOP_RENDERER_PORT
Lets a second worktree run `pnpm dev:desktop` while a primary checkout
already holds the default Vite dev port 5173 — required to actually
exercise the "Multica Canary" branding in isolation.
* feat(desktop): rebrand Electron.app Info.plist so dev shows Multica Canary
app.setName() can't override the macOS menu bar title or Cmd+Tab label
— those come from CFBundleName baked into the running bundle's
Info.plist. Patch the bundled Electron.app's plist during `pnpm
dev:desktop` so dev launches read "Multica Canary" everywhere, not
"Electron". Idempotent; unlinks before rewriting so we don't mutate a
pnpm-store inode shared with other projects.
Drops the VITE_REMOTE_API Vite-proxy path introduced in be8b099c.
The remote-backend proxy is no longer needed; direct dev via
VITE_API_URL covers every workflow we still support.
- remove dev:desktop:remote (root) and dev:remote (desktop) scripts
- revert electron.vite.config.ts to a flat config — no loadEnv, no
per-route proxies
- simplify App.tsx: single apiBaseUrl/wsUrl branch, and
DAEMON_TARGET_API_URL derives directly from VITE_API_URL
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Set webSecurity: false in BrowserWindow to bypass CORS when
connecting to remote API (standard Electron practice)
- Fix renderer dev server to port 5173 so localStorage persists
across restarts (prevents losing login state)
- Extract MulticaIcon and ThemeProvider to packages/ui (remove duplication)
- Extract shared CSS (scrollbar, shiki, entrance-spin) to packages/ui/styles/base.css
- Add NavigationAdapter.openInNewTab/getShareableUrl for platform-agnostic navigation
- Fix window.open() / window.location.href in shared views to use NavigationAdapter
- Add resolve.dedupe for React in electron-vite config
- Fix desktop tsconfig (noImplicitAny: true)
- Use catalog: for all desktop dependencies
- Add shadcn + tw-animate-css to desktop dependencies (fix phantom deps)
- Add typecheck scripts to all shared packages
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Root cause: "type": "module" made Node.js treat all .js as ESM, but
Electron loads preload via require() (CJS). Removing it makes .js
default to CJS, which is what Electron expects. No rollup overrides needed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Preload output as .cjs so Node.js treats it as CJS regardless of
"type": "module" in package.json
- Add electron-vite dev server ports (5173, 5174) to default CORS origins
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Preload must be CJS (Electron loads it via require), force format: "cjs"
and entryFileNames: "[name].js" so output matches main's reference
- @source paths were 4 levels up but need 5 (src/renderer/src/ to root)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace scattered API_URL, MAIN_VITE_API_URL, and RENDERER_VITE_API_URL
with a single MULTICA_API_URL across all apps and packages.
- Desktop: use envPrefix to expose MULTICA_* to main process, rename
RENDERER_VITE_API_URL → RENDERER_VITE_MULTICA_API_URL, remove
MAIN_VITE_API_URL (now read directly via MULTICA_API_URL)
- Web: add .env.development with MULTICA_API_URL, enforce required check
in next.config.ts, update .gitignore to allow .env.development
- Core: make MULTICA_API_URL required in api-client (no silent fallback)
- Scripts: pass MULTICA_API_URL in dev-local.sh for web process
- Turbo: update globalEnv from API_URL to MULTICA_API_URL
- Docs: update references to the new env var name
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move renderer files to src/renderer/src/ (electron-vite standard)
- Move index.html to src/renderer/
- Remove root: '.' config that broke HMR
- Use ELECTRON_RENDERER_URL instead of VITE_DEV_SERVER_URL
- Update tsconfig paths for new structure
This fixes hot module replacement not working after the monorepo
restructure. The previous non-standard directory layout with root: '.'
caused electron-vite's HMR to fail silently.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>