Skip to content

refactor(cli, supervisor, provider): unify Hook input and simplify OutputDecision#68

Merged
guyskk merged 2 commits intomainfrom
fix/pretooluse-hook-quality
Jan 25, 2026
Merged

refactor(cli, supervisor, provider): unify Hook input and simplify OutputDecision#68
guyskk merged 2 commits intomainfrom
fix/pretooluse-hook-quality

Conversation

@guyskk
Copy link
Copy Markdown
Owner

@guyskk guyskk commented Jan 23, 2026

Summary

This PR refactors the PreToolUse hook implementation from PR #66 to improve code quality and API design.

Changes

1. Unified Hook Input Structure

Problem: PR #66 had three separate input types (HookInputHeader, StopHookInput, PreToolUseInput)

Solution: Created single unified HookInput struct that contains all fields for both event types

  • SessionID: Always required
  • HookEventName: Determines which fields are used ("Stop" or "PreToolUse")
  • Stop event fields: StopHookActive (used when HookEventName == "Stop")
  • PreToolUse event fields: ToolName, ToolInput, ToolUseID, TranscriptPath, CWD (used when HookEventName == "PreToolUse")

Benefits:

  • Single source of truth for input structure
  • Cleaner JSON unmarshaling - no need for separate types
  • More maintainable as new event types are added

2. Simplified OutputDecision API

Problem: PR #66 had two separate methods (OutputDecision and OutputPreToolUseDecision)

Solution:

  • Added eventType parameter to OutputDecision
  • Internal implementation uses outputStopDecisionInternal and outputPreToolUseDecisionInternal
  • Unknown event types default to Stop format for backward compatibility

Benefits:

  • Single entry point for all hook decisions
  • Easier to add new event types (just add a new case)
  • Backward compatible with existing Stop event behavior

3. Removed DetectEventType Function

Problem: detectEventType function only read and parsed, then returned parts separately

Solution: Parse input directly in RunSupervisorHook using json.Decoder

Benefits:

  • Simpler code flow
  • One JSON decode operation instead of read + unmarshal
  • More memory efficient for large inputs

4. Code Quality Improvements

  • Converted all Chinese comments to English for consistency
  • Added comprehensive documentation for all structs and functions
  • Improved error messages
  • Fixed typos: "transcript_path" → "TranscriptPath"

5. Test Improvements

  • Added tests for unified HookInput struct parsing
  • Removed deprecated OutputPreToolUseDecision tests
  • Updated all tests to use new OutputDecision API
  • Added test for unknown event type defaulting to Stop

Testing

  • ✅ All unit tests pass (go test ./...)
  • ✅ Lint checks pass (gofmt, go vet, shellcheck, markdownlint)
  • ✅ Build succeeds for all platforms

Files Changed

  • internal/cli/hook.go - Unified input parsing, simplified logic
  • internal/cli/hook_test.go - Updated tests for unified input structure
  • internal/provider/provider.go - No changes (using literal "AskUserQuestion")
  • internal/supervisor/output.go - Simplified OutputDecision with eventType parameter
  • internal/supervisor/output_test.go - Updated tests for new API
  • internal/supervisor/logger_integration_test.go - Updated OutputDecision calls

Backward Compatibility

All changes maintain 100% backward compatibility with existing Stop hook functionality. Unknown event types default to Stop format, ensuring robust behavior for future Claude Code updates.

…PreToolUse hook

## Code Quality Improvements

1. **Unified code style** - Changed all Chinese comments to English for consistency
2. **Added constants** - Defined PreToolUseMatcherAskUserQuestion constant to avoid magic strings
3. **Improved type aliases** - Added detailed deprecation explanation for HookOutput
4. **Enhanced documentation** - Added comprehensive comments explaining PreToolUseInput fields

## Bug Fixes

1. **Fixed event type detection** - Unknown event types now correctly default to Stop event for backward compatibility
   - Previous: Only checked if eventType == ""
   - Fixed: Explicitly check for known types (Stop, PreToolUse), default to Stop for all others

2. **Fixed test expectations** - Updated TestDetectEventType to expect EventTypeStop for unknown event types

3. **Added session ID validation** - detectEventType now returns error when session_id is missing

## Test Improvements

1. **Added TestDetectEventType_EmptySessionID** - Validates error handling for missing session_id
2. **Added TestDetectEventType_InvalidJSON** - Validates error handling for malformed JSON
3. **Fixed test expectations** - Updated default feedback messages to use English

## Additional Changes

- Updated fallback feedback messages from Chinese to English:
  - "请继续完成任务" → "Please continue completing the task"
  - "请继续完成任务后再提问" → "Please complete the task before asking questions"
  - "任务还没有完成,请继续" → "Please continue completing the task"

All changes maintain backward compatibility with existing Stop hook functionality.
## Changes

1. **Unified Hook input** - Replaced separate HookInputHeader, StopHookInput, and PreToolUseInput with single HookInput struct
   - HookInput contains all fields for both event types
   - HookEventName determines which fields are used
   - Removed detectEventType function - parsing now happens directly in RunSupervisorHook

2. **Simplified OutputDecision** - Added eventType parameter instead of separate functions
   - OutputDecision now accepts EventType, allow, feedback
   - Internal methods: outputStopDecisionInternal and outputPreToolUseDecisionInternal
   - Deprecated OutputPreToolUseDecision now calls OutputDecision with EventTypePreToolUse

3. **Removed unnecessary constant** - Deleted PreToolUseMatcherAskUserQuestion constant, using literal string

## Benefits

- **Clearer API**: Single input type for all hook events
- **Better extensibility**: Easy to add new event types by adding new case in OutputDecision
- **Backward compatible**: Existing Stop event behavior unchanged
- **No magic strings**: Using literal "AskUserQuestion" directly

## Files Changed

- internal/cli/hook.go - Unified input parsing and simplified logic
- internal/cli/hook_test.go - Updated tests for unified HookInput
- internal/provider/provider.go - Removed constant, use string literal
- internal/supervisor/output.go - Refactored OutputDecision with eventType parameter
- internal/supervisor/output_test.go - Updated tests for new signature
- internal/supervisor/logger_integration_test.go - Updated OutputDecision calls

All tests pass and all checks succeed.
@guyskk guyskk changed the title fix(cli, supervisor, provider): improve code quality and fix bugs in PreToolUse hook refactor(cli, supervisor, provider): unify Hook input and simplify OutputDecision Jan 24, 2026
@guyskk guyskk merged commit fe5930b into main Jan 25, 2026
3 checks passed
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