adapto-cms-cli

command module
v0.1.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 9, 2026 License: MIT Imports: 2 Imported by: 0

README

Adapto CMS CLI

Command-line interface for the Adapto CMS Management API.

Install

Quick install (macOS/Linux)
curl -sSL https://raw.githubusercontent.com/adaptocms/adapto-cms-cli/main/scripts/install.sh | bash
From source
go install github.com/adaptocms/adapto-cms-cli@latest
From releases

Download the binary for your platform from GitHub Releases.

Quick Start

Existing account:

adapto auth login --email you@example.com --password yourpassword

New account:

adapto auth register --email you@example.com --password yourpassword
# the activation email contains a ready-to-run command:
adapto auth activate --token <token-from-email>
adapto onboard   # creates your first project + API key

Credentials are saved to ~/.config/adapto/credentials.json and read automatically. The flow is flag-driven so an agent can run it end to end; the only manual step is pasting the activation token from the email.

Manage content:

adapto articles list --json
adapto articles create --title "My Article" --content "Hello world" --slug my-article --author Jane --language en-US

LLM Integration

The CLI is built to be driven by LLM agents. One command gives an agent full knowledge of every command, flag, and workflow:

adapto llm-info

Pipe it into your agent's context (Claude Code, Cursor, MCP tools) and the agent can manage content end to end. Every command supports --json for machine-readable output.

Configuration

None needed in the common case: adapto auth login stores credentials in ~/.config/adapto/credentials.json and every command reads them from there.

For scripting and overrides:

Variable Description
ADAPTO_CLI_TOKEN Bearer token (overrides stored credentials)
ADAPTO_CLI_API_URL Management API base URL (default: https://api.adaptocms.com)
ADAPTO_CLI_TENANT_ID Tenant ID (overrides stored credentials)

All variables can also be passed as flags: --token, --api-url, --tenant-id.

Two APIs. The CLI talks only to the Management API (api.adaptocms.com). The ADAPTO_API_URL / ADAPTO_API_KEY variables found in client site .env files configure the read-only Public API and are ignored by the CLI. Never point ADAPTO_CLI_API_URL at public-api.adaptocms.com.

Commands

adapto
├── api-key                           Manage Public API keys
│   ├── issue                       Issue a Public API key for the active project
│   ├── list                        List the active project's API keys
│   └── revoke [api-key-id]         Revoke an API key
├── articles                          Manage articles
│   ├── archive <id>                Archive an article
│   ├── categories <id>             List categories of an article
│   ├── create                      Create an article
│   ├── create-translation <source_id>  Create an article translation
│   ├── delete <id>                 Delete an article
│   ├── get <id>                    Get an article by ID
│   ├── get-by-slug <slug>          Get an article by slug
│   ├── list                        List articles
│   ├── publish <id>                Publish an article
│   ├── translations <id>           List translations of an article
│   └── update <id>                 Update an article
├── auth                              Authentication commands
│   ├── activate                    Activate account and log in
│   ├── callback-github             Complete GitHub OAuth callback
│   ├── change-password             Change your password
│   ├── login                       Login with email and password
│   ├── login-github                Login via GitHub OAuth
│   ├── login-google                Login via Google credential
│   ├── logout                      Logout (revoke refresh token)
│   ├── me                          Get current user info
│   ├── orgs                        List your organizations and their tenants
│   ├── refresh                     Refresh access token
│   ├── register                    Register a new account
│   ├── request-password-reset      Request a password reset email
│   ├── resend-activation           Resend activation email
│   ├── reset-password              Reset password with token
│   └── switch-tenant               Switch active tenant/organization
├── categories                        Manage categories
│   ├── add-article <category_id> <article_id>  Add an article to a category
│   ├── articles <category_id>      List articles in a category
│   ├── create                      Create a category
│   ├── create-translation <source_id>  Create a category translation
│   ├── delete <id>                 Delete a category
│   ├── get <id>                    Get a category by ID
│   ├── get-by-slug <slug>          Get a category by slug
│   ├── list                        List categories
│   ├── remove-article <category_id> <article_id>  Remove an article from a category
│   ├── subcategories <id>          List subcategories
│   ├── translations <id>           List translations of a category
│   └── update <id>                 Update a category
├── collections                       Manage custom collections
│   ├── create                      Create a collection
│   ├── delete <id>                 Delete a collection
│   ├── get <id>                    Get a collection by ID
│   ├── get-by-slug <slug>          Get a collection by slug
│   ├── items                       Manage collection items
│   │   ├── archive <collection_id> <item_id>  Archive a collection item
│   │   ├── create <collection_id>  Create a collection item
│   │   ├── create-batch <collection_id>  Create multiple items in batch
│   │   ├── create-translation <collection_id> <source_id>  Create an item translation
│   │   ├── delete <collection_id> <item_id>  Delete a collection item
│   │   ├── get <collection_id> <item_id>  Get a collection item
│   │   ├── get-by-slug <collection_id> <slug>  Get a collection item by slug
│   │   ├── list <collection_id>  List items in a collection
│   │   ├── publish <collection_id> <item_id>  Publish a collection item
│   │   ├── translations <collection_id> <item_id>  List translations of an item
│   │   └── update <collection_id> <item_id>  Update a collection item
│   ├── list                        List collections
│   └── update <id>                 Update a collection
├── files                             Manage files
│   ├── create-metadata             Create file metadata (before upload)
│   ├── delete <id>                 Delete a file
│   ├── get <id>                    Get file info by ID
│   ├── list                        List files
│   ├── multipart-abort <file_id> <upload_id>  Abort a multipart upload (low-level)
│   ├── multipart-complete <file_id> <upload_id>  Complete a multipart upload (low-level)
│   ├── multipart-init <file_id>    Initialize a multipart upload (low-level)
│   ├── multipart-upload <file_id> <upload_id> <part_number> <filepath>  Upload one already-split part via a presigned S3 URL (low-level)
│   ├── update <id>                 Update file metadata
│   ├── upload <filepath>           Upload a file of any size
│   └── upload-by-id <file_id> <filepath>  Upload file content for an existing file record
├── llm-info                          Print full CLI reference for LLM consumption
├── microcopy                         Manage micro copy entries
│   ├── count                       Count micro copy entries
│   ├── create                      Create a micro copy entry
│   ├── create-translation <source_id>  Create a micro copy translation
│   ├── delete <id>                 Delete a micro copy entry
│   ├── get <id>                    Get micro copy by ID
│   ├── get-by-key <key>            Get micro copy by key
│   ├── get-by-language <language>  Get all micro copy for a language
│   ├── list                        List micro copy entries
│   ├── translations <id>           List translations of a micro copy entry
│   └── update <id>                 Update a micro copy entry
├── onboard                           Set up your first project and API key
├── org                               Manage organizations
│   ├── create                      Create an organization
│   └── list                        List your organizations
├── pages                             Manage pages
│   ├── archive <id>                Archive a page
│   ├── create                      Create a page
│   ├── create-translation <source_id>  Create a page translation
│   ├── delete <id>                 Delete a page
│   ├── get <id>                    Get a page by ID
│   ├── get-by-slug <slug>          Get a page by slug
│   ├── list                        List pages
│   ├── publish <id>                Publish a page
│   ├── translations <id>           List translations of a page
│   └── update <id>                 Update a page
├── project                           Manage projects
│   ├── create                      Create a project
│   ├── delete [project-id]         Delete a project and all its content
│   ├── list                        List your projects
│   ├── update [project-id]         Update a project
│   └── use [project-id]            Set the active project
├── status                            API status commands
│   └── version                     Get API version info
└── version                           Print the CLI version

Output

By default, commands output formatted tables. Use --json for JSON output:

adapto articles list --json
adapto articles get abc123 --json

Interactive Mode

When running in a terminal (TTY), missing required parameters will be prompted interactively. When piped or in scripts, missing parameters produce an error with usage hints.

File Upload

adapto files upload handles a file of any size in one command: it creates the metadata, initialises a multipart upload, requests presigned S3 URLs, streams the file to S3 in 5 MiB parts, and completes the upload.

# Single-step upload of any size (creates metadata + uploads content)
adapto files upload ./photo.jpg

# Override the stored filename, MIME type or tags
adapto files upload ./photo.jpg --filename hero.jpg --content-type image/jpeg --tags product,hero

# Two-step: create metadata first, then upload content by ID
adapto files create-metadata --filename photo.jpg --content-type image/jpeg
adapto files upload-by-id FILE_ID ./photo.jpg

File bytes go client → S3, never through the API. The Management API runs on AWS Lambda behind API Gateway, which base64-encodes binary request bodies into the invocation event (a 4/3 expansion) and caps that event at 6 MB. S3 separately requires every multipart part except the last to be at least 5 MiB — which base64-encodes to about 6.99 MB, over the cap. No chunk size satisfies both limits, so the CLI uses the API only for the control plane (metadata, init, presign, complete, abort) and PUTs the bytes straight to S3 over presigned URLs.

What that means in practice:

  • The file is read from disk one part at a time — memory use does not scale with file size.
  • Progress goes to stderr, so stdout (and --json) carries only the resulting file record.
  • A failure exits non-zero and aborts the multipart upload, so incomplete parts stop accruing S3 storage charges.
  • If S3 rejects a part with a 403 because its presigned URL expired mid-upload, the CLI re-presigns the remaining parts and carries on.

The multipart-* subcommands expose the same sequence step by step, also over presigned URLs, for when you want to drive it yourself:

adapto files multipart-init FILE_ID --json                          # -> upload_id
split -b 5242880 big.zip part-                                      # parts must be exactly 5 MiB
adapto files multipart-upload FILE_ID UPLOAD_ID 1 ./part-aa --json  # -> {"ETag": "...", "PartNumber": 1}
adapto files multipart-complete FILE_ID UPLOAD_ID --parts '[{"PartNumber":1,"ETag":"<etag>"}]'
adapto files multipart-abort FILE_ID UPLOAD_ID                      # discard an incomplete upload

ETags are printed unquoted. The server normalises quoted, unquoted and weak-validator (W/"...") forms, so multipart-complete accepts either.

Media Objects

Articles, pages, and collection items support attaching media (images, videos, embeds) via the --media-json flag on create, update, and create-translation commands:

adapto articles create \
  --title "My Post" \
  --content "<p>Hello</p>" \
  --slug my-post \
  --author "Jane" \
  --language en-US \
  --media-json '[{
    "placement_key": "hero_image",
    "media_object": {
      "id": "m1",
      "file_id": "FILE_ID",
      "url": "https://cdn.example.com/photo.jpg",
      "type": "image"
    },
    "alt_text": "Hero image"
  }]'

Each placement object supports:

  • placement_key: where the media goes (e.g. hero_image, body_image_1)
  • media_object: id, file_id, url, type (image/video/audio/document/other/youtube/vimeo/tiktok/instagram_reel/instagram_post), title, description
  • caption, alt_text, meta_data: optional metadata

The same --media-json flag works on adapto pages create/update and adapto collections items create/update.

Development

Building, testing, and releasing: see DEVELOPMENT.md.

License

MIT, see LICENSE.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
cmd
org
internal
client
Package client provides primitives to interact with the openapi HTTP API.
Package client provides primitives to interact with the openapi HTTP API.
upload
Package upload implements client-side S3 multipart uploads via presigned URLs.
Package upload implements client-side S3 multipart uploads via presigned URLs.
test
tools
gendocs command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL