@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
@@ -0,0 +1,1510 @@
1
+ # Command-Line Client <Badge type="tip" text="CLI" />
2
+
3
+ ::: tip For AI coding assistants: the command-line client
4
+
5
+ If you are using an AI coding assistant (such as Claude Code, OpenCode, QwenCode, GitHub Copilot, etc.) to drive EasyEDA Pro, ask the AI to follow the [For AI command-line client document](https://prodocs.easyeda.com/storage/texts/api/guide/cli-for-ai.md). That document is written for AI coding assistants: it drops redundant prose and provides directly executable commands, hard constraints, and verification steps.
6
+
7
+ You can also copy the prompt below directly to your AI coding assistant:
8
+
9
+ ```text
10
+ Please help me complete a design task through the EasyEDA Pro desktop client command line (easyeda-pro), as follows:
11
+ 1. Strictly follow the steps in https://prodocs.easyeda.com/storage/texts/api/guide/cli-for-ai.md;
12
+ 2. Before starting, confirm the endpoint connection state with easyeda-pro doctor, and confirm the project name and other details with me;
13
+ 3. After each key command, check the ok field of the response and the on-disk artifacts, then report the project directory, the paths of the exported artifacts, and the session shutdown result.
14
+ ```
15
+
16
+ :::
17
+
18
+ Besides the graphical interface, the EasyEDA Pro desktop client ships with a command-line client (CLI) and a local bridge service. They let you control a running editor from a script, or let an AI coding assistant drive the editor directly to complete design work.
19
+
20
+ The command-line client provides the following capabilities:
21
+
22
+ - Opening and creating projects, and managing multiple editor windows (sessions);
23
+ - Executing JavaScript inside the editor, and therefore calling any [extension API](./index);
24
+ - Querying the extension API reference and the design file format reference;
25
+ - Returning results as uniform JSON, which is convenient for scripts and AI to parse;
26
+ - Running as an [MCP](https://modelcontextprotocol.io/) server, and therefore serving directly as a tool for an AI coding assistant.
27
+
28
+ ## Basic Concepts
29
+
30
+ The command-line client treats a running editor as a programmable backend. There are three layers between the client and the editor:
31
+
32
+ | Concept | Description |
33
+ | --- | --- |
34
+ | Session | One editor window corresponds to one session, created by `open`, which returns the session ID |
35
+ | Invocation | A piece of JavaScript executed inside a given session through `invoke` |
36
+ | Bridge service | The local service provided by the client process. The `easyeda-pro` command communicates with the editor through it |
37
+
38
+ Both the command-line client and the service are provided by the `easyeda-pro` executable, so the same executable is used to start the graphical interface and to run command-line operations.
39
+
40
+ ## Preparation
41
+
42
+ ### I. Obtaining the Client
43
+
44
+ The command-line client is built into the EasyEDA Pro desktop client (need v4.1.60 and above) and does not need a separate installation. Download and install the EasyEDA Pro client for your system from the [client download page](https://easyeda.com/page/download).
45
+
46
+ After installation, the `easyeda-pro` executable is usually located at the following path (Windows x64 shown here):
47
+
48
+ ```
49
+ C:\Program Files\EasyEDA-Pro\easyeda-pro.exe
50
+ ```
51
+
52
+ The installer adds that directory to the system `PATH` during installation, so you can normally use the `easyeda-pro` command directly in a terminal. If the command is reported as not found, check whether the installation directory has been added to `PATH`, or use the full path to the executable instead.
53
+
54
+ You can also get installation packages for specific versions from the [client release history](../../faq/client-version) page.
55
+
56
+ ::: warning
57
+
58
+ The command-line client requires the desktop client edition of EasyEDA Pro. The browser / online edition does not support the session and bridge features described in this document.
59
+
60
+ :::
61
+
62
+ ### II. Verifying the Runtime Environment
63
+
64
+ Run the following command in a terminal. The client probes the local editor endpoint and reports its state:
65
+
66
+ ```shell
67
+ easyeda-pro doctor
68
+ ```
69
+
70
+ ```json
71
+ {
72
+ "ok": true,
73
+ "value": {
74
+ "endpoint": "EasyEDAProf126dbc1",
75
+ "connected": false,
76
+ "bridgeVersion": null,
77
+ "versionMatch": null,
78
+ "resultChannel": null
79
+ },
80
+ "logs": [],
81
+ "durationMs": 207
82
+ }
83
+ ```
84
+
85
+ A `connected` value of `false` means no editor is currently running. Open any editor window and the field becomes `true`.
86
+
87
+ You can likewise query the attributes of the current runtime environment from inside a script:
88
+
89
+ ```javascript
90
+ return {
91
+ isClient: eda.sys_Environment.isClient(),
92
+ isHalfOfflineMode: eda.sys_Environment.isHalfOfflineMode(),
93
+ version: eda.sys_Environment.getEditorCurrentVersion()
94
+ };
95
+ ```
96
+
97
+ Here [SYS_Environment.isClient()](../reference/pro-api.sys_environment.isclient) determines whether the current environment is the desktop client, [SYS_Environment.isHalfOfflineMode()](../reference/pro-api.sys_environment.ishalfofflinemode) determines whether it is semi-offline mode, and [SYS_Environment.getEditorCurrentVersion()](../reference/pro-api.sys_environment.geteditorcurrentversion) returns the current editor version.
98
+
99
+ ### III. Project Storage Directory
100
+
101
+ In semi-offline / fully-offline mode, the client data directory is located at:
102
+
103
+ ```
104
+ %USERPROFILE%\Documents\EasyEDA-Pro
105
+ ```
106
+
107
+ The `config.json` file in that directory records the various path settings, among which `APP_PROJECT_DIR` is the project directory list:
108
+
109
+ ```json
110
+ "APP_PROJECT_DIR": [
111
+ "C:\\Users\\username\\Documents\\EasyEDA-Pro\\projects",
112
+ "C:\\Users\\username\\Documents\\EasyEDA-Pro\\example-projects"
113
+ ]
114
+ ```
115
+
116
+ The read/write range of the [SYS_FileSystem](../reference/pro-api.sys_filesystem) APIs is exactly those directories and their subdirectories. You can also obtain the path list inside a script through [SYS_FileSystem.getProjectsPaths()](../reference/pro-api.sys_filesystem.getprojectspaths). Writing exported artifacts into the `projects\<project name>\` directory is the least troublesome approach.
117
+
118
+ ### IV. Response Structure
119
+
120
+ All command-line client commands return the same JSON structure:
121
+
122
+ ```json
123
+ {
124
+ "ok": true,
125
+ "value": {},
126
+ "logs": [],
127
+ "durationMs": 12
128
+ }
129
+ ```
130
+
131
+ On failure, the structure is as follows:
132
+
133
+ ```json
134
+ {
135
+ "ok": false,
136
+ "error": {
137
+ "code": "EXECUTION_ERROR",
138
+ "message": "..."
139
+ }
140
+ }
141
+ ```
142
+
143
+ When processing the result inside a script, only the outermost `ok` field needs to be checked.
144
+
145
+ ## Command Overview
146
+
147
+ ### I. Viewing Help
148
+
149
+ Run `--help` to see all commands of the command-line client:
150
+
151
+ ```shell
152
+ easyeda-pro --help
153
+ ```
154
+
155
+ ```
156
+ EasyEDA Pro 4.1.x.abcdef01
157
+
158
+ Usage:
159
+ easyeda-pro <command> [options]
160
+ easyeda-pro [global flags]
161
+
162
+ Commands:
163
+ activate Bring the server window up and focus it
164
+ open Open a project and return its session id; .eprj3 folder projects
165
+ stay in two-way sync with the editor; without --path open a bare editor
166
+ stop Gracefully stop the server
167
+ doctor Probe the endpoint and report its identity
168
+
169
+ session/ Manage sessions
170
+ list List sessions (origin cli/user, project path, window title)
171
+ close Close a session this CLI opened
172
+ abort Force-kill a session (last resort)
173
+
174
+ invoke Invoke a registered function by extension id + name
175
+ functions List extensions known to the session
176
+
177
+ doc/ Query the editor API reference (eda / external / format)
178
+ api Query the eda namespace (static editor API)
179
+ external Query the external namespace (extension-injected API)
180
+ format Query the format namespace (design format reference)
181
+
182
+ Global flags:
183
+ --help Show help for any command: easyeda-pro <command> --help
184
+ --search <query> Fuzzy-search commands when unsure of the name
185
+ --mcp stdio|http Start MCP server
186
+ ```
187
+
188
+ ### II. Searching for Commands
189
+
190
+ If you are not sure of a command name, use `--search` for a fuzzy search:
191
+
192
+ ```shell
193
+ easyeda-pro --search session
194
+ ```
195
+
196
+ ```
197
+ Matches:
198
+ session.list List sessions (each with origin cli/user, the project path and the window title)
199
+ session.close Close a session this CLI opened ...
200
+ session.abort Force-kill a session ...
201
+ open Open a project and return its session id ...
202
+ ```
203
+
204
+ Search keywords are English words such as `session` `invoke` `doc` `permission` `BoardOutline`.
205
+
206
+ ### III. Viewing Subcommand Help
207
+
208
+ Any command documents its usage through `--help`:
209
+
210
+ ```shell
211
+ easyeda-pro open --help
212
+ ```
213
+
214
+ ```
215
+ open
216
+
217
+ Open a project and return its session id; .eprj3 folder projects stay in two-way sync
218
+ with the editor (disk edits reload automatically, editor saves land on disk automatically);
219
+ without --path open a bare editor (visible window; --headless for a hidden render)
220
+
221
+ Usage:
222
+ easyeda-pro open [--path <undefined>] [--headless <boolean>]
223
+
224
+ Options:
225
+ --path Project file path (.eprj/.eprj2/.eprj3/.elib); omit to open a bare editor
226
+ --headless Open without a visible window (hidden render); default opens a GUI window
227
+ ```
228
+
229
+ ```shell
230
+ easyeda-pro invoke --help
231
+ ```
232
+
233
+ ```
234
+ invoke
235
+
236
+ Invoke a registered function by extension id + name (source runs on the editor command
237
+ space; omit extUuid to run with independent script permission)
238
+
239
+ Usage:
240
+ easyeda-pro invoke --session <undefined> [--code <undefined>] [--fn <undefined>]
241
+ [--args <undefined>] [--ext-uuid <undefined>] [--timeout <undefined>]
242
+
243
+ Options:
244
+ --session Session id (string, or positive integer)
245
+ --code Source snippet (string; async function body), reads args via __CLI__.args
246
+ --fn Function name (default: run)
247
+ --args Call arguments as JSON text, exposed to the source as __CLI__.args
248
+ --ext-uuid Extension id (optional; omit to run with independent script permission)
249
+ --timeout Invocation budget in ms (integer, 1-1800000; default 60000)
250
+ ```
251
+
252
+ The remaining subcommands can be inspected in the same way, for example `easyeda-pro session list --help`, `easyeda-pro doc api --help`, or `easyeda-pro --mcp --help`.
253
+
254
+ ### IV. Managing Sessions
255
+
256
+ Running `open` opens a new editor window and returns its session ID:
257
+
258
+ ```shell
259
+ easyeda-pro open
260
+ ```
261
+
262
+ ```json
263
+ {
264
+ "ok": true,
265
+ "value": {
266
+ "sessionId": "9aca2242-79bb-4e2b-9d03-754316927f96",
267
+ "renderId": 1,
268
+ "path": "",
269
+ "headless": false
270
+ },
271
+ "logs": [],
272
+ "durationMs": 1381
273
+ }
274
+ ```
275
+
276
+ You can also specify a project path when opening, or use `--headless` to open with a hidden window:
277
+
278
+ ```shell
279
+ # Open a specific project (.eprj3 folder projects sync in both directions automatically)
280
+ easyeda-pro open --path "C:\Users\username\Documents\EasyEDA-Pro\projects\MyBoard\MyBoard.eprj3"
281
+ ```
282
+
283
+ ```shell
284
+ # Hidden window (no GUI rendering)
285
+ easyeda-pro open --headless true
286
+ ```
287
+
288
+ Use `session list` to see all currently existing sessions:
289
+
290
+ ```shell
291
+ easyeda-pro session list
292
+ ```
293
+
294
+ ```json
295
+ {
296
+ "ok": true,
297
+ "value": [
298
+ {
299
+ "sessionId": "9aca…",
300
+ "renderId": 1,
301
+ "status": "alive",
302
+ "headless": false,
303
+ "origin": "cli",
304
+ "path": null,
305
+ "title": "EasyEDA Pro - V4.1.x"
306
+ },
307
+ {
308
+ "sessionId": "3c66…",
309
+ "renderId": 4,
310
+ "status": "alive",
311
+ "headless": false,
312
+ "origin": "cli",
313
+ "path": "C:\\…\\FMT_Test\\FMT_Test.eprj3",
314
+ "title": "FMT_Test | EasyEDA Pro"
315
+ }
316
+ ]
317
+ }
318
+ ```
319
+
320
+ Use `session close` to close a session opened by the command-line client. Adding the `--destroy` parameter closes the window along with it:
321
+
322
+ ```shell
323
+ easyeda-pro session close --session 9aca2242-79bb-4e2b-9d03-754316927f96 --destroy
324
+ ```
325
+
326
+ ::: tip
327
+
328
+ When a session created by `open` inside a script is no longer needed, close it with `session close --destroy`, so that windows do not pile up.
329
+
330
+ :::
331
+
332
+ ### V. Running as an MCP Server
333
+
334
+ The command-line client can run in MCP server mode, and therefore serve directly as a tool for an AI coding assistant:
335
+
336
+ ```shell
337
+ # Local client (Claude Code / Cursor, etc.)
338
+ easyeda-pro --mcp stdio
339
+ ```
340
+
341
+ ```shell
342
+ # Remote / browser-based agent
343
+ easyeda-pro --mcp http --port 3030 --token <token>
344
+ ```
345
+
346
+ ## Executing JavaScript
347
+
348
+ The `invoke` command executes a piece of JavaScript inside a given session. This is the core capability of the command-line client: through it, the entire extension API is reachable.
349
+
350
+ ### I. Basic Usage
351
+
352
+ The simplest invocation is shown below. The return value of the code is serialized to JSON and sent back:
353
+
354
+ ```shell
355
+ easyeda-pro invoke --session <SESSION_ID> --code "return 1 + 1"
356
+ ```
357
+
358
+ ```json
359
+ {
360
+ "ok": true,
361
+ "value": 2,
362
+ "logs": [],
363
+ "durationMs": 4
364
+ }
365
+ ```
366
+
367
+ ### II. Using Code Files
368
+
369
+ When the code is long, writing it directly on the command line becomes hard to maintain. It is recommended to save it as a `.js` file and pass it in through a pipe:
370
+
371
+ ```shell
372
+ cat > probe.js <<'EOF'
373
+ const out = {};
374
+ out.client = eda.sys_Environment.isClient();
375
+ out.version = eda.sys_Environment.getEditorCurrentVersion();
376
+ out.projectCount = (await eda.dmt_Project.getAllProjectsUuid()).length;
377
+ return out;
378
+ EOF
379
+
380
+ easyeda-pro invoke --session $S --ext-uuid eda --code "$(cat probe.js)"
381
+ ```
382
+
383
+ ### III. Commonly Used Options
384
+
385
+ | Option | Description |
386
+ | --- | --- |
387
+ | `--ext-uuid eda` | Runs with the identity of the editor's built-in extension, granting full external-interaction permissions (reading and writing local files, accessing system interfaces). Recommended to always attach it |
388
+ | `--timeout <ms>` | Timeout of a single invocation. Defaults to `60000`, maximum `1800000`. Increase it appropriately for time-consuming tasks such as batch operations and autorouting |
389
+
390
+ ### IV. Passing Arguments
391
+
392
+ `--args` passes JSON arguments into the code, where they are accessible through `__CLI__.args`:
393
+
394
+ ```shell
395
+ easyeda-pro invoke --session $S --ext-uuid eda \
396
+ --args '{"designator":"R1","x":1000,"y":800}' \
397
+ --code 'const a = __CLI__.args; return a.designator + "@" + a.x + "," + a.y;'
398
+ ```
399
+
400
+ ```json
401
+ {
402
+ "ok": true,
403
+ "value": "R1@1000,800",
404
+ "logs": [],
405
+ "durationMs": 6
406
+ }
407
+ ```
408
+
409
+ ### V. Code Conventions
410
+
411
+ The supplied code is treated as an async function body, so the following conventions apply:
412
+
413
+ - Use `return` to produce a result; the value is serialized to JSON;
414
+ - `await` can be used directly;
415
+ - It is recommended to use forward slashes in paths (`C:/Users/...`), to avoid escaping problems when passing through different terminals.
416
+
417
+ ```javascript
418
+ // Recommended path style
419
+ const DIR = 'C:/Users/username/Documents/EasyEDA-Pro/projects/MyBoard/';
420
+ ```
421
+
422
+ ### VI. Retrieving Files
423
+
424
+ Some export APIs return `File` or `Blob` objects, for example screenshots, BOMs, STEP files, and netlists. If such content needs to be sent back through JSON, it can first be converted to a Base64 string:
425
+
426
+ ```javascript
427
+ function toB64(b) {
428
+ return new Promise((res) => {
429
+ const fr = new FileReader();
430
+ fr.onload = () => res(String(fr.result).split(',')[1] || '');
431
+ fr.readAsDataURL(b);
432
+ });
433
+ }
434
+ ```
435
+
436
+ The example below gets a schematic PNG file and converts it to Base64:
437
+
438
+ ```javascript
439
+ const f = await eda.sch_ManufactureData.getPngFile('MySchematic', { width: 1400 });
440
+ return { name: f.name, size: f.size, b64: await toB64(f) };
441
+ ```
442
+
443
+ ### VII. Writing Files
444
+
445
+ A simpler approach is to write files straight into the project directory with the [SYS_FileSystem](../reference/pro-api.sys_filesystem) APIs:
446
+
447
+ ```javascript
448
+ const f = await eda.pcb_ManufactureData.get3DFile('MyBoard', 'step', ['Component Model'], 'Outfit', true);
449
+ await eda.sys_FileSystem.saveFileToFileSystem(
450
+ 'C:/Users/username/Documents/EasyEDA-Pro/projects/MyBoard/MyBoard.step',
451
+ f,
452
+ undefined,
453
+ true
454
+ ); // the 4th argument, force = true, means overwrite
455
+ ```
456
+
457
+ Frequently used file-system APIs:
458
+
459
+ | API | Description |
460
+ | --- | --- |
461
+ | [saveFileToFileSystem(uri, file, fileName?, force?)](../reference/pro-api.sys_filesystem.savefiletofilesystem) | Writes a file. If `uri` ends with `/` it is treated as a directory, otherwise as a complete file name |
462
+ | [readFileFromFileSystem(uri)](../reference/pro-api.sys_filesystem.readfilefromfilesystem) | Reads a file, returning a `File` object |
463
+ | [listFilesOfFileSystem(folderPath, recursive?)](../reference/pro-api.sys_filesystem.listfilesoffilesystem) | Lists a directory |
464
+ | [deleteFileInFileSystem(uri, force?)](../reference/pro-api.sys_filesystem.deletefileinfilesystem) | Deletes a file |
465
+ | [getProjectsPaths()](../reference/pro-api.sys_filesystem.getprojectspaths) / [getEdaPath()](../reference/pro-api.sys_filesystem.getedapath) / [getLibrariesPaths()](../reference/pro-api.sys_filesystem.getlibrariespaths) | Returns the various root directories |
466
+
467
+ ## Querying API Documentation
468
+
469
+ The extension API has several hundred classes. Its documentation is organized by progressive disclosure: first list all classes, then view the methods of a class, then view the full signature of a single method.
470
+
471
+ ### I. Listing All Classes
472
+
473
+ ```shell
474
+ easyeda-pro doc api
475
+ ```
476
+
477
+ The command returns an array of the form `{ name, comment }`. Class names are grouped by domain prefix:
478
+
479
+ | Prefix | Domain |
480
+ | --- | --- |
481
+ | `DMT_` | Document tree / project / board / schematic / PCB / editor control |
482
+ | `SCH_` | Schematic primitives (Component / Wire / Pin / Text / Drc / Netlist / ManufactureData) |
483
+ | `PCB_` | PCB primitives (Component / Pad / Line / Via / Polyline / Pour / Drc / ManufactureData / Layer / Net) |
484
+ | `LIB_` | Device library (Device / Symbol / Footprint / Classification) |
485
+ | `SYS_` | System (FileSystem / Dialog / Window / Setting / Environment / MessageBus) |
486
+ | `E*_` | Enumerations |
487
+
488
+ ### II. Viewing the Methods of a Class
489
+
490
+ ```shell
491
+ easyeda-pro doc api --class-name DMT_Project
492
+ ```
493
+
494
+ ```json
495
+ {
496
+ "ok": true,
497
+ "value": {
498
+ "title": "Document tree / Project management class",
499
+ "methods": [
500
+ { "name": "createProject", "comment": "Create Project" },
501
+ { "name": "openProject", "comment": "Open project" },
502
+ { "name": "getCurrentProjectInfo", "comment": "Get detailed properties of Current project" }
503
+ ],
504
+ "callPath": "dmt_Project"
505
+ }
506
+ }
507
+ ```
508
+
509
+ The `callPath` field in the return value is the property name of the class on the `eda` object, so methods of the `DMT_Project` class are called as `eda.dmt_Project.createProject(...)`.
510
+
511
+ ### III. Viewing the Full Signature of a Method
512
+
513
+ ```shell
514
+ easyeda-pro doc api --class-name DMT_Project --method-name createProject
515
+ ```
516
+
517
+ ```json
518
+ {
519
+ "ok": true,
520
+ "value": {
521
+ "title": "Create Project",
522
+ "params": [
523
+ { "name": "projectFriendlyName", "type": "string", "description": "Project friendly name", "required": true },
524
+ { "name": "projectName", "type": "string", "description": "Project name; must be unique; only letters, digits, and hyphens are allowed", "required": false },
525
+ { "name": "teamUuid", "type": "string" },
526
+ { "name": "fileFormat", "type": "EDMT_ProjectFileFormat", "description": "Project file format, EPRJ3 by default; only effective in the client's semi-offline / fully-offline mode" }
527
+ ],
528
+ "returns": { "type": "string | undefined", "description": "Project UUID, if it is undefined creation fails" },
529
+ "isAsync": true,
530
+ "example": "...(a directly runnable example)..."
531
+ }
532
+ }
533
+ ```
534
+
535
+ Every method ships with a directly runnable example. That is the most efficient way to learn how a method is used.
536
+
537
+ ### IV. Inspecting an Enumeration
538
+
539
+ ```shell
540
+ easyeda-pro doc api --class-name EPCB_LayerId
541
+ ```
542
+
543
+ ```json
544
+ {
545
+ "ok": true,
546
+ "value": {
547
+ "name": "EPCB_LayerId",
548
+ "comment": "Layer ID",
549
+ "values": [
550
+ { "name": "TOP", "value": 1, "description": "Top layer" },
551
+ { "name": "BOARD_OUTLINE", "value": 11, "description": "Board Outline layer" }
552
+ ]
553
+ }
554
+ }
555
+ ```
556
+
557
+ ### V. Querying the Design File Format
558
+
559
+ The design file format reference is queried through the `doc format` subcommand. Its usage is described in the [Generating Project Files Directly](#generating-project-files-directly) section:
560
+
561
+ ```shell
562
+ easyeda-pro doc format
563
+ ```
564
+
565
+ ```shell
566
+ easyeda-pro doc format --class-name TMSchComponent
567
+ ```
568
+
569
+ ## Drawing a Schematic with the Extension API
570
+
571
+ The example below draws a voltage-divider and filter circuit from scratch through the extension API, and exports the netlist, the BOM, and a screenshot.
572
+
573
+ ```text
574
+ VCC ──┬── R1(1kΩ) ──┬── MID ── R2(10kΩ) ──┬── GND
575
+ │ │ │
576
+ └── R3(1kΩ) ──┘ C1(100nF) ───┘ (C1 in parallel with R2)
577
+ ```
578
+
579
+ ### I. Creating a Session
580
+
581
+ ```shell
582
+ easyeda-pro open
583
+ export S=9aca2242-79bb-4e2b-9d03-754316927f96
584
+ ```
585
+
586
+ ### II. Creating a Project
587
+
588
+ [`DMT_Project.createProject()`](../reference/pro-api.dmt_project.createproject) creates a project, and [`DMT_Project.openProject()`](../reference/pro-api.dmt_project.openproject) then opens it:
589
+
590
+ ```javascript
591
+ // step1_create_proj.js
592
+ const uuid = await eda.dmt_Project.createProject(
593
+ 'MyBoard', // friendly name
594
+ 'my-board', // project name (letters / digits / hyphens)
595
+ undefined, // team, empty means personal
596
+ undefined, // folder, empty means root
597
+ 'Tutorial sample project', // description
598
+ undefined, // collaboration mode
599
+ EDMT_ProjectFileFormat.EPRJ3 // folder project format
600
+ );
601
+ await eda.dmt_Project.openProject(uuid);
602
+ await new Promise((r) => setTimeout(r, 3000));
603
+
604
+ const p = await eda.dmt_Project.getCurrentProjectInfo();
605
+ return {
606
+ uuid: p.uuid,
607
+ board: p.data[0].name,
608
+ schematic: p.data[0].schematic.name,
609
+ page: p.data[0].schematic.page[0].uuid,
610
+ pcb: p.data[0].pcb.uuid
611
+ };
612
+ ```
613
+
614
+ ```shell
615
+ easyeda-pro invoke --session $S --ext-uuid eda --code "$(cat step1_create_proj.js)"
616
+ ```
617
+
618
+ ```json
619
+ {
620
+ "ok": true,
621
+ "value": {
622
+ "uuid": "5d3ca5e2…",
623
+ "board": "Board1",
624
+ "schematic": "Schematic1",
625
+ "page": "429e4af1f4a665c3",
626
+ "pcb": "509258b8ebfffb42"
627
+ },
628
+ "logs": [],
629
+ "durationMs": 2611
630
+ }
631
+ ```
632
+
633
+ Once the project is created, the following files appear on disk:
634
+
635
+ ```
636
+ projects/MyBoard/
637
+ ├── MyBoard.eprj3
638
+ ├── sch/Schematic1/P1.esch2
639
+ ├── sch/Schematic1/Schematic1.ecfg
640
+ ├── pcb/PCB1.epcb2
641
+ └── panel/Panel1.epan2
642
+ ```
643
+
644
+ ### III. Searching for Devices
645
+
646
+ [`LIB_LibrariesList.getSystemLibraryUuid()`](../reference/pro-api.lib_librarieslist.getsystemlibraryuuid) returns the system library UUID, and [`LIB_Device.search()`](../reference/pro-api.lib_device.search) searches for devices inside a library:
647
+
648
+ ```javascript
649
+ // step2_search.js
650
+ const sysLib = await eda.lib_LibrariesList.getSystemLibraryUuid();
651
+ const items = await eda.lib_Device.search('0603WAF1001T5E');
652
+ return {
653
+ systemLibrary: sysLib,
654
+ first: {
655
+ name: items[0].name,
656
+ uuid: items[0].uuid,
657
+ lcsc: items[0].supplierId,
658
+ libraryUuid: items[0].libraryUuid
659
+ }
660
+ };
661
+ ```
662
+
663
+ ```json
664
+ {
665
+ "ok": true,
666
+ "value": {
667
+ "systemLibrary": "0819f05c4eef4c71ace90d822a990e87",
668
+ "first": {
669
+ "name": "0603WAF1001T5E",
670
+ "uuid": "18db11499a04403ba8c98e2f7a687fbc",
671
+ "lcsc": "C21190",
672
+ "libraryUuid": "0819f05c4eef4c71ace90d822a990e87"
673
+ }
674
+ },
675
+ "durationMs": 7282
676
+ }
677
+ ```
678
+
679
+ ::: tip
680
+
681
+ In semi-offline mode the system library is fully available. It contains a large number of real devices with LCSC part numbers, footprints, and 3D models, and the return value of `search()` can be fed directly into the placement APIs.
682
+
683
+ :::
684
+
685
+ The devices used in this example are:
686
+
687
+ | Device | LCSC part number | Description |
688
+ | --- | --- | --- |
689
+ | `0603WAF1001T5E` | C21190 | 1kΩ 0603 |
690
+ | `0603WAF1002T5E` | C25804 | 10kΩ 0603 |
691
+ | `CC0603KRX7R9BB104` | C14663 | 100nF 0603 |
692
+
693
+ ### IV. Placing Components
694
+
695
+ First open the schematic page with [`DMT_EditorControl.openDocument()`](../reference/pro-api.dmt_editorcontrol.opendocument), then place components with [`SCH_PrimitiveComponent.create()`](../reference/pro-api.sch_primitivecomponent.create).
696
+
697
+ The recommended approach is to read a snapshot of the component properties right after `create()`, then write `designator` and `otherProperty` back together in a single [`SCH_PrimitiveComponent.modify()`](../reference/pro-api.sch_primitivecomponent.modify) call. That way the designator and all device properties are set in one pass:
698
+
699
+ ```javascript
700
+ // step3_place.js
701
+ const pageUuid = '429e4af1f4a665c3'; // the page returned by the previous step
702
+ await eda.dmt_EditorControl.openDocument(pageUuid);
703
+ await new Promise((r) => setTimeout(r, 2500));
704
+
705
+ const LIB = '0819f05c4eef4c71ace90d822a990e87';
706
+ const R1K = { libraryType: '3', libraryUuid: LIB, uuid: '18db11499a04403ba8c98e2f7a687fbc' };
707
+ const R10K = { libraryType: '3', libraryUuid: LIB, uuid: 'b948db94476e4027ac8953235755ec96' };
708
+ const C100 = { libraryType: '3', libraryUuid: LIB, uuid: '96b39256cc3f4d80bd3b503deb4f3328' };
709
+
710
+ const out = [];
711
+ for (const [ref, lib, x, y] of [
712
+ ['R1', R1K, 400, 610],
713
+ ['R2', R10K, 400, 510],
714
+ ['C1', C100, 650, 510],
715
+ ['R3', R1K, 150, 610]
716
+ ]) {
717
+ // 1. Place the component (coordinates are in 10mil; rotation is the API angle)
718
+ const c = await eda.sch_PrimitiveComponent.create(lib, x, y, undefined, 90, false, true, true);
719
+ const id = c.getState_PrimitiveId();
720
+
721
+ // 2. Read the property snapshot first
722
+ const pre = (await eda.sch_PrimitiveComponent.get(id)).getState_OtherProperty();
723
+
724
+ // 3. Write the designator and properties back in one call
725
+ await eda.sch_PrimitiveComponent.modify(id, { designator: ref, otherProperty: pre });
726
+
727
+ // 4. Read the absolute pin coordinates for later wiring
728
+ const pins = await eda.sch_PrimitiveComponent.getAllPinsByPrimitiveId(id);
729
+ out.push({
730
+ ref,
731
+ id,
732
+ value: pre.Value,
733
+ pins: pins.map((p) => ({ n: p.pinNumber, x: p.x, y: p.y }))
734
+ });
735
+ }
736
+ return out;
737
+ ```
738
+
739
+ ```json
740
+ {
741
+ "ok": true,
742
+ "value": [
743
+ {
744
+ "ref": "R1",
745
+ "id": "4dc7d7c4967a383f",
746
+ "value": "1kΩ",
747
+ "pins": [
748
+ { "n": "2", "x": 400, "y": 590 },
749
+ { "n": "1", "x": 400, "y": 630 }
750
+ ]
751
+ },
752
+ {
753
+ "ref": "R2",
754
+ "id": "054e84ce1932ae79",
755
+ "value": "10kΩ",
756
+ "pins": [
757
+ { "n": "2", "x": 400, "y": 490 },
758
+ { "n": "1", "x": 400, "y": 530 }
759
+ ]
760
+ },
761
+ {
762
+ "ref": "C1",
763
+ "id": "6942169cfa200a6f",
764
+ "value": "100nF",
765
+ "pins": [
766
+ { "n": "1", "x": 650, "y": 530 },
767
+ { "n": "2", "x": 650, "y": 490 }
768
+ ]
769
+ },
770
+ {
771
+ "ref": "R3",
772
+ "id": "3acfabe56d603ec8",
773
+ "value": "1kΩ",
774
+ "pins": [
775
+ { "n": "2", "x": 150, "y": 590 },
776
+ { "n": "1", "x": 150, "y": 630 }
777
+ ]
778
+ }
779
+ ]
780
+ }
781
+ ```
782
+
783
+ ::: tip
784
+
785
+ Each component should be `create()`d first and then have its pin coordinates read back with [`SCH_PrimitiveComponent.getAllPinsByPrimitiveId()`](../reference/pro-api.sch_primitivecomponent.getallpinsbyprimitiveid). Do not compute them yourself; the pin coordinates are the only basis for the wiring that follows.
786
+
787
+ :::
788
+
789
+ ### V. Placing Net Flags
790
+
791
+ [`SCH_PrimitiveComponent.createNetFlag()`](../reference/pro-api.sch_primitivecomponent.createnetflag) places net flags. The supported types are `Power` `Ground` `AnalogGround` `ProtectGround`:
792
+
793
+ ```javascript
794
+ // step4_flags.js
795
+ const vcc = await eda.sch_PrimitiveComponent.createNetFlag('Power', 'VCC', 400, 660, 0, false);
796
+ const gnd = await eda.sch_PrimitiveComponent.createNetFlag('Ground', 'GND', 650, 410, 0, false);
797
+ return {
798
+ vcc: vcc.getState_PrimitiveId(),
799
+ gnd: gnd.getState_PrimitiveId(),
800
+ vccNet: vcc.getState_Net(),
801
+ gndNet: gnd.getState_Net()
802
+ };
803
+ ```
804
+
805
+ ```json
806
+ {
807
+ "ok": true,
808
+ "value": {
809
+ "vcc": "e6fc4f9698692111",
810
+ "gnd": "2535215168c2bb20",
811
+ "vccNet": "VCC",
812
+ "gndNet": "GND"
813
+ }
814
+ }
815
+ ```
816
+
817
+ ### VI. Drawing Wires
818
+
819
+ [`SCH_PrimitiveWire.create()`](../reference/pro-api.sch_primitivewire.create) draws wires. A wire is an orthogonal polyline; a single `create()` call can draw several segments, but consecutive segments must meet end to end and each segment must be horizontal or vertical:
820
+
821
+ ```javascript
822
+ // step5_wire.js
823
+ const plan = [
824
+ ['VCC->R1.1', [[400, 660, 400, 630]]],
825
+ ['R1.2->R2.1', [[400, 590, 400, 530]]],
826
+ ['C1.1->MID', [[650, 530, 400, 530]]],
827
+ ['C1.2->GND', [[650, 490, 650, 410]]],
828
+ ['R2.2->GND', [[400, 490, 400, 410, 650, 410]]],
829
+ ['R3.1->VCC', [[150, 630, 150, 660, 400, 660]]],
830
+ ['R3.2->GND', [[150, 590, 150, 410, 400, 410]]]
831
+ ];
832
+ const made = [];
833
+ for (const [tag, line] of plan) {
834
+ const w = await eda.sch_PrimitiveWire.create(line);
835
+ made.push({ tag, net: w.getState_Net(), id: w.getState_PrimitiveId() });
836
+ }
837
+ return made;
838
+ ```
839
+
840
+ ```json
841
+ {
842
+ "ok": true,
843
+ "value": [
844
+ { "tag": "VCC->R1.1", "id": "11b3075f364b1790" },
845
+ { "tag": "R1.2->R2.1", "id": "2d6fcb2792dae43f" },
846
+ { "tag": "C1.1->MID", "id": "2d6fcb2792dae43f" }
847
+ ]
848
+ }
849
+ ```
850
+
851
+ ::: tip
852
+
853
+ Adjacent segments are merged by the editor into a single `WIRE` primitive group. This is normal behavior. As long as the coordinates land exactly on the pins, the connection is correct.
854
+
855
+ :::
856
+
857
+ ### VII. Running a DRC Check
858
+
859
+ [`SCH_Drc.check()`](../reference/pro-api.sch_drc.check) runs the design rule check. Its parameters are:
860
+
861
+ | Parameter | Description |
862
+ | --- | --- |
863
+ | `strict` | Strict mode; currently always pass `true` |
864
+ | `userInterface` | Whether to open the bottom DRC panel; pass `false` in scripts |
865
+ | `includeVerboseError` | Pass `true` to get an array of violation details, `false` to get only a pass/fail boolean |
866
+
867
+ ```javascript
868
+ // step6_drc.js
869
+ await eda.sch_Document.save();
870
+ await new Promise((r) => setTimeout(r, 8000)); // wait for the editor to refresh
871
+
872
+ const verbose = await eda.sch_Drc.check(true, false, true); // array of violation details
873
+ const passed = await eda.sch_Drc.check(true, false, false); // pass/fail boolean
874
+ return {
875
+ violationCount: verbose.length,
876
+ passed,
877
+ violations: verbose.map((v) => v.rule + '(' + v.type + '):' + v.primitives.map((p) => p.name).join('|'))
878
+ };
879
+ ```
880
+
881
+ ```json
882
+ {
883
+ "ok": true,
884
+ "value": {
885
+ "violationCount": 0,
886
+ "passed": true,
887
+ "violations": []
888
+ }
889
+ }
890
+ ```
891
+
892
+ ::: tip
893
+
894
+ Wait 8 to 10 seconds after `save()` before running the DRC check, so the editor can finish its topology computation. That yields the most accurate result.
895
+
896
+ :::
897
+
898
+ ### VIII. Exporting the Netlist
899
+
900
+ [`SCH_ManufactureData.getNetlistFile()`](../reference/pro-api.sch_manufacturedata.getnetlistfile) exports a netlist file:
901
+
902
+ ```javascript
903
+ // step7_netlist.js
904
+ const f = await eda.sch_ManufactureData.getNetlistFile('MyBoard_NET', 'Protel2');
905
+ const txt = await f.text();
906
+ return { name: f.name, size: f.size, nets: txt.split('\n').slice(-24).join('\n') };
907
+ ```
908
+
909
+ ```json
910
+ {
911
+ "ok": true,
912
+ "value": {
913
+ "name": "MyBoard_NET.net",
914
+ "size": 4206,
915
+ "nets": "(\nGND \nR2-2 0603WAF1002T5E-2 Input \nC1-2 CC0603KRX7R9BB104-2 Passive \nR3-2 0603WAF1001T5E-2 Input \n)\n(\n$1N2 \nR2-1 …\n)\n(\nVCC \nR3-1 …\nR1-1 …\n)"
916
+ }
917
+ }
918
+ ```
919
+
920
+ The exported netlist matches the design intent exactly, so the connections can be asserted programmatically.
921
+
922
+ ### IX. Exporting the BOM
923
+
924
+ [`SCH_ManufactureData.getBomFile()`](../reference/pro-api.sch_manufacturedata.getbomfile) exports the BOM, in `csv` or `xlsx` format:
925
+
926
+ ```javascript
927
+ // step8_bom.js
928
+ const DIR = 'C:/Users/username/Documents/EasyEDA-Pro/projects/MyBoard/';
929
+
930
+ // CSV (text, can be read back and verified directly)
931
+ const csv = await eda.sch_ManufactureData.getBomFile('BOM', 'csv');
932
+ const csvText = await csv.text();
933
+ await eda.sys_FileSystem.saveFileToFileSystem(DIR + 'BOM.csv', new Blob([csvText], { type: 'text/csv' }), undefined, true);
934
+
935
+ // XLSX (binary, written straight to disk)
936
+ const xlsx = await eda.sch_ManufactureData.getBomFile('BOM', 'xlsx');
937
+ const saved = await eda.sys_FileSystem.saveFileToFileSystem(DIR + 'BOM.xlsx', xlsx, undefined, true);
938
+
939
+ return { csvText, xlsxSize: xlsx.size, saved };
940
+ ```
941
+
942
+ ```json
943
+ {
944
+ "ok": true,
945
+ "value": {
946
+ "csvText": "No.\tQuantity\tComment\tDesignator\tFootprint\tValue\tManufacturer Part\tManufacturer\tSupplier Part\tSupplier\n1\t1\t100nF\tC1\tC0603\t100nF\tCC0603KRX7R9BB104\tYAGEO\tC14663\tLCSC\n2\t2\t1kΩ\tR1,R3\tR0603\t1kΩ\t0603WAF1001T5E\tUNI-ROYAL\tC21190\tLCSC\n3\t1\t10kΩ\tR2\tR0603\t10kΩ\t0603WAF1002T5E\tUNI-ROYAL\tC25804\tLCSC\n",
947
+ "xlsxSize": 6893,
948
+ "saved": true
949
+ }
950
+ }
951
+ ```
952
+
953
+ R1 and R3, which share the same part number, are merged into one row with a quantity of 2.
954
+
955
+ ### X. Exporting a Screenshot
956
+
957
+ [`DMT_EditorControl.getCurrentRenderedAreaImage()`](../reference/pro-api.dmt_editorcontrol.getcurrentrenderedareaimage) returns an image of the currently rendered area:
958
+
959
+ ```javascript
960
+ // step9_shot.js
961
+ const tabId = await eda.dmt_EditorControl.openDocument('429e4af1f4a665c3');
962
+ await eda.dmt_EditorControl.zoomToAllPrimitives();
963
+ await new Promise((r) => setTimeout(r, 2000));
964
+
965
+ const blob = await eda.dmt_EditorControl.getCurrentRenderedAreaImage(tabId);
966
+ await eda.sys_FileSystem.saveFileToFileSystem('C:/Users/username/Documents/EasyEDA-Pro/projects/MyBoard/sch.png', blob, undefined, true);
967
+ return { saved: true, size: blob.size };
968
+ ```
969
+
970
+ To export the whole page instead, use [`SCH_ManufactureData.getPngFile()`](../reference/pro-api.sch_manufacturedata.getpngfile) and specify a resolution:
971
+
972
+ ```javascript
973
+ const png = await eda.sch_ManufactureData.getPngFile('MySchematic', { width: 1400 });
974
+ await eda.sys_FileSystem.saveFileToFileSystem(DIR + png.name, png, undefined, true);
975
+ ```
976
+
977
+ ### XI. Saving Documents
978
+
979
+ Schematic and PCB documents are saved through their respective `Document` classes:
980
+
981
+ ```javascript
982
+ await eda.sch_Document.save(); // schematic
983
+ await eda.pcb_Document.save(); // PCB
984
+ ```
985
+
986
+ `.eprj3` is a folder project format that stays in two-way sync with the editor: once the editor saves, the `.esch2` / `.epcb2` files on disk are updated immediately; conversely, if the files on disk are modified directly, the editor re-reads them shortly afterwards.
987
+
988
+ ### XII. Designing the PCB
989
+
990
+ The PCB side follows a flow similar to the schematic: draw the board outline, import changes from the schematic, auto-place, and autoroute.
991
+
992
+ ```javascript
993
+ // step10_pcb.js
994
+ const pcbUuid = '509258b8ebfffb42';
995
+
996
+ // 1. Open the PCB
997
+ await eda.dmt_EditorControl.openDocument(pcbUuid);
998
+ await new Promise((r) => setTimeout(r, 2500));
999
+
1000
+ // 2. Draw the board outline: EPCB_LayerId.BOARD_OUTLINE = 11
1001
+ // Using a polyline primitive with explicit vertices is the least error-prone option
1002
+ const poly = eda.pcb_MathPolygon.createPolygon([40, -340, 'L', 400, -340, 400, -120, 40, -120, 40, -340]);
1003
+ const outline = await eda.pcb_PrimitivePolyline.create('', 11, poly, 10, false);
1004
+
1005
+ // 3. Import changes from the schematic (the GUI equivalent of "Design - Import Changes")
1006
+ await eda.pcb_Document.importChanges();
1007
+ await new Promise((r) => setTimeout(r, 5000));
1008
+
1009
+ // 4. Auto-place
1010
+ const layout = await eda.pcb_Document.autoLayout();
1011
+
1012
+ // 5. Autoroute
1013
+ const route = await eda.pcb_Document.autoRouting();
1014
+
1015
+ // 6. Zoom to the board outline and take a screenshot
1016
+ await eda.pcb_Document.zoomToBoardOutline();
1017
+ const tabId = '509258b8ebfffb42@<project uuid>';
1018
+ const img = await eda.dmt_EditorControl.getCurrentRenderedAreaImage(tabId);
1019
+ await eda.sys_FileSystem.saveFileToFileSystem(DIR + 'pcb.png', img, undefined, true);
1020
+
1021
+ await eda.pcb_Document.save();
1022
+ return { outline: outline.getState_PrimitiveId(), layout, route, imgSize: img.size };
1023
+ ```
1024
+
1025
+ ```json
1026
+ {
1027
+ "ok": true,
1028
+ "value": {
1029
+ "outline": "24275a39b9fc526f",
1030
+ "layout": {
1031
+ "success": true,
1032
+ "totalComponentsCount": 4,
1033
+ "successComponentsCount": 4,
1034
+ "failedComponents": [],
1035
+ "duration": 974
1036
+ },
1037
+ "route": {
1038
+ "success": true,
1039
+ "totalNetsCount": 3,
1040
+ "successNetsCount": 3,
1041
+ "failedNets": [],
1042
+ "duration": 1405
1043
+ },
1044
+ "imgSize": 124914
1045
+ }
1046
+ }
1047
+ ```
1048
+
1049
+ [`PCB_Document.autoRouting()`](../reference/pro-api.pcb_document.autorouting) accepts parameters that specify which nets to route:
1050
+
1051
+ ```javascript
1052
+ await eda.pcb_Document.autoRouting({ RoutingNets: ['VCC'], optimization: 1 });
1053
+ ```
1054
+
1055
+ After routing, run [`PCB_Drc.check()`](../reference/pro-api.pcb_drc.check) to confirm connectivity:
1056
+
1057
+ ```javascript
1058
+ const passed = await eda.pcb_Drc.check(true, false, false); // true means everything passed
1059
+ ```
1060
+
1061
+ Many more capabilities live in classes such as `DMT_Board`, `PCB_Drc`, and `PCB_ManufactureData`: net classes, differential pairs, equal-length groups, copper pours, Gerber, coordinate files, IPC-2581, ODB++, and interactive BOM export. Browse them one by one with `doc api`.
1062
+
1063
+ ### XIII. Practical Recommendations
1064
+
1065
+ 1. Always attach `--ext-uuid eda` to `invoke`, so that the full permission set is granted;
1066
+ 2. Use forward slashes in paths uniformly, and confirm the target is inside the `APP_PROJECT_DIR` directory before writing;
1067
+ 3. When placing components, follow the sequence "`create()` → read the property snapshot → `modify(designator + otherProperty)`", so that the designator and properties are set in one pass;
1068
+ 4. Read pin coordinates with `getAllPinsByPrimitiveId()`; do not compute them yourself;
1069
+ 5. When there are many components, invoke in batches of 20 to 25 and leave headroom in the timeout;
1070
+ 6. After a change, wait 5 to 10 seconds before querying state (DRC / netlist / rendering), to get the final result;
1071
+ 7. Persist the key return value of each step as JSON evidence;
1072
+ 8. On completion, call `save()` and verify the artifacts on disk;
1073
+ 9. Close sessions with `session close --destroy` when they are no longer needed.
1074
+
1075
+ ## Generating Project Files Directly
1076
+
1077
+ Besides operating the editor through the extension API, you can also write `.eprj3` project files directly. The two approaches can be mixed: create the project skeleton with the API, then generate content through files.
1078
+
1079
+ ### I. Project File Structure
1080
+
1081
+ `.eprj3` is a folder-based project format, consisting of one directory plus a number of JSON / plain-text files. It is friendly to Git and to scripts.
1082
+
1083
+ ```
1084
+ MyBoard/
1085
+ ├── MyBoard.eprj3 # Project index and metadata (the only file created with the project)
1086
+ ├── sch/ # Schematics, one folder per schematic
1087
+ │ └── <schematic name>/
1088
+ │ ├── <page name>.esch2 # Page source
1089
+ │ ├── <schematic name>.ecfg # Design rules and configuration of that schematic
1090
+ │ └── <schematic name>.evar # Assembly variants
1091
+ ├── pcb/
1092
+ │ └── <PCB name>.epcb2 # PCB source
1093
+ └── panel/
1094
+ └── <panel name>.epan2 # Panel source
1095
+ ```
1096
+
1097
+ The file name is the document name.
1098
+
1099
+ ### II. Record Format
1100
+
1101
+ `.esch2`, `.epcb2`, and `.epan2` share one record format. Each file consists of multiple lines, one JSON record per line:
1102
+
1103
+ ```
1104
+ {"type":"<type>","ticket":<logical clock>,"id":"<16 lowercase hex chars>"}||{<payload>}|
1105
+ ```
1106
+
1107
+ - The shell and the payload are separated by `||`;
1108
+ - The line must end with `|` plus a line feed (`LF`, not `CRLF`);
1109
+ - `type` determines the meaning of the record.
1110
+
1111
+ Common types:
1112
+
1113
+ | File | Types |
1114
+ | --- | --- |
1115
+ | Schematic | `DOCHEAD` `META` `COMPONENT` `ATTR` `WIRE` `LINE` `TEXT` |
1116
+ | PCB | `DOCHEAD` `META` `COMPONENT` `ATTR` `PAD_NET` `NET` `POLY` `LINE` `LAYER` `RULE` |
1117
+
1118
+ ### III. Multi-Document Structure
1119
+
1120
+ An `.esch2` file does not correspond to a single page. It is a sequence of documents, each starting with a `DOCHEAD`:
1121
+
1122
+ ```
1123
+ DOCHEAD docType=SYMBOL uuid=<sheet symbol> ← the sheet (Drawing-Symbol_A4)
1124
+ DOCHEAD docType=SYMBOL uuid=<device symbol 1> ← the 1kΩ resistor symbol
1125
+ DOCHEAD docType=SYMBOL uuid=<device symbol 2>
1126
+ DOCHEAD docType=FOOTPRINT uuid=<footprint 1> ← R0603
1127
+ DOCHEAD docType=DEVICE uuid=<device 1> ← contains only DOCHEAD and META
1128
+ ...
1129
+ DOCHEAD docType=BLOB uuid=BLOB
1130
+ DOCHEAD docType=SCH_PAGE uuid=<page uuid> ← the actual page content
1131
+ ```
1132
+
1133
+ The device library (symbols, footprints, devices) is embedded in the same file. `.eprj3` has no separate project library; every device is an independent document inside the file.
1134
+
1135
+ It is recommended to keep the write order identical to the order the editor itself emits: `SYMBOL` → `FOOTPRINT` → `DEVICE` → `BLOB` → `SCH_PAGE`.
1136
+
1137
+ ### IV. Querying the Format Reference
1138
+
1139
+ Use `doc format` to query the field definitions of the various design-file records:
1140
+
1141
+ ```shell
1142
+ easyeda-pro doc format
1143
+ easyeda-pro doc format --class-name TMSchComponent
1144
+ easyeda-pro doc format --class-name TSchAttr
1145
+ easyeda-pro doc format --class-name TWire
1146
+ easyeda-pro doc format --class-name TSchLine
1147
+ ```
1148
+
1149
+ ```json
1150
+ {
1151
+ "ok": true,
1152
+ "value": {
1153
+ "name": "TMSchComponent",
1154
+ "comment": "Component (line format of the COMPONENT primitive)",
1155
+ "fields": [
1156
+ { "name": "partId", "type": "TPartId", "required": true },
1157
+ { "name": "x", "type": "number", "required": true },
1158
+ { "name": "y", "type": "number", "required": true },
1159
+ { "name": "rotation", "type": "number", "required": true },
1160
+ { "name": "isMirror", "type": "boolean", "required": true },
1161
+ {
1162
+ "name": "attrs",
1163
+ "type": "{ DeviceName: string; Devices: string; FootprintName: string; Footprints: string; SymbolName: string; Symbols: string }",
1164
+ "required": true
1165
+ },
1166
+ { "name": "zIndex", "type": "null | number", "required": true }
1167
+ ]
1168
+ }
1169
+ }
1170
+ ```
1171
+
1172
+ ::: tip
1173
+
1174
+ The field descriptions of `doc format` are quite detailed. Read them field by field before writing a file; that is more reliable than reverse-engineering from a real sample.
1175
+
1176
+ :::
1177
+
1178
+ Common type mapping:
1179
+
1180
+ | What you want to write | Type |
1181
+ | --- | --- |
1182
+ | Schematic component instance | `TMSchComponent` |
1183
+ | Schematic attributes (designator / value / net name, ...) | `TSchAttr` |
1184
+ | Schematic wire group / single segment | `TWire` / `TSchLine` |
1185
+ | PCB component instance | `TMPcbComponent` |
1186
+ | PCB attributes | `TPcbAttr` |
1187
+ | PCB pad-to-net mapping | `TPadNetWire` |
1188
+ | PCB trace / board outline polyline | `TPcbLine` / `TPcbPoly` + `TPcbBoard` |
1189
+ | The various forms of primitive id | `TElementId` / `TSingletonElementId` / `TKeyedElementId` / `TCompositeElementId` |
1190
+ | PART id | `TPartId` |
1191
+
1192
+ ### V. Writing Page Content
1193
+
1194
+ The example below writes the previously described voltage-divider circuit directly into `P1.esch2`.
1195
+
1196
+ #### 1. Creating the Project Skeleton with the API
1197
+
1198
+ First create and open the project through the API, to obtain the correct directory structure and avoid writing the index file by hand:
1199
+
1200
+ ```shell
1201
+ easyeda-pro open
1202
+ easyeda-pro invoke --session $S --ext-uuid eda --code "$(cat step1_create_proj.js)"
1203
+ ```
1204
+
1205
+ At this point `P1.esch2` contains the A4 sheet `SYMBOL` document, the `DEVICE` documents, the `BLOB` document, and an empty `SCH_PAGE` document.
1206
+
1207
+ #### 2. Collecting Library Documents
1208
+
1209
+ A symbol document contains a whole set of graphical definitions (`PART` `PIN` `LINE` `POLY` `ATTR`), which is not practical to write by hand. It must come from an actual editor export.
1210
+
1211
+ The recommended approach is: place the components once through the API and save, then read the `.esch2` file from disk and take the `SYMBOL` `FOOTPRINT` `DEVICE` document sections verbatim for reuse.
1212
+
1213
+ ```shell
1214
+ # Place components through the API and save
1215
+ easyeda-pro invoke --session $S --ext-uuid eda --code "$(cat place_and_save.js)"
1216
+ # The file is updated immediately after saving and can be read straight from disk
1217
+ ```
1218
+
1219
+ #### 3. Writing the SCH_PAGE Document Section
1220
+
1221
+ Only business records are written into the `SCH_PAGE` document section: component instances, attributes, and wires.
1222
+
1223
+ ```python
1224
+ # COMPONENT: partId points at the id of the PART row in the SYMBOL document
1225
+ # the ATTR "Symbol" points at the SYMBOL document uuid, "Device" at the DEVICE document uuid
1226
+ comp = {
1227
+ "type": "COMPONENT", "ticket": tk, "id": cid,
1228
+ "body": {
1229
+ "partId": "0603WAF1001T5E.1", # id of the PART row in the symbol document
1230
+ "x": 400, "y": 610,
1231
+ "rotation": 270, # file angle = (360 - API angle) % 360
1232
+ "isMirror": False,
1233
+ "attrs": {"Footprints": "[]", "Devices": "[]", "DeviceName": None,
1234
+ "FootprintName": None, "pinClass": {}, "differentialPairClass": {},
1235
+ "Symbols": "[]"},
1236
+ "zIndex": 4, "yAxisDirection": "up"
1237
+ }
1238
+ }
1239
+
1240
+ # ATTR: one key-value pair per record, parentId points back at the component
1241
+ def attr(cid, key, value, x=None, y=None, z=0):
1242
+ return {"type": "ATTR", "ticket": tk, "id": new_id(), "body": {
1243
+ "x": x, "y": y, "rotation": 0, "color": None, "fontFamily": None,
1244
+ "fontSize": None, "fontWeight": None, "italic": None, "underline": None,
1245
+ "align": None, "value": value, "keyVisible": None, "valueVisible": None,
1246
+ "key": key, "fillColor": None, "parentId": cid, "zIndex": z,
1247
+ "yAxisDirection": "up"}}
1248
+
1249
+ attrs = [
1250
+ attr(cid, "Symbol", "c828663d1111a8cf"), # -> SYMBOL document uuid
1251
+ attr(cid, "Device", "e16440afb3ce936d"), # -> DEVICE document uuid
1252
+ attr(cid, "Designator", "R1", x=410, y=610, z=2),
1253
+ attr(cid, "Name", "={Value}", x=410, y=600, z=30),
1254
+ attr(cid, "Manufacturer", "UNI-ROYAL"),
1255
+ attr(cid, "Manufacturer Part", "0603WAF1001T5E"),
1256
+ attr(cid, "Supplier", "LCSC"),
1257
+ attr(cid, "Supplier Part", "C21190"),
1258
+ attr(cid, "Value", "1kΩ"),
1259
+ # remaining attributes omitted
1260
+ ]
1261
+
1262
+ # WIRE (wire group) + LINE (single segment)
1263
+ wire = {"type": "WIRE", "ticket": tk, "id": wid, "body": {"zIndex": 10}}
1264
+ line = {"type": "LINE", "ticket": tk, "id": new_id(), "body": {
1265
+ "fillColor": None, "fillStyle": None, "strokeColor": None, "strokeStyle": None,
1266
+ "strokeWidth": None, "startX": 400, "startY": 630, "endX": 400, "endY": 660,
1267
+ "lineGroup": wid, "yAxisDirection": "up"}}
1268
+ ```
1269
+
1270
+ Three rules apply when writing:
1271
+
1272
+ 1. `partId` must be the id of the `PART` row in the `SYMBOL` document it references (of the form `0603WAF1001T5E.1`);
1273
+ 2. `id` is a random 16-character lowercase hexadecimal string, unique within the document;
1274
+ 3. `ticket` is unique within the document, and a component's `ticket` must be smaller than the `ticket` of its own attributes.
1275
+
1276
+ #### 4. Validating Reference Integrity
1277
+
1278
+ Run a static validation before writing to disk:
1279
+
1280
+ ```python
1281
+ # every COMPONENT partId must exist as a PART row in some SYMBOL document
1282
+ part_ids = {rec.id for doc in docs if doc.docType == 'SYMBOL'
1283
+ for rec in doc.recs if rec.type == 'PART'}
1284
+ doc_uuids = {d.uuid for d in docs}
1285
+
1286
+ for c in components:
1287
+ assert c.partId in part_ids or c.partId.startswith('pid'), c
1288
+ a = attrs_of(c)
1289
+ assert a['Symbol'] in doc_uuids
1290
+ assert a['Device'] in doc_uuids
1291
+
1292
+ # wires: every segment must be orthogonal and lineGroup must point at an existing WIRE
1293
+ for l in lines:
1294
+ assert l.startX == l.endX or l.startY == l.endY
1295
+ assert l.lineGroup in wire_ids
1296
+ ```
1297
+
1298
+ #### 5. Writing and Re-verifying
1299
+
1300
+ After writing the file into the project directory, wait for the editor to reload, then verify:
1301
+
1302
+ ```shell
1303
+ cp build/P1.esch2 "C:\Users\username\Documents\EasyEDA-Pro\projects\MyBoard\sch\Schematic1\P1.esch2"
1304
+ ```
1305
+
1306
+ ```javascript
1307
+ // Verification script: object counts + DRC + screenshot
1308
+ const comps = (await eda.sch_PrimitiveComponent.getAll()).map((c) => c.getState_Designator() || c.getState_ComponentType());
1309
+ const wires = await eda.sch_PrimitiveWire.getAllPrimitiveId();
1310
+ const drc = await eda.sch_Drc.check(true, false, false);
1311
+ await eda.sch_ManufactureData.getPngFile('check', { width: 1400 }); // also export an image
1312
+ return { comps, wireCount: wires.length, drcPassed: drc };
1313
+ ```
1314
+
1315
+ ```json
1316
+ {
1317
+ "ok": true,
1318
+ "value": {
1319
+ "comps": ["sheet", "netflag", "netflag", "R2", "R3", "C1", "R1"],
1320
+ "wireCount": 3,
1321
+ "drcPassed": true
1322
+ }
1323
+ }
1324
+ ```
1325
+
1326
+ The write is only considered complete when the object counts match expectations, the DRC passes, and the screenshot looks correct.
1327
+
1328
+ ::: tip
1329
+
1330
+ Always re-verify the object counts after writing a file by hand. If the count does not match, write the file again; the editor reloads it completely.
1331
+
1332
+ :::
1333
+
1334
+ ### VI. Writing PCB Files
1335
+
1336
+ Compared with `.esch2`, `.epcb2` adds one layer: the pad-to-net mapping. Its structure is as follows:
1337
+
1338
+ ```
1339
+ SYMBOL × N ← device symbols (for rendering)
1340
+ FOOTPRINT × N ← footprints (pads are defined here)
1341
+ DEVICE × N ← devices
1342
+ PCB ← the board document
1343
+ ├─ board template records: LAYER(60) / LAYER_PHYS / RULE / PREFERENCE / PRIMITIVE / PANELIZE / D3_ATTRIBUTE ...
1344
+ └─ business records: NET / COMPONENT / ATTR / PAD_NET / POLY (board outline) / LINE (trace)
1345
+ ```
1346
+
1347
+ Business records are written like this:
1348
+
1349
+ ```python
1350
+ # NET: one record per net
1351
+ {"type": "NET", "id": '["NET","VCC"]', "body": {"netType": None, "specialColor": None,
1352
+ "retLine": True, "differentialName": None, "isPositiveNet": False, "equalLengthGroupName": None}}
1353
+
1354
+ # COMPONENT: component instance (angles follow the PCB convention)
1355
+ {"type": "COMPONENT", "id": cid, "body": {
1356
+ "partitionId": "", "groupId": 0, "layerId": 1, # layerId 1 = top layer
1357
+ "x": 307.15, "y": -222.71, "angle": 270,
1358
+ "attrs": {"Reuse Block": "", "Group ID": "", "Channel ID": "$1I5", "Unique ID": "gge1",
1359
+ "DeviceName": '{"name":"0603WAF1001T5E","source":"","uuid":"<DEVICE uuid>"}'},
1360
+ "locked": False, "zIndex": -1, "pinSwap": False,
1361
+ "pinSwapInfo": {cid + "e7": {"pinClass": "", "differentialPairClass": ""},
1362
+ cid + "e8": {"pinClass": "", "differentialPairClass": ""}},
1363
+ "footprintPrimitives": True}}
1364
+
1365
+ # ATTR: composite id = component id + local id
1366
+ {"type": "ATTR", "id": cid + "e15", "body": {"parentId": cid, "layerId": 3, "key": "Footprint",
1367
+ "value": "<FOOTPRINT uuid>"}}
1368
+ {"type": "ATTR", "id": cid + "e16", "body": {"parentId": cid, "layerId": 3, "key": "Designator",
1369
+ "value": "R1", "x": 341.16, "y": -165.18, "angle": 270}}
1370
+
1371
+ # PAD_NET: pad-to-net mapping (the id is an array literal)
1372
+ {"type": "PAD_NET", "id": '["PAD_NET","<cid>","2","e7"]',
1373
+ "body": {"partitionId": "", "padNet": "VCC", "padLen": None, "propagationDelay": None, "attrsMap": {}}}
1374
+
1375
+ # POLY: board outline (layerId = 11 = BOARD_OUTLINE)
1376
+ {"type": "POLY", "id": pid, "body": {"partitionId": "", "groupId": 0, "netName": "",
1377
+ "layerId": 11, "width": 10, "path": [40, -340, "L", 400, -340, 400, -120, 40, -120, 40, -340],
1378
+ "locked": False, "zIndex": -1, "polyType": "NORMAL"}}
1379
+
1380
+ # LINE: trace
1381
+ {"type": "LINE", "id": lid, "body": {"partitionId": "", "groupId": 0, "netName": "VCC",
1382
+ "layerId": 1, "startX": 307.15, "startY": -193.05, "endX": 339.49, "endY": -225.39,
1383
+ "width": 10, "locked": False, "zIndex": -1}}
1384
+ ```
1385
+
1386
+ The relationships between the various ids are as follows:
1387
+
1388
+ - The `PAD_NET` id is `["PAD_NET", <component id>, <pad number>, <pad local id>]`, where the last field must match the id of the corresponding `PAD` row in the `FOOTPRINT` document;
1389
+ - A `pinSwapInfo` key is `<component id><pad local id>`;
1390
+ - An `ATTR` id is `<component id><local id>`, where the local id reuses the editor's naming such as `e0` `e15` `e16`;
1391
+ - The board outline `POLY` uses `layerId: 11`.
1392
+
1393
+ Recommendations for writing PCB files:
1394
+
1395
+ 1. Reuse board template records (`LAYER` `RULE` `PREFERENCE` `PRIMITIVE`, ...) exactly as the editor generates them; do not write them by hand;
1396
+ 2. Collect library documents (`SYMBOL` `FOOTPRINT` `DEVICE`) from an editor export;
1397
+ 3. Write business records (`NET` `COMPONENT` `ATTR` `PAD_NET` `POLY` `LINE`) by hand, and validate reference integrity;
1398
+ 4. After writing, verify the component count, the trace count, [`PCB_Net.getAllNetsName()`](../reference/pro-api.pcb_net.getallnetsname), the PCB DRC, and a rendered screenshot.
1399
+
1400
+ Besides geometric rules, [`PCB_Drc.check()`](../reference/pro-api.pcb_drc.check) also compares the schematic netlist with the PCB netlist. As long as the components and pad nets on the PCB match the schematic, the comparison passes.
1401
+
1402
+ ### VII. Practical Recommendations
1403
+
1404
+ 1. Create the project skeleton through the API (`createProject()` + `openProject()`) to avoid writing the index file by hand;
1405
+ 2. Collect library documents from an editor export, and write business records by hand;
1406
+ 3. Read the relevant types field by field with `doc format` before writing the file;
1407
+ 4. Follow the three writing rules: `partId` points at the `PART` row, `id` is random 16-character hexadecimal, `ticket` is unique within the document;
1408
+ 5. Terminate lines with `|` plus `LF`, and separate the shell from the payload with `||`;
1409
+ 6. Run static validation first (reference integrity, orthogonality, id and ticket uniqueness), then write to disk;
1410
+ 7. Wait 10 to 15 seconds after writing, then verify object counts, DRC, and the screenshot. If the count does not match, write the file again;
1411
+ 8. The two-way sync of `.eprj3` is immediate: once the editor saves, the disk files are updated at once, and they can be read back as the reference answer for a diff.
1412
+
1413
+ ## Comparison of the Two Approaches
1414
+
1415
+ | | Operating through the extension API | Writing `.eprj3` files directly |
1416
+ | --- | --- | --- |
1417
+ | Learning curve | Low | Medium (the format reference must be read first) |
1418
+ | Best suited for | Interactive operation, validation, exports, automated testing | Bulk project generation, code review, Git management, and AI generating projects directly |
1419
+ | Library documents | Built into the editor, searchable directly | Must be collected from an export |
1420
+ | Version control | Binary / SQLite formats are unfriendly | Plain text, easy to diff |
1421
+
1422
+ The two approaches can be mixed. The recommended flow:
1423
+
1424
+ ```text
1425
+ create project (API) → collect library documents (API + read disk) → generate business records (script / program) → write to disk
1426
+ ↓ ↓
1427
+ verify (API: DRC / netlist / BOM / screenshot) ←───────────────────────────────────────────────── wait for reload
1428
+ ```
1429
+
1430
+ ## Cheat Sheet
1431
+
1432
+ ### Commands
1433
+
1434
+ | Purpose | Command |
1435
+ | --- | --- |
1436
+ | Overview | `easyeda-pro --help` |
1437
+ | Fuzzy search commands | `easyeda-pro --search <keyword>` |
1438
+ | Usage of a command | `easyeda-pro <command> --help` |
1439
+ | Probe the endpoint | `easyeda-pro doctor` |
1440
+ | Open a window | `easyeda-pro open [--path <project>] [--headless <bool>]` |
1441
+ | List sessions | `easyeda-pro session list` |
1442
+ | Close a session | `easyeda-pro session close --session <id> --destroy` |
1443
+ | List classes | `easyeda-pro doc api` |
1444
+ | List methods | `easyeda-pro doc api --class-name <class>` |
1445
+ | Read a method | `easyeda-pro doc api --class-name <class> --method-name <method>` |
1446
+ | Inspect an enum | `easyeda-pro doc api --class-name <EEnum>` |
1447
+ | Inspect a format | `easyeda-pro doc format [--class-name <type>]` |
1448
+ | Execute JS | `easyeda-pro invoke --session <id> --ext-uuid eda --code "…" [--args '<json>'] [--timeout <ms>]` |
1449
+ | Run as MCP | `easyeda-pro --mcp stdio` / `--mcp http --port 3030` |
1450
+
1451
+ ### Frequently Used APIs
1452
+
1453
+ | Domain | Class | Frequently used methods |
1454
+ | --- | --- | --- |
1455
+ | Project | [DMT_Project](../reference/pro-api.dmt_project) | `createProject` `openProject` `getCurrentProjectInfo` |
1456
+ | Board / drawing | [DMT_Board](../reference/pro-api.dmt_board) [DMT_Schematic](../reference/pro-api.dmt_schematic) [DMT_Pcb](../reference/pro-api.dmt_pcb) | `createBoard` `createSchematic` `getAllBoardsInfo` |
1457
+ | Editor | [DMT_EditorControl](../reference/pro-api.dmt_editorcontrol) | `openDocument` `zoomToAllPrimitives` `getCurrentRenderedAreaImage` |
1458
+ | Device library | [LIB_LibrariesList](../reference/pro-api.lib_librarieslist) [LIB_Device](../reference/pro-api.lib_device) | `getSystemLibraryUuid` `search` |
1459
+ | Schematic primitives | [SCH_PrimitiveComponent](../reference/pro-api.sch_primitivecomponent) | `create` `createNetFlag` `modify` `getAllPinsByPrimitiveId` |
1460
+ | | [SCH_PrimitiveWire](../reference/pro-api.sch_primitivewire) | `create` `getAll` |
1461
+ | Schematic checks | [SCH_Drc](../reference/pro-api.sch_drc) [SCH_Netlist](../reference/pro-api.sch_netlist) [SCH_ManufactureData](../reference/pro-api.sch_manufacturedata) | `check` `getNetlistFile` `getBomFile` `getPngFile` |
1462
+ | Schematic documents | [SCH_Document](../reference/pro-api.sch_document) | `save` `getPrimitiveAtPoint` `getPrimitivesInRegion` |
1463
+ | PCB primitives | [PCB_PrimitiveComponent](../reference/pro-api.pcb_primitivecomponent) [PCB_PrimitiveLine](../reference/pro-api.pcb_primitiveline) [PCB_PrimitivePolyline](../reference/pro-api.pcb_primitivepolyline) | `create` and others |
1464
+ | PCB documents | [PCB_Document](../reference/pro-api.pcb_document) | `save` `importChanges` `autoLayout` `autoRouting` `zoomToBoardOutline` |
1465
+ | PCB checks / exports | [PCB_Drc](../reference/pro-api.pcb_drc) [PCB_ManufactureData](../reference/pro-api.pcb_manufacturedata) [PCB_Net](../reference/pro-api.pcb_net) | `check` `getGerberFile` `get3DFile` `getAllNetsName` |
1466
+ | Files | [SYS_FileSystem](../reference/pro-api.sys_filesystem) | `saveFileToFileSystem` `readFileFromFileSystem` `listFilesOfFileSystem` |
1467
+ | Environment | [SYS_Environment](../reference/pro-api.sys_environment) | `isClient` `getEditorCurrentVersion` `getUserInfo` |
1468
+
1469
+ ### Coordinate Systems and Units
1470
+
1471
+ | Domain | Convention |
1472
+ | --- | --- |
1473
+ | Schematic | Unit is 10mil; the origin is at the bottom-left corner of the sheet with Y pointing up; A4 is 1170 × 825 |
1474
+ | PCB | Unit is mil; `layerId` `1` is the top layer and `11` is the board outline layer |
1475
+ | Angles | The API uses counter-clockwise as positive; in schematic files `COMPONENT.rotation` is `(360 - API angle) % 360`, while on the PCB side `COMPONENT.angle` follows the API angle |
1476
+
1477
+ ## Full Script Example
1478
+
1479
+ The script below chains the procedure above into a complete, runnable example:
1480
+
1481
+ ```bash
1482
+ #!/usr/bin/env bash
1483
+ set -e
1484
+ L="easyeda-pro"
1485
+
1486
+ # 1. Create a session
1487
+ S=$($L open | python -c "import sys,json;print(json.load(sys.stdin)['value']['sessionId'])")
1488
+ echo "session = $S"
1489
+
1490
+ # 2. Create a project
1491
+ $L invoke --session $S --ext-uuid eda --code "$(cat step1_create_proj.js)"
1492
+
1493
+ # 3. Place components, net flags, and wires
1494
+ $L invoke --session $S --ext-uuid eda --code "$(cat step3_place.js)"
1495
+ $L invoke --session $S --ext-uuid eda --code "$(cat step4_flags.js)"
1496
+ $L invoke --session $S --ext-uuid eda --code "$(cat step5_wire.js)"
1497
+
1498
+ # 4. Save, wait for the refresh, run the DRC
1499
+ $L invoke --session $S --ext-uuid eda --code "await eda.sch_Document.save(); return true;"
1500
+ sleep 10
1501
+ $L invoke --session $S --ext-uuid eda --code "$(cat step6_drc.js)"
1502
+
1503
+ # 5. Export the netlist, the BOM, and a screenshot
1504
+ $L invoke --session $S --ext-uuid eda --code "$(cat step7_netlist.js)"
1505
+ $L invoke --session $S --ext-uuid eda --code "$(cat step8_bom.js)"
1506
+ $L invoke --session $S --ext-uuid eda --code "$(cat step9_shot.js)"
1507
+
1508
+ # 6. Close the session
1509
+ $L session close --session $S --destroy
1510
+ ```