コンポーネント 2
QGIS Live Harness
Driverの上に乗る基盤(このリポジトリ) — 操縦席+管制塔。
Driverが「QGIS側の手」なら、Harnessは「操縦席+管制塔」。 生のファイルJSONL/HTTPを直接読み書きする代わりに、 プラグイン開発の全工程を無人化する層を提供する。
言い換えると、Harnessとは「QGISプロセス内へプラグインとして移せない部分」 の総体である。ブートストラップ(初回インストール/プロセス起動)・ 自己監視・QGIS非依存の検証は原理的に外にしか置けず、 その不可還元な外側こそがHarnessの存在理由になる (詳細は「Harnessのプラグイン化」)。
HarnessがDriverに対して追加するもの:
| 要素 | 役割 |
|---|---|
scripts/live-drive.mjs (LivePage) |
Nodeからの高水準API。evaluate/pyeval/click/waitFor/screenshot/devreload/status/openPlugin/reloadPlugin/bridgeCall。使い勝手はPlaywright相当 |
scripts/qgis-session.mjs |
セッション管理。ensure=起動中へアタッチ/未起動なら起動(deployはしない。配置はUI操作のみ)、reload=器のホットリロード、devreload=repo側コード即反映 |
scripts/qgis-live-check.mjs |
L2検証ランナー(npm run test:live)。QGIS未起動でも内部でensureする |
scripts/qgis-mcp.mjs |
Harness側MCPアダプタ(stdio)。Driverの操作面を qgis_pyeval 等のtoolとして公開(後述) |
tests/e2e + Playwright |
L1検証。UIが実物Chromiumで動くことを利用したブラウザ単体テスト |
WEBENGINE_DEV_SRC 機構 |
開発対象コードをリポジトリに置いたままQGIS内で実行 → devreloadで即反映(devモード=junction配置時のみ起動時に設定) |
MCPによるAI連携
AIの接続方式はクライアントごとに異なるため、Driver側・Harness側で全方式を並列提供する:
| AIの種類 | 使う面 | 実装 | 提供元 |
|---|---|---|---|
| MCP(stdio) — Devin/Claude Desktop/IDE系 | MCP stdio | qgis_live_driver/mcp_stdio.py(stdlibのみ) または scripts/qgis-mcp.mjs(Node版・ツール豊富) |
Driver / Harness |
| MCP(HTTP) — リモート/マルチクライアント系 | MCP Streamable HTTP | POST /mcp |
Driver |
| MCP(HTTP) — ローカルのMCPクライアント | MCP Streamable HTTP + セッショントークン認証 | POST /mcp + Bearer(トークンはレジストリJSON参照) |
Driver |
| 汎用HTTPのみ — function calling/自作エージェント | plain REST | POST /api/* + GET /api/tools |
Driver |
| シェル/ファイルのみ — 制限環境 | 生ファイルプロトコル | commands.jsonl/results.jsonl |
Driver |
| Nodeライブラリ/CLI | LivePage・npm run live:* |
scripts/ 内 |
Harness |
MCPクライアント設定例(stdioの場合、Driver同梱shimを直接使う):
{
"mcpServers": {
"qgis-live": {
"command": "python",
"args": ["C:/Users/<user>/AppData/Roaming/QGIS/QGIS4/profiles/<profile>/python/plugins/qgis_live_driver/mcp_stdio.py"]
}
}
}
このリポジトリをDevin等で開く場合は .devin/mcp_config.json で
qgis-live(scripts/qgis-mcp.mjs)が登録済み。
tools: qgis_ensure / qgis_pyeval / qgis_eval / qgis_bridge_call /
qgis_screenshot / qgis_status / qgis_open_plugin /
qgis_devreload / qgis_reload。
各toolは内部でensureするためQGIS未起動でも自動で立ち上がり、
qgis_live_driver がlive中ならそれをhubとして使い
(pluginId引数はplugin_idルーティングに載る)、
qgis_screenshot はPNGをMCP image contentで返すためエージェントが画像として見られる。
認証モデル: 全チャネルでセッショントークン必須
(起動ごとに自動生成・ユーザ限定ACLファイルのみに保存)。
HTTPは 127.0.0.1 バインドでlocalhost限定の設計であり、
Host/Originがloopback以外のリクエストは拒否される。
クラウドMCPクライアント(Copilot Studio等)からの接続は設計対象外だが、
QGIS_LIVE_API_KEY + トンネルで無理やり公開する手順は
QGIS Live Driver「外部公開」 に残してある(非推奨)。
flowchart LR
CLIENT["MCPクライアント<br/>(Devin等)"]
subgraph SURF["接続面(全て同じdispatchへ)"]
MCP["Harness: qgis-mcp.mjs<br/>stdio JSON-RPC"]
SHIM["Driver: mcp_stdio.py<br/>stdio shim(stdlibのみ)"]
HTTP["Driver内蔵HTTP<br/>/mcp + /api/*"]
end
API["Harness: LivePage / ensure"]
QGIS["常駐QGISプロセス<br/>(Driver + 器)"]
CLIENT -->|"tools/call"| MCP --> API -->|ファイルJSONL| QGIS
CLIENT -->|stdio| SHIM -->|ファイルJSONL| QGIS
CLIENT -->|HTTP| HTTP -->|"submit()"| QGIS
QGIS -->|image content等| MCP --> CLIENT
プラグイン自動化環境(開発対象 = plugin.config.json の id)
Harnessは「任意QGISを操る」だけでなく、Qt WebEngineプラグインの開発ループ自体を無人化する。 deployするのは固定の器 (QWebEngineView + view用ドライバ)だけで、開発対象のロジック/UIは リポジトリに置いたまま実QGIS内で動作・観測・即時反映できる。
flowchart TD
WEB["QWebEngineView(実物Chromium)"]
BROWSER["同じ ui/ が通常ブラウザでも動く<br/>(mock bridgeにフォールバック)"]
PW["Playwright / DevTools / DOM検査<br/>がそのまま使える [L1]"]
SRC["WEBENGINE_DEV_SRC<br/>= このリポジトリ"]
LOAD["bridge.py / logic.py を実行時ロード<br/>(deploy物に含まない)"]
DR["npm run live:devreload<br/>→ 実行中QGISに即反映"]
PY["pyeval(Driver/器のドライバ経由)"]
ASSERT["iface / QgsProject / canvas の<br/>実状態を任意assert [L2]"]
WEB --> BROWSER --> PW
SRC --> LOAD --> DR
PY --> ASSERT
| 要素 | 面 | 役割 |
|---|---|---|
| QWebEngineView | 製品 | UIを実物Chromiumにする → Web標準自動化の適用が可能になる核 |
bridge.py/logic.py/ui/ |
製品 | 操作対象であり、配布物そのもの |
WEBENGINE_DEV_SRC |
器 | 製品コードをリポジトリに置いたままQGIS内で実行する機構(devモード時のみ設定) |
devreload |
器 | 編集→即反映(deploy/reloadPlugin/再起動 全て不要) |
pyeval |
器/Driver | UIの外側・QGIS内部状態まで踏み込む検証手段 |
要素の「面」について: 製品 = 配布プラグインに同梱、 器 = deployされるが配布物からは除去、Driver = 単独導入できる汎用部品、 Harness = リポジトリ側にのみ存在。
Qt Widgetsプラグインも検証対象になる(WebEngineへの作り替えは不要)
DOM/JSレベルのUI検査にはQWebEngineViewが必須だが、Qt Widgets製プラグインも
「UIの機能検証」は同等以上にできる。pyevalはQGISプロセス内で実行されるため、
Qtウィジェットツリー(findChildren/isVisible/text())の
読み取り、setText()/click()/QTestによる操作注入、
dialog.grab()やmainwindowのスクショまで、全てインプロセス・同期で行える。
ネイティブAPIを直接触るため検査深度はむしろ深く、CDP不応答・レンダラー飢餓といった
WebEngine固有の不安定さもない。検証目的でWebEngineへ作り替える必要はない。
異なるのは2点だけ:
- L1(QGIS無しのブラウザ単体テスト)はWidgetsでは原理的に不可能(HTMLを持たないため)。 ただしgeo_webviewのように内蔵HTTPサーバがWebページを配信するプラグインでは、 出力側を通常ブラウザ+PlaywrightでL1相当に試験できる
- 検査コードはDOMセレクタではなくQt API(
findChildren等)で書く
live dir(live_driver.py)を持たないWidgetsプラグインでも、
plugin.config.jsonに列挙すれば test:live がhub
(qgis_live_driver)経由で open_plugin/pyeval/run()/
スクショを検証する(同梱の geo_search・geo_webview がその例)。