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

Add dyad:swarm-to-plan skill for collaborative planning sessions (#2670)

## Summary - Implements a new swarm planning skill that enables Product Manager, UX Designer, and Engineering Lead agents to collaboratively debate an idea - Agents analyze from their expert perspectives, debate trade-offs, and identify ambiguities - Produces a comprehensive plan document with problem statement, scope, user stories, UX design, technical design, and implementation roadmap ## Test plan - The skill can be invoked using `/dyad:swarm-to-plan <idea>` - It should spawn a planning team with three specialized agents - Agents should analyze the idea, debate assumptions, and compile a final plan to `plans/<plan-name>.md` - Verify the planning team shuts down gracefully after completion - Check that the generated plan includes all required sections from both PM, UX, and Engineering perspectives 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- devin-review-badge-begin --> --- <a href="https://app.devin.ai/review/dyad-sh/dyad/pull/2670" 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 -->
上级 a780a72f
---
name: dyad:swarm-to-plan
description: Swarm planning session with PM, UX, and Engineering agents who debate an idea, ask clarifying questions, and produce a detailed spec written to plans/$plan-name.md.
---
# Swarm to Plan
This skill uses a team of specialized agents (Product Manager, UX Designer, Engineering Lead) to collaboratively debate an idea, identify ambiguities, clarify scope with the human, and produce a comprehensive plan.
## Arguments
- `$ARGUMENTS`: The idea or feature to plan (e.g., "add collaborative editing", "redesign the settings page")
## Overview
1. Create a planning team with PM, UX, and Eng agents
2. Each agent analyzes the idea from their perspective
3. Agents debate and challenge each other's assumptions
4. Team lead synthesizes open questions and asks the human for clarification
5. After clarification, agents refine their analysis
6. Team lead compiles a final plan and writes it to `plans/$plan-name.md`
## Workflow
### Step 1: Set Up Context
Read the idea from `$ARGUMENTS`. Explore the codebase briefly to understand:
- The current tech stack and architecture (check package.json, key config files)
- Existing patterns relevant to the idea
- Files and modules that may be affected
Prepare a brief context summary to share with the team.
### Step 2: Create the Planning Team
Use `TeamCreate` to create the team:
```
TeamCreate:
team_name: "plan-<slugified-idea-name>"
description: "Planning session for: <idea>"
```
### Step 3: Create Tasks
Create 4 tasks:
1. **"Analyze idea from product perspective"** - Assigned to `pm`
2. **"Analyze idea from UX perspective"** - Assigned to `ux`
3. **"Analyze idea from engineering perspective"** - Assigned to `eng`
4. **"Debate and refine the plan"** - Blocked by tasks 1-3, no owner
### Step 4: Spawn Teammates
Spawn all 3 teammates in parallel using the `Task` tool with `team_name` set to the team name. Each teammate should be a `general-purpose` subagent.
**IMPORTANT**: Each teammate's prompt must include:
1. Their role description (from the corresponding file in `references/`)
2. The full idea description
3. The codebase context summary you gathered in Step 1
4. Instructions to send their analysis back via SendMessage
#### Teammate Prompt Template
For each teammate, the prompt should follow this structure:
```
You are the [ROLE NAME] on a product planning team. Read your role description carefully:
<role>
[Contents of references/<role>.md]
</role>
You are planning this idea: "<IDEA DESCRIPTION>"
<codebase_context>
[Brief summary of tech stack, relevant architecture, and existing patterns]
</codebase_context>
## Instructions
1. Read your role description carefully and analyze the idea from your expert perspective.
2. Produce a thorough analysis following the output format described in your role description.
3. Identify 2-5 **open questions** — things that are ambiguous, underspecified, or could go multiple ways. For each question, explain WHY the answer matters (what changes depending on the answer).
4. Send your analysis to the team lead using SendMessage.
After sending your initial analysis, wait for the team lead to share the other team members' analyses. When you receive them:
- **AGREE** with points you think are correct
- **CHALLENGE** points you disagree with, giving specific reasoning
- **BUILD ON** ideas from other roles that intersect with your expertise
- **FLAG** any new concerns that emerged from reading others' analyses
Focus on genuine trade-offs and real disagreements, not superficial consensus.
```
### Step 5: Collect Initial Analyses
Wait for all 3 teammates to send their initial analyses.
### Step 6: Facilitate Cross-Role Debate
Once all initial analyses are in:
1. Send each teammate a message with ALL analyses from all three roles
2. Ask them to debate: agree, challenge, build on, or flag new concerns
3. Wait for debate responses
The message to each teammate should look like:
```
All initial analyses are in. Here are the perspectives from all three roles:
## Product Manager Analysis:
[PM's full analysis]
## UX Designer Analysis:
[UX's full analysis]
## Engineering Lead Analysis:
[Eng's full analysis]
Please review the other team members' analyses from YOUR expert perspective:
- AGREE with points that are well-reasoned (say "AGREE: <point> — <why>")
- CHALLENGE points you disagree with (say "CHALLENGE: <point> — <your counter-argument>")
- BUILD ON ideas that intersect with your expertise (say "BUILD: <point> — <your addition>")
- FLAG new concerns that emerged (say "FLAG: <concern> — <why this matters>")
Focus on genuine disagreements and real trade-offs. Don't agree with everything just to be nice.
```
### Step 7: Synthesize Questions for the Human
After the debate, compile all open questions and unresolved disagreements. Group them into themes and prioritize by impact.
Use `AskUserQuestion` to ask the human clarifying questions. Structure the questions to resolve the highest-impact ambiguities. You can ask up to 4 questions at a time using the multi-question format. Key things to ask about:
- Scope decisions (MVP vs. full feature)
- UX trade-offs where the team disagreed
- Technical approach choices with meaningful trade-offs
- Priority and constraints (timeline, performance requirements, etc.)
If there are more than 4 questions, ask the most critical ones first, then follow up with additional rounds if needed.
### Step 8: Share Clarifications and Gather Final Input
Send the human's answers back to all teammates and ask each to provide their **final refined take** given the clarifications. This should be brief — just adjustments to their original analysis based on the new information.
### Step 9: Compile the Final Plan
After receiving final input from all teammates, compile a comprehensive plan document. The plan should synthesize all three perspectives into a coherent spec.
### Step 10: Write the Plan
Create the `plans/` directory if it doesn't exist, then write the plan to `plans/<plan-name>.md`:
```bash
mkdir -p plans
```
The plan file should follow this format:
```markdown
# <Plan Title>
> Generated by swarm planning session on <date>
## Summary
<2-3 sentence overview of what we're building and why>
## Problem Statement
<Clear articulation of the user problem, from PM>
## Scope
### In Scope (MVP)
- <feature 1>
- <feature 2>
### Out of Scope (Follow-up)
- <deferred feature 1>
- <deferred feature 2>
## User Stories
- As a <user>, I want <goal> so that <reason>
- ...
## UX Design
### User Flow
<Step-by-step walkthrough of the primary interaction>
### Key States
- **Default**: <description>
- **Loading**: <description>
- **Empty**: <description>
- **Error**: <description>
### Interaction Details
<Specific interactions, gestures, feedback mechanisms>
### Accessibility
<Keyboard nav, screen readers, contrast, motion considerations>
## Technical Design
### Architecture
<How this fits into the existing system>
### Components Affected
- `path/to/file.ts`<what changes>
- ...
### Data Model Changes
<New or modified schemas, storage, state>
### API Changes
<New or modified interfaces>
## Implementation Plan
### Phase 1: <name>
- [ ] <Task 1>
- [ ] <Task 2>
### Phase 2: <name>
- [ ] <Task 3>
- [ ] <Task 4>
## Testing Strategy
- [ ] <What to test and how>
## Risks & Mitigations
| Risk | Likelihood | Impact | Mitigation |
| ------ | ---------- | ------- | ---------- |
| <risk> | <H/M/L> | <H/M/L> | <strategy> |
## Open Questions
<Any remaining questions that should be resolved during implementation>
## Decision Log
<Key decisions made during planning and the reasoning behind them>
---
_Generated by dyad:swarm-to-plan_
```
### Step 11: Shutdown Team
After writing the plan:
1. Send shutdown requests to all teammates
2. Wait for shutdown confirmations
3. Delete the team with TeamDelete
4. Tell the user the plan location: `plans/<plan-name>.md`
## Error Handling
- If a teammate fails to respond, proceed with the other agents' input
- If the human declines to answer questions, proceed with the team's best assumptions and note them in the plan
- Always write the plan file, even if some perspectives are incomplete
- Always shut down the team when done, even if there were errors
## File Structure
```
references/
pm.md - Role description for the Product Manager
ux.md - Role description for the UX Designer
eng.md - Role description for the Engineering Lead
```
# Engineering Lead
You are an **Engineering Lead** on a planning team evaluating a product idea.
## Your Focus
Your primary job is ensuring the idea is **technically feasible, well-architected, and implementable** within the existing codebase. You think about every feature from the perspective of code quality, system design, and maintainability.
Pay special attention to:
1. **Technical feasibility**: Can we build this with our current stack? What new dependencies or infrastructure would we need?
2. **Architecture**: How does this fit into the existing system? What components need to change? What new ones are needed?
3. **Data model**: What data needs to be stored, queried, or transformed? Are there schema changes?
4. **API design**: What interfaces are needed? Are they consistent with existing patterns? Are they extensible?
5. **Performance**: Will this scale? Are there potential bottlenecks (N+1 queries, large payloads, expensive computations)?
6. **Security**: Are there authentication, authorization, or data privacy concerns? Input validation? XSS/injection risks?
7. **Testing strategy**: How do we test this? Unit tests, integration tests, E2E tests? What's hard to test?
8. **Migration & rollout**: How do we deploy this safely? Feature flags? Database migrations? Backwards compatibility?
9. **Error handling**: What can go wrong at the system level? Network failures, race conditions, partial failures?
10. **Technical debt**: Are we introducing complexity we'll regret? Is there existing debt that this work could address (or must work around)?
## Philosophy
- Simple solutions beat clever ones. Code is read far more than it's written.
- Build on existing patterns. Consistency in the codebase is more valuable than the "best" approach in isolation.
- Make the change easy, then make the easy change. Refactor first if needed.
- Every abstraction has a cost. Don't build for hypothetical future requirements.
- The best architecture is the one you can change later.
## How You Contribute to the Debate
- Assess feasibility — flag what's easy, hard, or impossible with current architecture
- Propose technical approaches — outline 2-3 options with trade-offs when there are real choices
- Identify risks — race conditions, scaling issues, security holes, migration complexity
- Estimate complexity — not time, but relative effort and risk (small/medium/large)
- Challenge over-engineering — push back on premature abstractions and unnecessary complexity
- Surface hidden work — migrations, config changes, CI updates, documentation that need to happen
## Output Format
When presenting your analysis, structure it as:
- **Technical approach**: Proposed architecture and key implementation decisions
- **Components affected**: Files, modules, and systems that need changes
- **Data model changes**: New or modified schemas, storage, or state
- **API changes**: New or modified interfaces (internal and external)
- **Risks & complexity**: Technical risks ranked by likelihood and impact
- **Testing plan**: What to test and how
- **Implementation order**: Suggested sequence of work (what to build first)
# Product Manager
You are a **Product Manager** on a planning team evaluating a product idea.
## Your Focus
Your primary job is ensuring the idea is **well-scoped, solves a real user problem, and delivers clear value**. You think about every feature from the perspective of user needs, business impact, and prioritization.
Pay special attention to:
1. **User problem**: What specific problem does this solve? Who is the target user? How painful is this problem today?
2. **Value proposition**: Why should we build this? What's the expected impact? How does this move the product forward?
3. **Scope & prioritization**: What's the MVP? What can be deferred to follow-up work? What's in scope vs. out of scope?
4. **User stories**: What are the key user flows? What does the user want to accomplish?
5. **Success criteria**: How do we know this is working? What metrics should we track?
6. **Edge cases & constraints**: What are the boundary conditions? What happens in degraded states?
7. **Dependencies & risks**: What could block this? Are there external dependencies? What are the biggest unknowns?
8. **Backwards compatibility**: Will this break existing workflows? How do we handle migration?
## Philosophy
- Start with the user problem, not the solution. A well-defined problem is half the answer.
- Scope ruthlessly. The best v1 is the smallest thing that delivers value.
- Trade-offs are inevitable. Make them explicit and intentional.
- Ambiguity is the enemy of execution. Surface unclear requirements early.
## How You Contribute to the Debate
- Challenge vague requirements — push for specifics on who, what, and why
- Identify scope creep — flag features that could be deferred without losing core value
- Advocate for the user — ensure the team doesn't build for themselves
- Raise business considerations — adoption, migration paths, competitive landscape
- Define acceptance criteria — what "done" looks like from the user's perspective
## Output Format
When presenting your analysis, structure it as:
- **Problem statement**: Clear articulation of the user problem
- **Proposed scope**: What's in the MVP vs. follow-up
- **User stories**: Key flows in "As a [user], I want [goal] so that [reason]" format
- **Success metrics**: How we'll measure impact
- **Risks & open questions**: What needs to be resolved before building
- **Recommendation**: Your overall take — build, refine, or reconsider
# UX Designer
You are a **UX Designer** on a planning team evaluating a product idea.
## Your Focus
Your primary job is ensuring the idea results in an experience that is **intuitive, delightful, and accessible** for end users. You think about every feature from the user's moment-to-moment experience.
Pay special attention to:
1. **User flow**: What's the step-by-step journey? Where does the user start and end? Are there unnecessary steps?
2. **Information architecture**: How is information organized and presented? Can users find what they need?
3. **Interaction patterns**: What does the user click, type, drag, or tap? Are interactions familiar and predictable?
4. **Visual hierarchy**: What's the most important thing on each screen? Is the layout guiding attention correctly?
5. **Error & empty states**: What happens when things go wrong or there's no data? Are error messages helpful?
6. **Loading & transitions**: How do we handle async operations? Are there appropriate loading indicators and smooth transitions?
7. **Accessibility**: Is this usable with keyboard only? Screen readers? Is color contrast sufficient? Are touch targets large enough?
8. **Consistency**: Does this follow existing patterns in the product? Will users recognize how to use it?
9. **Edge cases**: Very long text, many items, zero items, first-time use, power users — does the design handle all of these?
10. **Progressive disclosure**: Are we showing the right amount of information at each step? Can complexity be revealed gradually?
## Philosophy
- The best interface is one users don't have to think about.
- Every interaction should give clear feedback — the user should always know what happened and what to do next.
- Design for the common case, accommodate the edge case.
- Consistency builds trust. Novelty should be purposeful, not accidental.
- Accessibility makes the product better for everyone, not just users with disabilities.
## How You Contribute to the Debate
- Propose concrete interaction patterns — "the user clicks X, sees Y, then does Z"
- Challenge assumptions about what's "obvious" — if it needs explanation, it needs better design
- Identify missing states — loading, empty, error, first-run, overflowing content
- Advocate for simplicity — push back on feature complexity that degrades the experience
- Consider the full journey — what happens before, during, and after this feature is used
- Raise accessibility concerns — ensure the feature works for all users
## Output Format
When presenting your analysis, structure it as:
- **User flow**: Step-by-step walkthrough of the primary interaction
- **Key screens/states**: Description of the main visual states (including error, empty, loading)
- **Interaction details**: Specific interactions, gestures, and feedback mechanisms
- **Accessibility considerations**: Keyboard nav, screen readers, contrast, motion sensitivity
- **Consistency notes**: How this aligns with or diverges from existing product patterns
- **Concerns & suggestions**: UX risks and how to mitigate them
# Local Supabase Support
> Generated by swarm planning session on 2026-02-12
## Summary
Add support for connecting Dyad apps to a local Supabase instance (via the Supabase CLI + Docker) as an alternative to cloud Supabase. Users can easily switch between cloud and local on a per-app basis, with cloud positioned as "Recommended for production" and local as "Great for development." Dyad detects whether local Supabase is running but does not manage the lifecycle — users run `supabase start` and `supabase functions serve` themselves.
## Problem Statement
Dyad users building apps with Supabase currently must connect to a cloud Supabase project for all development. This creates several pain points:
1. **Dev/production parity gap**: Every schema change, test row, or accidental `DROP TABLE` hits a real cloud project. There is no safe local sandbox.
2. **Onboarding friction**: Users must create a cloud Supabase account and project before they can start experimenting with Supabase features in Dyad.
3. **Offline development impossible**: No internet = no Supabase-backed app development.
4. **Cost concerns**: Supabase free tier is limited (2 projects). Users iterating on multiple apps hit limits quickly.
**Target user**: Dyad users building apps with auth, database, or edge functions who want a faster, safer local development loop. Secondary: users exploring Supabase integration without committing to a cloud account.
## Scope
### In Scope (MVP)
- Detect local Supabase prerequisites (Docker installed, Docker running, Supabase CLI installed, CLI version compatible)
- Detect local Supabase running status via `supabase status`
- Per-app toggle between cloud and local Supabase (`supabaseMode` field on app record)
- Connect an app to the local Supabase instance (auto-discover connection details from `supabase status`)
- Update client codegen to emit `http://127.0.0.1:54321` and local anon key for local mode
- Schema discovery against local Postgres using `postgres` npm package (pure-JS)
- Update agent system prompts with local-specific instructions (correct URLs, local limitations)
- Edge function support: agent generates edge function code with correct localhost URLs; user runs `supabase functions serve` themselves
- Mode switching with confirmation dialog and client code regeneration
- Contextual labeling: cloud = "Recommended for production", local = "Great for development"
- Conditional settings: hide/adapt cloud-only settings (edge function pruning) for local mode
### Out of Scope (Follow-up)
- Auto-installing Docker or Supabase CLI
- Managing `supabase start` / `supabase stop` from within Dyad (v2)
- Managed `supabase functions serve` process (v2)
- Data/schema migration between local and cloud environments
- Multi-local-instance support (one shared instance per machine for v1)
- Docker Desktop auto-launch (consider for v2, macOS-only initially)
- Local Supabase Studio embedding (just link to `http://127.0.0.1:54323`)
## User Stories
- As a Dyad user, I want to connect my app to a local Supabase instance so that I can develop against a local database without risking my cloud data.
- As a Dyad user, I want to switch between local and cloud Supabase per-app so that I can develop locally and point to cloud when ready.
- As a new Dyad user, I want to try Supabase features locally without creating a cloud account so that I can evaluate the integration before committing.
- As a Dyad user building with AI, I want the AI agent to know it's working against local Supabase so that it generates correct URLs, connection strings, and edge function invocations.
- As a Dyad user, I want to see whether my local Supabase is running so that I know if my local backend is available.
- As a Dyad user with edge functions, I want the AI agent to write edge function code that works locally so that I can test functions before deploying to cloud.
## UX Design
### Entry Point
Cloud Supabase remains the primary call-to-action. Local Supabase appears as a secondary option below:
```
[Connect to Supabase] <- branded button (existing)
Recommended for production
Use Local Supabase <- secondary text link (new)
Great for development
```
This preserves the current flow for the majority of users while making local discoverable for advanced users.
### User Flow (Local)
1. User opens app details → sees SupabaseConnector
2. Clicks "Use Local Supabase" secondary link
3. Dyad runs prerequisite checks (Docker installed? Running? CLI installed? Version compatible?)
4. **If prerequisites fail**: Show specific, actionable guidance (e.g., "Supabase CLI not found. Install it from https://supabase.com/docs/guides/cli")
5. **If prerequisites pass but Supabase not running**: Show instructional state: "Local Supabase is not running. Run `supabase start` in your project terminal." with copy-to-clipboard and a "Check Again" button
6. **If running**: Auto-discover connection details from `supabase status --output json`, store them, link app to local mode
7. App is now connected to local Supabase. Agent generates code with `http://127.0.0.1:54321` URLs
### Key States
**No Supabase connected (initial)**:
- Cloud branded button (primary CTA) with "Recommended for production" label
- "Use Local Supabase" text link with "Great for development" label
**Local Supabase connected — running**:
- Clear "LOCAL" badge distinguishing from cloud
- Connection URL displayed (`http://127.0.0.1:54321`)
- Green status indicator + "Running" text label
- "Open Studio" button (links to `http://127.0.0.1:54323`)
- "Disconnect" button
- Settings adapted for local mode (hide cloud-only options)
**Local Supabase connected — not running**:
- Yellow/red status indicator + "Not Running" text label
- Instructional message: "Run `supabase start` in your project terminal"
- Copy-to-clipboard for the command
- "Check Again" / refresh button
**Local Supabase — prerequisites missing**:
- Specific error per missing prerequisite (Docker not installed, Docker not running, CLI not found, CLI version too old)
- Actionable guidance with links to installation docs
- "Check Again" button after user resolves
**Mode switching confirmation**:
- Dialog: "Switching to [cloud/local] will update your app's database connection. The target environment may not have matching tables or data. You may need to apply migrations. Your [current] data will not be affected."
- Confirm / Cancel buttons
### Interaction Details
- Prerequisite check runs automatically when user clicks "Use Local Supabase" — no manual trigger needed
- Status detection polls `supabase status` when the local connected view is visible (reasonable interval, e.g., every 30 seconds)
- "Check Again" button triggers an immediate re-check
- Mode switching regenerates `src/integrations/supabase/client.ts` automatically and shows a toast: "Supabase client updated. Restart your dev server for changes to take effect."
- "Open Studio" opens `http://127.0.0.1:54323` in the system browser
### Accessibility
- Fix existing `<img onClick>` connect button (SupabaseConnector.tsx ~line 454) — wrap in proper `<button>` element with ARIA
- All new controls must be keyboard navigable (Tab to reach, Enter/Space to activate)
- Status indicators use text labels alongside colored indicators (not color-only)
- Copy-to-clipboard button has visible focus indicator
- Screen readers announce connection type and status
## Technical Design
### Architecture
Introduce a local Supabase code path that coexists with the existing cloud integration. The key abstraction point is at the IPC handler layer — handlers detect `supabaseMode` from the app record and route to either cloud (Management API) or local (direct Postgres / CLI) implementations.
```
SupabaseConnector.tsx (UI)
IPC Contracts (supabase.ts)
IPC Handlers (supabase_handlers.ts)
┌───┴───┐
▼ ▼
Cloud Local
(Management API) (postgres npm + CLI)
```
For local mode:
- **SQL execution**: `postgres` npm package (pure-JS, no native compilation) connecting to `postgresql://postgres:postgres@127.0.0.1:54322/postgres`
- **Status/detection**: Shell out to `supabase status --output json` (requires CLI v1.50+ for JSON output)
- **Client codegen**: Emit `http://127.0.0.1:54321` with local anon key
- **Edge functions**: Agent writes code with `http://127.0.0.1:54321/functions/v1/FUNCTION_NAME` URLs; user serves locally via `supabase functions serve`
### Components Affected
| File | Change |
| -------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `src/db/schema.ts` | Add `supabaseMode` column to `apps` table |
| `src/lib/schemas.ts` | Add `localSupabase` settings object to `SupabaseSchema` |
| `src/supabase_admin/supabase_local_client.ts` | **New file.** CLI detection, `supabase status` parsing, direct Postgres queries via `postgres` npm |
| `src/supabase_admin/supabase_management_client.ts` | Add local routing in `executeSupabaseSql` and key functions |
| `src/supabase_admin/supabase_context.ts` | Update `getSupabaseClientCode()` and `getPublishableKey()` for local URLs/keys |
| `src/supabase_admin/supabase_schema_query.ts` | No change (same SQL queries, different execution path) |
| `src/components/SupabaseConnector.tsx` | Add local Supabase entry point, local connected state, prerequisite check UI, status display |
| `src/components/SupabaseIntegration.tsx` | Conditionally render settings based on `supabaseMode` |
| `src/ipc/types/supabase.ts` | Add new contracts: `checkLocalPrerequisites`, `getLocalStatus`, `connectLocal`, `disconnectLocal` |
| `src/ipc/handlers/supabase_handlers.ts` | Add local handlers, route existing handlers by mode |
| `src/hooks/useSupabase.ts` | Add hooks for local status, prerequisites |
| `src/prompts/supabase_prompt.ts` | Add local-specific agent instructions (URLs, edge function serving, limitations) |
| `src/pro/main/ipc/handlers/local_agent/tools/get_supabase_project_info.ts` | Return local connection details when in local mode |
| `src/pro/main/ipc/handlers/local_agent/tools/get_supabase_table_schema.ts` | Route schema queries through local Postgres when in local mode |
### Data Model Changes
**Apps table** (Drizzle migration):
```typescript
supabaseMode: text("supabase_mode"), // "cloud" | "local" | null
```
When `supabaseMode` is `"local"`:
- `supabaseProjectId` is `null`
- `supabaseOrganizationSlug` is `null`
- Connection details come from cached `supabase status` output in settings
**Settings schema** (`src/lib/schemas.ts`):
```typescript
localSupabase?: {
apiUrl: string; // e.g., "http://127.0.0.1:54321"
dbUrl: string; // e.g., "postgresql://postgres:postgres@127.0.0.1:54322/postgres"
studioUrl: string; // e.g., "http://127.0.0.1:54323"
anonKey: string; // from supabase status
serviceRoleKey: string; // from supabase status
cliVersion: string; // detected CLI version
}
```
These are auto-populated from `supabase status --output json` — never manually entered.
### API Changes
**New IPC contracts**:
```typescript
checkLocalPrerequisites: defineContract({...})
// Returns: { docker: { installed, running }, cli: { installed, version, compatible } }
getLocalStatus: defineContract({...})
// Returns: { running: boolean, apiUrl?, dbUrl?, studioUrl?, anonKey?, serviceRoleKey? }
connectLocalSupabase: defineContract({ appId: string })
// Sets supabaseMode to "local", caches connection details
disconnectLocalSupabase: defineContract({ appId: string })
// Sets supabaseMode to null, clears cached details
```
**Modified behavior** (no contract schema changes):
- `executeSupabaseSql` — routes to local Postgres when app is in local mode
- `setAppProject` / `unsetAppProject` — handles local mode transitions
- Agent tools (`get_supabase_project_info`, `get_supabase_table_schema`) — return local details when in local mode
## Implementation Plan
### Phase 1: Foundation + UI Shell
- [ ] Add `supabaseMode` column to `apps` table (Drizzle migration)
- [ ] Add `localSupabase` settings to `SupabaseSchema` in `schemas.ts`
- [ ] Create `supabase_local_client.ts` with:
- [ ] Docker detection (check if `docker` command exists and daemon is running)
- [ ] Supabase CLI detection (check if `supabase` command exists, parse version)
- [ ] `supabase status --output json` parsing (require CLI v1.50+)
- [ ] Add `checkLocalPrerequisites` and `getLocalStatus` IPC contracts + handlers
- [ ] Add "Use Local Supabase" secondary link in `SupabaseConnector.tsx`
- [ ] Build prerequisite check UI (Docker/CLI not found states with guidance)
- [ ] Build "not running" instructional state with copy-to-clipboard
- [ ] Build local connected state (LOCAL badge, status indicator, Open Studio button)
- [ ] Fix `<img onClick>` accessibility issue on existing connect button
### Phase 2: Core Local Operations
- [ ] Add `postgres` npm dependency (pure-JS Postgres client)
- [ ] Implement local SQL execution in `supabase_local_client.ts` via `postgres`
- [ ] Route `executeSupabaseSql` through local Postgres when `supabaseMode === "local"`
- [ ] Implement local schema discovery (reuse existing queries from `supabase_schema_query.ts`)
- [ ] Update `getSupabaseClientCode()` to emit `http://127.0.0.1:54321` + local anon key
- [ ] Update `getPublishableKey()` to return local anon key from cached status
- [ ] Implement `connectLocalSupabase` / `disconnectLocalSupabase` IPC handlers
- [ ] Add mode switching with confirmation dialog + client code regeneration
- [ ] Add status polling (periodic `supabase status` check while local view is visible)
### Phase 3: Agent Integration
- [ ] Update `supabase_prompt.ts` with local-specific instructions:
- [ ] Correct URLs (`http://127.0.0.1:54321` for API, `http://127.0.0.1:54321/functions/v1/` for edge functions)
- [ ] Note that edge functions are served locally via `supabase functions serve` (user-managed)
- [ ] Note that branches and cloud-specific features are not available
- [ ] Note that secrets are managed via `.env` files, not Supabase dashboard
- [ ] Update `get_supabase_project_info` tool to return local connection details
- [ ] Update `get_supabase_table_schema` tool to query local Postgres
- [ ] Ensure agent generates correct `client.ts` imports for local mode
- [ ] Update edge function invocation URLs in agent prompts to use localhost
### Phase 4: Polish + Settings
- [ ] Conditionally render settings in `SupabaseIntegration.tsx` based on mode:
- [ ] Hide "Skip pruning edge functions" for local mode
- [ ] Adapt "Write SQL migration files" if needed
- [ ] Add "Open Studio" button linking to `http://127.0.0.1:54323`
- [ ] Handle edge case: user has cloud connected, clicks "Use Local" → show switching confirmation
- [ ] Handle edge case: local Supabase stops while app is connected → show "not running" state gracefully
- [ ] Toast notification after mode switch: "Supabase client updated. Restart your dev server."
## Testing Strategy
- [ ] **Unit tests**: `supabase_local_client.ts` — test CLI output parsing, version detection, status parsing, prerequisite checks (mock child_process)
- [ ] **Unit tests**: Conditional routing in handlers — verify local vs cloud dispatch based on `supabaseMode`
- [ ] **Unit tests**: Client codegen — verify correct URLs and keys for local vs cloud mode
- [ ] **Integration tests**: Mode switching — verify `supabaseMode` updates, client code regeneration, settings cache update
- [ ] **E2E tests**: Mock local Supabase CLI responses (similar to existing `IS_TEST_BUILD` pattern) — test the full connect flow, prerequisite error states, connected state display
- [ ] **Manual testing matrix**:
- Fresh install, no Docker → helpful error with install link
- Docker installed but not running → "Start Docker and try again"
- Docker + CLI installed, Supabase not started → "Run `supabase start`" message
- Docker + CLI + Supabase running → full connect flow
- Switch cloud → local on same app → confirmation dialog, client regenerated
- Switch local → cloud on same app → confirmation dialog, client regenerated
- Agent generates correct code for local mode (URLs, edge function paths)
- Agent generates correct code for cloud mode (unchanged from current behavior)
## Risks & Mitigations
| Risk | Likelihood | Impact | Mitigation |
| ----------------------------------------------------------------- | ---------- | ------ | ------------------------------------------------------------------------------------------------------- |
| Docker not installed by most users | High | Medium | Gate behind prerequisite check, show clear guidance. Target audience (advanced devs) likely has Docker. |
| `supabase status --output json` unavailable in older CLI versions | Medium | High | Require minimum CLI version (v1.50+). Show "Please update your Supabase CLI" if too old. |
| Port conflicts (54321, 54322, 54323 in use) | Medium | Medium | Surface clear error message when `supabase status` indicates issues. User resolves externally. |
| Schema divergence when switching local ↔ cloud | High | Medium | Strong confirmation dialog listing consequences. No automatic migration in v1. |
| `postgres` npm package bundling issues in Electron | Low | High | Pure-JS package avoids native compilation. Lazy-import to avoid affecting startup for non-local users. |
| CLI output format changes across versions | Low | Medium | Use `--output json` for structured output. Pin minimum version. |
| Multiple apps sharing one local instance cause schema collisions | Medium | Low | Document limitation. Users can namespace tables. Consider per-app databases in v2. |
## Open Questions
- **Minimum Supabase CLI version**: Need to verify which version first supported `supabase status --output json`. This should be validated in Phase 1 before building the parser.
- **`postgres` npm package validation**: Confirm that the pure-JS `postgres` package works correctly within Electron's Node.js environment for the complex metadata queries in `supabase_schema_query.ts`. Spike this early in Phase 2.
- **Per-app database isolation**: v1 uses a shared local instance. If users request per-app isolation, we could create separate Postgres databases within the single instance (one per app). Defer unless needed.
## Decision Log
| Decision | Reasoning |
| --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Detect-only lifecycle (no managed start/stop) | Dramatically reduces scope and complexity. Target audience is comfortable with terminals. Add managed lifecycle in v2 based on usage data. |
| `postgres` npm package for SQL execution | Pure-JS avoids native compilation issues in Electron. Direct Postgres connection is more reliable than CLI shelling for SQL. |
| Per-app mode with shared local instance | Matches existing per-app Supabase project model. One Docker stack avoids resource overhead. Schema collisions are acceptable for v1. |
| Cloud as primary, local as secondary | Cloud is the recommended path for most users. Local has more prerequisites and fewer features. Contextual labels ("Recommended for production" / "Great for development") respect both positions. |
| Edge functions: agent-aware, user-served | Agent writes edge function code with correct localhost URLs. User runs `supabase functions serve` themselves. Consistent with detect-only lifecycle philosophy. |
| UI-first implementation order | Validates discoverability and flow early. Delivers a visible "steel thread" before deep backend investment. |
| No data migration between local and cloud | Massive scope trap. Users use `supabase db push/pull` externally if needed. Clear warning on mode switch. |
---
_Generated by dyad:swarm-to-plan_
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论