--- name: pier-canvas description: >- Create or update a Pier Canvas under .pier/canvases using pier/canvas, pier/host, and project components. When mode / recipe / content are omitted, you infer the preview shell from intent (world mockup, fill board, docs, or methodology overview). Use only when explicitly invoked from Pier. compatibility: Requires Pier with the pier/canvas React runtime. disable-model-invocation: true --- # Create a Pier Canvas Canonical id: `pier-canvas`. In Pier, type `/canvas` and select it. Codex: `$pier-canvas`. Cursor / Claude Code: `/pier-canvas`. `disable-model-invocation` is a Cursor hint; Pier still sends the explicit invocation. If Cursor's `canvas` skill is present, follow this file. Canvas is a product-core overview, not a CLI side effect. Parameters are **skill invocation args**, not shell flags. | File | Owns | | --- | --- | | [authoring.md](references/authoring.md) | APIs, fonts, geometry, Mermaid, WorkflowDiagram, ScreenFlow | | [methodology.md](references/methodology.md) | Axes, expression, tab IA | | [verification.md](references/verification.md) | Delivery checks | | [host-data.md](references/host-data.md) | Plugin snapshots, applets, `settings.open` | | `packs/*/pack.json` | Fields, gates, anti-patterns, `template` | ## Invocation parameters Parse from the user message. **You infer omitted route args** (see **Auto-resolve**). The host only injects `locale=`. Unknown pack ids are hard failures. Explicit `mode=` / `recipe=` / `content=` / `presentation=` always win. | Param | Default | Meaning | | --- | --- | --- | | `mode` | *you infer* | `methodology` or `freeform`. Fallback after infer: `methodology`. | | `content` | *you infer* | `packs/content/` id. Methodology only. Fallback: `design-doc`. | | `presentation` | *resolved* | **Pack selection** below. Do not default every overview to five tabs. | | `ui` | `pier-default` | `packs/ui/` id | | `recipe` | *you infer* | `design`, `workflow`, `task-list`, or `task-dag`. Ignored in methodology. Daily tracking is the plugin panel (⌘N), not a canvas kanban. | | `slug` | from title | `.pier/canvases//` | | `locale` | injected | BCP-47 (`en`, `zh-CN`, …). | **Pack selection** (omitted presentation → from content; explicit id wins): | content | presentation | Use when | | --- | --- | --- | | `design-doc` | `decision_nav_4` | RFC / architecture. Overview → Problem → Design → Landing. No Day-1 tab. | | `closed-loop` | `primary_nav_5` | Runtime with a copyable Day-1 recipe. Overview → Problem → Design → **Day 1** → Landing. | | either | `one_pager` (explicit) | Single-scroll BLUF | Do not invent a Day-1 tab for `design-doc` unless the user has a real ≤4-step recipe **and** passes `presentation=primary_nav_5`. Project override: `.pier/canvas-packs/{content,presentation,ui}//pack.json`. ## Audience language Skill files and pack ids are English. **Every user-visible string must match the user.** 1. `locale=` (Pier injects UI language). 2. Else the language of the current request. 3. Never keep template English because the starter used it. Tab labels: `i18n/nav.json` → `labels[][] ?? labels[].en ?? view.label`. View ids stay English (`overview`, `problem`, `design`, `path`, `landing`). ## Auto-resolve (do this first) **You choose the preview shell.** The host does not infer the shell and does not rewrite the invoke. Do not start Workflow A just because `/pier-canvas` was typed. Do not ask which shell to use. | Intended artifact | Infer | Root | Pack / start from | | --- | --- | --- | --- | | Product **screens** | `mode=freeform recipe=design` | `WorldStage` | `packs/recipes/design/` · `templates/design-mockup.canvas.tsx` | | Approval / recover flowchart | `mode=freeform recipe=workflow` | `WorkflowDiagram` | `packs/recipes/workflow/` · `templates/workflow.canvas.tsx` | | One-screen board that owns scroll | `mode=freeform` | `` | compose; no starter | | Named task list island | `mode=freeform recipe=task-list` | `Frame` | `packs/recipes/task-list/` · `templates/task-list.canvas.tsx` | | Named task DAG island | `mode=freeform recipe=task-dag` | `Frame` | `packs/recipes/task-dag/` · `templates/task-dag.canvas.tsx` | | Manual / handbook | `mode=freeform` | `DocsShell` | `templates/docs.canvas.tsx` | | Component catalog | `mode=freeform` | `Frame` | `.pier/canvases/canvas-kit/` (no skill starter) | | Control plane with Day-1 recipe | `mode=methodology content=closed-loop` | `Frame` | `templates/closed-loop.canvas.tsx` | | Decision / RFC, or a bare invoke | `mode=methodology content=design-doc` | `Frame` | `templates/decision.canvas.tsx` | | Short single-scroll BLUF | `presentation=one_pager` | `Frame` | `templates/one-pager.canvas.tsx` | Mixed intent → pick the **primary** artifact. Architecture “design” is a document. App-screen “design” is a world mockup. - A mockup is **not** a design-doc with Artboards inside a Design tab. - Do not wrap a reading doc in `WorldStage`. - Do not stack phone/desktop frames as a document inside `Frame`. - Explicit args win. Omitted `mode` is **not** a synonym for methodology. - Do **not** scaffold a tracker-board canvas. Daily tracking is ⌘N → Task tracker. Unknown `recipe` ids are hard failures. When `recipe=` is set, use **Workflow B**. ## Stage selection (flow vs world vs fill) The files preview is **one shell**. **Pick the shell from the user's ask** — do not ask the user. Geometry: [authoring.md](references/authoring.md). | Root shell | When | Preview chrome | | --- | --- | --- | | `Frame` (flow) | Article, decision overview, scrolling dashboard | Reading measure (`max-w-5xl` comfortable / full-bleed wide); no zoom | | `DocsShell` (flow) | Manual with sidebar | Document font + reading size; **no floating font-scale control** | | `` | One-screen board that owns scroll | Full-bleed; measure dropped | | `WorldStage` | Multi-device mockups, whiteboard | Viewport zoom/pan; fit / 100% | - Full-bleed boards use **fill**, not world. - `ArtboardStage` is a **fit-all card in flow** (same as `Mermaid`). Wheel zoom is world only. ## Hard boundaries - Look at `.pier/canvases/canvas-kit/canvas-kit.canvas.tsx` and `sdk/*.d.ts`. **Only import named exports** from `pier/canvas`. Commands from `pier/host`. Plugin data: `plugin.list` / `inspect` → `useHostSnapshot("plugin:/")` → declared `pluginAction.invoke`. CRUD/OAuth via `settings.open`. See [host-data.md](references/host-data.md). Never ship `AccountsCard` / `canvasWidgets`. - Write under `.pier/canvases/**` unless the user asks otherwise. - Never `cursor/canvas`, `window.pier`, Electron, Node, IPC, `eval`, dynamic import, or host component source. - Do not register extra system skills per pack. ## Workflow A — methodology Use when you inferred an overview or `mode=methodology`. Not for a UI mockup. 1. Resolve packs (project then built-in). Hard fail if missing. 2. `kind: "composition"` unless the user needs `docs` or `kit`. 3. Write `.pier/canvases//{instance.json,data.json,.canvas.tsx}`. 4. Content pack → `data.json` from `required` / `gates` / `agentPrompt`. No layout. 5. Run gates; stop on failure. 6. Presentation pack → `views` / `antiPatterns` / `template`. BLUF first; one `primary`; ≤5 tabs. **static product design** (methodology **Expression selection**). No Play/Step unless a mechanism explainer. 7. UI pack `rules` / `forbidden` (default `pier-default`). 8. `instance.json`: `content`, `presentation`, `ui`, `status: "draft"`, `role: "overview"`. 9. Read `sdk/index.d.ts`. Run [verification.md](references/verification.md). Restyle: keep `data.json`, change packs, regenerate the Canvas. ## Workflow B — freeform Use when `mode=freeform`, `recipe=` is set, or you inferred a freeform shell. 1. Update in place when a matching Canvas exists. 2. Read relevant project code and `sdk/index.d.ts`. 3. Kind: `composition` | `docs` | `kit`. File: `.pier/canvases//.canvas.tsx`. 4. Start from the Auto-resolve template (or canvas-kit for `kit`). Pack `agentPrompt` + [authoring.md](references/authoring.md) own details. Do not copy applet source. Do not import `@pier-applet/pier.tasks/tracker-board`. 5. Export `canvas` metadata. No methodology `instance.json`. 6. Run [verification.md](references/verification.md). ## Content requirements - User-visible copy in the user's language. - Hierarchy before decoration. No fabricated data or empty decorative cards. - Charts: metrics, units, time ranges, sources. - **Mermaid chrome:** flowchart / architecture use `nodes` / `edges` with `kind` (`actor` | `agent` | `tool` | `artifact` | `external`). Status uses `tone`. Sequence (`sequence` / `sequenceDiagram`), state, `class`, ER, mindmap use native mermaid `source`. Card wash matches `WorkflowDiagram` (`color-mix` of status-fg into `--card`, theme ink). No left color rail. Mermaid is **static**. Details: [authoring.md](references/authoring.md) **Mermaid**. - Approval / recover: `WorkflowDiagram`, not Mermaid. Details: [authoring.md](references/authoring.md) **Workflow diagrams**. - Multi-screen user path: `recipe=design` + `ScreenFlow` on `WorldStage`. Details: [authoring.md](references/authoring.md) **Screen flows**. Call `validateScreenFlowPaint({ spec, frames })` after placing Layers; if it fails, apply only the first `supportedFixes` entry and re-run. Do not use `WorkflowDiagram` for artboards. - Every user action needs a recognizable UI change or error. ## Delivery - Project-relative path; created vs updated; `kind`. - Methodology: `content`, `presentation`, `ui` used. - Compilation, mount, interaction checks actually completed — and any that were not.