跳到主要內容

儀表盤插件

儀表盤插件允許你向 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簡短描述
iconLucide 圖標名稱(默認:Puzzle
versionSemver 版本字符串
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/data
  • POST /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)以匹配當前主題。

插件加載流程

  1. 儀表盤加載——main.tsxwindow.__HERMES_PLUGIN_SDK__ 上暴露 SDK
  2. App.tsx 調用 usePlugins(),獲取 GET /api/dashboard/plugins
  3. 對於每個插件:注入 CSS <link>(如果聲明),加載 JS <script>
  4. 插件 JS 調用 window.__HERMES_PLUGINS__.register(name, Component)
  5. 儀表盤將標籤頁添加到導航並將組件掛載為路由

插件在其腳本加載後最多有 2 秒的時間進行註冊。如果插件加載失敗,儀表盤將繼續運行而不包含該插件。

插件發現

儀表盤掃描以下目錄以查找 dashboard/manifest.json

  1. 用戶插件: ~/.hermes/plugins/<name>/dashboard/manifest.json
  2. 捆綁插件: <repo>/plugins/<name>/dashboard/manifest.json
  3. 項目插件: ./.hermes/plugins/<name>/dashboard/manifest.json(僅在設置 HERMES_ENABLE_PROJECT_PLUGINS 時)

用戶插件優先——如果多個來源中存在相同名稱的插件,則用戶版本勝出。

要在不重啟服務器的情況下強制重新掃描新添加的插件:

curl http://127.0.0.1:9119/api/dashboard/plugins/rescan

插件 API 端點

端點方法描述
/api/dashboard/pluginsGET列出已發現的插件
/api/dashboard/plugins/rescanGET強制重新掃描新插件
/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 並使用瀏覽器開發者工具驗證你的插件是否正確加載和註冊。