@polardbx/pxbaas 0.0.0-stage → 0.1.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (267) hide show
  1. package/README.md +107 -2
  2. package/bin/pxbaas.js +13 -0
  3. package/dist/app/preflight.d.ts +38 -0
  4. package/dist/app/preflight.d.ts.map +1 -0
  5. package/dist/app/preflight.js +79 -0
  6. package/dist/app/preflight.js.map +1 -0
  7. package/dist/app/spec-lint.d.ts +45 -0
  8. package/dist/app/spec-lint.d.ts.map +1 -0
  9. package/dist/app/spec-lint.js +407 -0
  10. package/dist/app/spec-lint.js.map +1 -0
  11. package/dist/app/templates.d.ts +143 -0
  12. package/dist/app/templates.d.ts.map +1 -0
  13. package/dist/app/templates.js +151 -0
  14. package/dist/app/templates.js.map +1 -0
  15. package/dist/cli/root.d.ts +3 -0
  16. package/dist/cli/root.d.ts.map +1 -0
  17. package/dist/cli/root.js +69 -0
  18. package/dist/cli/root.js.map +1 -0
  19. package/dist/commands/app/index.d.ts +8 -0
  20. package/dist/commands/app/index.d.ts.map +1 -0
  21. package/dist/commands/app/index.js +1476 -0
  22. package/dist/commands/app/index.js.map +1 -0
  23. package/dist/commands/auth/index.d.ts +3 -0
  24. package/dist/commands/auth/index.d.ts.map +1 -0
  25. package/dist/commands/auth/index.js +198 -0
  26. package/dist/commands/auth/index.js.map +1 -0
  27. package/dist/commands/completion/index.d.ts +3 -0
  28. package/dist/commands/completion/index.d.ts.map +1 -0
  29. package/dist/commands/completion/index.js +10 -0
  30. package/dist/commands/completion/index.js.map +1 -0
  31. package/dist/commands/data/index.d.ts +3 -0
  32. package/dist/commands/data/index.d.ts.map +1 -0
  33. package/dist/commands/data/index.js +245 -0
  34. package/dist/commands/data/index.js.map +1 -0
  35. package/dist/commands/db/index.d.ts +15 -0
  36. package/dist/commands/db/index.d.ts.map +1 -0
  37. package/dist/commands/db/index.js +389 -0
  38. package/dist/commands/db/index.js.map +1 -0
  39. package/dist/commands/doctor/index.d.ts +3 -0
  40. package/dist/commands/doctor/index.d.ts.map +1 -0
  41. package/dist/commands/doctor/index.js +305 -0
  42. package/dist/commands/doctor/index.js.map +1 -0
  43. package/dist/commands/functions/delete.d.ts +3 -0
  44. package/dist/commands/functions/delete.d.ts.map +1 -0
  45. package/dist/commands/functions/delete.js +55 -0
  46. package/dist/commands/functions/delete.js.map +1 -0
  47. package/dist/commands/functions/deploy.d.ts +3 -0
  48. package/dist/commands/functions/deploy.d.ts.map +1 -0
  49. package/dist/commands/functions/deploy.js +118 -0
  50. package/dist/commands/functions/deploy.js.map +1 -0
  51. package/dist/commands/functions/index.d.ts +3 -0
  52. package/dist/commands/functions/index.d.ts.map +1 -0
  53. package/dist/commands/functions/index.js +15 -0
  54. package/dist/commands/functions/index.js.map +1 -0
  55. package/dist/commands/functions/list.d.ts +6 -0
  56. package/dist/commands/functions/list.d.ts.map +1 -0
  57. package/dist/commands/functions/list.js +63 -0
  58. package/dist/commands/functions/list.js.map +1 -0
  59. package/dist/commands/functions/new.d.ts +3 -0
  60. package/dist/commands/functions/new.d.ts.map +1 -0
  61. package/dist/commands/functions/new.js +57 -0
  62. package/dist/commands/functions/new.js.map +1 -0
  63. package/dist/commands/gen/index.d.ts +3 -0
  64. package/dist/commands/gen/index.d.ts.map +1 -0
  65. package/dist/commands/gen/index.js +320 -0
  66. package/dist/commands/gen/index.js.map +1 -0
  67. package/dist/commands/instance/index.d.ts +8 -0
  68. package/dist/commands/instance/index.d.ts.map +1 -0
  69. package/dist/commands/instance/index.js +361 -0
  70. package/dist/commands/instance/index.js.map +1 -0
  71. package/dist/commands/login/index.d.ts +3 -0
  72. package/dist/commands/login/index.d.ts.map +1 -0
  73. package/dist/commands/login/index.js +160 -0
  74. package/dist/commands/login/index.js.map +1 -0
  75. package/dist/commands/login/login.d.ts +3 -0
  76. package/dist/commands/login/login.d.ts.map +1 -0
  77. package/dist/commands/login/login.js +185 -0
  78. package/dist/commands/login/login.js.map +1 -0
  79. package/dist/commands/logout/index.d.ts +3 -0
  80. package/dist/commands/logout/index.d.ts.map +1 -0
  81. package/dist/commands/logout/index.js +41 -0
  82. package/dist/commands/logout/index.js.map +1 -0
  83. package/dist/commands/profile/import-env.d.ts +13 -0
  84. package/dist/commands/profile/import-env.d.ts.map +1 -0
  85. package/dist/commands/profile/import-env.js +81 -0
  86. package/dist/commands/profile/import-env.js.map +1 -0
  87. package/dist/commands/profile/index.d.ts +3 -0
  88. package/dist/commands/profile/index.d.ts.map +1 -0
  89. package/dist/commands/profile/index.js +112 -0
  90. package/dist/commands/profile/index.js.map +1 -0
  91. package/dist/commands/rest/index.d.ts +3 -0
  92. package/dist/commands/rest/index.d.ts.map +1 -0
  93. package/dist/commands/rest/index.js +102 -0
  94. package/dist/commands/rest/index.js.map +1 -0
  95. package/dist/commands/skill/index.d.ts +11 -0
  96. package/dist/commands/skill/index.d.ts.map +1 -0
  97. package/dist/commands/skill/index.js +153 -0
  98. package/dist/commands/skill/index.js.map +1 -0
  99. package/dist/commands/status/index.d.ts +3 -0
  100. package/dist/commands/status/index.d.ts.map +1 -0
  101. package/dist/commands/status/index.js +59 -0
  102. package/dist/commands/status/index.js.map +1 -0
  103. package/dist/commands/storage/index.d.ts +3 -0
  104. package/dist/commands/storage/index.d.ts.map +1 -0
  105. package/dist/commands/storage/index.js +198 -0
  106. package/dist/commands/storage/index.js.map +1 -0
  107. package/dist/commands/whoami/index.d.ts +3 -0
  108. package/dist/commands/whoami/index.d.ts.map +1 -0
  109. package/dist/commands/whoami/index.js +82 -0
  110. package/dist/commands/whoami/index.js.map +1 -0
  111. package/dist/credentials/commit.d.ts +38 -0
  112. package/dist/credentials/commit.d.ts.map +1 -0
  113. package/dist/credentials/commit.js +57 -0
  114. package/dist/credentials/commit.js.map +1 -0
  115. package/dist/credentials/credential-store.d.ts +57 -0
  116. package/dist/credentials/credential-store.d.ts.map +1 -0
  117. package/dist/credentials/credential-store.js +180 -0
  118. package/dist/credentials/credential-store.js.map +1 -0
  119. package/dist/credentials/env-file.d.ts +44 -0
  120. package/dist/credentials/env-file.d.ts.map +1 -0
  121. package/dist/credentials/env-file.js +118 -0
  122. package/dist/credentials/env-file.js.map +1 -0
  123. package/dist/credentials/formatter.d.ts +39 -0
  124. package/dist/credentials/formatter.d.ts.map +1 -0
  125. package/dist/credentials/formatter.js +79 -0
  126. package/dist/credentials/formatter.js.map +1 -0
  127. package/dist/credentials/index.d.ts +13 -0
  128. package/dist/credentials/index.d.ts.map +1 -0
  129. package/dist/credentials/index.js +13 -0
  130. package/dist/credentials/index.js.map +1 -0
  131. package/dist/credentials/jwt-introspect.d.ts +32 -0
  132. package/dist/credentials/jwt-introspect.d.ts.map +1 -0
  133. package/dist/credentials/jwt-introspect.js +64 -0
  134. package/dist/credentials/jwt-introspect.js.map +1 -0
  135. package/dist/credentials/masker.d.ts +20 -0
  136. package/dist/credentials/masker.d.ts.map +1 -0
  137. package/dist/credentials/masker.js +37 -0
  138. package/dist/credentials/masker.js.map +1 -0
  139. package/dist/credentials/profile.d.ts +83 -0
  140. package/dist/credentials/profile.d.ts.map +1 -0
  141. package/dist/credentials/profile.js +184 -0
  142. package/dist/credentials/profile.js.map +1 -0
  143. package/dist/credentials/tenant-guard.d.ts +16 -0
  144. package/dist/credentials/tenant-guard.d.ts.map +1 -0
  145. package/dist/credentials/tenant-guard.js +53 -0
  146. package/dist/credentials/tenant-guard.js.map +1 -0
  147. package/dist/credentials/tty-guard.d.ts +19 -0
  148. package/dist/credentials/tty-guard.d.ts.map +1 -0
  149. package/dist/credentials/tty-guard.js +47 -0
  150. package/dist/credentials/tty-guard.js.map +1 -0
  151. package/dist/db/apply-schema.d.ts +144 -0
  152. package/dist/db/apply-schema.d.ts.map +1 -0
  153. package/dist/db/apply-schema.js +359 -0
  154. package/dist/db/apply-schema.js.map +1 -0
  155. package/dist/db/sql-file.d.ts +104 -0
  156. package/dist/db/sql-file.d.ts.map +1 -0
  157. package/dist/db/sql-file.js +584 -0
  158. package/dist/db/sql-file.js.map +1 -0
  159. package/dist/instance/provision.d.ts +89 -0
  160. package/dist/instance/provision.d.ts.map +1 -0
  161. package/dist/instance/provision.js +139 -0
  162. package/dist/instance/provision.js.map +1 -0
  163. package/dist/instance/zero-store.d.ts +47 -0
  164. package/dist/instance/zero-store.d.ts.map +1 -0
  165. package/dist/instance/zero-store.js +91 -0
  166. package/dist/instance/zero-store.js.map +1 -0
  167. package/dist/main.d.ts +3 -0
  168. package/dist/main.d.ts.map +1 -0
  169. package/dist/main.js +46 -0
  170. package/dist/main.js.map +1 -0
  171. package/dist/skill/assets.d.ts +38 -0
  172. package/dist/skill/assets.d.ts.map +1 -0
  173. package/dist/skill/assets.js +111 -0
  174. package/dist/skill/assets.js.map +1 -0
  175. package/dist/skill/hint.d.ts +39 -0
  176. package/dist/skill/hint.d.ts.map +1 -0
  177. package/dist/skill/hint.js +109 -0
  178. package/dist/skill/hint.js.map +1 -0
  179. package/dist/skill/hosts.d.ts +21 -0
  180. package/dist/skill/hosts.d.ts.map +1 -0
  181. package/dist/skill/hosts.js +38 -0
  182. package/dist/skill/hosts.js.map +1 -0
  183. package/dist/skill/installer.d.ts +88 -0
  184. package/dist/skill/installer.d.ts.map +1 -0
  185. package/dist/skill/installer.js +203 -0
  186. package/dist/skill/installer.js.map +1 -0
  187. package/dist/skill/ownership.d.ts +35 -0
  188. package/dist/skill/ownership.d.ts.map +1 -0
  189. package/dist/skill/ownership.js +52 -0
  190. package/dist/skill/ownership.js.map +1 -0
  191. package/package.json +63 -3
  192. package/skills/pxbaas-app-spec/SKILL.md +163 -0
  193. package/skills/pxbaas-app-spec/references/deploy-options.md +157 -0
  194. package/skills/pxbaas-app-spec/references/guardrails-pitfalls.md +89 -0
  195. package/skills/pxbaas-app-spec/references/runtime-contract.md +151 -0
  196. package/skills/pxbaas-app-spec/references/ssr-session.md +121 -0
  197. package/skills/pxbaas-app-spec/references/templates-examples.md +311 -0
  198. package/skills/pxbaas-cli/SKILL.md +171 -0
  199. package/skills/pxbaas-cli/references/api-reference.md +68 -0
  200. package/skills/pxbaas-cli/references/app-deploy.md +170 -0
  201. package/skills/pxbaas-cli/references/auth-and-credentials.md +100 -0
  202. package/skills/pxbaas-cli/references/data-postgrest.md +85 -0
  203. package/skills/pxbaas-cli/references/db-and-meta.md +97 -0
  204. package/skills/pxbaas-cli/references/edge-functions.md +71 -0
  205. package/skills/pxbaas-cli/references/multi-tenant-apps.md +138 -0
  206. package/skills/pxbaas-cli/references/provision.md +86 -0
  207. package/skills/pxbaas-cli/references/safety-and-two-phase.md +49 -0
  208. package/skills/pxbaas-cli/references/storage.md +61 -0
  209. package/skills/pxbaas-cli/references/troubleshooting.md +73 -0
  210. package/templates/webapp/api/index.ts +55 -0
  211. package/templates/webapp/csr-bff/README.md +81 -0
  212. package/templates/webapp/csr-bff/backend/index.ts +168 -0
  213. package/templates/webapp/csr-bff/db/rls.json +13 -0
  214. package/templates/webapp/csr-bff/db/schema.sql +49 -0
  215. package/templates/webapp/csr-bff/frontend/dist/admin.html +101 -0
  216. package/templates/webapp/csr-bff/frontend/dist/article.html +44 -0
  217. package/templates/webapp/csr-bff/frontend/dist/blog.js +206 -0
  218. package/templates/webapp/csr-bff/frontend/dist/blogger.html +53 -0
  219. package/templates/webapp/csr-bff/frontend/dist/index.html +70 -0
  220. package/templates/webapp/csr-bff/frontend/dist/login.html +56 -0
  221. package/templates/webapp/csr-bff/frontend/dist/profile.html +59 -0
  222. package/templates/webapp/csr-bff/frontend/dist/signup.html +78 -0
  223. package/templates/webapp/csr-bff/frontend/dist/style.css +27 -0
  224. package/templates/webapp/manifest.json +299 -0
  225. package/templates/webapp/mpa/about.html +29 -0
  226. package/templates/webapp/mpa/app.js +42 -0
  227. package/templates/webapp/mpa/index.html +42 -0
  228. package/templates/webapp/mpa/index.ts +60 -0
  229. package/templates/webapp/mpa/style.css +42 -0
  230. package/templates/webapp/react-vite/frontend/index.html +12 -0
  231. package/templates/webapp/react-vite/frontend/package-lock.json +1826 -0
  232. package/templates/webapp/react-vite/frontend/package.json +23 -0
  233. package/templates/webapp/react-vite/frontend/src/App.tsx +34 -0
  234. package/templates/webapp/react-vite/frontend/src/main.tsx +13 -0
  235. package/templates/webapp/react-vite/frontend/src/style.css +46 -0
  236. package/templates/webapp/react-vite/frontend/tsconfig.json +20 -0
  237. package/templates/webapp/react-vite/frontend/vite.config.ts +10 -0
  238. package/templates/webapp/react-vite-hono/backend/index.ts +21 -0
  239. package/templates/webapp/react-vite-hono/frontend/index.html +12 -0
  240. package/templates/webapp/react-vite-hono/frontend/package-lock.json +1826 -0
  241. package/templates/webapp/react-vite-hono/frontend/package.json +23 -0
  242. package/templates/webapp/react-vite-hono/frontend/src/App.tsx +47 -0
  243. package/templates/webapp/react-vite-hono/frontend/src/main.tsx +13 -0
  244. package/templates/webapp/react-vite-hono/frontend/src/style.css +66 -0
  245. package/templates/webapp/react-vite-hono/frontend/tsconfig.json +20 -0
  246. package/templates/webapp/react-vite-hono/frontend/vite.config.ts +10 -0
  247. package/templates/webapp/spa/index.ts +119 -0
  248. package/templates/webapp/ssr-auth/backend/index.ts +133 -0
  249. package/templates/webapp/ssr-auth/frontend/dist/index.html +15 -0
  250. package/templates/webapp/ssr-blog/README.md +111 -0
  251. package/templates/webapp/ssr-blog/backend/index.ts +764 -0
  252. package/templates/webapp/ssr-blog/db/rls.json +13 -0
  253. package/templates/webapp/ssr-blog/db/schema.sql +51 -0
  254. package/templates/webapp/ssr-blog/frontend/dist/index.html +39 -0
  255. package/templates/webapp/ssr-frameworks/README.md +64 -0
  256. package/templates/webapp/ssr-frameworks/backend/index.ts +241 -0
  257. package/templates/webapp/ssr-frameworks/frontend/dist/index.html +31 -0
  258. package/templates/webapp/ssr-hono/backend/index.ts +92 -0
  259. package/templates/webapp/ssr-hono/frontend/dist/index.html +12 -0
  260. package/templates/webapp/ssr-shop/README.md +80 -0
  261. package/templates/webapp/ssr-shop/backend/index.ts +491 -0
  262. package/templates/webapp/ssr-shop/db/rls.json +16 -0
  263. package/templates/webapp/ssr-shop/db/schema.sql +90 -0
  264. package/templates/webapp/ssr-shop/frontend/dist/index.html +12 -0
  265. package/templates/webapp/vanilla-static/frontend/app.js +6 -0
  266. package/templates/webapp/vanilla-static/frontend/index.html +19 -0
  267. package/templates/webapp/vanilla-static/frontend/style.css +43 -0
@@ -0,0 +1,171 @@
1
+ ---
2
+ name: pxbaas-cli
3
+ description: Use the PolarDB-X BaaS CLI (command `pxbaas`) to consume the data plane from the command line — run SQL, inspect tables/schema, query and edit table data (PostgREST), deploy/list/delete Edge Functions, manage storage objects and auth users, generate types, claim a free disposable instance (`pxbaas provision`), and scaffold/deploy/publish/rollback Webapps (`pxbaas app`). Use when the user works with a PolarDB-X BaaS / MySQL-Supabase instance through `pxbaas`, has no instance yet and wants to provision one, wants to deploy a demo webapp, or mentions the pxbaas CLI, querying BaaS tables/data, running SQL, edge function deploy, storage objects, auth users, gen types, or pxbaas login/doctor/401/403 errors. Data-plane consumption + self-service provisioning (not platform deployment or tenant lifecycle). Agent rules — never run `pxbaas login` (human-only TTY), but `pxbaas provision` and `pxbaas profile import <env-file>` (bind a single-tenant instance from a `.env` file) ARE agent-runnable; always pass `--json`; confirm destructive operations with the user before executing.
4
+ ---
5
+
6
+ # pxbaas-cli
7
+
8
+ Usage guide for `pxbaas`, the customer-facing CLI of **PolarDB-X BaaS** (the MySQL port of Supabase).
9
+
10
+ This skill covers **data-plane consumption**: the platform is already deployed by operators, and customers use `pxbaas` to query and operate it.
11
+ Platform deployment / component ops are **out of scope** — see the `supabase-dev` skill for those.
12
+
13
+ ## What is PolarDB-X BaaS (Supabase)?
14
+
15
+ Supabase is an open-source Backend-as-a-Service (a Firebase alternative) providing Auth, a PostgREST-style REST API, Realtime, Storage, Edge Functions, and a Studio console.
16
+ **PolarDB-X BaaS** replaces the PostgreSQL backend with **MySQL 8.0+ / PolarDB-X** while keeping the wire protocol compatible — the official `supabase-js` client works unmodified.
17
+
18
+ All requests go through a single Kong gateway (port **8000**). Key path prefixes:
19
+
20
+ | Component | Path prefix | Note |
21
+ |---|---|---|
22
+ | MysqlREST | `/rest/v1/` | PostgREST-compatible REST over MySQL |
23
+ | Auth (GoTrue) | `/auth/v1/` | Users, JWT, OAuth |
24
+ | Storage | `/storage/v1/` | Files, S3/OSS backend |
25
+ | Realtime | `/realtime/v1/` | WebSocket subscriptions |
26
+ | Edge Functions | `/functions/v1/` | Serverless TS/JS and immutable App candidates |
27
+ | Apps | `/apps/{mount}/` | Capability-gated Webapp frontend; backend API at `/apps/{mount}/api/*` |
28
+ | PG-Meta | `/pg/` | DB metadata — **admin only** |
29
+ | Management API | `/v1/projects/*` | Deploy/manage — **admin only** |
30
+
31
+ **Single-tenant vs multi-tenant:** in multi-tenant mode every request must carry a valid `tenant_id` (JWT claim and/or `X-Tenant-Id`), keys are per-tenant, and global keys are rejected. The `pxbaas` CLI handles this for you via the profile's `tenantId`.
32
+ → For the authoritative, always-in-sync API details (incl. multi-tenant behavior and limitations), fetch the live reference: **`GET ${endpoint}/docs`** (no auth). See `references/api-reference.md`.
33
+ → Deploying apps on a **multi-tenant** instance (tenant provisioning, the three credential tiers, where RLS metadata really lives, cross-tenant acceptance): see `references/multi-tenant-apps.md`.
34
+
35
+ ## When to use this skill
36
+
37
+ - Query/operate BaaS tables, data, Edge Functions, storage, or users from the command line
38
+ - Run SQL, inspect table schema, list tables, generate TypeScript types
39
+ - Deploy / list / delete an Edge Function
40
+ - Upload / download / delete storage objects
41
+ - Diagnose `pxbaas` connection, 401/403, credential, or tenant problems
42
+
43
+ ## Mental model (understand these 4 concepts first)
44
+
45
+ 1. **profile** — one environment config (endpoint + tenantId + role keys), stored in the OS keyring. You can have several; switch with `--profile <name>` or `pxbaas profile use`.
46
+ 2. **role** — `anon` (read / RLS-constrained) vs `service_role` (bypasses RLS, admin-level). Commands have different default roles; see the command map.
47
+ 3. **tenant** — the tenant boundary in multi-tenant mode. The CLI validates that the key's `tenant_id` matches the profile; cross-tenant access is rejected.
48
+ 4. **capability URLs** — `pxbaas status --json` returns the real URL of each capability (rest/auth/storage/functions/meta); the starting point for troubleshooting.
49
+
50
+ ## Non-negotiable rules
51
+
52
+ | # | Rule | Detail |
53
+ |---|---|---|
54
+ | **1** | **NEVER run `pxbaas login`** | It requires an interactive TTY; agents cannot complete it. Credentials are provisioned by a human. If not logged in, **ask the user to run `pxbaas login`** — do not attempt it and do not ask for plaintext keys. **Exception:** `pxbaas provision` IS agent-runnable (keys come from Zero over TLS and are stored without being shown) — see `references/provision.md`. |
55
+ | **2** | **Pass `--json` for anything you parse** | Status queries, remote operations, and any command whose result you read MUST use `--json` (parse JSON, never human-readable text). Pure local scaffolding, shell completion, and file-output commands (e.g. `gen types --output <file>`) are human-facing — `--json` is optional there. |
56
+ | **3** | **You cannot see plaintext keys** | Output shows only fingerprints (sha256 first 8 + last 4). Never expect, echo, or reconstruct a plaintext anon/service key. |
57
+ | **4** | **Confirm destructive ops first** | ⚠️ The CLI currently has **no built-in confirmation gate**. Before any write/delete/DDL, YOU must restate the target and impact and get the user's explicit consent. See `references/safety-and-two-phase.md`. |
58
+ | **5** | **Respect role & tenant isolation** | Prefer `anon` for reads; explain when `service_role` is needed (it bypasses RLS). Never mix credentials across profiles. |
59
+
60
+ ## First-run discovery
61
+
62
+ Run these (all read-only) to establish state before doing anything else:
63
+
64
+ ```bash
65
+ pxbaas status --json # 1. capability URLs; confirm endpoint and availability
66
+ pxbaas doctor --json # 2. health: connectivity, JWT validity, expiry, tenant status
67
+ pxbaas whoami --json # 3. current profile / tenant / role / key fingerprints
68
+ ```
69
+
70
+ If not logged in or `doctor` reports a failure → back to Rule 1: ask the user to run `pxbaas login`; do not work around it.
71
+
72
+ ## Command map (full surface)
73
+
74
+ Legend — **R** = read/safe · **W** = write · **D** = destructive (consent required). "Details" = which reference to open.
75
+
76
+ | Command | Default role | R/W/D | Details |
77
+ |---|---|---|---|
78
+ | `login` (human TTY only) | — | special | auth-and-credentials.md |
79
+ | `profile import <env-file>` (agent-runnable, single-tenant) | — | W (local) | auth-and-credentials.md |
80
+ | `logout` | — | W (local) | auth-and-credentials.md |
81
+ | `whoami` | — | R | auth-and-credentials.md |
82
+ | `status` | — | R | auth-and-credentials.md |
83
+ | `doctor` | — | R | troubleshooting.md |
84
+ | `profile ls` | — | R | auth-and-credentials.md |
85
+ | `profile use <name>` | — | W (local) | auth-and-credentials.md |
86
+ | `profile rm <name>` | — | D (local) | auth-and-credentials.md |
87
+ | `db query <sql>` | anon | R/W | db-and-meta.md |
88
+ | `db tables` | service_role | R | db-and-meta.md |
89
+ | `db schema <table>` | service_role | R | db-and-meta.md |
90
+ | `db create-table <name>` | service_role | **D** (DDL) | db-and-meta.md |
91
+ | `db add-column <table> <column>` | service_role | **D** (DDL) | db-and-meta.md |
92
+ | `gen types` | — | R | db-and-meta.md |
93
+ | `data select <table>` | anon | R | data-postgrest.md |
94
+ | `data insert <table>` | anon | W | data-postgrest.md |
95
+ | `data update <table>` | anon | W | data-postgrest.md |
96
+ | `data delete <table>` | anon | **D** | data-postgrest.md |
97
+ | `rest <method> <path>` | anon | R/W/D | data-postgrest.md |
98
+ | `functions new <slug>` | — | local | edge-functions.md |
99
+ | `functions deploy <slug>` | service_role | **D/W** | edge-functions.md |
100
+ | `functions list` | service_role | R | edge-functions.md |
101
+ | `functions delete <slug>` | service_role | **D** | edge-functions.md |
102
+ | `storage ls [path]` | — | R | storage.md |
103
+ | `storage cp <src> <dst>` | — | W | storage.md |
104
+ | `storage mv <src> <dst>` | — | W | storage.md |
105
+ | `storage rm <path>` | — | **D** | storage.md |
106
+ | `auth users list` | service_role | R | auth-and-credentials.md |
107
+ | `auth users get <userId>` | service_role | R | auth-and-credentials.md |
108
+ | `auth users create` | service_role | W | auth-and-credentials.md |
109
+ | `auth users delete <userId>` | service_role | **D** | auth-and-credentials.md |
110
+ | `auth users invite <email>` | service_role | W | auth-and-credentials.md |
111
+ | `completion <shell>` | — | R (local) | (this file) |
112
+ | `provision` (agent-runnable) | — | W (local+remote) | provision.md |
113
+ | `instance list` / `instance current` | — | R | provision.md |
114
+ | `instance credentials <id>` | — | R (`--reveal` for dashboard pw) | provision.md |
115
+ | `instance release <id>` | — | **D** (two-phase `--confirm`) | provision.md |
116
+ | `app new <name>` | — | local | app-deploy.md |
117
+ | `app capabilities` | service_role | R | app-deploy.md |
118
+ | `app deploy <name>` | service_role | **D/W** | app-deploy.md |
119
+ | `app publish <name>` / `app rollback <name>` / `app unpublish <name>` | service_role | **D/W** | app-deploy.md |
120
+ | `app verify <name>` / `app url <name>` | — | R | app-deploy.md |
121
+ | `app list` / `app templates` | service_role | R | app-deploy.md |
122
+ | `app remove <name>` | service_role | **D** (`--confirm`; legacy `spa/api/mpa` only) | app-deploy.md |
123
+ | `app destroy <name>` | service_role | **D** (two-phase `--confirm`; webapp only; deletes edge funcs + mount, **keeps DB tables**) | app-deploy.md |
124
+
125
+ For provisioning / multi-instance selection see **provision.md**; for the `pxbaas app` commands see **app-deploy.md**. For how to **write** edge-function webapp code (Deno runtime contract, guardrails, templates, raw deploy paths), use the companion **`pxbaas-app-spec` skill**. For the live platform API beyond the CLI (all endpoints, multi-tenant rules, error codes, limitations), see **api-reference.md** (`GET ${endpoint}/docs`).
126
+
127
+ ## Natural language → command
128
+
129
+ ```
130
+ "show the schema of todos" → pxbaas db schema todos --json
131
+ "what tables are there" → pxbaas db tables --json
132
+ "count the users" → pxbaas db query "SELECT count(*) FROM users" --json
133
+ "get order id=1" → pxbaas data select orders --filter "id=eq.1" --json
134
+ "generate TS types" → pxbaas gen types --output types.ts --json
135
+ "list deployed functions" → pxbaas functions list --json
136
+ "insert a row" → confirm first → pxbaas data insert <table> --values '{...}' --json
137
+ "deploy this function" → confirm first → pxbaas functions deploy <slug> --json
138
+ "delete this object" → confirm first → pxbaas storage rm <bucket/path> --json
139
+ "I need a BaaS instance" → pxbaas provision --json (free 15-day Zero instance; agent-runnable)
140
+ "which instance am I on" → pxbaas instance current --json (or pxbaas whoami --json)
141
+ "deploy this demo webapp" → confirm first → pxbaas app deploy <name> --json
142
+ "give me a shareable demo URL" → pxbaas app url <name> --json
143
+ "destroy/delete this webapp" → confirm first → pxbaas app destroy <name> --confirm --json (removes edge funcs + mount; DB tables kept)
144
+ "can't connect / error" → pxbaas doctor --json; if credentials missing, ask user to run pxbaas login
145
+ ```
146
+
147
+ ## What NOT to do
148
+
149
+ - **NEVER run `pxbaas login`** — it needs an interactive TTY. Ask the user to log in instead.
150
+ - **NEVER expect or echo plaintext keys** — output is fingerprint-only; never ask the user for a raw key to build a command.
151
+ - **NEVER run `data delete` / `storage rm` / `functions delete` / DDL without previewing first** and getting explicit user consent (no built-in gate exists).
152
+ - **NEVER write PostgreSQL SQL in `db query`** — the backend is MySQL/PolarDB-X (use `CAST(x AS t)`, backticks, `JSON_EXTRACT`, `UUID()`, not `::`, `"col"`, `->>`, `gen_random_uuid()`).
153
+ - **NEVER assume an API listed in `/docs` is available via the CLI** — `/docs` covers the whole platform including admin APIs (PG-Meta, Management API) and tenant lifecycle; the CLI wraps only the customer data-plane subset in the command map above.
154
+ - **NEVER mix credentials across profiles** or target another tenant; the CLI enforces tenant isolation.
155
+ - **NEVER write multi-tenant RLS policies into a tenant DB's `_mysqlrest_rls_*` copies, or with `table_schema='public'`** — the authoritative store is the central `supabase` DB keyed by the tenant database name, and a wrong value fails **silently** (RLS stays off). Prefer declaring RLS in `db/rls.json` and letting `pxbaas app db-init` bind `table_schema` for you. See `references/multi-tenant-apps.md`.
156
+ - **On a multi-tenant profile, `db query` / `db push` / `app db-init` route through `/api/tenant-ddl` with the per-tenant service_role key** — DDL runs on the tenant's OWN db (GRANT-isolated) and RLS goes through the structured `/rls/*` endpoints (`table_schema` bound server-side). `/pg/query` stays platform-admin only and rejects per-tenant keys; do not hand-run central RLS INSERTs with a global key.
157
+ - **NEVER parse human-readable output** — always use `--json`.
158
+ - **NEVER loop-retry Zero capacity/rate errors** (`429 SUPABASE_LIMIT_REACHED` / `503 SUPABASE_POOL_EXHAUSTED`) — stop, inform the user, offer `pxbaas instance release`; retry at most once for pool exhaustion.
159
+ - **NEVER expect plaintext keys from `pxbaas provision`** — it stores them in the keyring and shows only fingerprints (this is why it is agent-runnable, unlike `pxbaas login`).
160
+ - **NEVER upload frontend source, `.env` files, source maps, `node_modules`, Service Workers, or binary assets as a Webapp artifact.** Build first; upload only the bounded static output. Put large/binary assets on Storage/CDN (see app-deploy.md).
161
+
162
+ ## Global flags
163
+
164
+ `--json` (machine-readable output) · `--profile <name>` (select environment) · `--debug` (verbose) · `-V/--version`.
165
+
166
+ ## Installing / updating these skills
167
+
168
+ The CLI ships **two** bundled skills — `pxbaas-cli` (this one) and `pxbaas-app-spec` (webapp authoring) — installable into Agent hosts (offline, no login):
169
+ `pxbaas skill install --host <qoder|claude|cursor|qwen|hermes>` (or `--all`) installs **all** bundled skills; `--skill <name>` installs just one. Also `pxbaas skill list` and `pxbaas skill remove`. These are setup/meta commands, not part of the data-plane surface above.
170
+
171
+ > The command surface above is derived from the actual source (`apps/baas/src`). When commands change, update this skill and the references accordingly.
@@ -0,0 +1,68 @@
1
+ # Live API Reference (`/docs`)
2
+
3
+ Every running BaaS instance serves an authoritative, **no-auth** API reference as inline Markdown:
4
+
5
+ ```
6
+ GET ${endpoint}/docs
7
+ ```
8
+
9
+ - `${endpoint}` is the profile's Kong base URL (e.g. `http://<baas-url>:8000`). Get it from `pxbaas status --json` (`.endpoint`) or `pxbaas whoami --json`.
10
+ - No authentication required; returns `text/markdown`, HTTP 200.
11
+ - It is **version-aligned with the deployed instance**, so it is the most accurate source for API details, multi-tenant behavior, and limitations.
12
+
13
+ ## When to fetch it
14
+
15
+ Fetch `${endpoint}/docs` (via WebFetch, or `curl -s ${endpoint}/docs`) when you need deeper detail than this skill provides, e.g.:
16
+ - exact endpoint semantics for a component (REST/Auth/Storage/Realtime/Functions/Meta)
17
+ - single-tenant vs multi-tenant request requirements and key hierarchy
18
+ - error-code meanings, rate-limit behavior, tenant status codes
19
+ - the full "Limitations vs Official Supabase" list before writing SQL or designing queries
20
+
21
+ How to fetch:
22
+ ```bash
23
+ curl -s "$(pxbaas status --json | sed -n 's/.*"endpoint": *"\([^"]*\)".*/\1/p')/docs"
24
+ # or simply: curl -s http://<baas-url>:8000/docs
25
+ ```
26
+
27
+ ## What `/docs` contains (content map)
28
+
29
+ | Section | Covers |
30
+ |---|---|
31
+ | Overview & Component Summary | Path prefixes for MysqlREST / Auth / Storage / Realtime / Functions / PG-Meta / Management API / Studio, all via Kong :8000 |
32
+ | Single-Tenant vs Multi-Tenant | `MULTI_TENANT_MODE`, `tenant_id` claim / `X-Tenant-Id`, per-tenant `jwt_secret`, 403/410 semantics, storage path rewriting, key hierarchy |
33
+ | Quick Start | Minimum headers (`apikey` + `Authorization: Bearer`), example requests |
34
+ | Authentication & Keys | `anon_key` vs `service_role_key`, JWT structure (HS256, `role`/`iss`/`iat`/`exp`) |
35
+ | REST API (MysqlREST) | CRUD, filtering, sorting, pagination, embedding, RPC; limitations |
36
+ | Auth (GoTrue) | Open vs authenticated endpoints; extra OAuth providers (alipay/aliyun/wechat/customdid) |
37
+ | Storage | Public vs authenticated endpoints, upload/download/move/copy/list, signed URLs |
38
+ | Realtime | WebSocket (Phoenix Channel), `postgres_changes` event name, polling-based CDC |
39
+ | Edge Functions | `/functions/v1/<name>`, per-function `verify_jwt`, invocation examples |
40
+ | Meta (PG-Meta `/pg/`) | **Admin only** — tables/columns/schemas/query/indexes; multi-tenant needs platform admin |
41
+ | Studio / Management API | **Admin only** — `/v1/projects/*`, function deploy |
42
+ | Limitations vs Official Supabase | Unavailable features + behavioral differences (critical, see below) |
43
+ | Health & Version Endpoints | No-auth health checks per service |
44
+ | Appendix | Error format, common error codes, tenant-id format, CORS, rate limiting, SDK compatibility |
45
+
46
+ ## Critical facts agents must not miss
47
+
48
+ **Backend is MySQL/PolarDB-X, not PostgreSQL.** Write MySQL dialect:
49
+
50
+ | Official Supabase (PostgreSQL) | PolarDB-X BaaS (MySQL) |
51
+ |---|---|
52
+ | `column::type` | `CAST(column AS type)` |
53
+ | `->`, `->>`, `@>` | `JSON_EXTRACT`, `JSON_UNQUOTE`, `JSON_CONTAINS` |
54
+ | `ILIKE` | `LIKE` (default collation is case-insensitive) |
55
+ | `gen_random_uuid()` | `UUID()` |
56
+ | `"col"` (double quotes) | `` `col` `` (backticks) |
57
+ | `schema.table` (same DB) | separate databases `` `db`.`table` `` |
58
+ | `auth.uid()` in RLS | `{{request.jwt.claim.sub}}` template var |
59
+
60
+ **Unavailable features** (do not attempt): GraphQL (`pg_graphql`), pgvector, PostGIS, pg_cron, materialized views, foreign tables, table inheritance, EXCLUDE constraints, partial indexes, `CREATE EXTENSION`, `CREATE PUBLICATION`.
61
+
62
+ **Other constraints:** resource embedding (FK joins) needs physical foreign keys — often unavailable on PolarDB-X sharded tables; DDL cannot run via REST (use `/pg/` or Studio) and implicitly commits; RLS is application-layer via `_mysqlrest_rls_policies`.
63
+
64
+ **Common error codes:** 401 `Unauthorized` / `token_expired`; 403 `Forbidden` / `tenant_suspended`; 404 `tenant_not_found`; 410 `tenant_deleted`; 400 invalid `tenant_id`.
65
+
66
+ ## Scope caveat (important)
67
+
68
+ `/docs` documents the **entire platform API**, including admin-only surfaces (PG-Meta `/pg/`, Management API `/v1/projects/*`) and tenant lifecycle. The **`pxbaas` CLI wraps only the customer data-plane subset** listed in the SKILL.md command map. Do not assume that because an endpoint appears in `/docs`, the CLI (or the current credential) can call it — admin APIs need platform-admin credentials the customer CLI does not use.
@@ -0,0 +1,170 @@
1
+ # Webapp Demo Deploy — `pxbaas app` commands
2
+
3
+ Covers: `app new` · `app capabilities` · `app deploy` · `app publish` · `app rollback` · `app unpublish` · `app destroy` · `app verify` · `app url` · `app list` · `app remove` · `app templates`.
4
+
5
+ `pxbaas app` supports both the legacy `spa`/`api`/`mpa` Edge Function demos and schemaVersion 2 Webapps with a prebuilt static frontend plus an optional Deno or Hono backend. Webapp deploys create immutable function candidates and publish them to a stable App mount using generation compare-and-swap (CAS).
6
+
7
+ > **How to WRITE the webapp code** (runtime contract, frontend/backend guardrails, templates, and deploy paths) lives in the dedicated **`pxbaas-app-spec` skill**. This page is only the `pxbaas app` command surface.
8
+
9
+ ## URL models
10
+
11
+ Legacy modes keep the Edge Function URL:
12
+
13
+ ```
14
+ {endpoint}/functions/v1/{slug}
15
+ ```
16
+
17
+ A schemaVersion 2 Webapp uses the platform-provided App origin and stable mount:
18
+
19
+ ```
20
+ {appEndpoint}/apps/{mount}/ # static frontend
21
+ {appEndpoint}/apps/{mount}/api/* # optional backend; prefix is stripped
22
+ ```
23
+
24
+ Never derive `appEndpoint`. Read it from `pxbaas app capabilities --json`. Output is `Public` only when `originMode=isolated`, `hostEnforced=true`, and `publicExposureAllowed=true`; otherwise treat the URL as `Preview`.
25
+
26
+ ## pxbaas app new — scaffold
27
+
28
+ ```bash
29
+ pxbaas app new <name> --template <spa|api|mpa|vanilla-static|react-vite|react-vite-hono|ssr-hono|ssr-auth|ssr-blog|csr-bff|ssr-shop|ssr-frameworks> [--dir ./apps] [--slug <slug>] [--force] [--json]
30
+ ```
31
+
32
+ - Legacy templates: `spa`, `api`, and `mpa`.
33
+ - Webapp templates: `vanilla-static`, `react-vite`, `react-vite-hono`, `ssr-hono`, `ssr-auth`, `ssr-blog`, `csr-bff`, `ssr-shop`, `ssr-frameworks`.
34
+ - Reference application templates (ship `db/schema.sql` + README + a DEPLOY CONFIG block to fill before deploy): `ssr-blog` (full-site SSR + proxy-injected session), `csr-bff` (front/back separated CSR + BFF), `ssr-shop` (React SSR shop, browser-side session), `ssr-frameworks` (four-framework SSR showcase).
35
+ - React templates pin React 18.3.1, React DOM 18.3.1, React Router DOM 6.28.0, and Vite 5.4.21, include a lockfile, use ordinary CSS, and route with `HashRouter`.
36
+ - Webapp scaffolds use nested `frontend/` and optional `backend/` directories plus a schemaVersion 2 `app.json`.
37
+ - Legacy slugs must match `^[a-zA-Z0-9][a-zA-Z0-9_-]*$` (≤128). Webapp candidate slugs are generated by the CLI.
38
+
39
+ ## pxbaas app capabilities — discover Webapp support
40
+
41
+ ```bash
42
+ pxbaas app capabilities --json
43
+ ```
44
+
45
+ Check this before building or deploying a schemaVersion 2 Webapp. The CLI blocks before upload unless schema version 2, `appEndpoint`, and public static delivery are enabled. A backend also requires native Deno; Hono additionally requires an exact `honoVersion` with offline readiness. The response also lists `ssrLibs` (the curated SSR renderers the instance pre-cached — the only `npm:` packages a worker may import besides Hono; an empty list means no SSR renderer imports are allowed) and the session contract (`sessionMode`/`sessionHeaders`).
46
+
47
+ ## pxbaas app deploy — upload and publish (destructive; confirm first)
48
+
49
+ ```bash
50
+ pxbaas app deploy <name> [--dir ./apps] [--slug <slug>] [--entrypoint index.ts] \
51
+ [--frontend <built-dir>] [--backend <source-dir>] [--backend-framework deno|hono] \
52
+ [--verify-jwt] [--dry-run] [--skip-spec-check] [--json]
53
+ ```
54
+
55
+ Legacy `spa`/`api`/`mpa` behavior is unchanged. For `mode=webapp`, deploy:
56
+
57
+ 1. reads and validates Manifest v2;
58
+ 2. checks capabilities before any upload;
59
+ 3. stages only the prebuilt frontend, optional backend, and generated `app.json`;
60
+ 4. runs frontend/backend spec-lint and capability size limits;
61
+ 5. creates or loads the stable App mount;
62
+ 6. uploads an immutable `app_{appId}_r_{deployId}` candidate;
63
+ 7. publishes with `expectedGeneration` CAS and records the new generation locally.
64
+
65
+ For Hono, source must contain `npm:hono@{{HONO_VERSION}}`; deploy substitutes the exact capability version in the uploaded candidate. The local source keeps the placeholder. If publish fails, the candidate and current generation remain in local deployment state so `app publish` can retry safely.
66
+
67
+ All JSON failures use `{ "code": "...", "message": "..." }`. **Agents MUST NOT use `--skip-spec-check`** to force a bundled template or a failing artifact through — it bypasses the deployment/security contract. Only bypass when the user explicitly requests it, after you have listed every blocker and its impact.
68
+
69
+ **Legacy deploy output (`--json`)** includes the share URL, the preflight report, and the spec-lint result:
70
+ ```json
71
+ { "status": "deployed", "app": "shop", "slug": "shop", "verifyJwt": false,
72
+ "shareUrl": "http://pxsp-xxx:8000/functions/v1/shop",
73
+ "function": { "slug": "shop", "status": "ACTIVE", "version": 1, "verify_jwt": false },
74
+ "specLint": { "skipped": false, "passed": true, "blockers": [], "warnings": [ { "rule": "cors-options", "severity": "warning", "message": "...", "specRef": "pxbaas-app-spec/references/guardrails-pitfalls.md" } ] },
75
+ "preflight": { "quota": { "used": 2, "limit": 5, "ok": true }, "publicReachable": true, "warnings": ["verify_jwt=false: ..."] } }
76
+ ```
77
+ When the spec review fails, deploy exits non-zero with `status: "blocked"` and the list of blockers (each citing its `pxbaas-app-spec` reference).
78
+
79
+ ## Legacy preflight guardrails (run automatically before deploy)
80
+
81
+ | Check | Why | Effect |
82
+ |---|---|---|
83
+ | Function quota | each tenant defaults to `max_edge_functions=500` (429 over) | **blocker** when full; warning when near |
84
+ | Root-absolute refs | `/x` paths escape the `/functions/v1/` prefix onto Studio | warning: use relative paths / inline assets |
85
+ | Public reachability | sandbox URLs are internal; only `{public endpoint}/functions/v1/{slug}` is shareable | warning if endpoint is loopback/private |
86
+ | verify_jwt=false | the URL is public and the slug is enumerable | warning: never co-locate secrets |
87
+ | Entrypoint exists | deploy precondition | **blocker** if missing (`pxbaas app new` first) |
88
+ | Single-file size | worker memory ~150MB | warning if very large → suggest Storage/CDN |
89
+
90
+ **Quota stop-and-inform:** if the quota is full (or deploy returns 429), STOP — do not retry or work around. Tell the user, and offer `pxbaas app remove` / `pxbaas functions delete` to free a slot, or a platform-side quota increase. Let the user decide.
91
+
92
+ ## pxbaas app publish / rollback / unpublish
93
+
94
+ ```bash
95
+ pxbaas app publish <name> [--dir ./apps] [--json]
96
+ pxbaas app rollback <name> [--dir ./apps] [--json]
97
+ pxbaas app unpublish <name> [--dir ./apps] [--json]
98
+ ```
99
+
100
+ These commands are schemaVersion 2 only. They read `deployment.mountId`, `deployment.candidateFunctionSlug`, and `deployment.generation` from local `app.json`, send the generation as a CAS precondition, and persist the returned generation. A stale generation returns a normalized conflict code/message instead of silently overwriting another publish.
101
+
102
+ ## pxbaas app db-init — initialize the app's database (single- AND multi-tenant)
103
+
104
+ ```bash
105
+ pxbaas app db-init <name> [--dir ./apps] [--schema public] [--dry-run] [--yes] [--json]
106
+ ```
107
+
108
+ - Applies the app's bundled `db/schema.sql` (DDL + seed) plus the declarative `db/rls.json` (RLS registry). Shows the full plan and requires authorization (`--dry-run` previews; `--yes` for non-interactive); runs sequentially, **stops on the first error, never rolls back**. The CLI never auto-runs DDL during `deploy`.
109
+ - **Mode-aware:** single-tenant runs through `/pg/query` (`__SCHEMA__`→`--schema`, default `public`); multi-tenant runs through `/api/tenant-ddl` with the per-tenant service_role key (`__SCHEMA__` de-qualified, DDL on the tenant's own db, RLS via the structured `/rls/*` endpoints with `table_schema` bound server-side). See `references/multi-tenant-apps.md` §3b.
110
+ - **RLS source (hybrid):** `db/rls.json` is preferred; if absent, RLS INSERTs embedded in `schema.sql` are parsed (multi-tenant) or run verbatim (single-tenant). When both exist, `rls.json` wins and the embedded INSERTs are skipped with a warning.
111
+
112
+ ## pxbaas app destroy — permanently tear down a webapp (destructive; two-phase)
113
+
114
+ ```bash
115
+ pxbaas app destroy <name> [--dir ./apps] [--confirm] [--json]
116
+ ```
117
+
118
+ - schemaVersion 2 webapp only. Legacy `spa/api/mpa` functions keep using `app remove` (which now rejects a webapp and points here).
119
+ - **Reclaims two things**: the mount's edge-func candidates (`active`/`previous` plus any local unpublished `candidateFunctionSlug`) and the `_platform.app_mounts` mount-id record. Each function delete also revokes its share links and notifies the proxy (cache invalidation + quota release).
120
+ - **Does NOT drop DB business tables by default** (scope decision). Seed data and the central RLS metadata rows are left untouched. Pass `--purge-db` to also drop the app's own tables and remove its RLS registry rows (policies + the central `_mysqlrest_rls_tables` toggle, via `DELETE /api/tenant-ddl/rls/tables`), derived from `db/schema.sql` CREATE names + `db/rls.json`. On instances predating that DELETE endpoint the toggle row is left (harmless; re-created on the next `db-init`).
121
+ - Without `--confirm` it only previews what will be reclaimed (`status: "dry-run"`). With `--confirm` it destroys, then clears only the local `app.json` `deployment` block (source tree is kept for re-deploy).
122
+ - Idempotent: re-destroying an already-gone mount succeeds (`alreadyGone: true`). The server disables the mount before teardown, so a mid-way failure is safe to re-run.
123
+
124
+ ```json
125
+ { "status": "destroyed", "app": "shop", "mountId": "m-abc...", "alreadyGone": false,
126
+ "deletedFunctions": [ { "slug": "app_..._r_...", "deleted": true } ], "tablesUntouched": true }
127
+ ```
128
+
129
+ ## pxbaas app verify — cold-start-aware check
130
+
131
+ ```bash
132
+ pxbaas app verify <name> [--dir ./apps] [--slug <slug>] [--timeout 60] [--json]
133
+ ```
134
+
135
+ - Webapp mode resolves the stable mount, retries its frontend URL, and checks HTTP 200. It probes the backend only when `app.json` declares `backend.healthPath` (a mount-relative path such as `/api/health`); without it, verify does not require any fixed backend route.
136
+ - Legacy mode retries through sandbox cold start, checks HTTP 200 + content-type, and pings the built-in `?action=` API.
137
+ - Exits non-zero when verification fails.
138
+
139
+ ## pxbaas app url / list / remove / templates
140
+
141
+ ```bash
142
+ pxbaas app url <name> [--json] # print Public or Preview mount URL (legacy: share URL)
143
+ pxbaas app list [--json] # list deployed functions
144
+ pxbaas app remove <name> [--confirm] [--json] # delete a LEGACY spa/api/mpa function (two-phase; webapps use `app destroy`)
145
+ pxbaas app templates [--json] # list all bundled templates
146
+ ```
147
+
148
+ ## Constraints (state these to the user)
149
+
150
+ - A Webapp frontend must be prebuilt and prefix-safe: relative Vite base, `HashRouter`, no Service Worker, `.env`, source map, `node_modules`, source tree, or binary artifact.
151
+ - A first-release backend must call `Deno.serve`, avoid Node APIs and remote imports, declare no Secrets, and use `egressPolicy=deny`. Hono must match the exact capability version.
152
+ - Capabilities and artifact limits are authoritative per instance. Do not bypass an unsupported feature.
153
+ - Legacy Edge Function demos retain their cold-start and quota constraints. Put large/binary assets on Storage/CDN.
154
+ - Full limits and the code contract: see the **`pxbaas-app-spec` skill**.
155
+
156
+ ## Typical workflow
157
+
158
+ ```bash
159
+ pxbaas app capabilities --json
160
+ pxbaas app new shop --template react-vite-hono --json
161
+ (cd apps/shop/frontend && npm ci && npm run build)
162
+ pxbaas app deploy shop --frontend apps/shop/frontend/dist --backend apps/shop/backend --json
163
+ pxbaas app verify shop --json
164
+ pxbaas app url shop --json
165
+ # Later lifecycle operations use generation CAS:
166
+ pxbaas app rollback shop --json
167
+ pxbaas app unpublish shop --json
168
+ ```
169
+
170
+ > `pxbaas app` builds on `pxbaas functions` (see edge-functions.md) and needs an instance — provision one with `pxbaas provision` if you have none (see provision.md).
@@ -0,0 +1,100 @@
1
+ # Credentials, Environment & User Management
2
+
3
+ Covers: `login` (human-only) · `profile import` (agent-runnable, env-file) · `logout` · `whoami` · `status` · `doctor` · `profile` · `auth users`.
4
+
5
+ ## login — agents must NEVER run this
6
+
7
+ ```bash
8
+ pxbaas login --endpoint <url> --tenant-id <id> --anon-key-stdin --service-key-stdin
9
+ ```
10
+
11
+ - **Requires an interactive TTY** (it prompts via inquirer); agents cannot complete it. **Do not attempt.**
12
+ - Keys are read from stdin via `--anon-key-stdin` / `--service-key-stdin` so they never land in shell history.
13
+ - Credentials are stored in the OS keyring (keytar), falling back to a `0600` file when no keyring is available.
14
+ - If another command reports `No active profile. Use "pxbaas login" ...` → **ask the user to log in manually**, OR — if a Supabase/BaaS `.env` file for the instance is available — bind it non-interactively with `pxbaas profile import <env-file>` (see below; that one IS agent-runnable).
15
+
16
+ ## profile import — bind a single-tenant instance from a `.env` file (agents MAY run this)
17
+
18
+ ```bash
19
+ pxbaas profile import <env-file> --name <profile> [--intranet] --json
20
+ ```
21
+
22
+ - Reads `SUPABASE_URL` (fallback `SUPABASE_PUBLIC_URL` / `SUPABASE_INTRANET_URL`), `SUPABASE_ANON_KEY` (fallback `ANON_KEY` / `GLOBAL_ANON_KEY`) and `SUPABASE_SERVICE_ROLE_KEY` (fallback `SERVICE_ROLE_KEY` / `GLOBAL_SERVICE_ROLE_KEY`) from the file, validates the JWTs (rejects expired keys), then writes the profile + credentials and switches current to it.
23
+ - **Agent-runnable**: keys come from a file, never from argv/shell history, so no TTY is needed. Prefer this over `login` when you already have the instance `.env`.
24
+ - `--intranet` prefers `SUPABASE_INTRANET_URL` (VPC-internal entrypoint) over the public URL. `--name` sets the profile name (default: global `--profile`, else `default`); an existing profile of the same name is **overwritten**.
25
+ - **Single-tenant only for now.** A `MULTI_TENANT_MODE=true` env file is rejected with guidance — its global keys cannot access tenant resources; use `pxbaas login` with per-tenant anon/service keys instead.
26
+
27
+ ## Verify login state (run these first)
28
+
29
+ ```bash
30
+ pxbaas whoami --json # profile / endpoint / tenant / mode + key fingerprints (sha256 first 8 + last 4)
31
+ pxbaas status --json # capability URLs: real address of rest / auth / storage / functions / meta
32
+ pxbaas doctor --json # health checks: connectivity, JWT validity, expiry, tenant status
33
+ ```
34
+
35
+ `whoami --json` shape:
36
+ ```json
37
+ {
38
+ "profile": "local",
39
+ "endpoint": "http://<baas-url>:8000",
40
+ "tenantId": "tenant_a",
41
+ "mode": "multi-tenant",
42
+ "anonKey": { "fingerprint": "ab12cd34…wxyz", "role": "anon", "tenantId": "tenant_a", "expiry": "2026-12-31T23:59:59Z", "isExpired": false },
43
+ "serviceKey": { "fingerprint": "ef56gh78…wxyz", "role": "service_role", "tenantId": "tenant_a", "expiry": "2026-12-31T23:59:59Z", "isExpired": false },
44
+ "storedAt": "2026-09-15T10:00:00Z"
45
+ }
46
+ ```
47
+
48
+ `status --json` shape:
49
+ ```json
50
+ {
51
+ "profile": "local",
52
+ "endpoint": "http://<baas-url>:8000",
53
+ "tenantId": "tenant_a",
54
+ "mode": "multi-tenant",
55
+ "capabilities": {
56
+ "auth": "http://<baas-url>:8000/auth/v1",
57
+ "rest": "http://<baas-url>:8000/rest/v1",
58
+ "storage": "http://<baas-url>:8000/storage/v1",
59
+ "functions": "http://<baas-url>:8000/functions/v1",
60
+ "meta": "http://<baas-url>:8000/pg"
61
+ }
62
+ }
63
+ ```
64
+
65
+ - Output is **fingerprint-only**; you can never see a plaintext key. Do not expect or try to echo one.
66
+
67
+ ## logout
68
+
69
+ ```bash
70
+ pxbaas logout # clears credentials for the current profile
71
+ ```
72
+
73
+ ## profile — multi-environment management
74
+
75
+ ```bash
76
+ pxbaas profile ls --json # list all profiles
77
+ pxbaas profile use <name> --json # switch current profile
78
+ pxbaas profile rm <name> --json # remove a profile (destructive to local config — confirm first)
79
+ pxbaas profile import <env-file> --name <profile> --json # bind a single-tenant instance from a .env file (agent-runnable; see above)
80
+ ```
81
+
82
+ - You can also pass global `--profile <name>` to target one environment without changing the default.
83
+ - **Never mix credentials across profiles**: the CLI validates the key's `tenant_id` against the profile.
84
+
85
+ ## auth users — user management (requires service_role, bypasses RLS)
86
+
87
+ ```bash
88
+ pxbaas auth users list --page 1 --per-page 50 --json
89
+ pxbaas auth users get <userId> --json
90
+ pxbaas auth users create --email <email> --password <pwd> [--confirm-email] --json # write
91
+ pxbaas auth users delete <userId> --json # destructive
92
+ pxbaas auth users invite <email> --json # write (sends invite email)
93
+ ```
94
+
95
+ - `--email` and `--password` are required for `create`; `--confirm-email` defaults to true (auto-confirm the email).
96
+ - These hit the GoTrue admin API (`/auth/v1/admin/users`) and need `service_role`.
97
+ - **write/destructive**: confirm with the user before `create` / `delete` / `invite` (see safety-and-two-phase.md).
98
+ - `delete <userId>` is irreversible — run `get <userId>` first to verify identity.
99
+
100
+ > Underlying API details (Auth endpoints, multi-tenant key rules): fetch `${endpoint}/docs` — see api-reference.md.
@@ -0,0 +1,85 @@
1
+ # Data Operations & REST Passthrough (data / rest)
2
+
3
+ Covers: `data select` · `data insert` · `data update` · `data delete` · `rest`.
4
+ Backed by the PostgREST-style endpoint `/rest/v1/*` (capability `rest`). The current implementation uses the profile's **anon** key (RLS-constrained).
5
+
6
+ ## PostgREST filter syntax (`--filter`)
7
+
8
+ Format: `column=operator.value`
9
+
10
+ | Meaning | filter |
11
+ |---|---|
12
+ | equal | `id=eq.1` |
13
+ | not equal | `status=neq.deleted` |
14
+ | greater / less | `age=gt.18` / `age=lt.60` |
15
+ | range | `price=gte.100` / `price=lte.200` |
16
+ | IN | `id=in.(1,2,3)` |
17
+ | like | `name=like.*an*` |
18
+ | is null | `deleted_at=is.null` |
19
+
20
+ ## data select — read rows (safe, read-only)
21
+
22
+ ```bash
23
+ pxbaas data select <table> --filter "id=eq.1" --columns "*" --limit 100 --order created_at --ascending --json
24
+ ```
25
+
26
+ - **Flags:** `--filter <f>` · `--columns <list>` (default `*`) · `--limit <n>` (default 100) · `--order <column>` · `--ascending` (default descending) · `--json`
27
+ - **Output (`--json`):** the raw PostgREST array of row objects:
28
+ ```json
29
+ [ { "id": 1, "title": "Buy milk", "is_complete": false } ]
30
+ ```
31
+
32
+ ## data insert — insert rows (write)
33
+
34
+ ```bash
35
+ pxbaas data insert <table> --values '{"title":"hello","done":false}' --json
36
+ ```
37
+
38
+ - **Flags:** `--values <json>` (**required**; single object or array) · `--json`
39
+ - **Output (`--json`):** array of inserted rows (return=representation).
40
+ - ⚠️ write — confirm the target table and payload with the user first.
41
+
42
+ ## data update — update rows (write)
43
+
44
+ ```bash
45
+ pxbaas data update <table> --values '{"done":true}' --filter "id=eq.1" --json
46
+ ```
47
+
48
+ - **Flags:** `--values <json>` (**required**) · `--filter <f>` (**required**) · `--json`
49
+ - **Output (`--json`):** array of updated rows.
50
+ - ⚠️ `--filter` is mandatory, but still verify how many rows it matches to avoid collateral updates.
51
+
52
+ ## data delete — delete rows (destructive)
53
+
54
+ ```bash
55
+ pxbaas data delete <table> --filter "id=eq.1" --json
56
+ ```
57
+
58
+ - **Flags:** `--filter <f>` (**required**) · `--json`
59
+ - **Output (`--json`):** array of deleted rows.
60
+ - ⚠️ **Destructive, no built-in gate:** it issues `DELETE /rest/v1/<table>?<filter>` directly.
61
+ Before running: preview with `data select` using the SAME filter → restate the row count/content to the user → get explicit consent → then delete.
62
+
63
+ ## rest — raw HTTP passthrough (debugging)
64
+
65
+ ```bash
66
+ pxbaas rest GET "/todos?select=*&limit=5" --role anon --json
67
+ pxbaas rest POST "/todos" --data '{"title":"x"}' --role anon --json
68
+ ```
69
+
70
+ - **Signature:** `rest <method> <path>`
71
+ - **Flags:** `--data <json>` (request body) · `--role <anon|service_role>` (default anon) · `--json`
72
+ - `<path>` is relative to `/rest/v1/`. Use for cases the `data` shortcuts don't cover (custom headers, upsert, RPC via `/rpc/<fn>`).
73
+ - Write/delete methods are destructive — confirm first.
74
+
75
+ ## Workflow — safe write/delete
76
+
77
+ ```
78
+ 1) data select <table> --filter "<same filter>" # preview the affected rows
79
+ 2) restate to user: table + filter + row count + operation
80
+ 3) get explicit consent
81
+ 4) run insert/update/delete --json
82
+ 5) data select again to verify the result
83
+ ```
84
+
85
+ > REST endpoint details, embedding/RPC constraints: fetch `${endpoint}/docs` — see api-reference.md.