@glasstrace/sdk 1.2.0 → 1.3.0

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.
Files changed (43) hide show
  1. package/README.md +47 -0
  2. package/dist/{chunk-JKI4OCFV.js → chunk-A63WX7NR.js} +3 -3
  3. package/dist/{chunk-6RNBUUBR.js → chunk-AGCYKZFY.js} +2 -2
  4. package/dist/{chunk-4EZ6JTDG.js → chunk-AKZGMT33.js} +2 -2
  5. package/dist/{chunk-TWTWRJ25.js → chunk-AYUL5QMZ.js} +2 -2
  6. package/dist/{chunk-DST4UBXU.js → chunk-FMEWG3FY.js} +2 -2
  7. package/dist/{chunk-TWHCJKRS.js → chunk-FVHVDBGX.js} +3 -3
  8. package/dist/{chunk-X5MAXP5T.js → chunk-GTPTKN5A.js} +6 -3
  9. package/dist/{chunk-X5MAXP5T.js.map → chunk-GTPTKN5A.js.map} +1 -1
  10. package/dist/{chunk-6RIH6SFM.js → chunk-JMYKR5Z3.js} +89 -17
  11. package/dist/chunk-JMYKR5Z3.js.map +1 -0
  12. package/dist/cli/init.cjs +5 -3
  13. package/dist/cli/init.cjs.map +1 -1
  14. package/dist/cli/init.js +6 -6
  15. package/dist/cli/mcp-add.cjs +4 -2
  16. package/dist/cli/mcp-add.cjs.map +1 -1
  17. package/dist/cli/mcp-add.js +2 -2
  18. package/dist/cli/uninit.js +3 -3
  19. package/dist/cli/validate.cjs +4 -2
  20. package/dist/cli/validate.cjs.map +1 -1
  21. package/dist/cli/validate.js +2 -2
  22. package/dist/edge-entry.cjs +5 -2
  23. package/dist/edge-entry.cjs.map +1 -1
  24. package/dist/edge-entry.js +2 -2
  25. package/dist/index.cjs +92 -14
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.js +5 -5
  28. package/dist/node-entry.cjs +92 -14
  29. package/dist/node-entry.cjs.map +1 -1
  30. package/dist/node-entry.js +7 -7
  31. package/dist/node-subpath.cjs +4 -2
  32. package/dist/node-subpath.cjs.map +1 -1
  33. package/dist/node-subpath.js +3 -3
  34. package/dist/{source-map-uploader-DPUUCLNW.js → source-map-uploader-M2P5CDOB.js} +3 -3
  35. package/package.json +1 -1
  36. package/dist/chunk-6RIH6SFM.js.map +0 -1
  37. /package/dist/{chunk-JKI4OCFV.js.map → chunk-A63WX7NR.js.map} +0 -0
  38. /package/dist/{chunk-6RNBUUBR.js.map → chunk-AGCYKZFY.js.map} +0 -0
  39. /package/dist/{chunk-4EZ6JTDG.js.map → chunk-AKZGMT33.js.map} +0 -0
  40. /package/dist/{chunk-TWTWRJ25.js.map → chunk-AYUL5QMZ.js.map} +0 -0
  41. /package/dist/{chunk-DST4UBXU.js.map → chunk-FMEWG3FY.js.map} +0 -0
  42. /package/dist/{chunk-TWHCJKRS.js.map → chunk-FVHVDBGX.js.map} +0 -0
  43. /package/dist/{source-map-uploader-DPUUCLNW.js.map → source-map-uploader-M2P5CDOB.js.map} +0 -0
package/dist/index.js CHANGED
@@ -12,12 +12,12 @@ import {
12
12
  registerGlasstrace,
13
13
  waitForReady,
14
14
  withGlasstraceConfig
15
- } from "./chunk-6RIH6SFM.js";
15
+ } from "./chunk-JMYKR5Z3.js";
16
16
  import {
17
17
  GlasstraceSpanProcessor,
18
18
  SdkError,
19
19
  captureCorrelationId
20
- } from "./chunk-6RNBUUBR.js";
20
+ } from "./chunk-AGCYKZFY.js";
21
21
  import "./chunk-DQ25VOKK.js";
22
22
  import "./chunk-3TU62WD6.js";
23
23
  import {
@@ -27,7 +27,7 @@ import {
27
27
  performInit,
28
28
  saveCachedConfig,
29
29
  sendInitRequest
30
- } from "./chunk-JKI4OCFV.js";
30
+ } from "./chunk-A63WX7NR.js";
31
31
  import {
32
32
  isAnonymousMode,
33
33
  isProductionDisabled,
@@ -37,10 +37,10 @@ import {
37
37
  import {
38
38
  getOrCreateAnonKey,
39
39
  readAnonKey
40
- } from "./chunk-TWTWRJ25.js";
40
+ } from "./chunk-AYUL5QMZ.js";
41
41
  import {
42
42
  deriveSessionId
43
- } from "./chunk-X5MAXP5T.js";
43
+ } from "./chunk-GTPTKN5A.js";
44
44
  import "./chunk-NSBPE2FW.js";
45
45
  export {
46
46
  GlasstraceExporter,
@@ -14670,13 +14670,15 @@ var init_dist = __esm({
14670
14670
  });
14671
14671
  PresignedUploadResponseSchema = external_exports.object({
14672
14672
  uploadId: external_exports.string().uuid(),
14673
- expiresAt: external_exports.number().int().positive(),
14673
+ expiresAt: external_exports.number().int().nonnegative(),
14674
14674
  files: external_exports.array(
14675
14675
  external_exports.object({
14676
14676
  filePath: external_exports.string().min(1),
14677
14677
  clientToken: external_exports.string().min(1),
14678
14678
  pathname: external_exports.string().min(1),
14679
- maxBytes: external_exports.number().int().positive()
14679
+ maxBytes: external_exports.number().int().positive(),
14680
+ /** Vercel Blob access mode — explicit in the contract per DISC-756. */
14681
+ access: external_exports.enum(["public"])
14680
14682
  })
14681
14683
  ).min(1).max(100)
14682
14684
  });
@@ -14722,6 +14724,7 @@ var init_dist = __esm({
14722
14724
  FETCH_DURATION_MS: "glasstrace.fetch.duration_ms",
14723
14725
  FETCH_TARGET: "glasstrace.fetch.target",
14724
14726
  ENV_REFERENCED: "glasstrace.env.referenced",
14727
+ BUILD_HASH: "glasstrace.build.hash",
14725
14728
  SOURCE_FILE: "glasstrace.source.file",
14726
14729
  SOURCE_LINE: "glasstrace.source.line",
14727
14730
  SOURCE_MAPPED: "glasstrace.source.mapped",
@@ -18300,16 +18303,22 @@ var ERROR_RESPONSE_BODY_TRUNCATION_MARKER = "...[truncated]";
18300
18303
  var REDACTED = "[REDACTED]";
18301
18304
  var ERROR_STATUS_MIN = 400;
18302
18305
  var ERROR_STATUS_MAX = 599;
18303
- function isHttpErrorStatus(status) {
18306
+ function coerceHttpStatus(value) {
18304
18307
  let numeric;
18305
- if (typeof status === "number") {
18306
- numeric = status;
18307
- } else if (typeof status === "string" && status.length > 0) {
18308
- numeric = Number(status);
18308
+ if (typeof value === "number") {
18309
+ numeric = value;
18310
+ } else if (typeof value === "string") {
18311
+ const trimmed = value.trim();
18312
+ if (trimmed.length === 0) return void 0;
18313
+ numeric = Number(trimmed);
18309
18314
  } else {
18310
- return false;
18315
+ return void 0;
18311
18316
  }
18312
- if (!Number.isFinite(numeric)) return false;
18317
+ return Number.isFinite(numeric) ? numeric : void 0;
18318
+ }
18319
+ function isHttpErrorStatus(status) {
18320
+ const numeric = coerceHttpStatus(status);
18321
+ if (numeric === void 0) return false;
18313
18322
  return numeric >= ERROR_STATUS_MIN && numeric <= ERROR_STATUS_MAX;
18314
18323
  }
18315
18324
  var REDACTION_PATTERNS = [
@@ -18414,6 +18423,19 @@ function prepareErrorResponseBody(body) {
18414
18423
  return truncateErrorResponseBody(sanitized);
18415
18424
  }
18416
18425
 
18426
+ // src/build-info.ts
18427
+ var UNSET = "";
18428
+ function readBuildHashFromEnv() {
18429
+ const raw = process.env.GLASSTRACE_BUILD_HASH;
18430
+ if (typeof raw !== "string") return UNSET;
18431
+ const trimmed = raw.trim();
18432
+ return trimmed.length > 0 ? trimmed : UNSET;
18433
+ }
18434
+ var cachedBuildHash = readBuildHashFromEnv();
18435
+ function getBuildHash() {
18436
+ return cachedBuildHash === UNSET ? void 0 : cachedBuildHash;
18437
+ }
18438
+
18417
18439
  // src/enriching-exporter.ts
18418
18440
  var ATTR2 = GLASSTRACE_ATTRIBUTE_NAMES;
18419
18441
  var API_KEY_PENDING = "pending";
@@ -18529,6 +18551,10 @@ var GlasstraceExporter = class {
18529
18551
  if (env) {
18530
18552
  extra[ATTR2.ENVIRONMENT] = env;
18531
18553
  }
18554
+ const buildHash = getBuildHash();
18555
+ if (buildHash) {
18556
+ extra[ATTR2.BUILD_HASH] = buildHash;
18557
+ }
18532
18558
  const existingCid = attrs["glasstrace.correlation.id"];
18533
18559
  if (typeof existingCid === "string") {
18534
18560
  extra[ATTR2.CORRELATION_ID] = existingCid;
@@ -18569,7 +18595,7 @@ var GlasstraceExporter = class {
18569
18595
  }
18570
18596
  }
18571
18597
  }
18572
- const statusCode = attrs["http.status_code"] ?? attrs["http.response.status_code"];
18598
+ const statusCode = coerceHttpStatus(attrs["http.status_code"]) ?? coerceHttpStatus(attrs["http.response.status_code"]);
18573
18599
  if (statusCode !== void 0) {
18574
18600
  extra[ATTR2.HTTP_STATUS_CODE] = statusCode;
18575
18601
  }
@@ -22561,7 +22587,7 @@ function registerGlasstrace(options) {
22561
22587
  setCoreState(CoreState.REGISTERING);
22562
22588
  startRuntimeStateWriter({
22563
22589
  projectRoot: process.cwd(),
22564
- sdkVersion: "1.2.0"
22590
+ sdkVersion: "1.3.0"
22565
22591
  });
22566
22592
  const config2 = resolveConfig(options);
22567
22593
  if (config2.verbose) {
@@ -22727,8 +22753,8 @@ async function backgroundInit(config2, anonKeyForInit, generation) {
22727
22753
  if (config2.verbose) {
22728
22754
  console.info("[glasstrace] Background init firing.");
22729
22755
  }
22730
- const healthReport = collectHealthReport("1.2.0");
22731
- const initResult = await performInit(config2, anonKeyForInit, "1.2.0", healthReport);
22756
+ const healthReport = collectHealthReport("1.3.0");
22757
+ const initResult = await performInit(config2, anonKeyForInit, "1.3.0", healthReport);
22732
22758
  if (generation !== registrationGeneration) return;
22733
22759
  const currentState = getCoreState();
22734
22760
  if (currentState === CoreState.SHUTTING_DOWN || currentState === CoreState.SHUTDOWN) {
@@ -22751,7 +22777,7 @@ async function backgroundInit(config2, anonKeyForInit, generation) {
22751
22777
  }
22752
22778
  maybeInstallConsoleCapture();
22753
22779
  if (didLastInitSucceed()) {
22754
- startHeartbeat(config2, anonKeyForInit, "1.2.0", generation, (newApiKey, accountId) => {
22780
+ startHeartbeat(config2, anonKeyForInit, "1.3.0", generation, (newApiKey, accountId) => {
22755
22781
  setAuthState(AuthState.CLAIMING);
22756
22782
  emitLifecycleEvent("auth:claim_started", { accountId });
22757
22783
  setResolvedApiKey(newApiKey);
@@ -22909,7 +22935,54 @@ async function handleSourceMapUpload(distDir) {
22909
22935
 
22910
22936
  // src/capture-error.ts
22911
22937
  init_esm();
22938
+ init_dist();
22912
22939
  init_error_nudge();
22940
+
22941
+ // src/stack-frame.ts
22942
+ var PAREN_FRAME = /^\s*at\s+(?:[^()]+\s+)?\(([^()\s]+):(\d+):(\d+)\)\s*$/;
22943
+ var BARE_FRAME = /^\s*at\s+(?:async\s+)?([^()\s]+):(\d+):(\d+)\s*$/;
22944
+ var INTERNAL_FRAME_PATTERNS = [
22945
+ /^node:/,
22946
+ /^node:internal\//,
22947
+ /[/\\]node_modules[/\\]@glasstrace[/\\]sdk[/\\]/,
22948
+ /[/\\]packages[/\\]sdk[/\\]src[/\\]capture-error\./,
22949
+ /[/\\]packages[/\\]sdk[/\\]src[/\\]stack-frame\./
22950
+ ];
22951
+ function isInternalFrame(file2) {
22952
+ return INTERNAL_FRAME_PATTERNS.some((re2) => re2.test(file2));
22953
+ }
22954
+ function parseTopStackFrame(stack) {
22955
+ if (typeof stack !== "string" || stack.length === 0) return null;
22956
+ let cursor = 0;
22957
+ while (cursor < stack.length) {
22958
+ const newlineAt = stack.indexOf("\n", cursor);
22959
+ const lineEnd = newlineAt === -1 ? stack.length : newlineAt;
22960
+ const line = stack.slice(cursor, lineEnd);
22961
+ cursor = lineEnd + 1;
22962
+ if (!/^\s*at\s/.test(line)) continue;
22963
+ let file2;
22964
+ let lineStr;
22965
+ const parenMatch = PAREN_FRAME.exec(line);
22966
+ if (parenMatch) {
22967
+ file2 = parenMatch[1];
22968
+ lineStr = parenMatch[2];
22969
+ } else {
22970
+ const bareMatch = BARE_FRAME.exec(line);
22971
+ if (bareMatch) {
22972
+ file2 = bareMatch[1];
22973
+ lineStr = bareMatch[2];
22974
+ }
22975
+ }
22976
+ if (!file2 || !lineStr) continue;
22977
+ if (isInternalFrame(file2)) continue;
22978
+ const lineNum = Number.parseInt(lineStr, 10);
22979
+ if (!Number.isFinite(lineNum) || lineNum <= 0) continue;
22980
+ return { file: file2, line: lineNum };
22981
+ }
22982
+ return null;
22983
+ }
22984
+
22985
+ // src/capture-error.ts
22913
22986
  function captureError(error48) {
22914
22987
  try {
22915
22988
  const span = trace.getSpan(context.active());
@@ -22921,6 +22994,11 @@ function captureError(error48) {
22921
22994
  attributes["error.type"] = error48.constructor.name;
22922
22995
  if (error48.stack) {
22923
22996
  attributes["error.stack"] = error48.stack;
22997
+ const frame = parseTopStackFrame(error48.stack);
22998
+ if (frame) {
22999
+ attributes[GLASSTRACE_ATTRIBUTE_NAMES.SOURCE_FILE] = frame.file;
23000
+ attributes[GLASSTRACE_ATTRIBUTE_NAMES.SOURCE_LINE] = frame.line;
23001
+ }
22924
23002
  }
22925
23003
  }
22926
23004
  span.addEvent("glasstrace.error", attributes);