@mushi-mushi/core 1.15.0 → 1.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.js CHANGED
@@ -41,6 +41,9 @@ function formatBytes(n) {
41
41
  }
42
42
 
43
43
  // src/api-client.ts
44
+ var MUSHI_USER_TOKEN_HEADER = "X-Mushi-User-Token";
45
+ var MUSHI_SDK_PACKAGE_HEADER = "X-Mushi-SDK-Package";
46
+ var MUSHI_SDK_VERSION_HEADER = "X-Mushi-SDK-Version";
44
47
  var DEFAULT_API_ENDPOINT = "https://dxptnwrhwsqckaftyymj.supabase.co/functions/v1/api";
45
48
  var MUSHI_INTERNAL_HEADER = "X-Mushi-Internal";
46
49
  var MUSHI_INTERNAL_INIT_MARKER = "__mushiInternal";
@@ -52,13 +55,17 @@ function createApiClient(options) {
52
55
  apiKey,
53
56
  apiEndpoint = DEFAULT_API_ENDPOINT,
54
57
  timeout = DEFAULT_TIMEOUT,
55
- maxRetries = DEFAULT_MAX_RETRIES
58
+ maxRetries = DEFAULT_MAX_RETRIES,
59
+ getUserToken,
60
+ sdkPackage,
61
+ sdkVersion
56
62
  } = options;
57
63
  let baseUrl = apiEndpoint.replace(/\/$/, "");
58
64
  async function request(method, path, body, retries = maxRetries, internalKind, extraHeaders) {
59
65
  const url = `${baseUrl}${path}`;
60
66
  const controller = new AbortController();
61
67
  const timer = setTimeout(() => controller.abort(), timeout);
68
+ const userToken = getUserToken?.() ?? null;
62
69
  try {
63
70
  const response = await fetch(url, {
64
71
  method,
@@ -66,6 +73,9 @@ function createApiClient(options) {
66
73
  "Content-Type": "application/json",
67
74
  "X-Mushi-Api-Key": apiKey,
68
75
  "X-Mushi-Project": projectId,
76
+ ...sdkPackage ? { [MUSHI_SDK_PACKAGE_HEADER]: sdkPackage } : {},
77
+ ...sdkVersion ? { [MUSHI_SDK_VERSION_HEADER]: sdkVersion } : {},
78
+ ...userToken ? { [MUSHI_USER_TOKEN_HEADER]: userToken } : {},
69
79
  ...internalKind ? { [MUSHI_INTERNAL_HEADER]: internalKind } : {},
70
80
  ...extraHeaders
71
81
  },
@@ -127,6 +137,8 @@ function createApiClient(options) {
127
137
  "Content-Type": "application/json",
128
138
  "X-Mushi-Api-Key": apiKey,
129
139
  "X-Mushi-Project": projectId,
140
+ ...sdkPackage ? { [MUSHI_SDK_PACKAGE_HEADER]: sdkPackage } : {},
141
+ ...sdkVersion ? { [MUSHI_SDK_VERSION_HEADER]: sdkVersion } : {},
130
142
  [MUSHI_INTERNAL_HEADER]: "reporter-poll",
131
143
  "X-Reporter-Token-Hash": tokenHash,
132
144
  "X-Reporter-Ts": ts,
@@ -168,6 +180,19 @@ function createApiClient(options) {
168
180
  async getSdkConfig() {
169
181
  return request("GET", "/v1/sdk/config", void 0, maxRetries, "sdk-config");
170
182
  },
183
+ async askAssistant(input) {
184
+ return request(
185
+ "POST",
186
+ "/v1/sdk/assistant",
187
+ {
188
+ message: input.message,
189
+ threadId: input.threadId ?? null,
190
+ context: input.context ?? null
191
+ },
192
+ 1,
193
+ "community"
194
+ );
195
+ },
171
196
  async getLatestSdkVersion(packageName) {
172
197
  const query = new URLSearchParams({ package: packageName }).toString();
173
198
  return request("GET", `/v1/sdk/latest-version?${query}`, void 0, maxRetries, "sdk-config");
@@ -445,6 +470,60 @@ function writeCache(storage, projectId, entry) {
445
470
  }
446
471
  }
447
472
 
473
+ // src/env-config.ts
474
+ function first(...values) {
475
+ return values.find((v) => v !== void 0 && v !== "");
476
+ }
477
+ function tryImportMetaEnv(key) {
478
+ try {
479
+ const env = import.meta.env;
480
+ return typeof env === "object" && env !== null ? env[key] : void 0;
481
+ } catch {
482
+ return void 0;
483
+ }
484
+ }
485
+ function readProcessEnv(read) {
486
+ try {
487
+ return read();
488
+ } catch {
489
+ return void 0;
490
+ }
491
+ }
492
+ function resolveEnvConfig() {
493
+ const projectId = first(
494
+ tryImportMetaEnv("VITE_MUSHI_PROJECT_ID"),
495
+ tryImportMetaEnv("NEXT_PUBLIC_MUSHI_PROJECT_ID"),
496
+ tryImportMetaEnv("NUXT_PUBLIC_MUSHI_PROJECT_ID"),
497
+ tryImportMetaEnv("EXPO_PUBLIC_MUSHI_PROJECT_ID"),
498
+ readProcessEnv(() => process.env.NEXT_PUBLIC_MUSHI_PROJECT_ID),
499
+ readProcessEnv(() => process.env.EXPO_PUBLIC_MUSHI_PROJECT_ID),
500
+ readProcessEnv(() => process.env.MUSHI_PROJECT_ID)
501
+ );
502
+ const apiKey = first(
503
+ tryImportMetaEnv("VITE_MUSHI_API_KEY"),
504
+ tryImportMetaEnv("NEXT_PUBLIC_MUSHI_API_KEY"),
505
+ tryImportMetaEnv("NUXT_PUBLIC_MUSHI_API_KEY"),
506
+ tryImportMetaEnv("EXPO_PUBLIC_MUSHI_API_KEY"),
507
+ readProcessEnv(() => process.env.NEXT_PUBLIC_MUSHI_API_KEY),
508
+ readProcessEnv(() => process.env.EXPO_PUBLIC_MUSHI_API_KEY),
509
+ readProcessEnv(() => process.env.MUSHI_API_KEY)
510
+ );
511
+ const apiEndpoint = first(
512
+ tryImportMetaEnv("VITE_MUSHI_API_ENDPOINT"),
513
+ tryImportMetaEnv("NEXT_PUBLIC_MUSHI_API_ENDPOINT"),
514
+ tryImportMetaEnv("NUXT_PUBLIC_MUSHI_API_ENDPOINT"),
515
+ tryImportMetaEnv("EXPO_PUBLIC_MUSHI_API_ENDPOINT"),
516
+ readProcessEnv(() => process.env.NEXT_PUBLIC_MUSHI_API_ENDPOINT),
517
+ readProcessEnv(() => process.env.EXPO_PUBLIC_MUSHI_API_ENDPOINT),
518
+ readProcessEnv(() => process.env.MUSHI_API_ENDPOINT)
519
+ );
520
+ const result = {};
521
+ if (projectId) result.projectId = projectId;
522
+ if (apiKey) result.apiKey = apiKey;
523
+ if (apiEndpoint) result.apiEndpoint = apiEndpoint;
524
+ return result;
525
+ }
526
+
448
527
  // src/pre-filter.ts
449
528
  var DEFAULT_MIN_LENGTH = 10;
450
529
  var DEFAULT_MAX_LENGTH = 2e3;
@@ -1500,6 +1579,159 @@ function normaliseThrown(thrown) {
1500
1579
  return { name: "Error", message: String(thrown) };
1501
1580
  }
1502
1581
 
1503
- export { DEFAULT_API_ENDPOINT, MAX_REPORT_PAYLOAD_BYTES, MAX_SCREENSHOT_DATA_URL_BYTES, MUSHI_INTERNAL_HEADER, MUSHI_INTERNAL_INIT_MARKER, REGION_ENDPOINTS, captureEnvironment, checkReportPayloadSize, createApiClient, createBreadcrumbBuffer, createLogger, createOfflineQueue, createPiiScrubber, createPreFilter, createRateLimiter, estimateJsonBytes, formatBytes, getDeviceFingerprintHash, getReporterToken, getSessionId, newUuid, noopLogger, normaliseThrown, resolveRegionEndpoint, scrubPii };
1582
+ // src/design-tokens.ts
1583
+ var MUSHI_COLORS_LIGHT = {
1584
+ paper: "#F8F4ED",
1585
+ paperRaised: "#FFFFFF",
1586
+ ink: "#0E0D0B",
1587
+ inkMuted: "#5C5852",
1588
+ inkFaint: "#9A9489",
1589
+ inkDim: "#6E6760",
1590
+ rule: "rgba(14,13,11,0.10)",
1591
+ ruleStrong: "rgba(14,13,11,0.16)",
1592
+ accent: "#E03C2C",
1593
+ accentWash: "rgba(224,60,44,0.08)",
1594
+ accentInk: "#7A1F15",
1595
+ ok: "#16A34A",
1596
+ danger: "#DC2626"
1597
+ };
1598
+ var MUSHI_COLORS_DARK = {
1599
+ paper: "#0F0E0C",
1600
+ paperRaised: "#1A1815",
1601
+ ink: "#F2EBDD",
1602
+ inkMuted: "#928B7E",
1603
+ inkFaint: "#5A5650",
1604
+ inkDim: "#7A7268",
1605
+ rule: "rgba(242,235,221,0.10)",
1606
+ ruleStrong: "rgba(242,235,221,0.18)",
1607
+ accent: "#FF5A47",
1608
+ accentWash: "rgba(255,90,71,0.12)",
1609
+ accentInk: "#FFE5E0",
1610
+ ok: "#4ADE80",
1611
+ danger: "#F87171"
1612
+ };
1613
+ function mushiPalette(mode) {
1614
+ return mode === "dark" ? MUSHI_COLORS_DARK : MUSHI_COLORS_LIGHT;
1615
+ }
1616
+ var MUSHI_SPACING = {
1617
+ hairline: 2,
1618
+ tight: 4,
1619
+ snug: 8,
1620
+ comfy: 12,
1621
+ roomy: 16,
1622
+ lounge: 20,
1623
+ open: 24,
1624
+ wide: 32
1625
+ };
1626
+ var MUSHI_RADIUS = {
1627
+ none: 0,
1628
+ control: 4,
1629
+ card: 10,
1630
+ sheet: 16,
1631
+ pill: 999
1632
+ };
1633
+ var MUSHI_TYPE = {
1634
+ fontDisplay: `'Iowan Old Style', 'Palatino Linotype', 'Palatino', 'Book Antiqua', 'Cambria', Georgia, 'Times New Roman', serif`,
1635
+ fontBody: `system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI Variable Display', 'Segoe UI', sans-serif`,
1636
+ fontMono: `ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, Consolas, 'Liberation Mono', monospace`,
1637
+ sizeBody: 14,
1638
+ sizeLabel: 12,
1639
+ sizeTitle: 16,
1640
+ lineBody: 1.55
1641
+ };
1642
+ var MUSHI_Z = {
1643
+ base: 99999,
1644
+ /** banner sits one below the trigger so an open FAB overlaps it */
1645
+ banner: 99998,
1646
+ /** report/assistant panel sits one above the trigger */
1647
+ panel: 1e5,
1648
+ /** element-selector overlay — always on top */
1649
+ overlay: 2147483647
1650
+ };
1651
+ var MUSHI_MOTION = {
1652
+ easeStamp: "cubic-bezier(0.22, 1, 0.36, 1)",
1653
+ durationFast: 200,
1654
+ durationPanel: 300
1655
+ };
1656
+ var MUSHI_GEOMETRY = {
1657
+ bannerHeight: 36,
1658
+ fabSize: 52,
1659
+ edgeTabWidth: 28,
1660
+ /** default gutter from the screen edge (added on top of safe-area insets) */
1661
+ gutter: 24,
1662
+ panelWidth: 384,
1663
+ /** below this viewport width the panel becomes a full-width bottom sheet */
1664
+ panelSheetBreakpoint: 480
1665
+ };
1666
+ var MUSHI_COPY = {
1667
+ bannerLabel: "Beta",
1668
+ bannerMessage: "Help us improve \u2014 your feedback shapes what we ship.",
1669
+ bugCta: "Report a bug",
1670
+ featureCta: "Feature request",
1671
+ triggerText: "\u{1F41B}",
1672
+ panelTitle: "Send feedback",
1673
+ myReportsTab: "My reports",
1674
+ assistantTab: "Ask"
1675
+ };
1676
+ function mushiTokens(mode) {
1677
+ return {
1678
+ mode,
1679
+ colors: mushiPalette(mode),
1680
+ spacing: MUSHI_SPACING,
1681
+ radius: MUSHI_RADIUS,
1682
+ type: MUSHI_TYPE,
1683
+ z: MUSHI_Z,
1684
+ motion: MUSHI_MOTION,
1685
+ geometry: MUSHI_GEOMETRY,
1686
+ copy: MUSHI_COPY
1687
+ };
1688
+ }
1689
+
1690
+ // src/identity.ts
1691
+ var MUSHI_IDENTITY_TOKEN_PREFIX = "mushi.identity";
1692
+ function buildIdentityClaims(input) {
1693
+ const now = Math.floor(Date.now() / 1e3);
1694
+ const ttl = input.ttlSeconds && input.ttlSeconds > 0 ? Math.min(input.ttlSeconds, 3600) : 600;
1695
+ return {
1696
+ projectId: input.projectId,
1697
+ sub: input.userId,
1698
+ ...input.email ? { email: input.email } : {},
1699
+ ...input.name ? { name: input.name } : {},
1700
+ iat: now,
1701
+ exp: now + ttl
1702
+ };
1703
+ }
1704
+ function base64UrlDecode(segment) {
1705
+ const pad = segment.length % 4 === 0 ? "" : "=".repeat(4 - segment.length % 4);
1706
+ const base64 = segment.replace(/-/g, "+").replace(/_/g, "/") + pad;
1707
+ if (typeof atob === "function") return atob(base64);
1708
+ const B = globalThis.Buffer;
1709
+ if (B) return B.from(base64, "base64").toString("binary");
1710
+ return "";
1711
+ }
1712
+ function parseIdentityToken(token) {
1713
+ if (typeof token !== "string") return null;
1714
+ const parts = token.split(".");
1715
+ if (parts.length !== 3) return null;
1716
+ try {
1717
+ const json = base64UrlDecode(parts[1]);
1718
+ const payload = JSON.parse(json);
1719
+ const projectId = typeof payload.projectId === "string" ? payload.projectId : void 0;
1720
+ const sub = typeof payload.sub === "string" ? payload.sub : void 0;
1721
+ if (!projectId || !sub) return null;
1722
+ return {
1723
+ projectId,
1724
+ sub,
1725
+ ...typeof payload.email === "string" ? { email: payload.email } : {},
1726
+ ...typeof payload.name === "string" ? { name: payload.name } : {},
1727
+ ...typeof payload.iat === "number" ? { iat: payload.iat } : {},
1728
+ ...typeof payload.exp === "number" ? { exp: payload.exp } : {}
1729
+ };
1730
+ } catch {
1731
+ return null;
1732
+ }
1733
+ }
1734
+
1735
+ export { DEFAULT_API_ENDPOINT, MAX_REPORT_PAYLOAD_BYTES, MAX_SCREENSHOT_DATA_URL_BYTES, MUSHI_COLORS_DARK, MUSHI_COLORS_LIGHT, MUSHI_COPY, MUSHI_GEOMETRY, MUSHI_IDENTITY_TOKEN_PREFIX, MUSHI_INTERNAL_HEADER, MUSHI_INTERNAL_INIT_MARKER, MUSHI_MOTION, MUSHI_RADIUS, MUSHI_SPACING, MUSHI_TYPE, MUSHI_Z, REGION_ENDPOINTS, buildIdentityClaims, captureEnvironment, checkReportPayloadSize, createApiClient, createBreadcrumbBuffer, createLogger, createOfflineQueue, createPiiScrubber, createPreFilter, createRateLimiter, estimateJsonBytes, formatBytes, getDeviceFingerprintHash, getReporterToken, getSessionId, mushiPalette, mushiTokens, newUuid, noopLogger, normaliseThrown, parseIdentityToken, resolveEnvConfig, resolveRegionEndpoint, scrubPii };
1504
1736
  //# sourceMappingURL=index.js.map
1505
1737
  //# sourceMappingURL=index.js.map