Skip to content

Add clash check command with Claude Code hook support#9

Merged
mathew55 merged 6 commits intomainfrom
feature/clash-check
Feb 8, 2026
Merged

Add clash check command with Claude Code hook support#9
mathew55 merged 6 commits intomainfrom
feature/clash-check

Conversation

@mathew55
Copy link
Contributor

@mathew55 mathew55 commented Feb 8, 2026

Closes #2, closes #5

Summary

  • Adds clash check command for single-file conflict detection across worktrees
  • Supports two modes: manual (clash check <path>) with JSON on stdout, and hook mode (clash check with stdin) for Claude Code's PreToolUse hook
  • In hook mode, reads tool_input.file_path from stdin JSON, outputs conflicts to stderr on exit 2 (which Claude sees), and is silent on exit 0
  • Includes TTY guard so running bare clash check in a terminal shows helpful usage instead of blocking
  • Updates WorktreeManager with find_containing() and iter() methods
  • Adds conflicts_with() error field to WorktreePairConflict for surfacing detection failures

Hook configuration

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "clash check"
          }
        ]
      }
    ]
  }
}

Test plan

  • cargo build && cargo clippy -- -D warnings && cargo fmt --check
  • Manual mode: clash check src/main.rs outputs JSON to stdout
  • Hook mode: echo '{"tool_input":{"file_path":"src/main.rs"}}' | clash check reads from stdin
  • TTY guard: bare clash check in terminal prints helpful error, doesn't block
  • End-to-end: hook fires on Edit tool call and blocks conflicting file edits

🤖 Generated with Claude Code

mathew55 and others added 6 commits February 7, 2026 13:18
Checks a file against all worktrees for merge conflicts (via git
merge-tree) and active uncommitted changes (via gix HEAD comparison).
Outputs JSON with exit code 0 (clear) or 2 (conflicted). Building
block for Claude Code hook integration (#5).

Also adds WorktreeManager::find_containing() for identifying which
worktree a directory belongs to.

Closes #2

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This allows the PreToolUse hook config to be just `"command": "clash check"`
without needing a shell script or jq to extract the file path. When no path
is provided, reads JSON from stdin and extracts tool_input.file_path. In hook
mode, conflicts are output to stderr (which Claude sees on exit 2) and clean
results are silent. Includes a TTY guard to show helpful usage instead of
blocking when run interactively without arguments.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
In hook mode, output Claude Code's hookSpecificOutput JSON with
permissionDecision "ask" so the user can override conflicts instead
of being hard-blocked. Manual mode (`clash check <path>`) still uses
exit 2. Note: permissionDecisionReason doesn't render in the permission
prompt yet (anthropics/claude-code#17356).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fixes Denial of Service via Stack Exhaustion vulnerability in the
time crate (transitive dep via ratatui). Resolves CI failures in
Dependency Check and Security Audit jobs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Branch protection requires a status called "CI" but the workflow
only reported individual job names. Add a summary job that depends
on all other jobs and reports as "CI".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@mathew55 mathew55 merged commit ee95473 into main Feb 8, 2026
14 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.

Claude Code hook integration clash check - minimal: detect conflicts & active work on a file

1 participant