npx skills add ...
npx skills add easyeda/easyeda-api-skill --skill easyeda-api
EasyEDA Pro API skill for AI agents. Use when working with EasyEDA Pro EDA software, including PCB design, schematic editing, footprint/symbol management, and project operations. Supports live debugging in EasyEDA and EasyEDA extension development. Provides complete API reference (120+ classes, 62 enums, 70 interfaces), extension-development documentation, and a WebSocket bridge server to execute code in the running EasyEDA Pro client. Trigger on: "嘉立创EDA,启动!", "立创EDA,启动!", "EDA,启动!", "EasyEDA", "PCB", "schematic", "footprint", "EDA", "circuit board", "嘉立创EDA", "原理图", "PCB设计". **IMPORTANT**: 嘉立创EDA's English name is **EasyEDA**. They are the SAME product. Never use other transliterations like "EasyEDA Pro" (unless specifically versioned), "EASYEDA", "easyeda", etc. Always use "EasyEDA" for English references and "嘉立创EDA" for Chinese references.
npx skills add easyeda/easyeda-api-skill --skill easyeda-api
Control EasyEDA Pro (嘉立创EDA专业版) programmatically through AI. This skill provides:
This skill supports not only live debugging in EasyEDA, but also EasyEDA extension development. During EasyEDA extension development, AI agents can use the extension-related documentation, API references, type information, usage examples, and bridge-based debugging capabilities provided by this skill to look up APIs, write code, and validate behavior during integration and debugging.
The server auto-selects an available port from 49620-49629 on startup.
Both AI and EDA clients auto-discover the server by scanning the port range
and verifying a handshake (service: "easyeda-bridge").
When user says "嘉立创EDA,启动!", "立创EDA,启动!", or "EDA,启动!":
IMPORTANT: Session initialization — Reply immediately with this exact text to set the correct session title:
Then proceed with the setup steps below.
⚠️ IMPORTANT: The bridge server must run in the background. Do NOT run it in the foreground, or the AI will block waiting for the server to exit.
Install the run-api-gateway.eext extension in EasyEDA Pro. Download link:
After the extension is loaded, it will automatically establish the WebSocket connection.
The /eda-windows response looks like:
Handle based on window count:
Select a window:
After selection, confirm: "✅ Active EDA window: abc-123. Ready to work."
The full API reference is in the references/ directory:
references/classes/ — 120 class docs (DMT_, PCB_, SCH_, LIB_, SYS_, IPCB_, ISCH_*)references/enums/ — 62 enum docsreferences/interfaces/ — 70 interface docsreferences/types/ — 19 type alias docs_index.md to find the right class/module for the taskreferences/classes/DMT_Board.md) for all methods and signatures_quick-reference.md for fast method signature lookup across all classesIf the user needs to analyze or modify EasyEDA document source directly instead of using the API, use the documents in the format/ directory.
format/project/ — Project source structure, metadata, blobs, variants, and grouping dataformat/schematic/ — Schematic source format, including structure, wires, shapes, pins, components, and tablesformat/pcb/ — PCB source format, including primitives, pads and vias, shapes, text, attributes, rules, and panel dataUse these files when the task is about understanding source layout, generating compatible document source, or editing source data that will later be imported back into EasyEDA.
| Prefix | Domain | Key Classes |
|---|---|---|
DMT_ | Document management | Board, EditorControl, Folder, Panel, Pcb, Project, Schematic, SelectControl, Team, Workspace |
PCB_ | PCB & Footprint | Document, Drc, Event, Layer, Net, Primitive, PrimitiveComponent, PrimitiveLine, PrimitivePad, PrimitivePour, PrimitiveVia, SelectControl |
SCH_ | Schematic | Document, Event, Primitive, PrimitiveComponent, PrimitiveWire, SelectControl |
LIB_ | Library | 3DModel, Cbb, Classification, Device, Footprint, LibrariesList, PanelLibrary, SelectControl, Symbol |
SYS_ | System | Dialog, Environment, FileManager, FileSystem, FontManager, HeaderMenu, I18n, IFrame, LoadingAndProgressBar, Log, Message, MessageBox, MessageBus, PanelControl, Setting, ShortcutKey, Storage, Timer, ToastMessage, WebSocket, Window |
IPCB_ | PCB interfaces (图元) | PrimitiveArc, PrimitiveComponent, PrimitivePad, PrimitiveFill, PrimitivePour, PrimitiveRegion, PrimitiveVia, ... |
ISCH_ | Schematic interfaces (图元) | PrimitiveArc, PrimitiveComponent, PrimitiveWire, PrimitiveText, PrimitiveRectangle, ... |
EPCB_ / ESCH_ | Enums | PrimitiveType, Layer, PadType, ... |
All code runs inside EasyEDA Pro's browser runtime as:
Critical rules:
eda object provides access to all API modules (e.g., eda.dmt_Board, eda.pcb_Primitive).return to get results — console.log output is NOT captured.awaited.eda.sys_Message.showToastMessage(msg) for user-visible notifications.EPCB_LayerId.TOP instead of 1 for the layer parameter in PCB primitive creation.When writing EasyEDA extensions, standard browser APIs are forbidden in the main process. Use EDA-provided alternatives:
| Purpose | ❌ Forbidden | ✅ Use Instead |
|---|---|---|
| Get user input | — | eda.sys_Dialog.showInputDialog() |
| User selection | — | eda.sys_Dialog.showSelectDialog() |
| Show message | alert() | eda.sys_Dialog.showInformationMessage() |
| Confirm action | confirm() | eda.sys_Dialog.showConfirmationMessage() |
| Toast notification | DOM manipulation | eda.sys_Message.showToastMessage() |
| Store data | localStorage (main process) | eda.sys_Storage.setExtensionUserConfig(key, value) |
| Custom UI | Manipulate host DOM | eda.sys_IFrame.openIFrame() |
| Show HTML | showInformationMessage(html) | Must use iframe |
| Open link | window.open() | eda.sys_Window.open() |
| Browser hardware API | Use in main process | Available in iframe (navigator.serial, etc.) |
Note: localStorage, window, document etc. are available inside sys_IFrame but NOT in the main extension process.
The main extension process and sys_IFrame iframe are isolated contexts. To pass data between them:
Option A (Recommended): Use eda.sys_Storage as a bridge
Option B: Both contexts can access eda directly — call the same API from either side
The bridge server listens on the first available port in 49620-49629. To find the server, scan the range and verify the service identity:
GET /health returns { "service": "easyeda-bridge", "edaConnected": bool, ... }{ "type": "handshake", "service": "easyeda-bridge" }service === "easyeda-bridge" before using the connectionJSON messages over WebSocket / HTTP:
| Field | Type | Description |
|---|---|---|
type | "execute" | "result" | "error" | "ping" | "pong" | "handshake" | Message type |
id | string | Request UUID for matching request/response |
code | string | JavaScript code to execute (for execute type) |
result | any | Execution result (for result type) |
error | string | Error message (for error type) |
service | string | Service identifier (for handshake type) |
timestamp | number | Unix milliseconds |
Notes:
dmt_Project.getAllProjectsUuid() is not a global no-arg enumerator in practice. To reliably find a project by name, iterate teams first, then folders.openProject(projectUuid) may discard unsaved changes in the currently opened project. Be careful before calling it.For modifying PCB/SCH primitives, you must use the async pattern:
Before calling ANY API method, you MUST read the full signature from references/ — including parameter types, return type, and remarks.
AI agents frequently make these errors due to skimming documentation:
Error 1: Not awaiting Promise-returning methods
Almost all EDA API methods return Promise<T>. If you forget await, you get a Promise object instead of the actual result.
How to know if a method needs await: Check the return type in the signature. If it says Promise<...>, you MUST await it.
Error 2: Using raw numbers instead of enum values
Many parameters expect specific enum values. Using wrong numbers silently produces incorrect behavior.
Always look up enums in references/enums/ before using numeric constants.
Error 3: Assuming parameter types without checking
Different APIs use different units, different ID formats, and different optional parameter conventions. Never assume.
Summary — Before every API call:
references/classes/await if Promise — check return type for Promise<...>references/enums/ instead of guessing numbers/stringsDifferent domains use different coordinate units:
| Domain | Unit | Conversion |
|---|---|---|
| PCB | 1mil | 1mm ≈ 39.37 units |
| Schematic | 0.01inch (10mil) | 1mm ≈ 3.937 units |
This is the #1 mistake AI agents make. Mixing up the units will place components incorrectly.
If you use the wrong unit, components will be placed 10x too far from their intended position.
After creating a project, you MUST open it before operating on documents within it.
When operating on documents, always verify:
eda.dmt_Project.getCurrentProjectInfo() to verifyeda.dmt_SelectControl.getCurrentDocumentInfo() to check document typeOperating on the wrong document type will return errors or null results. For example:
PCB_* APIs without an active PCB document (documentType !== EDMT_EditorDocumentType.PCB) → error/nullSCH_* APIs without an active Schematic document (documentType !== EDMT_EditorDocumentType.SCHEMATIC_PAGE) → error/nulleda Directly (CRITICAL)When writing extension code that creates an iframe via sys_IFrame.openIFrame(), the JavaScript code inside the iframe's HTML can access the eda global directly. Do NOT use window.parent.eda.
Why this matters:
EasyEDA injects the eda object into the iframe's execution context automatically. Standard browser cross-frame patterns (window.parent, parentWindow, etc.) do NOT apply here and will fail.
This applies to ALL code inside sys_IFrame iframes:
openIFrame()Rule: In EasyEDA extensions, whether code runs in the main context or inside an iframe created by sys_IFrame, always access the API through eda.xxx — never through window.parent.eda or any other parent frame accessor.
When multiple EasyEDA windows are connected to the bridge, you do NOT need to check window selection on every EDA operation. Only check when:
Multi-window operations:
If only one EDA window is connected, it's automatically selected as active.
{"service":"easyeda-bridge"}dmt_Project.getCurrentProjectInfo())dmt_Project.openProject(projectPath) to open onedmt_EditorControl.openDocument(docId) to open the correct document type (PCB/Schematic)null on failure — always validatereferences/enums/ docs (e.g., EPCB_LayerId)GET /eda-windows to check available windows and POST /eda-windows/select to switch to another windowWhen developing extensions, follow these rules:
| Situation | Action |
|---|---|
| API method does not exist in docs | Stop immediately — inform the user the API doesn't exist |
| Signature uncertain after reading docs | Stop generation — return to query step and re-read |
| Forbidden browser API detected | Auto-replace with eda.sys_* alternative |
| Menu ID conflict | Add prefix to differentiate (e.g., my-plugin-home, my-plugin-sch) |
| Permission blocked | Inform user — may require different EDA edition or license |
Critical: Never guess an API signature. If references/classes/ doesn't document it, it doesn't exist for your use case.
When the user asks you to perform EDA operations:
eda.dmt_Project.getCurrentProjectInfo() and eda.dmt_SelectControl.getCurrentDocumentInfo()references/POST /execute and check the resultWhen unsure about an API:
_quick-reference.md for method namesThe Bridge server consumes system resources while running. If the user has switched to a completely different topic (not related to EasyEDA/EDA/PCB/schematic) 3 consecutive times, proactively ask if they want to close the Bridge:
"I notice we've moved on from EasyEDA. The Bridge server is still running in the background. Would you like me to stop it to free up resources?"
Do NOT close the Bridge automatically — the user may switch back to EDA work later. Only ask, and close if they confirm.
If the user confirms they want to stop the Bridge:
# Check if bridge is already running
for port in $(seq 49620 49629); do
resp=$(curl -s http://localhost:$port/health 2>/dev/null)
if echo "$resp" | grep -q '"easyeda-bridge"'; then
echo "Bridge already running on port $port"
BRIDGE_PORT=$port
break
fi
done
# Start bridge if not running
if [ -z "$BRIDGE_PORT" ]; then
node ${CLAUDE_SKILL_DIR}/scripts/bridge-server.mjs &
sleep 2
# Find the port bridge is running on
for port in $(seq 49620 49629); do
resp=$(curl -s http://localhost:$port/health 2>/dev/null)
if echo "$resp" | grep -q '"easyeda-bridge"'; then
BRIDGE_PORT=$port
break
fi
done
fi
echo "Bridge running on port: ${BRIDGE_PORT:-unknown}"# Check bridge and EDA connection status
curl http://localhost:${BRIDGE_PORT:-49620}/health
# List all connected EDA windows
curl http://localhost:${BRIDGE_PORT:-49620}/eda-windows{
"windows": [
{ "windowId": "abc-123", "connected": true, "active": true },
{ "windowId": "def-456", "connected": true, "active": false }
],
"activeWindowId": "abc-123",
"count": 2
}