@mushi-mushi/core 1.13.0 → 1.14.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/README.md CHANGED
@@ -69,4 +69,4 @@ MIT
69
69
  <!-- mushi-readme-stats-footer -->
70
70
  ---
71
71
 
72
- <sub>Monorepo scale (June 2026): 43 edge functions · 234 SQL migrations · 13 outbound plugins · 11 inbound adapters. Canonical counts: <a href="https://github.com/kensaurus/mushi-mushi/blob/master/docs/stats.md">docs/stats.md</a> · <code>pnpm docs-stats</code></sub>
72
+ <sub>Monorepo scale (June 2026): 47 edge functions · 256 SQL migrations · 13 outbound plugins · 11 inbound adapters · 18 pipeline agents. Canonical counts: <a href="https://github.com/kensaurus/mushi-mushi/blob/master/docs/stats.md">docs/stats.md</a> · <code>pnpm docs-stats</code></sub>
package/dist/index.cjs CHANGED
@@ -57,7 +57,7 @@ function createApiClient(options) {
57
57
  maxRetries = DEFAULT_MAX_RETRIES
58
58
  } = options;
59
59
  let baseUrl = apiEndpoint.replace(/\/$/, "");
60
- async function request(method, path, body, retries = maxRetries, internalKind) {
60
+ async function request(method, path, body, retries = maxRetries, internalKind, extraHeaders) {
61
61
  const url = `${baseUrl}${path}`;
62
62
  const controller = new AbortController();
63
63
  const timer = setTimeout(() => controller.abort(), timeout);
@@ -68,7 +68,8 @@ function createApiClient(options) {
68
68
  "Content-Type": "application/json",
69
69
  "X-Mushi-Api-Key": apiKey,
70
70
  "X-Mushi-Project": projectId,
71
- ...internalKind ? { [MUSHI_INTERNAL_HEADER]: internalKind } : {}
71
+ ...internalKind ? { [MUSHI_INTERNAL_HEADER]: internalKind } : {},
72
+ ...extraHeaders
72
73
  },
73
74
  body: body ? JSON.stringify(body) : void 0,
74
75
  signal: controller.signal,
@@ -81,7 +82,7 @@ function createApiClient(options) {
81
82
  const targetBase = target.replace(/\/v1\/.*$/, "").replace(/\/$/, "");
82
83
  if (targetBase !== baseUrl) {
83
84
  baseUrl = targetBase;
84
- return request(method, path, body, retries - 1, internalKind);
85
+ return request(method, path, body, retries - 1, internalKind, extraHeaders);
85
86
  }
86
87
  }
87
88
  }
@@ -89,7 +90,7 @@ function createApiClient(options) {
89
90
  const errorBody = await response.json().catch(() => ({}));
90
91
  if (response.status >= 500 && retries > 0) {
91
92
  await sleep(getBackoffDelay(maxRetries - retries));
92
- return request(method, path, body, retries - 1, internalKind);
93
+ return request(method, path, body, retries - 1, internalKind, extraHeaders);
93
94
  }
94
95
  return {
95
96
  ok: false,
@@ -297,6 +298,69 @@ function createApiClient(options) {
297
298
  1,
298
299
  "reporter-poll"
299
300
  );
301
+ },
302
+ // ─── Cross-app community (in-widget tester identity) ──────────
303
+ async sendMagicLink(email) {
304
+ return request(
305
+ "POST",
306
+ "/v1/tester/magic-link",
307
+ { email },
308
+ 1,
309
+ "community"
310
+ );
311
+ },
312
+ async linkReporterToken(reporterTokenHash, jwt) {
313
+ return request(
314
+ "POST",
315
+ "/v1/tester/link-reporter",
316
+ { reporter_token_hash: reporterTokenHash },
317
+ 1,
318
+ "community",
319
+ { Authorization: `Bearer ${jwt}` }
320
+ );
321
+ },
322
+ async getCrossAppReports(jwt, opts) {
323
+ const qs = new URLSearchParams();
324
+ if (opts?.limit) qs.set("limit", String(opts.limit));
325
+ if (opts?.offset) qs.set("offset", String(opts.offset));
326
+ const suffix = qs.size ? `?${qs.toString()}` : "";
327
+ return request(
328
+ "GET",
329
+ `/v1/tester/cross-app-reports${suffix}`,
330
+ void 0,
331
+ 1,
332
+ "community",
333
+ { Authorization: `Bearer ${jwt}` }
334
+ );
335
+ },
336
+ async getMyReputation(jwt) {
337
+ return request(
338
+ "GET",
339
+ "/v1/tester/reputation",
340
+ void 0,
341
+ 1,
342
+ "community",
343
+ { Authorization: `Bearer ${jwt}` }
344
+ );
345
+ },
346
+ async getPublicLeaderboard(limit = 20) {
347
+ return request(
348
+ "GET",
349
+ `/v1/public/tester-leaderboard?limit=${limit}`,
350
+ void 0,
351
+ 1,
352
+ "reporter-poll"
353
+ );
354
+ },
355
+ async getTesterStatus(jwt) {
356
+ return request(
357
+ "GET",
358
+ "/v1/me/tester-status",
359
+ void 0,
360
+ 1,
361
+ "community",
362
+ { Authorization: `Bearer ${jwt}` }
363
+ );
300
364
  }
301
365
  };
302
366
  }