Skip to content

feat(cli): install capture hooks into the harness (PROT-8)#7

Merged
BlakeHastings merged 3 commits into
mainfrom
feat/PROT-8-install-hooks
Jun 3, 2026
Merged

feat(cli): install capture hooks into the harness (PROT-8)#7
BlakeHastings merged 3 commits into
mainfrom
feat/PROT-8-install-hooks

Conversation

@BlakeHastings
Copy link
Copy Markdown
Member

PROT-8: Install capture hooks into the harness

Adds protostar install-hooks, which detects supported harnesses and wires
protostar'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), not
main, and targets that branch so the diff is only PROT-8's changes. Once
PROT-41 merges, retarget this PR to main.

Harness provider boundary

Harness integrations live behind an IHarness interface
(HarnessRegistry + ClaudeCodeHarness). Adding a harness is a single class
plus 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), 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 is a later ticket.
  • Claude Code - wires PostToolUse (Skill tool) and SessionStart via a
    surgical settings.json merge that preserves unrelated settings and is
    idempotent (managed entries are recognised by a marker and replaced, not
    duplicated).
  • Lifecycle - install and uninstall now wire and remove hooks
    (--no-hooks to opt out). Removal also lives standalone as
    install-hooks --remove.
  • Redirectable roots - harness paths resolve from --harness-home >
    PROTOSTAR_HARNESS_ROOT > CLAUDE_CONFIG_DIR > ~/.claude, which is what
    makes integration testable against a fake harness.

Install bug fix (found while dogfooding)

install previously copied only the single running .exe. That is correct for
a published self-contained single-file binary, but a framework-dependent build
(a local dotnet build) is an apphost that needs its .dll and runtime config
beside it, so the install was broken. install now copies the whole build
output in that case (single file otherwise), and uninstall clears protostar's
own directory safely.

Developer experience

  • pstar.ps1 / pstar.sh build-and-run the CLI in place.
  • Documented a safe scratch-harness workflow (PROTOSTAR_HARNESS_ROOT ->
    gitignored .dev/) so hook/install commands can be tested without touching
    the 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.

Copy link
Copy Markdown
Member

@ljones491 ljones491 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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/.
@BlakeHastings BlakeHastings force-pushed the feat/PROT-8-install-hooks branch from 9d37c6e to ed0f74a Compare June 2, 2026 23:08
@BlakeHastings BlakeHastings changed the base branch from feat/PROT-41-bdd-acceptance to main June 2, 2026 23:08
@BlakeHastings BlakeHastings reopened this Jun 2, 2026
@BlakeHastings BlakeHastings requested a review from ljones491 June 2, 2026 23:13
@BlakeHastings BlakeHastings merged commit e790d17 into main Jun 3, 2026
2 checks passed
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.

2 participants