{"id":"73e7f201-1e86-4c4d-a771-713aee0419a4","entityType":"agent","slug":"clawhub-techstylex-supabase-skills","name":"Volcengine Supabase","canonicalUrl":"https://www.xpersona.co/agent/clawhub-techstylex-supabase-skills","canonicalPath":"/agent/clawhub-techstylex-supabase-skills","generatedAt":"2026-10-11T14:14:10.217Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-11T11:49:30.349Z","emptyReason":null},"description":"Manage Volcengine Supabase workspaces, branches, SQL queries, migrations, Edge Functions, Storage, and TypeScript type generation via a local CLI. Run uv run... Skill: Volcengine Supabase Owner: techstylex Summary: Manage Volcengine Supabase workspaces, branches, SQL queries, migrations, Edge Functions, Storage, and TypeScript type generation via a local CLI. Run uv run... Tags: latest:1.0.0 Version history: v1.0.0 | 2026-03-12T14:25:41.318Z | user Initial release of volcengine-supabase. - Manage Volcengine Supabase workspaces, branches, SQL queries, migrations, Edge Functio","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.1K downloads reported by the source. Last updated 10/11/2026.","installCommand":"clawhub skill install s1730g4e9pkyngkq429k6axjcd83hp97:supabase-skills","sourceUrl":"https://clawhub.ai/techstylex/supabase-skills","homepage":"https://clawhub.ai/techstylex/skills/supabase-skills","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/techstylex/supabase-skills","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/techstylex/skills/supabase-skills","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":61,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"Manage Volcengine Supabase workspaces, branches, SQL queries, migrations, Edge Functions, Storage, and TypeScript type generation via a local CLI. Run uv run..."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-11T11:49:30.349Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T11:49:30.349Z","emptyReason":null},"stars":null,"forks":null,"downloads":1072,"packageName":null,"latestVersion":"1.0.0","tractionLabel":"1.1K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T11:49:30.267Z","emptyReason":null},"lastUpdatedAt":"2026-10-11T11:49:30.349Z","lastCrawledAt":"2026-10-11T11:49:30.267Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-12T11:49:30.267Z","lastVerifiedAt":null,"highlights":[{"version":"1.0.0","createdAt":"2026-03-12T14:25:41.318Z","changelog":"Initial release of volcengine-supabase. - Manage Volcengine Supabase workspaces, branches, SQL queries, migrations, Edge Functions, and Storage via local CLI commands. - Provides real-time results by invoking scripts/call_volcengine_supabase.py. - Supports common operations such as workspace listing, SQL execution, migration management, Edge Function deployment, and storage bucket creation. - Includes detailed instructions, usage examples, and best practices for safe and effective management. - Offers references and guides for application integration, schema design, RLS, and Edge Function development.","fileCount":33,"zipByteSize":53812}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s1730g4e9pkyngkq429k6axjcd83hp97:supabase-skills","setupComplexity":"low","setupSteps":["Setup complexity is LOW. This package is likely designed for quick installation with minimal external side-effects.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-techstylex-supabase-skills/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-techstylex-supabase-skills/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-techstylex-supabase-skills/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-techstylex-supabase-skills/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-techstylex-supabase-skills/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-techstylex-supabase-skills/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-11T14:14:10.216Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-techstylex-supabase-skills/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-techstylex-supabase-skills/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-techstylex-supabase-skills/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-techstylex-supabase-skills/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-11T11:49:30.349Z","emptyReason":null},"readme":"Skill: Volcengine Supabase\n\nOwner: techstylex\n\nSummary: Manage Volcengine Supabase workspaces, branches, SQL queries, migrations, Edge Functions, Storage, and TypeScript type generation via a local CLI. Run uv run...\n\nTags: latest:1.0.0\n\nVersion history:\n\nv1.0.0 | 2026-03-12T14:25:41.318Z | user\n\nInitial release of volcengine-supabase.\n\n- Manage Volcengine Supabase workspaces, branches, SQL queries, migrations, Edge Functions, and Storage via local CLI commands.\n- Provides real-time results by invoking scripts/call_volcengine_supabase.py.\n- Supports common operations such as workspace listing, SQL execution, migration management, Edge Function deployment, and storage bucket creation.\n- Includes detailed instructions, usage examples, and best practices for safe and effective management.\n- Offers references and guides for application integration, schema design, RLS, and Edge Function development.\n\nArchive index:\n\nArchive v1.0.0: 33 files, 53812 bytes\n\nFiles: _meta.json (134b), agents/openai.yaml (885b), references/app-integration-guide.md (10592b), references/edge-function-dev-guide.md (9531b), references/rls-guide.md (6246b), references/schema-guide.md (6886b), references/sql-playbook.md (5042b), references/tool-reference.md (2179b), references/workflows.md (878b), requirements.txt (130b), scripts/call_volcengine_supabase.py (11190b), scripts/volcengine_supabase/__init__.py (692b), scripts/volcengine_supabase/config.py (4082b), scripts/volcengine_supabase/models/__init__.py (1040b), scripts/volcengine_supabase/models/database.py (1111b), scripts/volcengine_supabase/models/edge_function.py (1244b), scripts/volcengine_supabase/models/storage.py (986b), scripts/volcengine_supabase/models/workspace.py (1159b), scripts/volcengine_supabase/platform/__init__.py (761b), scripts/volcengine_supabase/platform/aidap_client.py (20063b), scripts/volcengine_supabase/platform/supabase_client.py (5036b), scripts/volcengine_supabase/tools/__init__.py (936b), scripts/volcengine_supabase/tools/base.py (2752b), scripts/volcengine_supabase/tools/database_tools.py (10876b), scripts/volcengine_supabase/tools/edge_function_tools.py (10827b), scripts/volcengine_supabase/tools/storage_tools.py (4580b), scripts/volcengine_supabase/tools/workspace_tools.py (18704b), scripts/volcengine_supabase/utils/__init__.py (989b), scripts/volcengine_supabase/utils/common.py (1565b), scripts/volcengine_supabase/utils/decorators.py (1992b), scripts/volcengine_supabase/utils/targets.py (1133b), skill-card.md (2591b), SKILL.md (4793b)\n\nFile v1.0.0:SKILL.md\n\n---\nname: volcengine-supabase\ndescription: Manage Volcengine Supabase workspaces, branches, SQL queries, migrations, Edge Functions, Storage, and TypeScript type generation via a local CLI. Run uv run ./scripts/call_volcengine_supabase.py to get real-time results.\nmetadata: {\"clawdbot\":{\"emoji\":\"🧩\",\"homepage\":\"https://www.volcengine.com/\",\"requires\":{\"bins\":[\"uv\"]},\"os\":[\"darwin\",\"linux\"]},\"openclaw\":{\"emoji\":\"🧩\",\"homepage\":\"https://www.volcengine.com/\",\"requires\":{\"bins\":[\"uv\"]},\"os\":[\"darwin\",\"linux\"]},\"moltbot\":{\"emoji\":\"🧩\",\"homepage\":\"https://www.volcengine.com/\",\"requires\":{\"bins\":[\"uv\"]},\"os\":[\"darwin\",\"linux\"]}}\n---\n\n# 火山引擎 Supabase\n\n本 Skill 用于在对话中充当**火山引擎 Supabase 的智能运维与开发代理**。\n\n它会：\n- 识别用户的 Supabase 自然语言需求\n- 直接调用 `scripts/call_volcengine_supabase.py` 获取实时结果\n- 基于返回结果做解释、排障和下一步建议\n\n## 运行方式\n\n```bash\n# 方式 1：使用 uv（推荐）\nuv run ./scripts/call_volcengine_supabase.py <action> [options]\n\n# 方式 2：使用 python（需预装依赖）\npython ./scripts/call_volcengine_supabase.py <action> [options]\n```\n\n## 前置条件\n\n- 必需环境变量：`VOLCENGINE_ACCESS_KEY`、`VOLCENGINE_SECRET_KEY`（如果在沙箱环境/vefaas IAM 环境下运行，将自动获取临时凭证，可不配置环境变量）\n- 可选环境变量：`VOLCENGINE_REGION`、`DEFAULT_WORKSPACE_ID`、`READ_ONLY`、`SUPABASE_WORKSPACE_SLUG`、`SUPABASE_ENDPOINT_SCHEME`\n- 若未配置依赖，可先执行：`uv pip install -r requirements.txt` 或 `pip install -r requirements.txt`\n\n## 标准使用流程\n\n1. 先确认目标资源：`workspace_id` 或 `branch_id`\n2. 优先执行只读查询，确认现状\n3. 需要变更时，再执行写操作\n4. 变更后再次查询，确认结果已生效\n\n## 常用命令示例\n\n```bash\n# 查看可访问的 workspace\nuv run ./scripts/call_volcengine_supabase.py list-workspaces\n\n# 查看 workspace 详情\nuv run ./scripts/call_volcengine_supabase.py describe-workspace --workspace-id ws-xxxx\n\n# 获取 workspace URL\nuv run ./scripts/call_volcengine_supabase.py get-workspace-url --workspace-id ws-xxxx\n\n# 查看分支\nuv run ./scripts/call_volcengine_supabase.py list-branches --workspace-id ws-xxxx\n\n# 执行 SQL\nuv run ./scripts/call_volcengine_supabase.py execute-sql --workspace-id ws-xxxx --query \"SELECT * FROM pg_tables LIMIT 5\"\n\n# 从文件执行 migration\nuv run ./scripts/call_volcengine_supabase.py apply-migration --workspace-id ws-xxxx --name create_todos_table --query-file ./migration.sql\n\n# 部署 Edge Function\nuv run ./scripts/call_volcengine_supabase.py deploy-edge-function --workspace-id ws-xxxx --function-name hello --source-file ./index.ts\n\n# 创建 Storage bucket\nuv run ./scripts/call_volcengine_supabase.py create-storage-bucket --workspace-id ws-xxxx --bucket-name uploads --public\n```\n\n## 能力范围\n\n### 工作区与分支\n\n- `list-workspaces`\n- `describe-workspace`\n- `create-workspace`\n- `pause-workspace`\n- `restore-workspace`\n- `get-workspace-url`\n- `get-keys`\n- `list-branches`\n- `create-branch`\n- `delete-branch`\n- `reset-branch`\n\n### 数据库\n\n- `execute-sql`\n- `list-tables`\n- `list-migrations`\n- `list-extensions`\n- `apply-migration`\n- `generate-typescript-types`\n\n### Edge Functions / Storage\n\n- `list-edge-functions`\n- `get-edge-function`\n- `deploy-edge-function`\n- `delete-edge-function`\n- `list-storage-buckets`\n- `create-storage-bucket`\n- `delete-storage-bucket`\n- `get-storage-config`\n\n## 应用开发参考\n\n在使用本 Skill 管理 Supabase 资源的同时，以下文档提供应用开发场景的指导：\n\n| 需求 | 文档 |\n|------|------|\n| 将 Supabase 接入 TS/Python 应用（SDK 初始化 + CRUD） | `references/app-integration-guide.md` |\n| 数据库表结构设计与迁移规范 | `references/schema-guide.md` |\n| 行级安全策略（RLS）配置 | `references/rls-guide.md` |\n| Edge Function 编写与部署 | `references/edge-function-dev-guide.md` |\n\n> 💡 **典型工作流**：先用 CLI 创建 workspace / 建表 / 配置 RLS，再参考应用开发文档在业务代码中集成 Supabase SDK。\n\n## 注意事项\n\n- 默认遵循“先查后改”\n- `get-keys` 默认脱敏，只有明确需要时才加 `--reveal`\n- `reset-branch` 会丢失未追踪变更，且后端当前会忽略 `migration_version`\n- `READ_ONLY=true` 时，所有写操作会被拒绝\n\n## 参考资料\n\n- 工具说明：`references/tool-reference.md`\n- 操作流程：`references/workflows.md`\n- SQL 示例：`references/sql-playbook.md`\n- 应用集成：`references/app-integration-guide.md`\n- Schema 设计：`references/schema-guide.md`\n- RLS 策略：`references/rls-guide.md`\n- Edge Function 开发：`references/edge-function-dev-guide.md`\n\nFile v1.0.0:_meta.json\n\n{\n  \"ownerId\": \"kn7bkpvjyqeynm6mj3721mktc182sxrr\",\n  \"slug\": \"supabase-skills\",\n  \"version\": \"1.0.0\",\n  \"publishedAt\": 1773325541318\n}\n\nFile v1.0.0:references/app-integration-guide.md\n\n# 应用集成指南\n\n本指南介绍如何将 Supabase 集成到 TypeScript 或 Python 应用中，包括获取连接信息、初始化 SDK 客户端、和执行 CRUD 操作。\n\n---\n\n## 1. 获取连接信息\n\n使用本 Skill 获取 Supabase 实例的连接 URL 和密钥：\n\n```bash\n# 获取 Supabase API URL\nuv run ./scripts/call_volcengine_supabase.py get-workspace-url --workspace-id ws-xxxx\n\n# 获取 API Keys（默认脱敏）\nuv run ./scripts/call_volcengine_supabase.py get-keys --workspace-id ws-xxxx\n\n# 获取完整密钥（需要时）\nuv run ./scripts/call_volcengine_supabase.py get-keys --workspace-id ws-xxxx --reveal\n```\n\n你将获得以下信息，用于应用配置：\n\n| 信息 | 用途 |\n|------|------|\n| **Supabase URL** | API 端点地址 |\n| **anon key** | 客户端公开访问密钥（受 RLS 限制） |\n| **service_role key** | 服务端管理密钥（绕过 RLS，仅限后端使用） |\n\n> ⚠️ **安全提醒**：`service_role key` 拥有完整权限，**永远不要**暴露给客户端或前端代码。\n\n---\n\n## 2. 环境变量配置\n\n建议在 `.env` 文件中配置：\n\n```bash\nSUPABASE_URL=https://your-project-url.supabase.co\nSUPABASE_ANON_KEY=eyJ...your-anon-key\nSUPABASE_SERVICE_ROLE_KEY=eyJ...your-service-role-key  # 仅后端使用\n```\n\n---\n\n## 3. TypeScript 应用接入\n\n### 安装依赖\n\n```bash\nnpm install @supabase/supabase-js\n```\n\n### 初始化客户端\n\n```typescript\nimport { createClient, SupabaseClient } from '@supabase/supabase-js';\n\n// 服务端客户端（用于 API 路由、后端服务）\nfunction getSupabaseClient(token?: string): SupabaseClient {\n  const url = process.env.SUPABASE_URL!;\n  const key = process.env.SUPABASE_ANON_KEY!;\n\n  if (token) {\n    // 带用户认证的客户端（RLS 按用户过滤）\n    return createClient(url, key, {\n      global: {\n        headers: { Authorization: `Bearer ${token}` },\n      },\n      db: { timeout: 60000 },\n      auth: { autoRefreshToken: false, persistSession: false },\n    });\n  }\n\n  // 匿名客户端（RLS 按 anon 角色过滤）\n  return createClient(url, key, {\n    db: { timeout: 60000 },\n    auth: { autoRefreshToken: false, persistSession: false },\n  });\n}\n```\n\n### CRUD 操作示例\n\n#### 查询数据\n\n```typescript\nconst client = getSupabaseClient();\n\n// 基础查询\nconst { data, error } = await client.from('posts').select('*').limit(10);\n\n// 带过滤条件\nconst { data: activePosts } = await client\n  .from('posts')\n  .select('*')\n  .eq('published', true)\n  .order('created_at', { ascending: false })\n  .limit(20);\n\n// 选择特定列\nconst { data: titles } = await client.from('posts').select('id, title, created_at');\n\n// 模糊搜索\nconst { data: results } = await client.from('posts').select('*').ilike('title', '%keyword%');\n\n// 范围查询\nconst { data: recent } = await client\n  .from('posts')\n  .select('*')\n  .gte('created_at', '2024-01-01')\n  .lte('created_at', '2024-12-31');\n\n// 分页查询\nconst { data: page } = await client\n  .from('posts')\n  .select('*')\n  .range(0, 9); // 第 1-10 条\n\n// 关联查询（需要外键关系）\nconst { data: postsWithAuthor } = await client\n  .from('posts')\n  .select('*, users(name, email)');\n\n// 统计数量\nconst { count } = await client\n  .from('posts')\n  .select('*', { count: 'exact', head: true });\n```\n\n#### 插入数据\n\n```typescript\n// 单条插入\nconst { data, error } = await client\n  .from('posts')\n  .insert({ title: 'Hello World', content: 'My first post' })\n  .select(); // 返回插入的数据\n\n// 批量插入\nconst { data: batch } = await client\n  .from('posts')\n  .insert([\n    { title: 'Post 1', content: 'Content 1' },\n    { title: 'Post 2', content: 'Content 2' },\n  ])\n  .select();\n```\n\n#### 更新数据\n\n```typescript\n// 按条件更新\nconst { data, error } = await client\n  .from('posts')\n  .update({ published: true, updated_at: new Date().toISOString() })\n  .eq('id', 1)\n  .select();\n\n// UPSERT（存在则更新，不存在则插入）\nconst { data: upserted } = await client\n  .from('settings')\n  .upsert({ key: 'theme', value: 'dark' }, { onConflict: 'key' })\n  .select();\n```\n\n#### 删除数据\n\n```typescript\n// 按条件删除\nconst { error } = await client.from('posts').delete().eq('id', 1);\n\n// 多条件删除\nconst { error: batchError } = await client\n  .from('posts')\n  .delete()\n  .eq('published', false)\n  .lt('created_at', '2023-01-01');\n```\n\n#### 错误处理\n\n```typescript\nconst { data, error } = await client.from('posts').select('*');\n\nif (error) {\n  console.error(`Error code: ${error.code}, message: ${error.message}`);\n  // 常见错误码：\n  // PGRST116 - 查询结果为空（使用 .single() 时）\n  // PGRST200 - 关联查询缺少外键关系\n  // 42501    - RLS 策略拒绝访问\n  // 23505    - 唯一约束冲突\n  return;\n}\n\nconsole.log(data);\n```\n\n---\n\n## 4. Python 应用接入\n\n### 安装依赖\n\n```bash\npip install supabase httpx\n```\n\n### 初始化客户端\n\n```python\nimport os\nfrom typing import Optional\nimport httpx\nfrom supabase import create_client, Client, ClientOptions\n\n\ndef get_supabase_client(token: Optional[str] = None) -> Client:\n    url = os.environ[\"SUPABASE_URL\"]\n    key = os.environ[\"SUPABASE_ANON_KEY\"]\n\n    http_client = httpx.Client(\n        timeout=httpx.Timeout(connect=20.0, read=60.0, write=60.0, pool=10.0),\n        limits=httpx.Limits(max_connections=100, max_keepalive_connections=20),\n        follow_redirects=True,\n    )\n\n    if token:\n        # 带用户认证的客户端\n        options = ClientOptions(\n            httpx_client=http_client,\n            headers={\"Authorization\": f\"Bearer {token}\"},\n            auto_refresh_token=False,\n        )\n    else:\n        # 匿名客户端\n        options = ClientOptions(\n            httpx_client=http_client,\n            auto_refresh_token=False,\n        )\n\n    return create_client(url, key, options=options)\n```\n\n### CRUD 操作示例\n\n#### 查询数据\n\n```python\nclient = get_supabase_client()\n\n# 基础查询\nresponse = client.table('posts').select('*').limit(10).execute()\nprint(response.data)\n\n# 带过滤条件\nresponse = (client.table('posts')\n    .select('*')\n    .eq('published', True)\n    .order('created_at', desc=True)\n    .limit(20)\n    .execute())\n\n# 选择特定列\nresponse = client.table('posts').select('id, title, created_at').execute()\n\n# 模糊搜索\nresponse = client.table('posts').select('*').ilike('title', '%keyword%').execute()\n\n# 范围查询\nresponse = (client.table('posts')\n    .select('*')\n    .gte('created_at', '2024-01-01')\n    .lte('created_at', '2024-12-31')\n    .execute())\n\n# 分页查询\nresponse = client.table('posts').select('*').range(0, 9).execute()\n\n# 关联查询（需要外键）\nresponse = client.table('posts').select('*, users(name, email)').execute()\n\n# 统计数量\nresponse = client.table('posts').select('*', count='exact').execute()\nprint(response.count)\n```\n\n#### 插入数据\n\n```python\n# 单条插入\nresponse = client.table('posts').insert({\n    'title': 'Hello World',\n    'content': 'My first post'\n}).execute()\nprint(response.data)\n\n# 批量插入\nresponse = client.table('posts').insert([\n    {'title': 'Post 1', 'content': 'Content 1'},\n    {'title': 'Post 2', 'content': 'Content 2'},\n]).execute()\n```\n\n#### 更新数据\n\n```python\n# 按条件更新\nresponse = (client.table('posts')\n    .update({'published': True})\n    .eq('id', 1)\n    .execute())\n\n# UPSERT\nresponse = (client.table('settings')\n    .upsert({'key': 'theme', 'value': 'dark'})\n    .execute())\n```\n\n#### 删除数据\n\n```python\n# 按条件删除\nresponse = client.table('posts').delete().eq('id', 1).execute()\n```\n\n#### 错误处理\n\n```python\ntry:\n    response = client.table('posts').select('*').execute()\n    print(response.data)\nexcept Exception as e:\n    print(f\"Error: {e}\")\n```\n\n---\n\n## 5. RPC 调用（存储过程）\n\n如果需要复杂的数据库操作，可以先通过 `execute-sql` 创建存储过程，然后通过 SDK 调用。\n\n### 创建存储过程\n\n```bash\nuv run ./scripts/call_volcengine_supabase.py execute-sql \\\n  --workspace-id ws-xxxx \\\n  --query \"\nCREATE OR REPLACE FUNCTION search_posts(keyword text)\nRETURNS SETOF posts AS \\$\\$\n  SELECT * FROM posts\n  WHERE title ILIKE '%' || keyword || '%'\n     OR content ILIKE '%' || keyword || '%'\n  ORDER BY created_at DESC;\n\\$\\$ LANGUAGE sql STABLE;\n\"\n```\n\n### SDK 调用\n\n```typescript\n// TypeScript\nconst { data, error } = await client.rpc('search_posts', { keyword: 'supabase' });\n```\n\n```python\n# Python\nresponse = client.rpc('search_posts', {'keyword': 'supabase'}).execute()\n```\n\n---\n\n## 6. Storage 文件操作\n\n通过本 Skill 创建 Storage Bucket 后，可以在应用中使用 SDK 操作文件。\n\n### 创建 Bucket（通过 CLI）\n\n```bash\n# 创建公开 bucket\nuv run ./scripts/call_volcengine_supabase.py create-storage-bucket \\\n  --workspace-id ws-xxxx --bucket-name avatars --public\n\n# 创建私有 bucket\nuv run ./scripts/call_volcengine_supabase.py create-storage-bucket \\\n  --workspace-id ws-xxxx --bucket-name documents\n```\n\n### SDK 文件操作（TypeScript）\n\n```typescript\nconst client = getSupabaseClient();\n\n// 上传文件\nconst { data, error } = await client.storage\n  .from('avatars')\n  .upload('user1/avatar.png', fileBuffer, {\n    contentType: 'image/png',\n    cacheControl: '3600',\n  });\n\n// 获取公开 URL\nconst { data: urlData } = client.storage\n  .from('avatars')\n  .getPublicUrl('user1/avatar.png');\n\n// 获取签名 URL（临时访问私有文件）\nconst { data: signedUrl } = await client.storage\n  .from('documents')\n  .createSignedUrl('report.pdf', 3600); // 1 小时有效\n\n// 下载文件\nconst { data: fileData } = await client.storage\n  .from('documents')\n  .download('report.pdf');\n\n// 删除文件\nconst { data: deleteData } = await client.storage\n  .from('avatars')\n  .remove(['user1/old-avatar.png']);\n\n// 列出文件\nconst { data: files } = await client.storage\n  .from('avatars')\n  .list('user1/', { limit: 100, offset: 0 });\n```\n\n### SDK 文件操作（Python）\n\n```python\nclient = get_supabase_client()\n\n# 上传文件\nwith open('avatar.png', 'rb') as f:\n    response = client.storage.from_('avatars').upload('user1/avatar.png', f.read())\n\n# 获取公开 URL\nurl = client.storage.from_('avatars').get_public_url('user1/avatar.png')\n\n# 获取签名 URL\nsigned_url = client.storage.from_('documents').create_signed_url('report.pdf', 3600)\n\n# 下载文件\nfile_data = client.storage.from_('documents').download('report.pdf')\n\n# 删除文件\nresponse = client.storage.from_('avatars').remove(['user1/old-avatar.png'])\n\n# 列出文件\nfiles = client.storage.from_('avatars').list('user1/')\n```\n\nFile v1.0.0:references/edge-function-dev-guide.md\n\n# Edge Function 开发指南\n\n本指南介绍 Edge Function 的编写规范和常见模式，函数编写后通过 `deploy-edge-function` 部署。\n\n---\n\n## 基础结构\n\n每个 Edge Function 是一个 Deno 函数，使用 `Deno.serve()` 处理 HTTP 请求：\n\n```typescript\nDeno.serve(async (req: Request) => {\n  return new Response(JSON.stringify({ message: 'Hello World' }), {\n    headers: { 'Content-Type': 'application/json' },\n  });\n});\n```\n\n部署：\n\n```bash\nuv run ./scripts/call_volcengine_supabase.py deploy-edge-function \\\n  --workspace-id ws-xxxx \\\n  --function-name hello \\\n  --source-file ./functions/hello/index.ts\n```\n\n---\n\n## CORS 配置\n\n大多数前端调用都需要 CORS 支持：\n\n```typescript\nconst corsHeaders = {\n  'Access-Control-Allow-Origin': '*',\n  'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',\n  'Access-Control-Allow-Headers': 'Authorization, Content-Type, x-client-info, apikey',\n};\n\nDeno.serve(async (req: Request) => {\n  // 处理 CORS 预检请求\n  if (req.method === 'OPTIONS') {\n    return new Response('ok', { headers: corsHeaders });\n  }\n\n  try {\n    const data = { message: 'Hello World' };\n\n    return new Response(JSON.stringify(data), {\n      headers: { ...corsHeaders, 'Content-Type': 'application/json' },\n    });\n  } catch (error) {\n    return new Response(JSON.stringify({ error: error.message }), {\n      status: 500,\n      headers: { ...corsHeaders, 'Content-Type': 'application/json' },\n    });\n  }\n});\n```\n\n---\n\n## 请求处理\n\n### 读取请求体\n\n```typescript\nDeno.serve(async (req: Request) => {\n  // JSON 请求体\n  const body = await req.json();\n  const { name, email } = body;\n\n  // URL 参数\n  const url = new URL(req.url);\n  const page = url.searchParams.get('page') || '1';\n\n  // 请求头\n  const authHeader = req.headers.get('Authorization');\n\n  return new Response(JSON.stringify({ name, email, page }), {\n    headers: { 'Content-Type': 'application/json' },\n  });\n});\n```\n\n### 路由分发\n\n```typescript\nDeno.serve(async (req: Request) => {\n  const url = new URL(req.url);\n  const path = url.pathname;\n\n  if (req.method === 'GET' && path === '/') {\n    return handleList(req);\n  }\n  if (req.method === 'POST' && path === '/') {\n    return handleCreate(req);\n  }\n  if (req.method === 'PUT') {\n    return handleUpdate(req);\n  }\n  if (req.method === 'DELETE') {\n    return handleDelete(req);\n  }\n\n  return new Response('Not Found', { status: 404 });\n});\n```\n\n---\n\n## 带数据库访问\n\nEdge Function 可以通过 Supabase SDK 或直接使用环境变量中的连接信息访问数据库：\n\n```typescript\nimport { createClient } from 'https://esm.sh/@supabase/supabase-js@2';\n\nconst corsHeaders = {\n  'Access-Control-Allow-Origin': '*',\n  'Access-Control-Allow-Headers': 'Authorization, Content-Type, x-client-info, apikey',\n};\n\nDeno.serve(async (req: Request) => {\n  if (req.method === 'OPTIONS') {\n    return new Response('ok', { headers: corsHeaders });\n  }\n\n  try {\n    // 使用环境变量创建 Supabase 客户端\n    const supabaseUrl = Deno.env.get('SUPABASE_URL')!;\n    const supabaseKey = Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!;\n    const supabase = createClient(supabaseUrl, supabaseKey);\n\n    // 如果需要以用户身份访问（尊重 RLS）\n    const authHeader = req.headers.get('Authorization');\n    if (authHeader) {\n      const userToken = authHeader.replace('Bearer ', '');\n      const userClient = createClient(supabaseUrl, Deno.env.get('SUPABASE_ANON_KEY')!, {\n        global: { headers: { Authorization: `Bearer ${userToken}` } },\n      });\n      // 使用 userClient 进行受 RLS 保护的操作\n    }\n\n    // 示例：查询数据\n    const { data, error } = await supabase\n      .from('posts')\n      .select('*')\n      .order('created_at', { ascending: false })\n      .limit(10);\n\n    if (error) throw error;\n\n    return new Response(JSON.stringify(data), {\n      headers: { ...corsHeaders, 'Content-Type': 'application/json' },\n    });\n  } catch (error) {\n    return new Response(JSON.stringify({ error: error.message }), {\n      status: 500,\n      headers: { ...corsHeaders, 'Content-Type': 'application/json' },\n    });\n  }\n});\n```\n\n---\n\n## 常见模式\n\n### CRUD API\n\n```typescript\nimport { createClient } from 'https://esm.sh/@supabase/supabase-js@2';\n\nconst corsHeaders = {\n  'Access-Control-Allow-Origin': '*',\n  'Access-Control-Allow-Headers': 'Authorization, Content-Type, x-client-info, apikey',\n};\n\nDeno.serve(async (req: Request) => {\n  if (req.method === 'OPTIONS') {\n    return new Response('ok', { headers: corsHeaders });\n  }\n\n  const supabase = createClient(\n    Deno.env.get('SUPABASE_URL')!,\n    Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!,\n  );\n\n  try {\n    let result;\n\n    switch (req.method) {\n      case 'GET': {\n        const url = new URL(req.url);\n        const id = url.searchParams.get('id');\n        if (id) {\n          result = await supabase.from('items').select('*').eq('id', id).single();\n        } else {\n          result = await supabase.from('items').select('*').order('created_at', { ascending: false });\n        }\n        break;\n      }\n      case 'POST': {\n        const body = await req.json();\n        result = await supabase.from('items').insert(body).select();\n        break;\n      }\n      case 'PUT': {\n        const body = await req.json();\n        const { id, ...updates } = body;\n        result = await supabase.from('items').update(updates).eq('id', id).select();\n        break;\n      }\n      case 'DELETE': {\n        const url = new URL(req.url);\n        const id = url.searchParams.get('id');\n        result = await supabase.from('items').delete().eq('id', id!);\n        break;\n      }\n    }\n\n    if (result?.error) throw result.error;\n\n    return new Response(JSON.stringify(result?.data), {\n      headers: { ...corsHeaders, 'Content-Type': 'application/json' },\n    });\n  } catch (error) {\n    return new Response(JSON.stringify({ error: error.message }), {\n      status: 500,\n      headers: { ...corsHeaders, 'Content-Type': 'application/json' },\n    });\n  }\n});\n```\n\n### Webhook 处理器\n\n```typescript\nDeno.serve(async (req: Request) => {\n  if (req.method !== 'POST') {\n    return new Response('Method Not Allowed', { status: 405 });\n  }\n\n  try {\n    const payload = await req.json();\n\n    // 验证 Webhook 签名（根据实际来源调整）\n    const signature = req.headers.get('x-webhook-signature');\n    if (!signature) {\n      return new Response('Unauthorized', { status: 401 });\n    }\n\n    // 处理事件\n    console.log('Received webhook:', payload.type);\n\n    switch (payload.type) {\n      case 'order.created':\n        // 处理订单创建事件\n        break;\n      case 'payment.completed':\n        // 处理支付完成事件\n        break;\n      default:\n        console.log('Unhandled event type:', payload.type);\n    }\n\n    return new Response(JSON.stringify({ received: true }), {\n      headers: { 'Content-Type': 'application/json' },\n    });\n  } catch (error) {\n    return new Response(JSON.stringify({ error: error.message }), {\n      status: 500,\n      headers: { 'Content-Type': 'application/json' },\n    });\n  }\n});\n```\n\n### 数据聚合 / 报表\n\n```typescript\nimport { createClient } from 'https://esm.sh/@supabase/supabase-js@2';\n\nDeno.serve(async (req: Request) => {\n  const supabase = createClient(\n    Deno.env.get('SUPABASE_URL')!,\n    Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!,\n  );\n\n  try {\n    // 使用 RPC 调用数据库函数进行聚合\n    const { data: stats, error } = await supabase.rpc('get_dashboard_stats');\n    if (error) throw error;\n\n    return new Response(JSON.stringify(stats), {\n      headers: {\n        'Content-Type': 'application/json',\n        'Cache-Control': 'public, max-age=300', // 缓存 5 分钟\n      },\n    });\n  } catch (error) {\n    return new Response(JSON.stringify({ error: error.message }), {\n      status: 500,\n      headers: { 'Content-Type': 'application/json' },\n    });\n  }\n});\n```\n\n---\n\n## 部署与管理\n\n```bash\n# 部署函数（从文件）\nuv run ./scripts/call_volcengine_supabase.py deploy-edge-function \\\n  --workspace-id ws-xxxx \\\n  --function-name my-api \\\n  --source-file ./functions/my-api/index.ts\n\n# 部署函数（内联代码）\nuv run ./scripts/call_volcengine_supabase.py deploy-edge-function \\\n  --workspace-id ws-xxxx \\\n  --function-name hello \\\n  --source-code 'Deno.serve(() => new Response(\"Hello World\"))'\n\n# 部署时禁用 JWT 验证（公开 API）\nuv run ./scripts/call_volcengine_supabase.py deploy-edge-function \\\n  --workspace-id ws-xxxx \\\n  --function-name public-api \\\n  --source-file ./functions/public-api/index.ts \\\n  --no-verify-jwt\n\n# 查看已部署函数\nuv run ./scripts/call_volcengine_supabase.py list-edge-functions --workspace-id ws-xxxx\n\n# 查看函数详情\nuv run ./scripts/call_volcengine_supabase.py get-edge-function \\\n  --workspace-id ws-xxxx --function-name my-api\n\n# 删除函数\nuv run ./scripts/call_volcengine_supabase.py delete-edge-function \\\n  --workspace-id ws-xxxx --function-name my-api\n```\n\n---\n\n## 注意事项\n\n- **JWT 验证**：默认启用。如果函数需要公开访问（如 Webhook），使用 `--no-verify-jwt`\n- **函数命名**：只能使用小写字母、数字和连字符（如 `my-api`、`process-order`）\n- **超时**：Edge Function 有执行时间限制，避免长时间阻塞操作\n- **日志**：使用 `console.log()` 记录日志，可在平台控制台查看\n- **依赖导入**：使用 `https://esm.sh/` 导入 npm 包，或使用 `https://deno.land/` 导入 Deno 标准库\n\nFile v1.0.0:references/rls-guide.md\n\n# Row Level Security (RLS) 策略配置指南\n\n> 🔴 **所有表必须启用 RLS**。即使是公开数据表，也必须启用 RLS 并配置允许公开访问的策略。不启用 RLS 的表任何人都可以通过 anon key 直接读写所有数据，这是严重的安全隐患。\n\n---\n\n## 策略选择（决策表）\n\n根据数据访问需求，选择对应的策略场景：\n\n| 场景 | 说明 | 需要 user_id？ | 示例 |\n|------|------|:-----------:|------|\n| **A. 公开读写** | 所有人可读写 | ❌ | 公告、公共配置 |\n| **B. 公开读 + 登录写** | 所有人可读，仅登录用户可写 | ❌ | 博客文章、商品展示 |\n| **C. 仅登录用户** | 登录用户才能读写 | ❌ | 内部数据、会员内容 |\n| **D. 用户私有数据** | 用户只能操作自己的数据 | ✅ | 用户订单、个人笔记、私人设置 |\n\n> ⚠️ **常见误解**：`user_id` 字段**不是** RLS 的前提条件。只有场景 D（用户私有数据）才需要 `user_id`。\n\n---\n\n## 操作方式\n\n所有 RLS SQL 均可通过本 Skill 的 `execute-sql` 直接执行：\n\n```bash\nuv run ./scripts/call_volcengine_supabase.py execute-sql \\\n  --workspace-id ws-xxxx \\\n  --query \"ALTER TABLE my_table ENABLE ROW LEVEL SECURITY;\"\n```\n\n对于需要版本管理的 RLS 变更，建议通过 `apply-migration` 执行：\n\n```bash\nuv run ./scripts/call_volcengine_supabase.py apply-migration \\\n  --workspace-id ws-xxxx \\\n  --name enable_rls_for_posts \\\n  --query-file ./rls_migration.sql\n```\n\n---\n\n## 策略 SQL 模板\n\n> 💡 **命名规范**：Policy 名称应包含表名前缀（如 `posts_allow_public_read`），便于在多表环境中区分管理。以下模板使用 `<table_name>` 作为占位符，实际使用时替换为真实表名。\n\n> ⚠️ **幂等性**：`CREATE POLICY` 在策略已存在时会报错。如需重新配置，先删除再创建：\n> ```sql\n> DROP POLICY IF EXISTS \"policy_name\" ON <table_name>;\n> CREATE POLICY \"policy_name\" ON <table_name> ...;\n> ```\n> 修改已有表（如加字段）时，已有的 RLS 策略仍然生效，**无需重复配置**。\n\n### 场景 A：公开读写\n\n```sql\nALTER TABLE <table_name> ENABLE ROW LEVEL SECURITY;\n\nCREATE POLICY \"<table_name>_allow_public_select\" ON <table_name>\n  FOR SELECT USING (true);\n\nCREATE POLICY \"<table_name>_allow_public_insert\" ON <table_name>\n  FOR INSERT WITH CHECK (true);\n\nCREATE POLICY \"<table_name>_allow_public_update\" ON <table_name>\n  FOR UPDATE USING (true) WITH CHECK (true);\n\nCREATE POLICY \"<table_name>_allow_public_delete\" ON <table_name>\n  FOR DELETE USING (true);\n```\n\n### 场景 B：公开读 + 登录写\n\n```sql\nALTER TABLE <table_name> ENABLE ROW LEVEL SECURITY;\n\nCREATE POLICY \"<table_name>_allow_public_select\" ON <table_name>\n  FOR SELECT USING (true);\n\nCREATE POLICY \"<table_name>_auth_insert\" ON <table_name>\n  FOR INSERT WITH CHECK (auth.role() = 'authenticated');\n\nCREATE POLICY \"<table_name>_auth_update\" ON <table_name>\n  FOR UPDATE USING (auth.role() = 'authenticated')\n  WITH CHECK (auth.role() = 'authenticated');\n\nCREATE POLICY \"<table_name>_auth_delete\" ON <table_name>\n  FOR DELETE USING (auth.role() = 'authenticated');\n```\n\n### 场景 C：仅登录用户\n\n```sql\nALTER TABLE <table_name> ENABLE ROW LEVEL SECURITY;\n\nCREATE POLICY \"<table_name>_auth_select\" ON <table_name>\n  FOR SELECT USING (auth.role() = 'authenticated');\n\nCREATE POLICY \"<table_name>_auth_insert\" ON <table_name>\n  FOR INSERT WITH CHECK (auth.role() = 'authenticated');\n\nCREATE POLICY \"<table_name>_auth_update\" ON <table_name>\n  FOR UPDATE USING (auth.role() = 'authenticated')\n  WITH CHECK (auth.role() = 'authenticated');\n\nCREATE POLICY \"<table_name>_auth_delete\" ON <table_name>\n  FOR DELETE USING (auth.role() = 'authenticated');\n```\n\n### 场景 D：用户私有数据\n\n> ⚠️ 表中必须包含 `user_id` 字段（见下方 [user_id 字段定义](#user_id-字段定义)）。\n\n```sql\nALTER TABLE <table_name> ENABLE ROW LEVEL SECURITY;\n\nCREATE POLICY \"<table_name>_owner_select\" ON <table_name>\n  FOR SELECT USING (auth.uid() = user_id);\n\nCREATE POLICY \"<table_name>_owner_insert\" ON <table_name>\n  FOR INSERT WITH CHECK (auth.uid() = user_id);\n\nCREATE POLICY \"<table_name>_owner_update\" ON <table_name>\n  FOR UPDATE USING (auth.uid() = user_id)\n  WITH CHECK (auth.uid() = user_id);\n\nCREATE POLICY \"<table_name>_owner_delete\" ON <table_name>\n  FOR DELETE USING (auth.uid() = user_id);\n```\n\n---\n\n## user_id 字段定义\n\n仅在场景 D（用户私有数据）时，需要在表中添加 `user_id` 字段。\n\n### 建表时添加\n\n```sql\nCREATE TABLE <table_name> (\n  id bigserial PRIMARY KEY,\n  user_id uuid NOT NULL DEFAULT auth.uid(),\n  -- 其他字段 ...\n  created_at timestamptz NOT NULL DEFAULT now()\n);\n```\n\n### 为已有表添加\n\n```sql\nALTER TABLE <table_name>\n  ADD COLUMN user_id uuid NOT NULL DEFAULT auth.uid();\n```\n\n> 💡 使用 `auth.uid()` 作为默认值，Supabase 会在插入时自动填充当前用户 ID，防止客户端伪造。\n\n---\n\n## 检查当前 RLS 状态\n\n查看哪些表已启用 RLS：\n\n```bash\nuv run ./scripts/call_volcengine_supabase.py execute-sql \\\n  --workspace-id ws-xxxx \\\n  --query \"SELECT schemaname, tablename, rowsecurity FROM pg_tables WHERE schemaname = 'public' ORDER BY tablename;\"\n```\n\n查看已有的 Policy：\n\n```bash\nuv run ./scripts/call_volcengine_supabase.py execute-sql \\\n  --workspace-id ws-xxxx \\\n  --query \"SELECT schemaname, tablename, policyname, permissive, roles, cmd, qual, with_check FROM pg_policies WHERE schemaname = 'public' ORDER BY tablename, policyname;\"\n```\n\n---\n\n## 常见错误\n\n```sql\n-- ❌ 错误：忘记启用 RLS（表对所有人完全开放）\nCREATE TABLE posts (id serial PRIMARY KEY, title text);\n-- 缺少 ALTER TABLE posts ENABLE ROW LEVEL SECURITY;\n\n-- ❌ 错误：启用了 RLS 但没有创建策略（所有人都无法访问）\nALTER TABLE posts ENABLE ROW LEVEL SECURITY;\n-- 缺少 CREATE POLICY ...\n\n-- ❌ 错误：公开表也要求 user_id（增加了不必要的复杂度）\nCREATE POLICY \"公开读\" ON announcements\n  FOR SELECT USING (auth.uid() = user_id);\n-- 公开表应该用 USING (true)\n\n-- ✅ 正确：公开表使用 USING (true)\nCREATE POLICY \"allow_public_read\" ON announcements\n  FOR SELECT USING (true);\n```\n\nFile v1.0.0:references/schema-guide.md\n\n# 数据库 Schema 设计与迁移指南\n\n本指南提供数据库表结构设计规范和迁移最佳实践，所有 SQL 均可通过 `apply-migration` 或 `execute-sql` 执行。\n\n---\n\n## 命名约定\n\n| 对象 | 规则 | 示例 |\n|------|------|------|\n| 表名 | snake_case，复数 | `user_profiles`、`order_items` |\n| 字段名 | snake_case | `created_at`、`user_id` |\n| 主键 | `id` | `id bigserial PRIMARY KEY` |\n| 外键字段 | `<关联表单数>_id` | `user_id`、`category_id` |\n| 索引 | `ix_<表名>_<字段名>` | `ix_users_email` |\n| 唯一约束 | `uq_<表名>_<字段名>` | `uq_users_email` |\n\n---\n\n## 字段类型速查表\n\n| 用途 | 推荐类型 | 说明 |\n|------|----------|------|\n| 自增主键 | `bigserial` | 64 位自增整数 |\n| UUID 主键 | `uuid DEFAULT gen_random_uuid()` | 随机 UUID v4 |\n| 短文本 | `varchar(N)` | 有长度限制的字符串 |\n| 长文本 | `text` | 无长度限制 |\n| 整数 | `integer` / `bigint` | 32 位 / 64 位整数 |\n| 小数 | `numeric(P,S)` | 精确小数（金额等） |\n| 浮点 | `double precision` | 近似浮点（坐标等） |\n| 布尔 | `boolean` | true / false |\n| 时间戳 | `timestamptz` | 带时区（推荐） |\n| 日期 | `date` | 仅日期 |\n| JSON | `jsonb` | 二进制 JSON（可索引） |\n| 数组 | `text[]`、`integer[]` | PostgreSQL 原生数组 |\n| 向量 | `vector(N)` | pgvector 扩展（需先启用） |\n\n> ⚠️ 时间类型**始终使用 `timestamptz`**（带时区），避免时区相关问题。\n\n---\n\n## 建表模板\n\n### 基础表\n\n```sql\nCREATE TABLE IF NOT EXISTS public.todos (\n  id bigserial PRIMARY KEY,\n  title text NOT NULL,\n  description text,\n  done boolean NOT NULL DEFAULT false,\n  created_at timestamptz NOT NULL DEFAULT now(),\n  updated_at timestamptz\n);\n```\n\n通过 migration 执行：\n\n```bash\nuv run ./scripts/call_volcengine_supabase.py apply-migration \\\n  --workspace-id ws-xxxx \\\n  --name create_todos_table \\\n  --query \"CREATE TABLE IF NOT EXISTS public.todos (id bigserial PRIMARY KEY, title text NOT NULL, description text, done boolean NOT NULL DEFAULT false, created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz);\"\n```\n\n### 带外键关联\n\n```sql\nCREATE TABLE IF NOT EXISTS public.categories (\n  id bigserial PRIMARY KEY,\n  name varchar(100) NOT NULL,\n  created_at timestamptz NOT NULL DEFAULT now()\n);\n\nCREATE TABLE IF NOT EXISTS public.posts (\n  id bigserial PRIMARY KEY,\n  title varchar(255) NOT NULL,\n  content text,\n  category_id bigint REFERENCES public.categories(id) ON DELETE SET NULL,\n  published boolean NOT NULL DEFAULT false,\n  created_at timestamptz NOT NULL DEFAULT now(),\n  updated_at timestamptz\n);\n\nCREATE INDEX IF NOT EXISTS ix_posts_category_id ON public.posts(category_id);\nCREATE INDEX IF NOT EXISTS ix_posts_created_at ON public.posts(created_at DESC);\n```\n\n### 带用户关联（配合 RLS 场景 D）\n\n```sql\nCREATE TABLE IF NOT EXISTS public.notes (\n  id bigserial PRIMARY KEY,\n  user_id uuid NOT NULL DEFAULT auth.uid(),\n  title varchar(255) NOT NULL,\n  content text,\n  is_pinned boolean NOT NULL DEFAULT false,\n  created_at timestamptz NOT NULL DEFAULT now(),\n  updated_at timestamptz\n);\n\nCREATE INDEX IF NOT EXISTS ix_notes_user_id ON public.notes(user_id);\n```\n\n### 带 UUID 主键\n\n```sql\nCREATE TABLE IF NOT EXISTS public.projects (\n  id uuid PRIMARY KEY DEFAULT gen_random_uuid(),\n  name varchar(255) NOT NULL,\n  slug varchar(100) NOT NULL UNIQUE,\n  metadata jsonb DEFAULT '{}'::jsonb,\n  created_at timestamptz NOT NULL DEFAULT now()\n);\n```\n\n---\n\n## 常用 ALTER TABLE 操作\n\n### 添加字段\n\n```sql\n-- 添加可空字段（安全，推荐）\nALTER TABLE public.posts ADD COLUMN tags text[];\n\n-- 添加带默认值的非空字段（安全）\nALTER TABLE public.posts ADD COLUMN view_count integer NOT NULL DEFAULT 0;\n\n-- ❌ 危险：添加非空字段且无默认值（已有数据会报错）\n-- ALTER TABLE public.posts ADD COLUMN author_name text NOT NULL;\n```\n\n### 添加索引\n\n```sql\n-- 普通索引\nCREATE INDEX IF NOT EXISTS ix_posts_title ON public.posts(title);\n\n-- 唯一索引\nCREATE UNIQUE INDEX IF NOT EXISTS uq_posts_slug ON public.posts(slug);\n\n-- 复合索引\nCREATE INDEX IF NOT EXISTS ix_posts_category_published ON public.posts(category_id, published);\n\n-- GIN 索引（用于 jsonb 查询优化）\nCREATE INDEX IF NOT EXISTS ix_posts_metadata ON public.posts USING gin(metadata);\n```\n\n### 添加/删除约束\n\n```sql\n-- 添加唯一约束\nALTER TABLE public.posts ADD CONSTRAINT uq_posts_slug UNIQUE (slug);\n\n-- 添加外键约束\nALTER TABLE public.comments\n  ADD CONSTRAINT fk_comments_post_id\n  FOREIGN KEY (post_id) REFERENCES public.posts(id) ON DELETE CASCADE;\n\n-- 删除约束\nALTER TABLE public.posts DROP CONSTRAINT IF EXISTS uq_posts_slug;\n```\n\n---\n\n## 向后兼容变更注意事项\n\n| 操作 | 是否安全 | 说明 |\n|------|:--------:|------|\n| 添加可空字段 | ✅ | 已有行该字段为 NULL |\n| 添加带 DEFAULT 的非空字段 | ✅ | 已有行自动填充默认值 |\n| 添加非空字段无默认值 | ❌ | 已有行填充失败 |\n| 删除字段 | ⚠️ | 需确认无代码依赖 |\n| 修改字段类型 | ⚠️ | 可能丢失数据 |\n| 缩短 varchar 长度 | ❌ | 已有数据可能超长 |\n| 添加索引 | ✅ | 不影响现有数据 |\n| 添加唯一约束 | ⚠️ | 已有重复数据会失败 |\n\n---\n\n## 验证表结构\n\n```bash\n# 列出所有表\nuv run ./scripts/call_volcengine_supabase.py list-tables --workspace-id ws-xxxx\n\n# 查看表详细结构\nuv run ./scripts/call_volcengine_supabase.py execute-sql \\\n  --workspace-id ws-xxxx \\\n  --query \"SELECT column_name, data_type, is_nullable, column_default FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'posts' ORDER BY ordinal_position;\"\n\n# 查看索引\nuv run ./scripts/call_volcengine_supabase.py execute-sql \\\n  --workspace-id ws-xxxx \\\n  --query \"SELECT indexname, indexdef FROM pg_indexes WHERE schemaname = 'public' AND tablename = 'posts';\"\n\n# 查看外键\nuv run ./scripts/call_volcengine_supabase.py execute-sql \\\n  --workspace-id ws-xxxx \\\n  --query \"SELECT conname, conrelid::regclass, confrelid::regclass, pg_get_constraintdef(oid) FROM pg_constraint WHERE contype = 'f' AND connamespace = 'public'::regnamespace;\"\n```\n\n---\n\n## pgvector 支持\n\n```sql\n-- 1. 启用 pgvector 扩展\nCREATE EXTENSION IF NOT EXISTS vector;\n\n-- 2. 创建带向量字段的表\nCREATE TABLE IF NOT EXISTS public.documents (\n  id bigserial PRIMARY KEY,\n  content text NOT NULL,\n  metadata jsonb,\n  embedding vector(1536),\n  created_at timestamptz NOT NULL DEFAULT now()\n);\n\n-- 3. 创建向量索引（IVFFlat 或 HNSW）\nCREATE INDEX IF NOT EXISTS ix_documents_embedding ON public.documents\n  USING hnsw (embedding vector_cosine_ops);\n```\n\n验证扩展是否已启用：\n\n```bash\nuv run ./scripts/call_volcengine_supabase.py list-extensions --workspace-id ws-xxxx\n```\n\nFile v1.0.0:references/sql-playbook.md\n\n# SQL Playbook\n\n## 目录\n\n- 查看表结构\n- 常见 CRUD\n- Migration 示例\n- 关联查询与聚合\n- UPSERT 与批量操作\n- pgvector 示例\n- RLS 检查与配置\n\n## 1. 查看表结构\n\n```sql\nSELECT table_schema, table_name\nFROM information_schema.tables\nWHERE table_schema NOT IN ('pg_catalog', 'information_schema')\nORDER BY table_schema, table_name;\n```\n\n查看字段详情：\n\n```sql\nSELECT column_name, data_type, is_nullable, column_default\nFROM information_schema.columns\nWHERE table_schema = 'public' AND table_name = 'your_table'\nORDER BY ordinal_position;\n```\n\n查看索引：\n\n```sql\nSELECT indexname, indexdef\nFROM pg_indexes\nWHERE schemaname = 'public' AND tablename = 'your_table';\n```\n\n## 2. 常见 CRUD\n\n```sql\n-- 查询\nSELECT * FROM public.profiles ORDER BY created_at DESC LIMIT 20;\n```\n\n```sql\n-- 条件查询\nSELECT * FROM public.profiles\nWHERE status = 'active' AND created_at >= '2024-01-01'\nORDER BY created_at DESC;\n```\n\n```sql\n-- 插入\nINSERT INTO public.profiles (id, nickname)\nVALUES ('user-001', 'alice');\n```\n\n```sql\n-- 更新\nUPDATE public.profiles\nSET nickname = 'alice-updated', updated_at = now()\nWHERE id = 'user-001';\n```\n\n```sql\n-- 删除\nDELETE FROM public.profiles WHERE id = 'user-001';\n```\n\n## 3. Migration 示例\n\n```sql\nCREATE TABLE IF NOT EXISTS public.todos (\n  id bigserial PRIMARY KEY,\n  title text NOT NULL,\n  done boolean NOT NULL DEFAULT false,\n  created_at timestamptz NOT NULL DEFAULT now()\n);\n```\n\n添加字段（安全方式）：\n\n```sql\nALTER TABLE public.todos ADD COLUMN description text;\nALTER TABLE public.todos ADD COLUMN priority integer NOT NULL DEFAULT 0;\n```\n\n> 更多 Schema 设计规范请参考 [schema-guide.md](schema-guide.md)\n\n## 4. 关联查询与聚合\n\n```sql\n-- JOIN 查询\nSELECT p.title, p.content, u.name AS author_name\nFROM public.posts p\nJOIN public.users u ON p.author_id = u.id\nORDER BY p.created_at DESC\nLIMIT 20;\n```\n\n```sql\n-- LEFT JOIN（包含无关联的数据）\nSELECT p.title, c.name AS category_name\nFROM public.posts p\nLEFT JOIN public.categories c ON p.category_id = c.id;\n```\n\n```sql\n-- 聚合统计\nSELECT\n  category_id,\n  COUNT(*) AS post_count,\n  MAX(created_at) AS latest_post\nFROM public.posts\nGROUP BY category_id\nORDER BY post_count DESC;\n```\n\n```sql\n-- 分页查询\nSELECT * FROM public.posts\nORDER BY created_at DESC\nLIMIT 20 OFFSET 40;  -- 第 3 页，每页 20 条\n```\n\n## 5. UPSERT 与批量操作\n\n```sql\n-- UPSERT（插入或更新）\nINSERT INTO public.settings (key, value)\nVALUES ('theme', 'dark')\nON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;\n```\n\n```sql\n-- 批量 UPSERT\nINSERT INTO public.settings (key, value)\nVALUES\n  ('theme', 'dark'),\n  ('language', 'zh-CN'),\n  ('timezone', 'Asia/Shanghai')\nON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;\n```\n\n```sql\n-- 使用 CTE 进行复杂操作\nWITH updated AS (\n  UPDATE public.posts\n  SET published = true\n  WHERE status = 'draft' AND created_at < now() - interval '7 days'\n  RETURNING id\n)\nSELECT COUNT(*) AS published_count FROM updated;\n```\n\n## 6. pgvector 示例\n\n```sql\nCREATE EXTENSION IF NOT EXISTS vector;\n```\n\n```sql\nCREATE TABLE IF NOT EXISTS public.documents (\n  id bigserial PRIMARY KEY,\n  content text NOT NULL,\n  metadata jsonb,\n  embedding vector(1536)\n);\n```\n\n```sql\n-- 向量相似度搜索（余弦相似度）\nSELECT id, content, 1 - (embedding <=> '[0.1, 0.2, ...]'::vector) AS similarity\nFROM public.documents\nORDER BY embedding <=> '[0.1, 0.2, ...]'::vector\nLIMIT 10;\n```\n\n## 7. RLS 检查与配置\n\n检查 RLS 状态：\n\n```sql\nSELECT schemaname, tablename, rowsecurity\nFROM pg_tables\nWHERE schemaname = 'public'\nORDER BY tablename;\n```\n\n查看已有策略：\n\n```sql\nSELECT tablename, policyname, permissive, roles, cmd, qual\nFROM pg_policies\nWHERE schemaname = 'public'\nORDER BY tablename, policyname;\n```\n\n快速启用 RLS + 公开读写策略：\n\n```sql\nALTER TABLE public.your_table ENABLE ROW LEVEL SECURITY;\n\nCREATE POLICY \"allow_public_select\" ON public.your_table FOR SELECT USING (true);\nCREATE POLICY \"allow_public_insert\" ON public.your_table FOR INSERT WITH CHECK (true);\nCREATE POLICY \"allow_public_update\" ON public.your_table FOR UPDATE USING (true) WITH CHECK (true);\nCREATE POLICY \"allow_public_delete\" ON public.your_table FOR DELETE USING (true);\n```\n\n> 更多 RLS 场景模板请参考 [rls-guide.md](rls-guide.md)\n\n## 8. 存储过程（RPC）\n\n```sql\n-- 创建存储过程\nCREATE OR REPLACE FUNCTION search_posts(keyword text)\nRETURNS SETOF public.posts AS $$\n  SELECT * FROM public.posts\n  WHERE title ILIKE '%' || keyword || '%'\n     OR content ILIKE '%' || keyword || '%'\n  ORDER BY created_at DESC;\n$$ LANGUAGE sql STABLE;\n```\n\n```sql\n-- 创建聚合统计函数\nCREATE OR REPLACE FUNCTION get_dashboard_stats()\nRETURNS json AS $$\n  SELECT json_build_object(\n    'total_users', (SELECT COUNT(*) FROM public.users),\n    'total_posts', (SELECT COUNT(*) FROM public.posts),\n    'active_users', (SELECT COUNT(*) FROM public.users WHERE last_login > now() - interval '30 days')\n  );\n$$ LANGUAGE sql STABLE;\n```\n\nFile v1.0.0:references/tool-reference.md\n\n# Tool Reference\n\n## 环境变量\n\n- `VOLCENGINE_ACCESS_KEY`：火山引擎 Access Key\n- `VOLCENGINE_SECRET_KEY`：火山引擎 Secret Key\n- `VOLCENGINE_REGION`：地域，默认 `cn-beijing`\n- `DEFAULT_WORKSPACE_ID`：默认目标 workspace\n- `READ_ONLY`：设为 `true` 时禁止写操作\n- `SUPABASE_WORKSPACE_SLUG`：Edge Functions 使用的项目 slug\n- `SUPABASE_ENDPOINT_SCHEME`：生成 URL 的协议，默认 `http`\n\n## 目标参数规则\n\n- `--workspace-id` 既可传 `ws-...`，也可直接传 `br-...`\n- 若不传 `--workspace-id`，会尝试使用 `DEFAULT_WORKSPACE_ID`\n- 破坏性操作前，优先先查再改\n\n## 工作区与分支动作\n\n- `list-workspaces`\n- `describe-workspace --workspace-id ws-...`\n- `create-workspace --workspace-name demo`\n- `pause-workspace --workspace-id ws-...`\n- `restore-workspace --workspace-id ws-...`\n- `get-workspace-url --workspace-id ws-...`\n- `get-keys --workspace-id ws-... [--reveal]`\n- `list-branches --workspace-id ws-...`\n- `create-branch --workspace-id ws-... [--name develop]`\n- `delete-branch --workspace-id ws-... --branch-id br-...`\n- `reset-branch --workspace-id ws-... --branch-id br-... [--migration-version xxx]`\n\n## 数据库动作\n\n- `execute-sql --workspace-id ws-... --query \"SELECT 1\"`\n- `execute-sql --workspace-id ws-... --query-file ./query.sql`\n- `list-tables --workspace-id ws-... [--schemas public,auth]`\n- `list-migrations --workspace-id ws-...`\n- `list-extensions --workspace-id ws-...`\n- `apply-migration --workspace-id ws-... --name add_table --query-file ./migration.sql`\n- `generate-typescript-types --workspace-id ws-... [--schemas public]`\n\n## Edge Functions / Storage 动作\n\n- `list-edge-functions --workspace-id ws-...`\n- `get-edge-function --workspace-id ws-... --function-name hello`\n- `deploy-edge-function --workspace-id ws-... --function-name hello --source-file ./index.ts`\n- `delete-edge-function --workspace-id ws-... --function-name hello`\n- `list-storage-buckets --workspace-id ws-...`\n- `create-storage-bucket --workspace-id ws-... --bucket-name uploads --public`\n- `delete-storage-bucket --workspace-id ws-... --bucket-name uploads`\n- `get-storage-config --workspace-id ws-...`\n\nFile v1.0.0:references/workflows.md\n\n# Workflows\n\n## 1. 初次巡检\n\n1. 先运行 `list-workspaces`\n2. 再用 `describe-workspace` 查看目标状态\n3. 需要连接信息时，用 `get-workspace-url` 和 `get-keys`\n\n## 2. 安全变更流程\n\n1. 先 `list-branches` 确认现状\n2. 用 `create-branch` 创建隔离分支\n3. 在分支上执行 SQL / migration / function 部署\n4. 用查询动作确认结果\n5. 如有问题，再 `reset-branch` 或删除分支\n\n## 3. 数据库排障\n\n1. `list-tables` 确认 schema / table\n2. `list-extensions` 确认扩展\n3. 用 `execute-sql` 做临时查询\n4. 可复用 schema 变更使用 `apply-migration`\n\n## 4. Edge Function 发布\n\n1. `list-edge-functions`\n2. `get-edge-function`\n3. `deploy-edge-function`\n4. 再次查询确认发布结果\n\n## 5. Storage 管理\n\n1. `list-storage-buckets`\n2. `get-storage-config`\n3. `create-storage-bucket`\n4. 删除前确认数据影响\n\nFile v1.0.0:skill-card.md\n\n## Description:\n\nManage Volcengine Supabase workspaces, branches, SQL queries, migrations, Edge Functions, Storage, and TypeScript type generation through a local CLI.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[techstylex](https://clawhub.ai/user/techstylex)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and operators use this skill to inspect and manage Volcengine Supabase workspaces, branches, database SQL and migrations, Edge Functions, storage buckets, and generated TypeScript types from an agent conversation.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The security review flags credential and production-data risk from an unsafe HTTP default and real administrative operations.\n\nMitigation: Use least-privilege Volcengine credentials, set SUPABASE_ENDPOINT_SCHEME=https, and test destructive operations on an isolated branch before touching production resources.\n\nRisk: The security review says the READ_ONLY guard should not be relied on to prevent SQL changes.\n\nMitigation: Treat READ_ONLY as advisory only and review SQL, migration, branch reset, delete, deploy, and key-reveal commands before execution.\n\nRisk: The skill can reveal Supabase keys when get-keys is run with --reveal.\n\nMitigation: Avoid get-keys --reveal unless deliberately handling secrets, and keep any revealed service-role credentials out of client-side code and logs.\n\n## Reference(s):\n\n- [Volcengine](https://www.volcengine.com/)\n- [Tool Reference](references/tool-reference.md)\n- [Workflows](references/workflows.md)\n- [SQL Playbook](references/sql-playbook.md)\n- [Application Integration Guide](references/app-integration-guide.md)\n- [Schema Guide](references/schema-guide.md)\n- [RLS Guide](references/rls-guide.md)\n- [Edge Function Development Guide](references/edge-function-dev-guide.md)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, Code, Shell commands, Configuration, Guidance]\n\n**Output Format:** [Markdown with inline shell commands, code snippets, and JSON or text command results]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May execute local CLI commands against Volcengine Supabase when configured with credentials.]\n\n## Skill Version(s):\n\n1.0.0 (source: server release metadata and artifact _meta.json)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v1.0.0:agents/openai.yaml\n\n# Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\ninterface:\n  display_name: \"Volcengine Supabase\"\n  short_description: \"Manage Volcengine Supabase workspaces, branches, databases, Edge Functions, and Storage\"\n  default_prompt: \"Use $volcengine-supabase to complete this Supabase task on Volcengine.\"\n\nFile v1.0.0:requirements.txt\n\nhttpx>=0.27.0\npydantic>=2.0.0\ngit+https://github.com/sjcsjcsjc/volcengine-python-sdk.git@9905a8853a0e5fd26fdae93eefb4f201e8bef539","readmeExcerpt":"Skill: Volcengine Supabase Owner: techstylex Summary: Manage Volcengine Supabase workspaces, branches, SQL queries, migrations, Edge Functions, Storage, and TypeScript type generation via a local CLI. Run uv run... Tags: latest:1.0.0 Version history: v1.0.0 | 2026-03-12T14:25:41.318Z | user Initial release of volcengine-supabase. - Manage Volcengine Supabase workspaces, branches, SQL queries, migrations, Edge Functio","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"# 方式 1：使用 uv（推荐）\nuv run ./scripts/call_volcengine_supabase.py <action> [options]\n\n# 方式 2：使用 python（需预装依赖）\npython ./scripts/call_volcengine_supabase.py <action> [options]"},{"language":"bash","snippet":"# 查看可访问的 workspace\nuv run ./scripts/call_volcengine_supabase.py list-workspaces\n\n# 查看 workspace 详情\nuv run ./scripts/call_volcengine_supabase.py describe-workspace --workspace-id ws-xxxx\n\n# 获取 workspace URL\nuv run ./scripts/call_volcengine_supabase.py get-workspace-url --workspace-id ws-xxxx\n\n# 查看分支\nuv run ./scripts/call_volcengine_supabase.py list-branches --workspace-id ws-xxxx\n\n# 执行 SQL\nuv run ./scripts/call_volcengine_supabase.py execute-sql --workspace-id ws-xxxx --query \"SELECT * FROM pg_tables LIMIT 5\"\n\n# 从文件执行 migration\nuv run ./scripts/call_volcengine_supabase.py apply-migration --workspace-id ws-xxxx --name create_todos_table --query-file ./migration.sql\n\n# 部署 Edge Function\nuv run ./scripts/call_volcengine_supabase.py deploy-edge-function --workspace-id ws-xxxx --function-name hello --source-file ./index.ts\n\n# 创建 Storage bucket\nuv run ./scripts/call_volcengine_supabase.py create-storage-bucket --workspace-id ws-xxxx --bucket-name uploads --public"},{"language":"bash","snippet":"# 获取 Supabase API URL\nuv run ./scripts/call_volcengine_supabase.py get-workspace-url --workspace-id ws-xxxx\n\n# 获取 API Keys（默认脱敏）\nuv run ./scripts/call_volcengine_supabase.py get-keys --workspace-id ws-xxxx\n\n# 获取完整密钥（需要时）\nuv run ./scripts/call_volcengine_supabase.py get-keys --workspace-id ws-xxxx --reveal"},{"language":"bash","snippet":"SUPABASE_URL=https://your-project-url.supabase.co\nSUPABASE_ANON_KEY=eyJ...your-anon-key\nSUPABASE_SERVICE_ROLE_KEY=eyJ...your-service-role-key  # 仅后端使用"},{"language":"bash","snippet":"npm install @supabase/supabase-js"},{"language":"typescript","snippet":"import { createClient, SupabaseClient } from '@supabase/supabase-js';\n\n// 服务端客户端（用于 API 路由、后端服务）\nfunction getSupabaseClient(token?: string): SupabaseClient {\n  const url = process.env.SUPABASE_URL!;\n  const key = process.env.SUPABASE_ANON_KEY!;\n\n  if (token) {\n    // 带用户认证的客户端（RLS 按用户过滤）\n    return createClient(url, key, {\n      global: {\n        headers: { Authorization: `Bearer ${token}` },\n      },\n      db: { timeout: 60000 },\n      auth: { autoRefreshToken: false, persistSession: false },\n    });\n  }\n\n  // 匿名客户端（RLS 按 anon 角色过滤）\n  return createClient(url, key, {\n    db: { timeout: 60000 },\n    auth: { autoRefreshToken: false, persistSession: false },\n  });\n}"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: volcengine-supabase\ndescription: Manage Volcengine Supabase workspaces, branches, SQL queries, migrations, Edge Functions, Storage, and TypeScript type generation via a local CLI. Run uv run ./scripts/call_volcengine_supabase.py to get real-time results.\nmetadata: {\"clawdbot\":{\"emoji\":\"🧩\",\"homepage\":\"https://www.volcengine.com/\",\"requires\":{\"bins\":[\"uv\"]},\"os\":[\"darwin\",\"linux\"]},\"openclaw\":{\"emoji\":\"🧩\",\"homepage\":\"https://www.volcengine.com/\",\"requires\":{\"bins\":[\"uv\"]},\"os\":[\"darwin\",\"linux\"]},\"moltbot\":{\"emoji\":\"🧩\",\"homepage\":\"https://www.volcengine.com/\",\"requires\":{\"bins\":[\"uv\"]},\"os\":[\"darwin\",\"linux\"]}}\n---\n\n# 火山引擎 Supabase\n\n本 Skill 用于在对话中充当**火山引擎 Supabase 的智能运维与开发代理**。\n\n它会：\n- 识别用户的 Supabase 自然语言需求\n- 直接调用 `scripts/call_volcengine_supabase.py` 获取实时结果\n- 基于返回结果做解释、排障和下一步建议\n\n## 运行方式\n\n```bash\n# 方式 1：使用 uv（推荐）\nuv run ./scripts/call_volcengine_supabase.py <action> [options]\n\n# 方式 2：使用 python（需预装依赖）\npython ./scripts/call_volcengine_supabase.py <action> [options]\n```\n\n## 前置条件\n\n- 必需环境变量：`VOLCENGINE_ACCESS_KEY`、`VOLCENGINE_SECRET_KEY`（如果在沙箱环境/vefaas IAM 环境下运行，将自动获取临时凭证，可不配置环境变量）\n- 可选环境变量：`VOLCENGINE_REGION`、`DEFAULT_WORKSPACE_ID`、`READ_ONLY`、`SUPABASE_WORKSPACE_SLUG`、`SUPABASE_ENDPOINT_SCHEME`\n- 若未配置依赖，可先执行：`uv pip install -r requirements.txt` 或 `pip install -r requirements.txt`\n\n## 标准使用流程\n\n1. 先确认目标资源：`workspace_id` 或 `branch_id`\n2. 优先执行只读查询，确认现状\n3. 需要变更时，再执行写操作\n4. 变更后再次查询，确认结果已生效\n\n## 常用命令示例\n\n```bash\n# 查看可访问的 workspace\nuv run ./scripts/call_volcengine_supabase.py list-workspaces\n\n# 查看 workspace 详情\nuv run ./scripts/call_volcengine_supabase.py describe-workspace --workspace-id ws-xxxx\n\n# 获取 workspace URL\nuv run ./scripts/call_volcengine_supabase.py get-workspace-url --workspace-id ws-xxxx\n\n# 查看分支\nuv run ./scripts/call_volcengine_supabase.py list-branches --workspace-id ws-xxxx\n\n# 执行 SQL\nuv run ./scripts/call_volcengine_supabase.py execute-sql --workspace-id ws-xxxx --query \"SELECT * FROM pg_tables LIMIT 5\"\n\n# 从文件执行 migration\nuv run ./scripts/call_volcengine_supabase.py apply-migration --workspace-id ws-xxxx --name create_todos_table --query-file ./migration.sql\n\n# 部署 Edge Function\nuv run ./scripts/call_volcengine_supabase.py deploy-edge-function --workspace-id ws-xxxx --function-name hello --source-file ./index.ts\n\n# 创建 Storage bucket\nuv run ./scripts/call_volcengine_supabase.py create-storage-bucket --workspace-id ws-xxxx --bucket-name uploads --public\n```\n\n## 能力范围\n\n### 工作区与分支\n\n- `list-workspaces`\n- `describe-workspace`\n- `create-workspace`\n- `pause-workspace`\n- `restore-workspace`\n- `get-workspace-url`\n- `get-keys`\n- `list-branches`\n- `create-branch`\n- `delete-branch`\n- `reset-branch`\n\n### 数据库\n\n- `execute-sql`\n- `list-tables`\n- `list-migrations`\n- `list-extensions`\n- `apply-migration`\n- `generate-typescript-types`\n\n### Edge Functions / Storage\n\n- `list-edge-functions`\n- `get-edge-function`\n- `deploy-edge-function`\n- `delete-edge-function`\n- `list-storage-buckets`\n- `create-storage-bucket`\n- `delete-storage-bucket`\n- `get-storage-config`\n\n"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn7bkpvjyqeynm6mj3721mktc182sxrr\",\n  \"slug\": \"supabase-skills\",\n  \"version\": \"1.0.0\",\n  \"publishedAt\": 1773325541318\n}"},{"path":"references/app-integration-guide.md","content":"# 应用集成指南\n\n本指南介绍如何将 Supabase 集成到 TypeScript 或 Python 应用中，包括获取连接信息、初始化 SDK 客户端、和执行 CRUD 操作。\n\n---\n\n## 1. 获取连接信息\n\n使用本 Skill 获取 Supabase 实例的连接 URL 和密钥：\n\n```bash\n# 获取 Supabase API URL\nuv run ./scripts/call_volcengine_supabase.py get-workspace-url --workspace-id ws-xxxx\n\n# 获取 API Keys（默认脱敏）\nuv run ./scripts/call_volcengine_supabase.py get-keys --workspace-id ws-xxxx\n\n# 获取完整密钥（需要时）\nuv run ./scripts/call_volcengine_supabase.py get-keys --workspace-id ws-xxxx --reveal\n```\n\n你将获得以下信息，用于应用配置：\n\n| 信息 | 用途 |\n|------|------|\n| **Supabase URL** | API 端点地址 |\n| **anon key** | 客户端公开访问密钥（受 RLS 限制） |\n| **service_role key** | 服务端管理密钥（绕过 RLS，仅限后端使用） |\n\n> ⚠️ **安全提醒**：`service_role key` 拥有完整权限，**永远不要**暴露给客户端或前端代码。\n\n---\n\n## 2. 环境变量配置\n\n建议在 `.env` 文件中配置：\n\n```bash\nSUPABASE_URL=https://your-project-url.supabase.co\nSUPABASE_ANON_KEY=eyJ...your-anon-key\nSUPABASE_SERVICE_ROLE_KEY=eyJ...your-service-role-key  # 仅后端使用\n```\n\n---\n\n## 3. TypeScript 应用接入\n\n### 安装依赖\n\n```bash\nnpm install @supabase/supabase-js\n```\n\n### 初始化客户端\n\n```typescript\nimport { createClient, SupabaseClient } from '@supabase/supabase-js';\n\n// 服务端客户端（用于 API 路由、后端服务）\nfunction getSupabaseClient(token?: string): SupabaseClient {\n  const url = process.env.SUPABASE_URL!;\n  const key = process.env.SUPABASE_ANON_KEY!;\n\n  if (token) {\n    // 带用户认证的客户端（RLS 按用户过滤）\n    return createClient(url, key, {\n      global: {\n        headers: { Authorization: `Bearer ${token}` },\n      },\n      db: { timeout: 60000 },\n      auth: { autoRefreshToken: false, persistSession: false },\n    });\n  }\n\n  // 匿名客户端（RLS 按 anon 角色过滤）\n  return createClient(url, key, {\n    db: { timeout: 60000 },\n    auth: { autoRefreshToken: false, persistSession: false },\n  });\n}\n```\n\n### CRUD 操作示例\n\n#### 查询数据\n\n```typescript\nconst client = getSupabaseClient();\n\n// 基础查询\nconst { data, error } = await client.from('posts').select('*').limit(10);\n\n// 带过滤条件\nconst { data: activePosts } = await client\n  .from('posts')\n  .select('*')\n  .eq('published', true)\n  .order('created_at', { ascending: false })\n  .limit(20);\n\n// 选择特定列\nconst { data: titles } = await client.from('posts').select('id, title, created_at');\n\n// 模糊搜索\nconst { data: results } = await client.from('posts').select('*').ilike('title', '%keyword%');\n\n// 范围查询\nconst { data: recent } = await client\n  .from('posts')\n  .select('*')\n  .gte('created_at', '2024-01-01')\n  .lte('created_at', '2024-12-31');\n\n// 分页查询\nconst { data: page } = await client\n  .from('posts')\n  .select('*')\n  .range(0, 9); // 第 1-10 条\n\n// 关联查询（需要外键关系）\nconst { data: postsWithAuthor } = await client\n  .from('posts')\n  .select('*, users(name, email)');\n\n// 统计数量\nconst { count } = await client\n  .from('posts')\n  .select('*', { count: 'exact', head: true });\n```\n\n#### 插入数据\n\n```typescript\n// 单条插入\nconst { data, error } = await client\n  .from('posts')\n  .insert({ title: 'Hello World', content: 'My first post' })\n  .select(); // 返回插入的数据\n\n// 批量插入\nconst { data: batch } = await client\n  .from('posts')\n  .insert([\n    { title: 'Post 1', content: 'Content 1' },\n    { tit"},{"path":"references/edge-function-dev-guide.md","content":"# Edge Function 开发指南\n\n本指南介绍 Edge Function 的编写规范和常见模式，函数编写后通过 `deploy-edge-function` 部署。\n\n---\n\n## 基础结构\n\n每个 Edge Function 是一个 Deno 函数，使用 `Deno.serve()` 处理 HTTP 请求：\n\n```typescript\nDeno.serve(async (req: Request) => {\n  return new Response(JSON.stringify({ message: 'Hello World' }), {\n    headers: { 'Content-Type': 'application/json' },\n  });\n});\n```\n\n部署：\n\n```bash\nuv run ./scripts/call_volcengine_supabase.py deploy-edge-function \\\n  --workspace-id ws-xxxx \\\n  --function-name hello \\\n  --source-file ./functions/hello/index.ts\n```\n\n---\n\n## CORS 配置\n\n大多数前端调用都需要 CORS 支持：\n\n```typescript\nconst corsHeaders = {\n  'Access-Control-Allow-Origin': '*',\n  'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',\n  'Access-Control-Allow-Headers': 'Authorization, Content-Type, x-client-info, apikey',\n};\n\nDeno.serve(async (req: Request) => {\n  // 处理 CORS 预检请求\n  if (req.method === 'OPTIONS') {\n    return new Response('ok', { headers: corsHeaders });\n  }\n\n  try {\n    const data = { message: 'Hello World' };\n\n    return new Response(JSON.stringify(data), {\n      headers: { ...corsHeaders, 'Content-Type': 'application/json' },\n    });\n  } catch (error) {\n    return new Response(JSON.stringify({ error: error.message }), {\n      status: 500,\n      headers: { ...corsHeaders, 'Content-Type': 'application/json' },\n    });\n  }\n});\n```\n\n---\n\n## 请求处理\n\n### 读取请求体\n\n```typescript\nDeno.serve(async (req: Request) => {\n  // JSON 请求体\n  const body = await req.json();\n  const { name, email } = body;\n\n  // URL 参数\n  const url = new URL(req.url);\n  const page = url.searchParams.get('page') || '1';\n\n  // 请求头\n  const authHeader = req.headers.get('Authorization');\n\n  return new Response(JSON.stringify({ name, email, page }), {\n    headers: { 'Content-Type': 'application/json' },\n  });\n});\n```\n\n### 路由分发\n\n```typescript\nDeno.serve(async (req: Request) => {\n  const url = new URL(req.url);\n  const path = url.pathname;\n\n  if (req.method === 'GET' && path === '/') {\n    return handleList(req);\n  }\n  if (req.method === 'POST' && path === '/') {\n    return handleCreate(req);\n  }\n  if (req.method === 'PUT') {\n    return handleUpdate(req);\n  }\n  if (req.method === 'DELETE') {\n    return handleDelete(req);\n  }\n\n  return new Response('Not Found', { status: 404 });\n});\n```\n\n---\n\n## 带数据库访问\n\nEdge Function 可以通过 Supabase SDK 或直接使用环境变量中的连接信息访问数据库：\n\n```typescript\nimport { createClient } from 'https://esm.sh/@supabase/supabase-js@2';\n\nconst corsHeaders = {\n  'Access-Control-Allow-Origin': '*',\n  'Access-Control-Allow-Headers': 'Authorization, Content-Type, x-client-info, apikey',\n};\n\nDeno.serve(async (req: Request) => {\n  if (req.method === 'OPTIONS') {\n    return new Response('ok', { headers: corsHeaders });\n  }\n\n  try {\n    // 使用环境变量创建 Supabase 客户端\n    const supabaseUrl = Deno.env.get('SUPABASE_URL')!;\n    const supabaseKey = Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!;\n    const supabase = createClient(supabaseUrl, supabaseKey);\n\n    // 如果需要以用户身份访问（尊重 RLS）\n    const authHeader = req.headers.get('Authoriz"},{"path":"references/rls-guide.md","content":"# Row Level Security (RLS) 策略配置指南\n\n> 🔴 **所有表必须启用 RLS**。即使是公开数据表，也必须启用 RLS 并配置允许公开访问的策略。不启用 RLS 的表任何人都可以通过 anon key 直接读写所有数据，这是严重的安全隐患。\n\n---\n\n## 策略选择（决策表）\n\n根据数据访问需求，选择对应的策略场景：\n\n| 场景 | 说明 | 需要 user_id？ | 示例 |\n|------|------|:-----------:|------|\n| **A. 公开读写** | 所有人可读写 | ❌ | 公告、公共配置 |\n| **B. 公开读 + 登录写** | 所有人可读，仅登录用户可写 | ❌ | 博客文章、商品展示 |\n| **C. 仅登录用户** | 登录用户才能读写 | ❌ | 内部数据、会员内容 |\n| **D. 用户私有数据** | 用户只能操作自己的数据 | ✅ | 用户订单、个人笔记、私人设置 |\n\n> ⚠️ **常见误解**：`user_id` 字段**不是** RLS 的前提条件。只有场景 D（用户私有数据）才需要 `user_id`。\n\n---\n\n## 操作方式\n\n所有 RLS SQL 均可通过本 Skill 的 `execute-sql` 直接执行：\n\n```bash\nuv run ./scripts/call_volcengine_supabase.py execute-sql \\\n  --workspace-id ws-xxxx \\\n  --query \"ALTER TABLE my_table ENABLE ROW LEVEL SECURITY;\"\n```\n\n对于需要版本管理的 RLS 变更，建议通过 `apply-migration` 执行：\n\n```bash\nuv run ./scripts/call_volcengine_supabase.py apply-migration \\\n  --workspace-id ws-xxxx \\\n  --name enable_rls_for_posts \\\n  --query-file ./rls_migration.sql\n```\n\n---\n\n## 策略 SQL 模板\n\n> 💡 **命名规范**：Policy 名称应包含表名前缀（如 `posts_allow_public_read`），便于在多表环境中区分管理。以下模板使用 `<table_name>` 作为占位符，实际使用时替换为真实表名。\n\n> ⚠️ **幂等性**：`CREATE POLICY` 在策略已存在时会报错。如需重新配置，先删除再创建：\n> ```sql\n> DROP POLICY IF EXISTS \"policy_name\" ON <table_name>;\n> CREATE POLICY \"policy_name\" ON <table_name> ...;\n> ```\n> 修改已有表（如加字段）时，已有的 RLS 策略仍然生效，**无需重复配置**。\n\n### 场景 A：公开读写\n\n```sql\nALTER TABLE <table_name> ENABLE ROW LEVEL SECURITY;\n\nCREATE POLICY \"<table_name>_allow_public_select\" ON <table_name>\n  FOR SELECT USING (true);\n\nCREATE POLICY \"<table_name>_allow_public_insert\" ON <table_name>\n  FOR INSERT WITH CHECK (true);\n\nCREATE POLICY \"<table_name>_allow_public_update\" ON <table_name>\n  FOR UPDATE USING (true) WITH CHECK (true);\n\nCREATE POLICY \"<table_name>_allow_public_delete\" ON <table_name>\n  FOR DELETE USING (true);\n```\n\n### 场景 B：公开读 + 登录写\n\n```sql\nALTER TABLE <table_name> ENABLE ROW LEVEL SECURITY;\n\nCREATE POLICY \"<table_name>_allow_public_select\" ON <table_name>\n  FOR SELECT USING (true);\n\nCREATE POLICY \"<table_name>_auth_insert\" ON <table_name>\n  FOR INSERT WITH CHECK (auth.role() = 'authenticated');\n\nCREATE POLICY \"<table_name>_auth_update\" ON <table_name>\n  FOR UPDATE USING (auth.role() = 'authenticated')\n  WITH CHECK (auth.role() = 'authenticated');\n\nCREATE POLICY \"<table_name>_auth_delete\" ON <table_name>\n  FOR DELETE USING (auth.role() = 'authenticated');\n```\n\n### 场景 C：仅登录用户\n\n```sql\nALTER TABLE <table_name> ENABLE ROW LEVEL SECURITY;\n\nCREATE POLICY \"<table_name>_auth_select\" ON <table_name>\n  FOR SELECT USING (auth.role() = 'authenticated');\n\nCREATE POLICY \"<table_name>_auth_insert\" ON <table_name>\n  FOR INSERT WITH CHECK (auth.role() = 'authenticated');\n\nCREATE POLICY \"<table_name>_auth_update\" ON <table_name>\n  FOR UPDATE USING (auth.role() = 'authenticated')\n  WITH CHECK (auth.role() = 'authenticated');\n\nCREATE POLICY \"<table_name>_auth_delete\" ON <table_name>\n  FOR DELETE USING (auth.role() = 'authenticated');\n```\n\n### 场景 D：用户私有数据\n\n> ⚠️ 表中必须包含 `user_id` 字段（见下方 [user_id 字段定义](#user_id-字段定义)）。\n\n```sql\nALTER TABLE <tabl"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"Manage Volcengine Supabase workspaces, branches, SQL queries, migrations, Edge Functions, Storage, and TypeScript type generation via a local CLI. Run uv run... Skill: Volcengine Supabase Owner: techstylex Summary: Manage Volcengine Supabase workspaces, branches, SQL queries, migrations, Edge Functions, Storage, and TypeScript type generation via a local CLI. Run uv run... Tags: latest:1.0.0 Version history: v1.0.0 | 2026-03-12T14:25:41.318Z | user Initial release of volcengine-supabase. - Manage Volcengine Supabase workspaces, branches, SQL queries, migrations, Edge Functio","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1005,"uniquenessScore":45,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-11T11:49:30.349Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-11T11:49:30.349Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-11T14:14:10.217Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}