Cursor#
Use this guide to observe Cursor hook lifecycle events with NeMo Flow. The
repository ships a Cursor hook bundle under integrations/coding-agents/cursor/
because this integration does not assume an official Cursor plugin package
format.
Cursor GUI or IDE sessions can provide agent, subagent, tool, shell, MCP, file,
and response lifecycle events through .cursor/hooks.json. Complete LLM
lifecycle observability additionally requires Cursor model traffic to route
through the gateway if your Cursor build exposes that configuration.
Cursor CLI support must be verified separately with cursor-agent. Current
Cursor CLI builds require .cursor/hooks.json to set top-level "version": 1
and use direct command entries such as
{"command": "nemo-flow hook-forward cursor", "timeout": 30}. The nested
{"matcher": "*", "hooks": [...]} group shape used by Claude Code and Codex
does not fire in Cursor CLI. If CLI hooks still do not fire with direct
versioned entries, treat that Cursor CLI version as hook-limited and
gateway-only where model routing is configurable.
Warning
Cursor CLI hook coverage is not the same as Cursor IDE hook coverage. Current
headless CLI builds can emit fewer hook events than Cursor IDE sessions. Treat
missing CLI hook events as a Cursor CLI limitation after nemo-flow doctor cursor confirms the hook file uses the direct versioned shape.
Transparent Run#
Use the wrapper for no-install local observability:
nemo-flow cursor
Pass Cursor arguments after --:
nemo-flow cursor -- agent --resume <session-id>
This shortcut is equivalent to nemo-flow run -- cursor-agent. The wrapper
starts a gateway on a dynamic 127.0.0.1 port, temporarily merges NeMo Flow
hook entries into the project .cursor/hooks.json, launches Cursor, and
restores the original hook file after the agent exits. The temporary Cursor hook
file is written with top-level "version": 1 and direct command entries.
Inspect what would be launched without starting Cursor:
nemo-flow run \
--dry-run \
--print \
-- cursor-agent
Standalone Gateway#
Use the long-running gateway only when you want Cursor running outside the wrapper (e.g., the Cursor GUI). Start the gateway manually:
nemo-flow --bind 127.0.0.1:4040
Then point Cursor provider traffic at http://127.0.0.1:4040 wherever Cursor
exposes provider base URL configuration. Without the wrapper, hook events are
not captured — Cursor GUI mode only emits LLM lifecycle as traffic passes
through the gateway. Missing LLM spans are expected when Cursor sends model
traffic directly to the provider or through a remote service.
Captured Events#
Generated Cursor hooks include sessionStart, sessionEnd, subagentStart,
subagentStop, preToolUse, postToolUse, beforeShellExecution,
afterShellExecution, beforeMCPExecution, afterMCPExecution, preCompact,
and stop for scope, tool, and mark events. beforeSubmitPrompt,
afterAgentResponse, and afterAgentThought are retained as private LLM
correlation hints and are not emitted as standalone NeMo Flow events.
Tool events preserve Cursor shell and MCP payloads in metadata and use the
active subagent.id, subagent_id, or x-nemo-flow-subagent-id when present.
The transparent wrapper backs up the project hook file, merges NeMo Flow hook
entries for the run, and restores or removes the temporary file when the agent
exits.
Smoke Test#
Run a small Cursor GUI session that starts an agent and uses one simple tool. Then check hook forwarding directly:
curl -f http://127.0.0.1:4040/healthz
printf '{"session_id":"smoke-cursor","hook_event_name":"sessionStart"}' \
| NEMO_FLOW_GATEWAY_URL=http://127.0.0.1:4040 nemo-flow hook-forward cursor --fail-closed
For Cursor CLI, run an equivalent cursor-agent session and verify the gateway
receives hook requests. If no hook requests arrive, confirm .cursor/hooks.json
uses top-level "version": 1 with direct command entries, then document that
CLI version as hook-limited and rely only on gateway observability where
provider routing is available.
Verify Export#
End the Cursor session and confirm Agent Trajectory Interchange Format (ATIF) exists:
ls .nemo-flow/atif
The gateway writes <session-id>.atif.json on session end. If the file is
missing, confirm Cursor loaded .cursor/hooks.json, the gateway binary is on
PATH, --atif-dir or NEMO_FLOW_ATIF_DIR is configured, plugins.toml
enables the ATIF exporter with a writable output_directory, and user-managed
Cursor hooks pass nemo-flow doctor cursor.
Troubleshoot LLM Lifecycle#
If Cursor hook events appear but LLM spans are missing, provider traffic is not routed through the gateway. Confirm the active Cursor GUI or CLI mode supports provider base URL configuration for the model path being used.
If LLM spans exist but attach to the session instead of a subagent, pass
x-nemo-flow-subagent-id on gateway requests or include shared
conversation_id, generation_id, or request_id values in both hook payloads
and provider requests.