skillZs
★ LIVE SKILL TAGS ★
>>> LIVE SKILLS INDEX <<<
* OPEN SOURCE *
NO LOGIN, NO TRACKING
※ REAL INSTALL DATA ※
← back to all skills
penpot/penpot-ai-kit96 installs

penpot-router

Thin dispatcher / entry point for any Penpot request. Use FIRST on any Penpot task to ensure high_level_overview ran, read the user's intent, and route to exactly one target skill or workflow (build a screen, build a slide deck, build a design system, audit accessibility, audit tokens, migrate from Figma, rename layers, code review, extract DESIGN.md, etc.). Never mutates the canvas. Triggers: 'work on this Penpot file', 'help me with Penpot', 'I want to design/build/audit/migrate in Penpot', 'where do I start', 'which skill should I use', 'route this request', ambiguous Penpot asks.

How do I install this agent skill?

npx skills add https://github.com/penpot/penpot-ai-kit --skill penpot-router
view source ↗

Is this agent skill safe to install?

  • Gen Agent Trust Hubpass

    This skill acts as a router for Penpot design tasks. It is generally safe but possesses a standard attack surface for indirect prompt injection by processing external design data (layer names and tokens) from the workspace without explicit sanitization.

  • Socketpass

    No alerts

  • Snykpass

    Risk: LOW · No issues

What does this agent skill do?

penpot-router — the dispatcher

1. Title + How it works

penpot-router is a thin entry point. It does not draw, tokenize, or restructure anything — it reads the user's intent and hands off to exactly one downstream skill or workflow (build a screen, build a slide deck, build a design system, audit, migrate, extract DESIGN.md, …). Every mutation goes through execute_code; validate visually with export_shape; read structure with penpotUtils.shapeStructure (full tool surface: shared/penpot-mcp-tool-reference.md). This skill only ever uses high_level_overview plus read-only execute_code discovery calls (penpotUtils.shapeStructure, penpotUtils.tokenOverview()). Every mutation belongs to the skill it routes to; this router validates nothing visually because it changes nothing. If the host client already auto-selects skills by their description, this router degrades gracefully to documentation — the intent taxonomy in references/01-intent-taxonomy.md becomes a reference map rather than an active dispatcher.

2. The One Rule That Matters Most

Route to exactly one target, and run preflight before doing so. Never start mutating from inside the router, and never fan a single request out to multiple mutating skills in parallel. One request → one preflight (overview + a quick structure/token read) → one target skill or workflow → handoff. If intent is ambiguous between two targets, ask one disambiguating question; do not guess and act.

3. Penpot MCP Tool Reference

Full surface: shared/penpot-mcp-tool-reference.md. The router leans on only two calls:

CallWhy the router uses it
high_level_overviewMandatory session preamble. Must have been called before any routing decision is acted on.
execute_code (read-only)penpotUtils.shapeStructure(penpot.currentPage.root, 2) and penpotUtils.tokenOverview() to sense the current state of the file so routing is grounded in reality, not assumptions.

The router never calls execute_code to create/modify/delete, and never calls export_shape (nothing to validate). Downstream skills own all mutation and validation.

4. Plugin API Essentials

The router touches only read paths: penpot.currentPage, penpot.selection, penpot.library.local.tokens, penpotUtils.shapeStructure, penpotUtils.tokenOverview, penpotUtils.getPages. Gotchas (shared/plugin-api-gotchas.md):

  • #2 token application is async (~100 ms) — never read back a resolved value as authoritative; the router applies no tokens at all, so its only real trap is doing too much. If you are unsure whether a discovery helper exists with a given signature, verify with penpot_api_info (e.g. penpot_api_info("PenpotUtils", "shapeStructure")) rather than guessing.

5. Token-Aware Brief Contract

Before routing, restate the request as a compact contract so the chosen skill inherits a clean brief. Assign the role: "act as a senior design-systems triage lead who never starts work in the wrong flow." Capture:

  • Context — product, audience, and whether a design system already exists in this file (derived from tokenOverview() + shapeStructure).
  • Objective — a single verb-led intent ("build a settings screen", "audit contrast", "migrate the Figma button library"). If the user states two, split and route the primary; queue the rest.
  • Inputs — selected shapes/boards, target page, referenced tokens/components, external refs (code paths, Figma URLs).
  • Constraints — forbidden components, inviolable rules, mode (suggest/review/autofix), scope caps. If the user already said whether to avoid the generic-AI look, forward it as antiSlop: on|off — the build skill then stores it and skips its opt-in question. The router never asks it itself.
  • Acceptance Criteria — what "done" means for the downstream skill (e.g. "WCAG AA contrast ≥ 4.5:1 on body text", "all spacing on the 4px grid", "variant matrix complete for State axis"). The router does not verify these; it forwards them so the target skill can.

The router emits this contract as the handoff payload. It does not invent token values or names — if the request implies new tokens, that is the downstream skill's job (and a human approval gate).

6. Mandatory Workflow

Phase 0 — Discovery (read-only)

Goal: ensure the session is initialized and the file's state is known.

  1. Confirm high_level_overview has been called this session; if not, call it now.
  2. One read-only execute_code call for a shallow state sense:
    return {
      pages: penpotUtils.getPages().map(p => p.name),
      currentPage: penpot.currentPage && penpot.currentPage.name,
      selectionCount: penpot.selection.length,
      selection: penpot.selection.map(s => ({ id: s.id, name: s.name, type: s.type })),
      topLevel: penpotUtils.shapeStructure(penpot.currentPage.root, 1)
    };
    
  3. One read-only call for token state:
    return penpotUtils.tokenOverview();
    

Exit criterion: you know (a) whether tokens/sets exist, (b) what is selected, (c) the page layout at depth 1. ✋ Checkpoint: none needed — read-only — proceed straight to Phase 1.

Phase 1 — Intent classification

Goal: map the user's words to one row of the routing table (§8 / references/01-intent-taxonomy.md). Read the literal request, combine it with the Phase 0 state (e.g. "no tokens exist yet" biases a vague "set up my design system" toward penpot-foundations / the design-system-bootstrap workflow). If the request maps cleanly to one target, continue. If it maps to two or more with comparable confidence, ✋ Checkpoint: ask one disambiguating question (offer the two candidate targets in plain language).

Phase 2 — Handoff

Goal: transfer control with a clean brief.

  1. State the chosen target explicitly ("Routing to penpot-build-screen because…").
  2. Emit the §5 Token-Aware Brief Contract as the payload.
  3. Note any secondary intents queued for later.
  4. Invoke / instruct the target skill. The router's job ends here; it performs no mutations. Exit criterion: exactly one target named, contract emitted, secondary intents queued. ✋ Checkpoint (conditional): ask "Routing to X — confirm or redirect?" only when (a) Phase 1 was ambiguous (two candidates with comparable confidence), or (b) the target is an expensive mutating flow on a file with existing content (a migration, a bootstrap over a mature system, anything that will restructure components). For a clean, unambiguous match, state the route and proceed — the target skill's own Phase-0 checkpoint is the user's natural review point; a second confirmation here is friction, not safety.

7. Critical Rules

  1. Always confirm high_level_overview ran before acting on a route. No routing decision is executed in a session where the overview was skipped.
  2. One target per request. Split multi-intent requests; route the primary, queue the rest.
  3. Read-only only. The router never calls a mutating execute_code and never calls export_shape.
  4. No guessing on ambiguity. Two plausible targets → one question, not a coin flip.
  5. Ground the route in file state. Use Phase 0 reads to break ties (empty file vs. mature system).
  6. Forward the brief verbatim. Do not silently drop constraints or acceptance criteria.
  7. Degrade to documentation. If the host already routes by description, do not duplicate-dispatch; serve the taxonomy as a map and step aside.
  8. Default mode = suggest. The router proposes a route; it owns no canvas changes.

8. Domain Architecture — the routing table

The router's product is a decision, not a canvas artifact. The decision space is the table below. Full phrasing map and fallbacks: references/01-intent-taxonomy.md.

Skills

IntentTarget skillExample user phrasings
Establish tokens / foundations (color, spacing, type, radius scales; themes)penpot-foundations"set up our design tokens", "create a color + spacing scale", "add a dark theme", "bootstrap foundations"
Build / extend reusable components & variantspenpot-component-factory"make a Button component with variants", "build an Input with states", "turn this into a component", "add a Size axis"
Assemble a screen/view from brief + existing systempenpot-build-screen"design a settings screen", "lay out a dashboard", "build the pricing page from this brief"
Build a screen/view from code/markuppenpot-build-from-code"create this React page in Penpot", "push this component's JSX to a board", "build the screen to match this code"
Design a presentation / slide deck from a briefpenpot-build-deck"create a presentation", "build a slide deck", "pitch deck", "make slides for this talk", "turn this outline into slides"
Document/annotate a design for handoffpenpot-document-handoff"document this design", "annotate this screen", "prepare this for handoff", "add observation notes", "create a critique card", "explain this flow for devs"
Accessibility audit (WCAG)penpot-audit-accessibility"check accessibility", "WCAG AA audit", "contrast check", "are touch targets big enough", "a11y review"
Token governance auditpenpot-audit-tokens"find hardcoded colors", "audit token usage", "what's off the 4px grid", "find orphan/unused tokens"
Compare design vs. code (drift)penpot-design-to-code-review"does this design match the code", "design-to-code review", "find drift between Penpot and the component"
Extract a portable DESIGN.md spec from the filepenpot-design-md"generate a DESIGN.md", "export our design guidelines as markdown", "style guide file for our coding agent"
Import / migrate from Figmapenpot-migrate"migrate this Figma file", "import from Figma", "bring our Figma library into Penpot"
Check / steer a design away from the generic-AI lookpenpot-anti-slop"does this look AI-generated", "anti-slop check", "make it feel less generic", "¿parece hecho por IA?", "evita la estética IA"
Rename layers semanticallypenpot-rename-layers"rename these layers", "clean up layer names", "semantic HTML layer names", "fix Rectangle 12 names"

Workflows (multi-skill orchestrations)

IntentTarget workflowExample user phrasings
Decide where to start (meta)routing"I don't know which tool I need", "where do I begin", "help me with this Penpot file"
End-to-end design system from scratch/codedesign-system-bootstrap"set up a full design system", "tokens + components + docs from our codebase", "bootstrap the whole library"
Brief → finished screen (foundations check → build → a11y)brief-to-screen"take this brief and ship a screen", "design and validate this page end to end"
Brief → finished, playable deck (build-deck → a11y on slides + deck-quality loop)brief-to-deck"turn this outline into a polished deck", "design and validate this presentation end to end"
Keep Penpot in sync with codecode-to-penpot-sync"sync our components to code", "reconcile Penpot with the repo", "keep design and code aligned"
Full Figma → Penpot migration programfigma-migration"migrate our entire Figma project", "full Figma import with tokens, components, screens"
Gate a design on accessibility before handoffaccessibility-gate"block handoff until a11y passes", "run the accessibility gate", "validate before we ship"

9. Modes & Policies

Mode-default: suggest (see shared/modes-and-policies.md). The router is read-only by nature, so it has no safe-set auto-fix items — it never mutates the canvas under any mode. What it may do without asking: call high_level_overview, run read-only shapeStructure/tokenOverview discovery, and propose a route. What always requires the user (or the downstream skill's own gate): executing the route when intent is ambiguous, and anything the target skill does (those inherit that skill's mode).

10. State Management

The router writes minimal state (shared/state-management.md). It does not own a RUN_ID workflow — that belongs to the skill it routes to — but it records its decision so a resumed session can see how it got there:

  • storage.router = { lastIntent, chosenTarget, queuedIntents, overviewCalled: true } (session cache).
  • Optional in-file breadcrumb under namespace penpot-ai, key router.lastRoute, via setSharedPluginData (verify signature with penpot_api_info before relying on it).

On resume: re-read storage.router and the breadcrumb, re-run Phase 0 discovery (file state may have changed), and reclassify rather than blindly continuing — routing must reflect current reality.

11. User Checkpoints

After phaseArtifacts shownWhat we ask
Phase 0 (discovery)Page list, selection summary, token-set presence(Informational — no approval; proceed.)
Phase 1 (classification) — only if ambiguousTwo candidate targets in plain language"Which best matches what you want — A or B?"
Phase 2 (handoff) — only if ambiguous or the target is an expensive mutating flow on existing contentChosen target + the Token-Aware Brief Contract + queued intents"Routing to X — confirm or redirect?" (clean matches: state the route and proceed)

12. Naming Conventions

The router enforces no names itself, but it must speak the kit's vocabulary when restating the brief so the downstream skill inherits correct expectations (shared/naming-conventions.md): tokens in dot-notation (color.action.primary.bg), components in PascalCase (Button), variants as Property=Value pairs (State=Hover), layers as semantic kebab-case HTML names (nav, card-container). If a request implies a RUN_ID (any multi-step workflow), use the convention slug, e.g. dsb-2026-06-05-a, and let the target skill own it.

13. Anti-Rationalization Table

Excuse the LLM makesWhy it's wrongDeterministic countermeasure that halts the flow
"This is obviously a build request — I'll just start creating boards now."The router is read-only; starting mutation here bypasses the target skill's discovery, brief contract, and checkpoints.Stop. Route to penpot-build-screen/penpot-build-from-code, emit the §5 brief, and let that skill own Phase 0 and all mutation.
"The request mentions both tokens and a screen — I'll route to both at once."Fanning out to two mutating skills in parallel produces conflicting edits and an unauditable run.Split intents. Route the primary objective; queue the rest in storage.router.queuedIntents. One target per request.
"Intent is a bit ambiguous, but I'll pick the more likely skill and proceed."A wrong-flow start is expensive to undo (geometry/variant changes are not safe-set).Halt at the Phase 1 checkpoint; ask one disambiguating question offering the two candidate targets.
"high_level_overview was probably called earlier; I'll skip it."Acting without the MCP's own guidance loaded is the #1 cause of API misuse downstream.Confirm it ran this session; if uncertain, call it. No route is executed otherwise.
"The host client auto-selected a skill, but I'll re-dispatch to be safe."Double-dispatch causes the same work to run twice or two skills to fight.Detect host auto-selection; degrade to documentation (serve the taxonomy as a map) and step aside.
"I'll route based on the user's words alone — no need to read the file."Identical phrasing routes differently in an empty file vs. a mature system ("set up my design system" → bootstrap vs. extend).Run Phase 0 reads (tokenOverview, shapeStructure) and use file state to break ties before classifying.

14. Helper Code Snippets

Read-only discovery only — the router never mutates.

// Phase 0a — state sense (paste into one execute_code call)
return {
  pages: penpotUtils.getPages().map(p => p.name),
  currentPage: penpot.currentPage && penpot.currentPage.name,
  selectionCount: penpot.selection.length,
  selection: penpot.selection.map(s => ({ id: s.id, name: s.name, type: s.type })),
  topLevel: penpotUtils.shapeStructure(penpot.currentPage.root, 1)
};
// Phase 0b — token state (does a design system already exist?)
const ov = penpotUtils.tokenOverview();
return {
  hasTokens: !!(ov && ov.totalTokens),
  overview: ov
};
// Optional — drop a routing breadcrumb into the file (verify signature first via
// penpot_api_info("PenpotFile", "setSharedPluginData"))
penpot.currentFile.setSharedPluginData(
  "penpot-ai",
  "router.lastRoute",
  JSON.stringify({ chosenTarget: "REPLACE-ME", at: "RUN_ID_HERE" })
);
return { recorded: true };

15. Reference Resources

  • penpot_api_info("PenpotUtils", "shapeStructure"), penpot_api_info("PenpotUtils", "tokenOverview") — confirm discovery helper signatures.
  • penpot_api_info("PenpotFile", "setSharedPluginData") — confirm the breadcrumb signature.
  • shared/penpot-mcp-tool-reference.md — the tool surface.
  • shared/modes-and-policies.md — why the router is suggest-only.
  • Sibling skills' own SKILL.md descriptions — the authoritative trigger lists the router maps onto.

16. Supporting Files

references/ (progressive-disclosure deep dives)

FileLoaded whenContents
references/01-intent-taxonomy.mdPhase 1 (classification)Full map of user phrasings → target skill/workflow, with fallbacks, tie-breakers, and multi-intent splitting rules.
references/02-preflight-overview.mdPhase 0 (discovery)How to call high_level_overview and run the quick shapeStructure / tokenOverview reads that ground a routing decision.

scripts/ (paste-into-execute_code templates)

None. The router performs no mutations and needs no reusable mutation templates — its only execute_code usage is the inline read-only discovery snippets in §14.

workflows/ (vendored in native installs)

In a native Claude Code install this skill's bundle also carries workflows/ — the seven multi-skill pipelines (§8's workflow targets: routing, design-system-bootstrap, brief-to-screen, brief-to-deck, code-to-penpot-sync, figma-migration, accessibility-gate), each a README.md (prose) + pipeline.json (deterministic step list). When routing to a workflow, open its files from here; in seed-pointer installs they live at the kit root under workflows/.

Doctrine paths. shared/… and policies/… resolve inside this bundle in native installs (vendored by the installer); in a Claude Code plugin install they live at the plugin root — ${CLAUDE_PLUGIN_ROOT}/shared/…, two directories up from this file.

Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.

<a href="https://skillzs.dev/skills/penpot/penpot-ai-kit/penpot-router">View penpot-router on skillZs</a>