本卡屬 FR-090(母卡 CM-1682),第 7 棒:把最後三支還走舊式接法的套件(jedi-ai-bot、jedi-ai-dashboard、jedi-remote-agent)收進 core/plugins/。實作類,零行為變更,對外 URL 一字不改。建議 model:Sonnet 5,effort:medium——形狀已由 17 支現成範例定死,工作是機械搬遷加逐條實打驗證,不需要設計判斷;三支中 remote-agent 那支最重(adapter 多、有留在主專案的 binary 端點),做那支時放慢。

這一棒在做什麼(白話)

主專案接一支套件現在的標準是「三個地方」:pyproject 一行、core/plugins/<pkg>.py 一個檔(裡面固定三段:① 這支套件開的 port 主專案怎麼答、② 填表、③ 掛載)、core/plugins/__init__.pyPLUGINS 清單加一列。21 支套件裡有 18 支已經是這個形狀,剩下三支還是 FR-069 抽出時的舊形狀:接線寫在 api/ai/__init__.pyapi/ai_dashboard/__init__.pyapi/remote_agent/__init__.pycreate_module() 裡,靠 config/app_modules.pyREGISTERED_APPS 字串驅動 main.py 的 blueprint 載入迴圈掛上去。這張卡把三支搬成標準形狀,搬完主專案側 21 支一模一樣,PM 頁「有三個零件的裝法還是舊式」那句就可以拿掉。

為什麼會漏到現在:CM-1689 那棒的範圍是當時已經走 PLUGINS 迴圈的 11 支,這三支走 REGISTERED_APPS 另一條路,不在那張卡的清單;CM-1700/1701/1726 各自順手收了 evidence-classification/license/detection 三支同形態的,這三支沒人順到。CM-1730 寫守衛掃 PLUGINS 對 seed 時才暴露,暫時用 _CAPABILITY_PACKAGES_OUTSIDE_PLUGINS 直讀三支的能力點清單兜住。

首腦核對過的現況(2026-09-13)

在哪裡

api/ai/__init__.py                              整檔 → core/plugins/ai_bot.py(改完刪目錄)
api/ai_dashboard/__init__.py                    整檔 → core/plugins/ai_dashboard.py(改完刪目錄)
api/remote_agent/__init__.py                    接線段 → core/plugins/remote_agent.py(改完刪 __init__,routes/ 留)
api/remote_agent/routes/agent_file_route.py     留原地不動,由 core/plugins/remote_agent.py 的 mount() 掛
infra/ai/redis_chat_history_store.py            → core/plugins/ai_bot.py ① 段(唯一 caller 是接線);搬完刪 infra/ai/
infra/remote_agent/adapter/lazy.py              → core/plugins/remote_agent.py ① 段(唯一 caller 是接線);搬完刪該檔
config/app_modules.py:47,83,98                  三個字串改成註解,寫明改由 core/plugins/<pkg>.py 掛(比照 :100-110 license 那段寫法)
core/plugins/__init__.py                        import 三支 + PLUGINS 加三列
test/test_module_boundaries.py:1139 _CONVERGED_PLUGIN_DIRS       加三列
test/test_module_boundaries.py:1162 _PORT_IMPL_ALLOWED_OUTSIDE_PLUGINS   拿掉 infra/ai/redis_chat_history_store.py 與 infra/remote_agent/adapter/lazy.py 兩列
test/test_module_boundaries.py:1376 _CAPABILITY_EXEMPT_PACKAGES         拿掉三列
test/test_module_boundaries.py:1385 _CAPABILITY_PACKAGES_OUTSIDE_PLUGINS 改成空 tuple(常數與 _declared_capabilities() 的讀取邏輯保留,讓下次再有這種漏網有地方登記)
scripts/deliverables/plugin_metrics.py          HOST_WIRING_FILES 加三支(比照 :65 license 那列)

怎麼做