Skip to content

feat(cli): add supabase notebooks pull - #6598

Draft
SaxonF wants to merge 1 commit into
notebooks/02-api-deepobject-queryfrom
notebooks/04-cli-notebooks-pull
Draft

SaxonF wants to merge 1 commit into
notebooks/02-api-deepobject-queryfrom
notebooks/04-cli-notebooks-pull

Conversation

@SaxonF

@SaxonF SaxonF commented Sep 14, 2026

Copy link
Copy Markdown

Adds the supabase notebooks command family and its first subcommand, notebooks pull. Notebooks live in supabase/notebooks/<name>.json, one committed JSON file each, alongside supabase/functions/ and supabase/compute/.

supabase notebooks pull                     # write notebooks missing locally
supabase notebooks pull <notebook-id>       # replace one local copy

Identity is the name, not the id

The API assigns each notebook a uuid, but a checkout is shared through git and a uuid in a filename is unreadable — so the file name is the notebook's identity across the two sides. Two consequences the code is shaped around:

  • Notebook names are free text up to 255 characters, so a name can hold a path separator, a Windows device name, or a trailing dot. Those are reported and skipped, never sanitised: a sanitised name would push back later as a rename of somebody's notebook. Portable-filename aliases (Sales vs sales, NFC vs NFD) are refused before anything is written, so a checkout stays valid when it moves between filesystems.
  • Names are not unique in the API, so a project holding two notebooks of one name is refused rather than guessed at.

Reconciliation

Without an argument the checkout wins: only notebooks missing locally are written, and existing files are left alone. A notebook id is the opt-in overwrite path, and reconciles nothing — the argument says which notebook to replace, so the rest of the directory is not that invocation's business.

Local files naming no project notebook are the divergence the command asks about. Three answers rather than a confirmation, because the two useful ones point opposite ways: such a file is either one somebody deleted in the dashboard, or one somebody added locally and never pushed, and nothing in the list says which. An unattended run — non-TTY, machine output format, or a cancelled prompt — reports the divergence and leaves both sides alone rather than resolving it in a direction nobody chose.

Reviewer notes

  • Files are published through a temp file plus a hard link, so an interrupted pull leaves no partial file and never clobbers a file that appeared after the inventory was read. pull/SIDE_EFFECTS.md records the full side-effect surface.
  • The list walk follows the server's links.next cursor rather than counting rows, and fails closed on a missing or repeated cursor instead of looping.
  • notebooks.shared.ts is deliberately the shared half for the whole family; notebooks push lands on top of this PR in the stack and reuses it.

@SaxonF
SaxonF added this pull request to stack #6600 September 14, 2026 11:20
@SaxonF
SaxonF force-pushed the notebooks/04-cli-notebooks-pull branch from 425d460 to dafd923 Compare September 15, 2026 00:12
Adds the `supabase notebooks` command family and its first subcommand.
`notebooks pull` writes the linked project's notebooks into
`supabase/notebooks/<name>.json`, one committed JSON file per notebook.

A notebook's identity across the two sides is its name, because a
checkout is shared through git and the API's uuid is unreadable in a
filename. Names the API allows but a filesystem cannot hold are reported
rather than sanitised, and portable-filename aliases are refused before
anything is written, so a pull never renames somebody's notebook by
accident.

Without an argument the checkout wins: only notebooks missing locally are
written, and existing files are left alone. A notebook id is the opt-in
overwrite path for a single notebook. Local files naming no project
notebook are the divergence the command asks about — leave them, delete
them, or create them in the project — and an unattended run reports the
divergence and leaves both sides alone rather than resolving it in a
direction nobody chose.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@SaxonF
SaxonF force-pushed the notebooks/04-cli-notebooks-pull branch from dafd923 to 8812be5 Compare September 15, 2026 00:29
@SaxonF
SaxonF removed this pull request from stack #6600 September 15, 2026 00:30
@SaxonF
SaxonF changed the base branch from notebooks/03-cli-resource-output to notebooks/02-api-deepobject-query September 15, 2026 00:30
@SaxonF
SaxonF added this pull request to stack #6612 September 15, 2026 00:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant