spree-cli
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSpree CLI — Admin API from the terminal
Spree CLI — 从终端调用 Admin API
@spree/clispree apigh apispree api/api/v3/admincurl@spree/clispree apigh apispree api/api/v3/admincurlWhen to reach for the CLI
何时使用 CLI
- Debugging — "what status is order in?", "why did this 403?", "does this product have the variant I expect?". One command, JSON back, pipe to
or_x.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 (see ). The CLI is for interactive work, scripts, and agents.
@spree/admin-sdkspree-typescript-sdk- 调试——“order 当前是什么状态?”“为什么会出现这个 403?”“这个产品是否有我预期的 variant?”只需一条命令,即可返回 JSON,并通过管道传给
or_x。jq - 探索 API——列出端点及其所需 scopes,转储某个操作的 schema;全部离线完成。
- 编写脚本 / Agent——确定性、可管道化,并提供退出码。无需实例化客户端。
如果要构建应用,请优先使用 (参见 )。CLI 适用于交互操作、脚本和 Agent。
@spree/admin-sdkspree-typescript-sdkSetup
设置
The CLI is (binary: ). Verify it's available:
@spree/clispreebash
spree --version # or: pnpm exec spree --versionIf not installed: (or run via / inside a project).
npm i -g @spree/clipnpm exec spreenpx @spree/cli该 CLI 为 (二进制文件:)。确认它是否可用:
@spree/clispreebash
spree --version # or: pnpm exec spree --version如果尚未安装:执行 (也可以在项目中通过 / 运行)。
npm i -g @spree/clipnpm exec spreenpx @spree/cliCredentials — pick the layer that fits
凭据——选择适合的配置层级
Credentials resolve in this order (first match wins); host and key always resolve together per source:
- Explicit flags — , or
--api-key sk_xxxto select a saved profile. Outrank everything below.--profile prod - Env — set ; the host defaults to
SPREE_API_KEY, so local dev needs only the key. Sethttp://localhost:3000for a remote store. Note an exportedSPREE_BASE_URLoutranks a local project's saved key:SPREE_API_KEYbashSPREE_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 - Inside a local Spree project (a dir with , Rails app in
docker-compose.yml, or legacyserver/, and the dev stack running): zero config. The firstbackend/call mints a read-only key via the dev stack and saves it tospree api(gitignored). Just run commands..spree/credentials.json - Default profile (the first profile you becomes the default; key read from a prompt, never a flag):
spree auth loginbashspree 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 始终按同一来源成对解析:
- 显式参数——,或使用
--api-key sk_xxx选择已保存的 profile。其优先级高于下列所有来源。--profile prod - 环境变量——设置 ;host 默认为
SPREE_API_KEY,因此本地开发只需设置 key。若连接远程商店,请设置http://localhost:3000。请注意,导出的SPREE_BASE_URL优先级高于本地项目中保存的 key:SPREE_API_KEYbashSPREE_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 - 在本地 Spree 项目中(目录中存在 、位于
docker-compose.yml的 Rails 应用或旧版server/,并且开发环境栈正在运行):零配置。首次执行backend/调用时,会通过开发环境栈签发一个 只读 key,并将其保存到spree api(已加入 gitignore)。直接运行命令即可。.spree/credentials.json - 默认 profile(首次通过 创建的 profile 会成为默认项;key 通过交互式提示读取,绝不会作为参数传入):
spree auth loginbashspree 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 statusMinting a key with the scopes you need
按需签发具有所需 scopes 的 key
Auto-minted project keys are only. For writes, create a scoped secret key (in a project):
read_allbash
spree api-key create --type secret --scopes read_orders,write_productsScopes follow / ( implies ); / are the catch-alls. shows the scope each endpoint needs.
read_<resource>write_<resource>write_*read_*read_allwrite_allspree api endpoints自动签发的项目 key 仅有 。如需写入,请在项目中创建一个限定 scopes 的 secret key:
read_allbash
spree api-key create --type secret --scopes read_orders,write_productsScopes 遵循 / 格式( 隐含 ); / 是通用兜底项。 会显示每个端点所需的 scope。
read_<resource>write_<resource>write_*read_*read_allwrite_allspree api endpointsCore usage
核心用法
bash
undefinedbash
undefinedRead — 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 opUse / to find the right path and body shape before calling — this is how an agent should orient instead of guessing.
endpointsschemaCLI 内置了 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使用 / 在调用前查找正确的路径和请求体结构——Agent 应先据此定位接口,而不是靠猜测。
endpointsschemaShell completion
Shell 补全
bash
eval "$(spree completion zsh)" # bash and fish also supportedCompletes resource paths, Ransack predicate stems (, …), and scope names.
status_eq=name_cont=bash
eval "$(spree completion zsh)" # bash and fish also supported可补全资源路径、Ransack 谓词词干(、 等)和 scope 名称。
status_eq=name_cont=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
undefined1. 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
undefinedspree api patch /orders/or_x8k2J9aQ/cancel
undefinedReading errors
读取错误
Errors print the Stripe-style envelope to stderr and set the exit code:
- success ·
0API error (4xx/5xx — the1envelope) ·{error: {code, message, details}}usage/config error (bad flag, no credentials, unreachable host).2
A scope denial (, ) prints and the exact remediation — mint a key with that scope and pass it via or :
403code: access_denieddetails.required_scope--api-keySPREE_API_KEYtext
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 (, ) puts per-attribute messages in — read them to see which fields the body got wrong, then check for the correct shape.
422code: validation_errordetailsspree api schemaspree api status错误会以 Stripe 风格封装输出到 stderr,并设置退出码:
- 成功 ·
0API 错误(4xx/5xx——采用1封装)·{error: {code, message, details}}用法/配置错误(错误的参数、缺少凭据、无法连接 host)。2
出现 scope 拒绝(,)时,会打印 和准确的修复建议——签发一个具有该 scope 的 key,并通过 或 传入:
403code: access_denieddetails.required_scope--api-keySPREE_API_KEYtext
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_...>出现 校验错误(,)时,会按属性将消息放入 ——读取这些消息即可找出请求体中哪些字段有误,然后通过 查看正确结构。
422code: validation_errordetailsspree api schema当调用在到达 API 之前就失败时(host 错误、key 过期或拼写错误),可通过 诊断凭据与连通性层。
spree api statusBeyond spree api
: project commands for debugging
spree apispree api
之外:用于调试的项目命令
spree apiIn 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 consolebundle exec rspecbash
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 consolebundle exec rspecbash
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 generatespree sdk generate
(扩展包)
spree sdk generateRun it in an npm package that ships a typed client for an extension's endpoints, with in its . It doesn't need the dev stack; it runs the gem's own , then writes (, , , , ).
"spree": { "extension": "../my_extension" }package.jsonrake spree:openapi:generate spree:sdk:serializer_typessrc/generated/<api>/client.tsparams/filters.tstypes/spree.tsbash
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 staleSee § Generating an extension's client.
spree-typescript-sdkspree shellspree testcompose run在一个提供扩展端点类型化客户端的 npm 包中运行它,并确保 中包含 。它不需要开发环境栈;会运行该 gem 自身的 ,然后写入 (、、、、)。
package.json"spree": { "extension": "../my_extension" }rake spree:openapi:generate spree:sdk:serializer_typessrc/generated/<api>/client.tsparams/filters.tstypes/spree.tsbash
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 shellspree testcompose runWhat spree api
can't see
spree apispree api
无法查看的内容
spree api- Shopper carts. The Admin API exposes orders (,
/orders) but not in-progress carts. Inspect those in/order_groupsor through the Store API with the cart token.spree console - Store/Seller API responses. Use with a
curlkey (Store) or the seller SDK.pk_
- 买家购物车。 Admin API 提供订单(、
/orders)访问,但不提供进行中的购物车。请在/order_groups中检查购物车,或通过 Store API 并使用 cart token 进行检查。spree console - Store/Seller API 响应。 请使用带有 key 的
pk_(Store),或使用 seller SDK。curl
spree api
vs the Admin MCP server
spree apispree api
与 Admin MCP 服务器
spree apispree api/api/v3/admin/mcpsk_spree-mcpspree api/api/v3/admin/mcpsk_spree-mcpGotchas
常见陷阱
- The bundled spec for /
endpointsreflects the CLI's Spree version, not necessarily the live server's —schemashows the bundled version. If an endpoint is missing fromspree api statusbut exists on the server, the CLI may be older.endpoints - on the command line leaks into shell history — prefer
--api-keyor a profile.SPREE_API_KEY - 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 (sent as
--store-id <store_…>).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使用的内置规范反映的是 CLI 自身的 Spree 版本,不一定与在线服务器一致——schema会显示内置版本。如果某个端点未出现在spree api status中,但服务器上实际存在,则 CLI 版本可能较旧。endpoints - 在命令行中使用 会将密钥泄漏到 shell 历史记录中——应优先使用
--api-key或 profile。SPREE_API_KEY - 自动签发的项目 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