Skip to content

Local development: createBoolClient apiKey + the bool CLI (link, types, entities, deploy) - #13

Merged
max-bader merged 12 commits into
mainfrom
claude/bool-local-dev-mcp-pu8kdj
Jul 22, 2026
Merged

max-bader merged 12 commits into
mainfrom
claude/bool-local-dev-mcp-pu8kdj

Conversation

@HomemadeToast57

@HomemadeToast57 HomemadeToast57 commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

The SDK half of using a Bool project as a managed backend from your own machine (companion PR codehs/bool#487 adds the platform endpoints + MCP tools).

Client

createBoolClient({ ..., apiKey }) — a Bool data key (boolsk_ project admin, or boolk_ end-user) rides the api_key header on every gateway call (db / users / ai planes), so the client now works from Node scripts, a local Vite app, or CI. Without apiKey, behavior is byte-for-byte unchanged.

CLI (bool, zero dependencies)

  • bool link --project <id> — fetches the project's connection descriptor, writes bool.config.json (public), puts the owner-only admin data key in .env.bool (and gitignores it), and pulls entity types.
  • bool types — regenerates bool/types.d.ts from the project's entity schemas so bool.entities.<name> is fully typed locally.
  • bool entities — prints the declared models + fields.
  • bool entities pull / bool entities push — round-trip the entity schema files (bool/entities/*.jsonc) between the project and disk: pull writes them verbatim (paths confined to bool/entities/), push declares every local file on the project (additive migrations server-side; per-file results + warnings; exit 1 if any fail).
  • bool deploy — zips the app source (store-only zero-dep zip writer; node_modules/.git/build output/env files excluded) and publishes via the drop pipeline: POST /api/drops → PUT the archive → poll the signed status URL to ready/failed. Bool builds in the cloud; the project URL stays stable.

Platform calls authenticate with a personal access token (--token / BOOL_TOKEN). All command logic lives in src/cli.ts behind an injectable-deps seam; src/cli-entry.ts is the bin shim.

Tests

  • src/cli.test.ts — hermetic (stubbed fetch + temp dirs): link happy path + non-owner + v1-project error, types refresh, entities push (per-file results, warnings, failure exit) and pull (verbatim write + hostile-path confinement), deploy happy path / failed build / exclusion rules, entities listing, arg parsing, token errors.
  • src/zip.test.ts — CRC-32 check vector, structural validation of the archive, and an unzip round-trip when the system unzip exists.
  • src/client.test.ts — new "local development" block pinning the api_key header on all three planes (and its absence without the option).
  • bun test 94 pass / 0 fail; bun run typecheck and bun run build green (bin shebang verified).

Release

0.2.0-next.11 on the canary channel; CHANGELOG + README updated. Requires the platform endpoints from codehs/bool#487.

🤖 Generated with Claude Code

https://claude.ai/code/session_011zKXrczjUj4pce5BH9Y1HL

claude added 2 commits July 22, 2026 01:06
…pes, entities, deploy)

The SDK half of using a Bool project as a managed backend from your own
machine (the platform half adds the connection/types/drops endpoints).

- createBoolClient({ ..., apiKey }): a boolsk_/boolk_ data key rides the
  api_key header on every gateway call (db/users/ai), so the client works from
  Node, a local Vite app, or CI. No apiKey → behavior unchanged.
- New zero-dep CLI, bin `bool` (dist/cli-entry.js):
  - link --project <id>: fetches the connection descriptor, writes
    bool.config.json, puts the owner-only admin key in .env.bool (gitignored),
    pulls entity types.
  - types: refreshes bool/types.d.ts from the project's entity schemas.
  - entities: prints the declared models + fields.
  - deploy: zips the source (store-only zip, node_modules/.git/env excluded)
    and publishes via the drop pipeline, polling to ready/failed.
- Tests: cli.test.ts (hermetic, stubbed fetch + temp dirs), zip.test.ts
  (structure + CRC vector + optional unzip round-trip), client.test.ts local-
  development block (api_key header on all three planes).
- 0.2.0-next.11, changelog + README section.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011zKXrczjUj4pce5BH9Y1HL
…ies pull`

Round-trip the entity schema files (bool/entities/*.jsonc) between a project
and a local working copy:

- `bool entities pull` writes the project's schema files verbatim (paths from
  the network are confined to bool/entities/ — anything else is skipped) and
  refreshes types.
- `bool entities push` parses every local .jsonc (same whole-line-comment
  format the platform writes) and declares each on the project via
  POST /api/projects/[id]/entities — additive migrations server-side, per-file
  results + warnings reported, exit 1 if any file fails. Types refreshed after.
- parseArgs now captures positional subcommands.

Requires the entities POST + schemas endpoints from the platform PR.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011zKXrczjUj4pce5BH9Y1HL
@HomemadeToast57

Copy link
Copy Markdown
Collaborator Author

Verified this branch end-to-end from a local session against a real dev stack (dev Supabase + local platform server running codehs/bool#488, which speaks the same REST contract as #487):

  • bool link --project … --token … → wrote bool.config.json, fetched the owner boolsk_ key into .env.bool, pulled entity types ✓
  • bool types → refreshed the combined .d.ts (picked up a newly-defined entity) ✓
  • createBoolClient({ …, apiKey }) from a Node process: create / filter({ $regex }) / update / delete through the real gateway, all green ✓

One behavior worth documenting in the README/CLI output: on a private entity, admin-key creates must pass owner_id explicitly (auth.uid() is NULL on the admin path, and the column is NOT NULL) — public entities are unaffected.

🤖 Generated with Claude Code

Per PR review: with the boolsk_ admin key there is no end-user identity, so
owner_id doesn't default on a private entity — a fresh private table (NOT
NULL) rejects the insert without it. Noted in the README local-dev section
and in `bool link`'s next-steps output.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011zKXrczjUj4pce5BH9Y1HL

Copy link
Copy Markdown
Collaborator Author

Thanks for the end-to-end verification! Documented the private-entity owner_id behavior in d3b2f2b (README local-dev section + bool link's next-steps output), and fixed the MCP create_record description on the platform side (codehs/bool@8b558388) — it previously only described the nullable-column case, not the NOT-NULL rejection on fresh private tables.


Generated by Claude Code

claude added 2 commits July 22, 2026 01:47
The entities module + README now state what the API is (a simple, high-level,
Mongo-flavored data surface) rather than framing it comparatively.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011zKXrczjUj4pce5BH9Y1HL
…ackage

Everything in this repo ships to the world, so the notes lead with that:
write self-contained docs/comments/commits that explain the SDK on its own
terms, plus the basic dev/release conventions (hermetic tests, append-only
gateway paths, semver discipline).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011zKXrczjUj4pce5BH9Y1HL
@HomemadeToast57
HomemadeToast57 force-pushed the claude/bool-local-dev-mcp-pu8kdj branch from 09af708 to 0268aaf Compare July 22, 2026 02:09
claude and others added 7 commits July 22, 2026 02:29
Add complete guides and examples for developers building apps locally with Bool:

- docs/README.md: Documentation index and quickstart
- docs/LOCAL-DEVELOPMENT.md: Complete walkthrough with use cases and workflows
- docs/DEPLOYMENT.md: Publishing, CI/CD, monitoring, and troubleshooting
- docs/DATA-MODELING.md: Schema patterns, privacy, relationships, evolution
- docs/FAQ.md: Common questions and answers
- examples/todo-app-react.md: Full React todo app example
- examples/blog-with-cms.md: Blog with admin CMS example
- README.md: Updated with links to new guides

Covers: project linking, entity management, CRUD operations, authentication,
realtime subscriptions, deployment, schema design, error handling, and real-world
use cases (SaaS, blogs, dashboards, static sites, prototyping).

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011zKXrczjUj4pce5BH9Y1HL
Move all documentation out of SDK repo to bool.com/docs for single source of truth.

Removed:
- docs/LOCAL-DEVELOPMENT.md
- docs/DATA-MODELING.md
- docs/DEPLOYMENT.md
- docs/FAQ.md
- docs/README.md
- examples/todo-app-react.md
- examples/blog-with-cms.md

Updated: README.md to link to bool.com/docs for all guides and API reference.

Result: Clean SDK repo (source code only), documentation centralized on website.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011zKXrczjUj4pce5BH9Y1HL
apiJson() only threw on !res.ok, so a 200 with a non-JSON body (parsed to
null via res.json().catch(() => null)) was returned as null — and callers
(link, entities, entities pull) then crashed dereferencing it, e.g.
`TypeError: Cannot read properties of null (reading 'projectId')`. This is
what happens when --api-url points at a host serving the HTML app shell
(the Bool API isn't deployed there yet, or a login/redirect page).

Guard in apiJson: when res.ok but the body isn't a JSON object, throw a
CliError telling the user to check --api-url. Fixes all three callers at
once (deploy/entities push already guarded their own responses). Adds a
regression test; bumps to 0.2.0-next.12.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
`bool create <name> [--path <dir>] [--deploy]` creates a Bool project
(POST /api/projects), scaffolds a self-contained Vite + React todo app wired
to it through bool-sdk, links it (bool.config.json + .env.bool + types), and
declares a public `todos` entity so the deployed app works with no sign-in.
`--deploy` publishes immediately.

- New src/templates.ts holds the bundled todo app (zero-dep string map).
- Refactors cmdLink's config/key writing into a shared writeConfigAndKey so
  create reuses it; adds an apiPost helper (same non-JSON guard as apiJson).
- Tests: create happy path (scaffold + link + entity push, no deploy),
  non-empty-dir guard, missing-name usage. 98 pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
bool-sdk declares @supabase/supabase-js as a peer, so the `bool create` todo
template failed to cloud-build ("Rollup failed to resolve import
@supabase/supabase-js"). Add it to the template's dependencies. Verified with a
real npm install + vite build. Bumps to 0.2.0-next.14.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…plate

- bool create: abort (exit 1) if the entity push fails, instead of proceeding
  to deploy an app whose todos table was never created. Prints how to finish
  once the cause is fixed. (What produced a live-but-broken app when the
  platform entities POST wasn't reachable.)
- todo template: extract .message from thrown values so the UI shows the real
  error instead of "[object Object]" (bool-sdk throws raw, often-non-Error
  objects). Bumps to 0.2.0-next.15.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
No name → generate a friendly one (adjective-noun-NN) and scaffold into a
matching folder. With the default API URL (or BOOL_API_URL) set, `bool create`
alone stands up a todo app + project. Bumps to 0.2.0-next.16.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@max-bader
max-bader marked this pull request as ready for review July 22, 2026 21:22
@max-bader
max-bader merged commit e3272c6 into main Jul 22, 2026
4 checks passed
@max-bader
max-bader deleted the claude/bool-local-dev-mcp-pu8kdj branch July 22, 2026 21:38
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.

3 participants