@displaydev/cli

中文文档
0.52.0发布于 2026/11/13ES Module近 30 天下载 2381

CLI for display.dev — publish HTML and Markdown with public, company, private, or invited-person access.

原始使用文档
文档目录12 节
  1. Spaces files and folders
  2. Permanently delete items in Trash
  3. Install
  4. Authenticate
  5. Agent-native login
  6. Usage
  7. Copy defaults and destination
  8. Publish flags
  9. Testing
  10. MCP
  11. Inspecting an existing artifact
  12. Publishing this package

@displaydev/cli

CLI for display.dev — publish HTML and Markdown with public, company, private, or invited-person access.

Spaces files and folders

Create, read, update, and organize files and folders. Run dsp --help or a command group's --help for its options.

dsp space list
dsp space list-contents <spaceId>
dsp file create --parent-id <folderId> --preview
dsp file create <file> --parent-id <folderId> --content-type text/markdown --idempotency-key <requestKey>
dsp file get <fileId>
dsp file read <fileId>
dsp file search <fileId> <query>
dsp file edit <fileId> --old "old text" --new "new text" --base-revision <revisionId> --idempotency-key <requestKey>
dsp file export <fileId> --output <outputPath>
dsp file history <fileId>

Space and folder contents accept --sort name|modified|format|owner and --dir asc|desc. format sorts the displayed Type label, including labels for arbitrary file formats; --type remains a separate filter. Only Name keeps folders first, in either direction. Equal Type or Owner values follow Name in the selected direction, and missing owners stay last.

Space and folder child lists also support --sort createdBy for the displayed creator name. Use --dir asc or --dir desc. Equal creator names follow item Name in that direction. Unknown creators stay last. This option is not available in Home, Shared with me, the Space directory, or Trash.

Home (dsp file list --view home) and Shared with me (--view shared-with-me) also accept format and owner. dsp file list returns files only. Use dsp folder find --view home for Home folders, or --view shared-with-me for shared folders. Home shows folders before files under every sort. Shared with me mixes folders and files. The Space directory, Trash and fixed-order name search retain their existing sort choices. Pass each cursor back with the same query; if it is rejected after an item changes or becomes inaccessible, restart without a cursor.

Add --created-by <userId> to Space/folder contents or Home/Shared with me lists. Use --include-creators to return accessible creator choices across all matching pages before creator filtering, then select a returned userId. Created by is the original creating person, independently of Owner, Shared by, or later edits. Restart without a cursor when changing it. Space directory, Trash and fixed-order search do not accept these options.

dsp folder list <folderId> --include-creators
dsp folder list <folderId> --created-by <userId>
dsp file list --view home --created-by <userId>

Preview the destination and audience before creation. Omitted --parent-id selects My Space only for the commands that explicitly support it. Use the source's actual media type. A request key uses 16–128 letters, digits, periods, underscores, tildes, or hyphens. Keep the exact request key and source after an uncertain response. File updates retain the explicit base revision ID. Reconcile a stale revision rather than silently replacing the base.

Display retains Spaces request results for 24 hours. After that window, even the original request key can execute as a new operation. Read current state before retrying an older uncertain result. Reconcile that result before retrying. Do not rely on the request key alone to prevent a duplicate.

Spaces commands use file, folder, Space, and revision IDs. Copy each ID exactly. Do not pass those IDs to numbered compatibility selectors. Command groups include:

GroupTasks
dsp spaceBrowse Spaces, inspect current settings, create/manage direct membership, rename, delete/restore, and inspect or permanently delete items in Trash
dsp folderBrowse, create, rename, copy, move, find, inspect/change access, request access, and Trash/restore
dsp fileCreate/read/search/edit/replace/download, rename, copy, move, inspect history, Keep/delete eligible revisions, inspect/change access, and Trash/restore
dsp groupCreate groups, manage membership, and assign group administrators
dsp memberPreview Manager coverage and deactivate a member with explicit confirmation
dsp access-requestApprove or dismiss one stored request with current sharing authority
dsp comment / dsp threadNative discussions, replies, paging, editing, deletion, resolution, and reopening
dsp watch / dsp unwatchPersonal discussion subscriptions with --file <id>
dsp searchCross-file indexed search in Spaces. Legacy organizations retain name and exact-source modes.

Permanently delete items in Trash

Use dsp space list-trash <spaceId> to find the item IDs. Preview one explicit Space with dsp space delete-trash <spaceId> <itemId>… --preview. Use dsp space delete-trash <spaceId> --all --preview to review all eligible Trash in that Space. Review the selection, exclusions, and storage to free before confirming.

Repeat the same Space and selection with --confirm, --if-match <etag>, and --idempotency-key <requestKey>. Quote the argument so that the ETag's own double quotes reach the CLI. If the response is uncertain, keep the same Space, selection, ETag, and key. If the preview changed or a recovery hold blocked the request, get a fresh preview before trying again. My Space owners and Shared Space root Managers can use this operation with a person credential and the required scope.

JSON results for Spaces commands go to stdout. Diagnostics and continuation instructions go to stderr. file export streams exact bytes unless an output path is chosen. Overwriting a local output requires --overwrite. A failed command returns a nonzero exit code. The numbered-artifact exit-code table does not define every Spaces error. Keep cursors with their original query and filters.

A default personal key follows its owner's current Space access. Valid existing scoped personal keys also work in Spaces. They retain their scope limits and the Member publish cap, together with the owner's current Space access. Migration preserves the key and secret. OAuth keeps its approved scope limits.

Organization service keys need their own grants of access to eligible Shared Spaces. They do not inherit their creator's access. Organization roles alone grant no private content read. Do not switch identities, use compatibility commands, or widen an audience after denial.

Local MCP accepts local file paths. Hosted MCP accepts inline source or staged upload IDs. Hosted export_file returns a download descriptor, while local MCP can write an explicit output path. Upload and download credentials are secrets. Keep them out of shared logs and final replies. Public-link access alone does not authorize creating or editing files.

See Spaces and files and the CLI reference for task guidance.

Install

npm install -g @displaydev/cli

Authenticate

# Interactive login via email OTP
dsp login

# Or set an API key (from the dashboard)
export DISPLAYDEV_API_KEY=sk_live_...

Run dsp whoami to check which account and organization your credential uses. For scripts, dsp whoami --json prints user, organization, membership, and keyType. Organization keys return null for user and membership.

Agent-native login

An agent must not ask for, read, or relay a sign-in password or OTP. The user runs dsp login in their own terminal and completes the prompt or browser flow there. The agent then reuses the CLI's saved sign-in. It must not inspect the credential store, request tokens in chat, or start sign-in merely to bypass a permission denial. The invocation examples below document the CLI interface for a person or an explicitly controlled integration. They do not instruct an agent to collect OTPs.

The command adapts to its environment:

InvocationBehavior
dsp login --email [email protected] (TTY)Sends OTP, prompts for the code in the terminal.
dsp login --email [email protected] (non-TTY)Sends OTP and exits 0. The human completes verification in their own terminal.
dsp login --email [email protected] --code 123456Verifies the code, persists the token, exits.

For structured output that doesn't rely on prose parsing:

dsp login --email [email protected] --json
# → {"status":"otp_sent","email":"[email protected]",
#    "next":{"command":"dsp login","args":["--email","[email protected]","--code","<code>"]}}

dsp login --email [email protected] --code 123456 --json
# → {"status":"authenticated","method":"otp","email":"[email protected]",
#    "suggestedActions":[{"type":"install_skill","command":"npx",
#      "args":["skills","add","display-dev/skill","--skill","display-dev"],
#      "requiresApproval":true}]}

dsp login --email [email protected] --json
# → {"status":"authenticated","method":"sso",
#    "suggestedActions":[{"type":"install_skill","command":"npx",
#      "args":["skills","add","display-dev/skill","--skill","display-dev"],
#      "requiresApproval":true}]}

SSO is selected automatically when the organization for the submitted email requires it.

Login failures use {"status":"error","error":"<code>"}. Stable error codes are email_required, api_key_required, input_failed, invalid_api_key, sso_required, disposable_email, send_failed, invalid_or_expired_code, access_denied, device_code_expired, authentication_failed, and configuration_failed.

The OTP is single-use and expires after ten minutes. A human-controlled integration can use the compatible --code form, which places the OTP briefly in process arguments. Agents must not receive or relay it. The resulting session token is persisted and used only by the CLI.

After OTP, SSO, or API-key authentication, the CLI suggests the optional display.dev skill installation:

npx skills add display-dev/skill --skill display-dev

Installing the skill changes agent-owned configuration. An agent must get the user's approval before running the command. Login never runs the installer.

Usage

# Publish a file. User-scoped credentials create a private artifact;
# org-scoped service keys create a company artifact. Publishes without a
# credential create a public artifact you can claim.
# The display name defaults to the filename without the extension.
dsp publish ./report.html

# Share a report with the organization
dsp publish ./report.html --company

# Override the display name
dsp publish ./report.html --name "Q1 Report"

# Publish as public (no login required to view)
dsp publish ./report.html --name "Q1 Report" --public

# Share with external recipients (repeatable)
dsp publish ./proposal.html --name "Q1 Proposal" \
  --share [email protected] --share [email protected]

# Update an existing artifact from the version you edited
dsp publish ./report.html --id abc123 --base-version 5

# Change an existing artifact back to company auth
dsp publish ./report.html --id abc123 --base-version 5 --company

# Remove all guest shares from an existing artifact
dsp publish ./report.html --id abc123 --base-version 5 --clear-shares

# Browse and search artifacts
dsp list --author [email protected]
dsp search "quarterly"
dsp search "invoice total" --in abc123@5

# Read a bounded source range, pinned to a version
dsp read abc123@5 --offset 0 --limit 65536

# Replace one exact source span
dsp edit abc123 --base-version 5 --old "Q1" --new "Q2"

# Get artifact metadata, versions, outline, and open threads
dsp get-metadata abc123

# Make an independent copy from the current version
dsp make-copy abc123

# Within your organization, copy a retained version and invite a reviewer
dsp make-copy abc123@3 --name "Q1 plan" --visibility private --share [email protected]

# Delete an artifact
dsp delete abc123 --confirm

# Start MCP server (for Claude Desktop / Claude Code)
dsp mcp

Copy defaults and destination

dsp make-copy <shortId> needs no metadata lookup. The server uses the current version, Copy of <source name>, source visibility and no inherited recipients. Use --visibility private for a private copy. The public browser copy page initially selects Private. JSON includes sourceVersion, the version copied.

An eligible public artifact from another organization can be copied on every plan, using only its current version. The source organization must be active and allow public artifacts. A 404 means missing or unavailable source/version; it does not identify the cause. Confirm the active destination organization first. Bounded retries keep the same operation key and request. A key cannot be reused with different inputs or another destination. After an unresolved interruption, check that organization's artifacts before starting a new copy.

Publish flags

FlagEffect
--name <name>Display name override. Optional — defaults to the filename without the extension on create. On update, renames the artifact (re-derives the slug).
--id <shortId>Update an existing artifact (publishes a new version).
--base-version <n>Required with --id; the current version you edited from.
--publicSet visibility to public (no auth required to view).
--companySet visibility to company auth. This is the default for org-scoped service keys.
--visibility <level>Set visibility to public, company, or private.
--share <email>Grant guest access to an external email (repeatable).
--share-with <emails>Grant guest access to a comma-separated list of emails.
--clear-sharesRemove all guest shares. Only valid with --id.
--theme <theme>Markdown rendering theme.
--reloadRefresh open viewer tabs when the new version is ready.

Visibility and share flags default to "keep current" on update: omitting --public, --company, and --visibility leaves visibility unchanged; omitting --share, --share-with, and --clear-shares leaves the guest list unchanged. Use only one of --public, --company, or --visibility. Do not combine --clear-shares with either --share or --share-with.

On create, omitting visibility uses the credential context: user sessions and user-owned keys create Private artifacts, while organization-scoped service keys create Company artifacts. CI jobs using user-scoped credentials should pass --company when the result is meant for the organization.

For update mode, fetch the current version first with dsp get-metadata <shortId>. Use dsp search <text> --in <shortId> and dsp read <shortId> for bounded context, then dsp edit for one exact replacement. Use dsp export when you intentionally need the complete local file, and dsp publish --id for whole-source replacement. If the artifact changed on the server, reconcile against the current version and retry with that baseline.

Updates keep the format established for the artifact. Use a .md file for a Markdown artifact and a .html file for an HTML artifact. Publish a new artifact when converting between Markdown and HTML.

Testing

The CLI suite uses three distinct fetch-faking strategies, each pinned to a layer of the stack. New contributors pick the one that matches the layer they're testing — adding a fourth is almost always wrong.

  • Unit-level fetch fake (stubFetchJson(...)) — for exercising ApiClient and anything that composes it purely in-process. Low ceremony, full control over responses, no cross-process boundary. Use the stubFetchJson(body, init?) helper from cli/src/test-helpers.ts — it stubs global.fetch with a fresh JSON Response per call and returns the vi.fn() so tests can still inspect fetchMock.mock.calls[...]. Fall back to raw vi.stubGlobal('fetch', vi.fn().mockRejectedValue(...)) only for network- failure cases. Representative example: cli/src/api-client.spec.ts and the integration wire-up assertion in cli/src/mcp-mode-selection.spec.ts.
  • Hand-rolled createMockApiClient() — for MCP tool specs that verify argument-routing from an MCP tool handler to the right ApiClient method. No HTTP in the loop at all; the fake is a plain object of vi.fn()s. Representative example: cli/src/mcp-server.spec.ts and cli/src/mcp-publish-file-read.spec.ts.
  • Real localhost HTTP fixture (createHttpFixture + spawnCli) — for program.action E2E specs that need to exercise commander argv parsing, the stdout/stderr split, exit codes, and the full HTTP round-trip. Drives the CLI as a real child process. Representative examples: cli/src/cli-mode-selection.spec.ts, cli/src/cli-subcommands.spec.ts, cli/src/login-otp.spec.ts, cli/src/login-otp-send.spec.ts.

MCP

The CLI doubles as an MCP server over stdio. Add to your MCP client config:

{
  "mcpServers": {
    "display": {
      "command": "dsp",
      "args": ["mcp"],
      "env": {
        "DISPLAYDEV_API_KEY": "sk_live_..."
      }
    }
  }
}

Inspecting an existing artifact

Use dsp, not an anonymous web fetch, when inspecting an artifact URL. Gated artifacts return 403 without display.dev credentials.

The short ID is the path segment before the first hyphen. For https://display.dsp.so/YQyXggrM-product-video-script, it is YQyXggrM.

NeedCommand
Uploaded bytesdsp export <shortId>
HTML as Markdowndsp export <shortId> --format markdown
Specific versiondsp export <shortId>@<n>
Bounded source contextdsp read <shortId>[@<n>] [--offset <bytes>] [--limit <bytes>]
Metadata, versions, outline, and open threadsdsp get-metadata <shortId>
Browse artifactsdsp list
Search artifact namesdsp search <query>
Search within one sourcedsp search <query> --in <shortId>[@<n>]
Exact partial editdsp edit <shortId> --base-version <n> --old <text> --new <text>; use --old-file / --new-file for multiline UTF-8 inputs
Deprecated compatibilitydsp find [query] (writes a migration notice to stderr)

Read-only commands are safe for inspection. Commands such as publish, make-copy, edit, share, rename, delete, logo mutations, comment mutations, thread mutations, and watch mutations change published state; run them only when the user requests the change. delete requires --confirm.

The CLI defaults to https://api.display.dev. Set DISPLAYDEV_API_URL=http://api.display.test:3331 explicitly for local work.

Publishing this package

Production Delivery evaluates every master push and calls publish-cli.yml as a reusable child only when its planner admits the CLI. The child publishes only when cli/package.json contains a version newer than npm.

Whenever user-visible CLI behavior changes, update the version in the same change. While the package is pre-1.0:

  • Increase the minor version for a new feature or breaking change.
  • Increase the patch version for a backward-compatible fix.
  • Do not use 1.0.0 merely to signal a breaking change; that version is the separate stability commitment.

Publishing uses npm OIDC Trusted Publishing. Do not add an NPM_TOKEN or --provenance; sigstore provenance is unavailable for this private repository. The npm trusted-publisher entry must bind display-dev/display-dev to the calling workflow filename production-delivery.yml, not the reusable child filename. Update that package setting before changing the production caller.

版本与发布记录

@displaydev/cli 共发布 65 个版本,首次发布于 2026/04/13;过去 12 个月发布了 65 个版本。

版本发布日期距今
0.52.0latest2026/11/13今天
0.51.02026/11/103 天前
0.50.02026/11/085 天前
0.49.02026/11/067 天前
0.48.02026/11/067 天前
0.47.02026/11/067 天前

关于 @displaydev/cli 的常见问题

@displaydev/cli 是什么?

CLI for display.dev — publish HTML and Markdown with public, company, private, or invited-person access.

如何安装 @displaydev/cli?

在项目目录运行 npm install @displaydev/cli,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 dsp,可以用 npx dsp 直接运行。

@displaydev/cli 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/displaydev__cli 是否存在。

@displaydev/cli 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@displaydev/cli 可以商用吗?

@displaydev/cli 使用 未声明 许可。package.json 没有声明许可证。没有许可证的代码默认保留全部权利,商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括,不构成法律意见,请以许可原文为准。

@displaydev/cli 的下载量有多少?

根据 npm 官方下载统计,@displaydev/cli 在 2026/10/13 – 2026/11/11 这 30 天内被下载 2,381 次,日均约 79 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@displaydev/cli 还在维护吗?

最新版本 0.52.0 发布于 2026/11/13(今天);至今共发布 65 个版本,其中过去 12 个月发布了 65 个;首次发布于 2026/04/13。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。