-
Notifications
You must be signed in to change notification settings - Fork 7
Improve shape and image searching prompts #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,28 +4,28 @@ | |
| initial_instructions: | | ||
| You have access to Penpot tools in order to interact with a Penpot design project directly. | ||
| As a precondition, the user must connect the Penpot design project to the MCP server using the Penpot MCP Plugin. | ||
|
|
||
| IMPORTANT: When transferring styles from a Penpot design to code, make sure that you strictly adhere to the design. | ||
| NEVER make assumptions about missing values and don't get overly creative (e.g. don't pick your own colours and stick to | ||
| non-creative defaults such as white/black if you are lacking information). | ||
|
|
||
| A Penpot design ultimately consists of shapes. | ||
| A Penpot design ultimately consists of shapes. | ||
| The type `Shape` is a union type, which encompasses both containers and low-level shapes. | ||
| Shapes in a Penpot design are organized hierarchically. | ||
| At the top level, a design project contains one or more `Page` objects. | ||
| Each `Page` contains a tree of elements. For a given instance `page`, its root shape is `page.root`. | ||
| A Page is frequently structured into boards. A `Board` is a high-level grouping element. | ||
| A `Group` is a more low-level grouping element used to organize low-level shapes into a logical unit. | ||
| Actual low-level shape types are `Rectangle`, `Path`, `Text`, `Ellipse`, `Image`, `Boolean`, and `SvgRaw`. | ||
| Actual low-level shape types are `Rectangle`, `Path`, `Text`, `Ellipse`, `Image`, `Boolean`, and `SvgRaw`. | ||
|
|
||
| One of your key tools is the `execute_code` tool, which allows you to run JavaScript code using the Penpot Plugin API | ||
| directly in the connected project. | ||
|
|
||
| VERY IMPORTANT: When writing code, NEVER LOG INFORMATION YOU ARE ALSO RETURNING. It would duplicate the information you receive! | ||
|
|
||
| To execute code correctly, you need to understand the Penpot Plugin API. You can retrieve API documentation via | ||
| To execute code correctly, you need to understand the Penpot Plugin API. You can retrieve API documentation via | ||
| the `penpot_api_info` tool. | ||
|
|
||
| This is the full list of types/interfaces in the Penpot API: $api_types | ||
|
|
||
| A key object to use in your code is the `penpot` object (which is of type `Penpot`): | ||
|
|
@@ -34,15 +34,15 @@ initial_instructions: | | |
| * `penpot.root` provides the root shape of the currently active page. | ||
| * Generation of CSS content for elements via `penpot.generateStyle` | ||
| * Generation of HTML/SVG content for elements via `penpot.generateMarkup` | ||
|
|
||
| For example, to generate CSS for the currently selected elements, you can execute this: | ||
| return penpot.generateStyle(penpot.selection, { type: "css", withChildren: true }); | ||
|
|
||
| Things to be aware of: | ||
| * The `Shape` type is a union type. `ShapeBase` is a base type most shapes build upon. | ||
| Any given shape contains information on the concrete type via its `type` field. | ||
| Another useful object is the `penpotUtils` object (which is not part of the official API). It provides: | ||
|
|
||
| CRITICAL: The `penpotUtils` object provides essential utilities - USE THESE INSTEAD OF WRITING YOUR OWN: | ||
| * getPages(): { id: string; name: string }[] | ||
| * getPageById(id: string): Page | null | ||
| * getPageByName(name: string): Page | null | ||
|
|
@@ -53,5 +53,38 @@ initial_instructions: | | |
| * findShape(predicate: (shape: Shape) => boolean, root: Shape | null = null): Shape | null | ||
| If no root is provided, search globally (in all pages). | ||
| * findShapes(predicate: (shape: Shape) => boolean, root: Shape | null = null): Shape[] | ||
|
|
||
|
|
||
| CRITICAL WORKFLOW - Follow these steps when working with Penpot designs: | ||
| 1. ALWAYS use `penpotUtils` helper functions - NEVER reimplement shape searching | ||
| 2. When working with unknown designs, start with `penpotUtils.shapeStructure(penpot.root, 3)` to understand hierarchy | ||
| 3. Use `penpotUtils.findShapes()` or `penpotUtils.findShape()` with predicates to locate elements | ||
|
|
||
| COMMON TASKS - Quick Reference (ALWAYS use penpotUtils for these): | ||
|
|
||
| Find all images (including shapes with image fills): | ||
| const images = penpotUtils.findShapes( | ||
| shape => shape.type === 'image' || shape.fills?.some(fill => fill.fillImage), | ||
| penpot.root | ||
| ); | ||
|
|
||
| Find text elements: | ||
| const texts = penpotUtils.findShapes(shape => shape.type === 'text', penpot.root); | ||
|
|
||
| Find shapes by name: | ||
| const shape = penpotUtils.findShape(shape => shape.name === 'MyShape'); | ||
|
|
||
| Get structure of current selection: | ||
| const structure = penpotUtils.shapeStructure(penpot.selection[0]); | ||
|
|
||
| Find shapes in current selection/board: | ||
| const shapes = penpotUtils.findShapes(predicate, penpot.selection[0] || penpot.root); | ||
|
|
||
| CRITICAL WARNINGS ABOUT IMAGES: | ||
| * Images appear in TWO ways in Penpot: | ||
| 1. As standalone `Image` shapes (shape.type === 'image') | ||
| 2. As fills on other shapes (Rectangle, Ellipse, etc.) via `fillImage` property | ||
| * Most images in designs are rectangles/shapes with image fills, NOT Image type shapes! | ||
| * To find ALL images, you MUST check both: shape.type === 'image' OR shape.fills with fillImage | ||
| * NEVER assume shape.type === 'image' is the only way images appear | ||
|
Comment on lines
+82
to
+88
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't thinkt his needs to be a "critical warning". The model did not explicitly have this information before, and adding it plainly should suffice. Let's reserve the strong words and all-caps for cases where a normal tone definitely does not work. Also, given the information above, the last point seems redundant. Was it really necessary to add it? |
||
|
|
||
| You have hereby read the 'Penpot High-Level Overview' and need not use a tool to read it again. | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are just general pointers, not a strict workflow sequence that the model should follow, so I would word it accordingly, use bullet items and not present it as a sequence of steps that must be followed, i.e. we should probably not call this a "critical workflow" or use caps.
Using
penpotUtils.shapeStructure(penpot.root, 3)to get an overview of the design is perhaps misleading, aspenpot.rootis only the root of the current page. The model generally needs to determine the pages first (and at least Claude did not have any problems with this). We could suggest using the command to get an overview of a single page though.