diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index eeac173..2db187d 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -2,7 +2,7 @@ "name": "display-dev", "displayName": "Display", "description": "Publish, browse, search, read, edit, and share HTML or Markdown artifacts with public, private, or company-authenticated access. Includes Visualize for on-brand HTML pages, the display.dev MCP server, /display-dev:feedback for reviewer comments, a secret scan before publishes, and a session-start note about new comments.", - "version": "0.13.0", + "version": "0.13.1", "author": { "name": "display.dev", "url": "https://display.dev" @@ -19,7 +19,7 @@ "type": "http", "url": "https://api.display.dev/v1/mcp", "headers": { - "X-Client-Source": "display-dev-claude-plugin@0.13.0" + "X-Client-Source": "display-dev-claude-plugin@0.13.1" } } } diff --git a/commands/feedback.md b/commands/feedback.md index cdc5e0f..cee1a02 100644 --- a/commands/feedback.md +++ b/commands/feedback.md @@ -24,7 +24,7 @@ argument is optional: `$ARGUMENTS` Use one display.dev tool path for the whole task: 1. If a shell is available and `dsp` is on PATH, use the CLI. Add - `--client-source display-dev-claude-plugin@0.13.0` to every `dsp` command. + `--client-source display-dev-claude-plugin@0.13.1` to every `dsp` command. Prefix every command that changes state (`publish`, `edit`, `share`, `comment add`, `thread resolve`) with `DISPLAYDEV_ACTOR_TYPE=agent DISPLAYDEV_ACTOR_NAME=claude-code`, so the @@ -39,7 +39,7 @@ Use one display.dev tool path for the whole task: List the user's artifacts that have open comments: ```bash -dsp list --client-source display-dev-claude-plugin@0.13.0 --author me --sort updated_at --dir desc --limit 100 --json +dsp list --client-source display-dev-claude-plugin@0.13.1 --author me --sort updated_at --dir desc --limit 100 --json ``` (MCP: `list` with `author: ["me"]`, `sort: "updated_at"`, `limit: 100`.) @@ -57,8 +57,8 @@ updated artifacts has open comments, and stop. before the first hyphen: `https://display.dsp.so/abc12345-q3-plan` → `abc12345`. 2. Read the metadata and the open threads: - `dsp get-metadata --client-source display-dev-claude-plugin@0.13.0 ` and - `dsp comment --client-source display-dev-claude-plugin@0.13.0 list --artifact --status open` + `dsp get-metadata --client-source display-dev-claude-plugin@0.13.1 ` and + `dsp comment --client-source display-dev-claude-plugin@0.13.1 list --artifact --status open` (MCP: `get_metadata`, `list_comments`). Note the current version. 3. Sort each open thread into one group: - **Change request**: a change to the artifact's content. @@ -77,19 +77,19 @@ updated artifacts has open comments, and stop. 5. Make the approved changes as one new version: - If the artifact was published from a file in this workspace and the user confirms that file, edit it and publish it: - `DISPLAYDEV_ACTOR_TYPE=agent DISPLAYDEV_ACTOR_NAME=claude-code dsp publish --client-source display-dev-claude-plugin@0.13.0 --id --base-version `. + `DISPLAYDEV_ACTOR_TYPE=agent DISPLAYDEV_ACTOR_NAME=claude-code dsp publish --client-source display-dev-claude-plugin@0.13.1 --id --base-version `. - Otherwise export the current version - (`dsp export --client-source display-dev-claude-plugin@0.13.0 @ > `), edit the copy, and + (`dsp export --client-source display-dev-claude-plugin@0.13.1 @ > `), edit the copy, and publish it the same way. With MCP, edit the content you read and call `publish` with `short_id` and `base_version`. - For one small change, - `DISPLAYDEV_ACTOR_TYPE=agent DISPLAYDEV_ACTOR_NAME=claude-code dsp edit --client-source display-dev-claude-plugin@0.13.0 --base-version --old --new ` + `DISPLAYDEV_ACTOR_TYPE=agent DISPLAYDEV_ACTOR_NAME=claude-code dsp edit --client-source display-dev-claude-plugin@0.13.1 --base-version --old --new ` (MCP: `edit`) is also fine. 6. Close the threads: - Applied change: reply with one line, for example "Changed in v7: the churn figure now uses Q3 data.", then resolve the thread - (`DISPLAYDEV_ACTOR_TYPE=agent DISPLAYDEV_ACTOR_NAME=claude-code dsp comment --client-source display-dev-claude-plugin@0.13.0 add --artifact --parent --body `, - `DISPLAYDEV_ACTOR_TYPE=agent DISPLAYDEV_ACTOR_NAME=claude-code dsp thread --client-source display-dev-claude-plugin@0.13.0 resolve `; MCP: `add_comment`, + (`DISPLAYDEV_ACTOR_TYPE=agent DISPLAYDEV_ACTOR_NAME=claude-code dsp comment --client-source display-dev-claude-plugin@0.13.1 add --artifact --parent --body `, + `DISPLAYDEV_ACTOR_TYPE=agent DISPLAYDEV_ACTOR_NAME=claude-code dsp thread --client-source display-dev-claude-plugin@0.13.1 resolve `; MCP: `add_comment`, `resolve_thread`). - Question: reply with the answer and leave the thread open for the person who asked. @@ -103,10 +103,10 @@ Say so, then offer: - **Ask someone to review it**: ask for the reviewer's email address, then share the artifact with them - (`DISPLAYDEV_ACTOR_TYPE=agent DISPLAYDEV_ACTOR_NAME=claude-code dsp share --client-source display-dev-claude-plugin@0.13.0 --add-users `; MCP: `share`). Do not change + (`DISPLAYDEV_ACTOR_TYPE=agent DISPLAYDEV_ACTOR_NAME=claude-code dsp share --client-source display-dev-claude-plugin@0.13.1 --add-users `; MCP: `share`). Do not change the artifact's visibility. - **Wait for comments**: available only with a shell. Poll - `dsp comment --client-source display-dev-claude-plugin@0.13.0 list --artifact --status open --since ` + `dsp comment --client-source display-dev-claude-plugin@0.13.1 list --artifact --status open --since ` every 60 seconds in the background. When a comment arrives, continue with B. Stop after the time the user gives, or after 60 minutes. - **Nothing for now**: stop. diff --git a/skills/display-dev/SKILL.md b/skills/display-dev/SKILL.md index 6387220..47431a1 100644 --- a/skills/display-dev/SKILL.md +++ b/skills/display-dev/SKILL.md @@ -181,52 +181,14 @@ true: approaches the safe inline tool-call ceiling; and - the code-execution environment can send HTTPS requests to `api.display.dev`. -Then perform these steps: - -1. Measure the raw file byte length without reading its contents into the - conversation. Call `create_upload` with the basename and exact `size_bytes`. -2. In code execution, send the raw file bytes with `PUT` to the returned - first-party `upload_url`. Use every exact entry in `required_headers`, - including `Authorization`, `Content-Type`, and `Content-Length`. Do not - encode the file as JSON, base64, or multipart form data. It is acceptable - for the initiating execution trace to show the URL and bearer. -3. Call `publish` once with the returned `upload_id` plus the user-approved - name, visibility, sharing, or `short_id` / `base_version` update fields. For - an ordinary authenticated publish, omit visibility; pass `company` only - when the user asked to share with the organization. Do not also pass `content` or `format`. -4. Report the canonical artifact URL and relevant publish result. Do not repeat - the upload bearer or source. Discard the upload ID. - -The capability expires after 15 minutes. Do not finalize the same staged create concurrently. If `publish` returns `upload_unavailable`, start again with a new -`create_upload` without inferring or revealing whether expiry, ticket validity, -organization binding, or a missing object caused it. If it returns -`upload_size_mismatch`, report that exact mismatch, measure the raw file again, -and start with a new upload. Never reuse the old upload ID. Current per-artifact limits still apply: 10MB on -Free and 50MB on Solo, Pro, and Enterprise, including when the plan changes -between staging and publishing. +When these prerequisites hold, read [references/staged-upload.md](references/staged-upload.md) +before calling `create_upload`. If the tools are absent or `api.display.dev` is unreachable, use `dsp publish` where the file exists, ask the user to publish through the dashboard, or use inline `content` only when the source is small enough. Never install a runtime or move credentials to work around the missing capability. -For Claude Cowork Team and Enterprise, an Owner or Primary Owner must allow -`api.display.dev` for code execution, then the user must start a new task. MCP -connector traffic uses a separate path and does not grant shell egress. -Personal Claude Pro and Max currently provide no custom code-execution domain -allowlist, so large staged publishing is unavailable there; use one of the -fallbacks above. - -Example: - -```text -User: Publish the 20MB report generated in code execution for my organization. -Agent: Confirms the authorized remote tools, measures the file, calls -create_upload, transfers raw bytes through api.display.dev with every returned -header, calls publish(upload_id=...), and reports the artifact URL without the -temporary bearer or source. -``` - ## Create or sign in to a display.dev account When the host bundles the display.dev remote MCP server, sign-in uses that @@ -263,26 +225,8 @@ provisioning result. ## Add or transfer a company email domain -Email-domain management is Owner-only. Prefer the authorized MCP tools when -they are registered: - -- `list_email_domains` lists verified, pending, dormant, and transfer states. -- `add_email_domain` adds a domain and returns the DNS TXT record. A domain - already connected elsewhere creates an inert transfer request. -- `verify_email_domain` checks the fresh TXT record for an ordinary claim or - transfer request. It also rechecks a support-required transfer after support - confirms the blocker is resolved. -- `remove_email_domain` removes an ordinary row or cancels a non-terminal - transfer request. - -Installed-CLI equivalents are: - -```bash -dsp email-domains list -dsp email-domains add -dsp email-domains verify -dsp email-domains remove -``` +Email-domain management is Owner-only. For listing, adding, verifying, transferring, +or removing a domain, first read [references/email-domains.md](references/email-domains.md). The paid email domains add-on is human-operated. Neither MCP nor the direct CLI can enable or disable it. If the user asks to change it, direct a current Owner @@ -290,49 +234,12 @@ to **Settings → Email Domains**. Do not call the REST endpoint as a fallback o claim the add-on changed. After the Owner completes the change, continue with the registered domain-management tools when needed. -For a foreign-domain collision, surface the request-specific TXT record and -state that DNS verification does not move the domain by itself. After -verification, report `transfer_ready` or `transfer_support_required` without -inferring the source organization or its contents. Source-owner approval is -not required. - -Handle each returned transfer state explicitly: - -- `transfer_pending_dns`: publish the request-specific TXT record, then verify. - The Owner may cancel it with `remove_email_domain` or - `dsp email-domains remove `. -- `transfer_ready`: send a current target Owner to **Settings → Email Domains** - for final review and confirmation. The Owner may still cancel instead. -- `transfer_support_required`: do not guess at hidden source details. Tell the - user to contact support. After support confirms the issue is resolved, run - `verify_email_domain` or `dsp email-domains verify ` again on the - same unexpired request. The existing DNS proof is retained. If the retry - remains support-required, report that result without exposing or guessing - source details. The Owner may cancel instead. -- `transfer_expired`: the request is terminal and cannot be cancelled. Run - `add_email_domain` or `dsp email-domains add ` again to create a new - request and fresh TXT record. - -Completed transfers appear as ordinary `verified` rows. Cancelled requests are -terminal and no longer actionable; add the domain again only when the user -intends to start a fresh request. - Final confirmation is dashboard-only. When a transfer is ready, direct a current target Owner to **Settings → Email Domains** to review the people who will move, accept session revocation and source retirement, and confirm. Neither an MCP tool nor the CLI can complete the transfer. Never claim completion after DNS verification. -Example: - -```text -User: Transfer example.com to this organization. -Agent: add_email_domain returns a fresh TXT record because example.com is -already connected elsewhere. The user publishes it, then the agent runs -verify_email_domain. If the result is transfer_ready, the agent sends a target -Owner to Settings → Email Domains for the final review and confirmation. -``` - ## Share an artifact Use only the audience the user requested: diff --git a/skills/display-dev/references/email-domains.md b/skills/display-dev/references/email-domains.md new file mode 100644 index 0000000..5ab12ee --- /dev/null +++ b/skills/display-dev/references/email-domains.md @@ -0,0 +1,60 @@ +# Company email domains + +Prefer the authorized MCP tools when +they are registered: + +- `list_email_domains` lists verified, pending, dormant, and transfer states. +- `add_email_domain` adds a domain and returns the DNS TXT record. A domain + already connected elsewhere creates an inert transfer request. +- `verify_email_domain` checks the fresh TXT record for an ordinary claim or + transfer request. It also rechecks a support-required transfer after support + confirms the blocker is resolved. +- `remove_email_domain` removes an ordinary row or cancels a non-terminal + transfer request. + +Installed-CLI equivalents are: + +```bash +dsp email-domains list +dsp email-domains add +dsp email-domains verify +dsp email-domains remove +``` + +For a foreign-domain collision, surface the request-specific TXT record and +state that DNS verification does not move the domain by itself. After +verification, report `transfer_ready` or `transfer_support_required` without +inferring the source organization or its contents. Source-owner approval is +not required. + +Handle each returned transfer state explicitly: + +- `transfer_pending_dns`: publish the request-specific TXT record, then verify. + The Owner may cancel it with `remove_email_domain` or + `dsp email-domains remove `. +- `transfer_ready`: send a current target Owner to **Settings → Email Domains** + for final review and confirmation. The Owner may still cancel instead. +- `transfer_support_required`: do not guess at hidden source details. Tell the + user to contact support. After support confirms the issue is resolved, run + `verify_email_domain` or `dsp email-domains verify ` again on the + same unexpired request. The existing DNS proof is retained. If the retry + remains support-required, report that result without exposing or guessing + source details. The Owner may cancel instead. +- `transfer_expired`: the request is terminal and cannot be cancelled. Run + `add_email_domain` or `dsp email-domains add ` again to create a new + request and fresh TXT record. + +Completed transfers appear as ordinary `verified` rows. Cancelled requests are +terminal and no longer actionable; add the domain again only when the user +intends to start a fresh request. + +Example: + +```text +User: Transfer example.com to this organization. +Agent: add_email_domain returns a fresh TXT record because example.com is +already connected elsewhere. The user publishes it, then the agent runs +verify_email_domain. If the result is transfer_ready, the agent sends a target +Owner to Settings → Email Domains for the final review and confirmation. +``` + diff --git a/skills/display-dev/references/staged-upload.md b/skills/display-dev/references/staged-upload.md new file mode 100644 index 0000000..92a7aa9 --- /dev/null +++ b/skills/display-dev/references/staged-upload.md @@ -0,0 +1,43 @@ +# Staged remote MCP upload + +Then perform these steps: + +1. Measure the raw file byte length without reading its contents into the + conversation. Call `create_upload` with the basename and exact `size_bytes`. +2. In code execution, send the raw file bytes with `PUT` to the returned + first-party `upload_url`. Use every exact entry in `required_headers`, + including `Authorization`, `Content-Type`, and `Content-Length`. Do not + encode the file as JSON, base64, or multipart form data. It is acceptable + for the initiating execution trace to show the URL and bearer. +3. Call `publish` once with the returned `upload_id` plus the user-approved + name, visibility, sharing, or `short_id` / `base_version` update fields. For + an ordinary authenticated publish, omit visibility; pass `company` only + when the user asked to share with the organization. Do not also pass `content` or `format`. +4. Report the canonical artifact URL and relevant publish result. Do not repeat + the upload bearer or source. Discard the upload ID. + +The capability expires after 15 minutes. Do not finalize the same staged create concurrently. If `publish` returns `upload_unavailable`, start again with a new +`create_upload` without inferring or revealing whether expiry, ticket validity, +organization binding, or a missing object caused it. If it returns +`upload_size_mismatch`, report that exact mismatch, measure the raw file again, +and start with a new upload. Never reuse the old upload ID. Current per-artifact limits still apply: 10MB on +Free and 50MB on Solo, Pro, and Enterprise, including when the plan changes +between staging and publishing. + +For Claude Cowork Team and Enterprise, an Owner or Primary Owner must allow +`api.display.dev` for code execution, then the user must start a new task. MCP +connector traffic uses a separate path and does not grant shell egress. +Personal Claude Pro and Max currently provide no custom code-execution domain +allowlist, so large staged publishing is unavailable there; use one of the +fallbacks in `SKILL.md`. + +Example: + +```text +User: Publish the 20MB report generated in code execution for my organization. +Agent: Confirms the authorized remote tools, measures the file, calls +create_upload, transfers raw bytes through api.display.dev with every returned +header, calls publish(upload_id=...), and reports the artifact URL without the +temporary bearer or source. +``` + diff --git a/sources.lock b/sources.lock index 3f24107..dada5b2 100644 --- a/sources.lock +++ b/sources.lock @@ -2,7 +2,7 @@ # Change a skill in its own repository, release it there, then bump the ref # here and run tools/sync.sh. display-dev_repo=https://github.com/display-dev/skill.git -display-dev_ref=10df21fce1fdfc28f87e2095cb08cea24ea95e75 +display-dev_ref=f7edcdaaca439e1b1431a1e90e133238cf31d648 display-dev_path=display-dev visualize_repo=https://github.com/display-dev/visualize.git visualize_ref=53eb0dc560688b8174ff1b2811fe63d04042f42d