Skip to content

Conversation

@kaochannel154
Copy link
Contributor

@kaochannel154 kaochannel154 commented Dec 22, 2025

User description

What

  • Add a UI-only upgrade interstitial page at /settings/team/upgrade (standalone layout without sidebar/header via route group).
  • Implement plan cards with a glass style:
    • Personal: Free / Pro / Team
    • Business: Team / Enterprise
  • Current plan card: blue top glow + “Current plan” CTA.
  • Not-yet-available plans: “Coming Soon” CTA with disabled styling.
  • Update plan icons:
    • Free: lucide Orbit
    • Team: custom member icon (from provided SVG)
    • Enterprise: uses the previous Free glyph
Image Image

Refactor

  • Move GlassButton / GlassCard into @giselle-internal/ui and update Studio imports accordingly.

Notes

  • This PR is UI-only (no billing/checkout wiring yet). The existing “Upgrade to Pro” action remains unchanged.

PR Type

Enhancement


Description

  • Add team upgrade interstitial pricing page with Personal/Business plan tabs

  • Implement glass-styled pricing cards with plan features and CTAs

  • Refactor GlassButton and GlassCard into @giselle-internal/ui package

  • Update all Studio imports to use relocated glass components

  • Add plan icons (Free/Pro/Team/Enterprise) with custom member icon


Diagram Walkthrough

flowchart LR
  A["Studio App"] -->|"imports from"| B["@giselle-internal/ui"]
  B -->|"exports"| C["GlassButton"]
  B -->|"exports"| D["GlassCard"]
  E["Upgrade Page"] -->|"uses"| C
  E -->|"uses"| D
  E -->|"displays"| F["Pricing Cards"]
  F -->|"shows"| G["Personal Plans"]
  F -->|"shows"| H["Business Plans"]
Loading

File Walkthrough

Relevant files
Enhancement
9 files
page.tsx
Create team upgrade interstitial page entry point               
+6/-0     
layout.tsx
Add standalone layout for upgrade page without sidebar     
+15/-0   
upgrade-interstitial.client.tsx
Implement main upgrade interstitial UI with plan tabs       
+252/-0 
pricing-card.tsx
Create reusable pricing card component with glass styling
+119/-0 
plan-icon.tsx
Add plan variant icons for Free/Pro/Team/Enterprise           
+29/-0   
gradient-button.tsx
Add new gradient button component for future use                 
+49/-0   
member-icon.tsx
Add custom member icon SVG for Team plan display                 
+28/-0   
ui.tsx
Add Free/Pro/Team plan icons from website design                 
+105/-0 
willi-icon.tsx
Add Willi mascot icon components for branding                       
+39/-0   
Refactoring
11 files
glass-button.tsx
Move GlassButton to internal UI package with variants       
+129/-0 
glass-card.tsx
Move GlassCard to internal UI package with glass styling 
+26/-0   
glass-button.tsx
Remove glass-button from local components directory           
+0/-97   
page.tsx
Update import to use GlassButton from internal UI               
+1/-1     
invite-member-dialog.tsx
Update import to use GlassButton from internal UI               
+1/-1     
document-store-create-dialog.tsx
Update import to use GlassButton from internal UI               
+1/-1     
repository-registration-dialog.tsx
Update import to use GlassButton from internal UI               
+1/-1     
app-detail-client.tsx
Update import to use GlassButton from internal UI               
+1/-1     
showcase-client.tsx
Update import to use GlassButton from internal UI               
+1/-1     
create-app-button.tsx
Update import to use GlassButton from internal UI               
+1/-1     
create-workspace-button.tsx
Update import to use GlassButton from internal UI               
+1/-1     
Configuration changes
1 files
package.json
Export glass-button and glass-card from package                   
+2/-0     

Summary by CodeRabbit

  • New Features
    • Added a new team upgrade flow with pricing tiers for Personal and Business plans, including feature comparisons and plan selection interface.
    • Introduced new visual UI components for enhanced pricing presentation and improved navigation.

✏️ Tip: You can customize this high-level summary in your review settings.


Note

Adds a UI-only upgrade interstitial at /settings/team/upgrade with pricing cards and tabs, updates Team Settings to link to it, and moves GlassButton/GlassCard into the shared UI package.

  • Studio (Upgrade UI):
    • New standalone route apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade with layout.tsx and page.tsx rendering UpgradeInterstitial.
    • Implements pricing UI: pricing-card.tsx, tabbed plans in upgrade-interstitial.client.tsx, and plan icon selector plan-icon.tsx.
    • Team Settings page.tsx: replaces server upgrade action with a link-based Upgrade button to /settings/team/upgrade.
  • Shared UI:
    • Adds @giselle-internal/ui/glass-button and @giselle-internal/ui/glass-card components and exports them in internal-packages/ui/package.json.
  • Icons:
    • Adds packages/components/icons/member-icon.tsx and packages/components/icons/ui.tsx for plan glyphs.

Written by Cursor Bugbot for commit f3f8502. This will update automatically on new commits. Configure here.

Copilot AI review requested due to automatic review settings December 22, 2025 12:34
@kaochannel154 kaochannel154 requested a review from shige as a code owner December 22, 2025 12:34
@vercel
Copy link

vercel bot commented Dec 22, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
giselle Ready Ready Preview, Comment Dec 22, 2025 1:22pm
ui Ready Ready Preview, Comment Dec 22, 2025 1:22pm

@giselles-ai
Copy link

giselles-ai bot commented Dec 22, 2025

Finished running flow.

Step 1
🟢
On Pull Request OpenedStatus: Success Updated: Dec 22, 2025 12:34pm
Step 2
🟢
Manual QAStatus: Success Updated: Dec 22, 2025 12:37pm
🟢
Prompt for AI AgentsStatus: Success Updated: Dec 22, 2025 12:37pm
Step 3
🟢
Create a Comment for PRStatus: Success Updated: Dec 22, 2025 12:41pm
Step 4
🟢
Create Pull Request CommentStatus: Success Updated: Dec 22, 2025 12:41pm

@changeset-bot
Copy link

changeset-bot bot commented Dec 22, 2025

⚠️ No Changeset found

Latest commit: f3f8502

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

💥 An error occurred when fetching the changed packages and changesets in this PR
Some errors occurred when validating the changesets config:
The package or glob expression "giselles-ai" is specified in the `ignore` option but it is not found in the project. You may have misspelled the package name or provided an invalid glob expression. Note that glob expressions must be defined according to https://www.npmjs.com/package/micromatch.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 22, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

This PR introduces a new team upgrade interstitial flow with supporting UI components. It adds page routing structure, a tabbed pricing display with Personal and Business plan options, and new reusable glass-styled button and card components. The team settings page is updated to navigate to the new upgrade flow via client-side routing instead of invoking a server action.

Changes

Cohort / File(s) Summary
Upgrade UI Pages & Layout
apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/layout.tsx, apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/page.tsx
Adds layout wrapper with full-height centered container and page component rendering the upgrade interstitial
Upgrade Interstitial & Supporting Components
apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/upgrade-interstitial.client.tsx, apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/pricing-card.tsx, apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/plan-icon.tsx
Implements tabbed upgrade interface with Personal/Business tabs, pricing cards with features/CTAs, and variant-based circular plan icons
Icon Components
apps/studio.giselles.ai/packages/components/icons/member-icon.tsx, apps/studio.giselles.ai/packages/components/icons/ui.tsx
Adds MemberIcon and Free/Pro UI icons with SVG definitions and accessibility attributes
Glass UI Components & Exports
internal-packages/ui/components/glass-button.tsx, internal-packages/ui/components/glass-card.tsx, internal-packages/ui/package.json
Introduces reusable GlassButton (with variants: default, muted, comingSoon, currentPlan) and GlassCard components with layered styling; updates package exports
Team Settings Navigation
apps/studio.giselles.ai/app/(main)/settings/team/page.tsx
Replaces server action-based upgrade workflow with Link-based client navigation to /settings/team/upgrade

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–25 minutes

  • GlassButton complexity: Multiple variants with conditional styling, layered visuals (glow, reflection, borders), and hover fill logic require careful validation of class composition and visual behavior
  • UpgradeInterstitial logic: Tabbed interface state management, pricing card rendering with conditional gradients, and feature list mapping warrant verification of conditional rendering correctness
  • Icon SVG accuracy: Verify MemberIcon and Free/Pro SVG paths render correctly and scale appropriately in different contexts
  • Navigation migration: Confirm the Link-based upgrade flow works as expected and that removing the server action doesn't break any backend workflows

Poem

🐰✨ Glass buttons shimmer, cards glow bright,
Plans in tabs—a pricing sight!
Icons nestled, features mapped with care,
Navigation flows through crystal air.
The upgrade path now blooms so clear,
A hoppy journey, tier by tier! 🚀

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.88% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and accurately summarizes the main change: adding a team upgrade interstitial page with pricing plans, which is the primary focus of the PR.
Description check ✅ Passed The PR description is comprehensive and well-structured, covering all required sections with clear explanations of changes, refactoring, and diagrams.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/upgrade-interstitial-page

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@qodo-free-for-open-source-projects
Copy link

qodo-free-for-open-source-projects bot commented Dec 22, 2025

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a UI-only team upgrade interstitial page at /settings/team/upgrade with a standalone layout and implements plan cards in a glass style. It refactors GlassButton and GlassCard components by moving them from the Studio app into the shared @giselle-internal/ui package, updating all imports across the codebase. Additionally, plan icons are updated to use lucide's Orbit for Free, a custom member icon for Team, and the previous Free glyph for Enterprise.

  • Refactors glass components into shared UI package
  • Implements upgrade interstitial with Personal/Business tabs and plan cards
  • Updates plan icons with new variants

Reviewed changes

Copilot reviewed 21 out of 21 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
internal-packages/ui/package.json Adds exports for glass-button and glass-card components
internal-packages/ui/components/glass-card.tsx Creates new GlassCard component with glass morphism styling
internal-packages/ui/components/glass-button.tsx Creates new GlassButton component with multiple variants (default, muted, comingSoon, currentPlan)
apps/studio.giselles.ai/packages/components/icons/willi-icon.tsx Adds WilliIcon and WilliDuoIcon components
apps/studio.giselles.ai/packages/components/icons/ui.tsx Adds OSS, Free, Pro, and Team plan icons
apps/studio.giselles.ai/packages/components/icons/member-icon.tsx Adds MemberIcon component for Team plan
apps/studio.giselles.ai/components/ui/gradient-button.tsx Creates new GradientButton component for primary/disabled states
apps/studio.giselles.ai/components/ui/glass-button.tsx Removes old GlassButton implementation (moved to shared package)
apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/upgrade-interstitial.client.tsx Implements main upgrade interstitial UI with tabs and plan cards
apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/pricing-card.tsx Creates PricingCard component for displaying plan details
apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/plan-icon.tsx Implements CircleIcon component for plan icons
apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/page.tsx Page component for upgrade route
apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/layout.tsx Standalone layout without sidebar/header
apps/studio.giselles.ai/app/(main)/workspaces/create-workspace-button.tsx Updates import to use GlassButton from shared package
apps/studio.giselles.ai/app/(main)/ui/sidebar/create-app-button.tsx Updates import to use GlassButton from shared package
apps/studio.giselles.ai/app/(main)/stage/showcase/showcase-client.tsx Updates import to use GlassButton from shared package
apps/studio.giselles.ai/app/(main)/stage/showcase/[appId]/app-detail-client.tsx Updates import to use GlassButton from shared package
apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/repository-registration-dialog.tsx Updates import to use GlassButton from shared package
apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/document-store-create-dialog.tsx Updates import to use GlassButton from shared package
apps/studio.giselles.ai/app/(main)/settings/team/invite-member-dialog.tsx Updates import to use GlassButton from shared package
apps/studio.giselles.ai/app/(main)/settings/account/page.tsx Updates import to use GlassButton from shared package

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@@ -0,0 +1,129 @@
import clsx from "clsx/lite";
import { Slot } from "radix-ui";
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

The import should be from '@radix-ui/react-slot' instead of from 'radix-ui'. The package name is incorrect.

Copilot uses AI. Check for mistakes.
disabled,
...props
}: GlassButtonProps) {
const Comp = asChild ? Slot.Root : "button";
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

When using the correct import, this should be just Slot not Slot.Root. The Slot component is exported directly from '@radix-ui/react-slot'.

Suggested change
const Comp = asChild ? Slot.Root : "button";
const Comp = asChild ? Slot : "button";

Copilot uses AI. Check for mistakes.
)}

{/* Content */}
<Slot.Slottable>
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

When using the correct import, this should be just Slottable which needs to be imported separately from '@radix-ui/react-slot'. Slot.Slottable is not the correct API.

Copilot uses AI. Check for mistakes.
isCurrentPlan?: boolean;
}) {
const cardClassName = [
"relative flex flex-col overflow-hidden rounded-[20px] border border-white/10 pb-6 transition-all duration-300 w-full max-w-[330px] backdrop-blur-[40px] bg-white/5 shadow-[0_8px_32px_0_rgba(31,38,135,0.37),inset_0_1px_0_rgba(255,255,255,0.15)] before:content-[''] before:absolute before:inset-0 before:rounded-[20px] before:border before:border-white/15 before:bg-gradient-to-br before:from-white/10 before:to-transparent before:pointer-events-none h-[550px] sm:h-[600px] lg:h-[625px]",
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

This is an extremely long className string that is difficult to read and maintain. Consider extracting the class names into a clsx() call with logical groupings or using the cn() utility with multiple arguments.

Copilot uses AI. Check for mistakes.
@qodo-free-for-open-source-projects
Copy link

qodo-free-for-open-source-projects bot commented Dec 22, 2025

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
High-level
Decouple plan data from UI

To improve maintainability and reduce code duplication, extract the hardcoded
plan details from upgrade-interstitial.client.tsx into a separate configuration
object. Then, render the pricing cards dynamically based on the selected tab.

Examples:

apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/upgrade-interstitial.client.tsx [58-215]
				{tabId === "personal" ? (
					<div className="mt-10 flex justify-center">
						<div className="inline-grid flex-col gap-y-[23px] sm:grid sm:grid-cols-2 sm:gap-4 lg:grid-cols-3 lg:gap-6">
							<section className="flex justify-center">
								<PricingCard
									icon={<CircleIcon variant="free" />}
									title="Free"
									subtitle="Perfect for solo developers exploring AI agents"
									price={{ amount: "Free", cadence: "" }}
									isCurrentPlan

 ... (clipped 148 lines)

Solution Walkthrough:

Before:

export function UpgradeInterstitial() {
  const [tabId, setTabId] = useState("personal");
  // ...
  return (
    // ...
    {tabId === "personal" ? (
      <div className="grid ...">
        <PricingCard title="Free" ... />
        <PricingCard title="Pro" ... />
        <PricingCard title="Team" price={{ amount: "$100" }} features={["...", "...", ]} ... />
      </div>
    ) : (
      <div className="grid ...">
        <PricingCard title="Team" price={{ amount: "$100" }} features={["...", "...", ]} ... />
        <PricingCard title="Enterprise" ... />
      </div>
    )}
  );
}

After:

const ALL_PLANS = [
  { id: "free", category: "personal", title: "Free", ... },
  { id: "pro", category: "personal", title: "Pro", ... },
  { id: "team", category: ["personal", "business"], title: "Team", ... },
  { id: "enterprise", category: "business", title: "Enterprise", ... },
];

export function UpgradeInterstitial() {
  const [tabId, setTabId] = useState("personal");
  const displayedPlans = ALL_PLANS.filter(p => p.category.includes(tabId));

  return (
    // ...
    <div className="grid ...">
      {displayedPlans.map(plan => <PricingCard key={plan.id} {...plan} />)}
    </div>
  );
}
Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies significant code duplication for the 'Team' plan in upgrade-interstitial.client.tsx and proposes a robust solution to improve maintainability by decoupling plan data from the UI.

Medium
Possible issue
Correct the plan icon mapping

Correct the icon mapping in plan-icon.tsx by swapping the icons for the
"enterprise" and "free" plans to ensure they are displayed correctly.

apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/plan-icon.tsx [13-22]

 	const glyph =
 		variant === "enterprise" ? (
-			<FreeIcon />
+			<Orbit className="h-6 w-6" />
 		) : variant === "team" ? (
 			<MemberIcon />
 		) : variant === "pro" ? (
 			<ProIcon />
 		) : (
-			<Orbit className="h-6 w-6" />
+			<FreeIcon />
 		);
  • Apply / Chat
Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies a logical error in the icon mapping for pricing plans, which would result in displaying the wrong icon for the "enterprise" and "free" tiers.

Medium
  • Update

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (8)
apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/plan-icon.tsx (2)

13-22: Consider refactoring nested ternary for readability.

The nested ternary works but could be more maintainable as an object lookup or switch statement.

🔎 Suggested refactor using object lookup
-	const glyph =
-		variant === "enterprise" ? (
-			<FreeIcon />
-		) : variant === "team" ? (
-			<MemberIcon />
-		) : variant === "pro" ? (
-			<ProIcon />
-		) : (
-			<Orbit className="h-6 w-6" />
-		);
+	const glyphMap = {
+		enterprise: <FreeIcon />,
+		team: <MemberIcon />,
+		pro: <ProIcon />,
+		free: <Orbit className="h-6 w-6" />,
+	};
+	const glyph = glyphMap[variant];

25-25: Replace hardcoded color values with design tokens.

The className uses hardcoded hex colors (#ffffff33, #dddddd99, etc.) that should be replaced with CSS variables or Tailwind design tokens for consistency and maintainability.

Consider using Tailwind opacity utilities (e.g., bg-white/20, border-gray-200/60) or defining these colors in your design system.

apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/upgrade-interstitial.client.tsx (2)

43-51: Move inline styles to CSS module or Tailwind classes.

The inline textShadow style (lines 45-48) should be extracted to a CSS class or Tailwind utility for maintainability and reusability.

🔎 Suggested approaches

Option 1: Tailwind CSS custom utility (add to tailwind.config):

theme: {
  extend: {
    textShadow: {
      'blue-glow': '0 0 20px rgb(0, 135, 246), 0 0 40px rgb(0, 135, 246), 0 0 60px rgb(0, 135, 246)',
    }
  }
}

Then use: className="text-shadow-blue-glow"

Option 2: CSS module:

.glowTitle {
  text-shadow: rgb(0, 135, 246) 0px 0px 20px, 
               rgb(0, 135, 246) 0px 0px 40px, 
               rgb(0, 135, 246) 0px 0px 60px;
}

239-244: Use clsx for className composition.

Array.join for className composition is less idiomatic than using the clsx utility, which is already available in the project.

🔎 Suggested refactor
+import clsx from "clsx";

 <button
   key={option.id}
   type="button"
   onClick={() => onChange(option.id)}
-  className={[
-    "rounded-full px-5 py-2 text-[13px] font-semibold transition-colors",
-    isActive
-      ? "bg-white/90 text-black shadow-sm"
-      : "text-white/70 hover:text-white",
-  ].join(" ")}
+  className={clsx(
+    "rounded-full px-5 py-2 text-[13px] font-semibold transition-colors",
+    isActive
+      ? "bg-white/90 text-black shadow-sm"
+      : "text-white/70 hover:text-white"
+  )}
 >
apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/pricing-card.tsx (2)

83-93: Consider using a stable key instead of feature text.

Using feature string directly as the key will cause issues if two features have identical text. Consider using the index as a fallback or ensuring feature uniqueness is enforced upstream.

🔎 Safer key approach
-							{features.map((feature) => (
+							{features.map((feature, index) => (
 								<li
-									key={feature}
+									key={`feature-${index}`}
 									className="flex items-start gap-x-2 sm:gap-x-3 text-white-100 font-sans font-normal text-xs sm:text-sm leading-3 sm:leading-4"
 								>

49-49: Clarify the purpose of this empty div.

This div renders no content and its purpose isn't clear. If it's a spacer or layout element, consider adding a brief comment explaining its role, or remove it if unnecessary.

internal-packages/ui/components/glass-button.tsx (2)

46-70: Consider refactoring nested ternaries to an object lookup.

The 4-level nested ternary is difficult to read and maintain. An object lookup pattern would be cleaner and more consistent with variantClassName and sizeClassName.

🔎 Proposed refactor using object lookup
-	const styles: React.CSSProperties =
-		variant === "comingSoon"
-			? {
-					boxShadow: "0 10px 30px rgba(0, 0, 0, 0.35)",
-					background: "rgba(255, 255, 255, 0.05)",
-				}
-			: variant === "currentPlan"
-				? {
-						boxShadow:
-							"0 10px 30px rgba(0, 0, 0, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.12)",
-						background: "rgba(255, 255, 255, 0.04)",
-					}
-				: variant === "muted"
-					? {
-							boxShadow:
-								"0 8px 20px rgba(255, 255, 255, 0.05), 0 3px 10px rgba(0, 0, 0, 0.25), inset 0 1px 0 rgba(255, 255, 255, 0.18), inset 0 -1px 0 rgba(0, 0, 0, 0.25), 0 0 0 1px rgba(255, 255, 255, 0.08)",
-							background:
-								"linear-gradient(135deg, rgba(255,255,255,0.08) 0%, rgba(255,255,255,0.06) 50%, rgba(0,0,0,0.18) 100%)",
-						}
-					: {
-							boxShadow:
-								"0 8px 20px rgba(107, 143, 240, 0.2), 0 3px 10px rgba(107, 143, 240, 0.15), inset 0 1px 0 rgba(255, 255, 255, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(255, 255, 255, 0.08)",
-							background:
-								"linear-gradient(135deg, rgba(255,255,255,0.1) 0%, rgba(107,143,240,0.15) 50%, rgba(107,143,240,0.25) 100%)",
-						};
+	const variantStyles: Record<GlassButtonVariant, React.CSSProperties> = {
+		comingSoon: {
+			boxShadow: "0 10px 30px rgba(0, 0, 0, 0.35)",
+			background: "rgba(255, 255, 255, 0.05)",
+		},
+		currentPlan: {
+			boxShadow:
+				"0 10px 30px rgba(0, 0, 0, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.12)",
+			background: "rgba(255, 255, 255, 0.04)",
+		},
+		muted: {
+			boxShadow:
+				"0 8px 20px rgba(255, 255, 255, 0.05), 0 3px 10px rgba(0, 0, 0, 0.25), inset 0 1px 0 rgba(255, 255, 255, 0.18), inset 0 -1px 0 rgba(0, 0, 0, 0.25), 0 0 0 1px rgba(255, 255, 255, 0.08)",
+			background:
+				"linear-gradient(135deg, rgba(255,255,255,0.08) 0%, rgba(255,255,255,0.06) 50%, rgba(0,0,0,0.18) 100%)",
+		},
+		default: {
+			boxShadow:
+				"0 8px 20px rgba(107, 143, 240, 0.2), 0 3px 10px rgba(107, 143, 240, 0.15), inset 0 1px 0 rgba(255, 255, 255, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(255, 255, 255, 0.08)",
+			background:
+				"linear-gradient(135deg, rgba(255,255,255,0.1) 0%, rgba(107,143,240,0.15) 50%, rgba(107,143,240,0.25) 100%)",
+		},
+	};
+
+	const styles = variantStyles[variant];

84-103: Same refactor opportunity for glow styling.

The nested ternaries for backgroundColor and opacity could similarly use an object lookup for consistency and readability.

🔎 Proposed refactor
+	const glowConfig: Record<GlassButtonVariant, { color: string; opacity: number }> = {
+		comingSoon: { color: "#FFFFFF", opacity: 0.015 },
+		currentPlan: { color: "#FFFFFF", opacity: 0.03 },
+		muted: { color: "#FFFFFF", opacity: 0.05 },
+		default: { color: "#6B8FF0", opacity: 0.08 },
+	};

 			{/* Outer glow */}
 			<div
 				className="absolute inset-0 rounded-lg blur-[2px] -z-10"
 				style={{
-					backgroundColor:
-						variant === "comingSoon" || variant === "currentPlan"
-							? "#FFFFFF"
-							: variant === "muted"
-								? "#FFFFFF"
-								: "#6B8FF0",
-					opacity:
-						variant === "comingSoon"
-							? 0.015
-							: variant === "currentPlan"
-								? 0.03
-								: variant === "muted"
-									? 0.05
-									: 0.08,
+					backgroundColor: glowConfig[variant].color,
+					opacity: glowConfig[variant].opacity,
 				}}
 			/>
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 84e9300 and b486945.

📒 Files selected for processing (21)
  • apps/studio.giselles.ai/app/(main)/settings/account/page.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/invite-member-dialog.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/document-store-create-dialog.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/repository-registration-dialog.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/[appId]/app-detail-client.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/showcase-client.tsx
  • apps/studio.giselles.ai/app/(main)/ui/sidebar/create-app-button.tsx
  • apps/studio.giselles.ai/app/(main)/workspaces/create-workspace-button.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/layout.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/page.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/plan-icon.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/pricing-card.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/upgrade-interstitial.client.tsx
  • apps/studio.giselles.ai/components/ui/glass-button.tsx
  • apps/studio.giselles.ai/components/ui/gradient-button.tsx
  • apps/studio.giselles.ai/packages/components/icons/member-icon.tsx
  • apps/studio.giselles.ai/packages/components/icons/ui.tsx
  • apps/studio.giselles.ai/packages/components/icons/willi-icon.tsx
  • internal-packages/ui/components/glass-button.tsx
  • internal-packages/ui/components/glass-card.tsx
  • internal-packages/ui/package.json
💤 Files with no reviewable changes (1)
  • apps/studio.giselles.ai/components/ui/glass-button.tsx
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,js,jsx}: Favor clear, descriptive names and type annotations over clever tricks
If you need a multi-paragraph comment, refactor until intent is obvious

**/*.{ts,tsx,js,jsx}: Use async/await and proper error handling
Variables and functions should use camelCase naming
Booleans and functions should use is, has, can, should prefixes
Function names should clearly indicate purpose

Files:

  • internal-packages/ui/components/glass-card.tsx
  • apps/studio.giselles.ai/components/ui/gradient-button.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/repository-registration-dialog.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/plan-icon.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/upgrade-interstitial.client.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/layout.tsx
  • apps/studio.giselles.ai/app/(main)/settings/account/page.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/pricing-card.tsx
  • apps/studio.giselles.ai/app/(main)/workspaces/create-workspace-button.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/invite-member-dialog.tsx
  • apps/studio.giselles.ai/packages/components/icons/member-icon.tsx
  • internal-packages/ui/components/glass-button.tsx
  • apps/studio.giselles.ai/packages/components/icons/ui.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/document-store-create-dialog.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/page.tsx
  • apps/studio.giselles.ai/packages/components/icons/willi-icon.tsx
  • apps/studio.giselles.ai/app/(main)/ui/sidebar/create-app-button.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/[appId]/app-detail-client.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/showcase-client.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development-guide.mdc)

**/*.{ts,tsx}: MUST run pnpm biome check --write [filename] after EVERY code modification
All code changes must be formatted using Biome before being committed
Use Biome for formatting with tab indentation and double quotes
Follow organized imports pattern (enabled in biome.json)
Use TypeScript for type safety; avoid any types
Use Next.js patterns for web applications
Use async/await for asynchronous code rather than promises
Error handling: use try/catch blocks and propagate errors appropriately
Use kebab-case for all filenames
Use PascalCase for React components and classes
Use camelCase for variables, functions, and methods
Use prefixes like is, has, can, should for boolean variables (e.g., isEnabled, hasPermission)
Use prefixes like is, has, can, should for boolean functions (e.g., isTriggerRequiringCallsign(), hasActiveSubscription()) instead of imperative verbs
Use verbs or verb phrases for function naming that clearly indicate purpose (e.g., calculateTotalPrice(), not process())

Use PascalCase for React component and class names

Use TypeScript and avoid any

Files:

  • internal-packages/ui/components/glass-card.tsx
  • apps/studio.giselles.ai/components/ui/gradient-button.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/repository-registration-dialog.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/plan-icon.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/upgrade-interstitial.client.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/layout.tsx
  • apps/studio.giselles.ai/app/(main)/settings/account/page.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/pricing-card.tsx
  • apps/studio.giselles.ai/app/(main)/workspaces/create-workspace-button.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/invite-member-dialog.tsx
  • apps/studio.giselles.ai/packages/components/icons/member-icon.tsx
  • internal-packages/ui/components/glass-button.tsx
  • apps/studio.giselles.ai/packages/components/icons/ui.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/document-store-create-dialog.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/page.tsx
  • apps/studio.giselles.ai/packages/components/icons/willi-icon.tsx
  • apps/studio.giselles.ai/app/(main)/ui/sidebar/create-app-button.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/[appId]/app-detail-client.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/showcase-client.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/development-guide.mdc)

Use functional components with React hooks

Files:

  • internal-packages/ui/components/glass-card.tsx
  • apps/studio.giselles.ai/components/ui/gradient-button.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/repository-registration-dialog.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/plan-icon.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/upgrade-interstitial.client.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/layout.tsx
  • apps/studio.giselles.ai/app/(main)/settings/account/page.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/pricing-card.tsx
  • apps/studio.giselles.ai/app/(main)/workspaces/create-workspace-button.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/invite-member-dialog.tsx
  • apps/studio.giselles.ai/packages/components/icons/member-icon.tsx
  • internal-packages/ui/components/glass-button.tsx
  • apps/studio.giselles.ai/packages/components/icons/ui.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/document-store-create-dialog.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/page.tsx
  • apps/studio.giselles.ai/packages/components/icons/willi-icon.tsx
  • apps/studio.giselles.ai/app/(main)/ui/sidebar/create-app-button.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/[appId]/app-detail-client.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/showcase-client.tsx
**/*.{js,ts,tsx,jsx,py,java,cs,cpp,c,go,rb,php,swift,kt,scala,rs,dart}

📄 CodeRabbit inference engine (.cursor/rules/language-support.mdc)

Write all code comments in English

Files:

  • internal-packages/ui/components/glass-card.tsx
  • apps/studio.giselles.ai/components/ui/gradient-button.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/repository-registration-dialog.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/plan-icon.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/upgrade-interstitial.client.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/layout.tsx
  • apps/studio.giselles.ai/app/(main)/settings/account/page.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/pricing-card.tsx
  • apps/studio.giselles.ai/app/(main)/workspaces/create-workspace-button.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/invite-member-dialog.tsx
  • apps/studio.giselles.ai/packages/components/icons/member-icon.tsx
  • internal-packages/ui/components/glass-button.tsx
  • apps/studio.giselles.ai/packages/components/icons/ui.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/document-store-create-dialog.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/page.tsx
  • apps/studio.giselles.ai/packages/components/icons/willi-icon.tsx
  • apps/studio.giselles.ai/app/(main)/ui/sidebar/create-app-button.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/[appId]/app-detail-client.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/showcase-client.tsx
**/*

📄 CodeRabbit inference engine (.cursor/rules/naming-guide.mdc)

Use kebab-case for file names (e.g., user-profile.ts, api-client.tsx)

Files:

  • internal-packages/ui/components/glass-card.tsx
  • apps/studio.giselles.ai/components/ui/gradient-button.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/repository-registration-dialog.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/plan-icon.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/upgrade-interstitial.client.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/layout.tsx
  • apps/studio.giselles.ai/app/(main)/settings/account/page.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/pricing-card.tsx
  • apps/studio.giselles.ai/app/(main)/workspaces/create-workspace-button.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/invite-member-dialog.tsx
  • apps/studio.giselles.ai/packages/components/icons/member-icon.tsx
  • internal-packages/ui/components/glass-button.tsx
  • apps/studio.giselles.ai/packages/components/icons/ui.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/document-store-create-dialog.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/page.tsx
  • apps/studio.giselles.ai/packages/components/icons/willi-icon.tsx
  • apps/studio.giselles.ai/app/(main)/ui/sidebar/create-app-button.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/[appId]/app-detail-client.tsx
  • internal-packages/ui/package.json
  • apps/studio.giselles.ai/app/(main)/stage/showcase/showcase-client.tsx
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/naming-guide.mdc)

**/*.{js,ts,jsx,tsx}: Use camelCase for variable names, functions, and methods
Use verbs or verb phrases for function names to clearly indicate what the function does (e.g., calculateTotalPrice(), validateUserInput())
Use nouns or noun phrases for variable names to describe what the variable represents
Use boolean prefixes (is, has, can, should) for boolean variables and functions returning boolean values (e.g., isEnabled, hasPermission, isTriggerRequiringCallsign())

**/*.{js,ts,jsx,tsx}: Run pnpm biome check --write [filename] after every code change
All code must be formatted with Biome before commit

Files:

  • internal-packages/ui/components/glass-card.tsx
  • apps/studio.giselles.ai/components/ui/gradient-button.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/repository-registration-dialog.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/plan-icon.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/upgrade-interstitial.client.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/layout.tsx
  • apps/studio.giselles.ai/app/(main)/settings/account/page.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/pricing-card.tsx
  • apps/studio.giselles.ai/app/(main)/workspaces/create-workspace-button.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/invite-member-dialog.tsx
  • apps/studio.giselles.ai/packages/components/icons/member-icon.tsx
  • internal-packages/ui/components/glass-button.tsx
  • apps/studio.giselles.ai/packages/components/icons/ui.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/document-store-create-dialog.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/page.tsx
  • apps/studio.giselles.ai/packages/components/icons/willi-icon.tsx
  • apps/studio.giselles.ai/app/(main)/ui/sidebar/create-app-button.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/[appId]/app-detail-client.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/showcase-client.tsx
**/{components,pages}/**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Components should use React hooks and Next.js patterns

Files:

  • internal-packages/ui/components/glass-card.tsx
  • apps/studio.giselles.ai/components/ui/gradient-button.tsx
  • apps/studio.giselles.ai/packages/components/icons/member-icon.tsx
  • internal-packages/ui/components/glass-button.tsx
  • apps/studio.giselles.ai/packages/components/icons/ui.tsx
  • apps/studio.giselles.ai/packages/components/icons/willi-icon.tsx
**/*.{ts,tsx,js,jsx,css}

📄 CodeRabbit inference engine (AGENTS.md)

Files should use kebab-case naming

Files:

  • internal-packages/ui/components/glass-card.tsx
  • apps/studio.giselles.ai/components/ui/gradient-button.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/repository-registration-dialog.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/plan-icon.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/upgrade-interstitial.client.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/layout.tsx
  • apps/studio.giselles.ai/app/(main)/settings/account/page.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/pricing-card.tsx
  • apps/studio.giselles.ai/app/(main)/workspaces/create-workspace-button.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/invite-member-dialog.tsx
  • apps/studio.giselles.ai/packages/components/icons/member-icon.tsx
  • internal-packages/ui/components/glass-button.tsx
  • apps/studio.giselles.ai/packages/components/icons/ui.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/document-store-create-dialog.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/page.tsx
  • apps/studio.giselles.ai/packages/components/icons/willi-icon.tsx
  • apps/studio.giselles.ai/app/(main)/ui/sidebar/create-app-button.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/[appId]/app-detail-client.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/showcase-client.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Components should use PascalCase naming

Files:

  • internal-packages/ui/components/glass-card.tsx
  • apps/studio.giselles.ai/components/ui/gradient-button.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/repository-registration-dialog.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/plan-icon.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/upgrade-interstitial.client.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/layout.tsx
  • apps/studio.giselles.ai/app/(main)/settings/account/page.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/pricing-card.tsx
  • apps/studio.giselles.ai/app/(main)/workspaces/create-workspace-button.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/invite-member-dialog.tsx
  • apps/studio.giselles.ai/packages/components/icons/member-icon.tsx
  • internal-packages/ui/components/glass-button.tsx
  • apps/studio.giselles.ai/packages/components/icons/ui.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/document-store-create-dialog.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/page.tsx
  • apps/studio.giselles.ai/packages/components/icons/willi-icon.tsx
  • apps/studio.giselles.ai/app/(main)/ui/sidebar/create-app-button.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/[appId]/app-detail-client.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/showcase-client.tsx
🧠 Learnings (35)
📓 Common learnings
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: .cursor/rules/edit-workspace-tour.mdc:0-0
Timestamp: 2025-11-25T03:05:31.051Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/workspace-tour/assets/** : Replace GIFs and images in the `assets/` directory and update imports and references in `workspace-tour.tsx`
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: .cursor/rules/edit-workspace-tour.mdc:0-0
Timestamp: 2025-11-25T03:05:31.051Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/workspace-tour/workspace-tour.tsx : Update the `TourGlobalStyles` component in `workspace-tour.tsx` for animation changes
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: internal-packages/workflow-designer-ui/src/new-editor/AGENTS.md:0-0
Timestamp: 2025-11-25T03:07:19.740Z
Learning: Applies to internal-packages/workflow-designer-ui/src/new-editor/**/*.{ts,tsx} : Lift actions into the store (e.g., `updateNode`) and call them from components needing mutations instead of passing mutation callbacks as props
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: .cursor/rules/edit-workspace-tour.mdc:0-0
Timestamp: 2025-11-25T03:05:31.051Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/workspace-tour/workspace-tour.tsx : Import new images at the top of `workspace-tour.tsx` and update the `imageSrc` prop in the appropriate step component to use the new image
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: internal-packages/workflow-designer-ui/src/editor/properties-panel/trigger-node-properties-panel/providers/github-trigger/AGENTS.md:0-0
Timestamp: 2025-11-25T03:07:07.498Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/properties-panel/trigger-node-properties-panel/providers/github-trigger/components/{callsign,labels}*.tsx : Hide the 'Back' button in `input-callsign` and `input-labels` steps during reconfiguration mode to simplify UX.
📚 Learning: 2025-11-25T03:05:31.051Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: .cursor/rules/edit-workspace-tour.mdc:0-0
Timestamp: 2025-11-25T03:05:31.051Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/workspace-tour/workspace-tour.tsx : Modify the `CARD_STYLES` constants in `workspace-tour.tsx` to change step styling

Applied to files:

  • internal-packages/ui/components/glass-card.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/pricing-card.tsx
  • apps/studio.giselles.ai/app/(main)/workspaces/create-workspace-button.tsx
  • apps/studio.giselles.ai/packages/components/icons/ui.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/document-store-create-dialog.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/showcase-client.tsx
📚 Learning: 2025-11-25T03:05:31.051Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: .cursor/rules/edit-workspace-tour.mdc:0-0
Timestamp: 2025-11-25T03:05:31.051Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/workspace-tour/workspace-tour.tsx : Update the `TourGlobalStyles` component in `workspace-tour.tsx` for animation changes

Applied to files:

  • internal-packages/ui/components/glass-card.tsx
  • apps/studio.giselles.ai/components/ui/gradient-button.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/repository-registration-dialog.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/plan-icon.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/upgrade-interstitial.client.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/layout.tsx
  • apps/studio.giselles.ai/app/(main)/settings/account/page.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/pricing-card.tsx
  • apps/studio.giselles.ai/app/(main)/workspaces/create-workspace-button.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/invite-member-dialog.tsx
  • apps/studio.giselles.ai/packages/components/icons/member-icon.tsx
  • internal-packages/ui/components/glass-button.tsx
  • apps/studio.giselles.ai/packages/components/icons/ui.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/document-store-create-dialog.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/page.tsx
  • apps/studio.giselles.ai/packages/components/icons/willi-icon.tsx
  • apps/studio.giselles.ai/app/(main)/ui/sidebar/create-app-button.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/[appId]/app-detail-client.tsx
  • internal-packages/ui/package.json
  • apps/studio.giselles.ai/app/(main)/stage/showcase/showcase-client.tsx
📚 Learning: 2025-11-25T03:07:19.740Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: internal-packages/workflow-designer-ui/src/new-editor/AGENTS.md:0-0
Timestamp: 2025-11-25T03:07:19.740Z
Learning: Applies to internal-packages/workflow-designer-ui/src/new-editor/components/**/*.{ts,tsx} : Wrap presentational components in `React.memo` only when their props are stable and derived via selectors

Applied to files:

  • internal-packages/ui/components/glass-card.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/layout.tsx
  • internal-packages/ui/components/glass-button.tsx
📚 Learning: 2025-11-25T03:07:19.740Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: internal-packages/workflow-designer-ui/src/new-editor/AGENTS.md:0-0
Timestamp: 2025-11-25T03:07:19.740Z
Learning: Applies to internal-packages/workflow-designer-ui/src/new-editor/**/*.{ts,tsx} : Replace context-wide reads from `src/editor/v2` with fine-grained selectors against the Zustand store

Applied to files:

  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/repository-registration-dialog.tsx
  • apps/studio.giselles.ai/app/(main)/workspaces/create-workspace-button.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/invite-member-dialog.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/document-store-create-dialog.tsx
  • apps/studio.giselles.ai/app/(main)/ui/sidebar/create-app-button.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/showcase-client.tsx
📚 Learning: 2025-11-25T03:05:31.051Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: .cursor/rules/edit-workspace-tour.mdc:0-0
Timestamp: 2025-11-25T03:05:31.051Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/workspace-tour/assets/** : Replace GIFs and images in the `assets/` directory and update imports and references in `workspace-tour.tsx`

Applied to files:

  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/repository-registration-dialog.tsx
  • apps/studio.giselles.ai/app/(main)/settings/account/page.tsx
  • apps/studio.giselles.ai/app/(main)/workspaces/create-workspace-button.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/invite-member-dialog.tsx
  • apps/studio.giselles.ai/packages/components/icons/ui.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/document-store-create-dialog.tsx
  • apps/studio.giselles.ai/app/(main)/ui/sidebar/create-app-button.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/[appId]/app-detail-client.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/showcase-client.tsx
📚 Learning: 2025-11-25T03:05:31.051Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: .cursor/rules/edit-workspace-tour.mdc:0-0
Timestamp: 2025-11-25T03:05:31.051Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/workspace-tour/workspace-tour.tsx : Import new images at the top of `workspace-tour.tsx` and update the `imageSrc` prop in the appropriate step component to use the new image

Applied to files:

  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/repository-registration-dialog.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/layout.tsx
  • apps/studio.giselles.ai/app/(main)/workspaces/create-workspace-button.tsx
  • apps/studio.giselles.ai/packages/components/icons/ui.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/document-store-create-dialog.tsx
  • apps/studio.giselles.ai/app/(main)/ui/sidebar/create-app-button.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/showcase-client.tsx
📚 Learning: 2025-11-25T03:07:07.498Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: internal-packages/workflow-designer-ui/src/editor/properties-panel/trigger-node-properties-panel/providers/github-trigger/AGENTS.md:0-0
Timestamp: 2025-11-25T03:07:07.498Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/properties-panel/trigger-node-properties-panel/providers/github-trigger/components/{callsign,labels}*.tsx : Hide the 'Back' button in `input-callsign` and `input-labels` steps during reconfiguration mode to simplify UX.

Applied to files:

  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/repository-registration-dialog.tsx
  • apps/studio.giselles.ai/app/(main)/workspaces/create-workspace-button.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/invite-member-dialog.tsx
  • internal-packages/ui/components/glass-button.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/document-store-create-dialog.tsx
  • apps/studio.giselles.ai/app/(main)/ui/sidebar/create-app-button.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/showcase-client.tsx
📚 Learning: 2025-11-25T03:07:19.740Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: internal-packages/workflow-designer-ui/src/new-editor/AGENTS.md:0-0
Timestamp: 2025-11-25T03:07:19.740Z
Learning: Applies to internal-packages/workflow-designer-ui/src/new-editor/**/*.{ts,tsx} : Use shallow equality for arrays and objects in selectors to avoid false-positive updates

Applied to files:

  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/repository-registration-dialog.tsx
  • apps/studio.giselles.ai/app/(main)/workspaces/create-workspace-button.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/invite-member-dialog.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/document-store-create-dialog.tsx
  • apps/studio.giselles.ai/app/(main)/ui/sidebar/create-app-button.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/[appId]/app-detail-client.tsx
  • internal-packages/ui/package.json
  • apps/studio.giselles.ai/app/(main)/stage/showcase/showcase-client.tsx
📚 Learning: 2025-11-25T03:07:19.740Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: internal-packages/workflow-designer-ui/src/new-editor/AGENTS.md:0-0
Timestamp: 2025-11-25T03:07:19.740Z
Learning: Applies to internal-packages/workflow-designer-ui/src/new-editor/**/*.{ts,tsx} : Lift actions into the store (e.g., `updateNode`) and call them from components needing mutations instead of passing mutation callbacks as props

Applied to files:

  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/repository-registration-dialog.tsx
  • apps/studio.giselles.ai/app/(main)/workspaces/create-workspace-button.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/document-store-create-dialog.tsx
  • apps/studio.giselles.ai/app/(main)/ui/sidebar/create-app-button.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/showcase-client.tsx
📚 Learning: 2025-11-25T03:07:07.498Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: internal-packages/workflow-designer-ui/src/editor/properties-panel/trigger-node-properties-panel/providers/github-trigger/AGENTS.md:0-0
Timestamp: 2025-11-25T03:07:07.498Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/properties-panel/trigger-node-properties-panel/providers/github-trigger/**/*.tsx : Wrap all state updates in `startTransition` for consistent UI behavior during configuration and reconfiguration flows.

Applied to files:

  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/repository-registration-dialog.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/layout.tsx
  • internal-packages/ui/components/glass-button.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/document-store-create-dialog.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/showcase-client.tsx
📚 Learning: 2025-11-25T03:07:19.740Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: internal-packages/workflow-designer-ui/src/new-editor/AGENTS.md:0-0
Timestamp: 2025-11-25T03:07:19.740Z
Learning: Applies to internal-packages/workflow-designer-ui/src/new-editor/**/*.{ts,tsx} : Keep derivations simple and stable in selectors; maintain ordering when mapping to arrays so equality checks can short-circuit

Applied to files:

  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/repository-registration-dialog.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/invite-member-dialog.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/document-store-create-dialog.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/[appId]/app-detail-client.tsx
  • internal-packages/ui/package.json
📚 Learning: 2025-11-25T03:07:07.498Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: internal-packages/workflow-designer-ui/src/editor/properties-panel/trigger-node-properties-panel/providers/github-trigger/AGENTS.md:0-0
Timestamp: 2025-11-25T03:07:07.498Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/properties-panel/trigger-node-properties-panel/providers/github-trigger/**/*.tsx : Use `client.reconfigureGitHubTrigger()` for reconfiguration with parameters: `flowTriggerId`, `repositoryNodeId`, `installationId`, `event` (with updated callsign/labels), and `useExperimentalStorage`.

Applied to files:

  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/repository-registration-dialog.tsx
📚 Learning: 2025-11-25T03:07:07.498Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: internal-packages/workflow-designer-ui/src/editor/properties-panel/trigger-node-properties-panel/providers/github-trigger/AGENTS.md:0-0
Timestamp: 2025-11-25T03:07:07.498Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/properties-panel/trigger-node-properties-panel/providers/github-trigger/**/*.tsx : Manage setup wizard state progression through steps: `select-event` → `select-repository` → `confirm-repository` → optionally `input-callsign` → optionally `input-labels` → `configured`.

Applied to files:

  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/repository-registration-dialog.tsx
  • apps/studio.giselles.ai/app/(main)/workspaces/create-workspace-button.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/invite-member-dialog.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/showcase-client.tsx
📚 Learning: 2025-11-25T03:07:07.498Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: internal-packages/workflow-designer-ui/src/editor/properties-panel/trigger-node-properties-panel/providers/github-trigger/AGENTS.md:0-0
Timestamp: 2025-11-25T03:07:07.498Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/properties-panel/trigger-node-properties-panel/providers/github-trigger/**/*.tsx : Enable runtime toggle via `useGitHubTrigger()` hook which exposes `enableFlowTrigger()` and `disableFlowTrigger()` with optimistic UI updates.

Applied to files:

  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/repository-registration-dialog.tsx
📚 Learning: 2025-11-25T03:07:07.498Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: internal-packages/workflow-designer-ui/src/editor/properties-panel/trigger-node-properties-panel/providers/github-trigger/AGENTS.md:0-0
Timestamp: 2025-11-25T03:07:07.498Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/properties-panel/trigger-node-properties-panel/providers/github-trigger/**/*.tsx : Require callsign input for these GitHub events: `github.issue_comment.created`, `github.pull_request_comment.created`, `github.pull_request_review_comment.created`, `github.discussion_comment.created`.

Applied to files:

  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/repository-registration-dialog.tsx
📚 Learning: 2025-11-25T03:07:07.498Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: internal-packages/workflow-designer-ui/src/editor/properties-panel/trigger-node-properties-panel/providers/github-trigger/AGENTS.md:0-0
Timestamp: 2025-11-25T03:07:07.498Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/properties-panel/trigger-node-properties-panel/providers/github-trigger/**/*.tsx : Require labels input for these GitHub events: `github.issue.labeled`, `github.pull_request.labeled`.

Applied to files:

  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/repository-registration-dialog.tsx
📚 Learning: 2025-11-25T03:07:07.498Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: internal-packages/workflow-designer-ui/src/editor/properties-panel/trigger-node-properties-panel/providers/github-trigger/AGENTS.md:0-0
Timestamp: 2025-11-25T03:07:07.498Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/properties-panel/trigger-node-properties-panel/providers/github-trigger/**/*.tsx : Use `createTriggerEvent()` from `./utils/trigger-configuration` to build trigger event objects with appropriate properties.

Applied to files:

  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/repository-registration-dialog.tsx
📚 Learning: 2025-11-25T03:07:07.498Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: internal-packages/workflow-designer-ui/src/editor/properties-panel/trigger-node-properties-panel/providers/github-trigger/AGENTS.md:0-0
Timestamp: 2025-11-25T03:07:07.498Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/properties-panel/trigger-node-properties-panel/providers/github-trigger/**/*.tsx : Skip `input-callsign` and `input-labels` steps for events that don't require them, progressing directly to `configured` after `confirm-repository`.

Applied to files:

  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/repository-registration-dialog.tsx
📚 Learning: 2025-11-25T03:07:07.498Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: internal-packages/workflow-designer-ui/src/editor/properties-panel/trigger-node-properties-panel/providers/github-trigger/AGENTS.md:0-0
Timestamp: 2025-11-25T03:07:07.498Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/properties-panel/trigger-node-properties-panel/providers/github-trigger/github-trigger-properties-panel.tsx : Use helper functions `isTriggerRequiringCallsign()` and `isTriggerRequiringLabels()` defined in the panel file to determine which additional input steps are needed.

Applied to files:

  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/repository-registration-dialog.tsx
📚 Learning: 2025-08-14T02:34:56.156Z
Learnt from: gentamura
Repo: giselles-ai/giselle PR: 1590
File: internal-packages/workflow-designer-ui/src/editor/hooks/use-keyboard-shortcuts.ts:79-80
Timestamp: 2025-08-14T02:34:56.156Z
Learning: In the giselle codebase, React namespace types (React.KeyboardEvent, React.MouseEvent, React.ChangeEvent, etc.) are used consistently throughout the project without importing React itself, and verbatimModuleSyntax is not enabled in TypeScript configs. This pattern should be maintained for consistency rather than suggesting isolated changes to direct type imports.

Applied to files:

  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/repository-registration-dialog.tsx
  • apps/studio.giselles.ai/app/(main)/settings/account/page.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/document-store-create-dialog.tsx
  • apps/studio.giselles.ai/app/(main)/ui/sidebar/create-app-button.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/showcase-client.tsx
📚 Learning: 2025-06-23T12:31:58.286Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: .cursor/rules/edit-workspace-tour.mdc:0-0
Timestamp: 2025-06-23T12:31:58.286Z
Learning: The tour uses React portals to render above other UI elements, ensuring overlays and highlights are not obstructed by the main application UI.

Applied to files:

  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/upgrade-interstitial.client.tsx
📚 Learning: 2025-11-25T03:05:31.051Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: .cursor/rules/edit-workspace-tour.mdc:0-0
Timestamp: 2025-11-25T03:05:31.051Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/workspace-tour/workspace-tour.tsx : Modify CSS positioning in step components by adjusting Tailwind classes like `mt-[140px]` (margin-top) and `mr-8` (margin-right) in `workspace-tour.tsx`

Applied to files:

  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/layout.tsx
📚 Learning: 2025-11-25T03:05:31.051Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: .cursor/rules/edit-workspace-tour.mdc:0-0
Timestamp: 2025-11-25T03:05:31.051Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/workspace-tour/{steps.ts,workspace-tour.tsx} : Add new tour steps to the `tourSteps` array in `steps.ts`, create corresponding components in `workspace-tour.tsx` following the pattern of existing steps, and add the new step to the switch statement in the main `WorkspaceTour` component

Applied to files:

  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/layout.tsx
  • apps/studio.giselles.ai/packages/components/icons/ui.tsx
📚 Learning: 2025-11-28T00:51:04.090Z
Learnt from: shige
Repo: giselles-ai/giselle PR: 2290
File: apps/studio.giselles.ai/db/schema.ts:109-169
Timestamp: 2025-11-28T00:51:04.090Z
Learning: The team is consciously using Stripe API version 2025-11-17.preview for Stripe v2 billing cadence (stripeBillingCadenceHistories) and pricing plan subscription (stripePricingPlanSubscriptionHistories) features in apps/studio.giselles.ai/db/schema.ts with awareness that preview APIs may not be production-safe.

Applied to files:

  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/pricing-card.tsx
📚 Learning: 2025-11-25T03:07:19.740Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: internal-packages/workflow-designer-ui/src/new-editor/AGENTS.md:0-0
Timestamp: 2025-11-25T03:07:19.740Z
Learning: Applies to internal-packages/workflow-designer-ui/src/new-editor/**/*.{ts,tsx} : Avoid new object/array creation in selectors unless using an equality function that treats them as equal when unchanged

Applied to files:

  • apps/studio.giselles.ai/app/(main)/workspaces/create-workspace-button.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/invite-member-dialog.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/document-store-create-dialog.tsx
📚 Learning: 2025-11-25T03:05:31.051Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: .cursor/rules/edit-workspace-tour.mdc:0-0
Timestamp: 2025-11-25T03:05:31.051Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/workspace-tour/steps.ts : Modify the `tourSteps` array in `steps.ts` to change text, target elements, or placement for the workspace tour

Applied to files:

  • apps/studio.giselles.ai/app/(main)/workspaces/create-workspace-button.tsx
📚 Learning: 2025-06-23T12:31:58.286Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: .cursor/rules/edit-workspace-tour.mdc:0-0
Timestamp: 2025-06-23T12:31:58.286Z
Learning: The workspace tour feature in `internal-packages/workflow-designer-ui/src/editor/workspace-tour/` is implemented using React and relies on a `TourStep` interface that defines each step's target (CSS selector), title, content, and placement.

Applied to files:

  • apps/studio.giselles.ai/app/(main)/workspaces/create-workspace-button.tsx
  • apps/studio.giselles.ai/app/(main)/ui/sidebar/create-app-button.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/showcase-client.tsx
📚 Learning: 2025-11-25T03:06:27.023Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T03:06:27.023Z
Learning: Applies to internal-packages/ui/styles/aliases.css : Keep design token aliases minimal in `internal-packages/ui/styles/aliases.css` and submit as a separate small PR

Applied to files:

  • internal-packages/ui/components/glass-button.tsx
  • apps/studio.giselles.ai/packages/components/icons/ui.tsx
  • apps/studio.giselles.ai/packages/components/icons/willi-icon.tsx
  • internal-packages/ui/package.json
📚 Learning: 2025-11-25T03:05:21.219Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: .cursor/rules/development-guide.mdc:0-0
Timestamp: 2025-11-25T03:05:21.219Z
Learning: Applies to **/*.tsx : Use functional components with React hooks

Applied to files:

  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/document-store-create-dialog.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/[appId]/app-detail-client.tsx
  • internal-packages/ui/package.json
📚 Learning: 2025-11-25T03:06:27.023Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T03:06:27.023Z
Learning: Applies to **/{components,pages}/**/*.{tsx,ts} : Components should use React hooks and Next.js patterns

Applied to files:

  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/document-store-create-dialog.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/[appId]/app-detail-client.tsx
  • internal-packages/ui/package.json
  • apps/studio.giselles.ai/app/(main)/stage/showcase/showcase-client.tsx
📚 Learning: 2025-06-23T12:31:52.270Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: .cursor/rules/development-guide.mdc:0-0
Timestamp: 2025-06-23T12:31:52.270Z
Learning: Use functional components with React hooks for building React components.

Applied to files:

  • apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/document-store-create-dialog.tsx
  • apps/studio.giselles.ai/app/(main)/stage/showcase/[appId]/app-detail-client.tsx
📚 Learning: 2025-12-03T05:18:36.138Z
Learnt from: shige
Repo: giselles-ai/giselle PR: 2344
File: apps/studio.giselles.ai/app/stage/ui/navigation-rail/navigation-rail-expanded.tsx:14-20
Timestamp: 2025-12-03T05:18:36.138Z
Learning: In apps/studio.giselles.ai/app/stage/ui/navigation-rail/navigation-rail-expanded.tsx, "nav-action-history" is intentionally included in stageOnlyItemIds to hide it when the stage flag is disabled because the link destination is not yet implemented, even though it appears in the "Studio - Build Apps" section of navigation-items.ts.

Applied to files:

  • apps/studio.giselles.ai/app/(main)/stage/showcase/[appId]/app-detail-client.tsx
📚 Learning: 2025-11-25T03:05:21.219Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: .cursor/rules/development-guide.mdc:0-0
Timestamp: 2025-11-25T03:05:21.219Z
Learning: Applies to **/*.{ts,tsx} : Use Next.js patterns for web applications

Applied to files:

  • internal-packages/ui/package.json
📚 Learning: 2025-11-25T03:06:27.023Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T03:06:27.023Z
Learning: Applies to **/*.{tsx,ts} : Components should use PascalCase naming

Applied to files:

  • internal-packages/ui/package.json
🧬 Code graph analysis (4)
apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/plan-icon.tsx (1)
apps/studio.giselles.ai/packages/components/icons/member-icon.tsx (1)
  • MemberIcon (1-28)
apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/upgrade-interstitial.client.tsx (4)
internal-packages/workflow-designer-ui/src/editor/properties-panel/text-generation-node-properties-panel-v2/tools/ui/tabs.tsx (1)
  • Tabs (4-4)
apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/pricing-card.tsx (1)
  • PricingCard (4-100)
apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/plan-icon.tsx (1)
  • CircleIcon (8-29)
internal-packages/ui/components/glass-button.tsx (1)
  • GlassButton (15-129)
apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/pricing-card.tsx (1)
internal-packages/ui/components/glass-card.tsx (1)
  • GlassCard (7-26)
apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/page.tsx (1)
apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/upgrade-interstitial.client.tsx (1)
  • UpgradeInterstitial (9-219)
🪛 GitHub Actions: CI
apps/studio.giselles.ai/components/ui/gradient-button.tsx

[error] 48-49: File content differs from formatting output.

apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/page.tsx

[error] 5-7: File content differs from formatting output.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Cursor Bugbot
🔇 Additional comments (22)
apps/studio.giselles.ai/components/ui/gradient-button.tsx (2)

1-5: LGTM!

Imports are well-organized with external dependencies listed before local utilities, following standard conventions.


28-46: LGTM!

The component implementation follows React best practices with proper ref forwarding, Radix UI's asChild pattern for composition, and correct TypeScript typing. The structure is clean and extensible.

apps/studio.giselles.ai/packages/components/icons/member-icon.tsx (1)

1-28: LGTM!

The icon component follows established patterns with proper accessibility attributes and TypeScript typing.

apps/studio.giselles.ai/packages/components/icons/willi-icon.tsx (1)

1-39: LGTM!

Both icon components follow established patterns. The WilliDuoIcon composite approach creates a nice layered visual effect with appropriate positioning.

apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/layout.tsx (1)

1-15: LGTM!

Clean layout component with proper TypeScript typing and responsive design. The centered container with constrained max-width provides a consistent shell for upgrade content.

apps/studio.giselles.ai/app/(main)/ui/sidebar/create-app-button.tsx (1)

3-3: LGTM!

Import path correctly updated to use the shared internal UI package. No behavioral changes.

apps/studio.giselles.ai/app/(main)/stage/showcase/showcase-client.tsx (1)

15-15: LGTM!

Import path correctly updated to use the shared internal UI package. No behavioral changes.

apps/studio.giselles.ai/app/(main)/stage/showcase/[appId]/app-detail-client.tsx (1)

3-3: LGTM!

Import path correctly updated to use the shared internal UI package. No behavioral changes.

apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/repository-registration-dialog.tsx (1)

15-15: LGTM!

Import path correctly updated to use the shared internal UI package. No behavioral changes.

apps/studio.giselles.ai/app/(main)/workspaces/create-workspace-button.tsx (1)

3-3: LGTM!

Import path correctly updated to use the shared internal UI package. No behavioral changes.

apps/studio.giselles.ai/app/(main)/settings/team/vector-stores/document-store-create-dialog.tsx (1)

14-14: LGTM! Import path successfully migrated to internal UI package.

The GlassButton import has been correctly updated to use the internal UI library path, aligning with the PR's refactoring objective.

apps/studio.giselles.ai/app/(main)/settings/team/invite-member-dialog.tsx (1)

15-15: LGTM! Import path successfully migrated to internal UI package.

The GlassButton import has been correctly updated to use the internal UI library path, consistent with the refactoring objective.

internal-packages/ui/package.json (1)

28-29: LGTM! New exports correctly expose GlassButton and GlassCard.

The package exports follow the existing naming convention and enable the internal UI library migration across the codebase.

apps/studio.giselles.ai/app/(main)/settings/account/page.tsx (1)

1-1: LGTM! Import path successfully migrated to internal UI package.

Consistent with the refactoring effort to centralize UI components in the internal library.

apps/studio.giselles.ai/packages/components/icons/ui.tsx (1)

1-105: LGTM! Well-structured icon components.

Good practices observed:

  • Source attribution in header comment
  • Accessibility via <title> elements
  • Consistent structure across all icons
  • Uses currentColor for theming flexibility
apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/upgrade-interstitial.client.tsx (1)

70-80: Review accessibility pattern for disabled buttons.

The "Current plan" button uses pointer-events-none and tabIndex={-1} to disable interaction. While this achieves the visual effect, verify that this pattern meets your accessibility requirements, as it prevents keyboard navigation and may not announce the disabled state to all screen readers.

Consider whether:

  1. The button should remain focusable but disabled (disabled={true} without pointer-events-none)
  2. Alternative UI patterns (e.g., static text instead of a button) would be more semantically appropriate

This pattern is repeated for "Coming Soon" buttons throughout the file.

apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/pricing-card.tsx (2)

102-119: LGTM!

Good accessibility implementation with aria-hidden="true" and a descriptive <title> element. Using currentColor for the fill allows the icon color to be controlled by the parent's text color.


4-26: LGTM!

Clean component structure with well-typed props and sensible defaults. The conditional styling for isCurrentPlan is handled appropriately.

internal-packages/ui/components/glass-card.tsx (1)

1-26: LGTM!

Clean, minimal wrapper component with proper TypeScript types. The use of clsx/lite is appropriate, and the prop spreading pattern correctly allows consumers to override or extend behavior.

internal-packages/ui/components/glass-button.tsx (3)

25-28: LGTM!

The asChild pattern with Radix Slot is correctly implemented. Using aria-disabled when asChild is true and native disabled for the button element is the right approach for polymorphic component accessibility.


120-127: LGTM!

The hover overlay is correctly disabled for comingSoon, currentPlan variants, and when disableHoverFill or disabled is true. Good attention to interactive state handling.


2-2: The import statement is correct. The radix-ui package is a valid meta package from Radix UI that exports Slot, making import { Slot } from "radix-ui" a valid and documented approach. Both import { Slot } from "radix-ui" and import { Slot } from "@radix-ui/react-slot" are acceptable per Radix UI's official documentation. No changes are needed.

Comment on lines 5 to 6
}

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix formatting to pass CI.

The pipeline reports a formatting issue. Run pnpm biome check --write on this file to fix.

🔎 Expected fix

The file likely needs a blank line at the end:

 export default function TeamUpgradeInterstitialPage() {
 	return <UpgradeInterstitial />;
 }
-

Based on coding guidelines: "MUST run pnpm biome check --write [filename] after EVERY code modification."

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
}
export default function TeamUpgradeInterstitialPage() {
return <UpgradeInterstitial />;
}
🧰 Tools
🪛 GitHub Actions: CI

[error] 5-7: File content differs from formatting output.

🤖 Prompt for AI Agents
In apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/page.tsx around
lines 5-6, the file formatting is failing CI (likely missing a trailing
newline); run `pnpm biome check --write
apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/page.tsx` to
auto-fix formatting and ensure the file ends with a single blank line/EOF
newline, then save and commit the change so the pipeline passes.

Comment on lines +121 to +183
<section className="flex justify-center">
<PricingCard
icon={<CircleIcon variant="team" />}
title="Team"
subtitle="Perfect for teams collaborating on AI agents"
price={{ amount: "$100", cadence: "/month" }}
cta={
<div className="px-1 pt-3 pb-3">
<GlassButton
type="button"
variant="comingSoon"
disableHoverFill
aria-disabled="true"
tabIndex={-1}
className="w-full whitespace-nowrap pointer-events-none"
aria-label="Coming Soon"
>
Coming Soon
</GlassButton>
</div>
}
features={[
"All Pro features included",
"Team collaboration and sharing",
"Up to 10 users",
"Priority email support",
]}
/>
</section>
</div>
</div>
) : (
<div className="mt-10 flex justify-center">
<div className="inline-grid flex-col gap-y-[23px] sm:grid sm:grid-cols-2 sm:gap-4 lg:gap-6">
<section className="flex justify-center">
<PricingCard
icon={<CircleIcon variant="team" />}
title="Team"
subtitle="Perfect for teams collaborating on AI agents"
price={{ amount: "$100", cadence: "/month" }}
cta={
<div className="px-1 pt-3 pb-3">
<GlassButton
type="button"
variant="comingSoon"
disableHoverFill
aria-disabled="true"
tabIndex={-1}
className="w-full whitespace-nowrap pointer-events-none"
aria-label="Coming Soon"
>
Coming Soon
</GlassButton>
</div>
}
features={[
"All Pro features included",
"Team collaboration and sharing",
"Up to 10 users",
"Priority email support",
]}
/>
</section>
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Eliminate duplicate Team plan card definition.

The Team plan card is duplicated across both Personal (lines 121-149) and Business (lines 155-183) tabs with identical content. This violates DRY principles and creates maintenance burden.

🔎 Suggested refactor

Extract the Team card as a constant:

const TeamCard = (
	<PricingCard
		icon={<CircleIcon variant="team" />}
		title="Team"
		subtitle="Perfect for teams collaborating on AI agents"
		price={{ amount: "$100", cadence: "/month" }}
		cta={
			<div className="px-1 pt-3 pb-3">
				<GlassButton
					type="button"
					variant="comingSoon"
					disableHoverFill
					aria-disabled="true"
					tabIndex={-1}
					className="w-full whitespace-nowrap pointer-events-none"
					aria-label="Coming Soon"
				>
					Coming Soon
				</GlassButton>
			</div>
		}
		features={[
			"All Pro features included",
			"Team collaboration and sharing",
			"Up to 10 users",
			"Priority email support",
		]}
	/>
);

Then reference it in both tab contents.

🤖 Prompt for AI Agents
In
apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/upgrade-interstitial.client.tsx
around lines 121–183, the Team PricingCard JSX is duplicated in both tab panels;
extract the repeated JSX into a single reusable constant or component (e.g.,
TeamCard) defined once near the top of the file and replace both inline
occurrences with that reference so maintenance is centralized and duplication
removed.

Comment on lines 7 to 26
const gradientButtonVariants = cva(
"inline-flex w-full items-center justify-center rounded-full px-6 py-3 font-sans font-medium transition-all duration-300 shadow-lg hover:shadow-xl",
{
variants: {
variant: {
primary:
"bg-gradient-to-b from-[#1663F3] to-[#4A90E2] text-white hover:from-[#0F52BA] hover:to-[#367BFD]",
disabled:
"bg-gradient-to-b from-gray-600 to-gray-700 text-white cursor-not-allowed opacity-70",
},
size: {
default: "text-sm sm:text-base",
},
},
defaultVariants: {
variant: "primary",
size: "default",
},
},
);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

The disabled variant only styles the button but doesn't disable interaction.

The disabled variant applies visual styling (cursor-not-allowed, opacity-70) but doesn't prevent the button from being clicked. This creates a misleading UX where the button appears disabled but remains interactive, violating user expectations and accessibility best practices.

Consider either:

  1. Removing the disabled variant and relying on the HTML disabled attribute with appropriate styling, or
  2. Documenting that consumers must also pass the disabled prop when using variant="disabled"
🔎 Recommended approach using the disabled attribute
 const gradientButtonVariants = cva(
-	"inline-flex w-full items-center justify-center rounded-full px-6 py-3 font-sans font-medium transition-all duration-300 shadow-lg hover:shadow-xl",
+	"inline-flex w-full items-center justify-center rounded-full px-6 py-3 font-sans font-medium transition-all duration-300 shadow-lg hover:shadow-xl disabled:bg-gradient-to-b disabled:from-gray-600 disabled:to-gray-700 disabled:cursor-not-allowed disabled:opacity-70",
 	{
 		variants: {
 			variant: {
 				primary:
 					"bg-gradient-to-b from-[#1663F3] to-[#4A90E2] text-white hover:from-[#0F52BA] hover:to-[#367BFD]",
-				disabled:
-					"bg-gradient-to-b from-gray-600 to-gray-700 text-white cursor-not-allowed opacity-70",
 			},
 			size: {
 				default: "text-sm sm:text-base",
 			},
 		},
 		defaultVariants: {
 			variant: "primary",
 			size: "default",
 		},
 	},
 );

This approach styles the button based on the actual disabled HTML attribute, ensuring visual state matches functional state.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const gradientButtonVariants = cva(
"inline-flex w-full items-center justify-center rounded-full px-6 py-3 font-sans font-medium transition-all duration-300 shadow-lg hover:shadow-xl",
{
variants: {
variant: {
primary:
"bg-gradient-to-b from-[#1663F3] to-[#4A90E2] text-white hover:from-[#0F52BA] hover:to-[#367BFD]",
disabled:
"bg-gradient-to-b from-gray-600 to-gray-700 text-white cursor-not-allowed opacity-70",
},
size: {
default: "text-sm sm:text-base",
},
},
defaultVariants: {
variant: "primary",
size: "default",
},
},
);
const gradientButtonVariants = cva(
"inline-flex w-full items-center justify-center rounded-full px-6 py-3 font-sans font-medium transition-all duration-300 shadow-lg hover:shadow-xl disabled:bg-gradient-to-b disabled:from-gray-600 disabled:to-gray-700 disabled:cursor-not-allowed disabled:opacity-70",
{
variants: {
variant: {
primary:
"bg-gradient-to-b from-[#1663F3] to-[#4A90E2] text-white hover:from-[#0F52BA] hover:to-[#367BFD]",
},
size: {
default: "text-sm sm:text-base",
},
},
defaultVariants: {
variant: "primary",
size: "default",
},
},
);
🤖 Prompt for AI Agents
In apps/studio.giselles.ai/components/ui/gradient-button.tsx around lines 7 to
26, the "disabled" cva variant only changes visuals but does not set the HTML
disabled attribute, causing a mismatched interactive state; update the component
so the functional disabled state drives the visual styling: remove or stop
relying on a separate "variant: 'disabled'" and instead accept a disabled prop,
apply the disabled attribute to the underlying button element (and aria-disabled
for non-button elements), and conditionally include the disabled classes when
disabled === true; update the component's props typing and any callsites or docs
to ensure consumers pass disabled rather than just variant="disabled".

Comment on lines 48 to 49
export { GradientButton };

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical: Run Biome formatter to fix pipeline failure.

The pipeline is failing because the file has not been formatted with Biome. According to the coding guidelines, you MUST run Biome formatting after every code modification.

Please run the following command to format this file:

pnpm biome check --write apps/studio.giselles.ai/components/ui/gradient-button.tsx

As per coding guidelines, all TypeScript/TSX files must be formatted with Biome before commit.

🧰 Tools
🪛 GitHub Actions: CI

[error] 48-49: File content differs from formatting output.

🤖 Prompt for AI Agents
In apps/studio.giselles.ai/components/ui/gradient-button.tsx around lines 48 to
49, the file is not formatted with Biome causing the pipeline to fail; fix it by
running the Biome formatter on this file (pnpm biome check --write
apps/studio.giselles.ai/components/ui/gradient-button.tsx) and then re-commit
the formatted file so it conforms to the project coding guidelines.

variant === "enterprise" ? (
<FreeIcon />
) : variant === "team" ? (
<MemberIcon />
Copy link

Choose a reason for hiding this comment

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

Team plan icon size inconsistent with other icons

The MemberIcon used for the Team plan variant has dimensions of 22x22 (set in its SVG width and height attributes), while all other plan icons (FreeIcon, ProIcon, and Orbit) are 24x24. In CircleIcon, the Orbit icon explicitly receives className="h-6 w-6" to ensure 24x24 sizing, but MemberIcon is rendered without any size class override, causing the Team plan icon to appear visually smaller than the other plan icons in the pricing cards.

Additional Locations (1)

Fix in Cursor Fix in Web

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +15 to +19
export function GlassButton({
className,
variant = "default",
size = "default",
asChild = false,

Choose a reason for hiding this comment

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

P1 Badge Reinstate ref forwarding on GlassButton

GlassButton was rewritten as a plain function (no forwardRef), so it no longer forwards refs to the underlying <button>. Radix primitives composed with asChild (e.g. the DialogTrigger wrapping GlassButton in apps/studio.giselles.ai/app/(main)/settings/team/invite-member-dialog.tsx) pass a ref for focus management; React now warns that function components cannot receive refs and focus will not be restored to the trigger on dialog close. Wrap GlassButton in forwardRef again so the ref propagates.

Useful? React with 👍 / 👎.

@giselles-ai
Copy link

giselles-ai bot commented Dec 22, 2025

🔍 QA Testing Assistant by Giselle

📋 Manual QA Checklist

Based on the changes in this PR, here are the key areas to test manually:

  • 1. Page Access: Navigate to /settings/team/upgrade and verify the new "Plans that scale with you" page loads correctly.
  • 2. Standalone Layout: Confirm that the page is displayed in a standalone layout (i.e., the main app sidebar and header are not visible).
  • 3. Back Navigation: Locate the back arrow button in the top-left corner. Click it and verify you are redirected back to the /settings/team page.
  • 4. Tab Functionality:
    • Verify there are two tabs: "Personal" and "Business".
    • Confirm the "Personal" tab is active by default.
    • Click the "Business" tab and verify the content switches to show the "Team" and "Enterprise" plans.
    • Click back on the "Personal" tab and verify the content switches back to "Free", "Pro", and "Team" plans.
    • Verify the active tab has a distinct visual style (white background, black text).
  • 5. "Free" Plan Card (Current Plan):
    • Verify the card has a blue glow effect at the top.
    • Verify the icon is the Orbit icon.
    • Verify the title is "Free" and the price is "Free".
    • Verify the button text is "Current plan".
    • Confirm the "Current plan" button is visually distinct (muted style) and not interactive (no hover effect, not clickable).
  • 6. "Pro" Plan Card:
    • Verify the icon is the Pro icon.
    • Verify the title is "Pro" and the price is "$20 /month".
    • Verify the button text is "Get Started".
    • Confirm the "Get Started" button is interactive (shows hover and active/click effects).
  • 7. "Team" Plan Card:
    • Verify the icon is the custom MemberIcon (a group of people).
    • Verify the title is "Team" and the price is "$100 /month".
    • Verify the button text is "Coming Soon".
    • Confirm the "Coming Soon" button has a disabled style and is not interactive.
  • 8. "Enterprise" Plan Card:
    • Verify the icon is the Free icon glyph (a cloud).
    • Verify the title is "Enterprise" and the price is "Contact".
    • Verify the button text is "Coming Soon".
    • Confirm the "Coming Soon" button has a disabled style and is not interactive.
  • 9. Card Style: Confirm all plan cards have the intended "glass" visual style.
  • 10. Feature List: Check that each feature listed on every card is prefixed with a blue CircleCheckIcon.
  • 11. Responsive Design:
    • On a wide desktop screen, verify the "Personal" plans are in a 3-column layout.
    • On a tablet-sized screen, verify the plans are in a 2-column layout.
    • On a mobile screen, verify the plans stack vertically in a single column.
    • Ensure all text and UI elements are legible and well-aligned across all screen sizes.
  • 12. Account Settings Button: Go to /settings/account. Confirm the "Add Team" button (with a + icon) is displayed correctly and is interactive.
  • 13. Invite Member Dialog Buttons: Go to /settings/team and click "Invite Member". Confirm the buttons inside the dialog render correctly.
  • 14. Vector Stores Buttons: Go to /settings/team/vector-stores. Verify the "Create Document Store" and "Register Repository" buttons render and function as before.
  • 15. Showcase Page Button: Go to /stage/showcase. Check the "Run" GlassButton on any app card.
  • 16. App Detail Page Button: Navigate to an app's detail page (e.g., /stage/showcase/[appId]). Check the "Run" GlassButton.
  • 17. Sidebar Button: Check the "New App" button in the main sidebar.
  • 18. Workspaces Page Button: Go to /workspaces and verify the "New Workspace" button renders correctly.

✨ Prompt for AI Agents

Use the following prompts with Cursor or Claude Code to automate E2E testing:

📝 E2E Test Generation Prompt
You are an expert QA engineer specializing in automated E2E testing with Playwright. Your task is to generate comprehensive E2E tests for a new feature based on the provided context.

**Goal:** Create a new Playwright test suite for the "Team Upgrade Interstitial Page" and a regression smoke test suite for a refactored component. The tests must be robust, maintainable, and ready for CI integration.

---

### **1. Context Summary**

*   **PR Feature:** This PR introduces a new **UI-only** page at `/settings/team/upgrade`. This page displays pricing plans for team upgrades.
*   **Key Characteristics:**
    *   The page has a **standalone layout** (no main app sidebar or header).
    *   It features two tabs: "Personal" and "Business".
    *   "Personal" tab (default) shows Free, Pro, and Team plans.
    *   "Business" tab shows Team and Enterprise plans.
    *   Plan cards have different Call-to-Action (CTA) buttons based on their status:
        *   **Current Plan:** Disabled button with "Current plan" text and a blue visual glow.
        *   **Available Plan:** Enabled button ("Get Started").
        *   **Unavailable Plan:** Disabled button with "Coming Soon" text.
*   **Refactoring Impact (Regression Risk):**
    *   The `GlassButton` component was moved from the Studio app's local components to a shared internal UI library (`@giselle-internal/ui`).
    *   Multiple existing pages were updated to use the new import path. We need to ensure these buttons still render and function correctly.

---

### **2. Test Scenarios to Implement**

#### **Suite 1: New Feature - Team Upgrade Page**

**File:** `tests/e2e/settings-team-upgrade.spec.ts`

*   **Scenario 2.1: Page Rendering and Default State (Personal Plans)**
    *   **GIVEN** a logged-in user.
    *   **WHEN** they navigate to `/settings/team/upgrade`.
    *   **THEN** the page URL should be correct.
    *   **AND** the main heading "Plans that scale with you" should be visible.
    *   **AND** the page should have a standalone layout (e.g., the main "Workspaces" sidebar link should **not** be visible).
    *   **AND** the "Personal" tab should be active by default.
    *   **AND** three plan cards should be visible: "Free", "Pro", "Team".

*   **Scenario 2.2: "Free" Plan Card Verification**
    *   **GIVEN** the user is on the upgrade page.
    *   **WHEN** viewing the "Free" plan card.
    *   **THEN** it should contain the title "Free".
    *   **AND** the CTA button should have the text "Current plan".
    *   **AND** the "Current plan" button should be disabled (`aria-disabled="true"`).
    *   **AND** it should have the special styling for the current plan (a blue top glow).

*   **Scenario 2.3: "Pro" Plan Card Verification**
    *   **GIVEN** the user is on the upgrade page.
    *   **WHEN** viewing the "Pro" plan card.
    *   **THEN** it should contain the title "Pro" and price "$20 /month".
    *   **AND** the CTA button should have the text "Get Started".
    *   **AND** the "Get Started" button should be **enabled**.

*   **Scenario 2.4: "Team" Plan Card Verification (Personal Tab)**
    *   **GIVEN** the user is on the upgrade page.
    *   **WHEN** viewing the "Team" plan card.
    *   **THEN** it should contain the title "Team" and price "$100 /month".
    *   **AND** the CTA button should have the text "Coming Soon".
    *   **AND** the "Coming Soon" button should be disabled.

*   **Scenario 2.5: Switching to Business Tab**
    *   **GIVEN** the user is on the upgrade page.
    *   **WHEN** they click the "Business" tab.
    *   **THEN** the "Business" tab should become active.
    *   **AND** two plan cards should be visible: "Team" and "Enterprise".
    *   **AND** the "Team" card's CTA should be "Coming Soon" and disabled.
    *   **AND** the "Enterprise" card's CTA should be "Coming Soon" and disabled.

*   **Scenario 2.6: Navigation**
    *   **GIVEN** the user is on the upgrade page.
    *   **WHEN** they click the "Back to Team Settings" link.
    *   **THEN** the page should navigate to `/settings/team`.

#### **Suite 2: Regression - GlassButton Component**

**File:** `tests/e2e/regression-glass-button.spec.ts`

*   **Scenario 2.7: Invite Member Button**
    *   **GIVEN** a logged-in user.
    *   **WHEN** they navigate to the Team Settings page (`/settings/team`).
    *   **THEN** the "Invite Member" button should be visible and enabled.
    *   **AND** clicking it should open the "Invite new members" dialog.

*   **Scenario 2.8: Create App Button**
    *   **GIVEN** a logged-in user.
    *   **WHEN** they are on a page with the main sidebar (e.g., the dashboard at `/`).
    *   **THEN** the "Create App" button in the sidebar should be visible and enabled.

---

### **3. Playwright Implementation Instructions**

*   **General:**
    *   Assume a `login()` helper function is available to handle authentication in a `beforeEach` hook.
    *   Organize tests within `test.describe()` blocks.
    *   Use locator variables to avoid repeating selectors.

*   **Selectors to use:**
    ```typescript
    // For settings-team-upgrade.spec.ts
    const pageTitle = page.getByRole('heading', { name: 'Plans that scale with you' });
    const backLink = page.getByRole('link', { name: 'Back to Team Settings' });
    const personalTab = page.getByRole('button', { name: 'Personal' });
    const businessTab = page.getByRole('button', { name: 'Business' });
    
    // Use .filter() to scope assertions to a specific card
    const freePlanCard = page.locator('section').filter({ hasText: 'Free' });
    const proPlanCard = page.locator('section').filter({ hasText: 'Pro' });
    const teamPlanCard = page.locator('section').filter({ hasText: 'Team' });
    const enterprisePlanCard = page.locator('section').filter({ hasText: 'Enterprise' });

    // For regression-glass-button.spec.ts
    const inviteMemberButton = page.getByRole('button', { name: 'Invite Member' });
    const inviteDialogTitle = page.getByRole('heading', { name: 'Invite new members' });
    const createAppButton = page.getByRole('button', { name: 'Create App' });
    ```

*   **Key Assertions:**
    *   **Navigation:** `await expect(page).toHaveURL(...)`
    *   **Visibility:** `await expect(locator).toBeVisible()`
    *   **Absence:** `await expect(locator).not.toBeVisible()` (for checking standalone layout).
    *   **Button State:**
        *   `await expect(buttonLocator).toBeEnabled()`
        *   `await expect(buttonLocator).toBeDisabled()` (preferred) or `await expect(buttonLocator).toHaveAttribute('aria-disabled', 'true')`
    *   **Active Tab:** An active tab adds the class `bg-white/90`. Verify this.
        `await expect(personalTab).toHaveClass(/bg-white\/90/);`
    *   **Current Plan Style:** The "Current plan" card has a unique glow effect. You can assert its presence by checking for the specific `div` that creates the effect.
        ```typescript
        const glowEffect = freePlanCard.locator('div.blur-2xl');
        await expect(glowEffect).toBeVisible();
        ```

*   **Example Test Structure:**

    ```typescript
    import { test, expect } from '@playwright/test';
    
    test.describe('Team Upgrade Interstitial Page', () => {
      test.beforeEach(async ({ page }) => {
        // Assume login() is a pre-existing helper
        await login(page); 
        await page.goto('/settings/team/upgrade');
      });
    
      test('should render the page with personal plans by default', async ({ page }) => {
        await expect(page).toHaveURL('/settings/team/upgrade');
        await expect(page.getByRole('heading', { name: 'Plans that scale with you' })).toBeVisible();
        
        // Assert standalone layout by checking for the absence of a main layout element
        await expect(page.getByRole('link', { name: 'Workspaces' })).not.toBeVisible();

        // Assert Personal tab is active
        const personalTab = page.getByRole('button', { name: 'Personal' });
        await expect(personalTab).toHaveClass(/bg-white\/90/);
      });

      // ... other tests for this suite
    });
    ```

---

### **4. MCP Integration Guidelines**

*   The tests should be executable via the Playwright MCP script.
*   To run only the new feature tests, use a filter:
    `pnpm mcp playwright:test --filter=settings-team-upgrade.spec.ts`
*   To run only the regression tests:
    `pnpm mcp playwright:test --filter=regression-glass-button.spec.ts`
*   No special environment configuration is needed beyond the standard authenticated state.

---

### **5. CI-Ready Code Requirements**

*   **File Naming:** Use `feature-name.spec.ts` or `regression-component-name.spec.ts`.
*   **Test Isolation:** Each `test()` block must be atomic and self-contained. Use `beforeEach` for setup to ensure tests can run independently and in parallel.
*   **Descriptive Naming:** Use `test.describe('Feature Name', ...)` and `test('should do XYZ when ABC', ...)` for clear, readable test reports in CI.
*   **Locators:** Define locators at the top of the `describe` block or in a separate helper/POM file if the project structure supports it, to improve maintainability.
*   **Clarity:** Write code that is easy to understand. Add comments only for complex logic or assertions that aren't self-evident.


Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (5)
apps/studio.giselles.ai/app/(main)/settings/team/page.tsx (2)

172-172: Replace void team; with idiomatic TypeScript pattern.

Using the void operator to suppress unused variable warnings is non-idiomatic. Consider these alternatives:

  1. Remove the parameter if it's truly unused:

    function UpgradeButton() {
  2. Prefix with underscore to indicate intentionally unused:

    function UpgradeButton({ team: _team }: { team: CurrentTeam }) {
  3. Add a comment explaining why it's kept (e.g., for interface consistency or future use)

🔎 Proposed fix using underscore prefix
-function UpgradeButton({ team }: { team: CurrentTeam }) {
-	void team;
+function UpgradeButton({ team: _team }: { team: CurrentTeam }) {

102-106: Consider removing unnecessary form wrapper.

The UpgradeButton now uses Link-based navigation instead of form submission, making the <form> wrapper (lines 102-106) unnecessary. The form pattern is correctly used in UpdateButton (lines 181-196) where formAction is needed, but here it's redundant.

🔎 Proposed cleanup
-		<form>
-			<Suspense fallback={<Skeleton className="h-10 w-[120px] rounded-md" />}>
-				<UpgradeButton team={team} />
-			</Suspense>
-		</form>
+		<Suspense fallback={<Skeleton className="h-10 w-[120px] rounded-md" />}>
+			<UpgradeButton team={team} />
+		</Suspense>

Note: The asChild + Link pattern in lines 175-177 is correctly implemented and aligns with the PR objective to navigate to the new upgrade interstitial page.

Also applies to: 175-177

apps/studio.giselles.ai/app/(main)/playground/file-attachments.tsx (3)

133-136: Simplify state initialization.

The lazy initializer () => new Set() is unnecessary here since new Set() is already cheap to construct. You can initialize directly.

🔎 Proposed simplification
-	const [failedImageIds, setFailedImageIds] = useState<Set<string>>(
-		() => new Set(),
-	);
+	const [failedImageIds, setFailedImageIds] = useState<Set<string>>(new Set());

168-181: Consider simplifying boolean comparisons.

The explicit comparisons shouldUseLocalPreview === true (line 178) could be more concise. While functionally correct, idiomatic TypeScript omits explicit boolean comparisons.

🔎 Suggested refinements
 			const shouldUseLocalPreview =
 				serverImageUrl !== null &&
 				localPreview !== undefined &&
 				failedImageIds.has(file.id);
 			const imageUrl =
-				shouldUseLocalPreview === true
+				shouldUseLocalPreview
 					? localPreview
 					: (serverImageUrl ?? localPreview ?? null);

188-220: Verify unoptimized is intentional for user-uploaded images.

The error/load handler logic is correct: server images fall back to local previews on failure, and the parent is notified only when server images load successfully. The immutable state update pattern is appropriate.

However, the unoptimized prop bypasses Next.js image optimization. While this is common for user-uploaded content (especially blob: URLs and external sources), confirm this is intentional.

Optional: simplify boolean comparisons

Lines 200 and 215 use explicit === false checks. Consider:

 										if (
 											serverImageUrl !== null &&
 											localPreview !== undefined &&
-											failedImageIds.has(file.id) === false
+											!failedImageIds.has(file.id)
 										) {
 										if (
 											serverImageUrl !== null &&
 											onImageLoad &&
-											shouldUseLocalPreview === false
+											!shouldUseLocalPreview
 										) {
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b486945 and 64cd237.

📒 Files selected for processing (5)
  • apps/studio.giselles.ai/app/(main)/playground/file-attachments.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/page.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/page.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/upgrade-interstitial.client.tsx
  • apps/studio.giselles.ai/components/ui/gradient-button.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
  • apps/studio.giselles.ai/components/ui/gradient-button.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/page.tsx
  • apps/studio.giselles.ai/app/(upgrade)/settings/team/upgrade/upgrade-interstitial.client.tsx
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,js,jsx}: Favor clear, descriptive names and type annotations over clever tricks
If you need a multi-paragraph comment, refactor until intent is obvious

**/*.{ts,tsx,js,jsx}: Use async/await and proper error handling
Variables and functions should use camelCase naming
Booleans and functions should use is, has, can, should prefixes
Function names should clearly indicate purpose

Files:

  • apps/studio.giselles.ai/app/(main)/playground/file-attachments.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/page.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development-guide.mdc)

**/*.{ts,tsx}: MUST run pnpm biome check --write [filename] after EVERY code modification
All code changes must be formatted using Biome before being committed
Use Biome for formatting with tab indentation and double quotes
Follow organized imports pattern (enabled in biome.json)
Use TypeScript for type safety; avoid any types
Use Next.js patterns for web applications
Use async/await for asynchronous code rather than promises
Error handling: use try/catch blocks and propagate errors appropriately
Use kebab-case for all filenames
Use PascalCase for React components and classes
Use camelCase for variables, functions, and methods
Use prefixes like is, has, can, should for boolean variables (e.g., isEnabled, hasPermission)
Use prefixes like is, has, can, should for boolean functions (e.g., isTriggerRequiringCallsign(), hasActiveSubscription()) instead of imperative verbs
Use verbs or verb phrases for function naming that clearly indicate purpose (e.g., calculateTotalPrice(), not process())

Use PascalCase for React component and class names

Use TypeScript and avoid any

Files:

  • apps/studio.giselles.ai/app/(main)/playground/file-attachments.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/page.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/development-guide.mdc)

Use functional components with React hooks

Files:

  • apps/studio.giselles.ai/app/(main)/playground/file-attachments.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/page.tsx
**/*.{js,ts,tsx,jsx,py,java,cs,cpp,c,go,rb,php,swift,kt,scala,rs,dart}

📄 CodeRabbit inference engine (.cursor/rules/language-support.mdc)

Write all code comments in English

Files:

  • apps/studio.giselles.ai/app/(main)/playground/file-attachments.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/page.tsx
**/*

📄 CodeRabbit inference engine (.cursor/rules/naming-guide.mdc)

Use kebab-case for file names (e.g., user-profile.ts, api-client.tsx)

Files:

  • apps/studio.giselles.ai/app/(main)/playground/file-attachments.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/page.tsx
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/naming-guide.mdc)

**/*.{js,ts,jsx,tsx}: Use camelCase for variable names, functions, and methods
Use verbs or verb phrases for function names to clearly indicate what the function does (e.g., calculateTotalPrice(), validateUserInput())
Use nouns or noun phrases for variable names to describe what the variable represents
Use boolean prefixes (is, has, can, should) for boolean variables and functions returning boolean values (e.g., isEnabled, hasPermission, isTriggerRequiringCallsign())

**/*.{js,ts,jsx,tsx}: Run pnpm biome check --write [filename] after every code change
All code must be formatted with Biome before commit

Files:

  • apps/studio.giselles.ai/app/(main)/playground/file-attachments.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/page.tsx
**/*.{ts,tsx,js,jsx,css}

📄 CodeRabbit inference engine (AGENTS.md)

Files should use kebab-case naming

Files:

  • apps/studio.giselles.ai/app/(main)/playground/file-attachments.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/page.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Components should use PascalCase naming

Files:

  • apps/studio.giselles.ai/app/(main)/playground/file-attachments.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/page.tsx
🧠 Learnings (12)
📚 Learning: 2025-11-25T03:05:31.051Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: .cursor/rules/edit-workspace-tour.mdc:0-0
Timestamp: 2025-11-25T03:05:31.051Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/workspace-tour/workspace-tour.tsx : Import new images at the top of `workspace-tour.tsx` and update the `imageSrc` prop in the appropriate step component to use the new image

Applied to files:

  • apps/studio.giselles.ai/app/(main)/playground/file-attachments.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/page.tsx
📚 Learning: 2025-11-25T03:05:31.051Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: .cursor/rules/edit-workspace-tour.mdc:0-0
Timestamp: 2025-11-25T03:05:31.051Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/workspace-tour/assets/** : Replace GIFs and images in the `assets/` directory and update imports and references in `workspace-tour.tsx`

Applied to files:

  • apps/studio.giselles.ai/app/(main)/playground/file-attachments.tsx
  • apps/studio.giselles.ai/app/(main)/settings/team/page.tsx
📚 Learning: 2025-11-25T03:05:21.219Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: .cursor/rules/development-guide.mdc:0-0
Timestamp: 2025-11-25T03:05:21.219Z
Learning: Applies to **/*.tsx : Use functional components with React hooks

Applied to files:

  • apps/studio.giselles.ai/app/(main)/playground/file-attachments.tsx
📚 Learning: 2025-11-25T03:05:31.051Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: .cursor/rules/edit-workspace-tour.mdc:0-0
Timestamp: 2025-11-25T03:05:31.051Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/workspace-tour/workspace-tour.tsx : Update the `TourGlobalStyles` component in `workspace-tour.tsx` for animation changes

Applied to files:

  • apps/studio.giselles.ai/app/(main)/settings/team/page.tsx
📚 Learning: 2025-11-25T03:07:07.498Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: internal-packages/workflow-designer-ui/src/editor/properties-panel/trigger-node-properties-panel/providers/github-trigger/AGENTS.md:0-0
Timestamp: 2025-11-25T03:07:07.498Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/properties-panel/trigger-node-properties-panel/providers/github-trigger/components/{callsign,labels}*.tsx : Hide the 'Back' button in `input-callsign` and `input-labels` steps during reconfiguration mode to simplify UX.

Applied to files:

  • apps/studio.giselles.ai/app/(main)/settings/team/page.tsx
📚 Learning: 2025-11-25T03:07:19.740Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: internal-packages/workflow-designer-ui/src/new-editor/AGENTS.md:0-0
Timestamp: 2025-11-25T03:07:19.740Z
Learning: Applies to internal-packages/workflow-designer-ui/src/new-editor/**/*.{ts,tsx} : Lift actions into the store (e.g., `updateNode`) and call them from components needing mutations instead of passing mutation callbacks as props

Applied to files:

  • apps/studio.giselles.ai/app/(main)/settings/team/page.tsx
📚 Learning: 2025-11-25T03:07:07.498Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: internal-packages/workflow-designer-ui/src/editor/properties-panel/trigger-node-properties-panel/providers/github-trigger/AGENTS.md:0-0
Timestamp: 2025-11-25T03:07:07.498Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/properties-panel/trigger-node-properties-panel/providers/github-trigger/**/*.tsx : Wrap all state updates in `startTransition` for consistent UI behavior during configuration and reconfiguration flows.

Applied to files:

  • apps/studio.giselles.ai/app/(main)/settings/team/page.tsx
📚 Learning: 2025-12-03T05:18:36.138Z
Learnt from: shige
Repo: giselles-ai/giselle PR: 2344
File: apps/studio.giselles.ai/app/stage/ui/navigation-rail/navigation-rail-expanded.tsx:14-20
Timestamp: 2025-12-03T05:18:36.138Z
Learning: In apps/studio.giselles.ai/app/stage/ui/navigation-rail/navigation-rail-expanded.tsx, "nav-action-history" is intentionally included in stageOnlyItemIds to hide it when the stage flag is disabled because the link destination is not yet implemented, even though it appears in the "Studio - Build Apps" section of navigation-items.ts.

Applied to files:

  • apps/studio.giselles.ai/app/(main)/settings/team/page.tsx
📚 Learning: 2025-11-25T03:07:07.498Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: internal-packages/workflow-designer-ui/src/editor/properties-panel/trigger-node-properties-panel/providers/github-trigger/AGENTS.md:0-0
Timestamp: 2025-11-25T03:07:07.498Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/properties-panel/trigger-node-properties-panel/providers/github-trigger/**/*.tsx : Manage setup wizard state progression through steps: `select-event` → `select-repository` → `confirm-repository` → optionally `input-callsign` → optionally `input-labels` → `configured`.

Applied to files:

  • apps/studio.giselles.ai/app/(main)/settings/team/page.tsx
📚 Learning: 2025-11-25T03:07:19.740Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: internal-packages/workflow-designer-ui/src/new-editor/AGENTS.md:0-0
Timestamp: 2025-11-25T03:07:19.740Z
Learning: Applies to internal-packages/workflow-designer-ui/src/new-editor/**/*.{ts,tsx} : Replace context-wide reads from `src/editor/v2` with fine-grained selectors against the Zustand store

Applied to files:

  • apps/studio.giselles.ai/app/(main)/settings/team/page.tsx
📚 Learning: 2025-11-25T03:05:31.051Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: .cursor/rules/edit-workspace-tour.mdc:0-0
Timestamp: 2025-11-25T03:05:31.051Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/workspace-tour/{steps.ts,workspace-tour.tsx} : Add new tour steps to the `tourSteps` array in `steps.ts`, create corresponding components in `workspace-tour.tsx` following the pattern of existing steps, and add the new step to the switch statement in the main `WorkspaceTour` component

Applied to files:

  • apps/studio.giselles.ai/app/(main)/settings/team/page.tsx
📚 Learning: 2025-11-25T03:06:27.023Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T03:06:27.023Z
Learning: Applies to **/{components,pages}/**/*.{tsx,ts} : Components should use React hooks and Next.js patterns

Applied to files:

  • apps/studio.giselles.ai/app/(main)/settings/team/page.tsx
🧬 Code graph analysis (1)
apps/studio.giselles.ai/app/(main)/settings/team/page.tsx (1)
internal-packages/ui/components/button.tsx (1)
  • Button (23-105)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: codeql / languages (javascript) / Perform CodeQL for javascript
  • GitHub Check: Cursor Bugbot
🔇 Additional comments (1)
apps/studio.giselles.ai/app/(main)/playground/file-attachments.tsx (1)

13-14: LGTM — Imports align with the new image handling.

The addition of Next.js Image and React useState properly supports the enhanced fallback logic for uploaded images.

isCurrentPlan ? "ring-1 ring-[#1663F3]/25" : "",
]
.filter(Boolean)
.join(" ");
Copy link

Choose a reason for hiding this comment

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

PricingCard's before pseudo-element styles effectively invisible

The PricingCard component defines ::before pseudo-element styling including before:border before:border-white/15 before:bg-gradient-to-br before:from-white/10 in cardClassName. However, GlassCard sets before:opacity-[0.02] on its ::before element, and PricingCard doesn't override this opacity. Since CSS opacity affects the entire element, the border and gradient effects in PricingCard render at 2% opacity—essentially invisible. Adding before:opacity-100 to cardClassName would make these decorative effects visible as likely intended.

Additional Locations (1)

Fix in Cursor Fix in Web

aria-label="Get Started"
>
Get Started
</GlassButton>
Copy link

Choose a reason for hiding this comment

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

Pro plan button is clickable but has no action

The "Get Started" GlassButton for the Pro plan has no onClick handler or form action, making it a clickable button that does nothing when pressed. Unlike the "Coming Soon" buttons which are properly disabled with aria-disabled, tabIndex={-1}, and pointer-events-none, this button appears interactive and accepts clicks but provides no feedback or functionality. Users clicking this button would expect an upgrade flow to begin but nothing happens, creating a confusing experience.

Fix in Cursor Fix in Web

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
apps/studio.giselles.ai/packages/components/icons/ui.tsx (1)

3-57: LGTM! Clean icon components with good accessibility.

Both Free and Pro components are well-implemented:

  • Proper functional component structure with PascalCase naming
  • Accessible via <title> elements
  • Use currentColor for flexible theming
  • Consistent structure and viewBox dimensions
Optional: Add explicit TypeScript return types

For stricter type safety, consider adding return type annotations:

-export function Free() {
+export function Free(): React.ReactElement {
 	return (

...

-export function Pro() {
+export function Pro(): React.ReactElement {
 	return (

This makes the component contract more explicit, though TypeScript can infer these types correctly.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2324e6e and 8eeea9e.

📒 Files selected for processing (1)
  • apps/studio.giselles.ai/packages/components/icons/ui.tsx
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,js,jsx}: Favor clear, descriptive names and type annotations over clever tricks
If you need a multi-paragraph comment, refactor until intent is obvious

**/*.{ts,tsx,js,jsx}: Use async/await and proper error handling
Variables and functions should use camelCase naming
Booleans and functions should use is, has, can, should prefixes
Function names should clearly indicate purpose

Files:

  • apps/studio.giselles.ai/packages/components/icons/ui.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development-guide.mdc)

**/*.{ts,tsx}: MUST run pnpm biome check --write [filename] after EVERY code modification
All code changes must be formatted using Biome before being committed
Use Biome for formatting with tab indentation and double quotes
Follow organized imports pattern (enabled in biome.json)
Use TypeScript for type safety; avoid any types
Use Next.js patterns for web applications
Use async/await for asynchronous code rather than promises
Error handling: use try/catch blocks and propagate errors appropriately
Use kebab-case for all filenames
Use PascalCase for React components and classes
Use camelCase for variables, functions, and methods
Use prefixes like is, has, can, should for boolean variables (e.g., isEnabled, hasPermission)
Use prefixes like is, has, can, should for boolean functions (e.g., isTriggerRequiringCallsign(), hasActiveSubscription()) instead of imperative verbs
Use verbs or verb phrases for function naming that clearly indicate purpose (e.g., calculateTotalPrice(), not process())

Use PascalCase for React component and class names

Use TypeScript and avoid any

Files:

  • apps/studio.giselles.ai/packages/components/icons/ui.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/development-guide.mdc)

Use functional components with React hooks

Files:

  • apps/studio.giselles.ai/packages/components/icons/ui.tsx
**/*.{js,ts,tsx,jsx,py,java,cs,cpp,c,go,rb,php,swift,kt,scala,rs,dart}

📄 CodeRabbit inference engine (.cursor/rules/language-support.mdc)

Write all code comments in English

Files:

  • apps/studio.giselles.ai/packages/components/icons/ui.tsx
**/*

📄 CodeRabbit inference engine (.cursor/rules/naming-guide.mdc)

Use kebab-case for file names (e.g., user-profile.ts, api-client.tsx)

Files:

  • apps/studio.giselles.ai/packages/components/icons/ui.tsx
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/naming-guide.mdc)

**/*.{js,ts,jsx,tsx}: Use camelCase for variable names, functions, and methods
Use verbs or verb phrases for function names to clearly indicate what the function does (e.g., calculateTotalPrice(), validateUserInput())
Use nouns or noun phrases for variable names to describe what the variable represents
Use boolean prefixes (is, has, can, should) for boolean variables and functions returning boolean values (e.g., isEnabled, hasPermission, isTriggerRequiringCallsign())

**/*.{js,ts,jsx,tsx}: Run pnpm biome check --write [filename] after every code change
All code must be formatted with Biome before commit

Files:

  • apps/studio.giselles.ai/packages/components/icons/ui.tsx
**/{components,pages}/**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Components should use React hooks and Next.js patterns

Files:

  • apps/studio.giselles.ai/packages/components/icons/ui.tsx
**/*.{ts,tsx,js,jsx,css}

📄 CodeRabbit inference engine (AGENTS.md)

Files should use kebab-case naming

Files:

  • apps/studio.giselles.ai/packages/components/icons/ui.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Components should use PascalCase naming

Files:

  • apps/studio.giselles.ai/packages/components/icons/ui.tsx
🧠 Learnings (4)
📚 Learning: 2025-11-25T03:05:31.051Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: .cursor/rules/edit-workspace-tour.mdc:0-0
Timestamp: 2025-11-25T03:05:31.051Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/workspace-tour/workspace-tour.tsx : Update the `TourGlobalStyles` component in `workspace-tour.tsx` for animation changes

Applied to files:

  • apps/studio.giselles.ai/packages/components/icons/ui.tsx
📚 Learning: 2025-11-25T03:05:31.051Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: .cursor/rules/edit-workspace-tour.mdc:0-0
Timestamp: 2025-11-25T03:05:31.051Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/workspace-tour/workspace-tour.tsx : Import new images at the top of `workspace-tour.tsx` and update the `imageSrc` prop in the appropriate step component to use the new image

Applied to files:

  • apps/studio.giselles.ai/packages/components/icons/ui.tsx
📚 Learning: 2025-11-25T03:06:27.023Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T03:06:27.023Z
Learning: Applies to internal-packages/ui/styles/aliases.css : Keep design token aliases minimal in `internal-packages/ui/styles/aliases.css` and submit as a separate small PR

Applied to files:

  • apps/studio.giselles.ai/packages/components/icons/ui.tsx
📚 Learning: 2025-11-25T03:05:31.051Z
Learnt from: CR
Repo: giselles-ai/giselle PR: 0
File: .cursor/rules/edit-workspace-tour.mdc:0-0
Timestamp: 2025-11-25T03:05:31.051Z
Learning: Applies to internal-packages/workflow-designer-ui/src/editor/workspace-tour/assets/** : Replace GIFs and images in the `assets/` directory and update imports and references in `workspace-tour.tsx`

Applied to files:

  • apps/studio.giselles.ai/packages/components/icons/ui.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: codeql / languages (javascript) / Perform CodeQL for javascript
  • GitHub Check: Cursor Bugbot
  • GitHub Check: check

@shige
Copy link
Member

shige commented Dec 23, 2025

📝
This PR cannot be merged as is because it includes all of the options, such as plans that are not currently offered.
It will need to be hidden with flags and various adjustments will be required.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants