@windypro-rourou/dsh-eda 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (484) hide show
  1. package/README.md +1 -1
  2. package/lib/backend.js +49 -0
  3. package/lib/capabilities.js +6 -2
  4. package/lib/client.js +33 -0
  5. package/lib/index.js +197 -3
  6. package/package.json +10 -1
  7. package/skill/INDEX.md +10 -8
  8. package/skill/README.md +125 -0
  9. package/skill/README.zh-Hans.md +125 -0
  10. package/skill/SKILL.md +746 -746
  11. package/skill/format/index.md +152 -152
  12. package/skill/format/pcb/3d.md +166 -166
  13. package/skill/format/pcb/attr.md +63 -63
  14. package/skill/format/pcb/common.md +306 -306
  15. package/skill/format/pcb/component.md +132 -132
  16. package/skill/format/pcb/dimension.md +58 -58
  17. package/skill/format/pcb/index.md +17 -17
  18. package/skill/format/pcb/obj.md +43 -43
  19. package/skill/format/pcb/pad_via.md +151 -151
  20. package/skill/format/pcb/panel.md +64 -64
  21. package/skill/format/pcb/partition.md +43 -43
  22. package/skill/format/pcb/primitive.md +196 -196
  23. package/skill/format/pcb/rule.md +71 -71
  24. package/skill/format/pcb/shape.md +441 -441
  25. package/skill/format/pcb/text.md +62 -62
  26. package/skill/format/project/blob.md +30 -30
  27. package/skill/format/project/common.md +42 -42
  28. package/skill/format/project/group.md +62 -62
  29. package/skill/format/project/index.md +12 -12
  30. package/skill/format/project/instance.md +32 -32
  31. package/skill/format/project/meta.md +189 -189
  32. package/skill/format/project/variant.md +30 -30
  33. package/skill/format/schematic/attr.md +41 -41
  34. package/skill/format/schematic/common.md +47 -47
  35. package/skill/format/schematic/component.md +91 -91
  36. package/skill/format/schematic/index.md +14 -14
  37. package/skill/format/schematic/obj.md +41 -41
  38. package/skill/format/schematic/pin.md +59 -59
  39. package/skill/format/schematic/shape.md +231 -231
  40. package/skill/format/schematic/structure.md +53 -53
  41. package/skill/format/schematic/table.md +109 -109
  42. package/skill/format/schematic/text.md +47 -47
  43. package/skill/format/schematic/wire.md +132 -132
  44. package/skill/guide/ancillary-projects/easyeda-api-sdk.md +1 -0
  45. package/skill/guide/ancillary-projects/pro-api-types.md +5 -5
  46. package/skill/guide/ancillary-projects.md +10 -10
  47. package/skill/guide/cli.md +1510 -0
  48. package/skill/guide/error-handling.md +38 -38
  49. package/skill/guide/extension-json.md +135 -135
  50. package/skill/guide/extensions-marketplace.md +61 -61
  51. package/skill/guide/how-to-start.md +316 -301
  52. package/skill/guide/i18n.md +57 -57
  53. package/skill/guide/index.md +7 -7
  54. package/skill/guide/inline-frame.md +20 -20
  55. package/skill/guide/invoke-apis.md +81 -81
  56. package/skill/guide/stability.md +37 -37
  57. package/skill/references/_index.md +471 -398
  58. package/skill/references/_quick-reference.md +3103 -3028
  59. package/skill/references/classes/DMT_Board.md +537 -533
  60. package/skill/references/classes/DMT_EditorControl.md +1736 -1736
  61. package/skill/references/classes/DMT_Event.md +356 -356
  62. package/skill/references/classes/DMT_Folder.md +775 -775
  63. package/skill/references/classes/DMT_Panel.md +531 -531
  64. package/skill/references/classes/DMT_Pcb.md +579 -575
  65. package/skill/references/classes/DMT_Project.md +734 -573
  66. package/skill/references/classes/DMT_Schematic.md +1482 -1477
  67. package/skill/references/classes/DMT_SelectControl.md +96 -96
  68. package/skill/references/classes/DMT_Team.md +172 -172
  69. package/skill/references/classes/DMT_Workspace.md +198 -198
  70. package/skill/references/classes/EDA.md +1001 -961
  71. package/skill/references/classes/IPCB_ComplexPolygon.md +299 -299
  72. package/skill/references/classes/IPCB_Polygon.md +175 -175
  73. package/skill/references/classes/IPCB_PrimitiveArc.md +1901 -1901
  74. package/skill/references/classes/IPCB_PrimitiveAttribute.md +2993 -2993
  75. package/skill/references/classes/IPCB_PrimitiveComponent.md +2624 -2627
  76. package/skill/references/classes/IPCB_PrimitiveComponentPad.md +410 -410
  77. package/skill/references/classes/IPCB_PrimitiveDimension.md +1419 -1419
  78. package/skill/references/classes/IPCB_PrimitiveFill.md +1325 -1325
  79. package/skill/references/classes/IPCB_PrimitiveImage.md +1461 -1461
  80. package/skill/references/classes/IPCB_PrimitiveLine.md +1639 -1639
  81. package/skill/references/classes/IPCB_PrimitiveObject.md +1700 -1700
  82. package/skill/references/classes/IPCB_PrimitivePad.md +3155 -3155
  83. package/skill/references/classes/IPCB_PrimitivePolyline.md +1193 -1193
  84. package/skill/references/classes/IPCB_PrimitivePour.md +1858 -1858
  85. package/skill/references/classes/IPCB_PrimitivePoured.md +556 -556
  86. package/skill/references/classes/IPCB_PrimitiveRegion.md +1332 -1332
  87. package/skill/references/classes/IPCB_PrimitiveString.md +2315 -2315
  88. package/skill/references/classes/IPCB_PrimitiveVia.md +1588 -1588
  89. package/skill/references/classes/ISCH_PrimitiveArc.md +1676 -1676
  90. package/skill/references/classes/ISCH_PrimitiveAttribute.md +2541 -2541
  91. package/skill/references/classes/ISCH_PrimitiveBus.md +973 -973
  92. package/skill/references/classes/ISCH_PrimitiveCbbSymbolComponent.md +260 -260
  93. package/skill/references/classes/ISCH_PrimitiveCircle.md +1392 -1392
  94. package/skill/references/classes/ISCH_PrimitiveComponent.md +2910 -2913
  95. package/skill/references/classes/ISCH_PrimitiveComponentPin.md +155 -155
  96. package/skill/references/classes/ISCH_PrimitiveObject.md +960 -960
  97. package/skill/references/classes/ISCH_PrimitivePin.md +2402 -2402
  98. package/skill/references/classes/ISCH_PrimitivePolygon.md +1028 -1028
  99. package/skill/references/classes/ISCH_PrimitiveRectangle.md +1777 -1777
  100. package/skill/references/classes/ISCH_PrimitiveText.md +1771 -1771
  101. package/skill/references/classes/ISCH_PrimitiveWire.md +973 -973
  102. package/skill/references/classes/LIB_3DModel.md +782 -780
  103. package/skill/references/classes/LIB_Cbb.md +957 -957
  104. package/skill/references/classes/LIB_Classification.md +969 -965
  105. package/skill/references/classes/LIB_Device.md +1222 -1221
  106. package/skill/references/classes/LIB_Footprint.md +1298 -1153
  107. package/skill/references/classes/LIB_LibrariesList.md +361 -329
  108. package/skill/references/classes/LIB_PanelLibrary.md +855 -855
  109. package/skill/references/classes/LIB_SelectControl.md +89 -89
  110. package/skill/references/classes/LIB_SimulationModel.md +807 -821
  111. package/skill/references/classes/LIB_Symbol.md +1341 -1195
  112. package/skill/references/classes/PCB_Document.md +1770 -1754
  113. package/skill/references/classes/PCB_Drc.md +3379 -3375
  114. package/skill/references/classes/PCB_Event.md +1166 -1081
  115. package/skill/references/classes/PCB_ImageTool.md +363 -0
  116. package/skill/references/classes/PCB_Layer.md +1915 -1911
  117. package/skill/references/classes/PCB_ManufactureData.md +2968 -2968
  118. package/skill/references/classes/PCB_MathPolygon.md +916 -785
  119. package/skill/references/classes/PCB_Net.md +1128 -1128
  120. package/skill/references/classes/PCB_Primitive.md +217 -217
  121. package/skill/references/classes/PCB_PrimitiveArc.md +820 -894
  122. package/skill/references/classes/PCB_PrimitiveAttribute.md +635 -717
  123. package/skill/references/classes/PCB_PrimitiveComponent.md +1050 -1050
  124. package/skill/references/classes/PCB_PrimitiveDimension.md +789 -833
  125. package/skill/references/classes/PCB_PrimitiveFill.md +783 -861
  126. package/skill/references/classes/PCB_PrimitiveImage.md +803 -875
  127. package/skill/references/classes/PCB_PrimitiveLine.md +787 -858
  128. package/skill/references/classes/PCB_PrimitiveObject.md +796 -800
  129. package/skill/references/classes/PCB_PrimitivePad.md +947 -944
  130. package/skill/references/classes/PCB_PrimitivePolyline.md +744 -819
  131. package/skill/references/classes/PCB_PrimitivePour.md +808 -845
  132. package/skill/references/classes/PCB_PrimitivePoured.md +363 -363
  133. package/skill/references/classes/PCB_PrimitiveRegion.md +765 -799
  134. package/skill/references/classes/PCB_PrimitiveString.md +828 -910
  135. package/skill/references/classes/PCB_PrimitiveVia.md +761 -765
  136. package/skill/references/classes/PCB_RayTracerEngine.md +603 -263
  137. package/skill/references/classes/PCB_SelectControl.md +495 -495
  138. package/skill/references/classes/PCB_Tool.md +9 -0
  139. package/skill/references/classes/PNL_Document.md +83 -83
  140. package/skill/references/classes/SCH_Document.md +797 -809
  141. package/skill/references/classes/SCH_Drc.md +246 -242
  142. package/skill/references/classes/SCH_Event.md +583 -583
  143. package/skill/references/classes/SCH_ManufactureData.md +1209 -1205
  144. package/skill/references/classes/SCH_Net.md +200 -200
  145. package/skill/references/classes/SCH_Netlist.md +191 -191
  146. package/skill/references/classes/SCH_Primitive.md +337 -337
  147. package/skill/references/classes/SCH_PrimitiveArc.md +686 -692
  148. package/skill/references/classes/SCH_PrimitiveAttribute.md +579 -590
  149. package/skill/references/classes/SCH_PrimitiveBus.md +618 -624
  150. package/skill/references/classes/SCH_PrimitiveCircle.md +667 -683
  151. package/skill/references/classes/SCH_PrimitiveComponent.md +2256 -2240
  152. package/skill/references/classes/SCH_PrimitiveObject.md +666 -666
  153. package/skill/references/classes/SCH_PrimitivePin.md +737 -754
  154. package/skill/references/classes/SCH_PrimitivePolygon.md +621 -627
  155. package/skill/references/classes/SCH_PrimitiveRectangle.md +715 -731
  156. package/skill/references/classes/SCH_PrimitiveText.md +736 -746
  157. package/skill/references/classes/SCH_PrimitiveWire.md +701 -703
  158. package/skill/references/classes/SCH_SelectControl.md +520 -520
  159. package/skill/references/classes/SCH_SimulationEngine.md +133 -133
  160. package/skill/references/classes/SCH_Utils.md +121 -121
  161. package/skill/references/classes/SYS_ClientUrl.md +173 -173
  162. package/skill/references/classes/SYS_Dialog.md +825 -825
  163. package/skill/references/classes/SYS_Environment.md +640 -502
  164. package/skill/references/classes/SYS_ExternalApi.md +246 -0
  165. package/skill/references/classes/SYS_FileManager.md +1664 -1686
  166. package/skill/references/classes/SYS_FileSystem.md +1366 -1171
  167. package/skill/references/classes/SYS_FontManager.md +224 -224
  168. package/skill/references/classes/SYS_FormatConversion.md +349 -349
  169. package/skill/references/classes/SYS_HeaderMenu.md +480 -479
  170. package/skill/references/classes/SYS_Help.md +141 -0
  171. package/skill/references/classes/SYS_I18n.md +861 -861
  172. package/skill/references/classes/SYS_IFrame.md +541 -535
  173. package/skill/references/classes/SYS_LoadingAndProgressBar.md +246 -246
  174. package/skill/references/classes/SYS_Log.md +422 -424
  175. package/skill/references/classes/SYS_Math.md +1565 -1565
  176. package/skill/references/classes/SYS_Message.md +363 -363
  177. package/skill/references/classes/SYS_MessageBox.md +285 -285
  178. package/skill/references/classes/SYS_MessageBus.md +1618 -1618
  179. package/skill/references/classes/SYS_PanelControl.md +696 -696
  180. package/skill/references/classes/SYS_RightClickMenu.md +175 -175
  181. package/skill/references/classes/SYS_Setting.md +134 -85
  182. package/skill/references/classes/SYS_ShortcutKey.md +623 -623
  183. package/skill/references/classes/SYS_Storage.md +484 -484
  184. package/skill/references/classes/SYS_Timer.md +447 -447
  185. package/skill/references/classes/SYS_ToastMessage.md +194 -194
  186. package/skill/references/classes/SYS_Tool.md +317 -241
  187. package/skill/references/classes/SYS_Unit.md +594 -594
  188. package/skill/references/classes/SYS_WebSocket.md +401 -401
  189. package/skill/references/classes/SYS_Window.md +849 -850
  190. package/skill/references/enums/EDMT_EditorDocumentType.md +324 -278
  191. package/skill/references/enums/EDMT_EditorSplitScreenDirection.md +51 -47
  192. package/skill/references/enums/EDMT_EditorTabEventType.md +68 -62
  193. package/skill/references/enums/EDMT_IndicatorMarkerType.md +90 -80
  194. package/skill/references/enums/EDMT_ItemType.md +181 -157
  195. package/skill/references/enums/EDMT_ProjectCollaborationMode.md +51 -47
  196. package/skill/references/enums/EDMT_ProjectFileFormat.md +60 -0
  197. package/skill/references/enums/EDMT_ProjectReadyState.md +82 -0
  198. package/skill/references/enums/ELIB_DeviceJlcLibraryCategory.md +51 -47
  199. package/skill/references/enums/ELIB_LibraryType.md +129 -113
  200. package/skill/references/enums/ELIB_PreviewType.md +77 -69
  201. package/skill/references/enums/ELIB_SimulationModelType.md +51 -47
  202. package/skill/references/enums/ELIB_SymbolType.md +142 -124
  203. package/skill/references/enums/EPCB_AutoRoutingCornerStyle.md +51 -47
  204. package/skill/references/enums/EPCB_AutoRoutingExistingPrimitiveMode.md +51 -47
  205. package/skill/references/enums/EPCB_AutoRoutingOptimization.md +51 -47
  206. package/skill/references/enums/EPCB_DocumentCanvasUpdateCalculationActiveStatus.md +51 -47
  207. package/skill/references/enums/EPCB_DocumentRatlineCalculatingActiveStatus.md +55 -51
  208. package/skill/references/enums/EPCB_InactiveLayerDisplayMode.md +64 -58
  209. package/skill/references/enums/EPCB_LayerColorConfiguration.md +90 -80
  210. package/skill/references/enums/EPCB_LayerId.md +1169 -881
  211. package/skill/references/enums/EPCB_LayerStatus.md +64 -58
  212. package/skill/references/enums/EPCB_LayerType.md +129 -113
  213. package/skill/references/enums/EPCB_MouseEventType.md +64 -58
  214. package/skill/references/enums/EPCB_NetEventType.md +64 -58
  215. package/skill/references/enums/EPCB_PcbPlateType.md +51 -47
  216. package/skill/references/enums/EPCB_PdfOutputMethod.md +64 -58
  217. package/skill/references/enums/EPCB_PrimitiveArcInteractiveMode.md +51 -47
  218. package/skill/references/enums/EPCB_PrimitiveDimensionType.md +64 -58
  219. package/skill/references/enums/EPCB_PrimitiveEventType.md +64 -58
  220. package/skill/references/enums/EPCB_PrimitiveFillMode.md +68 -62
  221. package/skill/references/enums/EPCB_PrimitivePadHeatWeldingConnectionMethod.md +64 -58
  222. package/skill/references/enums/EPCB_PrimitivePadHoleType.md +64 -58
  223. package/skill/references/enums/EPCB_PrimitivePadShapeType.md +90 -80
  224. package/skill/references/enums/EPCB_PrimitivePadType.md +64 -58
  225. package/skill/references/enums/EPCB_PrimitivePourFillMethod.md +64 -58
  226. package/skill/references/enums/EPCB_PrimitiveRegionRuleType.md +107 -95
  227. package/skill/references/enums/EPCB_PrimitiveStringAlignMode.md +142 -124
  228. package/skill/references/enums/EPCB_PrimitiveType.md +233 -201
  229. package/skill/references/enums/EPCB_PrimitiveViaType.md +64 -58
  230. package/skill/references/enums/ESCH_DynamicSimulationEnginePullEventType.md +116 -102
  231. package/skill/references/enums/ESCH_DynamicSimulationEnginePushEventType.md +90 -80
  232. package/skill/references/enums/ESCH_ExportDocumentFileType.md +64 -58
  233. package/skill/references/enums/ESCH_MouseEventType.md +51 -47
  234. package/skill/references/enums/ESCH_PrimitiveComponentType.md +142 -124
  235. package/skill/references/enums/ESCH_PrimitiveEventType.md +77 -69
  236. package/skill/references/enums/ESCH_PrimitiveFillStyle.md +129 -113
  237. package/skill/references/enums/ESCH_PrimitiveLineType.md +77 -69
  238. package/skill/references/enums/ESCH_PrimitivePinShape.md +77 -69
  239. package/skill/references/enums/ESCH_PrimitivePinType.md +168 -146
  240. package/skill/references/enums/ESCH_PrimitiveTextAlignMode.md +142 -124
  241. package/skill/references/enums/ESCH_PrimitiveType.md +207 -179
  242. package/skill/references/enums/ESCH_SimulationNetlistType.md +38 -36
  243. package/skill/references/enums/ESCH_SpiceSimulationEnginePullEventType.md +51 -47
  244. package/skill/references/enums/ESCH_SpiceSimulationEnginePushEventType.md +77 -69
  245. package/skill/references/enums/ESYS_BottomPanelTab.md +94 -80
  246. package/skill/references/enums/ESYS_HeaderMenuEnvironment.md +181 -157
  247. package/skill/references/enums/ESYS_ImportProjectBoardOutlineSource.md +55 -51
  248. package/skill/references/enums/ESYS_ImportProjectImportOption.md +64 -58
  249. package/skill/references/enums/ESYS_ImportProjectSchematicObjectStyle.md +51 -47
  250. package/skill/references/enums/ESYS_ImportProjectViaSolderMaskExpansion.md +55 -51
  251. package/skill/references/enums/ESYS_JobState.md +95 -0
  252. package/skill/references/enums/ESYS_LeftPanelTab.md +94 -80
  253. package/skill/references/enums/ESYS_LogType.md +77 -102
  254. package/skill/references/enums/ESYS_NetlistType.md +129 -113
  255. package/skill/references/enums/ESYS_PanelPosition.md +69 -0
  256. package/skill/references/enums/ESYS_PanelTab.md +368 -0
  257. package/skill/references/enums/ESYS_RightPanelTab.md +237 -201
  258. package/skill/references/enums/ESYS_ShortcutKeyEffectiveEditorRange.md +220 -190
  259. package/skill/references/enums/ESYS_ShortcutKeyEffectiveEditorScene.md +103 -91
  260. package/skill/references/enums/ESYS_StartPageQuickStartItem.md +237 -205
  261. package/skill/references/enums/ESYS_Theme.md +51 -47
  262. package/skill/references/enums/ESYS_ToastMessageType.md +90 -80
  263. package/skill/references/enums/ESYS_Unit.md +116 -102
  264. package/skill/references/enums/ESYS_WindowEventType.md +64 -47
  265. package/skill/references/enums/ESYS_WindowOpenTarget.md +51 -47
  266. package/skill/references/enums/NetportDeviceName.md +146 -146
  267. package/skill/references/enums/SchToolBarDeviceName.md +278 -278
  268. package/skill/references/interfaces/BoardProps.md +169 -169
  269. package/skill/references/interfaces/BorderConfig.md +109 -0
  270. package/skill/references/interfaces/ButtonProps.md +196 -169
  271. package/skill/references/interfaces/CellClickInfo.md +142 -0
  272. package/skill/references/interfaces/CellCoord.md +88 -0
  273. package/skill/references/interfaces/CheckBoxProps.md +223 -196
  274. package/skill/references/interfaces/CheckChangeDetail.md +88 -0
  275. package/skill/references/interfaces/CheckboxEditConfig.md +159 -0
  276. package/skill/references/interfaces/ClipboardCellData.md +142 -0
  277. package/skill/references/interfaces/ClipboardConfig.md +115 -0
  278. package/skill/references/interfaces/ColorPickerProps.md +169 -0
  279. package/skill/references/interfaces/ColumnDef.md +605 -0
  280. package/skill/references/interfaces/ColumnEditTrigger.md +57 -0
  281. package/skill/references/interfaces/ColumnGroupDef.md +192 -0
  282. package/skill/references/interfaces/ColumnResizeConfig.md +142 -0
  283. package/skill/references/interfaces/ComponentPropsMap.md +517 -448
  284. package/skill/references/interfaces/CustomHeaderConfig.md +169 -0
  285. package/skill/references/interfaces/DialogProps.md +385 -385
  286. package/skill/references/interfaces/DragSortConfig.md +115 -0
  287. package/skill/references/interfaces/EditingConfig.md +196 -0
  288. package/skill/references/interfaces/FilteringConfig.md +250 -0
  289. package/skill/references/interfaces/FixedColumnConfig.md +88 -0
  290. package/skill/references/interfaces/FlexItemProps.md +116 -116
  291. package/skill/references/interfaces/FlexProps.md +224 -224
  292. package/skill/references/interfaces/GridItemProps.md +143 -143
  293. package/skill/references/interfaces/GridProps.md +143 -143
  294. package/skill/references/interfaces/IDMT_BoardItem.md +171 -171
  295. package/skill/references/interfaces/IDMT_BriefProjectItem.md +171 -171
  296. package/skill/references/interfaces/IDMT_EditorDocumentItem.md +169 -169
  297. package/skill/references/interfaces/IDMT_EditorSplitScreenItem.md +173 -173
  298. package/skill/references/interfaces/IDMT_EditorTabItem.md +169 -169
  299. package/skill/references/interfaces/IDMT_FolderItem.md +225 -225
  300. package/skill/references/interfaces/IDMT_IndicatorMarkerShape.md +393 -393
  301. package/skill/references/interfaces/IDMT_PanelItem.md +144 -144
  302. package/skill/references/interfaces/IDMT_PcbItem.md +171 -171
  303. package/skill/references/interfaces/IDMT_ProjectItem.md +143 -143
  304. package/skill/references/interfaces/IDMT_SchematicItem.md +225 -225
  305. package/skill/references/interfaces/IDMT_SchematicPageItem.md +198 -198
  306. package/skill/references/interfaces/IDMT_TeamItem.md +144 -144
  307. package/skill/references/interfaces/IDMT_WorkspaceItem.md +117 -117
  308. package/skill/references/interfaces/IDesignPortal.md +103 -103
  309. package/skill/references/interfaces/ILIB_3DModelItem.md +198 -198
  310. package/skill/references/interfaces/ILIB_3DModelSearchItem.md +277 -277
  311. package/skill/references/interfaces/ILIB_CbbItem.md +225 -225
  312. package/skill/references/interfaces/ILIB_CbbSearchItem.md +277 -277
  313. package/skill/references/interfaces/ILIB_ClassificationIndex.md +150 -150
  314. package/skill/references/interfaces/ILIB_ClassificationNode.md +98 -0
  315. package/skill/references/interfaces/ILIB_DeviceAssociationItem.md +210 -210
  316. package/skill/references/interfaces/ILIB_DeviceExtendPropertyItem.md +304 -304
  317. package/skill/references/interfaces/ILIB_DeviceItem.md +279 -279
  318. package/skill/references/interfaces/ILIB_DevicePropertiesForSearch.md +250 -250
  319. package/skill/references/interfaces/ILIB_DeviceSearchItem.md +521 -521
  320. package/skill/references/interfaces/ILIB_ExtendLibrary3DModelFunctions.md +64 -64
  321. package/skill/references/interfaces/ILIB_ExtendLibraryCbbFunctions.md +93 -99
  322. package/skill/references/interfaces/ILIB_ExtendLibraryClassificationIndex.md +150 -150
  323. package/skill/references/interfaces/ILIB_ExtendLibraryDeviceFunctions.md +143 -157
  324. package/skill/references/interfaces/ILIB_ExtendLibraryFootprintFunctions.md +63 -63
  325. package/skill/references/interfaces/ILIB_ExtendLibraryFunctions.md +123 -123
  326. package/skill/references/interfaces/ILIB_ExtendLibraryItem.md +97 -97
  327. package/skill/references/interfaces/ILIB_ExtendLibraryItemIndex.md +98 -98
  328. package/skill/references/interfaces/ILIB_ExtendLibrarySearchProperty.md +115 -115
  329. package/skill/references/interfaces/ILIB_ExtendLibrarySearchResult.md +169 -169
  330. package/skill/references/interfaces/ILIB_ExtendLibrarySearchResultDataLine.md +234 -234
  331. package/skill/references/interfaces/ILIB_ExtendLibrarySymbolFunctions.md +91 -105
  332. package/skill/references/interfaces/ILIB_ExtendLibraryUserIndex.md +96 -96
  333. package/skill/references/interfaces/ILIB_FootprintItem.md +256 -198
  334. package/skill/references/interfaces/ILIB_FootprintPropertiesForSearch.md +61 -61
  335. package/skill/references/interfaces/ILIB_FootprintSearchItem.md +277 -277
  336. package/skill/references/interfaces/ILIB_LibraryInfo.md +92 -92
  337. package/skill/references/interfaces/ILIB_LibraryItem.md +115 -115
  338. package/skill/references/interfaces/ILIB_PanelLibraryItem.md +198 -198
  339. package/skill/references/interfaces/ILIB_PanelLibrarySearchItem.md +277 -277
  340. package/skill/references/interfaces/ILIB_RegisterExtendLibraryProps.md +71 -0
  341. package/skill/references/interfaces/ILIB_SimulationModelItem.md +306 -306
  342. package/skill/references/interfaces/ILIB_SimulationModelSearchItem.md +304 -304
  343. package/skill/references/interfaces/ILIB_SymbolItem.md +306 -279
  344. package/skill/references/interfaces/ILIB_SymbolPropertiesForSearch.md +61 -61
  345. package/skill/references/interfaces/ILIB_SymbolSearchItem.md +304 -304
  346. package/skill/references/interfaces/IPCB_AutoLayoutResult.md +169 -169
  347. package/skill/references/interfaces/IPCB_AutoRoutingProps.md +220 -220
  348. package/skill/references/interfaces/IPCB_AutoRoutingResult.md +169 -169
  349. package/skill/references/interfaces/IPCB_BomPropertiesTableColumns.md +169 -169
  350. package/skill/references/interfaces/IPCB_DifferentialPairItem.md +115 -115
  351. package/skill/references/interfaces/IPCB_DiscretizeOptions.md +65 -65
  352. package/skill/references/interfaces/IPCB_DiscretizedPoint.md +88 -88
  353. package/skill/references/interfaces/IPCB_EqualLengthNetGroupItem.md +115 -115
  354. package/skill/references/interfaces/IPCB_LayerItem.md +277 -277
  355. package/skill/references/interfaces/IPCB_NetClassItem.md +115 -115
  356. package/skill/references/interfaces/IPCB_NetInfo.md +115 -115
  357. package/skill/references/interfaces/IPCB_PadPairGroupItem.md +88 -88
  358. package/skill/references/interfaces/IPCB_PadPairMinWireLengthItem.md +88 -88
  359. package/skill/references/interfaces/IPCB_PhysicalStackingConfiguration.md +115 -115
  360. package/skill/references/interfaces/IPCB_Primitive.md +218 -218
  361. package/skill/references/interfaces/IPCB_PrimitiveAPI.md +174 -175
  362. package/skill/references/interfaces/IPCB_PrimitivePadHeatWelding.md +151 -151
  363. package/skill/references/interfaces/IPCB_PrimitivePouredPourFill.md +142 -142
  364. package/skill/references/interfaces/IPCB_PrimitiveSolderMaskAndPasteMaskExpansion.md +154 -154
  365. package/skill/references/interfaces/IPCB_RayTracerBackgroundConfig.md +223 -0
  366. package/skill/references/interfaces/IPCB_RayTracerLightConfig.md +412 -0
  367. package/skill/references/interfaces/IPCB_RayTracerMaterialConfig.md +547 -0
  368. package/skill/references/interfaces/IPCB_RayTracerPcbMaterialConfig.md +196 -0
  369. package/skill/references/interfaces/IPCB_RayTracerRenderConfigurations.md +200 -0
  370. package/skill/references/interfaces/IPCB_RayTracerRendererConfig.md +196 -0
  371. package/skill/references/interfaces/IPCB_RayTracerSceneElement.md +115 -0
  372. package/skill/references/interfaces/IPCB_RayTracerSceneElementTransform.md +123 -0
  373. package/skill/references/interfaces/IPCB_RayTracerTexture.md +88 -0
  374. package/skill/references/interfaces/IPCB_SubstratePhysicalProperties.md +88 -88
  375. package/skill/references/interfaces/IRawNet.md +103 -103
  376. package/skill/references/interfaces/IRawPureSchematic.md +80 -80
  377. package/skill/references/interfaces/IRawSchematic.md +103 -103
  378. package/skill/references/interfaces/IRawWire.md +149 -149
  379. package/skill/references/interfaces/ISCH_DrcError.md +142 -142
  380. package/skill/references/interfaces/ISCH_DrcErrorPrimitive.md +142 -142
  381. package/skill/references/interfaces/ISCH_ExportPngResolution.md +94 -94
  382. package/skill/references/interfaces/ISCH_NetInfo.md +88 -88
  383. package/skill/references/interfaces/ISCH_Primitive.md +218 -219
  384. package/skill/references/interfaces/ISCH_PrimitiveAPI.md +174 -175
  385. package/skill/references/interfaces/ISCH_ProjectNetInfo.md +142 -142
  386. package/skill/references/interfaces/ISCH_WireInfo.md +169 -169
  387. package/skill/references/interfaces/ISYS_ComparisonResponse.md +115 -0
  388. package/skill/references/interfaces/ISYS_ExtensionExternalApiIndex.md +13 -0
  389. package/skill/references/interfaces/ISYS_ExtensionRegisteredExternalApis.md +13 -0
  390. package/skill/references/interfaces/ISYS_ExternalApiHelp.md +173 -0
  391. package/skill/references/interfaces/ISYS_ExternalApiRegistration.md +146 -0
  392. package/skill/references/interfaces/ISYS_FileSystemFileList.md +169 -169
  393. package/skill/references/interfaces/ISYS_HeaderMenuSub1MenuItem.md +205 -174
  394. package/skill/references/interfaces/ISYS_HeaderMenuSub2MenuItem.md +178 -147
  395. package/skill/references/interfaces/ISYS_HeaderMenuTopMenuItem.md +115 -115
  396. package/skill/references/interfaces/ISYS_HeaderMenus.md +408 -408
  397. package/skill/references/interfaces/ISYS_HelpAudienceEntry.md +92 -0
  398. package/skill/references/interfaces/ISYS_HelpClassSummary.md +205 -0
  399. package/skill/references/interfaces/ISYS_HelpData.md +92 -0
  400. package/skill/references/interfaces/ISYS_HelpMethodDetail.md +310 -0
  401. package/skill/references/interfaces/ISYS_JobHandle.md +65 -0
  402. package/skill/references/interfaces/ISYS_JobLogEntry.md +142 -0
  403. package/skill/references/interfaces/ISYS_JobStatus.md +176 -0
  404. package/skill/references/interfaces/ISYS_LogLine.md +115 -115
  405. package/skill/references/interfaces/ISYS_MathBBox.md +142 -142
  406. package/skill/references/interfaces/ISYS_MathPoint.md +88 -88
  407. package/skill/references/interfaces/ISYS_MathPolygonWithHoles.md +92 -92
  408. package/skill/references/interfaces/ISYS_MessageBusTask.md +115 -115
  409. package/skill/references/interfaces/ISYS_MultilingualLanguagesData.md +12 -12
  410. package/skill/references/interfaces/ISYS_RightClickMenuItem.md +174 -174
  411. package/skill/references/interfaces/ISYS_ShortcutKeyData.md +169 -169
  412. package/skill/references/interfaces/ISYS_ShortcutKeyDataWithCallFn.md +62 -62
  413. package/skill/references/interfaces/ISYS_ShortcutKeyDataWithUserDefinedShortcutKey.md +62 -62
  414. package/skill/references/interfaces/ISYS_WindowEventListenerRemovableObject.md +109 -109
  415. package/skill/references/interfaces/IconProps.md +88 -88
  416. package/skill/references/interfaces/ImageProps.md +115 -115
  417. package/skill/references/interfaces/InputEditConfig.md +182 -0
  418. package/skill/references/interfaces/InputProps.md +547 -520
  419. package/skill/references/interfaces/KeyboardConfig.md +61 -0
  420. package/skill/references/interfaces/ListChildren.md +223 -223
  421. package/skill/references/interfaces/ListProps.md +250 -223
  422. package/skill/references/interfaces/ModalProps.md +358 -358
  423. package/skill/references/interfaces/NumberEditConfig.md +234 -0
  424. package/skill/references/interfaces/RadioGroupProps.md +196 -196
  425. package/skill/references/interfaces/RadioItem.md +115 -115
  426. package/skill/references/interfaces/RichTableProps.md +1357 -0
  427. package/skill/references/interfaces/RowMetaConfig.md +142 -0
  428. package/skill/references/interfaces/ScrollerProps.md +169 -169
  429. package/skill/references/interfaces/SelectEditConfig.md +211 -0
  430. package/skill/references/interfaces/SelectListItem.md +142 -142
  431. package/skill/references/interfaces/SelectOption.md +142 -0
  432. package/skill/references/interfaces/SelectProps.md +169 -169
  433. package/skill/references/interfaces/SelectionConfig.md +358 -0
  434. package/skill/references/interfaces/SliderProps.md +142 -0
  435. package/skill/references/interfaces/SlotProps.md +88 -88
  436. package/skill/references/interfaces/SortState.md +88 -0
  437. package/skill/references/interfaces/SortingConfig.md +169 -0
  438. package/skill/references/interfaces/StyleProps.md +439 -385
  439. package/skill/references/interfaces/TextAreaProps.md +196 -196
  440. package/skill/references/interfaces/TextProps.md +169 -169
  441. package/skill/references/interfaces/TextareaEditConfig.md +182 -0
  442. package/skill/references/interfaces/ValidationRule.md +223 -0
  443. package/skill/references/interfaces/VirtualScrollConfig.md +115 -0
  444. package/skill/references/types/Align.md +9 -0
  445. package/skill/references/types/CellContentType.md +9 -0
  446. package/skill/references/types/ColumnDefOrGroup.md +12 -0
  447. package/skill/references/types/ColumnEditConfig.md +13 -0
  448. package/skill/references/types/ColumnType.md +9 -0
  449. package/skill/references/types/DataChangeType.md +9 -0
  450. package/skill/references/types/FilterMatchMode.md +9 -0
  451. package/skill/references/types/RichTableRow.md +12 -0
  452. package/skill/references/types/Serializable.md +10 -0
  453. package/skill/references/types/SerializablePrimitive.md +9 -0
  454. package/skill/references/types/SortOrder.md +9 -0
  455. package/skill/references/types/TPCB_LayerTypesOfInnerLayer.md +11 -11
  456. package/skill/references/types/TPCB_LayersInTheSelectable.md +42 -42
  457. package/skill/references/types/TPCB_LayersOfComponent.md +11 -11
  458. package/skill/references/types/TPCB_LayersOfCopper.md +15 -15
  459. package/skill/references/types/TPCB_LayersOfCustom.md +41 -41
  460. package/skill/references/types/TPCB_LayersOfDimension.md +16 -16
  461. package/skill/references/types/TPCB_LayersOfFill.md +28 -28
  462. package/skill/references/types/TPCB_LayersOfImage.md +22 -22
  463. package/skill/references/types/TPCB_LayersOfInner.md +41 -41
  464. package/skill/references/types/TPCB_LayersOfLine.md +25 -25
  465. package/skill/references/types/TPCB_LayersOfObject.md +12 -12
  466. package/skill/references/types/TPCB_LayersOfPad.md +11 -11
  467. package/skill/references/types/TPCB_LayersOfRegion.md +11 -11
  468. package/skill/references/types/TPCB_NumberOfCopperLayers.md +9 -9
  469. package/skill/references/types/TPCB_PolygonSourceArray.md +85 -83
  470. package/skill/references/types/TPCB_PrimitiveDimensionCoordinateSet.md +66 -66
  471. package/skill/references/types/TPCB_PrimitivePadHole.md +30 -30
  472. package/skill/references/types/TPCB_PrimitivePadShape.md +61 -61
  473. package/skill/references/types/TPCB_PrimitiveSpecialPadShape.md +19 -19
  474. package/skill/references/types/TSYS_ComparisonErrorCode.md +15 -0
  475. package/skill/references/types/TSYS_LanguageKeyValuePairs.md +13 -0
  476. package/skill/references/types/TSYS_MathPolygonGroup.md +15 -15
  477. package/skill/references/types/TSYS_MathPolygonInput.md +20 -20
  478. package/skill/references/types/TSYS_ShortcutKeys.md +96 -96
  479. package/skill/user-guide/using-extension.md +47 -47
  480. package/src/json-gen.test.js +430 -0
  481. package/skill/guide/ancillary-projects/pro-api-sdk.md +0 -1
  482. package/skill/references/interfaces/ISYS_PcbComparisonResponse.md +0 -115
  483. package/skill/references/types/ISYS_LanguageKeyValuePairs.md +0 -13
  484. package/skill/references/types/TSYS_PcbComparisonErrorCode.md +0 -10
package/skill/SKILL.md CHANGED
@@ -1,746 +1,746 @@
1
- ---
2
- name: easyeda-api
3
- description: >-
4
- EasyEDA Pro API skill for AI agents. Use when working with EasyEDA Pro EDA software,
5
- including PCB design, schematic editing, footprint/symbol management, and project operations.
6
- Supports live debugging in EasyEDA and EasyEDA extension development. Provides complete API
7
- reference (120+ classes, 62 enums, 70 interfaces), extension-development documentation, and a
8
- WebSocket bridge server to execute code in the running EasyEDA Pro client.
9
- Trigger on: "嘉立创EDA,启动!", "立创EDA,启动!", "EDA,启动!",
10
- "EasyEDA", "PCB", "schematic", "footprint", "EDA", "circuit board",
11
- "嘉立创EDA", "原理图", "PCB设计".
12
- **IMPORTANT**: 嘉立创EDA's English name is **EasyEDA**. They are the SAME product.
13
- Never use other transliterations like "EasyEDA Pro" (unless specifically versioned), "EASYEDA", "easyeda", etc. Always use "EasyEDA" for English references and "嘉立创EDA" for Chinese references.
14
- license: MIT
15
- compatibility: Requires Node.js 18+, EasyEDA Pro desktop client with extension support
16
- metadata:
17
- author: JLCEDA
18
- version: "1.1.28"
19
- openclaw:
20
- requires:
21
- bins:
22
- - node
23
- env:
24
- - CLAUDE_SKILL_DIR
25
- ---
26
-
27
- # EasyEDA Pro API Skill
28
-
29
- Control EasyEDA Pro (嘉立创EDA专业版) programmatically through AI. This skill provides:
30
-
31
- 1. **Complete API reference** — 120 classes, 62 enums, 70 interfaces, 19 type aliases
32
- 2. **WebSocket bridge** — Execute code in the running EasyEDA Pro client
33
- 3. **Code patterns** — Common operations for PCB, schematic, library, and project management
34
- 4. **Document source format reference** — File format specifications for project, schematic, and PCB sources when users need to analyze or modify EasyEDA document source directly instead of using the API
35
-
36
- This skill supports not only live debugging in EasyEDA, but also EasyEDA extension development.
37
- 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.
38
-
39
- ## Architecture
40
-
41
- ```
42
- ┌───────────┐ HTTP/WS ┌─────────────────┐ WebSocket ┌───────────┐
43
- │ AI Agent │ ◄───────────► │ Bridge Server │ ◄───────────► │ EasyEDA │
44
- │ │ Port Range │ (Node.js) │ Port Range │ (Client) │
45
- └───────────┘ 49620-49629 └─────────────────┘ 49620-49629 └───────────┘
46
- ```
47
-
48
- The server auto-selects an available port from 49620-49629 on startup.
49
- Both AI and EDA clients auto-discover the server by scanning the port range
50
- and verifying a handshake (`service: "easyeda-bridge"`).
51
-
52
- ## Quick Start
53
-
54
- ### 1. Command Triggers
55
-
56
- When user says **"嘉立创EDA,启动!"**, **"立创EDA,启动!"**, or **"EDA,启动!"**:
57
-
58
- **IMPORTANT: Session initialization** — Reply immediately with this exact text to set the correct session title:
59
-
60
- ```
61
- 📋 EasyEDA Session
62
- ```
63
-
64
- Then proceed with the setup steps below.
65
-
66
- ### 2. Install dependencies (if needed)
67
-
68
- ```bash
69
- cd ${CLAUDE_SKILL_DIR} && npm install
70
- ```
71
-
72
- ### 3. Start bridge server
73
-
74
- > **⚠️ 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.
75
-
76
- ```bash
77
- # Check if bridge is already running
78
- for port in $(seq 49620 49629); do
79
- resp=$(curl -s http://localhost:$port/health 2>/dev/null)
80
- if echo "$resp" | grep -q '"easyeda-bridge"'; then
81
- echo "Bridge already running on port $port"
82
- BRIDGE_PORT=$port
83
- break
84
- fi
85
- done
86
-
87
- # Start bridge if not running
88
- if [ -z "$BRIDGE_PORT" ]; then
89
- node ${CLAUDE_SKILL_DIR}/scripts/bridge-server.mjs &
90
- sleep 2
91
- # Find the port bridge is running on
92
- for port in $(seq 49620 49629); do
93
- resp=$(curl -s http://localhost:$port/health 2>/dev/null)
94
- if echo "$resp" | grep -q '"easyeda-bridge"'; then
95
- BRIDGE_PORT=$port
96
- break
97
- fi
98
- done
99
- fi
100
-
101
- echo "Bridge running on port: ${BRIDGE_PORT:-unknown}"
102
- ```
103
-
104
- ### 4. Connect EasyEDA
105
-
106
- Install the `run-api-gateway.eext` extension in EasyEDA Pro. Download link:
107
-
108
- - https://jlc-ext.com/item/oshwhub/run-api-gateway
109
-
110
- After the extension is loaded, it will automatically establish the WebSocket connection.
111
-
112
- ### 5. Verify connection and select EDA window
113
-
114
- ```bash
115
- # Check bridge and EDA connection status
116
- curl http://localhost:${BRIDGE_PORT:-49620}/health
117
-
118
- # List all connected EDA windows
119
- curl http://localhost:${BRIDGE_PORT:-49620}/eda-windows
120
- ```
121
-
122
- The `/eda-windows` response looks like:
123
- ```json
124
- {
125
- "windows": [
126
- { "windowId": "abc-123", "connected": true, "active": true },
127
- { "windowId": "def-456", "connected": true, "active": false }
128
- ],
129
- "activeWindowId": "abc-123",
130
- "count": 2
131
- }
132
- ```
133
-
134
- **Handle based on window count**:
135
- - **0 windows**: Tell user "No EasyEDA window is connected. Please ensure the EasyEDA extension (run-api-gateway.eext) is installed and loaded in EasyEDA. Download: https://jlc-ext.com/item/oshwhub/run-api-gateway"
136
- - **1 window**: Auto-selected as active. Tell user: "✅ Connected! Active EDA window: abc-123. Ready to work."
137
- - **2+ windows**: Show the available windows and ask user to select:
138
- ```
139
- Multiple EDA windows detected:
140
- - abc-123 (active)
141
- - def-456
142
-
143
- Which EDA window should I use?
144
- ```
145
-
146
- **Select a window**:
147
- ```bash
148
- curl -X POST http://localhost:${BRIDGE_PORT}/eda-windows/select \
149
- -H "Content-Type: application/json" \
150
- -d '{"windowId": "abc-123"}'
151
- ```
152
-
153
- After selection, confirm: "✅ Active EDA window: abc-123. Ready to work."
154
-
155
- ### 6. Execute code on EDA
156
-
157
- ```bash
158
- curl -X POST http://localhost:${BRIDGE_PORT:-49620}/execute \
159
- -H "Content-Type: application/json" \
160
- -d '{"code": "return await eda.dmt_Project.getCurrentProjectInfo();"}'
161
- ```
162
-
163
- ## API Documentation
164
-
165
- The full API reference is in the [references/](references/) directory:
166
-
167
- - [references/_index.md](references/_index.md) — Master index of all classes, enums, interfaces, and types
168
- - [references/_quick-reference.md](references/_quick-reference.md) — All method signatures for rapid lookup
169
- - `references/classes/` — 120 class docs (DMT_*, PCB_*, SCH_*, LIB_*, SYS_*, IPCB_*, ISCH_*)
170
- - `references/enums/` — 62 enum docs
171
- - `references/interfaces/` — 70 interface docs
172
- - `references/types/` — 19 type alias docs
173
-
174
- ### How to look up API
175
-
176
- 1. **Start with `_index.md`** to find the right class/module for the task
177
- 2. **Read the class doc** (e.g., `references/classes/DMT_Board.md`) for all methods and signatures
178
- 3. **Use `_quick-reference.md`** for fast method signature lookup across all classes
179
- 4. **Check enums/interfaces** for parameter types and return types
180
-
181
- ### Document Source Format Documentation
182
-
183
- If the user needs to analyze or modify EasyEDA document source directly instead of using the API, use the documents in the [format/](format/) directory.
184
-
185
- - [format/index.md](format/index.md) — Overview of the EasyEDA document source format references and version notes
186
- - `format/project/` — Project source structure, metadata, blobs, variants, and grouping data
187
- - `format/schematic/` — Schematic source format, including structure, wires, shapes, pins, components, and tables
188
- - `format/pcb/` — PCB source format, including primitives, pads and vias, shapes, text, attributes, rules, and panel data
189
-
190
- Use 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.
191
-
192
- ### API Module Overview
193
-
194
- | Prefix | Domain | Key Classes |
195
- |--------|--------|-------------|
196
- | `DMT_` | Document management | Board, EditorControl, Folder, Panel, Pcb, Project, Schematic, SelectControl, Team, Workspace |
197
- | `PCB_` | PCB & Footprint | Document, Drc, Event, Layer, Net, Primitive, PrimitiveComponent, PrimitiveLine, PrimitivePad, PrimitivePour, PrimitiveVia, SelectControl |
198
- | `SCH_` | Schematic | Document, Event, Primitive, PrimitiveComponent, PrimitiveWire, SelectControl |
199
- | `LIB_` | Library | 3DModel, Cbb, Classification, Device, Footprint, LibrariesList, PanelLibrary, SelectControl, Symbol |
200
- | `SYS_` | System | Dialog, Environment, FileManager, FileSystem, FontManager, HeaderMenu, I18n, IFrame, LoadingAndProgressBar, Log, Message, MessageBox, MessageBus, PanelControl, Setting, ShortcutKey, Storage, Timer, ToastMessage, WebSocket, Window |
201
- | `IPCB_` | PCB interfaces (图元) | PrimitiveArc, PrimitiveComponent, PrimitivePad, PrimitiveFill, PrimitivePour, PrimitiveRegion, PrimitiveVia, ... |
202
- | `ISCH_` | Schematic interfaces (图元) | PrimitiveArc, PrimitiveComponent, PrimitiveWire, PrimitiveText, PrimitiveRectangle, ... |
203
- | `EPCB_` / `ESCH_` | Enums | PrimitiveType, Layer, PadType, ... |
204
-
205
- ## Code Execution Context
206
-
207
- All code runs inside EasyEDA Pro's browser runtime as:
208
-
209
- ```javascript
210
- async function(eda) {
211
- // Your code here — `eda` is the global EDA API object
212
- // You MUST use `return` to send results back
213
- // Do not add comments to the generated code, as the code is typically executed as a single line
214
- }
215
- ```
216
-
217
- **Critical rules:**
218
- - The `eda` object provides access to all API modules (e.g., `eda.dmt_Board`, `eda.pcb_Primitive`).
219
- - Always refer to the API documentation for correct usage.
220
- - Do not add comments to the generated code, as the code is typically executed as a single line.
221
- - Always use `return` to get results — `console.log` output is NOT captured.
222
- - All API methods returning promises must be `await`ed.
223
- - Code runs in browser context — no Node.js APIs (fs, path, etc.) available.
224
- - Use `eda.sys_Message.showToastMessage(msg)` for user-visible notifications.
225
- - When reviewing API documentation and encountering enumerations, do not guess the enumeration values. You must use the enumeration members, for example: `EPCB_LayerId.TOP` instead of `1` for the layer parameter in PCB primitive creation.
226
-
227
- ### Extension Runtime Constraints
228
-
229
- When writing EasyEDA extensions, standard browser APIs are **forbidden** in the main process. Use EDA-provided alternatives:
230
-
231
- | Purpose | ❌ Forbidden | ✅ Use Instead |
232
- |---------|-------------|----------------|
233
- | Get user input | — | `eda.sys_Dialog.showInputDialog()` |
234
- | User selection | — | `eda.sys_Dialog.showSelectDialog()` |
235
- | Show message | `alert()` | `eda.sys_Dialog.showInformationMessage()` |
236
- | Confirm action | `confirm()` | `eda.sys_Dialog.showConfirmationMessage()` |
237
- | Toast notification | DOM manipulation | `eda.sys_Message.showToastMessage()` |
238
- | Store data | `localStorage` (main process) | `eda.sys_Storage.setExtensionUserConfig(key, value)` |
239
- | Custom UI | Manipulate host DOM | `eda.sys_IFrame.openIFrame()` |
240
- | Show HTML | `showInformationMessage(html)` | Must use iframe |
241
- | Open link | `window.open()` | `eda.sys_Window.open()` |
242
- | Browser hardware API | Use in main process | Available in iframe (`navigator.serial`, etc.) |
243
-
244
- **Note:** `localStorage`, `window`, `document` etc. are available **inside `sys_IFrame`** but NOT in the main extension process.
245
-
246
- ### Extension ↔ IFrame Data Passing
247
-
248
- The main extension process and `sys_IFrame` iframe are **isolated contexts**. To pass data between them:
249
-
250
- **Option A (Recommended):** Use `eda.sys_Storage` as a bridge
251
- ```javascript
252
- // In main extension process:
253
- await eda.sys_Storage.setExtensionUserConfig('myKey', JSON.stringify(data));
254
-
255
- // In iframe:
256
- const data = JSON.parse(await eda.sys_Storage.getExtensionUserConfig('myKey'));
257
- ```
258
-
259
- **Option B:** Both contexts can access `eda` directly — call the same API from either side
260
- ```javascript
261
- // In iframe HTML (NOT window.parent.eda):
262
- const info = await eda.dmt_Project.getCurrentProjectInfo();
263
- ```
264
-
265
- ## Communication Protocol
266
-
267
- ### Port Discovery
268
-
269
- The bridge server listens on the first available port in **49620-49629**.
270
- To find the server, scan the range and verify the service identity:
271
-
272
- ```bash
273
- for port in $(seq 49620 49629); do
274
- resp=$(curl -s http://127.0.0.1:$port/health 2>/dev/null)
275
- if echo "$resp" | grep -q '"easyeda-bridge"'; then
276
- BRIDGE_PORT=$port; break
277
- fi
278
- done
279
- ```
280
-
281
- ### Handshake
282
-
283
- - **HTTP**: `GET /health` returns `{ "service": "easyeda-bridge", "edaConnected": bool, ... }`
284
- - **WebSocket**: On connect, server sends `{ "type": "handshake", "service": "easyeda-bridge" }`
285
- - Clients MUST verify `service === "easyeda-bridge"` before using the connection
286
-
287
- ### Message Format
288
-
289
- JSON messages over WebSocket / HTTP:
290
-
291
- | Field | Type | Description |
292
- |-------|------|-------------|
293
- | `type` | `"execute"` \| `"result"` \| `"error"` \| `"ping"` \| `"pong"` \| `"handshake"` | Message type |
294
- | `id` | `string` | Request UUID for matching request/response |
295
- | `code` | `string` | JavaScript code to execute (for `execute` type) |
296
- | `result` | `any` | Execution result (for `result` type) |
297
- | `error` | `string` | Error message (for `error` type) |
298
- | `service` | `string` | Service identifier (for `handshake` type) |
299
- | `timestamp` | `number` | Unix milliseconds |
300
-
301
- ## Common Patterns
302
-
303
- ### Project & Board Operations
304
-
305
- ```javascript
306
- // Get current project info
307
- return await eda.dmt_Project.getCurrentProjectInfo();
308
-
309
- // List all boards in project
310
- return await eda.dmt_Board.getAllBoardsInfo();
311
-
312
- // Create a new board (optionally link to schematic/PCB)
313
- return await eda.dmt_Board.createBoard();
314
-
315
- // Switch to a document tab
316
- await eda.dmt_EditorControl.activateDocument(tabId);
317
- ```
318
-
319
- ### Example: Open a project by name and open its first schematic page
320
-
321
- ```javascript
322
- const targetProjectName = 'NE555 Circuit';
323
-
324
- // 1. Enumerate projects by team/folder and find the target by name
325
- const teams = await eda.dmt_Team.getAllTeamsInfo();
326
- const seenProjectUuid = new Set();
327
- let targetProjectUuid = null;
328
-
329
- for (const team of teams || []) {
330
- const teamProjects = await eda.dmt_Project.getAllProjectsUuid(team.uuid);
331
- for (const projectUuid of teamProjects || []) {
332
- if (seenProjectUuid.has(projectUuid)) continue;
333
- seenProjectUuid.add(projectUuid);
334
-
335
- const info = await eda.dmt_Project.getProjectInfo(projectUuid);
336
- const name = info?.friendlyName || info?.name || '';
337
- if (name === targetProjectName) {
338
- targetProjectUuid = projectUuid;
339
- break;
340
- }
341
- }
342
- if (targetProjectUuid) break;
343
-
344
- const folderUuids = await eda.dmt_Folder.getAllFoldersUuid(team.uuid);
345
- for (const folderUuid of folderUuids || []) {
346
- const folderProjects = await eda.dmt_Project.getAllProjectsUuid(team.uuid, folderUuid);
347
- for (const projectUuid of folderProjects || []) {
348
- if (seenProjectUuid.has(projectUuid)) continue;
349
- seenProjectUuid.add(projectUuid);
350
-
351
- const info = await eda.dmt_Project.getProjectInfo(projectUuid);
352
- const name = info?.friendlyName || info?.name || '';
353
- if (name === targetProjectName) {
354
- targetProjectUuid = projectUuid;
355
- break;
356
- }
357
- }
358
- if (targetProjectUuid) break;
359
- }
360
- if (targetProjectUuid) break;
361
- }
362
-
363
- if (!targetProjectUuid) {
364
- throw new Error(`Project not found: ${targetProjectName}`);
365
- }
366
-
367
- // 2. Open the project
368
- const opened = await eda.dmt_Project.openProject(targetProjectUuid);
369
- if (!opened) {
370
- throw new Error(`Failed to open project: ${targetProjectName}`);
371
- }
372
-
373
- // 3. Get the first schematic page and open it
374
- const schematics = await eda.dmt_Schematic.getAllSchematicsInfo();
375
- if (!Array.isArray(schematics) || schematics.length === 0) {
376
- throw new Error(`No schematics found in project: ${targetProjectName}`);
377
- }
378
-
379
- const firstSchematic = schematics[0];
380
- const pages = await eda.dmt_Schematic.getAllSchematicPagesInfo();
381
- const firstPage = (pages || []).find((page) => page.parentSchematicUuid === firstSchematic.uuid)
382
- || firstSchematic.page?.[0];
383
-
384
- if (!firstPage) {
385
- throw new Error(`No schematic page found in: ${firstSchematic.name}`);
386
- }
387
-
388
- const tabId = await eda.dmt_EditorControl.openDocument(firstPage.uuid);
389
-
390
- return {
391
- projectUuid: targetProjectUuid,
392
- schematicUuid: firstSchematic.uuid,
393
- pageUuid: firstPage.uuid,
394
- tabId,
395
- };
396
- ```
397
-
398
- **Notes:**
399
- - `dmt_Project.getAllProjectsUuid()` is **not** a global no-arg enumerator in practice. To reliably find a project by name, iterate teams first, then folders.
400
- - `openProject(projectUuid)` may discard unsaved changes in the currently opened project. Be careful before calling it.
401
-
402
- ### PCB Primitive Operations
403
-
404
- ```javascript
405
- // Get selected primitives
406
- const selected = eda.pcb_SelectControl.getAllSelectedPrimitives_PrimitiveId();
407
-
408
- // Create a line on copper layer
409
- // Layer parameter uses EPCB_LayerId enum — see references/enums/EPCB_LayerId.md
410
- await eda.pcb_PrimitiveLine.create(
411
- "GND", // net (string)
412
- EPCB_LayerId.TOP, // layer — use enum, NOT raw number
413
- 0, // startX (unit: 1mil)
414
- 0, // startY (unit: 1mil)
415
- 1000, // endX (unit: 1mil)
416
- 0, // endY (unit: 1mil)
417
- 10, // lineWidth
418
- false // primitiveLock
419
- );
420
-
421
- // Modify an existing primitive (async pattern)
422
- const prim = await eda.pcb_PrimitiveComponent.get([id]);
423
- const asyncPrim = prim.toAsync();
424
- asyncPrim.setState_X(newX);
425
- asyncPrim.setState_Y(newY);
426
- asyncPrim.done();
427
- ```
428
-
429
- ### PCB Async Primitive Pattern (IMPORTANT)
430
-
431
- For **modifying** PCB/SCH primitives, you must use the async pattern:
432
-
433
- ```javascript
434
- // 1. Get the primitive
435
- const prim = await eda.pcb_PrimitiveVia.get([viaId]);
436
- // 2. Convert to async mode
437
- const asyncPrim = prim.toAsync();
438
- // 3. Set new values
439
- asyncPrim.setState_X(newX);
440
- asyncPrim.setState_Y(newY);
441
- asyncPrim.setState_Diameter(diameter);
442
- // 4. Apply changes
443
- asyncPrim.done();
444
- ```
445
-
446
- ### Schematic Operations
447
-
448
- ```javascript
449
- // Get all pages
450
- return await eda.dmt_Schematic.getAllSchematicDocumentsInfo();
451
-
452
- // Create a schematic component
453
- // component parameter requires {libraryUuid, uuid} object — NOT a plain string
454
- await eda.sch_PrimitiveComponent.create(
455
- { libraryUuid: "...", uuid: "device-uuid-from-library" }, // component object
456
- 5000, // x (unit: 0.01inch = 10mil)
457
- 5000, // y (unit: 0.01inch = 10mil)
458
- "", // subPartName
459
- 0, // rotation (degrees, plain number)
460
- false, // mirror
461
- true, // addIntoBom
462
- true // addIntoPcb
463
- );
464
-
465
- // Get selected schematic primitives
466
- const ids = eda.sch_SelectControl.getAllSelectedPrimitives_PrimitiveId();
467
- ```
468
-
469
- ### Library Operations
470
-
471
- ```javascript
472
- // List all libraries in workspace
473
- return await eda.lib_LibrariesList.getAllLibrariesList();
474
-
475
- // Search devices
476
- return await eda.lib_Device.search("STM32");
477
-
478
- // Get symbol info
479
- return await eda.lib_Symbol.get(symbolUuid);
480
- ```
481
-
482
- ### System Functions
483
-
484
- ```javascript
485
- // Show toast message
486
- eda.sys_Message.showToastMessage("Operation complete!");
487
-
488
- // Show confirm dialog
489
- const confirmed = await eda.sys_Dialog.showConfirmationMessage("Proceed?");
490
-
491
- // File system (limited to extension sandbox)
492
- const content = await eda.sys_FileSystem.readFileFromFileSystem(path);
493
- await eda.sys_FileSystem.saveFileToFileSystem(path, content);
494
- ```
495
-
496
- ### DRC (Design Rule Check)
497
-
498
- ```javascript
499
- // Run DRC check
500
- const passed = await eda.pcb_Drc.check(true, true, false);
501
- // passed is boolean: true if DRC passed, false if errors found
502
- ```
503
-
504
- ## Common Mistakes
505
-
506
- ### Read API Signatures Carefully (CRITICAL)
507
-
508
- **Before calling ANY API method, you MUST read the full signature from `references/` — including parameter types, return type, and remarks.**
509
-
510
- AI agents frequently make these errors due to skimming documentation:
511
-
512
- **Error 1: Not `await`ing Promise-returning methods**
513
-
514
- Almost all EDA API methods return `Promise<T>`. If you forget `await`, you get a Promise object instead of the actual result.
515
-
516
- ```javascript
517
- // WRONG: Missing await — result is a Promise, not the project info
518
- const project = eda.dmt_Project.getCurrentProjectInfo();
519
- console.log(project); // Promise { <pending> }
520
-
521
- // CORRECT: Always await async methods
522
- const project = await eda.dmt_Project.getCurrentProjectInfo();
523
- console.log(project); // { uuid: "...", name: "...", ... }
524
- ```
525
-
526
- **How to know if a method needs `await`:** Check the return type in the signature. If it says `Promise<...>`, you MUST `await` it.
527
-
528
- ```typescript
529
- // From references/classes/DMT_Project.md:
530
- getCurrentProjectInfo(): Promise<IDMT_ProjectItem | null>
531
- // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
532
- // This is a Promise — you MUST await it
533
- ```
534
-
535
- **Error 2: Using raw numbers instead of enum values**
536
-
537
- Many parameters expect specific enum values. Using wrong numbers silently produces incorrect behavior.
538
-
539
- ```javascript
540
- // WRONG: What does layer "1" mean? Which copper layer? Signal? Mask?
541
- await eda.pcb_PrimitiveLine.create("GND", 1, 0, 0, 1000, 0, 10, false);
542
-
543
- // CORRECT: Use the enum — EPCB_LayerId.TOP is clear and type-safe
544
- // Check references/enums/EPCB_LayerId.md for the correct value
545
- await eda.pcb_PrimitiveLine.create("GND", EPCB_LayerId.TOP, 0, 0, 1000, 0, 10, false);
546
- ```
547
-
548
- **Always look up enums in `references/enums/` before using numeric constants.**
549
-
550
- **Error 3: Assuming parameter types without checking**
551
-
552
- Different APIs use different units, different ID formats, and different optional parameter conventions. Never assume.
553
-
554
- ```javascript
555
- // WRONG: Assuming create() parameters match modify() parameters
556
- // create() and modify() often have DIFFERENT parameter orders/types
557
-
558
- // CORRECT: Always read the exact signature for the method you're calling
559
- // Check references/classes/<ClassName>.md for each method's specific signature
560
- ```
561
-
562
- **Summary — Before every API call:**
563
- 1. **Read the signature** — parameter types, return type, all in `references/classes/`
564
- 2. **`await` if `Promise`** — check return type for `Promise<...>`
565
- 3. **Use enums** — look up in `references/enums/` instead of guessing numbers/strings
566
- 4. **Check remarks** — the "备注" section often has critical usage notes
567
-
568
- ### Coordinate Unit (CRITICAL)
569
-
570
- **Different domains use different coordinate units:**
571
-
572
- | Domain | Unit | Conversion |
573
- |--------|------|------------|
574
- | **PCB** | 1mil | 1mm ≈ 39.37 units |
575
- | **Schematic** | 0.01inch (10mil) | 1mm ≈ 3.937 units |
576
-
577
- **This is the #1 mistake AI agents make.** Mixing up the units will place components incorrectly.
578
-
579
- - PCB: 1 unit = 1mil = 0.001 inch = 0.0254 mm
580
- - Schematic: 1 unit = 0.01inch = 10mil = 0.254 mm
581
-
582
- If you use the wrong unit, components will be placed **10x too far** from their intended position.
583
-
584
- ```javascript
585
- // WRONG: thinking unit is 1mil (it's actually 0.01inch = 10mil)
586
- // Placing at x=500 thinking it's 500mil = 0.5inch — but 500 units = 5000mil = 5inch!
587
- await eda.sch_PrimitiveComponent.create({libraryUuid: "...", uuid: "dev-uuid"}, 500, 0, "", 0, false, true, true);
588
-
589
- // CORRECT: 50 units = 500mil = 0.5inch (in 0.01inch units)
590
- await eda.sch_PrimitiveComponent.create({libraryUuid: "...", uuid: "dev-uuid"}, 50, 0, "", 0, false, true, true);
591
- ```
592
-
593
- ### Document State (CRITICAL)
594
-
595
- **After creating a project, you MUST open it before operating on documents within it.**
596
-
597
- When operating on documents, always verify:
598
- 1. **Project is opened** — Use `eda.dmt_Project.getCurrentProjectInfo()` to verify
599
- 2. **Correct document is active** — Use `eda.dmt_SelectControl.getCurrentDocumentInfo()` to check document type
600
- 3. **Document type matches API domain** — PCB APIs require active PCB document, SCH APIs require active Schematic document
601
-
602
- ```javascript
603
- // WRONG: Assuming operation will work without checking document state
604
- await eda.pcb_PrimitiveLine.create(...); // May fail if no PCB document is open
605
-
606
- // CORRECT: Always verify document state first
607
- const project = await eda.dmt_Project.getCurrentProjectInfo();
608
- if (!project) {
609
- // If you just created a project, you MUST open it before any operations!
610
- return "Error: No project is currently opened. If you just created a project using dmt_Project.createProject(), you MUST call dmt_Project.openProject(projectPath) to open it first. You cannot operate on documents until a project is opened.";
611
- }
612
-
613
- const doc = await eda.dmt_SelectControl.getCurrentDocumentInfo();
614
- if (doc?.documentType !== EDMT_EditorDocumentType.PCB) {
615
- return "Error: No PCB document is currently active. Please open a PCB document first.";
616
- }
617
-
618
- // Now safe to perform PCB operations
619
- await eda.pcb_PrimitiveLine.create(...);
620
- ```
621
-
622
- **Operating on the wrong document type will return errors or null results.** For example:
623
- - Executing `PCB_*` APIs without an active PCB document (`documentType !== EDMT_EditorDocumentType.PCB`) → error/null
624
- - Executing `SCH_*` APIs without an active Schematic document (`documentType !== EDMT_EditorDocumentType.SCHEMATIC_PAGE`) → error/null
625
-
626
- ### IFrame Context — Always Use `eda` Directly (CRITICAL)
627
-
628
- 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`.
629
-
630
- **Why this matters:**
631
- 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.
632
-
633
- ```javascript
634
- // WRONG: Using window.parent to reach parent frame's eda object
635
- // This is a common mistake made by AI agents familiar with web iframe patterns
636
- const project = await window.parent.eda.dmt_Project.getCurrentProjectInfo();
637
-
638
- // CORRECT: eda is available directly in the iframe context
639
- const project = await eda.dmt_Project.getCurrentProjectInfo();
640
- ```
641
-
642
- **This applies to ALL code inside `sys_IFrame` iframes:**
643
- - Extension UI panels loaded via `openIFrame()`
644
- - Any HTML file inside the extension package displayed in an iframe
645
-
646
- **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.
647
-
648
- ### Multi-Window Support
649
-
650
- When multiple EasyEDA windows are connected to the bridge, you do NOT need to check window selection on every EDA operation. Only check when:
651
- 1. **First EDA operation** — Verify which window is active and tell the user
652
- 2. **EDA disconnected error** — If bridge returns an error about EDA being disconnected, ask user to select a new window
653
-
654
- **Multi-window operations:**
655
- ```bash
656
- # List all connected EDA windows
657
- curl http://localhost:49620/eda-windows
658
-
659
- # Select a specific window
660
- curl -X POST http://localhost:49620/eda-windows/select \
661
- -H "Content-Type: application/json" \
662
- -d '{"windowId": "abc-123-def"}'
663
-
664
- # Execute on specific window
665
- curl -X POST http://localhost:49620/execute \
666
- -H "Content-Type: application/json" \
667
- -d '{"code": "return await eda.dmt_Project.getCurrentProjectInfo();", "windowId": "abc-123-def"}'
668
- ```
669
-
670
- If only one EDA window is connected, it's automatically selected as active.
671
-
672
- ## Debugging Tips & Failure Strategies
673
-
674
- ### Troubleshooting
675
-
676
- 1. **Always check health first**: Scan ports 49620-49629 for `{"service":"easyeda-bridge"}`
677
- 2. **EDA not connected?**: Ensure bridge extension is loaded in EasyEDA. Download: https://jlc-ext.com/item/oshwhub/run-api-gateway
678
- 3. **Timeout errors**: Default 30s timeout. If timeout occurs:
679
- - Check if the correct project and document are opened (use `dmt_Project.getCurrentProjectInfo()`)
680
- - If no project is opened, use `dmt_Project.openProject(projectPath)` to open one
681
- - If no document is active, use `dmt_EditorControl.openDocument(docId)` to open the correct document type (PCB/Schematic)
682
- - If the document type is wrong (e.g., running PCB APIs on Schematic), switch to the correct document first
683
- - Complex operations may need code splitting
684
- 4. **Check return values**: Many methods return `null` on failure — always validate
685
- 5. **Layer numbers**: Use enums from `references/enums/` docs (e.g., `EPCB_LayerId`)
686
- 6. **EDA window disconnected**: If you get an error about a window being disconnected, use `GET /eda-windows` to check available windows and `POST /eda-windows/select` to switch to another window
687
- 7. **Permission errors**: All API interfaces are controlled by EDA's permission system. If a specific API consistently fails to execute (returns error or null) while other APIs work fine, and you've confirmed the call matches the documentation exactly, it may be **blocked by permissions** — not a code bug. The EDA client may restrict certain operations based on user license, project settings, or document state. Inform the user that the operation may require elevated permissions or a different EDA edition.
688
- 8. **Persistent errors?**: If you've verified the API call matches the documentation exactly, ruled out permission issues, and still encounter unexpected errors, consider reporting the issue through official EasyEDA support channels
689
-
690
- ### Failure Handling Rules
691
-
692
- When developing extensions, follow these rules:
693
-
694
- | Situation | Action |
695
- |-----------|--------|
696
- | API method does not exist in docs | **Stop immediately** — inform the user the API doesn't exist |
697
- | Signature uncertain after reading docs | **Stop generation** — return to query step and re-read |
698
- | Forbidden browser API detected | **Auto-replace** with `eda.sys_*` alternative |
699
- | Menu ID conflict | Add prefix to differentiate (e.g., `my-plugin-home`, `my-plugin-sch`) |
700
- | Permission blocked | Inform user — may require different EDA edition or license |
701
-
702
- **Critical:** Never guess an API signature. If `references/classes/` doesn't document it, it doesn't exist for your use case.
703
-
704
- ## Workflow for AI Agent
705
-
706
- When the user asks you to perform EDA operations:
707
-
708
- 1. **Understand the task** — What domain? (PCB/SCH/LIB/Project)
709
- 2. **Verify document state** — Check `eda.dmt_Project.getCurrentProjectInfo()` and `eda.dmt_SelectControl.getCurrentDocumentInfo()`
710
- 3. **Confirm correct document type** — PCB operations need active PCB, SCH operations need active Schematic
711
- 4. **Look up API** — Read relevant class docs from `references/`
712
- 5. **Check types** — Read enum/interface docs for parameter types
713
- 6. **Write code** — Follow the execution context rules above
714
- 7. **Execute** — Send via `POST /execute` and check the result
715
- 8. **Iterate** — If errors occur, read error messages and adjust
716
-
717
- When unsure about an API:
718
- - Search `_quick-reference.md` for method names
719
- - Read the specific class doc for detailed signatures and remarks
720
- - Check interface docs for complex parameter types
721
-
722
- ## Session Management
723
-
724
- ### Detecting Topic Changes
725
-
726
- The 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:
727
-
728
- > "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?"
729
-
730
- **Do NOT close the Bridge automatically** — the user may switch back to EDA work later. Only ask, and close if they confirm.
731
-
732
- ### Closing the Bridge
733
-
734
- If the user confirms they want to stop the Bridge:
735
-
736
- ```bash
737
- # Find and stop the bridge process
738
- for port in $(seq 49620 49629); do
739
- pid=$(lsof -ti :$port 2>/dev/null)
740
- if [ -n "$pid" ]; then
741
- kill $pid
742
- echo "Bridge stopped (PID: $pid, Port: $port)"
743
- break
744
- fi
745
- done
746
- ```
1
+ ---
2
+ name: easyeda-api
3
+ description: >-
4
+ EasyEDA Pro API skill for AI agents. Use when working with EasyEDA Pro EDA software,
5
+ including PCB design, schematic editing, footprint/symbol management, and project operations.
6
+ Supports live debugging in EasyEDA and EasyEDA extension development. Provides complete API
7
+ reference (120+ classes, 62 enums, 70 interfaces), extension-development documentation, and a
8
+ WebSocket bridge server to execute code in the running EasyEDA Pro client.
9
+ Trigger on: "嘉立创EDA,启动!", "立创EDA,启动!", "EDA,启动!",
10
+ "EasyEDA", "PCB", "schematic", "footprint", "EDA", "circuit board",
11
+ "嘉立创EDA", "原理图", "PCB设计".
12
+ **IMPORTANT**: 嘉立创EDA's English name is **EasyEDA**. They are the SAME product.
13
+ Never use other transliterations like "EasyEDA Pro" (unless specifically versioned), "EASYEDA", "easyeda", etc. Always use "EasyEDA" for English references and "嘉立创EDA" for Chinese references.
14
+ license: MIT
15
+ compatibility: Requires Node.js 18+, EasyEDA Pro desktop client with extension support
16
+ metadata:
17
+ author: JLCEDA
18
+ version: "1.1.56"
19
+ openclaw:
20
+ requires:
21
+ bins:
22
+ - node
23
+ env:
24
+ - CLAUDE_SKILL_DIR
25
+ ---
26
+
27
+ # EasyEDA Pro API Skill
28
+
29
+ Control EasyEDA Pro (嘉立创EDA专业版) programmatically through AI. This skill provides:
30
+
31
+ 1. **Complete API reference** — 120 classes, 62 enums, 70 interfaces, 19 type aliases
32
+ 2. **WebSocket bridge** — Execute code in the running EasyEDA Pro client
33
+ 3. **Code patterns** — Common operations for PCB, schematic, library, and project management
34
+ 4. **Document source format reference** — File format specifications for project, schematic, and PCB sources when users need to analyze or modify EasyEDA document source directly instead of using the API
35
+
36
+ This skill supports not only live debugging in EasyEDA, but also EasyEDA extension development.
37
+ 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.
38
+
39
+ ## Architecture
40
+
41
+ ```
42
+ ┌───────────┐ HTTP/WS ┌─────────────────┐ WebSocket ┌───────────┐
43
+ │ AI Agent │ ◄───────────► │ Bridge Server │ ◄───────────► │ EasyEDA │
44
+ │ │ Port Range │ (Node.js) │ Port Range │ (Client) │
45
+ └───────────┘ 49620-49629 └─────────────────┘ 49620-49629 └───────────┘
46
+ ```
47
+
48
+ The server auto-selects an available port from 49620-49629 on startup.
49
+ Both AI and EDA clients auto-discover the server by scanning the port range
50
+ and verifying a handshake (`service: "easyeda-bridge"`).
51
+
52
+ ## Quick Start
53
+
54
+ ### 1. Command Triggers
55
+
56
+ When user says **"嘉立创EDA,启动!"**, **"立创EDA,启动!"**, or **"EDA,启动!"**:
57
+
58
+ **IMPORTANT: Session initialization** — Reply immediately with this exact text to set the correct session title:
59
+
60
+ ```
61
+ 📋 EasyEDA Session
62
+ ```
63
+
64
+ Then proceed with the setup steps below.
65
+
66
+ ### 2. Install dependencies (if needed)
67
+
68
+ ```bash
69
+ cd ${CLAUDE_SKILL_DIR} && npm install
70
+ ```
71
+
72
+ ### 3. Start bridge server
73
+
74
+ > **⚠️ 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.
75
+
76
+ ```bash
77
+ # Check if bridge is already running
78
+ for port in $(seq 49620 49629); do
79
+ resp=$(curl -s http://localhost:$port/health 2>/dev/null)
80
+ if echo "$resp" | grep -q '"easyeda-bridge"'; then
81
+ echo "Bridge already running on port $port"
82
+ BRIDGE_PORT=$port
83
+ break
84
+ fi
85
+ done
86
+
87
+ # Start bridge if not running
88
+ if [ -z "$BRIDGE_PORT" ]; then
89
+ node ${CLAUDE_SKILL_DIR}/scripts/bridge-server.mjs &
90
+ sleep 2
91
+ # Find the port bridge is running on
92
+ for port in $(seq 49620 49629); do
93
+ resp=$(curl -s http://localhost:$port/health 2>/dev/null)
94
+ if echo "$resp" | grep -q '"easyeda-bridge"'; then
95
+ BRIDGE_PORT=$port
96
+ break
97
+ fi
98
+ done
99
+ fi
100
+
101
+ echo "Bridge running on port: ${BRIDGE_PORT:-unknown}"
102
+ ```
103
+
104
+ ### 4. Connect EasyEDA
105
+
106
+ Install the `run-api-gateway.eext` extension in EasyEDA Pro. Download link:
107
+
108
+ - https://jlc-ext.com/item/oshwhub/run-api-gateway
109
+
110
+ After the extension is loaded, it will automatically establish the WebSocket connection.
111
+
112
+ ### 5. Verify connection and select EDA window
113
+
114
+ ```bash
115
+ # Check bridge and EDA connection status
116
+ curl http://localhost:${BRIDGE_PORT:-49620}/health
117
+
118
+ # List all connected EDA windows
119
+ curl http://localhost:${BRIDGE_PORT:-49620}/eda-windows
120
+ ```
121
+
122
+ The `/eda-windows` response looks like:
123
+ ```json
124
+ {
125
+ "windows": [
126
+ { "windowId": "abc-123", "connected": true, "active": true },
127
+ { "windowId": "def-456", "connected": true, "active": false }
128
+ ],
129
+ "activeWindowId": "abc-123",
130
+ "count": 2
131
+ }
132
+ ```
133
+
134
+ **Handle based on window count**:
135
+ - **0 windows**: Tell user "No EasyEDA window is connected. Please ensure the EasyEDA extension (run-api-gateway.eext) is installed and loaded in EasyEDA. Download: https://jlc-ext.com/item/oshwhub/run-api-gateway"
136
+ - **1 window**: Auto-selected as active. Tell user: "✅ Connected! Active EDA window: abc-123. Ready to work."
137
+ - **2+ windows**: Show the available windows and ask user to select:
138
+ ```
139
+ Multiple EDA windows detected:
140
+ - abc-123 (active)
141
+ - def-456
142
+
143
+ Which EDA window should I use?
144
+ ```
145
+
146
+ **Select a window**:
147
+ ```bash
148
+ curl -X POST http://localhost:${BRIDGE_PORT}/eda-windows/select \
149
+ -H "Content-Type: application/json" \
150
+ -d '{"windowId": "abc-123"}'
151
+ ```
152
+
153
+ After selection, confirm: "✅ Active EDA window: abc-123. Ready to work."
154
+
155
+ ### 6. Execute code on EDA
156
+
157
+ ```bash
158
+ curl -X POST http://localhost:${BRIDGE_PORT:-49620}/execute \
159
+ -H "Content-Type: application/json" \
160
+ -d '{"code": "return await eda.dmt_Project.getCurrentProjectInfo();"}'
161
+ ```
162
+
163
+ ## API Documentation
164
+
165
+ The full API reference is in the [references/](references/) directory:
166
+
167
+ - [references/_index.md](references/_index.md) — Master index of all classes, enums, interfaces, and types
168
+ - [references/_quick-reference.md](references/_quick-reference.md) — All method signatures for rapid lookup
169
+ - `references/classes/` — 120 class docs (DMT_*, PCB_*, SCH_*, LIB_*, SYS_*, IPCB_*, ISCH_*)
170
+ - `references/enums/` — 62 enum docs
171
+ - `references/interfaces/` — 70 interface docs
172
+ - `references/types/` — 19 type alias docs
173
+
174
+ ### How to look up API
175
+
176
+ 1. **Start with `_index.md`** to find the right class/module for the task
177
+ 2. **Read the class doc** (e.g., `references/classes/DMT_Board.md`) for all methods and signatures
178
+ 3. **Use `_quick-reference.md`** for fast method signature lookup across all classes
179
+ 4. **Check enums/interfaces** for parameter types and return types
180
+
181
+ ### Document Source Format Documentation
182
+
183
+ If the user needs to analyze or modify EasyEDA document source directly instead of using the API, use the documents in the [format/](format/) directory.
184
+
185
+ - [format/index.md](format/index.md) — Overview of the EasyEDA document source format references and version notes
186
+ - `format/project/` — Project source structure, metadata, blobs, variants, and grouping data
187
+ - `format/schematic/` — Schematic source format, including structure, wires, shapes, pins, components, and tables
188
+ - `format/pcb/` — PCB source format, including primitives, pads and vias, shapes, text, attributes, rules, and panel data
189
+
190
+ Use 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.
191
+
192
+ ### API Module Overview
193
+
194
+ | Prefix | Domain | Key Classes |
195
+ |--------|--------|-------------|
196
+ | `DMT_` | Document management | Board, EditorControl, Folder, Panel, Pcb, Project, Schematic, SelectControl, Team, Workspace |
197
+ | `PCB_` | PCB & Footprint | Document, Drc, Event, Layer, Net, Primitive, PrimitiveComponent, PrimitiveLine, PrimitivePad, PrimitivePour, PrimitiveVia, SelectControl |
198
+ | `SCH_` | Schematic | Document, Event, Primitive, PrimitiveComponent, PrimitiveWire, SelectControl |
199
+ | `LIB_` | Library | 3DModel, Cbb, Classification, Device, Footprint, LibrariesList, PanelLibrary, SelectControl, Symbol |
200
+ | `SYS_` | System | Dialog, Environment, FileManager, FileSystem, FontManager, HeaderMenu, I18n, IFrame, LoadingAndProgressBar, Log, Message, MessageBox, MessageBus, PanelControl, Setting, ShortcutKey, Storage, Timer, ToastMessage, WebSocket, Window |
201
+ | `IPCB_` | PCB interfaces (图元) | PrimitiveArc, PrimitiveComponent, PrimitivePad, PrimitiveFill, PrimitivePour, PrimitiveRegion, PrimitiveVia, ... |
202
+ | `ISCH_` | Schematic interfaces (图元) | PrimitiveArc, PrimitiveComponent, PrimitiveWire, PrimitiveText, PrimitiveRectangle, ... |
203
+ | `EPCB_` / `ESCH_` | Enums | PrimitiveType, Layer, PadType, ... |
204
+
205
+ ## Code Execution Context
206
+
207
+ All code runs inside EasyEDA Pro's browser runtime as:
208
+
209
+ ```javascript
210
+ async function(eda) {
211
+ // Your code here — `eda` is the global EDA API object
212
+ // You MUST use `return` to send results back
213
+ // Do not add comments to the generated code, as the code is typically executed as a single line
214
+ }
215
+ ```
216
+
217
+ **Critical rules:**
218
+ - The `eda` object provides access to all API modules (e.g., `eda.dmt_Board`, `eda.pcb_Primitive`).
219
+ - Always refer to the API documentation for correct usage.
220
+ - Do not add comments to the generated code, as the code is typically executed as a single line.
221
+ - Always use `return` to get results — `console.log` output is NOT captured.
222
+ - All API methods returning promises must be `await`ed.
223
+ - Code runs in browser context — no Node.js APIs (fs, path, etc.) available.
224
+ - Use `eda.sys_Message.showToastMessage(msg)` for user-visible notifications.
225
+ - When reviewing API documentation and encountering enumerations, do not guess the enumeration values. You must use the enumeration members, for example: `EPCB_LayerId.TOP` instead of `1` for the layer parameter in PCB primitive creation.
226
+
227
+ ### Extension Runtime Constraints
228
+
229
+ When writing EasyEDA extensions, standard browser APIs are **forbidden** in the main process. Use EDA-provided alternatives:
230
+
231
+ | Purpose | ❌ Forbidden | ✅ Use Instead |
232
+ |---------|-------------|----------------|
233
+ | Get user input | — | `eda.sys_Dialog.showInputDialog()` |
234
+ | User selection | — | `eda.sys_Dialog.showSelectDialog()` |
235
+ | Show message | `alert()` | `eda.sys_Dialog.showInformationMessage()` |
236
+ | Confirm action | `confirm()` | `eda.sys_Dialog.showConfirmationMessage()` |
237
+ | Toast notification | DOM manipulation | `eda.sys_Message.showToastMessage()` |
238
+ | Store data | `localStorage` (main process) | `eda.sys_Storage.setExtensionUserConfig(key, value)` |
239
+ | Custom UI | Manipulate host DOM | `eda.sys_IFrame.openIFrame()` |
240
+ | Show HTML | `showInformationMessage(html)` | Must use iframe |
241
+ | Open link | `window.open()` | `eda.sys_Window.open()` |
242
+ | Browser hardware API | Use in main process | Available in iframe (`navigator.serial`, etc.) |
243
+
244
+ **Note:** `localStorage`, `window`, `document` etc. are available **inside `sys_IFrame`** but NOT in the main extension process.
245
+
246
+ ### Extension ↔ IFrame Data Passing
247
+
248
+ The main extension process and `sys_IFrame` iframe are **isolated contexts**. To pass data between them:
249
+
250
+ **Option A (Recommended):** Use `eda.sys_Storage` as a bridge
251
+ ```javascript
252
+ // In main extension process:
253
+ await eda.sys_Storage.setExtensionUserConfig('myKey', JSON.stringify(data));
254
+
255
+ // In iframe:
256
+ const data = JSON.parse(await eda.sys_Storage.getExtensionUserConfig('myKey'));
257
+ ```
258
+
259
+ **Option B:** Both contexts can access `eda` directly — call the same API from either side
260
+ ```javascript
261
+ // In iframe HTML (NOT window.parent.eda):
262
+ const info = await eda.dmt_Project.getCurrentProjectInfo();
263
+ ```
264
+
265
+ ## Communication Protocol
266
+
267
+ ### Port Discovery
268
+
269
+ The bridge server listens on the first available port in **49620-49629**.
270
+ To find the server, scan the range and verify the service identity:
271
+
272
+ ```bash
273
+ for port in $(seq 49620 49629); do
274
+ resp=$(curl -s http://127.0.0.1:$port/health 2>/dev/null)
275
+ if echo "$resp" | grep -q '"easyeda-bridge"'; then
276
+ BRIDGE_PORT=$port; break
277
+ fi
278
+ done
279
+ ```
280
+
281
+ ### Handshake
282
+
283
+ - **HTTP**: `GET /health` returns `{ "service": "easyeda-bridge", "edaConnected": bool, ... }`
284
+ - **WebSocket**: On connect, server sends `{ "type": "handshake", "service": "easyeda-bridge" }`
285
+ - Clients MUST verify `service === "easyeda-bridge"` before using the connection
286
+
287
+ ### Message Format
288
+
289
+ JSON messages over WebSocket / HTTP:
290
+
291
+ | Field | Type | Description |
292
+ |-------|------|-------------|
293
+ | `type` | `"execute"` \| `"result"` \| `"error"` \| `"ping"` \| `"pong"` \| `"handshake"` | Message type |
294
+ | `id` | `string` | Request UUID for matching request/response |
295
+ | `code` | `string` | JavaScript code to execute (for `execute` type) |
296
+ | `result` | `any` | Execution result (for `result` type) |
297
+ | `error` | `string` | Error message (for `error` type) |
298
+ | `service` | `string` | Service identifier (for `handshake` type) |
299
+ | `timestamp` | `number` | Unix milliseconds |
300
+
301
+ ## Common Patterns
302
+
303
+ ### Project & Board Operations
304
+
305
+ ```javascript
306
+ // Get current project info
307
+ return await eda.dmt_Project.getCurrentProjectInfo();
308
+
309
+ // List all boards in project
310
+ return await eda.dmt_Board.getAllBoardsInfo();
311
+
312
+ // Create a new board (optionally link to schematic/PCB)
313
+ return await eda.dmt_Board.createBoard();
314
+
315
+ // Switch to a document tab
316
+ await eda.dmt_EditorControl.activateDocument(tabId);
317
+ ```
318
+
319
+ ### Example: Open a project by name and open its first schematic page
320
+
321
+ ```javascript
322
+ const targetProjectName = 'NE555 Circuit';
323
+
324
+ // 1. Enumerate projects by team/folder and find the target by name
325
+ const teams = await eda.dmt_Team.getAllTeamsInfo();
326
+ const seenProjectUuid = new Set();
327
+ let targetProjectUuid = null;
328
+
329
+ for (const team of teams || []) {
330
+ const teamProjects = await eda.dmt_Project.getAllProjectsUuid(team.uuid);
331
+ for (const projectUuid of teamProjects || []) {
332
+ if (seenProjectUuid.has(projectUuid)) continue;
333
+ seenProjectUuid.add(projectUuid);
334
+
335
+ const info = await eda.dmt_Project.getProjectInfo(projectUuid);
336
+ const name = info?.friendlyName || info?.name || '';
337
+ if (name === targetProjectName) {
338
+ targetProjectUuid = projectUuid;
339
+ break;
340
+ }
341
+ }
342
+ if (targetProjectUuid) break;
343
+
344
+ const folderUuids = await eda.dmt_Folder.getAllFoldersUuid(team.uuid);
345
+ for (const folderUuid of folderUuids || []) {
346
+ const folderProjects = await eda.dmt_Project.getAllProjectsUuid(team.uuid, folderUuid);
347
+ for (const projectUuid of folderProjects || []) {
348
+ if (seenProjectUuid.has(projectUuid)) continue;
349
+ seenProjectUuid.add(projectUuid);
350
+
351
+ const info = await eda.dmt_Project.getProjectInfo(projectUuid);
352
+ const name = info?.friendlyName || info?.name || '';
353
+ if (name === targetProjectName) {
354
+ targetProjectUuid = projectUuid;
355
+ break;
356
+ }
357
+ }
358
+ if (targetProjectUuid) break;
359
+ }
360
+ if (targetProjectUuid) break;
361
+ }
362
+
363
+ if (!targetProjectUuid) {
364
+ throw new Error(`Project not found: ${targetProjectName}`);
365
+ }
366
+
367
+ // 2. Open the project
368
+ const opened = await eda.dmt_Project.openProject(targetProjectUuid);
369
+ if (!opened) {
370
+ throw new Error(`Failed to open project: ${targetProjectName}`);
371
+ }
372
+
373
+ // 3. Get the first schematic page and open it
374
+ const schematics = await eda.dmt_Schematic.getAllSchematicsInfo();
375
+ if (!Array.isArray(schematics) || schematics.length === 0) {
376
+ throw new Error(`No schematics found in project: ${targetProjectName}`);
377
+ }
378
+
379
+ const firstSchematic = schematics[0];
380
+ const pages = await eda.dmt_Schematic.getAllSchematicPagesInfo();
381
+ const firstPage = (pages || []).find((page) => page.parentSchematicUuid === firstSchematic.uuid)
382
+ || firstSchematic.page?.[0];
383
+
384
+ if (!firstPage) {
385
+ throw new Error(`No schematic page found in: ${firstSchematic.name}`);
386
+ }
387
+
388
+ const tabId = await eda.dmt_EditorControl.openDocument(firstPage.uuid);
389
+
390
+ return {
391
+ projectUuid: targetProjectUuid,
392
+ schematicUuid: firstSchematic.uuid,
393
+ pageUuid: firstPage.uuid,
394
+ tabId,
395
+ };
396
+ ```
397
+
398
+ **Notes:**
399
+ - `dmt_Project.getAllProjectsUuid()` is **not** a global no-arg enumerator in practice. To reliably find a project by name, iterate teams first, then folders.
400
+ - `openProject(projectUuid)` may discard unsaved changes in the currently opened project. Be careful before calling it.
401
+
402
+ ### PCB Primitive Operations
403
+
404
+ ```javascript
405
+ // Get selected primitives
406
+ const selected = eda.pcb_SelectControl.getAllSelectedPrimitives_PrimitiveId();
407
+
408
+ // Create a line on copper layer
409
+ // Layer parameter uses EPCB_LayerId enum — see references/enums/EPCB_LayerId.md
410
+ await eda.pcb_PrimitiveLine.create(
411
+ "GND", // net (string)
412
+ EPCB_LayerId.TOP, // layer — use enum, NOT raw number
413
+ 0, // startX (unit: 1mil)
414
+ 0, // startY (unit: 1mil)
415
+ 1000, // endX (unit: 1mil)
416
+ 0, // endY (unit: 1mil)
417
+ 10, // lineWidth
418
+ false // primitiveLock
419
+ );
420
+
421
+ // Modify an existing primitive (async pattern)
422
+ const prim = await eda.pcb_PrimitiveComponent.get([id]);
423
+ const asyncPrim = prim.toAsync();
424
+ asyncPrim.setState_X(newX);
425
+ asyncPrim.setState_Y(newY);
426
+ asyncPrim.done();
427
+ ```
428
+
429
+ ### PCB Async Primitive Pattern (IMPORTANT)
430
+
431
+ For **modifying** PCB/SCH primitives, you must use the async pattern:
432
+
433
+ ```javascript
434
+ // 1. Get the primitive
435
+ const prim = await eda.pcb_PrimitiveVia.get([viaId]);
436
+ // 2. Convert to async mode
437
+ const asyncPrim = prim.toAsync();
438
+ // 3. Set new values
439
+ asyncPrim.setState_X(newX);
440
+ asyncPrim.setState_Y(newY);
441
+ asyncPrim.setState_Diameter(diameter);
442
+ // 4. Apply changes
443
+ asyncPrim.done();
444
+ ```
445
+
446
+ ### Schematic Operations
447
+
448
+ ```javascript
449
+ // Get all pages
450
+ return await eda.dmt_Schematic.getAllSchematicDocumentsInfo();
451
+
452
+ // Create a schematic component
453
+ // component parameter requires {libraryUuid, uuid} object — NOT a plain string
454
+ await eda.sch_PrimitiveComponent.create(
455
+ { libraryUuid: "...", uuid: "device-uuid-from-library" }, // component object
456
+ 5000, // x (unit: 0.01inch = 10mil)
457
+ 5000, // y (unit: 0.01inch = 10mil)
458
+ "", // subPartName
459
+ 0, // rotation (degrees, plain number)
460
+ false, // mirror
461
+ true, // addIntoBom
462
+ true // addIntoPcb
463
+ );
464
+
465
+ // Get selected schematic primitives
466
+ const ids = eda.sch_SelectControl.getAllSelectedPrimitives_PrimitiveId();
467
+ ```
468
+
469
+ ### Library Operations
470
+
471
+ ```javascript
472
+ // List all libraries in workspace
473
+ return await eda.lib_LibrariesList.getAllLibrariesList();
474
+
475
+ // Search devices
476
+ return await eda.lib_Device.search("STM32");
477
+
478
+ // Get symbol info
479
+ return await eda.lib_Symbol.get(symbolUuid);
480
+ ```
481
+
482
+ ### System Functions
483
+
484
+ ```javascript
485
+ // Show toast message
486
+ eda.sys_Message.showToastMessage("Operation complete!");
487
+
488
+ // Show confirm dialog
489
+ const confirmed = await eda.sys_Dialog.showConfirmationMessage("Proceed?");
490
+
491
+ // File system (limited to extension sandbox)
492
+ const content = await eda.sys_FileSystem.readFileFromFileSystem(path);
493
+ await eda.sys_FileSystem.saveFileToFileSystem(path, content);
494
+ ```
495
+
496
+ ### DRC (Design Rule Check)
497
+
498
+ ```javascript
499
+ // Run DRC check
500
+ const passed = await eda.pcb_Drc.check(true, true, false);
501
+ // passed is boolean: true if DRC passed, false if errors found
502
+ ```
503
+
504
+ ## Common Mistakes
505
+
506
+ ### Read API Signatures Carefully (CRITICAL)
507
+
508
+ **Before calling ANY API method, you MUST read the full signature from `references/` — including parameter types, return type, and remarks.**
509
+
510
+ AI agents frequently make these errors due to skimming documentation:
511
+
512
+ **Error 1: Not `await`ing Promise-returning methods**
513
+
514
+ Almost all EDA API methods return `Promise<T>`. If you forget `await`, you get a Promise object instead of the actual result.
515
+
516
+ ```javascript
517
+ // WRONG: Missing await — result is a Promise, not the project info
518
+ const project = eda.dmt_Project.getCurrentProjectInfo();
519
+ console.log(project); // Promise { <pending> }
520
+
521
+ // CORRECT: Always await async methods
522
+ const project = await eda.dmt_Project.getCurrentProjectInfo();
523
+ console.log(project); // { uuid: "...", name: "...", ... }
524
+ ```
525
+
526
+ **How to know if a method needs `await`:** Check the return type in the signature. If it says `Promise<...>`, you MUST `await` it.
527
+
528
+ ```typescript
529
+ // From references/classes/DMT_Project.md:
530
+ getCurrentProjectInfo(): Promise<IDMT_ProjectItem | null>
531
+ // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
532
+ // This is a Promise — you MUST await it
533
+ ```
534
+
535
+ **Error 2: Using raw numbers instead of enum values**
536
+
537
+ Many parameters expect specific enum values. Using wrong numbers silently produces incorrect behavior.
538
+
539
+ ```javascript
540
+ // WRONG: What does layer "1" mean? Which copper layer? Signal? Mask?
541
+ await eda.pcb_PrimitiveLine.create("GND", 1, 0, 0, 1000, 0, 10, false);
542
+
543
+ // CORRECT: Use the enum — EPCB_LayerId.TOP is clear and type-safe
544
+ // Check references/enums/EPCB_LayerId.md for the correct value
545
+ await eda.pcb_PrimitiveLine.create("GND", EPCB_LayerId.TOP, 0, 0, 1000, 0, 10, false);
546
+ ```
547
+
548
+ **Always look up enums in `references/enums/` before using numeric constants.**
549
+
550
+ **Error 3: Assuming parameter types without checking**
551
+
552
+ Different APIs use different units, different ID formats, and different optional parameter conventions. Never assume.
553
+
554
+ ```javascript
555
+ // WRONG: Assuming create() parameters match modify() parameters
556
+ // create() and modify() often have DIFFERENT parameter orders/types
557
+
558
+ // CORRECT: Always read the exact signature for the method you're calling
559
+ // Check references/classes/<ClassName>.md for each method's specific signature
560
+ ```
561
+
562
+ **Summary — Before every API call:**
563
+ 1. **Read the signature** — parameter types, return type, all in `references/classes/`
564
+ 2. **`await` if `Promise`** — check return type for `Promise<...>`
565
+ 3. **Use enums** — look up in `references/enums/` instead of guessing numbers/strings
566
+ 4. **Check remarks** — the "备注" section often has critical usage notes
567
+
568
+ ### Coordinate Unit (CRITICAL)
569
+
570
+ **Different domains use different coordinate units:**
571
+
572
+ | Domain | Unit | Conversion |
573
+ |--------|------|------------|
574
+ | **PCB** | 1mil | 1mm ≈ 39.37 units |
575
+ | **Schematic** | 0.01inch (10mil) | 1mm ≈ 3.937 units |
576
+
577
+ **This is the #1 mistake AI agents make.** Mixing up the units will place components incorrectly.
578
+
579
+ - PCB: 1 unit = 1mil = 0.001 inch = 0.0254 mm
580
+ - Schematic: 1 unit = 0.01inch = 10mil = 0.254 mm
581
+
582
+ If you use the wrong unit, components will be placed **10x too far** from their intended position.
583
+
584
+ ```javascript
585
+ // WRONG: thinking unit is 1mil (it's actually 0.01inch = 10mil)
586
+ // Placing at x=500 thinking it's 500mil = 0.5inch — but 500 units = 5000mil = 5inch!
587
+ await eda.sch_PrimitiveComponent.create({libraryUuid: "...", uuid: "dev-uuid"}, 500, 0, "", 0, false, true, true);
588
+
589
+ // CORRECT: 50 units = 500mil = 0.5inch (in 0.01inch units)
590
+ await eda.sch_PrimitiveComponent.create({libraryUuid: "...", uuid: "dev-uuid"}, 50, 0, "", 0, false, true, true);
591
+ ```
592
+
593
+ ### Document State (CRITICAL)
594
+
595
+ **After creating a project, you MUST open it before operating on documents within it.**
596
+
597
+ When operating on documents, always verify:
598
+ 1. **Project is opened** — Use `eda.dmt_Project.getCurrentProjectInfo()` to verify
599
+ 2. **Correct document is active** — Use `eda.dmt_SelectControl.getCurrentDocumentInfo()` to check document type
600
+ 3. **Document type matches API domain** — PCB APIs require active PCB document, SCH APIs require active Schematic document
601
+
602
+ ```javascript
603
+ // WRONG: Assuming operation will work without checking document state
604
+ await eda.pcb_PrimitiveLine.create(...); // May fail if no PCB document is open
605
+
606
+ // CORRECT: Always verify document state first
607
+ const project = await eda.dmt_Project.getCurrentProjectInfo();
608
+ if (!project) {
609
+ // If you just created a project, you MUST open it before any operations!
610
+ return "Error: No project is currently opened. If you just created a project using dmt_Project.createProject(), you MUST call dmt_Project.openProject(projectPath) to open it first. You cannot operate on documents until a project is opened.";
611
+ }
612
+
613
+ const doc = await eda.dmt_SelectControl.getCurrentDocumentInfo();
614
+ if (doc?.documentType !== EDMT_EditorDocumentType.PCB) {
615
+ return "Error: No PCB document is currently active. Please open a PCB document first.";
616
+ }
617
+
618
+ // Now safe to perform PCB operations
619
+ await eda.pcb_PrimitiveLine.create(...);
620
+ ```
621
+
622
+ **Operating on the wrong document type will return errors or null results.** For example:
623
+ - Executing `PCB_*` APIs without an active PCB document (`documentType !== EDMT_EditorDocumentType.PCB`) → error/null
624
+ - Executing `SCH_*` APIs without an active Schematic document (`documentType !== EDMT_EditorDocumentType.SCHEMATIC_PAGE`) → error/null
625
+
626
+ ### IFrame Context — Always Use `eda` Directly (CRITICAL)
627
+
628
+ 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`.
629
+
630
+ **Why this matters:**
631
+ 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.
632
+
633
+ ```javascript
634
+ // WRONG: Using window.parent to reach parent frame's eda object
635
+ // This is a common mistake made by AI agents familiar with web iframe patterns
636
+ const project = await window.parent.eda.dmt_Project.getCurrentProjectInfo();
637
+
638
+ // CORRECT: eda is available directly in the iframe context
639
+ const project = await eda.dmt_Project.getCurrentProjectInfo();
640
+ ```
641
+
642
+ **This applies to ALL code inside `sys_IFrame` iframes:**
643
+ - Extension UI panels loaded via `openIFrame()`
644
+ - Any HTML file inside the extension package displayed in an iframe
645
+
646
+ **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.
647
+
648
+ ### Multi-Window Support
649
+
650
+ When multiple EasyEDA windows are connected to the bridge, you do NOT need to check window selection on every EDA operation. Only check when:
651
+ 1. **First EDA operation** — Verify which window is active and tell the user
652
+ 2. **EDA disconnected error** — If bridge returns an error about EDA being disconnected, ask user to select a new window
653
+
654
+ **Multi-window operations:**
655
+ ```bash
656
+ # List all connected EDA windows
657
+ curl http://localhost:49620/eda-windows
658
+
659
+ # Select a specific window
660
+ curl -X POST http://localhost:49620/eda-windows/select \
661
+ -H "Content-Type: application/json" \
662
+ -d '{"windowId": "abc-123-def"}'
663
+
664
+ # Execute on specific window
665
+ curl -X POST http://localhost:49620/execute \
666
+ -H "Content-Type: application/json" \
667
+ -d '{"code": "return await eda.dmt_Project.getCurrentProjectInfo();", "windowId": "abc-123-def"}'
668
+ ```
669
+
670
+ If only one EDA window is connected, it's automatically selected as active.
671
+
672
+ ## Debugging Tips & Failure Strategies
673
+
674
+ ### Troubleshooting
675
+
676
+ 1. **Always check health first**: Scan ports 49620-49629 for `{"service":"easyeda-bridge"}`
677
+ 2. **EDA not connected?**: Ensure bridge extension is loaded in EasyEDA. Download: https://jlc-ext.com/item/oshwhub/run-api-gateway
678
+ 3. **Timeout errors**: Default 30s timeout. If timeout occurs:
679
+ - Check if the correct project and document are opened (use `dmt_Project.getCurrentProjectInfo()`)
680
+ - If no project is opened, use `dmt_Project.openProject(projectPath)` to open one
681
+ - If no document is active, use `dmt_EditorControl.openDocument(docId)` to open the correct document type (PCB/Schematic)
682
+ - If the document type is wrong (e.g., running PCB APIs on Schematic), switch to the correct document first
683
+ - Complex operations may need code splitting
684
+ 4. **Check return values**: Many methods return `null` on failure — always validate
685
+ 5. **Layer numbers**: Use enums from `references/enums/` docs (e.g., `EPCB_LayerId`)
686
+ 6. **EDA window disconnected**: If you get an error about a window being disconnected, use `GET /eda-windows` to check available windows and `POST /eda-windows/select` to switch to another window
687
+ 7. **Permission errors**: All API interfaces are controlled by EDA's permission system. If a specific API consistently fails to execute (returns error or null) while other APIs work fine, and you've confirmed the call matches the documentation exactly, it may be **blocked by permissions** — not a code bug. The EDA client may restrict certain operations based on user license, project settings, or document state. Inform the user that the operation may require elevated permissions or a different EDA edition.
688
+ 8. **Persistent errors?**: If you've verified the API call matches the documentation exactly, ruled out permission issues, and still encounter unexpected errors, consider reporting the issue through official EasyEDA support channels
689
+
690
+ ### Failure Handling Rules
691
+
692
+ When developing extensions, follow these rules:
693
+
694
+ | Situation | Action |
695
+ |-----------|--------|
696
+ | API method does not exist in docs | **Stop immediately** — inform the user the API doesn't exist |
697
+ | Signature uncertain after reading docs | **Stop generation** — return to query step and re-read |
698
+ | Forbidden browser API detected | **Auto-replace** with `eda.sys_*` alternative |
699
+ | Menu ID conflict | Add prefix to differentiate (e.g., `my-plugin-home`, `my-plugin-sch`) |
700
+ | Permission blocked | Inform user — may require different EDA edition or license |
701
+
702
+ **Critical:** Never guess an API signature. If `references/classes/` doesn't document it, it doesn't exist for your use case.
703
+
704
+ ## Workflow for AI Agent
705
+
706
+ When the user asks you to perform EDA operations:
707
+
708
+ 1. **Understand the task** — What domain? (PCB/SCH/LIB/Project)
709
+ 2. **Verify document state** — Check `eda.dmt_Project.getCurrentProjectInfo()` and `eda.dmt_SelectControl.getCurrentDocumentInfo()`
710
+ 3. **Confirm correct document type** — PCB operations need active PCB, SCH operations need active Schematic
711
+ 4. **Look up API** — Read relevant class docs from `references/`
712
+ 5. **Check types** — Read enum/interface docs for parameter types
713
+ 6. **Write code** — Follow the execution context rules above
714
+ 7. **Execute** — Send via `POST /execute` and check the result
715
+ 8. **Iterate** — If errors occur, read error messages and adjust
716
+
717
+ When unsure about an API:
718
+ - Search `_quick-reference.md` for method names
719
+ - Read the specific class doc for detailed signatures and remarks
720
+ - Check interface docs for complex parameter types
721
+
722
+ ## Session Management
723
+
724
+ ### Detecting Topic Changes
725
+
726
+ The 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:
727
+
728
+ > "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?"
729
+
730
+ **Do NOT close the Bridge automatically** — the user may switch back to EDA work later. Only ask, and close if they confirm.
731
+
732
+ ### Closing the Bridge
733
+
734
+ If the user confirms they want to stop the Bridge:
735
+
736
+ ```bash
737
+ # Find and stop the bridge process
738
+ for port in $(seq 49620 49629); do
739
+ pid=$(lsof -ti :$port 2>/dev/null)
740
+ if [ -n "$pid" ]; then
741
+ kill $pid
742
+ echo "Bridge stopped (PID: $pid, Port: $port)"
743
+ break
744
+ fi
745
+ done
746
+ ```