# dsh-easyeda-bridge A DeepSeek Harness (DSH) plugin that embeds an **easyeda-bridge WebSocket gateway**, letting DSH drive an open **EasyEDA Pro (嘉立创EDA 专业版)** window directly. Companion EDA extension: [run-api-gateway](https://jlc-ext.com/item/oshwhub/run-api-gateway) ``` ┌──────────┐ WS(/eda) ┌──────────────────────────┐ HTTP/WS ┌──────────────┐ │ DSH │ ◄────────► │ This plugin (bridge) │ ◄────────► │ EasyEDA │ │ (Agent) │ 5 tools │ 127.0.0.1:49620-49629 │ auto │ (Pro Client)│ └──────────┘ └──────────────────────────┘ └──────────────┘ ``` ## Features - **Protocol-compatible** with the official `easyeda-api-skill` `scripts/bridge-server.mjs`: the EDA extension connects to `ws://127.0.0.1:/eda` → server sends `handshake(service=easyeda-bridge)` → extension `register(windowId)` → server sends `execute(id, code)` → extension runs and replies `result/error`. - **Dual-mode auto-switching**: - `own` — no bridge in the port range (default 49620-49629) → the plugin hosts an HTTP+WS server in-process. - `adopt` — another bridge already exists (e.g. the official `bridge-server` started by OpenCode) → reuse its HTTP API, so the EDA extension never connects to a second bridge and calls go to the right one; the own-to-adopt switch is self-healing. - **Five model-facing tools**: | Tool | Purpose | |------|---------| | `easyeda_status` | Bridge/EDA state, current document & schematic page, page-frame bounds, troubleshooting hints | | `easyeda_windows` | List connected windows; `selectWindowId` to switch the active window | | `easyeda_device` | Find devices: `query` keyword search (with `limit`) / `cNumber` LCSC C-number exact lookup, returns name/libraryUuid/deviceUuid/footprint | | `easyeda_execute` | Run `async (eda) => { … }` JS in a target window and return the result | | `easyeda_docs` | Search the bundled official API reference (`query` for signatures / `doc` for a full doc) | - **Bundled official API docs** (`docs/`, vendored from [easyeda/easyeda-api-skill](https://github.com/easyeda/easyeda-api-skill), MIT): 120+ classes, 62 enums, 70 interfaces, plus project/schematic/PCB source-format docs and an extension-dev guide — all offline. - **Official HTTP API surface**: `GET /health`, `GET /eda-windows`, `POST /eda-windows/select`, `POST /execute`, so other AI tools (OpenCode, etc.) can share the same bridge. ## Prerequisites (EDA side) 1. Open EasyEDA Pro (no project needed). 2. Install the **Run API Gateway** extension (see https://jlc-ext.com/item/oshwhub/run-api-gateway). 3. In the extension manager, enable **Allow external interaction** and **Show in top menu**. 4. If the extension loaded before the bridge started, click the **API Gateway → Reconnect** menu item. ## Install into DSH ### Runtime injection (no restart; for development) ```bash # In this plugin directory (make sure lib/ is fresh) DSH_CHECKOUT= bash scripts/build.sh # Inside a DSH environment dev_inject_plugin ``` ### Permanent install (survives restart) ```bash # Inside a DSH environment: writes profile bundles + link dependency and hot-loads it dev_install_package ``` The plugin's `cordis.patch.yml` inserts the `easyeda-bridge` row on assembly (no configuration needed). ## Usage (tell DSH) ``` 嘉立创EDA,启动! ``` DSH will: `easyeda_status` to confirm the bridge/window → (multi-window) `easyeda_windows` to select → `easyeda_execute` to verify with `return await eda.dmt_Project.getCurrentProjectInfo();`. Rules when writing `execute` code (full version in the plugin's systemPrompt guidance): - Code shape is `async (eda) => { … }`; **must `return`** (`console.log` is not captured); `await` all promises. - Runs in the EDA browser context: no Node API; use `eda.sys_*` instead of browser APIs. - Use enum members (e.g. `EPCB_LayerId.TOP`), not raw numbers — look them up via `easyeda_docs` (`references/enums/`). - Units: PCB 1 unit = 1mil (1mm≈39.37); schematic 1 unit = 0.01inch (1mm≈3.937). - Verify document state first: `eda.dmt_Project.getCurrentProjectInfo()` + `eda.dmt_SelectControl.getCurrentDocumentInfo()` (PCB APIs need an active PCB doc). - Modify primitives asynchronously: `const p = await eda.pcb_PrimitiveVia.get([id]); const a = p.toAsync(); a.setState_X(..); a.done()`. ## Development & tests ```bash npm install # install ws deps DSH_CHECKOUT= bash scripts/build.sh node scripts/mock-eda.mjs # end-to-end protocol smoke test (fake EDA extension) node scripts/test-adopt.mjs # adopt-mode test (simulates an existing external bridge) ``` Docs sync: see `docs/README.md` (update from easyeda/easyeda-api-skill). ## License Plugin code is MIT. Bundled docs (`docs/`) come from [easyeda/easyeda-api-skill](https://github.com/easyeda/easyeda-api-skill) (author JLCEDA, MIT); attribution in `docs/README.md`.