You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[wrangler] Add AI agent detection to analytics events (#11820)
* [wrangler] Add AI agent detection to analytics events
* fix: skip process ancestry checks to avoid wmic errors on Windows
The am-i-vibing library's detectAgenticEnvironment function uses
process-ancestry to check for running processes. When processAncestry
is undefined, it calls getProcessAncestry() which uses execSync('ps ...')
to walk up the entire process tree.
For each provider with processChecks (6 providers), it would call
getProcessAncestry() separately, causing:
- Massive slowdowns (tests took 78+ seconds instead of 3 seconds)
- Timeouts in CI environments (especially on Linux)
- Race conditions where output wasn't captured properly
By passing an empty array [], we skip process tree traversal entirely.
Environment variable detection is sufficient for identifying most
agentic environments (Claude Code, Cursor, Windsurf, etc.) and is
instantaneous.
Wrangler now detects when commands are executed by AI coding agents (such as Claude Code, Cursor, GitHub Copilot, etc.) using the `am-i-vibing` library. This information is included as an `agent` property in all analytics events, helping Cloudflare understand how developers interact with Wrangler through AI assistants.
8
+
9
+
The `agent` property will contain the agent ID (e.g., `"claude-code"`, `"cursor-agent"`) when detected, or `null` when running outside an agentic environment.
it("should send a request to the default URL",async()=>{
86
98
constrequests=mockMetricRequest();
87
99
@@ -92,7 +104,7 @@ describe("metrics", () => {
92
104
awaitPromise.all(dispatcher.requests);
93
105
expect(requests.count).toBe(1);
94
106
expect(std.debug).toMatchInlineSnapshot(
95
-
`"Metrics dispatcher: Posting data {\\"deviceId\\":\\"f82b1f46-eb7b-4154-aa9f-ce95f23b2288\\",\\"event\\":\\"some-event\\",\\"timestamp\\":1733961600000,\\"properties\\":{\\"category\\":\\"Workers\\",\\"wranglerVersion\\":\\"1.2.3\\",\\"wranglerMajorVersion\\":1,\\"wranglerMinorVersion\\":2,\\"wranglerPatchVersion\\":3,\\"os\\":\\"foo:bar\\",\\"a\\":1,\\"b\\":2}}"`
107
+
`"Metrics dispatcher: Posting data {\\"deviceId\\":\\"f82b1f46-eb7b-4154-aa9f-ce95f23b2288\\",\\"event\\":\\"some-event\\",\\"timestamp\\":1733961600000,\\"properties\\":{\\"category\\":\\"Workers\\",\\"wranglerVersion\\":\\"1.2.3\\",\\"wranglerMajorVersion\\":1,\\"wranglerMinorVersion\\":2,\\"wranglerPatchVersion\\":3,\\"os\\":\\"foo:bar\\",\\"agent\\":null,\\"a\\":1,\\"b\\":2}}"`
96
108
);
97
109
expect(std.out).toMatchInlineSnapshot(`""`);
98
110
expect(std.warn).toMatchInlineSnapshot(`""`);
@@ -123,7 +135,7 @@ describe("metrics", () => {
123
135
124
136
expect(requests.count).toBe(0);
125
137
expect(std.debug).toMatchInlineSnapshot(
126
-
`"Metrics dispatcher: Dispatching disabled - would have sent {\\"deviceId\\":\\"f82b1f46-eb7b-4154-aa9f-ce95f23b2288\\",\\"event\\":\\"some-event\\",\\"timestamp\\":1733961600000,\\"properties\\":{\\"category\\":\\"Workers\\",\\"wranglerVersion\\":\\"1.2.3\\",\\"wranglerMajorVersion\\":1,\\"wranglerMinorVersion\\":2,\\"wranglerPatchVersion\\":3,\\"os\\":\\"foo:bar\\",\\"a\\":1,\\"b\\":2}}."`
138
+
`"Metrics dispatcher: Dispatching disabled - would have sent {\\"deviceId\\":\\"f82b1f46-eb7b-4154-aa9f-ce95f23b2288\\",\\"event\\":\\"some-event\\",\\"timestamp\\":1733961600000,\\"properties\\":{\\"category\\":\\"Workers\\",\\"wranglerVersion\\":\\"1.2.3\\",\\"wranglerMajorVersion\\":1,\\"wranglerMinorVersion\\":2,\\"wranglerPatchVersion\\":3,\\"os\\":\\"foo:bar\\",\\"agent\\":null,\\"a\\":1,\\"b\\":2}}."`
127
139
);
128
140
expect(std.out).toMatchInlineSnapshot(`""`);
129
141
expect(std.warn).toMatchInlineSnapshot(`""`);
@@ -143,7 +155,7 @@ describe("metrics", () => {
143
155
awaitPromise.all(dispatcher.requests);
144
156
145
157
expect(std.debug).toMatchInlineSnapshot(`
146
-
"Metrics dispatcher: Posting data {\\"deviceId\\":\\"f82b1f46-eb7b-4154-aa9f-ce95f23b2288\\",\\"event\\":\\"some-event\\",\\"timestamp\\":1733961600000,\\"properties\\":{\\"category\\":\\"Workers\\",\\"wranglerVersion\\":\\"1.2.3\\",\\"wranglerMajorVersion\\":1,\\"wranglerMinorVersion\\":2,\\"wranglerPatchVersion\\":3,\\"os\\":\\"foo:bar\\",\\"a\\":1,\\"b\\":2}}
158
+
"Metrics dispatcher: Posting data {\\"deviceId\\":\\"f82b1f46-eb7b-4154-aa9f-ce95f23b2288\\",\\"event\\":\\"some-event\\",\\"timestamp\\":1733961600000,\\"properties\\":{\\"category\\":\\"Workers\\",\\"wranglerVersion\\":\\"1.2.3\\",\\"wranglerMajorVersion\\":1,\\"wranglerMinorVersion\\":2,\\"wranglerPatchVersion\\":3,\\"os\\":\\"foo:bar\\",\\"agent\\":null,\\"a\\":1,\\"b\\":2}}
147
159
Metrics dispatcher: Failed to send request: Failed to fetch"
148
160
`);
149
161
expect(std.out).toMatchInlineSnapshot(`""`);
@@ -162,12 +174,47 @@ describe("metrics", () => {
162
174
163
175
expect(requests.count).toBe(0);
164
176
expect(std.debug).toMatchInlineSnapshot(
165
-
`"Metrics dispatcher: Source Key not provided. Be sure to initialize before sending events {\\"deviceId\\":\\"f82b1f46-eb7b-4154-aa9f-ce95f23b2288\\",\\"event\\":\\"some-event\\",\\"timestamp\\":1733961600000,\\"properties\\":{\\"category\\":\\"Workers\\",\\"wranglerVersion\\":\\"1.2.3\\",\\"wranglerMajorVersion\\":1,\\"wranglerMinorVersion\\":2,\\"wranglerPatchVersion\\":3,\\"os\\":\\"foo:bar\\",\\"a\\":1,\\"b\\":2}}"`
177
+
`"Metrics dispatcher: Source Key not provided. Be sure to initialize before sending events {\\"deviceId\\":\\"f82b1f46-eb7b-4154-aa9f-ce95f23b2288\\",\\"event\\":\\"some-event\\",\\"timestamp\\":1733961600000,\\"properties\\":{\\"category\\":\\"Workers\\",\\"wranglerVersion\\":\\"1.2.3\\",\\"wranglerMajorVersion\\":1,\\"wranglerMinorVersion\\":2,\\"wranglerPatchVersion\\":3,\\"os\\":\\"foo:bar\\",\\"agent\\":null,\\"a\\":1,\\"b\\":2}}"`
166
178
);
167
179
expect(std.out).toMatchInlineSnapshot(`""`);
168
180
expect(std.warn).toMatchInlineSnapshot(`""`);
169
181
expect(std.err).toMatchInlineSnapshot(`""`);
170
182
});
183
+
184
+
it("should include agent ID when detected",async()=>{
Copy file name to clipboardExpand all lines: packages/wrangler/telemetry.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -26,6 +26,7 @@ Telemetry in Wrangler allows us to better identify bugs and gain visibility on u
26
26
- The format of the Wrangler configuration file (e.g. `toml`, `jsonc`)
27
27
- Total session duration of the command run (e.g. 3 seconds, etc.)
28
28
- Whether the Wrangler client is running in CI or in an interactive instance
29
+
- Whether the command was executed by an AI coding agent (e.g. Claude Code, Cursor, GitHub Copilot), and if so, which agent
29
30
- Error _type_ (e.g. `APIError` or `UserError`), and sanitised error messages that will not include user information like filepaths or stack traces (e.g. `Asset too large`).
30
31
- General machine information such as OS and OS Version
0 commit comments