feat(cli): install capture hooks into the harness (PROT-8)#7
Merged
Conversation
ljones491
reviewed
Jun 2, 2026
Member
ljones491
left a comment
There was a problem hiding this comment.
Looks good, will approve when retargeted to main. Install command installs separate group from existing hooks, and uninstall correctly avoids wiping non-protostar hooks.
My personal preference would be to group command classes under related features. For example, InstallHooksCommand and CaptureCommand under Hooks/, Install/Uninstall under Installation/, etc. But the current structure works fine.
Add `protostar install-hooks`, which detects supported harnesses and wires protostar's capture hooks into their config idempotently. Harness integrations live behind an IHarness provider boundary (HarnessRegistry + ClaudeCodeHarness), so adding a harness is a single class and harness-specific knowledge stays isolated from the command and orchestration layers. - install-hooks: interactive multi-select, or non-interactive via --harness/--all/--yes; supports --dry-run and --remove. - capture (hidden): the stub installed hooks invoke; reads the hook payload from stdin and acknowledges. Registry sync lands in a later ticket. - ClaudeCodeHarness wires PostToolUse (Skill) and SessionStart through a surgical settings.json merge that preserves unrelated settings and is idempotent (managed entries recognised by a marker, replaced not duplicated). - install/uninstall now wire and remove hooks as part of the lifecycle (--no-hooks to opt out). install also copies the full build output for a framework-dependent build so the installed binary actually runs, and uninstall clears protostar's own directory safely. - Harness paths resolve from --harness-home / PROTOSTAR_HARNESS_ROOT / CLAUDE_CONFIG_DIR / ~/.claude so integration is testable against a fake harness without touching the real one. - Reqnroll acceptance scenarios (Scenario Outline, one row per harness) cover install, idempotency, preservation of existing settings, dry-run, remove, the capture stub, and the install/uninstall lifecycle.
Add `pstar.ps1` / `pstar.sh` that build-and-run the CLI in place, so manual testing does not need the full `dotnet run --project` invocation. Document a safe scratch-harness workflow (PROTOSTAR_HARNESS_ROOT pointing at a gitignored .dev/) so install-hooks and install can be exercised without editing the real ~/.claude, plus the dev-build install behaviour and the capture stdin caveat. Ignore .dev/ and out/.
9d37c6e to
ed0f74a
Compare
ljones491
approved these changes
Jun 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PROT-8: Install capture hooks into the harness
Adds
protostar install-hooks, which detects supported harnesses and wiresprotostar's capture hooks into them idempotently, so skill use is captured
automatically with no manual config editing.
Jira: https://voidprojects.atlassian.net/browse/PROT-8
Important
This PR is based on
feat/PROT-41-bdd-acceptance(the BDD harness), notmain, and targets that branch so the diff is only PROT-8's changes. OncePROT-41 merges, retarget this PR to
main.Harness provider boundary
Harness integrations live behind an
IHarnessinterface(
HarnessRegistry+ClaudeCodeHarness). Adding a harness is a single classplus one registry entry; the command and orchestration layers never change, so
churn in any one harness's config format stays contained.
What it does
install-hooks- interactive multi-select (space to toggle), ornon-interactive via
--harness/--all/--yes. Supports--dry-runand--remove.capture(hidden) - the stub installed hooks invoke; reads the hookpayload from stdin and acknowledges. Registry sync is a later ticket.
PostToolUse(Skill tool) andSessionStartvia asurgical
settings.jsonmerge that preserves unrelated settings and isidempotent (managed entries are recognised by a marker and replaced, not
duplicated).
installanduninstallnow wire and remove hooks(
--no-hooksto opt out). Removal also lives standalone asinstall-hooks --remove.--harness-home>PROTOSTAR_HARNESS_ROOT>CLAUDE_CONFIG_DIR>~/.claude, which is whatmakes integration testable against a fake harness.
Install bug fix (found while dogfooding)
installpreviously copied only the single running.exe. That is correct fora published self-contained single-file binary, but a framework-dependent build
(a local
dotnet build) is an apphost that needs its.dlland runtime configbeside it, so the install was broken.
installnow copies the whole buildoutput in that case (single file otherwise), and
uninstallclears protostar'sown directory safely.
Developer experience
pstar.ps1/pstar.shbuild-and-run the CLI in place.PROTOSTAR_HARNESS_ROOT->gitignored
.dev/) so hook/install commands can be tested without touchingthe real
~/.claude.Testing
Reqnroll acceptance scenarios (Scenario Outline, one row per harness) cover
install, idempotency, preservation of existing settings/user hooks, dry-run,
remove, the capture stub, and the install/uninstall lifecycle. Full suite green
(15/15) locally.