feat(#192): Phase 2 — muse hooks install/uninstall/status (local activation)
Hooks declared in .musehooks.toml (Phase 1) are still never executed automatically -- this phase adds the explicit, local, per-clone activation step. muse commit integration (only running installed hooks) lands in Phase 3.
Added: - muse/core/paths.py: hooks_installed_toml_path() -> .muse/hooks-installed.toml. Deliberately the one place .muse/ IS the correct home for state -- whether *this specific clone* has installed hooks must never propagate via clone/push/pull, unlike .musehooks.toml itself. A cloned repo gaining silent hook activation would be a supply-chain risk; git avoids this by never auto-installing hooks from a fresh checkout either. - muse/core/hooks.py: HooksStatus dataclass + install_hooks() / uninstall_hooks() / is_installed() / get_status(). Three-state status model: "not_defined" (no hook point declares anything, wins even over a stale local marker), "defined_not_installed", "installed". Both install and uninstall are idempotent by design (calling twice is a no-op, not an error) -- matches how activation state should behave. - muse/cli/commands/hooks.py: `muse hooks install`, `muse hooks uninstall`, `muse hooks status` subcommands, following the same envelope/exit-code conventions as `muse hooks list` from Phase 1.
Tests (TDD, red confirmed before implementation): - tests/test_core_hooks_install.py (13 tests, HK_10-13): install/uninstall writing and clearing the marker, install-without-file-yet succeeding, the three status states including the "empty commands list still counts as defined" boundary and the "stale marker + deleted .musehooks.toml still resolves to not_defined" edge case, and idempotency for both install and uninstall. - tests/test_cmd_hooks_install.py (10 tests): install/uninstall/status via the real CLI (CliRunner), JSON schemas, not-a-repo exit 2, malformed-TOML exit 1, text-mode nudge naming the exact install command. - Manually smoke-tested against a real disposable repo via muse-dev: status before/after install/uninstall all correct.
43/43 tests pass across all four hooks test files. tests/test_app.py (27 tests) still green -- no regressions.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Semantic Changes
63 symbols
Files Changed
+2
~3
1180 in snapshot
0 comments
muse hub commit comment sha256:d4df453a03f8b54af479f32103d9023556b28a0e38292215446959f238f3e418 --body "your comment"
No comments yet. Be the first to start the discussion.