openpencil/packages/pen-ai-skills
Fini f93a9437aa fix(ai): edge-padding detector skips when any section has its own h-padding
User-reported 2026-05-11 mobile food design — the page had Header
(search bar + cart), Categories (icon row), and Bottom Nav each
carrying their own horizontal padding by design, but Hero section
left its frame edge-to-edge intentionally. Previous version saw
Hero's missing padding + ≥1 offending child and flagged → root got
+16px gutter on top of every per-section-padded sibling, producing
a visible double-inset / "边距过大" complaint.

Treat any non-fullbleed content child carrying its own h-padding as
a signal that the design has chosen the per-section gutter mode.
Once that signal is observed, skip the root-level recommendation
entirely so we don't double up. Hero / banner / image-bleed roles
remain filtered out of the signal pass via FULL_BLEED_ROLES so a
hero with no padding still doesn't activate the detector.

Test: covers the user's exact pattern (categories + content with
per-section padding + hero without) — previous expectation flipped
from "fire" to "do not fire".
2026-05-11 00:16:40 +08:00
..
corpus Merge origin/v0.8.0 into feat/rust-ification 2026-05-03 21:00:00 +08:00
skills Merge branch 'v0.8.0' of github.com:ZSeven-W/openpencil into v0.8.0 2026-05-10 21:37:11 +08:00
src fix(ai): edge-padding detector skips when any section has its own h-padding 2026-05-11 00:16:40 +08:00
.gitignore V0.5.2 (#82) 2026-03-24 21:16:28 +08:00
CLAUDE.md V0.7.0 (#95) 2026-04-11 23:25:13 +08:00
LICENSE V0.7.1 (#102) 2026-04-13 21:30:23 +08:00
package.json Merge branch 'v0.8.0' of github.com:ZSeven-W/openpencil into v0.8.0 2026-05-10 21:37:11 +08:00
README.md V0.7.1 (#102) 2026-04-13 21:30:23 +08:00
tsconfig.json V0.5.2 (#82) 2026-03-24 21:16:28 +08:00
vite-plugin-skills.ts V0.7.2-bugfix (#109) 2026-04-14 21:42:56 +08:00

@zseven-w/pen-ai-skills

AI prompt skill engine for OpenPencil — phase-driven prompt loading with intent matching, token budgets, and design memory.

Install

npm install @zseven-w/pen-ai-skills
# or
bun add @zseven-w/pen-ai-skills

Overview

When an LLM generates designs for OpenPencil, it needs context: PenNode schema, layout rules, semantic roles, icon names, style guides, and more. Loading everything at once wastes tokens. This package solves that with phase-based skill resolution — only the relevant prompts are loaded for each stage of the design workflow.

User message ──► resolveSkills(phase, message, options)
                      │
                      ├─ Phase filter (planning / generation / validation / maintenance)
                      ├─ Intent matching (landing page? dashboard? form? mobile app?)
                      ├─ Flag-based activation (hasDesignMd? hasVariables?)
                      ├─ Priority sorting (higher priority = selected first)
                      └─ Token budget trimming (cap per phase)
                      │
                      ▼
               AgentContext { skills[], memory, budget }

Quick Start

import { resolveSkills } from '@zseven-w/pen-ai-skills';

// Generation phase — user wants a landing page
const ctx = resolveSkills('generation', 'design a SaaS landing page', {
  flags: { hasDesignMd: false, hasVariables: true },
});

// ctx.skills contains the relevant prompts
for (const skill of ctx.skills) {
  console.log(`${skill.meta.name} (${skill.tokenCount} tokens)`);
  // schema (800 tokens)
  // layout (600 tokens)
  // landing-page (400 tokens)
  // ...
}

// Budget tracking
console.log(`${ctx.budget.used} / ${ctx.budget.max} tokens used`);

Phases

Phase Budget Purpose
planning 4,000 Analyze requirements, plan sections, choose style
generation 8,000 Generate PenNode trees with full design knowledge
validation 3,000 Check layout, spacing, accessibility, best practices
maintenance 5,000 Edit existing nodes, delete, reparent, modify properties

Skill Categories

Base Skills

Core design principles and workflow guides. Always loaded for their phase.

Domain Skills

Activated by intent matching — keywords in the user message trigger specialized knowledge:

Skill Triggers
Landing page landing, marketing, homepage
Dashboard dashboard, admin, analytics
Form UI form, login, signup, input
Mobile app mobile, app, screen, ios, android
CJK typography chinese, japanese, korean, CJK characters

Knowledge Skills

Reference material loaded by priority until the token budget is exhausted:

  • Role definitions — semantic roles (button, input, card, navbar) and their auto-defaults
  • Icon catalog — Lucide/Feather icon naming conventions
  • Design examples — complete component patterns in DSL
  • Copywriting — headline length, CTA text, placeholder copy rules
  • Code generation guides — React, Vue, Svelte, Flutter, SwiftUI, Compose, React Native, HTML

Design Memory

Track context across multi-turn generation sessions:

Document Context

import { createDesignContext, contextToPromptString } from '@zseven-w/pen-ai-skills';

const ctx = createDesignContext('/path/to/doc.op');
// Accumulates: palette, typography, spacing, aesthetic, page structure

const prompt = contextToPromptString(ctx);
// "Design system: palette #2563EB, #F8FAFC; font Space Grotesk / Inter; ..."

Generation History

import { createHistoryEntry, getRecentEntries } from '@zseven-w/pen-ai-skills';

const entry = createHistoryEntry({
  documentPath: '/path/to/doc.op',
  prompt: 'design a pricing section',
  phase: 'generation',
  skillsUsed: ['schema', 'layout', 'landing-page'],
  nodeCount: 28,
  sectionTypes: ['pricing'],
});

// Feed recent history back to prevent repetitive designs
const recent = getRecentEntries(allEntries, 5);

Diagnostics

Detect common design issues in generated output:

import { detectAllIssues } from '@zseven-w/pen-ai-skills';

const issues = detectAllIssues(document);
// [{ severity: 'warning', category: 'invisible-container', nodeId: 'frame-7', message: '...' }]
Detector Catches
Invisible containers Frames with no fill, stroke, or visual children
Empty paths Path nodes with no d attribute
Text explicit heights Text nodes with hardcoded pixel height (causes overflow)
Sibling inconsistencies Siblings with mixed width strategies in the same layout

Adding a Skill

Create a Markdown file in skills/ with YAML frontmatter:

---
name: my-custom-skill
description: Guidelines for designing checkout flows
phase: [generation, validation]
trigger:
  keywords: [checkout, cart, payment, purchase]
priority: 8
budget: 1500
category: domain
---

## Checkout Flow Design Rules

1. Always show order summary alongside the form
2. Use a single-column layout for payment fields
3. ...

The Vite plugin auto-compiles skills into a TypeScript registry on save during development.

Style Guide

Parse and apply external style guides:

import { parseStyleGuideFile, buildStyleMapping } from '@zseven-w/pen-ai-skills';

const guide = parseStyleGuideFile(markdownContent);
const mappings = buildStyleMapping(guide);
// [{ property: 'fill', from: '#000', to: '$text-primary' }, ...]

License

MIT