@@ -22,6 +22,7 @@ const CONTEXT: CliSetupClientContext = {
2222 platform : "linux" ,
2323 architecture : "x64" ,
2424 entryPoint : "direct" ,
25+ agentMarker : "cursor" ,
2526} ;
2627
2728describe ( "setupAttribution" , ( ) => {
@@ -61,16 +62,19 @@ describe("setupAttribution", () => {
6162 } ) ;
6263
6364 it ( "builds credential auth context without replacing the entry point" , ( ) => {
64- const context = buildCliSetupClientContext ( {
65- apiUrl : "https://api.test" ,
66- appUrl : "https://app.test" ,
67- apiKey : "secret" ,
68- projectId : "project-id" ,
69- orgId : undefined ,
70- projId : undefined ,
71- yolo : false ,
72- from : "homepage" ,
73- } ) ;
65+ const context = buildCliSetupClientContext (
66+ {
67+ apiUrl : "https://api.test" ,
68+ appUrl : "https://app.test" ,
69+ apiKey : "secret" ,
70+ projectId : "project-id" ,
71+ orgId : undefined ,
72+ projId : undefined ,
73+ yolo : false ,
74+ from : "homepage" ,
75+ } ,
76+ { } ,
77+ ) ;
7478
7579 expect ( context ) . toMatchObject ( {
7680 entryPoint : "homepage" ,
@@ -80,6 +84,85 @@ describe("setupAttribution", () => {
8084 expect ( context . platform ) . toBe ( process . platform ) ;
8185 expect ( context . architecture ) . toBe ( process . arch ) ;
8286 } ) ;
87+
88+ it . each ( [
89+ [ { CODEX_THREAD_ID : "thread-id" } , "codex" ] ,
90+ [ { CODEX_CI : "1" } , "codex" ] ,
91+ [ { CODEX_SANDBOX : "seatbelt" } , "codex" ] ,
92+ [ { CLAUDECODE : "1" } , "claude_code" ] ,
93+ [ { CLAUDE_CODE : "1" } , "claude_code" ] ,
94+ [ { CLAUDE_CODE_ENTRYPOINT : "cli" } , "claude_code" ] ,
95+ [ { CURSOR_AGENT : "1" } , "cursor" ] ,
96+ [ { CURSOR_TRACE_ID : "trace-id" } , "cursor" ] ,
97+ [ { CURSOR_EXTENSION_HOST_ROLE : "agent-exec" } , "cursor" ] ,
98+ [ { GEMINI_CLI : "1" } , "gemini_cli" ] ,
99+ [ { OPENCODE : "1" } , "opencode" ] ,
100+ [ { OPENCODE_CLIENT : "acp" } , "opencode" ] ,
101+ [ { VSCODE_AGENT : "1" } , "github_copilot" ] ,
102+ [ { COPILOT_MODEL : "model" } , "github_copilot" ] ,
103+ [ { COPILOT_ALLOW_ALL : "1" } , "github_copilot" ] ,
104+ [ { COPILOT_GITHUB_TOKEN : "secret" } , "github_copilot" ] ,
105+ [ { GOOSE_TERMINAL : "1" } , "goose" ] ,
106+ [ { ANTIGRAVITY_AGENT : "1" } , "antigravity" ] ,
107+ [ { AUGMENT_AGENT : "1" } , "augment" ] ,
108+ [ { REPL_ID : "repl-id" } , "replit" ] ,
109+ [ { AI_AGENT : "github_copilot_vscode_agent" } , "github_copilot" ] ,
110+ [ { AI_AGENT : "custom-agent" } , "other" ] ,
111+ [ { AGENT : "amp" } , "amp" ] ,
112+ [ { AGENT : "goose" } , "goose" ] ,
113+ ] as const ) ( "reports the coding agent marker from %j" , ( env , agentMarker ) => {
114+ const context = buildCliSetupClientContext (
115+ {
116+ apiUrl : "https://api.test" ,
117+ appUrl : "https://app.test" ,
118+ apiKey : undefined ,
119+ projectId : undefined ,
120+ orgId : undefined ,
121+ projId : undefined ,
122+ yolo : false ,
123+ } ,
124+ env ,
125+ ( ) => false ,
126+ ) ;
127+
128+ expect ( context . agentMarker ) . toBe ( agentMarker ) ;
129+ } ) ;
130+
131+ it ( "reports Devin from its local environment path" , ( ) => {
132+ const context = buildCliSetupClientContext (
133+ {
134+ apiUrl : "https://api.test" ,
135+ appUrl : "https://app.test" ,
136+ apiKey : undefined ,
137+ projectId : undefined ,
138+ orgId : undefined ,
139+ projId : undefined ,
140+ yolo : false ,
141+ } ,
142+ { } ,
143+ ( path ) => path === "/opt/.devin" ,
144+ ) ;
145+
146+ expect ( context . agentMarker ) . toBe ( "devin" ) ;
147+ } ) ;
148+
149+ it ( "omits the coding agent marker when no supported marker is present" , ( ) => {
150+ const context = buildCliSetupClientContext (
151+ {
152+ apiUrl : "https://api.test" ,
153+ appUrl : "https://app.test" ,
154+ apiKey : undefined ,
155+ projectId : undefined ,
156+ orgId : undefined ,
157+ projId : undefined ,
158+ yolo : false ,
159+ } ,
160+ { CI : "true" , CODEX_HOME : "/tmp/codex" } ,
161+ ( ) => false ,
162+ ) ;
163+
164+ expect ( context ) . not . toHaveProperty ( "agentMarker" ) ;
165+ } ) ;
83166} ) ;
84167
85168describe ( "createWizardEvents" , ( ) => {
@@ -153,7 +236,7 @@ describe("createWizardEvents", () => {
153236 } ) ;
154237 expect ( requests [ 4 ] ) . toMatchObject ( {
155238 event : "cliSetupTerminated" ,
156- clientContext : { authMode : "signin" } ,
239+ clientContext : { authMode : "signin" , agentMarker : "cursor" } ,
157240 properties : {
158241 outcome : "completed" ,
159242 durationMs : 65 ,
0 commit comments