Skip to content

EPMCDME-14834 Cursor IDE OTLP integration - #1

Closed
dzhalai wants to merge 47 commits into
mainfrom
EPMCDME-14834/cursor-ide-otlp-integration
Closed

dzhalai wants to merge 47 commits into
mainfrom
EPMCDME-14834/cursor-ide-otlp-integration

Conversation

@dzhalai

@dzhalai dzhalai commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator

Summary

Changes

Impact

Checklist

  • Self-reviewed
  • Manual testing performed
  • Documentation updated (if needed)
  • No breaking changes (or clearly documented)

vld-m and others added 30 commits September 10, 2026 16:51
Wire the connect command to support --cursor-ide as an analytics-only
target, short-circuiting the orchestrator with an explanatory note.
Adds --agent <name> to `codemie hook` so a hook process CodeMie did not
spawn (Cursor's hooks.json has no env key) can identify its agent;
precedence is flag beats CODEMIE_AGENT env. Splits resolveAgentName out
of initializeLoggerContext and threads it through initializeHookContext.

Reorders the CLI action body to resolve the agent before parsing stdin,
removes the pre-transform duplicate session_id/hook_event_name checks
(validateHookEvent already covers both), and adds two declarative
AgentHookConfig flags - transcriptOptional and neverBlockingExit - so an
agent can opt out of the transcript_path requirement and out of the
blocking exit-2 behavior via AgentRegistry lookup, with no agent-name
literal in the routing path.

cursor-ide-hooks-analytics EPMCDME-14834, tasks 1-2
Adds the cursor-ide agent plugin (analytics-only: never installed,
updated, or launched by CodeMie) with a hook transformer mapping
Cursor's raw payload (conversation_id, workspace_roots, tool_call_id)
onto the internal BaseHookEvent shape, and its 21-event name mapping
via the new declarative AgentHookConfig.eventNameMapping surface.

Extends InternalHookEventName with the 7 new internal event names the
mapping collapses onto, and BaseHookEvent with shared tool_name/
tool_input/tool_output/tool_use_id fields.

Threads a transform-derived session id fallback through
initializeLoggerContext/initializeHookContext so a hook invocation
CodeMie did not spawn (no CODEMIE_SESSION_ID in env) can still resolve
a session id from the transformed event, reordering the hook command's
action to transform before initializing context.

cursor-ide-hooks-analytics EPMCDME-14834, task 3
Extends routeHookEvent's switch with PreToolUse, PostToolUse,
PostToolUseFailure, SubagentStart, AgentResponse, AgentThought and
WorkspaceOpen, each with an allocation-light, non-blocking debug-log
handler. Without this the router's default branch silently dropped
these events, which is what cursor-ide's 21-event mapping collapses
onto beyond the existing 7 internal names.

cursor-ide-hooks-analytics EPMCDME-14834, task 4
Adds writeCursorResponse (cursor-ide.response.ts) emitting Cursor's
expected stdout response - {"permission":"allow"} for tool-permission
events, {"continue":true} for beforeSubmitPrompt, nothing otherwise -
wired declaratively via a new AgentHookConfig.writeStdoutResponse
field so hook.ts never branches on the agent name.

Neutralizes the two remaining exit-2 sites for a neverBlockingExit
agent: the .action body's catch path now exits 0 (still writing the
stdout response) instead of 1, and enforceAnalyticsAuthGate's direct
process.exit(2) now degrades to a thrown, caught, non-blocking failure
for such an agent, closing the auth-gate exit-2 site reachable via
beforeSubmitPrompt -> UserPromptSubmit.

Adds Logger.setStdoutSuppressed so debug()/success()'s own console
mirror can be redirected to stderr for the hook path, keeping stdout
free for the response contract once CODEMIE_AGENT's hookConfig is
known - closing the gap for every debug/info log the hook handlers
themselves emit while processing an event.

cursor-ide-hooks-analytics EPMCDME-14834, task 5
…race

Adds a shared resolveProjectRoot() helper (walk up for .git, fall back to
cwd) and a declarative hookConfig.captureEvent extension point so every
Cursor hook event is appended, sanitized and size-capped, to
.codemie/logs/cursor-hook-events.jsonl - the primary acceptance signal for
analytics ingestion. Capture is gated by CODEMIE_CURSOR_HOOK_TRACE (default
on) and never throws or blocks the hook.

cursor-ide-hooks-analytics EPMCDME-14834, task 6
Adds writeCursorIdeHooksConfig/writeCursorIdeHooksConfigAtPath, mirroring
the vscode-claude-code.ts read-merge-write-atomically shape and
codex-desktop.ts's backup-on-first-modification. Wires all 21 Cursor
native hook events to an absolute-path-resolved `codemie hook --agent
cursor-ide`, upserting by a command substring so re-runs are idempotent
and foreign hook entries/config keys are never clobbered.

cursor-ide-hooks-analytics EPMCDME-14834, task 8
Wires --cursor-ide --analytics to run the Task 8 connector, restructures
connectTargets() to run cursor-ide standalone before the daemon-lifecycle
block (it has no daemon of its own - hooks POST directly to /v1/metrics),
and rejects --cursor-ide without --analytics with a clear re-run hint.

cursor-ide-hooks-analytics EPMCDME-14834, task 7
Adds removeCursorIdeHooksConfig to the cursor-ide connector: strips only
codemie-authored entries from .cursor/hooks.json, drops an event key once
its entry list is empty, and restores the .codemie-backup file when
codemie's entries were the file's only content (or deletes a file we
created from scratch when no backup exists). Wires a --cursor-ide flag
onto proxy disconnect alongside --codex-desktop.

cursor-ide-hooks-analytics EPMCDME-14834, task 9
Stage 9 commit of sdlc-standard run artifacts: technical-analysis, spec,
plan, complexity assessments, implementation ledger, code-review verdict,
qa-gates result, and decision/event ledgers.
state.local.json, gate-plan.local.json, and *.local.diff are the
filenames the current sdlc-factory scripts actually write; the prior
patterns (.state.json, gate-plan.json, *.diff) never matched them,
leaving task directories dirty after every run.
flags

connectTargets() checked hasAnyTarget() before the analytics-specific
warning, and --analytics sets no target flag of its own - so
`codemie proxy connect --analytics` alone silently fell through to the
generic "select a target" list instead of explaining that --analytics
only applies to --cursor-ide.
writeCursorIdeHooksConfigAtPath() picked the codemie binary via PATH/argv1
(resolveCodemieBinary), which only tracks the installed package that
happens to be linked on PATH. Added resolveCodemieBinaryFromPackage(),
derived from this module's own location, so the wired hook command always
points at bin/codemie.js of the exact package instance that generated the
connector code - including a dev checkout, where `npm run build` alone is
then enough for Cursor to pick up new behavior with no re-link step.
Bypass the shared hook pipeline for cursor-ide via a new declarative
AgentHookConfig.otlpIngestion flag, fire-and-forget forwarding raw
hook events to a new local proxy route (/v1/otlp/hook-events ->
~/.codemie/logs/hook-events.jsonl), and route cursor-ide's daemon
lifecycle through the same connect/ensure-daemon path as every other
target so .cursor/hooks.json is always written on connect.

Includes SDLC review/QA artifacts for the recovery run (EPMCDME-14834).
…on-object payloads

Addresses code-review findings CR-010, CR-011, CR-014 on the OTLP
ingest plugin: reject unrecognized agentName values, create the log
directory/file with 0o700/0o600, and fall back safely when a raw
hook payload doesn't parse to a plain object.
Records the sdlc-autonomous run's research, plan, code-review, and QA
gate artifacts for the cursor-ide OTLP event-hooks proxy-backend leg.
lens-edge-case.md was written under a different filename than
commit-artifacts expects (lens-edge-case.json), so it was skipped in
the prior artifacts commit.
…l-be login workaround

Fix resolveSsoProxyConfig() so the active-profile path resolves the profile
name first and passes it into ConfigLoader.load(), engaging the same
env-var-override protection the explicit --profile path already had.
Without this, CODEMIE_BASE_URL/CODEMIE_URL silently clobbered the active
profile's baseUrl for daemon connects. Also fix ensureDaemon() to derive
syncApiUrl from codeMieUrl/baseUrl instead of the dead config.ssoConfig field.

Add scripts/manual-sso-login.js: logs in directly against a root-mounted
backend's /v1/local-auth/login and stores the token via the CLI's own
CredentialStore, working around codemie profile login's ensureApiBase()
always appending /code-assistant-api (which the local docker backend does
not mount routes under).

Bump otlp-ingest.plugin.ts logging from debug to info for pushToBackend
success/failure visibility, and add local-be profile pointing at the local
docker backend for manual testing.
Generated with AI

Co-Authored-By: codemie-ai <[email protected]>
vld-m and others added 17 commits September 16, 2026 17:37
Generated with AI

Co-Authored-By: codemie-ai <[email protected]>
Generated with AI

Co-Authored-By: codemie-ai <[email protected]>
Restores 26 task directories that were incorrectly removed alongside
branch-specific artifacts. Only the 4 cursor-ide OTLP branch tasks
should have been deleted.

Generated with AI

Co-Authored-By: codemie-ai <[email protected]>
Restores 18 additional task directories from main that were missed
in the previous revert commit.

Generated with AI

Co-Authored-By: codemie-ai <[email protected]>
Restores 4 test files removed in 539877c to reduce branch diff.
Updates assertions for cursor-ide target flag and ConfigLoader.load
signature changes introduced on this branch.

Generated with AI

Co-Authored-By: codemie-ai <[email protected]>
Extract outbound OTLP signal construction and delivery into a dedicated
OtlpDispatcher class, shrinking otlp-ingest.plugin.ts from 577 to 110
lines. Collapses wrapLogs/wrapTraces/wrapMetrics into a single wrapSignal
helper, promotes countLines/decodeJwtClaims/toStringField to private
methods, and replaces magic literals with named constants.
@dzhalai

dzhalai commented Sep 18, 2026

Copy link
Copy Markdown
Collaborator Author

Moved to codemie-ai#570

@dzhalai dzhalai closed this Sep 18, 2026
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.

2 participants