<!-- Install this guide with its sibling references/ and scripts/ directories. aiartifact init installs the complete bundle and adjusts the AGENTS.md section links. -->


# AI Artifact

`aiartifact` designs standalone HTML documents, publishes them as versioned pages, opens the published URL and brings reader feedback back to the agent. Keep the local file as the editable source; the hosted page is the deliverable.

## Delivery contract

Load this skill before creating or revising any standalone HTML deliverable: plans, reports, reviews, comparisons, diagrams, charts, dashboards and demos. Publish every completed HTML deliverable to AI Artifact, then open its returned URL and give that URL to the user. After revisions, publish the same source file again so readers keep the same URL with a new version.

Markdown is published when the user wants to share it. Application source files, scratch output and raw logs are not document deliverables. Ask before publishing confidential material; publication does not authorize making a private artifact public.

A local preview is a check, not delivery. If publishing fails, report the failure and preserve the source; do not substitute a local path for a successful publish. If the page was published but no browser can be opened, give the published URL and state that opening it was blocked.

## Bundled references

Resolve the following paths relative to this skill directory, not the project working directory. The complete installation includes these files and the validator; a standalone copy of SKILL.md is not sufficient.

- Before choosing a chart type, scale, chart palette, metric display or chart interaction, read [Data visualization](references/dataviz/index.md) and the focused references it names. Run the bundled [palette validator](scripts/validate_palette.js) for new or changed categorical palettes or surfaces; reuse a passing result when its inputs are unchanged.

- Before drawing an architecture, data-flow, state or comparison diagram, read [Diagramming](references/diagramming.md).

- Before writing the graph for an interactive canvas (see [Interactive canvas](#interactive-canvas)), read [Canvas graph](references/canvas-graph.md).

Ordinary text documents do not need any of these branches. These references are part of this skill, not separately installed or private skills.

## Designing HTML

When creating or revising HTML for publication, use these rules before publishing. Preserve an existing document's visual direction unless the user requests a redesign. Markdown uses the site's document style; apply the content hierarchy guidance without adding HTML styling to it.

### Choose a visual direction

Start with the reader, the document's subject and the one decision or action it should support. Honor the user's direction and any existing project design system. A technical report should prioritize reading and comparison; a presentation can use stronger visual emphasis. Match the treatment to the content rather than making every document a landing page.

Before writing HTML, choose a compact design plan: a palette with named roles and hex values, heading/body/utility type roles, a spacing scale and a layout. Include one subject-specific choice grounded in real content, such as a comparison structure or an engineering annotation. Use emphasis selectively; a large hero, gradient or repeated card grid needs a content reason, not just decoration. Use real content, and label any illustrative data.

### Typography

- Give headings, body text and utility text distinct roles. Choose complementary typefaces when they help express the subject; one well-chosen family with distinct sizes and weights is enough for a restrained report. Use monospace for code and tabular numerals for aligned numeric comparisons.
- Choose fonts that cover the document's language and declare a usable system fallback. External fonts are optional; the page must remain readable if they fail to load. Keep body text comfortably sized (normally at least 16px) with generous line height; constrain prose to a readable column rather than stretching it across the screen.
- Use a small, consistent type scale. Make heading levels distinguishable through size, weight and spacing, not color alone. Keep headings close to their content, allow long titles to wrap and reserve all-caps or extra letter spacing for short labels where the language supports it.

### Color and themes

- Assign CSS custom properties by role: page background, surface, primary text, muted text, border and accent. Choose neutrals and an accent that suit the subject; use the accent for the primary action or key evidence, rather than every section.
- Define a complete light palette on `:root` and override the same tokens under `prefers-color-scheme: dark`. Set `color-scheme: light dark` and explicit body background/text colors. Components should use those tokens so both themes receive deliberate contrast, not a naive color inversion.
- Keep status colors separate from the decorative accent. Pair success, warning and error colors with text or another visible indicator. Check muted text, links, borders, controls and focus states on their actual backgrounds in both themes.

### Layout and spacing

- Use a consistent spacing scale and group related content with flex/grid and `gap`. Use whitespace to separate sections before adding borders or boxes. Align repeated labels, values and controls; let content determine height rather than stretching cards to fill empty space.
- Give the page a bounded reading width and side gutters of at least 16px. At phone width (about 400 px), stack columns, wrap long labels and keep images within their containers. Put wide tables, code blocks and diagrams in their own scroll containers; the page body should not scroll sideways.
- Use cards when items are genuinely independent, tables when readers must compare the same attributes and prose when they need an explanation. Size the opening section to its content so the document itself is visible without passing a full-screen introduction.

### Information hierarchy

- Lead with the answer, recommendation or task the reader came for, then the supporting evidence and detail. Use the semantic heading structure described below. Number sections only when the numbers communicate a real sequence or ranking.
- Give each section a clear purpose and each control a concise action label. Add helper text only to resolve ambiguity or prevent mistakes; avoid subtitles that merely restate a heading. Keep source notes and secondary metadata quieter than the information they explain.
- Keep essential conclusions and evidence visible without animation or interaction. Use disclosure for secondary detail, with a label that tells readers what it contains. Add a chart or diagram only when it makes a relationship easier to understand; label values and units and preserve legibility in both themes.

### Interaction and accessibility

- Add interaction only when it helps the reader inspect the content. Use native buttons, links, form controls and disclosures for their intended actions, with associated labels and a visible keyboard focus state. Every control must work by keyboard as well as pointer; essential information must not depend on hover.
- Make state changes observable: identify the active tab or filter, show meaningful empty/error states and explain what changed. Keep interactions within the in-memory, embedded-data limits below; state resets on reload, and controls must not imply remote saving or submission.
- Keep text selectable for quoting. Use motion to clarify a change, respect `prefers-reduced-motion` and make content visible at rest; reading must not depend on a scroll-triggered reveal. Provide text alternatives for meaningful images.

### Verification scope and stopping condition

Choose checks from the actual change, not the HTML extension:

- **Instructions or content only:** review the changed text and necessary references. Do not run examples, browser QA, application tests, or a QA agent merely because a skill or report was edited. If wording affects wrapping or controls, check that specific impact.
- **New or changed rendering/interaction:** make one focused render pass and exercise the changed controls. Include narrow layouts, themes, keyboard paths, or sandbox behavior when the change affects them; do not build an exhaustive viewport/theme matrix by default. Use a hosted check when the sandbox is the relevant risk, rather than duplicating local and hosted QA.
- **High risk or explicit full-QA request:** use independent QA for the relevant boundaries. Otherwise, a standalone document does not require a QA subagent, checklist, screenshot collection, or separate report. Honor checks explicitly required by the user or repository.

Stop when the scoped checks pass. Reuse valid evidence for unchanged inputs; recheck only after an affected input changes, an actual failure, or a concrete evidence gap. Fix in-scope defects and report genuine verification limits. Editing the report does not require retesting the product or producing a report about it.

Return brief verification results with the deliverable URL. Create an additional QA artifact only when requested; publish a completed report once, not after every check. Live checklist updates require an explicit request. If delegating, use native completion notifications or a genuinely blocking wait; do not fill idle time with model-driven timer/status polling loops.

## How to publish

```sh
npx aiartifact login                       # once per machine; opens the browser and saves an API key
npx aiartifact publish ./docs/review-plan.html
npx aiartifact publish ./docs/qa-plan.md   # Markdown is rendered with the site's document style
```

- Run it inside the git checkout: repository, branch and commit are inferred from the working tree. Outside git, pass `--repo owner/name --branch name`.
- Optional flags: `--title`, `--description`, `--favicon` (one emoji), `--label` (a short version note such as "after review").
- Images referenced by relative path (`<img src="shots/a.png">`, `![](diagram.svg)`) next to the file are uploaded automatically; png, jpg, gif, webp, svg and avif only. A missing file is a warning, not an error.
- A successful HTML publish opens the returned URL in the system browser. Confirm the hosted page was opened; if an older CLI or the environment did not open it, open the returned URL with the available browser tool or the system URL opener (`open "<url>"` on macOS). Open only after publish succeeds, never the local file as a substitute. If opening fails, keep the successful publication and report its URL plus the opening limitation; do not publish a duplicate just to retry opening. Give the published URL to the user.
- `.aiartifact.json` in the repository root remembers which artifact each file maps to and stays local to the checkout (gitignored); never commit it. If the mapping is missing, the CLI looks up the active artifact by repository, branch and filename but sends base version 0. Review and merge the remote copy, then explicitly choose `--base-version N`. Never infer a trusted base from the latest remote version.
- A `409 conflict` means someone published a newer version of the same file since you last did. The current remote copy is written next to your file as `<name>.remote.<ext>`; merge it, then publish with `--base-version N` using the remote version named in the error.
- Limits: 16 MiB per file, 32 MiB per version including images, 30 publishes per minute.
- `AIARTIFACT_API_KEY` in the environment replaces `login` (for CI or another agent). `npx aiartifact login --key aa_live_…` saves a key you were handed, for example from the authorize page when the browser could not reach the CLI.

## Interactive canvas

A canvas is one self-contained HTML page that draws a system as lanes of nodes and edges plus sequence-diagram flows, with views to switch between, pan and zoom, a guided walkthrough that moves the camera one step at a time, and click-to-open cards showing each node's files and each message's request/response payload. You do not write the HTML; you write a graph JSON and the CLI wraps it in the page.

Use a canvas when the reader must be walked through something in order: the user asks to explain a workflow, flow, process or pipeline, how a request travels, or how a feature works end to end; the user says "canvas", "interactive", "walkthrough", "step by step" or "導覽"; a newcomer is being onboarded to a codebase; a PR's change spans three or more components; or an incident or data-flow narrative has concrete request/response samples to show. Do not use it when one static diagram says it (follow [Diagramming](references/diagramming.md) instead), for tables, reports or dashboards, or for anything without a sequence.

```sh
npx aiartifact canvas ./docs/checkout.graph.json      # validates, writes ./docs/checkout.graph.canvas.html
npx aiartifact publish ./docs/checkout.graph.canvas.html
```

- Write the graph by [Canvas graph](references/canvas-graph.md): lanes, nodes, edges, flows with payloads, views and a 2–12 step walkthrough. `--out PATH` chooses the output file; `--json` prints `{ out, nodes, edges, walkthrough }`.
- On validation failure the command prints one `path: message` line per issue and writes nothing. Fix the field at that path; never delete the element the message names just to silence it.
- `canvas` never publishes. Publish the generated `.canvas.html` with the normal `publish` command, then open and hand over the returned URL as for any HTML deliverable. Keep the graph JSON as the editable source and regenerate the HTML after each change.

## Writing the document

The page is served inside a sandboxed iframe with a strict Content-Security-Policy, so it must be self-contained:

- One file: inline your CSS and JavaScript. Images may be relative files (uploaded with the document) or `data:` URIs.
- External scripts only from `https://cdnjs.cloudflare.com`, `https://cdn.jsdelivr.net/npm/`, `https://cdn.tailwindcss.com` and `https://code.jquery.com`; stylesheets and fonts only from Google Fonts. Anything else is blocked silently.
- No `fetch`, `XMLHttpRequest`, WebSockets or form submissions: they are blocked. No `localStorage`, `sessionStorage` or cookies: the sandbox has an opaque origin, so these throw. Put all data in the file.
- Give the document a `<title>` (it becomes the artifact's title) and, for Markdown, a top-level `# Heading`.
- Use real heading elements for structure: `<h1>` for the title, `<h2>` for sections, `<h3>` for subsections in HTML (not styled `<div>`s); `#`, `##`, `###` in Markdown. The page builds its outline from the sections and subsections (a sidebar on desktop, a floating list on phones), so do not write a table of contents by hand; it would appear twice.
- Readers select text in the page to quote it in a comment, so write in plain, quotable paragraphs.

## The feedback loop

When the user says something like "check the comments", "see what they said" or "address the feedback":

```sh
npx aiartifact comments ./docs/review-plan.html --open   # open comments with quotes; also accepts the artifact id
```

Reading comments records the pull time; readers see "agent last pulled N min ago" on the page, so pull before you start working.

For each comment, decide and act:

```sh
npx aiartifact answer <comment-id> --version 3 --body "Fixed: the retry is idempotent now; see cart.test.ts:118" --agent "Claude Code"
npx aiartifact resolve <comment-id>            # only when the user asked you to close it; readers can resolve too
npx aiartifact publish ./docs/review-plan.html # the new version the answers refer to
```

`answer` marks the comment "answered in vN" on the page and shows your reply under it. If you answer before publishing, pass the version number the new publish will get (current version + 1); otherwise omit `--version` and it defaults to the latest.

Other command: `npx aiartifact list --json` lists artifacts for this repository and branch, including their management IDs.

## Managing artifacts

```sh
npx aiartifact rename ./docs/review-plan.html "Review plan"
npx aiartifact delete ./docs/review-plan.html --yes
npx aiartifact trash --json
npx aiartifact restore <batch-id> --yes
npx aiartifact restore <batch-id> --artifact <artifact-id> --yes
npx aiartifact purge <batch-id> --yes
npx aiartifact delete --repository <repository-id> --yes
npx aiartifact delete --branch-id <branch-id> --yes
```

- `delete` now moves content to Trash for exactly 30 days and keeps the local file mapping. Trash still counts toward storage; only a completed `purge` frees space. These operations affect site groupings, never Git repositories or branches.
- `trash [batch-id]` lists batches and their remaining artifacts. Use `list --json` for repository and branch IDs. `restore` and `purge` accept a batch ID, artifact ID, or a mapped file; use `--artifact` to select one item in a batch.
- Restore keeps IDs, URLs, versions, attachments, comments and original sharing permissions. Partial restore preserves other items' deadlines. Expired or purging content cannot be restored. Publishing into Trash requires restoration first.
- Rename changes only the display name (1–200 characters after trimming), without a new version. Normal publishing preserves a manually set name; explicit `--title` replaces it.
- Management commands support `--json`. Destructive operations and restoration require interactive confirmation or `--yes`; non-interactive calls without confirmation fail immediately. A pending purge returns exit code 2; retry the same command to continue.
- A `409 restore_required` means restore first. `operation_in_progress` means retry after the other mutation finishes. `identity_changed` means a different artifact now owns that file path: inspect it before reconciling the local mapping. Only `conflict` with remote content writes a merge copy; never discard that protection by automatically updating the remembered version.

## Sharing

Artifacts are private to the owner until they share them. Tell the user to open the page, press Share, and either invite people by email or turn on "Anyone with the link". Anonymous readers of a public link can read but not comment.
