Skip to content

refactor: extract hook protocol into coding-agent-hooks crate#452

Merged
eliothedeman merged 1 commit intomainfrom
eliot/practical-chatelet
Apr 16, 2026
Merged

refactor: extract hook protocol into coding-agent-hooks crate#452
eliothedeman merged 1 commit intomainfrom
eliot/practical-chatelet

Conversation

@eliothedeman
Copy link
Copy Markdown
Collaborator

Summary

  • Extracts the agent-agnostic hook handling logic into a new workspace crate called coding-agent-hooks (agent-hooks was already taken on crates.io)
  • The new crate provides HookProtocol trait, hook I/O types, AgentKind enum, all 6 agent protocol implementations, and tool/mode name normalization
  • The clash crate now depends on coding-agent-hooks and re-exports its types, keeping clash-specific extensions (typed tool input, interactive tool classification, SelectItem impl) local

Details

New crate: coding-agent-hooks

  • AgentKind enum with optional clap::ValueEnum derive behind a clap feature flag
  • HookProtocol trait — only 2 methods required to add a new agent
  • Effect enum (Allow/Ask/Deny) replacing claude_settings::PermissionRule in hook output types (serializes identically)
  • Protocol implementations for Claude, Gemini, Codex, AmazonQ, OpenCode, Copilot
  • Canonical tool alias table and permission mode resolution

Changes to clash crate

  • crate::hooks now re-exports from coding-agent-hooks + adds ToolUseHookInputExt extension trait for typed_tool_input()
  • crate::agents now re-exports from coding-agent-hooks + adds SelectItem impl
  • handlers.rs and cmd/hooks.rs updated to use Effect from new crate instead of PermissionRule
  • 7 files removed from clash/src/agents/ (moved to new crate)

Test plan

  • cargo test -p coding-agent-hooks — 50 tests pass (all agent protocols, I/O types, normalization)
  • cargo test -p clash — 389 tests pass (no regressions)
  • cargo test --workspace — full workspace green
  • cargo fmt --all -- --check — clean
  • cargo check --workspace — compiles without warnings

Move the agent-agnostic hook handling logic into a new workspace crate
called `coding-agent-hooks`. The name `agent-hooks` was taken on
crates.io.

The new crate provides:
- AgentKind enum with optional clap::ValueEnum (behind `clap` feature)
- HookProtocol trait abstracting agent-specific JSON formats
- Hook input/output types with an Effect enum (Allow/Ask/Deny)
- Protocol implementations for all 6 agents
- Tool name normalization and permission mode resolution tables

The clash crate now depends on coding-agent-hooks and re-exports its
types through crate::hooks and crate::agents. Clash-specific extensions
(typed_tool_input via ToolUseHookInputExt trait, is_interactive_tool,
SelectItem impl) remain in the clash crate.

Replaces claude_settings::PermissionRule in hook output types with the
new coding_agent_hooks::output::Effect enum, which serializes
identically (allow/ask/deny).
@eliothedeman eliothedeman enabled auto-merge April 16, 2026 17:06
@eliothedeman eliothedeman added this pull request to the merge queue Apr 16, 2026
Merged via the queue into main with commit 8c230eb Apr 16, 2026
2 checks passed
@eliothedeman eliothedeman deleted the eliot/practical-chatelet branch April 16, 2026 17:20
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.

1 participant