@mushi-mushi/cli 0.8.0 → 0.11.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 +106 -382
- package/dist/chunk-LXO45AYO.js +6 -0
- package/dist/{chunk-XHD3H54W.js → chunk-NYPX5KXR.js} +78 -0
- package/dist/detect.d.ts +1 -1
- package/dist/detect.js +1 -1
- package/dist/index.js +952 -12
- package/dist/init.js +67 -12
- package/dist/version.js +1 -1
- package/package.json +10 -10
- package/dist/chunk-KUQZQFOL.js +0 -6
package/README.md
CHANGED
|
@@ -1,446 +1,170 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @mushi-mushi/cli
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
> your terminal and CI pipelines, without ever opening a browser.
|
|
3
|
+
CLI for Mushi Mushi — set up the SDK in one command, then triage reports and monitor the pipeline from your terminal.
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
<a href="https://kensaur.us/mushi-mushi/docs/" title="Full docs with screenshots">
|
|
9
|
-
<img src="https://raw.githubusercontent.com/kensaurus/mushi-mushi/main/docs/screenshots/tour-pdca-loop.gif" alt="Admin console PDCA tour — what mushi init wires your project into" width="100%" />
|
|
10
|
-
</a>
|
|
11
|
-
|
|
12
|
-
<sub>↑ what the CLI connects to · <a href="https://kensaur.us/mushi-mushi/docs/admin/">admin docs with screenshots</a></sub>
|
|
13
|
-
|
|
14
|
-
</div>
|
|
15
|
-
|
|
16
|
-
## What it does
|
|
17
|
-
|
|
18
|
-
Like DNA repair enzymes that scan a genome for transcription errors and patch
|
|
19
|
-
them before the next cell division, `mushi-mushi` scans your live project for
|
|
20
|
-
bug patterns, feeds them back into your toolchain, and tells you which ones are
|
|
21
|
-
still open. The CLI is the command-line face of that repair loop:
|
|
22
|
-
|
|
23
|
-
| Before `@mushi-mushi/cli` | After `@mushi-mushi/cli` |
|
|
24
|
-
|---|---|
|
|
25
|
-
| Open the console to check if the bug you fixed is actually resolved | `mushi reports show <id>` in 1 second |
|
|
26
|
-
| Manually copy SDK snippets into each new project | `mushi init` auto-detects your framework and installs everything |
|
|
27
|
-
| No idea which mistake rules are active | `mushi lessons list` shows the current rule genome |
|
|
28
|
-
| CI doesn't know about lesson files | `mushi sync-lessons` writes `.mushi/lessons.json` every deploy |
|
|
29
|
-
| Debug auth failures by staring at headers | `mushi whoami` confirms key + endpoint in one shot |
|
|
30
|
-
|
|
31
|
-
---
|
|
32
|
-
|
|
33
|
-
## Quick start
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
# 1. Install globally (or use npx without installing)
|
|
37
|
-
npm install -g @mushi-mushi/cli # or: pnpm add -g / yarn global add
|
|
38
|
-
|
|
39
|
-
# 2. Get your credentials from the Mushi console:
|
|
40
|
-
# Project ID → https://kensaur.us/mushi-mushi/projects (copy chip)
|
|
41
|
-
# API key → https://kensaur.us/mushi-mushi/settings/api-keys
|
|
42
|
-
|
|
43
|
-
# 3. Save credentials
|
|
44
|
-
mushi login \
|
|
45
|
-
--api-key mushi_xxxxxxxxxxxxxxxxxxxx \
|
|
46
|
-
--endpoint https://<ref>.supabase.co/functions/v1/api \
|
|
47
|
-
--project-id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
|
48
|
-
|
|
49
|
-
# 4. Verify the connection
|
|
50
|
-
mushi whoami
|
|
51
|
-
|
|
52
|
-
# 5. Set up the SDK in a project
|
|
53
|
-
cd my-app && mushi init
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
---
|
|
57
|
-
|
|
58
|
-
## Environment variables
|
|
59
|
-
|
|
60
|
-
All credentials can be supplied via environment variables — ideal for CI
|
|
61
|
-
where a config file per runner is impractical:
|
|
62
|
-
|
|
63
|
-
| Variable | Description |
|
|
64
|
-
|---|---|
|
|
65
|
-
| `MUSHI_API_KEY` | SDK API key, looks like `mushi_...` |
|
|
66
|
-
| `MUSHI_PROJECT_ID` | Project UUID, from the Projects page |
|
|
67
|
-
| `MUSHI_API_ENDPOINT` | Supabase edge function URL |
|
|
68
|
-
|
|
69
|
-
Environment variables override `~/.mushirc`. Explicit command-line flags
|
|
70
|
-
override both.
|
|
71
|
-
|
|
72
|
-
```bash
|
|
73
|
-
# Example: CI usage without any persistent config file
|
|
74
|
-
export MUSHI_API_KEY=mushi_xxxx
|
|
75
|
-
export MUSHI_PROJECT_ID=542b34e0-019e-41fe-b900-7b637717bb86
|
|
76
|
-
export MUSHI_API_ENDPOINT=https://xyz.supabase.co/functions/v1/api
|
|
77
|
-
|
|
78
|
-
mushi sync-lessons # writes .mushi/lessons.json
|
|
79
|
-
mushi status # print project stats
|
|
80
|
-
mushi ping # smoke-test connectivity
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
---
|
|
84
|
-
|
|
85
|
-
## Finding your credentials
|
|
86
|
-
|
|
87
|
-
### API key
|
|
88
|
-
|
|
89
|
-
1. Open the Mushi console → **Settings → API Keys**
|
|
90
|
-
(`https://kensaur.us/mushi-mushi/settings`)
|
|
91
|
-
2. Click **Create API key**
|
|
92
|
-
3. Copy the value — it starts with `mushi_`
|
|
93
|
-
|
|
94
|
-
### Project ID
|
|
95
|
-
|
|
96
|
-
1. Open the Mushi console → **Projects**
|
|
97
|
-
(`https://kensaur.us/mushi-mushi/projects`)
|
|
98
|
-
2. On the project card, click the UUID chip to copy it
|
|
99
|
-
3. The UUID looks like `542b34e0-019e-41fe-b900-7b637717bb86`
|
|
100
|
-
|
|
101
|
-
### API endpoint
|
|
102
|
-
|
|
103
|
-
Unless you are self-hosting, use:
|
|
104
|
-
```
|
|
105
|
-
https://dxptnwrhwsqckaftyymj.supabase.co/functions/v1/api
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
---
|
|
109
|
-
|
|
110
|
-
## Commands
|
|
111
|
-
|
|
112
|
-
### `mushi init`
|
|
113
|
-
|
|
114
|
-
Set up the Mushi SDK in the current project. Auto-detects framework, installs
|
|
115
|
-
the right package, and writes a minimal config file.
|
|
116
|
-
|
|
117
|
-
```bash
|
|
118
|
-
mushi init
|
|
119
|
-
mushi init --project-id <uuid> --api-key <key> # non-interactive (CI)
|
|
120
|
-
mushi init --framework next # force a framework
|
|
121
|
-
mushi init --skip-install # print install command only
|
|
122
|
-
mushi init --yes # skip confirmation prompts
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
Supported frameworks: `next`, `react`, `vue`, `nuxt`, `svelte`, `sveltekit`,
|
|
126
|
-
`angular`, `expo`, `react-native`, `capacitor`, `vanilla`.
|
|
127
|
-
|
|
128
|
-
---
|
|
129
|
-
|
|
130
|
-
### `mushi login`
|
|
131
|
-
|
|
132
|
-
Save API credentials to `~/.mushirc` (mode `0o600`, readable only by you).
|
|
133
|
-
|
|
134
|
-
```bash
|
|
135
|
-
mushi login \
|
|
136
|
-
--api-key mushi_xxx \
|
|
137
|
-
--endpoint https://xyz.supabase.co/functions/v1/api \
|
|
138
|
-
--project-id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
---
|
|
142
|
-
|
|
143
|
-
### `mushi whoami`
|
|
144
|
-
|
|
145
|
-
Verify the API key is valid and print which project it belongs to.
|
|
146
|
-
|
|
147
|
-
```bash
|
|
148
|
-
mushi whoami
|
|
149
|
-
mushi whoami --json # machine-readable
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
Example output:
|
|
153
|
-
```
|
|
154
|
-
✓ Authenticated
|
|
155
|
-
Project: My App (542b34e0-019e-41fe-b900-7b637717bb86)
|
|
156
|
-
Endpoint: https://xyz.supabase.co/functions/v1/api
|
|
157
|
-
Reports: 47 total · 3 open
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
---
|
|
161
|
-
|
|
162
|
-
### `mushi ping`
|
|
163
|
-
|
|
164
|
-
Check that the Mushi backend is reachable. Useful as a CI health gate.
|
|
165
|
-
|
|
166
|
-
```bash
|
|
167
|
-
mushi ping
|
|
168
|
-
mushi ping --json # { ok: true, status: 200, latency_ms: 42 }
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
---
|
|
172
|
-
|
|
173
|
-
### `mushi status`
|
|
174
|
-
|
|
175
|
-
Print a project health summary: report counts by status and severity, fix and
|
|
176
|
-
lesson totals.
|
|
5
|
+
## One-command setup
|
|
177
6
|
|
|
178
7
|
```bash
|
|
179
|
-
mushi
|
|
180
|
-
|
|
8
|
+
npx @mushi-mushi/cli init
|
|
9
|
+
# equivalently:
|
|
10
|
+
npx mushi-mushi
|
|
181
11
|
```
|
|
182
12
|
|
|
183
|
-
|
|
13
|
+
The wizard:
|
|
184
14
|
|
|
185
|
-
|
|
15
|
+
1. Detects your framework (Next.js, Nuxt, SvelteKit, Angular, Expo, Capacitor, plain React/Vue/Svelte, or vanilla JS) from `package.json` and config files.
|
|
16
|
+
2. Picks the right SDK package (`@mushi-mushi/react`, `@mushi-mushi/vue`, etc.) plus `@mushi-mushi/web` when the framework SDK is API-only.
|
|
17
|
+
3. Detects your package manager (npm / pnpm / yarn / bun) from your lockfile and installs with that — `shell: false`, with Windows `.cmd` shim resolution.
|
|
18
|
+
4. Writes `MUSHI_PROJECT_ID` and `MUSHI_API_KEY` (with the right framework prefix — `NEXT_PUBLIC_`, `NUXT_PUBLIC_`, `VITE_`) to `.env.local` (or `.env`).
|
|
19
|
+
5. Warns you if `.env.local` isn't in `.gitignore` (covers `.env*.local`, `*.local`, etc.).
|
|
20
|
+
6. Prints the framework-specific provider snippet to copy-paste.
|
|
21
|
+
7. Offers to **send a real test report** so you see your first classified bug in the console immediately. Opt out via `--skip-test-report`.
|
|
186
22
|
|
|
187
|
-
|
|
23
|
+
It never silently overwrites existing env vars or modifies application code. Pasted credentials are sanitized (stripped of quotes / CR / LF / NUL) and validated against `^proj_[A-Za-z0-9_-]{10,}$` / `^mushi_[A-Za-z0-9_-]{10,}$` before anything is written to disk.
|
|
188
24
|
|
|
189
|
-
|
|
190
|
-
mushi config # show all config
|
|
191
|
-
mushi config apiKey mushi_xxx # update a value
|
|
192
|
-
mushi config endpoint https://... # update endpoint
|
|
193
|
-
mushi config projectId <uuid> # update project ID
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
---
|
|
197
|
-
|
|
198
|
-
### `mushi reports list`
|
|
199
|
-
|
|
200
|
-
List recent reports for the project.
|
|
201
|
-
|
|
202
|
-
```bash
|
|
203
|
-
mushi reports list
|
|
204
|
-
mushi reports list --status new --severity critical
|
|
205
|
-
mushi reports list --search "login button"
|
|
206
|
-
mushi reports list --limit 50 --json
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
Options:
|
|
210
|
-
- `--limit <n>` — max results, 1–100 (default: 20)
|
|
211
|
-
- `--status` — filter: `new`, `triaged`, `in_progress`, `resolved`, `dismissed`
|
|
212
|
-
- `--severity` — filter: `critical`, `high`, `medium`, `low`
|
|
213
|
-
- `--search <query>` — full-text search in summary and description
|
|
214
|
-
- `--json` — machine-readable output
|
|
215
|
-
|
|
216
|
-
---
|
|
217
|
-
|
|
218
|
-
### `mushi reports show <id>`
|
|
219
|
-
|
|
220
|
-
Print full details for a single report including environment, breadcrumbs, and
|
|
221
|
-
linked fix.
|
|
222
|
-
|
|
223
|
-
```bash
|
|
224
|
-
mushi reports show 7f3e8c20-...
|
|
225
|
-
mushi reports show 7f3e8c20-... --json
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
---
|
|
229
|
-
|
|
230
|
-
### `mushi reports triage <id>`
|
|
231
|
-
|
|
232
|
-
Update the status and/or severity of a report, and optionally add a note.
|
|
25
|
+
### Flags
|
|
233
26
|
|
|
234
27
|
```bash
|
|
235
|
-
mushi
|
|
236
|
-
mushi
|
|
237
|
-
mushi
|
|
28
|
+
mushi init --framework next # skip framework detection
|
|
29
|
+
mushi init --project-id proj_xxx --api-key mushi_xxx # skip credential prompts
|
|
30
|
+
mushi init --skip-install # print the install command instead
|
|
31
|
+
mushi init --skip-test-report # don't offer to send a test report
|
|
32
|
+
mushi init --cwd apps/web # run in a sub-package of a monorepo
|
|
33
|
+
mushi init --endpoint https://mushi.your-company.com # self-hosted Mushi API
|
|
34
|
+
mushi init -y # accept the detected framework
|
|
238
35
|
```
|
|
239
36
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
### `mushi reports resolve <id>`
|
|
243
|
-
|
|
244
|
-
Mark a report resolved. Shorthand for `triage --status resolved`.
|
|
37
|
+
Non-interactive use (CI): pass `--yes --project-id proj_xxx --api-key mushi_xxx` or the wizard exits with a clear error instead of hanging on a prompt.
|
|
245
38
|
|
|
246
|
-
|
|
247
|
-
mushi reports resolve <id>
|
|
248
|
-
mushi reports resolve <id> --note "fixed in PR #123"
|
|
249
|
-
```
|
|
39
|
+
Stale-version hint: the wizard checks the npm registry (2s timeout) and prints a one-line upgrade nudge if a newer stable is published. Opt out with `MUSHI_NO_UPDATE_CHECK=1`.
|
|
250
40
|
|
|
251
|
-
|
|
41
|
+
Monorepo awareness: if you run the wizard at a workspace root with no framework dep, it scans `apps/*`, `packages/*`, `examples/*` and tells you which sub-package you probably meant (`mushi init --cwd apps/web`).
|
|
252
42
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
Reopen a resolved or dismissed report.
|
|
43
|
+
## Install globally
|
|
256
44
|
|
|
257
45
|
```bash
|
|
258
|
-
|
|
259
|
-
mushi
|
|
46
|
+
npm install -g @mushi-mushi/cli
|
|
47
|
+
mushi --help
|
|
48
|
+
mushi --version
|
|
260
49
|
```
|
|
261
50
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
### `mushi reports dismiss <id>`
|
|
265
|
-
|
|
266
|
-
Dismiss a report (not a real bug / out of scope).
|
|
51
|
+
## Other commands
|
|
267
52
|
|
|
268
53
|
```bash
|
|
269
|
-
mushi
|
|
270
|
-
mushi
|
|
54
|
+
mushi login --api-key mushi_xxx # store credentials in ~/.mushirc (mode 0o600)
|
|
55
|
+
mushi status # project overview
|
|
56
|
+
mushi reports list # recent reports
|
|
57
|
+
mushi reports show <id> # one report
|
|
58
|
+
mushi reports triage <id> --status acknowledged --severity high
|
|
59
|
+
mushi deploy check # edge-function health probe
|
|
60
|
+
mushi index <path> # walk a local repo and feed RAG
|
|
61
|
+
mushi test # submit a test report end-to-end
|
|
62
|
+
mushi migrate # suggest the most relevant migration guide
|
|
63
|
+
mushi migrate --json # machine-readable JSON for CI
|
|
64
|
+
mushi config endpoint https://... # set API endpoint (https:// required outside localhost)
|
|
65
|
+
mushi sourcemaps upload --release <ver> --dir <dist> # upload .js.map / .css.map (sha256-idempotent)
|
|
271
66
|
```
|
|
272
67
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
### `mushi reports search <query>`
|
|
276
|
-
|
|
277
|
-
Search reports by keyword. Equivalent to `reports list --search <query>`.
|
|
278
|
-
|
|
279
|
-
```bash
|
|
280
|
-
mushi reports search "button not working"
|
|
281
|
-
mushi reports search "404" --status new --limit 20 --json
|
|
282
|
-
```
|
|
283
|
-
|
|
284
|
-
---
|
|
285
|
-
|
|
286
|
-
### `mushi lessons list`
|
|
287
|
-
|
|
288
|
-
List active mistake rules (lessons) extracted from past bug reports.
|
|
289
|
-
|
|
290
|
-
```bash
|
|
291
|
-
mushi lessons list
|
|
292
|
-
mushi lessons list --severity critical
|
|
293
|
-
mushi lessons list --limit 100 --json
|
|
294
|
-
```
|
|
295
|
-
|
|
296
|
-
---
|
|
297
|
-
|
|
298
|
-
### `mushi lessons show <id>`
|
|
299
|
-
|
|
300
|
-
Print full detail for a lesson: rule text, anti-pattern, and summary paragraph.
|
|
301
|
-
|
|
302
|
-
```bash
|
|
303
|
-
mushi lessons show <lesson-uuid>
|
|
304
|
-
mushi lessons show <lesson-uuid> --json
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
---
|
|
308
|
-
|
|
309
|
-
### `mushi sync-lessons`
|
|
68
|
+
### `mushi sourcemaps upload`
|
|
310
69
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
server
|
|
70
|
+
Recursively scans `--dir` for `.js.map` and `.css.map` files and uploads them
|
|
71
|
+
under the given `--release`. Each file is hashed (sha256) and skipped if the
|
|
72
|
+
server already has it for that release, so the command is safe to run from
|
|
73
|
+
every CI build without churning storage.
|
|
314
74
|
|
|
315
75
|
```bash
|
|
316
|
-
mushi
|
|
317
|
-
mushi
|
|
318
|
-
mushi
|
|
319
|
-
mushi sync-lessons --cwd ./apps/mobile
|
|
320
|
-
```
|
|
321
|
-
|
|
322
|
-
CI example (GitHub Actions):
|
|
323
|
-
```yaml
|
|
324
|
-
- name: Sync Mushi lessons
|
|
325
|
-
env:
|
|
326
|
-
MUSHI_API_KEY: ${{ secrets.MUSHI_API_KEY }}
|
|
327
|
-
MUSHI_PROJECT_ID: ${{ secrets.MUSHI_PROJECT_ID }}
|
|
328
|
-
MUSHI_API_ENDPOINT: https://dxptnwrhwsqckaftyymj.supabase.co/functions/v1/api
|
|
329
|
-
run: npx @mushi-mushi/cli sync-lessons
|
|
76
|
+
mushi sourcemaps upload --release 1.4.2 --dir ./dist
|
|
77
|
+
mushi sourcemaps upload --release "$GITHUB_SHA" --dir ./build --dry-run
|
|
78
|
+
mushi sourcemaps upload --release "$GITHUB_SHA" --dir ./build --silent
|
|
330
79
|
```
|
|
331
80
|
|
|
332
|
-
|
|
81
|
+
Requires `MUSHI_API_ENDPOINT` and `MUSHI_API_KEY` (or pass `--endpoint` /
|
|
82
|
+
`--api-key`). Exits non-zero on any upload failure so CI gates fail fast.
|
|
333
83
|
|
|
334
|
-
### `mushi
|
|
335
|
-
|
|
336
|
-
Submit a synthetic test report to verify the ingestion pipeline end-to-end.
|
|
337
|
-
Run this after deployment to confirm the SDK → API → DB path is healthy.
|
|
338
|
-
|
|
339
|
-
```bash
|
|
340
|
-
mushi test
|
|
341
|
-
mushi test --json
|
|
342
|
-
```
|
|
84
|
+
### `mushi migrate`
|
|
343
85
|
|
|
344
|
-
|
|
86
|
+
Reads `package.json` (deps + devDeps + peerDeps) and prints links to the
|
|
87
|
+
matching guides on the docs site. Detects:
|
|
345
88
|
|
|
346
|
-
|
|
89
|
+
- **In-transition shapes** — Capacitor + React Native side-by-side, Cordova
|
|
90
|
+
(or `cordova-ios`/`cordova-android`), Create React App.
|
|
91
|
+
- **Competitor SDKs** — Instabug / Luciq, Shake, LogRocket Feedback,
|
|
92
|
+
BugHerd, Pendo Feedback.
|
|
347
93
|
|
|
348
|
-
|
|
349
|
-
for private repos that cannot be auto-indexed via the GitHub App integration.
|
|
94
|
+
Exits non-zero when nothing matches, so it composes in shell scripts:
|
|
350
95
|
|
|
351
96
|
```bash
|
|
352
|
-
mushi
|
|
353
|
-
mushi index ./src --language ts --dry-run
|
|
354
|
-
mushi index . --json # { ok: true, files: 42, bytes: 123456 }
|
|
97
|
+
mushi migrate || echo "no migration suggestions for this project"
|
|
355
98
|
```
|
|
356
99
|
|
|
357
|
-
|
|
100
|
+
Only `published` guides ever surface — `draft` entries are filtered out so
|
|
101
|
+
the CLI never points users at a 404. This safety property is unit-pinned in
|
|
102
|
+
`packages/cli/src/migrate.test.ts` (positive control + negative control +
|
|
103
|
+
real-catalog regression guard).
|
|
358
104
|
|
|
359
|
-
### `mushi
|
|
105
|
+
### `mushi doctor`
|
|
360
106
|
|
|
361
|
-
|
|
107
|
+
Checks CLI and SDK health. Without flags it verifies local config and endpoint
|
|
108
|
+
reachability only.
|
|
362
109
|
|
|
363
110
|
```bash
|
|
364
|
-
mushi
|
|
365
|
-
mushi
|
|
366
|
-
mushi
|
|
111
|
+
mushi doctor # local checks only
|
|
112
|
+
mushi doctor --server # + calls /preflight on the backend (all 4 dispatch checks)
|
|
113
|
+
mushi doctor --json # machine-readable JSON output (exits 1 if any check fails)
|
|
367
114
|
```
|
|
368
115
|
|
|
369
|
-
|
|
116
|
+
Local checks performed:
|
|
370
117
|
|
|
371
|
-
|
|
118
|
+
| Check | What it verifies |
|
|
119
|
+
|---|---|
|
|
120
|
+
| CLI config | `~/.mushirc` exists, `projectId` and `apiKey` fields are present |
|
|
121
|
+
| Endpoint reachability | `GET /v1/sdk/config?project_id=...` returns 200 |
|
|
122
|
+
| SDK install | `@mushi-mushi/web` or framework-specific SDK is in `node_modules` |
|
|
372
123
|
|
|
373
|
-
|
|
124
|
+
With `--server`, also calls `GET /v1/admin/projects/:id/preflight` (same 4 checks
|
|
125
|
+
the admin console dispatch popover uses) and merges the results. The four
|
|
126
|
+
server checks (`key` values returned by the endpoint):
|
|
374
127
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
128
|
+
| `key` | What it verifies |
|
|
129
|
+
|---|---|
|
|
130
|
+
| `github` | A GitHub repo URL is linked (`project_repos.repo_url` or `project_settings.codebase_repo_url`) |
|
|
131
|
+
| `codebase` | Codebase indexing is enabled AND `pgvector` has at least one non-tombstoned file AND `last_indexed_at` is set |
|
|
132
|
+
| `anthropic` | A BYOK Anthropic key is stored in Supabase Vault (`project_settings.byok_anthropic_key_ref`) |
|
|
133
|
+
| `autofix` | The autofix toggle is ON (`project_settings.autofix_enabled = true`) |
|
|
379
134
|
|
|
380
|
-
|
|
135
|
+
`--server` requires `adminOrApiKey` credentials — set `MUSHI_API_KEY` to an
|
|
136
|
+
admin key (not a public SDK key).
|
|
381
137
|
|
|
382
|
-
### `mushi
|
|
138
|
+
### `mushi reset <projectId>`
|
|
383
139
|
|
|
384
|
-
|
|
140
|
+
Archives a project and wipes its test data so the full onboarding flow can be
|
|
141
|
+
re-run. Useful for development and QA.
|
|
385
142
|
|
|
386
143
|
```bash
|
|
387
|
-
mushi
|
|
388
|
-
mushi deploy check --json # { ok: true, status: 200, latency_ms: 38 }
|
|
144
|
+
mushi reset proj_xxx --confirm # required flag prevents accidental wipes
|
|
389
145
|
```
|
|
390
146
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
## Exit codes
|
|
147
|
+
Wipes: `fix_attempts`, `project_codebase_files`, `reports`, `fix_dispatch_jobs`.
|
|
148
|
+
Sets `projects.archived_at`. **Irreversible.**
|
|
394
149
|
|
|
395
|
-
|
|
396
|
-
|------|---------|
|
|
397
|
-
| `0` | Success |
|
|
398
|
-
| `1` | API or runtime error |
|
|
399
|
-
| `2` | Configuration error (missing credentials or endpoint) |
|
|
400
|
-
| `3` | Not found (report or lesson ID does not exist) |
|
|
150
|
+
### `mushi fixes tail --report-id <id>`
|
|
401
151
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
## Self-hosted Mushi
|
|
405
|
-
|
|
406
|
-
If you run a self-hosted Mushi instance, point the CLI at your edge function:
|
|
152
|
+
Streams dispatch events for a report in real-time via SSE. Pairs with
|
|
153
|
+
`mushi doctor --server` for headless debugging without opening the admin console.
|
|
407
154
|
|
|
408
155
|
```bash
|
|
409
|
-
mushi
|
|
410
|
-
--api-key mushi_xxx \
|
|
411
|
-
--endpoint https://your-ref.supabase.co/functions/v1/api \
|
|
412
|
-
--project-id <uuid>
|
|
156
|
+
mushi fixes tail --report-id 11111111-2222-3333-4444-555555555555
|
|
413
157
|
```
|
|
414
158
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
---
|
|
418
|
-
|
|
419
|
-
## Biological evolution analogy
|
|
420
|
-
|
|
421
|
-
Mushi Mushi is modelled on **cumulative selection** (Dawkins, _The Blind
|
|
422
|
-
Watchmaker_) and **closed-loop error correction** (Black Box Thinking, Matthew
|
|
423
|
-
Syed):
|
|
424
|
-
|
|
425
|
-
1. **Variation** — users report bugs via the SDK widget → raw reports accumulate
|
|
426
|
-
2. **Selection pressure** — the clustering pipeline groups similar bugs and
|
|
427
|
-
scores them by frequency and severity → weak signals are filtered out
|
|
428
|
-
3. **Memory** — high-signal clusters are promoted to _lessons_ (mistake rules)
|
|
429
|
-
→ the genome of known failure modes grows
|
|
430
|
-
4. **Expression** — the MCP server and CLI inject lessons into AI code review
|
|
431
|
-
→ the codebase adapts before the next mutation slips through
|
|
432
|
-
|
|
433
|
-
The CLI is the **field instrument** for monitoring this loop:
|
|
434
|
-
- `mushi status` — read the current fitness of your bug pipeline
|
|
435
|
-
- `mushi sync-lessons` — express the latest genome into your repo
|
|
436
|
-
- `mushi reports triage` — apply selection pressure manually when the
|
|
437
|
-
automated pipeline needs a nudge
|
|
438
|
-
|
|
439
|
-
---
|
|
159
|
+
Exits automatically when the job reaches a terminal status (`completed`,
|
|
160
|
+
`failed`, `cancelled`, `skipped`).
|
|
440
161
|
|
|
441
|
-
##
|
|
162
|
+
## Security notes
|
|
442
163
|
|
|
443
|
-
|
|
164
|
+
- `~/.mushirc` is written with mode `0o600` on Unix. Legacy configs with looser permissions are tightened on load.
|
|
165
|
+
- `--endpoint` values are parsed through `new URL()` and required to use `https://` except for `localhost` / `127.0.0.1` / `*.local`.
|
|
166
|
+
- The `--api-key` flag leaks into `ps -ef` — prefer the interactive prompt on shared machines.
|
|
167
|
+
- Full stack traces on error: `DEBUG=mushi mushi init`.
|
|
444
168
|
|
|
445
169
|
## License
|
|
446
170
|
|
|
@@ -12,6 +12,9 @@ var FRAMEWORK_IDS = [
|
|
|
12
12
|
"expo",
|
|
13
13
|
"react-native",
|
|
14
14
|
"capacitor",
|
|
15
|
+
"express",
|
|
16
|
+
"fastify",
|
|
17
|
+
"hono",
|
|
15
18
|
"vanilla"
|
|
16
19
|
];
|
|
17
20
|
function isFrameworkId(value) {
|
|
@@ -176,6 +179,71 @@ export default function App() {
|
|
|
176
179
|
import { Mushi } from '@mushi-mushi/capacitor'
|
|
177
180
|
|
|
178
181
|
await Mushi.configure({ projectId: '${projectId}', apiKey: '${apiKey}' })`
|
|
182
|
+
},
|
|
183
|
+
express: {
|
|
184
|
+
id: "express",
|
|
185
|
+
label: "Express",
|
|
186
|
+
packageName: "@mushi-mushi/node",
|
|
187
|
+
needsWebPackage: false,
|
|
188
|
+
snippet: (apiKey, projectId) => `// src/instrument.ts \u2014 load with: node --import ./dist/instrument.js
|
|
189
|
+
import { MushiNodeClient, attachUnhandledHook } from '@mushi-mushi/node'
|
|
190
|
+
import { mushiExpressErrorHandler } from '@mushi-mushi/node/express'
|
|
191
|
+
import type { Express } from 'express'
|
|
192
|
+
|
|
193
|
+
export const mushi = new MushiNodeClient({
|
|
194
|
+
projectId: '${projectId}',
|
|
195
|
+
apiKey: '${apiKey}',
|
|
196
|
+
environment: process.env.NODE_ENV ?? 'production',
|
|
197
|
+
})
|
|
198
|
+
attachUnhandledHook({ client: mushi })
|
|
199
|
+
|
|
200
|
+
export function attachMushi(app: Express) {
|
|
201
|
+
app.use(mushiExpressErrorHandler({ client: mushi }))
|
|
202
|
+
}`
|
|
203
|
+
},
|
|
204
|
+
fastify: {
|
|
205
|
+
id: "fastify",
|
|
206
|
+
label: "Fastify",
|
|
207
|
+
packageName: "@mushi-mushi/node",
|
|
208
|
+
needsWebPackage: false,
|
|
209
|
+
snippet: (apiKey, projectId) => `// src/instrument.ts \u2014 load with: node --import ./dist/instrument.js
|
|
210
|
+
import { MushiNodeClient, attachUnhandledHook } from '@mushi-mushi/node'
|
|
211
|
+
import { mushiFastifyPlugin } from '@mushi-mushi/node/fastify'
|
|
212
|
+
import Fastify from 'fastify'
|
|
213
|
+
|
|
214
|
+
export const mushi = new MushiNodeClient({
|
|
215
|
+
projectId: '${projectId}',
|
|
216
|
+
apiKey: '${apiKey}',
|
|
217
|
+
environment: process.env.NODE_ENV ?? 'production',
|
|
218
|
+
})
|
|
219
|
+
attachUnhandledHook({ client: mushi })
|
|
220
|
+
|
|
221
|
+
const app = Fastify()
|
|
222
|
+
mushiFastifyPlugin(app, { client: mushi })`
|
|
223
|
+
},
|
|
224
|
+
hono: {
|
|
225
|
+
id: "hono",
|
|
226
|
+
label: "Hono",
|
|
227
|
+
packageName: "@mushi-mushi/node",
|
|
228
|
+
needsWebPackage: false,
|
|
229
|
+
snippet: (apiKey, projectId) => `// src/instrument.ts \u2014 load with: node --import ./dist/instrument.js
|
|
230
|
+
import { MushiNodeClient, attachUnhandledHook } from '@mushi-mushi/node'
|
|
231
|
+
import { mushiHonoErrorHandler } from '@mushi-mushi/node/hono'
|
|
232
|
+
import { Hono } from 'hono'
|
|
233
|
+
|
|
234
|
+
export const mushi = new MushiNodeClient({
|
|
235
|
+
projectId: '${projectId}',
|
|
236
|
+
apiKey: '${apiKey}',
|
|
237
|
+
environment: process.env.NODE_ENV ?? 'production',
|
|
238
|
+
})
|
|
239
|
+
attachUnhandledHook({ client: mushi })
|
|
240
|
+
|
|
241
|
+
const app = new Hono()
|
|
242
|
+
app.onError(
|
|
243
|
+
mushiHonoErrorHandler({ client: mushi }, (err, c) =>
|
|
244
|
+
c.text('Internal Server Error', 500),
|
|
245
|
+
),
|
|
246
|
+
)`
|
|
179
247
|
},
|
|
180
248
|
vanilla: {
|
|
181
249
|
id: "vanilla",
|
|
@@ -209,6 +277,9 @@ function detectFramework(cwd, pkg) {
|
|
|
209
277
|
if (deps.has("svelte")) return FRAMEWORKS.svelte;
|
|
210
278
|
if (deps.has("vue")) return FRAMEWORKS.vue;
|
|
211
279
|
if (deps.has("react")) return FRAMEWORKS.react;
|
|
280
|
+
if (deps.has("express")) return FRAMEWORKS.express;
|
|
281
|
+
if (deps.has("fastify")) return FRAMEWORKS.fastify;
|
|
282
|
+
if (deps.has("hono") || deps.has("@hono/hono")) return FRAMEWORKS.hono;
|
|
212
283
|
if (existsSync(join(cwd, "next.config.js")) || existsSync(join(cwd, "next.config.ts"))) {
|
|
213
284
|
return FRAMEWORKS.next;
|
|
214
285
|
}
|
|
@@ -234,7 +305,14 @@ function installCommand(pm, packages) {
|
|
|
234
305
|
const verb = pm === "npm" ? "install" : "add";
|
|
235
306
|
return `${pm} ${verb} ${packages.join(" ")}`;
|
|
236
307
|
}
|
|
308
|
+
var SERVER_FRAMEWORK_IDS = /* @__PURE__ */ new Set(["express", "fastify", "hono"]);
|
|
237
309
|
function envVarsToWrite(apiKey, projectId, framework) {
|
|
310
|
+
if (SERVER_FRAMEWORK_IDS.has(framework.id)) {
|
|
311
|
+
return [
|
|
312
|
+
`MUSHI_PROJECT_ID=${projectId}`,
|
|
313
|
+
`MUSHI_API_KEY=${apiKey}`
|
|
314
|
+
].join("\n");
|
|
315
|
+
}
|
|
238
316
|
const prefix = framework.id === "next" ? "NEXT_PUBLIC_" : framework.id === "nuxt" ? "NUXT_PUBLIC_" : "VITE_";
|
|
239
317
|
return [
|
|
240
318
|
`${prefix}MUSHI_PROJECT_ID=${projectId}`,
|
package/dist/detect.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* PURPOSE: Pure detection helpers for framework, package manager, and project state.
|
|
4
4
|
* Kept side-effect-free so the wizard remains unit-testable.
|
|
5
5
|
*/
|
|
6
|
-
type FrameworkId = 'next' | 'react' | 'vue' | 'nuxt' | 'svelte' | 'sveltekit' | 'angular' | 'expo' | 'react-native' | 'capacitor' | 'vanilla';
|
|
6
|
+
type FrameworkId = 'next' | 'react' | 'vue' | 'nuxt' | 'svelte' | 'sveltekit' | 'angular' | 'expo' | 'react-native' | 'capacitor' | 'express' | 'fastify' | 'hono' | 'vanilla';
|
|
7
7
|
interface Framework {
|
|
8
8
|
id: FrameworkId;
|
|
9
9
|
label: string;
|