This commit is contained in:
alonso.torres 2026-01-08 10:33:35 +01:00
parent c931e6978b
commit 9233b8e548
2 changed files with 56 additions and 19 deletions

View File

@ -19,12 +19,19 @@ const statusElement = document.getElementById("connection-status");
* @param isConnectedState - whether the connection is in a connected state (affects color)
* @param message - optional additional message to append to the status
*/
function updateConnectionStatus(status: string, isConnectedState: boolean, message?: string): void {
function updateConnectionStatus(code: string, status: string, isConnectedState: boolean, message?: string): void {
if (statusElement) {
const displayText = message ? `${status}: ${message}` : status;
statusElement.textContent = displayText;
statusElement.style.color = isConnectedState ? "var(--accent-primary)" : "var(--error-700)";
}
parent.postMessage(
{
type: "update-connection-status",
status: code,
},
"*"
);
}
/**
@ -44,25 +51,23 @@ function sendTaskResponse(response: any): void {
/**
* Establishes a WebSocket connection to the MCP server.
*/
function connectToMcpServer(): void {
function connectToMcpServer(url: string, token: string): void {
if (ws?.readyState === WebSocket.OPEN) {
updateConnectionStatus("Already connected", true);
updateConnectionStatus("connected", "Already connected", true);
return;
}
try {
let wsUrl = PENPOT_MCP_WEBSOCKET_URL;
if (isMultiUserMode) {
// TODO obtain proper userToken from penpot
const userToken = "dummyToken";
wsUrl += `?userToken=${encodeURIComponent(userToken)}`;
url += `?userToken=${encodeURIComponent(token)}`;
}
ws = new WebSocket(wsUrl);
updateConnectionStatus("Connecting...", false);
ws = new WebSocket(url);
updateConnectionStatus("connecting", "Connecting...", false);
ws.onopen = () => {
console.log("Connected to MCP server");
updateConnectionStatus("Connected to MCP server", true);
updateConnectionStatus("connected", "Connected to MCP server", true);
};
ws.onmessage = (event) => {
@ -79,32 +84,37 @@ function connectToMcpServer(): void {
ws.onclose = (event: CloseEvent) => {
console.log("Disconnected from MCP server");
const message = event.reason || undefined;
updateConnectionStatus("Disconnected", false, message);
updateConnectionStatus("disconnected", "Disconnected", false, message);
ws = null;
};
ws.onerror = (error) => {
console.error("WebSocket error:", error);
// note: WebSocket error events typically don't contain detailed error messages
updateConnectionStatus("Connection error", false);
updateConnectionStatus("error", "Connection error", false);
};
} catch (error) {
console.error("Failed to connect to MCP server:", error);
const message = error instanceof Error ? error.message : undefined;
updateConnectionStatus("Connection failed", false, message);
updateConnectionStatus("error", "Connection failed", false, message);
}
}
document.querySelector("[data-handler='connect-mcp']")?.addEventListener("click", () => {
connectToMcpServer();
});
// document.querySelector("[data-handler='connect-mcp']")?.addEventListener("click", () => {
// connectToMcpServer();
// });
// Listen plugin.ts messages
window.addEventListener("message", (event) => {
if (event.data.source === "penpot") {
console.log("event", event.data);
if (event.data.type === "init-server") {
connectToMcpServer(event.data.url, event.data.token);
} else if (event.data.source === "penpot") {
document.body.dataset.theme = event.data.theme;
} else if (event.data.type === "task-response") {
// Forward task response back to MCP server
sendTaskResponse(event.data.response);
}
});
parent.postMessage({ type: "ui-initialized" }, "*");

View File

@ -1,6 +1,11 @@
import { ExecuteCodeTaskHandler } from "./task-handlers/ExecuteCodeTaskHandler";
import { Task, TaskHandler } from "./TaskHandler";
console.log("TOKEN", mcp.getToken());
console.log("SERVER", mcp.getServerUrl());
mcp.setMcpStatus("connecting");
/**
* Registry of all available task handlers.
*/
@ -11,12 +16,26 @@ declare const IS_MULTI_USER_MODE: boolean;
const isMultiUserMode = typeof IS_MULTI_USER_MODE !== "undefined" ? IS_MULTI_USER_MODE : false;
// Open the plugin UI (main.ts)
penpot.ui.open("Penpot MCP Plugin", `?theme=${penpot.theme}&multiUser=${isMultiUserMode}`, { width: 158, height: 200 });
penpot.ui.open("Penpot MCP Plugin", `?theme=${penpot.theme}&multiUser=${isMultiUserMode}`, {
width: 158,
height: 200,
hidden: true,
});
// Handle messages
penpot.ui.onMessage<string | { id: string; task: string; params: any }>((message) => {
// Handle plugin task requests
if (typeof message === "object" && message.task && message.id) {
console.log(message);
if (message.type === "ui-initialized") {
console.log("send message");
penpot.ui.sendMessage({
type: "init-server",
url: mcp.getServerUrl(),
token: mcp.getToken(),
});
} else if (message.type === "update-connection-status") {
mcp.setMcpStatus(message.status);
} else if (typeof message === "object" && message.task && message.id) {
handlePluginTaskRequest(message).catch((error) => {
console.error("Error in handlePluginTaskRequest:", error);
});
@ -67,3 +86,11 @@ penpot.on("themechange", (theme) => {
theme,
});
});
// console.log("send message");
// penpot.ui.sendMessage({
// source: "penpot",
// type: "init-server",
// url: mcp.getServerUrl(),
// token: mcp.getToken(),
// })