> ## Documentation Index
> Fetch the complete documentation index at: https://vlyai-1c28d863.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Plan mode

> Agent mode with a deliberate review step. Plan mode shows you what the agent intends to do before writing code — the cheapest way to catch a misunderstanding.

export const PromptBlock = ({children, variant}) => <div className={`vly-prompt ${variant || ""}`}>{children}</div>;

Plan mode is the safest way to make non-trivial changes in vly. Before any code is written, the agent shows you a **written plan** — the schema changes, pages affected, components to add — and waits for your approval. You can edit the plan directly or reply with refinements before approving.

The cost is 5–15 extra seconds per change. The savings, when the agent misreads your intent, are minutes-to-hours.

## When to use it

<CardGroup cols={2}>
  <Card title="✅ The first prompt of any project" icon="rocket">
    Sets the foundation. Catching a wrong schema decision now saves you a rewrite later.
  </Card>

  <Card title="✅ Schema changes" icon="database">
    Migrations are the most expensive thing to undo. See the migration plan first.
  </Card>

  <Card title="✅ Big features" icon="layout">
    "Add billing" or "Add multi-tenant workspaces" — both touch many files. Worth a plan review.
  </Card>

  <Card title="✅ When you're unsure" icon="circle-help">
    If you can't tell whether your prompt will produce what you want, Plan mode resolves the ambiguity for cheap.
  </Card>

  <Card title="❌ Tiny tweaks" icon="x-circle">
    "Make this button violet" — just use [Agent mode](/building/agent-mode) or [Code mode](/building/code-mode).
  </Card>

  <Card title="❌ When you've already iterated three times" icon="x-circle">
    By now, the project structure is stable; agent decisions are predictable. Switch to Agent mode for momentum.
  </Card>
</CardGroup>

## Anatomy of a plan

A typical plan has four sections:

<Steps>
  <Step title="Summary" icon="file-text">
    One paragraph restating what you asked for, in vly's own words. **Read this first** — if vly's restatement misses the point, fix the prompt before the plan.
  </Step>

  <Step title="Schema changes" icon="database">
    Concrete table-by-table changes — new tables, new fields, new indexes, migrations needed. Includes a pre/post diff.
  </Step>

  <Step title="Pages and components" icon="layout">
    What's added, edited, or removed. Includes the React Router changes and the affected components.
  </Step>

  <Step title="Integrations and side-effects" icon="puzzle">
    Any third-party services to wire up (Stripe, Resend, OpenAI, etc.) and any environment variables you'll need to provide.
  </Step>
</Steps>

## A worked example

You write:

<PromptBlock>
  Add a "team billing" feature. Each team can subscribe to one of three plans (Free / Pro $10/mo / Business $40/mo). Use Stripe for payments. The team's admin sees the current plan and can upgrade or downgrade. Non-admins see read-only "Current plan: X". When a team's subscription is past due, the entire team gets a banner.
</PromptBlock>

vly returns a plan that looks roughly like:

```markdown theme={null}
## Summary
Add team-level Stripe subscriptions with three plan tiers, an admin-only
billing UI, and a banner for past-due subscriptions.

## Schema changes
- Add `subscriptions` table:
    - teamId: id<"teams">
    - stripeCustomerId: string
    - stripeSubscriptionId: string
    - planTier: "free" | "pro" | "business"
    - status: "active" | "past_due" | "cancelled"
    - currentPeriodEnd: number
    - Index: by_team [teamId]
- Add `stripeCustomerId` field to `teams` table

## Pages and components
- New: /settings/billing (admin only)
- New: <BillingBanner /> in the app shell, shown when status === "past_due"
- New: <PlanCard /> component, three of them on the billing page
- Edited: middleware to redirect non-admins from /settings/billing
- Edited: /settings layout to add a "Billing" tab

## Integrations and side-effects
- Stripe integration (will prompt for STRIPE_SECRET_KEY,
  STRIPE_WEBHOOK_SECRET, and three STRIPE_PRICE_ID_* values)
- New Convex action: handleStripeWebhook
- Webhook endpoint: /api/stripe-webhook (you'll register this URL in
  the Stripe dashboard)
```

You read it. Maybe you notice "Business should be $39, not $40." You reply:

<PromptBlock>
  Almost perfect. Business plan is $39/month, not $40. Also: when downgrading from Pro or Business to Free, schedule the downgrade for the end of the current period (don't refund or cancel mid-period).
</PromptBlock>

vly updates the plan, you approve, and the agent writes \~15 files in 90 seconds, including a webhook handler that handles the deferred downgrade correctly.

The alternative would have been: agent writes the wrong price + no deferred downgrade, you discover it on the second test, you re-prompt twice. Plan mode saved two roundtrips.

## Editing the plan directly

You don't have to reply in prose. Click any line in the plan to edit it inline:

Common direct edits:

<Tabs>
  <Tab title="Rename a table">
    Click the table name. Rename. Plan re-validates references.
  </Tab>

  <Tab title="Drop a field">
    Click the field. Delete. Plan removes it from the schema and any pages that referenced it.
  </Tab>

  <Tab title="Change a type">
    Click the type. Edit. Plan re-runs the migration step against the new type.
  </Tab>

  <Tab title="Add a new entity">
    Click "+ table" at the bottom of Schema changes. Define inline.
  </Tab>
</Tabs>

## Approving and skipping

Three buttons appear at the bottom of every plan:

* **Approve and build** — write the code as planned.
* **Refine** — return to the prompt with the plan as context, write a follow-up.
* **Cancel** — discard the plan; no changes are made, no credits charged.

Plans don't cost credits to generate. Only the build does. So **always plan, never feel rushed to approve**.

## Tips

<Tip>
  **Read the Summary out loud.** If it doesn't match what's in your head, your prompt was the problem — fix the prompt, not the plan.
</Tip>

<Tip>
  **Use Plan mode for unfamiliar integrations.** When adding Stripe, Twilio, or anything you haven't wired up before, the plan reveals which env vars and webhook URLs you'll need *before* you commit.
</Tip>

<Tip>
  **Plans are part of version history.** Every plan you approve is saved alongside the resulting revision. You can read the original plan months later in [version history](/building/version-history).
</Tip>

## When Plan mode isn't enough

Some changes are big enough that even a plan review feels under-baked. For those:

<CardGroup cols={2}>
  <Card title="Branch first" icon="git-branch" href="/building/branching">
    Make the change on a branch, test it end-to-end, merge or discard. Plan + branch = the safest possible workflow.
  </Card>

  <Card title="Talk first, build later" icon="message-square">
    Use Agent mode to ask vly to *describe* an approach in chat, without acting. Then once you agree, ask it to do the thing.
  </Card>
</CardGroup>

## Related

<CardGroup cols={3}>
  <Card title="Agent mode" icon="bot" href="/building/agent-mode">
    The default. No plan review, faster iteration.
  </Card>

  <Card title="Code mode" icon="code" href="/building/code-mode">
    Hand-edit when a prompt is overkill.
  </Card>

  <Card title="Iterating effectively" icon="repeat" href="/building/iterating">
    Patterns for momentum across long sessions.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.