mirror of
https://github.com/penpot/penpot-mcp.git
synced 2026-09-12 15:09:30 +00:00
Add utils for Page handling, improve prompts explaining design structure
This commit is contained in:
parent
cf5231db66
commit
dacd87bbac
@ -9,7 +9,14 @@ initial_instructions: |
|
|||||||
NEVER make assumptions about missing values and don't get overly creative (e.g. don't pick your own colours and stick to
|
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).
|
non-creative defaults such as white/black if you are lacking information).
|
||||||
|
|
||||||
A Penpot project contains shapes and more general design elements (which we shall collectively refer to as "elements").
|
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 to organize low-level shapes into a logical unit.
|
||||||
|
Low-level shape types are `Rectangle`, `Path`, `Text`, `Ellipse`, `Image`, etc.
|
||||||
|
|
||||||
One of your key tools is the `execute_code` tool, which allows you to run JavaScript code using the Penpot Plugin API
|
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.
|
directly in the connected project.
|
||||||
@ -17,9 +24,9 @@ initial_instructions: |
|
|||||||
the `penpot_api_info` tool.
|
the `penpot_api_info` tool.
|
||||||
|
|
||||||
When writing code, a key object is the `penpot` object (which is of type `Penpot`):
|
When writing code, a key object is the `penpot` object (which is of type `Penpot`):
|
||||||
* `penpot.selection` provides the list of elements the user has selected in the Penpot UI.
|
* `penpot.selection` provides the list of shapes the user has selected in the Penpot UI.
|
||||||
If it is unclear which elements to work on, you can ask the user to select them for you.
|
If it is unclear which elements to work on, you can ask the user to select them for you.
|
||||||
* `penpot.root` provides the root element of the tree-structured design project, from which all shapes can be reached.
|
* `penpot.root` provides the root shape of the currently active page.
|
||||||
* Generation of CSS content for elements via `penpot.generateStyle`
|
* Generation of CSS content for elements via `penpot.generateStyle`
|
||||||
* Generation of HTML/SVG content for elements via `penpot.generateMarkup`
|
* Generation of HTML/SVG content for elements via `penpot.generateMarkup`
|
||||||
|
|
||||||
@ -31,6 +38,9 @@ initial_instructions: |
|
|||||||
Any given shape contains information on the concrete type via its `type` field.
|
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:
|
Another useful object is the `penpotUtils` object (which is not part of the official API). It provides:
|
||||||
|
* getPages(): { id: string; name: string }[]
|
||||||
|
* getPageById(id: string): Page | null
|
||||||
|
* getPageByName(name: string): Page | null
|
||||||
* shapeStructure(shape: Shape, maxDepth: number | undefined = undefined): object
|
* shapeStructure(shape: Shape, maxDepth: number | undefined = undefined): object
|
||||||
Generates an overview structure of the given shape,
|
Generates an overview structure of the given shape,
|
||||||
providing the shape's id, name and type, and recursively the children's structure.
|
providing the shape's id, name and type, and recursively the children's structure.
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Shape } from "@penpot/plugin-types";
|
import { Page, Shape } from "@penpot/plugin-types";
|
||||||
|
|
||||||
export class PenpotUtils {
|
export class PenpotUtils {
|
||||||
/**
|
/**
|
||||||
@ -27,6 +27,33 @@ export class PenpotUtils {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds all shapes that matches the given predicate in the given shape tree.
|
||||||
|
*
|
||||||
|
* @param predicate - A function that takes a shape and returns true if it matches the criteria
|
||||||
|
* @param root - The root shape to start the search from (defaults to penpot.root)
|
||||||
|
*/
|
||||||
|
public static findShapes(predicate: (shape: Shape) => boolean, root: Shape | null = penpot.root): Shape[] {
|
||||||
|
let result = new Array<Shape>();
|
||||||
|
|
||||||
|
let find = function (shape: Shape | null) {
|
||||||
|
if (!shape) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (predicate(shape)) {
|
||||||
|
result.push(shape);
|
||||||
|
}
|
||||||
|
if ("children" in shape && shape.children) {
|
||||||
|
for (let child of shape.children) {
|
||||||
|
find(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
find(root);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the first shape that matches the given predicate in the given shape tree.
|
* Finds the first shape that matches the given predicate in the given shape tree.
|
||||||
*
|
*
|
||||||
@ -64,4 +91,21 @@ export class PenpotUtils {
|
|||||||
public static findShapeById(id: string): Shape | null {
|
public static findShapeById(id: string): Shape | null {
|
||||||
return this.findShape((shape) => shape.id === id);
|
return this.findShape((shape) => shape.id === id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static findPage(predicate: (page: Page) => boolean): Page | null {
|
||||||
|
let page = penpot.currentFile!.pages.find(predicate);
|
||||||
|
return page || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static getPages(): { id: string; name: string }[] {
|
||||||
|
return penpot.currentFile!.pages.map((page) => ({ id: page.id, name: page.name }));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static getPageById(id: string): Page | null {
|
||||||
|
return this.findPage((page) => page.id === id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static getPageByName(name: string): Page | null {
|
||||||
|
return this.findPage((page) => page.name.toLowerCase() === name.toLowerCase());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user