codebyplan 1.13.40 → 1.13.42
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.
- package/dist/cli.js +1 -1
- package/package.json +1 -1
- package/templates/agents/cbp-database-agent.md +15 -4
- package/templates/hooks/validate-structure-patterns.sh +5 -3
- package/templates/hooks/validate-structure.sh +3 -2
- package/templates/settings.project.base.json +2 -0
- package/templates/skills/cbp-build-cc-skill/SKILL.md +8 -0
- package/templates/skills/cbp-build-cc-skill/reference/frontmatter-fields.md +3 -1
- package/templates/skills/cbp-round-complete/SKILL.md +7 -6
- package/templates/skills/cbp-round-end/SKILL.md +2 -2
- package/templates/skills/cbp-round-update/SKILL.md +7 -6
- package/templates/skills/cbp-supabase-branch-check/SKILL.md +1 -0
- package/templates/skills/cbp-supabase-migrate/SKILL.md +3 -1
- package/templates/skills/cbp-supabase-setup/SKILL.md +1 -0
- package/templates/skills/supabase/CHANGELOG.md +35 -0
- package/templates/skills/supabase/PROVENANCE.md +50 -0
- package/templates/skills/supabase/SKILL.md +136 -0
- package/templates/skills/supabase/assets/feedback-issue-template.md +17 -0
- package/templates/skills/supabase/references/skill-feedback.md +17 -0
- package/templates/skills/supabase-postgres-best-practices/CHANGELOG.md +29 -0
- package/templates/skills/supabase-postgres-best-practices/PROVENANCE.md +52 -0
- package/templates/skills/supabase-postgres-best-practices/SKILL.md +65 -0
- package/templates/skills/supabase-postgres-best-practices/references/_contributing.md +170 -0
- package/templates/skills/supabase-postgres-best-practices/references/_sections.md +39 -0
- package/templates/skills/supabase-postgres-best-practices/references/_template.md +34 -0
- package/templates/skills/supabase-postgres-best-practices/references/advanced-full-text-search.md +55 -0
- package/templates/skills/supabase-postgres-best-practices/references/advanced-jsonb-indexing.md +49 -0
- package/templates/skills/supabase-postgres-best-practices/references/conn-idle-timeout.md +46 -0
- package/templates/skills/supabase-postgres-best-practices/references/conn-limits.md +44 -0
- package/templates/skills/supabase-postgres-best-practices/references/conn-pooling.md +41 -0
- package/templates/skills/supabase-postgres-best-practices/references/conn-prepared-statements.md +46 -0
- package/templates/skills/supabase-postgres-best-practices/references/data-batch-inserts.md +54 -0
- package/templates/skills/supabase-postgres-best-practices/references/data-n-plus-one.md +53 -0
- package/templates/skills/supabase-postgres-best-practices/references/data-pagination.md +50 -0
- package/templates/skills/supabase-postgres-best-practices/references/data-upsert.md +50 -0
- package/templates/skills/supabase-postgres-best-practices/references/lock-advisory.md +56 -0
- package/templates/skills/supabase-postgres-best-practices/references/lock-deadlock-prevention.md +68 -0
- package/templates/skills/supabase-postgres-best-practices/references/lock-short-transactions.md +50 -0
- package/templates/skills/supabase-postgres-best-practices/references/lock-skip-locked.md +54 -0
- package/templates/skills/supabase-postgres-best-practices/references/monitor-explain-analyze.md +45 -0
- package/templates/skills/supabase-postgres-best-practices/references/monitor-pg-stat-statements.md +55 -0
- package/templates/skills/supabase-postgres-best-practices/references/monitor-vacuum-analyze.md +55 -0
- package/templates/skills/supabase-postgres-best-practices/references/query-composite-indexes.md +44 -0
- package/templates/skills/supabase-postgres-best-practices/references/query-covering-indexes.md +40 -0
- package/templates/skills/supabase-postgres-best-practices/references/query-index-types.md +48 -0
- package/templates/skills/supabase-postgres-best-practices/references/query-missing-indexes.md +43 -0
- package/templates/skills/supabase-postgres-best-practices/references/query-partial-indexes.md +45 -0
- package/templates/skills/supabase-postgres-best-practices/references/schema-constraints.md +80 -0
- package/templates/skills/supabase-postgres-best-practices/references/schema-data-types.md +46 -0
- package/templates/skills/supabase-postgres-best-practices/references/schema-foreign-key-indexes.md +59 -0
- package/templates/skills/supabase-postgres-best-practices/references/schema-lowercase-identifiers.md +55 -0
- package/templates/skills/supabase-postgres-best-practices/references/schema-partitioning.md +55 -0
- package/templates/skills/supabase-postgres-best-practices/references/schema-primary-keys.md +61 -0
- package/templates/skills/supabase-postgres-best-practices/references/security-privileges.md +54 -0
- package/templates/skills/supabase-postgres-best-practices/references/security-rls-basics.md +50 -0
- package/templates/skills/supabase-postgres-best-practices/references/security-rls-performance.md +63 -0
package/dist/cli.js
CHANGED
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
scope: org-shared
|
|
3
3
|
name: cbp-database-agent
|
|
4
4
|
description: Supabase database specialist. Handles migrations, RLS policies, type generation, and schema changes. Spawned as sub-executor by round-executor when plan includes DB work.
|
|
5
|
-
tools: Read, Write, Edit, Glob, Grep, Bash,
|
|
5
|
+
tools: Read, Write, Edit, Glob, Grep, Bash, mcp__supabase__apply_migration, mcp__supabase__execute_sql, mcp__supabase__list_tables, mcp__supabase__list_migrations, mcp__supabase__get_advisors, mcp__supabase__generate_typescript_types, mcp__supabase__search_docs
|
|
6
6
|
model: sonnet
|
|
7
7
|
effort: xhigh
|
|
8
8
|
---
|
|
@@ -70,10 +70,10 @@ Before any DB mutation, perform all three pre-flight checks in order:
|
|
|
70
70
|
|
|
71
71
|
Return `blocked` status with the cause list so the round-executor can surface it to the user.
|
|
72
72
|
|
|
73
|
-
3. **Main Project Guard.** Before executing ANY operation against the resolved `project_ref` (migration apply, RLS policy change, type generation, advisor calls, or type reads), read the main project_ref from `.codebyplan.json`:
|
|
73
|
+
3. **Main Project Guard.** Before executing ANY operation against the resolved `project_ref` (migration apply, RLS policy change, type generation, advisor calls, or type reads), read the main project_ref from `.codebyplan/shipment.json`:
|
|
74
74
|
|
|
75
75
|
```bash
|
|
76
|
-
jq -r '.shipment.surfaces.supabase.project_ref' .codebyplan.json
|
|
76
|
+
jq -r '.shipment.surfaces.supabase.project_ref' .codebyplan/shipment.json
|
|
77
77
|
```
|
|
78
78
|
|
|
79
79
|
If the `project_ref` resolved above matches this value, the agent is targeting the
|
|
@@ -187,6 +187,16 @@ For access pattern changes:
|
|
|
187
187
|
3. Follow existing patterns in the project for policy naming
|
|
188
188
|
4. Test with: `execute_sql` to verify policy exists
|
|
189
189
|
|
|
190
|
+
**Security requirements (official Supabase alignment):**
|
|
191
|
+
|
|
192
|
+
- Authorization predicates read `app_metadata` / `raw_app_meta_data`, never `user_metadata` / `raw_user_meta_data` — the latter is user-editable and basing a policy on it is a privilege-escalation hole.
|
|
193
|
+
- `update` policies must declare BOTH a `using` clause and a `with check` clause. `using` gates which existing rows are updatable; `with check` gates the new row values. Omitting `with check` lets a caller rewrite a row (e.g. reassign its owner) to a value that escapes the policy.
|
|
194
|
+
- `auth.role()` is deprecated — scope policies to roles with the `to` clause (`to authenticated`, `to anon`) instead of comparing `auth.role()` inside the predicate.
|
|
195
|
+
- Views in an exposed schema must be created with `security_invoker = true` (Postgres 15+); otherwise the view runs as its owner and bypasses the querying user's row-level security.
|
|
196
|
+
- Prefer `security invoker` functions. A `security definer` function bypasses row-level security and runs as its owner — reserve it for the recursion-break helper in Step 2.75, keep it in a non-exposed schema, guard it with an `auth.uid()` ownership check, and harden `search_path` per `rules/migration-security.md`.
|
|
197
|
+
- Capture any ad-hoc schema change made interactively via `execute_sql` during iteration back into a migration file (Step 2) — never leave a change preview-branch-only.
|
|
198
|
+
- When the correct syntax for a policy, view, or function construct is uncertain, call `search_docs` to consult authoritative Supabase documentation before authoring.
|
|
199
|
+
|
|
190
200
|
### Step 4: Generate TypeScript Types
|
|
191
201
|
|
|
192
202
|
After schema changes:
|
|
@@ -225,5 +235,6 @@ Populate all output contract fields. Include every file changed.
|
|
|
225
235
|
|
|
226
236
|
- **Spawned by**: `round-executor` (as sub-executor when plan includes DB work)
|
|
227
237
|
- **Returns to**: `round-executor`
|
|
228
|
-
- **Tools**: Supabase MCP tools (`apply_migration`, `execute_sql`, `list_tables`, `list_migrations`, `generate_typescript_types`), Bash for CLI commands
|
|
238
|
+
- **Tools**: Supabase MCP tools (`apply_migration`, `execute_sql`, `list_tables`, `list_migrations`, `get_advisors`, `generate_typescript_types`, `search_docs`), Bash for CLI commands
|
|
229
239
|
- **Rule**: `migration-infrastructure.md` — cross-agent mandate for migration push verification, backfill, and error resolution
|
|
240
|
+
- **Official skills** (vendored, for deeper guidance): `supabase` — Supabase security checklist, MCP surface, RLS/auth policy authoring; `supabase-postgres-best-practices` — Postgres query optimization, schema/index design, RLS performance.
|
|
@@ -9,9 +9,11 @@
|
|
|
9
9
|
|
|
10
10
|
# ===== Path-pattern enforcement =====
|
|
11
11
|
# Each row: enforce_path_pattern <prefix> <full_pattern> <block_msg> <expected_hint>
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
# references/ (plural) + assets/ subdirs and leading-underscore filenames (e.g. references/_sections.md)
|
|
13
|
+
# are carried by vendored upstream skills (.claude/skills/supabase*, supabase-postgres-best-practices).
|
|
14
|
+
_SUB='(templates|examples|reference|references|scripts|assets)/[a-z0-9._-]+\.(md|sh|json|ya?ml)'
|
|
15
|
+
enforce_path_pattern '^/\.claude/skills/' "^/\.claude/skills/[a-z0-9-]+/(SKILL\.md|PROVENANCE\.md|CHANGELOG\.md|[a-z0-9-]+\.md|${_SUB})$" 'Invalid skill path' "Pattern: /.claude/skills/{name}/SKILL.md | /.claude/skills/{name}/(PROVENANCE|CHANGELOG).md | /.claude/skills/{name}/{file}.md | /.claude/skills/{name}/(templates|examples|reference|references|scripts|assets)/{file}.{md,sh,json,yaml}"
|
|
16
|
+
enforce_path_pattern '^/\.claude/agents/' "^/\.claude/agents/([a-z0-9-]+\.md|[a-z0-9-]+/(AGENT\.md|PROVENANCE\.md|CHANGELOG\.md|[a-z0-9-]+\.md|${_SUB}))$" 'Invalid agent path' "Pattern: /.claude/agents/{name}.md | /.claude/agents/{name}/AGENT.md | /.claude/agents/{name}/(PROVENANCE|CHANGELOG).md | /.claude/agents/{name}/{file}.md | /.claude/agents/{name}/(templates|examples|reference|references|scripts|assets)/{file}.{md,sh,json,yaml}"
|
|
15
17
|
enforce_path_pattern '^/\.claude/rules/' '^/\.claude/rules/[a-z0-9-]+\.md$' 'Invalid native rule path' 'Pattern: /.claude/rules/{name}.md'
|
|
16
18
|
if match_path '^/\.claude/hooks/' && ! match_path '^/\.claude/hooks/__test-fixtures__/'; then
|
|
17
19
|
if ! match_path '^/\.claude/hooks/[a-z-]+\.sh$'; then
|
|
@@ -48,10 +48,11 @@ esac
|
|
|
48
48
|
FILENAME=$(basename "$FILE_PATH" ".$EXT")
|
|
49
49
|
|
|
50
50
|
if match_path '^/(\.claude|docs)/'; then
|
|
51
|
-
# Skip special naming patterns (SKILL/AGENT/CLAUDE/MEMORY/TASK-N/CHK-NNN/date/week-N/research phase/README/INDEX)
|
|
51
|
+
# Skip special naming patterns (SKILL/AGENT/CLAUDE/MEMORY/TASK-N/CHK-NNN/date/week-N/research phase/README/INDEX/PROVENANCE/CHANGELOG)
|
|
52
|
+
# PROVENANCE/CHANGELOG: uppercase filenames carried by vendored upstream skills (e.g. .claude/skills/supabase/*)
|
|
52
53
|
# CHK formats: CHK-001 (generic) or CHK-H001/CHK-A001/CHK-B001 (launch: Homepage/Application/Backdoor)
|
|
53
54
|
# INDEX: grep-native registry filename used by the architecture-map pipeline (.claude/architecture/INDEX.md) and vendor docs
|
|
54
|
-
if ! echo "$FILENAME" | grep -qE '^(SKILL|AGENT|CLAUDE|MEMORY|TASK-[1-9]|[0-9]{2}-[0-9]{2}-[0-9]{2}-CHK-([0-9]{3}|[HAB][0-9]{3})|CHK-([0-9]{3}|[HAB][0-9]{3})|[0-9]{2}-[0-9]{2}-[0-9]{2}|week-[0-9]+|[1-8]-|README|INDEX)'; then
|
|
55
|
+
if ! echo "$FILENAME" | grep -qE '^(SKILL|AGENT|CLAUDE|MEMORY|TASK-[1-9]|[0-9]{2}-[0-9]{2}-[0-9]{2}-CHK-([0-9]{3}|[HAB][0-9]{3})|CHK-([0-9]{3}|[HAB][0-9]{3})|[0-9]{2}-[0-9]{2}-[0-9]{2}|week-[0-9]+|[1-8]-|README|INDEX|PROVENANCE|CHANGELOG)'; then
|
|
55
56
|
if echo "$FILENAME" | grep -qE '[A-Z]|_'; then
|
|
56
57
|
block "Filename must be kebab-case (lowercase with hyphens)" "Got: $FILENAME, Expected: $(echo "$FILENAME" | tr '[:upper:]' '[:lower:]' | tr '_' '-')"
|
|
57
58
|
fi
|
|
@@ -133,6 +133,8 @@
|
|
|
133
133
|
"Skill(cbp-task-start)",
|
|
134
134
|
"Skill(cbp-task-testing)",
|
|
135
135
|
"Skill(cbp-todo)",
|
|
136
|
+
"Skill(supabase)",
|
|
137
|
+
"Skill(supabase-postgres-best-practices)",
|
|
136
138
|
"mcp__codebyplan__get_checkpoints",
|
|
137
139
|
"mcp__codebyplan__get_current_task",
|
|
138
140
|
"mcp__codebyplan__get_eslint_presets",
|
|
@@ -76,6 +76,14 @@ Pick the pattern that fits. This drives frontmatter choices:
|
|
|
76
76
|
|
|
77
77
|
Concrete templates: [examples/task-skill.md](examples/task-skill.md), [examples/knowledge-skill.md](examples/knowledge-skill.md), [examples/fork-skill.md](examples/fork-skill.md), [examples/dynamic-context.md](examples/dynamic-context.md).
|
|
78
78
|
|
|
79
|
+
#### Convention: User-only / permission-gated finalizer
|
|
80
|
+
|
|
81
|
+
A Task-pattern skill that must only run on explicit user confirmation is a **permission-gated finalizer**:
|
|
82
|
+
|
|
83
|
+
- MUST carry `disable-model-invocation: true` — the model cannot invoke it; only the user can (via `/skill-name`).
|
|
84
|
+
- Any upstream skill that auto-triggers it MUST instead emit a `Next: /skill-name` directive and STOP — model invocation of a `disable-model-invocation` skill is blocked at the runtime level.
|
|
85
|
+
- Canonical example: `/cbp-round-complete` (the round finalizer). `/cbp-round-update` routes a clean triage via a `Next: /cbp-round-complete` directive and stops — it cannot invoke round-complete directly.
|
|
86
|
+
|
|
79
87
|
### Step 5 — Fill the frontmatter
|
|
80
88
|
|
|
81
89
|
Read `${CLAUDE_SKILL_DIR}/templates/skill.md` as the canonical frontmatter. Fill only the fields you need — every field except `description` is optional, and even `description` falls back to the first markdown paragraph.
|
|
@@ -9,7 +9,7 @@ Source: official Claude Code skills spec. All fields are optional; `description`
|
|
|
9
9
|
| `when_to_use` | Additional trigger phrases. Appended to `description` in the listing |
|
|
10
10
|
| `argument-hint` | Autocomplete hint, e.g. `[issue-number]` |
|
|
11
11
|
| `arguments` | Named positional args, e.g. `[file mode]` → `$file`, `$mode` |
|
|
12
|
-
| `disable-model-invocation` | `true` → only user can invoke (via `/name`) |
|
|
12
|
+
| `disable-model-invocation` | `true` → only user can invoke (via `/name`). Upstream skills that auto-trigger this skill MUST emit a `Next: /name` directive instead — model invocation is blocked by the runtime; see SKILL.md Step 4 "Convention: User-only / permission-gated finalizer" |
|
|
13
13
|
| `user-invocable` | `false` → hidden from `/` menu, Claude-only |
|
|
14
14
|
| `allowed-tools` | Pre-approve tools while the skill is active |
|
|
15
15
|
| `model` | Override model for this skill's turn. **CBP skills normally OMIT this** so the skill inherits the active session model. Pinning a model (e.g. `sonnet`) forces that model and can carry the session's 1M `[1m]` context tier onto the skill, triggering "usage credits required for 1M context". Set it only as a deliberate, documented exception — see [/cbp-build-cc-mode](../../build-cc-mode/SKILL.md) |
|
|
@@ -33,3 +33,5 @@ Total skill-description budget in context: 1% of the context window (fallback 8,
|
|
|
33
33
|
| (default) | Yes | Yes | Description in context; body loads on invoke |
|
|
34
34
|
| `disable-model-invocation: true` | Yes | No | Description NOT in context; body loads on user invoke |
|
|
35
35
|
| `user-invocable: false` | No | Yes | Description in context; body loads on auto-invoke |
|
|
36
|
+
|
|
37
|
+
> **Upstream-directive rule**: a skill with `disable-model-invocation: true` cannot be invoked by another skill. Any upstream skill that auto-triggers it MUST emit a `Next: /skill-name` close-out directive and stop. See "Convention: User-only / permission-gated finalizer" in SKILL.md Step 4 for the full pattern and canonical example.
|
|
@@ -3,6 +3,7 @@ scope: org-shared
|
|
|
3
3
|
name: cbp-round-complete
|
|
4
4
|
description: Reconcile user git-add approvals, complete the round, and route to the next step
|
|
5
5
|
argument-hint: [chk-task-round | task-round]
|
|
6
|
+
disable-model-invocation: true
|
|
6
7
|
triggers: [cbp-task-check, cbp-standalone-task-check, cbp-round-input]
|
|
7
8
|
effort: low
|
|
8
9
|
---
|
|
@@ -28,9 +29,9 @@ Set `KIND` for the rest of this skill. MCP tool names vary by KIND:
|
|
|
28
29
|
|
|
29
30
|
# Round Complete Command
|
|
30
31
|
|
|
31
|
-
The **
|
|
32
|
+
The **user-invoked finalizer** for a round that `/cbp-round-update` triaged as clean. round-complete carries `disable-model-invocation: true`, so the model cannot invoke it — `/cbp-round-update` *directs* the user here with a `Next: /cbp-round-complete` directive, and the user runs it. It reconciles which files the **user** approved via `git add`, completes the round, and routes to the next step.
|
|
32
33
|
|
|
33
|
-
This skill is gated by an `ask`-tier `Skill(cbp-round-complete)` permission rule in `settings.json`. **The permission prompt IS the user confirmation** — there is NO AskUserQuestion inside this skill. If the user declines the permission, the skill does not run: nothing is synced, no round is completed, and the user can stage files and re-invoke
|
|
34
|
+
This skill is gated by an `ask`-tier `Skill(cbp-round-complete)` permission rule in `settings.json`. **The permission prompt IS the user confirmation** on the user's direct invoke — there is NO AskUserQuestion inside this skill. If the user declines the permission, the skill does not run: nothing is synced, no round is completed, and the user can stage files and re-invoke `/cbp-round-complete` when ready.
|
|
34
35
|
|
|
35
36
|
## HARD GATE — Every Step Must Execute
|
|
36
37
|
|
|
@@ -153,16 +154,16 @@ Payload: `round.context.round_complete = { staged_count, unstaged_count, route,
|
|
|
153
154
|
|
|
154
155
|
## Key Rules
|
|
155
156
|
|
|
156
|
-
- **
|
|
157
|
+
- **User-invoked only** — round-complete carries `disable-model-invocation: true`, so the model cannot invoke it. `/cbp-round-update` *directs* the user here on a clean triage (a `Next: /cbp-round-complete` directive); the user runs the skill.
|
|
158
|
+
- **Permission prompt = confirmation** — gated by `ask`-tier `Skill(cbp-round-complete)`. Because the skill is `disable-model-invocation: true`, this gate applies to the user's **direct** `/cbp-round-complete` invocation. NEVER add an AskUserQuestion to confirm running; the harness prompt is the gate. A declined permission is a clean no-op.
|
|
157
159
|
- **Step 2 (CLI) must exit 0** — if it fails, STOP before `complete_round`. The merge semantics are enforced by the CLI.
|
|
158
160
|
- **NEVER ask the user to git add files** — Step 2 only reads staging status. **NEVER stage files** — Claude does not touch the git staging area; the user's `git add` is the approval signal.
|
|
159
161
|
- **standalone KIND Step 3**: `caller_worktree_id` is REQUIRED for `complete_standalone_round` — always resolve and pass it.
|
|
160
|
-
- **Auto-triggered by `/cbp-round-update`** (clean triage), or run manually by the user.
|
|
161
162
|
|
|
162
163
|
## Integration
|
|
163
164
|
|
|
164
|
-
- **Gates**: `ask`-tier `Skill(cbp-round-complete)` permission prompt — the harness confirms before the skill runs; a decline makes NO writes. There is no in-skill AskUserQuestion.
|
|
165
|
-
- **
|
|
165
|
+
- **Gates**: `ask`-tier `Skill(cbp-round-complete)` permission prompt on the user's direct invoke — the harness confirms before the skill runs; a decline makes NO writes. There is no in-skill AskUserQuestion.
|
|
166
|
+
- **Invoked by**: the user only — round-complete carries `disable-model-invocation: true`, so the model cannot invoke it. `/cbp-round-update` *directs* the user here on a clean triage (a `Next: /cbp-round-complete` directive) but does not invoke it.
|
|
166
167
|
- **Reads (checkpoint KIND)**: `.codebyplan/state/checkpoints/<id>.json`, `.codebyplan/state/checkpoints/<id>/tasks/<id>.json`, `.codebyplan/state/checkpoints/<id>/tasks/<id>/rounds/<id>.json` (local-first; run `npx codebyplan sync` if missing; break-glass: MCP `get_current_task` / `get_rounds`). Delegates git+approval sync to `npx codebyplan round sync-approvals`.
|
|
167
168
|
- **Reads (standalone KIND)**: MCP `get_current_standalone_task` / `get_standalone_rounds` (standalone KIND still uses MCP until a later task).
|
|
168
169
|
- **Writes (checkpoint KIND)**: `codebyplan round complete` (Step 3); `codebyplan round update` (Step 4 breadcrumb). Break-glass: MCP `complete_round` / `update_round`. Round+task `files_changed` written by the CLI sync-approvals.
|
|
@@ -141,7 +141,7 @@ Example tables and the in-scope/out-of-scope classification: see `reference/find
|
|
|
141
141
|
- Skip the polish-spiral stop-gate (auto-loop has its own cap-exhausted termination).
|
|
142
142
|
- Skip Step 7's inline auto-apply (findings are deferred to the next loop round, not applied this round).
|
|
143
143
|
- Save findings via `update_round` exactly as in manual mode.
|
|
144
|
-
- Auto-trigger `/cbp-round-update` immediately. round-update triages the round and either routes to `/cbp-round-input` (spawn another round) or `/cbp-round-complete`
|
|
144
|
+
- Auto-trigger `/cbp-round-update` immediately. round-update triages the round and either routes to `/cbp-round-input` (spawn another round) or **directs the user to run** `/cbp-round-complete` on a clean exit — see cbp-round-update SKILL.md Step 2/3.
|
|
145
145
|
|
|
146
146
|
**Else (manual mode — flag absent or false):**
|
|
147
147
|
|
|
@@ -156,7 +156,7 @@ Step 7 already auto-applied in-scope findings and logged them to `round.context.
|
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
158
|
```
|
|
159
|
-
3. Auto-trigger `/cbp-round-update`. round-update triages the round: if out-of-scope findings (or a hard-fail) remain it routes to `/cbp-round-input` (which picks up the findings from round context and includes them in the new round's requirements automatically); if the round is clean it
|
|
159
|
+
3. Auto-trigger `/cbp-round-update`. round-update triages the round: if out-of-scope findings (or a hard-fail) remain it routes to `/cbp-round-input` (which picks up the findings from round context and includes them in the new round's requirements automatically); if the round is clean it **directs the user to run** `/cbp-round-complete` (the user-invoked finalizer that reconciles the user's `git add`s and completes the round).
|
|
160
160
|
|
|
161
161
|
## Key Rules
|
|
162
162
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
scope: org-shared
|
|
3
3
|
name: cbp-round-update
|
|
4
|
-
description: Triage a finished round (Claude-only)
|
|
4
|
+
description: Triage a finished round (Claude-only); direct user to run round-complete on a clean round, or trigger round-input when more work is needed
|
|
5
5
|
argument-hint: [chk-task-round | task-round]
|
|
6
|
-
triggers: [cbp-round-
|
|
6
|
+
triggers: [cbp-round-input]
|
|
7
7
|
effort: low
|
|
8
8
|
---
|
|
9
9
|
|
|
@@ -35,7 +35,7 @@ The completion + file-approval reconcile (`sync-approvals`, `complete_round` / `
|
|
|
35
35
|
|
|
36
36
|
## Routing in one line
|
|
37
37
|
|
|
38
|
-
- **Round is clean** →
|
|
38
|
+
- **Round is clean** → **direct the user to run** `/cbp-round-complete` (the user-invoked finalizer reconciles your `git add`s and completes the round; round-update cannot invoke it — round-complete is `disable-model-invocation: true`).
|
|
39
39
|
- **Round needs more work** → trigger `/cbp-round-input` (more changes / planning).
|
|
40
40
|
|
|
41
41
|
## Instructions
|
|
@@ -93,7 +93,7 @@ Display a one-line triage summary, e.g. `"ROUND-N triage: clean"` or `"ROUND-N t
|
|
|
93
93
|
|
|
94
94
|
### Step 3: Route
|
|
95
95
|
|
|
96
|
-
**3a — Clean → `/cbp-round-complete`.**
|
|
96
|
+
**3a — Clean → direct the user to `/cbp-round-complete`.** STOP and surface the directive: `Round clean. Next: run /cbp-round-complete to reconcile your git adds and finalize.` round-update does NOT invoke round-complete — round-complete carries `disable-model-invocation: true`, so only the user can run it (its `ask`-tier permission prompt is the user's confirmation on that direct invoke). Once the user runs it, round-complete reconciles the `git add`s, completes the round, and routes onward (all files staged → task-check; some withheld → round-input). round-update writes nothing here beyond the Step 2 summary. In `auto_loop_mode`, a clean triage is the loop's success exit — the directive applies here too (the user invokes round-complete to finalize); the loop continues only via the not-clean path in 3b, and round-complete owns the degenerate clean-but-unstaged guard.
|
|
97
97
|
|
|
98
98
|
**3b — Not clean → `/cbp-round-input`.** More changes or planning are needed. Routing is **independent of git staging** — round-input is reachable whether or not the user has staged anything (it performs its own deep analysis of the unapproved files). Two sub-cases:
|
|
99
99
|
|
|
@@ -104,7 +104,7 @@ Display a one-line triage summary, e.g. `"ROUND-N triage: clean"` or `"ROUND-N t
|
|
|
104
104
|
|
|
105
105
|
## Key Rules
|
|
106
106
|
|
|
107
|
-
- **Autonomous + Claude-only** — round-update never prompts before running. It is auto-triggered by `/cbp-round-end`.
|
|
107
|
+
- **Autonomous + Claude-only** — round-update never prompts before running. It is auto-triggered by `/cbp-round-end`. On a clean triage it **directs** the user to run `/cbp-round-complete` — it cannot invoke that skill (`disable-model-invocation: true`); the confirmation step is round-complete's own `ask`-tier permission prompt on the user's direct invoke, not an AskUserQuestion here. (The auto-loop cap-exhausted AskUserQuestion in Step 3b is a genuine user decision, not a run gate.)
|
|
108
108
|
- **Triage, never finalize** — round-update does NOT call `sync-approvals`, `complete_round`, or `complete_standalone_round`, and does NOT write file approvals. All of that is `/cbp-round-complete`.
|
|
109
109
|
- **Never touches git** — round-update reads `claude_approved` from the DB only; it never reads staging, asks the user to `git add`, or stages files.
|
|
110
110
|
- **git-add independence** — the "needs more work" route to `/cbp-round-input` fires regardless of whether files are staged. There is no clean-but-unstaged dead-end.
|
|
@@ -117,4 +117,5 @@ Display a one-line triage summary, e.g. `"ROUND-N triage: clean"` or `"ROUND-N t
|
|
|
117
117
|
- **Reads (standalone KIND)**: MCP `get_current_standalone_task`, `get_standalone_rounds` — standalone still uses MCP
|
|
118
118
|
- **Writes (checkpoint KIND)**: `codebyplan round update` — audit only (`auto_loop_decision` / `auto_loop_cap_exhausted`; break-glass: MCP `update_round`). No completion, no file-approval writes.
|
|
119
119
|
- **Writes (standalone KIND)**: MCP `update_standalone_round` — audit only — standalone still uses MCP
|
|
120
|
-
- **Triggers**: `/cbp-round-
|
|
120
|
+
- **Triggers**: `/cbp-round-input` (not-clean triage: outstanding findings, hard-fail, or unapproved Claude checks — fires independent of git staging; also the auto-loop dirty spawn), cap-exhausted prompt routes from Step 3b (any of the three options)
|
|
121
|
+
- **Directs the user to**: `/cbp-round-complete` (clean triage) — round-update cannot invoke it (`disable-model-invocation: true`); it emits a `Next: /cbp-round-complete` directive and the user runs it (its `ask`-tier permission prompt is the confirmation)
|
|
@@ -342,3 +342,4 @@ Both emit `status: passed` so callers proceed; the `reason` differs for traceabi
|
|
|
342
342
|
**Callers**: `cbp-ship-main` Step 2.5 invokes this skill pre-merge (`--mode pre_merge --target production`, only when a PR already exists for the branch); the caller proceeds on `passed` (Supabase Preview check green — including the CI-level `skipping` bucket, which Step 8 maps to `passed`) and `skipped` (no DB-path changes detected — the gate did not apply), and stops on `blocked`/`pending_pr`. Note: `status: "skipped"` is NOT the CI `skipping` bucket — the two are distinct layers.
|
|
343
343
|
**Canonical bucket contract**: the gh-checks bucket vocabulary used in Step 6 — `pass|fail|pending|skipping|cancel` — is the single canonical contract shared with `evaluateChecks()` in `packages/codebyplan-package/src/lib/ship.ts` (the generic poller inside `codebyplan ship`). Only `pass`/`skipping` are non-blocking, `pending` waits, and every other disposition blocks (fail-safe). The two pollers MUST NOT drift — any change to this enum or its dispositions must land in both places.
|
|
344
344
|
**Tools used**: `mcp__supabase__list_branches` for project_ref resolution; `mcp__supabase__get_logs` for failure diagnostics; `gh pr checks` for status polling; `supabase --experimental branches get` as CLI fallback.
|
|
345
|
+
- Official skill (vendored): `supabase` — advisor findings surfaced by this gate are scored against the Supabase security checklist.
|
|
@@ -270,6 +270,8 @@ Skip Steps 5.5 and 6 (dry-run pre-flight and apply) and proceed directly to Step
|
|
|
270
270
|
|
|
271
271
|
## Step 5 — Scaffold or Adopt
|
|
272
272
|
|
|
273
|
+
> Security reminder for authored migrations: when a migration creates row-level-security policies or views, follow the official `supabase` checklist — `update` policies need both `using` and `with check`; views in exposed schemas need `security_invoker = true`; authorization reads `app_metadata`, not `user_metadata`; `auth.role()` is deprecated — scope to roles with the `to` clause (`to authenticated`, `to anon`).
|
|
274
|
+
|
|
273
275
|
Parse `$ARGUMENTS`:
|
|
274
276
|
|
|
275
277
|
### Case A: `--new <name>`
|
|
@@ -439,4 +441,4 @@ Next: open a PR (if not already open) and the Supabase Preview check will run au
|
|
|
439
441
|
|
|
440
442
|
## Integration
|
|
441
443
|
|
|
442
|
-
Invoked by the developer or by `cbp-database-agent`'s routing rule. Companion: `/cbp-supabase-setup` (one-time enablement); ship-time hard-block lives in `cbp-supabase-branch-check`. References: [reference/advisor-triage.md](reference/advisor-triage.md) (severity), [reference/cli-fallback.md](reference/cli-fallback.md) (CLI apply). Context recording uses CLI write-through (`codebyplan checkpoint update` / `codebyplan task update`); MCP `update_checkpoint` / `update_task` as documented break-glass when CLI unavailable.
|
|
444
|
+
Invoked by the developer or by `cbp-database-agent`'s routing rule. Companion: `/cbp-supabase-setup` (one-time enablement); ship-time hard-block lives in `cbp-supabase-branch-check`. References: [reference/advisor-triage.md](reference/advisor-triage.md) (severity), [reference/cli-fallback.md](reference/cli-fallback.md) (CLI apply). Context recording uses CLI write-through (`codebyplan checkpoint update` / `codebyplan task update`); MCP `update_checkpoint` / `update_task` as documented break-glass when CLI unavailable. Deeper guidance: the vendored official skills `supabase` (security checklist, RLS/auth authoring, MCP surface) and `supabase-postgres-best-practices` (schema/index design, query performance).
|
|
@@ -243,3 +243,4 @@ Ready for /cbp-ship. Every PR will now get an isolated Supabase preview environm
|
|
|
243
243
|
|
|
244
244
|
- Dashboard walkthrough + GitHub checklist: [reference/branching-setup.md](reference/branching-setup.md)
|
|
245
245
|
- CLI detection + branch parsing + manual fallback: [reference/cli-fallback.md](reference/cli-fallback.md)
|
|
246
|
+
- Official skills (vendored): `supabase` and `supabase-postgres-best-practices` — deeper Supabase setup-security and Postgres best-practice guidance.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.1.4](https://github.com/supabase/agent-skills/compare/v0.1.3...v0.1.4) (2026-06-05)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add instructions to check changelog ([#74](https://github.com/supabase/agent-skills/issues/74)) ([4bb13d8](https://github.com/supabase/agent-skills/commit/4bb13d858d19f1f848505a66f46fc9603fdcde95))
|
|
9
|
+
* add npm supply-chain security guidance to supabase skill ([#94](https://github.com/supabase/agent-skills/issues/94)) ([82df90a](https://github.com/supabase/agent-skills/commit/82df90a5de1cd84386d8bc192746e50343b86dc0))
|
|
10
|
+
* instructions on exposing tables to the data api ([#71](https://github.com/supabase/agent-skills/issues/71)) ([f15a5a4](https://github.com/supabase/agent-skills/commit/f15a5a40779072a530c9e53c3f14ec4131118ea6))
|
|
11
|
+
* using Supabase agent skills ([#12](https://github.com/supabase/agent-skills/issues/12)) ([7c2e389](https://github.com/supabase/agent-skills/commit/7c2e3894fddfde8eb6c77d2a8921904543b9be7a))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
* bump supabase skill to v0.1.1 and fix Data API broken link ([#72](https://github.com/supabase/agent-skills/issues/72)) ([5a6542e](https://github.com/supabase/agent-skills/commit/5a6542e08fc026d90c9a6a0f5a67749e9ceb9946))
|
|
17
|
+
* cover SECURITY DEFINER, auth.role() deprecation, and BOLA in security checklist ([#85](https://github.com/supabase/agent-skills/issues/85)) ([133f43e](https://github.com/supabase/agent-skills/commit/133f43e8c2ffc48823ff0630c692cabecea3e3a3))
|
|
18
|
+
* update Data API doc link and bump supabase skill to v0.1.1 ([#73](https://github.com/supabase/agent-skills/issues/73)) ([e5f7a7c](https://github.com/supabase/agent-skills/commit/e5f7a7cfd697765848ffd6a4505f3c02e1ee17ee))
|
|
19
|
+
|
|
20
|
+
## [0.1.3](https://github.com/supabase/agent-skills/compare/v0.1.2...v0.1.3) (2026-06-02)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Features
|
|
24
|
+
|
|
25
|
+
* add instructions to check changelog ([#74](https://github.com/supabase/agent-skills/issues/74)) ([4bb13d8](https://github.com/supabase/agent-skills/commit/4bb13d858d19f1f848505a66f46fc9603fdcde95))
|
|
26
|
+
* add npm supply-chain security guidance to supabase skill ([#94](https://github.com/supabase/agent-skills/issues/94)) ([82df90a](https://github.com/supabase/agent-skills/commit/82df90a5de1cd84386d8bc192746e50343b86dc0))
|
|
27
|
+
* instructions on exposing tables to the data api ([#71](https://github.com/supabase/agent-skills/issues/71)) ([f15a5a4](https://github.com/supabase/agent-skills/commit/f15a5a40779072a530c9e53c3f14ec4131118ea6))
|
|
28
|
+
* using Supabase agent skills ([#12](https://github.com/supabase/agent-skills/issues/12)) ([7c2e389](https://github.com/supabase/agent-skills/commit/7c2e3894fddfde8eb6c77d2a8921904543b9be7a))
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
### Bug Fixes
|
|
32
|
+
|
|
33
|
+
* bump supabase skill to v0.1.1 and fix Data API broken link ([#72](https://github.com/supabase/agent-skills/issues/72)) ([5a6542e](https://github.com/supabase/agent-skills/commit/5a6542e08fc026d90c9a6a0f5a67749e9ceb9946))
|
|
34
|
+
* cover SECURITY DEFINER, auth.role() deprecation, and BOLA in security checklist ([#85](https://github.com/supabase/agent-skills/issues/85)) ([133f43e](https://github.com/supabase/agent-skills/commit/133f43e8c2ffc48823ff0630c692cabecea3e3a3))
|
|
35
|
+
* update Data API doc link and bump supabase skill to v0.1.1 ([#73](https://github.com/supabase/agent-skills/issues/73)) ([e5f7a7c](https://github.com/supabase/agent-skills/commit/e5f7a7cfd697765848ffd6a4505f3c02e1ee17ee))
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Provenance
|
|
2
|
+
|
|
3
|
+
This skill is vendored from the official Supabase **agent-skills** project.
|
|
4
|
+
|
|
5
|
+
| Field | Value |
|
|
6
|
+
|-------|-------|
|
|
7
|
+
| Upstream | https://github.com/supabase/agent-skills |
|
|
8
|
+
| Upstream path | `skills/supabase/` |
|
|
9
|
+
| Pinned commit | `1356046015476711a769601079262b5635929427` |
|
|
10
|
+
| Vendored on | 2026-06-08 |
|
|
11
|
+
| Skill version | `0.1.2` in `SKILL.md` frontmatter — but the vendored content is current to release **`0.1.4`** (2026-06-05) per `CHANGELOG.md`; upstream does not bump `metadata.version` per release, so trust the pinned commit + `CHANGELOG.md`, not the frontmatter field, when assessing drift |
|
|
12
|
+
| License | MIT |
|
|
13
|
+
|
|
14
|
+
The **only** CodeByPlan modification is the added `scope: org-shared` line in the
|
|
15
|
+
`SKILL.md` frontmatter (required by the CBP `.claude/` scope-marker convention —
|
|
16
|
+
`rules/scope-vocabulary.md`). Everything else — the `SKILL.md` body, `references/`,
|
|
17
|
+
`assets/`, and `CHANGELOG.md` — is upstream-verbatim.
|
|
18
|
+
|
|
19
|
+
## Refresh
|
|
20
|
+
|
|
21
|
+
Re-vendor when upstream publishes a newer version (typically on a `codebyplan`
|
|
22
|
+
package release):
|
|
23
|
+
|
|
24
|
+
1. Re-fetch every file under the upstream path above, pinned to the latest commit.
|
|
25
|
+
2. Re-inject the single `scope: org-shared` frontmatter line into `SKILL.md`.
|
|
26
|
+
3. Copy the result into **both** `packages/codebyplan-package/templates/skills/supabase/`
|
|
27
|
+
and the byte-identical `.claude/skills/supabase/` twin (GATE 6 sibling-identity).
|
|
28
|
+
4. Update the pinned commit + version in this file.
|
|
29
|
+
|
|
30
|
+
## License (MIT)
|
|
31
|
+
|
|
32
|
+
Copyright (c) 2026 Supabase
|
|
33
|
+
|
|
34
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
35
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
36
|
+
in the Software without restriction, including without limitation the rights
|
|
37
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
38
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
39
|
+
furnished to do so, subject to the following conditions:
|
|
40
|
+
|
|
41
|
+
The above copyright notice and this permission notice shall be included in all
|
|
42
|
+
copies or substantial portions of the Software.
|
|
43
|
+
|
|
44
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
45
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
46
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
47
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
48
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
49
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
50
|
+
SOFTWARE.
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
---
|
|
2
|
+
scope: org-shared
|
|
3
|
+
name: supabase
|
|
4
|
+
description: "Use when doing ANY task involving Supabase. Triggers: Supabase products (Database, Auth, Edge Functions, Realtime, Storage, Vectors, Cron, Queues); client libraries and SSR integrations (supabase-js, @supabase/ssr) in Next.js, React, SvelteKit, Astro, Remix; auth issues (login, logout, sessions, JWT, cookies, getSession, getUser, getClaims, RLS); Supabase CLI or MCP server; schema changes, migrations, security audits, Postgres extensions (pg_graphql, pg_cron, pg_vector)."
|
|
5
|
+
metadata:
|
|
6
|
+
author: supabase
|
|
7
|
+
version: "0.1.2"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Supabase
|
|
11
|
+
|
|
12
|
+
## Core Principles
|
|
13
|
+
|
|
14
|
+
**1. Supabase changes frequently — verify against changelog and current docs before implementing.**
|
|
15
|
+
Do not rely on training data for Supabase features. Function signatures, config.toml settings, and API conventions change between versions.
|
|
16
|
+
|
|
17
|
+
First, fetch `https://supabase.com/changelog.md` (a lightweight summary index — not a heavy pull), scan for `breaking-change` tags relevant to your task, and follow the linked page for any that apply. Then look up the relevant topic using the documentation access methods below.
|
|
18
|
+
|
|
19
|
+
**2. Verify your work.**
|
|
20
|
+
After implementing any fix, run a test query to confirm the change works. A fix without verification is incomplete.
|
|
21
|
+
|
|
22
|
+
**3. Recover from errors, don't loop.**
|
|
23
|
+
If an approach fails after 2-3 attempts, stop and reconsider. Try a different method, check documentation, inspect the error more carefully, and review relevant logs when available. Supabase issues are not always solved by retrying the same command, and the answer is not always in the logs, but logs are often worth checking before proceeding.
|
|
24
|
+
|
|
25
|
+
**4. Exposing tables to the Data API:** Depending on the user's [Data API settings](https://supabase.com/dashboard/project/<ref>/integrations/data_api/settings), newly created tables may not be automatically exposed via the Data (REST) API. If this is the case, `anon` and `authenticated` roles will need to be explicitly granted access.
|
|
26
|
+
|
|
27
|
+
> Note that this is separate from RLS, which controls which _rows_ are visible once a table is accessible, not whether the table is accessible at all.
|
|
28
|
+
|
|
29
|
+
When a user reports a SQL-created table is unexpectedly inaccessible, check their Data API settings and whether the roles have been granted access via explicit `GRANT` SQL. When granting public (`anon`/`authenticated`) access, always enable RLS too. See [Exposing a Table to the Data API](https://supabase.com/docs/guides/api/securing-your-api.md) for the full setup workflow.
|
|
30
|
+
|
|
31
|
+
**5. RLS in exposed schemas.**
|
|
32
|
+
Enable RLS on every table in any exposed schema, which includes `public` by default. This is critical in Supabase because tables in exposed schemas can be reachable through the Data API when the `anon`/`authenticated` roles have access (see [Exposing a Table to the Data API](https://supabase.com/docs/guides/api/securing-your-api.md)). For private schemas, prefer RLS as defense in depth. After enabling RLS, create policies that match the actual access model rather than defaulting every table to the same `auth.uid()` pattern.
|
|
33
|
+
|
|
34
|
+
**6. Security checklist.**
|
|
35
|
+
When working on any Supabase task that touches auth, RLS, views, storage, or user data, run through this checklist. These are Supabase-specific security traps that silently create vulnerabilities:
|
|
36
|
+
|
|
37
|
+
- **Auth and session security**
|
|
38
|
+
- **Never use `user_metadata` claims in JWT-based authorization decisions.** In Supabase, `raw_user_meta_data` is user-editable and can appear in `auth.jwt()`, so it is unsafe for RLS policies or any other authorization logic. Store authorization data in `raw_app_meta_data` / `app_metadata` instead.
|
|
39
|
+
- **Deleting a user does not invalidate existing access tokens.** Sign out or revoke sessions first, keep JWT expiry short for sensitive apps, and for strict guarantees validate `session_id` against `auth.sessions` on sensitive operations.
|
|
40
|
+
- **If you use `app_metadata` or `auth.jwt()` for authorization, remember JWT claims are not always fresh until the user's token is refreshed.**
|
|
41
|
+
|
|
42
|
+
- **API key and client exposure**
|
|
43
|
+
- **Never expose the `service_role` or secret key in public clients.** Prefer publishable keys for frontend code. Legacy `anon` keys are only for compatibility. In Next.js, any `NEXT_PUBLIC_` env var is sent to the browser.
|
|
44
|
+
|
|
45
|
+
- **RLS, views, and privileged database code**
|
|
46
|
+
- **Views bypass RLS by default.** In Postgres 15 and above, use `CREATE VIEW ... WITH (security_invoker = true)`. In older versions of Postgres, protect your views by revoking access from the `anon` and `authenticated` roles, or by putting them in an unexposed schema.
|
|
47
|
+
- **UPDATE requires a SELECT policy.** In Postgres RLS, an UPDATE needs to first SELECT the row. Without a SELECT policy, updates silently return 0 rows — no error, just no change.
|
|
48
|
+
- **`auth.role()` is deprecated — use the `TO` clause instead.** Supabase has deprecated `auth.role()` in favour of specifying the target role directly on the policy with `TO authenticated` or `TO anon`. Beyond deprecation, `auth.role() = 'authenticated'` breaks silently when anonymous sign-ins are enabled, because anonymous users carry the `authenticated` Postgres role and pass the check regardless of whether the user is genuinely signed in.
|
|
49
|
+
```sql
|
|
50
|
+
-- Deprecated (do not use)
|
|
51
|
+
create policy "example" on table_name for select
|
|
52
|
+
using ( auth.role() = 'authenticated' );
|
|
53
|
+
```
|
|
54
|
+
- **`TO authenticated` alone is authentication without authorization (BOLA / IDOR).** Using `TO authenticated` only checks the role — it does not restrict which rows a user can access. The correct pattern combines `TO authenticated` with an ownership predicate in `USING`:
|
|
55
|
+
```sql
|
|
56
|
+
create policy "example" on table_name for select
|
|
57
|
+
to authenticated
|
|
58
|
+
using ( (select auth.uid()) = user_id );
|
|
59
|
+
```
|
|
60
|
+
- **UPDATE policies require both `USING` and `WITH CHECK`.** Without `WITH CHECK`, a user can reassign a row's `user_id` to another user:
|
|
61
|
+
```sql
|
|
62
|
+
create policy "example" on table_name for update
|
|
63
|
+
to authenticated
|
|
64
|
+
using ( (select auth.uid()) = user_id )
|
|
65
|
+
with check ( (select auth.uid()) = user_id );
|
|
66
|
+
```
|
|
67
|
+
- **`SECURITY DEFINER` functions bypass RLS.** A `SECURITY DEFINER` function runs with its creator's privileges — typically a role with `bypassrls` (e.g., `postgres`). Never add `SECURITY DEFINER` to resolve a permission error; it silently removes access control without fixing the underlying cause. Prefer `SECURITY INVOKER`.
|
|
68
|
+
- **`SECURITY DEFINER` functions in `public` are callable by all roles.** Postgres grants `EXECUTE` to `PUBLIC` by default for every new function, so any `SECURITY DEFINER` function in `public` is a public API endpoint callable by `anon` and `authenticated` (which inherit from `PUBLIC`) without any additional grant. When `SECURITY DEFINER` is genuinely needed (e.g., bypassing RLS on an internal lookup table), keep the function in a non-exposed schema, always include an `auth.uid()` check in the function body, and run `supabase db advisors` after making changes.
|
|
69
|
+
|
|
70
|
+
- **Storage access control**
|
|
71
|
+
- **Storage upsert requires INSERT + SELECT + UPDATE.** Granting only INSERT allows new uploads but file replacement (upsert) silently fails. You need all three.
|
|
72
|
+
|
|
73
|
+
- **Dependency and supply-chain security**
|
|
74
|
+
- **Always pin package versions and commit lockfiles** when installing Supabase packages (`supabase-js`, `@supabase/ssr`, `supabase-py`, etc.). See the [npm security guide](https://supabase.com/docs/guides/security/npm-security.md) for the full checklist.
|
|
75
|
+
|
|
76
|
+
For any security concern not covered above, fetch the Supabase product security index: `https://supabase.com/docs/guides/security/product-security.md`
|
|
77
|
+
|
|
78
|
+
## Supabase CLI
|
|
79
|
+
|
|
80
|
+
Always discover commands via `--help` — never guess. The CLI structure changes between versions.
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
supabase --help # All top-level commands
|
|
84
|
+
supabase <group> --help # Subcommands (e.g., supabase db --help)
|
|
85
|
+
supabase <group> <command> --help # Flags for a specific command
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Supabase CLI Known gotchas:**
|
|
89
|
+
|
|
90
|
+
- `supabase db query` requires **CLI v2.79.0+** → use MCP `execute_sql` or `psql` as fallback
|
|
91
|
+
- `supabase db advisors` requires **CLI v2.81.3+** → use MCP `get_advisors` as fallback
|
|
92
|
+
- When you need a new migration SQL file, **always** create it with `supabase migration new <name>` first. Never invent a migration filename or rely on memory for the expected format.
|
|
93
|
+
|
|
94
|
+
**Version check and upgrade:** Run `supabase --version` to check. For CLI changelogs and version-specific features, consult the [CLI documentation](https://supabase.com/docs/reference/cli/introduction) or [GitHub releases](https://github.com/supabase/cli/releases).
|
|
95
|
+
|
|
96
|
+
## Supabase MCP Server
|
|
97
|
+
|
|
98
|
+
For setup instructions, server URL, and configuration, see the [MCP setup guide](https://supabase.com/docs/guides/getting-started/mcp).
|
|
99
|
+
|
|
100
|
+
**Troubleshooting connection issues** — follow these steps in order:
|
|
101
|
+
|
|
102
|
+
1. **Check if the server is reachable:**
|
|
103
|
+
`curl -so /dev/null -w "%{http_code}" https://mcp.supabase.com/mcp`
|
|
104
|
+
A `401` is expected (no token) and means the server is up. Timeout or "connection refused" means it may be down.
|
|
105
|
+
|
|
106
|
+
2. **Check `.mcp.json` configuration:**
|
|
107
|
+
Verify the project root has a valid `.mcp.json` with the correct server URL. If missing, create one pointing to `https://mcp.supabase.com/mcp`.
|
|
108
|
+
|
|
109
|
+
3. **Authenticate the MCP server:**
|
|
110
|
+
If the server is reachable and `.mcp.json` is correct but tools aren't visible, the user needs to authenticate. The Supabase MCP server uses OAuth 2.1 — tell the user to trigger the auth flow in their agent, complete it in the browser, and reload the session.
|
|
111
|
+
|
|
112
|
+
## Supabase Documentation
|
|
113
|
+
|
|
114
|
+
Before implementing any Supabase feature, find the relevant documentation. Use these methods in priority order:
|
|
115
|
+
|
|
116
|
+
1. **MCP `search_docs` tool** (preferred — returns relevant snippets directly)
|
|
117
|
+
2. **Fetch docs pages as markdown** — any docs page can be fetched by appending `.md` to the URL path.
|
|
118
|
+
3. **Web search** for Supabase-specific topics when you don't know which page to look at.
|
|
119
|
+
|
|
120
|
+
## Making and Committing Schema Changes
|
|
121
|
+
|
|
122
|
+
**To make schema changes, use `execute_sql` (MCP) or `supabase db query` (CLI).** These run SQL directly on the database without creating migration history entries, so you can iterate freely and generate a clean migration when ready.
|
|
123
|
+
|
|
124
|
+
Do NOT use `apply_migration` to change a local database schema — it writes a migration history entry on every call, which means you can't iterate, and `supabase db diff` / `supabase db pull` will produce empty or conflicting diffs. If you use it, you'll be stuck with whatever SQL you passed on the first try.
|
|
125
|
+
|
|
126
|
+
**When ready to commit** your changes to a migration file:
|
|
127
|
+
|
|
128
|
+
1. **Run advisors** → `supabase db advisors` (CLI v2.81.3+) or MCP `get_advisors`. Fix any issues.
|
|
129
|
+
2. **Review the Security Checklist above** if your changes involve views, functions, triggers, or storage.
|
|
130
|
+
3. **Generate the migration** → `supabase db pull <descriptive-name> --local --yes`
|
|
131
|
+
4. **Verify** → `supabase migration list --local`
|
|
132
|
+
|
|
133
|
+
## Reference Guides
|
|
134
|
+
|
|
135
|
+
- **Skill Feedback** → [references/skill-feedback.md](references/skill-feedback.md)
|
|
136
|
+
**MUST read when** the user reports that this skill gave incorrect guidance or is missing information.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
## What happened
|
|
2
|
+
|
|
3
|
+
**Task:** <!-- e.g., "Set up MFA on patient records" -->
|
|
4
|
+
|
|
5
|
+
**Skill said:** <!-- e.g., "Use auth.jwt()->'app_metadata' in the RLS policy" -->
|
|
6
|
+
|
|
7
|
+
**Expected:** <!-- e.g., "The function also needs SECURITY DEFINER + grant to supabase_auth_admin" -->
|
|
8
|
+
|
|
9
|
+
## Source
|
|
10
|
+
|
|
11
|
+
**File:** <!-- e.g., references/security-model.md -->
|
|
12
|
+
|
|
13
|
+
**Section:** <!-- e.g., "Trust Boundaries > user_metadata vs app_metadata" -->
|
|
14
|
+
|
|
15
|
+
## Fix suggestion
|
|
16
|
+
|
|
17
|
+
<!-- Leave blank if unsure -->
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Skill Feedback
|
|
2
|
+
|
|
3
|
+
Use this when the user reports that the skill gave incorrect guidance, is missing information, or could be improved. This is about the skill (agent instructions), not about Supabase the product.
|
|
4
|
+
|
|
5
|
+
## Steps
|
|
6
|
+
|
|
7
|
+
1. **Ask permission** — Ask the user if they'd like to submit feedback to the skill maintainers. If they decline, move on.
|
|
8
|
+
|
|
9
|
+
2. **Draft the issue** — Use the template at [assets/feedback-issue-template.md](../assets/feedback-issue-template.md) to structure the feedback. Fill in the fields based on the conversation. Always identify which specific reference file and section caused the problem.
|
|
10
|
+
|
|
11
|
+
3. **Submit** — Create a GitHub Issue on the `supabase/agent-skills` repository using the draft as the issue body. The title must follow this format: `user-feedback: <summary of the problem>`.
|
|
12
|
+
|
|
13
|
+
4. **Share the result** — Share the issue URL with the user after submission. If submission fails, give the user this link to create the issue manually:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
https://github.com/supabase/agent-skills/issues/new
|
|
17
|
+
```
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [1.3.0](https://github.com/supabase/agent-skills/compare/v1.2.0...v1.3.0) (2026-06-05)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add schema-constraints reference for safe migration patterns ([#30](https://github.com/supabase/agent-skills/issues/30)) ([9b236f3](https://github.com/supabase/agent-skills/commit/9b236f3ebd65d76a2c570f19931353da9c858d5a))
|
|
9
|
+
* using Supabase agent skills ([#12](https://github.com/supabase/agent-skills/issues/12)) ([7c2e389](https://github.com/supabase/agent-skills/commit/7c2e3894fddfde8eb6c77d2a8921904543b9be7a))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
* correct broken reference link in postgres best practices skill ([#58](https://github.com/supabase/agent-skills/issues/58)) ([f4e2277](https://github.com/supabase/agent-skills/commit/f4e22777fd8573537297b568c16e5a45a25927da))
|
|
15
|
+
* cover SECURITY DEFINER, auth.role() deprecation, and BOLA in security checklist ([#85](https://github.com/supabase/agent-skills/issues/85)) ([133f43e](https://github.com/supabase/agent-skills/commit/133f43e8c2ffc48823ff0630c692cabecea3e3a3))
|
|
16
|
+
|
|
17
|
+
## [1.2.0](https://github.com/supabase/agent-skills/compare/v1.1.1...v1.2.0) (2026-06-02)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Features
|
|
21
|
+
|
|
22
|
+
* add schema-constraints reference for safe migration patterns ([#30](https://github.com/supabase/agent-skills/issues/30)) ([9b236f3](https://github.com/supabase/agent-skills/commit/9b236f3ebd65d76a2c570f19931353da9c858d5a))
|
|
23
|
+
* using Supabase agent skills ([#12](https://github.com/supabase/agent-skills/issues/12)) ([7c2e389](https://github.com/supabase/agent-skills/commit/7c2e3894fddfde8eb6c77d2a8921904543b9be7a))
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
### Bug Fixes
|
|
27
|
+
|
|
28
|
+
* correct broken reference link in postgres best practices skill ([#58](https://github.com/supabase/agent-skills/issues/58)) ([f4e2277](https://github.com/supabase/agent-skills/commit/f4e22777fd8573537297b568c16e5a45a25927da))
|
|
29
|
+
* cover SECURITY DEFINER, auth.role() deprecation, and BOLA in security checklist ([#85](https://github.com/supabase/agent-skills/issues/85)) ([133f43e](https://github.com/supabase/agent-skills/commit/133f43e8c2ffc48823ff0630c692cabecea3e3a3))
|