RTECO-1017 - Detect agent + CI invocation context, enrich metrics wit…#1555
RTECO-1017 - Detect agent + CI invocation context, enrich metrics wit…#1555
Conversation
…h agent/is_agent/is_interactive
| // Fallback: generic AGENT env var (goose convention, codex pending). | ||
| if v := os.Getenv("AGENT"); v != "" { | ||
| return v | ||
| } |
There was a problem hiding this comment.
instead of falling back lets return "unknown" agent.
| // DetectExecutionContext captures all signals about who executed the CLI. | ||
| func DetectExecutionContext() ExecutionContext { | ||
| ec := ExecutionContext{ | ||
| IsInteractive: term.IsTerminal(int(os.Stdin.Fd())), |
There was a problem hiding this comment.
jfrog-cli core has a common util which can tell whether it is terminal or not we can reuse it.
| // Dimensions are independent: an agent may run inside CI; both will be reported. | ||
| type ExecutionContext struct { | ||
| Agent string // e.g. "claude", "cursor", "gemini", "" if none | ||
| CISystem string // e.g. "github_actions", "" if not CI |
There was a problem hiding this comment.
detecting CISystem is already part of existing metrics
| {"GOOSE_TERMINAL", "goose"}, | ||
| {"CURSOR_AGENT", "cursor"}, | ||
| {"CURSOR_TRACEID", "cursor"}, | ||
| {"COPILOT_CLI", "copilot"}, |
There was a problem hiding this comment.
both tests and code should have same source so that if there is any new addition devs doesnt have to update in tests again
| CISystem: ec.CISystem, | ||
| IsContainer: isRunningInContainer(), | ||
| IsAgent: ec.IsAgent, | ||
| Agent: ec.Agent, |
There was a problem hiding this comment.
we also should updated user-agent in http requests with the agent detected.
| {"replit", []string{"REPLIT_AGENT"}}, | ||
| {"windsurf", []string{"WINDSURF_SESSION_ID"}}, | ||
| {"aider", []string{"AIDER_MODEL"}}, | ||
| {"codex", []string{"CODEX_HOME"}}, |
There was a problem hiding this comment.
CODEX_HOME — false positive, always-on. Not only when codex is ran.
| func detectAgentTraceID(agent string) string { | ||
| switch agent { | ||
| case "cursor": | ||
| return os.Getenv("CURSOR_TRACEID") |
There was a problem hiding this comment.
the correct env variable is CURSOR_TRACE_ID otherwise we can never fetch trace ID
| return os.Getenv("CURSOR_TRACEID") | |
| return os.Getenv("CURSOR_TRACE_ID") |
| {"kilocode", []string{"KILO_IPC_SOCKET_PATH", "KILO_SERVER_PASSWORD"}}, | ||
| {"roo_code", []string{"ROO_CODE_IPC_SOCKET_PATH"}}, | ||
| {"replit", []string{"REPLIT_AGENT"}}, | ||
| {"windsurf", []string{"WINDSURF_SESSION_ID"}}, |
There was a problem hiding this comment.
couldnt find windsurf session id in docs is it WINDSURF=1 ?
| {"windsurf", []string{"WINDSURF_SESSION_ID"}}, | |
| {"windsurf", []string{"WINDSURF"}}, |
…h agent/is_agent/is_interactive
Summary
Adds detection of CLI invocation context — agent (Claude, Cursor, Gemini, Goose, Copilot, Windsurf, etc.), CI provider, and stdin TTY — and enriches the existing
jfcli_commands_countmetric with the new dimensions.Motivation
differentiate human / CI / agent invocations of
jf. Backend currently can't tell whether a command came from a developer's desktop, a CI runner, or an AI agent. Without this, we can't measure agent-driven usage or separate human vs automated traffic.Changes
common/commands/execution_context.go— single source of truth for invocation context.DetectExecutionContext()returns agent name, CI system, TTY presence, andpropagated trace ID.
common/commands/execution_context_test.go— unit tests covering each agent env var, CI providers, trace ID gating, and no-env fallback.utils/metrics/metrics.go—MetricsDatagainsIsAgent,Agent,IsInteractivefields (additive,omitempty).common/commands/metrics_collector.go—CollectMetricspopulates the new fields viaDetectExecutionContext.Detection
Agent identity is matched against an env-var table (first match wins, then generic
AGENTfallback):CLAUDECODE,CLAUDE_CODE_ENTRYPOINTGEMINI_CLIGOOSE_TERMINALCURSOR_AGENT,CURSOR_TRACEIDCOPILOT_CLIKILO_IPC_SOCKET_PATH,KILO_SERVER_PASSWORDROO_CODE_IPC_SOCKET_PATHREPLIT_AGENTWINDSURF_SESSION_IDAIDER_MODELCODEX_HOMECI detection reuses the existing
detectCISystem()provider list (Jenkins, Travis, CircleCI, GitHub Actions, GitLab, Buildkite, Bamboo, Azure DevOps, TeamCity, Drone, Bitbucket,AWS CodeBuild, plus generic fallbacks).
TraceIDis gated on agent identity — only Cursor'sCURSOR_TRACEIDis honored, and only when the detected agent iscursor. Prevents stale leakage from outer shells.