Skip to content

feat(spawn): add Treehouse worktree setup hook - #47

Closed
michael-sb wants to merge 12 commits into
kunchenguid:mainfrom
michael-sb:fm/worktree-setup-w3
Closed

feat(spawn): add Treehouse worktree setup hook#47
michael-sb wants to merge 12 commits into
kunchenguid:mainfrom
michael-sb:fm/worktree-setup-w3

Conversation

@michael-sb

Copy link
Copy Markdown

Intent

Add per-project worktree setup via treehouse post_create hook. A single global hook script (bin/fm-treehouse-post-create.sh) is wired in ~/.config/treehouse/config.toml and fires when treehouse provisions or resets a worktree. It locates firstmate's data/ from its own location and runs data/-setup.sh if it exists. Non-fatal on failure, logs to state/treehouse-setup-.log. Replaces earlier fm-spawn-based approach with treehouse-native lifecycle hook.

What Changed

  • Adds a Treehouse post_create hook script that runs optional per-project setup scripts from firstmate data and records non-fatal setup output under state logs.
  • Extends bootstrap to detect, validate, and install the global Treehouse hook configuration with hardened command parsing and quoting.
  • Updates spawn behavior, documentation, and tests for Treehouse-native worktree setup and hook environment handling.

Risk Assessment

✅ Low: Captain, the change is bounded to Treehouse hook wiring/spawn context plus focused tests, and I did not find substantiated merge-blocking or follow-up issues.

Testing

Inspected the targeted diff, ran the focused hook/bootstrap/spawn shell tests, captured reviewer-visible CLI evidence for hook wiring and setup execution/logging, and confirmed the worktree remained clean.

Evidence: treehouse-post-create-e2e-transcript
Treehouse post_create hook e2e verification
repo=/Users/michael/.no-mistakes/worktrees/458d9fed4d70/01KVSZTTNA0BR1Y3D5XK12THFM
commit=539e5297f842a684de95513470b186397e030a5a

$ FM_HOME=/var/folders/t0/dws_m6l52lj97dkt9f4hd_sh0000gn/T/no-mistakes-evidence/01KVSZTTNA0BR1Y3D5XK12THFM/treehouse-post-create-e2e/fm-home XDG_CONFIG_HOME=/var/folders/t0/dws_m6l52lj97dkt9f4hd_sh0000gn/T/no-mistakes-evidence/01KVSZTTNA0BR1Y3D5XK12THFM/treehouse-post-create-e2e/fm-home/xdg bin/fm-bootstrap.sh install treehouse-post-create-hook
installing treehouse-post-create-hook: /Users/michael/.no-mistakes/worktrees/458d9fed4d70/01KVSZTTNA0BR1Y3D5XK12THFM/bin/fm-bootstrap.sh install treehouse-post-create-hook

$ sed -n 1,20p /var/folders/t0/dws_m6l52lj97dkt9f4hd_sh0000gn/T/no-mistakes-evidence/01KVSZTTNA0BR1Y3D5XK12THFM/treehouse-post-create-e2e/fm-home/xdg/treehouse/config.toml
[hooks]
post_create = ["'/Users/michael/.no-mistakes/worktrees/458d9fed4d70/01KVSZTTNA0BR1Y3D5XK12THFM/bin/fm-treehouse-post-create.sh'"]

$ (cd /var/folders/t0/dws_m6l52lj97dkt9f4hd_sh0000gn/T/no-mistakes-evidence/01KVSZTTNA0BR1Y3D5XK12THFM/treehouse-post-create-e2e/worktrees/app && FM_HOME=/var/folders/t0/dws_m6l52lj97dkt9f4hd_sh0000gn/T/no-mistakes-evidence/01KVSZTTNA0BR1Y3D5XK12THFM/treehouse-post-create-e2e/fm-home /Users/michael/.no-mistakes/worktrees/458d9fed4d70/01KVSZTTNA0BR1Y3D5XK12THFM/bin/fm-treehouse-post-create.sh)

$ cat /var/folders/t0/dws_m6l52lj97dkt9f4hd_sh0000gn/T/no-mistakes-evidence/01KVSZTTNA0BR1Y3D5XK12THFM/treehouse-post-create-e2e/worktrees/app/setup-marker.txt
READY_FROM_SETUP

$ cat /var/folders/t0/dws_m6l52lj97dkt9f4hd_sh0000gn/T/no-mistakes-evidence/01KVSZTTNA0BR1Y3D5XK12THFM/treehouse-post-create-e2e/fm-home/state/treehouse-setup-app.log
setup ran in /var/folders/t0/dws_m6l52lj97dkt9f4hd_sh0000gn/T/no-mistakes-evidence/01KVSZTTNA0BR1Y3D5XK12THFM/treehouse-post-create-e2e/worktrees/app

$ test -f /var/folders/t0/dws_m6l52lj97dkt9f4hd_sh0000gn/T/no-mistakes-evidence/01KVSZTTNA0BR1Y3D5XK12THFM/treehouse-post-create-e2e/fm-home/state/treehouse-setup-app.log && test "$(cat /var/folders/t0/dws_m6l52lj97dkt9f4hd_sh0000gn/T/no-mistakes-evidence/01KVSZTTNA0BR1Y3D5XK12THFM/treehouse-post-create-e2e/worktrees/app/setup-marker.txt)" = READY_FROM_SETUP
verified: bootstrap wrote the hook config, the hook selected data/app-setup.sh for the matching project worktree, setup output was logged, and the worktree was modified by setup.

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

🔧 **Review** - 1 issue found → auto-fixed ✅
  • ⚠️ bin/fm-bootstrap.sh:130 - treehouse_hook_command_usable accepts an executable hook path anywhere in the shell command, so a post_create entry like echo /abs/bin/fm-treehouse-post-create.sh is treated as configured even though Treehouse would never execute the hook. Bootstrap would then stay silent while per-project setup never runs; restrict the match to the executable command word, allowing only known-safe prefixes such as environment assignments.

🔧 Fix: Captain, tighten treehouse hook detection
✅ Re-checked - no issues remain.

✅ **Test** - passed

✅ No issues found.

  • git status --short --branch
  • git diff --stat 2a2fe0566e63b883ec53dc3e34dc14306689f989..539e5297f842a684de95513470b186397e030a5a
  • git diff --name-only 2a2fe0566e63b883ec53dc3e34dc14306689f989..539e5297f842a684de95513470b186397e030a5a
  • tests/fm-treehouse-post-create.test.sh
  • tests/fm-bootstrap.test.sh
  • tests/fm-spawn-treehouse-env.test.sh
  • Created an isolated firstmate home and git worktree under /var/folders/t0/dws_m6l52lj97dkt9f4hd_sh0000gn/T/no-mistakes-evidence/01KVSZTTNA0BR1Y3D5XK12THFM/treehouse-post-create-e2e, ran bin/fm-bootstrap.sh install treehouse-post-create-hook with local FM_HOME/XDG_CONFIG_HOME, then invoked bin/fm-treehouse-post-create.sh from the matching worktree and verified the setup marker plus state/treehouse-setup-app.log.
  • git status --short
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

Treehouse v1.8.0 adds post_create/pre_destroy hooks that fire at worktree
lifecycle points. Use post_create to run per-project setup scripts
(data/<project>-setup.sh) right before treehouse get hands the worktree
over, which is earlier and simpler than waiting inside fm-spawn.

Add bin/fm-treehouse-post-create.sh, a single global hook script wired in
~/.config/treehouse/config.toml. It locates firstmate's data/ from its own
location and runs data/<project>-setup.sh if it exists (project name =
worktree directory basename, matching the data/projects.md convention).
Output is logged to state/treehouse-setup-<project>.log.

A failing setup script is non-fatal: treehouse continues on hook failure
by design, and the hook exits with the setup script's code so the failure
surfaces in treehouse's own logs. The mechanism is general - any project
can get a data/<name>-setup.sh and the hook picks it up automatically, no
per-project hardcoding. Secondmates have no project worktree, so the hook
is irrelevant to them.
@michael-sb

Copy link
Copy Markdown
Author

Sorry - my firstmate got a bit carried away - he can be quite proactive :D

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