Name | claude-hooks JSON |
Version |
0.1.1
JSON |
| download |
home_page | None |
Summary | Python utilities for handling Claude Code hooks with a framework for creating event-driven hooks |
upload_time | 2025-07-18 16:34:07 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.12 |
license | Apache-2.0 |
keywords |
ai
automation
claude
hooks
|
VCS |
 |
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# claude-hooks
## Why This Exists
A portable Python framework for writing Claude Code hooks that reduces boilerplate and provides essential infrastructure:
- **Portable Python Hooks**: Write hooks in Python with proper dependency management via `uv`
- **Automatic Logging**: Built-in rotating log files for all hook executions
- **Dependency Support**: Use `uv` inline dependencies in your hooks when needed
- **Isolated Environment**: All hooks run in their own virtual environment
- **Framework Structure**: Provides the scaffolding to focus on hook logic, not infrastructure
## Installation vs Creation
This package provides two main operations:
**`uvx claude-hooks init`** - **Installs** hook templates and creates/updates `settings.json`
- Creates template files for all hook types (or specific ones with arguments)
- Creates a new `settings.json` file or **merges** hook configurations into existing one
- Existing `settings.json` content is preserved - only adds missing hook entries
- Templates provide the framework structure and automatic logging setup
**`uvx claude-hooks create <filename>`** - **Creates** a single hook file
- Generates one hook file without touching `settings.json`
- Provided for flexibility init is expected to be most frequently used
```bash
# Install all hook templates + settings.json
uvx claude-hooks init
# Install specific hook templates + settings.json
uvx claude-hooks init notification pre-tool-use
# Create a single hook file (no settings.json changes)
uvx claude-hooks create notification.py
# See all available hook types and options
uvx claude-hooks init --help
uvx claude-hooks create --help
```
## Folder Structure
When you run `init`, this framework creates a specific folder structure:
```
.claude/
├── hooks/ # All hook files go here
│ ├── notification.py
│ ├── pre_tool_use.py
│ ├── post_tool_use.py
│ ├── stop.py
│ ├── subagent_stop.py
│ ├── pre_compact.py
│ └── logs/ # Auto-created when hooks run
│ ├── notification.log
│ ├── pretooluse.log
│ └── ...
└── settings.json # Claude Code configuration
```
**For global hooks in `~/.claude/`:**
- Hook files: `~/.claude/hooks/*.py`
- Log files: `~/.claude/hooks/logs/*.log`
- Settings: `~/.claude/settings.json`
**For project hooks:**
- Hook files: `./.claude/hooks/*.py`
- Log files: `./.claude/hooks/logs/*.log`
- Settings: `./.claude/settings.json`
## Global vs Project Hooks
You can install hooks at different levels to serve different purposes:
### Global Hooks (~/.claude/)
Install hooks in your global Claude directory for system-wide functionality:
```bash
cd ~/.claude
uvx claude-hooks init notification stop
```
**Use global hooks for:**
- **Universal logging**: Log all Claude Code activity across all projects
- **General notifications**: System-wide alerts and monitoring
- **Security policies**: Apply consistent security rules everywhere
- **Personal preferences**: Your own workflow and safety checks
### Project Hooks (./project-root/)
Install hooks in specific project directories for project-specific functionality:
```bash
cd /path/to/your/project
uvx claude-hooks init pre-tool-use post-tool-use
```
**Use project hooks for:**
- **Project-specific linting**: Run project's linter/formatter on file edits
- **Code quality**: Enforce project coding standards and conventions
- **CI/CD integration**: Validate changes before they're made
- **Team policies**: Shared rules that apply to all team members
### Why This Matters
**Global hooks** provide consistent behavior across all your Claude Code usage with centralized logging and personal preferences.
**Project hooks** can be shared with your team, ensuring consistent project-specific behavior for all team members.
Claude Code will use hooks from both locations when available, with project hooks taking precedence for overlapping functionality.
## Usage
### Simple Exit Code Hooks
```python
from claude_hooks import run_hooks
def security_hook(event):
# PreToolUse hook - supports approve, block, undefined
if event.tool_name == "Bash":
command = event.tool_input.get("command", "")
if "rm -rf" in command:
return event.block("Dangerous command blocked")
elif command.startswith("ls"):
return event.approve("Safe listing command")
return event.undefined() # Let Claude Code decide
if __name__ == "__main__":
run_hooks(security_hook)
```
### Advanced JSON Output Hooks
```python
from claude_hooks import run_hooks
def advanced_hook(event):
if event.tool_name == "Edit":
file_path = event.tool_input.get("file_path", "")
# Block with JSON output
if ".env" in file_path:
return event.block_json("Sensitive file access blocked")
# Approve with suppressed transcript output
if file_path.endswith(".log"):
return event.approve_json("Log access approved", suppress_output=True)
# Stop Claude entirely for critical files
if "critical" in file_path:
return event.stop_claude("Manual review required for critical files")
return event.undefined_json()
if __name__ == "__main__":
run_hooks(advanced_hook)
```
### Parallel Hook Execution
Run multiple hooks in parallel - any hook returning `BLOCK` immediately blocks the operation:
```python
from claude_hooks import run_hooks
def security_hook(event):
if "dangerous" in event.tool_input.get("command", ""):
return event.block("Security violation")
return event.undefined()
def audit_hook(event):
# Log all tool usage
print(f"Tool used: {event.tool_name}")
return event.undefined()
def compliance_hook(event):
if event.tool_name in ["Edit", "Write"]:
file_path = event.tool_input.get("file_path", "")
if ".env" in file_path:
return event.block("Compliance: No env file modifications")
return event.undefined()
if __name__ == "__main__":
# All hooks run in parallel - first block wins
run_hooks(security_hook, audit_hook, compliance_hook)
```
### Serial vs Parallel Execution
**Serial Execution**: Functions call each other in sequence
```python
def first_hook(event):
# First security check
if "rm -rf" in event.tool_input.get("command", ""):
return event.block("Dangerous command")
# Pass to next hook
return second_hook(event)
def second_hook(event):
# Second check after first passes
if "sudo" in event.tool_input.get("command", ""):
return event.block("Elevated privileges")
return event.undefined()
if __name__ == "__main__":
run_hooks(first_hook) # Only register the first - it calls the second
```
**Parallel Execution**: Register multiple functions to run simultaneously
```python
def security_hook(event):
if "rm -rf" in event.tool_input.get("command", ""):
return event.block("Security violation")
return event.undefined()
def compliance_hook(event):
if "sudo" in event.tool_input.get("command", ""):
return event.block("Compliance violation")
return event.undefined()
if __name__ == "__main__":
# Both hooks run in parallel - first to block wins
run_hooks(security_hook, compliance_hook)
```
### Hook-Specific Constraints
Each hook type supports different decision types:
```python
# PreToolUse - supports all decisions
def pre_tool_hook(event):
return event.approve("reason") # ✅ Allowed
return event.block("reason") # ✅ Allowed
return event.undefined() # ✅ Allowed
# PostToolUse - only block and undefined
def post_tool_hook(event):
return event.approve("reason") # ❌ Raises NotImplementedError
return event.block("reason") # ✅ Allowed
return event.undefined() # ✅ Allowed
# Notification - only undefined behavior
def notification_hook(event):
print(f"Received: {event.message}")
return None # ✅ Allowed (treated as undefined)
# or return event.undefined()
```
## Hook Types
| Hook Type | Supports | Description |
|-----------|----------|-------------|
| **PreToolUse** | approve, block, undefined | Called before tool execution, can block or approve tools |
| **PostToolUse** | block, undefined | Called after tool execution with response data |
| **Notification** | undefined only | Called for various Claude Code notifications |
| **Stop** | block, undefined | Called when Claude finishes, can prevent stopping |
| **SubagentStop** | block, undefined | Called when Claude subagent stops |
| **PreCompact** | undefined only | Called before conversation compaction |
## Output Modes
### Simple Exit Codes
- **Exit 0**: Success/approve (stdout shown to user in transcript)
- **Exit 2**: Block operation (stderr fed back to Claude)
### Advanced JSON Output
- **Decision Control**: `"approve"`, `"block"`, or undefined
- **Continue Control**: Stop Claude with `"continue": false`
- **Output Suppression**: Hide from transcript with `"suppressOutput": true`
- **Stop Reason**: Custom message when stopping Claude
Both upstream naming (`suppressOutput`, `stopReason`) and Python-style shortcuts (`suppress_output`, `stop_reason`) are supported.
## Upstream Compatibility
This framework is fully compatible with Claude Code's official hook specification:
- **Hook Input Format**: [https://docs.anthropic.com/en/docs/claude-code/hooks#hook-input](https://docs.anthropic.com/en/docs/claude-code/hooks#hook-input)
- **Hook Output Format**: [https://docs.anthropic.com/en/docs/claude-code/hooks#hook-output](https://docs.anthropic.com/en/docs/claude-code/hooks#hook-output)
## Testing Hooks
After creating or editing hook files, test them to catch runtime errors before they affect Claude Code sessions:
```bash
# From your hooks directory (where pyproject.toml is located)
cd ~/.claude/hooks # or cd ./hooks for project hooks
# Test hook types with sample data
uv run claude-hooks test notification --message "Test notification" -v
uv run claude-hooks test pre-tool-use --tool "Bash" --command "ls -la" -v
uv run claude-hooks test post-tool-use --tool "Read" --output "file contents" -v
uv run claude-hooks test stop --session-id "test-123" -v
# See all test options
uv run claude-hooks test --help
```
**Important**: Always run tests from the hooks directory after editing any hook files. Failed hooks show detailed error messages and stack traces to help debug issues.
## Convenience Features
This framework adds developer-friendly features on top of the upstream specification:
### Event Helper Classes
- **Type-safe access**: `event.tool_name`, `event.tool_input`, `event.tool_response`
- **Convenience properties**: `event.session_id`, `event.transcript_path`
- **Validation**: Automatic validation of required fields per hook type
### Decision Helper Methods
- **Simple**: `event.block("reason")`, `event.approve("reason")`, `event.undefined()`
- **JSON**: `event.block_json()`, `event.approve_json()`, `event.undefined_json()`, `event.stop_claude()`
- **Global**: `block()`, `approve()`, `undefined()`, `block_json()`, etc.
### Automatic Logging
All hook functions get automatic logging with no imports required:
```python
def my_hook(event):
event.logger.info("Hook executed successfully")
event.logger.debug("Detailed debug information")
event.logger.warning("Something needs attention")
event.logger.error("An error occurred")
return event.undefined()
```
**Log Location**: `logs/{event_name}.log` (e.g., `notification.log`, `pretooluse.log`)
**Log Format**: `timestamp [function_name] LEVEL: message`
**Control Log Level**: Set environment variable before starting Claude Code:
```bash
export CLAUDE_HOOKS_LOG_LEVEL=DEBUG # DEBUG, INFO (default), WARNING, ERROR, CRITICAL
claude
```
## License
Apache-2.0
Raw data
{
"_id": null,
"home_page": null,
"name": "claude-hooks",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.12",
"maintainer_email": null,
"keywords": "ai, automation, claude, hooks",
"author": null,
"author_email": "Chris Sanders <sanders.chris@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/8f/2b/e5235af6c2de8e0f838ffa97b1dc8c77c98c589242e9ac83d8bd06d15294/claude_hooks-0.1.1.tar.gz",
"platform": null,
"description": "# claude-hooks\n\n## Why This Exists\n\nA portable Python framework for writing Claude Code hooks that reduces boilerplate and provides essential infrastructure:\n\n- **Portable Python Hooks**: Write hooks in Python with proper dependency management via `uv`\n- **Automatic Logging**: Built-in rotating log files for all hook executions\n- **Dependency Support**: Use `uv` inline dependencies in your hooks when needed\n- **Isolated Environment**: All hooks run in their own virtual environment\n- **Framework Structure**: Provides the scaffolding to focus on hook logic, not infrastructure\n\n## Installation vs Creation\n\nThis package provides two main operations:\n\n**`uvx claude-hooks init`** - **Installs** hook templates and creates/updates `settings.json`\n- Creates template files for all hook types (or specific ones with arguments)\n- Creates a new `settings.json` file or **merges** hook configurations into existing one\n- Existing `settings.json` content is preserved - only adds missing hook entries\n- Templates provide the framework structure and automatic logging setup\n\n**`uvx claude-hooks create <filename>`** - **Creates** a single hook file\n- Generates one hook file without touching `settings.json`\n- Provided for flexibility init is expected to be most frequently used\n\n```bash\n# Install all hook templates + settings.json\nuvx claude-hooks init\n\n# Install specific hook templates + settings.json \nuvx claude-hooks init notification pre-tool-use\n\n# Create a single hook file (no settings.json changes)\nuvx claude-hooks create notification.py\n\n# See all available hook types and options\nuvx claude-hooks init --help\nuvx claude-hooks create --help\n```\n\n## Folder Structure\n\nWhen you run `init`, this framework creates a specific folder structure:\n\n```\n.claude/\n\u251c\u2500\u2500 hooks/ # All hook files go here\n\u2502 \u251c\u2500\u2500 notification.py\n\u2502 \u251c\u2500\u2500 pre_tool_use.py\n\u2502 \u251c\u2500\u2500 post_tool_use.py\n\u2502 \u251c\u2500\u2500 stop.py\n\u2502 \u251c\u2500\u2500 subagent_stop.py\n\u2502 \u251c\u2500\u2500 pre_compact.py\n\u2502 \u2514\u2500\u2500 logs/ # Auto-created when hooks run\n\u2502 \u251c\u2500\u2500 notification.log\n\u2502 \u251c\u2500\u2500 pretooluse.log\n\u2502 \u2514\u2500\u2500 ...\n\u2514\u2500\u2500 settings.json # Claude Code configuration\n```\n\n**For global hooks in `~/.claude/`:**\n- Hook files: `~/.claude/hooks/*.py` \n- Log files: `~/.claude/hooks/logs/*.log`\n- Settings: `~/.claude/settings.json`\n\n**For project hooks:**\n- Hook files: `./.claude/hooks/*.py`\n- Log files: `./.claude/hooks/logs/*.log`\n- Settings: `./.claude/settings.json`\n\n## Global vs Project Hooks\n\nYou can install hooks at different levels to serve different purposes:\n\n### Global Hooks (~/.claude/)\nInstall hooks in your global Claude directory for system-wide functionality:\n\n```bash\ncd ~/.claude\nuvx claude-hooks init notification stop\n```\n\n**Use global hooks for:**\n- **Universal logging**: Log all Claude Code activity across all projects\n- **General notifications**: System-wide alerts and monitoring\n- **Security policies**: Apply consistent security rules everywhere\n- **Personal preferences**: Your own workflow and safety checks\n\n### Project Hooks (./project-root/)\nInstall hooks in specific project directories for project-specific functionality:\n\n```bash\ncd /path/to/your/project\nuvx claude-hooks init pre-tool-use post-tool-use\n```\n\n**Use project hooks for:**\n- **Project-specific linting**: Run project's linter/formatter on file edits\n- **Code quality**: Enforce project coding standards and conventions\n- **CI/CD integration**: Validate changes before they're made\n- **Team policies**: Shared rules that apply to all team members\n\n### Why This Matters\n\n**Global hooks** provide consistent behavior across all your Claude Code usage with centralized logging and personal preferences.\n\n**Project hooks** can be shared with your team, ensuring consistent project-specific behavior for all team members.\n\nClaude Code will use hooks from both locations when available, with project hooks taking precedence for overlapping functionality.\n\n## Usage\n\n### Simple Exit Code Hooks\n\n```python\nfrom claude_hooks import run_hooks\n\ndef security_hook(event):\n # PreToolUse hook - supports approve, block, undefined\n if event.tool_name == \"Bash\":\n command = event.tool_input.get(\"command\", \"\")\n if \"rm -rf\" in command:\n return event.block(\"Dangerous command blocked\")\n elif command.startswith(\"ls\"):\n return event.approve(\"Safe listing command\")\n \n return event.undefined() # Let Claude Code decide\n\nif __name__ == \"__main__\":\n run_hooks(security_hook)\n```\n\n### Advanced JSON Output Hooks\n\n```python\nfrom claude_hooks import run_hooks\n\ndef advanced_hook(event):\n if event.tool_name == \"Edit\":\n file_path = event.tool_input.get(\"file_path\", \"\")\n \n # Block with JSON output\n if \".env\" in file_path:\n return event.block_json(\"Sensitive file access blocked\")\n \n # Approve with suppressed transcript output\n if file_path.endswith(\".log\"):\n return event.approve_json(\"Log access approved\", suppress_output=True)\n \n # Stop Claude entirely for critical files\n if \"critical\" in file_path:\n return event.stop_claude(\"Manual review required for critical files\")\n \n return event.undefined_json()\n\nif __name__ == \"__main__\":\n run_hooks(advanced_hook)\n```\n\n### Parallel Hook Execution\n\nRun multiple hooks in parallel - any hook returning `BLOCK` immediately blocks the operation:\n\n```python\nfrom claude_hooks import run_hooks\n\ndef security_hook(event):\n if \"dangerous\" in event.tool_input.get(\"command\", \"\"):\n return event.block(\"Security violation\")\n return event.undefined()\n\ndef audit_hook(event):\n # Log all tool usage\n print(f\"Tool used: {event.tool_name}\")\n return event.undefined()\n\ndef compliance_hook(event):\n if event.tool_name in [\"Edit\", \"Write\"]:\n file_path = event.tool_input.get(\"file_path\", \"\")\n if \".env\" in file_path:\n return event.block(\"Compliance: No env file modifications\")\n return event.undefined()\n\nif __name__ == \"__main__\":\n # All hooks run in parallel - first block wins\n run_hooks(security_hook, audit_hook, compliance_hook)\n```\n\n### Serial vs Parallel Execution\n\n**Serial Execution**: Functions call each other in sequence\n```python\ndef first_hook(event):\n # First security check\n if \"rm -rf\" in event.tool_input.get(\"command\", \"\"):\n return event.block(\"Dangerous command\")\n \n # Pass to next hook\n return second_hook(event)\n\ndef second_hook(event):\n # Second check after first passes\n if \"sudo\" in event.tool_input.get(\"command\", \"\"):\n return event.block(\"Elevated privileges\")\n \n return event.undefined()\n\nif __name__ == \"__main__\":\n run_hooks(first_hook) # Only register the first - it calls the second\n```\n\n**Parallel Execution**: Register multiple functions to run simultaneously\n```python\ndef security_hook(event):\n if \"rm -rf\" in event.tool_input.get(\"command\", \"\"):\n return event.block(\"Security violation\")\n return event.undefined()\n\ndef compliance_hook(event):\n if \"sudo\" in event.tool_input.get(\"command\", \"\"):\n return event.block(\"Compliance violation\")\n return event.undefined()\n\nif __name__ == \"__main__\":\n # Both hooks run in parallel - first to block wins\n run_hooks(security_hook, compliance_hook)\n```\n\n### Hook-Specific Constraints\n\nEach hook type supports different decision types:\n\n```python\n# PreToolUse - supports all decisions\ndef pre_tool_hook(event):\n return event.approve(\"reason\") # \u2705 Allowed\n return event.block(\"reason\") # \u2705 Allowed \n return event.undefined() # \u2705 Allowed\n\n# PostToolUse - only block and undefined\ndef post_tool_hook(event):\n return event.approve(\"reason\") # \u274c Raises NotImplementedError\n return event.block(\"reason\") # \u2705 Allowed\n return event.undefined() # \u2705 Allowed\n\n# Notification - only undefined behavior \ndef notification_hook(event):\n print(f\"Received: {event.message}\")\n return None # \u2705 Allowed (treated as undefined)\n # or return event.undefined()\n```\n\n## Hook Types\n\n| Hook Type | Supports | Description |\n|-----------|----------|-------------|\n| **PreToolUse** | approve, block, undefined | Called before tool execution, can block or approve tools |\n| **PostToolUse** | block, undefined | Called after tool execution with response data |\n| **Notification** | undefined only | Called for various Claude Code notifications |\n| **Stop** | block, undefined | Called when Claude finishes, can prevent stopping |\n| **SubagentStop** | block, undefined | Called when Claude subagent stops |\n| **PreCompact** | undefined only | Called before conversation compaction |\n\n## Output Modes\n\n### Simple Exit Codes\n- **Exit 0**: Success/approve (stdout shown to user in transcript)\n- **Exit 2**: Block operation (stderr fed back to Claude)\n\n### Advanced JSON Output\n- **Decision Control**: `\"approve\"`, `\"block\"`, or undefined\n- **Continue Control**: Stop Claude with `\"continue\": false`\n- **Output Suppression**: Hide from transcript with `\"suppressOutput\": true`\n- **Stop Reason**: Custom message when stopping Claude\n\nBoth upstream naming (`suppressOutput`, `stopReason`) and Python-style shortcuts (`suppress_output`, `stop_reason`) are supported.\n\n## Upstream Compatibility\n\nThis framework is fully compatible with Claude Code's official hook specification:\n\n- **Hook Input Format**: [https://docs.anthropic.com/en/docs/claude-code/hooks#hook-input](https://docs.anthropic.com/en/docs/claude-code/hooks#hook-input)\n- **Hook Output Format**: [https://docs.anthropic.com/en/docs/claude-code/hooks#hook-output](https://docs.anthropic.com/en/docs/claude-code/hooks#hook-output)\n\n## Testing Hooks\n\nAfter creating or editing hook files, test them to catch runtime errors before they affect Claude Code sessions:\n\n```bash\n# From your hooks directory (where pyproject.toml is located)\ncd ~/.claude/hooks # or cd ./hooks for project hooks\n\n# Test hook types with sample data\nuv run claude-hooks test notification --message \"Test notification\" -v\nuv run claude-hooks test pre-tool-use --tool \"Bash\" --command \"ls -la\" -v \nuv run claude-hooks test post-tool-use --tool \"Read\" --output \"file contents\" -v\nuv run claude-hooks test stop --session-id \"test-123\" -v\n\n# See all test options\nuv run claude-hooks test --help\n```\n\n**Important**: Always run tests from the hooks directory after editing any hook files. Failed hooks show detailed error messages and stack traces to help debug issues.\n\n## Convenience Features\n\nThis framework adds developer-friendly features on top of the upstream specification:\n\n### Event Helper Classes\n- **Type-safe access**: `event.tool_name`, `event.tool_input`, `event.tool_response` \n- **Convenience properties**: `event.session_id`, `event.transcript_path`\n- **Validation**: Automatic validation of required fields per hook type\n\n### Decision Helper Methods\n- **Simple**: `event.block(\"reason\")`, `event.approve(\"reason\")`, `event.undefined()`\n- **JSON**: `event.block_json()`, `event.approve_json()`, `event.undefined_json()`, `event.stop_claude()`\n- **Global**: `block()`, `approve()`, `undefined()`, `block_json()`, etc.\n\n### Automatic Logging\nAll hook functions get automatic logging with no imports required:\n\n```python\ndef my_hook(event):\n event.logger.info(\"Hook executed successfully\")\n event.logger.debug(\"Detailed debug information\") \n event.logger.warning(\"Something needs attention\")\n event.logger.error(\"An error occurred\")\n return event.undefined()\n```\n\n**Log Location**: `logs/{event_name}.log` (e.g., `notification.log`, `pretooluse.log`) \n**Log Format**: `timestamp [function_name] LEVEL: message`\n\n**Control Log Level**: Set environment variable before starting Claude Code:\n```bash\nexport CLAUDE_HOOKS_LOG_LEVEL=DEBUG # DEBUG, INFO (default), WARNING, ERROR, CRITICAL\nclaude\n```\n\n## License\n\nApache-2.0\n",
"bugtrack_url": null,
"license": "Apache-2.0",
"summary": "Python utilities for handling Claude Code hooks with a framework for creating event-driven hooks",
"version": "0.1.1",
"project_urls": {
"Homepage": "https://github.com/chrissanders/claude-hooks",
"Issues": "https://github.com/chrissanders/claude-hooks/issues",
"Repository": "https://github.com/chrissanders/claude-hooks"
},
"split_keywords": [
"ai",
" automation",
" claude",
" hooks"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "079edc2d04181a3b3df8bc713280687565ab1a74c35dd6aaf07b35b4e89336f7",
"md5": "b8aff035e311bf029fa6a5fb92c1ae0a",
"sha256": "06a6ffd2701829b354bf18534b4ac62ee796eb936f0250f4eb5ffaa7c3d1b8f9"
},
"downloads": -1,
"filename": "claude_hooks-0.1.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "b8aff035e311bf029fa6a5fb92c1ae0a",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.12",
"size": 22057,
"upload_time": "2025-07-18T16:34:06",
"upload_time_iso_8601": "2025-07-18T16:34:06.734682Z",
"url": "https://files.pythonhosted.org/packages/07/9e/dc2d04181a3b3df8bc713280687565ab1a74c35dd6aaf07b35b4e89336f7/claude_hooks-0.1.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "8f2be5235af6c2de8e0f838ffa97b1dc8c77c98c589242e9ac83d8bd06d15294",
"md5": "fee48d1bc285fc5ab84d6cd4d8588364",
"sha256": "620822fd92b6fd29c8bd25002884112cfaf0e11b4a560539e3e90c8c59e71e0c"
},
"downloads": -1,
"filename": "claude_hooks-0.1.1.tar.gz",
"has_sig": false,
"md5_digest": "fee48d1bc285fc5ab84d6cd4d8588364",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.12",
"size": 33538,
"upload_time": "2025-07-18T16:34:07",
"upload_time_iso_8601": "2025-07-18T16:34:07.627800Z",
"url": "https://files.pythonhosted.org/packages/8f/2b/e5235af6c2de8e0f838ffa97b1dc8c77c98c589242e9ac83d8bd06d15294/claude_hooks-0.1.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-18 16:34:07",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "chrissanders",
"github_project": "claude-hooks",
"github_not_found": true,
"lcname": "claude-hooks"
}