Skip to content

Commit 49ce7d0

Browse files
committed
Add plugin SDK: discover/load third-party AC_* commands via entry points
1 parent 5cda481 commit 49ce7d0

15 files changed

Lines changed: 319 additions & 1 deletion

File tree

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
## Table of Contents
1515

16+
- [What's new (2026-06-19) — Plugin SDK](#whats-new-2026-06-19--plugin-sdk)
1617
- [What's new (2026-06-19) — MCP Structured Output](#whats-new-2026-06-19--mcp-structured-output)
1718
- [What's new (2026-06-19) — Tweened Drag](#whats-new-2026-06-19--tweened-drag)
1819
- [What's new (2026-06-19) — Process-Doc (SOP) Generator](#whats-new-2026-06-19--process-doc-sop-generator)
@@ -83,6 +84,12 @@
8384

8485
---
8586

87+
## What's new (2026-06-19) — Plugin SDK
88+
89+
Third-party `AC_*` commands via entry points. Full reference: [`docs/source/Eng/doc/new_features/v31_features_doc.rst`](docs/source/Eng/doc/new_features/v31_features_doc.rst).
90+
91+
- **`discover_plugins` / `load_plugins`** (`AC_list_plugins` / `AC_load_plugins`, `ac_*`): a pip package registers new executor commands declaratively in the `je_auto_control.commands` entry-point group; AutoControl discovers and registers them at runtime (immediately usable from JSON flows, socket server, scheduler, MCP). Broken plugins are skipped; the declarative, namespaced complement to the runtime path loader.
92+
8693
## What's new (2026-06-19) — MCP Structured Output
8794

8895
MCP 2025-06-18 structured tool output. Full reference: [`docs/source/Eng/doc/new_features/v30_features_doc.rst`](docs/source/Eng/doc/new_features/v30_features_doc.rst).

README/README_zh-CN.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
## 目录
1414

15+
- [本次更新 (2026-06-19) — Plugin SDK](#本次更新-2026-06-19--plugin-sdk)
1516
- [本次更新 (2026-06-19) — MCP 结构化输出](#本次更新-2026-06-19--mcp-结构化输出)
1617
- [本次更新 (2026-06-19) — 缓动拖拽](#本次更新-2026-06-19--缓动拖拽)
1718
- [本次更新 (2026-06-19) — 流程文档(SOP)生成器](#本次更新-2026-06-19--流程文档sop生成器)
@@ -82,6 +83,12 @@
8283

8384
---
8485

86+
## 本次更新 (2026-06-19) — Plugin SDK
87+
88+
通过 entry points 注册第三方 `AC_*` 指令。完整参考:[`docs/source/Zh/doc/new_features/v31_features_doc.rst`](../docs/source/Zh/doc/new_features/v31_features_doc.rst)
89+
90+
- **`discover_plugins` / `load_plugins`**(`AC_list_plugins` / `AC_load_plugins``ac_*`):pip 包以 `je_auto_control.commands` entry-point 组声明式注册新执行器指令;AutoControl 于运行期发现并注册(立即可用于 JSON 流程、socket server、调度器、MCP)。坏插件会跳过;为运行期路径加载器的声明式、带命名空间对应物。
91+
8592
## 本次更新 (2026-06-19) — MCP 结构化输出
8693

8794
MCP 2025-06-18 结构化工具输出。完整参考:[`docs/source/Zh/doc/new_features/v30_features_doc.rst`](../docs/source/Zh/doc/new_features/v30_features_doc.rst)

README/README_zh-TW.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
## 目錄
1414

15+
- [本次更新 (2026-06-19) — Plugin SDK](#本次更新-2026-06-19--plugin-sdk)
1516
- [本次更新 (2026-06-19) — MCP 結構化輸出](#本次更新-2026-06-19--mcp-結構化輸出)
1617
- [本次更新 (2026-06-19) — 緩動拖曳](#本次更新-2026-06-19--緩動拖曳)
1718
- [本次更新 (2026-06-19) — 流程文件(SOP)產生器](#本次更新-2026-06-19--流程文件sop產生器)
@@ -82,6 +83,12 @@
8283

8384
---
8485

86+
## 本次更新 (2026-06-19) — Plugin SDK
87+
88+
透過 entry points 註冊第三方 `AC_*` 指令。完整參考:[`docs/source/Zh/doc/new_features/v31_features_doc.rst`](../docs/source/Zh/doc/new_features/v31_features_doc.rst)
89+
90+
- **`discover_plugins` / `load_plugins`**(`AC_list_plugins` / `AC_load_plugins``ac_*`):pip 套件以 `je_auto_control.commands` entry-point 群組宣告式註冊新執行器指令;AutoControl 於執行期探索並註冊(立即可用於 JSON 流程、socket server、排程器、MCP)。壞外掛會略過;為執行期路徑載入器的宣告式、具命名空間對應物。
91+
8592
## 本次更新 (2026-06-19) — MCP 結構化輸出
8693

8794
MCP 2025-06-18 結構化工具輸出。完整參考:[`docs/source/Zh/doc/new_features/v30_features_doc.rst`](../docs/source/Zh/doc/new_features/v30_features_doc.rst)
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
==================================================
2+
New Features (2026-06-19) — Plugin SDK
3+
==================================================
4+
5+
A third-party pip package can now register new ``AC_*`` executor commands
6+
declaratively via a setuptools **entry point** in the
7+
``je_auto_control.commands`` group — turning the monolith into an ecosystem
8+
(how pytest/Playwright grew). AutoControl discovers them at runtime;
9+
discovered commands are immediately usable from JSON action files, the
10+
socket server, the scheduler, and MCP. Pure standard library
11+
(``importlib.metadata``); full stack.
12+
13+
.. contents::
14+
:local:
15+
:depth: 2
16+
17+
18+
Authoring a plugin
19+
=================
20+
21+
A plugin package exposes an entry point whose target is a factory returning
22+
a ``{command_name: handler}`` mapping::
23+
24+
# in the plugin's pyproject.toml
25+
[project.entry-points."je_auto_control.commands"]
26+
my_pack = "my_pack.commands:provide"
27+
28+
# my_pack/commands.py
29+
def provide():
30+
return {"AC_my_command": lambda **kw: {"ok": True}}
31+
32+
33+
Discovering & loading
34+
====================
35+
36+
::
37+
38+
from je_auto_control import discover_plugins, load_plugins
39+
40+
discover_plugins() # {command_name: handler} from all plugins
41+
load_plugins() # discover + register into the executor
42+
43+
Broken plugins are skipped (logged), not fatal. Exposed as
44+
``AC_list_plugins`` (discover names) / ``AC_load_plugins`` (discover +
45+
register) and ``ac_list_plugins`` / ``ac_load_plugins``. The entry-point
46+
source is injectable, so discovery is unit-testable without installing a
47+
real plugin. This is the declarative, namespaced complement to the existing
48+
runtime path loader.

docs/source/Eng/eng_index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ Comprehensive guides for all AutoControl features.
5353
doc/new_features/v28_features_doc
5454
doc/new_features/v29_features_doc
5555
doc/new_features/v30_features_doc
56+
doc/new_features/v31_features_doc
5657
doc/ocr_backends/ocr_backends_doc
5758
doc/observability/observability_doc
5859
doc/operations_layer/operations_layer_doc
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
==========================================
2+
新功能 (2026-06-19) — Plugin SDK
3+
==========================================
4+
5+
第三方 pip 套件現在可透過 setuptools **entry point**(``je_auto_control.commands``
6+
群組)宣告式地註冊新的 ``AC_*`` 執行器指令——把單體變成生態系(pytest /
7+
Playwright 的成長方式)。AutoControl 於執行期探索它們;探索到的指令立即可
8+
用於 JSON action 檔、socket server、排程器與 MCP。純標準庫
9+
(``importlib.metadata``);走完整五層。
10+
11+
.. contents::
12+
:local:
13+
:depth: 2
14+
15+
16+
撰寫外掛
17+
========
18+
19+
外掛套件提供一個 entry point,其目標為回傳 ``{command_name: handler}``
20+
對應的工廠函式::
21+
22+
# 外掛的 pyproject.toml
23+
[project.entry-points."je_auto_control.commands"]
24+
my_pack = "my_pack.commands:provide"
25+
26+
# my_pack/commands.py
27+
def provide():
28+
return {"AC_my_command": lambda **kw: {"ok": True}}
29+
30+
31+
探索與載入
32+
==========
33+
34+
::
35+
36+
from je_auto_control import discover_plugins, load_plugins
37+
38+
discover_plugins() # 來自所有外掛的 {command_name: handler}
39+
load_plugins() # 探索 + 註冊到執行器
40+
41+
壞掉的外掛會被略過(記錄),不致命。對應 ``AC_list_plugins``(探索名稱)
42+
/ ``AC_load_plugins``(探索 + 註冊)以及 ``ac_list_plugins`` /
43+
``ac_load_plugins``。entry-point 來源可注入,因此探索能在不安裝真實外掛
44+
的情況下單元測試。這是既有執行期路徑載入器的宣告式、具命名空間的對應物。

docs/source/Zh/zh_index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ AutoControl 所有功能的完整使用指南。
5353
doc/new_features/v28_features_doc
5454
doc/new_features/v29_features_doc
5555
doc/new_features/v30_features_doc
56+
doc/new_features/v31_features_doc
5657
doc/ocr_backends/ocr_backends_doc
5758
doc/observability/observability_doc
5859
doc/operations_layer/operations_layer_doc

je_auto_control/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,10 @@
199199
from je_auto_control.utils.tween_drag import (
200200
easing_names, tween_drag, tween_points,
201201
)
202+
# Plugin SDK: discover/load third-party AC_* commands via entry points
203+
from je_auto_control.utils.plugin_sdk import (
204+
COMMANDS_GROUP, discover_plugins, load_plugins,
205+
)
202206
# Background popup/interrupt watchdog (unattended automation)
203207
from je_auto_control.utils.watchdog import (
204208
PopupWatchdog, WatchdogRule, default_popup_watchdog,
@@ -633,6 +637,7 @@ def start_autocontrol_gui(*args, **kwargs):
633637
"analyze_heal_log", "heal_stats", "scan_secrets",
634638
"describe_step", "generate_sop", "write_sop",
635639
"easing_names", "tween_drag", "tween_points",
640+
"COMMANDS_GROUP", "discover_plugins", "load_plugins",
636641
# MCP server
637642
"AuditLogger", "HttpMCPServer", "MCPContent", "MCPPrompt",
638643
"MCPPromptArgument", "MCPResource", "MCPServer", "MCPTool",

je_auto_control/gui/script_builder/command_schema.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,18 @@ def _add_misc_specs(specs: List[CommandSpec]) -> None:
681681
description="Drag along an eased path; 'start'/'end' [x,y] via JSON "
682682
"view.",
683683
))
684+
specs.append(CommandSpec(
685+
"AC_list_plugins", "Tools", "List Plugin Commands",
686+
fields=(FieldSpec("group", FieldType.STRING, optional=True,
687+
default="je_auto_control.commands"),),
688+
description="Discover third-party AC_* commands from entry points.",
689+
))
690+
specs.append(CommandSpec(
691+
"AC_load_plugins", "Tools", "Load Plugin Commands",
692+
fields=(FieldSpec("group", FieldType.STRING, optional=True,
693+
default="je_auto_control.commands"),),
694+
description="Discover + register third-party plugin commands.",
695+
))
684696
specs.append(CommandSpec(
685697
"AC_generate_sop", "Report", "Generate SOP Document",
686698
fields=(

je_auto_control/utils/executor/action_executor.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2882,6 +2882,18 @@ def _tween_drag(start: List[int], end: List[int], steps: int = 30,
28822882
return {"points": result["points"]}
28832883

28842884

2885+
def _list_plugins(group: str = "je_auto_control.commands") -> Dict[str, Any]:
2886+
"""Adapter: discover third-party plugin command names (no register)."""
2887+
from je_auto_control.utils.plugin_sdk import discover_plugins
2888+
return {"commands": sorted(discover_plugins(group))}
2889+
2890+
2891+
def _load_plugins(group: str = "je_auto_control.commands") -> Dict[str, Any]:
2892+
"""Adapter: discover + register third-party plugin commands."""
2893+
from je_auto_control.utils.plugin_sdk import load_plugins
2894+
return {"loaded": load_plugins(group)}
2895+
2896+
28852897
class Executor:
28862898
"""
28872899
Executor
@@ -3111,6 +3123,8 @@ def __init__(self):
31113123
"AC_scan_secrets": _scan_secrets,
31123124
"AC_generate_sop": _generate_sop,
31133125
"AC_tween_drag": _tween_drag,
3126+
"AC_list_plugins": _list_plugins,
3127+
"AC_load_plugins": _load_plugins,
31143128
"AC_a11y_record_start": _a11y_record_start,
31153129
"AC_a11y_record_stop": _a11y_record_stop,
31163130
"AC_a11y_record_events": _a11y_record_events,

0 commit comments

Comments
 (0)