@windypro-rourou/dsh-eda 0.1.3 → 0.1.5
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.
- package/README.md +3 -1
- package/lib/capabilities.js +3 -2
- package/lib/client.js +576 -452
- package/lib/index.js +89 -2
- package/package.json +10 -1
- package/skill/INDEX.md +10 -8
- package/skill/README.md +125 -0
- package/skill/README.zh-Hans.md +125 -0
- package/skill/SKILL.md +746 -746
- package/skill/format/index.md +152 -152
- package/skill/format/pcb/3d.md +166 -166
- package/skill/format/pcb/attr.md +63 -63
- package/skill/format/pcb/common.md +306 -306
- package/skill/format/pcb/component.md +132 -132
- package/skill/format/pcb/dimension.md +58 -58
- package/skill/format/pcb/index.md +17 -17
- package/skill/format/pcb/obj.md +43 -43
- package/skill/format/pcb/pad_via.md +151 -151
- package/skill/format/pcb/panel.md +64 -64
- package/skill/format/pcb/partition.md +43 -43
- package/skill/format/pcb/primitive.md +196 -196
- package/skill/format/pcb/rule.md +71 -71
- package/skill/format/pcb/shape.md +441 -441
- package/skill/format/pcb/text.md +62 -62
- package/skill/format/project/blob.md +30 -30
- package/skill/format/project/common.md +42 -42
- package/skill/format/project/group.md +62 -62
- package/skill/format/project/index.md +12 -12
- package/skill/format/project/instance.md +32 -32
- package/skill/format/project/meta.md +189 -189
- package/skill/format/project/variant.md +30 -30
- package/skill/format/schematic/attr.md +41 -41
- package/skill/format/schematic/common.md +47 -47
- package/skill/format/schematic/component.md +91 -91
- package/skill/format/schematic/index.md +14 -14
- package/skill/format/schematic/obj.md +41 -41
- package/skill/format/schematic/pin.md +59 -59
- package/skill/format/schematic/shape.md +231 -231
- package/skill/format/schematic/structure.md +53 -53
- package/skill/format/schematic/table.md +109 -109
- package/skill/format/schematic/text.md +47 -47
- package/skill/format/schematic/wire.md +132 -132
- package/skill/guide/ancillary-projects/easyeda-api-sdk.md +1 -0
- package/skill/guide/ancillary-projects/pro-api-types.md +5 -5
- package/skill/guide/ancillary-projects.md +10 -10
- package/skill/guide/cli.md +1510 -0
- package/skill/guide/error-handling.md +38 -38
- package/skill/guide/extension-json.md +135 -135
- package/skill/guide/extensions-marketplace.md +61 -61
- package/skill/guide/how-to-start.md +316 -301
- package/skill/guide/i18n.md +57 -57
- package/skill/guide/index.md +7 -7
- package/skill/guide/inline-frame.md +20 -20
- package/skill/guide/invoke-apis.md +81 -81
- package/skill/guide/stability.md +37 -37
- package/skill/references/_index.md +471 -398
- package/skill/references/_quick-reference.md +3103 -3028
- package/skill/references/classes/DMT_Board.md +537 -533
- package/skill/references/classes/DMT_EditorControl.md +1736 -1736
- package/skill/references/classes/DMT_Event.md +356 -356
- package/skill/references/classes/DMT_Folder.md +775 -775
- package/skill/references/classes/DMT_Panel.md +531 -531
- package/skill/references/classes/DMT_Pcb.md +579 -575
- package/skill/references/classes/DMT_Project.md +734 -573
- package/skill/references/classes/DMT_Schematic.md +1482 -1477
- package/skill/references/classes/DMT_SelectControl.md +96 -96
- package/skill/references/classes/DMT_Team.md +172 -172
- package/skill/references/classes/DMT_Workspace.md +198 -198
- package/skill/references/classes/EDA.md +1001 -961
- package/skill/references/classes/IPCB_ComplexPolygon.md +299 -299
- package/skill/references/classes/IPCB_Polygon.md +175 -175
- package/skill/references/classes/IPCB_PrimitiveArc.md +1901 -1901
- package/skill/references/classes/IPCB_PrimitiveAttribute.md +2993 -2993
- package/skill/references/classes/IPCB_PrimitiveComponent.md +2624 -2627
- package/skill/references/classes/IPCB_PrimitiveComponentPad.md +410 -410
- package/skill/references/classes/IPCB_PrimitiveDimension.md +1419 -1419
- package/skill/references/classes/IPCB_PrimitiveFill.md +1325 -1325
- package/skill/references/classes/IPCB_PrimitiveImage.md +1461 -1461
- package/skill/references/classes/IPCB_PrimitiveLine.md +1639 -1639
- package/skill/references/classes/IPCB_PrimitiveObject.md +1700 -1700
- package/skill/references/classes/IPCB_PrimitivePad.md +3155 -3155
- package/skill/references/classes/IPCB_PrimitivePolyline.md +1193 -1193
- package/skill/references/classes/IPCB_PrimitivePour.md +1858 -1858
- package/skill/references/classes/IPCB_PrimitivePoured.md +556 -556
- package/skill/references/classes/IPCB_PrimitiveRegion.md +1332 -1332
- package/skill/references/classes/IPCB_PrimitiveString.md +2315 -2315
- package/skill/references/classes/IPCB_PrimitiveVia.md +1588 -1588
- package/skill/references/classes/ISCH_PrimitiveArc.md +1676 -1676
- package/skill/references/classes/ISCH_PrimitiveAttribute.md +2541 -2541
- package/skill/references/classes/ISCH_PrimitiveBus.md +973 -973
- package/skill/references/classes/ISCH_PrimitiveCbbSymbolComponent.md +260 -260
- package/skill/references/classes/ISCH_PrimitiveCircle.md +1392 -1392
- package/skill/references/classes/ISCH_PrimitiveComponent.md +2910 -2913
- package/skill/references/classes/ISCH_PrimitiveComponentPin.md +155 -155
- package/skill/references/classes/ISCH_PrimitiveObject.md +960 -960
- package/skill/references/classes/ISCH_PrimitivePin.md +2402 -2402
- package/skill/references/classes/ISCH_PrimitivePolygon.md +1028 -1028
- package/skill/references/classes/ISCH_PrimitiveRectangle.md +1777 -1777
- package/skill/references/classes/ISCH_PrimitiveText.md +1771 -1771
- package/skill/references/classes/ISCH_PrimitiveWire.md +973 -973
- package/skill/references/classes/LIB_3DModel.md +782 -780
- package/skill/references/classes/LIB_Cbb.md +957 -957
- package/skill/references/classes/LIB_Classification.md +969 -965
- package/skill/references/classes/LIB_Device.md +1222 -1221
- package/skill/references/classes/LIB_Footprint.md +1298 -1153
- package/skill/references/classes/LIB_LibrariesList.md +361 -329
- package/skill/references/classes/LIB_PanelLibrary.md +855 -855
- package/skill/references/classes/LIB_SelectControl.md +89 -89
- package/skill/references/classes/LIB_SimulationModel.md +807 -821
- package/skill/references/classes/LIB_Symbol.md +1341 -1195
- package/skill/references/classes/PCB_Document.md +1770 -1754
- package/skill/references/classes/PCB_Drc.md +3379 -3375
- package/skill/references/classes/PCB_Event.md +1166 -1081
- package/skill/references/classes/PCB_ImageTool.md +363 -0
- package/skill/references/classes/PCB_Layer.md +1915 -1911
- package/skill/references/classes/PCB_ManufactureData.md +2968 -2968
- package/skill/references/classes/PCB_MathPolygon.md +916 -785
- package/skill/references/classes/PCB_Net.md +1128 -1128
- package/skill/references/classes/PCB_Primitive.md +217 -217
- package/skill/references/classes/PCB_PrimitiveArc.md +820 -894
- package/skill/references/classes/PCB_PrimitiveAttribute.md +635 -717
- package/skill/references/classes/PCB_PrimitiveComponent.md +1050 -1050
- package/skill/references/classes/PCB_PrimitiveDimension.md +789 -833
- package/skill/references/classes/PCB_PrimitiveFill.md +783 -861
- package/skill/references/classes/PCB_PrimitiveImage.md +803 -875
- package/skill/references/classes/PCB_PrimitiveLine.md +787 -858
- package/skill/references/classes/PCB_PrimitiveObject.md +796 -800
- package/skill/references/classes/PCB_PrimitivePad.md +947 -944
- package/skill/references/classes/PCB_PrimitivePolyline.md +744 -819
- package/skill/references/classes/PCB_PrimitivePour.md +808 -845
- package/skill/references/classes/PCB_PrimitivePoured.md +363 -363
- package/skill/references/classes/PCB_PrimitiveRegion.md +765 -799
- package/skill/references/classes/PCB_PrimitiveString.md +828 -910
- package/skill/references/classes/PCB_PrimitiveVia.md +761 -765
- package/skill/references/classes/PCB_RayTracerEngine.md +603 -263
- package/skill/references/classes/PCB_SelectControl.md +495 -495
- package/skill/references/classes/PCB_Tool.md +9 -0
- package/skill/references/classes/PNL_Document.md +83 -83
- package/skill/references/classes/SCH_Document.md +797 -809
- package/skill/references/classes/SCH_Drc.md +246 -242
- package/skill/references/classes/SCH_Event.md +583 -583
- package/skill/references/classes/SCH_ManufactureData.md +1209 -1205
- package/skill/references/classes/SCH_Net.md +200 -200
- package/skill/references/classes/SCH_Netlist.md +191 -191
- package/skill/references/classes/SCH_Primitive.md +337 -337
- package/skill/references/classes/SCH_PrimitiveArc.md +686 -692
- package/skill/references/classes/SCH_PrimitiveAttribute.md +579 -590
- package/skill/references/classes/SCH_PrimitiveBus.md +618 -624
- package/skill/references/classes/SCH_PrimitiveCircle.md +667 -683
- package/skill/references/classes/SCH_PrimitiveComponent.md +2256 -2240
- package/skill/references/classes/SCH_PrimitiveObject.md +666 -666
- package/skill/references/classes/SCH_PrimitivePin.md +737 -754
- package/skill/references/classes/SCH_PrimitivePolygon.md +621 -627
- package/skill/references/classes/SCH_PrimitiveRectangle.md +715 -731
- package/skill/references/classes/SCH_PrimitiveText.md +736 -746
- package/skill/references/classes/SCH_PrimitiveWire.md +701 -703
- package/skill/references/classes/SCH_SelectControl.md +520 -520
- package/skill/references/classes/SCH_SimulationEngine.md +133 -133
- package/skill/references/classes/SCH_Utils.md +121 -121
- package/skill/references/classes/SYS_ClientUrl.md +173 -173
- package/skill/references/classes/SYS_Dialog.md +825 -825
- package/skill/references/classes/SYS_Environment.md +640 -502
- package/skill/references/classes/SYS_ExternalApi.md +246 -0
- package/skill/references/classes/SYS_FileManager.md +1664 -1686
- package/skill/references/classes/SYS_FileSystem.md +1366 -1171
- package/skill/references/classes/SYS_FontManager.md +224 -224
- package/skill/references/classes/SYS_FormatConversion.md +349 -349
- package/skill/references/classes/SYS_HeaderMenu.md +480 -479
- package/skill/references/classes/SYS_Help.md +141 -0
- package/skill/references/classes/SYS_I18n.md +861 -861
- package/skill/references/classes/SYS_IFrame.md +541 -535
- package/skill/references/classes/SYS_LoadingAndProgressBar.md +246 -246
- package/skill/references/classes/SYS_Log.md +422 -424
- package/skill/references/classes/SYS_Math.md +1565 -1565
- package/skill/references/classes/SYS_Message.md +363 -363
- package/skill/references/classes/SYS_MessageBox.md +285 -285
- package/skill/references/classes/SYS_MessageBus.md +1618 -1618
- package/skill/references/classes/SYS_PanelControl.md +696 -696
- package/skill/references/classes/SYS_RightClickMenu.md +175 -175
- package/skill/references/classes/SYS_Setting.md +134 -85
- package/skill/references/classes/SYS_ShortcutKey.md +623 -623
- package/skill/references/classes/SYS_Storage.md +484 -484
- package/skill/references/classes/SYS_Timer.md +447 -447
- package/skill/references/classes/SYS_ToastMessage.md +194 -194
- package/skill/references/classes/SYS_Tool.md +317 -241
- package/skill/references/classes/SYS_Unit.md +594 -594
- package/skill/references/classes/SYS_WebSocket.md +401 -401
- package/skill/references/classes/SYS_Window.md +849 -850
- package/skill/references/enums/EDMT_EditorDocumentType.md +324 -278
- package/skill/references/enums/EDMT_EditorSplitScreenDirection.md +51 -47
- package/skill/references/enums/EDMT_EditorTabEventType.md +68 -62
- package/skill/references/enums/EDMT_IndicatorMarkerType.md +90 -80
- package/skill/references/enums/EDMT_ItemType.md +181 -157
- package/skill/references/enums/EDMT_ProjectCollaborationMode.md +51 -47
- package/skill/references/enums/EDMT_ProjectFileFormat.md +60 -0
- package/skill/references/enums/EDMT_ProjectReadyState.md +82 -0
- package/skill/references/enums/ELIB_DeviceJlcLibraryCategory.md +51 -47
- package/skill/references/enums/ELIB_LibraryType.md +129 -113
- package/skill/references/enums/ELIB_PreviewType.md +77 -69
- package/skill/references/enums/ELIB_SimulationModelType.md +51 -47
- package/skill/references/enums/ELIB_SymbolType.md +142 -124
- package/skill/references/enums/EPCB_AutoRoutingCornerStyle.md +51 -47
- package/skill/references/enums/EPCB_AutoRoutingExistingPrimitiveMode.md +51 -47
- package/skill/references/enums/EPCB_AutoRoutingOptimization.md +51 -47
- package/skill/references/enums/EPCB_DocumentCanvasUpdateCalculationActiveStatus.md +51 -47
- package/skill/references/enums/EPCB_DocumentRatlineCalculatingActiveStatus.md +55 -51
- package/skill/references/enums/EPCB_InactiveLayerDisplayMode.md +64 -58
- package/skill/references/enums/EPCB_LayerColorConfiguration.md +90 -80
- package/skill/references/enums/EPCB_LayerId.md +1169 -881
- package/skill/references/enums/EPCB_LayerStatus.md +64 -58
- package/skill/references/enums/EPCB_LayerType.md +129 -113
- package/skill/references/enums/EPCB_MouseEventType.md +64 -58
- package/skill/references/enums/EPCB_NetEventType.md +64 -58
- package/skill/references/enums/EPCB_PcbPlateType.md +51 -47
- package/skill/references/enums/EPCB_PdfOutputMethod.md +64 -58
- package/skill/references/enums/EPCB_PrimitiveArcInteractiveMode.md +51 -47
- package/skill/references/enums/EPCB_PrimitiveDimensionType.md +64 -58
- package/skill/references/enums/EPCB_PrimitiveEventType.md +64 -58
- package/skill/references/enums/EPCB_PrimitiveFillMode.md +68 -62
- package/skill/references/enums/EPCB_PrimitivePadHeatWeldingConnectionMethod.md +64 -58
- package/skill/references/enums/EPCB_PrimitivePadHoleType.md +64 -58
- package/skill/references/enums/EPCB_PrimitivePadShapeType.md +90 -80
- package/skill/references/enums/EPCB_PrimitivePadType.md +64 -58
- package/skill/references/enums/EPCB_PrimitivePourFillMethod.md +64 -58
- package/skill/references/enums/EPCB_PrimitiveRegionRuleType.md +107 -95
- package/skill/references/enums/EPCB_PrimitiveStringAlignMode.md +142 -124
- package/skill/references/enums/EPCB_PrimitiveType.md +233 -201
- package/skill/references/enums/EPCB_PrimitiveViaType.md +64 -58
- package/skill/references/enums/ESCH_DynamicSimulationEnginePullEventType.md +116 -102
- package/skill/references/enums/ESCH_DynamicSimulationEnginePushEventType.md +90 -80
- package/skill/references/enums/ESCH_ExportDocumentFileType.md +64 -58
- package/skill/references/enums/ESCH_MouseEventType.md +51 -47
- package/skill/references/enums/ESCH_PrimitiveComponentType.md +142 -124
- package/skill/references/enums/ESCH_PrimitiveEventType.md +77 -69
- package/skill/references/enums/ESCH_PrimitiveFillStyle.md +129 -113
- package/skill/references/enums/ESCH_PrimitiveLineType.md +77 -69
- package/skill/references/enums/ESCH_PrimitivePinShape.md +77 -69
- package/skill/references/enums/ESCH_PrimitivePinType.md +168 -146
- package/skill/references/enums/ESCH_PrimitiveTextAlignMode.md +142 -124
- package/skill/references/enums/ESCH_PrimitiveType.md +207 -179
- package/skill/references/enums/ESCH_SimulationNetlistType.md +38 -36
- package/skill/references/enums/ESCH_SpiceSimulationEnginePullEventType.md +51 -47
- package/skill/references/enums/ESCH_SpiceSimulationEnginePushEventType.md +77 -69
- package/skill/references/enums/ESYS_BottomPanelTab.md +94 -80
- package/skill/references/enums/ESYS_HeaderMenuEnvironment.md +181 -157
- package/skill/references/enums/ESYS_ImportProjectBoardOutlineSource.md +55 -51
- package/skill/references/enums/ESYS_ImportProjectImportOption.md +64 -58
- package/skill/references/enums/ESYS_ImportProjectSchematicObjectStyle.md +51 -47
- package/skill/references/enums/ESYS_ImportProjectViaSolderMaskExpansion.md +55 -51
- package/skill/references/enums/ESYS_JobState.md +95 -0
- package/skill/references/enums/ESYS_LeftPanelTab.md +94 -80
- package/skill/references/enums/ESYS_LogType.md +77 -102
- package/skill/references/enums/ESYS_NetlistType.md +129 -113
- package/skill/references/enums/ESYS_PanelPosition.md +69 -0
- package/skill/references/enums/ESYS_PanelTab.md +368 -0
- package/skill/references/enums/ESYS_RightPanelTab.md +237 -201
- package/skill/references/enums/ESYS_ShortcutKeyEffectiveEditorRange.md +220 -190
- package/skill/references/enums/ESYS_ShortcutKeyEffectiveEditorScene.md +103 -91
- package/skill/references/enums/ESYS_StartPageQuickStartItem.md +237 -205
- package/skill/references/enums/ESYS_Theme.md +51 -47
- package/skill/references/enums/ESYS_ToastMessageType.md +90 -80
- package/skill/references/enums/ESYS_Unit.md +116 -102
- package/skill/references/enums/ESYS_WindowEventType.md +64 -47
- package/skill/references/enums/ESYS_WindowOpenTarget.md +51 -47
- package/skill/references/enums/NetportDeviceName.md +146 -146
- package/skill/references/enums/SchToolBarDeviceName.md +278 -278
- package/skill/references/interfaces/BoardProps.md +169 -169
- package/skill/references/interfaces/BorderConfig.md +109 -0
- package/skill/references/interfaces/ButtonProps.md +196 -169
- package/skill/references/interfaces/CellClickInfo.md +142 -0
- package/skill/references/interfaces/CellCoord.md +88 -0
- package/skill/references/interfaces/CheckBoxProps.md +223 -196
- package/skill/references/interfaces/CheckChangeDetail.md +88 -0
- package/skill/references/interfaces/CheckboxEditConfig.md +159 -0
- package/skill/references/interfaces/ClipboardCellData.md +142 -0
- package/skill/references/interfaces/ClipboardConfig.md +115 -0
- package/skill/references/interfaces/ColorPickerProps.md +169 -0
- package/skill/references/interfaces/ColumnDef.md +605 -0
- package/skill/references/interfaces/ColumnEditTrigger.md +57 -0
- package/skill/references/interfaces/ColumnGroupDef.md +192 -0
- package/skill/references/interfaces/ColumnResizeConfig.md +142 -0
- package/skill/references/interfaces/ComponentPropsMap.md +517 -448
- package/skill/references/interfaces/CustomHeaderConfig.md +169 -0
- package/skill/references/interfaces/DialogProps.md +385 -385
- package/skill/references/interfaces/DragSortConfig.md +115 -0
- package/skill/references/interfaces/EditingConfig.md +196 -0
- package/skill/references/interfaces/FilteringConfig.md +250 -0
- package/skill/references/interfaces/FixedColumnConfig.md +88 -0
- package/skill/references/interfaces/FlexItemProps.md +116 -116
- package/skill/references/interfaces/FlexProps.md +224 -224
- package/skill/references/interfaces/GridItemProps.md +143 -143
- package/skill/references/interfaces/GridProps.md +143 -143
- package/skill/references/interfaces/IDMT_BoardItem.md +171 -171
- package/skill/references/interfaces/IDMT_BriefProjectItem.md +171 -171
- package/skill/references/interfaces/IDMT_EditorDocumentItem.md +169 -169
- package/skill/references/interfaces/IDMT_EditorSplitScreenItem.md +173 -173
- package/skill/references/interfaces/IDMT_EditorTabItem.md +169 -169
- package/skill/references/interfaces/IDMT_FolderItem.md +225 -225
- package/skill/references/interfaces/IDMT_IndicatorMarkerShape.md +393 -393
- package/skill/references/interfaces/IDMT_PanelItem.md +144 -144
- package/skill/references/interfaces/IDMT_PcbItem.md +171 -171
- package/skill/references/interfaces/IDMT_ProjectItem.md +143 -143
- package/skill/references/interfaces/IDMT_SchematicItem.md +225 -225
- package/skill/references/interfaces/IDMT_SchematicPageItem.md +198 -198
- package/skill/references/interfaces/IDMT_TeamItem.md +144 -144
- package/skill/references/interfaces/IDMT_WorkspaceItem.md +117 -117
- package/skill/references/interfaces/IDesignPortal.md +103 -103
- package/skill/references/interfaces/ILIB_3DModelItem.md +198 -198
- package/skill/references/interfaces/ILIB_3DModelSearchItem.md +277 -277
- package/skill/references/interfaces/ILIB_CbbItem.md +225 -225
- package/skill/references/interfaces/ILIB_CbbSearchItem.md +277 -277
- package/skill/references/interfaces/ILIB_ClassificationIndex.md +150 -150
- package/skill/references/interfaces/ILIB_ClassificationNode.md +98 -0
- package/skill/references/interfaces/ILIB_DeviceAssociationItem.md +210 -210
- package/skill/references/interfaces/ILIB_DeviceExtendPropertyItem.md +304 -304
- package/skill/references/interfaces/ILIB_DeviceItem.md +279 -279
- package/skill/references/interfaces/ILIB_DevicePropertiesForSearch.md +250 -250
- package/skill/references/interfaces/ILIB_DeviceSearchItem.md +521 -521
- package/skill/references/interfaces/ILIB_ExtendLibrary3DModelFunctions.md +64 -64
- package/skill/references/interfaces/ILIB_ExtendLibraryCbbFunctions.md +93 -99
- package/skill/references/interfaces/ILIB_ExtendLibraryClassificationIndex.md +150 -150
- package/skill/references/interfaces/ILIB_ExtendLibraryDeviceFunctions.md +143 -157
- package/skill/references/interfaces/ILIB_ExtendLibraryFootprintFunctions.md +63 -63
- package/skill/references/interfaces/ILIB_ExtendLibraryFunctions.md +123 -123
- package/skill/references/interfaces/ILIB_ExtendLibraryItem.md +97 -97
- package/skill/references/interfaces/ILIB_ExtendLibraryItemIndex.md +98 -98
- package/skill/references/interfaces/ILIB_ExtendLibrarySearchProperty.md +115 -115
- package/skill/references/interfaces/ILIB_ExtendLibrarySearchResult.md +169 -169
- package/skill/references/interfaces/ILIB_ExtendLibrarySearchResultDataLine.md +234 -234
- package/skill/references/interfaces/ILIB_ExtendLibrarySymbolFunctions.md +91 -105
- package/skill/references/interfaces/ILIB_ExtendLibraryUserIndex.md +96 -96
- package/skill/references/interfaces/ILIB_FootprintItem.md +256 -198
- package/skill/references/interfaces/ILIB_FootprintPropertiesForSearch.md +61 -61
- package/skill/references/interfaces/ILIB_FootprintSearchItem.md +277 -277
- package/skill/references/interfaces/ILIB_LibraryInfo.md +92 -92
- package/skill/references/interfaces/ILIB_LibraryItem.md +115 -115
- package/skill/references/interfaces/ILIB_PanelLibraryItem.md +198 -198
- package/skill/references/interfaces/ILIB_PanelLibrarySearchItem.md +277 -277
- package/skill/references/interfaces/ILIB_RegisterExtendLibraryProps.md +71 -0
- package/skill/references/interfaces/ILIB_SimulationModelItem.md +306 -306
- package/skill/references/interfaces/ILIB_SimulationModelSearchItem.md +304 -304
- package/skill/references/interfaces/ILIB_SymbolItem.md +306 -279
- package/skill/references/interfaces/ILIB_SymbolPropertiesForSearch.md +61 -61
- package/skill/references/interfaces/ILIB_SymbolSearchItem.md +304 -304
- package/skill/references/interfaces/IPCB_AutoLayoutResult.md +169 -169
- package/skill/references/interfaces/IPCB_AutoRoutingProps.md +220 -220
- package/skill/references/interfaces/IPCB_AutoRoutingResult.md +169 -169
- package/skill/references/interfaces/IPCB_BomPropertiesTableColumns.md +169 -169
- package/skill/references/interfaces/IPCB_DifferentialPairItem.md +115 -115
- package/skill/references/interfaces/IPCB_DiscretizeOptions.md +65 -65
- package/skill/references/interfaces/IPCB_DiscretizedPoint.md +88 -88
- package/skill/references/interfaces/IPCB_EqualLengthNetGroupItem.md +115 -115
- package/skill/references/interfaces/IPCB_LayerItem.md +277 -277
- package/skill/references/interfaces/IPCB_NetClassItem.md +115 -115
- package/skill/references/interfaces/IPCB_NetInfo.md +115 -115
- package/skill/references/interfaces/IPCB_PadPairGroupItem.md +88 -88
- package/skill/references/interfaces/IPCB_PadPairMinWireLengthItem.md +88 -88
- package/skill/references/interfaces/IPCB_PhysicalStackingConfiguration.md +115 -115
- package/skill/references/interfaces/IPCB_Primitive.md +218 -218
- package/skill/references/interfaces/IPCB_PrimitiveAPI.md +174 -175
- package/skill/references/interfaces/IPCB_PrimitivePadHeatWelding.md +151 -151
- package/skill/references/interfaces/IPCB_PrimitivePouredPourFill.md +142 -142
- package/skill/references/interfaces/IPCB_PrimitiveSolderMaskAndPasteMaskExpansion.md +154 -154
- package/skill/references/interfaces/IPCB_RayTracerBackgroundConfig.md +223 -0
- package/skill/references/interfaces/IPCB_RayTracerLightConfig.md +412 -0
- package/skill/references/interfaces/IPCB_RayTracerMaterialConfig.md +547 -0
- package/skill/references/interfaces/IPCB_RayTracerPcbMaterialConfig.md +196 -0
- package/skill/references/interfaces/IPCB_RayTracerRenderConfigurations.md +200 -0
- package/skill/references/interfaces/IPCB_RayTracerRendererConfig.md +196 -0
- package/skill/references/interfaces/IPCB_RayTracerSceneElement.md +115 -0
- package/skill/references/interfaces/IPCB_RayTracerSceneElementTransform.md +123 -0
- package/skill/references/interfaces/IPCB_RayTracerTexture.md +88 -0
- package/skill/references/interfaces/IPCB_SubstratePhysicalProperties.md +88 -88
- package/skill/references/interfaces/IRawNet.md +103 -103
- package/skill/references/interfaces/IRawPureSchematic.md +80 -80
- package/skill/references/interfaces/IRawSchematic.md +103 -103
- package/skill/references/interfaces/IRawWire.md +149 -149
- package/skill/references/interfaces/ISCH_DrcError.md +142 -142
- package/skill/references/interfaces/ISCH_DrcErrorPrimitive.md +142 -142
- package/skill/references/interfaces/ISCH_ExportPngResolution.md +94 -94
- package/skill/references/interfaces/ISCH_NetInfo.md +88 -88
- package/skill/references/interfaces/ISCH_Primitive.md +218 -219
- package/skill/references/interfaces/ISCH_PrimitiveAPI.md +174 -175
- package/skill/references/interfaces/ISCH_ProjectNetInfo.md +142 -142
- package/skill/references/interfaces/ISCH_WireInfo.md +169 -169
- package/skill/references/interfaces/ISYS_ComparisonResponse.md +115 -0
- package/skill/references/interfaces/ISYS_ExtensionExternalApiIndex.md +13 -0
- package/skill/references/interfaces/ISYS_ExtensionRegisteredExternalApis.md +13 -0
- package/skill/references/interfaces/ISYS_ExternalApiHelp.md +173 -0
- package/skill/references/interfaces/ISYS_ExternalApiRegistration.md +146 -0
- package/skill/references/interfaces/ISYS_FileSystemFileList.md +169 -169
- package/skill/references/interfaces/ISYS_HeaderMenuSub1MenuItem.md +205 -174
- package/skill/references/interfaces/ISYS_HeaderMenuSub2MenuItem.md +178 -147
- package/skill/references/interfaces/ISYS_HeaderMenuTopMenuItem.md +115 -115
- package/skill/references/interfaces/ISYS_HeaderMenus.md +408 -408
- package/skill/references/interfaces/ISYS_HelpAudienceEntry.md +92 -0
- package/skill/references/interfaces/ISYS_HelpClassSummary.md +205 -0
- package/skill/references/interfaces/ISYS_HelpData.md +92 -0
- package/skill/references/interfaces/ISYS_HelpMethodDetail.md +310 -0
- package/skill/references/interfaces/ISYS_JobHandle.md +65 -0
- package/skill/references/interfaces/ISYS_JobLogEntry.md +142 -0
- package/skill/references/interfaces/ISYS_JobStatus.md +176 -0
- package/skill/references/interfaces/ISYS_LogLine.md +115 -115
- package/skill/references/interfaces/ISYS_MathBBox.md +142 -142
- package/skill/references/interfaces/ISYS_MathPoint.md +88 -88
- package/skill/references/interfaces/ISYS_MathPolygonWithHoles.md +92 -92
- package/skill/references/interfaces/ISYS_MessageBusTask.md +115 -115
- package/skill/references/interfaces/ISYS_MultilingualLanguagesData.md +12 -12
- package/skill/references/interfaces/ISYS_RightClickMenuItem.md +174 -174
- package/skill/references/interfaces/ISYS_ShortcutKeyData.md +169 -169
- package/skill/references/interfaces/ISYS_ShortcutKeyDataWithCallFn.md +62 -62
- package/skill/references/interfaces/ISYS_ShortcutKeyDataWithUserDefinedShortcutKey.md +62 -62
- package/skill/references/interfaces/ISYS_WindowEventListenerRemovableObject.md +109 -109
- package/skill/references/interfaces/IconProps.md +88 -88
- package/skill/references/interfaces/ImageProps.md +115 -115
- package/skill/references/interfaces/InputEditConfig.md +182 -0
- package/skill/references/interfaces/InputProps.md +547 -520
- package/skill/references/interfaces/KeyboardConfig.md +61 -0
- package/skill/references/interfaces/ListChildren.md +223 -223
- package/skill/references/interfaces/ListProps.md +250 -223
- package/skill/references/interfaces/ModalProps.md +358 -358
- package/skill/references/interfaces/NumberEditConfig.md +234 -0
- package/skill/references/interfaces/RadioGroupProps.md +196 -196
- package/skill/references/interfaces/RadioItem.md +115 -115
- package/skill/references/interfaces/RichTableProps.md +1357 -0
- package/skill/references/interfaces/RowMetaConfig.md +142 -0
- package/skill/references/interfaces/ScrollerProps.md +169 -169
- package/skill/references/interfaces/SelectEditConfig.md +211 -0
- package/skill/references/interfaces/SelectListItem.md +142 -142
- package/skill/references/interfaces/SelectOption.md +142 -0
- package/skill/references/interfaces/SelectProps.md +169 -169
- package/skill/references/interfaces/SelectionConfig.md +358 -0
- package/skill/references/interfaces/SliderProps.md +142 -0
- package/skill/references/interfaces/SlotProps.md +88 -88
- package/skill/references/interfaces/SortState.md +88 -0
- package/skill/references/interfaces/SortingConfig.md +169 -0
- package/skill/references/interfaces/StyleProps.md +439 -385
- package/skill/references/interfaces/TextAreaProps.md +196 -196
- package/skill/references/interfaces/TextProps.md +169 -169
- package/skill/references/interfaces/TextareaEditConfig.md +182 -0
- package/skill/references/interfaces/ValidationRule.md +223 -0
- package/skill/references/interfaces/VirtualScrollConfig.md +115 -0
- package/skill/references/types/Align.md +9 -0
- package/skill/references/types/CellContentType.md +9 -0
- package/skill/references/types/ColumnDefOrGroup.md +12 -0
- package/skill/references/types/ColumnEditConfig.md +13 -0
- package/skill/references/types/ColumnType.md +9 -0
- package/skill/references/types/DataChangeType.md +9 -0
- package/skill/references/types/FilterMatchMode.md +9 -0
- package/skill/references/types/RichTableRow.md +12 -0
- package/skill/references/types/Serializable.md +10 -0
- package/skill/references/types/SerializablePrimitive.md +9 -0
- package/skill/references/types/SortOrder.md +9 -0
- package/skill/references/types/TPCB_LayerTypesOfInnerLayer.md +11 -11
- package/skill/references/types/TPCB_LayersInTheSelectable.md +42 -42
- package/skill/references/types/TPCB_LayersOfComponent.md +11 -11
- package/skill/references/types/TPCB_LayersOfCopper.md +15 -15
- package/skill/references/types/TPCB_LayersOfCustom.md +41 -41
- package/skill/references/types/TPCB_LayersOfDimension.md +16 -16
- package/skill/references/types/TPCB_LayersOfFill.md +28 -28
- package/skill/references/types/TPCB_LayersOfImage.md +22 -22
- package/skill/references/types/TPCB_LayersOfInner.md +41 -41
- package/skill/references/types/TPCB_LayersOfLine.md +25 -25
- package/skill/references/types/TPCB_LayersOfObject.md +12 -12
- package/skill/references/types/TPCB_LayersOfPad.md +11 -11
- package/skill/references/types/TPCB_LayersOfRegion.md +11 -11
- package/skill/references/types/TPCB_NumberOfCopperLayers.md +9 -9
- package/skill/references/types/TPCB_PolygonSourceArray.md +85 -83
- package/skill/references/types/TPCB_PrimitiveDimensionCoordinateSet.md +66 -66
- package/skill/references/types/TPCB_PrimitivePadHole.md +30 -30
- package/skill/references/types/TPCB_PrimitivePadShape.md +61 -61
- package/skill/references/types/TPCB_PrimitiveSpecialPadShape.md +19 -19
- package/skill/references/types/TSYS_ComparisonErrorCode.md +15 -0
- package/skill/references/types/TSYS_LanguageKeyValuePairs.md +13 -0
- package/skill/references/types/TSYS_MathPolygonGroup.md +15 -15
- package/skill/references/types/TSYS_MathPolygonInput.md +20 -20
- package/skill/references/types/TSYS_ShortcutKeys.md +96 -96
- package/skill/user-guide/using-extension.md +47 -47
- package/src/json-gen.test.js +430 -0
- package/skill/guide/ancillary-projects/pro-api-sdk.md +0 -1
- package/skill/references/interfaces/ISYS_PcbComparisonResponse.md +0 -115
- package/skill/references/types/ISYS_LanguageKeyValuePairs.md +0 -13
- package/skill/references/types/TSYS_PcbComparisonErrorCode.md +0 -10
package/lib/client.js
CHANGED
|
@@ -1,189 +1,252 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* dsh-lichuang-eda — browser half
|
|
2
|
+
* dsh-lichuang-eda — browser half (DSH 0.1.x / 0.2 desktop adapted).
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* - 连接教程(可折叠,默认收起,精简步骤)
|
|
8
|
-
* - 活动监视(主体):当前会话 agent 对官方 API 的实时调用流(动作/耗时/结果)
|
|
9
|
-
* - 离线导出(底部小结):仅兜底,导出可导入的标准版 JSON
|
|
4
|
+
* Design read: a technical side-panel for the shell's overlay layer — dark-first,
|
|
5
|
+
* editorial and restrained, wearing the host's own tokens + UI primitives so it
|
|
6
|
+
* reads as native chrome rather than a bolted-on widget.
|
|
10
7
|
*
|
|
11
|
-
*
|
|
12
|
-
* the
|
|
13
|
-
*
|
|
8
|
+
* 0.2 adaptation (the "挡到" fix):
|
|
9
|
+
* - the panel is registered into the `shell.overlay` SLOT (position:absolute,
|
|
10
|
+
* z-index 30) instead of a fixed body overlay with a 9999 z-index — it no
|
|
11
|
+
* longer covers the conversation, other panels, or the desktop chrome;
|
|
12
|
+
* - the entry point is a `conversation.session.header.utilities` pill (0.2's
|
|
13
|
+
* left sidebar is slot-owned); the 0.1.x sidebar DOM entry is kept as a
|
|
14
|
+
* compatibility path and the two never fight;
|
|
15
|
+
* - the panel is drag-resizable (120–760px, persisted) and follows the host
|
|
16
|
+
* theme through `--dsw-alias-*` tokens.
|
|
17
|
+
*
|
|
18
|
+
* Bundle format: `window.__ModuleLoader__.load({id, factory})` (lazy CJS).
|
|
14
19
|
*/
|
|
15
20
|
window.__ModuleLoader__.load({
|
|
16
21
|
id: "@windypro-rourou/dsh-eda",
|
|
17
22
|
factory: (require) => {
|
|
18
23
|
var module = { exports: {} };
|
|
19
24
|
var exports = module.exports;
|
|
25
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
20
26
|
|
|
21
|
-
const
|
|
27
|
+
const React = require("react");
|
|
28
|
+
const { createElement: h, useEffect, useMemo, useRef, useState } = React;
|
|
22
29
|
const { createRoot } = require("react-dom/client");
|
|
23
30
|
|
|
31
|
+
// ── host UI kit (same components the native chrome uses); degrade to our
|
|
32
|
+
// own token-based markup when a build does not ship it. ────────────────
|
|
33
|
+
let P = null;
|
|
34
|
+
try { P = require("@deepseek-ai/dsh-client-ui-primitives"); } catch (e) { P = null; }
|
|
35
|
+
const dsButton = P && P.Button ? P.Button : null;
|
|
36
|
+
const dsPill = P && P.Pill ? P.Pill : null;
|
|
37
|
+
const dsTooltip = P && P.Tooltip ? P.Tooltip : null;
|
|
38
|
+
const dsIcon = (name) => (P && P[name] ? P[name] : null);
|
|
39
|
+
|
|
24
40
|
//#region styles
|
|
41
|
+
/**
|
|
42
|
+
* Token-first styling: every colour comes from `--dsw-alias-*` with a
|
|
43
|
+
* dark-first fallback, so the panel inherits light/dark from the shell.
|
|
44
|
+
* Reused accent = one blue; no gradients, no heavy shadows (taste rule:
|
|
45
|
+
* restraint over decoration).
|
|
46
|
+
*/
|
|
25
47
|
const STYLE = `
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
48
|
+
.dsh-eda-root {
|
|
49
|
+
--eda-bg: var(--dsw-alias-bg-layer-1, #151922);
|
|
50
|
+
--eda-bg-base: var(--dsw-alias-bg-base, #0f1115);
|
|
51
|
+
--eda-bg-soft: var(--dsw-alias-bg-layer-2, #1a1f2b);
|
|
52
|
+
--eda-fg: var(--dsw-alias-label-primary, #d7dde6);
|
|
53
|
+
--eda-fg-2: var(--dsw-alias-label-secondary, #b6bdc9);
|
|
54
|
+
--eda-fg-3: var(--dsw-alias-label-tertiary, #8b93a3);
|
|
55
|
+
--eda-line: var(--dsw-alias-border-l1, #262a33);
|
|
56
|
+
--eda-line-soft: var(--dsw-alias-border-l2, rgba(255,255,255,.06));
|
|
57
|
+
--eda-accent: #4c8dff;
|
|
58
|
+
--eda-ok: var(--dsw-alias-state-success-primary, #22c55e);
|
|
59
|
+
--eda-warn: var(--dsw-alias-state-warn-primary, #eab308);
|
|
60
|
+
--eda-err: var(--dsw-alias-state-error-primary, #ef4444);
|
|
61
|
+
--eda-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
|
|
62
|
+
--eda-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", "Microsoft YaHei", system-ui, sans-serif;
|
|
63
|
+
|
|
64
|
+
position: absolute; top: 0; right: 0; bottom: 0;
|
|
65
|
+
width: var(--eda-w, 400px); max-width: 96vw;
|
|
66
|
+
display: flex; flex-direction: column; min-height: 0;
|
|
67
|
+
background: var(--eda-bg); color: var(--eda-fg);
|
|
68
|
+
border-left: 1px solid var(--eda-line);
|
|
69
|
+
font: 13px/1.55 var(--eda-sans);
|
|
70
|
+
font-variant-numeric: tabular-nums;
|
|
71
|
+
z-index: 30;
|
|
72
|
+
box-shadow: -14px 0 40px rgba(0,0,0,.22);
|
|
73
|
+
animation: edaIn .16s cubic-bezier(.22,.61,.36,1);
|
|
30
74
|
}
|
|
75
|
+
.dsh-eda-root[hidden] { display: none !important; }
|
|
76
|
+
@keyframes edaIn { from { transform: translateX(14px); opacity: 0; } to { transform: none; opacity: 1; } }
|
|
77
|
+
@media (prefers-reduced-motion: reduce) { .dsh-eda-root { animation: none; } }
|
|
78
|
+
|
|
79
|
+
.dsh-eda-grip { position: absolute; left: -3px; top: 0; bottom: 0; width: 7px; cursor: col-resize; z-index: 6; }
|
|
80
|
+
.dsh-eda-grip:hover { background: linear-gradient(90deg, transparent, rgba(76,141,255,.35)); }
|
|
81
|
+
|
|
82
|
+
/* top bar — sticky, quiet, 48px */
|
|
83
|
+
.eda-top { flex: none; height: 48px; display: flex; align-items: center; gap: 10px; padding: 0 12px 0 14px;
|
|
84
|
+
border-bottom: 1px solid var(--eda-line); background: var(--eda-bg); }
|
|
85
|
+
.eda-mark { flex: none; width: 24px; height: 24px; border-radius: 7px; display: grid; place-items: center;
|
|
86
|
+
color: #fff; background: linear-gradient(160deg, #3b7bf6, #2b5fd0); font-size: 11px; font-weight: 700; letter-spacing: .02em; }
|
|
87
|
+
.eda-title { min-width: 0; flex: 1; }
|
|
88
|
+
.eda-title b { display: block; font-size: 13px; font-weight: 600; letter-spacing: .01em; }
|
|
89
|
+
.eda-title span { display: block; font-size: 10.5px; color: var(--eda-fg-3); font-family: var(--eda-mono); }
|
|
90
|
+
.eda-iconbtn { flex: none; width: 26px; height: 26px; display: grid; place-items: center; border-radius: 7px;
|
|
91
|
+
border: 1px solid transparent; background: transparent; color: var(--eda-fg-3); cursor: pointer; font-size: 12px; line-height: 1; }
|
|
92
|
+
.eda-iconbtn:hover { color: var(--eda-fg); background: var(--dsw-alias-interactive-bg-hover, rgba(128,128,128,.12)); }
|
|
93
|
+
|
|
94
|
+
.eda-scroll { flex: 1 1 0; min-height: 0; overflow-y: auto; padding: 14px 14px 18px;
|
|
95
|
+
display: flex; flex-direction: column; gap: 12px; scrollbar-width: thin; }
|
|
96
|
+
.eda-scroll::-webkit-scrollbar { width: 9px; }
|
|
97
|
+
.eda-scroll::-webkit-scrollbar-thumb { background: var(--eda-line); border-radius: 9px; border: 2px solid transparent; background-clip: content-box; }
|
|
98
|
+
|
|
99
|
+
.eda-card { border: 1px solid var(--eda-line); border-radius: 10px; background: var(--eda-bg-soft); padding: 12px 13px; }
|
|
100
|
+
.eda-card-title { font-size: 10.5px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
|
|
101
|
+
color: var(--eda-fg-3); margin: 0 0 10px; }
|
|
102
|
+
.eda-note { font-size: 11.5px; color: var(--eda-fg-2); margin: 9px 0 0; line-height: 1.6; }
|
|
103
|
+
.eda-muted { font-size: 11px; color: var(--eda-fg-3); }
|
|
104
|
+
.eda-mono { font-family: var(--eda-mono); }
|
|
105
|
+
|
|
106
|
+
/* status row */
|
|
107
|
+
.eda-state { display: flex; align-items: center; gap: 9px; }
|
|
108
|
+
.eda-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; background: var(--eda-fg-3); }
|
|
109
|
+
.eda-dot.on { background: var(--eda-ok); box-shadow: 0 0 0 3px rgba(34,197,94,.16); }
|
|
110
|
+
.eda-dot.off { background: var(--eda-warn); }
|
|
111
|
+
.eda-dot.wait { background: var(--eda-fg-3); animation: edaPulse 1.3s ease-in-out infinite; }
|
|
112
|
+
@keyframes edaPulse { 0%,100% { opacity: .4 } 50% { opacity: 1 } }
|
|
113
|
+
.eda-state b { font-size: 12.5px; font-weight: 600; }
|
|
114
|
+
.eda-state small { font-family: var(--eda-mono); font-size: 10.5px; color: var(--eda-fg-3); margin-left: 7px; }
|
|
115
|
+
|
|
116
|
+
.eda-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 7px; margin-top: 11px; }
|
|
117
|
+
.eda-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px;
|
|
118
|
+
border: 1px solid var(--eda-line); border-radius: 8px; padding: 5px 11px; background: transparent;
|
|
119
|
+
color: var(--eda-fg); font: inherit; font-size: 11.5px; font-weight: 600; cursor: pointer;
|
|
120
|
+
transition: background .12s ease, border-color .12s ease, opacity .12s ease; }
|
|
121
|
+
.eda-btn:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover, rgba(128,128,128,.12)); }
|
|
122
|
+
.eda-btn:disabled { opacity: .45; cursor: default; }
|
|
123
|
+
.eda-btn.primary { background: var(--eda-accent); border-color: transparent; color: #fff; }
|
|
124
|
+
.eda-btn.primary:hover:not(:disabled) { background: #3f80f5; }
|
|
125
|
+
.eda-btn.big { width: 100%; padding: 8px 12px; font-size: 12.5px; }
|
|
126
|
+
.eda-btn.tiny { padding: 2px 8px; font-size: 10.5px; font-weight: 500; }
|
|
127
|
+
.eda-link { color: var(--eda-accent); text-decoration: none; font-size: 11.5px; }
|
|
128
|
+
.eda-link:hover { text-decoration: underline; }
|
|
129
|
+
|
|
130
|
+
/* connected CTA */
|
|
131
|
+
.eda-cta { display: flex; align-items: center; gap: 10px; margin-top: 11px; padding: 9px 11px;
|
|
132
|
+
border: 1px solid color-mix(in srgb, var(--eda-accent) 34%, transparent); border-radius: 9px;
|
|
133
|
+
background: color-mix(in srgb, var(--eda-accent) 8%, transparent); cursor: pointer; }
|
|
134
|
+
.eda-cta:hover { background: color-mix(in srgb, var(--eda-accent) 13%, transparent); }
|
|
135
|
+
.eda-cta-t { min-width: 0; flex: 1; }
|
|
136
|
+
.eda-cta-t i { display: block; font-style: normal; font-size: 10px; color: var(--eda-fg-3); letter-spacing: .04em; }
|
|
137
|
+
.eda-cta-t b { font-size: 12.5px; font-weight: 600; color: var(--eda-accent); }
|
|
138
|
+
.eda-cta-c { flex: none; font-size: 10.5px; color: var(--eda-fg-3); }
|
|
139
|
+
.eda-cta.ok .eda-cta-c { color: var(--eda-ok); }
|
|
140
|
+
|
|
141
|
+
/* guide */
|
|
142
|
+
.eda-steps { display: flex; flex-direction: column; gap: 10px; }
|
|
143
|
+
.eda-step { display: flex; gap: 10px; }
|
|
144
|
+
.eda-step-no { flex: none; width: 18px; height: 18px; border-radius: 50%; display: grid; place-items: center;
|
|
145
|
+
font-family: var(--eda-mono); font-size: 10px; color: var(--eda-fg-3); border: 1px solid var(--eda-line); margin-top: 1px; }
|
|
146
|
+
.eda-step b { display: block; font-size: 12px; font-weight: 600; }
|
|
147
|
+
.eda-step p { margin: 2px 0 0; font-size: 11px; color: var(--eda-fg-3); line-height: 1.55; }
|
|
148
|
+
|
|
149
|
+
/* timeline */
|
|
150
|
+
.eda-tl-head { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
|
|
151
|
+
.eda-tl-head .eda-card-title { flex: 1; margin: 0; }
|
|
152
|
+
.eda-select { font: inherit; font-size: 10.5px; font-family: var(--eda-mono); color: var(--eda-fg-2);
|
|
153
|
+
background: var(--eda-bg-base); border: 1px solid var(--eda-line); border-radius: 6px; padding: 2px 5px; max-width: 132px; }
|
|
154
|
+
.eda-tl { position: relative; margin: 6px 0 0; }
|
|
155
|
+
.eda-row { position: relative; display: flex; gap: 10px; padding: 8px 0 8px 2px; cursor: pointer;
|
|
156
|
+
border-bottom: 1px solid var(--eda-line-soft); }
|
|
157
|
+
.eda-row:last-child { border-bottom: 0; }
|
|
158
|
+
.eda-row:hover { background: color-mix(in srgb, var(--eda-fg) 4%, transparent); }
|
|
159
|
+
.eda-row-dot { flex: none; width: 7px; height: 7px; margin-top: 6px; border-radius: 50%; background: var(--eda-fg-3); position: relative; z-index: 1; }
|
|
160
|
+
.eda-row.ok .eda-row-dot { background: var(--eda-ok); }
|
|
161
|
+
.eda-row.err .eda-row-dot { background: var(--eda-err); }
|
|
162
|
+
.eda-row.pend .eda-row-dot { background: var(--eda-warn); animation: edaPulse 1s ease-in-out infinite; }
|
|
163
|
+
.eda-row-body { min-width: 0; flex: 1; }
|
|
164
|
+
.eda-row-line { display: flex; align-items: baseline; gap: 8px; }
|
|
165
|
+
.eda-seq { flex: none; font-family: var(--eda-mono); font-size: 10px; color: var(--eda-fg-3); }
|
|
166
|
+
.eda-row-name { flex: 1; min-width: 0; font-size: 12.5px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
167
|
+
.eda-row-meta { flex: none; font-family: var(--eda-mono); font-size: 10px; color: var(--eda-fg-3); }
|
|
168
|
+
.eda-row-meta .eda-pend { color: var(--eda-warn); }
|
|
169
|
+
.eda-row-code, .eda-row-out { margin-top: 3px; font-family: var(--eda-mono); font-size: 10.5px; color: var(--eda-fg-3);
|
|
170
|
+
overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
171
|
+
.eda-row-out.err { color: var(--eda-err); }
|
|
172
|
+
.eda-row-full { margin-top: 7px; padding: 8px 9px; border-radius: 8px; background: var(--eda-bg-base);
|
|
173
|
+
border: 1px solid var(--eda-line-soft); font-family: var(--eda-mono); font-size: 10.5px; line-height: 1.6;
|
|
174
|
+
color: var(--eda-fg-2); white-space: pre-wrap; word-break: break-word; max-height: 260px; overflow: auto; }
|
|
175
|
+
.eda-row-full i { display: block; font-style: normal; font-size: 9.5px; letter-spacing: .08em; text-transform: uppercase;
|
|
176
|
+
color: var(--eda-fg-3); margin: 6px 0 2px; }
|
|
177
|
+
.eda-row-full i:first-child { margin-top: 0; }
|
|
178
|
+
.eda-empty { font-size: 11.5px; color: var(--eda-fg-3); line-height: 1.6; }
|
|
179
|
+
.eda-hints { margin-top: 9px; display: flex; flex-direction: column; gap: 5px; }
|
|
180
|
+
.eda-hint { display: flex; gap: 7px; font-size: 11px; color: var(--eda-fg-2); }
|
|
181
|
+
.eda-hint s { text-decoration: none; color: var(--eda-fg-3); }
|
|
182
|
+
.eda-tl-foot { margin-top: 7px; font-size: 10.5px; color: var(--eda-fg-3); }
|
|
183
|
+
|
|
184
|
+
.eda-foot { flex: none; padding: 9px 14px; border-top: 1px solid var(--eda-line);
|
|
185
|
+
font-family: var(--eda-mono); font-size: 10px; color: var(--eda-fg-3); text-align: center; }
|
|
186
|
+
|
|
187
|
+
/* header pill (0.2 entry point) */
|
|
188
|
+
.eda-pill { display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 9px;
|
|
189
|
+
border: 1px solid var(--eda-line); border-radius: 999px; background: transparent; color: inherit;
|
|
190
|
+
font: inherit; font-size: 11.5px; cursor: pointer; transition: background .12s ease; }
|
|
191
|
+
.eda-pill:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(128,128,128,.12)); }
|
|
192
|
+
.eda-pill[data-active="true"] { border-color: color-mix(in srgb, var(--eda-accent) 46%, transparent);
|
|
193
|
+
background: color-mix(in srgb, var(--eda-accent) 12%, transparent); }
|
|
194
|
+
.eda-pill .eda-dot { width: 6px; height: 6px; }
|
|
195
|
+
.eda-pill[hidden] { display: none !important; }
|
|
196
|
+
|
|
197
|
+
/* update hint (top bar) — one quiet warning-tinted pill, click to copy */
|
|
198
|
+
.eda-update { flex: none; display: inline-flex; align-items: center; gap: 4px; height: 22px; padding: 0 8px;
|
|
199
|
+
border: 1px solid color-mix(in srgb, var(--eda-warn) 42%, transparent); border-radius: 999px;
|
|
200
|
+
background: color-mix(in srgb, var(--eda-warn) 10%, transparent); color: var(--eda-warn);
|
|
201
|
+
font: inherit; font-size: 10.5px; font-weight: 600; cursor: pointer; white-space: nowrap; }
|
|
202
|
+
.eda-update:hover { background: color-mix(in srgb, var(--eda-warn) 18%, transparent); }
|
|
203
|
+
|
|
204
|
+
/* 0.1.x sidebar entry */
|
|
205
|
+
[data-dsh-eda-entry] { display: flex; align-items: center; gap: 8px; width: 100%; padding: 9px 12px; margin: 2px 0;
|
|
206
|
+
border: 0; border-radius: 8px; background: transparent; color: inherit; font: inherit; cursor: pointer; text-align: left; }
|
|
31
207
|
[data-dsh-eda-entry]:hover { background: rgba(128,128,128,.14); }
|
|
32
208
|
[data-dsh-eda-entry][data-active] { background: rgba(128,128,128,.22); }
|
|
33
|
-
[data-dsh-eda-entry] .eda-entry-icon { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; flex: none; }
|
|
34
209
|
[data-dsh-eda-entry] .eda-entry-label { font-size: 13px; line-height: 1.2; opacity: .92; }
|
|
35
|
-
|
|
36
|
-
.dsh-eda-view { position: fixed; top: 0; right: 0; bottom: 0; width: min(420px, 94vw); z-index: 9999; }
|
|
37
|
-
.dsh-eda-view[hidden] { display: none !important; }
|
|
38
|
-
.dsh-eda-panel {
|
|
39
|
-
position: absolute; inset: 0; background: light-dark(#fbfbfc, #121417);
|
|
40
|
-
color: light-dark(#1c1f24, #e3e6ea);
|
|
41
|
-
border-left: 1px solid light-dark(rgba(0,0,0,.09), rgba(255,255,255,.10));
|
|
42
|
-
font: 13px/1.6 -apple-system, "Segoe UI", "Microsoft YaHei", system-ui, sans-serif;
|
|
43
|
-
color-scheme: light dark;
|
|
44
|
-
display: flex; flex-direction: column;
|
|
45
|
-
}
|
|
46
|
-
.eda-panel { display: flex; flex-direction: column; height: 100%; min-height: 0; }
|
|
47
|
-
|
|
48
|
-
.eda-head {
|
|
49
|
-
flex: none; display: flex; align-items: center; gap: 10px;
|
|
50
|
-
padding: 13px 16px; border-bottom: 1px solid light-dark(rgba(0,0,0,.08), rgba(255,255,255,.09));
|
|
51
|
-
}
|
|
52
|
-
.eda-head .eda-mark { width: 26px; height: 26px; border-radius: 6px; flex: none; background: #2563eb; color: #fff; display: grid; place-items: center; font-size: 12px; font-weight: 700; }
|
|
53
|
-
.eda-head .eda-tt { min-width: 0; flex: 1; }
|
|
54
|
-
.eda-head h1 { font-size: 14px; font-weight: 700; margin: 0; line-height: 1.3; }
|
|
55
|
-
.eda-head .eda-sub { font-size: 11px; opacity: .55; margin: 0; }
|
|
56
|
-
.eda-close { border: 0; background: transparent; color: inherit; cursor: pointer; font-size: 15px; line-height: 1; padding: 5px 8px; border-radius: 6px; opacity: .6; }
|
|
57
|
-
.eda-close:hover { opacity: 1; background: light-dark(rgba(0,0,0,.06), rgba(255,255,255,.08)); }
|
|
58
|
-
|
|
59
|
-
.eda-scroll { flex: 1 1 0; min-height: 0; overflow-y: auto; padding: 13px 16px 18px; display: flex; flex-direction: column; gap: 12px; }
|
|
60
|
-
|
|
61
|
-
.eda-card { border: 1px solid light-dark(rgba(0,0,0,.09), rgba(255,255,255,.10)); border-radius: 10px; padding: 12px 14px; background: light-dark(#ffffff, #17191d); }
|
|
62
|
-
.eda-card-title { font-size: 12px; font-weight: 600; opacity: .75; margin: 0 0 8px; }
|
|
63
|
-
|
|
64
|
-
.eda-note { font-size: 11.5px; opacity: .62; margin: 8px 0 0; line-height: 1.6; }
|
|
65
|
-
.eda-muted { font-size: 11px; opacity: .5; }
|
|
66
|
-
|
|
67
|
-
.eda-status { display: flex; align-items: center; gap: 8px; }
|
|
68
|
-
.eda-status .eda-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
|
|
69
|
-
.eda-status .eda-dot.on { background: #16a34a; }
|
|
70
|
-
.eda-status .eda-dot.off { background: #d97706; }
|
|
71
|
-
.eda-status .eda-dot.wait { background: #9ca3af; animation: edaPulse 1.2s ease-in-out infinite; }
|
|
72
|
-
.eda-status .eda-txt { font-size: 13px; font-weight: 600; }
|
|
73
|
-
.eda-status .eda-txt small { font-weight: 400; opacity: .55; margin-left: 6px; }
|
|
74
|
-
@keyframes edaPulse { 0%,100% { opacity: .45; } 50% { opacity: 1; } }
|
|
75
|
-
|
|
76
|
-
.eda-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
|
|
77
|
-
.eda-btn {
|
|
78
|
-
display: inline-flex; align-items: center; justify-content: center; gap: 6px;
|
|
79
|
-
border: 1px solid transparent; border-radius: 8px; padding: 6px 12px;
|
|
80
|
-
font: inherit; font-size: 12px; font-weight: 600; cursor: pointer;
|
|
81
|
-
transition: background .12s ease, border-color .12s ease;
|
|
82
|
-
}
|
|
83
|
-
.eda-btn.primary { background: #2563eb; color: #fff; }
|
|
84
|
-
.eda-btn.primary:hover { background: #1d4ed8; }
|
|
85
|
-
.eda-btn.primary:disabled { opacity: .5; cursor: default; }
|
|
86
|
-
.eda-btn.ghost { background: transparent; border-color: light-dark(rgba(0,0,0,.14), rgba(255,255,255,.16)); color: inherit; }
|
|
87
|
-
.eda-btn.ghost:hover { background: light-dark(rgba(0,0,0,.04), rgba(255,255,255,.06)); }
|
|
88
|
-
.eda-btn.ghost:disabled { opacity: .45; cursor: default; }
|
|
89
|
-
.eda-btn.big { width: 100%; padding: 8px 13px; font-size: 13px; }
|
|
90
|
-
.eda-link { color: #2563eb; text-decoration: none; font-size: 12px; }
|
|
91
|
-
.eda-link:hover { text-decoration: underline; }
|
|
92
|
-
|
|
93
|
-
/* connect wizard (collapsed by default, compact) */
|
|
94
|
-
.eda-steps { display: flex; flex-direction: column; gap: 9px; margin-top: 2px; }
|
|
95
|
-
.eda-step { display: flex; gap: 9px; }
|
|
96
|
-
.eda-step .eda-step-no { width: 19px; height: 19px; flex: none; border-radius: 50%; display: grid; place-items: center; font-size: 10.5px; font-weight: 700; background: light-dark(#eef2f7, #24272c); opacity: .85; }
|
|
97
|
-
.eda-step .eda-step-body { min-width: 0; flex: 1; }
|
|
98
|
-
.eda-step .eda-step-name { font-size: 12.5px; font-weight: 600; }
|
|
99
|
-
.eda-step .eda-step-hint { font-size: 11px; opacity: .58; margin-top: 1px; line-height: 1.5; }
|
|
100
|
-
.eda-step .eda-step-action { margin-top: 5px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
|
|
101
|
-
.eda-step .eda-step-result { font-size: 11.5px; opacity: .7; }
|
|
102
|
-
|
|
103
|
-
/* activity monitor (main) */
|
|
104
|
-
.eda-act { display: flex; flex-direction: column; gap: 0; }
|
|
105
|
-
.eda-act-item { display: flex; gap: 9px; padding: 9px 0; border-bottom: 1px solid light-dark(rgba(0,0,0,.05), rgba(255,255,255,.06)); cursor: pointer; }
|
|
106
|
-
.eda-act-item:hover { background: light-dark(rgba(0,0,0,.03), rgba(255,255,255,.03)); }
|
|
107
|
-
.eda-act-item:last-child { border-bottom: 0; }
|
|
108
|
-
.eda-act-item .eda-act-dot { flex: none; margin-top: 5px; width: 7px; height: 7px; border-radius: 50%; background: #9ca3af; }
|
|
109
|
-
.eda-act-item.ok .eda-act-dot { background: #16a34a; }
|
|
110
|
-
.eda-act-item.err .eda-act-dot { background: #dc2626; }
|
|
111
|
-
.eda-act-item.pend .eda-act-dot { background: #f59e0b; animation: edaPulse 1s ease-in-out infinite; }
|
|
112
|
-
.eda-act-item .eda-act-body { min-width: 0; flex: 1; }
|
|
113
|
-
.eda-act-item .eda-act-line { display: flex; align-items: baseline; gap: 8px; }
|
|
114
|
-
.eda-act-item .eda-act-seq { font-family: ui-monospace, Consolas, monospace; font-size: 10px; opacity: .45; flex: none; }
|
|
115
|
-
.eda-act-item .eda-act-name { font-size: 12.5px; font-weight: 600; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
116
|
-
.eda-act-item .eda-act-meta { font-size: 10.5px; opacity: .5; }
|
|
117
|
-
.eda-revoke { padding: 2px 8px !important; font-size: 10px !important; }
|
|
118
|
-
.eda-hints { display: flex; flex-direction: column; gap: 5px; margin-top: 2px; }
|
|
119
|
-
.eda-hint { font-size: 11px; opacity: .68; }
|
|
120
|
-
.eda-act-item .eda-act-meta .eda-pend { color: #f59e0b; opacity: 1; font-weight: 600; }
|
|
121
|
-
.eda-act-item .eda-act-code { font-family: ui-monospace, Consolas, monospace; font-size: 10.5px; opacity: .55; margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
122
|
-
.eda-act-item .eda-act-out { font-size: 11px; opacity: .65; margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
123
|
-
.eda-act-item .eda-act-out.err { color: #dc2626; opacity: .9; }
|
|
124
|
-
.eda-act-item .eda-act-full {
|
|
125
|
-
white-space: pre-wrap; word-break: break-all; font-family: ui-monospace, Consolas, monospace;
|
|
126
|
-
font-size: 10.5px; line-height: 1.55; opacity: .8; margin-top: 5px; padding: 7px 9px;
|
|
127
|
-
background: light-dark(rgba(0,0,0,.045), rgba(255,255,255,.05)); border-radius: 7px;
|
|
128
|
-
max-height: 240px; overflow: auto;
|
|
129
|
-
}
|
|
130
|
-
.eda-act-item .eda-act-full .eda-act-full-label { font-family: inherit; font-size: 10px; opacity: .5; margin: 0 0 2px; }
|
|
131
|
-
.eda-act-empty { font-size: 11.5px; opacity: .5; padding: 6px 0; }
|
|
132
|
-
|
|
133
|
-
/* activity header row: title + session switcher */
|
|
134
|
-
.eda-act-head { display: flex; align-items: center; gap: 8px; }
|
|
135
|
-
.eda-act-head .eda-card-title { flex: 1; margin: 0; }
|
|
136
|
-
.eda-sess {
|
|
137
|
-
font: inherit; font-size: 10.5px; border: 1px solid light-dark(rgba(0,0,0,.14), rgba(255,255,255,.16));
|
|
138
|
-
border-radius: 6px; background: transparent; color: inherit; padding: 2px 6px; max-width: 130px; cursor: pointer;
|
|
139
|
-
}
|
|
140
|
-
.eda-act-hint { font-size: 10.5px; opacity: .5; margin: 6px 0 0; }
|
|
141
|
-
|
|
142
|
-
/* 醒目对话入口 (connected CTA) */
|
|
143
|
-
.eda-cta {
|
|
144
|
-
display: flex; align-items: center; gap: 10px; margin-top: 10px; padding: 9px 12px;
|
|
145
|
-
border: 1px solid rgba(37,99,235,.35); border-radius: 10px; cursor: pointer;
|
|
146
|
-
background: linear-gradient(180deg, rgba(37,99,235,.10), rgba(37,99,235,.03));
|
|
147
|
-
}
|
|
148
|
-
.eda-cta:hover { background: rgba(37,99,235,.14); }
|
|
149
|
-
.eda-cta .eda-cta-bubble { font-size: 16px; flex: none; }
|
|
150
|
-
.eda-cta .eda-cta-text { min-width: 0; flex: 1; }
|
|
151
|
-
.eda-cta .eda-cta-title { font-size: 10.5px; opacity: .6; }
|
|
152
|
-
.eda-cta .eda-cta-phrase { font-family: inherit; font-size: 12.5px; font-weight: 700; color: #2563eb; }
|
|
153
|
-
.eda-cta .eda-cta-copy { flex: none; font-size: 10.5px; opacity: .55; }
|
|
154
|
-
.eda-cta.ok .eda-cta-copy { color: #16a34a; opacity: 1; }
|
|
155
|
-
|
|
156
|
-
/* offline export (footer, small) */
|
|
157
|
-
.eda-prompt textarea {
|
|
158
|
-
width: 100%; box-sizing: border-box; resize: vertical; min-height: 56px; border-radius: 8px;
|
|
159
|
-
border: 1px solid light-dark(rgba(0,0,0,.14), rgba(255,255,255,.16));
|
|
160
|
-
background: light-dark(#fafafa, #121317); color: inherit; font: inherit; font-size: 12px; line-height: 1.6;
|
|
161
|
-
padding: 8px 10px; outline: none;
|
|
162
|
-
}
|
|
163
|
-
.eda-prompt textarea:focus { border-color: #2563eb; }
|
|
164
|
-
.eda-prompt textarea::placeholder { opacity: .45; }
|
|
165
|
-
.eda-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
|
|
166
|
-
.eda-chip { border: 1px solid light-dark(rgba(0,0,0,.11), rgba(255,255,255,.13)); border-radius: 999px; padding: 3px 9px; font-size: 11px; cursor: pointer; color: inherit; background: transparent; }
|
|
167
|
-
.eda-chip:hover { border-color: rgba(37,99,235,.55); }
|
|
168
|
-
|
|
169
|
-
.eda-foot { font-size: 11px; opacity: .5; text-align: center; margin: 2px 0 0; }
|
|
170
210
|
`;
|
|
171
211
|
//#endregion
|
|
172
212
|
|
|
173
213
|
const API_BASE = "/api/dsh-eda";
|
|
214
|
+
/** The one upgrade command the update pill copies. */
|
|
215
|
+
const UPDATE_CMD = "dsh plugin --profile desktop add @windypro-rourou/dsh-eda@latest";
|
|
174
216
|
const LINKS = {
|
|
175
217
|
editor: "https://pro.lceda.cn/editor",
|
|
176
218
|
ext: "https://jlc-ext.com/item/oshwhub/run-api-gateway",
|
|
177
|
-
skill: "https://github.com/easyeda/easyeda-api-skill",
|
|
178
219
|
};
|
|
179
|
-
|
|
180
|
-
//#region data
|
|
181
220
|
const CONNECT_STEPS = [
|
|
182
|
-
{
|
|
183
|
-
{
|
|
184
|
-
{
|
|
185
|
-
{
|
|
221
|
+
{ n: 1, t: "一键安装官方桥", d: "官方 easyeda-api-skill → 本机 ~/.dsh/eda/bridge/(离线依赖,无需 npm)。" },
|
|
222
|
+
{ n: 2, t: "启动官方桥", d: "Bridge Server 监听 127.0.0.1:49620-49629,插件自动探测。" },
|
|
223
|
+
{ n: 3, t: "网页版装扩展 Run API Gateway", d: "编辑器 →「高级」→「扩展管理器」→ 安装;再开「外部交互」+「显示在顶部菜单」。" },
|
|
224
|
+
{ n: 4, t: "验证", d: "刷新编辑器页面;状态点变绿 = 已连上你的云画板。" },
|
|
186
225
|
];
|
|
226
|
+
const HINTS = [
|
|
227
|
+
"放置任意大类元件(R/C/L/二极管/LED/MCU…)并框内定位",
|
|
228
|
+
"引脚级连线 + VCC/GND 网络标志",
|
|
229
|
+
"原理图 / PCB 的 DRC、网表、BOM 导出",
|
|
230
|
+
"PCB 元件 / 过孔 / 走线(含底层铜)+ 现场截图",
|
|
231
|
+
"随时「紧急保存」到本地并留动作日志",
|
|
232
|
+
];
|
|
233
|
+
const ICON_EDA = "M3 3.6h7.2l2.8 2.8v6h-10z M10.2 3.6v2.8h2.8 M5 8.4h3 M5 10.4h2";
|
|
234
|
+
|
|
235
|
+
//#region store
|
|
236
|
+
/** Tiny external store: panel open/closed, shared by the pill and the overlay. */
|
|
237
|
+
function PanelStore() {
|
|
238
|
+
const listeners = new Set();
|
|
239
|
+
let open = false;
|
|
240
|
+
this.get = () => open;
|
|
241
|
+
this.set = (v) => { const next = !!v; if (next === open) return; open = next; for (const fn of listeners) fn(); };
|
|
242
|
+
this.toggle = () => this.set(!open);
|
|
243
|
+
this.subscribe = (fn) => { listeners.add(fn); return () => listeners.delete(fn); };
|
|
244
|
+
}
|
|
245
|
+
function useStore(store) {
|
|
246
|
+
const [v, setV] = useState(store.get());
|
|
247
|
+
useEffect(() => store.subscribe(() => setV(store.get())), [store]);
|
|
248
|
+
return v;
|
|
249
|
+
}
|
|
187
250
|
//#endregion
|
|
188
251
|
|
|
189
252
|
//#region hooks
|
|
@@ -192,12 +255,10 @@ window.__ModuleLoader__.load({
|
|
|
192
255
|
const [error, setError] = useState(false);
|
|
193
256
|
useEffect(() => {
|
|
194
257
|
let alive = true;
|
|
195
|
-
const load = () =>
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
.catch(() => { if (alive) { setStatus(null); setError(true); } });
|
|
200
|
-
};
|
|
258
|
+
const load = () => fetch(API_BASE + "/status")
|
|
259
|
+
.then((r) => (r.ok ? r.json() : Promise.reject(r.status)))
|
|
260
|
+
.then((b) => { if (alive) { setStatus(b); setError(false); } })
|
|
261
|
+
.catch(() => { if (alive) { setStatus(null); setError(true); } });
|
|
201
262
|
load();
|
|
202
263
|
const t = setInterval(load, 4000);
|
|
203
264
|
return () => { alive = false; clearInterval(t); };
|
|
@@ -205,14 +266,8 @@ window.__ModuleLoader__.load({
|
|
|
205
266
|
return [status, error];
|
|
206
267
|
}
|
|
207
268
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
* through the official API right now). `pinnedSid` = '' means "follow
|
|
211
|
-
* the freshest session" (the panel's default for 仅当前会话).
|
|
212
|
-
*/
|
|
213
|
-
function useActivity() {
|
|
214
|
-
const [feed, setFeed] = useState({ activities: [], sessions: [], currentSid: '', error: false });
|
|
215
|
-
const [pinnedSid, setPinnedSid] = useState("");
|
|
269
|
+
function useActivity(pinnedSid) {
|
|
270
|
+
const [feed, setFeed] = useState({ activities: [], sessions: [], currentSid: "", error: false });
|
|
216
271
|
useEffect(() => {
|
|
217
272
|
let alive = true;
|
|
218
273
|
const load = () => {
|
|
@@ -221,7 +276,12 @@ window.__ModuleLoader__.load({
|
|
|
221
276
|
.then((r) => (r.ok ? r.json() : Promise.reject(r.status)))
|
|
222
277
|
.then((b) => {
|
|
223
278
|
if (!alive) return;
|
|
224
|
-
setFeed({
|
|
279
|
+
setFeed({
|
|
280
|
+
activities: Array.isArray(b.activities) ? b.activities : [],
|
|
281
|
+
sessions: Array.isArray(b.sessions) ? b.sessions : [],
|
|
282
|
+
currentSid: b.currentSid ?? "",
|
|
283
|
+
error: false,
|
|
284
|
+
});
|
|
225
285
|
})
|
|
226
286
|
.catch(() => { if (alive) setFeed((prev) => ({ ...prev, error: true })); });
|
|
227
287
|
};
|
|
@@ -229,340 +289,407 @@ window.__ModuleLoader__.load({
|
|
|
229
289
|
const t = setInterval(load, 3000);
|
|
230
290
|
return () => { alive = false; clearInterval(t); };
|
|
231
291
|
}, [pinnedSid]);
|
|
232
|
-
return
|
|
292
|
+
return feed;
|
|
233
293
|
}
|
|
234
294
|
//#endregion
|
|
235
295
|
|
|
236
296
|
//#region components
|
|
237
|
-
/**
|
|
238
|
-
function
|
|
297
|
+
/** Brand mark: host icon when available, else a two-stroke chip glyph. */
|
|
298
|
+
function Mark() {
|
|
299
|
+
const Icon = dsIcon("IconBoardOutline16") || dsIcon("IconComponentOutline16");
|
|
300
|
+
if (Icon) return h("span", { className: "eda-mark" }, h(Icon, null));
|
|
301
|
+
return h("span", { className: "eda-mark" }, "EDA");
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function SendIcon() {
|
|
305
|
+
return h("svg", { width: 13, height: 13, viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: 1.3, "aria-hidden": "true" },
|
|
306
|
+
h("path", { d: "M2.6 3.4l10.8 4.6-10.8 4.6 1.7-4.6z", strokeLinejoin: "round" }));
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Compact update hint (top bar): rendered ONLY when /status reports a
|
|
311
|
+
* newer published release. One click copies the upgrade command; quiet,
|
|
312
|
+
* no modal, no badge hunting. Exported for the bundle runtime test.
|
|
313
|
+
*/
|
|
314
|
+
function UpdatePill({ status }) {
|
|
315
|
+
const [copied, setCopied] = useState(false);
|
|
316
|
+
if (status?.updateAvailable !== true) return null;
|
|
317
|
+
const latest = typeof status.latestVersion === "string" ? status.latestVersion : "";
|
|
318
|
+
if (latest === "") return null;
|
|
319
|
+
const copy = () => {
|
|
320
|
+
try { navigator.clipboard?.writeText(UPDATE_CMD); } catch (e) { /* clipboard unavailable */ }
|
|
321
|
+
setCopied(true);
|
|
322
|
+
setTimeout(() => setCopied(false), 1600);
|
|
323
|
+
};
|
|
324
|
+
return h("button", {
|
|
325
|
+
type: "button", className: "eda-update", onClick: copy,
|
|
326
|
+
title: "点击复制升级命令:" + UPDATE_CMD,
|
|
327
|
+
}, copied ? "已复制 ✓" : "v" + latest + " 可更新");
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/** Header pill — the 0.2 entry point (slot-owned header utilities). */
|
|
331
|
+
function HeaderPill({ store }) {
|
|
332
|
+
const open = useStore(store);
|
|
333
|
+
const [status] = useStatus();
|
|
334
|
+
const ready = status?.connected === true;
|
|
335
|
+
const cls = "eda-pill";
|
|
336
|
+
const inner = [
|
|
337
|
+
h("span", { className: "eda-dot " + (status === null ? "wait" : ready ? "on" : "off"), key: "d" }),
|
|
338
|
+
h("span", { key: "t" }, "嘉立创 EDA"),
|
|
339
|
+
];
|
|
340
|
+
if (dsButton) {
|
|
341
|
+
return h(dsButton, {
|
|
342
|
+
appearance: "ghost", size: "small", "data-active": open ? "true" : "false",
|
|
343
|
+
onClick: () => store.toggle(), title: "嘉立创 EDA 助手", className: cls,
|
|
344
|
+
}, inner);
|
|
345
|
+
}
|
|
346
|
+
return h("button", {
|
|
347
|
+
type: "button", className: cls, "data-active": open ? "true" : "false",
|
|
348
|
+
onClick: () => store.toggle(), title: "嘉立创 EDA 助手",
|
|
349
|
+
}, inner);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Connection card: one status line, then the three platform actions, then
|
|
354
|
+
* (when connected) the copy-the-prompt CTA. Errors stay inline and quiet.
|
|
355
|
+
*/
|
|
356
|
+
function ConnectCard({ status, error, install, bridge, onInstall, onStart }) {
|
|
239
357
|
const ready = status?.connected === true;
|
|
240
358
|
const [copied, setCopied] = useState(false);
|
|
241
|
-
const dot = status === null ? (error ? "off" : "wait") : (ready ? "on" : "off");
|
|
242
|
-
const state = status === null ? (error ? "状态服务未响应" : "检测中…") : (ready ? "已连接 · " + (status.port ? "127.0.0.1:" + status.port : "") : "未连接");
|
|
243
|
-
const win = status?.health?.match(/edaWindowCount:(\d+)/)?.[1] ?? null;
|
|
244
359
|
const inst = status?.bridgeInstalled === true;
|
|
245
|
-
const
|
|
360
|
+
const dot = status === null ? (error ? "off" : "wait") : ready ? "on" : "off";
|
|
361
|
+
const label = status === null ? (error ? "状态服务未响应" : "检测中…") : ready ? "已连接" : "未连接";
|
|
362
|
+
const port = ready && status?.port ? "127.0.0.1:" + status.port : "";
|
|
363
|
+
const win = status?.health?.match(/edaWindowCount:(\d+)/)?.[1];
|
|
364
|
+
const copy = () => {
|
|
246
365
|
const text = "嘉立创EDA,启动!帮我画一个 LED 点亮电路";
|
|
247
|
-
try { navigator.clipboard?.writeText(text); } catch { /* clipboard
|
|
366
|
+
try { navigator.clipboard?.writeText(text); } catch (e) { /* clipboard unavailable */ }
|
|
248
367
|
setCopied(true);
|
|
249
368
|
setTimeout(() => setCopied(false), 1600);
|
|
250
369
|
};
|
|
251
370
|
return h("div", { className: "eda-card" },
|
|
252
|
-
h("div", { className: "eda-
|
|
371
|
+
h("div", { className: "eda-state" },
|
|
253
372
|
h("span", { className: "eda-dot " + dot }),
|
|
254
|
-
h("
|
|
373
|
+
h("b", null, label),
|
|
374
|
+
h("small", null, [port, win !== undefined ? "窗口 " + win : ""].filter(Boolean).join(" · "))),
|
|
255
375
|
h("div", { className: "eda-actions" },
|
|
256
376
|
h("button", {
|
|
257
|
-
className: "eda-btn " + (inst ? "
|
|
258
|
-
disabled: inst ||
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
377
|
+
className: "eda-btn " + (inst ? "" : "primary"),
|
|
378
|
+
disabled: inst || install?.busy, onClick: onInstall,
|
|
379
|
+
title: inst ? "官方桥已安装(随本机持久)" : "下载官方 easyeda-api-skill 到本机",
|
|
380
|
+
}, inst ? "官方桥已装 ✓" : install?.busy ? "安装中…" : "一键安装官方桥"),
|
|
381
|
+
h("button", { className: "eda-btn", disabled: bridge?.busy, onClick: onStart },
|
|
382
|
+
bridge?.busy ? "启动中…" : "启动桥"),
|
|
263
383
|
h("a", { className: "eda-link", href: LINKS.editor, target: "_blank", rel: "noreferrer" }, "打开编辑器"),
|
|
264
384
|
h("a", { className: "eda-link", href: LINKS.ext, target: "_blank", rel: "noreferrer" }, "扩展直达")),
|
|
265
385
|
ready
|
|
266
|
-
? h("div", { className: "eda-cta" + (copied ? " ok" : ""), onClick:
|
|
267
|
-
|
|
268
|
-
h(
|
|
269
|
-
|
|
270
|
-
h("
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
386
|
+
? h("div", { className: "eda-cta" + (copied ? " ok" : ""), onClick: copy,
|
|
387
|
+
title: "点击复制,然后粘贴到对话里发送" },
|
|
388
|
+
h(SendIcon, null),
|
|
389
|
+
h("span", { className: "eda-cta-t" },
|
|
390
|
+
h("i", null, "去对话里说"),
|
|
391
|
+
h("b", null, "「嘉立创EDA,启动!」")),
|
|
392
|
+
h("span", { className: "eda-cta-c" }, copied ? "已复制 ✓" : "复制"))
|
|
393
|
+
: h("p", { className: "eda-note" }, "连上画板后,在对话里描述需求即可实时生成;离线导出仅作兜底。"),
|
|
394
|
+
install?.result ? h("p", { className: "eda-note" }, install.result) : null,
|
|
395
|
+
bridge?.result ? h("p", { className: "eda-note" }, bridge.result) : null);
|
|
276
396
|
}
|
|
277
397
|
|
|
278
|
-
|
|
279
|
-
function ConnectWizard({ open, setOpen }) {
|
|
398
|
+
function ConnectGuide({ open, setOpen }) {
|
|
280
399
|
if (!open) {
|
|
281
|
-
return h("button", { className: "eda-btn
|
|
400
|
+
return h("button", { className: "eda-btn", style: { width: "100%" }, onClick: () => setOpen(true) },
|
|
401
|
+
"连接教程 · 4 步(网页版官方栈)");
|
|
282
402
|
}
|
|
283
403
|
return h("div", { className: "eda-card" },
|
|
284
|
-
h("div", { className: "eda-card-title" }, "
|
|
404
|
+
h("div", { className: "eda-card-title" }, "连接教程"),
|
|
285
405
|
h("div", { className: "eda-steps" }, CONNECT_STEPS.map((s) =>
|
|
286
|
-
h("div", { className: "eda-step", key: s.
|
|
287
|
-
h("
|
|
288
|
-
h("div",
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
406
|
+
h("div", { className: "eda-step", key: s.n },
|
|
407
|
+
h("span", { className: "eda-step-no" }, String(s.n)),
|
|
408
|
+
h("div", null, h("b", null, s.t), h("p", null, s.d))))),
|
|
409
|
+
h("p", { className: "eda-note" },
|
|
410
|
+
h("a", { className: "eda-link", href: LINKS.editor, target: "_blank", rel: "noreferrer", style: { marginRight: 12 } }, "编辑器"),
|
|
411
|
+
h("a", { className: "eda-link", href: LINKS.ext, target: "_blank", rel: "noreferrer", style: { marginRight: 12 } }, "扩展"),
|
|
412
|
+
h("button", { className: "eda-link", onClick: () => setOpen(false),
|
|
413
|
+
style: { border: 0, background: "transparent", cursor: "pointer", padding: 0, font: "inherit" } }, "收起")));
|
|
294
414
|
}
|
|
295
415
|
|
|
296
416
|
/**
|
|
297
|
-
*
|
|
298
|
-
* numbered
|
|
299
|
-
* 撤回 (deletes the primitives that step created) or expanded; the card
|
|
300
|
-
* has 清空记录. When nothing has happened yet, a static capability
|
|
301
|
-
* preview keeps the panel informative (not blank).
|
|
417
|
+
* Record-style timeline (persisted on disk → never blank). Each step is
|
|
418
|
+
* numbered, expandable, and revocable while the bridge is connected.
|
|
302
419
|
*/
|
|
303
|
-
function
|
|
420
|
+
function Timeline({ feed, pinned, setSid, connected, onRevoke, busyId, onClear, clearing, note }) {
|
|
304
421
|
const [expanded, setExpanded] = useState(() => new Set());
|
|
305
|
-
const toggle = (id) => {
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
const
|
|
313
|
-
const sids = Array.isArray(sessions) ? sessions : [];
|
|
314
|
-
const hasMulti = sids.length > 1;
|
|
422
|
+
const toggle = (id) => setExpanded((prev) => {
|
|
423
|
+
const next = new Set(prev);
|
|
424
|
+
if (next.has(id)) next.delete(id); else next.add(id);
|
|
425
|
+
return next;
|
|
426
|
+
});
|
|
427
|
+
const list = feed.activities;
|
|
428
|
+
const sids = feed.sessions;
|
|
429
|
+
const multi = sids.length > 1;
|
|
315
430
|
return h("div", { className: "eda-card" },
|
|
316
|
-
h("div", { className: "eda-
|
|
317
|
-
h("div", { className: "eda-card-title" }, "Agent
|
|
318
|
-
|
|
431
|
+
h("div", { className: "eda-tl-head" },
|
|
432
|
+
h("div", { className: "eda-card-title" }, "Agent · 官方 API"),
|
|
433
|
+
multi
|
|
319
434
|
? h("select", {
|
|
320
|
-
className: "eda-
|
|
321
|
-
value: pinned ?? "",
|
|
322
|
-
onChange: (e) => setSid(e.target.value),
|
|
435
|
+
className: "eda-select", value: pinned ?? "", onChange: (e) => setSid(e.target.value),
|
|
323
436
|
title: "切换会话(默认跟随最新)",
|
|
324
437
|
},
|
|
325
|
-
h("option", { value: "" }, "
|
|
326
|
-
sids.map((s) => h("option", { value: s.sid ?? "", key: (s.sid || "
|
|
327
|
-
:
|
|
438
|
+
h("option", { value: "" }, "跟随最新"),
|
|
439
|
+
sids.map((s) => h("option", { value: s.sid ?? "", key: (s.sid || "platform") + s.lastTs }, s.label ?? "会话")))
|
|
440
|
+
: null,
|
|
328
441
|
list.length > 0
|
|
329
|
-
? h("button", { className: "eda-btn
|
|
442
|
+
? h("button", { className: "eda-btn tiny", disabled: clearing, onClick: onClear, title: "清空时间线(含磁盘历史)" },
|
|
443
|
+
clearing ? "清空…" : "清空")
|
|
330
444
|
: null),
|
|
331
445
|
list.length === 0
|
|
332
446
|
? h("div", null,
|
|
333
|
-
h("div", { className: "eda-
|
|
334
|
-
? "
|
|
335
|
-
: "
|
|
336
|
-
h("div", { className: "eda-hints" },
|
|
337
|
-
|
|
338
|
-
.map((t, i) => h("div", { className: "eda-hint", key: i }, "• " + t))))
|
|
447
|
+
h("div", { className: "eda-empty" }, feed.error
|
|
448
|
+
? "实时活动流未就绪(服务端模块未加载)。"
|
|
449
|
+
: "还没有记录。历史写入本机 activity.jsonl,面板不会空着。可以让 agent:"),
|
|
450
|
+
h("div", { className: "eda-hints" }, HINTS.map((t, i) =>
|
|
451
|
+
h("div", { className: "eda-hint", key: i }, h("s", null, "·"), h("span", null, t)))))
|
|
339
452
|
: h("div", null,
|
|
340
|
-
h("div", { className: "eda-
|
|
341
|
-
const
|
|
342
|
-
const
|
|
343
|
-
const
|
|
344
|
-
const
|
|
453
|
+
h("div", { className: "eda-tl" }, list.slice(0, 60).map((a, i) => {
|
|
454
|
+
const pend = a.status === "pending";
|
|
455
|
+
const open = expanded.has(a.id);
|
|
456
|
+
const revokable = connected && !pend && Array.isArray(a.revoke?.created) && a.revoke.created.length > 0;
|
|
457
|
+
const time = String(a.ts ?? "").slice(11, 19);
|
|
458
|
+
const meta = pend
|
|
459
|
+
? h("span", { className: "eda-pend" }, "执行中…")
|
|
460
|
+
: [time, a.durationMs ? a.durationMs + "ms" : "", a.tool ?? ""].filter(Boolean).join(" · ");
|
|
345
461
|
return h("div", {
|
|
346
|
-
className: "eda-
|
|
347
|
-
key: a.id ?? i,
|
|
348
|
-
onClick: () => toggle(a.id),
|
|
462
|
+
className: "eda-row " + (pend ? "pend" : a.ok === false ? "err" : a.ok ? "ok" : ""),
|
|
463
|
+
key: a.id ?? i, onClick: () => toggle(a.id),
|
|
349
464
|
},
|
|
350
|
-
h("span", { className: "eda-
|
|
351
|
-
h("div", { className: "eda-
|
|
352
|
-
h("div", { className: "eda-
|
|
353
|
-
h("span", { className: "eda-
|
|
354
|
-
h("span", { className: "eda-
|
|
355
|
-
h("span", { className: "eda-
|
|
356
|
-
? h("span", { className: "eda-pend" }, "执行中…")
|
|
357
|
-
: (t + (a.durationMs ? " · " + a.durationMs + "ms" : "") + " · " + (a.tool ?? ""))),
|
|
465
|
+
h("span", { className: "eda-row-dot" }),
|
|
466
|
+
h("div", { className: "eda-row-body" },
|
|
467
|
+
h("div", { className: "eda-row-line" },
|
|
468
|
+
h("span", { className: "eda-seq" }, "#" + (a.id ?? i)),
|
|
469
|
+
h("span", { className: "eda-row-name" }, a.action ?? a.tool ?? "调用 API"),
|
|
470
|
+
h("span", { className: "eda-row-meta" }, meta),
|
|
358
471
|
revokable
|
|
359
472
|
? h("button", {
|
|
360
|
-
className: "eda-btn
|
|
361
|
-
disabled: busyId === a.id,
|
|
473
|
+
className: "eda-btn tiny", disabled: busyId === a.id,
|
|
362
474
|
onClick: (e) => { e.stopPropagation(); onRevoke(a.id); },
|
|
363
475
|
title: "撤回该步(删除它新建的图元)",
|
|
364
|
-
}, busyId === a.id ? "
|
|
476
|
+
}, busyId === a.id ? "撤回…" : "撤回")
|
|
365
477
|
: null),
|
|
366
|
-
a.code ? h("div", { className: "eda-
|
|
367
|
-
!
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
478
|
+
a.code ? h("div", { className: "eda-row-code" }, a.code) : null,
|
|
479
|
+
!pend && a.ok === false && a.error
|
|
480
|
+
? h("div", { className: "eda-row-out err" }, a.error)
|
|
481
|
+
: !pend && a.result ? h("div", { className: "eda-row-out" }, a.result) : null,
|
|
482
|
+
open ? h("div", { className: "eda-row-full" },
|
|
483
|
+
a.code ? h("div", null, h("i", null, "代码"), a.code) : null,
|
|
484
|
+
a.revoke ? h("div", null, h("i", null, "撤回数据"),
|
|
485
|
+
`新建 ${a.revoke.created.length} 图元` + (a.revoke.deletedCount ? ` · 删除 ${a.revoke.deletedCount}(不可恢复)` : "")) : null,
|
|
486
|
+
a.result ? h("div", null, h("i", null, "结果"), a.result) : null,
|
|
487
|
+
a.error ? h("div", null, h("i", null, "错误"), a.error) : null) : null));
|
|
374
488
|
})),
|
|
375
|
-
h("div", { className: "eda-
|
|
489
|
+
h("div", { className: "eda-tl-foot" }, (multi ? "下拉切换会话 · " : "") + "点击条目展开 · 撤回只删该步新建图元")),
|
|
490
|
+
note ? h("p", { className: "eda-note", style: { wordBreak: "break-word" } }, note) : null);
|
|
376
491
|
}
|
|
377
492
|
|
|
378
|
-
/**
|
|
379
|
-
|
|
380
|
-
* AND the agent action log to local disk — a safety net if the cloud sync
|
|
381
|
-
* ever fails. Works (log-only) even when the bridge is disconnected.
|
|
382
|
-
*/
|
|
383
|
-
function SnapshotCard({ connected, busy, onSave, lastOut }) {
|
|
493
|
+
/** Emergency save: board state (.epro2 + SVG + netlist/BOM) + action log → disk. */
|
|
494
|
+
function SnapshotCard({ connected, state, onSave }) {
|
|
384
495
|
return h("div", { className: "eda-card" },
|
|
385
|
-
h("div", { className: "eda-card-title" }, "
|
|
386
|
-
h("button", { className: "eda-btn primary big", disabled: busy, onClick: onSave },
|
|
387
|
-
busy ? "保存中…" : "🛟
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
: "画板未连接:仍会保存 agent 动作日志(每一步留档)。"));
|
|
496
|
+
h("div", { className: "eda-card-title" }, "紧急保存"),
|
|
497
|
+
h("button", { className: "eda-btn primary big", disabled: state.busy, onClick: onSave },
|
|
498
|
+
state.busy ? "保存中…" : "🛟 保存画板到本地"),
|
|
499
|
+
h("p", { className: "eda-muted", style: { marginTop: 8 } }, connected
|
|
500
|
+
? "专业版 .epro2(可完整恢复)+ 预览 SVG + 网表/BOM。云端没同步上也能找回最后的工程。"
|
|
501
|
+
: "画板未连接:仍会保存 agent 动作日志,每一步留档。"),
|
|
502
|
+
state.out ? h("p", { className: "eda-note", style: { wordBreak: "break-all" } }, state.out) : null);
|
|
393
503
|
}
|
|
394
|
-
//#endregion
|
|
395
504
|
|
|
396
|
-
|
|
397
|
-
function EdaPanel({
|
|
505
|
+
/** Panel shell: top bar → scroll body → footer. */
|
|
506
|
+
function EdaPanel({ store }) {
|
|
398
507
|
const [status, error] = useStatus();
|
|
399
508
|
const ready = status?.connected === true;
|
|
400
|
-
const
|
|
401
|
-
const
|
|
402
|
-
const [
|
|
403
|
-
const [
|
|
404
|
-
const [
|
|
405
|
-
const [
|
|
509
|
+
const [pinned, setPinned] = useState("");
|
|
510
|
+
const feed = useActivity(pinned);
|
|
511
|
+
const [guide, setGuide] = useState(false);
|
|
512
|
+
const [install, setInstall] = useState({ busy: false, result: null });
|
|
513
|
+
const [bridge, setBridge] = useState({ busy: false, result: null });
|
|
514
|
+
const [save, setSave] = useState({ busy: false, out: null });
|
|
515
|
+
const [revoke, setRevoke] = useState({ busyId: null, out: null });
|
|
406
516
|
const [clearing, setClearing] = useState(false);
|
|
407
517
|
|
|
408
|
-
const
|
|
409
|
-
|
|
410
|
-
|
|
518
|
+
const post = (path) => fetch(API_BASE + path, {
|
|
519
|
+
method: "POST", headers: { "content-type": "application/json" }, body: "{}",
|
|
520
|
+
});
|
|
521
|
+
|
|
522
|
+
const doInstall = async () => {
|
|
523
|
+
if (install.busy) return;
|
|
524
|
+
setInstall({ busy: true, result: null });
|
|
411
525
|
try {
|
|
412
|
-
const res = await
|
|
413
|
-
if (!res.ok) {
|
|
526
|
+
const res = await post("/install");
|
|
527
|
+
if (!res.ok) { setInstall({ busy: false, result: "安装接口未就绪(旧模块),可对 AI 说「连接我的画板」。" }); return; }
|
|
414
528
|
const out = await res.json();
|
|
415
|
-
|
|
416
|
-
} catch (
|
|
529
|
+
setInstall({ busy: false, result: out.ok ? "✅ " + (out.script ?? "官方桥已安装") : "❌ " + (out.error ?? "安装失败") });
|
|
530
|
+
} catch (e) { setInstall({ busy: false, result: "请求失败:" + String(e) }); }
|
|
417
531
|
};
|
|
418
|
-
const
|
|
419
|
-
if (
|
|
420
|
-
|
|
532
|
+
const doStart = async () => {
|
|
533
|
+
if (bridge.busy) return;
|
|
534
|
+
setBridge({ busy: true, result: null });
|
|
421
535
|
try {
|
|
422
|
-
const res = await
|
|
423
|
-
if (!res.ok) {
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
536
|
+
const res = await post("/bridge");
|
|
537
|
+
if (!res.ok) { setBridge({ busy: false, result: "启动接口未就绪(旧模块),可对 AI 说「连接我的画板」。" }); return; }
|
|
538
|
+
const out = await res.json();
|
|
539
|
+
setBridge({ busy: false, result: out.ok ? `已启动(${out.state})` : `未启动:${out.error || out.note || "请先安装桥接"}` });
|
|
540
|
+
} catch (e) { setBridge({ busy: false, result: "请求失败:" + String(e) }); }
|
|
427
541
|
};
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
setInstallState({ busy: true, result: null });
|
|
542
|
+
const doSave = async () => {
|
|
543
|
+
if (save.busy) return;
|
|
544
|
+
setSave({ busy: true, out: null });
|
|
432
545
|
try {
|
|
433
|
-
const res = await
|
|
434
|
-
if (!res.ok) {
|
|
546
|
+
const res = await post("/snapshot");
|
|
547
|
+
if (!res.ok) { setSave({ busy: false, out: "紧急保存接口未就绪(旧模块),可对 AI 说「紧急保存」。" }); return; }
|
|
435
548
|
const out = await res.json();
|
|
436
|
-
|
|
437
|
-
|
|
549
|
+
setSave({
|
|
550
|
+
busy: false,
|
|
551
|
+
out: out.ok
|
|
552
|
+
? `✅ ${out.files?.length ?? 0} 个文件 → ${out.dir ?? ""}` + ((out.errors?.length ?? 0) > 0 ? `(${out.errors.length} 项降级)` : "")
|
|
553
|
+
: "❌ " + String(out.error ?? "保存失败"),
|
|
554
|
+
});
|
|
555
|
+
} catch (e) { setSave({ busy: false, out: "请求失败:" + String(e) }); }
|
|
438
556
|
};
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
setBridgeState({ busy: true, result: null });
|
|
557
|
+
const doRevoke = async (id) => {
|
|
558
|
+
if (revoke.busyId !== null) return;
|
|
559
|
+
setRevoke({ busyId: id, out: null });
|
|
443
560
|
try {
|
|
444
|
-
const res = await fetch(API_BASE + "/
|
|
445
|
-
|
|
561
|
+
const res = await fetch(API_BASE + "/activity/revoke?id=" + encodeURIComponent(id), {
|
|
562
|
+
method: "POST", headers: { "content-type": "application/json" }, body: "{}",
|
|
563
|
+
});
|
|
564
|
+
if (!res.ok) { setRevoke({ busyId: null, out: "撤回接口未就绪(旧模块)。" }); return; }
|
|
446
565
|
const out = await res.json();
|
|
447
|
-
|
|
448
|
-
} catch (
|
|
566
|
+
setRevoke({ busyId: null, out: out.ok ? "↩️ 已撤回:" + (out.note ?? "") : "⚠️ " + String(out.error ?? "撤回失败") });
|
|
567
|
+
} catch (e) { setRevoke({ busyId: null, out: "请求失败:" + String(e) }); }
|
|
449
568
|
};
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
setSaveState({ busy: true, out: null });
|
|
569
|
+
const doClear = async () => {
|
|
570
|
+
if (clearing) return;
|
|
571
|
+
setClearing(true);
|
|
454
572
|
try {
|
|
455
|
-
const res = await
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
else setSaveState({ busy: false, out: `✅ 已保存 ${out.files?.length ?? 0} 个文件 → ${out.dir ?? ""}${(out.errors?.length ?? 0) > 0 ? `(${out.errors.length} 项降级:${out.errors.slice(0, 2).join(";")})` : ""}` });
|
|
460
|
-
} catch (err) { setSaveState({ busy: false, out: "请求失败:" + String(err) }); }
|
|
573
|
+
const res = await post("/activity/clear");
|
|
574
|
+
setRevoke({ busyId: null, out: res.ok ? "🗑️ 时间线已清空" : "清空接口未就绪(旧模块)。" });
|
|
575
|
+
} catch (e) { setRevoke({ busyId: null, out: "请求失败:" + String(e) }); }
|
|
576
|
+
finally { setClearing(false); }
|
|
461
577
|
};
|
|
462
578
|
|
|
463
|
-
return h("div", { className: "eda-
|
|
464
|
-
h("div", { className: "eda-
|
|
465
|
-
h(
|
|
466
|
-
h("div", { className: "eda-
|
|
467
|
-
h("
|
|
468
|
-
h("
|
|
469
|
-
h(
|
|
579
|
+
return h("div", { className: "dsh-eda-root" },
|
|
580
|
+
h("div", { className: "eda-top" },
|
|
581
|
+
h(Mark, null),
|
|
582
|
+
h("div", { className: "eda-title" },
|
|
583
|
+
h("b", null, "嘉立创 EDA"),
|
|
584
|
+
h("span", null, "official bridge · v" + (status?.version ?? "—"))),
|
|
585
|
+
h(UpdatePill, { status }),
|
|
586
|
+
h("button", { className: "eda-iconbtn", onClick: () => store.set(false), title: "关闭面板", "aria-label": "关闭" }, "✕")),
|
|
470
587
|
h("div", { className: "eda-scroll" },
|
|
471
|
-
h(ConnectCard, { status, error, onInstall: doInstall,
|
|
472
|
-
h(
|
|
473
|
-
h(
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
588
|
+
h(ConnectCard, { status, error, install, bridge, onInstall: doInstall, onStart: doStart }),
|
|
589
|
+
h(ConnectGuide, { open: guide, setOpen: setGuide }),
|
|
590
|
+
h(Timeline, {
|
|
591
|
+
feed, pinned, setSid: setPinned, connected: ready,
|
|
592
|
+
onRevoke: doRevoke, busyId: revoke.busyId, onClear: doClear, clearing,
|
|
593
|
+
note: revoke.out,
|
|
594
|
+
}),
|
|
595
|
+
h(SnapshotCard, { connected: ready, state: save, onSave: doSave })),
|
|
596
|
+
h("div", { className: "eda-foot" }, "对话里生成(官方 eda.* API) · 本地留档(紧急保存)"));
|
|
477
597
|
}
|
|
478
|
-
//#endregion
|
|
479
598
|
|
|
480
|
-
|
|
481
|
-
|
|
599
|
+
/** Overlay wrapper: mounted in `shell.overlay`; `hidden` toggles visibility so
|
|
600
|
+
* the feed keeps running while the panel is closed (same surface as 0.1.x). */
|
|
601
|
+
function EdaOverlay({ store }) {
|
|
602
|
+
const open = useStore(store);
|
|
603
|
+
const [width, setWidth] = useState(() => {
|
|
604
|
+
try { return Math.min(760, Math.max(120, Number(localStorage.getItem("dsh-eda:width")) || 400)); } catch (e) { return 400; }
|
|
605
|
+
});
|
|
606
|
+
const drag = useRef(null);
|
|
607
|
+
const startDrag = (e) => {
|
|
608
|
+
e.preventDefault();
|
|
609
|
+
const move = (ev) => {
|
|
610
|
+
const next = Math.min(760, Math.max(120, window.innerWidth - ev.clientX));
|
|
611
|
+
drag.current = next;
|
|
612
|
+
setWidth(next);
|
|
613
|
+
};
|
|
614
|
+
const up = () => {
|
|
615
|
+
window.removeEventListener("mousemove", move);
|
|
616
|
+
window.removeEventListener("mouseup", up);
|
|
617
|
+
if (drag.current !== null) { try { localStorage.setItem("dsh-eda:width", String(drag.current)); } catch (err) { /* ignore */ } }
|
|
618
|
+
};
|
|
619
|
+
window.addEventListener("mousemove", move);
|
|
620
|
+
window.addEventListener("mouseup", up);
|
|
621
|
+
};
|
|
622
|
+
return h("div", { className: "dsh-eda-root", hidden: !open, style: { "--eda-w": width + "px" } },
|
|
623
|
+
h("div", { className: "dsh-eda-grip", onMouseDown: startDrag, title: "拖动调整宽度" }),
|
|
624
|
+
h(EdaPanel, { store }));
|
|
625
|
+
}
|
|
626
|
+
//#endregion
|
|
482
627
|
|
|
628
|
+
//#region mounts (0.1.x compatibility)
|
|
483
629
|
function sidebarRoot() {
|
|
484
630
|
const column = document.querySelector('[data-pane="sidebar"], [class*="sidebarCol"]');
|
|
485
631
|
if (column === null) return undefined;
|
|
486
632
|
const logoOwner = column.querySelector('[class*="logoRow"]')?.parentElement;
|
|
487
633
|
return logoOwner ?? (column.firstElementChild ?? undefined);
|
|
488
634
|
}
|
|
489
|
-
|
|
490
635
|
function newSessionButton(root) {
|
|
491
636
|
const nested = root.querySelector('button[class*="newSession"]');
|
|
492
637
|
if (nested !== null) return nested;
|
|
493
|
-
for (const child of root.children)
|
|
494
|
-
if (child.tagName === "BUTTON") return child;
|
|
495
|
-
}
|
|
638
|
+
for (const child of root.children) if (child.tagName === "BUTTON") return child;
|
|
496
639
|
return undefined;
|
|
497
640
|
}
|
|
498
|
-
|
|
499
|
-
function createEntry(controller) {
|
|
641
|
+
function createEntry(store) {
|
|
500
642
|
const entry = document.createElement("button");
|
|
501
643
|
entry.type = "button";
|
|
502
644
|
entry.dataset.dshEdaEntry = "";
|
|
503
645
|
entry.setAttribute("aria-label", "嘉立创 EDA 助手");
|
|
504
|
-
entry.setAttribute("title", "嘉立创 EDA
|
|
505
|
-
entry.innerHTML = '<span class="eda-entry-icon"
|
|
506
|
-
entry.addEventListener("click", () =>
|
|
646
|
+
entry.setAttribute("title", "嘉立创 EDA 助手(官方画板平台)");
|
|
647
|
+
entry.innerHTML = '<span class="eda-entry-icon"><svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.2" aria-hidden="true"><path d="' + ICON_EDA + '" stroke-linejoin="round" stroke-linecap="round"/></svg></span><span class="eda-entry-label">嘉立创 EDA</span>';
|
|
648
|
+
entry.addEventListener("click", () => store.toggle());
|
|
507
649
|
return entry;
|
|
508
650
|
}
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
const button = newSessionButton(root);
|
|
512
|
-
if (button === undefined) return false;
|
|
513
|
-
if (entry.parentElement !== root) {
|
|
514
|
-
const row = button.closest('[class*="logoRow"]');
|
|
515
|
-
const base = (row !== null && row.parentElement === root) ? row : button;
|
|
516
|
-
const family = Array.from(root.children).filter(
|
|
517
|
-
(el) => el instanceof HTMLElement && el.matches("[data-dsh-taskboard-entry], [data-dsh-ssh-entry], [data-dsh-logcat-entry], [data-dsh-eda-entry]"),
|
|
518
|
-
);
|
|
519
|
-
const anchor = family.length > 0 ? family[family.length - 1].nextElementSibling : base.nextElementSibling;
|
|
520
|
-
root.insertBefore(entry, anchor);
|
|
521
|
-
}
|
|
522
|
-
return true;
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
function mountSidebarEntry(controller) {
|
|
526
|
-
const entry = createEntry(controller);
|
|
651
|
+
function mountSidebarEntry(store) {
|
|
652
|
+
const entry = createEntry(store);
|
|
527
653
|
let root;
|
|
528
654
|
let placed = false;
|
|
529
655
|
let rootObserver;
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
if (
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
656
|
+
const place = () => {
|
|
657
|
+
const button = newSessionButton(root);
|
|
658
|
+
if (button === undefined) return false;
|
|
659
|
+
if (entry.parentElement !== root) {
|
|
660
|
+
const row = button.closest('[class*="logoRow"]');
|
|
661
|
+
const base = row !== null && row.parentElement === root ? row : button;
|
|
662
|
+
const family = Array.from(root.children).filter((el) =>
|
|
663
|
+
el instanceof HTMLElement && el.matches("[data-dsh-taskboard-entry], [data-dsh-ssh-entry], [data-dsh-logcat-entry], [data-dsh-eda-entry]"));
|
|
664
|
+
const anchor = family.length > 0 ? family[family.length - 1].nextElementSibling : base.nextElementSibling;
|
|
665
|
+
root.insertBefore(entry, anchor);
|
|
536
666
|
}
|
|
537
|
-
|
|
538
|
-
|
|
667
|
+
return true;
|
|
668
|
+
};
|
|
669
|
+
const tryPlace = () => {
|
|
670
|
+
if (root !== undefined && (!root.isConnected || (placed && !document.body.contains(entry)))) {
|
|
539
671
|
rootObserver?.disconnect();
|
|
540
672
|
root = undefined;
|
|
541
673
|
placed = false;
|
|
542
674
|
}
|
|
675
|
+
if (placed) return;
|
|
543
676
|
root ??= sidebarRoot();
|
|
544
677
|
if (root === undefined) return;
|
|
545
|
-
placed =
|
|
678
|
+
placed = place();
|
|
546
679
|
if (placed) {
|
|
547
680
|
rootObserver = new MutationObserver(() => {
|
|
548
681
|
if (root === undefined || !root.isConnected) { placed = false; tryPlace(); return; }
|
|
549
|
-
if (!root.contains(entry)) placed =
|
|
682
|
+
if (!root.contains(entry)) placed = place();
|
|
550
683
|
});
|
|
551
684
|
rootObserver.observe(root, { childList: true, subtree: true });
|
|
552
685
|
}
|
|
553
686
|
};
|
|
554
|
-
|
|
555
|
-
const waitObserver = new MutationObserver(() => { tryPlace(); });
|
|
687
|
+
const waitObserver = new MutationObserver(() => tryPlace());
|
|
556
688
|
waitObserver.observe(document.body, { childList: true, subtree: true });
|
|
557
|
-
|
|
558
|
-
const
|
|
559
|
-
|
|
560
|
-
else delete entry.dataset.active;
|
|
561
|
-
};
|
|
562
|
-
const unsubscribe = controller.subscribe(syncActive);
|
|
563
|
-
syncActive();
|
|
689
|
+
const sync = () => { if (store.get()) entry.dataset.active = "true"; else delete entry.dataset.active; };
|
|
690
|
+
const unsubscribe = store.subscribe(sync);
|
|
691
|
+
sync();
|
|
564
692
|
tryPlace();
|
|
565
|
-
|
|
566
693
|
return () => {
|
|
567
694
|
waitObserver.disconnect();
|
|
568
695
|
rootObserver?.disconnect();
|
|
@@ -571,86 +698,83 @@ window.__ModuleLoader__.load({
|
|
|
571
698
|
};
|
|
572
699
|
}
|
|
573
700
|
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
const panel = document.createElement("div");
|
|
587
|
-
panel.className = "dsh-eda-panel";
|
|
588
|
-
container.appendChild(panel);
|
|
589
|
-
document.body.appendChild(container);
|
|
590
|
-
root = createRoot(panel);
|
|
591
|
-
root.render(h(EdaPanel, { controller }));
|
|
592
|
-
};
|
|
593
|
-
|
|
594
|
-
ensure();
|
|
595
|
-
|
|
596
|
-
const applyOpen = () => {
|
|
597
|
-
if (container !== undefined) container.hidden = !controller.getSnapshot().panelOpen;
|
|
598
|
-
};
|
|
599
|
-
const unsubscribe = controller.subscribe(applyOpen);
|
|
600
|
-
applyOpen();
|
|
601
|
-
|
|
701
|
+
/**
|
|
702
|
+
* Fallback mount for shells without the slots service (and for the unit
|
|
703
|
+
* test's DOM stub): a body-level overlay. Still absolute-in-shell friendly:
|
|
704
|
+
* z-index stays low (40) and the panel keeps its own close affordance.
|
|
705
|
+
*/
|
|
706
|
+
function mountFallback(store) {
|
|
707
|
+
const container = document.createElement("div");
|
|
708
|
+
container.dataset.dshEdaView = "";
|
|
709
|
+
container.className = "dsh-eda-fallback";
|
|
710
|
+
const root = createRoot(container);
|
|
711
|
+
document.body.appendChild(container);
|
|
712
|
+
root.render(h(EdaOverlay, { store }));
|
|
602
713
|
return () => {
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
root = undefined;
|
|
606
|
-
container?.remove();
|
|
607
|
-
container = undefined;
|
|
714
|
+
root.unmount();
|
|
715
|
+
container.remove();
|
|
608
716
|
};
|
|
609
717
|
}
|
|
610
718
|
//#endregion
|
|
611
719
|
|
|
612
|
-
//#region controller
|
|
613
|
-
/** Minimal open/close controller: panelOpen + a tiny subscribe store. */
|
|
614
|
-
function PanelController() {
|
|
615
|
-
let panelOpen = false;
|
|
616
|
-
const listeners = new Set();
|
|
617
|
-
this.toggle = () => { panelOpen = !panelOpen; for (const fn of listeners) fn(); };
|
|
618
|
-
this.getSnapshot = () => ({ panelOpen });
|
|
619
|
-
this.subscribe = (fn) => { listeners.add(fn); return () => { listeners.delete(fn); }; };
|
|
620
|
-
}
|
|
621
|
-
//#endregion
|
|
622
|
-
|
|
623
720
|
//#region entry
|
|
624
|
-
/** Required services (fiber inject waiting — the runtime must be up first). */
|
|
625
721
|
const inject = ["slots"];
|
|
626
722
|
|
|
627
723
|
/**
|
|
628
|
-
* Mount the
|
|
724
|
+
* Mount the panel: 0.2 registers into `shell.overlay` + a header utility pill;
|
|
725
|
+
* 0.1.x keeps the sidebar DOM entry. Anything unavailable degrades quietly.
|
|
629
726
|
* @param ctx - client root context.
|
|
630
727
|
*/
|
|
631
728
|
function apply(ctx) {
|
|
632
729
|
const style = document.createElement("style");
|
|
633
|
-
style.textContent = STYLE;
|
|
730
|
+
style.textContent = STYLE + "\n.dsh-eda-fallback { position: fixed; inset: 0; pointer-events: none; z-index: 40; }\n.dsh-eda-fallback > .dsh-eda-root { pointer-events: auto; }";
|
|
634
731
|
style.dataset.dshEdaStyle = "";
|
|
635
732
|
document.head.appendChild(style);
|
|
636
733
|
|
|
637
|
-
const
|
|
734
|
+
const store = new PanelStore();
|
|
638
735
|
const disposers = [];
|
|
736
|
+
let slotRegistered = false;
|
|
737
|
+
|
|
639
738
|
try {
|
|
640
|
-
|
|
641
|
-
|
|
739
|
+
const slots = typeof ctx.get === "function" ? ctx.get("slots") : undefined;
|
|
740
|
+
if (slots !== undefined && slots !== null) {
|
|
741
|
+
disposers.push(slots.inject("conversation.session.header.utilities", () => slots.register(
|
|
742
|
+
{ name: "conversation.session.header.utilities", id: "eda-toggle", order: 30 },
|
|
743
|
+
() => h(HeaderPill, { store }),
|
|
744
|
+
)));
|
|
745
|
+
disposers.push(slots.inject("shell.overlay", () => slots.register(
|
|
746
|
+
{ name: "shell.overlay", id: "eda", order: 90 },
|
|
747
|
+
() => h(EdaOverlay, { store }),
|
|
748
|
+
)));
|
|
749
|
+
slotRegistered = true;
|
|
750
|
+
}
|
|
642
751
|
} catch (error) {
|
|
643
|
-
console.warn("[dsh-eda]
|
|
752
|
+
console.warn("[dsh-eda] slot registration failed, falling back to DOM mount", error);
|
|
644
753
|
}
|
|
754
|
+
|
|
755
|
+
try {
|
|
756
|
+
disposers.push(mountSidebarEntry(store));
|
|
757
|
+
} catch (error) {
|
|
758
|
+
console.warn("[dsh-eda] sidebar entry failed", error);
|
|
759
|
+
}
|
|
760
|
+
if (!slotRegistered) {
|
|
761
|
+
try {
|
|
762
|
+
disposers.push(mountFallback(store));
|
|
763
|
+
} catch (error) {
|
|
764
|
+
console.warn("[dsh-eda] fallback mount failed", error);
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
|
|
645
768
|
ctx.effect(() => () => {
|
|
646
769
|
for (const dispose of disposers.splice(0)) dispose();
|
|
647
770
|
style.remove();
|
|
648
|
-
}, "dsh-eda:
|
|
771
|
+
}, "dsh-eda: browser UI");
|
|
649
772
|
}
|
|
650
|
-
//#endregion
|
|
651
773
|
|
|
652
774
|
exports.apply = apply;
|
|
653
775
|
exports.inject = inject;
|
|
776
|
+
// Test seam (bundle runtime test renders the update pill directly).
|
|
777
|
+
exports.UpdatePill = UpdatePill;
|
|
654
778
|
return module.exports;
|
|
655
|
-
}
|
|
779
|
+
},
|
|
656
780
|
});
|