@glasstrace/sdk 1.3.9 → 1.5.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 (81) hide show
  1. package/README.md +124 -0
  2. package/dist/capture-error-BmQz7xF6.d.cts +455 -0
  3. package/dist/capture-error-CTgSYxek.d.ts +455 -0
  4. package/dist/{chunk-XS5W3SPL.js → chunk-4WI7B5FQ.js} +91 -5
  5. package/dist/chunk-4WI7B5FQ.js.map +1 -0
  6. package/dist/{chunk-JZ475QRH.js → chunk-D3QXU2VM.js} +22 -191
  7. package/dist/chunk-D3QXU2VM.js.map +1 -0
  8. package/dist/{chunk-GYTCZSAV.js → chunk-MFYOQOD7.js} +2 -2
  9. package/dist/{chunk-4WUHMLMM.js → chunk-MMKFFF2L.js} +2 -2
  10. package/dist/{chunk-JH7EGRC5.js → chunk-N3XIVM2U.js} +158 -12
  11. package/dist/chunk-N3XIVM2U.js.map +1 -0
  12. package/dist/{chunk-FKBCEOJ5.js → chunk-Q42BY5BA.js} +2 -2
  13. package/dist/{chunk-DBKG6SRI.js → chunk-QU26IKIJ.js} +2 -2
  14. package/dist/{chunk-ADUD4PEK.js → chunk-TANUWTFO.js} +3 -3
  15. package/dist/{chunk-LJMZXJ45.js → chunk-YLY7AGLC.js} +9 -6
  16. package/dist/chunk-YLY7AGLC.js.map +1 -0
  17. package/dist/chunk-ZBQQXVHD.js +208 -0
  18. package/dist/chunk-ZBQQXVHD.js.map +1 -0
  19. package/dist/cli/init.cjs +218 -35
  20. package/dist/cli/init.cjs.map +1 -1
  21. package/dist/cli/init.js +69 -12
  22. package/dist/cli/init.js.map +1 -1
  23. package/dist/cli/mcp-add.cjs +57 -26
  24. package/dist/cli/mcp-add.cjs.map +1 -1
  25. package/dist/cli/mcp-add.js +12 -9
  26. package/dist/cli/mcp-add.js.map +1 -1
  27. package/dist/cli/status.cjs +33 -3
  28. package/dist/cli/status.cjs.map +1 -1
  29. package/dist/cli/status.js +12 -3
  30. package/dist/cli/status.js.map +1 -1
  31. package/dist/cli/uninit.cjs +27 -3
  32. package/dist/cli/uninit.cjs.map +1 -1
  33. package/dist/cli/uninit.d.cts +10 -2
  34. package/dist/cli/uninit.d.ts +10 -2
  35. package/dist/cli/uninit.js +4 -3
  36. package/dist/cli/upgrade-instructions.cjs +440 -0
  37. package/dist/cli/upgrade-instructions.cjs.map +1 -0
  38. package/dist/cli/upgrade-instructions.d.cts +48 -0
  39. package/dist/cli/upgrade-instructions.d.ts +48 -0
  40. package/dist/cli/upgrade-instructions.js +80 -0
  41. package/dist/cli/upgrade-instructions.js.map +1 -0
  42. package/dist/cli/validate.cjs +12 -1
  43. package/dist/cli/validate.cjs.map +1 -1
  44. package/dist/cli/validate.js +2 -2
  45. package/dist/{edge-entry-BSKA1l_0.d.ts → edge-entry-AWO70gje.d.ts} +1 -1
  46. package/dist/{edge-entry-DyMWa6JK.d.cts → edge-entry-DaeG7D7S.d.cts} +1 -1
  47. package/dist/edge-entry.cjs +43 -2
  48. package/dist/edge-entry.cjs.map +1 -1
  49. package/dist/edge-entry.d.cts +2 -2
  50. package/dist/edge-entry.d.ts +2 -2
  51. package/dist/edge-entry.js +2 -2
  52. package/dist/index.cjs +594 -64
  53. package/dist/index.cjs.map +1 -1
  54. package/dist/{index.d-Bo_Rxund.d.cts → index.d-Dq33YwFT.d.cts} +91 -1
  55. package/dist/{index.d-Bo_Rxund.d.ts → index.d-Dq33YwFT.d.ts} +91 -1
  56. package/dist/index.d.cts +91 -431
  57. package/dist/index.d.ts +91 -431
  58. package/dist/index.js +291 -6
  59. package/dist/index.js.map +1 -1
  60. package/dist/node-entry.cjs +282 -71
  61. package/dist/node-entry.cjs.map +1 -1
  62. package/dist/node-entry.d.cts +3 -3
  63. package/dist/node-entry.d.ts +3 -3
  64. package/dist/node-entry.js +8 -7
  65. package/dist/node-subpath.cjs +12 -1
  66. package/dist/node-subpath.cjs.map +1 -1
  67. package/dist/node-subpath.d.cts +1 -1
  68. package/dist/node-subpath.d.ts +1 -1
  69. package/dist/node-subpath.js +3 -3
  70. package/dist/{source-map-uploader-FSTHCYDR.js → source-map-uploader-PB3M4PPP.js} +3 -3
  71. package/package.json +1 -1
  72. package/dist/chunk-JH7EGRC5.js.map +0 -1
  73. package/dist/chunk-JZ475QRH.js.map +0 -1
  74. package/dist/chunk-LJMZXJ45.js.map +0 -1
  75. package/dist/chunk-XS5W3SPL.js.map +0 -1
  76. /package/dist/{chunk-GYTCZSAV.js.map → chunk-MFYOQOD7.js.map} +0 -0
  77. /package/dist/{chunk-4WUHMLMM.js.map → chunk-MMKFFF2L.js.map} +0 -0
  78. /package/dist/{chunk-FKBCEOJ5.js.map → chunk-Q42BY5BA.js.map} +0 -0
  79. /package/dist/{chunk-DBKG6SRI.js.map → chunk-QU26IKIJ.js.map} +0 -0
  80. /package/dist/{chunk-ADUD4PEK.js.map → chunk-TANUWTFO.js.map} +0 -0
  81. /package/dist/{source-map-uploader-FSTHCYDR.js.map → source-map-uploader-PB3M4PPP.js.map} +0 -0
package/dist/index.cjs CHANGED
@@ -339,10 +339,10 @@ function mergeDefs(...defs) {
339
339
  function cloneDef(schema) {
340
340
  return mergeDefs(schema._zod.def);
341
341
  }
342
- function getElementAtPath(obj, path3) {
343
- if (!path3)
342
+ function getElementAtPath(obj, path4) {
343
+ if (!path4)
344
344
  return obj;
345
- return path3.reduce((acc, key) => acc?.[key], obj);
345
+ return path4.reduce((acc, key) => acc?.[key], obj);
346
346
  }
347
347
  function promiseAllObject(promisesObj) {
348
348
  const keys = Object.keys(promisesObj);
@@ -654,11 +654,11 @@ function aborted(x, startIndex = 0) {
654
654
  }
655
655
  return false;
656
656
  }
657
- function prefixIssues(path3, issues) {
657
+ function prefixIssues(path4, issues) {
658
658
  return issues.map((iss) => {
659
659
  var _a2;
660
660
  (_a2 = iss).path ?? (_a2.path = []);
661
- iss.path.unshift(path3);
661
+ iss.path.unshift(path4);
662
662
  return iss;
663
663
  });
664
664
  }
@@ -901,7 +901,7 @@ function formatError(error48, mapper = (issue2) => issue2.message) {
901
901
  }
902
902
  function treeifyError(error48, mapper = (issue2) => issue2.message) {
903
903
  const result = { errors: [] };
904
- const processError = (error49, path3 = []) => {
904
+ const processError = (error49, path4 = []) => {
905
905
  var _a2, _b;
906
906
  for (const issue2 of error49.issues) {
907
907
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -911,7 +911,7 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
911
911
  } else if (issue2.code === "invalid_element") {
912
912
  processError({ issues: issue2.issues }, issue2.path);
913
913
  } else {
914
- const fullpath = [...path3, ...issue2.path];
914
+ const fullpath = [...path4, ...issue2.path];
915
915
  if (fullpath.length === 0) {
916
916
  result.errors.push(mapper(issue2));
917
917
  continue;
@@ -943,8 +943,8 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
943
943
  }
944
944
  function toDotPath(_path) {
945
945
  const segs = [];
946
- const path3 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
947
- for (const seg of path3) {
946
+ const path4 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
947
+ for (const seg of path4) {
948
948
  if (typeof seg === "number")
949
949
  segs.push(`[${seg}]`);
950
950
  else if (typeof seg === "symbol")
@@ -13708,13 +13708,13 @@ function resolveRef(ref, ctx) {
13708
13708
  if (!ref.startsWith("#")) {
13709
13709
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
13710
13710
  }
13711
- const path3 = ref.slice(1).split("/").filter(Boolean);
13712
- if (path3.length === 0) {
13711
+ const path4 = ref.slice(1).split("/").filter(Boolean);
13712
+ if (path4.length === 0) {
13713
13713
  return ctx.rootSchema;
13714
13714
  }
13715
13715
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
13716
- if (path3[0] === defsKey) {
13717
- const key = path3[1];
13716
+ if (path4[0] === defsKey) {
13717
+ const key = path4[1];
13718
13718
  if (!key || !ctx.defs[key]) {
13719
13719
  throw new Error(`Reference not found: ${ref}`);
13720
13720
  }
@@ -14563,7 +14563,7 @@ function deriveSessionId(apiKey, origin, date5, windowIndex) {
14563
14563
  const digest = sha256Hex(input).slice(0, 16);
14564
14564
  return SessionIdSchema.parse(digest);
14565
14565
  }
14566
- var DevApiKeySchema, AnonApiKeySchema, SessionIdSchema, BuildHashSchema, SdkDiagnosticCodeSchema, CaptureConfigSchema, SdkCachedConfigSchema, GlasstraceOptionsSchema, GlasstraceEnvVarsSchema, GLASSTRACE_ATTRIBUTE_NAMES, DEFAULT_CAPTURE_CONFIG, MAX_SOURCE_MAP_FILE_PATH_LENGTH, MAX_SOURCE_MAP_FILE_SIZE, MAX_SOURCE_MAP_FILE_COUNT, MAX_PRESIGNED_CLIENT_TOKEN_LENGTH, MAX_PRESIGNED_PATHNAME_LENGTH, ImportGraphPayloadSchema, SdkHealthReportSchema, TierLimitsSchema, SdkInitResponseSchema, DiscoveryResponseSchema, SourceMapUploadResponseSchema, PresignedUploadRequestSchema, PresignedUploadResponseSchema, SourceMapManifestRequestSchema, SourceMapManifestResponseSchema, K;
14566
+ var DevApiKeySchema, AnonApiKeySchema, SessionIdSchema, BuildHashSchema, SdkDiagnosticCodeSchema, CaptureConfigSchema, SdkCachedConfigSchema, GlasstraceOptionsSchema, GlasstraceEnvVarsSchema, GLASSTRACE_ATTRIBUTE_NAMES, DEFAULT_CAPTURE_CONFIG, MAX_SOURCE_MAP_FILE_PATH_LENGTH, MAX_SOURCE_MAP_FILE_SIZE, MAX_SOURCE_MAP_FILE_COUNT, MAX_PRESIGNED_CLIENT_TOKEN_LENGTH, MAX_PRESIGNED_PATHNAME_LENGTH, ImportGraphPayloadSchema, SdkHealthReportSchema, TierLimitsSchema, SdkInitResponseSchema, DiscoveryResponseSchema, SourceMapUploadResponseSchema, PresignedUploadRequestSchema, PresignedUploadResponseSchema, SourceMapManifestRequestSchema, SourceMapManifestResponseSchema, K, SIDE_EFFECT_OPERATION_KINDS, SIDE_EFFECT_SEMANTIC_FIELD_KEYS, SIDE_EFFECT_OMISSION_REASONS, SIDE_EFFECT_OPERATION_STATUSES, SIDE_EFFECT_OPERATION_PHASES;
14567
14567
  var init_dist = __esm({
14568
14568
  "../protocol/dist/index.js"() {
14569
14569
  "use strict";
@@ -14591,7 +14591,18 @@ var init_dist = __esm({
14591
14591
  fullConsoleOutput: external_exports.boolean(),
14592
14592
  importGraph: external_exports.boolean(),
14593
14593
  consoleErrors: external_exports.boolean().optional().default(false),
14594
- errorResponseBodies: external_exports.boolean().optional().default(false)
14594
+ errorResponseBodies: external_exports.boolean().optional().default(false),
14595
+ /**
14596
+ * Account opt-in for side-effect evidence emission (SDK-049).
14597
+ *
14598
+ * When `false` (default), `recordSideEffect()` is a silent no-op:
14599
+ * no allowlist evaluation runs and no `glasstrace.side_effect.*`
14600
+ * attribute reaches the wire. When `true`, allowlisted side-effect
14601
+ * metadata is attached to the active OTel span subject to the
14602
+ * client-side allowlist enforcement layered with the product's
14603
+ * storage-time filter as defense-in-depth.
14604
+ */
14605
+ sideEffectEvidence: external_exports.boolean().optional().default(false)
14595
14606
  });
14596
14607
  SdkCachedConfigSchema = external_exports.object({
14597
14608
  response: external_exports.record(external_exports.string(), external_exports.unknown()),
@@ -14651,7 +14662,37 @@ var init_dist = __esm({
14651
14662
  TRIGGER_TYPE: "glasstrace.trigger.type",
14652
14663
  ELEMENT_FINGERPRINT: "glasstrace.element.fingerprint",
14653
14664
  ELEMENT_CONFIDENCE: "glasstrace.element.confidence",
14654
- TAB_ID: "glasstrace.tab.id"
14665
+ TAB_ID: "glasstrace.tab.id",
14666
+ // Side-effect evidence (SDK-049 / SCHEMA-036).
14667
+ // Top-level operation attributes attached to the active span when a
14668
+ // side-effect is recorded via `recordSideEffect()`. The wire-string
14669
+ // set aligns verbatim with the product-side filter in
14670
+ // `packages/ingestion/src/services/trace-writer.ts`.
14671
+ SIDE_EFFECT_KIND: "glasstrace.side_effect.kind",
14672
+ SIDE_EFFECT_OPERATION: "glasstrace.side_effect.operation",
14673
+ SIDE_EFFECT_STATUS: "glasstrace.side_effect.status",
14674
+ SIDE_EFFECT_PHASE: "glasstrace.side_effect.phase",
14675
+ // Allowlisted semantic field attributes — one per allowlisted key.
14676
+ // Wire keys are camelCase to match the SCHEMA-036 enum members
14677
+ // exactly; the SDK constant names are SCREAMING_SNAKE per the rest
14678
+ // of GLASSTRACE_ATTRIBUTE_NAMES.
14679
+ SIDE_EFFECT_FIELD_TEMPLATE_KEY: "glasstrace.side_effect.field.templateKey",
14680
+ SIDE_EFFECT_FIELD_PROVIDER_OPERATION: "glasstrace.side_effect.field.providerOperation",
14681
+ SIDE_EFFECT_FIELD_ROLE: "glasstrace.side_effect.field.role",
14682
+ SIDE_EFFECT_FIELD_LOCALE: "glasstrace.side_effect.field.locale",
14683
+ SIDE_EFFECT_FIELD_TIMEZONE: "glasstrace.side_effect.field.timezone",
14684
+ SIDE_EFFECT_FIELD_STATUS: "glasstrace.side_effect.field.status",
14685
+ SIDE_EFFECT_FIELD_PHASE: "glasstrace.side_effect.field.phase",
14686
+ // Omission reason attributes — one per allowlisted reason. The
14687
+ // attribute value carries an integer count; the rejected value is
14688
+ // never echoed.
14689
+ SIDE_EFFECT_OMITTED_PII: "glasstrace.side_effect.omitted.pii",
14690
+ SIDE_EFFECT_OMITTED_SECRET: "glasstrace.side_effect.omitted.secret",
14691
+ SIDE_EFFECT_OMITTED_RAW_PAYLOAD: "glasstrace.side_effect.omitted.raw_payload",
14692
+ SIDE_EFFECT_OMITTED_UNSUPPORTED_KEY: "glasstrace.side_effect.omitted.unsupported_key",
14693
+ SIDE_EFFECT_OMITTED_VALUE_TOO_LONG: "glasstrace.side_effect.omitted.value_too_long",
14694
+ SIDE_EFFECT_OMITTED_NOT_EMITTED: "glasstrace.side_effect.omitted.not_emitted",
14695
+ SIDE_EFFECT_OMITTED_CAPTURE_DISABLED: "glasstrace.side_effect.omitted.capture_disabled"
14655
14696
  };
14656
14697
  DEFAULT_CAPTURE_CONFIG = {
14657
14698
  requestBodies: false,
@@ -14660,7 +14701,8 @@ var init_dist = __esm({
14660
14701
  fullConsoleOutput: false,
14661
14702
  importGraph: false,
14662
14703
  consoleErrors: false,
14663
- errorResponseBodies: false
14704
+ errorResponseBodies: false,
14705
+ sideEffectEvidence: false
14664
14706
  };
14665
14707
  MAX_SOURCE_MAP_FILE_PATH_LENGTH = 512;
14666
14708
  MAX_SOURCE_MAP_FILE_SIZE = 50 * 1024 * 1024;
@@ -14849,6 +14891,45 @@ var init_dist = __esm({
14849
14891
  3204031479,
14850
14892
  3329325298
14851
14893
  ]);
14894
+ SIDE_EFFECT_OPERATION_KINDS = [
14895
+ "email",
14896
+ "calendar_link",
14897
+ "webhook",
14898
+ "external_api",
14899
+ "queue",
14900
+ "after_callback"
14901
+ ];
14902
+ SIDE_EFFECT_SEMANTIC_FIELD_KEYS = [
14903
+ "templateKey",
14904
+ "providerOperation",
14905
+ "role",
14906
+ "locale",
14907
+ "timezone",
14908
+ "status",
14909
+ "phase"
14910
+ ];
14911
+ SIDE_EFFECT_OMISSION_REASONS = [
14912
+ "pii",
14913
+ "secret",
14914
+ "raw_payload",
14915
+ "unsupported_key",
14916
+ "value_too_long",
14917
+ "not_emitted",
14918
+ "capture_disabled"
14919
+ ];
14920
+ SIDE_EFFECT_OPERATION_STATUSES = [
14921
+ "scheduled",
14922
+ "started",
14923
+ "succeeded",
14924
+ "failed",
14925
+ "unknown"
14926
+ ];
14927
+ SIDE_EFFECT_OPERATION_PHASES = [
14928
+ "request",
14929
+ "post_response",
14930
+ "background",
14931
+ "unknown"
14932
+ ];
14852
14933
  }
14853
14934
  });
14854
14935
 
@@ -16440,10 +16521,10 @@ function sanitize(input) {
16440
16521
  }
16441
16522
  function markerFileExists() {
16442
16523
  try {
16443
- const fs3 = require("node:fs");
16444
- const path3 = require("node:path");
16445
- const markerPath = path3.join(process.cwd(), ".glasstrace", "mcp-connected");
16446
- return fs3.existsSync(markerPath);
16524
+ const fs4 = require("node:fs");
16525
+ const path4 = require("node:path");
16526
+ const markerPath = path4.join(process.cwd(), ".glasstrace", "mcp-connected");
16527
+ return fs4.existsSync(markerPath);
16447
16528
  } catch {
16448
16529
  return false;
16449
16530
  }
@@ -16592,7 +16673,7 @@ __export(source_map_uploader_exports, {
16592
16673
  uploadToBlob: () => uploadToBlob
16593
16674
  });
16594
16675
  async function discoverSourceMapFiles(buildDir) {
16595
- const resolvedDir = path2.resolve(buildDir);
16676
+ const resolvedDir = path3.resolve(buildDir);
16596
16677
  const results = [];
16597
16678
  try {
16598
16679
  await walkDirMetadata(resolvedDir, resolvedDir, results);
@@ -16613,18 +16694,18 @@ async function discoverSourceMapFiles(buildDir) {
16613
16694
  async function walkDirMetadata(baseDir, currentDir, results) {
16614
16695
  let entries;
16615
16696
  try {
16616
- entries = await fs2.readdir(currentDir, { withFileTypes: true });
16697
+ entries = await fs3.readdir(currentDir, { withFileTypes: true });
16617
16698
  } catch {
16618
16699
  return;
16619
16700
  }
16620
16701
  for (const entry of entries) {
16621
- const fullPath = path2.join(currentDir, entry.name);
16702
+ const fullPath = path3.join(currentDir, entry.name);
16622
16703
  if (entry.isDirectory()) {
16623
16704
  await walkDirMetadata(baseDir, fullPath, results);
16624
16705
  } else if (entry.isFile() && entry.name.endsWith(".map")) {
16625
16706
  try {
16626
- const stat2 = await fs2.stat(fullPath);
16627
- const relativePath = path2.relative(baseDir, fullPath).replace(/\\/g, "/");
16707
+ const stat2 = await fs3.stat(fullPath);
16708
+ const relativePath = path3.relative(baseDir, fullPath).replace(/\\/g, "/");
16628
16709
  const compiledPath = relativePath.replace(/\.map$/, "");
16629
16710
  results.push({
16630
16711
  filePath: compiledPath,
@@ -16637,7 +16718,7 @@ async function walkDirMetadata(baseDir, currentDir, results) {
16637
16718
  }
16638
16719
  }
16639
16720
  async function readSourceMapContent(absolutePath) {
16640
- return fs2.readFile(absolutePath, "utf-8");
16721
+ return fs3.readFile(absolutePath, "utf-8");
16641
16722
  }
16642
16723
  async function collectSourceMaps(buildDir) {
16643
16724
  const fileInfos = await discoverSourceMapFiles(buildDir);
@@ -16892,12 +16973,12 @@ async function uploadSourceMapsAuto(apiKey, endpoint, buildHash, maps, options)
16892
16973
  );
16893
16974
  return uploadSourceMaps(apiKey, endpoint, buildHash, maps);
16894
16975
  }
16895
- var fs2, path2, crypto2, import_node_child_process, LARGE_FILE_WARNING_BYTES, PRESIGNED_THRESHOLD_BYTES, _blobClientLoader;
16976
+ var fs3, path3, crypto2, import_node_child_process, LARGE_FILE_WARNING_BYTES, PRESIGNED_THRESHOLD_BYTES, _blobClientLoader;
16896
16977
  var init_source_map_uploader = __esm({
16897
16978
  "src/source-map-uploader.ts"() {
16898
16979
  "use strict";
16899
- fs2 = __toESM(require("node:fs/promises"), 1);
16900
- path2 = __toESM(require("node:path"), 1);
16980
+ fs3 = __toESM(require("node:fs/promises"), 1);
16981
+ path3 = __toESM(require("node:path"), 1);
16901
16982
  crypto2 = __toESM(require("node:crypto"), 1);
16902
16983
  import_node_child_process = require("node:child_process");
16903
16984
  init_console_capture();
@@ -16934,6 +17015,7 @@ __export(src_exports, {
16934
17015
  performInit: () => performInit,
16935
17016
  readAnonKey: () => readAnonKey,
16936
17017
  readEnvVars: () => readEnvVars,
17018
+ recordSideEffect: () => recordSideEffect,
16937
17019
  registerGlasstrace: () => registerGlasstrace,
16938
17020
  resolveConfig: () => resolveConfig,
16939
17021
  saveCachedConfig: () => saveCachedConfig,
@@ -17052,11 +17134,11 @@ var fsPathCache;
17052
17134
  async function loadFsPath() {
17053
17135
  if (fsPathCache !== void 0) return fsPathCache;
17054
17136
  try {
17055
- const [fs3, path3] = await Promise.all([
17137
+ const [fs4, path4] = await Promise.all([
17056
17138
  import("node:fs/promises"),
17057
17139
  import("node:path")
17058
17140
  ]);
17059
- fsPathCache = { fs: fs3, path: path3 };
17141
+ fsPathCache = { fs: fs4, path: path4 };
17060
17142
  return fsPathCache;
17061
17143
  } catch {
17062
17144
  fsPathCache = null;
@@ -17577,35 +17659,35 @@ function atomicWriteFileSync(targetPath, payload, options = {}) {
17577
17659
  function atomicWriteFileSyncWithTmp(targetPath, tmpPath, payload, options = {}) {
17578
17660
  const mode = options.mode ?? 384;
17579
17661
  const encoding = options.encoding ?? "utf-8";
17580
- const fs3 = loadFsSync();
17662
+ const fs4 = loadFsSync();
17581
17663
  let fd = null;
17582
17664
  try {
17583
17665
  if (typeof payload === "string") {
17584
- fs3.writeFileSync(tmpPath, payload, { encoding, mode });
17666
+ fs4.writeFileSync(tmpPath, payload, { encoding, mode });
17585
17667
  } else {
17586
- fs3.writeFileSync(tmpPath, payload, { mode });
17668
+ fs4.writeFileSync(tmpPath, payload, { mode });
17587
17669
  }
17588
- fs3.chmodSync(tmpPath, mode);
17589
- fd = fs3.openSync(tmpPath, "r");
17590
- fs3.fsyncSync(fd);
17591
- fs3.closeSync(fd);
17670
+ fs4.chmodSync(tmpPath, mode);
17671
+ fd = fs4.openSync(tmpPath, "r");
17672
+ fs4.fsyncSync(fd);
17673
+ fs4.closeSync(fd);
17592
17674
  fd = null;
17593
- fs3.renameSync(tmpPath, targetPath);
17675
+ fs4.renameSync(tmpPath, targetPath);
17594
17676
  } catch (err) {
17595
17677
  if (fd !== null) {
17596
17678
  try {
17597
- fs3.closeSync(fd);
17679
+ fs4.closeSync(fd);
17598
17680
  } catch {
17599
17681
  }
17600
17682
  }
17601
- removeTmpResidueSync(fs3, tmpPath);
17683
+ removeTmpResidueSync(fs4, tmpPath);
17602
17684
  throw err;
17603
17685
  }
17604
- fsyncParentDirSyncWithFs(targetPath, fs3);
17686
+ fsyncParentDirSyncWithFs(targetPath, fs4);
17605
17687
  }
17606
- function removeTmpResidueSync(fs3, tmpPath) {
17688
+ function removeTmpResidueSync(fs4, tmpPath) {
17607
17689
  try {
17608
- fs3.unlinkSync(tmpPath);
17690
+ fs4.unlinkSync(tmpPath);
17609
17691
  return;
17610
17692
  } catch (err) {
17611
17693
  const code = errnoCodeOf(err);
@@ -17614,16 +17696,16 @@ function removeTmpResidueSync(fs3, tmpPath) {
17614
17696
  }
17615
17697
  }
17616
17698
  try {
17617
- fs3.rmdirSync(tmpPath);
17699
+ fs4.rmdirSync(tmpPath);
17618
17700
  } catch {
17619
17701
  }
17620
17702
  }
17621
- function fsyncParentDirSyncWithFs(targetPath, fs3) {
17703
+ function fsyncParentDirSyncWithFs(targetPath, fs4) {
17622
17704
  const parent = parentDir(targetPath);
17623
17705
  let fd = null;
17624
17706
  try {
17625
- fd = fs3.openSync(parent, "r");
17626
- fs3.fsyncSync(fd);
17707
+ fd = fs4.openSync(parent, "r");
17708
+ fs4.fsyncSync(fd);
17627
17709
  } catch (err) {
17628
17710
  const code = errnoCodeOf(err);
17629
17711
  if (code !== void 0 && PARENT_FSYNC_SWALLOWED_CODES.has(code)) {
@@ -17633,7 +17715,7 @@ function fsyncParentDirSyncWithFs(targetPath, fs3) {
17633
17715
  } finally {
17634
17716
  if (fd !== null) {
17635
17717
  try {
17636
- fs3.closeSync(fd);
17718
+ fs4.closeSync(fd);
17637
17719
  } catch {
17638
17720
  }
17639
17721
  }
@@ -17654,11 +17736,11 @@ var fsPathCache2;
17654
17736
  async function loadFsPath2() {
17655
17737
  if (fsPathCache2 !== void 0) return fsPathCache2;
17656
17738
  try {
17657
- const [fs3, path3] = await Promise.all([
17739
+ const [fs4, path4] = await Promise.all([
17658
17740
  import("node:fs/promises"),
17659
17741
  import("node:path")
17660
17742
  ]);
17661
- fsPathCache2 = { fs: fs3, path: path3 };
17743
+ fsPathCache2 = { fs: fs4, path: path4 };
17662
17744
  return fsPathCache2;
17663
17745
  } catch {
17664
17746
  fsPathCache2 = null;
@@ -17944,11 +18026,11 @@ var fsPathAsyncCache;
17944
18026
  async function loadFsPathAsync() {
17945
18027
  if (fsPathAsyncCache !== void 0) return fsPathAsyncCache;
17946
18028
  try {
17947
- const [fs3, path3] = await Promise.all([
18029
+ const [fs4, path4] = await Promise.all([
17948
18030
  import("node:fs/promises"),
17949
18031
  import("node:path")
17950
18032
  ]);
17951
- fsPathAsyncCache = { fs: fs3, path: path3 };
18033
+ fsPathAsyncCache = { fs: fs4, path: path4 };
17952
18034
  return fsPathAsyncCache;
17953
18035
  } catch {
17954
18036
  fsPathAsyncCache = null;
@@ -17957,9 +18039,9 @@ async function loadFsPathAsync() {
17957
18039
  }
17958
18040
  function loadFsSyncOrNull() {
17959
18041
  try {
17960
- const fs3 = require("node:fs");
17961
- const path3 = require("node:path");
17962
- return { readFileSync: fs3.readFileSync, join: path3.join };
18042
+ const fs4 = require("node:fs");
18043
+ const path4 = require("node:path");
18044
+ return { readFileSync: fs4.readFileSync, join: path4.join };
17963
18045
  } catch {
17964
18046
  return null;
17965
18047
  }
@@ -20427,7 +20509,7 @@ function appendRootPathToUrlIfNeeded(url2) {
20427
20509
  return void 0;
20428
20510
  }
20429
20511
  }
20430
- function appendResourcePathToUrl(url2, path3) {
20512
+ function appendResourcePathToUrl(url2, path4) {
20431
20513
  try {
20432
20514
  new URL(url2);
20433
20515
  } catch {
@@ -20437,11 +20519,11 @@ function appendResourcePathToUrl(url2, path3) {
20437
20519
  if (!url2.endsWith("/")) {
20438
20520
  url2 = url2 + "/";
20439
20521
  }
20440
- url2 += path3;
20522
+ url2 += path4;
20441
20523
  try {
20442
20524
  new URL(url2);
20443
20525
  } catch {
20444
- diag2.warn(`Configuration: Provided URL appended with '${path3}' is not a valid URL, using 'undefined' instead of '${url2}'`);
20526
+ diag2.warn(`Configuration: Provided URL appended with '${path4}' is not a valid URL, using 'undefined' instead of '${url2}'`);
20445
20527
  return void 0;
20446
20528
  }
20447
20529
  return url2;
@@ -22647,6 +22729,171 @@ function writeStateNow() {
22647
22729
  }
22648
22730
  }
22649
22731
 
22732
+ // src/agent-detection/upgrade-notice.ts
22733
+ var fs2 = __toESM(require("node:fs"), 1);
22734
+ var path2 = __toESM(require("node:path"), 1);
22735
+
22736
+ // src/agent-detection/inject.ts
22737
+ var HTML_START_RE = /^<!--\s*glasstrace:mcp:start(?:\s+v=([^\s>]+))?\s*-->$/;
22738
+ var HTML_END = "<!-- glasstrace:mcp:end -->";
22739
+ var HASH_START_RE = /^#\s*glasstrace:mcp:start(?:\s+v=(\S+))?$/;
22740
+ var HASH_END = "# glasstrace:mcp:end";
22741
+ function parseStartMarkerLine(line) {
22742
+ const trimmed = line.trim();
22743
+ const html = HTML_START_RE.exec(trimmed);
22744
+ if (html !== null) {
22745
+ return { kind: "html", stamp: html[1] ?? null };
22746
+ }
22747
+ const hash2 = HASH_START_RE.exec(trimmed);
22748
+ if (hash2 !== null) {
22749
+ return { kind: "hash", stamp: hash2[1] ?? null };
22750
+ }
22751
+ return null;
22752
+ }
22753
+ function isEndMarker(line) {
22754
+ const trimmed = line.trim();
22755
+ return trimmed === HTML_END || trimmed === HASH_END;
22756
+ }
22757
+ function isEndMarkerLine(line) {
22758
+ return isEndMarker(line);
22759
+ }
22760
+
22761
+ // src/agent-detection/upgrade-notice.ts
22762
+ var warningEmitted = false;
22763
+ var AGENT_INSTRUCTION_FILES = [
22764
+ "CLAUDE.md",
22765
+ "codex.md",
22766
+ ".cursorrules"
22767
+ ];
22768
+ function parseSemver(input) {
22769
+ const plusIdx = input.indexOf("+");
22770
+ const core = plusIdx === -1 ? input : input.slice(0, plusIdx);
22771
+ const m = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/.exec(core);
22772
+ if (m === null) return null;
22773
+ return {
22774
+ major: Number(m[1]),
22775
+ minor: Number(m[2]),
22776
+ patch: Number(m[3]),
22777
+ prerelease: m[4] ?? null
22778
+ };
22779
+ }
22780
+ function comparePrerelease(a, b) {
22781
+ const ap = a.split(".");
22782
+ const bp = b.split(".");
22783
+ const len = Math.min(ap.length, bp.length);
22784
+ for (let i = 0; i < len; i++) {
22785
+ const x = ap[i];
22786
+ const y = bp[i];
22787
+ const xNumeric = /^\d+$/.test(x);
22788
+ const yNumeric = /^\d+$/.test(y);
22789
+ if (xNumeric && yNumeric) {
22790
+ const xv = Number(x);
22791
+ const yv = Number(y);
22792
+ if (xv !== yv) return xv < yv ? -1 : 1;
22793
+ } else if (xNumeric) {
22794
+ return -1;
22795
+ } else if (yNumeric) {
22796
+ return 1;
22797
+ } else if (x !== y) {
22798
+ return x < y ? -1 : 1;
22799
+ }
22800
+ }
22801
+ return ap.length - bp.length;
22802
+ }
22803
+ function compareSemver(a, b) {
22804
+ const pa = parseSemver(a);
22805
+ const pb = parseSemver(b);
22806
+ if (pa === null || pb === null) return null;
22807
+ if (pa.major !== pb.major) return pa.major - pb.major;
22808
+ if (pa.minor !== pb.minor) return pa.minor - pb.minor;
22809
+ if (pa.patch !== pb.patch) return pa.patch - pb.patch;
22810
+ if (pa.prerelease === null && pb.prerelease === null) return 0;
22811
+ if (pa.prerelease === null) return 1;
22812
+ if (pb.prerelease === null) return -1;
22813
+ return comparePrerelease(pa.prerelease, pb.prerelease);
22814
+ }
22815
+ function isOptedOut() {
22816
+ const raw = process.env.GLASSTRACE_DISABLE_UPGRADE_NOTICE;
22817
+ if (typeof raw !== "string") return false;
22818
+ const trimmed = raw.trim().toLowerCase();
22819
+ return trimmed === "1" || trimmed === "true" || trimmed === "yes";
22820
+ }
22821
+ function isQuietCiContext() {
22822
+ const stderrIsTty = process.stderr.isTTY === true;
22823
+ if (stderrIsTty) return false;
22824
+ return process.env.CI === "true";
22825
+ }
22826
+ var MAX_AGENT_FILE_BYTES = 5 * 1024 * 1024;
22827
+ function inspectFile(filePath, runningSdkVersion) {
22828
+ let content;
22829
+ try {
22830
+ const stat2 = fs2.statSync(filePath);
22831
+ if (!stat2.isFile()) return "absent";
22832
+ if (stat2.size > MAX_AGENT_FILE_BYTES) return "absent";
22833
+ content = fs2.readFileSync(filePath, "utf-8");
22834
+ } catch {
22835
+ return "absent";
22836
+ }
22837
+ const lines = content.split("\n");
22838
+ let lastStart = null;
22839
+ let foundEnd = false;
22840
+ for (const line of lines) {
22841
+ const parsed = parseStartMarkerLine(line);
22842
+ if (parsed !== null) {
22843
+ lastStart = parsed;
22844
+ continue;
22845
+ }
22846
+ if (lastStart !== null && isEndMarkerLine(line)) {
22847
+ foundEnd = true;
22848
+ break;
22849
+ }
22850
+ }
22851
+ if (lastStart === null || !foundEnd) {
22852
+ return "no-section";
22853
+ }
22854
+ if (lastStart.stamp === null) {
22855
+ return "no-stamp";
22856
+ }
22857
+ const cmp = compareSemver(lastStart.stamp, runningSdkVersion);
22858
+ if (cmp === null) {
22859
+ return "unknown-stamp";
22860
+ }
22861
+ return cmp < 0 ? "stale" : "current";
22862
+ }
22863
+ function maybeWarnStaleAgentInstructions(options) {
22864
+ try {
22865
+ if (warningEmitted) return;
22866
+ if (typeof process === "undefined" || typeof process.versions?.node !== "string" || typeof process.env !== "object" || process.env === null) {
22867
+ return;
22868
+ }
22869
+ if (isOptedOut()) return;
22870
+ if (isQuietCiContext()) return;
22871
+ if (parseSemver(options.sdkVersion) === null) return;
22872
+ const staleFiles = [];
22873
+ for (const fileName of AGENT_INSTRUCTION_FILES) {
22874
+ const fullPath = path2.join(options.projectRoot, fileName);
22875
+ const state = inspectFile(fullPath, options.sdkVersion);
22876
+ if (state === "stale") {
22877
+ staleFiles.push(fileName);
22878
+ }
22879
+ }
22880
+ if (staleFiles.length === 0) return;
22881
+ const fileList = staleFiles.join(", ");
22882
+ const message = `[glasstrace] Glasstrace managed MCP section in ${fileList} was rendered by an older @glasstrace/sdk; run \`npx glasstrace upgrade-instructions\` to refresh (silence with GLASSTRACE_DISABLE_UPGRADE_NOTICE=1).
22883
+ `;
22884
+ warningEmitted = true;
22885
+ if (options.stderrWrite !== void 0) {
22886
+ options.stderrWrite(message);
22887
+ return;
22888
+ }
22889
+ try {
22890
+ process.stderr.write(message);
22891
+ } catch {
22892
+ }
22893
+ } catch {
22894
+ }
22895
+ }
22896
+
22650
22897
  // src/register.ts
22651
22898
  function maskKey(key) {
22652
22899
  if (key.length <= 12) return key.slice(0, 4) + "...";
@@ -22675,9 +22922,13 @@ function registerGlasstrace(options) {
22675
22922
  return;
22676
22923
  }
22677
22924
  setCoreState(CoreState.REGISTERING);
22925
+ maybeWarnStaleAgentInstructions({
22926
+ projectRoot: process.cwd(),
22927
+ sdkVersion: "1.5.0"
22928
+ });
22678
22929
  startRuntimeStateWriter({
22679
22930
  projectRoot: process.cwd(),
22680
- sdkVersion: "1.3.9"
22931
+ sdkVersion: "1.5.0"
22681
22932
  });
22682
22933
  const config2 = resolveConfig(options);
22683
22934
  if (config2.verbose) {
@@ -22844,8 +23095,8 @@ async function backgroundInit(config2, anonKeyForInit, generation) {
22844
23095
  if (config2.verbose) {
22845
23096
  console.info("[glasstrace] Background init firing.");
22846
23097
  }
22847
- const healthReport = collectHealthReport("1.3.9");
22848
- const initResult = await performInit(config2, anonKeyForInit, "1.3.9", healthReport);
23098
+ const healthReport = collectHealthReport("1.5.0");
23099
+ const initResult = await performInit(config2, anonKeyForInit, "1.5.0", healthReport);
22849
23100
  if (generation !== registrationGeneration) return;
22850
23101
  const currentState = getCoreState();
22851
23102
  if (currentState === CoreState.SHUTTING_DOWN || currentState === CoreState.SHUTDOWN) {
@@ -22868,7 +23119,7 @@ async function backgroundInit(config2, anonKeyForInit, generation) {
22868
23119
  }
22869
23120
  maybeInstallConsoleCapture();
22870
23121
  if (didLastInitSucceed()) {
22871
- startHeartbeat(config2, anonKeyForInit, "1.3.9", generation, (newApiKey, accountId) => {
23122
+ startHeartbeat(config2, anonKeyForInit, "1.5.0", generation, (newApiKey, accountId) => {
22872
23123
  setAuthState(AuthState.CLAIMING);
22873
23124
  emitLifecycleEvent("auth:claim_started", { accountId });
22874
23125
  setResolvedApiKey(newApiKey);
@@ -23160,6 +23411,284 @@ function firstToken(value) {
23160
23411
  }
23161
23412
  return void 0;
23162
23413
  }
23414
+
23415
+ // src/side-effect/allowlist.ts
23416
+ init_dist();
23417
+ var MAX_SIDE_EFFECT_OPERATION_LABEL_LENGTH = 96;
23418
+ var MAX_SIDE_EFFECT_FIELD_VALUE_LENGTH = 80;
23419
+ var MAX_SIDE_EFFECT_OPERATIONS_PER_SPAN = 5;
23420
+ var OPERATION_KIND_SET = new Set(
23421
+ SIDE_EFFECT_OPERATION_KINDS
23422
+ );
23423
+ var SEMANTIC_FIELD_KEY_SET = new Set(
23424
+ SIDE_EFFECT_SEMANTIC_FIELD_KEYS
23425
+ );
23426
+ var OPERATION_STATUS_SET = new Set(
23427
+ SIDE_EFFECT_OPERATION_STATUSES
23428
+ );
23429
+ var OPERATION_PHASE_SET = new Set(
23430
+ SIDE_EFFECT_OPERATION_PHASES
23431
+ );
23432
+ var OMISSION_REASON_SET = new Set(
23433
+ SIDE_EFFECT_OMISSION_REASONS
23434
+ );
23435
+ var TOKEN_REGEX = /^[A-Za-z0-9][A-Za-z0-9_.:-]*$/;
23436
+ var LOCALE_REGEX = /^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8}){0,3}$/;
23437
+ var TIMEZONE_REGEX = /^(?:UTC|GMT|[A-Za-z][A-Za-z0-9_+-]*(?:\/[A-Za-z0-9_+-]+){1,3})$/;
23438
+ var URL_SCHEME = /:\/\//;
23439
+ var URL_SCHEME_RELATIVE = /^\/\//;
23440
+ var EMAIL_LIKE = /[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/i;
23441
+ var QUERY_LIKE = /\?/;
23442
+ var FRAGMENT_LIKE = /#/;
23443
+ var HEADER_LIKE = /\b(authorization|set-cookie|cookie)\b\s*[:=]/i;
23444
+ var HEADER_TOKEN_LIKE = /\b(authorization|set-cookie|cookie)\b\s+\S+=/i;
23445
+ var BEARER_LIKE = /bearer\s+\S+/i;
23446
+ var TOKEN_KV_LIKE = /["']?(password|passwd|token|api[_-]?key|secret|client_secret)["']?\s*[:=]/i;
23447
+ var PROSE_LIKE = /[\r\n\t]|\s{2,}/;
23448
+ var UUID_LIKE = /[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/i;
23449
+ var GT_KEY_LIKE = /gt_(dev|anon|live)_[A-Za-z0-9_-]+/;
23450
+ function detectUnsafePattern(value) {
23451
+ if (value.trim() !== value) return "raw_payload";
23452
+ if (PROSE_LIKE.test(value)) return "raw_payload";
23453
+ if (URL_SCHEME.test(value)) return "raw_payload";
23454
+ if (URL_SCHEME_RELATIVE.test(value)) return "raw_payload";
23455
+ if (QUERY_LIKE.test(value)) return "raw_payload";
23456
+ if (FRAGMENT_LIKE.test(value)) return "raw_payload";
23457
+ if (BEARER_LIKE.test(value)) return "secret";
23458
+ if (HEADER_TOKEN_LIKE.test(value)) return "secret";
23459
+ if (TOKEN_KV_LIKE.test(value)) return "secret";
23460
+ if (HEADER_LIKE.test(value)) return "secret";
23461
+ if (UUID_LIKE.test(value)) return "secret";
23462
+ if (GT_KEY_LIKE.test(value)) return "secret";
23463
+ if (EMAIL_LIKE.test(value)) return "pii";
23464
+ return null;
23465
+ }
23466
+ function passesFieldValidator(key, value) {
23467
+ if (key === "locale") return LOCALE_REGEX.test(value);
23468
+ if (key === "timezone") return TIMEZONE_REGEX.test(value);
23469
+ return TOKEN_REGEX.test(value);
23470
+ }
23471
+ function checkOperationLabel(value) {
23472
+ if (typeof value !== "string" || value.length === 0) {
23473
+ return { accepted: false, reason: "raw_payload" };
23474
+ }
23475
+ if (value.length > MAX_SIDE_EFFECT_OPERATION_LABEL_LENGTH) {
23476
+ return { accepted: false, reason: "value_too_long" };
23477
+ }
23478
+ const unsafe = detectUnsafePattern(value);
23479
+ if (unsafe) {
23480
+ return { accepted: false, reason: unsafe };
23481
+ }
23482
+ if (!TOKEN_REGEX.test(value)) {
23483
+ return { accepted: false, reason: "raw_payload" };
23484
+ }
23485
+ return { accepted: true, value };
23486
+ }
23487
+ function checkSemanticFieldValue(key, value) {
23488
+ if (typeof value !== "string" || value.length === 0) {
23489
+ return { accepted: false, reason: "raw_payload" };
23490
+ }
23491
+ if (value.length > MAX_SIDE_EFFECT_FIELD_VALUE_LENGTH) {
23492
+ return { accepted: false, reason: "value_too_long" };
23493
+ }
23494
+ const unsafe = detectUnsafePattern(value);
23495
+ if (unsafe) {
23496
+ return { accepted: false, reason: unsafe };
23497
+ }
23498
+ if (!passesFieldValidator(key, value)) {
23499
+ return { accepted: false, reason: "raw_payload" };
23500
+ }
23501
+ return { accepted: true, value };
23502
+ }
23503
+ function checkSemanticFieldKey(key) {
23504
+ return typeof key === "string" && SEMANTIC_FIELD_KEY_SET.has(key);
23505
+ }
23506
+ function checkOperationKind(kind) {
23507
+ return typeof kind === "string" && OPERATION_KIND_SET.has(kind);
23508
+ }
23509
+ function checkOperationStatus(status) {
23510
+ return typeof status === "string" && OPERATION_STATUS_SET.has(status);
23511
+ }
23512
+ function checkOperationPhase(phase) {
23513
+ return typeof phase === "string" && OPERATION_PHASE_SET.has(phase);
23514
+ }
23515
+
23516
+ // src/side-effect/emit.ts
23517
+ init_esm();
23518
+ init_dist();
23519
+ var spanState = /* @__PURE__ */ new WeakMap();
23520
+ function getOrCreateState(span) {
23521
+ let state = spanState.get(span);
23522
+ if (!state) {
23523
+ state = { operationsRecorded: 0, omissions: /* @__PURE__ */ new Map() };
23524
+ spanState.set(span, state);
23525
+ }
23526
+ return state;
23527
+ }
23528
+ function getRecordingActiveSpan() {
23529
+ let span;
23530
+ try {
23531
+ span = trace.getActiveSpan();
23532
+ } catch {
23533
+ return void 0;
23534
+ }
23535
+ if (!span) return void 0;
23536
+ try {
23537
+ if (typeof span.isRecording === "function" && !span.isRecording()) {
23538
+ return void 0;
23539
+ }
23540
+ } catch {
23541
+ return void 0;
23542
+ }
23543
+ return span;
23544
+ }
23545
+ function recordOmissionOnActiveSpan(reason) {
23546
+ const span = getRecordingActiveSpan();
23547
+ if (!span) return;
23548
+ recordOmissionOnSpan(span, reason);
23549
+ }
23550
+ function recordOmissionOnSpan(span, reason) {
23551
+ const state = getOrCreateState(span);
23552
+ const previous = state.omissions.get(reason) ?? 0;
23553
+ const next = previous + 1;
23554
+ state.omissions.set(reason, next);
23555
+ const attribute = OMISSION_ATTRIBUTE_BY_REASON[reason];
23556
+ try {
23557
+ span.setAttribute(attribute, next);
23558
+ } catch {
23559
+ }
23560
+ }
23561
+ var OMISSION_ATTRIBUTE_BY_REASON = {
23562
+ pii: GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_OMITTED_PII,
23563
+ secret: GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_OMITTED_SECRET,
23564
+ raw_payload: GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_OMITTED_RAW_PAYLOAD,
23565
+ unsupported_key: GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_OMITTED_UNSUPPORTED_KEY,
23566
+ value_too_long: GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_OMITTED_VALUE_TOO_LONG,
23567
+ not_emitted: GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_OMITTED_NOT_EMITTED,
23568
+ capture_disabled: GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_OMITTED_CAPTURE_DISABLED
23569
+ };
23570
+ var FIELD_ATTRIBUTE_BY_KEY = {
23571
+ templateKey: GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_FIELD_TEMPLATE_KEY,
23572
+ providerOperation: GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_FIELD_PROVIDER_OPERATION,
23573
+ role: GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_FIELD_ROLE,
23574
+ locale: GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_FIELD_LOCALE,
23575
+ timezone: GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_FIELD_TIMEZONE,
23576
+ status: GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_FIELD_STATUS,
23577
+ phase: GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_FIELD_PHASE
23578
+ };
23579
+ function attachOperation(input) {
23580
+ const span = getRecordingActiveSpan();
23581
+ if (!span) return { kind: "no_active_span" };
23582
+ const state = getOrCreateState(span);
23583
+ if (state.operationsRecorded >= MAX_SIDE_EFFECT_OPERATIONS_PER_SPAN) {
23584
+ return { kind: "over_budget", span };
23585
+ }
23586
+ state.operationsRecorded += 1;
23587
+ try {
23588
+ span.setAttribute(GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_KIND, input.kind);
23589
+ span.setAttribute(
23590
+ GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_OPERATION,
23591
+ input.operation
23592
+ );
23593
+ if (input.status !== void 0) {
23594
+ span.setAttribute(
23595
+ GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_STATUS,
23596
+ input.status
23597
+ );
23598
+ }
23599
+ if (input.phase !== void 0) {
23600
+ span.setAttribute(
23601
+ GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_PHASE,
23602
+ input.phase
23603
+ );
23604
+ }
23605
+ } catch {
23606
+ }
23607
+ return { kind: "attached", span };
23608
+ }
23609
+ function attachField(span, key, value) {
23610
+ const attribute = FIELD_ATTRIBUTE_BY_KEY[key];
23611
+ try {
23612
+ span.setAttribute(attribute, value);
23613
+ } catch {
23614
+ }
23615
+ }
23616
+ function recordOmission(span, reason) {
23617
+ recordOmissionOnSpan(span, reason);
23618
+ }
23619
+
23620
+ // src/side-effect/index.ts
23621
+ function recordSideEffect(input) {
23622
+ try {
23623
+ runRecordSideEffect(input);
23624
+ } catch {
23625
+ }
23626
+ }
23627
+ function runRecordSideEffect(input) {
23628
+ if (!input || typeof input !== "object") return;
23629
+ let captureEnabled;
23630
+ try {
23631
+ captureEnabled = getActiveConfig().sideEffectEvidence === true;
23632
+ } catch {
23633
+ captureEnabled = false;
23634
+ }
23635
+ if (!captureEnabled) {
23636
+ return;
23637
+ }
23638
+ const candidate = input;
23639
+ if (!checkOperationKind(candidate.kind)) {
23640
+ return;
23641
+ }
23642
+ const labelOutcome = checkOperationLabel(candidate.operation);
23643
+ if (!labelOutcome.accepted) {
23644
+ recordOmissionOnActiveSpan(labelOutcome.reason);
23645
+ return;
23646
+ }
23647
+ let acceptedStatus;
23648
+ if (candidate.status !== void 0) {
23649
+ if (checkOperationStatus(candidate.status)) {
23650
+ acceptedStatus = candidate.status;
23651
+ } else {
23652
+ recordOmissionOnActiveSpan("unsupported_key");
23653
+ }
23654
+ }
23655
+ let acceptedPhase;
23656
+ if (candidate.phase !== void 0) {
23657
+ if (checkOperationPhase(candidate.phase)) {
23658
+ acceptedPhase = candidate.phase;
23659
+ } else {
23660
+ recordOmissionOnActiveSpan("unsupported_key");
23661
+ }
23662
+ }
23663
+ const outcome = attachOperation({
23664
+ kind: candidate.kind,
23665
+ operation: labelOutcome.value,
23666
+ status: acceptedStatus,
23667
+ phase: acceptedPhase
23668
+ });
23669
+ if (outcome.kind === "no_active_span") {
23670
+ return;
23671
+ }
23672
+ if (outcome.kind === "over_budget") {
23673
+ recordOmission(outcome.span, "value_too_long");
23674
+ return;
23675
+ }
23676
+ const fields = candidate.fields;
23677
+ if (fields && typeof fields === "object") {
23678
+ for (const [rawKey, rawValue] of Object.entries(fields)) {
23679
+ if (!checkSemanticFieldKey(rawKey)) {
23680
+ recordOmission(outcome.span, "unsupported_key");
23681
+ continue;
23682
+ }
23683
+ const valueOutcome = checkSemanticFieldValue(rawKey, rawValue);
23684
+ if (!valueOutcome.accepted) {
23685
+ recordOmission(outcome.span, valueOutcome.reason);
23686
+ continue;
23687
+ }
23688
+ attachField(outcome.span, rawKey, valueOutcome.value);
23689
+ }
23690
+ }
23691
+ }
23163
23692
  // Annotate the CommonJS export names for ESM import in node:
23164
23693
  0 && (module.exports = {
23165
23694
  GlasstraceExporter,
@@ -23185,6 +23714,7 @@ function firstToken(value) {
23185
23714
  performInit,
23186
23715
  readAnonKey,
23187
23716
  readEnvVars,
23717
+ recordSideEffect,
23188
23718
  registerGlasstrace,
23189
23719
  resolveConfig,
23190
23720
  saveCachedConfig,