From 142430c6d26a38f9319ef46a7aa9a502aad660ff Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 23 Jan 2026 16:56:36 +0000 Subject: [PATCH] refactor: Replace `python -m deepwork.hooks.*` with `deepwork hook` CLI Use the portable `deepwork hook` CLI command instead of direct Python module invocation. This ensures hooks work consistently across all installation methods (Nix flake, pipx, uv, pip). https://claude.ai/code/session_01BPfXueRHYbYPHGjQpMbyn5 --- .claude/settings.json | 4 ++-- doc/architecture.md | 2 +- src/deepwork/core/hooks_syncer.py | 6 ++++-- tests/unit/test_hooks_syncer.py | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/.claude/settings.json b/.claude/settings.json index ac649fc3..258abeec 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -155,7 +155,7 @@ "hooks": [ { "type": "command", - "command": "python -m deepwork.hooks.rules_check" + "command": "deepwork hook rules_check" } ] } @@ -166,7 +166,7 @@ "hooks": [ { "type": "command", - "command": "python -m deepwork.hooks.rules_check" + "command": "deepwork hook rules_check" } ] } diff --git a/doc/architecture.md b/doc/architecture.md index 95617d1f..87532d09 100644 --- a/doc/architecture.md +++ b/doc/architecture.md @@ -1147,7 +1147,7 @@ The hooks are installed to `.claude/settings.json` during `deepwork sync`: { "hooks": { "Stop": [ - {"matcher": "", "hooks": [{"type": "command", "command": "python -m deepwork.hooks.rules_check"}]} + {"matcher": "", "hooks": [{"type": "command", "command": "deepwork hook rules_check"}]} ] } } diff --git a/src/deepwork/core/hooks_syncer.py b/src/deepwork/core/hooks_syncer.py index 4a97cbd7..35a01036 100644 --- a/src/deepwork/core/hooks_syncer.py +++ b/src/deepwork/core/hooks_syncer.py @@ -35,8 +35,10 @@ def get_command(self, project_path: Path) -> str: Command string to execute """ if self.module: - # Python module - run directly with python -m - return f"python -m {self.module}" + # Python module - use deepwork hook CLI for portability + # Extract hook name from module path (e.g., "deepwork.hooks.rules_check" -> "rules_check") + hook_name = self.module.rsplit(".", 1)[-1] + return f"deepwork hook {hook_name}" elif self.script: # Script path is: .deepwork/jobs/{job_name}/hooks/{script} script_path = self.job_dir / "hooks" / self.script diff --git a/tests/unit/test_hooks_syncer.py b/tests/unit/test_hooks_syncer.py index 79527681..99edcfdb 100644 --- a/tests/unit/test_hooks_syncer.py +++ b/tests/unit/test_hooks_syncer.py @@ -43,7 +43,7 @@ def test_get_command_for_module(self, temp_dir: Path) -> None: ) cmd = entry.get_command(temp_dir) - assert cmd == "python -m deepwork.hooks.rules_check" + assert cmd == "deepwork hook rules_check" class TestJobHooks: