brakit 0.10.1 → 0.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.d.ts +41 -14
- package/dist/api.js +105 -17
- package/dist/bin/brakit.js +307 -37
- package/dist/dashboard-client.global.js +204 -191
- package/dist/dashboard.html +216 -192
- package/dist/mcp/server.js +78 -1
- package/dist/runtime/index.js +1330 -1122
- package/package.json +1 -1
package/dist/bin/brakit.js
CHANGED
|
@@ -10,7 +10,7 @@ var __export = (target, all) => {
|
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
// src/constants/config.ts
|
|
13
|
-
var PROJECT_HASH_LENGTH, SECRET_SCAN_ARRAY_LIMIT, PII_SCAN_ARRAY_LIMIT, MIN_SECRET_VALUE_LENGTH, FULL_RECORD_MIN_FIELDS, LIST_PII_MIN_ITEMS, MAX_OBJECT_SCAN_DEPTH, ISSUE_PRUNE_TTL_MS, OVERFETCH_UNWRAP_MIN_SIZE, STALE_ISSUE_TTL_MS, METRICS_DIR, PORT_FILE, VALID_ISSUE_STATES, VALID_AI_FIX_STATUSES, VALID_SECURITY_SEVERITIES,
|
|
13
|
+
var PROJECT_HASH_LENGTH, SECRET_SCAN_ARRAY_LIMIT, PII_SCAN_ARRAY_LIMIT, MIN_SECRET_VALUE_LENGTH, FULL_RECORD_MIN_FIELDS, LIST_PII_MIN_ITEMS, MAX_OBJECT_SCAN_DEPTH, ISSUE_PRUNE_TTL_MS, OVERFETCH_UNWRAP_MIN_SIZE, STALE_ISSUE_TTL_MS, METRICS_DIR, PORT_FILE, VALID_ISSUE_STATES, VALID_AI_FIX_STATUSES, VALID_SECURITY_SEVERITIES, DETAIL_PREVIEW_LENGTH;
|
|
14
14
|
var init_config = __esm({
|
|
15
15
|
"src/constants/config.ts"() {
|
|
16
16
|
"use strict";
|
|
@@ -29,8 +29,6 @@ var init_config = __esm({
|
|
|
29
29
|
VALID_ISSUE_STATES = /* @__PURE__ */ new Set(["open", "fixing", "resolved", "stale", "regressed"]);
|
|
30
30
|
VALID_AI_FIX_STATUSES = /* @__PURE__ */ new Set(["fixed", "wont_fix"]);
|
|
31
31
|
VALID_SECURITY_SEVERITIES = /* @__PURE__ */ new Set(["critical", "warning"]);
|
|
32
|
-
TELEMETRY_EVENT_CLI_INVOKED = "cli_invoked";
|
|
33
|
-
TELEMETRY_EVENT_CLI_UNINSTALL = "cli_uninstall";
|
|
34
32
|
DETAIL_PREVIEW_LENGTH = 120;
|
|
35
33
|
}
|
|
36
34
|
});
|
|
@@ -72,8 +70,91 @@ var init_type_guards = __esm({
|
|
|
72
70
|
}
|
|
73
71
|
});
|
|
74
72
|
|
|
73
|
+
// src/constants/detection.ts
|
|
74
|
+
var KNOWN_DEPENDENCY_NAMES, KNOWN_DEPENDENCY_SET;
|
|
75
|
+
var init_detection = __esm({
|
|
76
|
+
"src/constants/detection.ts"() {
|
|
77
|
+
"use strict";
|
|
78
|
+
KNOWN_DEPENDENCY_NAMES = [
|
|
79
|
+
// -- Frameworks (meta) --
|
|
80
|
+
"next",
|
|
81
|
+
"@remix-run/dev",
|
|
82
|
+
"nuxt",
|
|
83
|
+
"astro",
|
|
84
|
+
// -- Frameworks (backend) --
|
|
85
|
+
"@nestjs/core",
|
|
86
|
+
"@adonisjs/core",
|
|
87
|
+
"sails",
|
|
88
|
+
"express",
|
|
89
|
+
"fastify",
|
|
90
|
+
"hono",
|
|
91
|
+
"koa",
|
|
92
|
+
"@hapi/hapi",
|
|
93
|
+
"elysia",
|
|
94
|
+
"h3",
|
|
95
|
+
"nitro",
|
|
96
|
+
"@trpc/server",
|
|
97
|
+
// -- Bundlers --
|
|
98
|
+
"vite",
|
|
99
|
+
// -- ORM / query builders --
|
|
100
|
+
"prisma",
|
|
101
|
+
"@prisma/client",
|
|
102
|
+
"drizzle-orm",
|
|
103
|
+
"typeorm",
|
|
104
|
+
"sequelize",
|
|
105
|
+
"mongoose",
|
|
106
|
+
"kysely",
|
|
107
|
+
"knex",
|
|
108
|
+
"@mikro-orm/core",
|
|
109
|
+
"objection",
|
|
110
|
+
// -- DB drivers --
|
|
111
|
+
"pg",
|
|
112
|
+
"mysql2",
|
|
113
|
+
"mongodb",
|
|
114
|
+
"better-sqlite3",
|
|
115
|
+
"@libsql/client",
|
|
116
|
+
"@planetscale/database",
|
|
117
|
+
"ioredis",
|
|
118
|
+
"redis",
|
|
119
|
+
// -- Auth --
|
|
120
|
+
"lucia",
|
|
121
|
+
"next-auth",
|
|
122
|
+
"@auth/core",
|
|
123
|
+
"passport",
|
|
124
|
+
// -- Queues / messaging --
|
|
125
|
+
"bullmq",
|
|
126
|
+
"amqplib",
|
|
127
|
+
"kafkajs",
|
|
128
|
+
// -- Validation --
|
|
129
|
+
"zod",
|
|
130
|
+
"joi",
|
|
131
|
+
"yup",
|
|
132
|
+
"arktype",
|
|
133
|
+
"valibot",
|
|
134
|
+
// -- HTTP clients --
|
|
135
|
+
"axios",
|
|
136
|
+
"got",
|
|
137
|
+
"ky",
|
|
138
|
+
"undici",
|
|
139
|
+
// -- Realtime --
|
|
140
|
+
"socket.io",
|
|
141
|
+
"ws",
|
|
142
|
+
// -- CSS / styling --
|
|
143
|
+
"tailwindcss",
|
|
144
|
+
// -- Testing --
|
|
145
|
+
"vitest",
|
|
146
|
+
"jest",
|
|
147
|
+
"mocha",
|
|
148
|
+
// -- Runtime indicators --
|
|
149
|
+
"bun-types",
|
|
150
|
+
"@types/bun"
|
|
151
|
+
];
|
|
152
|
+
KNOWN_DEPENDENCY_SET = new Set(KNOWN_DEPENDENCY_NAMES);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
|
|
75
156
|
// src/constants/labels.ts
|
|
76
|
-
var DASHBOARD_PREFIX, DASHBOARD_API_REQUESTS, DASHBOARD_API_EVENTS, DASHBOARD_API_FLOWS, DASHBOARD_API_CLEAR, DASHBOARD_API_LOGS, DASHBOARD_API_FETCHES, DASHBOARD_API_ERRORS, DASHBOARD_API_QUERIES, DASHBOARD_API_INGEST, DASHBOARD_API_METRICS, DASHBOARD_API_ACTIVITY, DASHBOARD_API_METRICS_LIVE, DASHBOARD_API_INSIGHTS, DASHBOARD_API_SECURITY, DASHBOARD_API_TAB, DASHBOARD_API_FINDINGS, DASHBOARD_API_FINDINGS_REPORT, DASHBOARD_API_GRAPH, VALID_TABS_TUPLE, VALID_TABS
|
|
157
|
+
var DASHBOARD_PREFIX, DASHBOARD_API_REQUESTS, DASHBOARD_API_EVENTS, DASHBOARD_API_FLOWS, DASHBOARD_API_CLEAR, DASHBOARD_API_LOGS, DASHBOARD_API_FETCHES, DASHBOARD_API_ERRORS, DASHBOARD_API_QUERIES, DASHBOARD_API_INGEST, DASHBOARD_API_METRICS, DASHBOARD_API_ACTIVITY, DASHBOARD_API_METRICS_LIVE, DASHBOARD_API_INSIGHTS, DASHBOARD_API_SECURITY, DASHBOARD_API_TAB, DASHBOARD_API_FINDINGS, DASHBOARD_API_FINDINGS_REPORT, DASHBOARD_API_GRAPH, VALID_TABS_TUPLE, VALID_TABS;
|
|
77
158
|
var init_labels = __esm({
|
|
78
159
|
"src/constants/labels.ts"() {
|
|
79
160
|
"use strict";
|
|
@@ -105,9 +186,6 @@ var init_labels = __esm({
|
|
|
105
186
|
"explorer"
|
|
106
187
|
];
|
|
107
188
|
VALID_TABS = new Set(VALID_TABS_TUPLE);
|
|
108
|
-
POSTHOG_HOST = "https://us.i.posthog.com";
|
|
109
|
-
POSTHOG_CAPTURE_PATH = "/i/v0/e/";
|
|
110
|
-
POSTHOG_REQUEST_TIMEOUT_MS = 3e3;
|
|
111
189
|
}
|
|
112
190
|
});
|
|
113
191
|
|
|
@@ -136,7 +214,7 @@ var init_features = __esm({
|
|
|
136
214
|
MAX_TIMELINE_EVENTS = 20;
|
|
137
215
|
MAX_RESOLVED_DISPLAY = 5;
|
|
138
216
|
ENRICHMENT_SEVERITY_FILTER = ["critical", "warning"];
|
|
139
|
-
MCP_SERVER_VERSION = "0.10.
|
|
217
|
+
MCP_SERVER_VERSION = "0.10.2";
|
|
140
218
|
RECOVERY_WINDOW_MS = 5 * 60 * 1e3;
|
|
141
219
|
PORT_MIN = 1;
|
|
142
220
|
PORT_MAX = 65535;
|
|
@@ -145,13 +223,32 @@ var init_features = __esm({
|
|
|
145
223
|
}
|
|
146
224
|
});
|
|
147
225
|
|
|
226
|
+
// src/constants/telemetry.ts
|
|
227
|
+
var POSTHOG_HOST, POSTHOG_CAPTURE_PATH, POSTHOG_REQUEST_TIMEOUT_MS, TELEMETRY_EVENT_CLI_INVOKED, TELEMETRY_EVENT_CLI_UNINSTALL, TELEMETRY_EVENT_DASHBOARD_VIEWED, TELEMETRY_EVENT_SESSION, TELEMETRY_SDK_NAME, SPEED_BUCKET_THRESHOLDS;
|
|
228
|
+
var init_telemetry = __esm({
|
|
229
|
+
"src/constants/telemetry.ts"() {
|
|
230
|
+
"use strict";
|
|
231
|
+
POSTHOG_HOST = "https://us.i.posthog.com";
|
|
232
|
+
POSTHOG_CAPTURE_PATH = "/i/v0/e/";
|
|
233
|
+
POSTHOG_REQUEST_TIMEOUT_MS = 3e3;
|
|
234
|
+
TELEMETRY_EVENT_CLI_INVOKED = "cli_invoked";
|
|
235
|
+
TELEMETRY_EVENT_CLI_UNINSTALL = "cli_uninstall";
|
|
236
|
+
TELEMETRY_EVENT_DASHBOARD_VIEWED = "dashboard_viewed";
|
|
237
|
+
TELEMETRY_EVENT_SESSION = "session";
|
|
238
|
+
TELEMETRY_SDK_NAME = "node";
|
|
239
|
+
SPEED_BUCKET_THRESHOLDS = [200, 500, 1e3, 2e3, 5e3];
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
|
|
148
243
|
// src/constants/index.ts
|
|
149
244
|
var init_constants = __esm({
|
|
150
245
|
"src/constants/index.ts"() {
|
|
151
246
|
"use strict";
|
|
152
247
|
init_config();
|
|
248
|
+
init_detection();
|
|
153
249
|
init_labels();
|
|
154
250
|
init_features();
|
|
251
|
+
init_telemetry();
|
|
155
252
|
}
|
|
156
253
|
});
|
|
157
254
|
|
|
@@ -1206,6 +1303,7 @@ import { createHash as createHash2 } from "crypto";
|
|
|
1206
1303
|
import { readFile as readFile3, readdir } from "fs/promises";
|
|
1207
1304
|
import { existsSync as existsSync4 } from "fs";
|
|
1208
1305
|
import { join as join2, relative } from "path";
|
|
1306
|
+
init_detection();
|
|
1209
1307
|
var FRAMEWORKS = [
|
|
1210
1308
|
// Meta-frameworks first (they bundle Express/Vite internally)
|
|
1211
1309
|
{ name: "nextjs", dep: "next", devCmd: "next dev", bin: "next", defaultPort: 3e3, devArgs: ["dev", "--port"] },
|
|
@@ -1234,23 +1332,22 @@ async function detectProject(rootDir) {
|
|
|
1234
1332
|
const devCommand = matched?.devCmd ?? "";
|
|
1235
1333
|
const devBin = matched ? join2(rootDir, "node_modules", ".bin", matched.bin) : "";
|
|
1236
1334
|
const defaultPort = matched?.defaultPort ?? 3e3;
|
|
1237
|
-
const packageManager =
|
|
1335
|
+
const packageManager = detectPackageManager(rootDir);
|
|
1238
1336
|
return { framework, devCommand, devBin, defaultPort, packageManager };
|
|
1239
1337
|
}
|
|
1240
|
-
async function detectPackageManager(rootDir) {
|
|
1241
|
-
if (await fileExists(join2(rootDir, "bun.lockb"))) return "bun";
|
|
1242
|
-
if (await fileExists(join2(rootDir, "bun.lock"))) return "bun";
|
|
1243
|
-
if (await fileExists(join2(rootDir, "pnpm-lock.yaml"))) return "pnpm";
|
|
1244
|
-
if (await fileExists(join2(rootDir, "yarn.lock"))) return "yarn";
|
|
1245
|
-
if (await fileExists(join2(rootDir, "package-lock.json"))) return "npm";
|
|
1246
|
-
return "unknown";
|
|
1247
|
-
}
|
|
1248
1338
|
function detectFrameworkFromDeps(allDeps) {
|
|
1249
1339
|
for (const f of FRAMEWORKS) {
|
|
1250
1340
|
if (allDeps[f.dep]) return f.name;
|
|
1251
1341
|
}
|
|
1252
1342
|
return "unknown";
|
|
1253
1343
|
}
|
|
1344
|
+
function detectPackageManager(rootDir) {
|
|
1345
|
+
if (existsSync4(join2(rootDir, "bun.lockb")) || existsSync4(join2(rootDir, "bun.lock"))) return "bun";
|
|
1346
|
+
if (existsSync4(join2(rootDir, "pnpm-lock.yaml"))) return "pnpm";
|
|
1347
|
+
if (existsSync4(join2(rootDir, "yarn.lock"))) return "yarn";
|
|
1348
|
+
if (existsSync4(join2(rootDir, "package-lock.json"))) return "npm";
|
|
1349
|
+
return "unknown";
|
|
1350
|
+
}
|
|
1254
1351
|
var PYTHON_ENTRY_CANDIDATES = [
|
|
1255
1352
|
"app.py",
|
|
1256
1353
|
"main.py",
|
|
@@ -2005,7 +2102,7 @@ init_constants();
|
|
|
2005
2102
|
init_endpoint();
|
|
2006
2103
|
|
|
2007
2104
|
// src/index.ts
|
|
2008
|
-
var VERSION = "0.10.
|
|
2105
|
+
var VERSION = "0.10.2";
|
|
2009
2106
|
|
|
2010
2107
|
// src/cli/commands/install.ts
|
|
2011
2108
|
init_constants();
|
|
@@ -2346,10 +2443,6 @@ init_constants();
|
|
|
2346
2443
|
init_log();
|
|
2347
2444
|
init_type_guards();
|
|
2348
2445
|
|
|
2349
|
-
// src/telemetry/index.ts
|
|
2350
|
-
import { platform as platform2, release, arch } from "os";
|
|
2351
|
-
import { spawn } from "child_process";
|
|
2352
|
-
|
|
2353
2446
|
// src/telemetry/config.ts
|
|
2354
2447
|
init_features();
|
|
2355
2448
|
import { homedir as homedir2, platform } from "os";
|
|
@@ -2359,10 +2452,14 @@ import { randomUUID as randomUUID2 } from "crypto";
|
|
|
2359
2452
|
var IS_WINDOWS = platform() === "win32";
|
|
2360
2453
|
var CONFIG_DIR = join4(homedir2(), ".brakit");
|
|
2361
2454
|
var CONFIG_PATH = join4(CONFIG_DIR, "config.json");
|
|
2455
|
+
function isValidTelemetryConfig(value) {
|
|
2456
|
+
return typeof value === "object" && value !== null && typeof value.telemetry === "boolean" && typeof value.anonymousId === "string" && value.anonymousId.length > 0;
|
|
2457
|
+
}
|
|
2362
2458
|
function readConfig() {
|
|
2363
2459
|
try {
|
|
2364
2460
|
if (!existsSync6(CONFIG_PATH)) return null;
|
|
2365
|
-
|
|
2461
|
+
const parsed = JSON.parse(readFileSync4(CONFIG_PATH, "utf-8"));
|
|
2462
|
+
return isValidTelemetryConfig(parsed) ? parsed : null;
|
|
2366
2463
|
} catch {
|
|
2367
2464
|
return null;
|
|
2368
2465
|
}
|
|
@@ -2385,9 +2482,7 @@ function writeConfig(config) {
|
|
|
2385
2482
|
}
|
|
2386
2483
|
function getOrCreateConfig() {
|
|
2387
2484
|
const existing = readConfig();
|
|
2388
|
-
if (existing
|
|
2389
|
-
return existing;
|
|
2390
|
-
}
|
|
2485
|
+
if (existing) return existing;
|
|
2391
2486
|
const config = { telemetry: true, anonymousId: randomUUID2() };
|
|
2392
2487
|
writeConfig(config);
|
|
2393
2488
|
return config;
|
|
@@ -2397,16 +2492,19 @@ function isTelemetryEnabled() {
|
|
|
2397
2492
|
if (cachedEnabled !== null) return cachedEnabled;
|
|
2398
2493
|
const env = process.env.BRAKIT_TELEMETRY;
|
|
2399
2494
|
if (env !== void 0) {
|
|
2400
|
-
|
|
2495
|
+
const normalized = env.toLowerCase().trim();
|
|
2496
|
+
cachedEnabled = normalized !== "false" && normalized !== "0" && normalized !== "off";
|
|
2401
2497
|
return cachedEnabled;
|
|
2402
2498
|
}
|
|
2403
2499
|
cachedEnabled = readConfig()?.telemetry ?? true;
|
|
2404
2500
|
return cachedEnabled;
|
|
2405
2501
|
}
|
|
2406
2502
|
|
|
2407
|
-
// src/telemetry/
|
|
2408
|
-
|
|
2409
|
-
|
|
2503
|
+
// src/telemetry/transport.ts
|
|
2504
|
+
import { platform as platform2, release, arch } from "os";
|
|
2505
|
+
import { spawn } from "child_process";
|
|
2506
|
+
init_telemetry();
|
|
2507
|
+
init_log();
|
|
2410
2508
|
var POSTHOG_KEY = "phc_E9TwydCGnSfPLIUhNxChpeg32TSowjk31KiPhnLPP0x";
|
|
2411
2509
|
function commonProperties() {
|
|
2412
2510
|
return {
|
|
@@ -2420,7 +2518,7 @@ function commonProperties() {
|
|
|
2420
2518
|
};
|
|
2421
2519
|
}
|
|
2422
2520
|
function sendToPosthog(event, properties) {
|
|
2423
|
-
if (!isTelemetryEnabled()) return;
|
|
2521
|
+
if (!isTelemetryEnabled() || !POSTHOG_KEY) return;
|
|
2424
2522
|
const config = getOrCreateConfig();
|
|
2425
2523
|
const payload = {
|
|
2426
2524
|
api_key: POSTHOG_KEY,
|
|
@@ -2430,26 +2528,198 @@ function sendToPosthog(event, properties) {
|
|
|
2430
2528
|
properties: { ...commonProperties(), ...properties }
|
|
2431
2529
|
};
|
|
2432
2530
|
try {
|
|
2433
|
-
const
|
|
2531
|
+
const serializedPayload = JSON.stringify(payload);
|
|
2434
2532
|
const url = `${POSTHOG_HOST}${POSTHOG_CAPTURE_PATH}`;
|
|
2435
2533
|
const child = spawn(
|
|
2436
2534
|
process.execPath,
|
|
2437
2535
|
[
|
|
2438
2536
|
"-e",
|
|
2439
|
-
`fetch(${JSON.stringify(url)},{method:"POST",headers:{"content-type":"application/json"},body:${JSON.stringify(
|
|
2537
|
+
`fetch(${JSON.stringify(url)},{method:"POST",headers:{"content-type":"application/json"},body:${JSON.stringify(serializedPayload)},signal:AbortSignal.timeout(${POSTHOG_REQUEST_TIMEOUT_MS})}).catch(()=>{})`
|
|
2440
2538
|
],
|
|
2441
2539
|
{ detached: true, stdio: "ignore" }
|
|
2442
2540
|
);
|
|
2443
2541
|
child.unref();
|
|
2444
|
-
} catch {
|
|
2542
|
+
} catch (err) {
|
|
2543
|
+
brakitDebug(`telemetry send failed: ${err}`);
|
|
2445
2544
|
}
|
|
2446
2545
|
}
|
|
2447
2546
|
function trackEvent(event, properties) {
|
|
2448
|
-
sendToPosthog(event, { sdk:
|
|
2547
|
+
sendToPosthog(event, { sdk: TELEMETRY_SDK_NAME, ...properties });
|
|
2449
2548
|
}
|
|
2450
2549
|
|
|
2550
|
+
// src/telemetry/session.ts
|
|
2551
|
+
init_telemetry();
|
|
2552
|
+
var defaultTransport = { send: sendToPosthog, track: trackEvent };
|
|
2553
|
+
var Session = class {
|
|
2554
|
+
constructor(transport = defaultTransport) {
|
|
2555
|
+
// ── Setup phase ──
|
|
2556
|
+
this.startTime = 0;
|
|
2557
|
+
this.framework = "unknown";
|
|
2558
|
+
this.packageManager = "";
|
|
2559
|
+
this.isCustomCommand = false;
|
|
2560
|
+
this.adapters = [];
|
|
2561
|
+
this.setupDurationMs = 0;
|
|
2562
|
+
this.setupSucceeded = false;
|
|
2563
|
+
// ── Detection ──
|
|
2564
|
+
this.detectedDependencies = [];
|
|
2565
|
+
this.adaptersFailed = [];
|
|
2566
|
+
this.configFilesDetected = [];
|
|
2567
|
+
this.jsRuntime = "node";
|
|
2568
|
+
this.loadedPackages = [];
|
|
2569
|
+
// ── Python SDK ──
|
|
2570
|
+
this.pythonConnected = false;
|
|
2571
|
+
this.pythonFramework = "unknown";
|
|
2572
|
+
this.pythonAdapters = [];
|
|
2573
|
+
this.pythonVersion = "";
|
|
2574
|
+
// ── Runtime accumulation ──
|
|
2575
|
+
this.requestCount = 0;
|
|
2576
|
+
this.insightTypes = /* @__PURE__ */ new Set();
|
|
2577
|
+
this.rulesTriggered = /* @__PURE__ */ new Set();
|
|
2578
|
+
this.tabsViewed = /* @__PURE__ */ new Set();
|
|
2579
|
+
this.dashboardOpened = false;
|
|
2580
|
+
this.explainUsed = false;
|
|
2581
|
+
this.firstRequestAt = 0;
|
|
2582
|
+
this.dashboardOpenedAt = 0;
|
|
2583
|
+
this.exitReason = "unknown";
|
|
2584
|
+
this.transport = transport;
|
|
2585
|
+
}
|
|
2586
|
+
// ── Setup phase ──
|
|
2587
|
+
init(framework, packageManager, isCustomCommand, adapters) {
|
|
2588
|
+
getOrCreateConfig();
|
|
2589
|
+
this.startTime = Date.now();
|
|
2590
|
+
this.framework = framework;
|
|
2591
|
+
this.packageManager = packageManager;
|
|
2592
|
+
this.isCustomCommand = isCustomCommand;
|
|
2593
|
+
this.adapters = adapters;
|
|
2594
|
+
}
|
|
2595
|
+
recordSetup(detection, durationMs) {
|
|
2596
|
+
this.detectedDependencies = detection.detectedDependencies;
|
|
2597
|
+
this.adaptersFailed = detection.adaptersFailed;
|
|
2598
|
+
this.configFilesDetected = detection.configFilesDetected;
|
|
2599
|
+
this.jsRuntime = detection.jsRuntime;
|
|
2600
|
+
this.setupDurationMs = durationMs;
|
|
2601
|
+
this.setupSucceeded = true;
|
|
2602
|
+
}
|
|
2603
|
+
// ── Runtime events ──
|
|
2604
|
+
recordFirstRequest(loadedPackages) {
|
|
2605
|
+
if (!this.firstRequestAt) this.firstRequestAt = Date.now();
|
|
2606
|
+
this.loadedPackages = loadedPackages;
|
|
2607
|
+
}
|
|
2608
|
+
recordPythonStack(info) {
|
|
2609
|
+
this.pythonConnected = true;
|
|
2610
|
+
this.pythonFramework = info.framework;
|
|
2611
|
+
this.pythonAdapters = info.adapters;
|
|
2612
|
+
this.pythonVersion = info.pythonVersion;
|
|
2613
|
+
}
|
|
2614
|
+
recordDashboardOpened() {
|
|
2615
|
+
if (this.dashboardOpened) return;
|
|
2616
|
+
this.dashboardOpened = true;
|
|
2617
|
+
this.dashboardOpenedAt = Date.now();
|
|
2618
|
+
this.transport.track(TELEMETRY_EVENT_DASHBOARD_VIEWED, {
|
|
2619
|
+
time_to_dashboard_ms: this.startTime > 0 ? Date.now() - this.startTime : null,
|
|
2620
|
+
request_count_at_open: this.requestCount
|
|
2621
|
+
});
|
|
2622
|
+
}
|
|
2623
|
+
recordTabViewed(tab) {
|
|
2624
|
+
this.tabsViewed.add(tab);
|
|
2625
|
+
}
|
|
2626
|
+
recordExplainUsed() {
|
|
2627
|
+
this.explainUsed = true;
|
|
2628
|
+
}
|
|
2629
|
+
recordExitReason(reason) {
|
|
2630
|
+
if (this.exitReason === "unknown") this.exitReason = reason;
|
|
2631
|
+
}
|
|
2632
|
+
// ── Pre-flush snapshot from services ──
|
|
2633
|
+
recordCounts(requestCount, insightTypes, rulesTriggered) {
|
|
2634
|
+
this.requestCount = requestCount;
|
|
2635
|
+
for (const t of insightTypes) this.insightTypes.add(t);
|
|
2636
|
+
for (const r of rulesTriggered) this.rulesTriggered.add(r);
|
|
2637
|
+
}
|
|
2638
|
+
// ── Serialization ──
|
|
2639
|
+
/** Build the full PostHog session payload. Single source of truth for all fields. */
|
|
2640
|
+
toPostHogPayload(services) {
|
|
2641
|
+
const metricsStore = services.metricsStore;
|
|
2642
|
+
const analysisEngine = services.analysisEngine;
|
|
2643
|
+
const live = metricsStore.getLiveEndpoints();
|
|
2644
|
+
const insights = analysisEngine.getInsights();
|
|
2645
|
+
const findings = analysisEngine.getFindings();
|
|
2646
|
+
let totalRequests = 0;
|
|
2647
|
+
let totalDuration = 0;
|
|
2648
|
+
let slowestP95 = 0;
|
|
2649
|
+
for (const ep of live) {
|
|
2650
|
+
totalRequests += ep.summary.totalRequests;
|
|
2651
|
+
totalDuration += ep.summary.p95Ms * ep.summary.totalRequests;
|
|
2652
|
+
if (ep.summary.p95Ms > slowestP95) slowestP95 = ep.summary.p95Ms;
|
|
2653
|
+
}
|
|
2654
|
+
const now = Date.now();
|
|
2655
|
+
return {
|
|
2656
|
+
sdk: TELEMETRY_SDK_NAME,
|
|
2657
|
+
// Stack detection
|
|
2658
|
+
framework: this.framework,
|
|
2659
|
+
package_manager: this.packageManager,
|
|
2660
|
+
js_runtime: this.jsRuntime,
|
|
2661
|
+
framework_detection_candidates: this.detectedDependencies,
|
|
2662
|
+
config_files_detected: this.configFilesDetected,
|
|
2663
|
+
loaded_packages: this.loadedPackages,
|
|
2664
|
+
loaded_package_count: this.loadedPackages.length,
|
|
2665
|
+
adapters_detected: this.adapters,
|
|
2666
|
+
adapters_failed: this.adaptersFailed,
|
|
2667
|
+
// Python SDK
|
|
2668
|
+
python_connected: this.pythonConnected,
|
|
2669
|
+
python_framework: this.pythonFramework,
|
|
2670
|
+
python_adapters: this.pythonAdapters,
|
|
2671
|
+
python_version: this.pythonVersion,
|
|
2672
|
+
// Session metadata
|
|
2673
|
+
is_custom_command: this.isCustomCommand,
|
|
2674
|
+
first_session: readConfig() === null,
|
|
2675
|
+
setup_succeeded: this.setupSucceeded,
|
|
2676
|
+
setup_duration_ms: this.setupDurationMs,
|
|
2677
|
+
session_duration_s: Math.ceil((now - this.startTime) / 1e3),
|
|
2678
|
+
session_duration_ms: now - this.startTime,
|
|
2679
|
+
exit_reason: this.exitReason,
|
|
2680
|
+
// Usage
|
|
2681
|
+
request_count: this.requestCount,
|
|
2682
|
+
error_count: services.errorStore.getAll().length,
|
|
2683
|
+
query_count: services.queryStore.getAll().length,
|
|
2684
|
+
fetch_count: services.fetchStore.getAll().length,
|
|
2685
|
+
endpoint_count: live.length,
|
|
2686
|
+
avg_duration_ms: totalRequests > 0 ? Math.round(totalDuration / totalRequests) : 0,
|
|
2687
|
+
slowest_endpoint_bucket: speedBucket(slowestP95),
|
|
2688
|
+
// Analysis
|
|
2689
|
+
insight_count: insights.length,
|
|
2690
|
+
finding_count: findings.length,
|
|
2691
|
+
insight_types: [...this.insightTypes],
|
|
2692
|
+
rules_triggered: [...this.rulesTriggered],
|
|
2693
|
+
// Dashboard engagement
|
|
2694
|
+
tabs_viewed: [...this.tabsViewed],
|
|
2695
|
+
dashboard_opened: this.dashboardOpened,
|
|
2696
|
+
explain_used: this.explainUsed,
|
|
2697
|
+
// Timing
|
|
2698
|
+
time_to_first_request_ms: this.firstRequestAt ? this.firstRequestAt - this.startTime : null,
|
|
2699
|
+
time_to_dashboard_ms: this.dashboardOpenedAt ? this.dashboardOpenedAt - this.startTime : null
|
|
2700
|
+
};
|
|
2701
|
+
}
|
|
2702
|
+
flush(services) {
|
|
2703
|
+
this.transport.send(TELEMETRY_EVENT_SESSION, this.toPostHogPayload(services));
|
|
2704
|
+
getOrCreateConfig();
|
|
2705
|
+
}
|
|
2706
|
+
};
|
|
2707
|
+
function speedBucket(ms) {
|
|
2708
|
+
if (ms === 0) return "none";
|
|
2709
|
+
const t = SPEED_BUCKET_THRESHOLDS;
|
|
2710
|
+
if (ms < t[0]) return `<${t[0]}ms`;
|
|
2711
|
+
for (let i = 1; i < t.length; i++) {
|
|
2712
|
+
if (ms < t[i]) return `${t[i - 1]}-${t[i]}ms`;
|
|
2713
|
+
}
|
|
2714
|
+
return `>${t[t.length - 1]}ms`;
|
|
2715
|
+
}
|
|
2716
|
+
|
|
2717
|
+
// src/telemetry/index.ts
|
|
2718
|
+
init_telemetry();
|
|
2719
|
+
var session = new Session();
|
|
2720
|
+
|
|
2451
2721
|
// src/cli/commands/uninstall.ts
|
|
2452
|
-
|
|
2722
|
+
init_telemetry();
|
|
2453
2723
|
var PREPENDED_FILES = [
|
|
2454
2724
|
"app/entry.server.tsx",
|
|
2455
2725
|
"app/entry.server.ts",
|
|
@@ -2708,7 +2978,7 @@ async function clearBuildCaches(rootDir) {
|
|
|
2708
2978
|
}
|
|
2709
2979
|
|
|
2710
2980
|
// bin/brakit.ts
|
|
2711
|
-
|
|
2981
|
+
init_telemetry();
|
|
2712
2982
|
var sub = process.argv[2];
|
|
2713
2983
|
var command = sub === "uninstall" ? "uninstall" : sub === "mcp" ? "mcp" : "install";
|
|
2714
2984
|
var cwd = process.cwd();
|