Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"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 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.11.1",
"description": "Publish, browse, search, read, edit, and share HTML or Markdown artifacts with public, private, or company-authenticated access. Includes Visualize Lite 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.12.0",
"author": {
"name": "display.dev",
"url": "https://display.dev"
Expand All @@ -19,7 +19,7 @@
"type": "http",
"url": "https://api.display.dev/v1/mcp",
"headers": {
"X-Client-Source": "display-dev-claude-plugin@0.11.1"
"X-Client-Source": "display-dev-claude-plugin@0.12.0"
}
}
}
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Publish HTML or Markdown from Claude to [display.dev](https://display.dev), choose who can view it, and act on reviewer comments. One install gives Claude:

- the **display.dev skill**: publish, browse, search, read, edit, copy, and share artifacts with public, private, or company access;
- **Visualize Lite**: on-brand HTML reports, plans, diagrams, decks, and dashboards, with 103 reference design systems loaded when you pick one;
- the **display.dev MCP server** (`https://api.display.dev/v1/mcp`);
- **`/display-dev:feedback`**: lists your artifacts with open comments, shows a plan for each thread, and after you approve it, edits the artifact, replies, and resolves the threads. With no comments, it offers to ask a reviewer or to wait for comments;
- a **publish guard** hook that scans a publish for secrets (API keys, tokens, private keys). It blocks a public publish and asks before any other publish;
Expand All @@ -28,24 +29,25 @@ The hooks run in Claude Code and in Cowork on your own computer. The comment not
| Part | Runs | Sends or fetches | Stores |
|---|---|---|---|
| display.dev skill | The bundled helper scripts, the installed `dsp` CLI, and a bundled `jq` binary for JSON | Requests to `api.display.dev` for the actions you ask for. An anonymous publish sends the file to `https://api.display.dev/v1/public/artifacts`. | Nothing. `dsp` keeps its own sign-in. |
| Visualize Lite | The bundled scripts (Node) for palette, contrast, diagram, and image checks | When you choose a design system that is not bundled, its `README.md`, `DESIGN.md`, and `tokens.css` from `raw.githubusercontent.com/display-dev/visualize` at the pinned commit (see `skills/visualize-lite/design-systems/REMOTE.md`). Image generation calls only the provider you configure. | The artifacts you ask it to create, in your project |
| MCP server | Nothing on your machine | Tool calls to `https://api.display.dev/v1/mcp` after you sign in with OAuth, with the header `X-Client-Source: display-dev-claude-plugin@<version>` | Nothing |
| Publish guard hook | `hooks/publish-guard.sh` before each Bash command and each display.dev `publish` tool call | Nothing. It reads only the files named in a publish command, or the `content` of an MCP publish, and checks them for secrets on your machine. | Nothing |
| Comment note hook | `hooks/comment-digest.sh` at session start, only when `dsp` is installed | One request through `dsp` to `api.display.dev`: your 100 most recently updated artifacts with their names and open-thread counts. It never fetches comment text. | The open-thread count and name of each of your artifacts with open threads, in Claude Code's plugin data folder (`open-thread-counts.json`) |
| `/display-dev:feedback` | `dsp` commands or MCP tool calls | Reads the metadata, open comments, and source of the artifact you choose. After you approve the plan, publishes the new version and posts replies and resolves to `api.display.dev`. | A temporary copy of the artifact source while it edits |

## Maintaining

`skills/display-dev/` is a copy of a pinned commit of [display-dev/skill](https://github.com/display-dev/skill). Never edit it here. Change the skill in that repository, then update `sources.lock` and run:
`skills/display-dev/` is a copy of a pinned commit of [display-dev/skill](https://github.com/display-dev/skill), and `skills/visualize-lite/` of the [Visualize Lite](https://github.com/display-dev/visualize#visualize-lite) build in display-dev/visualize. Never edit them here. Change a skill in its own repository, then update `sources.lock` and run:

```sh
tools/sync.sh # copy the pinned skill into skills/
tools/sync.sh # copy the pinned skills into skills/
tools/sync.sh --check # CI: fail when skills/ has drifted
bash tests/hooks.sh # offline hook tests
```

Raise `version` in `.claude-plugin/plugin.json` with every release, together with the `X-Client-Source` suffix there and in `commands/feedback.md`. CI checks that they match.

For on-brand HTML pages, install [Visualize](https://github.com/display-dev/visualize) as well: `npx skills add display-dev/visualize --skill visualize`.
Visualize Lite is the trimmed, standalone build of Visualize (about 130 files), which keeps this plugin small enough for directory validation. It is generated in display-dev/visualize, so change it there, not here. It downloads a design system that is not bundled from that repository at the matching release tag.

Display's privacy policy: https://display.dev/privacy

Expand Down
22 changes: 11 additions & 11 deletions commands/feedback.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.11.1` to every `dsp` command.
`--client-source display-dev-claude-plugin@0.12.0` 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
Expand All @@ -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.11.1 --author me --sort updated_at --dir desc --limit 100 --json
dsp list --client-source display-dev-claude-plugin@0.12.0 --author me --sort updated_at --dir desc --limit 100 --json
```

(MCP: `list` with `author: ["me"]`, `sort: "updated_at"`, `limit: 100`.)
Expand All @@ -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.11.1 <shortId>` and
`dsp comment --client-source display-dev-claude-plugin@0.11.1 list --artifact <shortId> --status open`
`dsp get-metadata --client-source display-dev-claude-plugin@0.12.0 <shortId>` and
`dsp comment --client-source display-dev-claude-plugin@0.12.0 list --artifact <shortId> --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.
Expand All @@ -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.11.1 <path> --id <shortId> --base-version <version>`.
`DISPLAYDEV_ACTOR_TYPE=agent DISPLAYDEV_ACTOR_NAME=claude-code dsp publish --client-source display-dev-claude-plugin@0.12.0 <path> --id <shortId> --base-version <version>`.
- Otherwise export the current version
(`dsp export --client-source display-dev-claude-plugin@0.11.1 <shortId>@<version> > <tmp file>`), edit the copy, and
(`dsp export --client-source display-dev-claude-plugin@0.12.0 <shortId>@<version> > <tmp file>`), 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.11.1 <shortId> --base-version <version> --old <text> --new <text>`
`DISPLAYDEV_ACTOR_TYPE=agent DISPLAYDEV_ACTOR_NAME=claude-code dsp edit --client-source display-dev-claude-plugin@0.12.0 <shortId> --base-version <version> --old <text> --new <text>`
(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.11.1 add --artifact <shortId> --parent <rootCommentId> --body <text>`,
`DISPLAYDEV_ACTOR_TYPE=agent DISPLAYDEV_ACTOR_NAME=claude-code dsp thread --client-source display-dev-claude-plugin@0.11.1 resolve <rootCommentId>`; MCP: `add_comment`,
(`DISPLAYDEV_ACTOR_TYPE=agent DISPLAYDEV_ACTOR_NAME=claude-code dsp comment --client-source display-dev-claude-plugin@0.12.0 add --artifact <shortId> --parent <rootCommentId> --body <text>`,
`DISPLAYDEV_ACTOR_TYPE=agent DISPLAYDEV_ACTOR_NAME=claude-code dsp thread --client-source display-dev-claude-plugin@0.12.0 resolve <rootCommentId>`; MCP: `add_comment`,
`resolve_thread`).
- Question: reply with the answer and leave the thread open for the
person who asked.
Expand All @@ -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.11.1 <shortId> --add-users <email>`; MCP: `share`). Do not change
(`DISPLAYDEV_ACTOR_TYPE=agent DISPLAYDEV_ACTOR_NAME=claude-code dsp share --client-source display-dev-claude-plugin@0.12.0 <shortId> --add-users <email>`; 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.11.1 list --artifact <shortId> --status open --since <start time>`
`dsp comment --client-source display-dev-claude-plugin@0.12.0 list --artifact <shortId> --status open --since <start time>`
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.
71 changes: 71 additions & 0 deletions skills/visualize-lite/AUTHORING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Visualize Authoring

This document is for maintainers. It is not part of the normal creation, review, or polish loading graph.

## Design principles

These are decisions that shape every edit to `SKILL.md`, `reference/`, and `detect.mjs`. Reverse one only after considering the failure mode it prevents.

### 1. Brand cues are hard invariants, not aspirational prose

Named fonts, named palettes, named anti-references from the resolved brand profile (or from fallback project instructions) are enforceable invariants — checked in preflight and re-audited at pre-render time. Revise before render; do not surface a violation to the user. Soft prose like "follow the brand profile" loses every time to the training prior.

### 2. Reflex-rejection lives at the picking step, not the refusal step

The composition reflex check runs in preflight, before shape sketching. Its output stays internal — the shape gate carries forward only the chosen alternative, not the rejection process. Anti-reflex procedures upstream of generation catch reflexes not yet cataloged; post-build refusal rules force the model into the next-most-common reflex instead. Reference implementation: impeccable's 4-step font-selection procedure.

### 3. Catalog access follows the task's scope

`teach` and [System Explore](reference/explore-system.md) use the catalog and reference packages as calibration when deriving project identities. Catalog choices do not themselves establish project authority; adoption follows `teach`'s draft-and-confirm contract.

Creation and revision can apply reference packages as artifact themes, and Artifact Explore can compare them. [SKILL.md's Artifact themes contract](SKILL.md#artifact-themes) owns project defaults and explicit artifact overrides. Browsing the catalog must not silently replace resolved project guidance or turn an artifact treatment into project authority.

### 4. Required shape-gate fields are source-conditional

Unconditional gate fields — pre-committed visible ingredients, primitive budgets, mandatory signature moves — induce format-induced collapse (Findings-EMNLP 2025: SFT 20.8% → DPO 10.8% diversity drop under structured-output requirements). Primitives follow sections that need them. Signature moves exist only when the source motivates one. Ingredients are derived from sections + primitives, not separately listed.

### 5. Instructions-only — no exemplars, no project paths, no calibrated numbers

The skill produces from-scratch using only prose instructions plus the brand profile chain. Pre-loaded exemplar images, project-specific shortIds or file paths, model-generated probability weights (`Font A 60% / Font B 25%`), and specific pixel values in prose (`32–40px padding`) all break the from-scratch premise. If a proposed change needs external state or per-project configuration, the change is wrong-shaped for this skill.

### 6. Specificity, not novelty

The *specificity and comprehension pass* assesses whether composition communicates the actual material. A familiar arrangement is acceptable when it serves the reader; structural change corrects a demonstrated deficiency rather than merely differing from a common layout. Cumulative denial across artifacts (avoiding a pattern because it was used before) confuses brand consistency with reflex — brand-consistent work *should* repeat. Only avoid reflexes that are wrong for the brand or source.

### 7. Two-model design center

The skill must work for both Claude and Codex (and future models with similar reflex shapes). Claude's reflex is precedent-inheritance — copying whatever sibling artifact exists. Codex's reflex is safe-median picks — cream paper, system-ui, soft shadows, eyebrow-chip mastheads. Procedures and invariants catch both. A proposed change that helps one model and hurts the other is wrong.

## Reverse-with-caution

Already tried and rejected — don't reintroduce without confronting the reason:

- **Cream-paper composition stack as an absolute BAN (in `SKILL.md`).** Considered as BAN 9 (`cream-band background + system-ui + soft shadow on bordered cards`) and BAN 10 (`eyebrow chips + lowercase wordmark + 4-col mono meta strip`) to catch the Codex research-report reflex. Rejected: instance-shaped (model dodges by changing one detail), and absolute bans don't carve out for brands that legitimately live in those aesthetics. The failure is now caught upstream by principle 1 (brand-fidelity lock).
- **Multi-persona generate-then-synthesize at the brand-words step.** Considered for measured diversity gain (Cambridge Design Science multi-persona work). Rejected per principle 7: overlap-rejection competes with brand fidelity — three personas should agree on brand identity moves, not have those rejected as shared reflex.
- **LLM-judged "marker-density" check post-build.** Considered for catching reflex co-occurrence patterns. Rejected: false-positives on legitimate brand-aligned output that uses cataloged moves; false-negatives on unfamiliar combinations. `detect.mjs` stays deterministic regex-based.
- **Verbalized-sampling probability weights.** Considered (Zhang et al. 2025, measured 1.6–2.1× diversity gain). Rejected per principle 5: model-generated weights without calibration are theater.
- **Specific pixel numbers in prose (`32–40px padding`, type ratio `≥ 4x`).** Rejected per principle 5 — bakes one aesthetic into the skill and doesn't travel across registers.

## Templates

Templates live at `templates/<slug>/template.md`. Each template directory contains exactly that one live authoring file. Required frontmatter is `name` and `description`; `shell` is optional and must resolve to `shells/<slug>/README.md`. Do not add `category`, `patterns`, `optional_patterns`, or `fixtures` frontmatter.

Template bodies describe selection and composition: Use when, Do not use when, Structure, Creation guidance, Hierarchy contract, Mobile contract, and Failure modes. Keep them compact and specific to reader outcomes. Mention pattern recipes in prose only when the template genuinely benefits from them.

## Pattern Recipes

Recipes live at `patterns/<slug>.md`. They are creation guidance for recurring rendered patterns, not importable components and not review rubrics. Required frontmatter is `name` and `description`; `variants` is optional. Minimal examples are allowed when they remove ambiguity, but they should not become a shared skin.

## Shells

Shells live at `shells/<slug>/` and exist only for behavior-heavy mechanics: slide navigation, keyboard control, hash sync, scaling, print, or similar. A shell README documents content slots, behaviors, accessibility invariants, print/export expectations, and what an agent may customize. Runtime files are read only when the artifact needs to inline or modify mechanics.

Artifact Explore follows the same single-file harness shape as a prototype exploration: review controls sit outside same-DOM candidate roots, each direction scopes its CSS to its own root, and width controls never impose a fixed document height. Temporary candidate drafts and screenshots are construction evidence, not fixtures or a publishable package.

## Fixtures

Fixtures live under `fixtures/` and are tooling assets. They are not authoring inputs and templates do not reference them. If `fixtures/manifest.json` lists a file, validators must be able to resolve it. Keep fixtures targeted to detector coverage, contrast checks, mobile overflow checks, shell smoke, or human visual inspection.

## Fixture Styles

Preview-only CSS belongs in `preview-kit/fixture-styles/` or inside the fixture itself. Do not recreate `components/` as a reusable component library. If a style is required for generated artifacts, it belongs in the artifact, not the preview kit.
Loading
Loading