Skip to content

Add herdr plugin integration and WT_* hook environment - #53

Open
bkildow wants to merge 1 commit into
mainfrom
feat/herdr-plugin-hooks
Open

Add herdr plugin integration and WT_* hook environment#53
bkildow wants to merge 1 commit into
mainfrom
feat/herdr-plugin-hooks

Conversation

@bkildow

@bkildow bkildow commented Sep 9, 2026

Copy link
Copy Markdown
Owner

Summary

  • wt herdr init installs a global herdr plugin. Its worktree.created hook applies shared files and runs setup hooks in herdr-created worktrees; its worktree.removed hook handles cleanup. Project root is resolved from the event's repo_key, so it works for both .bare and .git layouts and for checkouts outside the project tree.
  • post_remove hooks (new .worktree.yml key). herdr deletes the checkout before emitting worktree.removed, so ordinary teardown hooks are skipped there with a warning rather than run against the wrong directory. post_remove runs from the project root with WT_* exported, e.g. ddev delete -Oy "$(basename "$WT_WORKTREE_PATH")".
  • Setup/removal race: the created hook records its PID in herdr's plugin state dir; the removed hook stops and waits on a still-running setup before cleanup.
  • WT_* environment for all hooks: WT_PROJECT_ROOT, WT_WORKTREE_ID, WT_WORKTREE_PATH, WT_BRANCH_NAME are now exported to every hook across wt add, wt setup, wt remove, wt prune, the Claude Code hooks, and the herdr hooks. Hook runners take TemplateVars instead of a bare path.
  • Docs: README sections for wt herdr init, hook environment variables, and post-remove hooks; integrations/herdr/README.md records what herdr 0.9.0 actually does, with captured payloads.

Test plan

  • make dev (fmt, lint, tests, build) clean
  • Unit tests: event parsing, project-root resolution for both layouts, quiet no-op on non-wt repos, teardown skipped when dir gone / run when present, in-flight setup stopped, WT_* env visible to setup/teardown/post_remove
  • Live against herdr 0.9.0: sidebar-equivalent create → shared symlinks + setup in checkout; remove → post_remove from project root; remove during a 20s setup → setup killed, no stray process, pid file cleaned
  • Live wt add (foreground and background) and wt remove show correct per-worktree WT_* values
  • ddev delete <name> confirmed to work after the project directory is deleted (basis for the post_remove example)

https://claude.ai/code/session_01DYtq4h1YVJrotQVtc4bpDR

wt herdr init installs a global herdr plugin whose worktree.created and
worktree.removed event hooks call back into wt, so worktrees created from
herdr's sidebar get shared files applied and setup hooks run, and removals
get cleaned up.

Because herdr emits worktree.removed after the checkout is deleted,
ordinary teardown hooks are skipped there (they would run against the
wrong directory) and a new post_remove hook list runs from the project
root instead. The created hook records its PID in herdr's plugin state
dir so the removed hook can stop a setup that is still running.

All hooks (setup, parallel_setup, teardown, parallel_teardown,
post_remove) now receive WT_PROJECT_ROOT, WT_WORKTREE_ID,
WT_WORKTREE_PATH and WT_BRANCH_NAME, mirroring the template variables,
across wt add, wt setup, wt remove, wt prune, and the Claude Code and
herdr hooks.

Verified end to end against herdr 0.9.0, including removal while setup
is still running.

Claude-Session: https://claude.ai/code/session_01DYtq4h1YVJrotQVtc4bpDR
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant