mcpField
E
easyeda-api

easyeda-api

github.com/easyedaその他979631 回インストール3 日前に更新
リポジトリ

easyeda-api について

easyeda-apiは、EasyEDA Proを扱うAIエージェント向けのスキルで、API、ドキュメント形式、拡張機能開発を扱います。資料に加え、実行中のEDAクライアントでコードを動かし、動作を確認するWebSocketブリッジを備えています。

主な機能

  1. 01APIクラスと型のリファレンス
  2. 02WebSocketブリッジでのコード実行
  3. 03PCB、回路図、ライブラリ、プロジェクトの操作例
  4. 04プロジェクト、回路図、PCBのソース形式ガイド
  5. 05拡張機能の開発とデバッグ支援

活用シーン

  1. 01EasyEDA拡張機能の開発時にAPIを調べる
  2. 02接続済みEasyEDA Proでコードを実行する
  3. 03EasyEDAドキュメントのソースを確認・編集する
  4. 04PCBや回路図の操作を検証する

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/easyeda/easyeda-api-skill --skill easyeda-api

インストール後、Claude Code で/easyeda-apiを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

README.md
README.zh-Hans.md
format/
index.md
format/pcb/
obj.md
common.md
attr.md
3d.md
dimension.md
component.md
index.md
pad_via.md
panel.md
rule.md
partition.md
primitive.md
text.md
shape.md
format/project/
common.md
group.md
blob.md
index.md
meta.md
variant.md
instance.md
format/schematic/
common.md
obj.md
component.md
index.md
pin.md
shape.md

詳細

EasyEDA Pro API スキル

AI を通じて EasyEDA Pro(嘉立创EDA专业版)をプログラムから操作します。このスキルは以下を提供します。

  1. 完全な API リファレンス — 120 クラス、62 列挙型、70 インターフェース、19 型エイリアス
  2. WebSocket ブリッジ — 実行中の EasyEDA Pro クライアントでコードを実行します
  3. コードパターン — PCB、回路図、ライブラリ、プロジェクト管理でよく使われる操作
  4. ドキュメントソース形式のリファレンス — API を使用せず、EasyEDA ドキュメントのソースを直接解析または変更する必要がある場合に参照できる、プロジェクト、回路図、PCB ソースのファイル形式仕様

このスキルは、EasyEDA でのライブデバッグだけでなく、EasyEDA 拡張機能の開発もサポートします。 EasyEDA 拡張機能の開発中、AI エージェントはこのスキルが提供する拡張機能関連ドキュメント、API リファレンス、型情報、使用例、ブリッジ経由のデバッグ機能を活用して API を調べ、コードを記述し、統合やデバッグ中の動作を検証できます。

アーキテクチャ

┌───────────┐   HTTP/WS     ┌─────────────────┐   WebSocket   ┌───────────┐
│ AI Agent  │ ◄───────────► │  Bridge Server  │ ◄───────────► │  EasyEDA  │
│           │  Port Range   │  (Node.js)      │  Port Range   │  (Client) │
└───────────┘  49620-49629  └─────────────────┘  49620-49629  └───────────┘

サーバーは起動時に、49620-49629 の範囲から利用可能なポートを自動選択します。 AI クライアントと EDA クライアントはどちらもポート範囲をスキャンし、ハンドシェイク(service: "easyeda-bridge")を検証してサーバーを自動検出します。

クイックスタート

1. コマンドトリガー

ユーザーが 「嘉立创EDA,启动!」、「立创EDA,启动!」、または 「EDA,启动!」 と言った場合:

重要:セッションの初期化 — 正しいセッションタイトルを設定するため、すぐに以下の正確なテキストを返信します。

📋 EasyEDA Session

その後、以下のセットアップ手順に進みます。

2. 依存関係をインストールする(必要な場合)
cd ${CLAUDE_SKILL_DIR} && npm install
3. ブリッジサーバーを起動する

⚠️ 重要:ブリッジサーバーはバックグラウンドで実行する必要があります。フォアグラウンドで実行しないでください。サーバーの終了を待つ間、AI がブロックされます。

# Check if bridge is already running
for port in $(seq 49620 49629); do
  resp=$(curl -s http://localhost:$port/health 2>/dev/null)
  if echo "$resp" | grep -q '"easyeda-bridge"'; then
    echo "Bridge already running on port $port"
    BRIDGE_PORT=$port
    break
  fi
done

# Start bridge if not running
if [ -z "$BRIDGE_PORT" ]; then
  node ${CLAUDE_SKILL_DIR}/scripts/bridge-server.mjs &
  sleep 2
  # Find the port bridge is running on
  for port in $(seq 49620 49629); do
    resp=$(curl -s http://localhost:$port/health 2>/dev/null)
    if echo "$resp" | grep -q '"easyeda-bridge"'; then
      BRIDGE_PORT=$port
      break
    fi
  done
fi

echo "Bridge running on port: ${BRIDGE_PORT:-unknown}"
4. EasyEDA を接続する

EasyEDA Pro に run-api-gateway.eext 拡張機能をインストールします。ダウンロードリンク:

拡張機能が読み込まれると、WebSocket 接続が自動的に確立されます。

5. 接続を確認して EDA ウィンドウを選択する
# Check bridge and EDA connection status
curl http://localhost:${BRIDGE_PORT:-49620}/health

# List all connected EDA windows
curl http://localhost:${BRIDGE_PORT:-49620}/eda-windows

/eda-windows の応答は次のようになります。

{
  "windows": [
    { "windowId": "abc-123", "connected": true, "active": true },
    { "windowId": "def-456", "connected": true, "active": false }
  ],
  "activeWindowId": "abc-123",
  "count": 2
}

ウィンドウ数に応じた対応:

  • 0 ウィンドウ:ユーザーに「EasyEDA ウィンドウが接続されていません。EasyEDA 拡張機能(run-api-gateway.eext)が EasyEDA にインストールされ、読み込まれていることを確認してください。ダウンロード先:https://jlc-ext.com/item/oshwhub/run-api-gateway」と伝えます。
  • 1 ウィンドウ:アクティブなウィンドウとして自動選択されます。ユーザーに「✅ 接続しました!アクティブな EDA ウィンドウ:abc-123。作業を開始できます。」と伝えます。
  • 2 つ以上のウィンドウ:利用可能なウィンドウを表示し、ユーザーに選択を求めます。
    Multiple EDA windows detected:
    - abc-123 (active)
    - def-456
    
    Which EDA window should I use?
    

ウィンドウを選択する:

curl -X POST http://localhost:${BRIDGE_PORT}/eda-windows/select \
  -H "Content-Type: application/json" \
  -d '{"windowId": "abc-123"}'

選択後、「✅ アクティブな EDA ウィンドウ:abc-123。作業を開始できます。」と確認します。

6. EDA でコードを実行する
curl -X POST http://localhost:${BRIDGE_PORT:-49620}/execute \
  -H "Content-Type: application/json" \
  -d '{"code": "return await eda.dmt_Project.getCurrentProjectInfo();"}'

API ドキュメント

API リファレンスの全文は references/ ディレクトリにあります。

  • references/_index.md — すべてのクラス、列挙型、インターフェース、型のマスターインデックス
  • references/_quick-reference.md — すばやく参照できる、すべてのメソッドシグネチャ
  • references/classes/ — 120 件のクラスドキュメント(DMT_, PCB_, SCH_, LIB_, SYS_, IPCB_, ISCH_*)
  • references/enums/ — 62 件の列挙型ドキュメント
  • references/interfaces/ — 70 件のインターフェースドキュメント
  • references/types/ — 19 件の型エイリアスドキュメント
API の調べ方
  1. まず _index.md を確認して、タスクに適したクラスやモジュールを探します
  2. クラスのドキュメントを読み(例:references/classes/DMT_Board.md)、すべてのメソッドとシグネチャを確認します
  3. すべてのクラスを対象にメソッドシグネチャをすばやく調べるには、_quick-reference.md を使用します
  4. パラメーター型と戻り値の型は、列挙型/インターフェースを確認します
ドキュメントソース形式のドキュメント

API を使用せずに EasyEDA のドキュメントソースを直接分析または変更する必要がある場合は、format/ ディレクトリ内のドキュメントを使用してください。

  • format/index.md — EasyEDA ドキュメントソース形式のリファレンスとバージョンに関する注記の概要
  • format/project/ — プロジェクトソースの構造、メタデータ、blob、バリアント、グループ化データ
  • format/schematic/ — 回路図ソース形式。構造、配線、図形、ピン、コンポーネント、テーブルを含みます
  • format/pcb/ — PCB ソース形式。プリミティブ、パッドとビア、図形、テキスト、属性、ルール、パネルデータを含みます

ソースのレイアウトを理解する、互換性のあるドキュメントソースを生成する、または後で EasyEDA にインポートし直すソースデータを編集するタスクでは、これらのファイルを使用してください。

API モジュールの概要
PrefixDomainKey Classes
DMT_ドキュメント管理Board, EditorControl, Folder, Panel, Pcb, Project, Schematic, SelectControl, Team, Workspace
PCB_PCB とフットプリントDocument, Drc, Event, Layer, Net, Primitive, PrimitiveComponent, PrimitiveLine, PrimitivePad, PrimitivePour, PrimitiveVia, SelectControl
SCH_回路図Document, Event, Primitive, PrimitiveComponent, PrimitiveWire, SelectControl
LIB_ライブラリ3DModel, Cbb, Classification, Device, Footprint, LibrariesList, PanelLibrary, SelectControl, Symbol
SYS_システムDialog, Environment, FileManager, FileSystem, FontManager, HeaderMenu, I18n, IFrame, LoadingAndProgressBar, Log, Message, MessageBox, MessageBus, PanelControl, Setting, ShortcutKey, Storage, Timer, ToastMessage, WebSocket, Window
IPCB_PCB インターフェース(図元)PrimitiveArc, PrimitiveComponent, PrimitivePad, PrimitiveFill, PrimitivePour, PrimitiveRegion, PrimitiveVia, ...
ISCH_回路図インターフェース(図元)PrimitiveArc, PrimitiveComponent, PrimitiveWire, PrimitiveText, PrimitiveRectangle, ...
EPCB_ / ESCH_列挙型PrimitiveType, Layer, PadType, ...

コード実行コンテキスト

すべてのコードは EasyEDA Pro のブラウザーランタイム内で、次のように実行されます。

async function(eda) {
  // Your code here — `eda` is the global EDA API object
  // You MUST use `return` to send results back
  // Do not add comments to the generated code, as the code is typically executed as a single line
}

重要なルール:

  • eda オブジェクトからすべての API モジュール(例:eda.dmt_Board、eda.pcb_Primitive)にアクセスできます。
  • 正しい使用方法については、必ず API ドキュメントを参照してください。
  • 生成されたコードにコメントを追加しないでください。コードは通常、単一行として実行されるためです。
  • 結果を取得するには、必ず return を使用してください。console.log の出力は取得されません。
  • Promise を返す API メソッドは、すべて await してください。
  • コードはブラウザーコンテキストで実行されるため、Node.js API(fs、path など)は使用できません。
  • ユーザーに表示する通知には、eda.sys_Message.showToastMessage(msg) を使用してください。
  • API ドキュメントを確認する際に列挙型がある場合、列挙値を推測しないでください。PCB プリミティブ作成時のレイヤーパラメーターには 1 ではなく EPCB_LayerId.TOP を使用するなど、列挙型のメンバーを使用する必要があります。
拡張機能のランタイム制約

EasyEDA 拡張機能を作成する際、メインプロセスでは標準のブラウザー API の使用は禁止されています。EDA が提供する代替機能を使用してください。

目的❌ 使用禁止✅ 代わりに使用
ユーザー入力の取得—eda.sys_Dialog.showInputDialog()
ユーザーによる選択—eda.sys_Dialog.showSelectDialog()
メッセージの表示alert()eda.sys_Dialog.showInformationMessage()
アクションの確認confirm()eda.sys_Dialog.showConfirmationMessage()
トースト通知DOM 操作eda.sys_Message.showToastMessage()
データの保存localStorage(メインプロセス)eda.sys_Storage.setExtensionUserConfig(key, value)
カスタム UIホストの DOM の操作eda.sys_IFrame.openIFrame()
HTML の表示showInformationMessage(html)iframe を使用する必要があります
リンクを開くwindow.open()eda.sys_Window.open()
ブラウザーのハードウェア APIメインプロセスでの使用iframe 内で使用可能(navigator.serial など)

注: localStorage、window、document などは sys_IFrame 内では使用できますが、拡張機能のメインプロセスでは使用できません。

拡張機能 ↔ IFrame のデータ受け渡し

拡張機能のメインプロセスと sys_IFrame の iframe は分離されたコンテキストです。両者の間でデータを渡すには、次の方法を使用します。

オプション A(推奨): eda.sys_Storage をブリッジとして使用します

// In main extension process:
await eda.sys_Storage.setExtensionUserConfig('myKey', JSON.stringify(data));

// In iframe:
const data = JSON.parse(await eda.sys_Storage.getExtensionUserConfig('myKey'));

オプション B: どちらのコンテキストからも eda に直接アクセスできます。同じ API をどちらからでも呼び出せます

// In iframe HTML (NOT window.parent.eda):
const info = await eda.dmt_Project.getCurrentProjectInfo();

通信プロトコル

ポートの検出

ブリッジサーバーは、49620-49629 の範囲で最初に利用可能なポートをリッスンします。 サーバーを見つけるには、この範囲をスキャンしてサービスの識別情報を確認します。

for port in $(seq 49620 49629); do
  resp=$(curl -s http://127.0.0.1:$port/health 2>/dev/null)
  if echo "$resp" | grep -q '"easyeda-bridge"'; then
    BRIDGE_PORT=$port; break
  fi
done
ハンドシェイク
  • HTTP: GET /health は { "service": "easyeda-bridge", "edaConnected": bool, ... } を返します
  • WebSocket: 接続時に、サーバーは { "type": "handshake", "service": "easyeda-bridge" } を送信します
  • クライアントは接続を使用する前に、service === "easyeda-bridge" であることを必ず確認してください
メッセージ形式

WebSocket / HTTP 経由の JSON メッセージ:

フィールド型説明
type"execute" | "result" | "error" | "ping" | "pong" | "handshake"メッセージの種類
idstringリクエストとレスポンスを対応付けるためのリクエスト UUID
codestring実行する JavaScript コード(execute 型の場合)
resultany実行結果(result 型の場合)
errorstringエラーメッセージ(error 型の場合)
servicestringサービス識別子(handshake 型の場合)
timestampnumberUnix ミリ秒

よくあるパターン

プロジェクトと基板の操作
// Get current project info
return await eda.dmt_Project.getCurrentProjectInfo();

// List all boards in project
return await eda.dmt_Board.getAllBoardsInfo();

// Create a new board (optionally link to schematic/PCB)
return await eda.dmt_Board.createBoard();

// Switch to a document tab
await eda.dmt_EditorControl.activateDocument(tabId);
例: 名前を指定してプロジェクトを開き、最初の回路図ページを開く
const targetProjectName = 'NE555 Circuit';

// 1. Enumerate projects by team/folder and find the target by name
const teams = await eda.dmt_Team.getAllTeamsInfo();
const seenProjectUuid = new Set();
let targetProjectUuid = null;

for (const team of teams || []) {
  const teamProjects = await eda.dmt_Project.getAllProjectsUuid(team.uuid);
  for (const projectUuid of teamProjects || []) {
    if (seenProjectUuid.has(projectUuid)) continue;
    seenProjectUuid.add(projectUuid);

    const info = await eda.dmt_Project.getProjectInfo(projectUuid);
    const name = info?.friendlyName || info?.name || '';
    if (name === targetProjectName) {
      targetProjectUuid = projectUuid;
      break;
    }
  }
  if (targetProjectUuid) break;

  const folderUuids = await eda.dmt_Folder.getAllFoldersUuid(team.uuid);
  for (const folderUuid of folderUuids || []) {
    const folderProjects = await eda.dmt_Project.getAllProjectsUuid(team.uuid, folderUuid);
    for (const projectUuid of folderProjects || []) {
      if (seenProjectUuid.has(projectUuid)) continue;
      seenProjectUuid.add(projectUuid);

      const info = await eda.dmt_Project.getProjectInfo(projectUuid);
      const name = info?.friendlyName || info?.name || '';
      if (name === targetProjectName) {
        targetProjectUuid = projectUuid;
        break;
      }
    }
    if (targetProjectUuid) break;
  }
  if (targetProjectUuid) break;
}

if (!targetProjectUuid) {
  throw new Error(`Project not found: ${targetProjectName}`);
}

// 2. Open the project
const opened = await eda.dmt_Project.openProject(targetProjectUuid);
if (!opened) {
  throw new Error(`Failed to open project: ${targetProjectName}`);
}

// 3. Get the first schematic page and open it
const schematics = await eda.dmt_Schematic.getAllSchematicsInfo();
if (!Array.isArray(schematics) || schematics.length === 0) {
  throw new Error(`No schematics found in project: ${targetProjectName}`);
}

const firstSchematic = schematics[0];
const pages = await eda.dmt_Schematic.getAllSchematicPagesInfo();
const firstPage = (pages || []).find((page) => page.parentSchematicUuid === firstSchematic.uuid)
  || firstSchematic.page?.[0];

if (!firstPage) {
  throw new Error(`No schematic page found in: ${firstSchematic.name}`);
}

const tabId = await eda.dmt_EditorControl.openDocument(firstPage.uuid);

return {
  projectUuid: targetProjectUuid,
  schematicUuid: firstSchematic.uuid,
  pageUuid: firstPage.uuid,
  tabId,
};

注:

  • 実際には、dmt_Project.getAllProjectsUuid() はグローバルな引数なしの列挙関数ではありません。名前から確実にプロジェクトを見つけるには、まずチームを、次にフォルダーを順に調べてください。
  • openProject(projectUuid) を呼び出すと、現在開いているプロジェクトの未保存の変更が破棄されることがあります。呼び出す前に注意してください。
PCB プリミティブの操作
// Get selected primitives
const selected = eda.pcb_SelectControl.getAllSelectedPrimitives_PrimitiveId();

// Create a line on copper layer
// Layer parameter uses EPCB_LayerId enum — see references/enums/EPCB_LayerId.md
await eda.pcb_PrimitiveLine.create(
  "GND",                       // net (string)
  EPCB_LayerId.TOP,            // layer — use enum, NOT raw number
  0,                           // startX (unit: 1mil)
  0,                           // startY (unit: 1mil)
  1000,                        // endX (unit: 1mil)
  0,                           // endY (unit: 1mil)
  10,                          // lineWidth
  false                        // primitiveLock
);

// Modify an existing primitive (async pattern)
const prim = await eda.pcb_PrimitiveComponent.get([id]);
const asyncPrim = prim.toAsync();
asyncPrim.setState_X(newX);
asyncPrim.setState_Y(newY);
asyncPrim.done();
PCB 非同期プリミティブのパターン(重要)

PCB / SCH プリミティブを変更する場合は、非同期パターンを使用する必要があります。

// 1. Get the primitive
const prim = await eda.pcb_PrimitiveVia.get([viaId]);
// 2. Convert to async mode
const asyncPrim = prim.toAsync();
// 3. Set new values
asyncPrim.setState_X(newX);
asyncPrim.setState_Y(newY);
asyncPrim.setState_Diameter(diameter);
// 4. Apply changes
asyncPrim.done();
回路図の操作
// Get all pages
return await eda.dmt_Schematic.getAllSchematicDocumentsInfo();

// Create a schematic component
// component parameter requires {libraryUuid, uuid} object — NOT a plain string
await eda.sch_PrimitiveComponent.create(
  { libraryUuid: "...", uuid: "device-uuid-from-library" },  // component object
  5000,                        // x (unit: 0.01inch = 10mil)
  5000,                        // y (unit: 0.01inch = 10mil)
  "",                          // subPartName
  0,                           // rotation (degrees, plain number)
  false,                       // mirror
  true,                        // addIntoBom
  true                         // addIntoPcb
);

// Get selected schematic primitives
const ids = eda.sch_SelectControl.getAllSelectedPrimitives_PrimitiveId();
ライブラリの操作
// List all libraries in workspace
return await eda.lib_LibrariesList.getAllLibrariesList();

// Search devices
return await eda.lib_Device.search("STM32");

// Get symbol info
return await eda.lib_Symbol.get(symbolUuid);
システム関数
// Show toast message
eda.sys_Message.showToastMessage("Operation complete!");

// Show confirm dialog
const confirmed = await eda.sys_Dialog.showConfirmationMessage("Proceed?");

// File system (limited to extension sandbox)
const content = await eda.sys_FileSystem.readFileFromFileSystem(path);
await eda.sys_FileSystem.saveFileToFileSystem(path, content);
DRC(デザインルールチェック)
// Run DRC check
const passed = await eda.pcb_Drc.check(true, true, false);
// passed is boolean: true if DRC passed, false if errors found

よくある間違い

API シグネチャを注意深く確認する(重要)

API メソッドを呼び出す前に、必ず references/ からシグネチャ全体を確認してください。パラメーターの型、戻り値の型、備考も含めて確認する必要があります。

AI エージェントは、ドキュメントをざっと読むことで、次のようなエラーを頻繁に起こします。

エラー 1:Promise を返すメソッドに await を付けない

EDA API メソッドのほとんどは Promise<T> を返します。await を付け忘れると、実際の結果ではなく Promise オブジェクトを取得してしまいます。

// WRONG: Missing await — result is a Promise, not the project info
const project = eda.dmt_Project.getCurrentProjectInfo();
console.log(project); // Promise { <pending> }

// CORRECT: Always await async methods
const project = await eda.dmt_Project.getCurrentProjectInfo();
console.log(project); // { uuid: "...", name: "...", ... }

メソッドに await が必要かどうかを確認する方法: シグネチャの戻り値の型を確認してください。Promise<...> と記載されている場合は、必ず await を付けてください。

// From references/classes/DMT_Project.md:
getCurrentProjectInfo(): Promise<IDMT_ProjectItem | null>
//                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//                       This is a Promise — you MUST await it

エラー 2:列挙型の値ではなく生の数値を使う

多くのパラメーターでは、特定の列挙型の値が必要です。誤った数値を使うと、気付かないまま誤った動作につながります。

// WRONG: What does layer "1" mean? Which copper layer? Signal? Mask?
await eda.pcb_PrimitiveLine.create("GND", 1, 0, 0, 1000, 0, 10, false);

// CORRECT: Use the enum — EPCB_LayerId.TOP is clear and type-safe
// Check references/enums/EPCB_LayerId.md for the correct value
await eda.pcb_PrimitiveLine.create("GND", EPCB_LayerId.TOP, 0, 0, 1000, 0, 10, false);

数値定数を使う前に、必ず references/enums/ で列挙型を確認してください。

エラー 3:確認せずにパラメーターの型を決めつける

API によって、単位、ID の形式、オプションパラメーターの規則は異なります。決めつけないでください。

// WRONG: Assuming create() parameters match modify() parameters
// create() and modify() often have DIFFERENT parameter orders/types

// CORRECT: Always read the exact signature for the method you're calling
// Check references/classes/<ClassName>.md for each method's specific signature

まとめ — API を呼び出す前に必ず確認すること:

  1. シグネチャを読む — パラメーターの型、戻り値の型を references/classes/ で確認する
  2. Promise の場合は await を付ける — 戻り値の型に Promise<...> があるか確認する
  3. 列挙型を使う — 数値や文字列を推測せず、references/enums/ で確認する
  4. 備考を確認する — 「备注」セクションには、使用上の重要な注意事項が記載されていることがよくあります
座標の単位(重要)

ドメインごとに座標の単位が異なります。

ドメイン単位換算
PCB1mil1mm ≈ 39.37 units
Schematic0.01inch(10mil)1mm ≈ 3.937 units

これは AI エージェントが最もよく間違える点です。 単位を取り違えると、部品が誤った位置に配置されます。

  • PCB:1 unit = 1mil = 0.001 inch = 0.0254 mm
  • Schematic:1 unit = 0.01inch = 10mil = 0.254 mm

誤った単位を使うと、部品は意図した位置から10倍離れた場所に配置されます。

// WRONG: thinking unit is 1mil (it's actually 0.01inch = 10mil)
// Placing at x=500 thinking it's 500mil = 0.5inch — but 500 units = 5000mil = 5inch!
await eda.sch_PrimitiveComponent.create({libraryUuid: "...", uuid: "dev-uuid"}, 500, 0, "", 0, false, true, true);

// CORRECT: 50 units = 500mil = 0.5inch (in 0.01inch units)
await eda.sch_PrimitiveComponent.create({libraryUuid: "...", uuid: "dev-uuid"}, 50, 0, "", 0, false, true, true);
ドキュメントの状態(重要)

プロジェクトを作成した後、その中のドキュメントを操作する前に、必ずプロジェクトを開いてください。

ドキュメントを操作するときは、次の項目を必ず確認してください。

  1. プロジェクトが開いている — eda.dmt_Project.getCurrentProjectInfo() を使って確認する
  2. 正しいドキュメントがアクティブである — eda.dmt_SelectControl.getCurrentDocumentInfo() を使ってドキュメントの種類を確認する
  3. ドキュメントの種類が API のドメインと一致している — PCB API にはアクティブな PCB ドキュメントが必要で、SCH API にはアクティブな Schematic ドキュメントが必要です
// WRONG: Assuming operation will work without checking document state
await eda.pcb_PrimitiveLine.create(...); // May fail if no PCB document is open

// CORRECT: Always verify document state first
const project = await eda.dmt_Project.getCurrentProjectInfo();
if (!project) {
  // If you just created a project, you MUST open it before any operations!
  return "Error: No project is currently opened. If you just created a project using dmt_Project.createProject(), you MUST call dmt_Project.openProject(projectPath) to open it first. You cannot operate on documents until a project is opened.";
}

const doc = await eda.dmt_SelectControl.getCurrentDocumentInfo();
if (doc?.documentType !== EDMT_EditorDocumentType.PCB) {
  return "Error: No PCB document is currently active. Please open a PCB document first.";
}

// Now safe to perform PCB operations
await eda.pcb_PrimitiveLine.create(...);

誤った種類のドキュメントを操作すると、エラーまたは null の結果が返されます。 例:

  • アクティブな PCB ドキュメントがない状態(documentType !== EDMT_EditorDocumentType.PCB)で PCB_* API を実行 → エラー/null
  • アクティブな Schematic ドキュメントがない状態(documentType !== EDMT_EditorDocumentType.SCHEMATIC_PAGE)で SCH_* API を実行 → エラー/null
IFrame のコンテキスト — 常に eda を直接使う(重要)

sys_IFrame.openIFrame() で iframe を作成する拡張機能のコードを書く場合、iframe の HTML 内にある JavaScript コードから eda グローバルに直接アクセスできます。window.parent.eda は使わないでください。

重要な理由: EasyEDA は eda オブジェクトを iframe の実行コンテキストに自動的に挿入します。標準的なブラウザーのフレーム間アクセス方法(window.parent、parentWindow など)はここでは適用されず、失敗します。

// WRONG: Using window.parent to reach parent frame's eda object
// This is a common mistake made by AI agents familiar with web iframe patterns
const project = await window.parent.eda.dmt_Project.getCurrentProjectInfo();

// CORRECT: eda is available directly in the iframe context
const project = await eda.dmt_Project.getCurrentProjectInfo();

これは sys_IFrame の iframe 内にあるすべてのコードに適用されます。

  • openIFrame() で読み込む拡張機能の UI パネル
  • iframe に表示される拡張機能パッケージ内のすべての HTML ファイル

ルール: EasyEDA 拡張機能では、メインコンテキストでも sys_IFrame で作成した iframe 内でも、API には常に eda.xxx を通じてアクセスしてください。window.parent.eda やその他の親フレームへのアクセサーは使わないでください。

複数ウィンドウのサポート

複数の EasyEDA ウィンドウがブリッジに接続されている場合、EDA の操作ごとにウィンドウの選択状態を確認する必要はありません。確認が必要なのは、次の場合だけです。

  1. 最初の EDA 操作 — どのウィンドウがアクティブか確認し、ユーザーに伝えます
  2. EDA の切断エラー — ブリッジから EDA が切断されているというエラーが返された場合は、新しいウィンドウを選択するようユーザーに依頼します

複数ウィンドウでの操作:

# List all connected EDA windows
curl http://localhost:49620/eda-windows

# Select a specific window
curl -X POST http://localhost:49620/eda-windows/select \
  -H "Content-Type: application/json" \
  -d '{"windowId": "abc-123-def"}'

# Execute on specific window
curl -X POST http://localhost:49620/execute \
  -H "Content-Type: application/json" \
  -d '{"code": "return await eda.dmt_Project.getCurrentProjectInfo();", "windowId": "abc-123-def"}'

EDA ウィンドウが 1 つだけ接続されている場合は、自動的にアクティブとして選択されます。

デバッグのヒントと失敗時の対処方法

トラブルシューティング
  1. 必ず最初にヘルスチェックを行います:ポート 49620-49629 をスキャンして {"service":"easyeda-bridge"} を確認します
  2. EDA が接続されていませんか?:ブリッジ拡張機能が EasyEDA で読み込まれていることを確認します。ダウンロード先:https://jlc-ext.com/item/oshwhub/run-api-gateway
  3. タイムアウトエラー:デフォルトのタイムアウトは 30s です。タイムアウトが発生した場合:
    • 正しいプロジェクトとドキュメントが開かれているか確認します(dmt_Project.getCurrentProjectInfo() を使用)
    • プロジェクトが開かれていない場合は、dmt_Project.openProject(projectPath) を使用して開きます
    • アクティブなドキュメントがない場合は、dmt_EditorControl.openDocument(docId) を使用して正しい種類のドキュメント(PCB/回路図)を開きます
    • ドキュメントの種類が違う場合(例:回路図で PCB API を実行している場合)は、先に正しいドキュメントに切り替えます
    • 複雑な操作では、コードを分割する必要がある場合があります
  4. 戻り値を確認します:多くのメソッドは失敗時に null を返すため、必ず検証します
  5. レイヤー番号:references/enums/ のドキュメントにある列挙型(例:EPCB_LayerId)を使用します
  6. EDA ウィンドウが切断された場合:ウィンドウが切断されたというエラーが表示された場合は、GET /eda-windows を使用して利用可能なウィンドウを確認し、POST /eda-windows/select を使用して別のウィンドウに切り替えます
  7. 権限エラー:すべての API インターフェースは EDA の権限システムによって制御されます。他の API が正常に動作している一方で、特定の API が一貫して実行に失敗し(エラーまたは null を返し)、呼び出しがドキュメントと完全に一致していることも確認済みの場合、コードのバグではなく、権限によってブロックされている可能性があります。EDA クライアントは、ユーザーライセンス、プロジェクト設定、またはドキュメントの状態に基づいて特定の操作を制限することがあります。より高い権限または別の EDA エディションが必要な可能性があることをユーザーに伝えてください
  8. エラーが続きますか?:API 呼び出しがドキュメントと完全に一致していることを確認し、権限の問題も除外したうえで予期しないエラーが続く場合は、EasyEDA の公式サポート窓口への報告を検討してください
失敗時の処理ルール

拡張機能を開発する際は、次のルールに従ってください。

状況対応
API メソッドがドキュメントに存在しない直ちに停止 — API が存在しないことをユーザーに伝えます
ドキュメントを読んでもシグネチャが不明確生成を停止 — クエリの手順に戻って読み直します
禁止されたブラウザー API が検出されたeda.sys_* の代替手段に自動置換します
メニュー ID の競合識別できるようにプレフィックスを追加します(例:my-plugin-home、my-plugin-sch)
権限によってブロックされているユーザーに伝えます — 別の EDA エディションまたはライセンスが必要な場合があります

重要: API シグネチャを決して推測しないでください。references/classes/ に記載されていない場合、このユースケースでは使用できません。

AI エージェント向けワークフロー

ユーザーから EDA 操作を依頼された場合:

  1. タスクを把握する — 対象のドメインは何ですか?(PCB/SCH/LIB/Project)
  2. ドキュメントの状態を確認する — eda.dmt_Project.getCurrentProjectInfo() と eda.dmt_SelectControl.getCurrentDocumentInfo() を確認します
  3. 正しいドキュメントタイプであることを確認する — PCB 操作にはアクティブな PCB、SCH 操作にはアクティブな Schematic が必要です
  4. API を調べる — references/ の関連クラスのドキュメントを読みます
  5. 型を確認する — パラメーターの型について、列挙型/インターフェースのドキュメントを読みます
  6. コードを記述する — 上記の実行コンテキストのルールに従います
  7. 実行する — POST /execute 経由で送信し、結果を確認します
  8. 繰り返す — エラーが発生した場合は、エラーメッセージを読んで調整します

API が不明な場合:

  • _quick-reference.md でメソッド名を検索します
  • 詳細なシグネチャと補足事項について、該当するクラスのドキュメントを読みます
  • 複雑なパラメーター型については、インターフェースのドキュメントを確認します

セッション管理

トピックの変更を検出する

Bridge サーバーは実行中にシステムリソースを消費します。ユーザーがまったく別のトピック(EasyEDA/EDA/PCB/回路図に関連しないトピック)に3 回連続で切り替えた場合は、Bridge を終了するかどうかを積極的に尋ねてください:

「EasyEDA から別の話題に移ったようです。Bridge サーバーはバックグラウンドで引き続き実行されています。リソースを解放するため、停止しますか?」

Bridge を自動的に終了しないでください — ユーザーが後で EDA 作業に戻る可能性があります。確認を尋ね、ユーザーが同意した場合にのみ終了してください。

Bridge を終了する

ユーザーが Bridge の停止に同意した場合:

# Find and stop the bridge process
for port in $(seq 49620 49629); do
  pid=$(lsof -ti :$port 2>/dev/null)
  if [ -n "$pid" ]; then
    kill $pid
    echo "Bridge stopped (PID: $pid, Port: $port)"
    break
  fi
done

コメント