emdash-cli
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseEmDash CLI
EmDash CLI
The EmDash CLI (, with the short alias ) manages EmDash CMS instances. Commands fall into two categories:
emdashem- Local commands work with project files or a configured database: ,
init,doctor,seed,migrate, andexport-seed.secrets - Remote commands talk to a running EmDash instance: ,
types,login,logout,whoami,content,schema,media,search,taxonomy, andmenu.site
Run and for the installed version's exact commands and flags. Resolve the current target with a read command before a destructive or bulk mutation; examples in this skill do not authorize changing an instance the user did not place in scope.
npx emdash --helpnpx emdash <command> --helpEmDash CLI(,短别名为 )用于管理 EmDash CMS 实例。命令分为两类:
emdashem- 本地命令用于处理项目文件或已配置的数据库:、
init、doctor、seed、migrate和export-seed。secrets - 远程命令用于与正在运行的 EmDash 实例通信:、
types、login、logout、whoami、content、schema、media、search、taxonomy和menu。site
要查看已安装版本的确切命令和标志,请运行 和 。在执行破坏性或批量修改之前,先使用只读命令确定当前目标;本 skill 中的示例并不授权更改用户未指定范围的实例。
npx emdash --helpnpx emdash <command> --helpAuthentication
身份验证
Remote commands resolve auth automatically:
- flag
--token - env var
EMDASH_TOKEN - Stored credentials from
emdash login - Dev bypass (localhost only — no token needed)
For a localhost development server with the development bypass enabled, the client can authenticate automatically. For a remote instance, run or provide a scoped token.
emdash login --url https://example.com远程命令会自动按以下顺序解析身份验证信息:
- 标志
--token - 环境变量
EMDASH_TOKEN - 保存的凭据
emdash login - 开发绕过(dev bypass,仅限 localhost——无需 token)
对于启用了 dev bypass 的 localhost 开发服务器,客户端可以自动完成身份验证。对于远程实例,请运行 或提供具有限定作用域的 token。
emdash login --url https://example.comCustom Headers & Reverse Proxies
自定义请求头与反向代理
Sites behind Cloudflare Access or other reverse proxies need auth headers on every request. The CLI supports this via flags and environment variables.
--header部署在 Cloudflare Access 或其他反向代理之后的站点,需要在每个请求中携带身份验证请求头。CLI 支持通过 标志和环境变量进行配置。
--headerService tokens for automation
用于自动化的服务令牌
bash
undefinedbash
undefinedProvide sensitive headers through the environment in CI.
在 CI 中通过环境变量提供敏感请求头。
export EMDASH_HEADERS="CF-Access-Client-Id: xxx
CF-Access-Client-Secret: yyy"
npx emdash whoami --url https://example.com
`emdash login --header` persists custom headers to `~/.config/emdash/auth.json` for later commands. Prefer environment-provided headers in CI so a service secret is not written to the credential file or shell history.export EMDASH_HEADERS="CF-Access-Client-Id: xxx
CF-Access-Client-Secret: yyy"
npx emdash whoami --url https://example.com
`emdash login --header` 会将自定义请求头持久化到 `~/.config/emdash/auth.json`,供后续命令使用。在 CI 中应优先通过环境变量提供请求头,以免将服务密钥写入凭据文件或 shell 历史记录。Cloudflare Access Browser Flow
Cloudflare Access 浏览器流程
If you don't have service tokens and is installed, the CLI will automatically:
cloudflared- Detect when Access blocks the request
- Try to get a cached JWT via
cloudflared access token - Fall back to for browser-based auth
cloudflared access login
This works for interactive use but isn't suitable for CI. Use service tokens for automation.
如果没有服务令牌,但已安装 ,CLI 将自动执行以下操作:
cloudflared- 检测 Access 阻止请求的情况
- 尝试通过 获取缓存的 JWT
cloudflared access token - 回退到 以执行基于浏览器的身份验证
cloudflared access login
此方式适用于交互式使用,但不适合 CI。自动化操作应使用服务令牌。
Generic Reverse Proxy Auth
通用反向代理身份验证
The flag works with any auth scheme:
--headerbash
undefined--headerbash
undefinedBasic auth
基础身份验证
npx emdash login --url https://example.com -H "Authorization: Basic dXNlcjpwYXNz"
npx emdash login --url https://example.com -H "Authorization: Basic dXNlcjpwYXNz"
Custom auth header
自定义身份验证请求头
npx emdash login --url https://example.com -H "X-API-Key: secret123"
undefinednpx emdash login --url https://example.com -H "X-API-Key: secret123"
undefinedQuick Reference
快速参考
Database Setup
数据库设置
For normal site startup, use the project's package script. The first request runs pending migrations and, before setup is completed, applies the bundled seed's schema and structure once; sample content comes from the setup wizard, , or . The Astro integration generates when the server starts.
/_emdash/api/setup/dev-bypassemdash seedemdash-env.d.tsbash
undefined正常启动站点时,请使用项目的 package script。首次请求会执行待处理的 migration;在 setup 完成前,还会一次性应用 bundled seed 的 schema 和结构。示例内容来自 setup wizard、 或 。服务器启动时,Astro integration 会生成 。
/_emdash/api/setup/dev-bypassemdash seedemdash-env.d.tsbash
undefinedStart the site with its package script
使用项目的 package script 启动站点
pnpm dev
pnpm dev
Export an existing database as a seed file
将现有数据库导出为 seed 文件
(the runtime auto-discovers .emdash/seed.json on first boot;
(运行时会在首次启动时自动发现 .emdash/seed.json;
mkdir -p
because the directory may not exist yet)
mkdir -p使用 mkdir -p,因为该目录可能尚不存在)
mkdir -p .emdash
npx emdash export-seed > .emdash/seed.json
npx emdash export-seed --with-content=all > .emdash/seed.json
undefinedmkdir -p .emdash
npx emdash export-seed > .emdash/seed.json
npx emdash export-seed --with-content=all > .emdash/seed.json
undefinedType Generation
类型生成
bash
undefinedbash
undefinedGenerate types from local dev server
从本地开发服务器生成类型
npx emdash types
npx emdash types
Generate from remote
从远程实例生成类型
npx emdash types --url https://example.com
npx emdash types --url https://example.com
Custom output path
自定义输出路径
npx emdash types --output src/types/cms.ts
Writes `.emdash/types.ts` (TypeScript interfaces) and `.emdash/schema.json`.npx emdash types --output src/types/cms.ts
将类型写入 `.emdash/types.ts`(TypeScript interfaces)和 `.emdash/schema.json`。Authentication
身份验证
bash
undefinedbash
undefinedLogin (OAuth Device Flow)
登录(OAuth Device Flow)
npx emdash login --url https://example.com
npx emdash login --url https://example.com
Check current user
查看当前用户
npx emdash whoami
npx emdash whoami
Logout
退出登录
npx emdash logout
npx emdash logout
Generate an encryption key for deployment
为部署生成加密密钥
npx emdash secrets generate
undefinednpx emdash secrets generate
undefinedContent CRUD
内容 CRUD
The CLI is designed for agents. Create and update auto-publish by default so agents get read-after-write consistency without managing drafts.
bash
undefined该 CLI 专为 agents 设计。create 和 update 默认会自动发布,让 agents 无需管理草稿即可获得写后读一致性。
bash
undefinedList content
列出内容
npx emdash content list posts
npx emdash content list posts --status published --limit 10
npx emdash content list posts
npx emdash content list posts --status published --limit 10
Get a single item (Portable Text fields converted to markdown)
获取单个条目(Portable Text 字段会转换为 markdown)
Returns draft data if a pending draft exists
如果存在待处理草稿,则返回草稿数据
npx emdash content get posts 01ABC123
npx emdash content get posts 01ABC123 --raw # skip PT->markdown conversion
npx emdash content get posts 01ABC123 --published # ignore pending drafts
npx emdash content get posts 01ABC123
npx emdash content get posts 01ABC123 --raw # 跳过 PT->markdown 转换
npx emdash content get posts 01ABC123 --published # 忽略待处理草稿
Create content (auto-publishes by default)
创建内容(默认自动发布)
npx emdash content create posts --data '{"title": "Hello", "body": "# World"}'
npx emdash content create posts --file post.json --slug hello-world
npx emdash content create posts --draft --data '...' # keep as draft
cat post.json | npx emdash content create posts --stdin
npx emdash content create posts --data '{"title": "Hello", "body": "# World"}'
npx emdash content create posts --file post.json --slug hello-world
npx emdash content create posts --draft --data '...' # 保留为草稿
cat post.json | npx emdash content create posts --stdin
Update (requires --rev from a prior get, auto-publishes by default)
更新(需要使用先前 get 获得的 --rev,默认自动发布)
npx emdash content update posts 01ABC123 --rev MToyMDI2... --data '{"title": "Updated"}'
npx emdash content update posts 01ABC123 --rev MToyMDI2... --draft --data '...' # keep as draft
npx emdash content update posts 01ABC123 --rev MToyMDI2... --data '{"title": "Updated"}'
npx emdash content update posts 01ABC123 --rev MToyMDI2... --draft --data '...' # 保留为草稿
Delete (soft delete)
删除(软删除)
npx emdash content delete posts 01ABC123
npx emdash content delete posts 01ABC123
Lifecycle
生命周期
npx emdash content publish posts 01ABC123
npx emdash content unpublish posts 01ABC123
npx emdash content schedule posts 01ABC123 --at 2026-03-01T09:00:00Z
npx emdash content restore posts 01ABC123
undefinednpx emdash content publish posts 01ABC123
npx emdash content unpublish posts 01ABC123
npx emdash content schedule posts 01ABC123 --at 2026-03-01T09:00:00Z
npx emdash content restore posts 01ABC123
undefinedSchema Management
Schema 管理
bash
undefinedbash
undefinedList collections
列出 collection
npx emdash schema list
npx emdash schema list
Get collection with fields
获取 collection 及其 fields
npx emdash schema get posts
npx emdash schema get posts
Create collection
创建 collection
npx emdash schema create articles --label Articles --description "Blog articles"
npx emdash schema create articles --label Articles --description "Blog articles"
Delete a collection after inspecting it and confirming the target
删除 collection 前先检查并确认目标
npx emdash schema get articles
npx emdash schema delete articles
npx emdash schema get articles
npx emdash schema delete articles
Add field
添加 field
npx emdash schema add-field posts body --type portableText --label "Body Content"
npx emdash schema add-field posts featured --type boolean --required
npx emdash schema add-field posts body --type portableText --label "Body Content"
npx emdash schema add-field posts featured --type boolean --required
Remove field
移除 field
npx emdash schema remove-field posts featured
`schema add-field` supports the field types printed by `npx emdash schema add-field --help`. The full product schema supports additional field types that are not necessarily creatable through this command.npx emdash schema remove-field posts featured
`schema add-field` 支持 `npx emdash schema add-field --help` 输出的 field 类型。完整产品 schema 还支持其他 field 类型,但这些类型不一定能通过此命令创建。Media
Media
bash
undefinedbash
undefinedList media
列出 media
npx emdash media list
npx emdash media list --mime image/png
npx emdash media list
npx emdash media list --mime image/png
Upload
上传
npx emdash media upload ./photo.jpg --alt "A sunset" --caption "Bristol, 2026"
npx emdash media upload ./photo.jpg --alt "A sunset" --caption "Bristol, 2026"
Get / delete
获取/删除
npx emdash media get 01MEDIA123
npx emdash media delete 01MEDIA123
undefinednpx emdash media get 01MEDIA123
npx emdash media delete 01MEDIA123
undefinedSearch
搜索
bash
npx emdash search "hello world"
npx emdash search "hello" --collection posts --limit 5bash
npx emdash search "hello world"
npx emdash search "hello" --collection posts --limit 5Taxonomies
Taxonomy
bash
npx emdash taxonomy list
npx emdash taxonomy terms categories
npx emdash taxonomy add-term categories --name "Tech" --slug tech
npx emdash taxonomy add-term categories --name "Frontend" --parent 01PARENT123bash
npx emdash taxonomy list
npx emdash taxonomy terms categories
npx emdash taxonomy add-term categories --name "Tech" --slug tech
npx emdash taxonomy add-term categories --name "Frontend" --parent 01PARENT123Menus
Menu
bash
npx emdash menu list
npx emdash menu get primarybash
npx emdash menu list
npx emdash menu get primarySite Export and Import
站点导出与导入
emdash site.emdashadminemdash logintransfer:exporttransfer:analyzetransfer:executeINSUFFICIENT_SCOPEbash
undefinedemdash site.emdashadminemdash logintransfer:exporttransfer:analyzetransfer:executeINSUFFICIENT_SCOPEbash
undefinedExport (re-run the same command to resume after an interruption)
导出(中断后可重新运行同一命令以继续)
npx emdash site export --url https://old.example.com --output site.emdash
npx emdash site export --url https://old.example.com --output site.emdash --no-comments
npx emdash site export --url https://old.example.com --output site.emdash
npx emdash site export --url https://old.example.com --output site.emdash --no-comments
Import, step 1: upload and analyze; prints the plan and its digest
导入第 1 步:上传并分析;打印计划和摘要
npx emdash site import site.emdash --url https://new.example.com --analyze
npx emdash site import site.emdash --url https://new.example.com --analyze
--map-principal editor@example.com=editor@example.com --use-target-title
--map-principal editor@example.com=editor@example.com --use-target-title
npx emdash site import site.emdash --url https://new.example.com --analyze
npx emdash site import site.emdash --url https://new.example.com --analyze
--map-principal editor@example.com=editor@example.com --use-target-title
--map-principal editor@example.com=editor@example.com --use-target-title
Import, step 2: execute exactly the reviewed plan
导入第 2 步:严格执行已审阅的计划
npx emdash site import site.emdash --url https://new.example.com --plan sha256:<hex> --confirm
npx emdash site import site.emdash --url https://new.example.com --plan sha256:<hex> --confirm
Follow up on an import by operation id
通过 operation ID 跟踪导入
npx emdash site import status <operation-id> --url https://new.example.com
npx emdash site import resume <operation-id> [site.emdash] --url https://new.example.com
npx emdash site import receipt <operation-id> --url https://new.example.com
npx emdash site import status <operation-id> --url https://new.example.com
npx emdash site import resume <operation-id> [site.emdash] --url https://new.example.com
npx emdash site import receipt <operation-id> --url https://new.example.com
Stop an import, or lift the write block a failed or cancelled import leaves
停止导入,或解除失败或已取消导入留下的写入锁定
(neither deletes what the import wrote; --yes skips the prompt)
(两者都不会删除导入已写入的数据;--yes 会跳过提示)
npx emdash site import cancel <operation-id> --url https://new.example.com
npx emdash site import abandon <operation-id> --url https://new.example.com
Show the user the plan (differences from the source site, warnings, blockers, principal mappings) and get their confirmation before running `--confirm`; it writes to the target site and blocks other writes there until it finishes. `site import` exits `2` when the plan has blockers, and `site import status` exits `1` for an import that failed, was cancelled or abandoned, or expired. Only cancel or abandon an import when the user asks: abandoning leaves partial data on the site, which then has to be reset before another import. `--map-principal` takes `<principal id or email>=<user id, email, or none>` and is repeatable; decision flags only work with `--analyze`, and each change produces a new plan digest. The public site is not hidden during an import, so the target should stay private until the command prints a receipt with `receiptDigestValid: true`.npx emdash site import cancel <operation-id> --url https://new.example.com
npx emdash site import abandon <operation-id> --url https://new.example.com
向用户展示计划(与源站点的差异、警告、阻塞项和 principal 映射),并在运行 `--confirm` 前获得用户确认。该命令会写入目标站点,并在完成前阻止该站点上的其他写入操作。当计划包含阻塞项时,`site import` 的退出码为 `2`;如果导入失败、被取消、被放弃或已过期,`site import status` 的退出码为 `1`。仅在用户要求时取消或放弃导入:放弃会在站点中留下部分数据,之后必须重置才能再次导入。`--map-principal` 接受 `<principal id or email>=<user id, email, or none>` 格式且可以重复使用;决策标志仅在配合 `--analyze` 时有效,每次更改都会生成新的计划摘要。导入期间不会隐藏公开站点,因此目标站点应保持私有,直到命令打印包含 `receiptDigestValid: true` 的 receipt。Drafts and Publishing
草稿与发布
The CLI auto-publishes on and by default. This means:
createupdate- creates the item and immediately publishes it
create - updates the item and publishes if a draft revision was created
update - returns draft data if a pending draft exists (e.g. from the admin UI)
get
Use on create/update to skip auto-publishing. Use on get to ignore pending drafts.
--draft--publishedCollections that support revisions store edits as draft revisions. The CLI handles this transparently — agents don't need to know whether a collection uses revisions or not.
CLI 默认在 create 和 update 时自动发布。这意味着:
- 创建条目后立即发布
create - 更新条目;如果创建了草稿 revision,则会将其发布
update - 如果存在待处理草稿(例如来自 admin UI),则返回草稿数据
get
在 create/update 时使用 可跳过自动发布。在 get 时使用 可忽略待处理草稿。
--draft--published支持 revisions 的 collection 会将编辑存储为草稿 revision。CLI 会透明地处理这些操作,agents 无需了解 collection 是否使用 revisions。
JSON Output
JSON 输出
All remote commands support for machine-readable output. It's auto-enabled when stdout is piped. always writes progress to stderr, so stdout holds only the JSON result; errors are .
--jsonemdash site{ "error": { "code", "message" } }bash
undefined所有远程命令都支持 ,用于输出机器可读的数据。当 stdout 被管道传输时,该选项会自动启用。 始终将进度写入 stderr,因此 stdout 仅保留 JSON 结果;错误格式为 。
--jsonemdash site{ "error": { "code", "message" } }bash
undefinedPipe to jq
管道传输至 jq
npx emdash content list posts --json | jq '.items[].slug'
npx emdash content list posts --json | jq '.items[].slug'
Use in scripts
在脚本中使用
ID=$(npx emdash content create posts --data '{"title":"Hello"}' --json | jq -r '.id')
undefinedID=$(npx emdash content create posts --data '{"title":"Hello"}' --json | jq -r '.id')
undefinedEditing Flow
编辑流程
For details on how content editing works — Portable Text/markdown conversion, tokens, and raw mode — see EDITING-FLOW.md.
_rev有关内容编辑工作原理的详细信息——Portable Text/markdown 转换、 token 和 raw mode——请参阅 EDITING-FLOW.md。
_rev