Skip to content

Refine builder partner prompt flow#998

Open
tannerlinsley wants to merge 1 commit into
mainfrom
taren/builder-lovable-partner-flow
Open

Refine builder partner prompt flow#998
tannerlinsley wants to merge 1 commit into
mainfrom
taren/builder-lovable-partner-flow

Conversation

@tannerlinsley

@tannerlinsley tannerlinsley commented Jun 18, 2026

Copy link
Copy Markdown
Member

What changed

  • Added Lovable as an active gold partner with light and dark SVG logo assets.
  • Added partner constraint handling so mutually exclusive hosting/auth/data partners are deselected or hidden appropriately across tiers.
  • Simplified the Application Starter flow from AI-backed analysis/generation to deterministic prompt composition and copy actions.
  • Reworked /builder so integrations are visible immediately, prompt/CLI output refreshes as the starter input and options change, and selected hosting partners expose the relevant Deploy action.
  • Kept /builder Summary prompt preview aligned with the exact prompt that Copy Prompt will copy.

Why

Lovable needs to participate in gold partner rotation and in the builder prompt/deploy flow without adding latency or conflicting partner choices. The builder can now resolve the final prompt locally from the selected options instead of waiting on AI generation.

Validation

  • pnpm exec tsc --pretty false
  • pnpm run lint (passes with existing warnings)
  • git diff --check
  • Commit hook ran pnpm run format && pnpm run test successfully; lint still reports the existing 10 warnings in unrelated files.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added direct “Deploy/Start” support for Cloudflare, Lovable, Netlify, and Railway from the Application Starter, including guided partner selection and one-click launch links.
  • Improvements

    • Updated the workflow to a “Copy Prompt” / submit-first flow: hotkeys now submit, options can reveal immediately, and options/actions are now collapsible with clearer “Next” behavior.
    • Strengthened partner compatibility rules and improved inactive partner styling; added Lovable-specific guidance.
    • Deploy links now open cleanly in a new tab; starter resolution/analysis is now deterministic and CLI flags are more consistent.

@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 821c73f8-89df-42f2-808c-b0032d65c5fa

📥 Commits

Reviewing files that changed from the base of the PR and between e62ca0d and ece0a3a.

⛔ Files ignored due to path filters (2)
  • src/images/lovable-black.svg is excluded by !**/*.svg
  • src/images/lovable-white.svg is excluded by !**/*.svg
📒 Files selected for processing (17)
  • src/components/ApplicationStarter.tsx
  • src/components/ApplicationStarterHotkeys.client.tsx
  • src/components/application-builder/parts.tsx
  • src/components/application-builder/shared.ts
  • src/components/application-builder/useApplicationBuilder.tsx
  • src/components/builder/BuilderWorkspace.tsx
  • src/components/builder/DeployDialog.tsx
  • src/components/builder/useBuilderUrl.ts
  • src/components/deploy/shared.ts
  • src/components/home/HomeApplicationStarter.tsx
  • src/components/landing/RouterLanding.tsx
  • src/components/landing/StartLanding.tsx
  • src/components/stack/CategoryArticle.tsx
  • src/utils/application-starter.server.ts
  • src/utils/application-starter.ts
  • src/utils/partner-pages.ts
  • src/utils/partners.tsx
✅ Files skipped from review due to trivial changes (4)
  • src/components/home/HomeApplicationStarter.tsx
  • src/components/landing/StartLanding.tsx
  • src/components/landing/RouterLanding.tsx
  • src/components/stack/CategoryArticle.tsx
🚧 Files skipped from review as they are similar to previous changes (13)
  • src/utils/partner-pages.ts
  • src/components/deploy/shared.ts
  • src/components/builder/DeployDialog.tsx
  • src/components/builder/useBuilderUrl.ts
  • src/components/ApplicationStarterHotkeys.client.tsx
  • src/components/application-builder/shared.ts
  • src/components/builder/BuilderWorkspace.tsx
  • src/utils/application-starter.server.ts
  • src/components/application-builder/parts.tsx
  • src/utils/application-starter.ts
  • src/utils/partners.tsx
  • src/components/ApplicationStarter.tsx
  • src/components/application-builder/useApplicationBuilder.tsx

📝 Walkthrough

Walkthrough

The PR refactors the Application Starter from an AI-driven analyze/generate flow to a single deterministic resolver, adds Lovable as a new hosting deploy partner, and introduces a unique-constraint system (auth-provider, hosting) to enforce partner mutual exclusivity. The ApplicationStarter UI is reorganized around showOptionsSection/showActionSection with per-partner deploy actions, and the server-side AI planner is removed entirely.

Changes

Application Starter: Deterministic Resolver, Partner Constraints, and UI Refactor

Layer / File(s) Summary
Partner unique constraints and Lovable partner definition
src/utils/partners.tsx, src/utils/partner-pages.ts
Introduces PartnerUniqueConstraint type and uniqueConstraints field on Partner and ApplicationStarterPartnerSuggestion. Annotates Clerk, WorkOS, Netlify, Cloudflare, Vercel, and Railway with auth-provider or hosting constraints. Adds the complete Lovable partner definition with SVG assets and Lovable guidance copy.
Partner compatibility, conflict helpers, and inference rule updates
src/utils/partners.tsx
Adds exported helpers to detect unique-constraint conflicts, compute compatible partner id sets with tier-based resolution, filter visible suggestions, and check per-constraint membership. Updates inference logic to skip conflicting partners and normalize inferred ids via compatibility helpers. Updates composeApplicationStarterInput to emit compatibility-adjusted partner id lists.
Deterministic server resolver and recipe/CLI command updates
src/utils/application-starter.server.ts, src/utils/application-starter.ts
Removes AI provider selection and model-based analysis from the server, replacing both functions with direct deterministic resolution. buildRecipe now pre-filters partner ids for compatibility before applying overrides; buildCliCommand always emits --package-manager and explicit --tailwind/--no-tailwind flags.
Shared type contracts, partner button styling, and hotkey prop rename
src/components/application-builder/shared.ts, src/components/application-builder/parts.tsx, src/components/ApplicationStarterHotkeys.client.tsx
Updates applyResult to accept an optional silent flag. Adds --starter-partner-active-border-color CSS variable and derives semi-transparent hover/active border colors from partner accent. Introduces mutedPartnerIds computation and muted state styling to gray out conflicting partners. Renames onAnalyze to onSubmit in hotkeys props.
useApplicationBuilder hook refactor to unified resolver
src/components/application-builder/useApplicationBuilder.tsx
Replaces React Query + analyze/generate dual path with a single resolveSubmittedInput function handling race protection, loading phrases, and error analytics. Adds revealOptionsImmediately option and hasRevealedOptions state; introduces isRebuildingResult tracking and user-edit detection. Adds conflict-aware togglePartner and openLovableStart action; rewrites openNetlifyStart and generatePrompt. Removes analysis/lucky fields from returned API.
ApplicationStarter component UI refactor with deploy actions
src/components/ApplicationStarter.tsx
Adds revealOptionsImmediately prop, HostingDeployPartnerId union, and deployToSelectedHostingPartner flow routing to Cloudflare/Lovable/Netlify/Railway deploy/start actions. Adds local render helpers for copy-prompt, copy-CLI, and selected-partner deploy buttons. Restructures compact and non-compact layouts around showOptionsSection/showActionSection with a "Next" button before actions. Renames AnalyzeShortcutHint to SubmitShortcutHint.
BuilderWorkspace integration with starter result tracking
src/components/builder/BuilderWorkspace.tsx
Tracks latestStarterResult via onResolvedResult callback, computes displayedSummary merging starter result's cliCommand/prompt, memoizes starterBuilderIntegration with silent-capable applyResult, enables immediate option reveal, and renders the summary panel from displayedSummary.
Deploy dialog navigation and provider URL refactor
src/components/builder/DeployDialog.tsx, src/components/deploy/shared.ts
Changes DeployDialog provider "Deploy Now" button from window.open to anchor-style navigation with href, target="_blank", and rel="noopener noreferrer". Refactors PROVIDER_INFO deploy URL builders for Cloudflare, Netlify, and Railway to use URL API and searchParams instead of template literals.
CLI command and call-site updates
src/components/builder/useBuilderUrl.ts, src/components/home/HomeApplicationStarter.tsx, src/components/landing/..., src/components/stack/CategoryArticle.tsx
useCliCommand unconditionally appends --package-manager. Removes primaryButtonColor from HomeApplicationStarter. Updates primaryActionLabel text to "Copy Start Prompt" / "Copy Router Prompt" across landing pages and CategoryArticle.

Sequence Diagram(s)

sequenceDiagram
  participant User
  rect rgba(99, 102, 241, 0.5)
    Note over User,ApplicationStarter: Options reveal phase
    User->>ApplicationStarter: Type input, click "Next"
    ApplicationStarter->>useApplicationBuilder: submitCurrentInput()
    useApplicationBuilder->>useApplicationBuilder: hasRevealedOptions = true
  end
  rect rgba(16, 185, 129, 0.5)
    Note over ApplicationStarter,resolveApplicationStarterDeterministically: Resolution phase
    useApplicationBuilder->>resolveApplicationStarterDeterministically: resolveSubmittedInput(submittedInput)
    resolveApplicationStarterDeterministically-->>useApplicationBuilder: ApplicationStarterResult
    useApplicationBuilder->>BuilderIntegration: applyResult(result, {silent?})
    useApplicationBuilder-->>ApplicationStarter: result, showActionSection=true
  end
  rect rgba(245, 158, 11, 0.5)
    Note over ApplicationStarter,HostingPartner: Deploy/copy phase
    ApplicationStarter->>ApplicationStarter: renderSelectedHostingDeployButton()
    User->>ApplicationStarter: Click "Deploy to Lovable/Netlify/..."
    ApplicationStarter->>useApplicationBuilder: openLovableStart() / openNetlifyStart()
    useApplicationBuilder->>HostingPartner: open URL with resolved prompt
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~90 minutes

Suggested reviewers

  • KevinVandy

Poem

🐇 A bunny once clicked "Generate," then sighed,
"Too many AI hops—let's simplify inside!"
With unique constraints and a Lovable deploy,
The prompt now just copies—what elegant joy.
One resolver to rule them, no model in sight,
The starter hops forward, deterministic and bright! 🚀

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.63% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Refine builder partner prompt flow' directly captures the main focus of this PR: refining the builder's partner selection and prompt flow mechanics.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch taren/builder-lovable-partner-flow

Comment @coderabbitai help to get the list of available commands and usage tips.

@tannerlinsley tannerlinsley marked this pull request as ready for review June 18, 2026 07:51

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/utils/partners.tsx (1)

1557-1622: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Let tier resolution see all inferred constraint matches.

Lines 1582-1583 make the first inferred partner for a unique constraint win before getApplicationStarterCompatiblePartnerIds runs on Line 1622. If input matches multiple hosting/auth partners, rule order can suppress a higher-tier partner, bypassing the intended tier-based compatibility resolution.

Proposed fix
   const blockedUniqueConstraints = new Set(
     selectedSourcePartners.flatMap(getPartnerUniqueConstraints),
   )
   const inferredCategories = new Set<PartnerCategory>()
-  const inferredUniqueConstraints = new Set<PartnerUniqueConstraint>()
   const inferredPartnerIds = Array<string>()

@@
     const isBlockedByUniqueConstraint = partnerUniqueConstraints.some(
-      (uniqueConstraint) =>
-        blockedUniqueConstraints.has(uniqueConstraint) ||
-        inferredUniqueConstraints.has(uniqueConstraint),
+      (uniqueConstraint) => blockedUniqueConstraints.has(uniqueConstraint),
     )

@@
-    if (hasUniqueConstraint) {
-      for (const uniqueConstraint of partnerUniqueConstraints) {
-        inferredUniqueConstraints.add(uniqueConstraint)
-      }
-    } else {
+    if (!hasUniqueConstraint) {
       inferredCategories.add(partner.category)
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/utils/partners.tsx` around lines 1557 - 1622, The current code adds
inferred partners to the inferredPartnerIds array during loop iteration,
allowing rule order to suppress higher-tier partners before tier-based
resolution can occur. Instead of immediately pushing partners to
inferredPartnerIds when a rule matches, pass both the inferredPartnerIds array
and the accumulated inferred constraints (inferredUniqueConstraints and
inferredCategories sets) to the getApplicationStarterCompatiblePartnerIds
function so it can perform proper tier-based compatibility resolution with
complete visibility of all matching partners and their constraints, rather than
having the loop iteration order pre-filter the candidates.
src/components/ApplicationStarter.tsx (1)

359-535: ⚠️ Potential issue | 🟠 Major

Compact mode doesn't expose final actions (copy/deploy)—submitButton is never passed by any compact mode callers.

All three instances using mode="compact" (CategoryArticle.tsx, StartLanding.tsx, RouterLanding.tsx) omit the submitButton prop. Since line 921 renders {compact ? submitButton : null}, compact pages will render no action buttons. The primaryActionLabel and secondaryActionLabel passed to these components are only used in full mode. Either compact callers should pass submitButton with the expected actions, or ApplicationStarter should auto-generate one from the label props when in compact mode.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/ApplicationStarter.tsx` around lines 359 - 535, The
ApplicationStarter component in compact mode does not expose final action
buttons because the submitButton prop is never passed by the three compact mode
callers (CategoryArticle.tsx, StartLanding.tsx, and RouterLanding.tsx). Fix this
by either modifying each of these three caller components to pass a submitButton
prop containing copy and deploy actions when instantiating ApplicationStarter in
compact mode, or alternatively modify the ApplicationStarter component to
auto-generate the submitButton from the primaryActionLabel and
secondaryActionLabel props when in compact mode and submitButton is not
provided. Choose the approach that best fits the application architecture.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/ApplicationStarter.tsx`:
- Around line 311-316: The onSubmit handler in the ApplicationStarter component
calls generatePrompt() and submitCurrentInput() without checking
action-availability conditions that the buttons enforce, allowing keyboard
submissions to bypass validation. Add the same guard conditions used by the
buttons (checking hasMigrationRepositoryUrlError, empty input, and generating
state) to the onSubmit handler before executing either action to ensure keyboard
submits respect the same gating as button clicks.

In `@src/utils/application-starter.server.ts`:
- Around line 52-54: The issue is that
getInferredApplicationStarterPartnerIdsFromUserInput is being called with an
empty array for selected partners, which can result in inferred partner IDs that
conflict with partners already selected in request.input, diverging from how
buildRecipe handles partner filtering. To fix this, extract the compatible
selected partner IDs from request.input by calling
getApplicationStarterCompatiblePartnerIds on the selected partners in
request.input, store the result in a local variable before the return statement
to avoid recomputation, and then pass that local variable instead of the empty
array to getInferredApplicationStarterPartnerIdsFromUserInput so that inferred
partners are properly filtered against the selected partner constraints.

In `@src/utils/partners.tsx`:
- Around line 629-633: The applicationStarterPromptInstructions array at line
632 excludes Cloudflare, Netlify, and Railway from being added when Lovable is
selected, but Vercel should also be included in this exclusion list since it is
marked as a hosting-constrained partner in this file. Update the instruction
string that currently mentions "Cloudflare, Netlify, or Railway" to also include
"Vercel" in the list of hosting targets to avoid adding when Lovable is
selected.

---

Outside diff comments:
In `@src/components/ApplicationStarter.tsx`:
- Around line 359-535: The ApplicationStarter component in compact mode does not
expose final action buttons because the submitButton prop is never passed by the
three compact mode callers (CategoryArticle.tsx, StartLanding.tsx, and
RouterLanding.tsx). Fix this by either modifying each of these three caller
components to pass a submitButton prop containing copy and deploy actions when
instantiating ApplicationStarter in compact mode, or alternatively modify the
ApplicationStarter component to auto-generate the submitButton from the
primaryActionLabel and secondaryActionLabel props when in compact mode and
submitButton is not provided. Choose the approach that best fits the application
architecture.

In `@src/utils/partners.tsx`:
- Around line 1557-1622: The current code adds inferred partners to the
inferredPartnerIds array during loop iteration, allowing rule order to suppress
higher-tier partners before tier-based resolution can occur. Instead of
immediately pushing partners to inferredPartnerIds when a rule matches, pass
both the inferredPartnerIds array and the accumulated inferred constraints
(inferredUniqueConstraints and inferredCategories sets) to the
getApplicationStarterCompatiblePartnerIds function so it can perform proper
tier-based compatibility resolution with complete visibility of all matching
partners and their constraints, rather than having the loop iteration order
pre-filter the candidates.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bfddbf6e-6091-4e33-9cff-2f74b177eb8c

📥 Commits

Reviewing files that changed from the base of the PR and between ada579a and 99df813.

⛔ Files ignored due to path filters (2)
  • src/images/lovable-black.svg is excluded by !**/*.svg
  • src/images/lovable-white.svg is excluded by !**/*.svg
📒 Files selected for processing (15)
  • src/components/ApplicationStarter.tsx
  • src/components/ApplicationStarterHotkeys.client.tsx
  • src/components/application-builder/parts.tsx
  • src/components/application-builder/shared.ts
  • src/components/application-builder/useApplicationBuilder.tsx
  • src/components/builder/BuilderWorkspace.tsx
  • src/components/builder/useBuilderUrl.ts
  • src/components/home/HomeApplicationStarter.tsx
  • src/components/landing/RouterLanding.tsx
  • src/components/landing/StartLanding.tsx
  • src/components/stack/CategoryArticle.tsx
  • src/utils/application-starter.server.ts
  • src/utils/application-starter.ts
  • src/utils/partner-pages.ts
  • src/utils/partners.tsx

Comment thread src/components/ApplicationStarter.tsx
Comment on lines +52 to 54
inferredPartnerIds: getApplicationStarterCompatiblePartnerIds(
getInferredApplicationStarterPartnerIdsFromUserInput(request.input, []),
recipe,
),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Keep analysis partner inference aligned with selected-partner constraints.

Line 53 passes [] for selected partners, so inferredPartnerIds can still include a hosting/auth partner that conflicts with a partner already selected in request.input. That makes the analysis payload diverge from buildRecipe, which filters inferred partners against compatible selected partners before applying overrides.

Suggested fix
-    inferredPartnerIds: getApplicationStarterCompatiblePartnerIds(
-      getInferredApplicationStarterPartnerIdsFromUserInput(request.input, []),
-    ),
+    inferredPartnerIds: getApplicationStarterCompatiblePartnerIds(
+      getInferredApplicationStarterPartnerIdsFromUserInput(
+        request.input,
+        getApplicationStarterCompatiblePartnerIds(
+          getApplicationStarterSelectedPartnerIds(request.input),
+        ),
+      ).filter(
+        (partnerId) =>
+          !hasApplicationStarterPartnerConflictWithAny(
+            partnerId,
+            getApplicationStarterCompatiblePartnerIds(
+              getApplicationStarterSelectedPartnerIds(request.input),
+            ),
+          ),
+      ),
+    ),

Consider storing the compatible selected IDs in a local before the return to avoid recomputing them.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/utils/application-starter.server.ts` around lines 52 - 54, The issue is
that getInferredApplicationStarterPartnerIdsFromUserInput is being called with
an empty array for selected partners, which can result in inferred partner IDs
that conflict with partners already selected in request.input, diverging from
how buildRecipe handles partner filtering. To fix this, extract the compatible
selected partner IDs from request.input by calling
getApplicationStarterCompatiblePartnerIds on the selected partners in
request.input, store the result in a local variable before the return statement
to avoid recomputation, and then pass that local variable instead of the empty
array to getInferredApplicationStarterPartnerIdsFromUserInput so that inferred
partners are properly filtered against the selected partner constraints.

Comment thread src/utils/partners.tsx
@tannerlinsley tannerlinsley force-pushed the taren/builder-lovable-partner-flow branch 7 times, most recently from e11804c to e62ca0d Compare June 18, 2026 18:05
@tannerlinsley tannerlinsley force-pushed the taren/builder-lovable-partner-flow branch from e62ca0d to ece0a3a Compare June 18, 2026 18:17
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.

1 participant