Feature Request: Proactive Hooks for Deterministic Command Chaining

Resolved 💬 4 comments Opened Jul 30, 2025 by coygeek Closed Jan 7, 2026

Title: Feature Request: Proactive Hooks for Deterministic Command Chaining

Area: Agent Tooling, Hooks

Is this a bug report or a feature request?

This is a feature request.

Problem Statement

The current hooks system (PreToolUse, PostToolUse, Stop, etc.) as documented in hooks-guide.md and hooks.md is incredibly powerful for validating tool usage, providing feedback, and running post-processing tasks. However, its design is fundamentally reactive. Hooks trigger based on a tool call the model has already decided to make.

This creates a limitation for workflows that require deterministic, sequential execution of commands. For example, in a standard CI or linting workflow, a developer might want to enforce the following logic:

  1. Run npm run build.
  2. If and only if build succeeds, run npm run test.
  3. If and only if test succeeds, run npm run lint.

Currently, achieving this requires complex prompting ("run build, then if it succeeds run test...") or a potentially brittle implementation using Stop/SubagentStop hooks. The model must reason about and decide to run each subsequent step, introducing non-determinism, latency, and additional token cost for what should be a fixed, predictable sequence.

Proposed Solution

I propose the introduction of a new hook type or a new property within the existing PostToolUse hook that enables proactive command chaining. This would allow users to define a "follow-up" action that is automatically executed upon the successful completion of a matched tool call.

A new hook event, perhaps named OnToolSuccess, could be introduced. This hook would only trigger if the initial tool call completes with an exit code of 0.

Here is a conceptual example of how this could look in .claude/settings.json:

{
  "hooks": {
    "OnToolSuccess": [
      {
        "matcher": "Bash(npm run build)",
        "action": {
          "type": "command",
          "command": "npm run test"
        },
        "description": "After a successful build, automatically run the test suite."
      },
      {
        "matcher": "Bash(npm run test)",
        "action": {
          "type": "command",
          "command": "npm run lint"
        },
        "description": "After all tests pass, automatically run the linter."
      }
    ]
  }
}

How it would work:

  1. Claude is prompted to build the project.
  2. It calls the Bash tool with the command npm run build.
  3. The command succeeds (exit code 0).
  4. The OnToolSuccess hook system finds a match for Bash(npm run build).
  5. Claude Code automatically executes the defined follow-up action: npm run test, without requiring another reasoning step from the model.
  6. The result of npm run test is then returned to the model for the next turn.

Use Cases & Rationale

This feature would unlock more robust and efficient automation for common developer workflows:

  • Reliable CI/CD Sequences: Chain build, test, and lint commands to create simple, deterministic pipelines directly within Claude Code.
  • Code Generation & Formatting: Automatically run a code formatter (e.g., prettier) and then a linter (e.g., eslint --fix) after Claude uses the Write or Edit tools on specific file types.
  • Multi-Step Data Processing: Create sequences like download_data.sh, unzip_data.sh, and then process_data.py.
  • Infrastructure Management: Chain Terraform commands like terraform plan followed by a custom approval script.

The key benefits are:

  • Determinism: Removes model variability from routine, sequential tasks, making automation more reliable.
  • Efficiency: Reduces token cost and latency by eliminating the need for the model to "re-think" the next logical step in a fixed workflow.
  • Simplicity: Allows users to define simple state-machine logic declaratively in configuration files, rather than through complex prompts or Stop hook hacks.
  • Empowerment: Gives power users a first-class mechanism for orchestrating more complex, multi-step agentic tasks.

Current Workarounds and Their Limitations

  1. Complex Prompting: A user can prompt Claude with the entire sequence. This is verbose, must be repeated, and is susceptible to model interpretation errors.
  2. Using Stop/SubagentStop Hooks: One could use a Stop hook to check the last command's result from the transcript and then feed a new instruction back to Claude. This is indirect, complex to implement correctly, and not the intended purpose of the Stop hook.

This proposed feature provides a clean, first-class solution for a very common and valuable pattern in developer automation. Thank you for considering this request

View original on GitHub ↗

This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗