@glasstrace/sdk 1.2.1 → 1.3.1

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 (54) hide show
  1. package/README.md +47 -0
  2. package/dist/{chunk-CTJO7PUZ.js → chunk-5PFPEA4C.js} +75 -9
  3. package/dist/chunk-5PFPEA4C.js.map +1 -0
  4. package/dist/{chunk-2GCN27SI.js → chunk-CRM3EYOL.js} +2 -2
  5. package/dist/{chunk-MD5XPCTQ.js → chunk-DW2UJUNB.js} +2 -2
  6. package/dist/chunk-DW2UJUNB.js.map +1 -0
  7. package/dist/{chunk-YMLMZCPR.js → chunk-JFR42QG5.js} +2 -2
  8. package/dist/{chunk-EBYISKQP.js → chunk-MQHLWSIX.js} +2 -1
  9. package/dist/{chunk-EBYISKQP.js.map → chunk-MQHLWSIX.js.map} +1 -1
  10. package/dist/{chunk-NFPDYME5.js → chunk-USLH3OTM.js} +3 -3
  11. package/dist/{chunk-NFPDYME5.js.map → chunk-USLH3OTM.js.map} +1 -1
  12. package/dist/{chunk-HV5ID2WJ.js → chunk-X4IK6KES.js} +3 -3
  13. package/dist/{chunk-47B2G3FE.js → chunk-XS3BO7RY.js} +2 -2
  14. package/dist/cli/init.cjs +1 -1
  15. package/dist/cli/init.cjs.map +1 -1
  16. package/dist/cli/init.js +6 -6
  17. package/dist/cli/mcp-add.cjs.map +1 -1
  18. package/dist/cli/mcp-add.js +2 -2
  19. package/dist/cli/uninit.cjs.map +1 -1
  20. package/dist/cli/uninit.js +3 -3
  21. package/dist/cli/validate.cjs.map +1 -1
  22. package/dist/cli/validate.js +2 -2
  23. package/dist/{edge-entry-DYl05SJ-.d.cts → edge-entry-DT9OhPTC.d.cts} +1 -1
  24. package/dist/{edge-entry-CFq085RZ.d.ts → edge-entry-shCc8_Y1.d.ts} +1 -1
  25. package/dist/edge-entry.cjs +1 -0
  26. package/dist/edge-entry.cjs.map +1 -1
  27. package/dist/edge-entry.d.cts +2 -2
  28. package/dist/edge-entry.d.ts +2 -2
  29. package/dist/edge-entry.js +2 -2
  30. package/dist/index.cjs +74 -4
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/{index.d-CYYe3PxB.d.cts → index.d-DiI6uVEW.d.cts} +1 -1
  33. package/dist/{index.d-CYYe3PxB.d.ts → index.d-DiI6uVEW.d.ts} +1 -1
  34. package/dist/index.d.cts +4 -4
  35. package/dist/index.d.ts +4 -4
  36. package/dist/index.js +5 -5
  37. package/dist/node-entry.cjs +74 -4
  38. package/dist/node-entry.cjs.map +1 -1
  39. package/dist/node-entry.d.cts +2 -2
  40. package/dist/node-entry.d.ts +2 -2
  41. package/dist/node-entry.js +7 -7
  42. package/dist/node-subpath.cjs.map +1 -1
  43. package/dist/node-subpath.d.cts +1 -1
  44. package/dist/node-subpath.d.ts +1 -1
  45. package/dist/node-subpath.js +3 -3
  46. package/dist/{source-map-uploader-RA4Z7TWA.js → source-map-uploader-LACAGKIW.js} +3 -3
  47. package/package.json +1 -1
  48. package/dist/chunk-CTJO7PUZ.js.map +0 -1
  49. package/dist/chunk-MD5XPCTQ.js.map +0 -1
  50. /package/dist/{chunk-2GCN27SI.js.map → chunk-CRM3EYOL.js.map} +0 -0
  51. /package/dist/{chunk-YMLMZCPR.js.map → chunk-JFR42QG5.js.map} +0 -0
  52. /package/dist/{chunk-HV5ID2WJ.js.map → chunk-X4IK6KES.js.map} +0 -0
  53. /package/dist/{chunk-47B2G3FE.js.map → chunk-XS3BO7RY.js.map} +0 -0
  54. /package/dist/{source-map-uploader-RA4Z7TWA.js.map → source-map-uploader-LACAGKIW.js.map} +0 -0
package/README.md CHANGED
@@ -199,6 +199,53 @@ body data. If your account enables the flag but a span never carries
199
199
  the internal attribute (no adapter set it), the public attribute is
200
200
  still absent. The default is "off, twice".
201
201
 
202
+ ## Source maps
203
+
204
+ Glasstrace uploads server-side source maps at build time and resolves
205
+ compiled-output stack frames back to original source on the dashboard
206
+ and in agent prompts. Three span attributes connect the runtime trace
207
+ to the build-time manifest:
208
+
209
+ | Attribute | When stamped | Source |
210
+ |---|---|---|
211
+ | `glasstrace.build.hash` | every server span | `process.env.GLASSTRACE_BUILD_HASH` (read once at module load) |
212
+ | `glasstrace.source.file` | error spans only | top user-attributable frame of `Error.stack` |
213
+ | `glasstrace.source.line` | error spans only | top user-attributable frame of `Error.stack` |
214
+
215
+ The build hash links a runtime span to the source maps uploaded
216
+ during the same build. Set the env var in your deploy step:
217
+
218
+ ```bash
219
+ # Vercel / GitHub Actions / any CI
220
+ GLASSTRACE_BUILD_HASH=$(git rev-parse HEAD) npm run start
221
+ ```
222
+
223
+ The Glasstrace `next.config.ts` wrapper (`withGlasstraceConfig`) and
224
+ the `@glasstrace/sdk/node` upload helpers compute the same hash via
225
+ `computeBuildHash()` (preferring `git rev-parse HEAD`, falling back
226
+ to a deterministic content hash). When the runtime env var is unset,
227
+ the SDK silently omits the attribute — no crash, no diagnostic — so
228
+ projects that have not adopted the convention behave exactly as
229
+ before; their stored traces simply do not render mapped frames in
230
+ the dashboard.
231
+
232
+ The error-source attributes are stamped only by the manual
233
+ `captureError()` API, on the `glasstrace.error` span event. They
234
+ report the compiled-output `file:line` from the top user-attributable
235
+ frame; ingestion's resolver then maps that pair back to original
236
+ source via the uploaded source map manifest. The SDK skips frames
237
+ inside Node's built-in modules (`node:internal/*`, `node:fs`, etc.)
238
+ and inside its own `node_modules/@glasstrace/sdk/` closure, so the
239
+ reported frame is always the caller of `captureError()`. If
240
+ `Error.stack` is absent, malformed, or contains only internal frames,
241
+ the attributes are silently omitted and only the existing
242
+ `error.message` / `error.type` / `error.stack` event attributes are
243
+ recorded.
244
+
245
+ These attributes are additive: any consumer that does not understand
246
+ them ignores them. Existing trace pipelines and dashboards continue
247
+ to work unchanged.
248
+
202
249
  ## Browser-extension discovery
203
250
 
204
251
  `glasstrace init` writes a small static file at
@@ -33,7 +33,7 @@ import {
33
33
  performInit,
34
34
  recordSpansDropped,
35
35
  recordSpansExported
36
- } from "./chunk-HV5ID2WJ.js";
36
+ } from "./chunk-X4IK6KES.js";
37
37
  import {
38
38
  isAnonymousMode,
39
39
  isProductionDisabled,
@@ -43,11 +43,11 @@ import {
43
43
  atomicWriteFileSync,
44
44
  getOrCreateAnonKey,
45
45
  readAnonKey
46
- } from "./chunk-MD5XPCTQ.js";
46
+ } from "./chunk-DW2UJUNB.js";
47
47
  import {
48
48
  GLASSTRACE_ATTRIBUTE_NAMES,
49
49
  deriveSessionId
50
- } from "./chunk-EBYISKQP.js";
50
+ } from "./chunk-MQHLWSIX.js";
51
51
  import {
52
52
  __require
53
53
  } from "./chunk-NSBPE2FW.js";
@@ -264,6 +264,19 @@ function prepareErrorResponseBody(body) {
264
264
  return truncateErrorResponseBody(sanitized);
265
265
  }
266
266
 
267
+ // src/build-info.ts
268
+ var UNSET = "";
269
+ function readBuildHashFromEnv() {
270
+ const raw = process.env.GLASSTRACE_BUILD_HASH;
271
+ if (typeof raw !== "string") return UNSET;
272
+ const trimmed = raw.trim();
273
+ return trimmed.length > 0 ? trimmed : UNSET;
274
+ }
275
+ var cachedBuildHash = readBuildHashFromEnv();
276
+ function getBuildHash() {
277
+ return cachedBuildHash === UNSET ? void 0 : cachedBuildHash;
278
+ }
279
+
267
280
  // src/enriching-exporter.ts
268
281
  var ATTR = GLASSTRACE_ATTRIBUTE_NAMES;
269
282
  var API_KEY_PENDING = "pending";
@@ -379,6 +392,10 @@ var GlasstraceExporter = class {
379
392
  if (env) {
380
393
  extra[ATTR.ENVIRONMENT] = env;
381
394
  }
395
+ const buildHash = getBuildHash();
396
+ if (buildHash) {
397
+ extra[ATTR.BUILD_HASH] = buildHash;
398
+ }
382
399
  const existingCid = attrs["glasstrace.correlation.id"];
383
400
  if (typeof existingCid === "string") {
384
401
  extra[ATTR.CORRELATION_ID] = existingCid;
@@ -4207,7 +4224,7 @@ function registerGlasstrace(options) {
4207
4224
  setCoreState(CoreState.REGISTERING);
4208
4225
  startRuntimeStateWriter({
4209
4226
  projectRoot: process.cwd(),
4210
- sdkVersion: "1.2.1"
4227
+ sdkVersion: "1.3.1"
4211
4228
  });
4212
4229
  const config = resolveConfig(options);
4213
4230
  if (config.verbose) {
@@ -4373,8 +4390,8 @@ async function backgroundInit(config, anonKeyForInit, generation) {
4373
4390
  if (config.verbose) {
4374
4391
  console.info("[glasstrace] Background init firing.");
4375
4392
  }
4376
- const healthReport = collectHealthReport("1.2.1");
4377
- const initResult = await performInit(config, anonKeyForInit, "1.2.1", healthReport);
4393
+ const healthReport = collectHealthReport("1.3.1");
4394
+ const initResult = await performInit(config, anonKeyForInit, "1.3.1", healthReport);
4378
4395
  if (generation !== registrationGeneration) return;
4379
4396
  const currentState = getCoreState();
4380
4397
  if (currentState === CoreState.SHUTTING_DOWN || currentState === CoreState.SHUTDOWN) {
@@ -4397,7 +4414,7 @@ async function backgroundInit(config, anonKeyForInit, generation) {
4397
4414
  }
4398
4415
  maybeInstallConsoleCapture();
4399
4416
  if (didLastInitSucceed()) {
4400
- startHeartbeat(config, anonKeyForInit, "1.2.1", generation, (newApiKey, accountId) => {
4417
+ startHeartbeat(config, anonKeyForInit, "1.3.1", generation, (newApiKey, accountId) => {
4401
4418
  setAuthState(AuthState.CLAIMING);
4402
4419
  emitLifecycleEvent("auth:claim_started", { accountId });
4403
4420
  setResolvedApiKey(newApiKey);
@@ -4692,7 +4709,7 @@ async function handleSourceMapUpload(distDir) {
4692
4709
  );
4693
4710
  return;
4694
4711
  }
4695
- const { discoverSourceMapFiles, computeBuildHash, uploadSourceMaps } = await import("./source-map-uploader-RA4Z7TWA.js");
4712
+ const { discoverSourceMapFiles, computeBuildHash, uploadSourceMaps } = await import("./source-map-uploader-LACAGKIW.js");
4696
4713
  const files = await discoverSourceMapFiles(distDir);
4697
4714
  if (files.length === 0) {
4698
4715
  console.info("[glasstrace] No source map files found. Skipping upload.");
@@ -4711,6 +4728,50 @@ async function handleSourceMapUpload(distDir) {
4711
4728
  }
4712
4729
  }
4713
4730
 
4731
+ // src/stack-frame.ts
4732
+ var PAREN_FRAME = /^\s*at\s+(?:[^()]+\s+)?\(([^()\s]+):(\d+):(\d+)\)\s*$/;
4733
+ var BARE_FRAME = /^\s*at\s+(?:async\s+)?([^()\s]+):(\d+):(\d+)\s*$/;
4734
+ var INTERNAL_FRAME_PATTERNS = [
4735
+ /^node:/,
4736
+ /^node:internal\//,
4737
+ /[/\\]node_modules[/\\]@glasstrace[/\\]sdk[/\\]/,
4738
+ /[/\\]packages[/\\]sdk[/\\]src[/\\]capture-error\./,
4739
+ /[/\\]packages[/\\]sdk[/\\]src[/\\]stack-frame\./
4740
+ ];
4741
+ function isInternalFrame(file) {
4742
+ return INTERNAL_FRAME_PATTERNS.some((re) => re.test(file));
4743
+ }
4744
+ function parseTopStackFrame(stack) {
4745
+ if (typeof stack !== "string" || stack.length === 0) return null;
4746
+ let cursor = 0;
4747
+ while (cursor < stack.length) {
4748
+ const newlineAt = stack.indexOf("\n", cursor);
4749
+ const lineEnd = newlineAt === -1 ? stack.length : newlineAt;
4750
+ const line = stack.slice(cursor, lineEnd);
4751
+ cursor = lineEnd + 1;
4752
+ if (!/^\s*at\s/.test(line)) continue;
4753
+ let file;
4754
+ let lineStr;
4755
+ const parenMatch = PAREN_FRAME.exec(line);
4756
+ if (parenMatch) {
4757
+ file = parenMatch[1];
4758
+ lineStr = parenMatch[2];
4759
+ } else {
4760
+ const bareMatch = BARE_FRAME.exec(line);
4761
+ if (bareMatch) {
4762
+ file = bareMatch[1];
4763
+ lineStr = bareMatch[2];
4764
+ }
4765
+ }
4766
+ if (!file || !lineStr) continue;
4767
+ if (isInternalFrame(file)) continue;
4768
+ const lineNum = Number.parseInt(lineStr, 10);
4769
+ if (!Number.isFinite(lineNum) || lineNum <= 0) continue;
4770
+ return { file, line: lineNum };
4771
+ }
4772
+ return null;
4773
+ }
4774
+
4714
4775
  // src/capture-error.ts
4715
4776
  function captureError(error) {
4716
4777
  try {
@@ -4723,6 +4784,11 @@ function captureError(error) {
4723
4784
  attributes["error.type"] = error.constructor.name;
4724
4785
  if (error.stack) {
4725
4786
  attributes["error.stack"] = error.stack;
4787
+ const frame = parseTopStackFrame(error.stack);
4788
+ if (frame) {
4789
+ attributes[GLASSTRACE_ATTRIBUTE_NAMES.SOURCE_FILE] = frame.file;
4790
+ attributes[GLASSTRACE_ATTRIBUTE_NAMES.SOURCE_LINE] = frame.line;
4791
+ }
4726
4792
  }
4727
4793
  }
4728
4794
  span.addEvent("glasstrace.error", attributes);
@@ -4746,4 +4812,4 @@ export {
4746
4812
  withGlasstraceConfig,
4747
4813
  captureError
4748
4814
  };
4749
- //# sourceMappingURL=chunk-CTJO7PUZ.js.map
4815
+ //# sourceMappingURL=chunk-5PFPEA4C.js.map