Makes the repo's AI-agent setup tool-agnostic: instructions live in
`AGENTS.md` files, skills live in `.agents/skills/`, and Claude Code,
Codex, Cursor, and Copilot all read the same sources. Also sweeps the
skills for stale and duplicated content while everything was being
moved.
**Changed:**
- Every `CLAUDE.md` (root, `apps/studio`, `apps/docs`, `apps/kb`) is now
a one-line `@AGENTS.md` import; the content moved verbatim into an
`AGENTS.md` beside it. The root one moved from `.claude/CLAUDE.md` to
the repo root for consistency.
- All skills now live in `.agents/skills/`; `.claude/skills` is a single
symlink to it (replacing the old mix of real dirs and per-skill
symlinks). Path references in `.coderabbit.yaml`, code comments, and
docs updated to match.
- `.github/copilot-instructions.md` keeps only the review policy and
points at `AGENTS.md` + `.agents/skills/`. Copilot code review reads
those natively now, so the per-topic
`.github/instructions/*.instructions.md` files were duplicates of the
skills.
- Stale skill content fixed: `studio-queries` imported a toast library
Studio doesn't use, `telemetry-standards` and `studio-testing` used
import paths that don't resolve, `safe-sql-execution` cited a boundary
test that doesn't exist, the ask-the-docs references described an
`AiPrompt` mechanism that was replaced by the ID-keyed registry, plus a
handful of wrong paths, a self-contradicting `waitForTimeout` rule, an
invalid Playwright signature, and a ConfigCat flag described as PostHog.
- `studio-error-handling` now explains when to use `AlertError` (the
default) vs `ErrorMatcher`.
**Added:**
- `apps/docs/AGENTS.md` (docs test requirements, from the old Cursor
rule)
- `studio-shortcuts` skill (from the old Copilot instruction file,
verified against the current registry)
- `ask-the-docs/reference/graphql-endpoint.md` and
`search-embeddings.md` (from the old Cursor rules, with the missing
resolver/registration/codegen steps filled in)
- Feature-flag measurement section in `telemetry-standards`
**Removed:**
- `.cursor/` (rules folded in as above; skill symlinks no longer needed)
and `.cursorignore`
- `.github/instructions/` (8 files)
- `vercel-composition-patterns/AGENTS.md` – a 946-line verbatim
concatenation of its own `rules/` directory, and a nested `AGENTS.md`
that agents could auto-load as repo instructions
- `edit-the-docs/reference/structure-and-flow.md` – word-for-word copy
of the skill's own Phase 2 text
## To test
- `readlink .claude/skills` → `../.agents/skills`, and `ls
.claude/skills/copywriting/SKILL.md` resolves
- Open a Claude Code session at the repo root and in `apps/studio` – the
imported `AGENTS.md` content should load as before
- `git diff master --stat -M` shows the skill moves as 100% renames
(content unchanged except the listed fixes)
- Spot-check a fixed claim, e.g. `import { toast } from 'sonner'` in
`studio-queries`, or the `logs.all` ESLint rule cited in
`clickhouse-logs-queries/references/codebase-integration.md`
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **Documentation**
- Expanded guidance for documentation workflows, GraphQL resources,
search, ClickHouse logs, React forms, Studio testing, shortcuts,
telemetry, accessibility, copywriting, and composition patterns.
- Clarified local testing, linting, build workflows, error handling, and
AI coding agent usage.
- Added contributor guidance for the knowledge base, documentation, and
Studio areas.
- **Chores**
- Consolidated agent instructions and skill references.
- Removed obsolete editor-specific guidance, duplicate links, and
superseded documentation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
3.6 KiB
name, description
| name | description |
|---|---|
| studio-shortcuts | Keyboard shortcut conventions for Supabase Studio. Use when adding a repeated user action, toolbar action, list/table operation, or sub-page navigation that should have shortcut coverage, when registering or changing a shortcut, or when adding a search/filter Input (which needs the staged-Escape handler). Covers the shortcut registry, useShortcut, ShortcutTooltip/ShortcutBadge, the reference sheet, and collision rules. |
Studio Keyboard Shortcuts
When Studio UI changes introduce or materially alter repeated user actions, consider whether keyboard shortcut coverage should be added or updated. Shortcuts use the shared Studio shortcut system and must be discoverable from the visible UI.
Rules
- Never add a one-off
keydownlistener for a normal Studio action — register it through the shortcut registry anduseShortcut. - Every registered shortcut is exposed where the action is visible, via
ShortcutTooltip,ShortcutBadge, or a command-menu badge. G then …chords are reserved for navigation.- Avoid broad
Mod+lettershortcuts that overlap common browser, editor, system, copy/save/search, or devtools behavior. - Before adding a shortcut, check the registry and any remaining non-registry listeners for collisions.
- Every search/filter
<Input>getsonKeyDown={onSearchInputEscape(...)}— see Search inputs.
Preferred pattern
- Add definitions in
apps/studio/state/shortcuts/registry.tsorapps/studio/state/shortcuts/registry/*. - Register with
useShortcut. - Gate availability with
enabled. - Surface visible actions with
ShortcutTooltiporShortcutBadge. - Prefer scoped, mnemonic sequential chords over global modifier chords.
- Set
showInSettings: falseon contextual shortcuts (scoped to a specific page state, sheet, or panel). - When a shortcut group should appear in the reference sheet (
Shift+?), add the group key toSHORTCUT_REFERENCE_GROUP_ORDERinapps/studio/state/shortcuts/referenceGroups.tsand a human label toGROUP_LABELSinShortcutsReferenceSheet.tsx. - For sheet-scoped shortcuts (active only while a
<Sheet>is open), mountuseShortcutinside the sheet component gated by theopenprop ({ enabled: open }) —apps/studio/components/interfaces/Platform/Webhooks/PlatformWebhooksDeliveryDetailsSheet.tsxis the canonical example. A shortcut that opens a sheet from anywhere is global instead, gated by whatever makes the action valid (e.g.useConnectSheetShortcutchecks project health).
Search inputs
Every <Input> used as a search or filter field must include the staged-Escape handler from apps/studio/lib/keyboard.ts:
import { onSearchInputEscape } from '@/lib/keyboard'
;<Input
value={query}
onChange={(e) => setQuery(e.target.value)}
onKeyDown={onSearchInputEscape(query, setQuery)}
/>
Behavior:
- Escape while the input has a value → clears the value, keeps focus (so a second Escape then blurs)
- Escape while the input is empty → blurs the input
- Stops propagation on Escape so the keystroke does not accidentally close a parent dialog or sheet
When pairing with useShortcut(LIST_PAGE_FOCUS_SEARCH, ...) to focus a search input via keyboard, always also add onSearchInputEscape on the same input — focus and escape-to-blur are always a pair.
Key files
apps/studio/state/shortcuts/registry.ts, apps/studio/state/shortcuts/useShortcut.tsx, apps/studio/components/ui/Shortcut*.tsx, apps/studio/lib/keyboard.ts.
Tests
E2E tests for a feature with shortcuts cover both click interactions and the keyboard path — see studio-e2e-tests.