diff --git a/example.php b/example.php index 983abf99e9..5ff0bff027 100644 --- a/example.php +++ b/example.php @@ -38,7 +38,7 @@ final class Config public const string TITLE = 'Appwrite'; public const string DESCRIPTION = 'Appwrite backend as a service'; public const string LICENSE_NAME = 'BSD-3-Clause'; - public const string LICENSE_URL = 'https://raw.githubusercontent.com/appwrite/appwrite/master/LICENSE'; + public const string LICENSE_URL = 'https://raw.githubusercontent.com/appwrite/appwrite/main/LICENSE'; public const string COVER_IMAGE = 'https://github.com/appwrite/appwrite/raw/main/public/images/github.png'; public const string TWITTER = 'appwrite'; public const string DISCORD_CHANNEL = '564160730845151244'; diff --git a/templates/android/README.md.twig b/templates/android/README.md.twig index 706a09671a..bcf1d8c2ad 100644 --- a/templates/android/README.md.twig +++ b/templates/android/README.md.twig @@ -1,11 +1,10 @@ # {{ spec.info.title }} {{sdk.name}} SDK ![Maven Central](https://img.shields.io/maven-central/v/{{ sdk.namespace | caseDot }}/{{ sdk.gitRepoName | caseDash }}.svg?color=green&style=flat-square) -![License](https://img.shields.io/github/license/{{ sdk.gitUserName|url_encode }}/{{ sdk.gitRepoName|url_encode }}.svg?style=flat-square) +![License](https://img.shields.io/badge/license-{{ spec.info.license.name|replace({'-': '--', '_': '__'})|url_encode }}-blue.svg?style=flat-square) ![Version](https://img.shields.io/badge/api%20version-{{ spec.info.version|url_encode }}-blue.svg?style=flat-square) -[![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator) {% if sdk.twitterHandle %} -[![Twitter Account](https://img.shields.io/twitter/follow/{{ sdk.twitterHandle }}?color=00acee&label=twitter&style=flat-square)](https://twitter.com/{{ sdk.twitterHandle }}) +[![X Account](https://img.shields.io/badge/follow-%40{{ sdk.twitterHandle|replace({'-': '--', '_': '__'})|url_encode }}-000000?logo=x&style=flat-square)](https://x.com/{{ sdk.twitterHandle }}) {% endif %} {% if sdk.discordChannel %} [![Discord](https://img.shields.io/discord/{{ sdk.discordChannel }}?label=discord&style=flat-square)]({{ sdk.discordUrl }}) @@ -23,134 +22,90 @@ ## Installation -### Gradle +The SDK requires Android 7.0 (API level 24) or later and is published to Maven Central as `{{ sdk.namespace | caseDot }}:{{ sdk.gitRepoName | caseDash }}`. Make sure `mavenCentral()` is among your repositories (new Android Studio projects include it in `settings.gradle.kts`), then add the dependency to your app module's build file. -Appwrite's Android SDK is hosted on Maven Central. In order to fetch the Appwrite SDK, add this to your root level `build.gradle(.kts)` file: +Kotlin DSL (`build.gradle.kts`): -```groovy -repositories { - mavenCentral() +```kotlin +dependencies { + implementation("{{ sdk.namespace | caseDot }}:{{ sdk.gitRepoName | caseDash }}:{{ sdk.version }}") } ``` -If you would like to fetch our SNAPSHOT releases, you need to add the SNAPSHOT maven repository to your `build.gradle(.kts)`: +Groovy (`build.gradle`): ```groovy -repositories { - maven { - url "https://s01.oss.sonatype.org/content/repositories/snapshots/" - } +dependencies { + implementation '{{ sdk.namespace | caseDot }}:{{ sdk.gitRepoName | caseDash }}:{{ sdk.version }}' } ``` -Next, add the dependency to your project's `build.gradle(.kts)` file: - -```groovy -implementation("{{ sdk.namespace | caseDot }}:{{ sdk.gitRepoName | caseDash }}:{{ sdk.version }}") -``` +### Code shrinking (R8) -### Maven -Add this to your project's `pom.xml` file: +The SDK ships the R8 rules it needs, so no extra configuration is required. Your own classes that the SDK fills from JSON (the `nestedType` of documents, rows and preferences, and the `payloadType` of Realtime subscriptions) are read by Gson through reflection. Annotate them with `@Keep` so R8 keeps their fields: -```xml - - - {{ sdk.namespace | caseDot }} - {{ sdk.gitRepoName | caseDash }} - {{sdk.version}} - - +```kotlin +@Keep +data class Note(val title: String, val body: String) ``` +{% if sdk.gettingStarted %} -### Code shrinking (R8) +{{ sdk.gettingStarted|trim|raw }} +{% endif %} + +## Push notifications -The SDK ships the R8 rules it needs, so no extra configuration is required. Your own classes -that the SDK fills from JSON (the `nestedType` of documents, rows and preferences, and the -`payloadType` of Realtime subscriptions) are read by Gson through reflection. Annotate them -with `@Keep` so R8 keeps their fields: +`Push` subscribes to topics over the Appwrite push broker. With no topic it subscribes to the signed-in user's own topic: ```kotlin -@Keep -data class Note(val title: String, val body: String) +import {{ sdk.namespace | caseDot }}.services.Push + +val push = Push(client, context) + +val subscription = push.subscribe { message -> + Log.d("Appwrite", "${message.topic}: ${message.data}") +} + +subscription.unsubscribe() ``` -### Push notifications - -#### Background delivery - -A subscription with `background = true` keeps delivering after the app is backgrounded, its -process is killed, or the device restarts, until it is unsubscribed or `push.close()` is -called (do this on sign-out). No service is kept running: a scheduled job and alarm wake the -app every 15 to 60 seconds to reconnect, and the broker replays what was sent in between -(`retry = true`). It reconnects with the credential saved at subscribe time, so use a session -(`client.setSession(...)`), not a short-lived JWT. - -While the app is not on screen, each message is also posted as a notification that opens -your launch activity with `Push.EXTRA_TOPIC` and `Push.EXTRA_PAYLOAD` in its extras. It shows the -title, body and image sent with `createPush`, falling back to the subscription's `title`, and to -the raw payload as the body for messages that are not a JSON object. A push with neither a title -nor a body, such as a data-only push, posts no notification; it still reaches your callback or -`PushReceiver`. On Android 13 and later it needs the `POST_NOTIFICATIONS` -permission: the first background subscription asks for it from the visible activity (the one -`Push` is created with, else the next one to resume), or call -`Push.requestNotificationPermission(activity)` to ask yourself. Set its -icon with `` -in your ``. While the app is on screen your callback shows the message, so no -notification is posted unless the subscription passes `notifyInForeground = true`. To handle -messages that arrive while no callback is listening in code, subclass `PushReceiver` and declare -it with the `{{ sdk.namespace | caseDot }}.push.MESSAGE` action (see its docs). - -#### Delivery while the app is closed - -Messages sent while the app is closed arrive at the next scheduled wake-up. While the device is -awake that is about every 15 seconds, or about every 60 seconds once exact alarms are allowed; -without exact alarms the wake-ups are inexact, so battery saver can defer them further. In Doze -(screen off and idle for a while) Android limits background alarms, exact ones included, to about -one every nine minutes, so a closed app can take several minutes to receive a message: allowing -exact alarms makes wake-ups punctual, it does not lift Doze. For immediate delivery, also in -Doze, use `push.setForeground(true)` (see below). +### Background delivery + +A subscription with `background = true` keeps delivering after the app is backgrounded, its process is killed, or the device restarts, until it is unsubscribed or `push.close()` is called (do this on sign-out). No service is kept running: a scheduled job and alarm wake the app every 15 to 60 seconds to reconnect, and the broker replays what was sent in between (`retry = true`). It reconnects with the credential saved at subscribe time, so use a session (`client.setSession(...)`), not a short-lived JWT. + +While the app is not on screen, each message is also posted as a notification that opens your launch activity with `Push.EXTRA_TOPIC` and `Push.EXTRA_PAYLOAD` in its extras. It shows the title, body and image sent with `createPush`, falling back to the subscription's `title`, and to the raw payload as the body for messages that are not a JSON object. A push with neither a title nor a body, such as a data-only push, posts no notification; it still reaches your callback or `PushReceiver`. + +On Android 13 and later it needs the `POST_NOTIFICATIONS` permission: the first background subscription asks for it from the visible activity (the one `Push` is created with, else the next one to resume), or call `Push.requestNotificationPermission(activity)` to ask yourself. Set its icon with `` in your ``. + +While the app is on screen your callback shows the message, so no notification is posted unless the subscription passes `notifyInForeground = true`. To handle messages that arrive while no callback is listening in code, subclass `PushReceiver` and declare it with the `{{ sdk.namespace | caseDot }}.push.MESSAGE` action (see its docs). + +### Delivery while the app is closed + +Messages sent while the app is closed arrive at the next scheduled wake-up. While the device is awake that is about every 15 seconds, or about every 60 seconds once exact alarms are allowed; without exact alarms the wake-ups are inexact, so battery saver can defer them further. In Doze (screen off and idle for a while) Android limits background alarms, exact ones included, to about one every nine minutes, so a closed app can take several minutes to receive a message: allowing exact alarms makes wake-ups punctual, it does not lift Doze. For immediate delivery, also in Doze, use `push.setForeground(true)` (see below). The SDK uses exact alarms on its own whenever the app may schedule them. To allow it: -1. Declare the permissions in your app's `AndroidManifest.xml`. Both are optional and subject to - Google Play policy: `SCHEDULE_EXACT_ALARM` needs a declaration in the Play Console, and - `USE_EXACT_ALARM` is reserved for alarm, clock and calendar apps (the SDK does not use it). +1. Declare the permissions in your app's `AndroidManifest.xml`. Both are optional and subject to Google Play policy: `SCHEDULE_EXACT_ALARM` needs a declaration in the Play Console, and `USE_EXACT_ALARM` is reserved for alarm, clock and calendar apps (the SDK does not use it). ```xml ``` -2. On Android 13 and later the user has to allow exact alarms, under Settings > Apps > Special app - access > Alarms & reminders. Android 12 grants a declared `SCHEDULE_EXACT_ALARM` - automatically, and older versions need nothing. Check with `Push.backgroundStatus(context)`: when `bestEffort` is - true, explain why to the user, then from a user action open that screen with `Push.requestExactAlarms(context)`, or - ask for the battery-optimisation exemption with `Push.requestIgnoreBatteryOptimizations(context)`. Both return false when there is - nothing to ask, including when the permission is not declared. The SDK never opens these - screens on its own. - -If `backgroundRestricted` is true, the user restricted the app's background usage and messages can -wait until the app is opened. Exact alarms don't lift it, and neither does foreground mode: Android -stops a restricted app's foreground service once it leaves the screen. Ask the user to choose -Unrestricted in the app's battery settings (Settings > Apps > your app > Battery); granting the -battery optimisation exemption also lets the SDK's alarms and jobs run, and `bestEffort` then -reflects only the exact-alarm state. - -If the user force-stops the app (Settings > Force stop, and on some devices swiping it away from -recents), Android cancels its alarms and jobs: nothing is delivered until the app is opened -again, and the broker then replays what was sent meanwhile. - -For immediate delivery even after a kill and during Doze, call `push.setForeground(true)` from -the foreground: it adds a foreground service -with a quiet ongoing notification. If you never enable it, you can remove the service from -your merged manifest, so the Play Console does not ask you to declare it: +2. On Android 13 and later the user has to allow exact alarms, under Settings > Apps > Special app access > Alarms & reminders. Android 12 grants a declared `SCHEDULE_EXACT_ALARM` automatically, and older versions need nothing. Check with `Push.backgroundStatus(context)`: when `bestEffort` is true, explain why to the user, then from a user action open that screen with `Push.requestExactAlarms(context)`, or ask for the battery-optimisation exemption with `Push.requestIgnoreBatteryOptimizations(context)`. Both return false when there is nothing to ask, including when the permission is not declared. The SDK never opens these screens on its own. + +If `backgroundRestricted` is true, the user restricted the app's background usage and messages can wait until the app is opened. Exact alarms don't lift it, and neither does foreground mode: Android stops a restricted app's foreground service once it leaves the screen. Ask the user to choose Unrestricted in the app's battery settings (Settings > Apps > your app > Battery); granting the battery optimisation exemption also lets the SDK's alarms and jobs run, and `bestEffort` then reflects only the exact-alarm state. + +If the user force-stops the app (Settings > Force stop, and on some devices swiping it away from recents), Android cancels its alarms and jobs: nothing is delivered until the app is opened again, and the broker then replays what was sent meanwhile. + +For immediate delivery even after a kill and during Doze, call `push.setForeground(true)` from the foreground: it adds a foreground service with a quiet ongoing notification. If you never enable it, you can remove the service from your merged manifest, so the Play Console does not ask you to declare it: ```xml ``` -#### Opening a tapped notification +### Opening a tapped notification Read the `data` sent with `createPush` when the user taps a background notification: @@ -162,18 +117,19 @@ push.getInitialNotification()?.let { openSale(it.data["saleId"]) } val stop = push.onNotificationOpened { opened -> openSale(opened.data["saleId"]) } ``` -A tap made while nothing listens is kept for `getInitialNotification()`. The tap intent still -carries `Push.EXTRA_TOPIC` and `Push.EXTRA_PAYLOAD` for apps that read their activity's intent. +A tap made while nothing listens is kept for `getInitialNotification()`. The tap intent still carries `Push.EXTRA_TOPIC` and `Push.EXTRA_PAYLOAD` for apps that read their activity's intent. -{% if sdk.gettingStarted %} +## Learn more -{{ sdk.gettingStarted|raw }} -{% endif %} +- [Android quick start](https://appwrite.io/docs/quick-starts/android) and [Java quick start](https://appwrite.io/docs/quick-starts/android-java) +- [Android SDK reference](https://appwrite.io/docs/references/cloud/client-android-kotlin/account) +- [Appwrite docs](https://appwrite.io/docs) +- [Discord community](https://appwrite.io/discord) ## Contribution -This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/master/CONTRIBUTING.md) before sending a pull-request. +This library is auto-generated by the Appwrite [SDK Generator](https://github.com/appwrite/sdk-generator). To learn how you can help improve this SDK, please read the [contribution guide](https://github.com/appwrite/sdk-generator/blob/main/CONTRIBUTING.md) before sending a pull request. ## License -Please see the [{{spec.info.license.name}} license]({{spec.info.license.url}}) file for more information. \ No newline at end of file +Please see the [{{spec.info.license.name}} license]({{spec.info.license.url}}) file for more information. diff --git a/templates/claude-plugin/README.md.twig b/templates/claude-plugin/README.md.twig index 20ffed0468..0318f74e11 100644 --- a/templates/claude-plugin/README.md.twig +++ b/templates/claude-plugin/README.md.twig @@ -1,18 +1,85 @@ +{% set name = spec.info.title | caseLower %} # {{ spec.info.title }} Claude Code Plugin -![License](https://img.shields.io/github/license/{{ sdk.gitUserName|url_encode }}/{{ sdk.gitRepoName|url_encode }}.svg?style=flat-square) -![Version](https://img.shields.io/badge/api%20version-{{ sdk.version }}-blue.svg?style=flat-square) -[![Twitter Account](https://img.shields.io/twitter/follow/appwrite?color=00acee&label=twitter&style=flat-square)](https://twitter.com/appwrite) -[![Discord](https://img.shields.io/discord/564160730845151244?label=discord&style=flat-square)](https://appwrite.io/discord) +![License](https://img.shields.io/badge/license-{{ spec.info.license.name|replace({'-': '--', '_': '__'})|url_encode }}-blue.svg?style=flat-square) +![Version](https://img.shields.io/badge/version-{{ sdk.version|url_encode }}-blue.svg?style=flat-square) +{% if sdk.twitterHandle %} +[![X Account](https://img.shields.io/badge/follow-%40{{ sdk.twitterHandle|replace({'-': '--', '_': '__'})|url_encode }}-000000?logo=x&style=flat-square)](https://x.com/{{ sdk.twitterHandle }}) +{% endif %} +{% if sdk.discordChannel %} +[![Discord](https://img.shields.io/discord/{{ sdk.discordChannel }}?label=discord&style=flat-square)]({{ sdk.discordUrl }}) +{% endif %} -Appwrite tools for Claude Code. This plugin packages Appwrite SDK skills, the hosted Appwrite MCP server, and deployment commands in Claude Code's native plugin format. +{{ spec.info.title }} tools for Claude Code. This plugin packages {{ spec.info.title }} SDK skills, the hosted {{ spec.info.title }} MCP server, and deployment commands in Claude Code's native plugin format. + +## Installation + +The plugin is listed in Anthropic's official marketplace, which Claude Code adds automatically. Install it from your shell: + +```sh +claude plugin install {{ name }}@claude-plugins-official +``` + +Or from a Claude Code session: + +```text +/plugin install {{ name }}@claude-plugins-official +``` + +To install from this repository instead, add it as a marketplace first: + +```text +/plugin marketplace add {{ sdk.gitUserName }}/{{ sdk.gitRepoName }} +/plugin install {{ name }}@{{ name }} +``` + +Run `/reload-plugins` to load the plugin in a session that is already open. + +## Included skills + +- `/{{ name }}:typescript` +- `/{{ name }}:dart` +- `/{{ name }}:kotlin` +- `/{{ name }}:swift` +- `/{{ name }}:php` +- `/{{ name }}:python` +- `/{{ name }}:ruby` +- `/{{ name }}:go` +- `/{{ name }}:rust` +- `/{{ name }}:dotnet` +- `/{{ name }}:cli` + +These skills give Claude Code language-specific {{ spec.info.title }} context for authentication, database queries, storage, realtime, functions, and server-side administration. Claude loads them automatically when a task matches, or you can invoke one directly. + +## Included commands + +- `/{{ name }}:deploy-site` +- `/{{ name }}:deploy-function` + +These commands are manual-only, so Claude does not start a deployment on its own. + +## Hosted MCP server + +The plugin configures one `{{ name }}` server at `https://mcp.appwrite.io/`. It provides tools for working with your {{ spec.info.title }} organizations and projects, and for searching the latest {{ spec.info.title }} documentation. + +The hosted server uses browser-based OAuth, so the plugin does not require an API key, project ID, endpoint, or other manually configured secret. In a Claude Code session, open `/mcp`, select the `{{ name }}` server, and choose **Authenticate**. From your shell, run: + +```sh +claude mcp login plugin:{{ name }}:{{ name }} +``` + +After authentication, try: + +> Use {{ spec.info.title }} to show my workspace context and list my projects. + +If authentication expires, choose **Re-authenticate** from `/mcp` or run the login command again. If the browser does not open, use the URL printed by Claude Code. Run `claude mcp get plugin:{{ name }}:{{ name }}` to check the server's authentication and connection status. ## Structure ```text .claude-plugin/ ├── plugin.json # Plugin manifest -└── marketplace.json # Marketplace manifest for install-by-name flows +└── marketplace.json # Marketplace manifest skills/ # Claude Code skills (per language) ├── typescript/ │ └── SKILL.md @@ -34,85 +101,46 @@ skills/ # Claude Code skills (per language) │ └── SKILL.md ├── dotnet/ │ └── SKILL.md -├── cli/ -│ └── SKILL.md +└── cli/ + └── SKILL.md commands/ # Manual commands with side effects ├── deploy-site.md └── deploy-function.md -.mcp.json # Hosted Appwrite MCP server +.mcp.json # Hosted {{ spec.info.title }} MCP server ``` -## Included Skills - -- `/{{ spec.info.title | caseLower }}:typescript` -- `/{{ spec.info.title | caseLower }}:dart` -- `/{{ spec.info.title | caseLower }}:kotlin` -- `/{{ spec.info.title | caseLower }}:swift` -- `/{{ spec.info.title | caseLower }}:php` -- `/{{ spec.info.title | caseLower }}:python` -- `/{{ spec.info.title | caseLower }}:ruby` -- `/{{ spec.info.title | caseLower }}:go` -- `/{{ spec.info.title | caseLower }}:rust` -- `/{{ spec.info.title | caseLower }}:dotnet` -- `/{{ spec.info.title | caseLower }}:cli` - -These skills give Claude Code language-specific Appwrite context for authentication, database queries, storage, realtime, functions, and server-side administration. - -## Included Commands - -- `/{{ spec.info.title | caseLower }}:deploy-site` -- `/{{ spec.info.title | caseLower }}:deploy-function` - -These commands are marked as manual-only so Claude will not invoke deployment workflows automatically. - -## Hosted MCP Server - -The plugin configures one `{{ spec.info.title | caseLower }}` server at `https://mcp.appwrite.io/`. It provides tools for working with your {{ spec.info.title }} workspace and projects and for searching the latest {{ spec.info.title }} documentation. +## Local development -The hosted server uses browser-based OAuth, so the plugin does not require an API key, project ID, endpoint, or other manually configured secret. In an interactive Claude Code session, open `/mcp` and authenticate the `{{ spec.info.title | caseLower }}` plugin server, or run: +From a clone of this repository, validate the plugin and marketplace: ```sh -claude mcp login plugin:{{ spec.info.title | caseLower }}:{{ spec.info.title | caseLower }} -``` - -After authentication, try: - -> Use {{ spec.info.title }} to show my workspace context and list my projects. - -If authentication expires, run `claude mcp login plugin:{{ spec.info.title | caseLower }}:{{ spec.info.title | caseLower }}` again or choose **Re-authenticate** from `/mcp`. If the browser does not open, use the URL printed by Claude Code. Use `claude mcp get plugin:{{ spec.info.title | caseLower }}:{{ spec.info.title | caseLower }}` and `/mcp` to inspect approval, authentication, and connection status. - -## Local Development - -Validate the generated plugin and marketplace: - -```sh -cd examples/claude-plugin claude plugin validate . ``` -Load the plugin directly for a dev session: +Load the plugin directly for a development session: ```sh -claude --plugin-dir ./examples/claude-plugin +claude --plugin-dir . ``` -Then verify: - -- `/help` shows the `{{ spec.info.title | caseLower }}` namespace -- `/{{ spec.info.title | caseLower }}:typescript` loads the TypeScript skill +Then check that `/help` lists the `{{ name }}` namespace and that `/{{ name }}:typescript` loads the TypeScript skill. -Install it end to end through the bundled marketplace: +To test the install-by-name flow, add the clone as a local marketplace: ```sh -claude plugin marketplace add ./examples/claude-plugin --scope local -claude plugin install {{ spec.info.title | caseLower }}@{{ spec.info.title | caseLower }} --scope local +claude plugin marketplace add ./ --scope local +claude plugin install {{ name }}@{{ name }} --scope local ``` -Use `--plugin-dir` for fast iteration on skills and commands. Use the bundled marketplace when you want install-by-name flows such as `appwrite@appwrite`. +## Learn more + +- [{{ spec.info.title }} in Claude Code](https://appwrite.io/docs/tooling/ai/agents/claude-code) +- [{{ spec.info.title }} MCP server](https://appwrite.io/docs/tooling/ai/mcp-servers) +- [Claude Code plugins documentation](https://code.claude.com/docs/en/discover-plugins) ## Contribution -This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/master/CONTRIBUTING.md) before sending a pull-request. +This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/main/CONTRIBUTING.md) before sending a pull-request. ## License diff --git a/templates/claude-plugin/marketplace.json.twig b/templates/claude-plugin/marketplace.json.twig index e02f6a8a36..994e03e625 100644 --- a/templates/claude-plugin/marketplace.json.twig +++ b/templates/claude-plugin/marketplace.json.twig @@ -17,7 +17,7 @@ "name": "Appwrite", "email": "team@appwrite.io" }, - "homepage": "https://appwrite.io/docs/tooling/ai/ai-dev-tools/claude-code", + "homepage": "https://appwrite.io/docs/tooling/ai/agents/claude-code", "repository": "https://github.com/{{ sdk.gitUserName }}/{{ sdk.gitRepoName }}", "license": "{{ spec.info.license.name }}", "keywords": [ diff --git a/templates/claude-plugin/plugin.json.twig b/templates/claude-plugin/plugin.json.twig index ea589b65e0..97d0a5a0ec 100644 --- a/templates/claude-plugin/plugin.json.twig +++ b/templates/claude-plugin/plugin.json.twig @@ -6,7 +6,7 @@ "name": "Appwrite", "email": "team@appwrite.io" }, - "homepage": "https://appwrite.io/docs/tooling/ai/ai-dev-tools/claude-code", + "homepage": "https://appwrite.io/docs/tooling/ai/agents/claude-code", "repository": "https://github.com/{{ sdk.gitUserName }}/{{ sdk.gitRepoName }}", "license": "{{ spec.info.license.name }}", "keywords": [ diff --git a/templates/cli/README.md.twig b/templates/cli/README.md.twig index 818b48cdd1..b0daf10201 100644 --- a/templates/cli/README.md.twig +++ b/templates/cli/README.md.twig @@ -1,10 +1,10 @@ # {{ spec.info.title }} {{sdk.name}} SDK -![License](https://img.shields.io/github/license/{{ sdk.gitUserName|url_encode }}/{{ sdk.gitRepoName|url_encode }}.svg?style=flat-square) +![License](https://img.shields.io/badge/license-{{ spec.info.license.name|replace({'-': '--', '_': '__'})|url_encode }}-blue.svg?style=flat-square) ![Version](https://img.shields.io/badge/api%20version-{{ spec.info.version|url_encode }}-blue.svg?style=flat-square) -[![Build Status](https://img.shields.io/travis/com/{{ sdk.gitUserName|url_encode }}/sdk-generator?style=flat-square)](https://travis-ci.com/{{ sdk.gitUserName|url_encode }}/sdk-generator) +[![npm](https://img.shields.io/npm/v/{{ language.params.npmPackage|url_encode }}?style=flat-square)](https://www.npmjs.com/package/{{ language.params.npmPackage }}) {% if sdk.twitterHandle %} -[![Twitter Account](https://img.shields.io/twitter/follow/{{ sdk.twitterHandle }}?color=00acee&label=twitter&style=flat-square)](https://twitter.com/{{ sdk.twitterHandle }}) +[![X Account](https://img.shields.io/badge/follow-%40{{ sdk.twitterHandle|replace({'-': '--', '_': '__'})|url_encode }}-000000?logo=x&style=flat-square)](https://x.com/{{ sdk.twitterHandle }}) {% endif %} {% if sdk.discordChannel %} [![Discord](https://img.shields.io/discord/{{ sdk.discordChannel }}?label=discord&style=flat-square)]({{ sdk.discordUrl }}) @@ -22,42 +22,59 @@ ## Installation -The {{ spec.info.title }} CLI is a command line tool to help you interact with the {{ spec.info.title }} API. The CLI is distributed both as an [`npm package`](https://www.npmjs.com/package/{{ spec.info.title|caseLower }}-cli) as well as [native binaries](https://github.com/{{ sdk.gitUserName|url_encode }}/{{ sdk.gitRepoName|url_encode }}/releases/latest) for specific operating systems and architectures. +The {{ spec.info.title }} CLI is a command line tool to help you interact with the {{ spec.info.title }} API. You can install it with [Homebrew](https://brew.sh), [`npm`](https://www.npmjs.com/package/{{ language.params.npmPackage }}), [Scoop](https://scoop.sh) or our install scripts, or download a [native binary](https://github.com/{{ sdk.gitUserName|url_encode }}/{{ sdk.gitRepoName|url_encode }}/releases/latest) for your operating system and architecture. -### Install using NPM ---- +### macOS and Linux -If you have `npm` installed, it's as easy as running +#### Homebrew -```sh -$ npm install -g {{ language.params.npmPackage }} +```bash +brew install {{ language.params.homebrewTapOwner }}/{{ language.params.homebrewTapName }}/{{ language.params.executableName }} ``` -Once the installation is complete, you can verify the install using +Homebrew pulls the formula from the [`{{ language.params.homebrewTapOwner }}/homebrew-{{ language.params.homebrewTapName }}`](https://github.com/{{ language.params.homebrewTapOwner }}/homebrew-{{ language.params.homebrewTapName }}) tap and downloads the native binary for your platform. -```sh -$ {{ language.params.executableName|caseLower }} -v -{{ sdk.version }} -``` +#### npm -### Install using prebuilt binaries ---- +```bash +npm install -g {{ language.params.npmPackage }} +``` -If you do not have `npm` installed, you can always install the prebuilt binaries for your architecture and OS using our convenient installation scripts. +#### Install script -### Linux / MacOS Terminal ```bash -$ wget -q {{ sdk.url }}/cli/install.sh -O - | /bin/bash +wget -q {{ sdk.url }}/cli/install.sh -O - | /bin/bash ``` -### MacOS / Linux via [Homebrew](https://brew.sh) +### Windows + +#### PowerShell + +```powershell +iwr -useb {{ sdk.url }}/cli/install.ps1 | iex +``` + +#### Scoop + +```powershell +scoop install https://raw.githubusercontent.com/{{ sdk.gitUserName }}/{{ sdk.gitRepoName|caseDash }}/master/scoop/appwrite.config.json +``` + +The npm package also works on Windows: + +```powershell +npm install -g {{ language.params.npmPackage }} +``` + +### Verify the installation + ```bash -$ brew install {{ language.params.homebrewTapOwner }}/{{ language.params.homebrewTapName }}/{{ language.params.executableName }} +{{ language.params.executableName|caseLower }} -v ``` -Homebrew pulls the formula from the [`{{ language.params.homebrewTapOwner }}/homebrew-{{ language.params.homebrewTapName }}`](https://github.com/{{ language.params.homebrewTapOwner }}/homebrew-{{ language.params.homebrewTapName }}) tap and downloads the native binary for your platform. +This prints the installed version, for example `{{ sdk.version }}`. -### Shell completion +## Shell completion Install completion for your current shell: @@ -65,36 +82,17 @@ Install completion for your current shell: {{ language.params.executableName|caseLower }} completion install ``` -You can also generate or install completion scripts manually: +You can also install completion for a specific shell: ```bash -# zsh {{ language.params.executableName|caseLower }} completion install zsh -# bash {{ language.params.executableName|caseLower }} completion install bash -# fish {{ language.params.executableName|caseLower }} completion install fish ``` For zsh, ensure `~/.zfunc` is in your `fpath` and `compinit` is loaded from your shell config. - -### Windows -Via Powershell -```powershell -$ iwr -useb {{ sdk.url }}/cli/install.ps1 | iex -``` -Via [Scoop](https://scoop.sh) -```powershell -$ scoop install https://raw.githubusercontent.com/{{ sdk.gitUserName }}/{{ sdk.gitRepoName | caseDash }}/master/scoop/appwrite.config.json -``` - -Once the installation completes, you can verify your install using -``` -$ {{ language.params.executableName|caseLower }} -v -{{ sdk.version }} -``` - {% if sdk.gettingStarted %} + {{ sdk.gettingStarted|raw }} {% endif %} @@ -151,35 +149,38 @@ Includes and resource paths are resolved relative to the chosen file. ## Contribution -This library is auto-generated by {{ spec.info.title | caseUcfirst }} custom [SDK Generator](https://github.com/{{ spec.info.title | lower }}/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/{{ spec.info.title | lower }}/sdk-generator/blob/master/CONTRIBUTING.md) before sending a pull-request. +This library is auto-generated by {{ spec.info.title|caseUcfirst }} custom [SDK Generator](https://github.com/{{ spec.info.title|lower }}/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/{{ spec.info.title|lower }}/sdk-generator/blob/main/CONTRIBUTING.md) before sending a pull request. -To build and test the CLI for development, follow these steps +To build and test the CLI for development: -1. Clone the SDK Generator repository and cd into the directory -```sh -$ git clone https://github.com/{{ spec.info.title | lower }}/sdk-generator -$ cd sdk-generator -``` +1. Clone the SDK Generator repository and change into it. -2. Ensure Docker is running locally and then install the composer dependencies using -```sh -$ docker run --rm --interactive --tty --volume "$(pwd)":/app composer install --ignore-platform-reqs --optimize-autoloader --no-plugins --no-scripts --prefer-dist + ```sh + git clone https://github.com/{{ spec.info.title|lower }}/sdk-generator + cd sdk-generator + ``` -# Generate the CLI -$ docker run --rm -v $(pwd):/app -w /app php:8.5-cli php example.php cli -``` +2. Make sure Docker is running, then install the Composer dependencies and generate the CLI. -3. Head over to the generated SDK and build it. -```sh -$ cd examples/cli -$ go mod tidy -$ go build -ldflags="-s -w" -o {{ language.params.executableName|caseLower }} . -``` + ```sh + docker run --rm --interactive --tty --volume "$(pwd)":/app composer install --ignore-platform-reqs --optimize-autoloader --no-plugins --no-scripts --prefer-dist + docker run --rm --volume "$(pwd)":/app --workdir /app php:8.5-cli php example.php cli + ``` + +3. Build the generated CLI. + + ```sh + cd examples/cli + go mod tidy + go build -ldflags="-s -w" -o {{ language.params.executableName|caseLower }} . + ``` + +4. Run the CLI. + + ```sh + ./{{ language.params.executableName|caseLower }} -v + ``` -4. You can now use the CLI -```sh -$ ./{{ language.params.executableName|caseLower }} -v -``` ## License -Please see the [{{spec.info.license.name}} license]({{spec.info.license.url}}) file for more information. +Please see the [{{ spec.info.license.name }} license](LICENSE.md) file for more information. diff --git a/templates/codex-plugin/README.md.twig b/templates/codex-plugin/README.md.twig index fd3107a2cb..6aa224a99e 100644 --- a/templates/codex-plugin/README.md.twig +++ b/templates/codex-plugin/README.md.twig @@ -1,121 +1,132 @@ -# {{ spec.info.title }} Codex CLI Plugin +{% set name = spec.info.title | caseLower %} +# {{ spec.info.title }} Codex Plugin -![License](https://img.shields.io/github/license/{{ sdk.gitUserName|url_encode }}/{{ sdk.gitRepoName|url_encode }}.svg?style=flat-square) -![Version](https://img.shields.io/badge/api%20version-{{ sdk.version }}-blue.svg?style=flat-square) -[![Twitter Account](https://img.shields.io/twitter/follow/appwrite?color=00acee&label=twitter&style=flat-square)](https://twitter.com/appwrite) -[![Discord](https://img.shields.io/discord/564160730845151244?label=discord&style=flat-square)](https://appwrite.io/discord) +![License](https://img.shields.io/badge/license-{{ spec.info.license.name|replace({'-': '--', '_': '__'})|url_encode }}-blue.svg?style=flat-square) +![Version](https://img.shields.io/badge/version-{{ sdk.version|url_encode }}-blue.svg?style=flat-square) +{% if sdk.twitterHandle %} +[![X Account](https://img.shields.io/badge/follow-%40{{ sdk.twitterHandle|replace({'-': '--', '_': '__'})|url_encode }}-000000?logo=x&style=flat-square)](https://x.com/{{ sdk.twitterHandle }}) +{% endif %} +{% if sdk.discordChannel %} +[![Discord](https://img.shields.io/discord/{{ sdk.discordChannel }}?label=discord&style=flat-square)]({{ sdk.discordUrl }}) +{% endif %} -{{ spec.info.title }} tools for the [OpenAI Codex CLI](https://github.com/openai/codex). This plugin packages {{ spec.info.title }} SDK skills, {{ spec.info.title }} deployment workflow skills, and the hosted {{ spec.info.title }} MCP server. +{{ spec.info.title }} tools for [Codex](https://github.com/openai/codex). This plugin packages {{ spec.info.title }} SDK skills, {{ spec.info.title }} deployment workflow skills, and the hosted {{ spec.info.title }} MCP server. -## Structure +## Installation -```text -plugins/{{ spec.info.title | caseLower }}/skills/ # Codex skills (auto-loaded by description match) -|-- {{ spec.info.title | caseLower }}-typescript/SKILL.md -|-- {{ spec.info.title | caseLower }}-dart/SKILL.md -|-- {{ spec.info.title | caseLower }}-kotlin/SKILL.md -|-- {{ spec.info.title | caseLower }}-swift/SKILL.md -|-- {{ spec.info.title | caseLower }}-php/SKILL.md -|-- {{ spec.info.title | caseLower }}-python/SKILL.md -|-- {{ spec.info.title | caseLower }}-ruby/SKILL.md -|-- {{ spec.info.title | caseLower }}-go/SKILL.md -|-- {{ spec.info.title | caseLower }}-rust/SKILL.md -|-- {{ spec.info.title | caseLower }}-dotnet/SKILL.md -|-- {{ spec.info.title | caseLower }}-cli/SKILL.md -|-- {{ spec.info.title | caseLower }}-deploy-site/SKILL.md -`-- {{ spec.info.title | caseLower }}-deploy-function/SKILL.md -plugins/{{ spec.info.title | caseLower }}/.codex-plugin/plugin.json # Codex plugin manifest -.agents/plugins/marketplace.json # Local marketplace manifest -plugins/{{ spec.info.title | caseLower }}/.mcp.json # MCP server config for plugin installs -plugins/{{ spec.info.title | caseLower }}/config.toml # MCP server config snippet for manual installs -``` +### From the OpenAI Curated marketplace -## Installation +1. Run `codex`, then run `/plugins`. +2. Switch to the **OpenAI Curated** marketplace. +3. Search for **{{ spec.info.title }}** and install the plugin. +4. Sign in to {{ spec.info.title }} and approve access when prompted, then start a new Codex session. -Codex plugins include a `.codex-plugin/plugin.json` manifest for plugin installation. For manual installs, Codex CLI loads skills from `~/.codex/skills/` and reads MCP server configuration from `~/.codex/config.toml`. Install the generated files manually by copying them into those locations. +The plugin can also be installed from **Plugins** in the ChatGPT desktop app. -To install through a local Codex marketplace, add this directory as a marketplace source using the generated `.agents/plugins/marketplace.json` file. +### From this repository -### macOS / Linux +Add this repository as a marketplace and install the plugin from it: ```sh -# Copy skills -mkdir -p ~/.codex/skills -cp -R plugins/{{ spec.info.title | caseLower }}/skills/* ~/.codex/skills/ - -# Append the MCP config snippet to your Codex config -mkdir -p ~/.codex -cat plugins/{{ spec.info.title | caseLower }}/config.toml >> ~/.codex/config.toml +codex plugin marketplace add {{ sdk.gitUserName }}/{{ sdk.gitRepoName }} +codex plugin add {{ name }}@{{ name }} ``` -### Windows (PowerShell) +Start a new Codex session to load the bundled skills. -```powershell -# Copy skills -New-Item -ItemType Directory -Force -Path "$HOME\.codex\skills" | Out-Null -Copy-Item -Recurse plugins\{{ spec.info.title | caseLower }}\skills\* "$HOME\.codex\skills\" +### Manual setup + +To use the skills and the MCP server without the plugin, copy the skills into your user skills folder and register the server. -# Append the MCP config snippet to your Codex config -New-Item -ItemType Directory -Force -Path "$HOME\.codex" | Out-Null -Get-Content plugins\{{ spec.info.title | caseLower }}\config.toml | Add-Content "$HOME\.codex\config.toml" +macOS / Linux: + +```sh +mkdir -p ~/.agents/skills +cp -R plugins/{{ name }}/skills/* ~/.agents/skills/ +codex mcp add {{ name }} --url https://mcp.appwrite.io/ ``` -## Included Skills +Windows (PowerShell): -Each skill ships as `plugins/{{ spec.info.title | caseLower }}/skills/{{ spec.info.title | caseLower }}-/SKILL.md`. Codex loads them based on the `description` field in the frontmatter, so they activate automatically when a session is about Appwrite work in that language: +```powershell +New-Item -ItemType Directory -Force -Path "$HOME\.agents\skills" | Out-Null +Copy-Item -Recurse plugins\{{ name }}\skills\* "$HOME\.agents\skills\" +codex mcp add {{ name }} --url https://mcp.appwrite.io/ +``` -- `{{ spec.info.title | caseLower }}-typescript` -- `{{ spec.info.title | caseLower }}-dart` -- `{{ spec.info.title | caseLower }}-kotlin` -- `{{ spec.info.title | caseLower }}-swift` -- `{{ spec.info.title | caseLower }}-php` -- `{{ spec.info.title | caseLower }}-python` -- `{{ spec.info.title | caseLower }}-ruby` -- `{{ spec.info.title | caseLower }}-go` -- `{{ spec.info.title | caseLower }}-rust` -- `{{ spec.info.title | caseLower }}-dotnet` -- `{{ spec.info.title | caseLower }}-cli` -- `{{ spec.info.title | caseLower }}-deploy-site` -- `{{ spec.info.title | caseLower }}-deploy-function` +Instead of `codex mcp add`, you can merge `plugins/{{ name }}/config.toml` into `~/.codex/config.toml`. -The language skills give Codex language-specific {{ spec.info.title }} context for authentication, database queries, storage, realtime, functions, and server-side administration. The deployment skills walk through {{ spec.info.title }} Sites and Functions deployment with the {{ spec.info.title }} CLI. +## Included skills -## Deployment Workflows +The plugin ships these skills under `plugins/{{ name }}/skills/`: -Deployment workflows are exposed as explicit skills: +- `{{ name }}-typescript` +- `{{ name }}-dart` +- `{{ name }}-kotlin` +- `{{ name }}-swift` +- `{{ name }}-php` +- `{{ name }}-python` +- `{{ name }}-ruby` +- `{{ name }}-go` +- `{{ name }}-rust` +- `{{ name }}-dotnet` +- `{{ name }}-cli` +- `deploy-site` +- `deploy-function` -- `${{ spec.info.title | caseLower }}-deploy-site` -- `${{ spec.info.title | caseLower }}-deploy-function` +The language skills give Codex language-specific {{ spec.info.title }} context for authentication, database queries, storage, realtime, functions, and server-side administration. The `deploy-site` and `deploy-function` skills walk through deploying {{ spec.info.title }} Sites and Functions with the {{ spec.info.title }} CLI. -Use these to walk through deploying {{ spec.info.title }} sites and functions with the {{ spec.info.title }} CLI. Codex can also load them automatically when a task matches the skill description. +Codex loads a skill when a task matches its `description`. To invoke one explicitly, type `$` or run `/skills` and pick it. -## Hosted MCP Server +## Hosted MCP server -The bundled plugin and `plugins/{{ spec.info.title | caseLower }}/config.toml` register one `{{ spec.info.title | caseLower }}` server at `https://mcp.appwrite.io/`. It provides tools for working with your {{ spec.info.title }} workspace and projects and for searching the latest {{ spec.info.title }} documentation. +The plugin registers one `{{ name }}` server at `https://mcp.appwrite.io/`. It provides tools for working with your {{ spec.info.title }} organizations and projects, and for searching the latest {{ spec.info.title }} documentation. -The hosted server uses browser-based OAuth, so no API key, project ID, endpoint, or other manually configured secret is required. After installing the plugin or merging the manual configuration, authenticate with: +The hosted server uses browser-based OAuth, so no API key, project ID, endpoint, or other manually configured secret is required. Codex asks you to sign in when you install the plugin. To sign in again, or after a manual setup, run: ```sh -codex mcp login {{ spec.info.title | caseLower }} +codex mcp login {{ name }} ``` Then try: > Use {{ spec.info.title }} to show my workspace context and list my projects. -If the browser does not open, use the authorization URL printed by Codex. Run `codex mcp logout {{ spec.info.title | caseLower }}` followed by `codex mcp login {{ spec.info.title | caseLower }}` to refresh the OAuth session, and use `codex mcp get {{ spec.info.title | caseLower }}` to inspect the server configuration and status. +If the browser does not open, use the authorization URL printed by Codex. Run `codex mcp logout {{ name }}` followed by `codex mcp login {{ name }}` to refresh the OAuth session, and `codex mcp list` to check that the server is configured. -## Verify +## Structure + +```text +.agents/plugins/marketplace.json # Marketplace manifest +plugins/{{ name }}/ +├── .codex-plugin/plugin.json # Plugin manifest +├── .mcp.json # MCP server config for plugin installs +├── config.toml # MCP server config for manual setup +└── skills/ + ├── {{ name }}-typescript/SKILL.md + ├── {{ name }}-dart/SKILL.md + ├── {{ name }}-kotlin/SKILL.md + ├── {{ name }}-swift/SKILL.md + ├── {{ name }}-php/SKILL.md + ├── {{ name }}-python/SKILL.md + ├── {{ name }}-ruby/SKILL.md + ├── {{ name }}-go/SKILL.md + ├── {{ name }}-rust/SKILL.md + ├── {{ name }}-dotnet/SKILL.md + ├── {{ name }}-cli/SKILL.md + ├── {{ name }}-deploy-site/SKILL.md + └── {{ name }}-deploy-function/SKILL.md +``` -After copying, run `codex` and check: +## Learn more -- A session about {{ spec.info.title }} TypeScript work loads the `{{ spec.info.title | caseLower }}-typescript` skill (visible in the session header). -- Typing `$` lets you invoke the `{{ spec.info.title | caseLower }}-deploy-*` skills explicitly. -- `codex mcp list` (or `codex --debug`) lists the `{{ spec.info.title | caseLower }}` server. +- [{{ spec.info.title }} in Codex](https://appwrite.io/docs/tooling/ai/agents/codex) +- [{{ spec.info.title }} MCP server](https://appwrite.io/docs/tooling/ai/mcp-servers) +- [Codex plugins documentation](https://learn.chatgpt.com/docs/plugins) ## Contribution -This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/master/CONTRIBUTING.md) before sending a pull-request. +This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/main/CONTRIBUTING.md) before sending a pull-request. ## License diff --git a/templates/codex-plugin/plugin.json.twig b/templates/codex-plugin/plugin.json.twig index c4492f8f7f..089d548486 100644 --- a/templates/codex-plugin/plugin.json.twig +++ b/templates/codex-plugin/plugin.json.twig @@ -7,7 +7,7 @@ "email": "team@appwrite.io", "url": "https://appwrite.io" }, - "homepage": "https://appwrite.io/docs/tooling/ai/ai-dev-tools/codex", + "homepage": "https://appwrite.io/docs/tooling/ai/agents/codex", "repository": "https://github.com/{{ sdk.gitUserName }}/{{ sdk.gitRepoName }}", "license": "{{ spec.info.license.name }}", "keywords": [ diff --git a/templates/cursor-plugin/README.md.twig b/templates/cursor-plugin/README.md.twig index ba85dcd065..1e7637e626 100644 --- a/templates/cursor-plugin/README.md.twig +++ b/templates/cursor-plugin/README.md.twig @@ -1,54 +1,47 @@ -# {{ spec.info.title }} {{ sdk.name | caseSpace }} +{% set languages = {'typescript': 'TypeScript', 'dart': 'Dart', 'kotlin': 'Kotlin', 'swift': 'Swift', 'php': 'PHP', 'python': 'Python', 'ruby': 'Ruby', 'go': 'Go', 'rust': 'Rust', 'dotnet': '.NET', 'cli': 'CLI'} %} +# {{ spec.info.title }} Cursor Plugin -![License](https://img.shields.io/github/license/{{ sdk.gitUserName|url_encode }}/{{ sdk.gitRepoName|url_encode }}.svg?style=flat-square) +![License](https://img.shields.io/badge/license-{{ spec.info.license.name|replace({'-': '--', '_': '__'})|url_encode }}-blue.svg?style=flat-square) ![Version](https://img.shields.io/badge/api%20version-{{ spec.info.version|url_encode }}-blue.svg?style=flat-square) {% if sdk.twitterHandle %} -[![Twitter Account](https://img.shields.io/twitter/follow/{{ sdk.twitterHandle }}?color=00acee&label=twitter&style=flat-square)](https://twitter.com/{{ sdk.twitterHandle }}) +[![X Account](https://img.shields.io/badge/follow-%40{{ sdk.twitterHandle|replace({'-': '--', '_': '__'})|url_encode }}-000000?logo=x&style=flat-square)](https://x.com/{{ sdk.twitterHandle }}) {% endif %} {% if sdk.discordChannel %} [![Discord](https://img.shields.io/discord/{{ sdk.discordChannel }}?label=discord&style=flat-square)]({{ sdk.discordUrl }}) {% endif %} -{% if sdk.warning %} -{{ sdk.warning|raw }} -{% endif %} - -{{ sdk.description }} +{{ spec.info.title }} tools for Cursor. This plugin packages {{ spec.info.title }} SDK skills, the hosted {{ spec.info.title }} MCP server, and deployment commands. ## Installation -Install this plugin in Cursor by adding the plugin directory to your project or Cursor plugins folder. +Install the plugin from the [Cursor Marketplace](https://cursor.com/marketplace/appwrite): -## Structure +1. Open **Customize** in the Cursor sidebar. +2. Search for **{{ spec.info.title }}**. +3. Select **Install** and choose a project or user scope. -{% set languages = ['typescript', 'dart', 'kotlin', 'swift', 'php', 'python', 'ruby', 'go', 'rust', 'dotnet'] %} -``` -.cursor-plugin/ -└── plugin.json # Plugin manifest -skills/ # Agent skills (per language) -{% for lang in languages %} -├── {{ spec.info.title | caseLower }}-{{ lang }}/ -│ └── SKILL.md -{% endfor %} -commands/ # Agent-executable commands -├── deploy-site.md -└── deploy-function.md -.mcp.json # Hosted Appwrite MCP server -``` +To try a local copy instead, clone this repository into `~/.cursor/plugins/local/{{ spec.info.title | caseLower }}` and run **Developer: Reload Window**. A marketplace install with the same plugin name takes precedence over the local copy. ## Skills -This plugin includes {{ spec.info.title }} SDK skills for the following languages: +The plugin includes {{ spec.info.title }} skills for the following languages and tools: -{% for lang in languages %} -- **{{ lang | capitalize }}** — `skills/{{ spec.info.title | caseLower }}-{{ lang }}/SKILL.md` +{% for lang, label in languages %} +- **{{ label }}**: `{{ spec.info.title | caseLower }}-{{ lang }}` {% endfor %} -Each skill provides comprehensive SDK usage examples including authentication, database operations, file storage, real-time subscriptions, and more. +Each skill gives the agent {{ spec.info.title }} context for authentication, database operations, file storage, realtime subscriptions, functions, and more. Cursor loads a skill when a task matches its description. + +## Commands + +Agent-executable commands for deploying from your editor: -## Hosted MCP Server +- **deploy-site**: Deploy an {{ spec.info.title }} site with the {{ spec.info.title }} CLI. Covers init, push, non-interactive CI/CD mode, site management, variables, and logs. +- **deploy-function**: Deploy an {{ spec.info.title }} function with the {{ spec.info.title }} CLI. Covers init, push, non-interactive CI/CD mode, function management, executions, variables, and local development. -This plugin configures the hosted {{ spec.info.title }} MCP server at `https://mcp.appwrite.io/`. It gives Cursor access to your {{ spec.info.title }} workspace and projects as well as the latest {{ spec.info.title }} documentation. +## Hosted MCP server + +The plugin configures the hosted {{ spec.info.title }} MCP server at `https://mcp.appwrite.io/` under the name `{{ spec.info.title | caseLower }}`. It gives Cursor access to your {{ spec.info.title }} organizations and projects, and to the latest {{ spec.info.title }} documentation. Cursor starts a browser-based OAuth flow when the server first connects. Sign in to {{ spec.info.title }} and approve access; no API key, project ID, endpoint, or other secret needs to be added to `.mcp.json`. @@ -56,23 +49,37 @@ After authentication, try: > Use {{ spec.info.title }} to show my workspace context and list my projects. -If the server does not connect, open Cursor's MCP settings, restart the `{{ spec.info.title | caseLower }}` server, and complete the sign-in prompt. Clear or reauthenticate the server from the same settings when the OAuth session expires, and inspect Cursor's MCP output logs for connection errors. - -## Commands - -Agent-executable commands for deploying directly from your editor: +If the server does not connect, open **Customize**, turn the `{{ spec.info.title | caseLower }}` MCP server off and on again, and complete the sign-in prompt. Do the same when the OAuth session expires, and check Cursor's MCP output logs for connection errors. -- **deploy-site** — Deploy an {{ spec.info.title }} site using the CLI. Covers init, push, CI/CD non-interactive mode, site management, variables, and logs. -- **deploy-function** — Deploy an {{ spec.info.title }} function using the CLI. Covers init, push, CI/CD non-interactive mode, function management, executions, variables, and local development. +## Structure +```text +.cursor-plugin/ +└── plugin.json # Plugin manifest +skills/ # Agent skills +{% for lang in languages|keys %} +{{ loop.last ? '└──' : '├──' }} {{ spec.info.title | caseLower }}-{{ lang }}/ +{{ loop.last ? ' ' : '│' }} └── SKILL.md +{% endfor %} +commands/ # Agent-executable commands +├── deploy-site.md +└── deploy-function.md +.mcp.json # Hosted {{ spec.info.title }} MCP server +``` {% if sdk.gettingStarted %} -{{ sdk.gettingStarted|raw }} +{{ sdk.gettingStarted|trim|raw }} {% endif %} +## Learn more + +- [{{ spec.info.title }} in Cursor](https://appwrite.io/docs/tooling/ai/agents/cursor) +- [{{ spec.info.title }} MCP server](https://appwrite.io/docs/tooling/ai/mcp-servers) +- [Cursor plugins documentation](https://cursor.com/docs/plugins) + ## Contribution -This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/master/CONTRIBUTING.md) before sending a pull-request. +This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/main/CONTRIBUTING.md) before sending a pull-request. ## License diff --git a/templates/dart/README.md.twig b/templates/dart/README.md.twig index a4de613f16..60996940e7 100644 --- a/templates/dart/README.md.twig +++ b/templates/dart/README.md.twig @@ -1,11 +1,10 @@ # {{ spec.info.title }} {{sdk.name}} SDK [![pub package](https://img.shields.io/pub/v/{{ language.params.packageName }}.svg?style=flat-square)](https://pub.dartlang.org/packages/{{ language.params.packageName }}) -![License](https://img.shields.io/github/license/{{ sdk.gitUserName|url_encode }}/{{ sdk.gitRepoName|url_encode }}.svg?style=flat-square) +![License](https://img.shields.io/badge/license-{{ spec.info.license.name|replace({'-': '--', '_': '__'})|url_encode }}-blue.svg?style=flat-square) ![Version](https://img.shields.io/badge/api%20version-{{spec.info.version | split('.') | slice(0,2) | join('.') ~ '.x' | url_encode}}-blue.svg?style=flat-square) -[![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator) {% if sdk.twitterHandle %} -[![Twitter Account](https://img.shields.io/twitter/follow/{{ sdk.twitterHandle }}?color=00acee&label=twitter&style=flat-square)](https://twitter.com/{{ sdk.twitterHandle }}) +[![X Account](https://img.shields.io/badge/follow-%40{{ sdk.twitterHandle|replace({'-': '--', '_': '__'})|url_encode }}-000000?logo=x&style=flat-square)](https://x.com/{{ sdk.twitterHandle }}) {% endif %} {% if sdk.discordChannel %} [![Discord](https://img.shields.io/discord/{{ sdk.discordChannel }}?label=discord&style=flat-square)]({{ sdk.discordUrl }}) @@ -23,28 +22,26 @@ ## Installation -Add this to your package's `pubspec.yaml` file: +Add the package from the command line: -```yml -dependencies: - {{ language.params.packageName }}: ^{{sdk.version}} +```bash +dart pub add {{ language.params.packageName }} ``` -You can install packages from the command line: +Or add it to your package's `pubspec.yaml` file and run `dart pub get`: -```bash -dart pub add {{ language.params.packageName }} +```yaml +dependencies: + {{ language.params.packageName }}: ^{{sdk.version}} ``` {% if sdk.gettingStarted %} - {{ sdk.gettingStarted|raw }} {% endif %} - ## Contribution -This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/master/CONTRIBUTING.md) before sending a pull-request. +This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/main/CONTRIBUTING.md) before sending a pull-request. ## License -Please see the [{{spec.info.license.name}} license]({{spec.info.license.url}}) file for more information. \ No newline at end of file +Please see the [{{spec.info.license.name}} license]({{spec.info.license.url}}) file for more information. diff --git a/templates/deno/README.md.twig b/templates/deno/README.md.twig index ce631e0c47..f39cc82991 100644 --- a/templates/deno/README.md.twig +++ b/templates/deno/README.md.twig @@ -1,10 +1,9 @@ # {{ spec.info.title }} {{sdk.name}} SDK -![License](https://img.shields.io/github/license/{{ sdk.gitUserName|url_encode }}/{{ sdk.gitRepoName|url_encode }}.svg?style=flat-square) +![License](https://img.shields.io/badge/license-{{ spec.info.license.name|replace({'-': '--', '_': '__'})|url_encode }}-blue.svg?style=flat-square) ![Version](https://img.shields.io/badge/api%20version-{{ spec.info.version|url_encode }}-blue.svg?style=flat-square) -[![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator) {% if sdk.twitterHandle %} -[![Twitter Account](https://img.shields.io/twitter/follow/{{ sdk.twitterHandle }}?color=00acee&label=twitter&style=flat-square)](https://twitter.com/{{ sdk.twitterHandle }}) +[![X Account](https://img.shields.io/badge/follow-%40{{ sdk.twitterHandle|replace({'-': '--', '_': '__'})|url_encode }}-000000?logo=x&style=flat-square)](https://x.com/{{ sdk.twitterHandle }}) {% endif %} {% if sdk.discordChannel %} [![Discord](https://img.shields.io/discord/{{ sdk.discordChannel }}?label=discord&style=flat-square)]({{ sdk.discordUrl }}) diff --git a/templates/dotnet/README.md.twig b/templates/dotnet/README.md.twig index bfa8795933..c52c536e81 100644 --- a/templates/dotnet/README.md.twig +++ b/templates/dotnet/README.md.twig @@ -1,10 +1,9 @@ # {{ spec.info.title }} {{sdk.name}} SDK -![License](https://img.shields.io/github/license/{{ sdk.gitUserName|url_encode }}/{{ sdk.gitRepoName|url_encode }}.svg?style=flat-square) +![License](https://img.shields.io/badge/license-{{ spec.info.license.name|replace({'-': '--', '_': '__'})|url_encode }}-blue.svg?style=flat-square) ![Version](https://img.shields.io/badge/api%20version-{{ spec.info.version|url_encode }}-blue.svg?style=flat-square) -[![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator) {% if sdk.twitterHandle %} -[![Twitter Account](https://img.shields.io/twitter/follow/{{ sdk.twitterHandle }}?color=00acee&label=twitter&style=flat-square)](https://twitter.com/{{ sdk.twitterHandle }}) +[![X Account](https://img.shields.io/badge/follow-%40{{ sdk.twitterHandle|replace({'-': '--', '_': '__'})|url_encode }}-000000?logo=x&style=flat-square)](https://x.com/{{ sdk.twitterHandle }}) {% endif %} {% if sdk.discordChannel %} [![Discord](https://img.shields.io/discord/{{ sdk.discordChannel }}?label=discord&style=flat-square)]({{ sdk.discordUrl }}) @@ -22,52 +21,33 @@ ## Installation -### .NET -Add this reference to your project's `.csproj` file: +The package targets .NET Standard 2.0 and .NET Framework 4.6.2, so it runs on .NET 5 or later, .NET Core 2.0 or later, and .NET Framework 4.6.2 or later. -```xml - +Install it with the .NET CLI: + +```bash +dotnet add package {{ spec.info.title | caseUcfirst }} --version {{ sdk.version }} ``` -You can install packages from the command line: +Or with the Package Manager Console: ```powershell -# Package Manager Install-Package {{ spec.info.title | caseUcfirst }} -Version {{ sdk.version }} - -# or .NET CLI -dotnet add package {{ spec.info.title | caseUcfirst }} --version {{ sdk.version }} ``` -{% if sdk.gettingStarted %} - -{{ sdk.gettingStarted|raw }} -{% endif %} - -### Preparing Models for Databases API - -For the .NET SDK, we use the `System.Text.Json` library for serialization/deserialization support. The default behavior converts property names from `PascalCase` to `camelCase` on serializing to JSON. In case the names of attributes in your Appwrite collection are not created in `camelCase`, this serializer behavior can cause errors due to mismatches in the names in the serialized JSON and the actual attribute names in your collection. - -The way to fix this is to add the `JsonPropertyName` attribute to the properties in the POCO class you create for your model. - -For e.g., if you have two attributes, `name` (`string` type) and `release_date` (`DateTime` type), your POCO class would be created as follows: - -```csharp -public class TestModel -{ - [JsonPropertyName("name")] - public string Name { get; set; } +Or add a reference to your project's `.csproj` file: - [JsonPropertyName("release_date")] - public DateTime ReleaseDate { get; set; } -} +```xml + ``` +{% if sdk.gettingStarted %} -The `JsonPropertyName` attribute will ensure that your data object for the Appwrite database is serialized with the correct names. +{{ sdk.gettingStarted|trim|raw }} +{% endif %} ## Contribution -This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/master/CONTRIBUTING.md) before sending a pull-request. +This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/main/CONTRIBUTING.md) before sending a pull-request. ## License diff --git a/templates/flutter/README.md.twig b/templates/flutter/README.md.twig index 91e0487ab6..bcc66b70ac 100644 --- a/templates/flutter/README.md.twig +++ b/templates/flutter/README.md.twig @@ -1,11 +1,10 @@ # {{ spec.info.title }} {{sdk.name}} SDK [![pub package](https://img.shields.io/pub/v/{{ language.params.packageName }}?style=flat-square)](https://pub.dartlang.org/packages/{{ language.params.packageName }}) -![License](https://img.shields.io/github/license/{{ sdk.gitUserName|url_encode }}/{{ sdk.gitRepoName|url_encode }}.svg?style=flat-square) +![License](https://img.shields.io/badge/license-{{ spec.info.license.name|replace({'-': '--', '_': '__'})|url_encode }}-blue.svg?style=flat-square) ![Version](https://img.shields.io/badge/api%20version-{{spec.info.version | split('.') | slice(0,2) | join('.') ~ '.x' | url_encode}}-blue.svg?style=flat-square) -[![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator) {% if sdk.twitterHandle %} -[![Twitter Account](https://img.shields.io/twitter/follow/{{ sdk.twitterHandle }}?color=00acee&label=twitter&style=flat-square)](https://twitter.com/{{ sdk.twitterHandle }}) +[![X Account](https://img.shields.io/badge/follow-%40{{ sdk.twitterHandle|replace({'-': '--', '_': '__'})|url_encode }}-000000?logo=x&style=flat-square)](https://x.com/{{ sdk.twitterHandle }}) {% endif %} {% if sdk.discordChannel %} [![Discord](https://img.shields.io/discord/{{ sdk.discordChannel }}?label=discord&style=flat-square)]({{ sdk.discordUrl }}) @@ -23,25 +22,22 @@ ## Installation -Add this to your package's `pubspec.yaml` file: +Add the package from the command line: -```yml -dependencies: - {{ language.params.packageName }}: ^{{sdk.version}} +```bash +flutter pub add {{ language.params.packageName }} ``` -You can install packages from the command line: +Or add it to your app's `pubspec.yaml` file and run `flutter pub get`: -```bash -flutter pub add {{ language.params.packageName }} +```yaml +dependencies: + {{ language.params.packageName }}: ^{{sdk.version}} ``` -### Push on Android +### Android requirements -`Push` includes a native Android plugin, so the SDK needs Android 7.0 (API 24) or later: apps -with a lower `minSdk` fail to build until they raise it. `flutter_local_notifications` also needs -core library desugaring. Add both to `android/app/build.gradle.kts` (desugaring is configured when -the app is assembled, so a plugin cannot apply it for you): +The SDK includes a native Android plugin, so it needs Android 7.0 (API 24) or later, and `flutter_local_notifications` needs core library desugaring. Apps with a lower `minSdk` or without desugaring fail to build. Desugaring is configured when the app is assembled, so a plugin cannot apply it for you. Add both to `android/app/build.gradle.kts`: ```kotlin android { @@ -58,81 +54,66 @@ dependencies { } ``` -A subscription with `background: true` keeps delivering after the app is backgrounded, killed or -the device restarts, until it is unsubscribed or `push.close()` is called (do this on sign-out). -The plugin saves the subscription, and a scheduled job and alarm wake the app every 15 to 60 -seconds to reconnect; the broker replays what was sent in between (`retry: true`). While the app -is not on screen, each message is posted as a notification that opens the app. It reconnects with the -credential saved at subscribe time, so use a session rather than a short-lived JWT. +{% if sdk.gettingStarted %} +{{ sdk.gettingStarted|raw }} +{% endif %} +## Push -On Android 13 and later, the first background subscription asks the user for the -`POST_NOTIFICATIONS` runtime permission. If they decline, the subscription still delivers to your -callback but posts no notification. Notifications show the title, body and image sent with -`createPush`, falling back to the subscription's `title` when only a body is sent. A push with no -title or body, such as a data-only push, posts no notification and reaches your callback only. -Messages that are not a JSON object show the subscription's `title` with the raw payload as body. +`Push` delivers messages from Appwrite to your app over a persistent connection, without FCM or APNs. Subscribe to one or more topics and handle each message in a callback: -Notifications are posted while the app is backgrounded or closed. While it is on screen your -callback shows the message, so none is posted unless the subscription passes -`notifyInForeground: true`. +```dart +final push = Push(client); + +final subscription = await push.subscribe('news', (message) { + print('${message.topic}: ${message.data}'); +}); + +subscription.unsubscribe(); +``` + +### Background delivery on Android + +A subscription with `background: true` keeps delivering after the app is backgrounded, killed or the device restarts, until it is unsubscribed or `push.close()` is called (do this on sign-out). The plugin saves the subscription, and a scheduled job and alarm wake the app every 15 to 60 seconds to reconnect; the broker replays what was sent in between (`retry: true`). While the app is not on screen, each message is posted as a notification that opens the app. It reconnects with the credential saved at subscribe time, so use a session rather than a short-lived JWT. + +On Android 13 and later, the first background subscription asks the user for the `POST_NOTIFICATIONS` runtime permission. If they decline, the subscription still delivers to your callback but posts no notification. Notifications show the title, body and image sent with `createPush`, falling back to the subscription's `title` when only a body is sent. A push with no title or body, such as a data-only push, posts no notification and reaches your callback only. Messages that are not a JSON object show the subscription's `title` with the raw payload as body. + +Notifications are posted while the app is backgrounded or closed. While it is on screen your callback shows the message, so none is posted unless the subscription passes `notifyInForeground: true`. ```dart -final sub = await push.subscribe('news', (message) => print(message.data), - background: true, title: 'News'); +final subscription = await push.subscribe( + 'news', + (message) => print(message.data), + background: true, + title: 'News', +); // Optional: immediate delivery even after a kill and during Doze, with a quiet ongoing // notification (call while the app is in the foreground). await push.setForeground(true); ``` -Foreground mode runs a `remoteMessaging` foreground service, which Google Play asks apps to -declare in the Play Console. Apps that never enable it can remove the service from their merged -manifest with `tools:node="remove"` on `io.{{ spec.info.title | caseLower }}.flutter.services.PushService` and -`android.permission.FOREGROUND_SERVICE_REMOTE_MESSAGING`. +Foreground mode runs a `remoteMessaging` foreground service, which Google Play asks apps to declare in the Play Console. Apps that never enable it can remove the service from their merged manifest with `tools:node="remove"` on `io.{{ spec.info.title | caseLower }}.flutter.services.PushService` and `android.permission.FOREGROUND_SERVICE_REMOTE_MESSAGING`. + +Set the notification icon with `` in your ``; without it a generic icon is used. #### Delivery while the app is closed -Messages sent while the app is closed arrive at the next scheduled wake-up. While the device is -awake that is about every 15 seconds, or about every 60 seconds once exact alarms are allowed; -without exact alarms the wake-ups are inexact, so battery saver can defer them further. In Doze -(screen off and idle for a while) Android limits background alarms, exact ones included, to about -one every nine minutes, so a closed app can take several minutes to receive a message: allowing -exact alarms makes wake-ups punctual, it does not lift Doze. For immediate delivery, also in -Doze, use `push.setForeground(true)` (see above). +Messages sent while the app is closed arrive at the next scheduled wake-up. While the device is awake that is about every 15 seconds, or about every 60 seconds once exact alarms are allowed; without exact alarms the wake-ups are inexact, so battery saver can defer them further. In Doze (screen off and idle for a while) Android limits background alarms, exact ones included, to about one every nine minutes, so a closed app can take several minutes to receive a message: allowing exact alarms makes wake-ups punctual, it does not lift Doze. For immediate delivery, also in Doze, use `push.setForeground(true)` (see above). The SDK uses exact alarms on its own whenever the app may schedule them. To allow it: -1. Declare the permissions in your app's `AndroidManifest.xml`. Both are optional and subject to - Google Play policy: `SCHEDULE_EXACT_ALARM` needs a declaration in the Play Console, and - `USE_EXACT_ALARM` is reserved for alarm, clock and calendar apps (the SDK does not use it). +1. Declare the permissions in your app's `AndroidManifest.xml`. Both are optional and subject to Google Play policy: `SCHEDULE_EXACT_ALARM` needs a declaration in the Play Console, and `USE_EXACT_ALARM` is reserved for alarm, clock and calendar apps (the SDK does not use it). ```xml ``` -2. On Android 13 and later the user has to allow exact alarms, under Settings > Apps > Special app - access > Alarms & reminders. Android 12 grants a declared `SCHEDULE_EXACT_ALARM` - automatically, and older versions need nothing. Check with `await push.backgroundStatus()`: when `bestEffort` is - true, explain why to the user, then from a user action open that screen with `push.requestExactAlarms()`, or - ask for the battery-optimisation exemption with `push.requestIgnoreBatteryOptimizations()`. Both return false when there is - nothing to ask, including when the permission is not declared. The SDK never opens these - screens on its own. - -If `backgroundRestricted` is true, the user restricted the app's background usage and messages can -wait until the app is opened. Exact alarms don't lift it, and neither does foreground mode: Android -stops a restricted app's foreground service once it leaves the screen. Ask the user to choose -Unrestricted in the app's battery settings (Settings > Apps > your app > Battery); granting the -battery optimisation exemption also lets the SDK's alarms and jobs run, and `bestEffort` then -reflects only the exact-alarm state. It is always false below Android 9. - -If the user force-stops the app (Settings > Force stop, and on some devices swiping it away from -recents), Android cancels its alarms and jobs: nothing is delivered until the app is opened -again, and the broker then replays what was sent meanwhile. - -Set the notification icon with -`` in your -``; without it a generic icon is used. +2. On Android 13 and later the user has to allow exact alarms, under Settings > Apps > Special app access > Alarms & reminders. Android 12 grants a declared `SCHEDULE_EXACT_ALARM` automatically, and older versions need nothing. Check with `await push.backgroundStatus()`: when `bestEffort` is true, explain why to the user, then from a user action open that screen with `push.requestExactAlarms()`, or ask for the battery-optimisation exemption with `push.requestIgnoreBatteryOptimizations()`. Both return false when there is nothing to ask, including when the permission is not declared. The SDK never opens these screens on its own. + +If `backgroundRestricted` is true, the user restricted the app's background usage and messages can wait until the app is opened. Exact alarms don't lift it, and neither does foreground mode: Android stops a restricted app's foreground service once it leaves the screen. Ask the user to choose Unrestricted in the app's battery settings (Settings > Apps > your app > Battery); granting the battery optimisation exemption also lets the SDK's alarms and jobs run, and `bestEffort` then reflects only the exact-alarm state. It is always false below Android 9. + +If the user force-stops the app (Settings > Force stop, and on some devices swiping it away from recents), Android cancels its alarms and jobs: nothing is delivered until the app is opened again, and the broker then replays what was sent meanwhile. ### Opening a tapped notification @@ -147,18 +128,12 @@ if (opened != null) openSale(opened.data['saleId']); final stop = push.onNotificationOpened((opened) => openSale(opened.data['saleId'])); ``` -On Android the SDK's native plugin reports the taps, on iOS `flutter_local_notifications`, and -on the web the notification's click while the page is open. - -{% if sdk.gettingStarted %} - -{{ sdk.gettingStarted|raw }} -{% endif %} +On Android the SDK's native plugin reports the taps, on iOS `flutter_local_notifications`, and on the web the notification's click while the page is open. ## Contribution -This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/master/CONTRIBUTING.md) before sending a pull-request. +This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/main/CONTRIBUTING.md) before sending a pull-request. ## License -Please see the [{{spec.info.license.name}} license]({{spec.info.license.url}}) file for more information. \ No newline at end of file +Please see the [{{spec.info.license.name}} license]({{spec.info.license.url}}) file for more information. diff --git a/templates/go/README.md.twig b/templates/go/README.md.twig index 3a7bc49517..2f5df70b73 100644 --- a/templates/go/README.md.twig +++ b/templates/go/README.md.twig @@ -1,10 +1,9 @@ # {{ spec.info.title }} {{sdk.name}} SDK -![License](https://img.shields.io/github/license/{{ sdk.gitUserName|url_encode }}/{{ sdk.gitRepoName|url_encode }}.svg?style=flat-square) +![License](https://img.shields.io/badge/license-{{ spec.info.license.name|replace({'-': '--', '_': '__'})|url_encode }}-blue.svg?style=flat-square) ![Version](https://img.shields.io/badge/api%20version-{{ spec.info.version|url_encode }}-blue.svg?style=flat-square) -[![Build Status](https://img.shields.io/travis/com/{{ sdk.gitUserName|url_encode }}/sdk-generator?style=flat-square)](https://travis-ci.com/{{ sdk.gitUserName|url_encode }}/sdk-generator) {% if sdk.twitterHandle %} -[![Twitter Account](https://img.shields.io/twitter/follow/{{ sdk.twitterHandle }}?color=00acee&label=twitter&style=flat-square)](https://twitter.com/{{ sdk.twitterHandle }}) +[![X Account](https://img.shields.io/badge/follow-%40{{ sdk.twitterHandle|replace({'-': '--', '_': '__'})|url_encode }}-000000?logo=x&style=flat-square)](https://x.com/{{ sdk.twitterHandle }}) {% endif %} {% if sdk.discordChannel %} [![Discord](https://img.shields.io/discord/{{ sdk.discordChannel }}?label=discord&style=flat-square)]({{ sdk.discordUrl }}) @@ -22,92 +21,120 @@ ## Installation -Initialize your go module if you haven't already: +Add the SDK to your Go module: ```bash -go mod init +go get {{ sdk | goPackagePath }} ``` -To install using `go get`: +If you don't have a module yet, create one first with `go mod init `. -```bash -go get {{ sdk | goPackagePath }} +{% if sdk.gettingStarted %} +{{ sdk.gettingStarted|trim|raw }} +{% else %} +## Getting Started + +### Init your SDK + +Create a client with your Appwrite API endpoint, project ID and an API key. You can find the project ID in your project settings, and create an API key with the scopes you need in your project's API keys section. + +```go +client := appwrite.NewClient( + appwrite.WithEndpoint("https://.cloud.appwrite.io/v1"), + appwrite.WithProject(""), + appwrite.WithKey(""), +) ``` -## Testing the SDK +If you self-host Appwrite, use your own endpoint, such as `https:///v1`. Add `appwrite.WithSelfSigned(true)` only in development, when your server uses a self-signed certificate. -* Clone this repo. -* Create a project and within this project a collection. -* Configure the documents in the collection to have a attribute `key` = `hello`. -* Then inject these environment variables: +### Make your first request - ```bash - export YOUR_ENDPOINT=https://.cloud.{{ sdk.gitUserName|url_encode }}.io/v1 - export YOUR_PROJECT_ID=616a09..0180 - export YOUR_KEY=7055781..cd95 - export DATABASE_ID=616a09..0180 - export COLLECTION_ID=616a09..20180 - ``` +Create a service from the client and call any of its methods. Required parameters are positional; optional parameters are passed with the service's `With` options. -* Create `main.go` file with: +```go +package main - ```go - package main +import ( + "fmt" + "log" - import ( - "log" - "os" - "time" + "{{ sdk | goPackagePath }}/appwrite" + "{{ sdk | goPackagePath }}/id" +) - "{{ sdk | goPackagePath }}/appwrite" - "{{ sdk | goPackagePath }}/id" +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://.cloud.appwrite.io/v1"), + appwrite.WithProject(""), + appwrite.WithKey(""), ) - func main() { - client := appwrite.NewClient( - appwrite.WithEndpoint(os.Getenv("YOUR_ENDPOINT")), - appwrite.WithProject(os.Getenv("YOUR_PROJECT_ID")), - appwrite.WithKey(os.Getenv("YOUR_KEY")), - ) + users := appwrite.NewUsers(client) - databases := appwrite.NewDatabases(client) + user, err := users.Create( + id.Unique(), + users.WithCreateEmail("email@example.com"), + users.WithCreatePassword("password"), + users.WithCreateName("Walter O'Brien"), + ) + if err != nil { + log.Fatal(err) + } - data := map[string]interface{}{ - "hello": "world", - } - doc, err := databases.CreateDocument( - os.Getenv("DATABASE_ID"), - os.Getenv("COLLECTION_ID"), - id.Unique(), - data, - ) - if err != nil { - log.Printf("Error creating document: %v", err) - } + fmt.Println(user.Id, user.Name, user.Email) +} +``` - log.Printf("Created document: %v", doc) - } - ``` +### Error handling -* After that, run the following +Failed requests return a `*client.AppwriteError` with the HTTP status code, the error message and the raw response body. Use `errors.As` to read them. - ```bash - go run main.go - ``` +```go +package main -* You should see the following output: +import ( + "errors" + "fmt" + "log" - ```bash - 2021/10/16 03:41:17 Created document: map[$collection:616a095b20180 $id:616a2dbd4df16 $permissions:map[read:[] write:[]] hello:world] - ``` + "{{ sdk | goPackagePath }}/appwrite" + "{{ sdk | goPackagePath }}/client" + "{{ sdk | goPackagePath }}/id" +) -{% if sdk.gettingStarted %} -{{ sdk.gettingStarted|raw }} +func main() { + users := appwrite.NewUsers(appwrite.NewClient( + appwrite.WithEndpoint("https://.cloud.appwrite.io/v1"), + appwrite.WithProject(""), + appwrite.WithKey(""), + )) + + user, err := users.Create(id.Unique(), users.WithCreateEmail("email@example.com")) + if err != nil { + var appwriteError *client.AppwriteError + if errors.As(err, &appwriteError) { + log.Fatalf("Appwrite error %d: %s", appwriteError.GetStatusCode(), appwriteError.GetMessage()) + } + log.Fatal(err) + } + + fmt.Println(user.Name) +} +``` + +### Learn more + +- [Go quick start](https://appwrite.io/docs/quick-starts/go) +- [Go API reference](https://appwrite.io/docs/references/cloud/server-go) +- [Package documentation](https://pkg.go.dev/{{ sdk | goPackagePath }}) +- [Appwrite docs](https://appwrite.io/docs) +- [Discord community](https://appwrite.io/discord) {% endif %} ## Contribution -This library is auto-generated by {{ spec.info.title }} custom [SDK Generator](https://github.com/{{ sdk.gitUserName|url_encode }}/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/{{ sdk.gitUserName|url_encode }}/sdk-generator/blob/master/CONTRIBUTING.md) before sending a pull-request. +This library is auto-generated by {{ spec.info.title }} custom [SDK Generator](https://github.com/{{ sdk.gitUserName|url_encode }}/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/{{ sdk.gitUserName|url_encode }}/sdk-generator/blob/main/CONTRIBUTING.md) before sending a pull-request. ## License diff --git a/templates/kotlin/README.md.twig b/templates/kotlin/README.md.twig index 1b266ab007..8f846a53d4 100644 --- a/templates/kotlin/README.md.twig +++ b/templates/kotlin/README.md.twig @@ -1,10 +1,10 @@ # {{ spec.info.title }} {{sdk.name}} SDK ![Maven Central](https://img.shields.io/maven-central/v/{{ sdk.namespace | caseDot }}/{{ sdk.gitRepoName | caseDash }}.svg?color=green&style=flat-square) -![License](https://img.shields.io/github/license/{{ sdk.gitUserName|url_encode }}/{{ sdk.gitRepoName|url_encode }}.svg?style=flat-square) +![License](https://img.shields.io/badge/license-{{ spec.info.license.name|replace({'-': '--', '_': '__'})|url_encode }}-blue.svg?style=flat-square) ![Version](https://img.shields.io/badge/api%20version-{{ spec.info.version|url_encode }}-blue.svg?style=flat-square) {% if sdk.twitterHandle %} -[![Twitter Account](https://img.shields.io/twitter/follow/{{ sdk.twitterHandle }}?color=00acee&label=twitter&style=flat-square)](https://twitter.com/{{ sdk.twitterHandle }}) +[![X Account](https://img.shields.io/badge/follow-%40{{ sdk.twitterHandle|replace({'-': '--', '_': '__'})|url_encode }}-000000?logo=x&style=flat-square)](https://x.com/{{ sdk.twitterHandle }}) {% endif %} {% if sdk.discordChannel %} [![Discord](https://img.shields.io/discord/{{ sdk.discordChannel }}?label=discord&style=flat-square)]({{ sdk.discordUrl }}) @@ -22,54 +22,49 @@ ## Installation -### Gradle +The SDK requires Java 11 or later and is published to Maven Central as `{{ sdk.namespace | caseDot }}:{{ sdk.gitRepoName | caseDash }}`. Make sure `mavenCentral()` is among your repositories, then add the dependency. -Appwrite's Kotlin SDK is hosted on Maven Central. In order to fetch the Appwrite SDK, add this to your root level `build.gradle(.kts)` file: +Gradle Kotlin DSL (`build.gradle.kts`): -```groovy -repositories { - mavenCentral() +```kotlin +dependencies { + implementation("{{ sdk.namespace | caseDot }}:{{ sdk.gitRepoName | caseDash }}:{{ sdk.version }}") } ``` -If you would like to fetch our SNAPSHOT releases, you need to add the SNAPSHOT maven repository to your `build.gradle(.kts)`: +Gradle Groovy (`build.gradle`): ```groovy -repositories { - maven { - url "https://s01.oss.sonatype.org/content/repositories/snapshots/" - } +dependencies { + implementation '{{ sdk.namespace | caseDot }}:{{ sdk.gitRepoName | caseDash }}:{{ sdk.version }}' } ``` -Next, add the dependency to your project's `build.gradle(.kts)` file: - -```groovy -implementation("{{ sdk.namespace | caseDot }}:{{ sdk.gitRepoName | caseDash }}:{{ sdk.version }}") -``` - -### Maven -Add this to your project's `pom.xml` file: +Maven (`pom.xml`): ```xml - - - {{ sdk.namespace | caseDot }} - {{ sdk.gitRepoName | caseDash }} - {{sdk.version}} - - + + {{ sdk.namespace | caseDot }} + {{ sdk.gitRepoName | caseDash }} + {{ sdk.version }} + ``` - {% if sdk.gettingStarted %} -{{ sdk.gettingStarted|raw }} +{{ sdk.gettingStarted|trim|raw }} {% endif %} +## Learn more + +- [Kotlin quick start](https://appwrite.io/docs/quick-starts/kotlin) +- [Kotlin SDK reference](https://appwrite.io/docs/references/cloud/server-kotlin/users) +- [Appwrite docs](https://appwrite.io/docs) +- [Discord community](https://appwrite.io/discord) + ## Contribution -This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/master/CONTRIBUTING.md) before sending a pull-request. +This library is auto-generated by the Appwrite [SDK Generator](https://github.com/appwrite/sdk-generator). To learn how you can help improve this SDK, please read the [contribution guide](https://github.com/appwrite/sdk-generator/blob/main/CONTRIBUTING.md) before sending a pull request. ## License -Please see the [{{spec.info.license.name}} license]({{spec.info.license.url}}) file for more information. \ No newline at end of file +Please see the [{{spec.info.license.name}} license]({{spec.info.license.url}}) file for more information. diff --git a/templates/node/README.md.twig b/templates/node/README.md.twig index 7fbc98b115..89f34bf28e 100644 --- a/templates/node/README.md.twig +++ b/templates/node/README.md.twig @@ -1,10 +1,9 @@ # {{ spec.info.title }} {{sdk.name}} SDK -![License](https://img.shields.io/github/license/{{ sdk.gitUserName|url_encode }}/{{ sdk.gitRepoName|url_encode }}.svg?style=flat-square) +![License](https://img.shields.io/badge/license-{{ spec.info.license.name|replace({'-': '--', '_': '__'})|url_encode }}-blue.svg?style=flat-square) ![Version](https://img.shields.io/badge/api%20version-{{ spec.info.version|url_encode }}-blue.svg?style=flat-square) -[![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator) {% if sdk.twitterHandle %} -[![Twitter Account](https://img.shields.io/twitter/follow/{{ sdk.twitterHandle }}?color=00acee&label=twitter&style=flat-square)](https://twitter.com/{{ sdk.twitterHandle }}) +[![X Account](https://img.shields.io/badge/follow-%40{{ sdk.twitterHandle|replace({'-': '--', '_': '__'})|url_encode }}-000000?logo=x&style=flat-square)](https://x.com/{{ sdk.twitterHandle }}) {% endif %} {% if sdk.discordChannel %} [![Discord](https://img.shields.io/discord/{{ sdk.discordChannel }}?label=discord&style=flat-square)]({{ sdk.discordUrl }}) @@ -22,20 +21,35 @@ ## Installation -To install via [NPM](https://www.npmjs.com/): +Requires Node.js 18.17 or later. ```bash -npm install {{ language.params.npmPackage }} --save +npm install {{ language.params.npmPackage }} ``` +The package ships ES modules, CommonJS and TypeScript types: + +```js +import {{ '{' }} Client, Users {{ '}' }} from '{{ language.params.npmPackage }}'; +``` + +```js +const {{ '{' }} Client, Users {{ '}' }} = require('{{ language.params.npmPackage }}'); +``` + +Deno can use the same package through its npm support: + +```ts +import {{ '{' }} Client, Users {{ '}' }} from 'npm:{{ language.params.npmPackage }}'; +``` {% if sdk.gettingStarted %} -{{ sdk.gettingStarted|raw }} +{{ sdk.gettingStarted|trim|raw }} {% endif %} ## Contribution -This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/master/CONTRIBUTING.md) before sending a pull-request. +This library is auto-generated by the Appwrite [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/main/CONTRIBUTING.md) before sending a pull-request. ## License diff --git a/templates/php/README.md.twig b/templates/php/README.md.twig index 9d75af00b2..a3fae71314 100644 --- a/templates/php/README.md.twig +++ b/templates/php/README.md.twig @@ -1,10 +1,9 @@ # {{ spec.info.title }} {{sdk.name}} SDK -![License](https://img.shields.io/github/license/{{ sdk.gitUserName|url_encode }}/{{ sdk.gitRepoName|url_encode }}.svg?style=flat-square&v=1) +![License](https://img.shields.io/badge/license-{{ spec.info.license.name|replace({'-': '--', '_': '__'})|url_encode }}-blue.svg?style=flat-square) ![Version](https://img.shields.io/badge/api%20version-{{ spec.info.version|url_encode }}-blue.svg?style=flat-square&v=1) -[![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator) {% if sdk.twitterHandle %} -[![Twitter Account](https://img.shields.io/twitter/follow/{{ sdk.twitterHandle }}?color=00acee&label=twitter&style=flat-square)](https://twitter.com/{{ sdk.twitterHandle }}) +[![X Account](https://img.shields.io/badge/follow-%40{{ sdk.twitterHandle|replace({'-': '--', '_': '__'})|url_encode }}-000000?logo=x&style=flat-square)](https://x.com/{{ sdk.twitterHandle }}) {% endif %} {% if sdk.discordChannel %} [![Discord](https://img.shields.io/discord/{{ sdk.discordChannel }}?label=discord&style=flat-square)]({{ sdk.discordUrl }}) @@ -22,7 +21,7 @@ ## Installation -To install via [Composer](http://getcomposer.org/): +To install via [Composer](https://getcomposer.org/): ```bash composer require {{ language.params.composerVendor }}/{{ language.params.composerPackage }} @@ -56,15 +55,14 @@ $client->setEndpoint('{{ spec | endpoint }}'); ``` Configure timeouts, TLS, redirects, and connection reuse on the injected transport. The SDK's `setTimeout()`, `setConnectTimeout()`, and `setSelfSigned()` methods only configure the default cURL transport. Endpoint, authentication, headers, request encoding, and response handling remain the SDK's responsibility. A transport used with `responseType: 'location'` must have redirect following disabled. - {% if sdk.gettingStarted %} -{{ sdk.gettingStarted|raw }} +{{ sdk.gettingStarted|trim|raw }} {% endif %} ## Contribution -This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/master/CONTRIBUTING.md) before sending a pull-request. +This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/main/CONTRIBUTING.md) before sending a pull-request. ## License diff --git a/templates/python/README.md.twig b/templates/python/README.md.twig index c10cff691a..ab883ef870 100644 --- a/templates/python/README.md.twig +++ b/templates/python/README.md.twig @@ -1,10 +1,9 @@ # {{ spec.info.title }} {{sdk.name}} SDK -![License](https://img.shields.io/github/license/{{ sdk.gitUserName|url_encode }}/{{ sdk.gitRepoName|url_encode }}.svg?style=flat-square) +![License](https://img.shields.io/badge/license-{{ spec.info.license.name|replace({'-': '--', '_': '__'})|url_encode }}-blue.svg?style=flat-square) ![Version](https://img.shields.io/badge/api%20version-{{ spec.info.version|url_encode }}-blue.svg?style=flat-square) -[![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator) {% if sdk.twitterHandle %} -[![Twitter Account](https://img.shields.io/twitter/follow/{{ sdk.twitterHandle }}?color=00acee&label=twitter&style=flat-square)](https://twitter.com/{{ sdk.twitterHandle }}) +[![X Account](https://img.shields.io/badge/follow-%40{{ sdk.twitterHandle|replace({'-': '--', '_': '__'})|url_encode }}-000000?logo=x&style=flat-square)](https://x.com/{{ sdk.twitterHandle }}) {% endif %} {% if sdk.discordChannel %} [![Discord](https://img.shields.io/discord/{{ sdk.discordChannel }}?label=discord&style=flat-square)]({{ sdk.discordUrl }}) @@ -22,26 +21,25 @@ ## Installation -To install via [PyPI](https://pypi.org/): +Requires Python 3.9 or later. Install the [`{{ language.params.pipPackage }}`](https://pypi.org/project/{{ language.params.pipPackage }}/) package from PyPI: ```bash pip install {{ language.params.pipPackage }} ``` -Or with `uv`: +Or with [uv](https://docs.astral.sh/uv/): ```bash uv add {{ language.params.pipPackage }} ``` - {% if sdk.gettingStarted %} -{{ sdk.gettingStarted|raw }} +{{ sdk.gettingStarted|raw|trim }} {% endif %} ## Contribution -This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/master/CONTRIBUTING.md) before sending a pull-request. +This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/main/CONTRIBUTING.md) before sending a pull-request. ## License diff --git a/templates/react-native/README.md.twig b/templates/react-native/README.md.twig index 71aeaad8ab..5d44d6f0c8 100644 --- a/templates/react-native/README.md.twig +++ b/templates/react-native/README.md.twig @@ -1,10 +1,9 @@ # {{ spec.info.title }} {{sdk.name}} SDK -![License](https://img.shields.io/github/license/{{ sdk.gitUserName|url_encode }}/{{ sdk.gitRepoName|url_encode }}.svg?style=flat-square) +![License](https://img.shields.io/badge/license-{{ spec.info.license.name|replace({'-': '--', '_': '__'})|url_encode }}-blue.svg?style=flat-square) ![Version](https://img.shields.io/badge/api%20version-{{ spec.info.version|url_encode }}-blue.svg?style=flat-square) -[![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator) {% if sdk.twitterHandle %} -[![Twitter Account](https://img.shields.io/twitter/follow/{{ sdk.twitterHandle }}?color=00acee&label=twitter&style=flat-square)](https://twitter.com/{{ sdk.twitterHandle }}) +[![X Account](https://img.shields.io/badge/follow-%40{{ sdk.twitterHandle|replace({'-': '--', '_': '__'})|url_encode }}-000000?logo=x&style=flat-square)](https://x.com/{{ sdk.twitterHandle }}) {% endif %} {% if sdk.discordChannel %} [![Discord](https://img.shields.io/discord/{{ sdk.discordChannel }}?label=discord&style=flat-square)]({{ sdk.discordUrl }}) @@ -22,40 +21,45 @@ ## Installation -To install +```bash +npx expo install {{ language.params.npmPackage }} react-native-url-polyfill +``` + +The SDK uses Expo modules. In a React Native project created without Expo, run `npx install-expo-modules@latest` first. + +{% if sdk.gettingStarted %} +{{ sdk.gettingStarted|trim|raw }} + +{% endif %} +## Push + +`Push` connects over a raw TCP socket, so it needs `react-native-tcp-socket` and a development or standalone build (native modules do not run in Expo Go): ```bash -npx expo install react-native-appwrite react-native-url-polyfill +npx expo install react-native-tcp-socket ``` -### Push +Background delivery outside Android also needs `react-native-background-actions` and `expo-notifications`. + +Create the service from your client once the user is signed in: -`Push` connects over a raw TCP socket, so it needs `react-native-tcp-socket` and a development -or standalone build (native modules do not run in Expo Go). +```js +import {{ '{' }} Push {{ '}' }} from '{{ language.params.npmPackage }}'; -On Expo SDK 52 and older, enable package exports in `metro.config.js` so `mqtt` resolves to its -React Native build (Expo SDK 53 and later do this by default): +const push = new Push(client); +``` + +On Expo SDK 52 and older, enable package exports in `metro.config.js` so `mqtt` resolves to its React Native build (Expo SDK 53 and later do this by default): ```js config.resolver.unstable_enablePackageExports = true; ``` -#### Background delivery on Android +### Background delivery on Android -A subscription with `background: true` keeps delivering after the app is backgrounded, killed or -the device restarts, until it is unsubscribed or `push.close()` is called (do this on sign-out). -The SDK's native Android module (autolinked) saves the subscription, and a scheduled job and -alarm wake the app every 15 to 60 seconds to reconnect; the broker replays what was sent in -between (`retry: true`). While the app is not on screen, each message is posted as a -notification that opens the app. It reconnects with the credential saved at subscribe time, so use a session rather -than a short-lived JWT. +A subscription with `background: true` keeps delivering after the app is backgrounded, killed or the device restarts, until it is unsubscribed or `push.close()` is called (do this on sign-out). The SDK's native Android module (autolinked) saves the subscription, and a scheduled job and alarm wake the app every 15 to 60 seconds to reconnect; the broker replays what was sent in between (`retry: true`). While the app is not on screen, each message is posted as a notification that opens the app. It reconnects with the credential saved at subscribe time, so use a session rather than a short-lived JWT. -On Android 13 and later, the first background subscription asks the user for the -`POST_NOTIFICATIONS` runtime permission. If they decline, the subscription still delivers to your -callback but posts no notification. Notifications show the title, body and image sent with -`createPush`, falling back to the subscription's `title` when only a body is sent. A push with no -title or body, such as a data-only push, posts no notification and reaches only your callback. -Messages that are not a JSON object show the subscription's `title` with the raw payload as the body. +On Android 13 and later, the first background subscription asks the user for the `POST_NOTIFICATIONS` runtime permission. If they decline, the subscription still delivers to your callback but posts no notification. Notifications show the title, body and image sent with `createPush`, falling back to the subscription's `title` when only a body is sent. A push with no title or body, such as a data-only push, posts no notification and reaches only your callback. Messages that are not a JSON object show the subscription's `title` with the raw payload as the body. ```js const sub = await push.subscribe('news', (message) => console.log(message.data), { @@ -68,55 +72,30 @@ const sub = await push.subscribe('news', (message) => console.log(message.data), await push.setForeground(true); ``` -Notifications are posted while the app is backgrounded or closed. While it is on screen your -callback shows the message, so none is posted unless the subscription passes -`notifyInForeground: true`. +Notifications are posted while the app is backgrounded or closed. While it is on screen your callback shows the message, so none is posted unless the subscription passes `notifyInForeground: true`. -#### Delivery while the app is closed +### Delivery while the app is closed -Messages sent while the app is closed arrive at the next scheduled wake-up. While the device is -awake that is about every 15 seconds, or about every 60 seconds once exact alarms are allowed; -without exact alarms the wake-ups are inexact, so battery saver can defer them further. In Doze -(screen off and idle for a while) Android limits background alarms, exact ones included, to about -one every nine minutes, so a closed app can take several minutes to receive a message: allowing -exact alarms makes wake-ups punctual, it does not lift Doze. For immediate delivery, also in -Doze, use `push.setForeground(true)` (see above). +Messages sent while the app is closed arrive at the next scheduled wake-up. While the device is awake that is about every 15 seconds, or about every 60 seconds once exact alarms are allowed; without exact alarms the wake-ups are inexact, so battery saver can defer them further. In Doze (screen off and idle for a while) Android limits background alarms, exact ones included, to about one every nine minutes, so a closed app can take several minutes to receive a message: allowing exact alarms makes wake-ups punctual, it does not lift Doze. For immediate delivery, also in Doze, use `push.setForeground(true)` (see above). The SDK uses exact alarms on its own whenever the app may schedule them. To allow it: -1. Declare the permissions in your app's `AndroidManifest.xml`. Both are optional and subject to - Google Play policy: `SCHEDULE_EXACT_ALARM` needs a declaration in the Play Console, and - `USE_EXACT_ALARM` is reserved for alarm, clock and calendar apps (the SDK does not use it). +1. Declare the permissions in your app's `AndroidManifest.xml`. Both are optional and subject to Google Play policy: `SCHEDULE_EXACT_ALARM` needs a declaration in the Play Console, and `USE_EXACT_ALARM` is reserved for alarm, clock and calendar apps (the SDK does not use it). ```xml ``` -With Expo, list them under `android.permissions` in `app.json` instead. + With Expo, list them under `android.permissions` in `app.json` instead. -2. On Android 13 and later the user has to allow exact alarms, under Settings > Apps > Special app - access > Alarms & reminders. Android 12 grants a declared `SCHEDULE_EXACT_ALARM` - automatically, and older versions need nothing. Check with `await push.backgroundStatus()`: when `bestEffort` is - true, explain why to the user, then from a user action open that screen with `push.requestExactAlarms()`, or - ask for the battery-optimisation exemption with `push.requestIgnoreBatteryOptimizations()`. Both return false when there is - nothing to ask, including when the permission is not declared. The SDK never opens these - screens on its own. +2. On Android 13 and later the user has to allow exact alarms, under Settings > Apps > Special app access > Alarms & reminders. Android 12 grants a declared `SCHEDULE_EXACT_ALARM` automatically, and older versions need nothing. Check with `await push.backgroundStatus()`: when `bestEffort` is true, explain why to the user, then from a user action open that screen with `push.requestExactAlarms()`, or ask for the battery-optimisation exemption with `push.requestIgnoreBatteryOptimizations()`. Both return false when there is nothing to ask, including when the permission is not declared. The SDK never opens these screens on its own. -If `backgroundRestricted` is true, the user restricted the app's background usage and messages can -wait until the app is opened. Exact alarms don't lift it, and neither does foreground mode: Android -stops a restricted app's foreground service once it leaves the screen. Ask the user to choose -Unrestricted in the app's battery settings (Settings > Apps > your app > Battery); granting the -battery optimisation exemption also lets the SDK's alarms and jobs run, and `bestEffort` then -reflects only the exact-alarm state. It is always false below Android 9. +If `backgroundRestricted` is true, the user restricted the app's background usage and messages can wait until the app is opened. Exact alarms don't lift it, and neither does foreground mode: Android stops a restricted app's foreground service once it leaves the screen. Ask the user to choose Unrestricted in the app's battery settings (Settings > Apps > your app > Battery); granting the battery optimisation exemption also lets the SDK's alarms and jobs run, and `bestEffort` then reflects only the exact-alarm state. It is always false below Android 9. -If the user force-stops the app (Settings > Force stop, and on some devices swiping it away from -recents), Android cancels its alarms and jobs: nothing is delivered until the app is opened -again, and the broker then replays what was sent meanwhile. +If the user force-stops the app (Settings > Force stop, and on some devices swiping it away from recents), Android cancels its alarms and jobs: nothing is delivered until the app is opened again, and the broker then replays what was sent meanwhile. -Set the notification icon with -`` in your -``; without it a generic icon is used. +Set the notification icon with `` in your ``; without it a generic icon is used. ```js const status = await push.backgroundStatus(); // null outside Android @@ -128,19 +107,13 @@ if (status?.backgroundRestricted && !status.ignoringBatteryOptimizations) { } ``` -Saved background delivery follows the app's current session, also while the app is closed: each -background run re-reads the session cookie, so a rotated session of the same user replaces the -saved one, and signing out (no session) or signing in as someone else stops background delivery. -If the broker still refuses the credential, delivery stops and `onError` reports it the next time -the app registers one. Still call `push.close()` on sign-out. +Saved background delivery follows the app's current session, also while the app is closed: each background run re-reads the session cookie, so a rotated session of the same user replaces the saved one, and signing out (no session) or signing in as someone else stops background delivery. If the broker still refuses the credential, delivery stops and `onError` reports it the next time the app registers one. Still call `push.close()` on sign-out. -#### Upgrading from an earlier release candidate +### Upgrading from an earlier release candidate -The Expo config plugin is gone: the native module now declares everything background delivery -needs. Remove `"react-native-appwrite"` from the `plugins` list in `app.json`, or `expo config` -fails to load it. +The Expo config plugin is gone: the native module now declares everything background delivery needs. Remove `"react-native-appwrite"` from the `plugins` list in `app.json`, or `expo config` fails to load it. -#### Opening a tapped notification +### Opening a tapped notification Read the `data` sent with `createPush` when the user taps a background notification: @@ -157,19 +130,18 @@ const stop = push.onNotificationOpened(({ topic, data }) => openSale(data.saleId On Android the SDK's native module reports the taps. Elsewhere they come from `expo-notifications`. -Foreground mode runs a `remoteMessaging` foreground service, which Google Play asks apps to -declare in the Play Console. Apps that never enable it can remove the service from their merged -manifest with `tools:node="remove"` on `io.{{ spec.info.title | caseLower }}.reactnative.services.PushService` and -`android.permission.FOREGROUND_SERVICE_REMOTE_MESSAGING`. +Foreground mode runs a `remoteMessaging` foreground service, which Google Play asks apps to declare in the Play Console. Apps that never enable it can remove the service from their merged manifest with `tools:node="remove"` on `io.{{ spec.info.title | caseLower }}.reactnative.services.PushService` and `android.permission.FOREGROUND_SERVICE_REMOTE_MESSAGING`. -{% if sdk.gettingStarted %} +## Learn more -{{ sdk.gettingStarted|raw }} -{% endif %} +- [React Native quick start](https://appwrite.io/docs/quick-starts/react-native) +- [Appwrite docs](https://appwrite.io/docs) +- [Discord community](https://appwrite.io/discord) +- [React Native playground](https://github.com/appwrite/playground-for-react-native) ## Contribution -This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/master/CONTRIBUTING.md) before sending a pull-request. +This library is auto-generated by the Appwrite [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/main/CONTRIBUTING.md) before sending a pull-request. ## License diff --git a/templates/ruby/README.md.twig b/templates/ruby/README.md.twig index b95a4c9268..008eea50ee 100644 --- a/templates/ruby/README.md.twig +++ b/templates/ruby/README.md.twig @@ -1,10 +1,9 @@ # {{ spec.info.title }} {{sdk.name}} SDK -![License](https://img.shields.io/github/license/{{ sdk.gitUserName|url_encode }}/{{ sdk.gitRepoName|url_encode }}.svg?style=flat-square) +![License](https://img.shields.io/badge/license-{{ spec.info.license.name|replace({'-': '--', '_': '__'})|url_encode }}-blue.svg?style=flat-square) ![Version](https://img.shields.io/badge/api%20version-{{ spec.info.version|url_encode }}-blue.svg?style=flat-square) -[![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator) {% if sdk.twitterHandle %} -[![Twitter Account](https://img.shields.io/twitter/follow/{{ sdk.twitterHandle }}?color=00acee&label=twitter&style=flat-square)](https://twitter.com/{{ sdk.twitterHandle }}) +[![X Account](https://img.shields.io/badge/follow-%40{{ sdk.twitterHandle|replace({'-': '--', '_': '__'})|url_encode }}-000000?logo=x&style=flat-square)](https://x.com/{{ sdk.twitterHandle }}) {% endif %} {% if sdk.discordChannel %} [![Discord](https://img.shields.io/discord/{{ sdk.discordChannel }}?label=discord&style=flat-square)]({{ sdk.discordUrl }}) @@ -22,20 +21,25 @@ ## Installation -To install via [Gem](https://rubygems.org/): +Add the [`{{ language.params.gemPackage }}`](https://rubygems.org/gems/{{ language.params.gemPackage }}) gem to your Gemfile with Bundler: ```bash -gem install {{ language.params.gemPackage }} +bundle add {{ language.params.gemPackage }} ``` +Or install it directly: + +```bash +gem install {{ language.params.gemPackage }} +``` {% if sdk.gettingStarted %} -{{ sdk.gettingStarted|raw }} +{{ sdk.gettingStarted|raw|trim }} {% endif %} ## Contribution -This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/master/CONTRIBUTING.md) before sending a pull-request. +This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/main/CONTRIBUTING.md) before sending a pull-request. ## License diff --git a/templates/rust/README.md.twig b/templates/rust/README.md.twig index 135787dfde..d54ca2d6e9 100644 --- a/templates/rust/README.md.twig +++ b/templates/rust/README.md.twig @@ -1,6 +1,6 @@ # {{ spec.info.title }} Rust SDK -![License](https://img.shields.io/github/license/{{ sdk.gitUserName }}/sdk-for-rust.svg) +![License](https://img.shields.io/badge/license-{{ spec.info.license.name|replace({'-': '--', '_': '__'})|url_encode }}-blue.svg) ![Version](https://img.shields.io/badge/api%20version-{{ spec.info.version }}-blue.svg) [![Crates.io](https://img.shields.io/crates/v/{{ sdk.cratePackage | default('appwrite') }}.svg)](https://crates.io/crates/{{ sdk.cratePackage | default('appwrite') }}) [![Documentation](https://docs.rs/{{ sdk.cratePackage | default('appwrite') }}/badge.svg)](https://docs.rs/{{ sdk.cratePackage | default('appwrite') }}) @@ -29,16 +29,18 @@ Or using `cargo add`: ```bash cargo add {{ sdk.cratePackage | default('appwrite') }} +cargo add tokio --features full ``` +The SDK is async and runs on the [Tokio](https://tokio.rs) runtime. {% if sdk.gettingStarted %} -{{ sdk.gettingStarted|raw }} +{{ sdk.gettingStarted|trim|raw }} {% endif %} ## Contribution -This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/master/CONTRIBUTING.md) before sending a pull-request. +This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/main/CONTRIBUTING.md) before sending a pull-request. ## License diff --git a/templates/skills/README.md.twig b/templates/skills/README.md.twig index e09eb1c49a..7c439ff4f5 100644 --- a/templates/skills/README.md.twig +++ b/templates/skills/README.md.twig @@ -1,33 +1,33 @@ -# {{ spec.info.title }} {{sdk.name}} +# {{ spec.info.title }} Agent Skills -![License](https://img.shields.io/github/license/{{ sdk.gitUserName|url_encode }}/{{ sdk.gitRepoName|url_encode }}.svg?style=flat-square) +![License](https://img.shields.io/badge/license-{{ spec.info.license.name|replace({'-': '--', '_': '__'})|url_encode }}-blue.svg?style=flat-square) ![Version](https://img.shields.io/badge/api%20version-{{ spec.info.version|url_encode }}-blue.svg?style=flat-square) -[![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator) {% if sdk.twitterHandle %} -[![Twitter Account](https://img.shields.io/twitter/follow/{{ sdk.twitterHandle }}?color=00acee&label=twitter&style=flat-square)](https://twitter.com/{{ sdk.twitterHandle }}) +[![X Account](https://img.shields.io/badge/follow-%40{{ sdk.twitterHandle|replace({'-': '--', '_': '__'})|url_encode }}-000000?logo=x&style=flat-square)](https://x.com/{{ sdk.twitterHandle }}) {% endif %} {% if sdk.discordChannel %} [![Discord](https://img.shields.io/discord/{{ sdk.discordChannel }}?label=discord&style=flat-square)]({{ sdk.discordUrl }}) {% endif %} -{% if sdk.warning %} -{{ sdk.warning|raw }} -{% endif %} - -{{ sdk.description }} +{{ spec.info.title }} skills for AI coding agents such as Claude Code, Cursor, Codex, GitHub Copilot, and Zed. Each skill gives the agent current, language-specific guidance for building with {{ spec.info.title }}: client setup, authentication, TablesDB queries, storage, realtime, functions, and the {{ spec.info.title }} CLI. The skills follow the [Agent Skills](https://agentskills.io) open standard. {% if sdk.coverImage %} ![{{ spec.info.title }}]({{ sdk.coverImage }}) {% endif %} - {% if sdk.gettingStarted %} -{{ sdk.gettingStarted|raw }} +{{ sdk.gettingStarted|trim|raw }} {% endif %} +## Learn more + +- [{{ spec.info.title }} skills documentation](https://appwrite.io/docs/tooling/ai/skills) +- [{{ spec.info.title }} MCP server](https://appwrite.io/docs/tooling/ai/mcp-servers) +- [Agent Skills specification](https://agentskills.io) + ## Contribution -This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/master/CONTRIBUTING.md) before sending a pull-request. +This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/main/CONTRIBUTING.md) before sending a pull-request. ## License diff --git a/templates/swift/README.md.twig b/templates/swift/README.md.twig index a9afe20d0a..1cbe2249eb 100644 --- a/templates/swift/README.md.twig +++ b/templates/swift/README.md.twig @@ -1,11 +1,10 @@ # {{ spec.info.title }} {{sdk.name}} SDK -![Swift Package Manager](https://img.shields.io/github/v/release/{{ sdk.gitUserName }}/{{ sdk.gitRepoName }}.svg?color=green&style=flat-square) -![License](https://img.shields.io/github/license/{{ sdk.gitUserName | url_encode }}/{{ sdk.gitRepoName|url_encode }}.svg?style=flat-square) +![Swift Package Manager](https://img.shields.io/badge/swift%20package%20manager-{{ sdk.version|replace({'-': '--', '_': '__'})|url_encode }}-green.svg?style=flat-square) +![License](https://img.shields.io/badge/license-{{ spec.info.license.name|replace({'-': '--', '_': '__'})|url_encode }}-blue.svg?style=flat-square) ![Version](https://img.shields.io/badge/api%20version-{{ spec.info.version|url_encode }}-blue.svg?style=flat-square) -[![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator) {% if sdk.twitterHandle %} -[![Twitter Account](https://img.shields.io/twitter/follow/{{ sdk.twitterHandle }}?color=00acee&label=twitter&style=flat-square)](https://twitter.com/{{ sdk.twitterHandle }}) +[![X Account](https://img.shields.io/badge/follow-%40{{ sdk.twitterHandle|replace({'-': '--', '_': '__'})|url_encode }}-000000?logo=x&style=flat-square)](https://x.com/{{ sdk.twitterHandle }}) {% endif %} {% if sdk.discordChannel %} [![Discord](https://img.shields.io/discord/{{ sdk.discordChannel }}?label=discord&style=flat-square)]({{ sdk.discordUrl }}) @@ -23,46 +22,45 @@ ## Installation -### Xcode with Swift Package Manager +Requires Swift 6.1 or later (Xcode 16.3 or later). Supported platforms are iOS 15, macOS 12, tvOS 15 and watchOS 8 or later{% if language.name == 'Swift' %}, plus Linux{% endif %}. -The Appwrite Swift SDK is available via Swift Package Manager. In order to use the Appwrite Swift SDK from Xcode, select File > **Add Packages** +### Xcode -In the dialog that appears, enter the Appwrite Swift SDK [package URL]({{ sdk.gitRepo }}) in the search field. Once found, select `sdk-for-{{ sdk.name | lower }}`. - -On the right, select your version rules and ensure your desired target is selected in the **Add to Project** field. - -Now click add package and you're done! +1. In Xcode, select **File > Add Package Dependencies...** +2. Enter `https://github.com/{{ sdk.gitUserName }}/{{ sdk.gitRepoName }}` in the search field and select `{{ sdk.gitRepoName }}`. +3. Choose a dependency rule, for example **Up to Next Major Version** from `{{ sdk.version }}`, and click **Add Package**. +4. Add the `{{ spec.info.title | caseUcfirst }}` library to your app target and click **Add Package**. ### Swift Package Manager -Add the package to your `Package.swift` dependencies: +Add the package to the dependencies in your `Package.swift`: ```swift - dependencies: [ - .package(url: "{{ sdk.gitRepo }}", from: "{{ sdk.version }}"), - ], +dependencies: [ + .package(url: "https://github.com/{{ sdk.gitUserName }}/{{ sdk.gitRepoName }}", from: "{{ sdk.version }}"), +], ``` -Then add it to your target: +Then add the `{{ spec.info.title | caseUcfirst }}` product to your target: ```swift - targets: [ - .target( - name: "YourAppTarget", - dependencies: [ - .product(name: "{{ spec.info.title | caseUcfirst }}", package: "{{ sdk.gitRepoName }}") - ] - ), +targets: [ + .target( + name: "YourAppTarget", + dependencies: [ + .product(name: "{{ spec.info.title | caseUcfirst }}", package: "{{ sdk.gitRepoName }}"), + ] + ), +], ``` - {% if sdk.gettingStarted %} -{{ sdk.gettingStarted|raw }} +{{ sdk.gettingStarted|trim|raw }} {% endif %} ## Contribution -This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/master/CONTRIBUTING.md) before sending a pull-request. +This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/main/CONTRIBUTING.md) before sending a pull-request. ## License diff --git a/templates/unity/README.md.twig b/templates/unity/README.md.twig index 2f48e6fb18..911343ddae 100644 --- a/templates/unity/README.md.twig +++ b/templates/unity/README.md.twig @@ -1,11 +1,10 @@ # {{ spec.info.title }} {{ sdk.name }} SDK -![License](https://img.shields.io/github/license/{{ sdk.gitUserName|url_encode }}/{{ sdk.gitRepoName|url_encode }}.svg?style=flat-square) +![License](https://img.shields.io/badge/license-{{ spec.info.license.name|replace({'-': '--', '_': '__'})|url_encode }}-blue.svg?style=flat-square) ![Version](https://img.shields.io/badge/api%20version-{{ spec.info.version|url_encode }}-blue.svg?style=flat-square) ![Unity](https://img.shields.io/badge/Unity-2021.3%2B-blue.svg?style=flat-square) -[![Build Status](https://img.shields.io/travis/com/{{ sdk.gitUserName|url_encode }}/{{ sdk.gitRepoName|url_encode }}?style=flat-square)](https://travis-ci.com/{{ sdk.gitUserName|url_encode }}/{{ sdk.gitRepoName|url_encode }}) {% if sdk.twitterHandle %} -[![Twitter Account](https://img.shields.io/twitter/follow/{{ sdk.twitterHandle }}?color=00acee&label=twitter&style=flat-square)](https://twitter.com/{{ sdk.twitterHandle }}) +[![X Account](https://img.shields.io/badge/follow-%40{{ sdk.twitterHandle|replace({'-': '--', '_': '__'})|url_encode }}-000000?logo=x&style=flat-square)](https://x.com/{{ sdk.twitterHandle }}) {% endif %} {% if sdk.discordChannel %} [![Discord](https://img.shields.io/discord/{{ sdk.discordChannel }}?label=discord&style=flat-square)]({{ sdk.discordUrl }}) @@ -23,32 +22,43 @@ ## Installation +Requires Unity 2021.3 or later. Installing from a git URL also requires [Git](https://git-scm.com/downloads) on your `PATH`. + ### Unity Package Manager (UPM) -1. Open Unity and go to **Window > Package Manager**. -2. Click the **+** button and select **Add package from git URL**. -3. Enter the following URL: +1. In Unity, open **Window > Package Manager**. +2. Click the **+** button and select **Add package from git URL** (**Install package from git URL** in Unity 6). +3. Enter the following URL and click **Add** (**Install** in Unity 6): -```sh +```text https://github.com/{{ sdk.gitUserName|url_encode }}/{{ sdk.gitRepoName|url_encode }}.git#{{ sdk.version }} ``` -4. Click **Add**. +The `#{{ sdk.version }}` suffix pins the package to a release. Change it to any released tag, or omit it to track the latest commit on the default branch. -The `#{{ sdk.version }}` suffix pins the package to a specific release. Change it to any released tag, or omit `#{{ sdk.version }}` to track the latest commit on the default branch. +You can also add the package to `Packages/manifest.json` directly: -### Manual Installation +```json +{ + "dependencies": { + "{{ language.params.packageName }}": "https://github.com/{{ sdk.gitUserName|url_encode }}/{{ sdk.gitRepoName|url_encode }}.git#{{ sdk.version }}" + } +} +``` -Download the latest release from [GitHub]({{ sdk.url }}/releases/latest) and import the Unity package into your project. +### Install from disk +1. Download the source code archive of a release from [GitHub](https://github.com/{{ sdk.gitUserName|url_encode }}/{{ sdk.gitRepoName|url_encode }}/releases) and extract it. +2. In **Window > Package Manager**, click the **+** button and select **Add package from disk** (**Install package from disk** in Unity 6). +3. Select the `package.json` file in the extracted folder. {% if sdk.gettingStarted %} -{{ sdk.gettingStarted|raw }} +{{ sdk.gettingStarted|trim|raw }} {% endif %} ## Contribution -This library is auto-generated by the {{ spec.info.title }} [SDK Generator](https://github.com/{{ sdk.gitUserName|url_encode }}/{{ sdk.gitRepoName|url_encode }}). To learn how you can help improve this SDK, please check the [contribution guide](https://github.com/{{ sdk.gitUserName|url_encode }}/{{ sdk.gitRepoName|url_encode }}/blob/master/CONTRIBUTING.md) before sending a pull request. +This library is auto-generated by the {{ spec.info.title }} [SDK Generator](https://github.com/appwrite/sdk-generator). To learn how you can help improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/main/CONTRIBUTING.md) before sending a pull request. ## License diff --git a/templates/web/README.md.twig b/templates/web/README.md.twig index be6a791342..800262ad47 100644 --- a/templates/web/README.md.twig +++ b/templates/web/README.md.twig @@ -1,10 +1,9 @@ # {{ spec.info.title }} {{sdk.name}} SDK -![License](https://img.shields.io/github/license/{{ sdk.gitUserName|url_encode }}/{{ sdk.gitRepoName|url_encode }}.svg?style=flat-square) +![License](https://img.shields.io/badge/license-{{ spec.info.license.name|replace({'-': '--', '_': '__'})|url_encode }}-blue.svg?style=flat-square) ![Version](https://img.shields.io/badge/api%20version-{{ spec.info.version|url_encode }}-blue.svg?style=flat-square) -[![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator) {% if sdk.twitterHandle %} -[![Twitter Account](https://img.shields.io/twitter/follow/{{ sdk.twitterHandle }}?color=00acee&label=twitter&style=flat-square)](https://twitter.com/{{ sdk.twitterHandle }}) +[![X Account](https://img.shields.io/badge/follow-%40{{ sdk.twitterHandle|replace({'-': '--', '_': '__'})|url_encode }}-000000?logo=x&style=flat-square)](https://x.com/{{ sdk.twitterHandle }}) {% endif %} {% if sdk.discordChannel %} [![Discord](https://img.shields.io/discord/{{ sdk.discordChannel }}?label=discord&style=flat-square)]({{ sdk.discordUrl }}) @@ -22,15 +21,13 @@ ## Installation -### NPM - -To install via [NPM](https://www.npmjs.com/): +### npm ```bash -npm install {{ language.params.npmPackage }} --save +npm install {{ language.params.npmPackage }} ``` -If you're using a bundler (like [Rollup](https://rollupjs.org/) or [webpack](https://webpack.js.org/)), you can import the {{ spec.info.title }} module when you need it: +Import the modules you need. The package ships ES modules, CommonJS and TypeScript types: ```js import {{ '{' }} Client, Account {{ '}' }} from '{{ language.params.npmPackage }}'; @@ -38,19 +35,22 @@ import {{ '{' }} Client, Account {{ '}' }} from '{{ language.params.npmPackage } ### CDN -To install with a CDN (content delivery network) add the following scripts to the bottom of your tag, but before you use any {{ spec.info.title }} services: +Add the script before any code that uses the SDK. It exposes every export on the global `Appwrite` object: ```html - + + ``` {% if sdk.gettingStarted %} -{{ sdk.gettingStarted|raw }} +{{ sdk.gettingStarted|trim|raw }} {% endif %} ## Contribution -This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/master/CONTRIBUTING.md) before sending a pull-request. +This library is auto-generated by the Appwrite [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/main/CONTRIBUTING.md) before sending a pull-request. ## License diff --git a/templates/zed-extension/README.md.twig b/templates/zed-extension/README.md.twig index 43b20eff36..c064c3180c 100644 --- a/templates/zed-extension/README.md.twig +++ b/templates/zed-extension/README.md.twig @@ -1,19 +1,37 @@ # Appwrite MCP Server for Zed -Use Appwrite's hosted MCP server from Zed to manage projects and resources with the Agent Panel. Authentication uses Appwrite's browser-based OAuth flow, so the extension does not require API keys or manually entered secrets. +Use Appwrite's hosted MCP server from Zed to manage projects and resources with the Agent Panel. Authentication uses Appwrite's browser-based OAuth flow, so no API keys or manually entered secrets are required. ![Appwrite MCP successfully running in Zed](docs/appwrite-mcp-working.png) ## Installation -1. Open the Zed Extension Gallery with `zed: extensions` or from **Zed > Extensions**. -2. Search for **Appwrite MCP Server** and select **Install**. -3. Open **Settings > AI > MCP Servers** and enable **Appwrite MCP Server**. -4. Complete the Appwrite authentication flow in your browser. +This extension is not published in the Zed extension gallery. Zed connects to remote MCP servers natively, so the recommended setup needs no extension at all. + +### Add the remote server (recommended) + +1. Open **Settings > AI > MCP Servers**, select **Add Server**, then **Add Remote Server**. +2. Use this configuration: + + ```json + { + "appwrite": { + "url": "https://mcp.appwrite.io/" + } + } + ``` + +3. Complete the Appwrite authentication flow in your browser. + +The same entry can be added under `context_servers` in your settings file (`zed: open settings file`). + +### Install this extension as a dev extension + +The extension wraps the same server with [`mcp-remote`](https://www.npmjs.com/package/mcp-remote). To use it, [install Rust with rustup](https://www.rust-lang.org/tools/install), clone this repository, run `zed: install dev extension` from the Command Palette, and select the cloned folder. Then enable **Appwrite MCP Server** in **Settings > AI > MCP Servers** and complete the authentication flow in your browser. ## Enable Appwrite tools -Open the Agent Panel, select the active Agent profile, and enable the Appwrite MCP tools for that profile. You can then test the connection with: +Open the Agent Panel, select the active agent profile, and enable the Appwrite MCP tools for that profile. You can then test the connection with: > Use Appwrite to show my workspace context and list my projects. @@ -25,11 +43,11 @@ Zed asks for confirmation before tool calls by default. Review and approve write ### The browser did not open -Restart **Appwrite MCP Server** from **Settings > AI > MCP Servers**. If the browser still does not open, copy the authentication URL from the server output and open it manually. +Restart the Appwrite server from **Settings > AI > MCP Servers**. If the browser still does not open, copy the authentication URL from the server output and open it manually. ### The server status is not green -Open **Settings > AI > MCP Servers** and check the status next to **Appwrite MCP Server**. Restart the server and confirm that the extension is allowed to install the `mcp-remote` npm package. +Open **Settings > AI > MCP Servers** and check the indicator next to the Appwrite server. Restart the server. With the dev extension, also confirm that Zed was able to install the `mcp-remote` npm package. ### The OAuth session needs to be refreshed @@ -37,4 +55,10 @@ Sign out or clear the saved Appwrite MCP authorization from the server controls, ### Inspect logs -Run `zed: open log` from the Command Palette and search for `appwrite-mcp` or `mcp-remote`. +Run `zed: open log` from the Command Palette and search for `appwrite` or `mcp-remote`. + +## Learn more + +- [Appwrite in Zed](https://appwrite.io/docs/tooling/ai/agents/zed) +- [Appwrite MCP server](https://appwrite.io/docs/tooling/ai/mcp-servers) +- [MCP servers in Zed](https://zed.dev/docs/ai/mcp)