Skip to content

Cursor scaffold wires only sessionStart — port the profile-appropriate hook subset to the Cursor 3.x hook contract #2419

Description

@TomCruiseTorpedo

Summary

Follow-up to #2065 / #2066. That work gave Cursor an independent memory root (ECC_AGENT_DATA_HOME) and wired a single sessionStart hook (cursor-session-env.js). But the Cursor scaffold's scaffolds/cursor/hooks.json still registers only that one hook, while scripts/hooks/ ships ~48 hook scripts that are wired for the Claude Code target. So an ECC-on-Cursor user today gets the data-root isolation but almost none of ECC's hook-driven behaviour — no continual-learning on stop, no post-edit format/typecheck, no quality gate, no commit-quality guard, no compaction hooks.

This proposes wiring the generalizable subset of ECC's existing hooks into the Cursor scaffold, adapted to Cursor's hook contract and gated by hook profile.

Current state

scaffolds/cursor/hooks.json:

{ "version": 1, "hooks": { "sessionStart": [ { "command": "node .cursor/scripts/hooks/cursor-session-env.js" } ] } }

Cursor hook contract (3.x) — relevant facts

Cursor's agent hooks map closely onto ECC's Claude-side model, so most hooks port by event-name mapping + matcher translation. Proposed mapping:

ECC hook(s) Cursor event Blocking
post-edit-format / -typecheck / -console-warn afterFileEdit (matcher Write) no
pre-bash-commit-quality, block-no-verify, pre-bash-dev-server-block beforeShellExecution (regex matcher) yes (permission)
post-bash-* afterShellExecution no
quality-gate, stop-format-typecheck, evaluate-session stop no
pre-compact / suggest-compact preCompact no
session-end / -marker sessionEnd no

Four contract constraints the implementation must respect (all observed on current Cursor):

  1. One hook per event array. Cursor currently executes only the first entry in an event's array. ECC already solves this on the Claude side with *-dispatcher.js fan-out scripts — the Cursor wiring should register a single dispatcher per event and fan out internally, not list N hooks.
  2. CLI vs editor surface. The Cursor CLI does not emit every event the editor does; hooks should tolerate an event never firing on the CLI surface.
  3. afterFileEdit is not exhaustive on batch/mid-session edits — post-edit hooks must be advisory, not relied on for correctness.
  4. Cloud-agent gaps. Cloud agents do not receive stop, sessionStart/sessionEnd, or MCP events, and run only command-based hooks. Continual-learning-on-stop must degrade gracefully (no error) when the event never arrives.

hooks.json requires "version": 1.

Proposed scope

  • Include (generalizable, useful to any ECC-on-Cursor user): continual-learning (stop/sessionEndevaluate-session), post-edit format/typecheck, quality gate, commit-quality / block-no-verify shell guards, pre-compact.
  • Exclude (environment- or operator-specific; keep out of the default scaffold): desktop notifications, tmux/dev-server automation, any vendor-specific security monitors, cost tracking.
  • Profile-gate it: honour the existing ECC_HOOK_PROFILE (minimal → sessionStart + continual-learning only; full → the whole applicable subset). minimal should remain the safe default for Cursor.
  • Prefer the dispatcher pattern so the "first-hook-only" limitation and future event additions are both handled in one place.

Why this is worth doing upstream

The gap affects every ECC user who runs on Cursor, not any one setup — the hooks already exist; they're simply not wired for the Cursor target. Completing the parity that #2066 started makes the Cursor install a first-class citizen rather than a memory-root-only install.

Offer

Happy to implement this if the direction is acceptable — including the Cursor-contract adapters, dispatcher wiring, and profile gating, tested against both the Cursor editor and CLI surfaces.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High priorityarea:installInstallation, activation, upgrade, repair, or uninstallbugSomething isn't workingchurn-signalLikely contributor to failed adoption or uninstallharness:cursorCursor adapter or integration

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions