diff --git a/.agents/skills/api-types/SKILL.md b/.agents/skills/api-types/SKILL.md index f9aefbc9bb6..0cef4dc41ec 100644 --- a/.agents/skills/api-types/SKILL.md +++ b/.agents/skills/api-types/SKILL.md @@ -10,11 +10,13 @@ The generated API contract has three specs: API v1, API v2, and Platform. Their ## Update types 1. Make the API/schema change and ensure it is deployed to production before relying on a type PR. Production is the merge-gate source of truth. -2. Run `pnpm api:codegen` against a running local API environment. It fetches all three local OpenAPI specs and updates the committed files. +2. Update the committed types, either: + - Run `pnpm api:codegen` against a running local API environment. It fetches all three local OpenAPI specs and updates the committed files. + - Or, if you don't have a local API environment running, run `pnpm api:codegen:prod`. It fetches the three production OpenAPI specs directly and overwrites the committed files with them (no diffing — it always writes). 3. Inspect and commit only the intended generated type changes. 4. Run `pnpm api:verify-types`. It fetches the three production OpenAPI specs, regenerates types with the repository tooling, and compares them with the committed files. -Complete the update only when `pnpm api:verify-types` passes after the production deployment is available. +Complete the update only when `pnpm api:verify-types` passes after the production deployment is available. If you used `api:codegen:prod`, this should already pass since the committed files came straight from production. ## Interpret verification diff --git a/.agents/skills/edit-the-docs/SKILL.md b/.agents/skills/edit-the-docs/SKILL.md index 607dd4b3093..fd5b1873b78 100644 --- a/.agents/skills/edit-the-docs/SKILL.md +++ b/.agents/skills/edit-the-docs/SKILL.md @@ -21,14 +21,14 @@ Improves **existing** Supabase docs pages: structure, order, connective text, an 1. **Read before you rewrite.** Open the target page and nearby pages of the same type. Name the reader's goal and the page type before moving sections. 2. **Don't invent product truth. Verify it, in its own PR.** Style and structure work preserves behavior claims, UI labels, and positioning as written. Correcting a claim is PR 3 work, and adding one belongs to the additions branches above it. Those PRs follow [`write-the-docs`](../write-the-docs/SKILL.md) grounding rules: read the code, separate shipped behavior from product intent, and flag what you inferred. -3. **Follow CONTRIBUTING.md and WORD_LIST.md** for voice, terminology, and formatting. See [`apps/docs/CONTRIBUTING.md`](../../../apps/docs/CONTRIBUTING.md) and [`apps/docs/WORD_LIST.md`](../../../apps/docs/WORD_LIST.md). +3. **Follow the [style guide](../../../apps/docs/style-guide/README.md)** for voice, terminology, structure, and components. 4. **Prefer brevity.** Use broad strokes when mechanical detail doesn't help the reader's task. Cut redundancy. Don't over-explain. -5. **Reuse sibling skills.** Get IA and architecture from [`ask-the-docs`](../ask-the-docs/SKILL.md). Get validation and self-review from [`review-the-docs`](../review-the-docs/SKILL.md). Apply the shared pitfalls in [`write-the-docs/reference/common-pitfalls.md`](../write-the-docs/reference/common-pitfalls.md) rather than duplicating them here. +5. **Reuse sibling skills.** Get IA and architecture from [`ask-the-docs`](../ask-the-docs/SKILL.md). Get validation and self-review from [`review-the-docs`](../review-the-docs/SKILL.md). Apply the style guide's [timeless documentation](../../../apps/docs/style-guide/03-page-structure.md#write-timeless-documentation) rather than duplicating it here. 6. **One change type per diff.** A diff that mixes reworded prose with moved sections is unreviewable, because the reader can't tell a move from a rewrite. Separate them by commit in a single PR, or by branch in a stack. ## Phase 0: Size and split -1. Identify the document type per CONTRIBUTING.md. The types are explainer, tutorial, guide, reference, and troubleshooting. +1. Identify the document type per [`03-page-structure.md`](../../../apps/docs/style-guide/03-page-structure.md#document-types). The types are explainer, tutorial, guide, reference, and troubleshooting. 2. State the reader's goal and prerequisites in one or two lines. 3. Note structural problems: mixed information types interrupting a procedure, missing intro navigation on a long page, weak transitions, redundancy, or over-explained mechanics. 4. Sort the diagnosis into the buckets below. **Drop any bucket that comes back empty, and say so.** Style, structure, and technical revision take one commit or branch each. Additions take as many as the content needs, so the edit has no fixed size. A style edit plus a structural edit is the common shape, because most pages that need restructuring are already correct. Two buckets is a complete result, not a truncated one. @@ -52,20 +52,20 @@ Inline changes only. Nothing in this PR moves a line from one place to another. **Rewrite:** - Use second person, present tense, short paragraphs, and ordered steps for sequential actions. -- Put procedures in procedure format, per the Procedures section of CONTRIBUTING.md. Start each step with an imperative verb, keep one action or a closely related set per step, present 7 ± 2 steps per chunk, and group anything longer into named phases or smaller procedures. -- Apply the inline rules in CONTRIBUTING.md for admonitions, emphasis, links, lists, and the "Styling, formatting, and grammar" section. +- Put procedures in procedure format. Per-step formatting is in [`02-elements.md`](../../../apps/docs/style-guide/02-elements.md#procedures); how many steps to present at once and when to split into phases is in [`03-page-structure.md`](../../../apps/docs/style-guide/03-page-structure.md#chunking). +- Apply [`02-elements.md`](../../../apps/docs/style-guide/02-elements.md) for admonitions, emphasis, links, and lists, and [`01-voice-and-tone.md`](../../../apps/docs/style-guide/01-voice-and-tone.md) for person, tense, and sentence-level grammar. - Keep code samples executable in their stated context, and mark intentionally omitted code. Prefer partials under `apps/docs/content/_partials/` over copied blocks. - **Check the alt text on every image, and open the image to do it.** Alt text on an existing page usually names the topic rather than describing the picture, and a topic name is what the nearby heading already says. Describe what a reader who can't see it would need: the labeled parts, the relationships between them, and any values the diagram carries. This is a rewrite of existing text, so it belongs in this PR. **Cut:** - Restated points and mechanical over-explanation. -- The shared pitfalls in [`common-pitfalls.md`](../write-the-docs/reference/common-pitfalls.md): timelessness, internal planning context in shipped MDX, redundancy, single-item lists, and admonition restatement. -- Terminology that doesn't match [`apps/docs/WORD_LIST.md`](../../../apps/docs/WORD_LIST.md). Crawl the list for terms already on the page, not only the ones you introduce. An existing page is where nonconforming terminology accumulates. +- Time-anchored language and unshipped features: [timeless documentation](../../../apps/docs/style-guide/03-page-structure.md#write-timeless-documentation). Internal planning context in shipped MDX: [keep internal context out](../../../apps/docs/style-guide/03-page-structure.md#keep-internal-context-out). Repeated points: [brevity](../../../apps/docs/style-guide/01-voice-and-tone.md#brevity). Single-item lists and restated admonitions: [`02-elements.md`](../../../apps/docs/style-guide/02-elements.md). +- Terminology that doesn't match [`WORD_LIST.md`](../../../apps/docs/style-guide/WORD_LIST.md). Run both passes from [Use with an AI agent](../../../apps/docs/style-guide/WORD_LIST.md#use-with-an-ai-agent): [Phrase groups](../../../apps/docs/style-guide/WORD_LIST.md#phrase-groups) gives you every literal term list in one read, then `grep '^### ' WORD_LIST.md` and open only the entries matching words on the page. Cover terms already on the page, not only the ones you introduce. An existing page is where nonconforming terminology accumulates. ## PR 2: Structure -Apply the **Mixed information types**, **Navigation**, and **Cross-references and glue** guidance in the Guides section of [`apps/docs/CONTRIBUTING.md`](../../../apps/docs/CONTRIBUTING.md). +Apply [`03-page-structure.md`](../../../apps/docs/style-guide/03-page-structure.md) — section grouping, navigation, and glue. This section is the procedure for doing that on an existing page; the rules live in the guide. **Work in this order, and settle the outline before you move a line.** A restructure invalidates every branch above it in the stack, so each revision costs a full restack, and a restack is where content gets dropped in conflict resolution. Reworking the shape twice costs far more than getting it right once. @@ -77,36 +77,19 @@ Write the matched heading texts down. For the rest of this PR they are immutable ### 2. Classify every substantial section -Each one is **procedural** (the reader performs actions), **contextual** (the reader needs to understand something before acting), or **reference** (the reader looks something up). +Classify each one against the information types in [`03-page-structure.md`](../../../apps/docs/style-guide/03-page-structure.md#information-types), then collapse them into the three buckets you'll group by: **procedural** (Procedure), **contextual** (Concept and Process), and **reference** (Structure and Fact). A principle or a fact usually rides along in the section it qualifies rather than getting one of its own. -**Classify by what the reader is doing, not by what the section is about.** Subject matter is the trap: on a page about tables every section is "about tables", so grouping by topic produces one task-named bucket that quietly collects the background as well. A reader opens a section on schemas to understand something, not to do something, so it is context no matter how much it is about tables. +The guide has the two rules that decide the hard cases: classify by what the reader is doing rather than what the section is about, and split a section that serves two types instead of filing it under the larger half. -**A section serving two classes gets split, not filed under the larger half.** Give the new half a heading, keep the heading text of the half that stays, and cross-reference the two. One cross-reference costs less than a reader hunting for the half they need. +Write the bucket for every section down before moving anything. A page where every section lands in one bucket is a page that wasn't really classified. ### 3. Write the target outline before touching the file Produce the whole heading tree, with levels, and check it against the locked list from step 1. Put it in front of the requester along with the Phase 0 diagnosis. The outline is the artifact that gets revised, not the page. -Order the groups: a short conceptual opener when the page serves newcomers, then procedures, then context, then reference. The action path runs uninterrupted and the background sits after it. +Order the groups per [`03-page-structure.md`](../../../apps/docs/style-guide/03-page-structure.md#grouping-sections), which has the order that works and a worked outline. A short concept opener can precede the procedure group; keep that group uninterrupted, and put the remaining background after it. -A guide about database tables settled here: - -``` -## What is a table? <- short conceptual opener -## Creating and managing tables <- procedures -### Creating tables -### Securing your tables -### Loading data -### Joining tables with foreign keys -## How tables are organized <- context -### Primary keys -### Relationships between tables -### Schemas -## Reference -### Data types -``` - -"Joining tables with foreign keys" held both classes. The steps kept the heading and stayed in the procedures group; the idea of a relational database moved to "Relationships between tables" in the context group. +When a section held two types and you split it in step 2, the half that keeps the original heading text stays in its original group, so the locked anchor from step 1 survives. The new half takes a new heading and moves to the group its type belongs to. ### 4. Move, then add the glue the new shape needs @@ -187,7 +170,7 @@ Run this per change type, before you submit the commit or branch that carries it - [ ] Section groups follow information type, and procedures aren't interrupted by long context - [ ] Intro navigation is present only when the page needs it, and links resolve - [ ] Connective text is selective, not link spam -- [ ] Voice matches CONTRIBUTING.md and WORD_LIST.md +- [ ] Voice matches [`01-voice-and-tone.md`](../../../apps/docs/style-guide/01-voice-and-tone.md) and terminology matches [`WORD_LIST.md`](../../../apps/docs/style-guide/WORD_LIST.md) - [ ] Every image has alt text that describes the image, checked against the image itself - [ ] No invented behavior or positioning - [ ] Shared pitfalls checklist considered @@ -209,13 +192,14 @@ Run this per change type, before you submit the commit or branch that carries it **Style and structure:** -- Mixed information types, navigation, and glue: the Guides section of [`apps/docs/CONTRIBUTING.md`](../../../apps/docs/CONTRIBUTING.md) -- Procedure format: the Procedures section of [`apps/docs/CONTRIBUTING.md`](../../../apps/docs/CONTRIBUTING.md) -- Terminology: [`apps/docs/WORD_LIST.md`](../../../apps/docs/WORD_LIST.md) +- Style guide entry point: [`style-guide/README.md`](../../../apps/docs/style-guide/README.md) +- Section grouping, navigation, glue, and chunking: [`03-page-structure.md`](../../../apps/docs/style-guide/03-page-structure.md) +- Procedure format and other components: [`02-elements.md`](../../../apps/docs/style-guide/02-elements.md) +- Terminology: [`WORD_LIST.md`](../../../apps/docs/style-guide/WORD_LIST.md) **Sibling skills:** -- Pitfalls and drafting mechanics: [`common-pitfalls.md`](../write-the-docs/reference/common-pitfalls.md), [`drafting-mechanics.md`](../write-the-docs/reference/drafting-mechanics.md) +- Drafting mechanics: [`drafting-mechanics.md`](../write-the-docs/reference/drafting-mechanics.md) - Runnable verification: [`test-the-docs`](../test-the-docs/SKILL.md) - Architecture and IA: [`ask-the-docs`](../ask-the-docs/SKILL.md) - Net-new drafts: [`write-the-docs`](../write-the-docs/SKILL.md) diff --git a/.agents/skills/pm-the-docs/reference/write-the-docs-checklist.md b/.agents/skills/pm-the-docs/reference/write-the-docs-checklist.md index 27aef67c5aa..5d1b48c2500 100644 --- a/.agents/skills/pm-the-docs/reference/write-the-docs-checklist.md +++ b/.agents/skills/pm-the-docs/reference/write-the-docs-checklist.md @@ -20,7 +20,7 @@ _Self-serve first ([agent skills](../../../../apps/docs/CONTRIBUTING.md#ai-agent - **Examples are runnable and have been tested** (commands, code, expected result) - **Correct stage** like GA is stated; limitations are named honestly. - The page **lives in the right place** in the IA and links to and from related pages. -- Terminology and formatting match existing docs (and style guide once it lands). +- Terminology and formatting match the [style guide](../../../../apps/docs/style-guide/README.md). ### 1. Frame diff --git a/.agents/skills/review-the-docs/SKILL.md b/.agents/skills/review-the-docs/SKILL.md index 1ca33014850..ec3521bbf45 100644 --- a/.agents/skills/review-the-docs/SKILL.md +++ b/.agents/skills/review-the-docs/SKILL.md @@ -106,17 +106,17 @@ Inspect changed files from `gh pr view` or: gh pr diff --repo supabase/supabase --name-only ``` -| PR type | Path signals | Primary skill section | -| --------------------------- | ------------------------------------------------------------------------------------------------ | -------------------------------------------------------------- | -| **Markdown-schema handler** | `apps/docs/internals/markdown-schema/`, `generate-guides-markdown.ts` | [Schema handler review](#schema-handler-review) | -| **Pipeline / internals** | `apps/docs/internals/` (not just one new handler) | [Pipeline review](#pipeline-review) | -| **Content-only MDX** | `apps/docs/content/**` only | [Content review](#content-review) | -| **Tutorial / quickstart** | `apps/docs/content/guides/**/tutorials/`, `quickstarts/`, plus `examples/` | [Tutorial review](#tutorial-review) → also `work-linear-issue` | -| **Example app only** | `examples/**` without matching MDX | [Example review](#example-review) | -| **Studio ↔ docs links** | `apps/studio/**` | [Studio review](#studio-review) | -| **Docs UI / components** | `apps/docs/components/`, `apps/docs/features/` (no pipeline) | [Component review](#component-review) | -| **Docs tooling** | `.agents/skills/`, `apps/docs/AGENTS.md`, `apps/docs/CONTRIBUTING.md`, `apps/docs/DEVELOPERS.md` | [Docs tooling review](#docs-tooling-review) | -| **Mixed** | Multiple path groups above | Run each applicable section; note overlap | +| PR type | Path signals | Primary skill section | +| --------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- | +| **Markdown-schema handler** | `apps/docs/internals/markdown-schema/`, `generate-guides-markdown.ts` | [Schema handler review](#schema-handler-review) | +| **Pipeline / internals** | `apps/docs/internals/` (not just one new handler) | [Pipeline review](#pipeline-review) | +| **Content-only MDX** | `apps/docs/content/**` only | [Content review](#content-review) | +| **Tutorial / quickstart** | `apps/docs/content/guides/**/tutorials/`, `quickstarts/`, plus `examples/` | [Tutorial review](#tutorial-review) → also `work-linear-issue` | +| **Example app only** | `examples/**` without matching MDX | [Example review](#example-review) | +| **Studio ↔ docs links** | `apps/studio/**` | [Studio review](#studio-review) | +| **Docs UI / components** | `apps/docs/components/`, `apps/docs/features/` (no pipeline) | [Component review](#component-review) | +| **Docs tooling** | `.agents/skills/`, `apps/docs/AGENTS.md`, `apps/docs/CONTRIBUTING.md`, `apps/docs/DEVELOPERS.md`, `apps/docs/style-guide/` | [Docs tooling review](#docs-tooling-review) | +| **Mixed** | Multiple path groups above | Run each applicable section; note overlap | When a PR spans types (e.g. schema handler + component refactor), run **all** matching sections. @@ -202,14 +202,22 @@ Verify both guides and reference output when `generate-reference-markdown.ts` or MDX prose, partials, navigation — no pipeline or example changes. -Check the prose against [`apps/docs/CONTRIBUTING.md`](../../../apps/docs/CONTRIBUTING.md) and -[`apps/docs/WORD_LIST.md`](../../../apps/docs/WORD_LIST.md) yourself. No CI or local -check covers terminology. CodeRabbit reviews style, terminology, and structure -on `apps/docs/content/**/*.mdx`, but only once the PR is open. +Check the prose against the [style guide](../../../apps/docs/style-guide/README.md) yourself. No CI or local +check covers style or terminology. CodeRabbit reviews style, terminology, and +structure on `apps/docs/content/**/*.mdx`, but only once the PR is open. + +Check [`WORD_LIST.md`](../../../apps/docs/style-guide/WORD_LIST.md) against the finished page last, using the +two-pass protocol in [Use with an AI agent](../../../apps/docs/style-guide/WORD_LIST.md#use-with-an-ai-agent): [Phrase +groups](../../../apps/docs/style-guide/WORD_LIST.md#phrase-groups) for the literal term lists, then `grep '^### ' +WORD_LIST.md` and read only the entries matching words on the page. Include terms +the author didn't introduce. Checklist: -- [ ] Prose follows CONTRIBUTING.md and the word list +- [ ] Voice follows [`01-voice-and-tone.md`](../../../apps/docs/style-guide/01-voice-and-tone.md) +- [ ] Section grouping and chunking follow [`03-page-structure.md`](../../../apps/docs/style-guide/03-page-structure.md) +- [ ] Components follow [`02-elements.md`](../../../apps/docs/style-guide/02-elements.md) +- [ ] Terminology matches [`WORD_LIST.md`](../../../apps/docs/style-guide/WORD_LIST.md) - [ ] Frontmatter valid (`title`, `description` where required) - [ ] Internal links resolve (`/docs/guides/...`, not broken anchors) - [ ] `$CodeSample` paths match existing example directories @@ -293,7 +301,8 @@ Checklist: - [ ] `.claude/skills` is still a single Git symlink to `../.agents/skills` — no per-skill symlinks or copies under `.claude/` - [ ] Cross-skill links resolve: relative for in-repo skills; absolute `docs-agent-skills` URLs only for skills that remain in that private repo - [ ] No personal vault paths, Obsidian references, or private-process-only instructions -- [ ] `apps/docs/CONTRIBUTING.md` / `DEVELOPERS.md` pointers match skill names and checklist stages +- [ ] `apps/docs/CONTRIBUTING.md` / `DEVELOPERS.md` / `AGENTS.md` pointers match skill names and checklist stages +- [ ] A style rule added to a skill belongs in `apps/docs/style-guide/` instead, with the skill pointing at it - [ ] Reference files under a skill stay near the ~250-line guideline (split if bloated) ```bash diff --git a/.agents/skills/write-the-docs/SKILL.md b/.agents/skills/write-the-docs/SKILL.md index d983bb5c6b0..cbb965bc55d 100644 --- a/.agents/skills/write-the-docs/SKILL.md +++ b/.agents/skills/write-the-docs/SKILL.md @@ -3,7 +3,7 @@ name: write-the-docs description: >- Draft new or updated Supabase docs content for a feature or launch, grounded in product intent (Linear when available), a read of the actual - code, and the docs style guide once one exists. Use when asked to write + code, and the docs style guide. Use when asked to write docs for a new feature, a product launch, or a Linear ticket that needs net-new content rather than a bug fix. Not for implementing existing docs bug reports — use work-linear-issue for that. Not for restructuring @@ -18,7 +18,7 @@ Drafts net-new Supabase docs content (or product-grounded rewrites) for a featur 1. **Gather before drafting.** Never draft from a ticket title alone. Pull all four inputs below first; a thin gather phase produces a draft that's wrong about how the feature actually works. 2. **Separate confirmed behavior from product intent from inference.** Code tells you what the feature does today. Linear/PRD/PRFAQ (or prior Frame/Shape output) tells you what it's meant to do and how it should be positioned. Anything you had to guess, flag explicitly rather than stating it as fact. -3. **Follow CONTRIBUTING.md and WORD_LIST.md for voice, terminology, and formatting only, never for content accuracy.** These are a style reference, not a source of truth: rule 2's Linear+code read is what governs what the page actually says. Don't silently invent voice/structure rules either; name the nearest existing-page precedent you followed instead (see [reference/style-fallback.md](reference/style-fallback.md)). +3. **Follow the [style guide](../../../apps/docs/style-guide/README.md) for writing conventions, including voice, terminology, formatting, page structure, and elements. Never follow it for content accuracy.** It is a style reference, not a source of truth: rule 2's Linear+code read is what governs what the page actually says. Don't invent voice or structure rules. When the guide and Google's developer documentation style guide both come up short, say so in the handoff rather than copying whatever the nearest page happens to do. 4. **Reuse, don't duplicate.** For docs-app architecture/placement questions, use [`ask-the-docs`](../ask-the-docs/SKILL.md) and [`audit-docs-ia`](https://github.com/supabase/docs-agent-skills/blob/main/.claude/skills/audit-docs-ia/SKILL.md) rather than re-deriving that knowledge here. 5. **Know what you're actually drafting.** Not everything that looks like "docs for a feature" is a hand-written page — see the content-type gate below before you start writing. If the ask is restructure, reorder, connective text, or clarity on an existing page (no new product story), use [`edit-the-docs`](../edit-the-docs/SKILL.md) instead. @@ -26,7 +26,7 @@ Drafts net-new Supabase docs content (or product-grounded rewrites) for a featur Four inputs, read in this sequence (sequence, not priority; Linear remains the product-intent source and code remains the behavior source per rule 2 and Phase 1 step 3): -1. **Style guide — voice/terminology reference.** Start with [`apps/docs/CONTRIBUTING.md`](../../../apps/docs/CONTRIBUTING.md) and [`apps/docs/WORD_LIST.md`](../../../apps/docs/WORD_LIST.md) for voice, structure, and terminology. If those don't cover the case, fall back to the nearest comparable existing page under `apps/docs/content/` and say explicitly: _"no dedicated style guide yet — following the precedent of ``."_ See [reference/style-fallback.md](reference/style-fallback.md). +1. **Style guide — voice/terminology reference.** Read [`style-guide/README.md`](../../../apps/docs/style-guide/README.md) and follow the step that matches what you're drafting. Check [`WORD_LIST.md`](../../../apps/docs/style-guide/WORD_LIST.md) for the terms you plan to introduce. The guide's closing section says what to consult when it's silent; follow that rather than matching a neighbouring page. 2. **Linear — the ticket and its product context.** Linear is an internal Supabase tool: preferred when available, not required for open-source contributors. When a Linear issue is available, pull it, then its parent project/initiative description too (PRD, PRFAQ, RFC, or initiative narrative) and any PM comments. Product framing/positioning language usually lives one level up from the ticket, in the parent project or initiative description rather than the ticket body. Distinguish scope the ticket actually commits to from aspirational language in the PRD. If there is no Linear issue and no prior Frame/Shape product-intent output, stop drafting: ask internal authors for a Linear URL, otherwise hand off to [`pm-the-docs`](../pm-the-docs/SKILL.md) (Frame) and [`ask-the-docs`](../ask-the-docs/SKILL.md) when Shape/IA is unsettled. Resume only after product intent exists — never invent positioning, and never run Frame/Shape inside this Draft skill. 3. **Code.** Read the actual implementation before writing a single behavior claim — the PRD describes intent, the code describes what shipped. Check the Linear issue/project first for a linked `supabase/supabase` PR — its diff and description are the most precise "what actually shipped" source, more precise than a general codebase read. If no PR is linked, locate the feature directly in `supabase/supabase` (or the product's own repo), and apply [`ask-the-docs`](../ask-the-docs/SKILL.md)'s reuse/minimalism lens: understand what exists before describing it. When behavior spans services (CLI, Auth, migrations, platform, …), follow [`pm-the-docs`](../pm-the-docs/SKILL.md) → [universe-lookup](../pm-the-docs/reference/universe-lookup.md) **capability gate** (universe when accessible, else OSS public search / linked repos — not `ask-the-docs`). If code and PRD disagree, the code wins for behavior claims — flag the mismatch rather than silently picking one. 4. **Whatever else the author supplies.** Screenshots, example projects, related pages, Slack threads, a specific voice sample. Screenshots are for more than general context — use them to verify the _exact_ button/menu/field labels before writing instructional steps that reference them; a mismatched UI label is one of the easiest, most avoidable errors in a draft. Ask for these when the feature's user-facing shape is still unclear after 1–3, rather than guessing. @@ -49,18 +49,16 @@ When in doubt, ask `ask-the-docs` rather than guessing — this classification i - Place the page using existing IA precedent; for a placement call that isn't obvious, consult [`audit-docs-ia`](https://github.com/supabase/docs-agent-skills/blob/main/.claude/skills/audit-docs-ia/SKILL.md)'s nav/IA knowledge rather than guessing a nav slot. - **Wire it into navigation, not just onto disk.** Placement (which section) and nav enablement (whether it actually shows up) are separate — confirm the current nav-registration mechanism via `ask-the-docs`/`audit-docs-ia` rather than assuming a page is discoverable just because the file exists in the right folder. - Ground every behavior claim in Phase 1's code read (the linked PR when there is one); ground every "why this matters" framing in Linear/PM context or prior Frame/Shape output; mark inferred material inline (e.g. an HTML comment or a flagged line in the handoff summary) so a reviewer can find it fast. -- **Write for timelessness.** Prefer documenting what exists now over promising future features. See [reference/common-pitfalls.md](reference/common-pitfalls.md#2-timeless-documentation). -- **Keep it concise and avoid redundancy.** See [reference/common-pitfalls.md](reference/common-pitfalls.md#4-redundancy-and-over-explanation). -- **Prefer paragraphs over single-item lists.** See [reference/common-pitfalls.md](reference/common-pitfalls.md#5-single-item-lists). +- **Write timeless documentation, cut redundancy, and prefer a paragraph to a single-item list.** See [timeless documentation](../../../apps/docs/style-guide/03-page-structure.md#write-timeless-documentation), [brevity](../../../apps/docs/style-guide/01-voice-and-tone.md#brevity), and [lists](../../../apps/docs/style-guide/02-elements.md#lists). - **Strip internal business context before the final draft.** HTML comments flagging PRD intent, roadmap speculation, internal ticket discussions, or "gap-fill" notes must be removed from MDX before handoff. Open-source docs shouldn't expose internal planning. Flag assumptions and open questions for reviewers in the PR description instead, not in the shipped content. -- Search [`apps/docs/WORD_LIST.md`](../../../apps/docs/WORD_LIST.md) when introducing or reviewing technical terms, UI actions, abbreviations, and potentially ambiguous language during drafting. This targeted search supplements, but does not replace, the full-file compliance check in Phase 2.5. +- Search [`WORD_LIST.md`](../../../apps/docs/style-guide/WORD_LIST.md) when introducing or reviewing technical terms, UI actions, abbreviations, and potentially ambiguous language during drafting. Use the two-pass protocol in [Use with an AI agent](../../../apps/docs/style-guide/WORD_LIST.md#use-with-an-ai-agent) rather than reading the file end to end. - Reuse repeated content through `apps/docs/content/_partials/` instead of copying it. For nav wiring, partials, and file placement, see [`ask-the-docs`](../ask-the-docs/SKILL.md)'s `app-map.md` and `federated-docs.md`. ## Phase 2.5 — Review checklist Before handing off, confirm: -- [ ] CONTRIBUTING.md / WORD_LIST.md followed, or precedent page named explicitly +- [ ] Style guide followed, or the gap named explicitly in the handoff - [ ] Every behavior claim traces to the code read (ideally the linked PR), not just the PRD - [ ] Every "why it matters" / positioning line traces to Linear/PM context or prior Frame/Shape output, not invented - [ ] Inferred or assumed material is flagged, not stated as fact @@ -75,13 +73,15 @@ Before handing off, confirm: ### Compliance checklist -Re-read [`apps/docs/CONTRIBUTING.md`](../../../apps/docs/CONTRIBUTING.md) and [`apps/docs/WORD_LIST.md`](../../../apps/docs/WORD_LIST.md) in full before handoff, not just the sections searched during drafting. When a dedicated style guide lands in the repo, extend this checklist to cover it too. +Before handoff, run both passes from [Use with an AI agent](../../../apps/docs/style-guide/WORD_LIST.md#use-with-an-ai-agent): read [Phrase groups](../../../apps/docs/style-guide/WORD_LIST.md#phrase-groups) for the literal term lists, then `grep '^### ' WORD_LIST.md` and read only the entries matching words on the page. Cover terms you didn't introduce, not just the ones you searched while drafting. Then check the draft against each numbered file in the [style guide](../../../apps/docs/style-guide/README.md). - [ ] Parentheses used only for acronyms or `(Optional)`, not prose asides - [ ] Bold, italics, and code used only for their distinct purposes (UI labels, must-not-miss terms), not for visual emphasis alone - [ ] No dash-based asides where a direct sentence reads better -- [ ] Terminology matches `WORD_LIST.md` (including any terms flagged as imprecise, not just spelling/capitalization) -- [ ] Headings, admonitions, and links follow CONTRIBUTING.md's "Styling, formatting, and grammar" and "Components and elements" sections +- [ ] Terminology matches [`WORD_LIST.md`](../../../apps/docs/style-guide/WORD_LIST.md) (including any terms flagged as imprecise, not just spelling/capitalization) +- [ ] Voice, tense, and brevity follow [`01-voice-and-tone.md`](../../../apps/docs/style-guide/01-voice-and-tone.md) +- [ ] Document type, section grouping, and chunking follow [`03-page-structure.md`](../../../apps/docs/style-guide/03-page-structure.md) +- [ ] Admonitions, headings, links, and other components follow [`02-elements.md`](../../../apps/docs/style-guide/02-elements.md) ## Phase 3 — Handoff @@ -95,8 +95,8 @@ This skill stops at a reviewable draft. It does not open worktrees or PRs itself ## Additional resources -- Style / terminology: [`apps/docs/CONTRIBUTING.md`](../../../apps/docs/CONTRIBUTING.md), [`apps/docs/WORD_LIST.md`](../../../apps/docs/WORD_LIST.md), [reference/style-fallback.md](reference/style-fallback.md) -- Common pitfalls to avoid: [reference/common-pitfalls.md](reference/common-pitfalls.md) +- Style: [`style-guide/README.md`](../../../apps/docs/style-guide/README.md) routes to the file for each level +- Repo mechanics (nav wiring, partials, reference pipeline): [`apps/docs/CONTRIBUTING.md`](../../../apps/docs/CONTRIBUTING.md) - Drafting mechanics: [reference/drafting-mechanics.md](reference/drafting-mechanics.md) - Content-type gate detail: [reference/content-type-gate.md](reference/content-type-gate.md) - Existing-page restructure/clarity: [`edit-the-docs`](../edit-the-docs/SKILL.md) diff --git a/.agents/skills/write-the-docs/reference/common-pitfalls.md b/.agents/skills/write-the-docs/reference/common-pitfalls.md deleted file mode 100644 index 87df439528d..00000000000 --- a/.agents/skills/write-the-docs/reference/common-pitfalls.md +++ /dev/null @@ -1,94 +0,0 @@ -# Common pitfalls in docs drafts - -Patterns to watch for when drafting docs, based on review feedback. These are guidelines, not absolute rules — use judgment based on context. - -## 1. Internal planning context in open-source docs - -**Principle:** Supabase docs are open source. Internal planning context, unshipped features, and business intent shouldn't be visible in the public repo. - -**What to watch for:** - -- HTML comments referencing PRDs, roadmaps, or internal ticket discussions -- "Gap-fill" notes about what's planned but not shipped -- Internal product strategy or positioning discussions -- References to any project-management or ticketing system (internal or a contributor's own tools) - -**Where to put internal context instead:** - -- PR description (for review-time context) -- The team's project-management tool (for product/PM handoff) -- Internal docs (for roadmap tracking) - -## 2. Timeless documentation - -**Principle:** Prefer documenting what exists now over promising future features ([Google's timeless documentation](https://developers.google.com/style/timeless-documentation)). Future promises become stale. - -**Common patterns to watch for:** - -- "Coming soon" / "will be available" / "once finalized" -- "This page is a placeholder" -- "Being rolled out gradually" without concrete eligibility criteria - -**Better alternatives:** - -- Document what exists today -- Wait to publish until the feature is complete -- If phased rollout is real, be specific: "Available to organizations on Pro and Enterprise plans" - -**Context matters:** Changelog and roadmap content naturally references the future — this guidance applies primarily to feature documentation. - -## 3. Placeholder pages - -**Principle:** Generally avoid shipping pages that explicitly say "This is a placeholder" or "More details coming soon." - -**Alternatives:** - -- Wait to publish until content is ready -- If navigation structure requires it, link to external resources that are complete -- Ship minimal but useful content (what's true today) rather than promises - -**Valid exceptions:** Navigation structure needs, federated docs where the placeholder provides context and links out, cross-references where the page existing (even minimal) provides value. - -## 4. Redundancy and over-explanation - -**Principle:** Avoid restating the same point in multiple ways. Prefer brevity — sometimes broad strokes help more than mechanical detail. - -**Common patterns:** - -- Multiple ways of saying the same thing: "It's free" + "You won't be billed" + "No charge" -- Admonition stating a risk, then body text restating it verbatim -- Adjacent sentences that rephrase each other -- Over-explaining mechanical steps or implementation detail that doesn't help the reader complete the task - -**How to catch it:** If you can remove a sentence without losing information, it's probably redundant. If a procedure works with less setup explanation, prefer the shorter path. - -## 5. Single-item lists - -**Principle:** Prefer paragraphs over single-item bullet lists. - -**Why:** Single-item lists can signal incomplete content. - -**Valid exceptions:** Layout consistency across sections, future expansion expected, or when the item needs special visual emphasis. - -## 6. Restating admonition content - -**Principle:** Admonitions and body text should cover distinct points, not repeat each other. - -**What to watch for:** An admonition stating a risk/limitation, then the next paragraph restating it verbatim. - -## Summary checklist - -Before submitting a draft, check: - -- [ ] No HTML comments with internal PRD/roadmap/ticket context in MDX -- [ ] Future promises minimized where appropriate (timeless documentation) -- [ ] Placeholder pages avoided where possible -- [ ] No unnecessary redundancy or mechanical over-explanation -- [ ] Single-item lists avoided unless there's a reason -- [ ] Admonitions and body text cover distinct points - -**Note:** These are guidelines based on review feedback, not absolute rules. Use judgment based on content type, context, and the specific documentation needs. The goal is clearer, more maintainable docs, not rigid adherence to formatting rules. - -## Style guide consolidation - -This content is style guidance, not skill-specific process. It belongs in a shared, human-and-agent-readable style guide rather than only inside this skill. When a dedicated style guide exists in the repo, fold this content into it and replace this file with a pointer, the same pattern [reference/style-fallback.md](style-fallback.md) already uses for CONTRIBUTING.md/WORD_LIST.md. diff --git a/.agents/skills/write-the-docs/reference/drafting-mechanics.md b/.agents/skills/write-the-docs/reference/drafting-mechanics.md index c46f9a091d3..347f78fdc23 100644 --- a/.agents/skills/write-the-docs/reference/drafting-mechanics.md +++ b/.agents/skills/write-the-docs/reference/drafting-mechanics.md @@ -1,8 +1,10 @@ # Drafting mechanics -Mechanics that come up during drafting but aren't worth duplicating from -`CONTRIBUTING.md` or `ask-the-docs`. For nav wiring, partials, and file -placement, see `ask-the-docs`'s `app-map.md` and `federated-docs.md`. +Mechanics that come up during drafting but aren't worth duplicating from the +style guide or `ask-the-docs`. For style rules, see +[`apps/docs/style-guide/`](../../../../apps/docs/style-guide/README.md). For nav +wiring, partials, and file placement, see `ask-the-docs`'s `app-map.md` and +`federated-docs.md`. ## Link paths @@ -38,6 +40,6 @@ From the repository root, run `pnpm format` to apply Prettier to changed MDX files. This enforces repo-wide formatting rules, including lowercase SQL keyword casing in code samples. -Check terminology against [`apps/docs/WORD_LIST.md`](../../../../apps/docs/WORD_LIST.md) +Check terminology against [`WORD_LIST.md`](../../../../apps/docs/style-guide/WORD_LIST.md) yourself. Treat its replacements as suggestions when context matters: rewrite the sentence instead of applying one that changes its technical meaning. diff --git a/.agents/skills/write-the-docs/reference/style-fallback.md b/.agents/skills/write-the-docs/reference/style-fallback.md deleted file mode 100644 index f89cd073210..00000000000 --- a/.agents/skills/write-the-docs/reference/style-fallback.md +++ /dev/null @@ -1,22 +0,0 @@ -# Style guide fallback - -There is no separate published style guide yet beyond what already lives in -this repo. Use the public sources below, in order. - -This fallback governs voice, formatting, and terminology only. It's not a -source of truth for behavior or product framing (that's the Gather phase's -Linear + code read, per SKILL.md rule 3). - -1. Read [`apps/docs/CONTRIBUTING.md`](../../../../apps/docs/CONTRIBUTING.md) - for authoring conventions (voice, structure, document types). -2. Read [`apps/docs/WORD_LIST.md`](../../../../apps/docs/WORD_LIST.md) for - preferred spelling, capitalization, and terminology. -3. If those don't cover the case, find the nearest comparable existing page - under `apps/docs/content/` (same product area, similar content type — - reference vs. guide vs. quickstart) and follow its voice, heading - structure, and code-sample conventions. -4. State which page you followed as precedent in the handoff summary — e.g. - "no dedicated style guide yet — following the precedent of - `guides/storage/uploads.mdx`." -5. When a dedicated style guide is added to the repo later, prefer it over - precedent-matching and drop this fallback step. diff --git a/.coderabbit.yaml b/.coderabbit.yaml index 3d201281eb4..05fb08b4164 100644 --- a/.coderabbit.yaml +++ b/.coderabbit.yaml @@ -34,7 +34,7 @@ reviews: Strictly enforce event naming: [object]_[verb] in snake_case. Only approved verbs: opened, clicked, submitted, created, removed, updated, retrieved, intended, evaluated, added, enabled, disabled, copied, exposed, failed, - converted. Properties must be camelCase for new events (match existing + converted, completed. Properties must be camelCase for new events (match existing convention when adding to existing events). Flag any usage of useSendEventMutation. Verify @group Events and @source JSDoc tags are accurate. Check that new interfaces are added to the TelemetryEvent union type. @@ -74,8 +74,8 @@ reviews: Flag style, terminology, and structure issues as usual. When a page has two or more of them, add one comment pointing the author at the `/write-the-docs` skill for new content or `/edit-the-docs` for an existing page (canonical files in - `.agents/skills/`); both apply apps/docs/CONTRIBUTING.md and - apps/docs/WORD_LIST.md. Skip that pointer on a single issue, so it stays a + `.agents/skills/`); both apply the docs style guide in + apps/docs/style-guide/. Skip that pointer on a single issue, so it stays a signal that the author isn't using the skills rather than boilerplate. - path: '{apps,packages}/**/*.{tsx,jsx,css,mdx}' instructions: | diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index a72095d25c9..e39729fd27f 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -22,4 +22,7 @@ /apps/studio/components/interfaces/Organization/Documents/ @supabase/security /apps/studio/pages/new/index.tsx @supabase/security +/apps/studio/lib/ai/ @supabase/ai +/apps/studio/pages/api/ai/ @supabase/ai + /packages/shared-data/compute-disk-limits.ts @supabase/platform diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 7cce99d31de..35a40aac630 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -38,10 +38,9 @@ Provide a clear numbered procedure that the PR reviewer can walk through. 1. For example, `Open the live and preview links side-by-side.` 2. For example, `See the issue is fixed.` - ## Checklist Check all before review: - [ ] I have read [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) -- [ ] If I wrote a new docs topic or edited an existing topic, I used the `/write-the-docs` or `/edit-the-docs` skill, which references [WORD_LIST](https://github.com/supabase/supabase/blob/master/apps/docs/WORD_LIST.md) and the docs [CONTRIBUTING](https://github.com/supabase/supabase/blob/master/apps/docs/CONTRIBUTING.md) guide +- [ ] If I wrote a new docs topic or edited an existing topic, I used the `/write-the-docs` or `/edit-the-docs` skill, which applies the docs [style guide](https://github.com/supabase/supabase/tree/master/apps/docs/style-guide) diff --git a/.github/workflows/docs-search-v2-ingest.yml b/.github/workflows/docs-search-v2-ingest.yml new file mode 100644 index 00000000000..5f54f2babb5 --- /dev/null +++ b/.github/workflows/docs-search-v2-ingest.yml @@ -0,0 +1,53 @@ +name: Ingest Docs Content for Search V2 + +on: + push: + branches: + - master + paths: + - '.github/workflows/docs-search-v2-ingest.yml' + - 'apps/docs/content/**/*.mdx' + - 'apps/docs/scripts/search_v2/**' + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-prod + cancel-in-progress: false + +permissions: + contents: read + +jobs: + ingest: + runs-on: blacksmith-4vcpu-ubuntu-2404 + + env: + SEARCH_V2_SUPABASE_PROJECT_ID: ${{ secrets.SEARCH_V2_SUPABASE_PROJECT_ID }} + SEARCH_V2_SUPABASE_SECRET_KEY: ${{ secrets.SEARCH_V2_SUPABASE_SECRET_KEY }} + + steps: + - name: Check out repo + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false + sparse-checkout: | + apps/docs + packages + patches + + - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 + name: Install pnpm + with: + run_install: false + + - name: Setup node + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version-file: '.nvmrc' + + - name: Download dependencies + run: pnpm install --frozen-lockfile + + - name: Ingest content + working-directory: ./apps/docs + run: pnpm run search-v2:ingest diff --git a/.github/workflows/library-tests.yml b/.github/workflows/library-tests.yml index 9eca55ab6e4..48c68a4236f 100644 --- a/.github/workflows/library-tests.yml +++ b/.github/workflows/library-tests.yml @@ -51,7 +51,7 @@ jobs: - run: pnpm --filter library build:registry - name: Check generated registry run: | - registry_changes="$(git status --porcelain --untracked-files=all -- apps/ui-library/public/r)" + registry_changes="$(git status --porcelain --untracked-files=all -- apps/ui-library/public/r apps/ui-library/__registry__)" if [ -n "$registry_changes" ]; then printf '%s\n' "$registry_changes" echo 'Run pnpm --filter library build:registry and commit the generated registry files.' diff --git a/.github/workflows/studio-lint-ratchet-decrease.yml b/.github/workflows/studio-lint-ratchet-decrease.yml index 0b0faabf5f3..71ac4bcbec6 100644 --- a/.github/workflows/studio-lint-ratchet-decrease.yml +++ b/.github/workflows/studio-lint-ratchet-decrease.yml @@ -47,6 +47,7 @@ jobs: permission-pull-requests: write - name: Decrease ESLint ratchet baselines and open PR + id: decrease-baselines env: GH_TOKEN: ${{ steps.app-token.outputs.token }} DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} @@ -69,6 +70,7 @@ jobs: if git diff --quiet; then echo "No baseline updates detected." + echo "changed=false" >> "$GITHUB_OUTPUT" exit 0 fi @@ -81,11 +83,45 @@ jobs: pr_url=$(gh pr list --state open --head "$BRANCH" --json url --jq '.[0].url // ""' 2>/dev/null || echo "") if [ -z "$pr_url" ]; then - gh pr create \ + pr_url=$(gh pr create \ --title "[bot] Decrease ESLint ratchet baselines" \ --body "Automated weekly decrease of ESLint ratchet baselines." \ --base "$DEFAULT_BRANCH" \ - --head "$BRANCH" + --head "$BRANCH") else gh pr comment "$pr_url" --body "Updated ESLint ratchet baselines with the latest weekly decreases." fi + + echo "changed=true" >> "$GITHUB_OUTPUT" + echo "pr_url=$pr_url" >> "$GITHUB_OUTPUT" + + - name: 'Notify #team-frontend about rules that hit a zero baseline' + if: steps.decrease-baselines.outputs.changed == 'true' + env: + PR_URL: ${{ steps.decrease-baselines.outputs.pr_url }} + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_DASHBOARD_WEBHOOK_URL }} + run: | + set -euo pipefail + + zero_rules=$(jq -r '.rules | to_entries | map(select(.value == 0) | .key) | join(", ")' apps/studio/.github/eslint-rule-baselines.json) + + if [ -z "$zero_rules" ]; then + echo "No rules dropped to a baseline of 0; nothing to notify." + exit 0 + fi + + if [ -z "${SLACK_WEBHOOK_URL:-}" ]; then + echo "::warning::SLACK_DASHBOARD_WEBHOOK_URL secret is not set; skipping Slack notification for zero-baseline rules: $zero_rules" + exit 0 + fi + + pr_number="${PR_URL##*/}" + text="<@U0A1BRW39PC> the weekly ratchet-baseline job just dropped these rules to 0 in <${PR_URL}|#${pr_number}>: ${zero_rules}. Can you remove them from ratchet tracking and bump their ESLint severity to \"error\"?" + + payload=$(jq -n --arg text "$text" '{text: $text}') + + if ! curl --fail --silent --show-error -X POST "$SLACK_WEBHOOK_URL" \ + -H 'Content-Type: application/json' \ + -d "$payload"; then + echo "::warning::Failed to post Slack notification for zero-baseline rules: $zero_rules" + fi diff --git a/.github/workflows/www-partner-form-sync-check.yml b/.github/workflows/www-partner-form-sync-check.yml new file mode 100644 index 00000000000..4af0843b4c1 --- /dev/null +++ b/.github/workflows/www-partner-form-sync-check.yml @@ -0,0 +1,60 @@ +name: Partner intake form / HubSpot sync check + +# Deliberately its own workflow, path-filtered to only the files this check +# actually concerns — NOT part of www-tests.yml's `pnpm test` run, which +# gates every apps/www PR. A HubSpot-side change surfaced by the scheduled +# www-partner-form-sync.yml bot PR (which touches only the generated +# snapshot) should fail *this* check, not block unrelated apps/www work. +on: + pull_request: + branches: ['master'] + paths: + - 'apps/www/components/Partners/PartnerIntakeForm.fields.ts' + - 'apps/www/components/Partners/PartnerIntakeForm.sync.test.ts' + - 'apps/www/components/Partners/__generated__/partner-intake-form.hubspot.json' + - 'apps/www/lib/staticFormCrm.ts' + - 'apps/www/vitest.sync.config.ts' + - 'apps/www/package.json' + - '.github/workflows/www-partner-form-sync-check.yml' + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +env: + CI: true + +jobs: + check: + runs-on: blacksmith-4vcpu-ubuntu-2404 + + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false + sparse-checkout: | + apps/www + packages + supabase + patches + + - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 + name: Install pnpm + with: + run_install: false + + - name: Use Node.js + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version-file: '.nvmrc' + cache: 'pnpm' + + - name: Install deps + run: pnpm install --frozen-lockfile + + - name: Run partner intake form / HubSpot sync check + run: pnpm run test:partner-form-sync + working-directory: ./apps/www diff --git a/.github/workflows/www-partner-form-sync.yml b/.github/workflows/www-partner-form-sync.yml new file mode 100644 index 00000000000..df3c793201b --- /dev/null +++ b/.github/workflows/www-partner-form-sync.yml @@ -0,0 +1,78 @@ +name: Sync partner intake form from HubSpot + +on: + schedule: + # Run at 00:00 UTC every Monday + - cron: '0 0 * * 1' + workflow_dispatch: + +permissions: + pull-requests: write + contents: write + +jobs: + sync-partner-form: + runs-on: blacksmith-4vcpu-ubuntu-2404 + + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false + ref: ${{ github.ref }} + sparse-checkout: | + apps/www + packages + patches + + - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 + name: Install pnpm + with: + run_install: false + + - name: Use Node.js + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version-file: '.nvmrc' + cache: 'pnpm' + + - name: Install deps + run: pnpm install --frozen-lockfile + + - name: Fetch the live HubSpot form and regenerate the snapshot + run: pnpm run sync:partner-form + working-directory: ./apps/www + + - name: Generate token + id: app-token + uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 + with: + client-id: ${{ vars.GH_AUTOFIX_APP_CLIENT_ID }} + private-key: ${{ secrets.GH_AUTOFIX_PRIVATE_KEY }} + permission-pull-requests: write + permission-contents: write + + # Only opens/updates a PR when the regenerated snapshot actually + # differs from what's committed — i.e. only when the live HubSpot form + # has changed since the last sync. The PR's existence is the drift + # alert: PartnerIntakeForm.sync.test.ts (run by the normal + # www-tests.yml suite on this PR) fails until a human reconciles + # PartnerIntakeForm.tsx / staticFormCrm.ts with the new snapshot. + - name: Create pull request + uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0 + with: + token: ${{ steps.app-token.outputs.token }} + commit-message: 'chore(www): sync partner intake form snapshot from HubSpot' + title: 'chore(www): partner intake form has changed in HubSpot' + body: | + The live "Become a Partner" HubSpot form no longer matches the + checked-in snapshot at + `apps/www/components/Partners/__generated__/partner-intake-form.hubspot.json`. + + `PartnerIntakeForm.sync.test.ts` will fail on this PR until + `apps/www/components/Partners/PartnerIntakeForm.fields.ts` and + `apps/www/lib/staticFormCrm.ts` are updated by hand to match — + see the comment at the top of that test for what it checks. + branch: 'gha/auto-sync-partner-intake-form' + base: 'master' + add-paths: | + apps/www/components/Partners/__generated__/partner-intake-form.hubspot.json diff --git a/.github/workflows/www-tests.yml b/.github/workflows/www-tests.yml index 321df0844af..c54fb5bdce8 100644 --- a/.github/workflows/www-tests.yml +++ b/.github/workflows/www-tests.yml @@ -4,7 +4,11 @@ on: pull_request: branches: ['master'] paths: + - '.github/workflows/www-tests.yml' - 'apps/www/**/*.ts*' + - 'apps/www/package.json' + - 'apps/www/turbo.jsonc' + - 'scripts/upload-static-assets.sh' - 'packages/common/sentry.ts' - 'packages/common/sentry.test.ts' - 'apps/www/next.config.mjs' @@ -45,6 +49,7 @@ jobs: apps/www apps/docs/content/guides packages + scripts supabase patches diff --git a/.prettierignore b/.prettierignore index 41a171fe018..7223d3acfc4 100644 --- a/.prettierignore +++ b/.prettierignore @@ -14,13 +14,14 @@ apps/www/public/images/* apps/www/public/changelog.md apps/www/public/changelog/*.md apps/www/.generated/* +# Written by apps/www/scripts/syncPartnerIntakeForm.mjs +apps/www/components/Partners/__generated__ apps/docs/**/generated/* apps/docs/examples/* examples/slack-clone/nextjs-slack-clone/full-schema.sql # ignore files with custom js formatting apps/studio/public apps/**/.turbo -apps/docs/CONTRIBUTING.md apps/docs/__generated__ # Generated by apps/docs/internals/generate-markdown-manifest.ts apps/docs/lib/markdown-manifest.ts diff --git a/AGENTS.md b/AGENTS.md index 207950b9d5f..d49e92295d4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -60,10 +60,10 @@ Never hand-edit generated files: `packages/api-types/types/**`, `**/routeTree.ge ## Skills -The skills in `.agents/skills/` are the source of truth for conventions — load the relevant ones before working, don't guess: +The skills in `.agents/skills/` are the source of truth for conventions. Load the relevant ones before working, don't guess. One exception: for docs **content** style, `apps/docs/style-guide/` is the source of truth and the docs skills are the process that applies it. - `copywriting` — any user-facing text, anywhere in the monorepo -- `pm-the-docs` / `write-the-docs` / `edit-the-docs` / `ask-the-docs` / `review-the-docs` — anything under `apps/docs` (see `apps/docs/CONTRIBUTING.md` for the authoring skill model) +- `pm-the-docs` / `write-the-docs` / `edit-the-docs` / `ask-the-docs` / `review-the-docs` — anything under `apps/docs` (see `apps/docs/CONTRIBUTING.md` for the authoring skill model, and `apps/docs/style-guide/` for the content style rules they apply) - `telemetry-standards` — PostHog events, `packages/common/telemetry-constants.ts` - `dev-toolbar-review` — `packages/dev-tools`, `packages/common/posthog-client.ts`, `packages/common/feature-flags.tsx` - `safe-sql-execution` — any code that builds or executes SQL against user databases diff --git a/apps/design-system/components/colors.tsx b/apps/design-system/components/colors.tsx index 23948a3802a..d50fc829a9e 100644 --- a/apps/design-system/components/colors.tsx +++ b/apps/design-system/components/colors.tsx @@ -7,10 +7,14 @@ const color = colors['default'] const Colors = ({ definition, + classes, }: { definition: 'background' | 'border' | 'text' | 'colors' | 'palletes' + /** Optional subset of utility classes. Defaults to the full set for `definition`. */ + classes?: string[] }) => { const [copiedIndex, setCopiedIndex] = useState(null) + const items = classes ?? color[definition] const handleCopy = async (value: string, index: number) => { try { @@ -63,7 +67,7 @@ const Colors = ({ return ( <> - {color[definition].map((x: string, i) => { + {items.map((x: string, i) => { return ( `s, use `focus-inset` only. `focus-ring` will look fine in some browsers and invisible in others diff --git a/apps/design-system/content/docs/color-usage.mdx b/apps/design-system/content/docs/color-usage.mdx index 51e5b530f87..c31587550d0 100644 --- a/apps/design-system/content/docs/color-usage.mdx +++ b/apps/design-system/content/docs/color-usage.mdx @@ -5,21 +5,58 @@ description: Colors system breakdown with best practices. The shorthand utility classes below simplify our full color palette by providing sensible, contrast-checked defaults. Use them whenever possible to ensure accessible text colors and balanced background fills. +## Primary and brand colors + +Primary is the theme's functional accent. Changing `--primary-hue` updates primary text, buttons, selected controls, and focus rings. Brand is the fixed Supabase palette for product identity. + +| Role | Tokens | Follows the primary hue? | +| ----------------- | ------------------------------------------------------------ | ------------------------ | +| Functional accent | `--primary`, `--primary-solid`, `--primary-bright`, `--ring` | Yes | +| Supabase identity | `brand-default`, `brand-*` | No | + +### Primary ink + +`--primary` is for readable UI: links, labels, radios, step dots, and other small indicators. Utilities include `text-primary`, `bg-primary`, and `border-primary`. + +In light mode it is darkened to meet WCAG AA for normal text. In dark mode it stays bright so those controls remain visible on dark surfaces. + +### Primary solid + +`--primary-solid` is the deeper fill for primary buttons. In dark mode it is darker than `--primary` so buttons do not read as lime. In light mode it matches `--primary`, so ink and buttons share one green. Primary Button uses `bg-primary-solid` / `text-primary-solid-foreground`. + +### Bright primary + +`--primary-bright` gives focus rings, selected controls, and other interactive chrome a brighter version of the primary hue. It stays vivid when light-mode `--primary` is darkened for readable text. Use `bg-primary-bright`, `border-primary-bright`, and the shared `ring-ring` focus treatment. + +### Brand green + +`brand-default` remains the fixed Supabase green for explicitly branded surfaces. + +Toggle the theme to compare the swatches below. Light mode collapses primary and primary-solid; dark mode separates bright ink from the deeper button plate: + + + +See also [Typography](../docs/typography) (`text-primary`) and [Accessibility](../docs/accessibility#focus-management) (shared focus ring). + ## Text Use accent text colors (e.g. text-destructive, text-warning) sparingly to avoid visual overload. -Use `text-primary` for readable branded text such as links, labels, and statuses. On light-theme -surfaces it meets the 4.5:1 WCAG AA requirement for normal text. Use `bg-brand-default` / -`border-brand-default` when you need the canonical bright Supabase green as a fill or border. +Use `text-primary` for readable branded text such as links, labels, and statuses. It meets +WCAG AA for normal text on the surfaces used by the apps: darkened in light mode, bright in +dark mode. Primary buttons use a separate solid plate in dark mode; focus chrome uses +the brighter primary hue. See [Primary and brand colors](#primary-and-brand-colors). ## Background -Use `bg-brand-default` when the canonical Supabase green is required as a fill. The same -`brand-default` suffix applies to borders and other non-text utilities, such as -`border-brand-default`. +Use `bg-primary-bright` for selected controls that need a vivid fill, and `bg-primary` +for smaller indicators such as radios and step dots. Use `bg-brand-default` only when +the canonical Supabase green is required. Details in [Primary and brand colors](#primary-and-brand-colors). @@ -40,7 +77,7 @@ We use backgrounds in 2 different ways. In the ./www and ./docs sites, we use a {children} ``` -### Backgrounds and Surfaces +### Backgrounds and surfaces #### `./apps/www` + `./apps/docs` @@ -72,7 +109,7 @@ This is not to be confused with `Dialogs`, they require to use the same app back -## Other Colors +## Other colors These can also be accessed with `foreground`. Like `text-foreground-light`. diff --git a/apps/design-system/content/docs/components/button.mdx b/apps/design-system/content/docs/components/button.mdx index d4535fc407f..88b9355511f 100644 --- a/apps/design-system/content/docs/components/button.mdx +++ b/apps/design-system/content/docs/components/button.mdx @@ -100,13 +100,17 @@ Used for actions that are not as important as the primary action, or for actions -### Only an icon +### Icon-only -Displaying only an Icon in a button. +Render an [icon](./icons) in a button without accompanying text. Ensure the button is accessible by: - - We should update the button component to support this use case better. - +- Wrapping it in a [Tooltip](./tooltip) for sighted users. +- Adding an `aria-label` prop for screen readers. +- Setting its `aria-describedby` prop to `undefined` when the tooltip content repeats the label. Otherwise screen readers read the label twice. + +Consider also squaring off the button container as shown in the example below. For the default `tiny` size (`h-[26px]`), use `w-6.5` so the button is square. + +Compact icon-only buttons may also benefit from the `hit-area` utility. This increases their tap target slightly each side without changing the visual layout. See the [Table](./table#actions) component for more information. diff --git a/apps/design-system/content/docs/components/combobox.mdx b/apps/design-system/content/docs/components/combobox.mdx index 3ad33b0124e..5b00f003667 100644 --- a/apps/design-system/content/docs/components/combobox.mdx +++ b/apps/design-system/content/docs/components/combobox.mdx @@ -132,3 +132,9 @@ You can create a responsive combobox by using the `` on desktop and t ### Form + +### Create from list + +When users can create an option while choosing one, give the action a clear verb label and place it at the bottom of the list, separated from the existing options. Keep the current selection in place while they create the new option. + + diff --git a/apps/design-system/content/docs/components/textarea.mdx b/apps/design-system/content/docs/components/textarea.mdx index 07b91d58963..a1ab2438d55 100644 --- a/apps/design-system/content/docs/components/textarea.mdx +++ b/apps/design-system/content/docs/components/textarea.mdx @@ -72,6 +72,12 @@ import { Textarea } from '@/components/ui/textarea' +### With addon + +An addon places supporting content inside the same bordered field as the textarea. Wrap `InputGroupTextarea` and `InputGroupAddon` in `InputGroup`, and use `align="block-end"` to place the addon below the text. + + + ### Form diff --git a/apps/design-system/content/docs/components/toggle-group.mdx b/apps/design-system/content/docs/components/toggle-group.mdx index 5cedba42af4..f06d35cba17 100644 --- a/apps/design-system/content/docs/components/toggle-group.mdx +++ b/apps/design-system/content/docs/components/toggle-group.mdx @@ -89,3 +89,37 @@ import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group' ### Disabled + +## Segmented + +A Supabase addition, not part of shadcn or Radix. A segmented control is a compact row of two to +four mutually exclusive options sharing one continuous track, for switching view state (Data or +Definition) or filtering a list (All, Active, Revoked). The choice takes effect immediately and is +never saved, so reach for a [Switch](../components/switch) or +[Radio Group](../components/radio-group) when the setting is persisted, and +[Tabs](../components/tabs) when the options swap whole panels of content. Items paint nothing +themselves; a single indicator slides between them, so the group always has exactly one thing +selected. Give a filter an explicit **All** segment rather than letting deselection stand for +"no filter". + + + + + +## Props + +`ToggleGroup` forwards every prop to the underlying +[Radix Toggle Group](https://www.radix-ui.com/docs/primitives/components/toggle-group#api-reference). +These are the ones worth knowing about. + +| Prop | Type | Default | Description | +| --------------- | --------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `type` | `'single' \| 'multiple'` | | Required by Radix. Only a `'single'` group gets the segmented indicator; a `'multiple'` group falls back to items painting their own background. | +| `variant` | `'default' \| 'outline' \| 'segmented'` | `'default'` | Styles the root and every item, which inherit it through context. `segmented` drops the gaps and per-item borders in favor of an indicator that slides between segments, respecting `prefers-reduced-motion`. | +| `size` | `'tiny' \| 'sm' \| 'default' \| 'lg'` | `'default'` | Item height and padding, inherited through context. `tiny` suits a dense toolbar or table footer. Segments hug their labels, so add `className="flex-1"` to each item, plus a width on the root, if you need them equal. | +| `tone` | `'text' \| 'outline' \| 'primary'` | `'text'` | Segmented only. `text` is a flat `bg-accent` fill, `outline` adds a container border and a raised bordered indicator, `primary` fills the indicator with brand. | +| `allowDeselect` | `boolean` | `true` | Whether clicking the active item in a `type="single"` group clears it, emitting `''`. Set `false` for a segmented control, which has no empty state. | +| `aria-label` | `string` | | Names what is being switched or filtered. The segments name the options, not the axis. | + +`variant` and `size` are the shadcn variant axes; `segmented`, `tone` and `allowDeselect` are the +Supabase additions. `default` and `outline` are unchanged from shadcn. diff --git a/apps/design-system/content/docs/fragments/filter-bar.mdx b/apps/design-system/content/docs/fragments/filter-bar.mdx index 34cbf1ac0e3..669004d818d 100644 --- a/apps/design-system/content/docs/fragments/filter-bar.mdx +++ b/apps/design-system/content/docs/fragments/filter-bar.mdx @@ -50,6 +50,34 @@ export function FilterDemo() { } ``` +## Variants + +The default variant joins filters into a segmented bar. Use the pill variant to show each filter as a separate rounded chip: + +### Segmented + + + +### Pill + + + +```tsx + +``` + ## API Reference ### FilterProperty @@ -60,6 +88,7 @@ interface FilterProperty { name: string type: 'string' | 'number' | 'date' | 'boolean' operators: string[] + formatValue?: (value: FilterCondition['value']) => string options?: string[] | ((search?: string) => Promise | string[]) } ``` @@ -94,6 +123,7 @@ interface FilterCondition { | onFreeformTextChange | (text: string) => void | Callback when free-form text changes | | actions | FilterBarAction[]? | Optional custom actions to show in the menu | | isLoading | boolean? | If true, dims the bar while work is in progress | +| variant | 'default' \| 'pill'? | Filter appearance. Defaults to 'default' | ## Custom actions (e.g. AI) diff --git a/apps/design-system/content/docs/typography.mdx b/apps/design-system/content/docs/typography.mdx index ec6302c945b..80b5ed96808 100644 --- a/apps/design-system/content/docs/typography.mdx +++ b/apps/design-system/content/docs/typography.mdx @@ -14,4 +14,7 @@ The shorthands below are composed of core [Tailwind utility classes](../docs/tai | `text-code-inline` | Apply to a `code` element for inline code or similar custom inline content | | `text-primary` | Accessible Supabase green for readable branded text | -`text-primary` is independent from `bg-brand-default`, `border-brand-default`, and other non-text brand utilities. Its light-mode value has at least 4.5:1 contrast against the light surfaces used by the apps, meeting WCAG AA for normal text. +`text-primary` meets WCAG AA for normal text on app surfaces: darkened in light mode, +bright in dark mode. Focus rings and selected controls derive their brighter fill from +the same primary hue. See [Primary and brand colors](../docs/color-usage#primary-and-brand-colors) for when +to use each green. diff --git a/apps/design-system/content/docs/ui-patterns/charts.mdx b/apps/design-system/content/docs/ui-patterns/charts.mdx index db889d46815..849a4a273bc 100644 --- a/apps/design-system/content/docs/ui-patterns/charts.mdx +++ b/apps/design-system/content/docs/ui-patterns/charts.mdx @@ -222,27 +222,27 @@ type ChartConfig = { Line chart component for displaying time-series data. -| Prop | Type | Default | Description | -| ------------------- | --------------------------------------------------------------------- | ----------------------------- | ----------------------------------------------------------------- | -| `data` | `ChartLineTick[]` | - | Array of data points with timestamp | -| `dataKey` | `string` | - | Key in data object to plot | -| `config` | `ChartConfig?` | - | Chart configuration for styling | -| `onLineClick` | `(datum: ChartLineTick, tooltipData?: CategoricalChartState) => void` | - | Click handler for line points | -| `DateTimeFormat` | `string` | `'MMM D, YYYY, hh:mma'` | Date format for tooltips and labels | -| `isFullHeight` | `boolean` | `false` | Whether chart should take full height | -| `className` | `string` | - | Additional CSS classes | -| `color` | `string` | `'hsl(var(--brand-default))'` | Line color | -| `hoverColor` | `string` | `'hsl(var(--brand-500))'` | Line color on hover | -| `chartHighlight` | `ChartHighlight` | - | Highlight selection configuration | -| `updateDateRange` | `(from: string, to: string) => void` | - | Callback when date range is updated via highlight | -| `highlightActions` | `ChartHighlightAction[]` | - | Actions to show when area is highlighted | -| `syncId` | `string` | - | ID to sync multiple charts | -| `showHighlightArea` | `boolean` | `true` | Whether to show highlight area | -| `cursor` | `string` | - | Cursor style (defaults to 'crosshair' if chartHighlight provided) | -| `showGrid` | `boolean` | `false` | Whether to show grid lines | -| `showYAxis` | `boolean` | `false` | Whether to show Y-axis | -| `YAxisProps` | `object` | - | Additional Y-axis props (tick, tickFormatter, width, etc.) | -| `strokeWidth` | `number` | `1.5` | Line stroke width | +| Prop | Type | Default | Description | +| ------------------- | --------------------------------------------------------------------- | ------------------------- | ----------------------------------------------------------------- | +| `data` | `ChartLineTick[]` | - | Array of data points with timestamp | +| `dataKey` | `string` | - | Key in data object to plot | +| `config` | `ChartConfig?` | - | Chart configuration for styling | +| `onLineClick` | `(datum: ChartLineTick, tooltipData?: CategoricalChartState) => void` | - | Click handler for line points | +| `DateTimeFormat` | `string` | `'MMM D, YYYY, hh:mma'` | Date format for tooltips and labels | +| `isFullHeight` | `boolean` | `false` | Whether chart should take full height | +| `className` | `string` | - | Additional CSS classes | +| `color` | `string` | `'var(--primary-bright)'` | Line color | +| `hoverColor` | `string` | `'hsl(var(--brand-500))'` | Line color on hover | +| `chartHighlight` | `ChartHighlight` | - | Highlight selection configuration | +| `updateDateRange` | `(from: string, to: string) => void` | - | Callback when date range is updated via highlight | +| `highlightActions` | `ChartHighlightAction[]` | - | Actions to show when area is highlighted | +| `syncId` | `string` | - | ID to sync multiple charts | +| `showHighlightArea` | `boolean` | `true` | Whether to show highlight area | +| `cursor` | `string` | - | Cursor style (defaults to 'crosshair' if chartHighlight provided) | +| `showGrid` | `boolean` | `false` | Whether to show grid lines | +| `showYAxis` | `boolean` | `false` | Whether to show Y-axis | +| `YAxisProps` | `object` | - | Additional Y-axis props (tick, tickFormatter, width, etc.) | +| `strokeWidth` | `number` | `1.5` | Line stroke width | #### ChartLineTick Type @@ -275,26 +275,26 @@ Line chart component for displaying time-series data. Bar chart component for displaying time-series data. -| Prop | Type | Default | Description | -| ------------------- | -------------------------------------------------------------------- | ----------------------------- | ----------------------------------------------------------------- | -| `data` | `ChartBarTick[]` | - | Array of data points with timestamp | -| `dataKey` | `string` | - | Key in data object to plot | -| `config` | `ChartConfig?` | - | Chart configuration for styling | -| `onBarClick` | `(datum: ChartBarTick, tooltipData?: CategoricalChartState) => void` | - | Click handler for bars | -| `DateTimeFormat` | `string` | `'MMM D, YYYY, hh:mma'` | Date format for tooltips and labels | -| `isFullHeight` | `boolean` | `false` | Whether chart should take full height | -| `className` | `string` | - | Additional CSS classes | -| `color` | `string` | `'hsl(var(--brand-default))'` | Bar color | -| `hoverColor` | `string` | `'hsl(var(--brand-500))'` | Bar color on hover | -| `chartHighlight` | `ChartHighlight` | - | Highlight selection configuration | -| `updateDateRange` | `(from: string, to: string) => void` | - | Callback when date range is updated via highlight | -| `highlightActions` | `ChartHighlightAction[]` | - | Actions to show when area is highlighted | -| `syncId` | `string` | - | ID to sync multiple charts | -| `showHighlightArea` | `boolean` | `true` | Whether to show highlight area | -| `cursor` | `string` | - | Cursor style (defaults to 'crosshair' if chartHighlight provided) | -| `showGrid` | `boolean` | `false` | Whether to show grid lines | -| `showYAxis` | `boolean` | `false` | Whether to show Y-axis | -| `YAxisProps` | `object` | - | Additional Y-axis props (tick, tickFormatter, width, etc.) | +| Prop | Type | Default | Description | +| ------------------- | -------------------------------------------------------------------- | ------------------------------- | ----------------------------------------------------------------- | +| `data` | `ChartBarTick[]` | - | Array of data points with timestamp | +| `dataKey` | `string` | - | Key in data object to plot | +| `config` | `ChartConfig?` | - | Chart configuration for styling | +| `onBarClick` | `(datum: ChartBarTick, tooltipData?: CategoricalChartState) => void` | - | Click handler for bars | +| `DateTimeFormat` | `string` | `'MMM D, YYYY, hh:mma'` | Date format for tooltips and labels | +| `isFullHeight` | `boolean` | `false` | Whether chart should take full height | +| `className` | `string` | - | Additional CSS classes | +| `color` | `string` | `'var(--primary-bright)'` | Bar color | +| `hoverColor` | `string` | `'var(--primary-bright-hover)'` | Bar color on hover | +| `chartHighlight` | `ChartHighlight` | - | Highlight selection configuration | +| `updateDateRange` | `(from: string, to: string) => void` | - | Callback when date range is updated via highlight | +| `highlightActions` | `ChartHighlightAction[]` | - | Actions to show when area is highlighted | +| `syncId` | `string` | - | ID to sync multiple charts | +| `showHighlightArea` | `boolean` | `true` | Whether to show highlight area | +| `cursor` | `string` | - | Cursor style (defaults to 'crosshair' if chartHighlight provided) | +| `showGrid` | `boolean` | `false` | Whether to show grid lines | +| `showYAxis` | `boolean` | `false` | Whether to show Y-axis | +| `YAxisProps` | `object` | - | Additional Y-axis props (tick, tickFormatter, width, etc.) | #### ChartBarTick Type diff --git a/apps/design-system/registry/default/block/chart-composed-basic.tsx b/apps/design-system/registry/default/block/chart-composed-basic.tsx index d185c5e79bb..50452e943a6 100644 --- a/apps/design-system/registry/default/block/chart-composed-basic.tsx +++ b/apps/design-system/registry/default/block/chart-composed-basic.tsx @@ -48,7 +48,7 @@ export default function ComposedChartBasic() { const chartConfig = { standard_score: { label: 'Standard Score', - color: 'hsl(var(--brand-default))', + color: 'var(--primary-bright)', }, performance: { label: 'Performance', diff --git a/apps/design-system/registry/default/example/button-icon.tsx b/apps/design-system/registry/default/example/button-icon.tsx index e9cac7c1660..89600f1cce1 100644 --- a/apps/design-system/registry/default/example/button-icon.tsx +++ b/apps/design-system/registry/default/example/button-icon.tsx @@ -1,6 +1,21 @@ -import { ChevronRight } from 'lucide-react' -import { Button } from 'ui' +import { ExternalLink } from 'lucide-react' +import { Button, Tooltip, TooltipContent, TooltipTrigger } from 'ui' export default function ButtonIcon() { - return + return ( + + + + + View logs + + ) } diff --git a/apps/design-system/registry/default/example/checkbox-with-text.tsx b/apps/design-system/registry/default/example/checkbox-with-text.tsx index 13031d362bf..ccd2e0b902f 100644 --- a/apps/design-system/registry/default/example/checkbox-with-text.tsx +++ b/apps/design-system/registry/default/example/checkbox-with-text.tsx @@ -4,7 +4,7 @@ import { Checkbox } from 'ui' export default function CheckboxWithText() { return ( -
+