Skip to content

Conversation

@ashwin-ant
Copy link
Collaborator

Closes the gap between Python and TypeScript SDK hook output types by adding:

  • reason field for explaining decisions
  • continue_ field for controlling execution flow
  • suppressOutput field for hiding stdout
  • stopReason field for stop explanations
  • decision now supports both "approve" and "block" (not just "block")
  • AsyncHookJSONOutput type for deferred hook execution
  • Proper typing for hookSpecificOutput with discriminated unions

Also adds comprehensive examples and tests:

  • New examples in hooks.py demonstrating all new fields
  • Unit tests in test_tool_callbacks.py for new output types
  • E2E tests in e2e-tests/test_hooks.py with real API calls
  • CI integration in .github/workflows/test.yml

🤖 Generated with Claude Code

@ashwin-ant ashwin-ant force-pushed the ashwin/hooktypes branch 2 times, most recently from bd31bc0 to 3cf6b56 Compare October 9, 2025 03:43
@ashwin-ant ashwin-ant marked this pull request as ready for review October 9, 2025 03:56
@ashwin-ant ashwin-ant requested a review from a team October 9, 2025 03:56
Copy link

@bcherny bcherny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @szwang for the stamp

szwang
szwang previously approved these changes Oct 9, 2025
Copy link
Collaborator

@szwang szwang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm! left a few minor questions and nonblocking ideas

stopReason: NotRequired[str]

# Decision fields
decision: NotRequired[Literal["approve", "block"]]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this used for every hook specific output? It feels more intuitive to me as something pre-tool use but not sure of how it gets used beyond that.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will stick with this since it's mirroring TS types, but we should revisit

$job = Start-Job { python examples/hooks.py DecisionFields }
Wait-Job $job -Timeout 120 | Out-Null
Stop-Job $job
Receive-Job $job
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we actually running on Windows for test-examples? Since runs-on: ubuntu-latest

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, good catch

"systemMessage": "⚠️ Command blocked by hook",
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would love to better understand the difference between decision and permissionDecision

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

decision and reason are actually deprecated, so it's a little confusing right now

ashwin-ant and others added 2 commits October 9, 2025 17:01
Closes the gap between Python and TypeScript SDK hook output types by adding:
- `reason` field for explaining decisions
- `continue_` field for controlling execution flow
- `suppressOutput` field for hiding stdout
- `stopReason` field for stop explanations
- `decision` now supports both "approve" and "block" (not just "block")
- `AsyncHookJSONOutput` type for deferred hook execution
- Proper typing for `hookSpecificOutput` with discriminated unions

Also adds comprehensive examples and tests:
- New examples in hooks.py demonstrating all new fields
- Unit tests in test_tool_callbacks.py for new output types
- E2E tests in e2e-tests/test_hooks.py with real API calls
- CI integration in .github/workflows/test.yml

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
- Remove deprecated `decision: "approve"` in favor of `permissionDecision: "allow"`
- Update `decision` type to only allow "block" (approve is deprecated)
- Replace string assertions with JSON parsing in unit tests for robustness
- Add HookJSONOutput type annotations to test hook functions
- Rename test to match actual behavior (permission decision vs generic decision)
- Update examples and documentation to use new permissionDecision API

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@ashwin-ant ashwin-ant merged commit e8d7e71 into main Oct 10, 2025
26 checks passed
@ashwin-ant ashwin-ant deleted the ashwin/hooktypes branch October 10, 2025 01:13
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.

4 participants