跳转到内容
本页面的翻译由 LLM 生成。如果你发现翻译有误,请在 GitHub 上提交 issue 告诉我们。

插件

PK-Herdr 插件是可分享、可执行的工作流包。插件可以是 Bash 脚本、JavaScript 应用、Lua 脚本、Rust 二进制,或你机器上能运行的任何 argv 命令。PK-Herdr 负责宿主侧: 安装、清单校验、按键绑定、终端窗格、事件、调用上下文和 socket 访问。插件负责自己的实现语言、依赖、文件和持久状态。

插件的存在是为了让 PK-Herdr 保持精简。核心继续专注于终端工作区、窗格、 智能体和稳定的 CLI/socket API。插件把这套已有的扩展面变成可复用的 工作流,让大家可以构建、安装和分享,而不必把每种工作流都塞进 PK-Herdr 本体。

插件不是 SDK 集成。它是一个带 herdr-plugin.toml 清单和 PK-Herdr 可启动 命令的目录。PK-Herdr 校验清单、注入运行时上下文、启动声明的命令并记录日志。 命令在需要做更多工作时,通过 CLI 或 socket 回调 PK-Herdr。

没有单独的插件 SDK,也没有受限的命令集。整个 PK-Herdr CLI 就是插件 API: CLI 参考中的每条命令插件都能用,你自己能以 herdr ... 运行的任何东西,插件也能运行。大多数插件应通过指向运行中 PK-Herdr 二进制的 HERDR_BIN_PATH 调用 PK-Herdr,这样插件在 Unix socket 和 Windows 命名管道之间保持可移植。想自己发送原始 JSON 请求时,使用 socket API。

运行时动作注册和非终端的原生插件 UI 不在插件 v1 范围内。动作、事件钩子、 窗格和链接处理器都在清单中声明。

插件是运行在你机器上的普通代码。安装或链接一个插件时,它的构建和运行时 命令以你的用户身份、在你的环境中执行,并且可以调用完整的 PK-Herdr CLI — 和你给编辑器、shell 或编程智能体添加的任何扩展一样。这种开放性正是设计 初衷,加上一点判断力就能保持安全。

从你信任的作者和仓库安装插件,并先大致看看新插件做什么: herdr-plugin.toml 清单,以及它运行的脚本或二进制。pk-herdr plugin install 在交互式终端中会 展示来源和将要运行的命令的预览,你可以在确认前审查。对已经信任的来源用 --yes,想固定某个特定版本时用 --ref。

PK-Herdr 校验清单,并把每个插件的配置和状态放在各自的目录中,但它不会审查 或沙箱化插件的行为。第三方插件来自它们的作者,而不是 PK-Herdr,审查与运行 由你自行决定。

清单是 PK-Herdr 和插件之间的契约。它声明包元数据、支持的平台、可选的构建 命令,以及 PK-Herdr 可以运行的入口点。

id = "example.layout"
name = "Layout"
version = "0.1.0"
min_herdr_version = "0.7.0"
description = "Apply project layouts"
platforms = ["linux", "macos", "windows"]
[[build]]
command = ["npm", "ci"]
[[build]]
command = ["npm", "run", "build"]
platforms = ["linux", "macos"]
[[startup]]
command = ["node", "dist/restore.js"]
[[actions]]
id = "apply"
title = "Apply layout"
contexts = ["workspace"]
command = ["node", "dist/apply.js"]
[[events]]
on = "worktree.created"
command = ["pk-herdr", "workspace", "list"]
[[panes]]
id = "board"
title = "Project board"
placement = "overlay"
command = ["herdr-board"]
[[link_handlers]]
id = "github-issue"
title = "Open GitHub issue"
pattern = "^https://github\\.com/[^/]+/[^/]+/(issues|pull)/[0-9]+$"
action = "apply"

顶层的 id、name、version 和 min_herdr_version 是必填项。 把 min_herdr_version 设为支持你插件所用的插件 API、事件名和清单字段的 最老 PK-Herdr 版本。当插件的最低版本比当前二进制更新时,PK-Herdr 会拒绝链接 或安装。description 可选。插件 id 可以使用 ASCII 字母、数字、点、 冒号、下划线和连字符。

动作 id、窗格 id 和链接处理器 id 是插件内部的本地 id。它们可以使用 ASCII 字母、数字、冒号、下划线和连字符,但不能用点。每种 id 在插件内 必须唯一。当需要全局唯一名称时,PK-Herdr 会把动作 id 限定为 plugin.id.action 的形式。

用 platforms = ["linux", "macos", "windows"] 声明插件可以运行的平台。 构建命令、启动钩子、动作、事件钩子、窗格和链接处理器也可以声明自己的 platforms;条目级的 platforms 覆盖顶层列表。没有顶层 platforms 的本地 插件在链接时会给出警告。

command 的值是 argv 数组。PK-Herdr 不会通过 shell 运行它们,所以除非你的 命令自己启动 shell,否则没有 shell 展开。语言相关的行为放到你的脚本或 二进制里。

从一个包含 herdr-plugin.toml 和一个可执行脚本或程序的目录开始:

my-plugin/
herdr-plugin.toml
index.js
id = "example.workspace-tools"
name = "Workspace Tools"
version = "0.1.0"
min_herdr_version = "0.7.0"
description = "Small workspace helpers"
platforms = ["linux", "macos", "windows"]
[[actions]]
id = "list-workspaces"
title = "List workspaces"
contexts = ["workspace"]
command = ["node", "index.js"]

在命令内部通过 HERDR_BIN_PATH 回调 PK-Herdr:

const { spawnSync } = require("node:child_process");
const herdr = process.env.HERDR_BIN_PATH ?? "herdr";
const result = spawnSync(herdr, ["workspace", "list"], {
encoding: "utf8",
stdio: ["ignore", "pipe", "pipe"],
});
process.stdout.write(result.stdout);
process.stderr.write(result.stderr);
process.exit(result.status ?? 1);

这个示例用了 Node,但插件本身完全不要求 Node。清单可以启动 Bash、 PowerShell、Python、Rust、Go、Lua、Bun 或用户机器上可用的任何其他命令。

安装一个示例插件:

Terminal window
pk-herdr plugin install ogulcancelik/herdr-plugin-examples/agent-telegram-notify
pk-herdr plugin config-dir examples.agent-telegram-notify
pk-herdr plugin list
pk-herdr plugin action list --plugin examples.agent-telegram-notify

在本地编写插件时,改为链接工作目录:

Terminal window
pk-herdr plugin link /path/to/plugin
pk-herdr plugin config-dir example.layout
pk-herdr plugin action list --plugin example.layout
pk-herdr plugin action invoke example.layout.apply
pk-herdr plugin pane open --plugin example.layout --entrypoint board
pk-herdr plugin log list --plugin example.layout

plugin install 只接受 GitHub 简写,比如 owner/repo/subdir。它用 git 克隆,在交互式终端展示预览,运行受支持的构建命令,然后把检出保存到 PK-Herdr 管理的插件数据下并注册。非交互式安装用 --yes。重新安装 GitHub 管理的插件会替换该托管检出。已安装和已链接的插件及其启用状态对当前用户 全局生效,可在所有 PK-Herdr 会话中使用。即使 PK-Herdr 服务器没有运行,也可以通过 plugin install 和 plugin link 注册插件。仅安装在 PK-Herdr 0.7.3 命名会话中的 插件必须重新 install 或 link;现有的插件配置和状态会保留。 不允许覆盖安装到本地链接的插件之上;请先 unlink 或 uninstall 本地插件。 plugin install 和 plugin link 会创建 插件的配置和状态目录,plugin config-dir <id> 打印配置目录,方便安装 文档和 shell 脚本使用。

plugin uninstall <id-or-source> 注销插件。对 GitHub 管理的安装,它还会 删除托管检出,并且既接受插件 id,也接受与 install 相同的 owner/repo[/subdir...] 简写。plugin unlink <id> 只注销插件、不动文件, 对本地开发很有用。v1 没有单独的 plugin update;要刷新托管插件,请从 GitHub 重新安装。

示例菜谱仓库是 ogulcancelik/herdr-plugin-examples。它在子目录中包含 多个独立示例插件,包括 agent-telegram-notify、github-link-preview 和 dev-layout-bootstrap。这些是供复制的示例,不是持续维护的官方插件。

构建命令在 GitHub plugin install 过程中运行,时机在确认之后、PK-Herdr 注册插件之前。如果构建命令失败,安装中止,插件不会被注册。plugin link 不运行构建命令;本地作者自己构建工作树。构建命令可以生成文件,但在 安装预览之后修改 herdr-plugin.toml 会导致安装中止。构建失败时会显示 插件 id、构建序号、工作目录、命令、退出状态或 spawn 错误,以及截断后的 stdout/stderr,不会解读工具输出。

构建命令同样是普通的 argv 命令,但它们不会收到运行时插件上下文或 PK-Herdr socket 环境变量。插件作者应在文档中说明所需的系统工具,比如 cargo、npm、bun 或 lua;PK-Herdr 报告构建失败,但不会安装缺失的 工具链。

PK-Herdr 恢复会话且 API socket 就绪后,会为每个已启用插件运行一次 [[startup]] 命令。实时交接由新服务器接管时会再次运行,但客户端连接、 配置重载以及插件 link 或 enable 时不会运行。PK-Herdr 异步启动这些命令,并在 普通插件命令日志中记录完成情况。启动钩子失败不会停止服务器。

启动钩子是一次性初始化命令,不是受监督的守护进程。钩子应恢复插件自己的 状态、调用所需的 PK-Herdr API,然后退出。例如,插件可以把声明式 Agent 视图保存到 HERDR_PLUGIN_STATE_DIR,再由启动钩子读取并重新应用。

启动钩子会收到普通运行时插件环境和 HERDR_PLUGIN_EVENT=startup。安装预览会 列出所有启动命令,让用户检查将自动运行的代码。

运行时命令以插件目录为工作目录执行。PK-Herdr 注入 HERDR_SOCKET_PATH、 HERDR_BIN_PATH、HERDR_ENV=1、HERDR_PLUGIN_ID、HERDR_PLUGIN_ROOT、 HERDR_PLUGIN_CONFIG_DIR、HERDR_PLUGIN_STATE_DIR、 HERDR_PLUGIN_CONTEXT_JSON,以及可用时的 HERDR_WORKSPACE_ID、 HERDR_TAB_ID 和 HERDR_PANE_ID。动作命令还会收到 HERDR_PLUGIN_ACTION_ID;启动钩子和事件钩子收到 HERDR_PLUGIN_EVENT (启动钩子中的值为 startup),事件钩子还会收到 HERDR_PLUGIN_EVENT_JSON;窗格命令收到 HERDR_PLUGIN_ENTRYPOINT_ID。

HERDR_PLUGIN_ROOT 是已安装或已链接的插件目录。不要把用户凭据或持久 状态放在那里,因为 GitHub 安装的插件根目录是托管的源码检出。把 .env 这类用户可编辑的配置放在 HERDR_PLUGIN_CONFIG_DIR 下,把本地运行时 状态放在 HERDR_PLUGIN_STATE_DIR 下。PK-Herdr 会创建这些目录,并在旧版 插件配置位置存在时把内容初始化到 HERDR_PLUGIN_CONFIG_DIR,但不会校验、 同步或删除其中的内容。文件格式和生命周期归插件所有。

HERDR_PLUGIN_CONTEXT_JSON 在本次调用可用时,可以包含工作区、标签页、 聚焦窗格、worktree、智能体、选中文本、点击的 URL 和链接处理器字段。 shell 插件可以从各个环境变量读取常用 id,或解析上下文 JSON 获取完整结构。

当插件需要从 Node、PowerShell、Bash 或其他运行时可移植地调用 PK-Herdr 时, 使用 HERDR_BIN_PATH。HERDR_SOCKET_PATH 背后的原始 socket 传输是 操作系统相关的: Unix 客户端连接 Unix socket 路径,Windows 客户端连接 命名管道。通过 HERDR_BIN_PATH 的 CLI 调用可以避开这种传输差异。可用 命令见 CLI 参考,原始请求结构见 socket API。

清单中窗格的 placement 默认为 overlay,它在活动窗格上方打开一个 临时的缩放覆盖层,关闭时恢复之前的焦点和缩放。plugin.pane.open 请求 可以用 overlay、popup、split、tab 或 zoomed 覆盖清单的 placement。

placement = "popup" 会打开一个会话级模态终端弹窗,而不改变平铺布局。 可以在清单或 open 请求中指定可选的 width 和 height;省略时默认为终端大小的一半,数字表示外层终端单元格数,"80%" 这样的字符串表示终端区域的百分比。 弹窗会接收包括 Escape 在内的所有终端输入,并在命令退出或发送 popup.close 请求时关闭。 小于弹窗最小尺寸的值会限制为最小值。

如果某个插件窗格应始终是临时的,可直接在入口点上声明 placement:

[[panes]]
id = "picker"
title = "Picker"
platforms = ["linux", "macos"]
placement = "popup"
width = "80%"
height = 20
command = ["sh", "picker.sh"]

split、tab、zoomed 和 overlay 插件窗格打开后就是普通的 PK-Herdr 窗格。插件可以通过 socket 或 CLI 调用 pane.move、pane.swap、pane.resize、pane.zoom 等标准窗格 API; 窗格跨标签页或工作区移动时,PK-Herdr 会让插件窗格的所有权跟随底层窗格。 弹窗不是 PK-Herdr 窗格,而是会话级单例资源:它没有窗格 id,不会改变插件焦点上下文,不会发出窗格生命周期事件,也不参与 pane、layout、持久化或智能体 API。 其进程不会收到 HERDR_PANE_ID;底层平铺窗格仍可通过 HERDR_PLUGIN_CONTEXT_JSON 获取。 在 Settings、复制模式或其他 PK-Herdr 模态界面打开时尝试打开弹窗会返回 ui_busy;启动成功后,plugin.pane.open 返回 ok。

在 Windows 上,构建命令、动作命令和事件命令会在裸命令位于 PATH 上时 解析常见的 PATHEXT shim,比如 npm.cmd、bun.cmd 和 pnpm.cmd。 窗格命令使用 PK-Herdr 常规的 Windows 窗格启动器,仍然必须是有效的 Windows argv 命令。

把某个键绑定到已安装的插件动作:

[[keys.command]]
key = "prefix+l"
type = "plugin_action"
command = "example.layout.apply"
description = "apply layout"

用 [[link_handlers]] 把对匹配终端 URL 的修饰键点击路由到插件动作, 而不是在浏览器中打开 URL。修饰键点击的修饰键在所有平台上都是 Control, 包括 macOS,因为被捕获的终端鼠标上报无法把 Command/Super 和普通点击 区分开。pattern 是对被点击 URL 匹配的 Rust 正则表达式,action 必须 指向同一插件声明的动作。链接处理器动作在 HERDR_PLUGIN_CONTEXT_JSON 中收到 invocation_source = "link_click"、clicked_url 和 link_handler_id;shell 插件也可以读取 HERDR_PLUGIN_CLICKED_URL 和 HERDR_PLUGIN_LINK_HANDLER_ID。每个插件内的处理器按清单顺序检查。

v1 没有 PK-Herdr 管理的插件存储 API。需要持久状态的插件应自己管理文件或 数据库。

社区插件可以在插件市场中发现,它是打了 herdr-plugin 主题 标签的公开 GitHub 仓库的自动索引。插件仍然是普通的 GitHub 仓库: 发布一个 带 herdr-plugin.toml 的仓库,然后分享 pk-herdr plugin install owner/repo[/subdir]。

要让插件被收录,给它的公开仓库添加 GitHub 主题标签 herdr-plugin。索引 每 30 分钟刷新一次。发现机制的工作方式见插件市场。