儀表盤插件
儀表盤插件允許你向 Web 儀表盤添加自定義標籤頁。插件可以顯示自己的 UI、調用 Hermes API,並可選擇註冊後端端點——所有這些都無需修改儀表盤的源代碼。
快速開始
創建一個包含清單文件和 JS 文件的插件目錄:
mkdir -p ~/.hermes/plugins/my-plugin/dashboard/dist
manifest.json:
{
"name": "my-plugin",
"label": "My Plugin",
"icon": "Sparkles",
"version": "1.0.0",
"tab": {
"path": "/my-plugin",
"position": "after:skills"
},
"entry": "dist/index.js"
}
dist/index.js:
(function () {
var SDK = window.__HERMES_PLUGIN_SDK__;
var React = SDK.React;
var Card = SDK.components.Card;
var CardHeader = SDK.components.CardHeader;
var CardTitle = SDK.components.CardTitle;
var CardContent = SDK.components.CardContent;
function MyPage() {
return React.createElement(Card, null,
React.createElement(CardHeader, null,
React.createElement(CardTitle, null, "My Plugin")
),
React.createElement(CardContent, null,
React.createElement("p", { className: "text-sm text-muted-foreground" },
"Hello from my custom dashboard tab!"
)
)
);
}
window.__HERMES_PLUGINS__.register("my-plugin", MyPage);
})();
刷新儀表盤——你的標籤頁將出現在導航欄中。
插件結構
插件位於標準的 ~/.hermes/plugins/ 目錄內。儀表盤擴展是一個 dashboard/ 子文件夾:
~/.hermes/plugins/my-plugin/
plugin.yaml # optional — existing CLI/gateway plugin manifest
__init__.py # optional — existing CLI/gateway hooks
dashboard/ # dashboard extension
manifest.json # required — tab config, icon, entry point
dist/
index.js # required — pre-built JS bundle
style.css # optional — custom CSS
plugin_api.py # optional — backend API routes
單個插件可以從一個目錄同時擴展 CLI/網關(通過 plugin.yaml + __init__.py)和儀表盤(通過 dashboard/)。
清單參考
manifest.json 文件向儀表盤描述你的插件:
{
"name": "my-plugin",
"label": "My Plugin",
"description": "What this plugin does",
"icon": "Sparkles",
"version": "1.0.0",
"tab": {
"path": "/my-plugin",
"position": "after:skills"
},
"entry": "dist/index.js",
"css": "dist/style.css",
"api": "plugin_api.py"
}
| 字段 | 必需 | 描述 |
|---|---|---|
name | 是 | 唯一的插件標識符(小寫,可以使用連字符) |
label | 是 | 在導航標籤頁中顯示的顯示名稱 |
description | 否 | 簡短描述 |
icon | 否 | Lucide 圖標名稱(默認:Puzzle) |
version | 否 | Semver 版本字符串 |
tab.path | 是 | 標籤頁的 URL 路徑(例如 /my-plugin) |
tab.position | 否 | 插入標籤頁的位置:end(默認)、after:<tab>、before:<tab> |
entry | 是 | 相對於 dashboard/ 的 JS bundle 路徑 |
css | 否 | 要注入的 CSS 文件路徑 |
api | 否 | 包含 FastAPI 路由的 Python 文件路徑 |
標籤頁位置
position 字段控制你的標籤頁在導航中的顯示位置:
"end"— 在所有內置標籤頁之後(默認)"after:skills"— 在 Skills 標籤頁之後"before:config"— 在 Config 標籤頁之前"after:cron"— 在 Cron 標籤頁之後
冒號後面的值是目標標籤頁的路徑段(不帶前導斜槓)。
可用圖標
插件可以使用以下任何 Lucide 圖標名稱:
Activity, BarChart3, Clock, Code, Database, Eye, FileText, Globe, Heart, KeyRound, MessageSquare, Package, Puzzle, Settings, Shield, Sparkles, Star, Terminal, Wrench, Zap
無法識別的圖標名稱將回退到 Puzzle。
插件 SDK
插件不捆綁 React 或 UI 組件——它們使用暴露在 window.__HERMES_PLUGIN_SDK__ 上的 SDK。這避免了版本衝突並保持插件 bundle 小巧。
SDK 內容
var SDK = window.__HERMES_PLUGIN_SDK__;
// React
SDK.React // React instance
SDK.hooks.useState // React hooks
SDK.hooks.useEffect
SDK.hooks.useCallback
SDK.hooks.useMemo
SDK.hooks.useRef
SDK.hooks.useContext
SDK.hooks.createContext
// API
SDK.api // Hermes API client (getStatus, getSessions, etc.)
SDK.fetchJSON // Raw fetch for custom endpoints — handles auth automatically
// UI Components (shadcn/ui style)
SDK.components.Card
SDK.components.CardHeader
SDK.components.CardTitle
SDK.components.CardContent
SDK.components.Badge
SDK.components.Button
SDK.components.Input
SDK.components.Label
SDK.components.Select
SDK.components.SelectOption
SDK.components.Separator
SDK.components.Tabs
SDK.components.TabsList
SDK.components.TabsTrigger
// Utilities
SDK.utils.cn // Tailwind class merger (clsx + twMerge)
SDK.utils.timeAgo // "5m ago" from unix timestamp
SDK.utils.isoTimeAgo // "5m ago" from ISO string
// Hooks
SDK.useI18n // i18n translations
SDK.useTheme // Current theme info
使用 SDK.fetchJSON
用於調用插件的後端 API 端點:
SDK.fetchJSON("/api/plugins/my-plugin/data")
.then(function (result) {
console.log(result);
})
.catch(function (err) {
console.error("API call failed:", err);
});
fetchJSON 自動注入會話認證令牌,處理錯誤,並解析 JSON。
使用現有 API 方法
SDK.api 對象擁有所有內置 Hermes 端點的方法:
// Fetch agent status
SDK.api.getStatus().then(function (status) {
console.log("Version:", status.version);
});
// List sessions
SDK.api.getSessions(10).then(function (resp) {
console.log("Sessions:", resp.sessions.length);
});
後端 API 路由
插件可以通過在清單中設置 api 字段來註冊 FastAPI 路由。創建一個導出 router 的 Python 文件:
# plugin_api.py
from fastapi import APIRouter
router = APIRouter()
@router.get("/data")
async def get_data():
return {"items": ["one", "two", "three"]}
@router.post("/action")
async def do_action(body: dict):
return {"ok": True, "received": body}
路由掛載在 /api/plugins/<name>/,因此上述示例變為:
GET /api/plugins/my-plugin/dataPOST /api/plugins/my-plugin/action
插件 API 路由繞過會話令牌認證,因為儀表盤服務器僅綁定到 localhost。
訪問 Hermes 內部組件
後端路由可以從 hermes-agent 代碼庫中導入:
from fastapi import APIRouter
from hermes_state import SessionDB
from hermes_cli.config import load_config
router = APIRouter()
@router.get("/session-count")
async def session_count():
db = SessionDB()
try:
count = len(db.list_sessions(limit=9999))
return {"count": count}
finally:
db.close()
自定義 CSS
如果你的插件需要自定義樣式,請添加一個 CSS 文件並在清單中引用它:
{
"css": "dist/style.css"
}
CSS 文件在插件加載時作為 <link> 標籤注入。使用特定的類名以避免與儀表盤現有樣式衝突。
/* dist/style.css */
.my-plugin-chart {
border: 1px solid var(--color-border);
background: var(--color-card);
padding: 1rem;
}
你可以使用儀表盤的 CSS 自定義屬性(例如 --color-border, --color-foreground)以匹配當前主題。
插件加載流程
- 儀表盤加載——
main.tsx在window.__HERMES_PLUGIN_SDK__上暴露 SDK App.tsx調用usePlugins(),獲取GET /api/dashboard/plugins- 對於每個插件:注入 CSS
<link>(如果聲明),加載 JS<script> - 插件 JS 調用
window.__HERMES_PLUGINS__.register(name, Component) - 儀表盤將標籤頁添加到導航並將組件掛載為路由
插件在其腳本加載後最多有 2 秒的時間進行註冊。如果插件加載失敗,儀表盤將繼續運行而不包含該插件。
插件發現
儀表盤掃描以下目錄以查找 dashboard/manifest.json:
- 用戶插件:
~/.hermes/plugins/<name>/dashboard/manifest.json - 捆綁插件:
<repo>/plugins/<name>/dashboard/manifest.json - 項目插件:
./.hermes/plugins/<name>/dashboard/manifest.json(僅在設置HERMES_ENABLE_PROJECT_PLUGINS時)
用戶插件優先——如果多個來源中存在相同名稱的插件,則用戶版本勝出。
要在不重啟服務器的情況下強制重新掃描新添加的插件:
curl http://127.0.0.1:9119/api/dashboard/plugins/rescan
插件 API 端點
| 端點 | 方法 | 描述 |
|---|---|---|
/api/dashboard/plugins | GET | 列出已發現的插件 |
/api/dashboard/plugins/rescan | GET | 強制重新掃描新插件 |
/dashboard-plugins/<name>/<path> | GET | 提供插件靜態資源 |
/api/plugins/<name>/* | * | 插件註冊的 API 路由 |
示例插件
代碼庫在 plugins/example-dashboard/ 中包含一個示例插件,演示了:
- 使用 SDK 組件(Card、Badge、Button)
- 調用後端 API 路由
- 通過
window.__HERMES_PLUGINS__.register()進行註冊
要嘗試它,請運行 hermes dashboard — “Example” 標籤頁將出現在 Skills 之後。
提示
- 無需構建步驟 — 編寫純 JavaScript IIFE。如果你更喜歡 JSX,可以使用任何打包工具(esbuild、Vite、webpack),目標輸出為 IIFE 並將 React 作為外部依賴。
- 保持捆綁包小巧 — React 和所有 UI 組件均由 SDK 提供。你的捆綁包應僅包含你的插件邏輯。
- 使用主題變量 — 在 CSS 中引用
var(--color-*)以自動匹配用戶選擇的任何主題。 - 本地測試 — 運行
hermes dashboard --no-open並使用瀏覽器開發者工具驗證你的插件是否正確加載和註冊。