Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@
"@ai-sdk/svelte": "^1.1.24",
"@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@315d6c5",
"@appwrite.io/pink-icons": "0.25.0",
"@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@bd82d9a",
"@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@6916470",
"@appwrite.io/pink-legacy": "^1.0.3",
"@appwrite.io/pink-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@bd82d9a",
"@appwrite.io/pink-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@33845eb",
"@faker-js/faker": "^9.9.0",
"@popperjs/core": "^2.11.8",
"@sentry/sveltekit": "^8.38.0",
Expand Down
20 changes: 10 additions & 10 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion src/lib/actions/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,10 @@ export enum Click {
VariablesCreateClick = 'click_variable_create',
VariablesUpdateClick = 'click_variable_update',
VariablesImportClick = 'click_variable_import',
WebsiteOpenClick = 'click_open_website'
WebsiteOpenClick = 'click_open_website',
CopyPromptStarterKitClick = 'click_copy_prompt_starter_kit',
OpenInCursorClick = 'click_open_in_cursor',
OpenInLovableClick = 'click_open_in_lovable'
}

export enum Submit {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,4 @@
aspect-ratio: 1/1;
}
}

:global(.ai-icon-holder.notification) {
width: 36px !important;
height: 32px !important;
}
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<script lang="ts">
import { app } from '$lib/stores/app';
import Light from '../assets/cursor-ai.svg';
import Dark from '../assets/dark/cursor-ai.svg';
</script>

<img src={$app.themeInUse === 'dark' ? Dark : Light} width="20" height="20" alt="Cursor" />
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import { Card } from '$lib/components';
import { page } from '$app/state';
import { onMount } from 'svelte';
import { realtime, sdk } from '$lib/stores/sdk';
import { getApiEndpoint, realtime, sdk } from '$lib/stores/sdk';
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
import { addNotification } from '$lib/stores/notifications';
import { fade } from 'svelte/transition';
Expand All @@ -26,6 +26,7 @@
import { PlatformType } from '@appwrite.io/console';
import { project } from '../../store';
import { getCorrectTitle, type PlatformProps } from './store';
import LlmBanner from './llmBanner.svelte';

let { isConnectPlatform = false }: PlatformProps = $props();

Expand All @@ -35,6 +36,60 @@
let isPlatformCreated = $state(isConnectPlatform);

const projectId = page.params.project;
const VERSIONS_ENDPOINT = (() => {
const endpoint = getApiEndpoint(page.params.region);
const url = new URL('/versions', endpoint);
return url.toString();
})();
let androidSdkVersion = $state('11.3.0');

function buildAndroidInstructions(version: string) {
return `
Confirm you're working inside the correct Android project before editing anything:
- Navigate into the directory that contains the real Android app module (look for gradlew, settings.gradle, and the app-level build.gradle(.kts)).
- If Cursor opens in a parent folder (like your home directory) or you see multiple Android projects, ask which one to modify before making changes.
- Update the app-level build.gradle.kts by default, but be ready to edit a Groovy build.gradle if the project hasn't migrated to Kotlin DSL yet.

Prefer Version Catalogs when adding the Appwrite SDK:
1. If ./gradle/libs.versions.toml exists, add or reuse an Appwrite entry:
\`\`\`toml
[libraries]
appwrite = { module = "io.appwrite:sdk-for-android", version = "${version}" }
\`\`\`
2. Reference it inside the module's dependencies block:
\`\`\`kotlin
dependencies {
implementation(libs.appwrite)
}
\`\`\`
Only when the project lacks ./gradle/libs.versions.toml should you hardcode the dependency:
\`\`\`kotlin
implementation("io.appwrite:sdk-for-android:${version}")
\`\`\`
Legacy Groovy scripts should use:
\`\`\`groovy
implementation "io.appwrite:sdk-for-android:${version}"
\`\`\`

Before introducing any new files, search the project (app/src, libs/, shared modules, etc.) for existing Appwrite client helpers (look for \`Client(\`, \`AppwriteClient\`, or \`.setEndpoint\`). If a client already exists, update its configuration instead of creating a duplicate.

Ensure the Appwrite client is initialized with the application context and current project info:
\`\`\`kotlin
val client = Client(applicationContext)
.setEndpoint("${sdk.forProject(page.params.region, page.params.project).client.config.endpoint}")
.setProject("${projectId}")

val account = Account(client)
\`\`\`

From the app's entry point (e.g., Application class or the first launched Activity), automatically invoke a helper that pings Appwrite so the user can verify connectivity and will be reflected on the Appwrite console:
\`\`\`kotlin
client.ping()
\`\`\`
`;
}

const alreadyExistsInstructions = $derived(buildAndroidInstructions(androidSdkVersion));

const gitCloneCode =
'\ngit clone https://github.com/appwrite/starter-for-android\ncd starter-for-android\n';
Expand All @@ -43,6 +98,22 @@
const val APPWRITE_PROJECT_NAME = "${$project.name}"
const val APPWRITE_PUBLIC_ENDPOINT = "${sdk.forProject(page.params.region, page.params.project).client.config.endpoint}"`;

async function fetchAndroidSdkVersion() {
try {
const response = await fetch(VERSIONS_ENDPOINT);
if (!response.ok) {
throw new Error(`Failed to fetch versions: ${response.status}`);
}
const data = await response.json();
const latestVersion = data?.['client-android'];
if (typeof latestVersion === 'string' && latestVersion.trim()) {
androidSdkVersion = latestVersion.trim();
}
} catch (error) {
console.error('Unable to fetch latest Android SDK version', error);
}
}

async function createAndroidPlatform() {
try {
isCreatingPlatform = true;
Expand Down Expand Up @@ -83,6 +154,7 @@ const val APPWRITE_PUBLIC_ENDPOINT = "${sdk.forProject(page.params.region, page.
}

onMount(() => {
fetchAndroidSdkVersion();
const unsubscribe = realtime.forConsole(page.params.region, 'console', (response) => {
if (response.events.includes(`projects.${projectId}.ping`)) {
connectionSuccessful = true;
Expand Down Expand Up @@ -171,6 +243,12 @@ const val APPWRITE_PUBLIC_ENDPOINT = "${sdk.forProject(page.params.region, page.
{#if isPlatformCreated}
<Fieldset legend="Clone starter" badge="Optional">
<Layout.Stack gap="l">
<LlmBanner
platform="android"
{configCode}
{alreadyExistsInstructions}
openers={['cursor']} />

<Typography.Text variant="m-500">
1. If you're starting a new project, you can clone our starter kit from
GitHub using the terminal, VSCode or Android Studio.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import { app } from '$lib/stores/app';
import { project } from '../../store';
import { getCorrectTitle, type PlatformProps } from './store';
import LlmBanner from './llmBanner.svelte';

let { isConnectPlatform = false, platform = PlatformType.Appleios }: PlatformProps = $props();

Expand All @@ -38,14 +39,38 @@

const projectId = page.params.project;

const alreadyExistsInstructions = `
Install the Appwrite iOS SDK using the following package URL:

\`\`\`
https://github.com/appwrite/sdk-for-apple
\`\`\`

From a suitable lib directory, export the Appwrite client as a global variable:

\`\`\`
let client = Client()
.setEndpoint("${sdk.forProject(page.params.region, page.params.project).client.config.endpoint}")
.setProject("${projectId}")

let account = Account(client)
\`\`\`

On the homepage of the app, create a button that says "Send a ping" and when clicked, it should call the following function:

\`\`\`
client.ping()
\`\`\`
`;

const gitCloneCode =
'\ngit clone https://github.com/appwrite/starter-for-ios\ncd starter-for-ios\n';

const configCode = `APPWRITE_PROJECT_ID: "${projectId}"
APPWRITE_PROJECT_NAME: "${$project.name}"
APPWRITE_PUBLIC_ENDPOINT: "${sdk.forProject(page.params.region, page.params.project).client.config.endpoint}"`;

let platforms: { [key: string]: PlatformType } = {
const platforms: { [key: string]: PlatformType } = {
iOS: PlatformType.Appleios,
macOS: PlatformType.Applemacos,
watchOS: PlatformType.Applewatchos,
Expand Down Expand Up @@ -199,6 +224,12 @@ APPWRITE_PUBLIC_ENDPOINT: "${sdk.forProject(page.params.region, page.params.proj
{#if isPlatformCreated}
<Fieldset legend="Clone starter" badge="Optional">
<Layout.Stack gap="l">
<LlmBanner
platform="apple"
{configCode}
{alreadyExistsInstructions}
openers={['cursor']} />

<Typography.Text variant="m-500">
1. If you're starting a new project, you can clone our starter kit from
GitHub using the terminal or XCode.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import { Card } from '$lib/components';
import { page } from '$app/state';
import { onMount } from 'svelte';
import { realtime, sdk } from '$lib/stores/sdk';
import { getApiEndpoint, realtime, sdk } from '$lib/stores/sdk';
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
import { addNotification } from '$lib/stores/notifications';
import { fade } from 'svelte/transition';
Expand All @@ -27,6 +27,7 @@
import { PlatformType } from '@appwrite.io/console';
import { project } from '../../store';
import { getCorrectTitle, type PlatformProps } from './store';
import LlmBanner from './llmBanner.svelte';

let { isConnectPlatform = false, platform = PlatformType.Flutterandroid }: PlatformProps =
$props();
Expand All @@ -37,6 +38,38 @@
let isPlatformCreated = $state(isConnectPlatform);

const projectId = page.params.project;
const VERSIONS_ENDPOINT = (() => {
const endpoint = getApiEndpoint(page.params.region);
const url = new URL('/versions', endpoint);
return url.toString();
})();
let flutterSdkVersion = $state('20.3.0');

function buildFlutterInstructions(version: string) {
return `
Install the Appwrite Flutter SDK using the following command:

\`\`\`
flutter pub add appwrite:${version}
\`\`\`

From a suitable lib directory, export the Appwrite client as a global variable, hardcode the project details too:

\`\`\`
final Client client = Client()
.setProject("${projectId}")
.setEndpoint("${sdk.forProject(page.params.region, page.params.project).client.config.endpoint}");
\`\`\`

On the homepage of the app, create a button that says "Send a ping" and when clicked, it should call the following function:

\`\`\`
client.ping();
\`\`\`
`;
}
Comment on lines +48 to +70
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

🧩 Analysis chain

Verify the Flutter package installation syntax and API availability.

Two concerns:

  1. Line 50: The syntax appwrite:${version} may not be valid for Flutter's pub add command. Flutter typically uses package_name version format without a colon.

  2. Line 64: Verify that the Appwrite Flutter SDK client has a ping() method.

Run the following script to check the Flutter pub add syntax:

Also, please search the web to verify:

  1. The correct syntax for flutter pub add with specific versions
  2. Whether the Appwrite Flutter SDK client supports a ping() method

🏁 Script executed:

#!/bin/bash
# Check Flutter pub add command syntax in official docs

rg -n "flutter pub add" --type=md -A 2 -B 2

Length of output: 0


🌐 Web query:

What is the correct syntax for flutter pub add command with a specific version?

💡 Result:

You include the version after a colon. Examples:

  • Add a package with a caret (compatible) constraint:
    flutter pub add package_name:^1.2.3. [1]

  • Add an exact version:
    flutter pub add package_name:1.2.3. [2]

To add as a dev dependency use --dev (e.g. flutter pub add --dev package_name:^1.2.3). [1][2]

Sources: [1] Flutter docs — Using packages. [2] dart/pub hosted example (Cloudsmith documentation).


🌐 Web query:

Does Appwrite Flutter SDK client have a ping method?

💡 Result:

Short answer: No — the Appwrite Flutter/Dart client doesn't expose a single Client.ping() method. Use the Health service (e.g., Health.getXXX or GET /v1/health) or call the desired endpoint (e.g., /v1/health) via the SDK instead. [1][2]

Sources:

  • Appwrite Health API docs (usage across SDKs). [1]
  • Appwrite REST Health endpoints (/v1/health). [2]

Replace client.ping() with a valid Appwrite Flutter SDK health check call.

The Flutter pub add syntax at line 50 is correct. However, line 64 has a critical issue: the Appwrite Flutter SDK client does not expose a ping() method. The Appwrite Flutter/Dart client should use the Health service instead.

Replace the ping example with a Health service call, such as calling the /v1/health endpoint via the SDK's Health service.

🤖 Prompt for AI Agents
In
src/routes/(console)/project-[region]-[project]/overview/platforms/createFlutter.svelte
around lines 45 to 67, the example uses client.ping() which does not exist on
the Appwrite Flutter SDK; replace that line with a call to the SDK’s Health
service (the Health endpoint for /v1/health) using the SDK’s health client
method (e.g., invoke the Health service getter and call its health check
method), handle the returned Future/response and errors appropriately so the
example shows a valid health check call instead of client.ping().


const alreadyExistsInstructions = $derived(buildFlutterInstructions(flutterSdkVersion));

const gitCloneCode =
'\ngit clone https://github.com/appwrite/starter-for-flutter\ncd starter-for-flutter\n';
Expand Down Expand Up @@ -111,6 +144,22 @@
[PlatformType.Flutterwindows]: 'Package name'
};

async function fetchFlutterSdkVersion() {
try {
const response = await fetch(VERSIONS_ENDPOINT);
if (!response.ok) {
throw new Error(`Failed to fetch versions: ${response.status}`);
}
const data = await response.json();
const latestVersion = data?.['client-flutter'];
if (typeof latestVersion === 'string' && latestVersion.trim()) {
flutterSdkVersion = latestVersion.trim();
}
} catch (error) {
console.error('Unable to fetch latest Flutter SDK version', error);
}
}

async function createFlutterPlatform() {
try {
isCreatingPlatform = true;
Expand Down Expand Up @@ -158,6 +207,7 @@
}

onMount(() => {
fetchFlutterSdkVersion();
const unsubscribe = realtime.forConsole(page.params.region, 'console', (response) => {
if (response.events.includes(`projects.${projectId}.ping`)) {
connectionSuccessful = true;
Expand Down Expand Up @@ -281,6 +331,11 @@
{#if isPlatformCreated}
<Fieldset legend="Clone starter" badge="Optional">
<Layout.Stack gap="l">
<LlmBanner
platform="flutter"
{configCode}
{alreadyExistsInstructions}
openers={['cursor']} />
<Typography.Text variant="m-500">
1. If you're starting a new project, you can clone our starter kit from
GitHub using the terminal, VSCode or Android Studio.
Expand Down
Loading