From d063456fd32330d3ff3ca5422c1d8b89e969b318 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Tue, 18 Aug 2026 09:37:51 +0530 Subject: [PATCH 1/2] chore: update AgentSkills SDK to 0.3.0 --- CHANGELOG.md | 9 + skills/appwrite-cli/SKILL.md | 852 ++++++----------------------------- 2 files changed, 137 insertions(+), 724 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b91f53..8f09267 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 0.3.0 + +* Updated: Rewrote the `appwrite-cli` skill as guidance rather than a command catalog, deferring flag listings to `appwrite --help` +* Added: When to use `appwrite.config.json` versus a one-off `appwrite client` call +* Added: Separation of authentication from project selection, including CI keys and `--force` on TTY-less runs +* Added: Cloud regional endpoints and why `whoami` keeps the account login host +* Added: Which resources belong to `pull`/`push` and which are service commands only +* Added: Generating type-safe application code from the local config with `appwrite generate` + ## 0.2.1 * Fixed: Permission and access-control wording in skills updated for TablesDB (`row`/`table` instead of `document`/`collection`) diff --git a/skills/appwrite-cli/SKILL.md b/skills/appwrite-cli/SKILL.md index f53dedb..e7494a0 100644 --- a/skills/appwrite-cli/SKILL.md +++ b/skills/appwrite-cli/SKILL.md @@ -1,816 +1,220 @@ --- name: appwrite-cli -description: Appwrite CLI skill. Use when managing Appwrite projects from the command line. Covers installation, login, project initialization, multi-file project configuration, deploying functions/sites/tables/buckets/teams/webhooks/topics, flag-based list queries, non-interactive CI/CD mode, and generating type-safe SDKs. +description: How to use the Appwrite CLI well. Covers when to use appwrite.config.json vs `appwrite client`, pull/push vs one-shot service calls, type-safe SDK and model generation, query flags, CI auth, Cloud regional endpoints, function/site variables, and traps that `--help` will not mention. Does not catalog commands — run `appwrite --help` for flags. Use whenever running `appwrite`, deploying or pulling functions/sites/tables, generating application code from a table schema, initializing or linking a project, scripting Appwrite, or when the user mentions the Appwrite CLI, appwrite.config.json, `appwrite generate`, `appwrite types`, or `appwrite client`. --- # Appwrite CLI -## Installation +`appwrite --help` already lists flags. Read it instead of guessing. -```bash -# npm -npm install -g appwrite-cli - -# macOS (Homebrew native binary) -brew tap appwrite/appwrite -brew install appwrite/appwrite/appwrite +## Config vs `client` -# macOS / Linux (script) -curl -sL https://appwrite.io/cli/install.sh | bash - -# Windows (Scoop) -scoop install https://raw.githubusercontent.com/appwrite/sdk-for-cli/master/scoop/appwrite.config.json -``` - -Verify installation: - -```bash -appwrite -v -``` +A **real project** (repo, schema, functions, deploys, CI) lives in `appwrite.config.json`. Init once. Pull and push after that. Do not `appwrite client --project-id` on every command — the config already names the project. -## Login & Initialization +A **one-off** (inspect a user, patch one row, poke a remote you will not return to) uses `appwrite client`. Do not scaffold a project for a single API call. ```bash -# Login to your account +# Good — project appwrite login +appwrite list-projects --json +appwrite init project --project-id +appwrite pull table +# edit appwrite.config.json, then: +appwrite push table --force -# Login to a self-hosted instance -appwrite login --endpoint "https://your-instance.com/v1" - -# Switch to a different saved account -appwrite login --switch +# Bad — project treated as a pile of API calls +appwrite tablesdb create-table --database-id main --table-id songs ... +appwrite tablesdb create-varchar-column --database-id main --table-id songs ... +# the next clone has no record of this -# Initialize a project (creates appwrite.config.json) -appwrite init project +# Good — one-off (already logged in) +appwrite client --project-id +appwrite users get --user-id --json -# Verify by fetching project info -appwrite projects get --project-id "" +# Bad — one-off that litters a repo +cd ~/some-unrelated-app && appwrite init project ``` -`appwrite whoami` can show `https://cloud.appwrite.io/v1` as the account login endpoint. That is expected for Appwrite Cloud login. Do not rewrite it to a regional endpoint. Only project configuration and project-scoped API calls use the region endpoint, such as `https://.cloud.appwrite.io/v1`. +No session? `appwrite client --endpoint https://.cloud.appwrite.io/v1 --key "$APPWRITE_API_KEY" --project-id `. -## Configuration +`appwrite client --project-id` writes `appwrite.config.json` in this directory (or updates one found walking up). That is how you link a folder quickly. Do not run it at the root of an unrelated repo. `APPWRITE_PROJECT_ID` / `APPWRITE_ENDPOINT` override the file without touching it — use those when you are already inside a project and need a one-shot against something else. -```bash -# Switch endpoint/project for scripted use -appwrite client --endpoint "https://.cloud.appwrite.io/v1" -appwrite client --project-id "" -``` +## Auth is not the project -> For the full list of CLI commands, see [CLI Commands](https://appwrite.io/docs/tooling/command-line/commands). -> For headless / CI/CD usage, see [Non-Interactive Mode](https://appwrite.io/docs/tooling/command-line/non-interactive). - -## appwrite.config.json - -Resources can be configured inline in `appwrite.config.json` or split into separate JSON array files using `includes`. - -```json -{ - "projectId": "", - "projectName": "Production", - "endpoint": "https://.cloud.appwrite.io/v1", - "includes": { - "functions": "appwrite/functions.json", - "sites": "appwrite/sites.json", - "webhooks": "appwrite/webhooks.json" - }, - "settings": { - "services": { - "account": true, - "databases": true, - "functions": true, - "sites": true, - "messaging": true - }, - "protocols": { - "rest": true, - "graphql": true, - "websocket": true - }, - "auth": { - "methods": { - "email-password": true, - "magic-url": true - }, - "security": { - "sessionsLimit": 10, - "passwordDictionary": true - } - } - }, - "tablesDB": [], - "tables": [], - "buckets": [], - "teams": [], - "topics": [] -} -``` - -Each `includes` value must be a relative `.json` path inside the project directory and must point to a JSON array. A resource cannot be defined both inline and in `includes`. When functions or sites are included, their `path` values are resolved relative to the include file directory. - -Example `appwrite/functions.json`: - -```json -[ - { - "$id": "", - "name": "userAuth", - "enabled": true, - "logging": true, - "runtime": "node-22", - "buildSpecification": "s-1vcpu-512mb", - "runtimeSpecification": "s-1vcpu-512mb", - "deploymentRetention": 7, - "events": [], - "schedule": "", - "timeout": 15, - "entrypoint": "src/main.js", - "commands": "npm install", - "ignore": "node_modules\n.tmp", - "path": "../functions/userAuth" - } -] -``` +| Layer | Lives in | Set with | +|---|---|---| +| Who you are (session or API key) | global CLI prefs | `appwrite login` or `appwrite client --key` | +| Which project | `appwrite.config.json` | `init project`, `pull`, or `client --project-id` | -### Pull and push project configuration +`init project` talks to the **console**. It needs a login session. An API key cannot list organizations. ```bash -# Pull or push everything -appwrite pull all --all -appwrite push all --all +# Good — CI against a checked-in config +appwrite client --key "$APPWRITE_API_KEY" +appwrite push function --force -# Pull or push individual resource groups -appwrite pull settings -appwrite push settings -appwrite pull webhooks -appwrite push webhooks -appwrite pull functions -appwrite push functions +# Bad — CI that bakes the key into the repo +appwrite client --key 'standard_....' +# and commits appwrite.config.json with secrets inside ``` -## Deploying Functions +Env beats the config: `APPWRITE_PROJECT_ID`, `APPWRITE_ENDPOINT`, `APPWRITE_ORGANIZATION_ID`. Check in the config (no secrets). Put keys in the environment. -```bash -# Create a new function -appwrite init functions +`--force` skips prompts. Agents and CI have no TTY, so a push that needs confirmation fails without it (`Pass --force instead`). Ask the user, then pass `--force`. Do not use it to skip a change table whose local column is empty. -# Pull existing functions from Console -appwrite pull functions +`appwrite login --switch` rotates saved accounts. `appwrite client --debug` prints the effective endpoint/project with credentials masked. `appwrite client --reset` signs out of everything. -# Deploy functions -appwrite push functions -``` +## Cloud endpoints -### Function configuration in appwrite.config.json - -```json -{ - "functions": [ - { - "$id": "", - "name": "userAuth", - "enabled": true, - "logging": true, - "runtime": "node-22", - "buildSpecification": "s-1vcpu-512mb", - "runtimeSpecification": "s-1vcpu-512mb", - "deploymentRetention": 7, - "scopes": [], - "events": [], - "schedule": "", - "timeout": 15, - "entrypoint": "src/main.js", - "commands": "npm install", - "ignore": "node_modules\n.tmp", - "path": "functions/userAuth" - } - ] -} -``` - -Key function config fields: - -| Field | Description | -|-------|-------------| -| `enabled` | Enables or disables the function. Disabled functions cannot be executed. | -| `logging` | Stores execution logs for debugging and observability. | -| `runtime` | Runtime used to execute the function, such as `node-22`. | -| `buildSpecification` | Compute specification used while building the deployment. | -| `runtimeSpecification` | Compute specification used while running executions. | -| `deploymentRetention` | Number of days to retain old deployments before they are automatically deleted. | -| `scopes` | API scopes granted to the function's generated execution key. | -| `events` | Event patterns that trigger the function. | -| `schedule` | Cron expression for scheduled execution. Empty string disables scheduling. | -| `timeout` | Maximum execution duration in seconds. | -| `entrypoint` | File inside `path` that starts the function. | -| `commands` | Build/install command run before deployment. | -| `ignore` | Extra newline-separated ignore rules used when packaging code. `.gitignore` is read automatically. | -| `path` | Local function source directory. If configured through `includes`, this is resolved relative to the include file. | - -### Function commands - -| Command | Description | -|---------|-------------| -| `appwrite functions list` | List all functions | -| `appwrite functions create` | Create a new function | -| `appwrite functions get --function-id ` | Get a function by ID | -| `appwrite functions update --function-id ` | Update a function | -| `appwrite functions delete --function-id ` | Delete a function | -| `appwrite functions list-runtimes` | List all active runtimes | -| `appwrite functions list-deployments --function-id ` | List deployments | -| `appwrite functions create-deployment --function-id ` | Upload a new deployment | -| `appwrite functions update-deployment --function-id --deployment-id ` | Set active deployment | -| `appwrite functions delete-deployment --function-id --deployment-id ` | Delete a deployment | -| `appwrite functions download-deployment --function-id --deployment-id ` | Download deployment | -| `appwrite functions create-execution --function-id ` | Trigger execution | -| `appwrite functions list-executions --function-id ` | List execution logs | -| `appwrite functions get-execution --function-id --execution-id ` | Get execution log | -| `appwrite functions list-variables --function-id ` | List variables | -| `appwrite functions create-variable --function-id --key --value ` | Create variable | -| `appwrite functions update-variable --function-id --variable-id --key --value ` | Update variable | -| `appwrite functions delete-variable --function-id --variable-id ` | Delete variable | - -### List functions with flag-based queries - -Prefer the query flags for common filtering, sorting, and pagination. Use `--queries` only for raw Appwrite JSON query strings or advanced automation. +`appwrite whoami` showing `https://cloud.appwrite.io/v1` is the **account** login host. Leave it. Project API calls use the region host (`https://fra.cloud.appwrite.io/v1`, and so on). `init project` and `client --project-id` pin that region into the config. Self-hosted: one endpoint for both. ```bash -appwrite functions list \ - --where 'name=api' \ - --sort-desc '$createdAt' \ - --limit 10 \ - --offset 0 \ - --json - -appwrite functions list-deployments \ - --function-id \ - --limit 5 \ - --cursor-after -``` - -### Trigger a function with body +# Good — project work uses the config's regional endpoint +cat appwrite.config.json # "endpoint": "https://fra.cloud.appwrite.io/v1" -```bash -appwrite functions create-execution \ - --function-id \ - --body '{"key": "value"}' +# Bad — "fixing" whoami +appwrite client --endpoint https://fra.cloud.appwrite.io/v1 +# now login/session calls go to a region host they do not belong on ``` -### Local development - -```bash -appwrite run functions -``` +## Schema vs rows -### Deployment activation +| Pull / push (config) | Service commands (not in the config) | +|---|---| +| settings, functions, sites, tables and columns, buckets, teams, webhooks, topics | rows, users, files, executions, messages | -```bash -# Deploy and activate the deployment -appwrite push functions --function-id --activate +If it should survive a fresh clone, it belongs in the config. Edit the file, then push. Creating the same resources with `tablesdb create-*` or `functions create` bypasses the file the next `pull` / `push` expects. -# Deploy without switching live traffic -appwrite push functions --function-id --activate=false -``` +`databases` is deprecated. Use `tablesdb` and `push table`. -### Function variables +If the change table shows remote values against empty local, the config is missing those fields. Pull that resource, then push. Do not `--force` through it, and do not pull everything as a ritual — `pull settings` is slow. -Do not define function variables in `appwrite.config.json`. Put them in a `.env` file inside the configured function `path`. Variables are saved after they are pushed, so use `--with-variables` only when you want to create, replace, or remove the remote variables from the local `.env` file. - -```bash -# functions/userAuth/.env -PUBLIC_FLAG=enabled -SECRET_TOKEN=replace-me - -# Sync function variables from .env -appwrite push functions --function-id --with-variables - -# Push code without changing saved variables -appwrite push functions --function-id - -# Run locally with variables fetched from function settings -appwrite run functions --with-variables -``` - -## Deploying Sites - -```bash -# Create a new site -appwrite init sites - -# Pull existing sites from Console -appwrite pull sites - -# Deploy sites -appwrite push sites -``` - -### Site configuration in appwrite.config.json - -```json -{ - "sites": [ - { - "$id": "", - "name": "Documentation template", - "logging": true, - "framework": "astro", - "timeout": 30, - "installCommand": "npm install", - "buildCommand": "npm run build", - "outputDirectory": "./dist", - "buildSpecification": "s-1vcpu-512mb", - "runtimeSpecification": "s-1vcpu-512mb", - "buildRuntime": "node-22", - "adapter": "ssr", - "fallbackFile": "", - "startCommand": "npm run start", - "deploymentRetention": 7, - "path": "sites/documentation-template" - } - ] -} +```text + id │ key │ remote │ local + ───────────────┼─────────────────┼────────┼─────── + Service │ account │ true │ + Auth method │ email-password │ true │ ``` -Key site config fields: - -| Field | Description | -|-------|-------------| -| `logging` | Stores site request and build logs. | -| `framework` | Framework preset used for build and deployment defaults. | -| `timeout` | Maximum request or function duration in seconds for server-rendered sites. | -| `installCommand` | Command used to install dependencies. | -| `buildCommand` | Command used to build the site. | -| `outputDirectory` | Directory containing static build output. | -| `buildSpecification` | Compute specification used while building the deployment. | -| `runtimeSpecification` | Compute specification used while serving runtime workloads. | -| `buildRuntime` | Runtime used to build the site, such as `node-22`. | -| `adapter` | Deployment adapter, such as static or SSR behavior. | -| `fallbackFile` | Fallback file for SPA routing or missing routes. | -| `startCommand` | Command used to start server-rendered output. | -| `deploymentRetention` | Number of days to retain old deployments before they are automatically deleted. | -| `path` | Local site source directory. If configured through `includes`, this is resolved relative to the include file. | - -### Site commands - -| Command | Description | -|---------|-------------| -| `appwrite sites list` | List all sites | -| `appwrite sites create` | Create a new site | -| `appwrite sites get --site-id ` | Get a site by ID | -| `appwrite sites update --site-id ` | Update a site | -| `appwrite sites delete --site-id ` | Delete a site | -| `appwrite sites list-frameworks` | List available frameworks | -| `appwrite sites list-specifications` | List allowed specs | -| `appwrite sites list-templates` | List available templates | -| `appwrite sites get-template --template-id ` | Get template details | -| `appwrite sites list-deployments --site-id ` | List deployments | -| `appwrite sites create-deployment --site-id ` | Create deployment | -| `appwrite sites get-deployment --site-id --deployment-id ` | Get deployment | -| `appwrite sites delete-deployment --site-id --deployment-id ` | Delete deployment | -| `appwrite sites update-site-deployment --site-id --deployment-id ` | Set active deployment | -| `appwrite sites update-deployment-status --site-id --deployment-id ` | Cancel ongoing build | -| `appwrite sites list-variables --site-id ` | List variables | -| `appwrite sites create-variable --site-id --key --value ` | Create variable | -| `appwrite sites update-variable --site-id --variable-id --key --value ` | Update variable | -| `appwrite sites delete-variable --site-id --variable-id ` | Delete variable | -| `appwrite sites list-logs --site-id ` | List request logs | -| `appwrite sites get-log --site-id --log-id ` | Get a log | -| `appwrite sites delete-log --site-id --log-id ` | Delete a log | - -### Site variables - -Do not define site variables in `appwrite.config.json`. Put them in a `.env` file inside the configured site `path`. Variables are saved after they are pushed, so use `--with-variables` only when you want to create, replace, or remove the remote variables from the local `.env` file. - ```bash -# sites/documentation-template/.env -PUBLIC_SITE_NAME=docs - -appwrite push sites --site-id --with-variables +# Good — local column was empty, so sync first, then push +appwrite pull settings +appwrite push settings --force -# Push code without changing saved variables -appwrite push sites --site-id +# Bad — empty local, forced through +appwrite push settings --force ``` -## Managing Tables (Databases) +`push all --all --force` pushes every resource. Scope it (`push function --function-id api`) unless you mean that. -```bash -# Create a new table -appwrite init tables +`unique()` is fine for a one-shot row or user. Resources you will push need a **stable** `$id` in the config so the next pull matches. -# Pull existing tables from Console -appwrite pull tables +## Type-safe application code -# Deploy tables -appwrite push tables -``` +When writing application code against TablesDB, inspect `appwrite.config.json` before inventing interfaces, database IDs, table IDs, or column names. The generators read the local config; they do not inspect the remote schema. A stale config produces stale code. -### Table configuration in appwrite.config.json - -```json -{ - "tablesDB": [ - { - "$id": "", - "name": "songs", - "enabled": true - } - ], - "tables": [ - { - "$id": "", - "$permissions": ["create(\"any\")", "read(\"any\")"], - "databaseId": "", - "name": "music", - "enabled": true, - "rowSecurity": false, - "columns": [ - { - "key": "title", - "type": "varchar", - "required": true, - "size": 255 - } - ], - "indexes": [] - } - ] -} -``` +If the remote schema is the source of truth, update the config first with `appwrite pull table`. Do not pull over local, unpushed schema edits. If the local config is ahead, generate from it as-is. -### Database commands (TablesDB) - -| Command | Description | -|---------|-------------| -| `appwrite tables-db list-tables --database-id ` | List tables | -| `appwrite tables-db create-table --database-id ` | Create table | -| `appwrite tables-db get-table --database-id --table-id ` | Get table | -| `appwrite tables-db update-table --database-id --table-id ` | Update table | -| `appwrite tables-db delete-table --database-id --table-id ` | Delete table | -| `appwrite tables-db list-columns --database-id --table-id ` | List columns | -| `appwrite tables-db get-column --database-id --table-id --key ` | Get column | -| `appwrite tables-db delete-column --database-id --table-id --key ` | Delete column | -| `appwrite tables-db list-column-indexes --database-id --table-id ` | List indexes | -| `appwrite tables-db create-column-index --database-id --table-id ` | Create index | -| `appwrite tables-db delete-column-index --database-id --table-id --key ` | Delete index | - -### Column type commands - -> **Note:** The legacy `string` type is deprecated. Use explicit string column types instead. - -| Command | Description | -|---------|-------------| -| `create-varchar-column` | Varchar column — inline storage, fully indexable (max 16,383 chars, size ≤ 768 for full index) | -| `create-text-column` | Text column — off-page storage, prefix index only (max 16,383 chars) | -| `create-mediumtext-column` | Mediumtext column — off-page storage (max ~4M chars) | -| `create-longtext-column` | Longtext column — off-page storage (max ~1B chars) | -| `create-boolean-column` | Boolean column | -| `create-integer-column` | Integer column (optional min/max) | -| `create-float-column` | Float column (optional min/max) | -| `create-email-column` | Email column | -| `create-url-column` | URL column | -| `create-ip-column` | IP address column | -| `create-datetime-column` | Datetime column (ISO 8601) | -| `create-enum-column` | Enum column (whitelist of accepted values) | -| `create-relationship-column` | Relationship column | - -All column commands use `appwrite tables-db --database-id --table-id `. - -### Row operations +For TypeScript, prefer `appwrite generate`. It emits a complete TablesDB wrapper: database and table choices, create/update payloads, returned rows, query fields, and query values are checked by TypeScript. This is stronger than generated model interfaces alone. ```bash -# Create a row -appwrite tables-db create-row \ - --database-id "" --table-id "" \ - --row-id 'unique()' --data '{ "title": "Hello World" }' \ - --permissions 'read("any")' 'write("team:abc")' - -# List rows (JSON output) -appwrite tables-db list-rows \ - --database-id "" --table-id "" --json - -# Get a row -appwrite tables-db get-row \ - --database-id "" --table-id "" --row-id "" +appwrite generate ``` -### List rows and documents with query flags +Use the generated API instead of dropping back to raw string IDs and handwritten payload types: -Use `--where`, `--sort-asc`, `--sort-desc`, `--limit`, `--offset`, `--cursor-after`, and `--cursor-before` on list commands. Row and document list/get commands also support repeated `--select` flags. - -```bash -appwrite tables-db list-rows \ - --database-id "" \ - --table-id "" \ - --where 'status=active' \ - --where 'score>=10' \ - --sort-asc 'name' \ - --select '$id' \ - --select 'name' \ - --limit 25 \ - --json - -appwrite databases list-documents \ - --database-id "" \ - --collection-id "" \ - --where 'email!=null' \ - --cursor-before "" -``` - -`--where` parses strings, numbers, booleans, `null`, and JSON arrays. Supported operators are `=`, `!=`, `>`, `>=`, `<`, and `<=`. +```typescript +import { databases, type Songs } from "./generated/appwrite/index.js"; -## Managing Buckets (Storage) +// Database lookup uses its ID; table lookup uses its name from the config. +const songs = databases.use("main").use("Songs"); -```bash -# Create a new bucket -appwrite init buckets - -# Pull existing buckets from Console -appwrite pull buckets +const page = await songs.list({ + queries: (query) => [ + query.equal("published", true), + query.orderDesc("createdAt"), + query.limit(20), + ], +}); -# Deploy buckets -appwrite push buckets +const first: Songs | undefined = page.rows[0]; ``` -### Storage commands - -| Command | Description | -|---------|-------------| -| `appwrite storage list-buckets` | List all buckets | -| `appwrite storage create-bucket` | Create a bucket | -| `appwrite storage get-bucket --bucket-id ` | Get a bucket | -| `appwrite storage update-bucket --bucket-id ` | Update a bucket | -| `appwrite storage delete-bucket --bucket-id ` | Delete a bucket | -| `appwrite storage list-files --bucket-id ` | List files | -| `appwrite storage create-file --bucket-id ` | Upload a file | -| `appwrite storage get-file --bucket-id --file-id ` | Get file metadata | -| `appwrite storage delete-file --bucket-id --file-id ` | Delete a file | -| `appwrite storage get-file-download --bucket-id --file-id ` | Download a file | -| `appwrite storage get-file-preview --bucket-id --file-id ` | Get image preview | -| `appwrite storage get-file-view --bucket-id --file-id ` | View file in browser | - -## Managing Teams - -```bash -# Create a new team -appwrite init teams - -# Pull existing teams from Console -appwrite pull teams - -# Deploy teams -appwrite push teams -``` +Do not guess the literals in that example: read the generated types or the config. In particular, `.use()` for a table takes its `name`, which may differ from its `$id`. Let compilation expose a misspelled table, column, or wrong query value. Run the project's type checker after generation. -### Team commands +`generate` currently provides the full wrapper for TypeScript. It detects client versus server output from the installed Appwrite package. Server output reads `APPWRITE_API_KEY`; never put that key in generated constants or commit it. Override language, import source, module extension, or client/server mode only when detection is wrong—read `appwrite generate --help` for those flags. -| Command | Description | -|---------|-------------| -| `appwrite teams list` | List all teams | -| `appwrite teams create` | Create a team | -| `appwrite teams get --team-id ` | Get a team | -| `appwrite teams update-name --team-id ` | Update team name | -| `appwrite teams delete --team-id ` | Delete a team | -| `appwrite teams list-memberships --team-id ` | List members | -| `appwrite teams create-membership --team-id ` | Invite a member | -| `appwrite teams update-membership --team-id --membership-id ` | Update member roles | -| `appwrite teams delete-membership --team-id --membership-id ` | Remove a member | -| `appwrite teams get-prefs --team-id ` | Get team preferences | -| `appwrite teams update-prefs --team-id ` | Update team preferences | +For another supported language, or when the project deliberately uses the regular SDK directly, use `appwrite types `. It supports TypeScript (`ts`), JavaScript (`js`), PHP (`php`), Kotlin (`kotlin`), Swift (`swift`), Java (`java`), Dart (`dart`), and C# (`cs`). Pass these short values to `--language`; names such as `typescript` and `csharp` are not the command's accepted values. Generated files type row data, but they do **not** type-check raw database/table IDs or `Query` calls: -## Managing Webhooks +For TypeScript, pass a `.ts` destination when the result will be imported as a module. Passing a directory instead creates `appwrite.d.ts` inside it. ```bash -# Pull existing webhooks from Console -appwrite pull webhooks - -# Deploy configured webhooks -appwrite push webhooks +appwrite types ./src/appwrite-types.ts --language ts ``` -### Webhook configuration in `appwrite/webhooks.json` - -```json -[ - { - "$id": "", - "name": "Deploy events", - "url": "https://example.com/appwrite/webhook", - "events": ["functions.*.deployments.*.create"], - "enabled": true, - "tls": true - } -] +```typescript +import { Client, TablesDB } from "appwrite"; +import type { Songs } from "./appwrite-types.js"; + +// Read these values from appwrite.config.json and expose them through the +// application's existing configuration mechanism. +const client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject(""); +const tablesDB = new TablesDB(client); + +const page = await tablesDB.listRows({ + databaseId: "main", // still an unchecked string + tableId: "songs", // still an unchecked string +}); ``` -### Webhook commands - -| Command | Description | -|---------|-------------| -| `appwrite webhooks list` | List webhooks | -| `appwrite webhooks create` | Create a webhook | -| `appwrite webhooks get --webhook-id ` | Get a webhook | -| `appwrite webhooks update --webhook-id ` | Update a webhook | -| `appwrite webhooks delete --webhook-id ` | Delete a webhook | - -## Managing Topics (Messaging) - -```bash -# Create a new topic -appwrite init topics +Do not describe `types --strict` as “full type safety.” It only converts field names to the target language's naming conventions. Use `generate` when a fully typed TypeScript table API is the goal. -# Pull existing topics from Console -appwrite pull topics +Generated code is derived output. Do not patch it to fix a schema or naming problem; fix `appwrite.config.json` or the generator inputs and regenerate. After every table or column change, rerun the same generation command the repository uses and run its formatter/type checker. Preserve the repository's existing output path and check-in convention. -# Deploy topics -appwrite push topics -``` +## Functions and sites -### Messaging commands - -| Command | Description | -|---------|-------------| -| `appwrite messaging list-messages` | List all messages | -| `appwrite messaging create-email` | Create email message | -| `appwrite messaging create-push` | Create push notification | -| `appwrite messaging create-sms` | Create SMS message | -| `appwrite messaging get-message --message-id ` | Get a message | -| `appwrite messaging delete --message-id ` | Delete a message | -| `appwrite messaging list-topics` | List all topics | -| `appwrite messaging create-topic` | Create a topic | -| `appwrite messaging get-topic --topic-id ` | Get a topic | -| `appwrite messaging update-topic --topic-id ` | Update a topic | -| `appwrite messaging delete-topic --topic-id ` | Delete a topic | -| `appwrite messaging list-subscribers --topic-id ` | List subscribers | -| `appwrite messaging create-subscriber --topic-id ` | Add subscriber | -| `appwrite messaging delete-subscriber --topic-id --subscriber-id ` | Remove subscriber | - -## User Management +Variables live in `/.env`, not in `appwrite.config.json`. `--with-variables` **replaces** the remote set from that file. Omit it unless you intend to sync secrets. ```bash -# Create a user -appwrite users create --user-id "unique()" \ - --email hello@appwrite.io +# Good — ship code, leave remote vars alone +appwrite push function --function-id api --activate --force -# List users -appwrite users list +# Bad — remote vars you did not list locally are gone +appwrite push function --function-id api --with-variables --force -# Get a user -appwrite users get --user-id "" - -# Delete a user -appwrite users delete --user-id "" +# Good — deploy without switching live traffic +appwrite push function --function-id api --activate=false --force ``` -## Project Management +`--async` returns before the build finishes. Local: `appwrite run function`. -Project-level commands use the singular `project` service for current-project operations that do not need `--project-id`. +## Queries and output -```bash -# Project settings and policies -appwrite project update-service --service-id functions --enabled true -appwrite project update-protocol --protocol-id rest --enabled true -appwrite project list-policies -appwrite project get-policy --policy-id "" - -# OAuth2 providers -appwrite project list-o-auth-2-providers -appwrite project get-o-auth-2-provider --provider github -appwrite project update-o-auth-2-git-hub --enabled true - -# Mock phones and short-lived API keys -appwrite project create-mock-phone --phone "+12025550123" --otp "123456" -appwrite project list-mock-phones -appwrite project create-ephemeral-key -``` - -## Generate Type-Safe SDK +Prefer `--filter`, `--sort-asc` / `--sort-desc`, `--limit`, `--select`, `--cursor-after`. `--where` is deprecated. `--queries` only for Query JSON the flags cannot express. ```bash -# Auto-detect language and generate -appwrite generate - -# Specify output directory -appwrite generate --output ./src/generated - -# Specify language -appwrite generate --language typescript - -# Override generated import settings -appwrite generate --appwrite-import-source node-appwrite --import-extension .js -``` - -Generated files: - -| File | Description | -|------|-------------| -| `types.ts` | Type definitions from your database schema | -| `databases.ts` | Typed database helpers for querying and mutating rows | -| `constants.ts` | Configuration constants (endpoint, project ID) | -| `index.ts` | Entry point that exports all helpers | +# Good +appwrite users list \ + --filter 'emailVerification=true' \ + --sort-desc '$createdAt' \ + --limit 20 \ + --json -Usage: - -```typescript -import { databases } from "./generated/appwrite"; - -const customers = databases.use("main").use("customers"); - -// Create -const customer = await customers.create({ - name: "Walter O' Brian", - email: "walter@example.com" -}); - -// List with typed queries -const results = await customers.list({ - queries: (q) => [ - q.equal("name", "Walter O' Brian"), - q.orderDesc("$createdAt"), - q.limit(10) - ] -}); - -// Update -await customers.update("customer-id-123", { - email: "walter@scorpion.com" -}); - -// Delete -await customers.delete("customer-id-123"); - -// Bulk create -await customers.createMany([ - { name: "Walter O' Brian", email: "walter@example.com" }, - { name: "Paige Dineen", email: "paige@example.com" } -]); -``` - -## Non-Interactive / CI/CD Mode - -For headless automation, see the [Non-Interactive Mode docs](https://appwrite.io/docs/tooling/command-line/non-interactive). - -### Deploy non-interactively - -```bash -# Push everything -appwrite push all --all --force - -# Push specific resources -appwrite push functions --all --force -appwrite push functions --function-id --force -appwrite push sites --all --force -appwrite push tables --all --force -appwrite push teams --all --force -appwrite push buckets --all --force -appwrite push webhooks --all --force -appwrite push topics --all --force +# Bad +appwrite users list --queries '[{"method":"equal","attribute":"emailVerification","values":[true]}]' ``` -## Global Command Options +`--filter` parses `true` / `false` / `null`, numbers, and JSON arrays. Repeat the flag to AND. List pages cap at 100; prefer `--cursor-after ` over a large `--offset`. -| Option | Description | -|--------|-------------| -| `-v, --version` | Output version number | -| `-V, --verbose` | Show complete error log | -| `-j, --json` | Output in JSON format | -| `-f, --force` | Confirm all warnings | -| `-a, --all` | Select all resources | -| `--id [id...]` | Pass a list of IDs | -| `--report` | Generate GitHub error report link | -| `--console` | Get direct link to Console | -| `--open` | Open Console link in browser | -| `-h, --help` | Display help | +`--json` for scripts (empty fields dropped). `--raw` for the unfiltered payload. Secrets stay redacted unless `--show-secrets`. -## Maintenance Commands +## The config file itself -```bash -# Update CLI using the detected install method -appwrite update - -# Show manual update instructions -appwrite update --manual +The CLI walks **up** from cwd looking for `appwrite.config.json` (or the legacy `appwrite.json`). `push` from `functions/api/` still hits the project root. A stray config in a parent directory will capture you. -# Install shell completions -appwrite completion install -``` +Split large projects with `includes` — each value is a relative `.json` array. A resource cannot be both inline and included. Function and site `path` values resolve relative to the include file, not the repo root. -## Examples - -```bash -# List users with JSON output -appwrite users list --json - -# Get verbose error output -appwrite users list --verbose - -# View a row in the Console -appwrite tables-db get-row \ - --database-id "" \ - --table-id "" \ - --row-id "" \ - --console --open - -# Generate error report -appwrite login --report -``` +Do not invent the file from memory. `init project` or `pull` writes a valid one. Then edit. From e4246f673c8ae3df8f7ab2b8097f04c2d4b2acbe Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sat, 17 Oct 2026 15:32:30 +0100 Subject: [PATCH 2/2] docs: refresh README --- README.md | 82 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 49 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index a650d0a..74d7ff7 100644 --- a/README.md +++ b/README.md @@ -1,53 +1,57 @@ -# Appwrite AgentSkills +# Appwrite Agent Skills -![License](https://img.shields.io/github/license/appwrite/agent-skills.svg?style=flat-square) -![Version](https://img.shields.io/badge/api%20version-1.9.x-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) -[![Twitter Account](https://img.shields.io/twitter/follow/appwrite?color=00acee&label=twitter&style=flat-square)](https://twitter.com/appwrite) +![License](https://img.shields.io/badge/license-BSD--3--Clause-blue.svg?style=flat-square) +![Version](https://img.shields.io/badge/api%20version-2.5.x-blue.svg?style=flat-square) +[![X Account](https://img.shields.io/badge/follow-%40appwrite-000000?logo=x&style=flat-square)](https://x.com/appwrite) [![Discord](https://img.shields.io/discord/564160730845151244?label=discord&style=flat-square)](https://appwrite.io/discord) -**This SDK is compatible with Appwrite server version 1.9.x. For older versions, please check [previous releases](https://github.com/appwrite/agent-skills.git/releases).** - -Appwrite is an open-source backend as a service server that abstracts and simplifies complex and repetitive development tasks behind a very simple to use REST API. Appwrite aims to help you develop your apps faster and in a more secure way. Use the AgentSkills SDK to integrate your app with the Appwrite server to easily start interacting with all of Appwrite backend APIs and tools. For full API documentation and tutorials go to [https://appwrite.io/docs](https://appwrite.io/docs) +Appwrite 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 Appwrite: client setup, authentication, TablesDB queries, storage, realtime, functions, and the Appwrite CLI. The skills follow the [Agent Skills](https://agentskills.io) open standard. ![Appwrite](https://github.com/appwrite/appwrite/raw/main/public/images/github.png) +## Installation -## Getting Started - -Agent Skills to help developers using AI coding agents with Appwrite. Agent Skills are folders of instructions, scripts, and resources that agents like Claude Code, Cursor, GitHub Copilot, and others can discover and use to work more accurately and efficiently. +Install the skills with the [Skills CLI](https://github.com/vercel-labs/skills): -These skills follow the Agent Skills Open Standard: https://agentskills.io/home - -### Install the skills +```bash +npx skills add appwrite/skills +``` -Install directly with the Skills CLI: +The CLI asks which skills to install, which agents should use them, and whether to install them in the current project or globally. To skip the prompts, pass the choices as flags: ```bash -npx skills add appwrite/agent-skills +npx skills add appwrite/skills --skill appwrite-typescript --skill appwrite-cli --agent claude-code --global --yes ``` -This installs the packaged `appwrite-*` skills into your local skills directory. +Run `npx skills add appwrite/skills --list` to see every skill in the repository without installing anything. -### Available language skills +If you use Claude Code, Cursor, or Codex, the Appwrite plugin for that tool bundles these skills together with the hosted Appwrite MCP server: -- `appwrite-typescript` -- `appwrite-dart` -- `appwrite-kotlin` -- `appwrite-swift` -- `appwrite-php` -- `appwrite-python` -- `appwrite-ruby` -- `appwrite-go` -- `appwrite-dotnet` +- [Claude Code plugin](https://github.com/appwrite/claude-plugin) +- [Cursor plugin](https://github.com/appwrite/cursor-plugin) +- [Codex plugin](https://github.com/appwrite/codex-plugin) -### Usage +## Available skills -Skills are automatically available once installed. The agent will use them when relevant tasks are detected. +| Skill | Use it for | +| --- | --- | +| `appwrite-typescript` | Web, React Native, Node.js, and Deno apps | +| `appwrite-dart` | Flutter apps and Dart servers | +| `appwrite-kotlin` | Android apps and Kotlin/JVM servers | +| `appwrite-swift` | Apple platform apps and Swift servers | +| `appwrite-php` | PHP servers, including Laravel and Symfony | +| `appwrite-python` | Python servers, including Django, Flask, and FastAPI | +| `appwrite-ruby` | Ruby servers, including Rails and Sinatra | +| `appwrite-go` | Go servers | +| `appwrite-rust` | Rust servers | +| `appwrite-dotnet` | C# and .NET servers | +| `appwrite-cli` | The Appwrite CLI: project config, deployments, and code generation | -### Prompt examples +## Usage -Use these as copy-paste prompt starters. +Agents load a skill automatically when a task matches its description. To make sure a specific skill is used, name it in your prompt. + +### Prompt examples #### TypeScript (server-side) @@ -90,7 +94,7 @@ Prefer dependency injection for the Appwrite client. ```text Use the appwrite-go skill. -Implement a CLI command that creates a document-style row, then reads it back and prints JSON output. +Implement a CLI command that creates a row in TablesDB, then reads it back and prints JSON output. Use context timeouts and structured error messages. ``` @@ -102,6 +106,13 @@ Generate Android repository code to paginate rows using cursor queries and expos Keep UI concerns out of the data layer. ``` +#### Appwrite CLI + +```text +Use the appwrite-cli skill. +Pull the functions in my project, add a new Node.js function that runs on a schedule, and deploy it. +``` + #### Migration prompt (Databases -> TablesDB) ```text @@ -110,10 +121,15 @@ Migrate this existing Databases-based code to TablesDB APIs. Keep behavior identical and list each API mapping you changed. ``` +## Learn more + +- [Appwrite skills documentation](https://appwrite.io/docs/tooling/ai/skills) +- [Appwrite 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