| name | managing-herdr-plugins |
| description | Installs, audits, forks, develops, links, updates, and removes Herdr plugins. Use whenever working with Herdr plugins, herdr-plugin.toml, the Herdr marketplace, local plugin forks, plugin PRs, or switching Herdr from an upstream plugin to a local checkout. |
Managing Herdr Plugins
Manage Herdr plugins without running unreviewed code and keep Adam's local
forks, mr inventory, Stow-managed registry, and Org notes consistent.
Non-negotiable rules
-
Audit before execution. Read
the security audit procedure completely and
audit the exact source snapshot before running a build, package install,
test, plugin action, herdr plugin install, or herdr plugin link.
-
Treat a plugin as arbitrary code running as the user. Herdr does not sandbox
plugins, and the marketplace is an automatic, unreviewed GitHub index.
-
An audit reduces risk; it cannot prove that code is non-malicious. Do not
install when the audit is incomplete, a binary is unverifiable, dependencies
are unpinned, or a critical finding remains.
-
Present the audit report, exact commit SHA, and residual risks, then obtain
the user's explicit approval before first execution or installation.
-
Never edit ~/.config/herdr/plugins.json manually. Herdr rewrites it, often
replacing its Stow symlink. After every install, reinstall, link, unlink,
enable, disable, or uninstall, run:
stow --adopt -d ~/.STOW -t ~ --no-folding herdr-config
-
Use GNU Stow, never ln, for Herdr configuration links.
-
A fork used for local development belongs under ~/.GIT/3rd-party, must be
registered in ~/.config/mr/groups.d/26-AI, and must be documented in
~/org/notes/herdr.org.
-
Before editing another repository (~/.config/mr, ~/org, or a plugin),
read that repository's agent instructions and inspect its Git status. Do not
overwrite unrelated changes.
-
Never stage, commit, or rewrite history in ~/org. Edit the required Org
files in the working tree only, then leave them unstaged for the repository's
auto-commit and auto-sync. Do not run git add, git commit, git commit --amend, rebase, reset, or force-push in ~/org. If an existing unmerged
path cannot be cleared without an index update, stop and obtain explicit user
permission before a single file-scoped git add that marks only the resolved
conflict; leave the merge commit to auto-commit.
Decide which workflow applies
- Evaluate or install upstream: audit a detached inspection checkout, then
install the reviewed SHA with Herdr.
- Develop, patch, or contribute: fork upstream, manage the checkout with
mr, audit it, build it, and use herdr plugin link so Herdr executes the
local working tree.
- Refresh an existing plugin: audit all commits and dependency changes since
the previously approved SHA before reinstalling or rebuilding.
Installing a reviewed upstream plugin
plugin install accepts GitHub shorthand only: owner/repo[/subdir...].
-
Clone without running repository code and record the immutable commit:
audit_dir=$(mktemp -d)
git -c core.hooksPath=/dev/null clone --no-recurse-submodules \
https://github.com/OWNER/REPO.git "$audit_dir/REPO"
git -C "$audit_dir/REPO" checkout --detach REF
reviewed_sha=$(git -C "$audit_dir/REPO" rev-parse HEAD)
-
Apply the complete security audit to the whole checkout and the plugin
subdirectory. A subdirectory plugin can still be affected by repository-root
build files, workspaces, dependencies, CI, and shared code, so do not audit
only the subdirectory.
-
Ask for approval using the audit report and reviewed_sha.
-
Install the exact reviewed revision. Prefer the interactive trust preview;
use --yes only for an already reviewed noninteractive installation:
source=OWNER/REPO
herdr plugin install "$source" --ref "$reviewed_sha"
-
Adopt the generated registry, then verify the registration:
stow --adopt -d ~/.STOW -t ~ --no-folding herdr-config
herdr plugin list --plugin PLUGIN_ID --json | jq .
herdr plugin action list --plugin PLUGIN_ID
There is no plugin update in plugin v1. To update a GitHub-managed plugin,
audit the new revision and reinstall it with a new exact --ref.
Creating and tracking a local fork
Use repository name REPO as the mr entry name unless local conventions
require otherwise.
-
Create Adam's GitHub fork without cloning into an unmanaged location:
gh repo fork OWNER/REPO --clone=false
-
Add this stanza to ~/.config/mr/groups.d/26-AI, following the surrounding
ordering and formatting:
[$HOME/.GIT/3rd-party/REPO]
checkout = github_clone
remotes = auto_remotes
lib =
set_git_origin_user OWNER
Add set_git_origin_name REPO only when the checkout directory name and
upstream repository name differ. Do not add automatic build or link fixups:
future updates must be audited before they execute.
-
Check out and verify the managed repository:
mrco REPO
git -C ~/.GIT/3rd-party/REPO remote -v
git -C ~/.GIT/3rd-party/REPO config remote.pushDefault
Local mr conventions normally retain upstream as origin, add Adam's fork
as github, and add machine remotes. Verify rather than assuming names.
-
Audit the exact checkout before installing dependencies or building it.
-
Work on a topic branch, not the upstream default branch:
git -C ~/.GIT/3rd-party/REPO switch -c TYPE/TOPIC
Making Herdr use the local fork
Set plugin_root to the checkout directory containing herdr-plugin.toml; for
a monorepo it may be ~/.GIT/3rd-party/REPO/SUBDIR.
-
Determine the plugin id from herdr-plugin.toml and inspect any current
registration:
herdr plugin list --plugin PLUGIN_ID --json | jq .
-
If the same id is GitHub-managed, uninstall it. If it is already local,
unlink it. These commands unregister the plugin; uninstall additionally
removes Herdr's managed GitHub checkout, while unlink leaves local files:
herdr plugin uninstall PLUGIN_ID
herdr plugin unlink PLUGIN_ID
stow --adopt -d ~/.STOW -t ~ --no-folding herdr-config
-
Build the audited checkout using the repository's documented locked and
reproducible process. plugin link does not run manifest build commands.
-
Link the working tree and adopt the registry:
plugin_root=$(realpath ~/.GIT/3rd-party/REPO)
herdr plugin link "$plugin_root"
stow --adopt -d ~/.STOW -t ~ --no-folding herdr-config
-
Prove that Herdr points to the fork rather than a managed upstream clone:
herdr plugin list --plugin PLUGIN_ID --json |
jq -e --arg root "$plugin_root" \
'.result.plugins | length == 1 and
.[0].source.kind == "local" and .[0].plugin_root == $root'
Do not copy fork source into this configuration repository and do not create a
second manifest here. The registry's absolute local path is the source of truth;
mr ensures the checkout occupies the same path on managed machines.
Local development loop
-
Source/script changes are read from the linked working tree on the next
invocation. Event hooks may execute them without a manual action.
-
Disable the plugin before pulling, rebasing, switching to, or introducing
unreviewed executable code. Adopt the registry. Audit and rebuild the new
snapshot before relinking/enabling it, then adopt the registry again.
-
Rebuild compiled plugins after source changes.
-
Rerun herdr plugin link "$plugin_root" after changing
herdr-plugin.toml, because actions, events, panes, and link handlers are
registered from the manifest. Adopt plugins.json afterward.
-
Startup hooks do not run merely because a plugin is linked or enabled. Test
them with a deliberate Herdr server restart/handoff after approval.
-
Exercise narrow entrypoints and inspect logs:
herdr plugin action list --plugin PLUGIN_ID
herdr plugin action invoke PLUGIN_ID.ACTION
herdr plugin pane open --plugin PLUGIN_ID --entrypoint PANE_ID
herdr plugin log list --plugin PLUGIN_ID --limit 50
-
Run repository tests and linters only after their commands and dependencies
have been audited.
-
Before each rebuild after pulling/rebasing, review the incoming diff,
dependency/lockfile changes, generated files, and resulting tree. Repeat the
full audit when trust boundaries or executable paths changed.
Contributing changes upstream
- Keep one focused topic branch and include tests/documentation expected by
upstream.
- Review
git diff origin/DEFAULT...HEAD for secrets, unrelated changes, new
executable behavior, and dependency changes.
- Commit and push to the verified writable fork remote (normally
github).
- Create a PR targeting
OWNER/REPO; include what was tested and any security
implications. Obtain user approval before publishing the PR.
- Keep Herdr linked to
~/.GIT/3rd-party/REPO[/SUBDIR] while the PR is open.
Do not reinstall upstream merely because a PR exists.
- After merge, fetch/rebase the fork, audit the merged revision, rebuild, and
relink. To return to Herdr-managed upstream later, unlink the local plugin
and install an audited exact upstream SHA.
Required Org documentation
Keep ~/org/notes/herdr.org's final two top-level sections named
* Useful keybindings and * Installed plugins; do not append a new top-level
section after them.
- Under
* Useful keybindings, update the appropriate table whenever the
plugin adds or changes a binding. Ensure the documented key, config entry,
qualified action id, and actual behavior agree.
- Put only installed or linked plugins under
* Installed plugins.
- Put evaluated but rejected plugins under a separate
* Rejected plugins
section before the final * Useful keybindings and * Installed plugins
sections. Record why installation was rejected.
- Each plugin subsection should contain upstream and fork links, plugin id,
purpose, local checkout/subdirectory, currently reviewed SHA, audit
date/verdict and residual risks, build command,
herdr plugin link command,
useful actions, and PR/issue links as applicable.
- If no keybinding exists, say so in the appropriate plugin subsection rather
than inventing one.
- Leave Org documentation changes unstaged and uncommitted. The
~/org
auto-commit and auto-sync must create and synchronize the commit; never run
staging, commit, or history-rewriting commands there.
Registry and final verification
After any plugin registry mutation:
stow --adopt -d ~/.STOW -t ~ --no-folding herdr-config
readlink ~/.config/herdr/plugins.json
herdr plugin list --plugin PLUGIN_ID --json | jq .
git -C ~/.GIT/adamspiers.org/herdr-config diff -- .config/herdr/plugins.json
git -C ~/.config/mr diff -- groups.d/26-AI
git -C ~/org diff -- notes/herdr.org
Confirm no unrelated registry entries changed, the linked root is under
~/.GIT/3rd-party, the plugin remains enabled only when intended, and all
three repositories contain only expected changes.
Herdr facts and references
- Remote installs run manifest
[[build]] commands; local links do not.
- Commands run as argv arrays unless the manifest explicitly invokes a shell.
- Runtime commands receive the plugin root, config/state directories, context,
socket, and Herdr binary paths. They can call the full Herdr CLI.
- User-editable configuration belongs in
HERDR_PLUGIN_CONFIG_DIR; durable
state belongs in HERDR_PLUGIN_STATE_DIR, not the managed source checkout.
- Official documentation:
Plugins,
CLI reference, and
Marketplace.