diff options
| author | github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> | 2026-08-03 19:00:20 +0000 |
|---|---|---|
| committer | github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> | 2026-08-03 19:00:20 +0000 |
| commit | 3642e67c7b9c1d8608d72f288e80b410c602e55c (patch) | |
| tree | 31e956f8d0ce3ffa7ad06495c6523cc3c7b3a3a5 /website/src/content/docs/plugins.mdx | |
| parent | 346411fa21afd297f5ed3b3fa56f9e3fbf7654b7 (diff) | |
docs: update website manifest for v0.8.0
Diffstat (limited to 'website/src/content/docs/plugins.mdx')
| -rw-r--r-- | website/src/content/docs/plugins.mdx | 372 |
1 files changed, 0 insertions, 372 deletions
diff --git a/website/src/content/docs/plugins.mdx b/website/src/content/docs/plugins.mdx deleted file mode 100644 index 1d93bedc..00000000 --- a/website/src/content/docs/plugins.mdx +++ /dev/null @@ -1,372 +0,0 @@ ---- -title: Plugins -description: Author local Herdr plugins with manifest actions, event hooks, and panes. ---- - -Herdr plugins are shareable, executable workflow packages. A plugin can be a -Bash script, JavaScript app, Lua script, Rust binary, or any other argv command -your machine can run. Herdr owns the host surface: installation, manifest -validation, keybindings, terminal panes, events, invocation context, and socket -access. The plugin owns its implementation language, dependencies, files, and -durable state. - -Plugins exist so Herdr can stay lean. The core stays focused on terminal -workspaces, panes, agents, and a stable CLI/socket API. Plugins turn that -existing extension surface into reusable workflows that people can build, -install, and share without adding every workflow to Herdr itself. - -A plugin is not an SDK integration. It is a directory with a -`herdr-plugin.toml` manifest and commands Herdr can launch. Herdr validates the -manifest, injects runtime context, starts the declared commands, and records -logs. The commands call back into Herdr through the CLI or socket when they need -to do more work. - -There is no separate plugin SDK or restricted command set. The entire Herdr CLI -is the plugin API: every command in the [CLI reference](/docs/cli-reference/) is -available to a plugin, and anything you can run as `herdr ...` yourself a plugin -can run too. Most plugins should call Herdr through `HERDR_BIN_PATH`, which -points at the running Herdr binary. That keeps plugins portable across Unix -sockets and Windows named pipes. Use the [socket API](/docs/socket-api/) when -you want to send raw JSON requests yourself. - -Runtime action registration and native non-terminal plugin UI are not part of -plugin v1. Actions, event hooks, panes, and link handlers are all declared in -the manifest. - -## Trust and security - -A plugin is ordinary code that runs on your machine. When you install or link -one, its build and runtime commands run as your user, with your environment, and -can call the full Herdr CLI — the same as any extension you add to an editor, -shell, or coding agent. That openness is the point, and a little judgment keeps -it safe. - -Install plugins from authors and repositories you trust, and skim what a new one -does first: the `herdr-plugin.toml` manifest and the scripts or binaries it runs. -`herdr plugin install` shows a preview of the source and the commands it will run -in interactive terminals, so you can review before confirming. Use `--yes` for -sources you already trust, and pin `--ref` when you want a specific revision. - -Herdr validates the manifest and keeps each plugin's config and state in its own -directory, but it does not review or sandbox what a plugin does. Third-party -plugins come from their authors, not from Herdr, so they are yours to vet and run -at your own discretion. - -## Manifest - -The manifest is the contract between Herdr and the plugin. It declares package -metadata, supported platforms, optional build commands, and the entrypoints -Herdr can run. - -```toml -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 = ["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" -``` - -Top-level `id`, `name`, `version`, and `min_herdr_version` are required. -Set `min_herdr_version` to the oldest Herdr version that supports the plugin -APIs, event names, and manifest fields your plugin uses. Herdr refuses to link -or install a plugin when its minimum version is newer than the current binary. -`description` is optional. Plugin ids may use ASCII letters, digits, dot, -colon, underscore, and hyphen. - -Action ids, pane ids, and link handler ids are local ids inside the plugin. -They may use ASCII letters, digits, colon, underscore, and hyphen, but not -dots. Each id type must be unique inside a plugin. Herdr qualifies action ids -as `plugin.id.action` when it needs a globally unique name. - -Use `platforms = ["linux", "macos", "windows"]` to declare where the plugin -can run. Build commands, startup hooks, actions, event hooks, panes, and link -handlers can also declare their own `platforms`; item-level platforms override -the top-level list. Local plugins without top-level `platforms` link with a -warning. - -`command` values are argv arrays. Herdr does not run them through a shell, so -there is no shell expansion unless your command starts a shell itself. Put -language-specific behavior in your script or binary. - -## First plugin - -Start with a directory that contains `herdr-plugin.toml` and one executable -script or program: - -```text -my-plugin/ - herdr-plugin.toml - index.js -``` - -```toml -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"] -``` - -Inside the command, call back into Herdr with `HERDR_BIN_PATH`: - -```js -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); -``` - -This example uses Node, but nothing about plugins requires Node. The manifest -could launch Bash, PowerShell, Python, Rust, Go, Lua, Bun, or any other command -available on the user's machine. - -## Install and link - -Install an example plugin: - -```bash -herdr plugin install ogulcancelik/herdr-plugin-examples/agent-telegram-notify -herdr plugin config-dir examples.agent-telegram-notify -herdr plugin list -herdr plugin action list --plugin examples.agent-telegram-notify -``` - -When you are authoring a local plugin, link the working directory instead: - -```bash -herdr plugin link /path/to/plugin -herdr plugin config-dir example.layout -herdr plugin action list --plugin example.layout -herdr plugin action invoke example.layout.apply -herdr plugin pane open --plugin example.layout --entrypoint board -herdr plugin log list --plugin example.layout -``` - -`plugin install` accepts GitHub shorthand only, such as -`owner/repo/subdir`. It clones with `git`, shows a preview in interactive -terminals, runs supported build commands, then stores the checkout under -Herdr-managed plugin data and registers it. Use `--yes` for noninteractive -installs. Reinstalling a GitHub-managed plugin replaces that managed checkout. -Installed and linked plugins, including their enabled state, are global to the -current user and available in every Herdr session. Both `plugin install` and -`plugin link` can register plugins while no Herdr server is running. Plugins -installed only in a named session on Herdr 0.7.3 must be installed or linked -again. Existing plugin config and state remain in place. -Installing over a locally linked plugin is refused; unlink or uninstall the -local plugin first. `plugin install` and `plugin link` create the plugin's -config and state directories, and `plugin config-dir <id>` prints the config -directory for setup docs and shell scripts. - -`plugin uninstall <id-or-source>` unregisters the plugin. For GitHub-managed -installs it also removes the managed checkout, and it accepts either the plugin -id or the same `owner/repo[/subdir...]` shorthand used by install. -`plugin unlink <id>` only unregisters a plugin and leaves files alone, which is -useful for local development. There is no separate `plugin update` in v1; -reinstall from GitHub to refresh a managed plugin. - -The example cookbook repo is `ogulcancelik/herdr-plugin-examples`. It contains -separate example plugins in subdirectories, including `agent-telegram-notify`, -`github-link-preview`, and `dev-layout-bootstrap`. These are examples to copy, -not maintained official plugins. - -## Build commands - -Build commands run during GitHub `plugin install` after confirmation and before -Herdr registers the plugin. If a build command fails, install aborts and the -plugin is not registered. `plugin link` does not run build commands; local -authors build their working tree themselves. Build commands may generate files, -but changing `herdr-plugin.toml` after the install preview aborts install. Build -failures show the plugin id, build index, working directory, command, exit -status or spawn error, and capped stdout/stderr without interpreting tool output. - -Build commands are plain argv commands too, but they do not receive runtime -plugin context or Herdr socket env. Plugin authors should document required -system tools such as `cargo`, `npm`, `bun`, or `lua`; Herdr reports build -failures but does not install missing toolchains. - -## Startup hooks - -`[[startup]]` commands run once for each enabled plugin after Herdr restores the -session and its API socket is ready. They run again when a new server takes over -during live handoff, but not when a client attaches, config reloads, or a plugin -is linked or enabled. Herdr starts them asynchronously and records their -completion in the normal plugin command log. A startup failure does not stop the -server. - -Startup hooks are one-shot initialization commands, not supervised daemons. A -hook should restore plugin-owned state, call any required Herdr APIs, and exit. -For example, a plugin can save a declarative Agent view under -`HERDR_PLUGIN_STATE_DIR`, then read and reapply that view from its startup hook. - -Startup hooks receive the normal runtime plugin environment and -`HERDR_PLUGIN_EVENT=startup`. The install preview lists every startup command so -users can review code that will run automatically. - -## Commands and environment - -Runtime commands run with the plugin directory as their working directory. Herdr -injects `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`, and any available -`HERDR_WORKSPACE_ID`, `HERDR_TAB_ID`, and `HERDR_PANE_ID`. Action commands also -receive `HERDR_PLUGIN_ACTION_ID`; startup and event hooks receive -`HERDR_PLUGIN_EVENT` (`startup` for startup hooks), event hooks additionally -receive `HERDR_PLUGIN_EVENT_JSON`, and pane commands receive -`HERDR_PLUGIN_ENTRYPOINT_ID`. - -`HERDR_PLUGIN_ROOT` is the installed or linked plugin directory. Do not store -user credentials or durable state there, because GitHub-installed plugin roots -are managed source checkouts. Put user-editable config such as `.env` files -under `HERDR_PLUGIN_CONFIG_DIR`, and put local runtime state under -`HERDR_PLUGIN_STATE_DIR`. Herdr creates those directories and seeds -`HERDR_PLUGIN_CONFIG_DIR` from the legacy plugin config locations when present, -but it does not validate, sync, or delete their contents. The plugin owns the -file format and lifecycle. - -`HERDR_PLUGIN_CONTEXT_JSON` can include workspace, tab, focused pane, worktree, -agent, selected text, clicked URL, and link handler fields when they are -available for that invocation. Shell plugins can read the individual env vars -for common ids, or parse the context JSON for the full shape. - -Use `HERDR_BIN_PATH` when a plugin needs to call Herdr portably from Node, -PowerShell, Bash, or another runtime. The raw socket transport behind -`HERDR_SOCKET_PATH` is OS-specific: Unix clients connect to a Unix socket path, -while Windows clients connect to a named pipe. CLI calls through -`HERDR_BIN_PATH` avoid that transport difference. See the -[CLI reference](/docs/cli-reference/) for available commands and -[socket API](/docs/socket-api/) for raw request shapes. - -## Panes - -Manifest pane `placement` defaults to `overlay`, which opens a temporary zoomed -overlay over the active pane and restores the previous focus and zoom when it -closes. A `plugin.pane.open` request can override the manifest placement with -`overlay`, `popup`, `split`, `tab`, or `zoomed`. - -`placement = "popup"` opens a session-modal terminal popup without changing the -tiled layout. It accepts optional `width` and `height` fields in the manifest or -open request; omit them for the default half-size popup, use numbers for outer -terminal-cell dimensions, or use strings like `"80%"` for a percentage of the -terminal area. It receives all terminal input, including Escape, and closes -when the command exits or a `popup.close` request is sent. Dimensions smaller -than the popup minimum are clamped. - -Declare the placement directly on a plugin pane entrypoint when the pane should -always be transient: - -```toml -[[panes]] -id = "picker" -title = "Picker" -platforms = ["linux", "macos"] -placement = "popup" -width = "80%" -height = 20 -command = ["sh", "picker.sh"] -``` - -Split, tab, zoomed, and overlay plugin panes are normal Herdr panes after they -open. Plugins can call standard pane APIs such as `pane.move`, `pane.swap`, -`pane.resize`, and `pane.zoom` through the socket or CLI; Herdr keeps plugin -pane ownership attached to the underlying pane when it moves across tabs or -workspaces. A popup is a singleton session resource rather than a Herdr pane: -it has no pane ID, does not change plugin focus context, emits no pane lifecycle -events, and does not participate in pane, layout, persistence, or agent APIs. -Its process does not receive `HERDR_PANE_ID`; the underlying tiled pane remains -available through `HERDR_PLUGIN_CONTEXT_JSON`. -Opening a popup returns `ui_busy` while Settings, Copy mode, or another Herdr -modal is active, and `plugin.pane.open` returns an `ok` result after launch. - -On Windows, build commands, action commands, and event commands resolve common -`PATHEXT` shims such as `npm.cmd`, `bun.cmd`, and `pnpm.cmd` when the bare -command is on `PATH`. Pane commands use Herdr's normal Windows pane launcher and -must still be valid Windows argv commands. - -## Keybindings - -Bind a key to an installed plugin action: - -```toml -[[keys.command]] -key = "prefix+l" -type = "plugin_action" -command = "example.layout.apply" -description = "apply layout" -``` - -## Link handlers - -Use `[[link_handlers]]` to route modified clicks on matching terminal URLs to a -plugin action instead of opening the URL in the browser. The modified-click -modifier is Control on every platform, including macOS, because captured -terminal mouse reports do not expose Command/Super separately from a plain -click. `pattern` is a Rust regular expression matched against the clicked URL, -and `action` must -name an action declared by the same plugin. Link handler actions receive -`invocation_source = "link_click"`, `clicked_url`, and `link_handler_id` in -`HERDR_PLUGIN_CONTEXT_JSON`; shell plugins can also read -`HERDR_PLUGIN_CLICKED_URL` and `HERDR_PLUGIN_LINK_HANDLER_ID`. Handlers are -checked in manifest order inside each plugin. - -## Storage - -There is no Herdr-managed plugin storage API in v1. Plugins that need durable -state should own their files or database. - -## Marketplace - -Community plugins are discoverable in the [marketplace](/plugins/), an automatic -index of public GitHub repositories tagged with the topic `herdr-plugin`. -Plugins stay ordinary GitHub repositories: publish one with `herdr-plugin.toml`, -then share `herdr plugin install owner/repo[/subdir]`. - -To get a plugin listed, add the GitHub topic `herdr-plugin` to its public -repository. The index refreshes every 30 minutes. See -[Marketplace](/docs/marketplace/) for how discovery works. |
