Skip to content

Cursor inadvertently invokes Claude Code hooks when .cursor/hooks.json is not installed #1262

@SnowingFox

Description

@SnowingFox

What happened?

When using Cursor as the primary agent without .cursor/hooks.json installed (e.g. only Claude Code hooks exist in .claude/settings.json), Cursor sessions are incorrectly attributed to Claude Code.

The root cause is the first-writer-wins ownership model in DispatchLifecycleEvent. When .cursor/hooks.json is present, Cursor fires entire hooks cursor session-start first, calling StoreAgentTypeHint to claim the session. Claude Code's hooks later fire for the same session ID but the ownership check (state.AgentType != ag.Type()) detects the mismatch and skips them — everything works correctly.

When .cursor/hooks.json is absent, no Cursor hook fires to claim the session. Claude Code (running as a Cursor subagent) reads its own .claude/settings.json hooks and fires entire hooks claude-code session-start, incorrectly claiming ownership of a session that belongs to Cursor. All subsequent lifecycle events are then processed under the wrong agent, producing incorrect checkpoints, session metadata, and step counts.

In short: the fix for this is present in the codebase (the ownership check), but it only works when Cursor hooks are also installed. If only Claude Code hooks are installed, there is nothing to claim the session on Cursor's behalf first.

Steps to reproduce

  1. Have Claude Code hooks installed in .claude/settings.json (entire agent add claude-code or entire enable).
  2. Do not install Cursor hooks — .cursor/hooks.json should not exist.
  3. Open a Cursor session in the repository. Cursor will invoke Claude Code as a subagent.
  4. Observe that entire hooks claude-code session-start fires and claims the session.
  5. Check .entire/logs/ — the session is attributed to claude-code, not cursor.
  6. Now install Cursor hooks (entire agent add cursor) so .cursor/hooks.json exists, and repeat. The session is now correctly owned by cursor and the Claude Code hooks are skipped.

Entire CLI version

0.6.2

OS and architecture

macos 26 arm64

Agent

cursor

Terminal

No response

Logs / debug output

Additional context

  • A PR is in progress to fix this.
  • Relevant code: the ownership check lives in DispatchLifecycleEvent (cmd/entire/cli/lifecycle.go ~line 55). Session ownership is set via StoreAgentTypeHint in handleLifecycleSessionStart.
  • When working correctly, logs contain: "skipping forwarded hook for non-owning agent" with owning_agent=cursor and firing_agent=claude-code.
  • The fix likely involves ensuring that when Cursor is detected as the IDE (e.g. via an env var or by the presence of Cursor-specific hook payload fields), the session is pre-claimed for Cursor even without .cursor/hooks.json — or that entire enable / entire agent add warns the user to install Cursor hooks when using Cursor.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions