CLI reference
Use the BaseBuddy CLI to set up, inspect, and update BaseBuddy app data safely.
The BaseBuddy CLI is the safe way for operators and agents to update BaseBuddy app data without hand-editing files or database rows.
Run commands from the BaseBuddy app root. By default, the CLI reads and writes:
textprocess.cwd()/basebuddy-data/basebuddy.config.jsonEnv secrets still belong in .env or your production host, not in CLI flags and not in the config file.
If BASEBUDDY_APP_STATE_BACKEND is supabase-same-project or supabase-split-project, the same commands read and write basebuddy.app_state in Postgres/Supabase. Split-project app data also needs BASEBUDDY_APP_STATE_DATABASE_URL.
Use App data storage options before deciding which app-data backend your CLI commands should write to.
Setup and diagnostics
| Command | What it does |
|---|---|
pnpm basebuddy | Show CLI help |
pnpm basebuddy agent:setup --json | Print the recommended agent-first setup workflow |
pnpm basebuddy doctor | Check app data, owner, env, database role, database connection, and optional storage readiness |
pnpm basebuddy doctor --json | Print redacted machine-readable setup status |
pnpm basebuddy doctor --skip-db-check | Check setup without opening a live database connection |
pnpm basebuddy setup | Create BaseBuddy app data if it does not exist |
pnpm basebuddy setup --owner-email owner@example.com --owner-name "Owner" --owner-password "strong-password" | Create the first owner and BaseBuddy app data |
pnpm basebuddy app-data:sql | Print the SQL for Supabase/Postgres app-data tables |
pnpm basebuddy app-data:migrate | Create Supabase/Postgres app-data tables |
pnpm basebuddy app-data:check | Verify Supabase/Postgres app-data tables exist |
pnpm setup:check | Run the setup checker script with live database reachability |
doctor exits 0 when required setup is ready and 1 when any required check is missing or invalid.
Use a restricted database role for BASEBUDDY_CONTENT_DATABASE_URL in production. doctor flags broad role names such as postgres, and the editor marks fields read-only when Postgres says the role cannot update their columns.
Use Agent CLI setup when an AI agent needs a complete setup path from env checks through project mapping.
Supabase/Postgres app-data tables
Use these commands when BASEBUDDY_APP_STATE_BACKEND is supabase-same-project or supabase-split-project:
bashpnpm basebuddy app-data:migrate
pnpm basebuddy app-data:checkapp-data:migrate creates only:
basebuddy.app_statebasebuddy.audit_events
It does not alter content schemas, content rows, mapped tables, storage buckets, or project mappings.
If your runtime database role cannot create schemas or tables, print the SQL:
bashpnpm basebuddy app-data:sqlRun that SQL with an admin role in your database SQL editor, then return to BaseBuddy and run pnpm basebuddy app-data:check.
Users
| Command | What it does |
|---|---|
pnpm basebuddy users:list --json | List local users without password hashes or salts |
pnpm basebuddy user:create --email editor@example.com --name "Editor" --password "strong-password" | Create a local password user |
pnpm basebuddy users:delete --email editor@example.com | Delete a local user when doing so will not remove the last owner of a project |
Deleting a user also removes that user's sessions and project memberships. The CLI blocks deletion when the user is the last owner of any project.
Projects
| Command | What it does |
|---|---|
pnpm basebuddy projects:list --actor-email owner@example.com --json | List projects visible to one user |
pnpm basebuddy projects:list --all --json | List every project in the config file |
pnpm basebuddy projects:create --actor-email owner@example.com --name "Docs" --slug docs | Create a project and make the actor the owner |
pnpm basebuddy projects:update --project docs --name "Docs Hub" --slug docs-hub | Update project name or address |
pnpm basebuddy projects:update --project docs --website-url https://docs.example.com | Update the project website URL |
pnpm basebuddy projects:update --project docs --clear-website-url | Clear the project website URL |
pnpm basebuddy projects:delete --project docs | Delete a project from BaseBuddy app state |
Project deletion removes the BaseBuddy project record and its invitations. It does not drop user tables, delete content rows, or remove storage objects.
Members and invitations
| Command | What it does |
|---|---|
pnpm basebuddy members:list --project docs --actor-email owner@example.com --json | List project members |
pnpm basebuddy members:add --project docs --actor-email owner@example.com --email editor@example.com --roles editor | Add an existing local user to a project |
pnpm basebuddy members:update --project docs --actor-email owner@example.com --user-email editor@example.com --roles editor,author --author-scopes author_123:true | Update member roles and author scopes |
pnpm basebuddy members:remove --project docs --actor-email owner@example.com --user-email editor@example.com | Remove a project member |
pnpm basebuddy invites:list --project docs --actor-email owner@example.com --json | List project invitations |
pnpm basebuddy invites:create --project docs --actor-email owner@example.com --email viewer@example.com --roles viewer --json | Create an invite and return the invite path |
pnpm basebuddy invites:revoke --project docs --actor-email owner@example.com --invitation-id invitation_id | Revoke a pending invite |
Supported roles are owner, admin, editor, author, and viewer. Author scopes are config values that connect a BaseBuddy member to mapped content author IDs.
Permissions
| Command | What it does |
|---|---|
pnpm basebuddy permissions:get --project docs --actor-email owner@example.com --json | List permission definitions and member permission state |
pnpm basebuddy permissions:set --project docs --actor-email owner@example.com --user-email editor@example.com --allow mapping.write --deny project.delete | Set allow/deny overrides for one member |
Permission definitions live in code. The config file stores only per-member allowPermissionKeys and denyPermissionKeys.
Schema inspection
| Command | What it does |
|---|---|
pnpm basebuddy schema:inspect --schema public --json | Inspect visible tables, columns, primary keys, foreign keys, enums, and sample rows |
pnpm basebuddy schema:inspect --schema public --table posts,authors --json | Inspect only selected tables |
pnpm basebuddy schema:inspect --schema public --table posts --no-samples --json | Inspect schema without reading sample rows |
schema:inspect reads from BASEBUDDY_CONTENT_DATABASE_URL. It does not print the connection string. Use it before drafting mapping JSON, especially when an agent is setting up a project for a schema it has not seen before.
If a table is missing from the output, BaseBuddy cannot map it yet. Check the schema name, table name, and database user's permissions before continuing.
Mapping
| Command | What it does |
|---|---|
pnpm basebuddy mapping:draft --schema public --table posts --json | Draft valid mapping JSON from inspected schema |
pnpm basebuddy mapping:draft --schema public --table pages --hints mapping-hints.json --json | Draft mapping JSON using a small hints file for custom names |
pnpm basebuddy mapping:explain --input mapping.json --json | Summarize sources, mapped fields, editor fields, custom fields, workflow, and storage |
pnpm basebuddy mapping:get --project docs --json | Print the current project mapping |
pnpm basebuddy mapping:validate --input mapping.json --json | Normalize and validate mapping JSON without saving |
pnpm basebuddy mapping:set --project docs --input mapping.json --binding-status ready --json | Save a new mapping revision |
mapping:draft returns an object with mappingConfig, summary, and valid. Save the mappingConfig object as the JSON file you pass to mapping:set.
Use hints when the database uses names BaseBuddy cannot safely infer:
json{
"postsTable": "public.pages",
"titleColumn": "headline",
"slugColumn": "slug",
"contentFields": [
{
"column": "body_md",
"kind": "markdown",
"label": "Body"
}
],
"customFields": [
{
"column": "faq_json",
"kind": "json",
"label": "FAQ"
}
],
"workflow": {
"mode": "published_flag",
"publishedFlagColumn": "is_published",
"publishedAtColumn": "published_at"
}
}mapping:set updates the saved mapping and appends a mapping revision. It does not rename tables, add columns, or change user content schemas. Always run mapping:explain before saving generated mapping JSON.
Sidebar layout
| Command | What it does |
|---|---|
pnpm basebuddy sidebar:get --project docs --json | Print the post sidebar layout |
pnpm basebuddy sidebar:set --project docs --input sidebar.json --json | Save a sidebar layout revision |
pnpm basebuddy sidebar:reset --project docs --json | Reset sidebar layout to the default config |
Sidebar JSON is normalized before saving. Invalid nodes are dropped or normalized instead of being written directly.
Storage mapping and storage env
| Command | What it does |
|---|---|
pnpm basebuddy storage:status --json | Check optional Supabase/S3 storage env completeness without printing secrets |
pnpm basebuddy storage:get --project docs --library media --json | Print media storage mapping metadata |
pnpm basebuddy storage:get --project docs --library files --json | Print file storage mapping metadata |
pnpm basebuddy storage:set --project docs --library media --provider supabase_bucket --bucket media | Save Supabase bucket metadata for media |
pnpm basebuddy storage:set --project docs --library files --provider s3_compatible --bucket files --region auto --endpoint https://example.r2.cloudflarestorage.com | Save S3-compatible bucket metadata for files |
pnpm basebuddy storage:set --project docs --library media --provider none | Clear mapped media storage |
Storage mapping saves only non-secret metadata: provider, bucket, endpoint, region, and public URL base. Supabase keys and S3 access keys stay in env.
What the CLI does not do
The CLI does not edit content rows, upload files, delete storage objects, publish/unpublish/archive content, or manage deployment env values.
Those workflows still belong in the app UI, database tools, storage provider dashboard, or deployment platform.
Agent usage
Agents should start with:
bashpnpm basebuddy agent:setup --jsonThen use doctor, schema:inspect, mapping:draft, mapping:explain, and mapping:set in that order. This keeps schema discovery, config validation, IDs, revision history, permission checks, and secret redaction in one code path.
Direct edits to basebuddy-data/basebuddy.config.json should be treated as emergency repair only.