pencil-skill について
pencil-skillは、AgentによるPencilのJSONベースの`.pen`デザインファイル作成・編集を支援します。形式固有の規則、コンポーネント再利用、変数、検証を扱い、MCPなしで動くCLIスクリプトも備えています。
主な機能
- 01`.pen`文書とノードの規則
- 02コンポーネント参照と子孫の上書き
- 03変数とテーマのバインド
- 04CLIによる読み書きと検証
- 05レイアウト、テキスト、デザイン規範
活用シーン
- 01AgentでPencilデザインを作成・編集
- 02コンポーネントを再利用しデザイン変数を適用
- 03文書構造とノードを確認
- 04編集後にレイアウトとテキスト設定を検証
MCP 対応
スクリプトは`.pen`ファイルを直接操作し、MCPなしで動作します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ de-novo/ pencil-skill --skill pencil-skillインストール後、Claude Code で/pencil-skillを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
.gitignorepackage.jsonLICENSEAGENTS.mdREADME.mdassets/example-card.penreddit-ui.penreferences/component-patterns.mdpen-schema.jsonpen-to-tailwind.mdpen-types.tsrules/aesthetic-checklist.mdaesthetic-content.mdaesthetic-color.mdaesthetic-typography.mdaesthetic-decoration.mdaesthetic-layout.mdcolor-ratio.mdcolor-dark-mode.mdcolor-accessibility.mdcolor-semantic.mdcomponent-atomic.mdcomponent-naming.mdcomponent-variant.mdcomponent-slot.mdlayout-auto-layout.mdlayout-no-overlap.mdlayout-overflow.mdlayout-canvas-placement.mdcomponent-reuse-first.md詳細
pencil-skill
1) 概要
Pencil は、JSON ベースの .pen 形式を使用するデザインツールです。
.pen は Git で扱いやすいため、エージェントが直接作成・変更するのに最適です。
重要なのは一般的な JSON 構文ではなく、Pencil 固有のルール(ref、slot、textGrowth、変数バインディング)です。
2) コアドキュメント構造
{
"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とchildrenは必須ですthemesとvariablesは省略可能ですが、デザインシステムには実質的に不可欠です
3) オブジェクトタイプの一覧
rectangle:基本的な長方形ellipse:円/円弧line:線polygon:ポリゴンpath:パスジオメトリtext:テキストframe:レイアウトコンテナー。スロットも宣言できますgroup:グループコンテナーnote:注釈prompt:プロンプトメモcontext:コンテキストメモicon_font:アイコンフォントベースのベクターアイコンref:再利用可能なコンポーネントのインスタンス
4) レイアウト(概要)
コアプロパティだけを覚えておきましょう。
layout:none | vertical | horizontalgap、paddingjustifyContent:start | center | end | space_between | space_aroundalignItems:start | center | end
注意点:
- フレックス(
vertical/horizontal)コンテナー内では、子のx、yの値は実質的に無視されます
実用的なフレームプロパティ
| プロパティ | 型 | 説明 |
|---|---|---|
clip | boolean | true の場合、フレームの境界外にあるコンテンツをクリップします。デフォルトは false です |
一般的なエンティティプロパティ(すべてのノードタイプ)
| プロパティ | 型 | 説明 |
|---|---|---|
enabled | boolean | false の場合、ノードを非表示にします(フレーム固有ではなく、すべてのエンティティに適用されます) |
[
{
"type": "frame",
"id": "modal-overlay",
"clip": true,
"layout": "vertical"
},
{
"type": "frame",
"id": "hidden-panel",
"enabled": false,
"layout": "vertical"
}
]
5) SizingBehavior
fit_contentfill_containerfit_content(${number})
width と height には、数値、変数、または上記の SizingBehavior の値を使用できます。
6) グラフィックスの基本
fill:色/グラデーション/画像/mesh_gradientstroke:align、thickness、join、cap、dashPattern、filleffect:blur、background_blur、shadow
色の値には、16 進数形式(#RGB、#RRGGBB、#RRGGBBAA)を推奨します。
7) テキストのルール(重要)
textでは、最初にtextGrowthを設定しますtextGrowth:auto | fixed-width | fixed-width-heighttextGrowthを設定せずにwidth/heightを設定すると、動作が無視されたり、一貫しなくなったりする場合があります
8) コンポーネント(reusable + ref + descendants + slot)
コンポーネントの定義
frame(または別のエンティティ)にreusable: trueを追加します- その
idがコンポーネントのキーになります
インスタンスの作成
type: "ref"ref: "<reusable id>"
descendants のオーバーライド
- キーには子の
id値を使用します - スラッシュ区切りのパスで深い階層の子にアクセスします:
"container/button/label"
slot パターン
- コンポーネントに
slot: ["body"]を宣言します - 内部フレームを
name: "body"で作成します ref.childrenを通じてコンテンツを挿入します
9) 変数
バインディング形式:
"$variable.name"
例:
{
"fill": "$color.surface",
"padding": "$space.card.padding"
}
検証項目:
$の後のキーがvariablesに存在している必要があります- テーマベースの変数値を使用する場合は、
themesの軸/値と一致している必要があります
10) IconFont
対応ファミリー:
lucidefeatherMaterial Symbols OutlinedMaterial Symbols RoundedMaterial Symbols Sharpphosphor
11) 禁止パターン
| パターン | 結果 |
|---|---|
id に / を使用する(例:"a/b") | ❌ 無効 |
同じファイル内で id 値が重複している | ❌ 無効 |
ref が存在しない reusable id を参照している | ❌ 無効 |
textGrowth が設定されていない text に width/height を設定する | ⚠️ 警告(無視される場合があります) |
"$unknown.var" を参照する | ⚠️ 警告(未解決の変数) |
重要なルール
これらのルールにより、エージェントがよく犯すミスを防げます。
ルール 1:コンポーネントの再利用は必須です
一致する再利用可能なコンポーネントが存在する場合、必ず ref で再利用してください。
search-nodes.mjs --reusableで利用可能なコンポーネントを確認します- 一致するコンポーネントがある場合、
refインスタンスとして挿入します descendantsでカスタマイズします- 一致するものがない場合に限り、新しいコンポーネントを作成します
ルール 2:変数は必須です
ハードコードは禁止です。 色、間隔、タイポグラフィには変数を使用してください。
get-variables.mjsで既存の変数を確認します"$variable.name"形式で値を参照します- 新しい変数が必要な場合は、まず
set-variables.mjsで登録します
ルール 3:テキストのはみ出しを防止します
すべてのテキストノードについて、次の手順を実行します。
- 最初に
textGrowth(autoまたはfixed-width)を設定します - 親フレームにレイアウトがある場合は、幅に
fill_containerを使用します - 編集後に
validate-pen.mjsで検証します
ルール 4:変更後は必ず検証します
変更のたびに、次の手順を実行します。
validate-pen.mjsで構造とリントを検証しますread-tree.mjs --depth 2で構造を確認します
ルール 5:アセットを再利用します
ロゴ、画像、アイコンについて、次の手順を実行します。
search-nodes.mjs --name "logo|brand|icon"で既存のアセットを検索します- 見つかった場合は、
batch-design.mjsのcopy操作で複製します - 既存のアセットがない場合に限り、新しいアセットを作成します
12)作成時の必須チェックリスト
- ルートに
versionとchildrenが存在する -
idが一意で、スラッシュを含まない - 各
refの参照先となる再利用可能なコンポーネントが存在する -
variablesの参照が実在するキー($...)と一致する - テキストに
width/heightを使用する前にtextGrowthを設定している - スロットを使用する場合は、
slot宣言、nameフレーム、ref.childrenの挿入関係を確認する - 必要に応じてテーマの軸と値の整合性を確認する
プロパティのエイリアス
スキーマの $defs では、単数形と複数形の両方を定義しています。
ノードのプロパティでは、正規のキーは単数形です。
fill(値には単一の塗りつぶし、または配列を指定できます)stroke(値には単一の線、または配列を指定できます)effect(値には単一の効果、または配列を指定できます)
スクリプトは複数形(fills、strokes、effects)を受け付け、書き込み時に単数形のキーへ正規化します。
AGENTS.md(エージェントガイド)
AGENTS.md は、ルールの概要と、詳細を記載した個別の rules/*.md ファイルへの参照をまとめた簡潔なガイドです。ルールの編集後に再生成するには、次を実行します。node scripts/compile-agents.mjs
CLI ツール
これらのスクリプトは .pen ファイルを直接操作します。MCP がなくても動作します。
読み取りツール
| スクリプト | 目的 | 使用方法 |
|---|---|---|
read-tree.mjs | ノードツリー構造を出力 | node scripts/read-tree.mjs file.pen [--depth 2] [--id nodeId] |
search-nodes.mjs | ノードを検索 | node scripts/search-nodes.mjs file.pen --type frame [--reusable] [--name regex] |
get-variables.mjs | 変数/テーマを表示 | node scripts/get-variables.mjs file.pen [--format json] |
find-space.mjs | 空きスペースの座標を検索 | node scripts/find-space.mjs file.pen --width 300 --height 200 |
書き込みツール
| スクリプト | 目的 | 使用方法 |
|---|---|---|
batch-design.mjs | ノードの挿入/更新/削除/移動/複製 | node scripts/batch-design.mjs file.pen --ops '[{"op":"update","id":"node1","props":{"name":"Header"}}]' |
replace-props.mjs | プロパティを一括置換 | node scripts/replace-props.mjs file.pen --match '{"fill":"#FF0000"}' --replace '{"fill":"$color.primary"}' |
set-variables.mjs | 変数を追加/更新 | node scripts/set-variables.mjs file.pen --var 'name=type:value' |
set-variables.mjs のテーマ構文(@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'
検証ツール
| スクリプト | 目的 | 使用方法 |
|---|---|---|
validate-pen.mjs | 構造検証+値の型チェック+リント | node scripts/validate-pen.mjs file.pen |
batch-design の操作
batch-design.mjs は、JSON 配列で操作を受け付けます。
insert — 新しいノードを挿入
{
"op": "insert",
"parentId": "frame-1",
"node": {
"type": "text",
"id": "title",
"content": "Hello",
"textGrowth": "auto"
}
}
update — プロパティを更新(ディープマージ)
{
"op": "update",
"id": "title",
"props": {
"content": "Updated",
"fill": "$color.primary"
}
}
delete — ノードを削除
{
"op": "delete",
"id": "title"
}
move — 別の親ノードへ移動
{
"op": "move",
"id": "title",
"toParentId": "frame-2",
"index": 0
}
copy — ノードを複製
{
"op": "copy",
"id": "card-1",
"newId": "card-2",
"toParentId": "grid"
}
注:
toParentIdは省略可能です。省略した場合、複製したノードはルートレベルに挿入されます。- コピー時は、すべての子ノードの ID を一意にする必要があります →
newIdのプレフィックスを使用することを推奨します - 一度に送信する操作が多くなりすぎないようにしてください(25 件以下を推奨)
- バックアップは自動的に作成されます(
.pen.bak)
標準ワークフロー
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
デザインルール
本番環境向けのデザインに必要なルールです。8 カテゴリーに 41 のルールがあります。
優先度別ルールカテゴリー
| 優先度 | カテゴリー | 影響度 | プレフィックス | ルール数 |
|---|---|---|---|---|
| 1 | レイアウトとオーバーフロー | CRITICAL | layout- | 8 |
| 2 | デザイントークン | CRITICAL | token- | 5 |
| 3 | AI らしさを避けるデザイン | HIGH | aesthetic- | 6 |
| 4 | コンポーネントシステム | HIGH | component- | 5 |
| 5 | タイポグラフィ | MEDIUM | typo- | 5 |
| 6 | カラーシステム | MEDIUM | color- | 4 |
| 7 | 余白システム | MEDIUM | spacing- | 4 |
| 8 | ショーケースとスタイルガイド | MEDIUM | showcase- | 4 |
クイックリファレンス
1. レイアウトとオーバーフロー(CRITICAL)
layout-auto-layout— すべてのコンテナで自動レイアウトを使用するlayout-sizing— シナリオ別の幅/高さのルールlayout-overflow— オーバーフロー防止チェックリストlayout-responsive— レスポンシブのシミュレーション(別フレーム)layout-spacing-consistency— gap/padding の一貫性layout-z-order— Z オーダーとオーバーレイの配置layout-no-overlap— 要素の重なりを防ぐlayout-canvas-placement— 最上位キャンバスの配置、レイヤーの重なりを防止
2. デザイントークン(CRITICAL)
token-naming— 命名形式:$category.purpose.varianttoken-semantic-colors— 必須のセマンティックカラーシステムtoken-theme-required— ライト/ダークテーマが必須token-no-hardcode— ハードコードしないtoken-workflow— トークン設定のワークフロー
3. AI らしさを避けるデザイン(HIGH)
aesthetic-layout— AI らしく見えるレイアウトを避けるaesthetic-typography— AI らしく見える書体の選択を避けるaesthetic-color— AI らしく見える色を避けるaesthetic-decoration— AI らしく見える装飾を避けるaesthetic-content— AI らしく見えるコンテンツを避けるaesthetic-checklist— 自己確認用チェックリスト
4. コンポーネントシステム(HIGH)
component-atomic— アトミックデザインを適用するcomponent-naming— Figma 標準の命名component-variant— バリアントのパターンcomponent-slot— スロットのパターンcomponent-reuse-first— コンポーネントの再利用を優先する
5. タイポグラフィ(MEDIUM)
typo-scale— 文字サイズのスケールを定義するtypo-weight— font-weight の使用ルールtypo-pairing— 書体の組み合わせガイドtypo-line-height— line-height のルールtypo-text-rules— テキストレイアウトのルール
6. カラーシステム(MEDIUM)
color-semantic— セマンティックカラーシステムcolor-accessibility— WCAG 2.1 AA アクセシビリティcolor-ratio— 60-30-10 の配色比率color-dark-mode— ダークモードのルール
7. 余白システム(MEDIUM)
spacing-8pt-grid— 8pt グリッドシステムspacing-proximity— 近接の原則spacing-padding— padding システムspacing-forbidden— 禁止パターン
8. ショーケースとスタイルガイド(MEDIUM)
showcase-pre-design— 必須のデザイン前プロセスshowcase-design-system— デザインシステム優先の原則showcase-frame— ショーケースフレームのパターンshowcase-final-checklist— 最終 QA チェックリスト
使用方法
各ルールの詳しい説明とコード例については、個別のルールファイルを確認してください。
rules/layout-auto-layout.md
rules/token-naming.md
rules/aesthetic-layout.md
ルールの概要をまとめたエージェントガイド:AGENTS.md — すべてのルールは rules/*.md にあります
参考資料
スキーマと型
- pen-schema.json:公式 JSON Schema(v2.8)
- pen-types.ts:TypeScript の型定義
変換ガイド
- pen-to-tailwind.md:.pen → Tailwind CSS 変換表
- component-patterns.md:UI コンポーネントのパターン
例
- example-card.pen:.pen ファイルの完全な例
- reddit-ui.pen:再利用可能なコンポーネントを使った Reddit 風の 3 列 UI レイアウト