Write the penpot SKILL.md core workflow, token conventions and Tailwind translation table #215

Closed
opened 2026-09-14 23:15:15 +00:00 by david · 1 comment
Owner

Summary

Complete skills/penpot/SKILL.md: how to read a DESIGN.md, how to bootstrap the Penpot library from it (assets + imported components), the composition rules, the Tailwind → Penpot translation table, the four creation paths, and the lossy areas the agent must not promise. This is the judgement half of the feature — the extension guarantees valid payloads, the skill decides what to build.

Background

Depends on: #213, #214

The skill is where an agent's discretion lives, and its value is that it encodes decisions already made rather than leaving them to be re-derived:

  • DESIGN.md is not a schema. It is human-authored markdown, and the reference design system is Tailwind + shadcn/ui, so component recipes appear as Tailwind class strings that are not Penpot specs. The one machine-readable source is a Tailwind v4 @theme block in the project's CSS (--color-flip7-teal: #2BA8A2; …), which DESIGN.md may also embed. Read tokens deterministically from there; use the prose for semantics and layout intent.
  • Components cannot be read off the page. They come from the committed library artifact, imported per project and linked, then placed as instances.
  • Screens must reference the library by id. The agent passes names (colour: "flip7-gold", typography: "h2") and the extension resolves ids, which is what makes an asset edit restyle every screen.

This step also states the lossy areas plainly, because a skill that overpromises produces silent disappointment: gradients, coloured glows, dashed borders, pseudo-element constructions and all animation have no faithful Penpot equivalent.

Documentation Required

A separate process downloads these into the listed folders before this issue is implemented. Check the folders for the actual reference material before starting.

docs/reference/tailwindcss/

docs/reference/penpot-api/

docs/reference/svg/

docs/reference/pi-coding-agent/

Implementation Details

Extend skills/penpot/SKILL.md (keeping the frontmatter and image → design section from the earlier step, and the Reference section pointing at the vendored docs). Sections to add:

  1. Design-system bootstrap (the shared prerequisite). Ordered steps:

    • read DESIGN.md; if the project has CSS with a Tailwind v4 @theme block, read that for tokens (names, hex, type scale, radii) and treat DESIGN.md's prose as semantics;
    • list what exists (penpot_list_projects, penpot_get_file, penpot_list_library) before creating anything, so a re-run does not duplicate assets;
    • create the colour and typography assets from the tokens (penpot_create_color, penpot_create_typography), naming them exactly as the design system does;
    • import the committed component library (penpot_import_library), then link it (penpot_link_library) — state explicitly that an imported library is not usable until linked;
    • record the mapping from token name → asset name, and state what to do when DESIGN.md names a colour/type that has no asset (stop and ask, or create it explicitly — never silently substitute a near-match).
  2. Token conventions. A short, prescriptive table: DESIGN.md token → what the agent passes to the tools (e.g. --color-flip7-tealcolour: "flip7-teal"; --text-h2typography: "h2"). Rule: never pass hex values when a matching asset exists.

  3. Component conventions. Components come from the library; screens use penpot_instance_component. When no library component matches, compose primitives and name the frame so it can be promoted to a component later in the UI. Do not fake a component with a loose frame.

  4. Composition rules. One screen = one root frame; regions as child frames; layout frames wherever Tailwind would use flex (row/column, gap, padding, align/justify) and absolute positioning only as a fallback; text always via penpot_add_text with a typography asset; assets matched against the existing library first (link_colors in the SVG path); commit per screen (one commit = one revision); never write outside a designated target.

  5. Tailwind → Penpot translation table. Include at least:

    Tailwind idiom Penpot equivalent
    rounded-full pill radius (half the shorter side)
    rounded-lg / -xl / -2xl 8 / 12 / 16 px corner radius
    h-12, p-4, gap-2 48 px height, 16 px padding, 8 px gap
    bg-gradient-to-br from-… to-… gradient fill, two stops, diagonal (lossy — see below)
    shadow-glow-gold drop shadow, gold at ~40 % alpha, ~20 px blur, 4 px y-offset
    border-2 border-flip7-teal 2 px stroke in the linked teal asset
    flex items-center gap-2 frame layout: row, align centre, gap 8
    font-extrabold tracking-widest typography asset + letter-spacing
    hidden md:block no equivalent — pick one breakpoint as the canvas, state the choice
    hover: / CSS keyframes no equivalent — out of scope

    Keep the numbers consistent with Tailwind v4's spacing scale (1 unit = 4 px) and say so.

  6. Creation paths. Four short sections: design system (bootstrap above), greenfield screen (from a prompt/spec: shell → regions → contents → styling, committing per screen), code → design (SVG: state the supported subset — rect, circle, path without arcs, text, g, fills, strokes, translate/scale/matrix — and that everything else lands as svg-raw with a reported reason), and image → design (already written; link to it rather than repeating it).

  7. Lossy areas. A flat list stating what will not survive: gradients (single-colour fills or two-stop gradients only), coloured glows/shadows approximations, dashed/compound borders, pseudo-element constructions (folded ribbon tails, decorative overlays), all animation and interaction states, and any font the instance does not ship (naming the substitution policy). Each with the honest failure mode, not just the keyword.

  8. Reference. Keep/extend the pointer index to the vendored docs/ files with one line each.

Keep every instruction operational: name the tool, name the parameter, give the rule. Prefer short sections and tables over prose.

Acceptance Criteria

  • skills/penpot/SKILL.md retains valid frontmatter and is listed by /skills.
  • The bootstrap section states the @theme-first token reading rule, the list-before-create rule, the import-then-link rule, and the no-silent-substitution rule.
  • The token conventions table maps DESIGN.md/@theme names to the exact arguments the tools take, and forbids hex when a matching asset exists.
  • The component conventions require library instances where a component matches, and require naming composed frames otherwise.
  • The composition rules cover one-screen-one-frame, region frames, layout-first with absolute fallback, typography assets for all text, and one commit per screen.
  • The Tailwind → Penpot table covers at least the rows listed above, with numbers consistent with the 4 px spacing scale, and marks the rows that have no equivalent.
  • All four creation paths are documented, with the SVG subset and its svg-raw fallback stated, and the image path cross-referenced rather than duplicated.
  • The lossy-areas list names each limitation and its failure mode (gradients, glows, dashed borders, pseudo-elements, animation, missing fonts).
  • The Reference section points at the vendored docs/ files.
  • No instruction references a tool or parameter that does not exist in the extension.

Test Plan

  1. Load and inspect the skill:

    # in pi
    /skills          # expect penpot listed
    /reload          # no skill-validation errors
    head -10 skills/penpot/SKILL.md
    
  2. Cross-check every tool/parameter named in the skill against the registered tools:

    grep -rn "penpot_" skills/penpot/SKILL.md
    grep -rn 'name: "penpot_' extensions/penpot/src/tools/*.ts
    

    Every name in the skill must appear in the extension (and vice versa: a tool not mentioned should be either intentional or a gap worth filling).

  3. Dry-read the skill against one real DESIGN.md (with an @theme block): confirm the token names in the table can actually be derived from that file, and that following the bootstrap steps would not create duplicate assets on a second run.

## Summary Complete `skills/penpot/SKILL.md`: how to read a `DESIGN.md`, how to bootstrap the Penpot library from it (assets + imported components), the composition rules, the Tailwind → Penpot translation table, the four creation paths, and the lossy areas the agent must not promise. This is the judgement half of the feature — the extension guarantees valid payloads, the skill decides what to build. ## Background **Depends on:** #213, #214 The skill is where an agent's discretion lives, and its value is that it encodes decisions already made rather than leaving them to be re-derived: - **`DESIGN.md` is not a schema.** It is human-authored markdown, and the reference design system is Tailwind + shadcn/ui, so component recipes appear as Tailwind class strings that are *not* Penpot specs. The one machine-readable source is a Tailwind v4 `@theme` block in the project's CSS (`--color-flip7-teal: #2BA8A2;` …), which DESIGN.md may also embed. Read tokens deterministically from there; use the prose for semantics and layout intent. - **Components cannot be read off the page.** They come from the committed library artifact, imported per project and linked, then placed as instances. - **Screens must reference the library by id.** The agent passes names (`colour: "flip7-gold"`, `typography: "h2"`) and the extension resolves ids, which is what makes an asset edit restyle every screen. This step also states the lossy areas plainly, because a skill that overpromises produces silent disappointment: gradients, coloured glows, dashed borders, pseudo-element constructions and all animation have no faithful Penpot equivalent. ## Documentation Required A separate process downloads these into the listed folders before this issue is implemented. Check the folders for the actual reference material before starting. **`docs/reference/tailwindcss/`** - https://tailwindcss.com/docs/theme — the `@theme` directive: `--color-*`, `--font-*`, `--text-*`, `--spacing-*`, `--radius-*` custom properties. This is the source for the token-reading instructions and for the translation table's numbers. - https://tailwindcss.com/docs/adding-custom-styles — custom utilities and arbitrary values, i.e. the class strings that appear in DESIGN.md recipes. - https://tailwindcss.com/docs/functions-and-directives — where `@theme` sits relative to other directives, so the "find the token block" instruction is accurate in a real file. **`docs/reference/penpot-api/`** - https://help.penpot.app/user-guide/design-systems/assets/ — colours and typographies as assets, and how linked styling behaves for a designer. - https://help.penpot.app/user-guide/design-systems/components/ — components and instances, for the "components come from the library" convention. - https://help.penpot.app/user-guide/design-systems/layout/ — flex/grid layout, gap, padding, sizing ("hug" = `auto`), which the composition rules and the translation table both depend on. - https://help.penpot.app/user-guide/design-systems/libraries/ — connecting a library to a consuming file, i.e. the import → link step the convention depends on. - https://help.penpot.app/user-guide/boards/ — boards/frames and their clipping/positioning behaviour. - https://raw.githubusercontent.com/penpot/penpot/2.17.2/common/src/app/common/types/shape.cljc — the layout/sizing field names behind the translation table, so the table points at real properties rather than UI labels. - https://help.penpot.app/user-guide/gradients/ or https://help.penpot.app/user-guide/ — gradient fills, for stating exactly what the gradient row of the translation table can and cannot express. **`docs/reference/svg/`** - https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Element and .../Attribute/d — the honest capability list for the code → design path (what converts, what falls back to `svg-raw`). **`docs/reference/pi-coding-agent/`** - https://pi.dev/docs/latest/skills — frontmatter and structure rules, and how a skill references vendored files. ## Implementation Details Extend `skills/penpot/SKILL.md` (keeping the frontmatter and image → design section from the earlier step, and the Reference section pointing at the vendored docs). Sections to add: 1. **Design-system bootstrap (the shared prerequisite).** Ordered steps: - read `DESIGN.md`; if the project has CSS with a Tailwind v4 `@theme` block, read **that** for tokens (names, hex, type scale, radii) and treat DESIGN.md's prose as semantics; - list what exists (`penpot_list_projects`, `penpot_get_file`, `penpot_list_library`) before creating anything, so a re-run does not duplicate assets; - create the colour and typography assets from the tokens (`penpot_create_color`, `penpot_create_typography`), naming them exactly as the design system does; - import the committed component library (`penpot_import_library`), then link it (`penpot_link_library`) — state explicitly that an imported library is **not** usable until linked; - record the mapping from token name → asset name, and state what to do when DESIGN.md names a colour/type that has no asset (stop and ask, or create it explicitly — never silently substitute a near-match). 2. **Token conventions.** A short, prescriptive table: DESIGN.md token → what the agent passes to the tools (e.g. `--color-flip7-teal` → `colour: "flip7-teal"`; `--text-h2` → `typography: "h2"`). Rule: never pass hex values when a matching asset exists. 3. **Component conventions.** Components come from the library; screens use `penpot_instance_component`. When no library component matches, compose primitives and **name the frame** so it can be promoted to a component later in the UI. Do not fake a component with a loose frame. 4. **Composition rules.** One screen = one root frame; regions as child frames; layout frames wherever Tailwind would use flex (`row`/`column`, gap, padding, align/justify) and absolute positioning only as a fallback; text always via `penpot_add_text` with a typography asset; assets matched against the existing library first (`link_colors` in the SVG path); commit per screen (one commit = one revision); never write outside a designated target. 5. **Tailwind → Penpot translation table.** Include at least: | Tailwind idiom | Penpot equivalent | |---|---| | `rounded-full` | pill radius (half the shorter side) | | `rounded-lg` / `-xl` / `-2xl` | 8 / 12 / 16 px corner radius | | `h-12`, `p-4`, `gap-2` | 48 px height, 16 px padding, 8 px gap | | `bg-gradient-to-br from-… to-…` | gradient fill, two stops, diagonal (lossy — see below) | | `shadow-glow-gold` | drop shadow, gold at ~40 % alpha, ~20 px blur, 4 px y-offset | | `border-2 border-flip7-teal` | 2 px stroke in the linked teal asset | | `flex items-center gap-2` | frame layout: row, align centre, gap 8 | | `font-extrabold tracking-widest` | typography asset + letter-spacing | | `hidden md:block` | **no equivalent** — pick one breakpoint as the canvas, state the choice | | `hover:` / CSS keyframes | **no equivalent** — out of scope | Keep the numbers consistent with Tailwind v4's spacing scale (1 unit = 4 px) and say so. 6. **Creation paths.** Four short sections: **design system** (bootstrap above), **greenfield screen** (from a prompt/spec: shell → regions → contents → styling, committing per screen), **code → design** (SVG: state the supported subset — `rect`, `circle`, `path` without arcs, `text`, `g`, fills, strokes, `translate`/`scale`/`matrix` — and that everything else lands as `svg-raw` with a reported reason), and **image → design** (already written; link to it rather than repeating it). 7. **Lossy areas.** A flat list stating what will not survive: gradients (single-colour fills or two-stop gradients only), coloured glows/shadows approximations, dashed/compound borders, pseudo-element constructions (folded ribbon tails, decorative overlays), all animation and interaction states, and any font the instance does not ship (naming the substitution policy). Each with the honest failure mode, not just the keyword. 8. **Reference.** Keep/extend the pointer index to the vendored `docs/` files with one line each. Keep every instruction operational: name the tool, name the parameter, give the rule. Prefer short sections and tables over prose. ## Acceptance Criteria - [ ] `skills/penpot/SKILL.md` retains valid frontmatter and is listed by `/skills`. - [ ] The bootstrap section states the `@theme`-first token reading rule, the list-before-create rule, the import-then-**link** rule, and the no-silent-substitution rule. - [ ] The token conventions table maps DESIGN.md/`@theme` names to the exact arguments the tools take, and forbids hex when a matching asset exists. - [ ] The component conventions require library instances where a component matches, and require naming composed frames otherwise. - [ ] The composition rules cover one-screen-one-frame, region frames, layout-first with absolute fallback, typography assets for all text, and one commit per screen. - [ ] The Tailwind → Penpot table covers at least the rows listed above, with numbers consistent with the 4 px spacing scale, and marks the rows that have no equivalent. - [ ] All four creation paths are documented, with the SVG subset and its `svg-raw` fallback stated, and the image path cross-referenced rather than duplicated. - [ ] The lossy-areas list names each limitation and its failure mode (gradients, glows, dashed borders, pseudo-elements, animation, missing fonts). - [ ] The Reference section points at the vendored `docs/` files. - [ ] No instruction references a tool or parameter that does not exist in the extension. ## Test Plan 1. Load and inspect the skill: ```bash # in pi /skills # expect penpot listed /reload # no skill-validation errors head -10 skills/penpot/SKILL.md ``` 2. Cross-check every tool/parameter named in the skill against the registered tools: ```bash grep -rn "penpot_" skills/penpot/SKILL.md grep -rn 'name: "penpot_' extensions/penpot/src/tools/*.ts ``` Every name in the skill must appear in the extension (and vice versa: a tool not mentioned should be either intentional or a gap worth filling). 3. Dry-read the skill against one real `DESIGN.md` (with an `@theme` block): confirm the token names in the table can actually be derived from that file, and that following the bootstrap steps would not create duplicate assets on a second run.
david closed this issue 2026-09-15 07:57:00 +00:00
Author
Owner

pi-loop opened and merged a pull request for this issue: #248

pi-loop opened and merged a pull request for this issue: https://git.excelera.net/david/pi-extensions-and-skills/pulls/248
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
david/pi-extensions-and-skills#215
No description provided.