@glasstrace/sdk 0.7.0 → 0.7.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/{chunk-PLJVIWHN.js → chunk-CNNEPHWN.js} +18 -2
- package/dist/chunk-CNNEPHWN.js.map +1 -0
- package/dist/cli/init.cjs +22 -24
- package/dist/cli/init.cjs.map +1 -1
- package/dist/cli/init.js +3 -13
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/mcp-add.cjs +4 -2
- package/dist/cli/mcp-add.cjs.map +1 -1
- package/dist/cli/mcp-add.js +3 -13
- package/dist/cli/mcp-add.js.map +1 -1
- package/dist/index.cjs +105 -37
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +107 -39
- package/dist/index.js.map +1 -1
- package/package.json +1 -6
- package/dist/chunk-PLJVIWHN.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -306,8 +306,12 @@ declare function performInit(config: ResolvedConfig, anonKey: AnonApiKey | null,
|
|
|
306
306
|
/**
|
|
307
307
|
* Returns the current capture config from the three-tier fallback chain:
|
|
308
308
|
* 1. In-memory config from latest init response
|
|
309
|
-
* 2. File cache
|
|
309
|
+
* 2. File cache (read at most once per process lifetime)
|
|
310
310
|
* 3. DEFAULT_CAPTURE_CONFIG
|
|
311
|
+
*
|
|
312
|
+
* The disk read is cached via `configCacheChecked` to avoid repeated
|
|
313
|
+
* synchronous I/O on the hot path (called by GlasstraceExporter on
|
|
314
|
+
* every span export batch).
|
|
311
315
|
*/
|
|
312
316
|
declare function getActiveConfig(): CaptureConfig;
|
|
313
317
|
|
package/dist/index.d.ts
CHANGED
|
@@ -306,8 +306,12 @@ declare function performInit(config: ResolvedConfig, anonKey: AnonApiKey | null,
|
|
|
306
306
|
/**
|
|
307
307
|
* Returns the current capture config from the three-tier fallback chain:
|
|
308
308
|
* 1. In-memory config from latest init response
|
|
309
|
-
* 2. File cache
|
|
309
|
+
* 2. File cache (read at most once per process lifetime)
|
|
310
310
|
* 3. DEFAULT_CAPTURE_CONFIG
|
|
311
|
+
*
|
|
312
|
+
* The disk read is cached via `configCacheChecked` to avoid repeated
|
|
313
|
+
* synchronous I/O on the hot path (called by GlasstraceExporter on
|
|
314
|
+
* every span export batch).
|
|
311
315
|
*/
|
|
312
316
|
declare function getActiveConfig(): CaptureConfig;
|
|
313
317
|
|
package/dist/index.js
CHANGED
|
@@ -186,13 +186,14 @@ function classifyFetchTarget(url) {
|
|
|
186
186
|
|
|
187
187
|
// src/init-client.ts
|
|
188
188
|
import { readFileSync } from "fs";
|
|
189
|
-
import { writeFile, mkdir } from "fs/promises";
|
|
189
|
+
import { readFile, writeFile, mkdir, chmod } from "fs/promises";
|
|
190
190
|
import { join } from "path";
|
|
191
191
|
var GLASSTRACE_DIR = ".glasstrace";
|
|
192
192
|
var CONFIG_FILE = "config";
|
|
193
193
|
var TWENTY_FOUR_HOURS_MS = 24 * 60 * 60 * 1e3;
|
|
194
194
|
var INIT_TIMEOUT_MS = 1e4;
|
|
195
195
|
var currentConfig = null;
|
|
196
|
+
var configCacheChecked = false;
|
|
196
197
|
var rateLimitBackoff = false;
|
|
197
198
|
function loadCachedConfig(projectRoot) {
|
|
198
199
|
const root = projectRoot ?? process.cwd();
|
|
@@ -222,12 +223,14 @@ async function saveCachedConfig(response, projectRoot) {
|
|
|
222
223
|
const dirPath = join(root, GLASSTRACE_DIR);
|
|
223
224
|
const configPath = join(dirPath, CONFIG_FILE);
|
|
224
225
|
try {
|
|
225
|
-
await mkdir(dirPath, { recursive: true });
|
|
226
|
+
await mkdir(dirPath, { recursive: true, mode: 448 });
|
|
227
|
+
await chmod(dirPath, 448);
|
|
226
228
|
const cached = {
|
|
227
229
|
response,
|
|
228
230
|
cachedAt: Date.now()
|
|
229
231
|
};
|
|
230
|
-
await writeFile(configPath, JSON.stringify(cached), "utf-8");
|
|
232
|
+
await writeFile(configPath, JSON.stringify(cached), { encoding: "utf-8", mode: 384 });
|
|
233
|
+
await chmod(configPath, 384);
|
|
231
234
|
} catch (err) {
|
|
232
235
|
console.warn(
|
|
233
236
|
`[glasstrace] Failed to cache config to ${configPath}: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -280,6 +283,78 @@ async function sendInitRequest(config, anonKey, sdkVersion, importGraph, healthR
|
|
|
280
283
|
const body = await response.json();
|
|
281
284
|
return SdkInitResponseSchema.parse(body);
|
|
282
285
|
}
|
|
286
|
+
async function writeClaimedKey(newApiKey, projectRoot) {
|
|
287
|
+
const root = projectRoot ?? process.cwd();
|
|
288
|
+
const envLocalPath = join(root, ".env.local");
|
|
289
|
+
let envLocalWritten = false;
|
|
290
|
+
try {
|
|
291
|
+
let content;
|
|
292
|
+
try {
|
|
293
|
+
content = await readFile(envLocalPath, "utf-8");
|
|
294
|
+
if (/^GLASSTRACE_API_KEY=.*/m.test(content)) {
|
|
295
|
+
content = content.replace(
|
|
296
|
+
/^GLASSTRACE_API_KEY=.*$/gm,
|
|
297
|
+
`GLASSTRACE_API_KEY=${newApiKey}`
|
|
298
|
+
);
|
|
299
|
+
} else {
|
|
300
|
+
if (content.length > 0 && !content.endsWith("\n")) {
|
|
301
|
+
content += "\n";
|
|
302
|
+
}
|
|
303
|
+
content += `GLASSTRACE_API_KEY=${newApiKey}
|
|
304
|
+
`;
|
|
305
|
+
}
|
|
306
|
+
} catch (readErr) {
|
|
307
|
+
const code = readErr instanceof Error ? readErr.code : void 0;
|
|
308
|
+
if (code !== "ENOENT") {
|
|
309
|
+
throw readErr;
|
|
310
|
+
}
|
|
311
|
+
content = `GLASSTRACE_API_KEY=${newApiKey}
|
|
312
|
+
`;
|
|
313
|
+
}
|
|
314
|
+
await writeFile(envLocalPath, content, { encoding: "utf-8", mode: 384 });
|
|
315
|
+
await chmod(envLocalPath, 384);
|
|
316
|
+
envLocalWritten = true;
|
|
317
|
+
} catch {
|
|
318
|
+
}
|
|
319
|
+
if (envLocalWritten) {
|
|
320
|
+
try {
|
|
321
|
+
process.stderr.write(
|
|
322
|
+
"[glasstrace] Account claimed! API key written to .env.local. Restart your dev server to use it.\n"
|
|
323
|
+
);
|
|
324
|
+
} catch {
|
|
325
|
+
}
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
let claimedKeyWritten = false;
|
|
329
|
+
try {
|
|
330
|
+
const dirPath = join(root, GLASSTRACE_DIR);
|
|
331
|
+
await mkdir(dirPath, { recursive: true, mode: 448 });
|
|
332
|
+
await chmod(dirPath, 448);
|
|
333
|
+
const claimedKeyPath = join(dirPath, "claimed-key");
|
|
334
|
+
await writeFile(claimedKeyPath, newApiKey, {
|
|
335
|
+
encoding: "utf-8",
|
|
336
|
+
mode: 384
|
|
337
|
+
});
|
|
338
|
+
await chmod(claimedKeyPath, 384);
|
|
339
|
+
claimedKeyWritten = true;
|
|
340
|
+
} catch {
|
|
341
|
+
}
|
|
342
|
+
if (claimedKeyWritten) {
|
|
343
|
+
try {
|
|
344
|
+
process.stderr.write(
|
|
345
|
+
"[glasstrace] Account claimed! API key written to .glasstrace/claimed-key. Copy it to your .env.local file.\n"
|
|
346
|
+
);
|
|
347
|
+
} catch {
|
|
348
|
+
}
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
try {
|
|
352
|
+
process.stderr.write(
|
|
353
|
+
"[glasstrace] Account claimed but could not write key to disk. Visit your dashboard settings to rotate and retrieve a new API key.\n"
|
|
354
|
+
);
|
|
355
|
+
} catch {
|
|
356
|
+
}
|
|
357
|
+
}
|
|
283
358
|
async function performInit(config, anonKey, sdkVersion) {
|
|
284
359
|
if (rateLimitBackoff) {
|
|
285
360
|
rateLimitBackoff = false;
|
|
@@ -308,14 +383,8 @@ async function performInit(config, anonKey, sdkVersion) {
|
|
|
308
383
|
await saveCachedConfig(result);
|
|
309
384
|
if (result.claimResult) {
|
|
310
385
|
try {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
`
|
|
314
|
-
);
|
|
315
|
-
} catch (logErr) {
|
|
316
|
-
console.warn(
|
|
317
|
-
`[glasstrace] Failed to write claim migration message: ${logErr instanceof Error ? logErr.message : String(logErr)}`
|
|
318
|
-
);
|
|
386
|
+
await writeClaimedKey(result.claimResult.newApiKey);
|
|
387
|
+
} catch {
|
|
319
388
|
}
|
|
320
389
|
return { claimResult: result.claimResult };
|
|
321
390
|
}
|
|
@@ -366,9 +435,13 @@ function getActiveConfig() {
|
|
|
366
435
|
if (currentConfig) {
|
|
367
436
|
return currentConfig.config;
|
|
368
437
|
}
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
438
|
+
if (!configCacheChecked) {
|
|
439
|
+
configCacheChecked = true;
|
|
440
|
+
const cached = loadCachedConfig();
|
|
441
|
+
if (cached) {
|
|
442
|
+
currentConfig = cached;
|
|
443
|
+
return cached.config;
|
|
444
|
+
}
|
|
372
445
|
}
|
|
373
446
|
return { ...DEFAULT_CAPTURE_CONFIG };
|
|
374
447
|
}
|
|
@@ -3564,15 +3637,7 @@ function registerGlasstrace(options) {
|
|
|
3564
3637
|
() => Promise.resolve(anonKey),
|
|
3565
3638
|
() => sessionManager.getSessionId(getResolvedApiKey())
|
|
3566
3639
|
);
|
|
3567
|
-
|
|
3568
|
-
console.info("[glasstrace] Background init firing.");
|
|
3569
|
-
}
|
|
3570
|
-
const initResult = await performInit(config, anonKey, "0.7.0");
|
|
3571
|
-
if (initResult?.claimResult) {
|
|
3572
|
-
setResolvedApiKey(initResult.claimResult.newApiKey);
|
|
3573
|
-
notifyApiKeyResolved();
|
|
3574
|
-
}
|
|
3575
|
-
maybeInstallConsoleCapture();
|
|
3640
|
+
await backgroundInit(config, anonKey, currentGeneration);
|
|
3576
3641
|
} catch (err) {
|
|
3577
3642
|
console.warn(
|
|
3578
3643
|
`[glasstrace] Background init failed: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -3588,15 +3653,7 @@ function registerGlasstrace(options) {
|
|
|
3588
3653
|
notifyApiKeyResolved();
|
|
3589
3654
|
effectiveKey = anonKey;
|
|
3590
3655
|
if (currentGeneration !== registrationGeneration) return;
|
|
3591
|
-
|
|
3592
|
-
console.info("[glasstrace] Background init firing.");
|
|
3593
|
-
}
|
|
3594
|
-
const initResult = await performInit(config, anonKey, "0.7.0");
|
|
3595
|
-
if (initResult?.claimResult) {
|
|
3596
|
-
setResolvedApiKey(initResult.claimResult.newApiKey);
|
|
3597
|
-
notifyApiKeyResolved();
|
|
3598
|
-
}
|
|
3599
|
-
maybeInstallConsoleCapture();
|
|
3656
|
+
await backgroundInit(config, anonKey, currentGeneration);
|
|
3600
3657
|
} catch (err) {
|
|
3601
3658
|
console.warn(
|
|
3602
3659
|
`[glasstrace] Background init failed: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -3614,11 +3671,7 @@ function registerGlasstrace(options) {
|
|
|
3614
3671
|
} catch {
|
|
3615
3672
|
}
|
|
3616
3673
|
if (currentGeneration !== registrationGeneration) return;
|
|
3617
|
-
|
|
3618
|
-
console.info("[glasstrace] Background init firing.");
|
|
3619
|
-
}
|
|
3620
|
-
await performInit(config, anonKeyForInit, "0.7.0");
|
|
3621
|
-
maybeInstallConsoleCapture();
|
|
3674
|
+
await backgroundInit(config, anonKeyForInit, currentGeneration);
|
|
3622
3675
|
} catch (err) {
|
|
3623
3676
|
console.warn(
|
|
3624
3677
|
`[glasstrace] Background init failed: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -3635,6 +3688,18 @@ function registerGlasstrace(options) {
|
|
|
3635
3688
|
);
|
|
3636
3689
|
}
|
|
3637
3690
|
}
|
|
3691
|
+
async function backgroundInit(config, anonKeyForInit, generation) {
|
|
3692
|
+
if (config.verbose) {
|
|
3693
|
+
console.info("[glasstrace] Background init firing.");
|
|
3694
|
+
}
|
|
3695
|
+
const initResult = await performInit(config, anonKeyForInit, "0.7.2");
|
|
3696
|
+
if (generation !== registrationGeneration) return;
|
|
3697
|
+
if (initResult?.claimResult) {
|
|
3698
|
+
setResolvedApiKey(initResult.claimResult.newApiKey);
|
|
3699
|
+
notifyApiKeyResolved();
|
|
3700
|
+
}
|
|
3701
|
+
maybeInstallConsoleCapture();
|
|
3702
|
+
}
|
|
3638
3703
|
function getDiscoveryHandler() {
|
|
3639
3704
|
return discoveryHandler;
|
|
3640
3705
|
}
|
|
@@ -3658,7 +3723,7 @@ function isDiscoveryEnabled(config) {
|
|
|
3658
3723
|
import * as fs2 from "fs/promises";
|
|
3659
3724
|
import * as path2 from "path";
|
|
3660
3725
|
import * as crypto from "crypto";
|
|
3661
|
-
import {
|
|
3726
|
+
import { execFileSync } from "child_process";
|
|
3662
3727
|
async function collectSourceMaps(buildDir) {
|
|
3663
3728
|
const results = [];
|
|
3664
3729
|
try {
|
|
@@ -3692,7 +3757,7 @@ async function walkDir(baseDir, currentDir, results) {
|
|
|
3692
3757
|
}
|
|
3693
3758
|
async function computeBuildHash(maps) {
|
|
3694
3759
|
try {
|
|
3695
|
-
const sha =
|
|
3760
|
+
const sha = execFileSync("git", ["rev-parse", "HEAD"], { encoding: "utf-8" }).trim();
|
|
3696
3761
|
if (sha) {
|
|
3697
3762
|
return sha;
|
|
3698
3763
|
}
|
|
@@ -3994,6 +4059,9 @@ function captureError(error) {
|
|
|
3994
4059
|
};
|
|
3995
4060
|
if (error instanceof Error) {
|
|
3996
4061
|
attributes["error.type"] = error.constructor.name;
|
|
4062
|
+
if (error.stack) {
|
|
4063
|
+
attributes["error.stack"] = error.stack;
|
|
4064
|
+
}
|
|
3997
4065
|
}
|
|
3998
4066
|
span.addEvent("glasstrace.error", attributes);
|
|
3999
4067
|
maybeShowMcpNudge(String(error));
|