spree-cli

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Spree CLI — Admin API from the terminal

Spree CLI — 从终端调用 Admin API

@spree/cli
ships a
spree api
command group: a generic Admin API v3 client modeled on
gh api
. It is the fastest way to inspect and manipulate store data from a terminal, and the most reliable way for an agent to debug — no SDK boilerplate, structured JSON in/out, and offline endpoint discovery.
spree api
talks to the Admin API only (
/api/v3/admin
, secret key auth). It can't call the Store or Seller APIs; use
curl
or the SDKs for those. It works against any Spree 6 instance (and 5.5+). Inside a local project it provisions a read-only key for itself; for any other server you supply a key.
@spree/cli
提供
spree api
命令组:这是一个仿照
gh api
的通用 Admin API v3 客户端。它是从终端检查和操作商店数据最快的方式,也是 Agent 进行调试最可靠的途径——无需 SDK 样板代码,使用结构化 JSON 进行输入/输出,并支持离线端点发现。
spree api
仅与 Admin API(
/api/v3/admin
,secret key 认证)通信。它无法调用 Store API 或 Seller API;请对这些 API 使用
curl
或 SDK。它适用于任何 Spree 6 实例(以及 5.5+)。在本地项目中,它会自动配置只读 key;对于其他服务器,你需要提供 key。

When to reach for the CLI

何时使用 CLI

  • Debugging — "what status is order
    or_x
    in?", "why did this 403?", "does this product have the variant I expect?". One command, JSON back, pipe to
    jq
    .
  • Exploring the API — list endpoints and their required scopes, dump an operation's schema, all offline.
  • Scripting / agents — deterministic, pipeable, exit-coded. No client to instantiate.
For building an app, prefer
@spree/admin-sdk
(see
spree-typescript-sdk
). The CLI is for interactive work, scripts, and agents.
  • 调试——“order
    or_x
    当前是什么状态?”“为什么会出现这个 403?”“这个产品是否有我预期的 variant?”只需一条命令,即可返回 JSON,并通过管道传给
    jq
    。
  • 探索 API——列出端点及其所需 scopes,转储某个操作的 schema;全部离线完成。
  • 编写脚本 / Agent——确定性、可管道化,并提供退出码。无需实例化客户端。
如果要构建应用,请优先使用
@spree/admin-sdk
(参见
spree-typescript-sdk
)。CLI 适用于交互操作、脚本和 Agent。

Setup

设置

The CLI is
@spree/cli
(binary:
spree
). Verify it's available:
bash
spree --version          # or: pnpm exec spree --version
If not installed:
npm i -g @spree/cli
(or run via
pnpm exec spree
/
npx @spree/cli
inside a project).
该 CLI 为
@spree/cli
(二进制文件:
spree
)。确认它是否可用:
bash
spree --version          # or: pnpm exec spree --version
如果尚未安装:执行
npm i -g @spree/cli
(也可以在项目中通过
pnpm exec spree
/
npx @spree/cli
运行)。

Credentials — pick the layer that fits

凭据——选择适合的配置层级

Credentials resolve in this order (first match wins); host and key always resolve together per source:
  1. Explicit flags —
    --api-key sk_xxx
    , or
    --profile prod
    to select a saved profile. Outrank everything below.
  2. Env — set
    SPREE_API_KEY
    ; the host defaults to
    http://localhost:3000
    , so local dev needs only the key. Set
    SPREE_BASE_URL
    for a remote store. Note an exported
    SPREE_API_KEY
    outranks a local project's saved key:
    bash
    SPREE_API_KEY=sk_xxx spree api get /products            # → localhost:3000
    SPREE_BASE_URL=https://store.example.com SPREE_API_KEY=sk_xxx spree api get /orders
  3. Inside a local Spree project (a dir with
    docker-compose.yml
    , Rails app in
    server/
    , or legacy
    backend/
    , and the dev stack running): zero config. The first
    spree api
    call mints a read-only key via the dev stack and saves it to
    .spree/credentials.json
    (gitignored). Just run commands.
  4. Default profile (the first profile you
    spree auth login
    becomes the default; key read from a prompt, never a flag):
    bash
    spree auth login --profile prod --base-url https://store.example.com
    spree api get /orders --profile prod    # or omit --profile once it's the default
Confirm what's resolved and that the server is reachable:
bash
spree api status
凭据按以下顺序解析(首个匹配项生效);host 和 key 始终按同一来源成对解析:
  1. 显式参数——
    --api-key sk_xxx
    ,或使用
    --profile prod
    选择已保存的 profile。其优先级高于下列所有来源。
  2. 环境变量——设置
    SPREE_API_KEY
    ;host 默认为
    http://localhost:3000
    ,因此本地开发只需设置 key。若连接远程商店,请设置
    SPREE_BASE_URL
    。请注意,导出的
    SPREE_API_KEY
    优先级高于本地项目中保存的 key:
    bash
    SPREE_API_KEY=sk_xxx spree api get /products            # → localhost:3000
    SPREE_BASE_URL=https://store.example.com SPREE_API_KEY=sk_xxx spree api get /orders
  3. 在本地 Spree 项目中(目录中存在
    docker-compose.yml
    、位于
    server/
    的 Rails 应用或旧版
    backend/
    ,并且开发环境栈正在运行):零配置。首次执行
    spree api
    调用时,会通过开发环境栈签发一个 只读 key,并将其保存到
    .spree/credentials.json
    (已加入 gitignore)。直接运行命令即可。
  4. 默认 profile(首次通过
    spree auth login
    创建的 profile 会成为默认项;key 通过交互式提示读取,绝不会作为参数传入):
    bash
    spree auth login --profile prod --base-url https://store.example.com
    spree api get /orders --profile prod    # or omit --profile once it's the default
确认最终解析出的配置以及服务器是否可访问:
bash
spree api status

Minting a key with the scopes you need

按需签发具有所需 scopes 的 key

Auto-minted project keys are
read_all
only. For writes, create a scoped secret key (in a project):
bash
spree api-key create --type secret --scopes read_orders,write_products
Scopes follow
read_<resource>
/
write_<resource>
(
write_*
implies
read_*
);
read_all
/
write_all
are the catch-alls.
spree api endpoints
shows the scope each endpoint needs.
自动签发的项目 key 仅有
read_all
。如需写入,请在项目中创建一个限定 scopes 的 secret key:
bash
spree api-key create --type secret --scopes read_orders,write_products
Scopes 遵循
read_<resource>
/
write_<resource>
格式(
write_*
隐含
read_*
);
read_all
/
write_all
是通用兜底项。
spree api endpoints
会显示每个端点所需的 scope。

Core usage

核心用法

bash
undefined
bash
undefined

Read — Ransack filters as repeatable -q, plus sort/page/limit/expand/fields

Read — Ransack filters as repeatable -q, plus sort/page/limit/expand/fields

spree api get /products -q status_eq=active -q name_cont=shirt --sort -created_at --limit 10 spree api get /orders/or_x8k2J9aQ --expand items,payments,fulfillments spree api get /products --fields name,slug,status # id is always returned
spree api get /products -q status_eq=active -q name_cont=shirt --sort -created_at --limit 10 spree api get /orders/or_x8k2J9aQ --expand items,payments,fulfillments spree api get /products --fields name,slug,status # id is always returned

Write — JSON body inline, from @file, or '-' for stdin

Write — JSON body inline, from @file, or '-' for stdin

spree api post /products -d '{"name":"Classic Tee","prices":[{"currency":"USD","amount":"29.99"}]}' spree api patch /orders/or_x8k2J9aQ/cancel spree api post /orders/or_x8k2J9aQ/refunds -d @refund.json cat prices.json | spree api post /prices/bulk_upsert -d - spree api delete /products/prod_86Rf07xd

- **Paths** take the Admin API path; the `/api/v3/admin` prefix is optional (paste a full path and it still works).
- **Output** is JSON: indented + colored in a terminal, compact + uncolored when piped (clean for `jq`). `--format table` renders collections for humans.
- Mutations carry an automatic `Idempotency-Key`, so retries are safe.
spree api post /products -d '{"name":"Classic Tee","prices":[{"currency":"USD","amount":"29.99"}]}' spree api patch /orders/or_x8k2J9aQ/cancel spree api post /orders/or_x8k2J9aQ/refunds -d @refund.json cat prices.json | spree api post /prices/bulk_upsert -d - spree api delete /products/prod_86Rf07xd

- **路径**使用 Admin API 路径;可省略 `/api/v3/admin` 前缀(粘贴完整路径也有效)。
- **输出**为 JSON:在终端中缩进并着色,在管道中则紧凑且不着色(便于交给 `jq` 处理)。`--format table` 会以适合人阅读的表格形式呈现集合。
- **变更操作**会自动携带 `Idempotency-Key`,因此重试是安全的。

Discovery (offline — no server needed)

离线发现(无需服务器)

The CLI bundles a snapshot of the Admin API OpenAPI spec:
bash
spree api endpoints --resource orders        # every orders endpoint + required scope
spree api endpoints --search "gift card"     # fuzzy search across method/path/summary
spree api schema "POST /orders"              # full request/response schema for one op
Use
endpoints
/
schema
to find the right path and body shape before calling — this is how an agent should orient instead of guessing.
CLI 内置了 Admin API OpenAPI 规范的快照:
bash
spree api endpoints --resource orders        # every orders endpoint + required scope
spree api endpoints --search "gift card"     # fuzzy search across method/path/summary
spree api schema "POST /orders"              # full request/response schema for one op
使用
endpoints
/
schema
在调用前查找正确的路径和请求体结构——Agent 应先据此定位接口,而不是靠猜测。

Shell completion

Shell 补全

bash
eval "$(spree completion zsh)"     # bash and fish also supported
Completes resource paths, Ransack predicate stems (
status_eq=
,
name_cont=
…), and scope names.
bash
eval "$(spree completion zsh)"     # bash and fish also supported
可补全资源路径、Ransack 谓词词干(
status_eq=
、
name_cont=
等)和 scope 名称。

Debugging workflow (the high-value path for agents)

调试工作流(Agent 最有价值的路径)

When a request or app behavior is wrong, the CLI is the fastest probe. A typical loop:
bash
undefined
当请求或应用行为出现异常时,CLI 是最快的排查工具。典型流程如下:
bash
undefined

1. Reproduce the read and see the actual state

1. Reproduce the read and see the actual state

spree api get /orders/or_x8k2J9aQ --expand payments,fulfillments | jq '.status, .payment_status, .fulfillment_status'
spree api get /orders/or_x8k2J9aQ --expand payments,fulfillments | jq '.status, .payment_status, .fulfillment_status'

2. If a write failed, find the endpoint's contract

2. If a write failed, find the endpoint's contract

spree api schema "PATCH /orders/{id}/cancel"
spree api schema "PATCH /orders/{id}/cancel"

3. Re-run the write and read the error envelope verbatim

3. Re-run the write and read the error envelope verbatim

spree api patch /orders/or_x8k2J9aQ/cancel
undefined
spree api patch /orders/or_x8k2J9aQ/cancel
undefined

Reading errors

读取错误

Errors print the Stripe-style envelope to stderr and set the exit code:
  • 0
    success ·
    1
    API error (4xx/5xx — the
    {error: {code, message, details}}
    envelope) ·
    2
    usage/config error (bad flag, no credentials, unreachable host).
A scope denial (
403
,
code: access_denied
) prints
details.required_scope
and the exact remediation — mint a key with that scope and pass it via
--api-key
or
SPREE_API_KEY
:
text
access_denied: API key lacks scope: write_products
{ "details": { "required_scope": "write_products" } }
Hint: this key lacks `write_products`. Create one that has it and use it:
  spree api-key create --type secret --scopes write_products
  then pass it via --api-key <sk_...> or export SPREE_API_KEY=<sk_...>
A validation error (
422
,
code: validation_error
) puts per-attribute messages in
details
— read them to see which fields the body got wrong, then check
spree api schema
for the correct shape.
spree api status
diagnoses the credential/reachability layer when calls fail before reaching the API at all (wrong host, expired/typo'd key).
错误会以 Stripe 风格封装输出到 stderr,并设置退出码:
  • 0
    成功 ·
    1
    API 错误(4xx/5xx——采用
    {error: {code, message, details}}
    封装)·
    2
    用法/配置错误(错误的参数、缺少凭据、无法连接 host)。
出现 scope 拒绝(
403
,
code: access_denied
)时,会打印
details.required_scope
和准确的修复建议——签发一个具有该 scope 的 key,并通过
--api-key
或
SPREE_API_KEY
传入:
text
access_denied: API key lacks scope: write_products
{ "details": { "required_scope": "write_products" } }
Hint: this key lacks `write_products`. Create one that has it and use it:
  spree api-key create --type secret --scopes write_products
  then pass it via --api-key <sk_...> or export SPREE_API_KEY=<sk_...>
出现 校验错误(
422
,
code: validation_error
)时,会按属性将消息放入
details
——读取这些消息即可找出请求体中哪些字段有误,然后通过
spree api schema
查看正确结构。
当调用在到达 API 之前就失败时(host 错误、key 过期或拼写错误),可通过
spree api status
诊断凭据与连通性层。

Beyond
spree api
: project commands for debugging

spree api
之外:用于调试的项目命令

In a scaffolded project (Docker dev stack), these commands run inside the web container. In a classic Rails app without Docker, use the native equivalents (
bin/rails console
,
bundle exec rspec
, …).
bash
spree console                           # Rails console: Spree::Cart.find_by_prefix_id!('cart_…')
spree shell                             # interactive bash in the web container (alias: spree bash)
spree test spec/models/spree/brand_spec.rb:15   # RSpec with RAILS_ENV=test; args pass straight through
spree logs                              # web logs (spree logs worker for jobs)
spree db:console                        # psql against the dev database
spree add dashboard                     # scaffold apps/dashboard (or: spree add seller-dashboard)
spree plugin new brands                 # scaffold a dashboard plugin repo (the Rails engine half is a separate spree_extension gem)
spree encryption init [--print]         # add Active Record encryption keys to .env (never overwrites; --print only prints a set)
spree add mcp                           # add the Admin MCP server gem (spree_mcp) — see spree-mcp
spree add paypal                        # add spree_paypal_checkout at the project's Spree version (6.0.3+)
spree task openapi:generate             # write server/openapi/admin.yaml from the app's rswag specs — see spree-resource
spree filters types                     # TypeScript typings for your app's custom list filters, into each app under apps/
在通过脚手架创建的项目中(Docker 开发环境栈),这些命令会在 web 容器内运行。在不使用 Docker 的传统 Rails 应用中,请使用对应的原生命令(
bin/rails console
、
bundle exec rspec
等)。
bash
spree console                           # Rails console: Spree::Cart.find_by_prefix_id!('cart_…')
spree shell                             # interactive bash in the web container (alias: spree bash)
spree test spec/models/spree/brand_spec.rb:15   # RSpec with RAILS_ENV=test; args pass straight through
spree logs                              # web logs (spree logs worker for jobs)
spree db:console                        # psql against the dev database
spree add dashboard                     # scaffold apps/dashboard (or: spree add seller-dashboard)
spree plugin new brands                 # scaffold a dashboard plugin repo (the Rails engine half is a separate spree_extension gem)
spree encryption init [--print]         # add Active Record encryption keys to .env (never overwrites; --print only prints a set)
spree add mcp                           # add the Admin MCP server gem (spree_mcp) — see spree-mcp
spree add paypal                        # add spree_paypal_checkout at the project's Spree version (6.0.3+)
spree task openapi:generate             # write server/openapi/admin.yaml from the app's rswag specs — see spree-resource
spree filters types                     # TypeScript typings for your app's custom list filters, into each app under apps/

spree sdk generate
(extension packages)

spree sdk generate
(扩展包)

Run it in an npm package that ships a typed client for an extension's endpoints, with
"spree": { "extension": "../my_extension" }
in its
package.json
. It doesn't need the dev stack; it runs the gem's own
rake spree:openapi:generate spree:sdk:serializer_types
, then writes
src/generated/<api>/
(
client.ts
,
params/
,
filters.ts
,
types/
,
spree.ts
).
bash
spree sdk generate               # regenerate after an endpoint or serializer change
spree sdk generate --no-backend  # from the committed openapi/*.yaml only
spree sdk generate --check       # CI: fail when generated files are stale
See
spree-typescript-sdk
§ Generating an extension's client.
spree shell
and
spree test
still work when the web container is crash-looping: they fall back to a one-off
compose run
.
在一个提供扩展端点类型化客户端的 npm 包中运行它,并确保
package.json
中包含
"spree": { "extension": "../my_extension" }
。它不需要开发环境栈;会运行该 gem 自身的
rake spree:openapi:generate spree:sdk:serializer_types
,然后写入
src/generated/<api>/
(
client.ts
、
params/
、
filters.ts
、
types/
、
spree.ts
)。
bash
spree sdk generate               # regenerate after an endpoint or serializer change
spree sdk generate --no-backend  # from the committed openapi/*.yaml only
spree sdk generate --check       # CI: fail when generated files are stale
参见
spree-typescript-sdk
中“生成扩展客户端”的章节。
即使 web 容器不断崩溃,
spree shell
和
spree test
仍可使用:它们会回退为一次性的
compose run
。

What
spree api
can't see

spree api
无法查看的内容

  • Shopper carts. The Admin API exposes orders (
    /orders
    ,
    /order_groups
    ) but not in-progress carts. Inspect those in
    spree console
    or through the Store API with the cart token.
  • Store/Seller API responses. Use
    curl
    with a
    pk_
    key (Store) or the seller SDK.
  • 买家购物车。 Admin API 提供订单(
    /orders
    、
    /order_groups
    )访问,但不提供进行中的购物车。请在
    spree console
    中检查购物车,或通过 Store API 并使用 cart token 进行检查。
  • Store/Seller API 响应。 请使用带有
    pk_
    key 的
    curl
    (Store),或使用 seller SDK。

spree api
vs the Admin MCP server

spree api
与 Admin MCP 服务器

spree api
uses a secret key and suits scripts and debugging. The Admin MCP server (
/api/v3/admin/mcp
) is for an AI client acting for a signed-in person through OAuth, and it refuses
sk_
keys. See
spree-mcp
.
spree api
使用 secret key,适合脚本和调试。Admin MCP 服务器(
/api/v3/admin/mcp
)面向通过 OAuth 代表已登录用户操作的 AI 客户端,并拒绝使用
sk_
key。参见
spree-mcp
。

Gotchas

常见陷阱

  • The bundled spec for
    endpoints
    /
    schema
    reflects the CLI's Spree version, not necessarily the live server's —
    spree api status
    shows the bundled version. If an endpoint is missing from
    endpoints
    but exists on the server, the CLI may be older.
  • --api-key
    on the command line leaks into shell history — prefer
    SPREE_API_KEY
    or a profile.
  • Auto-minted project keys are read-only by design; a write returning 403 in a fresh project means you need an explicit scoped key, not a bug.
  • Secret-key scopes can't be edited after creation. For different access, mint a new key and revoke the old one (
    spree api-key revoke <id>
    ).
  • Multi-store host? Pass
    --store-id <store_…>
    (sent as
    X-Spree-Store-Id
    ).
  • The CLI talks to a running server; it can't bootstrap one. Inside a project, ensure the dev stack is up (
    spree dev
    ).
  • endpoints
    /
    schema
    使用的内置规范反映的是 CLI 自身的 Spree 版本,不一定与在线服务器一致——
    spree api status
    会显示内置版本。如果某个端点未出现在
    endpoints
    中,但服务器上实际存在,则 CLI 版本可能较旧。
  • 在命令行中使用
    --api-key
    会将密钥泄漏到 shell 历史记录中——应优先使用
    SPREE_API_KEY
    或 profile。
  • 自动签发的项目 key 按设计即为只读。在全新项目中,写入操作返回 403 意味着需要显式创建带限定 scopes 的 key,而不是程序存在缺陷。
  • secret key 的 scopes 创建后无法修改。若需要不同的访问权限,请签发新 key,并撤销旧 key(
    spree api-key revoke <id>
    )。
  • 遇到多商店 host 时,请传入
    --store-id <store_…>
    (将作为
    X-Spree-Store-Id
    发送)。
  • CLI 会与正在运行的服务器通信,无法自行启动服务器。在项目中,请确保开发环境栈已启动(
    spree dev
    )。