mirror of
https://github.com/penpot/penpot-mcp.git
synced 2026-04-25 11:18:37 +00:00
Add PenpotUtils (utility functions the LLM can make use of)
This commit is contained in:
parent
afb00f6033
commit
865606b7b0
@ -2,29 +2,35 @@
|
||||
# This file contains various prompts and instructions that can be used by the server
|
||||
|
||||
initial_instructions: |
|
||||
You have access to Penpot tools in order to interact with Penpot design projects directly.
|
||||
As a precondition, the user must connect a Penpot project to the MCP server using the Penpot MCP Plugin.
|
||||
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.
|
||||
|
||||
A Penpot project contains shapes and more general design elements (which we shall collectively refer to as "elements").
|
||||
|
||||
One of the 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.
|
||||
|
||||
When writing code, a key object is the `penpot` object (which is of type `Penpot`). It provides useful functionality:
|
||||
To execute code correctly, you need to understand the Penpot Plugin API. You can retrieve API documentation via
|
||||
the `penpot_api_info` tool.
|
||||
|
||||
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.
|
||||
If it is unclear which elements to work on, you can ask the user to select them for you.
|
||||
* Generation of CSS content for elements:
|
||||
generateStyle(shapes: Shape[], options?: {
|
||||
type?: "css";
|
||||
withPrelude?: boolean;
|
||||
includeChildren?: boolean;
|
||||
}): string;
|
||||
* Generation of HTML/SVG content corresponding to elements:
|
||||
generateMarkup(shapes: Shape[], options?: {
|
||||
type?: "html" | "svg";
|
||||
}): string;
|
||||
* `penpot.root` provides the root element of the tree-structured design project, from which all shapes can be reached.
|
||||
* 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 not part of the official API). It provides:
|
||||
* shapeStructure(shape: Shape, maxDepth: number | undefined = undefined): object
|
||||
Generates an overview structure of the given shape,
|
||||
providing the shape's id, name and type, and recursively the children's structure.
|
||||
* findShapeById(id: string): Shape | null
|
||||
* findShape(predicate: (shape: Shape) => boolean, root: Shape | null = penpot.root): Shape | null
|
||||
|
||||
You have hereby read the 'Penpot High-Level Overview' and need not use a tool to read it again.
|
||||
|
||||
67
penpot-plugin/src/PenpotUtils.ts
Normal file
67
penpot-plugin/src/PenpotUtils.ts
Normal file
@ -0,0 +1,67 @@
|
||||
import { Shape } from "@penpot/plugin-types";
|
||||
|
||||
export class PenpotUtils {
|
||||
/**
|
||||
* Generates an overview structure of the given shape,
|
||||
* providing its id, name and type, and recursively its children's attributes.
|
||||
* The `type` field indicates the type in the Penpot API.
|
||||
*
|
||||
* @param shape - The root shape to generate the structure from
|
||||
* @param maxDepth - Optional maximum depth to traverse (leave undefined for unlimited)
|
||||
* @returns An object representing the shape structure
|
||||
*/
|
||||
public static shapeStructure(shape: Shape, maxDepth: number | undefined = undefined): object {
|
||||
let children = undefined;
|
||||
if (maxDepth === undefined || maxDepth > 0) {
|
||||
if ("children" in shape && shape.children) {
|
||||
children = shape.children.map((child) =>
|
||||
this.shapeStructure(child, maxDepth === undefined ? undefined : maxDepth - 1)
|
||||
);
|
||||
}
|
||||
}
|
||||
return {
|
||||
id: shape.id,
|
||||
name: shape.name,
|
||||
type: shape.type,
|
||||
children: children,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the first shape 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 findShape(predicate: (shape: Shape) => boolean, root: Shape | null = penpot.root): Shape | null {
|
||||
let find = function (shape: Shape | null): Shape | null {
|
||||
if (!shape) {
|
||||
return null;
|
||||
}
|
||||
if (predicate(shape)) {
|
||||
return shape;
|
||||
}
|
||||
if ("children" in shape && shape.children) {
|
||||
for (let child of shape.children) {
|
||||
let result = find(child);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
return find(root);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a shape by its unique ID.
|
||||
*
|
||||
* @param id - The unique ID of the shape to find
|
||||
* @returns The shape with the matching ID, or null if not found
|
||||
*/
|
||||
public static findShapeById(id: string): Shape | null {
|
||||
return this.findShape((shape) => shape.id === id);
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
import { Task, TaskHandler } from "../TaskHandler";
|
||||
import { ExecuteCodeTaskParams, ExecuteCodeTaskResultData } from "../../../common/src";
|
||||
import { PenpotUtils } from "../PenpotUtils.ts";
|
||||
|
||||
/**
|
||||
* Console implementation that captures all log output for code execution.
|
||||
@ -179,6 +180,7 @@ export class ExecuteCodeTaskHandler extends TaskHandler<ExecuteCodeTaskParams> {
|
||||
penpot: penpot,
|
||||
storage: {},
|
||||
console: new ExecuteCodeTaskConsole(),
|
||||
penpotUtils: PenpotUtils,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user