pencil-skill

📁 de-novo/pencil-skill 📅 3 days ago
10
总安装量
10
周安装量
#28919
全站排名
安装命令
npx skills add https://github.com/de-novo/pencil-skill --skill pencil-skill

Agent 安装分布

codex 9
opencode 8
gemini-cli 8
github-copilot 8
amp 8
kimi-cli 8

Skill 文档

pencil-skill

1) Overview

Pencil is a design tool that uses the JSON-based .pen format. Because .pen is Git-friendly, it is ideal for agents to create and modify directly. The key is not generic JSON syntax, but Pencil-specific rules (ref, slot, textGrowth, variable binding).

2) Core Document Structure

{
  "version": "2.8",
  "themes": {
    "mode": [
      "light",
      "dark"
    ]
  },
  "variables": {
    "color.surface": {
      "type": "color",
      "value": [
        {
          "theme": {
            "mode": "light"
          },
          "value": "#FFFFFF"
        },
        {
          "theme": {
            "mode": "dark"
          },
          "value": "#111827"
        }
      ]
    }
  },
  "children": []
}
  • version and children are required
  • themes and variables are optional, but practically essential for a design system

3) List of Object Types

  • rectangle: basic rectangle
  • ellipse: circle/arc
  • line: line
  • polygon: polygon
  • path: path geometry
  • text: text
  • frame: layout container + can declare slots
  • group: group container
  • note: annotation
  • prompt: prompt memo
  • context: context memo
  • icon_font: icon-font-based vector icon
  • ref: reusable component instance

4) Layout (Summary)

Remember only the core properties:

  • layout: none | vertical | horizontal
  • gap, padding
  • justifyContent: start | center | end | space_between | space_around
  • alignItems: start | center | end

Gotcha:

  • Child x, y values are effectively ignored inside flex (vertical/horizontal) containers

Practical frame properties

Property Type Description
clip boolean Clips content outside the frame bounds when true. Default is false

General entity properties (all node types)

Property Type Description
enabled boolean Hides the node when false (applies to all entities, not frame-specific)
[
  {
    "type": "frame",
    "id": "modal-overlay",
    "clip": true,
    "layout": "vertical"
  },
  {
    "type": "frame",
    "id": "hidden-panel",
    "enabled": false,
    "layout": "vertical"
  }
]

5) SizingBehavior

  • fit_content
  • fill_container
  • fit_content(${number})

width and height can use numbers, variables, or the SizingBehavior values above.

6) Graphics Essentials

  • fill: color / gradient / image / mesh_gradient
  • stroke: align, thickness, join, cap, dashPattern, fill
  • effect: blur, background_blur, shadow

Color values are recommended in hex format (#RGB, #RRGGBB, #RRGGBBAA).

7) Text Rules (Important)

  • Set textGrowth first for text
  • textGrowth: auto | fixed-width | fixed-width-height
  • If you set width/height without textGrowth, behavior may be ignored or inconsistent

8) Components (reusable + ref + descendants + slot)

Defining a component

  • Add reusable: true to a frame (or another entity)
  • Its id acts as the component key

Creating an instance

  • type: "ref"
  • ref: "<reusable id>"

descendants override

  • Keys are child id values
  • Access deep children with slash paths: "container/button/label"

slot pattern

  • Declare slot: ["body"] in the component
  • Create an internal frame with name: "body"
  • Inject content through ref.children

9) Variables

Binding format:

  • "$variable.name"

Example:

{
  "fill": "$color.surface",
  "padding": "$space.card.padding"
}

Validation points:

  • The key after $ must exist in variables
  • When using theme-based variable values, they must match themes axis/value

10) IconFont

Supported families:

  • lucide
  • feather
  • Material Symbols Outlined
  • Material Symbols Rounded
  • Material Symbols Sharp
  • phosphor

11) Forbidden Patterns

Pattern Result
/ in id (e.g., "a/b") ❌ invalid
Duplicate id values in the same file ❌ invalid
ref points to a non-existent reusable id ❌ invalid
width/height on text without textGrowth ⚠️ warning (may be ignored)
"$unknown.var" reference ⚠️ warning (unresolved variable)

Critical Rules

These rules prevent the most common mistakes agents make.

Rule 1: Component reuse is mandatory

If a matching reusable component exists, you must reuse it with ref.

  1. Check available components with search-nodes.mjs --reusable
  2. If a matching component exists, insert it as a ref instance
  3. Customize with descendants
  4. Create a new one only when no match exists

Rule 2: Variables are mandatory

No hardcoding. Colors, spacing, and typography must use variables.

  1. Check existing variables with get-variables.mjs
  2. Reference values in "$variable.name" format
  3. If a new variable is needed, register it first with set-variables.mjs

Rule 3: Prevent text overflow

For every text node:

  1. Set textGrowth first (auto or fixed-width)
  2. If the parent frame has layout, use fill_container for width
  3. Validate with validate-pen.mjs after editing

Rule 4: Always validate after changes

After each modification:

  1. Validate structural/lint with validate-pen.mjs
  2. Verify structure with read-tree.mjs --depth 2

Rule 5: Reuse assets

For logos, images, and icons:

  1. Search existing assets with search-nodes.mjs --name "logo|brand|icon"
  2. If found, duplicate using batch-design.mjs copy op
  3. Create new assets only when none exist

12) Required Checklist for Creation

  • Root version and children exist
  • id is unique and does not use slashes
  • Target reusable component for each ref exists
  • variables references match real keys ($...)
  • textGrowth is set before using width/height on text
  • When using slot, confirm slot declaration, name frame, and ref.children injection relationship
  • Check theme axis/value consistency when needed

Property Aliases

The schema defines both singular and plural forms in $defs. On node properties, the canonical key is singular:

  • fill (value can be single fill or array)
  • stroke (value can be single stroke or array)
  • effect (value can be single effect or array)

Scripts accept plural forms (fills, strokes, effects) and normalize them to singular keys on write.

AGENTS.md (Agent Guide)

AGENTS.md is a concise guide with rule summaries and references to individual rules/*.md files for full details. To regenerate after editing rules: node scripts/compile-agents.mjs

CLI Tools

These scripts manipulate .pen files directly. They work without MCP.

Read Tools

Script Purpose Usage
read-tree.mjs Print node tree structure node scripts/read-tree.mjs file.pen [--depth 2] [--id nodeId]
search-nodes.mjs Search nodes node scripts/search-nodes.mjs file.pen --type frame [--reusable] [--name regex]
get-variables.mjs View variables/themes node scripts/get-variables.mjs file.pen [--format json]
find-space.mjs Find empty-space coordinates node scripts/find-space.mjs file.pen --width 300 --height 200

Write Tools

Script Purpose Usage
batch-design.mjs Insert/update/delete/move/copy nodes node scripts/batch-design.mjs file.pen --ops '[{"op":"update","id":"node1","props":{"name":"Header"}}]'
replace-props.mjs Bulk property replacement node scripts/replace-props.mjs file.pen --match '{"fill":"#FF0000"}' --replace '{"fill":"$color.primary"}'
set-variables.mjs Add/update variables node scripts/set-variables.mjs file.pen --var 'name=type:value'

set-variables.mjs theme syntax (@theme):

# Single value
node scripts/set-variables.mjs file.pen --var 'color.primary=color:#0D9488'

# Per-theme variable setting — @theme syntax
node scripts/set-variables.mjs file.pen --var 'color.bg=color:#FFFFFF@light,#0F172A@dark'
node scripts/set-variables.mjs file.pen --var 'space.md=number:12'

Validation Tool

Script Purpose Usage
validate-pen.mjs Structural validation + value-type checks + lint node scripts/validate-pen.mjs file.pen

batch-design Operations

batch-design.mjs accepts operations as a JSON array:

insert — Insert a new node

{
  "op": "insert",
  "parentId": "frame-1",
  "node": {
    "type": "text",
    "id": "title",
    "content": "Hello",
    "textGrowth": "auto"
  }
}

update — Update properties (deep merge)

{
  "op": "update",
  "id": "title",
  "props": {
    "content": "Updated",
    "fill": "$color.primary"
  }
}

delete — Delete a node

{
  "op": "delete",
  "id": "title"
}

move — Move to another parent

{
  "op": "move",
  "id": "title",
  "toParentId": "frame-2",
  "index": 0
}

copy — Duplicate a node

{
  "op": "copy",
  "id": "card-1",
  "newId": "card-2",
  "toParentId": "grid"
}

Notes:

  • toParentId is optional. If omitted, the copied node is inserted at the root level.
  • During copy, all internal child ids must remain unique → using a newId prefix is recommended
  • Do not send too many ops at once (25 or fewer recommended)
  • Backup is automatically created (.pen.bak)

Standard Workflow

1. read-tree.mjs          → Inspect current structure
2. search-nodes.mjs       → Search reusable components
3. get-variables.mjs      → Check variables/themes
4. find-space.mjs         → Calculate frame placement coordinates
5. batch-design.mjs       → Create/modify nodes
6. validate-pen.mjs       → Validate results

Design Rules

Required rules for production-grade design. 41 rules, 8 categories.

Rule Categories by Priority

Priority Category Impact Prefix Rules
1 Layout & Overflow CRITICAL layout- 8
2 Design Tokens CRITICAL token- 5
3 Anti-AI Aesthetic HIGH aesthetic- 6
4 Component System HIGH component- 5
5 Typography MEDIUM typo- 5
6 Color System MEDIUM color- 4
7 Spacing System MEDIUM spacing- 4
8 Showcase & Style Guide MEDIUM showcase- 4

Quick Reference

1. Layout & Overflow (CRITICAL)

  • layout-auto-layout — Auto Layout is required for all containers
  • layout-sizing — width/height rules by scenario
  • layout-overflow — overflow prevention checklist
  • layout-responsive — responsive simulation (separate frame)
  • layout-spacing-consistency — gap/padding consistency
  • layout-z-order — Z-order and overlay placement
  • layout-no-overlap — prevent element overlap
  • layout-canvas-placement — Top-level canvas placement, no layer overlap

2. Design Tokens (CRITICAL)

  • token-naming — naming format: $category.purpose.variant
  • token-semantic-colors — required semantic color system
  • token-theme-required — light/dark themes required
  • token-no-hardcode — no hardcoding
  • token-workflow — token setup workflow

3. Anti-AI Aesthetic (HIGH)

  • aesthetic-layout — avoid AI-looking layouts
  • aesthetic-typography — avoid AI-looking type choices
  • aesthetic-color — avoid AI-looking colors
  • aesthetic-decoration — avoid AI-looking decoration
  • aesthetic-content — avoid AI-looking content
  • aesthetic-checklist — self-check checklist

4. Component System (HIGH)

  • component-atomic — apply Atomic Design
  • component-naming — Figma-standard naming
  • component-variant — variant patterns
  • component-slot — slot patterns
  • component-reuse-first — component reuse first

5. Typography (MEDIUM)

  • typo-scale — define type scale
  • typo-weight — font-weight usage rules
  • typo-pairing — type pairing guide
  • typo-line-height — line-height rules
  • typo-text-rules — text layout rules

6. Color System (MEDIUM)

  • color-semantic — semantic color system
  • color-accessibility — WCAG 2.1 AA accessibility
  • color-ratio — 60-30-10 color ratio
  • color-dark-mode — dark mode rules

7. Spacing System (MEDIUM)

  • spacing-8pt-grid — 8pt grid system
  • spacing-proximity — proximity principle
  • spacing-padding — padding system
  • spacing-forbidden — forbidden patterns

8. Showcase & Style Guide (MEDIUM)

  • showcase-pre-design — required pre-design process
  • showcase-design-system — design-system-first principle
  • showcase-frame — showcase frame pattern
  • showcase-final-checklist — final QA checklist

How to Use

Check each individual rule file for detailed explanations and code examples:

rules/layout-auto-layout.md
rules/token-naming.md
rules/aesthetic-layout.md

Agent guide with rule summaries: AGENTS.md — full rules in rules/*.md

References

Schema & Types

Conversion Guide

Examples