Skip to content

Conversation

@atharvadeosthale
Copy link
Member

@atharvadeosthale atharvadeosthale commented Oct 26, 2025

Summary by CodeRabbit

  • New Features

    • Added AI-powered starter-kit banner across platform setup flows to generate, copy, and present guided setup prompts with quick-open actions for external tools.
    • Added a theme-aware cursor icon to the project overview UI.
    • Added analytics tracking for copy and quick-open actions from the starter-kit banner.
  • Chores

    • Updated UI component and icon dependency versions.

@railway-app
Copy link

railway-app bot commented Oct 26, 2025

This PR was not deployed automatically as @atharvadeosthale does not have access to the Railway project.

In order to get automatic PR deploys, please add @atharvadeosthale to your workspace on Railway.

@appwrite
Copy link

appwrite bot commented Oct 26, 2025

Console

Project ID: 688b7bf400350cbd60e9

Sites (1)
Site Status Logs Preview QR
 console-stage
688b7cf6003b1842c9dc
Ready Ready View Logs Preview URL QR Code

Tip

You can use Avatars API to generate QR code for any text or URLs.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 26, 2025

Walkthrough

Adds an LLM-assisted starter-kit banner and supporting logic to platform creation flows. New files: src/routes/(console)/project-[region]-[project]/overview/platforms/llmBanner.svelte, CursorIconLarge.svelte, and store.ts (adds LLMPromptConfig, generatePromptFromConfig, buildPlatformConfig). Integrates the banner into Android, Apple, Flutter, React Native, and Web create flows. Updates src/lib/actions/analytics.ts to add three Click enum members. Updates two @appwrite package references in package.json.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Review src/routes/(console)/project-[region]-[project]/overview/platforms/store.ts for type correctness, prompt generation logic, and error messages.
  • Inspect src/routes/(console)/project-[region]-[project]/overview/platforms/llmBanner.svelte for prompt derivation, state handling, accessibility, analytics calls, and external opener URL construction.
  • Verify prop wiring and content passed (configCode, alreadyExistsInstructions, llmConfig) in createAndroid.svelte, createApple.svelte, createFlutter.svelte, createReactNative.svelte, and createWeb.svelte.
  • Ensure the new enum members in src/lib/actions/analytics.ts are consistent with usages.
  • Quick checks: CursorIconLarge.svelte theme selection and the two package.json dependency URL updates.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "Copy prompt v2" is partially related to the changeset, referring to a legitimate and significant feature introduced in the pull request. The PR does add the ability to copy setup prompts, with new analytics events (CopyPromptStarterKitClick) and a copy button in the LlmBanner component. However, the title does not fully capture the main architectural change, which is the introduction of the LlmBanner component system and LLM configuration infrastructure across multiple platform flows. The title also omits the "open in" functionality (Cursor, Lovable) that is equally important to the feature set. Despite these gaps, the title remains clear, specific, and directly related to a core feature of the changeset.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch revert-2491-revert-2477-copy-prompt

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a67689f and e4cf187.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (1)
  • package.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • package.json

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.

@atharvadeosthale atharvadeosthale marked this pull request as ready for review October 28, 2025 08:56
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: 3

🧹 Nitpick comments (7)
src/routes/(console)/project-[region]-[project]/overview/platforms/createReactNative.svelte (1)

71-75: Consider consistent prop naming.

The promptConfigCode variable is passed to LlmBanner as configCode, while other platform files directly use a variable named configCode. Consider renaming this to configCode for consistency across the codebase.

Apply this diff:

-    const promptConfigCode = `
+    const configCode = `
     const client = new Client()
         .setProject("${projectId}")
         .setEndpoint("${sdk.forProject(page.params.region, page.params.project).client.config.endpoint}")
     `;

Then update line 260:

                     <LlmBanner
                         platform="reactnative"
-                        configCode={promptConfigCode}
+                        {configCode}
                         {alreadyExistsInstructions}
                         openers={['cursor']} />
src/routes/(console)/project-[region]-[project]/overview/platforms/createWeb.svelte (1)

166-212: Consider standardizing the banner configuration approach.

The Web platform uses a LLMPromptConfig object approach while other platforms (Android, Apple, Flutter, React Native) use individual props (platform, configCode, alreadyExistsInstructions). This creates an inconsistency across the codebase.

Consider either:

  1. Updating other platforms to use the LLMPromptConfig approach, or
  2. Updating Web to use individual props like other platforms

The LLMPromptConfig approach appears more maintainable and type-safe, so option 1 might be preferable.

src/routes/(console)/project-[region]-[project]/overview/platforms/llmBanner.svelte (3)

28-33: Consider user-friendly error handling instead of throwing.

The derived config throws an error if required props are missing. This could crash the component and show a developer-facing error to users. Consider either:

  1. Rendering a fallback UI with a user-friendly message, or
  2. Using console.error and returning a minimal valid config

Example:

 const config = $derived.by(() => {
     if (customConfig) return customConfig;
     if (platform && configCode)
         return buildPlatformConfig(platform, configCode, alreadyExistsInstructions);
-    throw new Error('LlmBanner: must provide either config OR (platform + configCode)');
+    console.error('LlmBanner: must provide either config OR (platform + configCode)');
+    return null;
 });

Then add a guard in the template:

{#if showAlert && config}
  <!-- existing content -->
{/if}

135-135: Use kebab-case for aria attributes.

The ariaLabel prop should be aria-label following HTML attribute naming conventions. While Svelte may handle the conversion, using the standard kebab-case is clearer.

Apply this diff:

-                                ariaLabel="Open action menu"
+                                aria-label="Open action menu"

190-244: Reduce reliance on !important.

The styles contain multiple !important declarations which suggest CSS specificity issues. Consider using more specific selectors or scoped styles instead of forcing precedence with !important. This makes the styles more maintainable and easier to override when needed.

src/routes/(console)/project-[region]-[project]/overview/platforms/store.ts (2)

112-120: Consider narrowing the platformKey parameter type.

The platformKey parameter is currently typed as string, but it could be narrowed to the keys of platformConfigs for better type safety at compile time.

Apply this diff to narrow the type:

 export function buildPlatformConfig(
-    platformKey: string,
+    platformKey: keyof typeof platformConfigs,
     configCode: string,
     alreadyExistsInstructions: string
 ): LLMPromptConfig {

122-131: Optional: Use object property shorthand.

Line 124 can use ES6 shorthand syntax for cleaner code.

Apply this diff:

     return {
         title: config.title,
-        alreadyExistsInstructions: alreadyExistsInstructions,
+        alreadyExistsInstructions,
         cloneCommand: `git clone https://github.com/appwrite/${config.repoName}\ncd ${config.repoName}`,
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bfcb207 and 8787d8b.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (10)
  • package.json (1 hunks)
  • src/lib/actions/analytics.ts (1 hunks)
  • src/routes/(console)/project-[region]-[project]/overview/components/CursorIconLarge.svelte (1 hunks)
  • src/routes/(console)/project-[region]-[project]/overview/platforms/createAndroid.svelte (3 hunks)
  • src/routes/(console)/project-[region]-[project]/overview/platforms/createApple.svelte (3 hunks)
  • src/routes/(console)/project-[region]-[project]/overview/platforms/createFlutter.svelte (3 hunks)
  • src/routes/(console)/project-[region]-[project]/overview/platforms/createReactNative.svelte (3 hunks)
  • src/routes/(console)/project-[region]-[project]/overview/platforms/createWeb.svelte (3 hunks)
  • src/routes/(console)/project-[region]-[project]/overview/platforms/llmBanner.svelte (1 hunks)
  • src/routes/(console)/project-[region]-[project]/overview/platforms/store.ts (1 hunks)
🔇 Additional comments (13)
package.json (1)

27-27: Dependency updates verified and valid.

Both commit hashes (85d1b43) for @appwrite.io/pink-icons-svelte and @appwrite.io/pink-svelte are reachable and successfully resolve in the lockfile. The dependencies are compatible with Svelte 5.25.3 and with each other (pink-svelte correctly depends on pink-icons-svelte 2.0.0-RC.1).

The llmBanner component exists and uses icons from the updated pink-icons-svelte library. The codebase extensively uses both updated dependencies across hundreds of files with no import breakage detected. The lockfile confirms successful resolution and no version conflicts.

src/routes/(console)/project-[region]-[project]/overview/platforms/createAndroid.svelte (1)

200-204: LGTM!

The LlmBanner integration follows the established pattern and correctly passes the necessary props.

src/routes/(console)/project-[region]-[project]/overview/platforms/createReactNative.svelte (1)

42-62: LGTM!

The setup instructions are well-structured and correctly use template literals to interpolate the dynamic projectId and endpoint values.

src/routes/(console)/project-[region]-[project]/overview/platforms/createApple.svelte (1)

73-78: Good refactor to const.

Changing platforms from let to const is appropriate since the object is never reassigned. This makes the code's intent clearer.

src/routes/(console)/project-[region]-[project]/overview/platforms/createFlutter.svelte (2)

42-62: LGTM!

The setup instructions are well-structured and correctly use template literals to interpolate dynamic values. The Flutter SDK integration guidance is clear and comprehensive.


308-312: LGTM!

The LlmBanner integration follows the established pattern across other platform creation flows.

src/lib/actions/analytics.ts (1)

198-201: LGTM!

The new analytics event identifiers follow the established naming convention and align with the LLM banner feature's interaction tracking needs. The trailing comma addition is also a good practice.

src/routes/(console)/project-[region]-[project]/overview/platforms/createWeb.svelte (1)

356-356: LGTM!

The LlmBanner integration correctly uses the config object and includes both 'cursor' and 'lovable' openers, providing users with multiple AI tool options.

src/routes/(console)/project-[region]-[project]/overview/platforms/llmBanner.svelte (2)

87-98: LGTM!

The copyPrompt function correctly implements clipboard copying with proper analytics tracking and user feedback via notifications.


51-83: Well-structured opener configuration.

The openersConfig object provides a clean, extensible pattern for supporting multiple AI tools. The URL generation logic correctly encodes prompts and tracks analytics events.

src/routes/(console)/project-[region]-[project]/overview/platforms/store.ts (3)

20-29: LGTM: Well-structured type definition.

The LLMPromptConfig type is comprehensive and includes all necessary fields for prompt generation across different platforms.


35-57: LGTM: Clear prompt generation logic.

The function generates a well-structured prompt with appropriate fallback handling (line 44) and clear section delineation.


69-110: Web platform is intentionally configured separately—no missing configuration.

The web platform already exists and is properly implemented, but uses a different configuration approach than the other platforms. The createWeb.svelte component defines its own llmConfig directly (lines 166-212) rather than relying on the platformConfigs mapping. This is by design, not an oversight, since web platforms have different setup requirements than mobile frameworks.

No action required.

import Dark from '../assets/dark/cursor-ai.svg';
</script>

<img src={$app.themeInUse === 'dark' ? Dark : Light} width="20" height="20" alt="" />
Copy link
Contributor

@coderabbitai coderabbitai bot Oct 28, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add descriptive alt text for accessibility.

The img element has an empty alt attribute. Consider adding descriptive alt text like "Cursor AI" or "Cursor" to improve accessibility for screen-reader users.

Apply this diff:

-<img src={$app.themeInUse === 'dark' ? Dark : Light} width="20" height="20" alt="" />
+<img src={$app.themeInUse === 'dark' ? Dark : Light} width="20" height="20" alt="Cursor" />
📝 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
<img src={$app.themeInUse === 'dark' ? Dark : Light} width="20" height="20" alt="" />
<img src={$app.themeInUse === 'dark' ? Dark : Light} width="20" height="20" alt="Cursor" />
🤖 Prompt for AI Agents
In
src/routes/(console)/project-[region]-[project]/overview/components/CursorIconLarge.svelte
around line 7, the <img> tag currently has an empty alt attribute; replace
alt="" with a descriptive string such as alt="Cursor AI" (or "Cursor" if
preferred) so screen readers receive meaningful context, keeping the rest of the
tag (theme-based src, width, height) unchanged.

Copy link
Member

Choose a reason for hiding this comment

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

👍

Copy link
Contributor

Choose a reason for hiding this comment

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

Thank you for thanking me! Your feedback helps me improve my assistance. I'm always here to help with your code reviews and questions!

  (\   /)
  ( ^_^ )
 o(")_(")o

atharvadeosthale and others added 2 commits October 28, 2025 14:33
…orms/createApple.svelte

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
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: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8787d8b and 1adc92f.

📒 Files selected for processing (1)
  • src/routes/(console)/project-[region]-[project]/overview/platforms/createApple.svelte (3 hunks)
🔇 Additional comments (3)
src/routes/(console)/project-[region]-[project]/overview/platforms/createApple.svelte (3)

31-31: LGTM!

The import is correctly structured and the component is properly utilized in the template.


73-78: Good immutability improvement.

Changing from let to const prevents accidental mutation and follows best practices since this object is never reassigned.


228-232: LGTM!

The LlmBanner component is properly integrated with appropriate props and logical placement within the Clone starter flow.

@HarshMN2345 HarshMN2345 self-requested a review October 29, 2025 10:45
{/if}

<style lang="scss">
:global(.btn-no-right-radius),
Copy link
Member

Choose a reason for hiding this comment

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

Can we please avoid or reduce the use of global classes here? They tend to introduce unintended side effects

Copy link
Member Author

Choose a reason for hiding this comment

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

Strangely things were not working if I didn't use global, I'll try again

variant="m-500"
>{o.label}</Typography.Text>
<Typography.Text
variant="m-400"
Copy link
Member

Choose a reason for hiding this comment

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

m-400 is the default, we can omit this

color: var(--fgcolor-neutral-primary) !important;
}
& :global(p) {
Copy link
Member

Choose a reason for hiding this comment

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

Typography colors are not working?

import Dark from '../assets/dark/cursor-ai.svg';
</script>

<img src={$app.themeInUse === 'dark' ? Dark : Light} width="20" height="20" alt="" />
Copy link
Member

Choose a reason for hiding this comment

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

👍

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants