From tac
Designs hook-based event systems for ADW observability, capturing agent events like PreToolUse and broadcasting via hooks and WebSockets for real-time monitoring.
npx claudepluginhub melodic-software/claude-code-plugins --plugin tacThis skill is limited to using the following tools:
Design hook-based event systems for capturing and broadcasting agent activities in AI Developer Workflows.
Configures ADW hooks for observability including PreToolUse and PostToolUse, with settings.json setup and Python scripts for event logging and workflow monitoring.
Create event-driven hooks for Claude Code automation. Use when the user wants to create hooks, automate tool validation, add pre/post processing, enforce security policies, or configure settings.json hooks. Triggers: create hook, build hook, PreToolUse, PostToolUse, event automation, tool validation, security hook
Creates, validates, and refines Claude Code plugin hooks for workflow automation. Supports command hooks (shell scripts), prompt hooks (LLM decisions), event matching, decision schemas, and production safety validation.
Share bugs, ideas, or general feedback.
Design hook-based event systems for capturing and broadcasting agent activities in AI Developer Workflows.
Documentation Verification: This skill references Claude Code hook events and configuration that may change between releases. Before implementing, invoke
hook-managementskill to verify current event types and hook configuration patterns.
Verification Checkpoint:
hook-management for current event types?Implementation Note: Full hook event architecture requires Claude Agent SDK with custom tooling. This skill provides design patterns and specifications.
Documentation Verification: The event types listed here are Claude Code internal types that may change between releases. For authoritative current event types, query the
hook-managementskill which delegates todocs-managementfor official documentation.
ADW systems capture these event types:
| Event Type | Icon | Source | Payload |
|---|---|---|---|
PreToolUse | ๐ช | Hook | Tool name, inputs, session |
PostToolUse | ๐ช | Hook | Tool name, outputs, duration |
TextBlock | ๐ฌ | Agent | Response text, tokens |
ToolUseBlock | ๐ ๏ธ | Agent | Tool invocation record |
ThinkingBlock | ๐ง | Agent | Extended thinking content |
StepStart | โ๏ธ | System | Step name, inputs |
StepEnd | โ๏ธ | System | Step name, outputs, duration |
Create Pydantic models for events:
class ADWEvent(BaseModel):
type: str # Event type from table
adw_id: str # 8-char correlation ID
step: str # Current step name
timestamp: datetime
payload: dict # Type-specific data
summary: str | None # AI-generated summary
Set up Claude Code hooks:
{
"hooks": {
"PreToolUse": [{
"matcher": ".*",
"command": "python hooks/pre_tool.py"
}],
"PostToolUse": [{
"matcher": ".*",
"command": "python hooks/post_tool.py"
}]
}
}
Agent Execution
โ
โโโ PreToolUse โโโบ Hook Script โโโฌโโ Log to DB
โ โโโ Summarize (Haiku)
โผ โโโ Broadcast (WebSocket)
Tool Execution
โ
โโโ PostToolUse โโโบ Hook Script โโโฌโโ Log to DB
โ โโโ Summarize (Haiku)
โผ โโโ Broadcast (WebSocket)
Continue...
AI-generated event summaries using Haiku:
async def summarize_event(event: ADWEvent) -> str:
prompt = f"""Summarize in 15 words or less:
Event: {event.type}
Tool: {event.payload.get('tool_name', 'N/A')}
Data: {str(event.payload)[:500]}
"""
return await claude.complete(prompt, model="haiku")
Event distribution to clients:
class EventBroadcaster:
def __init__(self, ws_manager, db_client):
self.ws = ws_manager
self.db = db_client
async def broadcast(self, event: ADWEvent):
# Log to database first
await self.db.log_event(event)
# Broadcast to WebSocket clients
await self.ws.broadcast(event.dict())
#!/usr/bin/env python
import sys, json, asyncio
from adw_modules import broadcast, summarize
async def main():
data = json.load(sys.stdin)
event = {
"type": "PreToolUse",
"adw_id": data.get("adw_id"),
"step": data.get("step"),
"payload": {
"tool_name": data["tool_name"],
"tool_input": data["tool_input"]
}
}
event["summary"] = await summarize(event)
await broadcast(event)
if __name__ == "__main__":
asyncio.run(main())
#!/usr/bin/env python
import sys, json, asyncio
from adw_modules import broadcast, summarize
async def main():
data = json.load(sys.stdin)
event = {
"type": "PostToolUse",
"adw_id": data.get("adw_id"),
"step": data.get("step"),
"payload": {
"tool_name": data["tool_name"],
"tool_output": data.get("tool_output", "")[:1000],
"duration_ms": data.get("duration_ms", 0)
}
}
event["summary"] = await summarize(event)
await broadcast(event)
if __name__ == "__main__":
asyncio.run(main())
When designing hook event architecture:
## Hook Event Architecture Design
### Event Types
| Type | Trigger | Payload Schema |
| --- | --- | --- |
| [type] | [when triggered] | [fields] |
### Hook Configuration
```json
[hooks.json configuration]
[ASCII diagram of flow]
[How Haiku generates summaries]
[WebSocket or other broadcast mechanism]
[Event logging tables]
## Design Checklist
- [ ] Event types defined with payloads
- [ ] Hook configuration specified
- [ ] Event pipeline documented
- [ ] Summarization prompt designed
- [ ] Broadcast mechanism chosen
- [ ] Database schema defined
- [ ] Error handling considered
- [ ] Performance implications assessed
## Anti-Patterns
| Anti-Pattern | Problem | Solution |
| --- | --- | --- |
| Sync broadcasting | Blocks agent execution | Async dispatch |
| No correlation ID | Can't trace workflows | Use adw_id |
| Raw payload logging | Token waste | Truncate large data |
| Missing summaries | Hard to scan | Always summarize |
| No error handling | Silent failures | Log and recover |
## Cross-References
- @hook-event-patterns.md - Event type details
- @websocket-architecture.md - Broadcasting patterns
- @production-patterns.md - Database logging
- @adw-framework.md - ADW overview
## Version History
- **v1.0.0** (2026-01-01): Initial release (Lesson 14)
---
## Last Updated
**Date:** 2026-01-01
**Model:** claude-opus-4-5-20251101