Skip to content

Web migration cleanup, runtime electronAPI shim, and VPS deployment#1

Merged
zhaiiker merged 1 commit into
mainfrom
fix/web-migration-cleanup-vps-ready
May 18, 2026
Merged

Web migration cleanup, runtime electronAPI shim, and VPS deployment#1
zhaiiker merged 1 commit into
mainfrom
fix/web-migration-cleanup-vps-ready

Conversation

@kiro-agent
Copy link
Copy Markdown

@kiro-agent kiro-agent Bot commented May 18, 2026

This pull request was generated by @kiro-agent 👻

Comment with /kiro fix to address specific feedback or /kiro all to address everything.
Learn about Kiro autonomous agent


Summary

This PR continues the migration from the Electron desktop edition to a pure
Node.js backend + React web UI that can run on a VPS 24/7.
The migration plan in MIGRATION_PROGRESS.md claimed to be complete, but
the running app failed because several layers still pointed at Electron
(tray, window manager, logger) and the frontend's HTTP types/imports were
broken. This PR cleans all that up and gets the project bootable as a pure
web app.

Note on testing: the sandbox where this work was done has no access to
the public npm registry, so I could not run npm install / npm run dev
to confirm a green boot end-to-end. The fixes here are based on a static
walk-through of every broken import / Electron reference. After merging,
please run npm ci && npm run build && npm start and capture any
remaining errors so we can address them in a follow-up.

What was broken

  • backend/tray.ts, backend/tray/, backend/window/, backend/logger/
    still imported electron (BrowserWindow / Tray / nativeImage / app).
  • backend/types/electron.d.ts declared an electron module ambiently.
  • backend/oauth/manager.ts imported the now-stub inAppLoginManager and
    storeManager even though neither was used.
  • frontend/src/services/api.ts and several stores imported types from
    '../../../../shared/types', which resolves outside the project tree.
  • 22 frontend components and 5 pages still called window.electronAPI.*,
    but electronAPI was never set.
  • The backend bound to 127.0.0.1 and the management API was disabled
    by default; there was no path that produced a runnable secret.
  • There was no path to serve the built UI; npm start only ran the
    proxy on the API port.

What this PR does

Cleanup

  • Delete backend/tray.ts, backend/tray/, backend/window/,
    backend/logger/, and backend/types/electron.d.ts.
  • Drop electron-updater and canvas from dependencies.
  • Re-export InAppLogin* types as export type so the isolatedModules
    flag is happy.
  • Clean unused imports from backend/oauth/manager.ts.

Type / import correctness

  • Rewrite frontend/src/types/electron.d.ts so all type imports resolve
    through @shared/types. The ElectronAPI shape is preserved as a
    client-side contract (used by the runtime shim).
  • Fix the broken '../../../../shared/types' imports in 8 frontend files.

Compatibility shim instead of a 30-file rewrite

  • Add frontend/src/services/electronShim.ts, which materialises
    window.electronAPI.* at runtime on top of ApiService. Every legacy
    call (window.electronAPI.providers.getAll(), etc.) now goes over HTTP
    to /v0/management/* automatically.
  • Emulate push-style listeners (onStatusChanged, onConfigChanged,
    onNewLog, ...) with low-frequency polling so dashboards still update.
  • Install the shim once from frontend/src/main.tsx.

Single-port web deployment

  • The Koa proxy now optionally serves the built frontend with proper MIME
    types, sane caching, and SPA index.html fallback.
    Set CHAT2API_FRONTEND_DIR or run after npm run build and the UI is
    reachable on the same port as the API.
  • Default bind address is now 0.0.0.0 so the container is reachable
    from outside.
  • On first boot the backend auto-generates a strong Management API
    secret, persists it, prints it to stdout once, and enables the API.
    Operators can pin it with CHAT2API_MANAGEMENT_SECRET in production.

VPS / 24x7 ergonomics

  • Add Dockerfile (multi-stage, non-root, prod-only deps) and
    docker-compose.yml (named volume for /data, env-driven secret).
  • Add .dockerignore, .env.example, DEPLOYMENT.md covering Caddy /
    Nginx / systemd setups, environment variables, and data persistence.
  • Surface OpenAI / Management / UI URLs in the boot log.

Files

A  Dockerfile
A  docker-compose.yml
A  .dockerignore
A  .env.example
A  DEPLOYMENT.md
A  frontend/src/services/electronShim.ts
M  backend/index.ts
M  backend/proxy/server.ts
M  backend/oauth/manager.ts
M  backend/oauth/index.ts
M  frontend/src/main.tsx
M  frontend/src/services/api.ts
M  frontend/src/types/electron.d.ts
M  frontend/src/stores/{dashboard,logs,prompts,providers,proxy,settings}Store.ts
M  frontend/src/components/models/ToolCallingPanel.tsx
M  package.json
D  backend/tray.ts
D  backend/tray/, backend/window/, backend/logger/
D  backend/types/electron.d.ts

Try it

npm ci
npm run build
npm start
# or
docker compose up -d --build

The first-run banner contains the management secret you'll need to log
into the web UI at http://<host>:8080/.

Follow-ups (out of scope for this PR)

  • Once the app is running, walk through the components that still call
    window.electronAPI.* and migrate them to call ApiService directly
    (the shim is a stop-gap, not a destination).
  • Review oauth flows in the browser context — the in-app browser login
    is now stubbed out and only manual-token entry is supported.
  • Add a /health Prometheus exporter and a dist build of the UI to
    the Docker image so the frontend/ source isn't needed at runtime.

- Remove leftover Electron-only modules: backend/tray, backend/window,
  backend/logger, backend/tray.ts and backend/types/electron.d.ts.
- Drop now-unused electron and electron-updater deps from package.json.
- Fix broken '../../../../shared/types' imports in frontend (services,
  stores, components) to the @shared/types alias.
- Add a runtime electronShim that materialises window.electronAPI on
  top of ApiService so legacy components keep working over HTTP, and
  emulate push events (proxy status, config, logs) via polling.
- Backend now optionally serves the built frontend with SPA fallback so
  a single port can host the OpenAI proxy, the management API and the
  web UI simultaneously.
- Auto-generate a Management API secret on first run and print it to
  stdout once; allow pinning via CHAT2API_MANAGEMENT_SECRET.
- Bind 0.0.0.0 by default and surface OpenAI / Management / UI URLs in
  the boot log.
- Clean up backend/oauth/manager.ts (drop dead inAppLogin imports and
  unused storeManager) and re-export inAppLogin types correctly under
  isolatedModules.
- Add Dockerfile, docker-compose.yml, .dockerignore, .env.example and
  DEPLOYMENT.md for VPS / 24x7 deployments.

Co-authored-by: ZhaiKer <216113428+zhaiiker@users.noreply.github.com>
@zhaiiker zhaiiker merged commit 70068fa into main May 18, 2026
zhaiiker pushed a commit that referenced this pull request May 21, 2026
…responsive

fix: language persistence and mobile responsiveness
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants