@guidelytech/shared 0.15.0 → 0.17.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.
package/dist/index.cjs CHANGED
@@ -31,6 +31,7 @@ __export(index_exports, {
31
31
  AGENT_TURN_ROLES: () => AGENT_TURN_ROLES,
32
32
  ANNOTATION_COLORS: () => ANNOTATION_COLORS,
33
33
  APP_LIFECYCLE_EVENTS: () => APP_LIFECYCLE_EVENTS,
34
+ ARTICLE_HREF_PREFIX: () => ARTICLE_HREF_PREFIX,
34
35
  ARTICLE_VISIBILITIES: () => ARTICLE_VISIBILITIES,
35
36
  AUTOCAPTURE_EVENTS: () => AUTOCAPTURE_EVENTS,
36
37
  AgentEventsRequestSchema: () => AgentEventsRequestSchema,
@@ -41,6 +42,7 @@ __export(index_exports, {
41
42
  AuthoringPickSchema: () => AuthoringPickSchema,
42
43
  AutocaptureSettingsSchema: () => AutocaptureSettingsSchema,
43
44
  BUTTON_ACTIONS: () => BUTTON_ACTIONS,
45
+ BugReportSchema: () => BugReportSchema,
44
46
  ButtonSchema: () => ButtonSchema,
45
47
  CAPTURE_PARAM: () => CAPTURE_PARAM,
46
48
  CAPTURE_SCREENSHOT_MAX_BYTES: () => CAPTURE_SCREENSHOT_MAX_BYTES,
@@ -106,6 +108,10 @@ __export(index_exports, {
106
108
  LocaleSchema: () => LocaleSchema,
107
109
  LocalizationSettingsSchema: () => LocalizationSettingsSchema,
108
110
  MAX_ANNOTATIONS: () => MAX_ANNOTATIONS,
111
+ MAX_APP_VERSION_LENGTH: () => MAX_APP_VERSION_LENGTH,
112
+ MAX_BREADCRUMBS: () => MAX_BREADCRUMBS,
113
+ MAX_BUG_REPORT_LENGTH: () => MAX_BUG_REPORT_LENGTH,
114
+ MAX_BUG_REPORT_SCREENSHOT_BYTES: () => MAX_BUG_REPORT_SCREENSHOT_BYTES,
109
115
  MAX_COLLECTION_DEPTH: () => MAX_COLLECTION_DEPTH,
110
116
  MAX_COMPLAINT_ANSWER_LENGTH: () => MAX_COMPLAINT_ANSWER_LENGTH,
111
117
  MAX_COMPLAINT_ATTACHMENT_BYTES: () => MAX_COMPLAINT_ATTACHMENT_BYTES,
@@ -113,6 +119,13 @@ __export(index_exports, {
113
119
  MAX_COMPLAINT_FIELDS: () => MAX_COMPLAINT_FIELDS,
114
120
  MAX_COMPLAINT_LENGTH: () => MAX_COMPLAINT_LENGTH,
115
121
  MAX_CUSTOM_CSS: () => MAX_CUSTOM_CSS,
122
+ MAX_DEBUG_IMAGES: () => MAX_DEBUG_IMAGES,
123
+ MAX_DETAIL_FRAMES: () => MAX_DETAIL_FRAMES,
124
+ MAX_DETAIL_THREADS: () => MAX_DETAIL_THREADS,
125
+ MAX_ERROR_TAGS: () => MAX_ERROR_TAGS,
126
+ MAX_EXCEPTION_CHAIN: () => MAX_EXCEPTION_CHAIN,
127
+ MAX_EXCEPTION_DETAIL_BYTES: () => MAX_EXCEPTION_DETAIL_BYTES,
128
+ MAX_EXCEPTION_DETAIL_RAW_BYTES: () => MAX_EXCEPTION_DETAIL_RAW_BYTES,
116
129
  MAX_FEEDBACK_COMMENT: () => MAX_FEEDBACK_COMMENT,
117
130
  MAX_FEEDBACK_DESCRIPTION: () => MAX_FEEDBACK_DESCRIPTION,
118
131
  MAX_FEEDBACK_NOTE: () => MAX_FEEDBACK_NOTE,
@@ -140,11 +153,13 @@ __export(index_exports, {
140
153
  PDF_PAGES_CLASS: () => PDF_PAGES_CLASS,
141
154
  PLACEMENTS: () => PLACEMENTS,
142
155
  PLATFORMS: () => PLATFORMS,
156
+ PerformanceSettingsSchema: () => PerformanceSettingsSchema,
143
157
  PostMessageSchema: () => PostMessageSchema,
144
158
  ProjectThemeSchema: () => ProjectThemeSchema,
145
159
  PublishedGuideSchema: () => PublishedGuideSchema,
146
160
  RC_MODULE_IDS: () => RC_MODULE_IDS,
147
161
  RC_MODULE_LABELS: () => RC_MODULE_LABELS,
162
+ RECORDING_LEVELS: () => RECORDING_LEVELS,
148
163
  REPLAY_MAX_COMPRESSED_BYTES: () => REPLAY_MAX_COMPRESSED_BYTES,
149
164
  REPLAY_MAX_RAW_BYTES: () => REPLAY_MAX_RAW_BYTES,
150
165
  REPLY_TIMES: () => REPLY_TIMES,
@@ -194,6 +209,8 @@ __export(index_exports, {
194
209
  WS_MAX_MESSAGES_PER_SOCKET: () => WS_MAX_MESSAGES_PER_SOCKET,
195
210
  WS_MAX_MESSAGE_BYTES: () => WS_MAX_MESSAGE_BYTES,
196
211
  applyGuideTranslations: () => applyGuideTranslations,
212
+ articleHref: () => articleHref,
213
+ articleIdFromHref: () => articleIdFromHref,
197
214
  articleTextEntries: () => articleTextEntries,
198
215
  assignGuideVariant: () => assignGuideVariant,
199
216
  baseLanguage: () => baseLanguage,
@@ -206,11 +223,13 @@ __export(index_exports, {
206
223
  contrastIssues: () => contrastIssues,
207
224
  contrastRatio: () => contrastRatio,
208
225
  cssSelectorError: () => cssSelectorError,
226
+ customFingerprint: () => customFingerprint,
209
227
  defaultGuideConfig: () => defaultGuideConfig,
210
228
  defaultStep: () => defaultStep,
211
229
  describeCaptureStep: () => describeCaptureStep,
212
230
  describeRule: () => describeRule,
213
231
  emptyRuleGroup: () => emptyRuleGroup,
232
+ errorFilterDrops: () => errorFilterDrops,
214
233
  evaluateRule: () => evaluateRule,
215
234
  evaluateRules: () => evaluateRules,
216
235
  evenWeights: () => evenWeights,
@@ -240,6 +259,7 @@ __export(index_exports, {
240
259
  isRuleGroup: () => isRuleGroup,
241
260
  isSafeMediaUrl: () => isSafeMediaUrl,
242
261
  isVideoContentType: () => isVideoContentType,
262
+ isVideoFileUrl: () => isVideoFileUrl,
243
263
  localeName: () => localeName,
244
264
  localizeAnnouncement: () => localizeAnnouncement,
245
265
  localizeArticle: () => localizeArticle,
@@ -252,10 +272,12 @@ __export(index_exports, {
252
272
  mediaKind: () => mediaKind,
253
273
  mediaMaxBytes: () => mediaMaxBytes,
254
274
  needsReview: () => needsReview,
275
+ normalizeAppVersion: () => normalizeAppVersion,
255
276
  normalizeErrorMessage: () => normalizeErrorMessage,
256
277
  normalizeFrameFile: () => normalizeFrameFile,
257
278
  normalizeLocale: () => normalizeLocale,
258
279
  normalizeSnapshot: () => normalizeSnapshot,
280
+ normalizeTags: () => normalizeTags,
259
281
  orderedModules: () => orderedModules,
260
282
  pageLabel: () => pageLabel,
261
283
  pageName: () => pageName,
@@ -273,7 +295,9 @@ __export(index_exports, {
273
295
  propertyAttributeAllowed: () => propertyAttributeAllowed,
274
296
  queryConditionRegex: () => queryConditionRegex,
275
297
  randomId: () => randomId,
298
+ reactNativeBundleUrl: () => reactNativeBundleUrl,
276
299
  readableTextOn: () => readableTextOn,
300
+ recordingLevel: () => recordingLevel,
277
301
  relativeLuminance: () => relativeLuminance,
278
302
  resolveCaptureSettings: () => resolveCaptureSettings,
279
303
  resolveLocale: () => resolveLocale,
@@ -294,6 +318,7 @@ __export(index_exports, {
294
318
  slugify: () => slugify,
295
319
  snapshotFromSelector: () => snapshotFromSelector,
296
320
  stableStringify: () => stableStringify,
321
+ stepVideo: () => stepVideo,
297
322
  stripOrigin: () => stripOrigin,
298
323
  supportsPlatform: () => supportsPlatform,
299
324
  templateConfig: () => templateConfig,
@@ -301,16 +326,19 @@ __export(index_exports, {
301
326
  toTranslationCsv: () => toTranslationCsv,
302
327
  toXliff: () => toXliff,
303
328
  translationCoverage: () => translationCoverage,
329
+ trimExceptionDetail: () => trimExceptionDetail,
304
330
  unreadAnnouncements: () => unreadAnnouncements,
305
331
  validateGuideConfig: () => validateGuideConfig,
306
332
  variantProblems: () => variantProblems,
307
333
  variantRanges: () => variantRanges,
334
+ videoThumbnailUrl: () => videoThumbnailUrl,
308
335
  visibleAnnouncements: () => visibleAnnouncements,
309
336
  visibleArticleIds: () => visibleArticleIds,
310
337
  visibleButtons: () => visibleButtons,
311
338
  visitorAudiences: () => visitorAudiences,
312
339
  visitorLocales: () => visitorLocales,
313
340
  withExperimentBucket: () => withExperimentBucket,
341
+ withRecordingLevel: () => withRecordingLevel,
314
342
  withVisibility: () => withVisibility
315
343
  });
316
344
  module.exports = __toCommonJS(index_exports);
@@ -331,18 +359,18 @@ function slugify(input) {
331
359
  return input.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64) || "untitled";
332
360
  }
333
361
  var ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
334
- function randomId(size = 16) {
362
+ function randomId(size2 = 16) {
335
363
  const g = typeof globalThis !== "undefined" ? globalThis : {};
336
364
  let bytes;
337
365
  if (g.crypto && typeof g.crypto.getRandomValues === "function") {
338
- bytes = new Uint8Array(size);
366
+ bytes = new Uint8Array(size2);
339
367
  g.crypto.getRandomValues(bytes);
340
368
  } else {
341
- bytes = new Uint8Array(size);
342
- for (let i = 0; i < size; i++) bytes[i] = Math.floor(Math.random() * 256);
369
+ bytes = new Uint8Array(size2);
370
+ for (let i = 0; i < size2; i++) bytes[i] = Math.floor(Math.random() * 256);
343
371
  }
344
372
  let out = "";
345
- for (let i = 0; i < size; i++) out += ALPHABET[bytes[i] % ALPHABET.length];
373
+ for (let i = 0; i < size2; i++) out += ALPHABET[bytes[i] % ALPHABET.length];
346
374
  return out;
347
375
  }
348
376
  function isPlainObject(v) {
@@ -820,6 +848,11 @@ var StepSchema = import_zod2.z.object({
820
848
  imageUrl: import_zod2.z.string().url().max(2e3).optional().or(import_zod2.z.literal("")),
821
849
  /** Alternative text for `imageUrl` (screen readers); empty = decorative. */
822
850
  imageAlt: import_zod2.z.string().max(300).optional(),
851
+ /**
852
+ * Video (YouTube, Vimeo, Loom, a file…): drawn as a poster with a play button that opens the video
853
+ * in a new tab. The poster is `imageUrl` when set, else the provider's thumbnail.
854
+ */
855
+ videoUrl: import_zod2.z.string().url().max(2e3).optional().or(import_zod2.z.literal("")),
823
856
  buttons: import_zod2.z.array(ButtonSchema).max(6).default([]),
824
857
  target: TargetSchema.optional(),
825
858
  placement: import_zod2.z.enum(PLACEMENTS).default("auto"),
@@ -965,9 +998,9 @@ var GuideConfigSchema = import_zod2.z.object({
965
998
  /** Everyone, only identified (logged-in) users, or only anonymous visitors; applied on top of `targeting`. */
966
999
  visibility: import_zod2.z.enum(GUIDE_VISIBILITIES).default("everyone"),
967
1000
  targeting: RuleGroupSchema.default(() => emptyRuleGroup()),
968
- trigger: TriggerSchema.default({}),
969
- frequency: FrequencySchema.default({}),
970
- appearance: AppearanceSchema.default({}),
1001
+ trigger: TriggerSchema.prefault({}),
1002
+ frequency: FrequencySchema.prefault({}),
1003
+ appearance: AppearanceSchema.prefault({}),
971
1004
  checklist: ChecklistConfigSchema.optional(),
972
1005
  survey: SurveyConfigSchema.optional(),
973
1006
  /** Restrict guide to url pattern(s) (applied before trigger). On mobile these match the screen path `/<Screen>`. */
@@ -1074,19 +1107,91 @@ var ProjectThemeSchema = import_zod2.z.object({
1074
1107
  // src/events.ts
1075
1108
  var import_zod3 = require("zod");
1076
1109
 
1110
+ // src/error-detail.ts
1111
+ var MAX_EXCEPTION_DETAIL_BYTES = 64 * 1024;
1112
+ var MAX_EXCEPTION_DETAIL_RAW_BYTES = 1024 * 1024;
1113
+ var MAX_BREADCRUMBS = 100;
1114
+ var MAX_EXCEPTION_CHAIN = 20;
1115
+ var MAX_DETAIL_FRAMES = 250;
1116
+ var MAX_DETAIL_THREADS = 100;
1117
+ var MAX_DEBUG_IMAGES = 500;
1118
+ var MAX_ERROR_TAGS = 50;
1119
+ var size = (v) => {
1120
+ try {
1121
+ return JSON.stringify(v)?.length ?? 0;
1122
+ } catch {
1123
+ return Infinity;
1124
+ }
1125
+ };
1126
+ function normalizeTags(tags) {
1127
+ const out = {};
1128
+ for (const [k, v] of Object.entries(tags ?? {})) {
1129
+ if (Object.keys(out).length >= MAX_ERROR_TAGS) break;
1130
+ if (!k || v === void 0 || v === null) continue;
1131
+ out[k.slice(0, 32)] = String(v).slice(0, 200);
1132
+ }
1133
+ return out;
1134
+ }
1135
+ function trimExceptionDetail(detail, max = MAX_EXCEPTION_DETAIL_BYTES) {
1136
+ const d = detail;
1137
+ if (d.breadcrumbs?.values && d.breadcrumbs.values.length > MAX_BREADCRUMBS) d.breadcrumbs.values = d.breadcrumbs.values.slice(-MAX_BREADCRUMBS);
1138
+ if (d.exception?.values && d.exception.values.length > MAX_EXCEPTION_CHAIN) d.exception.values = d.exception.values.slice(-MAX_EXCEPTION_CHAIN);
1139
+ if (d.threads?.values && d.threads.values.length > MAX_DETAIL_THREADS) d.threads.values = d.threads.values.slice(0, MAX_DETAIL_THREADS);
1140
+ if (d.debug_meta?.images && d.debug_meta.images.length > MAX_DEBUG_IMAGES) d.debug_meta.images = d.debug_meta.images.slice(0, MAX_DEBUG_IMAGES);
1141
+ const stacks = () => [...d.exception?.values ?? [], ...d.threads?.values ?? []].map((x) => x.stacktrace).filter((s) => !!s);
1142
+ for (const s of stacks()) if (s.frames && s.frames.length > MAX_DETAIL_FRAMES) s.frames = s.frames.slice(-MAX_DETAIL_FRAMES);
1143
+ if (size(d) <= max) return d;
1144
+ while (d.breadcrumbs?.values.length && size(d) > max) d.breadcrumbs.values = d.breadcrumbs.values.slice(Math.ceil(d.breadcrumbs.values.length / 2));
1145
+ if (size(d) <= max) return d;
1146
+ for (const s of stacks())
1147
+ for (const f of s.frames ?? []) {
1148
+ delete f.vars;
1149
+ delete f.pre_context;
1150
+ delete f.post_context;
1151
+ }
1152
+ if (size(d) <= max) return d;
1153
+ if (d.threads?.values) d.threads.values = d.threads.values.filter((t) => t.crashed || t.current);
1154
+ if (size(d) <= max) return d;
1155
+ if (d.extra) d.extra = { _trimmed: true };
1156
+ if (d.request) delete d.request.data;
1157
+ for (const s of stacks()) while (s.frames && s.frames.length > 20 && size(d) > max) s.frames.splice(Math.floor(s.frames.length / 2) - 5, 10);
1158
+ if (d.debug_meta?.images && size(d) > max) d.debug_meta.images = d.debug_meta.images.slice(0, 50);
1159
+ return d;
1160
+ }
1161
+ var matches = (patterns, value) => patterns.some((p) => typeof p === "string" ? p !== "" && value.includes(p) : safeTest(p, value));
1162
+ function safeTest(re, value) {
1163
+ re.lastIndex = 0;
1164
+ return re.test(value);
1165
+ }
1166
+ function errorFilterDrops(e, opts) {
1167
+ const message = e.message ?? "";
1168
+ if (opts.ignoreErrors?.length && (matches(opts.ignoreErrors, `${e.type || "Error"}: ${message}`) || matches(opts.ignoreErrors, message))) return true;
1169
+ if (!e.file) return false;
1170
+ if (opts.denyUrls?.length && matches(opts.denyUrls, e.file)) return true;
1171
+ if (opts.allowUrls?.length && !matches(opts.allowUrls, e.file)) return true;
1172
+ return false;
1173
+ }
1174
+
1077
1175
  // src/events-util.ts
1078
1176
  var SENSITIVE_PROPERTY_PATTERN = /(password|passwd|secret|token|credit|card|cvv|ssn|iban)/i;
1079
1177
  var MAX_PROPERTY_BYTES = 8 * 1024;
1178
+ var MAX_APP_VERSION_LENGTH = 64;
1179
+ function normalizeAppVersion(input) {
1180
+ if (typeof input !== "string" && typeof input !== "number") return null;
1181
+ const printable = Array.from(String(input)).filter((c) => c.charCodeAt(0) > 31 && c.charCodeAt(0) !== 127).join("");
1182
+ const v = printable.trim().slice(0, MAX_APP_VERSION_LENGTH).trim();
1183
+ return v || null;
1184
+ }
1080
1185
  function sanitizeProperties(props) {
1081
1186
  if (!props) return {};
1082
1187
  const out = {};
1083
- let size = 0;
1188
+ let size2 = 0;
1084
1189
  for (const [k, v] of Object.entries(props)) {
1085
1190
  if (SENSITIVE_PROPERTY_PATTERN.test(k)) continue;
1086
1191
  if (typeof v === "function" || typeof v === "symbol") continue;
1087
1192
  const str2 = typeof v === "string" ? v : JSON.stringify(v ?? null);
1088
- size += k.length + (str2?.length ?? 0);
1089
- if (size > MAX_PROPERTY_BYTES) break;
1193
+ size2 += k.length + (str2?.length ?? 0);
1194
+ if (size2 > MAX_PROPERTY_BYTES) break;
1090
1195
  out[k.slice(0, 100)] = typeof v === "string" ? v.slice(0, 1e3) : v;
1091
1196
  }
1092
1197
  return out;
@@ -1096,16 +1201,23 @@ function sanitizeProperties(props) {
1096
1201
  var MAX_STACK_FRAMES = 30;
1097
1202
  var V8 = /^\s*at (?:(.+?) \()?((?:[a-z][\w+.-]*:)?[^\s()]+?):(\d+):(\d+)\)?\s*$/i;
1098
1203
  var GECKO = /^\s*(.*?)@(.+?):(\d+):(\d+)\s*$/;
1204
+ var HERMES = /^\s*at (?:(.+?) \()?address at ([^\s()]+?):(\d+):(\d+)\)?\s*$/;
1205
+ function reactNativeBundleUrl(file) {
1206
+ const base = file.replace(/[?#].*$/, "").split("/").pop() || file;
1207
+ return `app:///${base}`;
1208
+ }
1099
1209
  function parseStack(stack, max = MAX_STACK_FRAMES) {
1100
1210
  if (!stack || typeof stack !== "string") return [];
1101
1211
  const frames = [];
1102
1212
  for (const raw of stack.split("\n")) {
1103
1213
  if (frames.length >= max) break;
1104
1214
  const line = raw.slice(0, 1e3);
1105
- const m = V8.exec(line) ?? GECKO.exec(line);
1215
+ const hermes = HERMES.exec(line);
1216
+ const m = hermes ?? V8.exec(line) ?? GECKO.exec(line);
1106
1217
  if (!m) continue;
1107
1218
  const fn = (m[1] || "").trim();
1108
- frames.push({ fn: fn ? fn.slice(0, 200) : void 0, file: m[2]?.slice(0, 500), line: Number(m[3]), col: Number(m[4]) });
1219
+ const file = hermes ? reactNativeBundleUrl(m[2]) : m[2];
1220
+ frames.push({ fn: fn ? fn.slice(0, 200) : void 0, file: file?.slice(0, 500), line: Number(m[3]), col: Number(m[4]) });
1109
1221
  }
1110
1222
  return frames;
1111
1223
  }
@@ -1125,13 +1237,23 @@ function normalizeFrameFile(file) {
1125
1237
  var SOURCEMAP_MAX_FILE_BYTES = 100 * 1024 * 1024;
1126
1238
  var SOURCEMAP_MAX_FILES_PER_UPLOAD = 200;
1127
1239
  function fingerprintError(input) {
1128
- const top = (input.frames ?? []).find((f) => f.file);
1129
- const frameKey = input.original ? `src:${input.original.source}:${input.original.name || "?"}` : top ? `${normalizeFrameFile(top.file)}:${top.fn || "?"}` : "";
1240
+ const withFile = (input.frames ?? []).filter((f) => f.file || f.module);
1241
+ const top = withFile.find((f) => f.inApp === true) ?? withFile.find((f) => f.inApp !== false) ?? withFile[0];
1242
+ const frameKey = input.original ? `src:${input.original.source}:${input.original.name || "?"}` : top ? `${top.file ? normalizeFrameFile(top.file) : `mod:${top.module}`}:${top.fn || "?"}` : "";
1130
1243
  const key = [input.type || "Error", normalizeErrorMessage(input.message || ""), frameKey].join("|");
1131
1244
  const a = fnv1a(key).toString(16).padStart(8, "0");
1132
1245
  const b = fnv1a(`guidely:${key}`).toString(16).padStart(8, "0");
1133
1246
  return a + b;
1134
1247
  }
1248
+ function customFingerprint(parts, computed) {
1249
+ if (!Array.isArray(parts) || parts.length === 0) return computed;
1250
+ const items = parts.filter((p) => typeof p === "string" || typeof p === "number").map((p) => String(p).slice(0, 200)).slice(0, 20);
1251
+ if (items.length === 0) return computed;
1252
+ const isDefault = (p) => /^\{\{\s*default\s*\}\}$/i.test(p);
1253
+ if (items.every(isDefault)) return computed;
1254
+ const key = items.map((p) => isDefault(p) ? computed : p).join("|");
1255
+ return fnv1a(key).toString(16).padStart(8, "0") + fnv1a(`guidely:fp:${key}`).toString(16).padStart(8, "0");
1256
+ }
1135
1257
 
1136
1258
  // src/events.ts
1137
1259
  var EVENT_NAMES = [
@@ -1143,6 +1265,8 @@ var EVENT_NAMES = [
1143
1265
  "guide_skipped",
1144
1266
  "guide_dismissed",
1145
1267
  "guide_abandoned",
1268
+ /** The video on a guide step was clicked (opened in a new tab). Properties: videoUrl. */
1269
+ "guide_video_clicked",
1146
1270
  "checklist_task_completed",
1147
1271
  "checklist_completed",
1148
1272
  "checklist_dismissed",
@@ -1175,6 +1299,14 @@ var EVENT_NAMES = [
1175
1299
  var AUTOCAPTURE_EVENTS = ["page_view", "page_leave", "click", "rage_click", "exception", "heatmap", "app_install", "app_update", "app_open", "app_background"];
1176
1300
  var APP_LIFECYCLE_EVENTS = ["app_install", "app_update", "app_open", "app_background"];
1177
1301
  var GUIDE_LIFECYCLE_EVENTS = ["guide_viewed", "guide_started", "step_viewed", "step_completed", "guide_completed", "guide_skipped", "guide_dismissed", "guide_abandoned"];
1302
+ var ExceptionDetailField = import_zod3.z.preprocess((v) => {
1303
+ if (!v || typeof v !== "object" || Array.isArray(v)) return void 0;
1304
+ try {
1305
+ return JSON.stringify(v).length > MAX_EXCEPTION_DETAIL_RAW_BYTES ? void 0 : v;
1306
+ } catch {
1307
+ return void 0;
1308
+ }
1309
+ }, import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()).optional());
1178
1310
  var SdkEventSchema = import_zod3.z.object({
1179
1311
  eventId: import_zod3.z.string().min(8).max(64),
1180
1312
  name: import_zod3.z.enum(EVENT_NAMES),
@@ -1190,7 +1322,19 @@ var SdkEventSchema = import_zod3.z.object({
1190
1322
  stepId: import_zod3.z.string().max(64).optional(),
1191
1323
  stepIndex: import_zod3.z.number().int().min(0).optional(),
1192
1324
  url: import_zod3.z.string().max(2e3).optional(),
1193
- properties: import_zod3.z.record(import_zod3.z.unknown()).optional()
1325
+ /**
1326
+ * Version of the customer's app when the event happened (`appVersion` SDK option, auto-detected on
1327
+ * mobile). Stored per event so reports can filter and break down by version; see `normalizeAppVersion`.
1328
+ */
1329
+ appVersion: import_zod3.z.string().max(200).optional().nullable(),
1330
+ properties: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()).optional(),
1331
+ /**
1332
+ * `exception` events only: breadcrumbs, contexts, tags, extra, the exception chain, threads and
1333
+ * debug images in the Sentry event shape (`ExceptionDetail`, docs/error-monitoring/sdks.md), outside
1334
+ * the 8 KB property budget. The server trims it to 64 KB and stores it in ErrorEventDetail; one over
1335
+ * 1 MB (or that isn't an object) is dropped without failing the batch.
1336
+ */
1337
+ detail: ExceptionDetailField
1194
1338
  });
1195
1339
  var EventBatchSchema = import_zod3.z.object({
1196
1340
  events: import_zod3.z.array(SdkEventSchema).min(1).max(50),
@@ -1203,8 +1347,8 @@ var import_zod4 = require("zod");
1203
1347
  var IdentifyRequestSchema = import_zod4.z.object({
1204
1348
  anonymousId: import_zod4.z.string().min(1).max(128),
1205
1349
  userId: import_zod4.z.string().min(1).max(256).optional().nullable(),
1206
- traits: import_zod4.z.record(import_zod4.z.unknown()).optional(),
1207
- account: import_zod4.z.object({ id: import_zod4.z.string().min(1).max(256), traits: import_zod4.z.record(import_zod4.z.unknown()).optional() }).optional().nullable(),
1350
+ traits: import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()).optional(),
1351
+ account: import_zod4.z.object({ id: import_zod4.z.string().min(1).max(256), traits: import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()).optional() }).optional().nullable(),
1208
1352
  sessionId: import_zod4.z.string().max(128).optional(),
1209
1353
  url: import_zod4.z.string().max(2e3).optional()
1210
1354
  });
@@ -1221,7 +1365,7 @@ var SurveyResponseRequestSchema = import_zod4.z.object({
1221
1365
  userId: import_zod4.z.string().max(256).optional().nullable(),
1222
1366
  accountId: import_zod4.z.string().max(256).optional().nullable(),
1223
1367
  guideVersion: import_zod4.z.number().int(),
1224
- answers: import_zod4.z.record(import_zod4.z.union([import_zod4.z.string().max(5e3), import_zod4.z.number(), import_zod4.z.boolean(), import_zod4.z.array(import_zod4.z.string().max(500)).max(50)])),
1368
+ answers: import_zod4.z.record(import_zod4.z.string(), import_zod4.z.union([import_zod4.z.string().max(5e3), import_zod4.z.number(), import_zod4.z.boolean(), import_zod4.z.array(import_zod4.z.string().max(500)).max(50)])),
1225
1369
  responseId: import_zod4.z.string().min(8).max(64)
1226
1370
  });
1227
1371
  var GuideStateUpdateSchema = import_zod4.z.object({
@@ -1243,7 +1387,7 @@ var AuthoringPickSchema = import_zod4.z.object({
1243
1387
  url: import_zod4.z.string().max(2e3).optional(),
1244
1388
  rect: import_zod4.z.object({ x: import_zod4.z.number(), y: import_zod4.z.number(), width: import_zod4.z.number(), height: import_zod4.z.number() }).optional(),
1245
1389
  /** Compact snapshot of the picked element (tag mode: feature rules are proposed from it). */
1246
- elementSnapshot: import_zod4.z.record(import_zod4.z.unknown()).optional()
1390
+ elementSnapshot: import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()).optional()
1247
1391
  });
1248
1392
  var PublishedGuideSchema = import_zod4.z.object({
1249
1393
  id: import_zod4.z.string(),
@@ -1321,9 +1465,38 @@ var FileComplaintSchema = import_zod6.z.object({
1321
1465
  }).optional().nullable()
1322
1466
  });
1323
1467
 
1324
- // src/agents.ts
1468
+ // src/bug-reports.ts
1325
1469
  var import_zod7 = require("zod");
1326
1470
 
1471
+ // src/bug-reports-limits.ts
1472
+ var MAX_BUG_REPORT_LENGTH = 4e3;
1473
+ var MAX_BUG_REPORT_SCREENSHOT_BYTES = 4 * 1024 * 1024;
1474
+
1475
+ // src/bug-reports.ts
1476
+ var BugReportSchema = import_zod7.z.object({
1477
+ anonymousId: import_zod7.z.string().min(1).max(128),
1478
+ userId: import_zod7.z.string().max(256).optional().nullable(),
1479
+ sessionId: import_zod7.z.string().max(128).optional().nullable(),
1480
+ message: import_zod7.z.string().trim().min(1).max(MAX_BUG_REPORT_LENGTH),
1481
+ email: import_zod7.z.string().trim().toLowerCase().email().max(254).optional().nullable(),
1482
+ name: import_zod7.z.string().trim().max(200).optional().nullable(),
1483
+ /** The exception event the report is about (the SDK sends the page's last error unless told otherwise). */
1484
+ associatedEventId: import_zod7.z.string().trim().max(64).optional().nullable(),
1485
+ url: import_zod7.z.string().max(2e3).optional().nullable(),
1486
+ appVersion: import_zod7.z.string().max(200).optional().nullable(),
1487
+ /** widget (the built-in dialog) or api (captureFeedback). */
1488
+ source: import_zod7.z.enum(["widget", "api"]).default("api"),
1489
+ tags: import_zod7.z.record(import_zod7.z.string().max(64), import_zod7.z.string().max(200)).optional(),
1490
+ sdk: import_zod7.z.object({ name: import_zod7.z.string().max(60), version: import_zod7.z.string().max(30) }).optional(),
1491
+ screenshot: import_zod7.z.object({
1492
+ fileName: import_zod7.z.string().trim().min(1).max(200),
1493
+ data: import_zod7.z.string().max(Math.ceil(MAX_BUG_REPORT_SCREENSHOT_BYTES * 4 / 3) + 64)
1494
+ }).optional().nullable()
1495
+ });
1496
+
1497
+ // src/agents.ts
1498
+ var import_zod8 = require("zod");
1499
+
1327
1500
  // src/agents-limits.ts
1328
1501
  var AGENT_TURN_ROLES = ["user", "assistant", "tool", "system"];
1329
1502
  var AGENT_OUTCOMES = ["success", "failure", "escalated", "abandoned"];
@@ -1336,51 +1509,51 @@ var AGENT_METADATA_MAX_BYTES = 4096;
1336
1509
  var SCOUT_AGENT_ID = "scout";
1337
1510
 
1338
1511
  // src/agents.ts
1339
- var ENVIRONMENTS = ["development", "staging", "production"];
1340
- var AgentToolCallSchema = import_zod7.z.object({
1341
- name: import_zod7.z.string().trim().min(1).max(100),
1342
- status: import_zod7.z.enum(AGENT_TOOL_STATUSES).optional(),
1343
- latencyMs: import_zod7.z.number().int().min(0).max(36e5).optional()
1512
+ var EnvironmentKey = import_zod8.z.string().trim().regex(/^[a-z][a-z0-9-]{0,29}$/, "environment: use an environment key such as production");
1513
+ var AgentToolCallSchema = import_zod8.z.object({
1514
+ name: import_zod8.z.string().trim().min(1).max(100),
1515
+ status: import_zod8.z.enum(AGENT_TOOL_STATUSES).optional(),
1516
+ latencyMs: import_zod8.z.number().int().min(0).max(36e5).optional()
1344
1517
  }).strip();
1345
- var AgentMetadataSchema = import_zod7.z.record(import_zod7.z.string().max(100), import_zod7.z.unknown()).transform((m) => {
1518
+ var AgentMetadataSchema = import_zod8.z.record(import_zod8.z.string().max(100), import_zod8.z.unknown()).transform((m) => {
1346
1519
  const out = {};
1347
- let size = 0;
1520
+ let size2 = 0;
1348
1521
  for (const [k, v] of Object.entries(m)) {
1349
1522
  const key = k.trim();
1350
1523
  if (!key || key.startsWith("$") || SENSITIVE_PROPERTY_PATTERN.test(key)) continue;
1351
1524
  if (!(typeof v === "string" || typeof v === "boolean" || v === null || typeof v === "number" && Number.isFinite(v))) continue;
1352
1525
  const value = typeof v === "string" ? v.slice(0, 500) : v;
1353
- size += key.length + String(value).length;
1354
- if (size > AGENT_METADATA_MAX_BYTES || Object.keys(out).length >= AGENT_METADATA_MAX_KEYS) break;
1526
+ size2 += key.length + String(value).length;
1527
+ if (size2 > AGENT_METADATA_MAX_BYTES || Object.keys(out).length >= AGENT_METADATA_MAX_KEYS) break;
1355
1528
  out[key] = value;
1356
1529
  }
1357
1530
  return out;
1358
1531
  });
1359
- var id = (max) => import_zod7.z.string().trim().min(1).max(max);
1360
- var optionalId = (max) => import_zod7.z.string().trim().max(max).optional().nullable().transform((v) => v || null);
1361
- var AgentTurnInputSchema = import_zod7.z.object({
1362
- type: import_zod7.z.literal("agent.conversation").optional(),
1532
+ var id = (max) => import_zod8.z.string().trim().min(1).max(max);
1533
+ var optionalId = (max) => import_zod8.z.string().trim().max(max).optional().nullable().transform((v) => v || null);
1534
+ var AgentTurnInputSchema = import_zod8.z.object({
1535
+ type: import_zod8.z.literal("agent.conversation").optional(),
1363
1536
  conversationId: id(128),
1364
1537
  agentId: id(64).refine((v) => v.toLowerCase() !== SCOUT_AGENT_ID, { message: `"${SCOUT_AGENT_ID}" is reserved for Guidely's built-in Scout agent` }),
1365
- agentName: import_zod7.z.string().trim().max(100).optional(),
1366
- turnId: import_zod7.z.string().trim().min(1).max(128).optional(),
1367
- role: import_zod7.z.enum(AGENT_TURN_ROLES),
1368
- text: import_zod7.z.string().max(AGENT_TURN_MAX_TEXT).default(""),
1369
- toolCalls: import_zod7.z.array(AgentToolCallSchema).max(AGENT_TOOL_CALLS_PER_TURN).default([]),
1370
- latencyMs: import_zod7.z.number().int().min(0).max(36e5).optional(),
1371
- outcome: import_zod7.z.enum(AGENT_OUTCOMES).optional(),
1372
- taskSuccess: import_zod7.z.boolean().optional(),
1373
- occurredAt: import_zod7.z.string().datetime({ offset: true }).optional(),
1538
+ agentName: import_zod8.z.string().trim().max(100).optional(),
1539
+ turnId: import_zod8.z.string().trim().min(1).max(128).optional(),
1540
+ role: import_zod8.z.enum(AGENT_TURN_ROLES),
1541
+ text: import_zod8.z.string().max(AGENT_TURN_MAX_TEXT).default(""),
1542
+ toolCalls: import_zod8.z.array(AgentToolCallSchema).max(AGENT_TOOL_CALLS_PER_TURN).default([]),
1543
+ latencyMs: import_zod8.z.number().int().min(0).max(36e5).optional(),
1544
+ outcome: import_zod8.z.enum(AGENT_OUTCOMES).optional(),
1545
+ taskSuccess: import_zod8.z.boolean().optional(),
1546
+ occurredAt: import_zod8.z.string().datetime({ offset: true }).optional(),
1374
1547
  userId: optionalId(256),
1375
1548
  anonymousId: optionalId(128),
1376
1549
  accountId: optionalId(256),
1377
1550
  sessionId: optionalId(128),
1378
1551
  metadata: AgentMetadataSchema.default({})
1379
1552
  });
1380
- var turns = import_zod7.z.array(AgentTurnInputSchema).min(1).max(AGENT_TURNS_PER_BATCH);
1381
- var sdkInfo = import_zod7.z.object({ name: import_zod7.z.string().max(60), version: import_zod7.z.string().max(30) }).optional();
1382
- var SdkAgentEventsSchema = import_zod7.z.object({ turns, sdk: sdkInfo });
1383
- var AgentEventsRequestSchema = import_zod7.z.preprocess(
1553
+ var turns = import_zod8.z.array(AgentTurnInputSchema).min(1).max(AGENT_TURNS_PER_BATCH);
1554
+ var sdkInfo = import_zod8.z.object({ name: import_zod8.z.string().max(60), version: import_zod8.z.string().max(30) }).optional();
1555
+ var SdkAgentEventsSchema = import_zod8.z.object({ turns, sdk: sdkInfo });
1556
+ var AgentEventsRequestSchema = import_zod8.z.preprocess(
1384
1557
  (v) => {
1385
1558
  if (Array.isArray(v)) return { turns: v };
1386
1559
  if (v && typeof v === "object" && !("turns" in v)) {
@@ -1389,11 +1562,11 @@ var AgentEventsRequestSchema = import_zod7.z.preprocess(
1389
1562
  }
1390
1563
  return v;
1391
1564
  },
1392
- import_zod7.z.object({ turns, environment: import_zod7.z.enum(ENVIRONMENTS).default("production"), sdk: sdkInfo })
1565
+ import_zod8.z.object({ turns, environment: EnvironmentKey.default("production"), sdk: sdkInfo })
1393
1566
  );
1394
1567
 
1395
1568
  // src/feedback.ts
1396
- var import_zod8 = require("zod");
1569
+ var import_zod9 = require("zod");
1397
1570
 
1398
1571
  // src/feedback-limits.ts
1399
1572
  var FEEDBACK_STATUSES = ["new", "under_review", "planned", "in_progress", "released", "declined"];
@@ -1417,60 +1590,79 @@ var feedbackReference = (number) => `#${number}`;
1417
1590
 
1418
1591
  // src/feedback.ts
1419
1592
  var visitor = {
1420
- anonymousId: import_zod8.z.string().min(1).max(128),
1421
- userId: import_zod8.z.string().max(256).optional().nullable()
1593
+ anonymousId: import_zod9.z.string().min(1).max(128),
1594
+ userId: import_zod9.z.string().max(256).optional().nullable()
1422
1595
  };
1423
- var FeedbackListRequestSchema = import_zod8.z.object({
1596
+ var FeedbackListRequestSchema = import_zod9.z.object({
1424
1597
  ...visitor,
1425
- q: import_zod8.z.string().trim().max(200).optional(),
1426
- sort: import_zod8.z.enum(["top", "new", "trending"]).default("top"),
1427
- status: import_zod8.z.enum(FEEDBACK_STATUSES).optional(),
1598
+ q: import_zod9.z.string().trim().max(200).optional(),
1599
+ sort: import_zod9.z.enum(["top", "new", "trending"]).default("top"),
1600
+ status: import_zod9.z.enum(FEEDBACK_STATUSES).optional(),
1428
1601
  /** "open" = not released or declined. */
1429
- filter: import_zod8.z.enum(["open", "all", "mine", "following"]).default("open"),
1430
- productArea: import_zod8.z.string().trim().max(60).optional(),
1431
- page: import_zod8.z.number().int().min(1).max(100).default(1)
1602
+ filter: import_zod9.z.enum(["open", "all", "mine", "following"]).default("open"),
1603
+ productArea: import_zod9.z.string().trim().max(60).optional(),
1604
+ page: import_zod9.z.number().int().min(1).max(100).default(1)
1432
1605
  });
1433
- var FeedbackVisitorSchema = import_zod8.z.object(visitor);
1434
- var SubmitFeedbackSchema = import_zod8.z.object({
1606
+ var FeedbackVisitorSchema = import_zod9.z.object(visitor);
1607
+ var SubmitFeedbackSchema = import_zod9.z.object({
1435
1608
  ...visitor,
1436
- title: import_zod8.z.string().trim().min(3, "Give your idea a short title").max(MAX_FEEDBACK_TITLE),
1437
- description: import_zod8.z.string().trim().max(MAX_FEEDBACK_DESCRIPTION).default(""),
1438
- productArea: import_zod8.z.string().trim().max(60).optional().nullable(),
1439
- priority: import_zod8.z.enum(FEEDBACK_PRIORITIES).default("nice_to_have"),
1609
+ title: import_zod9.z.string().trim().min(3, "Give your idea a short title").max(MAX_FEEDBACK_TITLE),
1610
+ description: import_zod9.z.string().trim().max(MAX_FEEDBACK_DESCRIPTION).default(""),
1611
+ productArea: import_zod9.z.string().trim().max(60).optional().nullable(),
1612
+ priority: import_zod9.z.enum(FEEDBACK_PRIORITIES).default("nice_to_have"),
1440
1613
  /** Filed from this Scout conversation (Scout offered it). */
1441
- conversationId: import_zod8.z.string().min(1).max(64).optional().nullable(),
1442
- pageUrl: import_zod8.z.string().max(2e3).optional()
1614
+ conversationId: import_zod9.z.string().min(1).max(64).optional().nullable(),
1615
+ pageUrl: import_zod9.z.string().max(2e3).optional()
1443
1616
  });
1444
- var FeedbackVoteSchema = import_zod8.z.object({
1617
+ var FeedbackVoteSchema = import_zod9.z.object({
1445
1618
  ...visitor,
1446
- priority: import_zod8.z.enum(FEEDBACK_PRIORITIES).default("nice_to_have"),
1447
- note: import_zod8.z.string().trim().max(MAX_FEEDBACK_NOTE).optional(),
1448
- conversationId: import_zod8.z.string().min(1).max(64).optional().nullable()
1619
+ priority: import_zod9.z.enum(FEEDBACK_PRIORITIES).default("nice_to_have"),
1620
+ note: import_zod9.z.string().trim().max(MAX_FEEDBACK_NOTE).optional(),
1621
+ conversationId: import_zod9.z.string().min(1).max(64).optional().nullable()
1449
1622
  });
1450
- var FeedbackFollowSchema = import_zod8.z.object({ ...visitor, follow: import_zod8.z.boolean() });
1451
- var FeedbackCommentSchema = import_zod8.z.object({ ...visitor, body: import_zod8.z.string().trim().min(1).max(MAX_FEEDBACK_COMMENT) });
1452
- var FeedbackSimilarSchema = import_zod8.z.object({ ...visitor, title: import_zod8.z.string().trim().min(3).max(MAX_FEEDBACK_TITLE) });
1453
- var FeedbackUpdatesReadSchema = import_zod8.z.object({ ...visitor, ids: import_zod8.z.array(import_zod8.z.string().min(1).max(64)).max(100).optional() });
1623
+ var FeedbackFollowSchema = import_zod9.z.object({ ...visitor, follow: import_zod9.z.boolean() });
1624
+ var FeedbackCommentSchema = import_zod9.z.object({ ...visitor, body: import_zod9.z.string().trim().min(1).max(MAX_FEEDBACK_COMMENT) });
1625
+ var FeedbackSimilarSchema = import_zod9.z.object({ ...visitor, title: import_zod9.z.string().trim().min(3).max(MAX_FEEDBACK_TITLE) });
1626
+ var FeedbackUpdatesReadSchema = import_zod9.z.object({ ...visitor, ids: import_zod9.z.array(import_zod9.z.string().min(1).max(64)).max(100).optional() });
1454
1627
 
1455
1628
  // src/capture.ts
1456
- var import_zod9 = require("zod");
1457
- var AutocaptureSettingsSchema = import_zod9.z.object({ pageviews: import_zod9.z.boolean(), pageLeave: import_zod9.z.boolean(), clicks: import_zod9.z.boolean(), rageClicks: import_zod9.z.boolean(), heatmaps: import_zod9.z.boolean(), mouseMovement: import_zod9.z.boolean(), appLifecycle: import_zod9.z.boolean() }).partial();
1458
- var ErrorTrackingSettingsSchema = import_zod9.z.object({ enabled: import_zod9.z.boolean() }).partial();
1459
- var ReplaySettingsSchema = import_zod9.z.object({
1460
- enabled: import_zod9.z.boolean(),
1461
- sampleRate: import_zod9.z.number().int().min(0).max(100),
1462
- recordConsole: import_zod9.z.boolean(),
1463
- recordNetwork: import_zod9.z.boolean(),
1464
- recordNetworkPayloads: import_zod9.z.boolean(),
1465
- maskAllText: import_zod9.z.boolean(),
1466
- blockSelectors: import_zod9.z.array(import_zod9.z.string().min(1).max(200)).max(50),
1467
- retentionDays: import_zod9.z.number().int().min(1).max(365)
1629
+ var import_zod10 = require("zod");
1630
+ var AutocaptureSettingsSchema = import_zod10.z.object({ pageviews: import_zod10.z.boolean(), pageLeave: import_zod10.z.boolean(), clicks: import_zod10.z.boolean(), rageClicks: import_zod10.z.boolean(), heatmaps: import_zod10.z.boolean(), mouseMovement: import_zod10.z.boolean(), appLifecycle: import_zod10.z.boolean() }).partial();
1631
+ var ErrorTrackingSettingsSchema = import_zod10.z.object({ enabled: import_zod10.z.boolean() }).partial();
1632
+ var PerformanceSettingsSchema = import_zod10.z.object({ enabled: import_zod10.z.boolean(), sampleRate: import_zod10.z.number().min(0).max(100) }).partial();
1633
+ var ReplaySettingsSchema = import_zod10.z.object({
1634
+ enabled: import_zod10.z.boolean(),
1635
+ sampleRate: import_zod10.z.number().int().min(0).max(100),
1636
+ recordConsole: import_zod10.z.boolean(),
1637
+ recordNetwork: import_zod10.z.boolean(),
1638
+ recordNetworkPayloads: import_zod10.z.boolean(),
1639
+ maskAllText: import_zod10.z.boolean(),
1640
+ blockSelectors: import_zod10.z.array(import_zod10.z.string().min(1).max(200)).max(50),
1641
+ retentionDays: import_zod10.z.number().int().min(1).max(365)
1468
1642
  }).partial();
1469
1643
  var DEFAULT_CAPTURE_SETTINGS = {
1470
1644
  autocapture: { pageviews: true, pageLeave: true, clicks: true, rageClicks: true, heatmaps: true, mouseMovement: true, appLifecycle: true },
1471
1645
  errorTracking: { enabled: true },
1646
+ performance: { enabled: false, sampleRate: 100 },
1472
1647
  replay: { enabled: false, sampleRate: 100, recordConsole: true, recordNetwork: true, recordNetworkPayloads: false, maskAllText: false, blockSelectors: [], retentionDays: 30 }
1473
1648
  };
1649
+ var RECORDING_LEVELS = ["off", "privacy", "standard", "full"];
1650
+ var RECORDING_PRESETS = {
1651
+ privacy: { maskAllText: true, recordConsole: false, recordNetwork: false, recordNetworkPayloads: false },
1652
+ standard: { maskAllText: false, recordConsole: true, recordNetwork: true, recordNetworkPayloads: false },
1653
+ full: { maskAllText: false, recordConsole: true, recordNetwork: true, recordNetworkPayloads: true }
1654
+ };
1655
+ function recordingLevel(replay) {
1656
+ if (!replay.enabled) return "off";
1657
+ for (const level of ["privacy", "standard", "full"]) {
1658
+ const preset = RECORDING_PRESETS[level];
1659
+ if (Object.keys(preset).every((k) => replay[k] === preset[k])) return level;
1660
+ }
1661
+ return "custom";
1662
+ }
1663
+ function withRecordingLevel(replay, level) {
1664
+ return level === "off" ? { ...replay, enabled: false } : { ...replay, ...RECORDING_PRESETS[level], enabled: true };
1665
+ }
1474
1666
  function resolveCaptureSettings(settings) {
1475
1667
  const s = settings && typeof settings === "object" ? settings : {};
1476
1668
  const obj = (v) => v && typeof v === "object" && !Array.isArray(v) ? v : {};
@@ -1478,25 +1670,29 @@ function resolveCaptureSettings(settings) {
1478
1670
  const a = AutocaptureSettingsSchema.safeParse(obj(s.autocapture));
1479
1671
  const e = ErrorTrackingSettingsSchema.safeParse(obj(s.errorTracking));
1480
1672
  const r = ReplaySettingsSchema.safeParse(obj(s.replay));
1673
+ const p = PerformanceSettingsSchema.safeParse(obj(s.performance));
1481
1674
  return {
1482
1675
  autocapture: { ...d.autocapture, ...a.success ? a.data : {} },
1483
1676
  errorTracking: { ...d.errorTracking, ...e.success ? e.data : {} },
1484
- replay: { ...d.replay, ...r.success ? r.data : {} }
1677
+ replay: { ...d.replay, ...r.success ? r.data : {} },
1678
+ performance: { ...d.performance, ...p.success ? p.data : {} }
1485
1679
  };
1486
1680
  }
1487
1681
  var HEATMAP_VIEWPORTS = { mobile: [0, 767], tablet: [768, 1279], desktop: [1280, 1e5] };
1488
- var ReplayChunkSchema = import_zod9.z.object({
1489
- sessionId: import_zod9.z.string().min(1).max(128),
1490
- windowId: import_zod9.z.string().min(1).max(64),
1491
- seq: import_zod9.z.number().int().min(0).max(1e6),
1492
- anonymousId: import_zod9.z.string().min(1).max(128),
1493
- userId: import_zod9.z.string().max(256).optional().nullable(),
1682
+ var ReplayChunkSchema = import_zod10.z.object({
1683
+ sessionId: import_zod10.z.string().min(1).max(128),
1684
+ windowId: import_zod10.z.string().min(1).max(64),
1685
+ seq: import_zod10.z.number().int().min(0).max(1e6),
1686
+ anonymousId: import_zod10.z.string().min(1).max(128),
1687
+ userId: import_zod10.z.string().max(256).optional().nullable(),
1494
1688
  /** rrweb `eventWithTime` objects, in order. */
1495
- events: import_zod9.z.array(import_zod9.z.object({ type: import_zod9.z.number().int(), timestamp: import_zod9.z.number() }).passthrough()).min(1).max(5e4),
1496
- url: import_zod9.z.string().max(2e3).optional(),
1497
- device: import_zod9.z.object({ type: import_zod9.z.string().max(20), browser: import_zod9.z.string().max(40).optional(), os: import_zod9.z.string().max(40).optional() }).optional(),
1498
- viewport: import_zod9.z.object({ width: import_zod9.z.number().int().min(0).max(1e5), height: import_zod9.z.number().int().min(0).max(1e5) }).optional(),
1499
- sdk: import_zod9.z.object({ name: import_zod9.z.string().max(60), version: import_zod9.z.string().max(30) }).optional()
1689
+ events: import_zod10.z.array(import_zod10.z.object({ type: import_zod10.z.number().int(), timestamp: import_zod10.z.number() }).passthrough()).min(1).max(5e4),
1690
+ url: import_zod10.z.string().max(2e3).optional(),
1691
+ device: import_zod10.z.object({ type: import_zod10.z.string().max(20), browser: import_zod10.z.string().max(40).optional(), os: import_zod10.z.string().max(40).optional() }).optional(),
1692
+ viewport: import_zod10.z.object({ width: import_zod10.z.number().int().min(0).max(1e5), height: import_zod10.z.number().int().min(0).max(1e5) }).optional(),
1693
+ sdk: import_zod10.z.object({ name: import_zod10.z.string().max(60), version: import_zod10.z.string().max(30) }).optional(),
1694
+ /** The app's version (`appVersion` SDK option); recordings can be filtered by it. */
1695
+ appVersion: import_zod10.z.string().max(200).optional()
1500
1696
  });
1501
1697
  var REPLAY_MAX_COMPRESSED_BYTES = 2 * 1024 * 1024;
1502
1698
  var REPLAY_MAX_RAW_BYTES = 16 * 1024 * 1024;
@@ -1813,6 +2009,19 @@ function isSafeMediaUrl(url) {
1813
2009
  return false;
1814
2010
  }
1815
2011
  }
2012
+ function videoThumbnailUrl(url) {
2013
+ const embed = url ? toEmbedUrl(url) : null;
2014
+ if (embed?.provider !== "youtube") return null;
2015
+ const id2 = embed.src.split("/embed/")[1]?.split("?")[0];
2016
+ return id2 ? `https://i.ytimg.com/vi/${id2}/hqdefault.jpg` : null;
2017
+ }
2018
+ function isVideoFileUrl(url) {
2019
+ return isSafeMediaUrl(url) && /\.(mp4|webm|m4v|mov|ogv)$/i.test(new URL(url).pathname);
2020
+ }
2021
+ function stepVideo(step) {
2022
+ if (!step.videoUrl || !isSafeMediaUrl(step.videoUrl)) return null;
2023
+ return { url: step.videoUrl, poster: (step.imageUrl && isSafeMediaUrl(step.imageUrl) ? step.imageUrl : null) ?? videoThumbnailUrl(step.videoUrl) };
2024
+ }
1816
2025
 
1817
2026
  // src/resource-center.ts
1818
2027
  var MAX_COLLECTION_DEPTH = 3;
@@ -1935,9 +2144,19 @@ function unreadAnnouncements(items, lastSeenAt) {
1935
2144
  if (Number.isNaN(seen)) return items.length;
1936
2145
  return items.filter((a) => Date.parse(a.publishedAt) > seen).length;
1937
2146
  }
2147
+ var ARTICLE_HREF_PREFIX = "#guidely-article:";
2148
+ var ARTICLE_ID = /^[A-Za-z0-9_-]{1,64}$/;
2149
+ function articleHref(articleId) {
2150
+ return `${ARTICLE_HREF_PREFIX}${articleId}`;
2151
+ }
2152
+ function articleIdFromHref(href) {
2153
+ if (!href || !href.startsWith(ARTICLE_HREF_PREFIX)) return null;
2154
+ const id2 = href.slice(ARTICLE_HREF_PREFIX.length);
2155
+ return ARTICLE_ID.test(id2) ? id2 : null;
2156
+ }
1938
2157
 
1939
2158
  // src/howto.ts
1940
- var import_zod10 = require("zod");
2159
+ var import_zod11 = require("zod");
1941
2160
 
1942
2161
  // src/howto-limits.ts
1943
2162
  var CAPTURE_PARAM = "guidely_capture";
@@ -1946,36 +2165,36 @@ var CAPTURE_SCREENSHOT_MAX_BYTES = 8 * 1024 * 1024;
1946
2165
  // src/howto.ts
1947
2166
  var HOWTO_STEP_KINDS = ["action", "text", "heading", "tip", "alert"];
1948
2167
  var HOWTO_ACTIONS = ["click", "type", "select", "navigate"];
1949
- var NormalizedRectSchema = import_zod10.z.object({
1950
- x: import_zod10.z.number().min(0).max(1),
1951
- y: import_zod10.z.number().min(0).max(1),
1952
- width: import_zod10.z.number().min(0).max(1),
1953
- height: import_zod10.z.number().min(0).max(1)
2168
+ var NormalizedRectSchema = import_zod11.z.object({
2169
+ x: import_zod11.z.number().min(0).max(1),
2170
+ y: import_zod11.z.number().min(0).max(1),
2171
+ width: import_zod11.z.number().min(0).max(1),
2172
+ height: import_zod11.z.number().min(0).max(1)
1954
2173
  });
1955
- var CapturedElementSchema = import_zod10.z.object({
2174
+ var CapturedElementSchema = import_zod11.z.object({
1956
2175
  /** Visible name: aria-label, associated label, text, placeholder, alt or title. */
1957
- label: import_zod10.z.string().max(200).default(""),
2176
+ label: import_zod11.z.string().max(200).default(""),
1958
2177
  /** button, link, tab, menuitem, checkbox, radio, field, dropdown, option, element… */
1959
- role: import_zod10.z.string().max(40).default("element"),
1960
- tag: import_zod10.z.string().max(40).default("")
2178
+ role: import_zod11.z.string().max(40).default("element"),
2179
+ tag: import_zod11.z.string().max(40).default("")
1961
2180
  });
1962
- var CaptureStepSchema = import_zod10.z.object({
2181
+ var CaptureStepSchema = import_zod11.z.object({
1963
2182
  /** Random id from the SDK; a retried upload with the same id is stored once. */
1964
- clientId: import_zod10.z.string().min(1).max(64),
1965
- action: import_zod10.z.enum(HOWTO_ACTIONS),
1966
- url: import_zod10.z.string().max(2e3),
1967
- pageTitle: import_zod10.z.string().max(300).default(""),
2183
+ clientId: import_zod11.z.string().min(1).max(64),
2184
+ action: import_zod11.z.enum(HOWTO_ACTIONS),
2185
+ url: import_zod11.z.string().max(2e3),
2186
+ pageTitle: import_zod11.z.string().max(300).default(""),
1968
2187
  element: CapturedElementSchema.optional(),
1969
2188
  /** Typed text or chosen option; absent when it was sensitive (`valueRedacted`). */
1970
- value: import_zod10.z.string().max(200).optional(),
1971
- valueRedacted: import_zod10.z.boolean().default(false),
2189
+ value: import_zod11.z.string().max(200).optional(),
2190
+ valueRedacted: import_zod11.z.boolean().default(false),
1972
2191
  /** Selectors for the element, so the step can later become an interactive tour step. */
1973
- selectors: import_zod10.z.array(SelectorStrategySchema).max(10).default([]),
2192
+ selectors: import_zod11.z.array(SelectorStrategySchema).max(10).default([]),
1974
2193
  /** Where the element sits in the screenshot. */
1975
2194
  highlight: NormalizedRectSchema.optional(),
1976
2195
  /** Number of regions the SDK blurred in the screenshot before upload. */
1977
- redactions: import_zod10.z.number().int().min(0).max(1e3).default(0),
1978
- occurredAt: import_zod10.z.string().datetime().optional()
2196
+ redactions: import_zod11.z.number().int().min(0).max(1e3).default(0),
2197
+ occurredAt: import_zod11.z.string().datetime().optional()
1979
2198
  });
1980
2199
  function quoted(s) {
1981
2200
  const t = (s ?? "").replace(/\s+/g, " ").trim();
@@ -2046,12 +2265,12 @@ function hostAndPath(url) {
2046
2265
  return url.slice(0, 80);
2047
2266
  }
2048
2267
  }
2049
- var NormalizedPointSchema = import_zod10.z.object({ x: import_zod10.z.number().min(0).max(1), y: import_zod10.z.number().min(0).max(1) });
2268
+ var NormalizedPointSchema = import_zod11.z.object({ x: import_zod11.z.number().min(0).max(1), y: import_zod11.z.number().min(0).max(1) });
2050
2269
  var ANNOTATION_COLORS = ["brand", "red", "amber", "green", "black", "white"];
2051
- var HowToAnnotationSchema = import_zod10.z.discriminatedUnion("type", [
2052
- import_zod10.z.object({ id: import_zod10.z.string().min(1).max(32), type: import_zod10.z.literal("arrow"), from: NormalizedPointSchema, to: NormalizedPointSchema, color: import_zod10.z.enum(ANNOTATION_COLORS).default("brand") }),
2053
- import_zod10.z.object({ id: import_zod10.z.string().min(1).max(32), type: import_zod10.z.literal("text"), at: NormalizedPointSchema, text: import_zod10.z.string().trim().min(1).max(120), color: import_zod10.z.enum(ANNOTATION_COLORS).default("brand") }),
2054
- import_zod10.z.object({ id: import_zod10.z.string().min(1).max(32), type: import_zod10.z.literal("box"), rect: NormalizedRectSchema, color: import_zod10.z.enum(ANNOTATION_COLORS).default("brand") })
2270
+ var HowToAnnotationSchema = import_zod11.z.discriminatedUnion("type", [
2271
+ import_zod11.z.object({ id: import_zod11.z.string().min(1).max(32), type: import_zod11.z.literal("arrow"), from: NormalizedPointSchema, to: NormalizedPointSchema, color: import_zod11.z.enum(ANNOTATION_COLORS).default("brand") }),
2272
+ import_zod11.z.object({ id: import_zod11.z.string().min(1).max(32), type: import_zod11.z.literal("text"), at: NormalizedPointSchema, text: import_zod11.z.string().trim().min(1).max(120), color: import_zod11.z.enum(ANNOTATION_COLORS).default("brand") }),
2273
+ import_zod11.z.object({ id: import_zod11.z.string().min(1).max(32), type: import_zod11.z.literal("box"), rect: NormalizedRectSchema, color: import_zod11.z.enum(ANNOTATION_COLORS).default("brand") })
2055
2274
  ]);
2056
2275
  var MAX_ANNOTATIONS = 30;
2057
2276
 
@@ -2653,6 +2872,16 @@ var SCRIPT_STUB_METHODS = [
2653
2872
  "openComplaint",
2654
2873
  "openIdeas",
2655
2874
  "captureException",
2875
+ "captureFeedback",
2876
+ "showBugReport",
2877
+ "captureMessage",
2878
+ "addBreadcrumb",
2879
+ "setTag",
2880
+ "setTags",
2881
+ "setExtra",
2882
+ "setExtras",
2883
+ "setContext",
2884
+ "setUser",
2656
2885
  "agentConversation",
2657
2886
  "trackAgentTurn",
2658
2887
  "on"
@@ -3184,7 +3413,7 @@ function parseTranslationCsv(text) {
3184
3413
 
3185
3414
  // src/index.ts
3186
3415
  var SDK_API_VERSION = "v1";
3187
- var SHARED_VERSION = "0.15.0";
3416
+ var SHARED_VERSION = "0.17.0";
3188
3417
  // Annotate the CommonJS export names for ESM import in node:
3189
3418
  0 && (module.exports = {
3190
3419
  ADVANCE_ON,
@@ -3198,6 +3427,7 @@ var SHARED_VERSION = "0.15.0";
3198
3427
  AGENT_TURN_ROLES,
3199
3428
  ANNOTATION_COLORS,
3200
3429
  APP_LIFECYCLE_EVENTS,
3430
+ ARTICLE_HREF_PREFIX,
3201
3431
  ARTICLE_VISIBILITIES,
3202
3432
  AUTOCAPTURE_EVENTS,
3203
3433
  AgentEventsRequestSchema,
@@ -3208,6 +3438,7 @@ var SHARED_VERSION = "0.15.0";
3208
3438
  AuthoringPickSchema,
3209
3439
  AutocaptureSettingsSchema,
3210
3440
  BUTTON_ACTIONS,
3441
+ BugReportSchema,
3211
3442
  ButtonSchema,
3212
3443
  CAPTURE_PARAM,
3213
3444
  CAPTURE_SCREENSHOT_MAX_BYTES,
@@ -3273,6 +3504,10 @@ var SHARED_VERSION = "0.15.0";
3273
3504
  LocaleSchema,
3274
3505
  LocalizationSettingsSchema,
3275
3506
  MAX_ANNOTATIONS,
3507
+ MAX_APP_VERSION_LENGTH,
3508
+ MAX_BREADCRUMBS,
3509
+ MAX_BUG_REPORT_LENGTH,
3510
+ MAX_BUG_REPORT_SCREENSHOT_BYTES,
3276
3511
  MAX_COLLECTION_DEPTH,
3277
3512
  MAX_COMPLAINT_ANSWER_LENGTH,
3278
3513
  MAX_COMPLAINT_ATTACHMENT_BYTES,
@@ -3280,6 +3515,13 @@ var SHARED_VERSION = "0.15.0";
3280
3515
  MAX_COMPLAINT_FIELDS,
3281
3516
  MAX_COMPLAINT_LENGTH,
3282
3517
  MAX_CUSTOM_CSS,
3518
+ MAX_DEBUG_IMAGES,
3519
+ MAX_DETAIL_FRAMES,
3520
+ MAX_DETAIL_THREADS,
3521
+ MAX_ERROR_TAGS,
3522
+ MAX_EXCEPTION_CHAIN,
3523
+ MAX_EXCEPTION_DETAIL_BYTES,
3524
+ MAX_EXCEPTION_DETAIL_RAW_BYTES,
3283
3525
  MAX_FEEDBACK_COMMENT,
3284
3526
  MAX_FEEDBACK_DESCRIPTION,
3285
3527
  MAX_FEEDBACK_NOTE,
@@ -3307,11 +3549,13 @@ var SHARED_VERSION = "0.15.0";
3307
3549
  PDF_PAGES_CLASS,
3308
3550
  PLACEMENTS,
3309
3551
  PLATFORMS,
3552
+ PerformanceSettingsSchema,
3310
3553
  PostMessageSchema,
3311
3554
  ProjectThemeSchema,
3312
3555
  PublishedGuideSchema,
3313
3556
  RC_MODULE_IDS,
3314
3557
  RC_MODULE_LABELS,
3558
+ RECORDING_LEVELS,
3315
3559
  REPLAY_MAX_COMPRESSED_BYTES,
3316
3560
  REPLAY_MAX_RAW_BYTES,
3317
3561
  REPLY_TIMES,
@@ -3361,6 +3605,8 @@ var SHARED_VERSION = "0.15.0";
3361
3605
  WS_MAX_MESSAGES_PER_SOCKET,
3362
3606
  WS_MAX_MESSAGE_BYTES,
3363
3607
  applyGuideTranslations,
3608
+ articleHref,
3609
+ articleIdFromHref,
3364
3610
  articleTextEntries,
3365
3611
  assignGuideVariant,
3366
3612
  baseLanguage,
@@ -3373,11 +3619,13 @@ var SHARED_VERSION = "0.15.0";
3373
3619
  contrastIssues,
3374
3620
  contrastRatio,
3375
3621
  cssSelectorError,
3622
+ customFingerprint,
3376
3623
  defaultGuideConfig,
3377
3624
  defaultStep,
3378
3625
  describeCaptureStep,
3379
3626
  describeRule,
3380
3627
  emptyRuleGroup,
3628
+ errorFilterDrops,
3381
3629
  evaluateRule,
3382
3630
  evaluateRules,
3383
3631
  evenWeights,
@@ -3407,6 +3655,7 @@ var SHARED_VERSION = "0.15.0";
3407
3655
  isRuleGroup,
3408
3656
  isSafeMediaUrl,
3409
3657
  isVideoContentType,
3658
+ isVideoFileUrl,
3410
3659
  localeName,
3411
3660
  localizeAnnouncement,
3412
3661
  localizeArticle,
@@ -3419,10 +3668,12 @@ var SHARED_VERSION = "0.15.0";
3419
3668
  mediaKind,
3420
3669
  mediaMaxBytes,
3421
3670
  needsReview,
3671
+ normalizeAppVersion,
3422
3672
  normalizeErrorMessage,
3423
3673
  normalizeFrameFile,
3424
3674
  normalizeLocale,
3425
3675
  normalizeSnapshot,
3676
+ normalizeTags,
3426
3677
  orderedModules,
3427
3678
  pageLabel,
3428
3679
  pageName,
@@ -3440,7 +3691,9 @@ var SHARED_VERSION = "0.15.0";
3440
3691
  propertyAttributeAllowed,
3441
3692
  queryConditionRegex,
3442
3693
  randomId,
3694
+ reactNativeBundleUrl,
3443
3695
  readableTextOn,
3696
+ recordingLevel,
3444
3697
  relativeLuminance,
3445
3698
  resolveCaptureSettings,
3446
3699
  resolveLocale,
@@ -3461,6 +3714,7 @@ var SHARED_VERSION = "0.15.0";
3461
3714
  slugify,
3462
3715
  snapshotFromSelector,
3463
3716
  stableStringify,
3717
+ stepVideo,
3464
3718
  stripOrigin,
3465
3719
  supportsPlatform,
3466
3720
  templateConfig,
@@ -3468,16 +3722,19 @@ var SHARED_VERSION = "0.15.0";
3468
3722
  toTranslationCsv,
3469
3723
  toXliff,
3470
3724
  translationCoverage,
3725
+ trimExceptionDetail,
3471
3726
  unreadAnnouncements,
3472
3727
  validateGuideConfig,
3473
3728
  variantProblems,
3474
3729
  variantRanges,
3730
+ videoThumbnailUrl,
3475
3731
  visibleAnnouncements,
3476
3732
  visibleArticleIds,
3477
3733
  visibleButtons,
3478
3734
  visitorAudiences,
3479
3735
  visitorLocales,
3480
3736
  withExperimentBucket,
3737
+ withRecordingLevel,
3481
3738
  withVisibility
3482
3739
  });
3483
3740
  //# sourceMappingURL=index.cjs.map