@mushi-mushi/core 1.13.0 → 1.15.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/CONTRIBUTING.md +23 -1
- package/README.md +1 -1
- package/dist/index.cjs +92 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +98 -5
- package/dist/index.d.ts +98 -5
- package/dist/index.js +92 -18
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CONTRIBUTING.md
CHANGED
|
@@ -63,7 +63,7 @@ packages/
|
|
|
63
63
|
verify/ Fix verification (BSL)
|
|
64
64
|
apps/
|
|
65
65
|
admin/ Admin dashboard (React + Tailwind)
|
|
66
|
-
docs/ Documentation site (
|
|
66
|
+
docs/ Documentation site (Nextra — apps/docs)
|
|
67
67
|
tooling/
|
|
68
68
|
eslint-config/ Shared ESLint flat config
|
|
69
69
|
tsconfig/ Shared TypeScript configs
|
|
@@ -81,6 +81,28 @@ tooling/
|
|
|
81
81
|
```
|
|
82
82
|
6. Open a pull request
|
|
83
83
|
|
|
84
|
+
### Documentation (docs-as-code)
|
|
85
|
+
|
|
86
|
+
If your PR changes **user-visible SDK or CLI behavior**, update docs in the **same PR**:
|
|
87
|
+
|
|
88
|
+
| Surface | When to update |
|
|
89
|
+
| --- | --- |
|
|
90
|
+
| `packages/*/README.md` | npm-facing install/API/config changes for that package |
|
|
91
|
+
| `apps/docs/content/**/*.mdx` | Long-form guides, quickstarts, admin console docs |
|
|
92
|
+
| Root `README.md` | Marketing stats only when counts change — run `pnpm check:docs-stats` |
|
|
93
|
+
|
|
94
|
+
Guardrails (run locally before pushing):
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
pnpm check:docs-stats # root README stat badges
|
|
98
|
+
pnpm check:sdk-version-matrix # apps/docs/content/sdks/index.mdx versions
|
|
99
|
+
pnpm check:internal-doc-links # dead /foo links in MDX
|
|
100
|
+
pnpm check:bundle-docs # @mushi-mushi/web size-limit vs README
|
|
101
|
+
pnpm gen:llms-txt # regenerate apps/docs/public/llms.txt after nav changes
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
README changes on npm packages only appear on [npmjs.com](https://www.npmjs.com) after the next **Changesets publish**.
|
|
105
|
+
|
|
84
106
|
## Changesets
|
|
85
107
|
|
|
86
108
|
We use [Changesets](https://github.com/changesets/changesets) for versioning. If your PR modifies a published package (`core`, `web`, `react`, `vue`, `svelte`, `angular`, `react-native`, `cli`, `mcp`), add a changeset:
|
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):
|
|
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
|
}
|
|
@@ -515,20 +579,27 @@ function formatPretty(entry) {
|
|
|
515
579
|
function formatJson(entry) {
|
|
516
580
|
return JSON.stringify(entry);
|
|
517
581
|
}
|
|
518
|
-
function
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
case "fatal":
|
|
582
|
+
function makeEmitter(destination) {
|
|
583
|
+
if (destination === "stderr") {
|
|
584
|
+
return (level, formatted) => {
|
|
522
585
|
console.error(formatted);
|
|
523
|
-
|
|
524
|
-
case "warn":
|
|
525
|
-
console.warn(formatted);
|
|
526
|
-
break;
|
|
527
|
-
default:
|
|
528
|
-
console.log(formatted);
|
|
586
|
+
};
|
|
529
587
|
}
|
|
588
|
+
return (level, formatted) => {
|
|
589
|
+
switch (level) {
|
|
590
|
+
case "error":
|
|
591
|
+
case "fatal":
|
|
592
|
+
console.error(formatted);
|
|
593
|
+
break;
|
|
594
|
+
case "warn":
|
|
595
|
+
console.warn(formatted);
|
|
596
|
+
break;
|
|
597
|
+
default:
|
|
598
|
+
console.log(formatted);
|
|
599
|
+
}
|
|
600
|
+
};
|
|
530
601
|
}
|
|
531
|
-
function buildLogger(scope, minLevel, baseMeta, formatter) {
|
|
602
|
+
function buildLogger(scope, minLevel, baseMeta, formatter, emit) {
|
|
532
603
|
let currentLevel = minLevel;
|
|
533
604
|
function log(level, msg, meta) {
|
|
534
605
|
if (LEVEL_VALUE[level] < LEVEL_VALUE[currentLevel]) return;
|
|
@@ -553,7 +624,8 @@ function buildLogger(scope, minLevel, baseMeta, formatter) {
|
|
|
553
624
|
`${scope}:${childScope}`,
|
|
554
625
|
currentLevel,
|
|
555
626
|
{ ...baseMeta, ...childMeta },
|
|
556
|
-
formatter
|
|
627
|
+
formatter,
|
|
628
|
+
emit
|
|
557
629
|
);
|
|
558
630
|
},
|
|
559
631
|
setLevel(level) {
|
|
@@ -566,11 +638,13 @@ function createLogger(options) {
|
|
|
566
638
|
scope,
|
|
567
639
|
level = "info",
|
|
568
640
|
meta = {},
|
|
569
|
-
format = "auto"
|
|
641
|
+
format = "auto",
|
|
642
|
+
destination = "stdout"
|
|
570
643
|
} = options;
|
|
571
644
|
const resolvedFormat = format === "auto" ? detectFormat() : format;
|
|
572
645
|
const formatter = resolvedFormat === "json" ? formatJson : formatPretty;
|
|
573
|
-
|
|
646
|
+
const emit = makeEmitter(destination);
|
|
647
|
+
return buildLogger(scope, level, meta, formatter, emit);
|
|
574
648
|
}
|
|
575
649
|
var noopLogger = {
|
|
576
650
|
debug: () => {
|