Skip to content

Commit 403ae7f

Browse files
authored
feat(telemetry): emit project detection telemetry field in CLI (#2595)
1 parent 759924e commit 403ae7f

4 files changed

Lines changed: 23 additions & 4 deletions

File tree

‎src/core/project/fsUtils.ts‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,23 @@ export function enclosingProjectRoot(directory: string): string | undefined {
2323
}
2424
}
2525

26-
/** Checks the project header without requiring the v1 project schema to parse. */
27-
export async function isV0Project(rootPath: string): Promise<boolean> {
26+
/** Classifies the project header without requiring either project schema to parse. */
27+
export async function detectProjectFormat(rootPath: string): Promise<"v0" | "v1" | "unknown"> {
2828
try {
2929
const contents = await readFile(projectSpecPath(rootPath), "utf8");
3030
const header = z.object({ version: z.unknown().optional() }).safeParse(JSON.parse(contents));
31-
return header.success && header.data.version === 1;
31+
if (!header.success) return "unknown";
32+
if (header.data.version === 1) return "v0";
33+
if (header.data.version === 2) return "v1";
3234
} catch {
3335
// Leave unreadable or malformed specs to normal project validation.
34-
return false;
3536
}
37+
return "unknown";
38+
}
39+
40+
/** Checks the project header without requiring the v1 project schema to parse. */
41+
export async function isV0Project(rootPath: string): Promise<boolean> {
42+
return (await detectProjectFormat(rootPath)) === "v0";
3643
}
3744

3845
export function toPythonPackageName(name: string): string {

‎src/index.ts‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { homedir } from "os";
22
import { join } from "path";
33

44
import { CoreClient } from "./core";
5+
import { detectProjectFormat, enclosingProjectRoot } from "./core/project/fsUtils";
56
import { createRuntimeShellOpener } from "./core/runtimeShell";
67
import {
78
createApplicationSignalsClient,
@@ -75,6 +76,12 @@ process.exit(
7576
const globalConfig = await globalConfigAccessor.get();
7677
try {
7778
rootLogger.info(`running CLI`);
79+
const projectRoot = enclosingProjectRoot(process.cwd());
80+
if (projectRoot) {
81+
commandRunMetricEvent.setAttributes({
82+
project_format: await detectProjectFormat(projectRoot),
83+
});
84+
}
7885

7986
// factories (rather than instances) lets CoreClient build one client per
8087
// region on demand.

‎src/telemetry/client.test.tsx‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ describe("DefaultTelemetryClient", () => {
5959
exit_reason: "success",
6060
command_path: "/agentcore",
6161
});
62+
metricEvent.setAttributes({ project_format: "v0" });
6263

6364
await metricEvent.emit(123);
6465

@@ -67,6 +68,7 @@ describe("DefaultTelemetryClient", () => {
6768
exit_reason: "failure",
6869
command_path: "/agentcore",
6970
});
71+
metricEvent2.setAttributes({ project_format: "unknown" });
7072

7173
await metricEvent2.emit(456);
7274
await client.shutdown();
@@ -89,6 +91,7 @@ describe("DefaultTelemetryClient", () => {
8991
exit_reason: "success",
9092
command_path: "/agentcore",
9193
is_tui: false,
94+
project_format: "v0",
9295
},
9396
},
9497
{
@@ -99,6 +102,7 @@ describe("DefaultTelemetryClient", () => {
99102
exit_reason: "failure",
100103
command_path: "/agentcore",
101104
is_tui: false,
105+
project_format: "unknown",
102106
},
103107
},
104108
]);

‎src/telemetry/shapes.tsx‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ export const commandRunSchema = safeSchema({
6363
error_name: errorNameSchema.optional(),
6464
error_source: z.enum(Object.values(ERROR_SOURCE)).optional(),
6565
is_tui: z.boolean().default(false),
66+
project_format: z.enum(["v0", "v1", "unknown"]).optional(),
6667
project_runtime_count: z.number().int().nonnegative().optional(),
6768
project_memory_count: z.number().int().nonnegative().optional(),
6869
project_knowledge_base_count: z.number().int().nonnegative().optional(),

0 commit comments

Comments
 (0)