关于 emdash-cli
emdash-cli 是用于管理 EmDash CMS 项目和实例的命令行技能,涵盖本地设置与远程内容操作,并支持脚本和 Agent 工作流所需的机器可读输出。
主要功能
- 01本地设置、迁移与种子数据
- 02远程内容和架构操作
- 03媒体、搜索、分类与菜单
- 04身份验证和自定义请求头
- 05站点导出与导入
- 06面向脚本的 JSON 输出
适用场景
- 01设置或诊断 CMS 项目
- 02通过命令行编辑并发布内容
- 03在脚本中自动化 CMS 任务
- 04在实例间迁移站点数据
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ emdash-cms/ emdash --skill emdash-cli安装后在 Claude Code 中输入/emdash-cli确认已加载。
附带文件EDITING-FLOW.md
详细介绍
EmDash CLI
EmDash CLI(emdash,短别名为 em)用于管理 EmDash CMS 实例。命令分为两类:
- 本地命令适用于项目文件或已配置的数据库:
init、doctor、seed、migrate、export-seed和secrets。 - 远程命令用于与运行中的 EmDash 实例通信:
types、login、logout、whoami、content、schema、media、search、taxonomy、menu和site。
运行 npx emdash --help 和 npx emdash <command> --help,查看已安装版本的准确命令和标志。执行破坏性或批量修改前,先用读取命令确认当前目标;本技能中的示例不代表授权你更改用户未指定范围内的实例。
身份验证
远程命令会自动解析身份验证信息:
--token标志EMDASH_TOKEN环境变量- 通过
emdash login保存的凭据 - 开发绕过(仅限 localhost——无需令牌)
对于启用了开发绕过的 localhost 开发服务器,客户端可以自动进行身份验证。对于远程实例,请运行 emdash login --url https://example.com,或提供范围受限的令牌。
自定义标头与反向代理
位于 Cloudflare Access 或其他反向代理之后的站点需要在每个请求中携带身份验证标头。CLI 支持通过 --header 标志和环境变量配置这些标头。
自动化的服务令牌
# Provide sensitive headers through the environment in CI.
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 浏览器身份验证流程
如果没有服务令牌,且已安装 cloudflared,CLI 将自动:
- 检测 Access 是否拦截了请求
- 尝试通过
cloudflared access token获取缓存的 JWT - 如果失败,则通过
cloudflared access login使用浏览器进行身份验证
此方式适用于交互式使用,但不适用于 CI。自动化场景请使用服务令牌。
通用反向代理身份验证
--header 标志适用于任何身份验证方案:
# Basic auth
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"
快速参考
数据库设置
对于常规站点启动,请使用项目的 package 脚本。首次请求会运行待处理的迁移;在设置完成之前,还会应用捆绑的种子数据中的架构和结构(仅一次)。示例内容来自设置向导、/_emdash/api/setup/dev-bypass 或 emdash seed。Astro 集成会在服务器启动时生成 emdash-env.d.ts。
# Start the site with its package script
pnpm dev
# Export an existing database as a seed file
# (the runtime auto-discovers .emdash/seed.json on first boot;
# `mkdir -p` because the directory may not exist yet)
mkdir -p .emdash
npx emdash export-seed > .emdash/seed.json
npx emdash export-seed --with-content=all > .emdash/seed.json
类型生成
# Generate types from local dev server
npx emdash types
# Generate from remote
npx emdash types --url https://example.com
# Custom output path
npx emdash types --output src/types/cms.ts
会写入 .emdash/types.ts(TypeScript 接口)和 .emdash/schema.json。
身份验证
# Login (OAuth Device Flow)
npx emdash login --url https://example.com
# Check current user
npx emdash whoami
# Logout
npx emdash logout
# Generate an encryption key for deployment
npx emdash secrets generate
内容 CRUD
此 CLI 专为 Agent 设计。创建和更新操作默认会自动发布,让 Agent 无需管理草稿即可在写入后读取到一致的数据。
# List content
npx emdash content list posts
npx emdash content list posts --status published --limit 10
# Get a single item (Portable Text fields converted to 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
# 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
# Update (requires --rev from a prior get, auto-publishes by default)
npx emdash content update posts 01ABC123 --rev MToyMDI2... --data '{"title": "Updated"}'
npx emdash content update posts 01ABC123 --rev MToyMDI2... --draft --data '...' # keep as draft
# Delete (soft delete)
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
架构管理
# List collections
npx emdash schema list
# Get collection with fields
npx emdash schema get posts
# Create collection
npx emdash schema create articles --label Articles --description "Blog articles"
# Delete a collection after inspecting it and confirming the target
npx emdash schema get articles
npx emdash schema delete articles
# Add field
npx emdash schema add-field posts body --type portableText --label "Body Content"
npx emdash schema add-field posts featured --type boolean --required
# Remove field
npx emdash schema remove-field posts featured
schema add-field 支持的字段类型可通过 npx emdash schema add-field --help 查看。完整的产品架构还支持其他字段类型,但这些类型不一定能通过此命令创建。
媒体
# List media
npx emdash media list
npx emdash media list --mime image/png
# Upload
npx emdash media upload ./photo.jpg --alt "A sunset" --caption "Bristol, 2026"
# Get / delete
npx emdash media get 01MEDIA123
npx emdash media delete 01MEDIA123
搜索
npx emdash search "hello world"
npx emdash search "hello" --collection posts --limit 5
分类法
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 01PARENT123
菜单
npx emdash menu list
npx emdash menu get primary
站点导出和导入
emdash site 会将整个站点(内容模型、内容、历史记录、设置和媒体,但不包括用户或密钥)复制到 .emdash 站点包中,并将站点包导入空站点。令牌需要具有 admin 权限(emdash login 生成的令牌具备此权限),或具有 transfer:export、transfer:analyze 和 transfer:execute 作用域。INSUFFICIENT_SCOPE 错误表示令牌不具备这两者中的任何一项。站点包包含每一条目以及作者和评论者的电子邮件地址:请将其视为数据库备份。
# Export (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
# Import, step 1: upload and analyze; prints the plan and its digest
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 [email protected][email protected] --use-target-title
# Import, step 2: execute exactly the reviewed plan
npx emdash site import site.emdash --url https://new.example.com --plan sha256:<hex> --confirm
# Follow up on an import by 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
# Stop an import, or lift the write block a failed or cancelled import leaves
# (neither deletes what the import wrote; --yes skips the prompt)
npx emdash site import cancel <operation-id> --url https://new.example.com
npx emdash site import abandon <operation-id> --url https://new.example.com
运行 --confirm 前,向用户展示计划(与源站点的差异、警告、阻止项、主体映射),并征得他们确认;此操作会写入目标站点,并在完成前阻止对该站点的其他写入。若计划存在阻止项,site import 会以 2 退出;对于失败、取消、放弃或过期的导入,site import status 会以 1 退出。只有在用户提出要求时,才取消或放弃导入:放弃会使站点留下部分数据,必须先重置站点,才能再次导入。--map-principal 接受 <principal id or email>=<user id, email, or none>,且可重复使用;决策标志仅在使用 --analyze 时有效,每次变更都会生成新的计划摘要。导入期间公开站点不会隐藏,因此目标站点应保持私有,直到命令输出包含 receiptDigestValid: true 的回执。
草稿与发布
默认情况下,CLI 会在 create 和 update 后自动发布。这意味着:
create会创建条目并立即发布update会更新条目,并在创建草稿修订时发布get会在存在待处理草稿时返回草稿数据(例如来自管理界面)
在 create/update 中使用 --draft 可跳过自动发布。在 get 中使用 --published 可忽略待处理草稿。
支持修订的集合会将编辑内容存储为草稿修订。CLI 会透明地处理这些内容——Agent 无需了解集合是否使用修订。
JSON 输出
所有远程命令都支持 --json,用于生成机器可读的输出。stdout 通过管道传输时会自动启用此选项。emdash site 始终将进度信息写入 stderr,因此 stdout 中只包含 JSON 结果;错误格式为 { "error": { "code", "message" } }。
# Pipe to jq
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')
编辑流程
有关内容编辑工作方式的详情——Portable Text/markdown 转换、_rev 令牌和原始模式——请参阅 EDITING-FLOW.md。