@glasstrace/sdk 0.4.0 → 0.4.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-TJ6ETQPH.js → chunk-67H2JEI4.js} +11 -5
- package/dist/{chunk-TJ6ETQPH.js.map → chunk-67H2JEI4.js.map} +1 -1
- package/dist/{chunk-STECO33B.js → chunk-PLJVIWHN.js} +1 -1
- package/dist/chunk-PLJVIWHN.js.map +1 -0
- package/dist/{chunk-EC5IINUT.js → chunk-TVOYTJ7I.js} +17 -4
- package/dist/chunk-TVOYTJ7I.js.map +1 -0
- package/dist/cli/init.cjs +9 -3
- package/dist/cli/init.cjs.map +1 -1
- package/dist/cli/init.js +3 -3
- package/dist/cli/mcp-add.cjs.map +1 -1
- package/dist/cli/mcp-add.js +2 -2
- package/dist/index.cjs +102 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -3
- package/dist/index.d.ts +10 -3
- package/dist/index.js +77 -39
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-EC5IINUT.js.map +0 -1
- package/dist/chunk-STECO33B.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -354,9 +354,13 @@ declare class GlasstraceExporter implements SpanExporter {
|
|
|
354
354
|
* Enriches a ReadableSpan with all glasstrace.* attributes.
|
|
355
355
|
* Returns a new ReadableSpan wrapper; the original span is not mutated.
|
|
356
356
|
*
|
|
357
|
-
*
|
|
358
|
-
*
|
|
359
|
-
*
|
|
357
|
+
* Only {@link SessionManager.getSessionId} is individually guarded because
|
|
358
|
+
* it calls into crypto and schema validation — a session ID failure should
|
|
359
|
+
* not prevent the rest of enrichment. The other helper calls
|
|
360
|
+
* ({@link deriveErrorCategory}, {@link deriveOrmProvider},
|
|
361
|
+
* {@link classifyFetchTarget}) are pure functions on typed string inputs
|
|
362
|
+
* and rely on the outer catch for any unexpected failure.
|
|
363
|
+
*
|
|
360
364
|
* On total failure, returns the original span unchanged.
|
|
361
365
|
*/
|
|
362
366
|
private enrichSpan;
|
|
@@ -467,6 +471,9 @@ declare function uploadSourceMaps(apiKey: string, endpoint: string, buildHash: s
|
|
|
467
471
|
* explicit, opt-in API for manual error reporting. If no span is active
|
|
468
472
|
* or OTel is not available, the call is silently ignored.
|
|
469
473
|
*
|
|
474
|
+
* On the first captured error, may display a one-time diagnostic nudge
|
|
475
|
+
* to stderr if the MCP connection marker is absent (dev environments only).
|
|
476
|
+
*
|
|
470
477
|
* @param error - The error to capture. Accepts `Error` objects, strings, or any value.
|
|
471
478
|
*
|
|
472
479
|
* @example
|
package/dist/index.d.ts
CHANGED
|
@@ -354,9 +354,13 @@ declare class GlasstraceExporter implements SpanExporter {
|
|
|
354
354
|
* Enriches a ReadableSpan with all glasstrace.* attributes.
|
|
355
355
|
* Returns a new ReadableSpan wrapper; the original span is not mutated.
|
|
356
356
|
*
|
|
357
|
-
*
|
|
358
|
-
*
|
|
359
|
-
*
|
|
357
|
+
* Only {@link SessionManager.getSessionId} is individually guarded because
|
|
358
|
+
* it calls into crypto and schema validation — a session ID failure should
|
|
359
|
+
* not prevent the rest of enrichment. The other helper calls
|
|
360
|
+
* ({@link deriveErrorCategory}, {@link deriveOrmProvider},
|
|
361
|
+
* {@link classifyFetchTarget}) are pure functions on typed string inputs
|
|
362
|
+
* and rely on the outer catch for any unexpected failure.
|
|
363
|
+
*
|
|
360
364
|
* On total failure, returns the original span unchanged.
|
|
361
365
|
*/
|
|
362
366
|
private enrichSpan;
|
|
@@ -467,6 +471,9 @@ declare function uploadSourceMaps(apiKey: string, endpoint: string, buildHash: s
|
|
|
467
471
|
* explicit, opt-in API for manual error reporting. If no span is active
|
|
468
472
|
* or OTel is not available, the call is silently ignored.
|
|
469
473
|
*
|
|
474
|
+
* On the first captured error, may display a one-time diagnostic nudge
|
|
475
|
+
* to stderr if the MCP connection marker is absent (dev environments only).
|
|
476
|
+
*
|
|
470
477
|
* @param error - The error to capture. Accepts `Error` objects, strings, or any value.
|
|
471
478
|
*
|
|
472
479
|
* @example
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
buildImportGraph,
|
|
3
3
|
discoverTestFiles,
|
|
4
4
|
extractImports
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-67H2JEI4.js";
|
|
6
6
|
import {
|
|
7
7
|
DEFAULT_CAPTURE_CONFIG,
|
|
8
8
|
GLASSTRACE_ATTRIBUTE_NAMES,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
SourceMapUploadResponseSchema,
|
|
13
13
|
getOrCreateAnonKey,
|
|
14
14
|
readAnonKey
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-TVOYTJ7I.js";
|
|
16
16
|
import {
|
|
17
17
|
INVALID_SPAN_CONTEXT,
|
|
18
18
|
SamplingDecision,
|
|
@@ -452,9 +452,13 @@ var GlasstraceExporter = class {
|
|
|
452
452
|
* Enriches a ReadableSpan with all glasstrace.* attributes.
|
|
453
453
|
* Returns a new ReadableSpan wrapper; the original span is not mutated.
|
|
454
454
|
*
|
|
455
|
-
*
|
|
456
|
-
*
|
|
457
|
-
*
|
|
455
|
+
* Only {@link SessionManager.getSessionId} is individually guarded because
|
|
456
|
+
* it calls into crypto and schema validation — a session ID failure should
|
|
457
|
+
* not prevent the rest of enrichment. The other helper calls
|
|
458
|
+
* ({@link deriveErrorCategory}, {@link deriveOrmProvider},
|
|
459
|
+
* {@link classifyFetchTarget}) are pure functions on typed string inputs
|
|
460
|
+
* and rely on the outer catch for any unexpected failure.
|
|
461
|
+
*
|
|
458
462
|
* On total failure, returns the original span unchanged.
|
|
459
463
|
*/
|
|
460
464
|
enrichSpan(span) {
|
|
@@ -497,44 +501,39 @@ var GlasstraceExporter = class {
|
|
|
497
501
|
}
|
|
498
502
|
}
|
|
499
503
|
const errorMessage = attrs["exception.message"];
|
|
500
|
-
if (errorMessage) {
|
|
504
|
+
if (typeof errorMessage === "string") {
|
|
501
505
|
extra[ATTR.ERROR_MESSAGE] = errorMessage;
|
|
502
506
|
}
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
extra[ATTR.ERROR_CATEGORY] = deriveErrorCategory(errorType);
|
|
508
|
-
}
|
|
509
|
-
} catch {
|
|
507
|
+
const errorType = attrs["exception.type"];
|
|
508
|
+
if (typeof errorType === "string") {
|
|
509
|
+
extra[ATTR.ERROR_CODE] = errorType;
|
|
510
|
+
extra[ATTR.ERROR_CATEGORY] = deriveErrorCategory(errorType);
|
|
510
511
|
}
|
|
511
512
|
const errorField = attrs["error.field"];
|
|
512
|
-
if (errorField) {
|
|
513
|
+
if (typeof errorField === "string") {
|
|
513
514
|
extra[ATTR.ERROR_FIELD] = errorField;
|
|
514
515
|
}
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
const operation = attrs["db.operation"];
|
|
526
|
-
if (operation) {
|
|
527
|
-
extra[ATTR.ORM_OPERATION] = operation;
|
|
528
|
-
}
|
|
516
|
+
const spanAny = span;
|
|
517
|
+
const instrumentationName = spanAny.instrumentationScope?.name ?? spanAny.instrumentationLibrary?.name ?? "";
|
|
518
|
+
const ormProvider = deriveOrmProvider(instrumentationName);
|
|
519
|
+
if (ormProvider) {
|
|
520
|
+
extra[ATTR.ORM_PROVIDER] = ormProvider;
|
|
521
|
+
const table = attrs["db.sql.table"];
|
|
522
|
+
const prismaModel = attrs["db.prisma.model"];
|
|
523
|
+
const model = typeof table === "string" ? table : typeof prismaModel === "string" ? prismaModel : void 0;
|
|
524
|
+
if (model) {
|
|
525
|
+
extra[ATTR.ORM_MODEL] = model;
|
|
529
526
|
}
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
const url = attrs["http.url"] ?? attrs["url.full"];
|
|
534
|
-
if (url && span.kind === SpanKind.CLIENT) {
|
|
535
|
-
extra[ATTR.FETCH_TARGET] = classifyFetchTarget(url);
|
|
527
|
+
const operation = attrs["db.operation"];
|
|
528
|
+
if (typeof operation === "string") {
|
|
529
|
+
extra[ATTR.ORM_OPERATION] = operation;
|
|
536
530
|
}
|
|
537
|
-
}
|
|
531
|
+
}
|
|
532
|
+
const httpUrl = attrs["http.url"];
|
|
533
|
+
const fullUrl = attrs["url.full"];
|
|
534
|
+
const url = typeof httpUrl === "string" ? httpUrl : typeof fullUrl === "string" ? fullUrl : void 0;
|
|
535
|
+
if (url && span.kind === SpanKind.CLIENT) {
|
|
536
|
+
extra[ATTR.FETCH_TARGET] = classifyFetchTarget(url);
|
|
538
537
|
}
|
|
539
538
|
return createEnrichedSpan(span, extra);
|
|
540
539
|
} catch {
|
|
@@ -3542,7 +3541,7 @@ function registerGlasstrace(options) {
|
|
|
3542
3541
|
if (config.verbose) {
|
|
3543
3542
|
console.info("[glasstrace] Background init firing.");
|
|
3544
3543
|
}
|
|
3545
|
-
await performInit(config, anonKey, "0.4.
|
|
3544
|
+
await performInit(config, anonKey, "0.4.2");
|
|
3546
3545
|
maybeInstallConsoleCapture();
|
|
3547
3546
|
} catch (err) {
|
|
3548
3547
|
console.warn(
|
|
@@ -3562,7 +3561,7 @@ function registerGlasstrace(options) {
|
|
|
3562
3561
|
if (config.verbose) {
|
|
3563
3562
|
console.info("[glasstrace] Background init firing.");
|
|
3564
3563
|
}
|
|
3565
|
-
await performInit(config, anonKey, "0.4.
|
|
3564
|
+
await performInit(config, anonKey, "0.4.2");
|
|
3566
3565
|
maybeInstallConsoleCapture();
|
|
3567
3566
|
} catch (err) {
|
|
3568
3567
|
console.warn(
|
|
@@ -3584,7 +3583,7 @@ function registerGlasstrace(options) {
|
|
|
3584
3583
|
if (config.verbose) {
|
|
3585
3584
|
console.info("[glasstrace] Background init firing.");
|
|
3586
3585
|
}
|
|
3587
|
-
await performInit(config, anonKeyForInit, "0.4.
|
|
3586
|
+
await performInit(config, anonKeyForInit, "0.4.2");
|
|
3588
3587
|
maybeInstallConsoleCapture();
|
|
3589
3588
|
} catch (err) {
|
|
3590
3589
|
console.warn(
|
|
@@ -3683,7 +3682,10 @@ async function uploadSourceMaps(apiKey, endpoint, buildHash, maps) {
|
|
|
3683
3682
|
sourceMap: m.content
|
|
3684
3683
|
}))
|
|
3685
3684
|
};
|
|
3686
|
-
|
|
3685
|
+
let baseUrl = endpoint;
|
|
3686
|
+
while (baseUrl.endsWith("/")) {
|
|
3687
|
+
baseUrl = baseUrl.slice(0, -1);
|
|
3688
|
+
}
|
|
3687
3689
|
const response = await fetch(`${baseUrl}/v1/source-maps`, {
|
|
3688
3690
|
method: "POST",
|
|
3689
3691
|
headers: {
|
|
@@ -3767,6 +3769,41 @@ async function handleSourceMapUpload(distDir) {
|
|
|
3767
3769
|
}
|
|
3768
3770
|
}
|
|
3769
3771
|
|
|
3772
|
+
// src/nudge/error-nudge.ts
|
|
3773
|
+
import { existsSync } from "fs";
|
|
3774
|
+
import { join as join3 } from "path";
|
|
3775
|
+
var hasFired = false;
|
|
3776
|
+
function sanitize(input) {
|
|
3777
|
+
return input.replace(/[\x00-\x1f\x7f]/g, "");
|
|
3778
|
+
}
|
|
3779
|
+
function maybeShowMcpNudge(errorSummary) {
|
|
3780
|
+
if (hasFired) {
|
|
3781
|
+
return;
|
|
3782
|
+
}
|
|
3783
|
+
const config = resolveConfig();
|
|
3784
|
+
if (isProductionDisabled(config)) {
|
|
3785
|
+
return;
|
|
3786
|
+
}
|
|
3787
|
+
let markerExists = false;
|
|
3788
|
+
try {
|
|
3789
|
+
const markerPath = join3(process.cwd(), ".glasstrace", "mcp-connected");
|
|
3790
|
+
markerExists = existsSync(markerPath);
|
|
3791
|
+
} catch {
|
|
3792
|
+
markerExists = false;
|
|
3793
|
+
}
|
|
3794
|
+
if (markerExists) {
|
|
3795
|
+
return;
|
|
3796
|
+
}
|
|
3797
|
+
hasFired = true;
|
|
3798
|
+
const safe = sanitize(errorSummary);
|
|
3799
|
+
process.stderr.write(
|
|
3800
|
+
`[glasstrace] Error captured: ${safe}
|
|
3801
|
+
Debug with AI: ask your agent "What's the latest Glasstrace error?"
|
|
3802
|
+
Not connected? Run: npx glasstrace mcp add
|
|
3803
|
+
`
|
|
3804
|
+
);
|
|
3805
|
+
}
|
|
3806
|
+
|
|
3770
3807
|
// src/capture-error.ts
|
|
3771
3808
|
function captureError(error) {
|
|
3772
3809
|
try {
|
|
@@ -3779,6 +3816,7 @@ function captureError(error) {
|
|
|
3779
3816
|
attributes["error.type"] = error.constructor.name;
|
|
3780
3817
|
}
|
|
3781
3818
|
span.addEvent("glasstrace.error", attributes);
|
|
3819
|
+
maybeShowMcpNudge(String(error));
|
|
3782
3820
|
} catch {
|
|
3783
3821
|
}
|
|
3784
3822
|
}
|