Unverified 提交 fc62c32e authored 作者: Will Chen's avatar Will Chen 提交者: GitHub

Add AI permission request hook and multi-platform roadmap (#2734)

## Summary - Add AI-powered permission request hook that analyzes Claude Code tool requests and classifies them as safe (GREEN), uncertain (YELLOW), or dangerous (RED) - Add comprehensive multi-platform roadmap for expanding Dyad from desktop-only to web + mobile (PWA) with freemium model ## Test plan - Verify permission-request-hook.py is properly formatted and placed in `.claude/hooks/` - Review multi-platform roadmap documentation for completeness and accuracy - No behavior changes to existing functionality 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- devin-review-badge-begin --> --- <a href="https://app.devin.ai/review/dyad-sh/dyad/pull/2734" target="_blank"> <picture> <source media="(prefers-color-scheme: dark)" srcset="https://static.devin.ai/assets/gh-open-in-devin-review-dark.svg?v=1"> <img src="https://static.devin.ai/assets/gh-open-in-devin-review-light.svg?v=1" alt="Open with Devin"> </picture> </a> <!-- devin-review-badge-end --> Co-authored-by: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
上级 41eb8e34
......@@ -179,6 +179,10 @@ def main():
tool_name = input_data.get("tool_name", "")
tool_input = input_data.get("tool_input")
# Never auto-answer AskUserQuestion - let the user respond
if tool_name == "AskUserQuestion":
sys.exit(0)
if not isinstance(tool_input, dict):
sys.exit(0)
......
# Multi-Platform Dyad: Web + Mobile Roadmap
> Generated by swarm planning session on 2026-02-14
## Summary
Turn Dyad from a desktop-only Electron app into a multi-platform product supporting web browsers and mobile devices (via PWA), while preserving the desktop app as the free, local, open-source flagship. The web version runs on server-side containers with a freemium business model. Data syncs between platforms via GitHub (code) and proprietary cloud sync (settings, chat history, metadata).
## Problem Statement
Dyad is currently limited to users who download and install a desktop app on macOS, Windows, or Linux. This creates three problems:
1. **High friction onboarding** -- competitors like v0, Bolt, Lovable, and Replit are browser-first, letting users try instantly from a link. Dyad's installation requirement kills conversion before users experience the product.
2. **No cross-device access** -- users can only interact with their projects from the machine where Dyad is installed. There's no way to check project status, send a quick prompt, or review changes from a phone or another computer.
3. **Limited viral distribution** -- browser-based tools can be shared via URL. Desktop apps require "download this app, install it, then try it." Every step loses users.
**Target users:**
- **Web:** Same developer/non-developer persona as desktop, but reached through lower-friction channels (links, embeds, social sharing)
- **Mobile (PWA):** Existing Dyad users who want lightweight access away from their desk -- reviewing, monitoring, quick chat interactions
## Scope
### In Scope (MVP -- Phase 0 + Phase 1)
- Backend service extraction from Electron main process into standalone Node.js server
- Server-side container infrastructure for live app preview (via E2B or Fly Machines)
- Web client with core chat + build + preview + deploy loop
- User authentication (GitHub OAuth, extending Dyad Pro infrastructure)
- Freemium tier (limited projects/compute on free, expanded on Pro)
- Responsive layout foundations (preparing for PWA mobile)
- Server-side database (better-sqlite3 or PostgreSQL with same Drizzle schema)
- Cloud-side secret storage for API keys (replacing Electron safeStorage)
- Basic usage tracking and rate limiting
### In Scope (Follow-up Phases)
- Full handler parity (all 40+ IPC handler categories via HTTP API)
- PWA mobile optimization (bottom tab nav, touch targets, service worker)
- GitHub-based code sync between desktop and web
- Proprietary cloud sync for settings, chat history, app metadata
- Billing/payment integration for Pro tier
- Offline messaging for PWA ("you're offline" states)
### Out of Scope
- Native mobile apps (iOS/Android via Capacitor) -- only if PWA hits hard walls
- Real-time collaboration / multi-user editing
- Desktop-to-web migration of local files (GitHub is the bridge)
- Local model support on web (Ollama/LM Studio -- desktop only)
- MCP server support on web (requires local process spawning -- desktop only)
- Capacitor/Xcode/Android Studio integration on web (desktop only)
## User Stories
### Web (Phase 1)
- As a new user, I want to try Dyad in my browser without installing anything, so I can evaluate it in under 3 minutes
- As a web user, I want to chat with the AI and see my generated app running in a live preview, so I get the same instant feedback loop as desktop
- As a web user, I want to deploy my app to Vercel from the browser, so I can ship without switching to desktop
- As a web user, I want to connect my own API keys (OpenAI, Anthropic, etc.), so I maintain the BYOK philosophy
- As a free-tier user, I want to see my usage limits clearly before I hit them, so I'm not surprised by a paywall mid-workflow
- As a free-tier user who hits limits, I want to be offered both "Upgrade to Pro" and "Download desktop (free, unlimited)" as options
### Mobile/PWA (Phase 3)
- As an existing Dyad user on my phone, I want to check my project status and recent chat history, so I can stay informed away from my desk
- As a mobile user, I want to send a quick prompt to my AI agent, so I can kick off work while commuting
- As a mobile user, I want to review generated code diffs and approve changes, so I don't block progress when away from desktop
### Sync (Phase 4)
- As a user with both desktop and web, I want my code synced via GitHub so I can work on either platform
- As a user, I want my settings, chat history, and preferences to sync across devices, so I don't have to reconfigure on each platform
## UX Design
### Platform-Specific Use Cases
| Platform | Primary Use Case | Layout |
| ---------- | ----------------------------------------------------------------- | ---------------------------------------------------------- |
| Desktop | Full creation (chat, code, preview, deploy, git, local models) | Three-panel: sidebar + chat + preview |
| Web | Full creation (cloud-backed, same loop minus local-only features) | Three-panel: sidebar + chat + preview (no custom titlebar) |
| Mobile/PWA | Monitoring, reviewing, lightweight chat | Single-panel with bottom tab navigation |
### User Flow (Web MVP)
1. User visits dyad.sh/app (or similar)
2. Sees landing page with "Try now" CTA -- no signup required for first experience
3. After 5 minutes or first meaningful action, prompted for GitHub OAuth signup
4. Creates or opens a project -> enters chat view
5. Sends prompt to AI -> streaming response with code generation
6. Server-side container spins up (5-15s, "Starting environment..." indicator)
7. Live preview appears in side panel once container is ready
8. User iterates via chat -> code updates -> preview hot-reloads
9. User deploys to Vercel via existing integration
10. Usage tracked against free tier limits (visible in sidebar)
### Key States
- **Container starting:** Progress indicator in preview panel ("Starting environment...") -- honest about 5-15s cold start
- **Container active:** Live preview iframe connected to remote container
- **Container disconnected:** "Preview disconnected -- Reconnecting..." overlay (not blank white screen)
- **Offline (PWA):** Cached project list and chat history (read-only) with "You're offline. Connect to continue building." banner
- **Free tier limit approaching:** Usage indicator in sidebar (similar to existing `AICreditStatus`)
- **Free tier limit reached:** Dual-CTA dialog: "Upgrade to Pro" or "Download desktop (free, unlimited)"
- **Build error (remote):** Same `DyadOutput`/`DyadLogs` components with "Cloud Build" label to indicate remote origin
### Interaction Details
| Interaction | Desktop | Web | Mobile/PWA |
| --------------- | -------------------------------------- | ------------------------------------------ | --------------------------------- |
| Navigation | Sidebar + keyboard shortcuts | Sidebar (collapsible) | Bottom tab bar (< 768px) |
| File attachment | Drag-drop + native dialog | Drag-drop + `<input file>` | Camera/photo library/file picker |
| Context menus | Right-click | Right-click | Long-press |
| Code editing | Monaco editor | Monaco editor | Read-only code viewer |
| Panel layout | Resizable multi-panel | Resizable multi-panel | Single panel, swipe/tab to switch |
| Preview | Local dev server in side panel | Remote container in side panel | Full-screen with toggle button |
| Window controls | Custom titlebar (macOS/Windows) | None (browser chrome) | None (OS chrome) |
| Settings | Local file pickers, node path selector | Cloud storage, account management, billing | Drill-down navigation pattern |
### Accessibility
- Touch targets: minimum 44x44pt on mobile breakpoints (current `h-7`/`h-8` buttons upscaled via responsive classes)
- Safe areas: `env(safe-area-inset-*)` for mobile notches/home indicators
- Motion sensitivity: Audit Framer Motion animations for `prefers-reduced-motion`
- Screen readers: Base UI ARIA support carries over; audit hidden radio input pattern
- Keyboard navigation: Standard browser Tab/Enter/Escape on web (no custom interception)
## Technical Design
### Architecture
**Option A: Backend Service Extraction (selected)**
Extract the Electron main process business logic into a standalone Node.js server. The existing IPC contracts (Zod schemas) become HTTP/WebSocket endpoints. Desktop Electron becomes a thin shell that spawns the local server. Web and mobile clients talk to the same API over HTTP.
```
Desktop: Electron shell -> Local Node.js server -> Local SQLite + Local filesystem
Web/PWA: Browser -> Cloud Node.js server -> Cloud DB + Container filesystem
```
**Why this approach:**
- IPC contracts map mechanically to HTTP routes (channel name -> route, Zod input -> request body, Zod output -> response body)
- Stream contracts map to SSE/WebSocket
- React frontend has zero direct Electron references in components -- it's already web-ready
- Single codebase with `PlatformProvider` context for capability-based conditional rendering
- `createClient()` in `src/ipc/contracts/core.ts` is the single function to swap (IPC invoke -> HTTP fetch)
### Components Affected
**Must Change (Infrastructure):**
| Component | Current | Target |
| ----------------------------------- | -------------------------------------- | ----------------------------------------------------------------------------------------------- |
| `src/ipc/handlers/*.ts` (40+ files) | `ipcMain.handle()` | Extract pure service functions; thin handler wrappers for both IPC and HTTP |
| `src/ipc/contracts/core.ts` | `window.electron.ipcRenderer.invoke()` | HTTP fetch adapter for web, keep IPC for desktop |
| `src/preload.ts` | Electron contextBridge | HTTP client for web |
| `src/db/index.ts` | `better-sqlite3` (local) | Same for desktop; server-side DB for web |
| `src/main/settings.ts` | File JSON + `safeStorage` | Platform-agnostic `SettingsProvider` (safeStorage for desktop, encrypted cloud storage for web) |
| `src/paths/paths.ts` | `electron.app.getPath()` | Abstract path provider |
| `src/main.ts` | Full Electron app lifecycle | Thin Electron shell; business logic extracted |
| `src/ipc/utils/git_utils.ts` | dugite + isomorphic-git | isomorphic-git for web; keep dugite for desktop |
| `src/ipc/utils/simpleSpawn.ts` | `child_process.spawn()` | Remote container execution for web |
| `electron-log` (all handlers) | Electron-specific logger | Platform-agnostic logger (pino) |
**Unchanged (Portable):**
- `src/components/**` -- React UI (zero Electron refs)
- `src/atoms/**` -- Jotai state
- `src/pages/**`, `src/routes/**` -- TanStack Router
- `src/db/schema.ts` -- Drizzle ORM schema (fully portable)
- `src/ipc/types/**` -- Zod schemas (pure validation)
### Data Model Changes
**Schema changes:**
- Add `userId` column to: `apps`, `chats`, `messages`, `versions`, `prompts`, `themes`, `languageModels` tables (for multi-tenant web)
- Add `WHERE userId = ?` to all queries in multi-tenant mode
- These are standard Drizzle migrations (`drizzle-kit generate`)
- Desktop: `userId` is always a fixed local-user ID (no behavior change)
**Database driver strategy:**
- Desktop: `better-sqlite3` (keep current, fast, synchronous)
- Web server: `better-sqlite3` per-user (simple) or PostgreSQL (scalable) -- same Drizzle schema either way
- Mobile/PWA: No local DB -- all data from web server API
**Settings storage:**
- Desktop: File JSON + `safeStorage` encryption (unchanged)
- Web: Server-side encrypted storage for API keys (AES-256-GCM with server key or secrets manager); non-sensitive settings in DB
- PWA: No local settings -- use web server
**File storage:**
- Desktop: Local filesystem (`~/dyad-apps/`) -- unchanged
- Web: Container filesystem (ephemeral per session) + persistent cloud storage per project (S3/GCS or container volumes)
### API Changes
**New HTTP/WebSocket API layer:**
IPC contracts transform mechanically:
```
IPC: ipcMain.handle("create-app", handler) -> HTTP: POST /api/create-app
IPC: ipcRenderer.invoke("create-app", data) -> HTTP: fetch("/api/create-app", {body: data})
```
Stream contracts transform to SSE:
```
StreamContract: onChunk/onEnd/onError -> SSE: event: chunk/end/error
```
**New endpoints (web-specific):**
- `POST /api/auth/login` -- GitHub OAuth flow
- `POST /api/auth/session` -- Session management
- `POST /api/containers/create` -- Provision container for project
- `DELETE /api/containers/:id` -- Teardown container
- `GET /api/containers/:id/proxy/*` -- Proxy to container dev server
- `POST /api/sync/upload` -- Upload local DB data to cloud
- `GET /api/sync/download` -- Download cloud data to local
- `GET /api/usage` -- Current usage vs. tier limits
**Authentication middleware:**
- All API endpoints require auth (except initial anonymous trial)
- Session-based (JWT or secure cookie)
- Built on existing Dyad Pro infrastructure
### Container Architecture
**Platform recommendation:** Start with E2B (purpose-built AI code execution sandboxes)
**Container lifecycle:**
1. User opens/creates project -> `ContainerManager.provision(projectId, userId)`
2. Container initializes with project files from cloud storage
3. Runs `npm install && npm run dev` inside container
4. Preview URL proxied to browser via `/api/containers/:id/proxy/*`
5. Container idle timeout: 15 min (free) / 60 min (Pro)
6. Container shutdown: files persisted to cloud storage, container destroyed
7. Next session: new container, files restored from cloud storage
**Cost controls:**
- Free tier: 1 concurrent container, 30 min/day active time
- Pro tier: 3+ concurrent containers, extended active time
- Container auto-sleep after idle timeout
- Resource limits per container (CPU, memory, disk)
### Sync Architecture
**Code sync (GitHub -- already built):**
- Existing `github_handlers.ts` with push/pull/clone/fetch/rebase
- `apps` table already stores `githubOrg`, `githubRepo`, `githubBranch`
- Desktop user pushes to GitHub; web user clones from GitHub
- No new infrastructure needed
**Everything-else sync (new proprietary service):**
- Simple export/import for MVP: user clicks "Sync to cloud" on desktop, uploads relevant table data via API
- Tables synced: `apps` (metadata only, not `path`), `chats`, `messages`, `prompts`, `themes`, `languageModels`, settings
- Conflict resolution: last-write-wins for settings/preferences (with "Settings updated from your other device" toast); explicit conflict picker for project metadata
- Lazy-load old chat histories (only sync recent chats; `messages.aiMessagesJson` can be large)
## Implementation Plan
### Phase 0: Service Extraction (Foundation)
Extract business logic from Electron main process into pure, testable service functions. No abstract interfaces -- just separation of concerns.
- [ ] Extract service functions from the 5 most critical handler files: `chat_stream_handlers.ts`, `chat_handlers.ts`, `app_handlers.ts`, `github_handlers.ts`, `settings_handlers.ts`
- [ ] Replace `electron-log` imports with platform-agnostic logger (pino) across all handler files
- [ ] Create `PlatformProvider` context and expand `useSystemPlatform` hook to detect desktop/web/mobile
- [ ] Ensure all existing desktop tests still pass (zero user-facing changes)
### Phase 1: Web MVP with Server-Side Containers
Build the web version with the full chat + build + preview + deploy experience.
**Backend:**
- [ ] Create standalone Node.js HTTP server (Hono/Express) with routes generated from IPC contracts
- [ ] Implement HTTP client adapter to replace `ipcRenderer.invoke()` for web
- [ ] Set up server-side database (better-sqlite3 or PostgreSQL with Drizzle)
- [ ] Add `userId` columns to all user-facing tables; add tenant isolation middleware
- [ ] Implement authentication (GitHub OAuth, session management, extending Dyad Pro)
- [ ] Replace `safeStorage` with server-side encrypted secret storage for API keys
- [ ] Implement cloud file storage for projects (S3/GCS)
- [ ] Set up E2B (or Fly Machines) container infrastructure
- [ ] Build `ContainerManager`: provision, proxy, idle timeout, shutdown, file persistence
- [ ] Implement streaming chat via SSE/WebSocket
- [ ] Add usage tracking middleware and rate limiting
- [ ] Security hardening: container sandboxing, input validation, resource limits
**Frontend:**
- [ ] Remove custom titlebar on web (relocate chat tabs, title bar actions)
- [ ] Replace Electron file dialogs with web `<input type="file">`
- [ ] Replace `shell.openExternal()` with `window.open()`
- [ ] Add login/signup flow (GitHub OAuth)
- [ ] Add container status widget in preview panel ("Starting environment..." indicator)
- [ ] Add "Preview disconnected -- Reconnecting..." overlay
- [ ] Add freemium usage indicator in sidebar
- [ ] Add free tier limit dialog with dual CTA (upgrade / download desktop)
- [ ] Web-compatible onboarding flow (replace YouTube link with interactive walkthrough)
- [ ] Error messaging adapted for remote builds ("Cloud Build" label on `DyadOutput`)
### Phase 2: Backend Convergence + Full Handler Parity
Unify desktop and web backends to prevent codebase divergence.
- [ ] Port remaining 35+ IPC handler categories to HTTP endpoints
- [ ] Desktop Electron app spawns local Node.js server (same server as web, running locally)
- [ ] Unified feature development: new features work on both desktop and web from a single implementation
- [ ] Audit isomorphic-git coverage vs. dugite -- implement web-compatible git for all critical operations
- [ ] Unify Dyad Pro subscription: one account, one Pro status, works on desktop + web
- [ ] Billing/payment integration (Stripe or similar)
- [ ] Feature flags for platform-specific capabilities (`hasFilesystem`, `hasShell`, `hasLocalModels`, etc.)
### Phase 3: PWA Mobile Optimization
Make the web version excellent on mobile devices.
- [ ] Responsive layout: sidebar collapses to bottom tab bar at < 768px viewport
- [ ] Touch target audit: all interactive elements >= 44x44pt on mobile breakpoints
- [ ] Safe area support: `env(safe-area-inset-*)` for notches/home indicators
- [ ] Service worker for PWA installability and offline shell
- [ ] Web app manifest for install-to-homescreen
- [ ] Mobile-specific input adaptations: camera/photo picker for file attachments, virtual keyboard handling
- [ ] Offline state: cached project list + chat history (read-only) with offline banner
- [ ] Chat/preview as swipeable tabs instead of side-by-side panels on mobile
- [ ] Code viewer (read-only) replacing Monaco editor on mobile
- [ ] Long-press for context menus (replacing right-click)
### Phase 4: Cross-Device Sync
Enable seamless work across desktop and web.
- [ ] GitHub code sync: prominent "Push to GitHub" / "Pull from GitHub" UI flows
- [ ] Sync API: export/import for chat history, messages, prompts, themes, settings, language model configs
- [ ] Sync status indicator in sidebar footer (checkmark/spinner/warning)
- [ ] Conflict resolution: last-write-wins for settings (with toast notification), explicit picker for project metadata
- [ ] First-time sync setup flow: "Sign in -> Choose apps to sync -> Done"
- [ ] Lazy-load old chat histories during sync (skip large `aiMessagesJson` for old chats)
- [ ] Desktop "Connect to cloud" opt-in flow
### Phase 5: Polish + Advanced Features
- [ ] Audit and optimize container cold start times
- [ ] Advanced offline support (queued operations that sync when back online)
- [ ] Evaluate native mobile (Capacitor) if PWA hits hard walls (push notifications, performance)
- [ ] Collaboration features (share project link, real-time co-editing)
- [ ] Advanced sync (CRDT-based or operational transforms if last-write-wins proves insufficient)
## Testing Strategy
- [ ] **Unit tests:** Extract service functions are tested independently with mocked platform APIs (Vitest, existing test infrastructure)
- [ ] **Integration tests:** HTTP API layer tested with supertest -- verify Zod contract compatibility between IPC and HTTP transports
- [ ] **E2E tests (Desktop):** Keep existing Playwright Electron tests; verify Electron shell + extracted backend still works
- [ ] **E2E tests (Web):** Standard Playwright browser tests against the web app; cover auth flow, chat+preview loop, deploy, freemium limits
- [ ] **Container tests:** Integration tests for container provisioning, preview proxying, idle timeout, crash recovery
- [ ] **Sync tests:** Round-trip tests for GitHub code sync and proprietary data sync; conflict resolution scenarios
- [ ] **Responsive tests:** Playwright at mobile viewport sizes for PWA breakpoints, touch target sizes
- [ ] **Contract tests:** Automated verification that IPC contracts and HTTP API contracts stay in sync (they share Zod schemas)
- [ ] **Security tests:** Container escape testing, API key storage encryption verification, tenant isolation verification
## Risks & Mitigations
| Risk | Likelihood | Impact | Mitigation |
| --------------------------------------------------------------- | ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------- |
| Container infrastructure complexity delays Phase 1 | H | H | Start with managed platform (E2B) to minimize ops; self-host only at scale |
| Container costs exceed freemium revenue | M | H | Aggressive idle timeouts, free tier time limits, monitor cost-per-user closely |
| Two-codebase divergence (desktop vs. web backend) | H | M | Timebox: Phase 2 convergence must start within 6 months of web MVP launch |
| User trust concerns storing API keys in cloud | M | H | Clear trust indicators in UI, key rotation support, consider browser-side key storage with proxy pattern |
| isomorphic-git missing critical git features for web | M | M | Audit git usage early; fall back to server-side git proxy for unsupported operations |
| Freemium conversion < 5% makes web unsustainable | M | H | Track conversion from day one; adjust free tier limits; desktop download as fallback CTA |
| Container security (arbitrary npm install, user code execution) | M | H | Use gVisor/Firecracker sandboxing; network isolation; resource limits; security audit before public launch |
| Sync conflicts cause data loss | L | H | Last-write-wins with confirmation toast for low-stakes data; explicit conflict UI for high-stakes data; never auto-delete |
| PWA limitations frustrate mobile users | M | L | Monitor PWA capability gaps; Capacitor wrapping is the escape hatch if needed |
| Desktop development slows due to web investment | M | M | Run as parallel tracks; shared component library (Storybook already set up); convergence in Phase 2 |
## Open Questions
1. **Container platform selection:** E2B vs. Fly Machines vs. self-hosted. Recommend E2B proof-of-concept spike as first action to validate latency, cost, and reliability.
2. **Exact freemium tier limits:** How many free projects? How much active container time per day? What storage limits? These directly control infrastructure burn rate and need data from the E2B spike to set.
3. **Web version URL/branding:** Is it dyad.sh/app? app.dyad.sh? A separate domain? Affects auth cookies, CORS, and SEO.
4. **Desktop-only feature messaging:** When a web user encounters a feature that only works on desktop (local models, MCP servers, Capacitor builds), what's the UX? Banner? Tooltip? Redirect to download?
5. **Existing DYAD_ENGINE_URL pattern:** The codebase already has a remote engine URL concept. How much of the backend extraction has already been contemplated or partially built? This could accelerate Phase 0-1 significantly.
## Decision Log
| Decision | Options Considered | Chosen | Reasoning |
| ----------------------------- | ---------------------------------------------------------------- | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Web preview approach | WebContainers, server-side containers, deploy-only (no preview) | Server-side containers | Preserves Dyad's core value prop (instant preview). WebContainers is Chromium-only and can't run shell commands. Deploy-only is too degraded. |
| Business model | Free web, paid-only web, freemium | Freemium | Desktop stays free/local (preserves open-source identity). Web Pro is the upsell. Freemium maximizes reach while generating revenue to cover infrastructure. |
| Mobile approach | Native (Capacitor), PWA, defer entirely | PWA first | Lowest cost, instant updates, no App Store friction. Mobile use case is lightweight (review, chat) which PWA handles well. Capacitor is the escape hatch if needed. |
| Data sync model | GitHub only, proprietary sync only, hybrid, no sync | Hybrid (GitHub for code + proprietary for everything else) | GitHub for code leverages existing infrastructure and aligns with "Bridge, Don't Replace." Proprietary sync for settings/metadata fills the gap GitHub can't cover. |
| Backend architecture | Cloud-only, local-only-everywhere, backend extraction (Option A) | Backend extraction | Preserves local-first for desktop. Same business logic serves both local (Electron) and cloud (web). IPC contracts map mechanically to HTTP. |
| Phase ordering | Abstraction first, web backend first, simultaneous | Service extraction first, then web backend | PM argued abstraction-first is premature. Eng agreed to drop TransportAdapter but keep service extraction. Build working web backend, then converge. |
| Database for web | sql.js (WASM in browser), server-side SQLite, PostgreSQL | Server-side DB | Web version is inherently cloud-based. No reason to run SQLite in browser when there's a server. Same Drizzle schema works with any driver. |
| Single vs. separate frontends | Single React codebase, separate frontends per platform | Single codebase | Frontend has zero direct Electron references. Platform differences handled via PlatformProvider context and responsive CSS. Separate frontends would diverge immediately. |
---
_Generated by dyad:swarm-to-plan_
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论