Skip to main content

Claude Code

Run uvx jes login first. See Setup.

Install​

uvx jes claude-settings

Merge the hooks object it prints into ~/.claude/settings.json. Each command is pinned to the jes release that printed it. Print the settings again after you upgrade.

uvx jes claude-settings
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "uvx jes@0.0.1 claude-hook",
"timeout": 60
}
]
}
],
"PreToolUse": [
{
"hooks": [
{
"type": "command",
"command": "uvx jes@0.0.1 claude-hook",
"timeout": 60
}
]
}
],
"PostToolUse": [
{
"hooks": [
{
"type": "command",
"command": "uvx jes@0.0.1 claude-hook",
"timeout": 60
}
]
}
],
"MessageDisplay": [
{
"hooks": [
{
"type": "command",
"command": "uvx jes@0.0.1 claude-hook",
"timeout": 60
}
]
}
]
}
}

What each hook does​

EventStageIf jes blocks
UserPromptSubmitinputReturns decision: block with the refusal as the reason.
PreToolUsetool_callDenies the call. The tool does not run.
PostToolUsetool_resultReplaces the output the model reads. A Bash result is checked on stdout and stderr together, and a block clears stderr too.
MessageDisplayoutputReplaces the text on screen once the message is final. The parts of each streamed message are kept apart, so two replies at once don't mix.

Limits​

  • PostToolUse fires after the tool has run. A blocked result keeps the model from reading it, but a shell command or file write is not undone. PreToolUse is what stops the command.
  • MessageDisplay changes only what you see. The transcript, and what Claude reads on the next turn, keep the original reply.
  • If the PostToolUse or MessageDisplay process dies before it prints JSON, Claude Code lets the text through. A model error is still caught and turned into a refusal.