@mushi-mushi/cli 0.30.2 → 0.30.4
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/{chunk-AHDD44WU.js → chunk-26JWYLCK.js} +13 -11
- package/dist/{chunk-SXSI2W6Z.js → chunk-2DMHQVRU.js} +10 -0
- package/dist/chunk-F7TLL2FB.js +10 -0
- package/dist/{chunk-LDPFTQLE.js → chunk-LGGE3LH7.js} +10 -0
- package/dist/chunk-ODY6NZY2.js +8 -0
- package/dist/{chunk-AJ6TRLJX.js → chunk-SV6HHYWE.js} +7 -5
- package/dist/{connect-MJFNVD6I.js → connect-XPSH7MK3.js} +3 -3
- package/dist/{connect-4TSPUKYX.js → connect-YDQ65VJY.js} +3 -3
- package/dist/{endpoint-NHECZL47.js → endpoint-GXIRH2BW.js} +5 -1
- package/dist/{endpoint-TEBF4IH6.js → endpoint-KI5FMW2S.js} +5 -1
- package/dist/index.js +141 -101
- package/dist/init.d.ts +3 -2
- package/dist/init.js +28 -6
- package/dist/{version-5BNKTJFR.js → version-35BA3FDB.js} +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-P7JI5H57.js +0 -8
- package/dist/chunk-X67SYMCO.js +0 -10
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
import {
|
|
3
3
|
MUSHI_CLI_VERSION,
|
|
4
4
|
MUSHI_MCP_PIN_SPEC
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-F7TLL2FB.js";
|
|
6
|
+
import {
|
|
7
|
+
CLOUD_API_ENDPOINT,
|
|
8
|
+
assertEndpoint,
|
|
9
|
+
normalizeEndpoint
|
|
10
|
+
} from "./chunk-LGGE3LH7.js";
|
|
6
11
|
import {
|
|
7
12
|
detectFramework,
|
|
8
13
|
envVarsToWrite,
|
|
9
14
|
readPackageJson
|
|
10
15
|
} from "./chunk-KOBEOGNF.js";
|
|
11
|
-
import {
|
|
12
|
-
CLOUD_API_ENDPOINT,
|
|
13
|
-
assertEndpoint,
|
|
14
|
-
normalizeEndpoint
|
|
15
|
-
} from "./chunk-LDPFTQLE.js";
|
|
16
16
|
import {
|
|
17
17
|
__require
|
|
18
18
|
} from "./chunk-PDX44BCA.js";
|
|
@@ -122,11 +122,13 @@ function loadConfig(path = CONFIG_PATH, opts = {}) {
|
|
|
122
122
|
if (keychainKey) {
|
|
123
123
|
file = { ...file, apiKey: keychainKey };
|
|
124
124
|
}
|
|
125
|
-
const endpointFromEnv = process.env["MUSHI_API_ENDPOINT"]
|
|
125
|
+
const endpointFromEnv = process.env["MUSHI_API_ENDPOINT"]?.trim() || process.env["MUSHI_ENDPOINT"]?.trim() || void 0;
|
|
126
126
|
const fromEnv = {
|
|
127
127
|
...process.env["MUSHI_API_KEY"] ? { apiKey: process.env["MUSHI_API_KEY"] } : {},
|
|
128
128
|
...process.env["MUSHI_PROJECT_ID"] ? { projectId: process.env["MUSHI_PROJECT_ID"] } : {},
|
|
129
|
-
|
|
129
|
+
// Saved endpoints are normalized by assertEndpoint; the env value isn't,
|
|
130
|
+
// so strip trailing slashes here (no `.../api//v1/...` in any caller).
|
|
131
|
+
...endpointFromEnv ? { endpoint: normalizeEndpoint(endpointFromEnv) } : {},
|
|
130
132
|
...process.env["MUSHI_CONSOLE_URL"] ? { consoleUrl: process.env["MUSHI_CONSOLE_URL"].trim() } : {}
|
|
131
133
|
};
|
|
132
134
|
return { ...file, ...fromEnv };
|
|
@@ -564,7 +566,7 @@ function normalizeApiError(error, httpStatus) {
|
|
|
564
566
|
}
|
|
565
567
|
async function apiCall(path, config, options = {}, callOptions = {}) {
|
|
566
568
|
const timeoutMs = callOptions.timeoutMs ?? API_TIMEOUT_MS;
|
|
567
|
-
const endpoint = config.endpoint;
|
|
569
|
+
const endpoint = config.endpoint ? normalizeEndpoint(config.endpoint) : config.endpoint;
|
|
568
570
|
if (!endpoint) {
|
|
569
571
|
return {
|
|
570
572
|
ok: false,
|
|
@@ -878,8 +880,8 @@ var MCP_CLIENT_LABEL = {
|
|
|
878
880
|
continue: "Continue",
|
|
879
881
|
zed: "Zed"
|
|
880
882
|
};
|
|
881
|
-
function buildHostedMcpServerBlock(url) {
|
|
882
|
-
return { type: "http", url };
|
|
883
|
+
function buildHostedMcpServerBlock(url, oauth) {
|
|
884
|
+
return oauth ? { type: "http", url, oauth } : { type: "http", url };
|
|
883
885
|
}
|
|
884
886
|
function isPlainObject(value) {
|
|
885
887
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
var TEST_REPORT_TIMEOUT_MS = 1e4;
|
|
3
3
|
var TEST_REPORT_FETCH_TIMEOUT_MS = TEST_REPORT_TIMEOUT_MS;
|
|
4
4
|
var CLOUD_API_ENDPOINT = "https://dxptnwrhwsqckaftyymj.supabase.co/functions/v1/api";
|
|
5
|
+
var CLOUD_MCP_OAUTH_URL = "https://kensaur.us/mushi-mushi/hosted-mcp/";
|
|
6
|
+
function firstEndpoint(...candidates) {
|
|
7
|
+
for (const c of candidates) {
|
|
8
|
+
const v = c?.trim();
|
|
9
|
+
if (v) return v;
|
|
10
|
+
}
|
|
11
|
+
return void 0;
|
|
12
|
+
}
|
|
5
13
|
function resolveCloudEndpoint(explicit) {
|
|
6
14
|
if (explicit?.trim()) return explicit.trim();
|
|
7
15
|
const fromEnv = process.env.MUSHI_API_ENDPOINT?.trim();
|
|
@@ -36,6 +44,8 @@ function normalizeEndpoint(url) {
|
|
|
36
44
|
export {
|
|
37
45
|
TEST_REPORT_FETCH_TIMEOUT_MS,
|
|
38
46
|
CLOUD_API_ENDPOINT,
|
|
47
|
+
CLOUD_MCP_OAUTH_URL,
|
|
48
|
+
firstEndpoint,
|
|
39
49
|
resolveCloudEndpoint,
|
|
40
50
|
assertEndpoint,
|
|
41
51
|
normalizeEndpoint
|
|
@@ -4,6 +4,14 @@
|
|
|
4
4
|
var TEST_REPORT_TIMEOUT_MS = 1e4;
|
|
5
5
|
var TEST_REPORT_FETCH_TIMEOUT_MS = TEST_REPORT_TIMEOUT_MS;
|
|
6
6
|
var CLOUD_API_ENDPOINT = "https://dxptnwrhwsqckaftyymj.supabase.co/functions/v1/api";
|
|
7
|
+
var CLOUD_MCP_OAUTH_URL = "https://kensaur.us/mushi-mushi/hosted-mcp/";
|
|
8
|
+
function firstEndpoint(...candidates) {
|
|
9
|
+
for (const c of candidates) {
|
|
10
|
+
const v = c?.trim();
|
|
11
|
+
if (v) return v;
|
|
12
|
+
}
|
|
13
|
+
return void 0;
|
|
14
|
+
}
|
|
7
15
|
function resolveCloudEndpoint(explicit) {
|
|
8
16
|
if (explicit?.trim()) return explicit.trim();
|
|
9
17
|
const fromEnv = process.env.MUSHI_API_ENDPOINT?.trim();
|
|
@@ -38,6 +46,8 @@ function normalizeEndpoint(url) {
|
|
|
38
46
|
export {
|
|
39
47
|
TEST_REPORT_FETCH_TIMEOUT_MS,
|
|
40
48
|
CLOUD_API_ENDPOINT,
|
|
49
|
+
CLOUD_MCP_OAUTH_URL,
|
|
50
|
+
firstEndpoint,
|
|
41
51
|
resolveCloudEndpoint,
|
|
42
52
|
assertEndpoint,
|
|
43
53
|
normalizeEndpoint
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
MUSHI_CLI_VERSION
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ODY6NZY2.js";
|
|
4
4
|
import {
|
|
5
5
|
assertEndpoint,
|
|
6
6
|
normalizeEndpoint
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-2DMHQVRU.js";
|
|
8
8
|
import {
|
|
9
9
|
__require
|
|
10
10
|
} from "./chunk-3RG5ZIWI.js";
|
|
@@ -108,11 +108,13 @@ function loadConfig(path = CONFIG_PATH, opts = {}) {
|
|
|
108
108
|
if (keychainKey) {
|
|
109
109
|
file = { ...file, apiKey: keychainKey };
|
|
110
110
|
}
|
|
111
|
-
const endpointFromEnv = process.env["MUSHI_API_ENDPOINT"]
|
|
111
|
+
const endpointFromEnv = process.env["MUSHI_API_ENDPOINT"]?.trim() || process.env["MUSHI_ENDPOINT"]?.trim() || void 0;
|
|
112
112
|
const fromEnv = {
|
|
113
113
|
...process.env["MUSHI_API_KEY"] ? { apiKey: process.env["MUSHI_API_KEY"] } : {},
|
|
114
114
|
...process.env["MUSHI_PROJECT_ID"] ? { projectId: process.env["MUSHI_PROJECT_ID"] } : {},
|
|
115
|
-
|
|
115
|
+
// Saved endpoints are normalized by assertEndpoint; the env value isn't,
|
|
116
|
+
// so strip trailing slashes here (no `.../api//v1/...` in any caller).
|
|
117
|
+
...endpointFromEnv ? { endpoint: normalizeEndpoint(endpointFromEnv) } : {},
|
|
116
118
|
...process.env["MUSHI_CONSOLE_URL"] ? { consoleUrl: process.env["MUSHI_CONSOLE_URL"].trim() } : {}
|
|
117
119
|
};
|
|
118
120
|
return { ...file, ...fromEnv };
|
|
@@ -495,7 +497,7 @@ function normalizeApiError(error, httpStatus) {
|
|
|
495
497
|
}
|
|
496
498
|
async function apiCall(path, config, options = {}, callOptions = {}) {
|
|
497
499
|
const timeoutMs = callOptions.timeoutMs ?? API_TIMEOUT_MS;
|
|
498
|
-
const endpoint = config.endpoint;
|
|
500
|
+
const endpoint = config.endpoint ? normalizeEndpoint(config.endpoint) : config.endpoint;
|
|
499
501
|
if (!endpoint) {
|
|
500
502
|
return {
|
|
501
503
|
ok: false,
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
resolveSdkEnvKey,
|
|
4
4
|
runConnect
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-26JWYLCK.js";
|
|
6
|
+
import "./chunk-F7TLL2FB.js";
|
|
7
|
+
import "./chunk-LGGE3LH7.js";
|
|
7
8
|
import "./chunk-KOBEOGNF.js";
|
|
8
|
-
import "./chunk-LDPFTQLE.js";
|
|
9
9
|
import "./chunk-PDX44BCA.js";
|
|
10
10
|
export {
|
|
11
11
|
resolveSdkEnvKey,
|
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
saveConfig,
|
|
7
7
|
savedSdkKeyFor,
|
|
8
8
|
waitForIngestReady
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-SV6HHYWE.js";
|
|
10
10
|
import {
|
|
11
11
|
MUSHI_MCP_PIN_SPEC
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-ODY6NZY2.js";
|
|
13
13
|
import {
|
|
14
14
|
detectFramework,
|
|
15
15
|
envVarsToWrite,
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
} from "./chunk-AIZRI665.js";
|
|
18
18
|
import {
|
|
19
19
|
assertEndpoint
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-2DMHQVRU.js";
|
|
21
21
|
import "./chunk-3RG5ZIWI.js";
|
|
22
22
|
|
|
23
23
|
// src/connect.ts
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CLOUD_API_ENDPOINT,
|
|
3
|
+
CLOUD_MCP_OAUTH_URL,
|
|
3
4
|
TEST_REPORT_FETCH_TIMEOUT_MS,
|
|
4
5
|
assertEndpoint,
|
|
6
|
+
firstEndpoint,
|
|
5
7
|
normalizeEndpoint,
|
|
6
8
|
resolveCloudEndpoint
|
|
7
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-2DMHQVRU.js";
|
|
8
10
|
import "./chunk-3RG5ZIWI.js";
|
|
9
11
|
export {
|
|
10
12
|
CLOUD_API_ENDPOINT,
|
|
13
|
+
CLOUD_MCP_OAUTH_URL,
|
|
11
14
|
TEST_REPORT_FETCH_TIMEOUT_MS,
|
|
12
15
|
assertEndpoint,
|
|
16
|
+
firstEndpoint,
|
|
13
17
|
normalizeEndpoint,
|
|
14
18
|
resolveCloudEndpoint
|
|
15
19
|
};
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
CLOUD_API_ENDPOINT,
|
|
4
|
+
CLOUD_MCP_OAUTH_URL,
|
|
4
5
|
TEST_REPORT_FETCH_TIMEOUT_MS,
|
|
5
6
|
assertEndpoint,
|
|
7
|
+
firstEndpoint,
|
|
6
8
|
normalizeEndpoint,
|
|
7
9
|
resolveCloudEndpoint
|
|
8
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-LGGE3LH7.js";
|
|
9
11
|
import "./chunk-PDX44BCA.js";
|
|
10
12
|
export {
|
|
11
13
|
CLOUD_API_ENDPOINT,
|
|
14
|
+
CLOUD_MCP_OAUTH_URL,
|
|
12
15
|
TEST_REPORT_FETCH_TIMEOUT_MS,
|
|
13
16
|
assertEndpoint,
|
|
17
|
+
firstEndpoint,
|
|
14
18
|
normalizeEndpoint,
|
|
15
19
|
resolveCloudEndpoint
|
|
16
20
|
};
|
package/dist/index.js
CHANGED
|
@@ -53,11 +53,20 @@ import {
|
|
|
53
53
|
setGlobalOutputFormat,
|
|
54
54
|
trySaveKeyToKeychain,
|
|
55
55
|
writeMcpServerEntry
|
|
56
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-26JWYLCK.js";
|
|
57
57
|
import {
|
|
58
58
|
MUSHI_CLI_VERSION,
|
|
59
59
|
MUSHI_MCP_PIN_SPEC
|
|
60
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-F7TLL2FB.js";
|
|
61
|
+
import {
|
|
62
|
+
CLOUD_API_ENDPOINT,
|
|
63
|
+
CLOUD_MCP_OAUTH_URL,
|
|
64
|
+
TEST_REPORT_FETCH_TIMEOUT_MS,
|
|
65
|
+
assertEndpoint,
|
|
66
|
+
firstEndpoint,
|
|
67
|
+
normalizeEndpoint,
|
|
68
|
+
resolveCloudEndpoint
|
|
69
|
+
} from "./chunk-LGGE3LH7.js";
|
|
61
70
|
import {
|
|
62
71
|
FRAMEWORKS,
|
|
63
72
|
detectFramework,
|
|
@@ -66,13 +75,6 @@ import {
|
|
|
66
75
|
installCommand,
|
|
67
76
|
readPackageJson
|
|
68
77
|
} from "./chunk-KOBEOGNF.js";
|
|
69
|
-
import {
|
|
70
|
-
CLOUD_API_ENDPOINT,
|
|
71
|
-
TEST_REPORT_FETCH_TIMEOUT_MS,
|
|
72
|
-
assertEndpoint,
|
|
73
|
-
normalizeEndpoint,
|
|
74
|
-
resolveCloudEndpoint
|
|
75
|
-
} from "./chunk-LDPFTQLE.js";
|
|
76
78
|
import "./chunk-PDX44BCA.js";
|
|
77
79
|
|
|
78
80
|
// src/index.ts
|
|
@@ -225,15 +227,15 @@ var DeviceAuthRequestError = class extends Error {
|
|
|
225
227
|
this.retryable = status === void 0 || status >= 500 || status === 408;
|
|
226
228
|
}
|
|
227
229
|
};
|
|
228
|
-
async function withOneRetry(
|
|
230
|
+
async function withOneRetry(run) {
|
|
229
231
|
try {
|
|
230
|
-
return await
|
|
232
|
+
return await run();
|
|
231
233
|
} catch (err) {
|
|
232
234
|
if (err instanceof DeviceAuthRequestError && err.retryable) {
|
|
233
235
|
if (deviceAuthRetryDelayMs > 0) {
|
|
234
236
|
await defaultSleep(deviceAuthRetryDelayMs);
|
|
235
237
|
}
|
|
236
|
-
return
|
|
238
|
+
return run();
|
|
237
239
|
}
|
|
238
240
|
throw err;
|
|
239
241
|
}
|
|
@@ -465,7 +467,7 @@ function chooseProjectNonInteractive(projects, preferredName) {
|
|
|
465
467
|
return match ? { kind: "existing", id: match.id, name: match.name } : { kind: "new", name: preferredName };
|
|
466
468
|
}
|
|
467
469
|
async function runLogin(opts = {}) {
|
|
468
|
-
const { CLOUD_API_ENDPOINT: CLOUD_API_ENDPOINT2, resolveCloudEndpoint: resolveCloudEndpoint2 } = await import("./endpoint-
|
|
470
|
+
const { CLOUD_API_ENDPOINT: CLOUD_API_ENDPOINT2, resolveCloudEndpoint: resolveCloudEndpoint2 } = await import("./endpoint-KI5FMW2S.js");
|
|
469
471
|
const endpoint = opts.endpoint ? resolveCloudEndpoint2(opts.endpoint) : CLOUD_API_ENDPOINT2;
|
|
470
472
|
const consoleBase = await resolveConsoleUrl();
|
|
471
473
|
let apiKey = opts.apiKey;
|
|
@@ -1185,7 +1187,7 @@ var HASH_ROUTER_PATTERNS = [
|
|
|
1185
1187
|
/location\.hash\b/,
|
|
1186
1188
|
/addEventListener\(['"]hashchange['"]/
|
|
1187
1189
|
];
|
|
1188
|
-
var HASH_TEMPLATE_PATTERN = /['"`]
|
|
1190
|
+
var HASH_TEMPLATE_PATTERN = /['"`]\/?#\//;
|
|
1189
1191
|
async function scanDirForPattern(dir, patterns, maxDepth = 6, maxFiles = 2e3) {
|
|
1190
1192
|
const { readdir: readdir2, readFile: readFile3 } = await import("fs/promises");
|
|
1191
1193
|
const { join: join11 } = await import("path");
|
|
@@ -1294,6 +1296,19 @@ async function collectMcpSources(root, home) {
|
|
|
1294
1296
|
}
|
|
1295
1297
|
return { sources, invalid };
|
|
1296
1298
|
}
|
|
1299
|
+
function claudeOAuthCannotDiscover(entry, url) {
|
|
1300
|
+
let host;
|
|
1301
|
+
try {
|
|
1302
|
+
host = new URL(url).hostname.toLowerCase();
|
|
1303
|
+
} catch {
|
|
1304
|
+
return false;
|
|
1305
|
+
}
|
|
1306
|
+
if (!host.endsWith(".supabase.co")) return false;
|
|
1307
|
+
const headers = isJsonObject(entry.headers) ? Object.keys(entry.headers).map((h) => h.toLowerCase()) : [];
|
|
1308
|
+
if (headers.includes("authorization") || headers.includes("x-mushi-api-key")) return false;
|
|
1309
|
+
const oauth = isJsonObject(entry.oauth) ? entry.oauth : {};
|
|
1310
|
+
return typeof oauth.authServerMetadataUrl !== "string" || oauth.authServerMetadataUrl.length === 0;
|
|
1311
|
+
}
|
|
1297
1312
|
function assessMushiEntry(source, name, entry, cliKeySaved) {
|
|
1298
1313
|
const label = `${name} (${source.path})`;
|
|
1299
1314
|
if (!isJsonObject(entry)) return { usable: false, stdio: false, detail: `${label}: not an object` };
|
|
@@ -1305,6 +1320,13 @@ function assessMushiEntry(source, name, entry, cliKeySaved) {
|
|
|
1305
1320
|
detail: `${label}: has a url but no "type": "http" \u2014 Claude Code skips it`
|
|
1306
1321
|
};
|
|
1307
1322
|
}
|
|
1323
|
+
if (source.claudeCode && claudeOAuthCannotDiscover(entry, entry.url)) {
|
|
1324
|
+
return {
|
|
1325
|
+
usable: false,
|
|
1326
|
+
stdio: false,
|
|
1327
|
+
detail: `${label}: Claude Code sign-in cannot find OAuth metadata on a supabase.co URL ("Dynamic Client Registration rejected (HTTP 404)") \u2014 use ${CLOUD_MCP_OAUTH_URL} for Mushi Cloud, or add "oauth": { "authServerMetadataUrl": "<url>/.well-known/oauth-authorization-server" }`
|
|
1328
|
+
};
|
|
1329
|
+
}
|
|
1308
1330
|
return { usable: true, stdio: false, detail: `${label}: hosted OAuth \u2014 sign in from the IDE's MCP panel` };
|
|
1309
1331
|
}
|
|
1310
1332
|
const env = isJsonObject(entry.env) ? entry.env : {};
|
|
@@ -1524,7 +1546,7 @@ async function checkOnboardingStatus(config, _consoleBase, cwd, doFetch = global
|
|
|
1524
1546
|
}
|
|
1525
1547
|
async function checkVersionDrift(cwd, doFetch) {
|
|
1526
1548
|
const checks = [];
|
|
1527
|
-
const { MUSHI_CLI_VERSION: MUSHI_CLI_VERSION2 } = await import("./version-
|
|
1549
|
+
const { MUSHI_CLI_VERSION: MUSHI_CLI_VERSION2 } = await import("./version-35BA3FDB.js");
|
|
1528
1550
|
if (MUSHI_CLI_VERSION2 === "0.0.0-dev") return checks;
|
|
1529
1551
|
const parse2 = (v) => {
|
|
1530
1552
|
const m = v.replace(/^[~^]/, "").match(/^(\d+)\.(\d+)\.(\d+)/);
|
|
@@ -1769,7 +1791,7 @@ async function runInit(options = {}) {
|
|
|
1769
1791
|
const framework = await chooseFramework(detected, options);
|
|
1770
1792
|
const consoleBase = await resolveConsoleUrl({ cwd });
|
|
1771
1793
|
const endpoint = resolveCloudEndpoint(
|
|
1772
|
-
options.endpoint
|
|
1794
|
+
firstEndpoint(options.endpoint, process.env.MUSHI_API_ENDPOINT, loadConfig().endpoint)
|
|
1773
1795
|
);
|
|
1774
1796
|
options = { ...options, endpoint };
|
|
1775
1797
|
const credentials = await acquireCredentials(options, consoleBase, endpoint);
|
|
@@ -2448,7 +2470,7 @@ async function maybeOfferConnect(credentials, options, _consoleBase) {
|
|
|
2448
2470
|
if (p.isCancel(answer) || !answer) return;
|
|
2449
2471
|
const endpoint = resolveCloudEndpoint(options.endpoint);
|
|
2450
2472
|
try {
|
|
2451
|
-
const { runConnect: runConnect2 } = await import("./connect-
|
|
2473
|
+
const { runConnect: runConnect2 } = await import("./connect-XPSH7MK3.js");
|
|
2452
2474
|
const saved = loadConfig();
|
|
2453
2475
|
const result = await runConnect2(
|
|
2454
2476
|
{
|
|
@@ -3673,7 +3695,8 @@ async function writeProjectBootstrapFiles(opts) {
|
|
|
3673
3695
|
try {
|
|
3674
3696
|
existing = await readFile2(envPath, "utf8");
|
|
3675
3697
|
envUpdated = true;
|
|
3676
|
-
} catch {
|
|
3698
|
+
} catch (err) {
|
|
3699
|
+
if (err.code !== "ENOENT") throw err;
|
|
3677
3700
|
}
|
|
3678
3701
|
const MUSHI_LINE_RE = /^(NEXT_PUBLIC_|NUXT_PUBLIC_|VITE_|EXPO_PUBLIC_)?MUSHI_[A-Z_]+=.*/gm;
|
|
3679
3702
|
const MUSHI_COMMENT_RE = /^# Mushi MCP\b.*/gm;
|
|
@@ -3715,7 +3738,7 @@ Typical first-time flow:
|
|
|
3715
3738
|
# mushi whoami to confirm`).action(async (opts) => {
|
|
3716
3739
|
const savedConfig = loadConfig();
|
|
3717
3740
|
const endpoint = resolveCloudEndpoint(
|
|
3718
|
-
opts.endpoint
|
|
3741
|
+
firstEndpoint(opts.endpoint, process.env.MUSHI_API_ENDPOINT, savedConfig.endpoint)
|
|
3719
3742
|
);
|
|
3720
3743
|
const consoleBase = await resolveConsoleUrl();
|
|
3721
3744
|
console.log("");
|
|
@@ -3867,7 +3890,14 @@ function buildSetupServerBlock(opts) {
|
|
|
3867
3890
|
note: "Note: endpoint does not end in /api \u2014 cannot derive the hosted MCP URL; writing a local stdio entry instead."
|
|
3868
3891
|
};
|
|
3869
3892
|
}
|
|
3870
|
-
return { block:
|
|
3893
|
+
return { block: hostedOAuthBlock(opts.ide, opts.endpoint, hostedUrl), hosted: true };
|
|
3894
|
+
}
|
|
3895
|
+
function hostedOAuthBlock(ide, endpoint, hostedUrl) {
|
|
3896
|
+
if (endpoint.replace(/\/+$/, "") === CLOUD_API_ENDPOINT) return buildHostedMcpServerBlock(CLOUD_MCP_OAUTH_URL);
|
|
3897
|
+
if (ide !== "claude") return buildHostedMcpServerBlock(hostedUrl);
|
|
3898
|
+
return buildHostedMcpServerBlock(hostedUrl, {
|
|
3899
|
+
authServerMetadataUrl: `${hostedUrl}/.well-known/oauth-authorization-server`
|
|
3900
|
+
});
|
|
3871
3901
|
}
|
|
3872
3902
|
function buildZedServerBlock(opts) {
|
|
3873
3903
|
const { env } = buildMcpServerBlock({ ...opts, client: "zed" });
|
|
@@ -4681,17 +4711,17 @@ function registerNudgeCommand(program2) {
|
|
|
4681
4711
|
}
|
|
4682
4712
|
const phase = opts.phase;
|
|
4683
4713
|
const overrides = {};
|
|
4684
|
-
const parseNumericFlag = (flag, raw, min) => {
|
|
4714
|
+
const parseNumericFlag = (flag, raw, min, integer = false) => {
|
|
4685
4715
|
const n = Number(raw);
|
|
4686
|
-
if (!Number.isFinite(n) || n < min) {
|
|
4716
|
+
if (!Number.isFinite(n) || n < min || integer && !Number.isInteger(n)) {
|
|
4687
4717
|
console.error(
|
|
4688
|
-
`error: --${flag} must be a finite number >= ${min} (got "${raw}")`
|
|
4718
|
+
`error: --${flag} must be a finite ${integer ? "integer" : "number"} >= ${min} (got "${raw}")`
|
|
4689
4719
|
);
|
|
4690
4720
|
process.exit(1);
|
|
4691
4721
|
}
|
|
4692
4722
|
return n;
|
|
4693
4723
|
};
|
|
4694
|
-
if (opts.max !== void 0) overrides.maxProactivePerSession = parseNumericFlag("max", opts.max, 1);
|
|
4724
|
+
if (opts.max !== void 0) overrides.maxProactivePerSession = parseNumericFlag("max", opts.max, 1, true);
|
|
4695
4725
|
if (opts.cooldown !== void 0) overrides.dismissCooldownHours = parseNumericFlag("cooldown", opts.cooldown, 0);
|
|
4696
4726
|
if (opts.dwell !== void 0) overrides.pageDwellMinutes = parseNumericFlag("dwell", opts.dwell, 0);
|
|
4697
4727
|
if (opts.welcome !== void 0) overrides.firstSessionSeconds = parseNumericFlag("welcome", opts.welcome, 0);
|
|
@@ -5169,18 +5199,18 @@ function registerTddCommands(program2) {
|
|
|
5169
5199
|
config
|
|
5170
5200
|
);
|
|
5171
5201
|
if (!runsRes.ok) break;
|
|
5172
|
-
const
|
|
5173
|
-
if (!
|
|
5174
|
-
if (
|
|
5202
|
+
const run = runsRes.data.runs.find((r) => r.id === res.data.runId);
|
|
5203
|
+
if (!run) break;
|
|
5204
|
+
if (run.status === "completed") {
|
|
5175
5205
|
console.log(`
|
|
5176
|
-
\u2713 Done! ${
|
|
5177
|
-
if (
|
|
5206
|
+
\u2713 Done! ${run.pages_crawled ?? 0} pages crawled.`);
|
|
5207
|
+
if (run.proposal_id) console.log(` Proposal id: ${run.proposal_id}`);
|
|
5178
5208
|
console.log(` Review in the console: Inventory \u2192 Discovery \u2192 Past proposals`);
|
|
5179
5209
|
break;
|
|
5180
5210
|
}
|
|
5181
|
-
if (
|
|
5211
|
+
if (run.status === "failed") {
|
|
5182
5212
|
console.error(`
|
|
5183
|
-
\u2717 Crawl failed: ${
|
|
5213
|
+
\u2717 Crawl failed: ${run.error_message ?? "unknown"}`);
|
|
5184
5214
|
process.exit(1);
|
|
5185
5215
|
}
|
|
5186
5216
|
process.stdout.write(".");
|
|
@@ -5940,9 +5970,9 @@ Examples:
|
|
|
5940
5970
|
}
|
|
5941
5971
|
if (data.gate_runs.length > 0) {
|
|
5942
5972
|
console.log("\nGate Results:");
|
|
5943
|
-
for (const
|
|
5944
|
-
const g =
|
|
5945
|
-
console.log(` ${g} ${
|
|
5973
|
+
for (const run of data.gate_runs) {
|
|
5974
|
+
const g = run.status === "pass" ? "OK" : run.status === "fail" ? "FAIL" : "SKIP";
|
|
5975
|
+
console.log(` ${g} ${run.gate.padEnd(22)} ${run.status} (${run.findings_count} finding${run.findings_count !== 1 ? "s" : ""})`);
|
|
5946
5976
|
}
|
|
5947
5977
|
}
|
|
5948
5978
|
const refresh = data.gate_refresh;
|
|
@@ -6225,25 +6255,25 @@ Pipeline started!
|
|
|
6225
6255
|
console.log(JSON.stringify(result.data, null, 2));
|
|
6226
6256
|
return;
|
|
6227
6257
|
}
|
|
6228
|
-
const
|
|
6229
|
-
const statusIcon =
|
|
6258
|
+
const run = result.data;
|
|
6259
|
+
const statusIcon = run.status === "completed" ? "\u2705" : run.status === "failed" ? "\u274C" : run.status === "running" ? "\u23F3" : "\u26AA";
|
|
6230
6260
|
console.log(`
|
|
6231
|
-
${statusIcon} Pipeline ${runId.slice(0, 8)} \xB7 ${
|
|
6261
|
+
${statusIcon} Pipeline ${runId.slice(0, 8)} \xB7 ${run.root_skill_slug} \xB7 ${run.mode}
|
|
6232
6262
|
`);
|
|
6233
|
-
const steps =
|
|
6263
|
+
const steps = run.steps ?? [];
|
|
6234
6264
|
for (const step of steps) {
|
|
6235
6265
|
const icon = step.status === "passed" ? "\u2705" : step.status === "failed" ? "\u274C" : step.status === "running" ? "\u23F3" : "\u26AA";
|
|
6236
6266
|
const pr = step.pr_url ? ` \u2192 ${step.pr_url}` : "";
|
|
6237
6267
|
console.log(` ${icon} Step ${step.step_index + 1}: ${step.skill_slug}${pr}`);
|
|
6238
6268
|
if (step.notes) console.log(` ${step.notes}`);
|
|
6239
6269
|
}
|
|
6240
|
-
if (
|
|
6270
|
+
if (run.context_packet) {
|
|
6241
6271
|
console.log(`
|
|
6242
6272
|
${"\u2500".repeat(60)}`);
|
|
6243
6273
|
console.log(`Context Packet (paste into your Cursor agent):
|
|
6244
6274
|
`);
|
|
6245
|
-
console.log(
|
|
6246
|
-
if (
|
|
6275
|
+
console.log(run.context_packet.slice(0, 6e3));
|
|
6276
|
+
if (run.context_packet.length > 6e3) console.log("\n\u2026 [truncated \u2014 full packet via --json]");
|
|
6247
6277
|
}
|
|
6248
6278
|
console.log();
|
|
6249
6279
|
});
|
|
@@ -6505,7 +6535,7 @@ Examples:
|
|
|
6505
6535
|
}
|
|
6506
6536
|
|
|
6507
6537
|
// src/commands/selfhost.ts
|
|
6508
|
-
import {
|
|
6538
|
+
import { spawnSync } from "child_process";
|
|
6509
6539
|
import { randomBytes } from "crypto";
|
|
6510
6540
|
function hasSupabaseCli() {
|
|
6511
6541
|
try {
|
|
@@ -6515,28 +6545,28 @@ function hasSupabaseCli() {
|
|
|
6515
6545
|
return false;
|
|
6516
6546
|
}
|
|
6517
6547
|
}
|
|
6518
|
-
function
|
|
6519
|
-
|
|
6520
|
-
|
|
6521
|
-
|
|
6522
|
-
}
|
|
6523
|
-
const
|
|
6524
|
-
|
|
6525
|
-
|
|
6526
|
-
|
|
6527
|
-
|
|
6528
|
-
|
|
6529
|
-
|
|
6530
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
6531
|
-
});
|
|
6532
|
-
process.stdout.write("\u2713\n");
|
|
6533
|
-
return { ok: true, stdout: out, stderr: "" };
|
|
6534
|
-
} catch (err) {
|
|
6548
|
+
function selfhostStepCommand(step) {
|
|
6549
|
+
return `supabase ${step.args.join(" ")}${step.mayFail ? " || true" : ""}`;
|
|
6550
|
+
}
|
|
6551
|
+
function runSupabase(args, opts) {
|
|
6552
|
+
process.stdout.write(` \u203A ${opts.label} \u2026 `);
|
|
6553
|
+
const r = spawnSync("supabase", args, {
|
|
6554
|
+
cwd: opts.cwd,
|
|
6555
|
+
encoding: "utf8",
|
|
6556
|
+
timeout: 3e5,
|
|
6557
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
6558
|
+
});
|
|
6559
|
+
if (r.error || r.status !== 0) {
|
|
6535
6560
|
process.stdout.write("\u2717\n");
|
|
6536
|
-
const
|
|
6537
|
-
|
|
6538
|
-
|
|
6561
|
+
const stderr = (r.stderr ?? "").trim();
|
|
6562
|
+
return {
|
|
6563
|
+
ok: false,
|
|
6564
|
+
stdout: r.stdout ?? "",
|
|
6565
|
+
stderr: stderr || r.error?.message || `exited with ${r.status ?? r.signal}`
|
|
6566
|
+
};
|
|
6539
6567
|
}
|
|
6568
|
+
process.stdout.write("\u2713\n");
|
|
6569
|
+
return { ok: true, stdout: r.stdout, stderr: "" };
|
|
6540
6570
|
}
|
|
6541
6571
|
var REQUIRED_FUNCTIONS = [
|
|
6542
6572
|
"api",
|
|
@@ -6546,55 +6576,43 @@ var REQUIRED_FUNCTIONS = [
|
|
|
6546
6576
|
"fix-worker",
|
|
6547
6577
|
"webhooks-github-indexer"
|
|
6548
6578
|
];
|
|
6549
|
-
|
|
6550
|
-
const supabaseDir = opts.cwd ? `${opts.cwd}/packages/server/supabase` : "packages/server/supabase";
|
|
6551
|
-
const printOnly = !!(opts.printCommands || !hasSupabaseCli());
|
|
6552
|
-
if (printOnly) {
|
|
6553
|
-
console.log("");
|
|
6554
|
-
console.log("supabase CLI not found (or --print-commands was passed).");
|
|
6555
|
-
console.log("Run the following commands manually:\n");
|
|
6556
|
-
} else {
|
|
6557
|
-
console.log("");
|
|
6558
|
-
console.log("mushi selfhost up \u2014 deploying self-hosted Mushi Mushi\n");
|
|
6559
|
-
}
|
|
6579
|
+
function buildSelfhostSteps(opts, printOnly, internalToken) {
|
|
6560
6580
|
const steps = [];
|
|
6561
6581
|
if (opts.projectRef && !/^[a-z0-9-]+$/i.test(opts.projectRef)) {
|
|
6562
|
-
|
|
6563
|
-
`);
|
|
6564
|
-
process.exit(1);
|
|
6582
|
+
return { ok: false, error: `--project-ref must be alphanumeric (got: ${opts.projectRef}).` };
|
|
6565
6583
|
}
|
|
6566
6584
|
if (opts.projectRef) {
|
|
6567
6585
|
steps.push({
|
|
6568
6586
|
label: `link to Supabase project ${opts.projectRef}`,
|
|
6569
|
-
|
|
6587
|
+
args: ["link", "--project-ref", opts.projectRef],
|
|
6570
6588
|
critical: true
|
|
6571
6589
|
});
|
|
6572
6590
|
}
|
|
6573
6591
|
steps.push({
|
|
6574
6592
|
label: "apply database migrations",
|
|
6575
|
-
|
|
6593
|
+
args: ["db", "push"],
|
|
6576
6594
|
critical: true
|
|
6577
6595
|
});
|
|
6578
6596
|
if (opts.anthropicKey && printOnly) {
|
|
6579
6597
|
steps.push({
|
|
6580
6598
|
label: "set ANTHROPIC_API_KEY secret",
|
|
6581
|
-
|
|
6599
|
+
args: ["secrets", "set", "ANTHROPIC_API_KEY=sk-ant-..."]
|
|
6582
6600
|
});
|
|
6583
6601
|
} else if (opts.anthropicKey) {
|
|
6584
6602
|
if (!/^[A-Za-z0-9_-]+$/.test(opts.anthropicKey)) {
|
|
6585
|
-
|
|
6586
|
-
|
|
6587
|
-
|
|
6588
|
-
|
|
6603
|
+
return {
|
|
6604
|
+
ok: false,
|
|
6605
|
+
error: "--anthropic-key does not look like an API key (letters, digits, - and _ only).\n Set it manually instead: supabase secrets set ANTHROPIC_API_KEY=<your key>"
|
|
6606
|
+
};
|
|
6589
6607
|
}
|
|
6590
6608
|
steps.push({
|
|
6591
6609
|
label: "set ANTHROPIC_API_KEY secret",
|
|
6592
|
-
|
|
6610
|
+
args: ["secrets", "set", `ANTHROPIC_API_KEY=${opts.anthropicKey}`]
|
|
6593
6611
|
});
|
|
6594
6612
|
} else if (printOnly) {
|
|
6595
6613
|
steps.push({
|
|
6596
6614
|
label: "set ANTHROPIC_API_KEY secret",
|
|
6597
|
-
|
|
6615
|
+
args: ["secrets", "set", "ANTHROPIC_API_KEY=sk-ant-..."]
|
|
6598
6616
|
});
|
|
6599
6617
|
}
|
|
6600
6618
|
if (opts.adminBaseUrl) {
|
|
@@ -6606,43 +6624,65 @@ async function runSelfhostUp(opts) {
|
|
|
6606
6624
|
adminUrlOk = false;
|
|
6607
6625
|
}
|
|
6608
6626
|
if (!adminUrlOk) {
|
|
6609
|
-
|
|
6610
|
-
`\u2717 --admin-base-url must be a plain http(s) URL (got: ${opts.adminBaseUrl}).
|
|
6611
|
-
`
|
|
6612
|
-
);
|
|
6613
|
-
process.exit(1);
|
|
6627
|
+
return { ok: false, error: `--admin-base-url must be a plain http(s) URL (got: ${opts.adminBaseUrl}).` };
|
|
6614
6628
|
}
|
|
6615
6629
|
steps.push({
|
|
6616
6630
|
label: "set ADMIN_BASE_URL secret",
|
|
6617
|
-
|
|
6631
|
+
args: ["secrets", "set", `ADMIN_BASE_URL=${opts.adminBaseUrl}`]
|
|
6618
6632
|
});
|
|
6619
6633
|
}
|
|
6620
|
-
const internalToken = randomBytes(32).toString("hex");
|
|
6621
6634
|
steps.push({
|
|
6622
6635
|
label: "set MUSHI_INTERNAL_CALLER_SECRET (recovery cron auth)",
|
|
6623
|
-
|
|
6636
|
+
args: [
|
|
6637
|
+
"secrets",
|
|
6638
|
+
"set",
|
|
6639
|
+
`MUSHI_INTERNAL_CALLER_SECRET=${printOnly ? "<openssl rand -hex 32>" : internalToken}`
|
|
6640
|
+
]
|
|
6624
6641
|
});
|
|
6625
6642
|
if (!opts.skipDeploy) {
|
|
6626
6643
|
for (const fn of REQUIRED_FUNCTIONS) {
|
|
6627
6644
|
steps.push({
|
|
6628
6645
|
label: `deploy edge function: ${fn}`,
|
|
6629
|
-
|
|
6646
|
+
args: ["functions", "deploy", fn, "--no-verify-jwt"]
|
|
6630
6647
|
});
|
|
6631
6648
|
}
|
|
6632
6649
|
}
|
|
6633
6650
|
steps.push({
|
|
6634
6651
|
label: "create screenshots storage bucket",
|
|
6635
|
-
|
|
6652
|
+
args: ["storage", "create", "screenshots", "--public"],
|
|
6653
|
+
mayFail: true
|
|
6636
6654
|
});
|
|
6655
|
+
return { ok: true, steps };
|
|
6656
|
+
}
|
|
6657
|
+
async function runSelfhostUp(opts) {
|
|
6658
|
+
const supabaseDir = opts.cwd ? `${opts.cwd}/packages/server/supabase` : "packages/server/supabase";
|
|
6659
|
+
const printOnly = !!(opts.printCommands || !hasSupabaseCli());
|
|
6660
|
+
if (printOnly) {
|
|
6661
|
+
console.log("");
|
|
6662
|
+
console.log("supabase CLI not found (or --print-commands was passed).");
|
|
6663
|
+
console.log("Run the following commands manually:\n");
|
|
6664
|
+
} else {
|
|
6665
|
+
console.log("");
|
|
6666
|
+
console.log("mushi selfhost up \u2014 deploying self-hosted Mushi Mushi\n");
|
|
6667
|
+
}
|
|
6668
|
+
const built = buildSelfhostSteps(opts, printOnly, randomBytes(32).toString("hex"));
|
|
6669
|
+
if (!built.ok) {
|
|
6670
|
+
process.stderr.write(`\u2717 ${built.error}
|
|
6671
|
+
`);
|
|
6672
|
+
process.exit(1);
|
|
6673
|
+
}
|
|
6637
6674
|
let aborted = false;
|
|
6638
|
-
for (const step of steps) {
|
|
6675
|
+
for (const step of built.steps) {
|
|
6639
6676
|
if (printOnly) {
|
|
6640
6677
|
console.log(`# ${step.label}`);
|
|
6641
|
-
|
|
6678
|
+
console.log(` $ ${selfhostStepCommand(step)}`);
|
|
6642
6679
|
console.log("");
|
|
6643
6680
|
} else {
|
|
6644
|
-
const result =
|
|
6645
|
-
if (!result.ok) {
|
|
6681
|
+
const result = runSupabase(step.args, { label: step.label, cwd: supabaseDir });
|
|
6682
|
+
if (!result.ok && step.mayFail) {
|
|
6683
|
+
process.stdout.write(` (fine if it already exists) ${result.stderr.split("\n")[0]}
|
|
6684
|
+
`);
|
|
6685
|
+
} else if (!result.ok) {
|
|
6646
6686
|
if (result.stderr) {
|
|
6647
6687
|
process.stderr.write(` ${result.stderr.split("\n")[0]}
|
|
6648
6688
|
`);
|
|
@@ -10685,8 +10725,8 @@ function registerUxRunsCommands(program2) {
|
|
|
10685
10725
|
console.log(JSON.stringify(result.data, null, 2));
|
|
10686
10726
|
return;
|
|
10687
10727
|
}
|
|
10688
|
-
const { run
|
|
10689
|
-
if (
|
|
10728
|
+
const { run, surfaces } = result.data;
|
|
10729
|
+
if (run.branch) console.log(`Kept changes: ${run.branch}
|
|
10690
10730
|
`);
|
|
10691
10731
|
const order = ["regressed", "reverted", "blocked", "iterating", "baseline", "accepted", "skipped", "pending"];
|
|
10692
10732
|
for (const s of [...surfaces].sort((a, b) => order.indexOf(a.status) - order.indexOf(b.status))) {
|
package/dist/init.d.ts
CHANGED
|
@@ -87,8 +87,9 @@ declare function createProject(endpoint: string, cliToken: string, name: string,
|
|
|
87
87
|
/**
|
|
88
88
|
* Mint a fresh report:write key for an existing project (raw keys can't be
|
|
89
89
|
* recovered, so selecting a project always mints a new one). Throws
|
|
90
|
-
* DeviceAuthRequestError on failure (
|
|
91
|
-
* can tell the user WHY minting failed instead of a
|
|
90
|
+
* DeviceAuthRequestError on failure (a single attempt, no retry — minting isn't
|
|
91
|
+
* idempotent) so the wizard can tell the user WHY minting failed instead of a
|
|
92
|
+
* bare "could not mint".
|
|
92
93
|
*/
|
|
93
94
|
declare function mintProjectKey(endpoint: string, cliToken: string, projectId: string, opts?: {
|
|
94
95
|
/**
|
package/dist/init.js
CHANGED
|
@@ -25,10 +25,10 @@ import {
|
|
|
25
25
|
saveConfig,
|
|
26
26
|
savedSdkKeyFor,
|
|
27
27
|
trySaveKeyToKeychain
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-SV6HHYWE.js";
|
|
29
29
|
import {
|
|
30
30
|
MUSHI_CLI_VERSION
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-ODY6NZY2.js";
|
|
32
32
|
import {
|
|
33
33
|
FRAMEWORKS,
|
|
34
34
|
detectFramework,
|
|
@@ -39,10 +39,12 @@ import {
|
|
|
39
39
|
} from "./chunk-AIZRI665.js";
|
|
40
40
|
import {
|
|
41
41
|
CLOUD_API_ENDPOINT,
|
|
42
|
+
CLOUD_MCP_OAUTH_URL,
|
|
42
43
|
TEST_REPORT_FETCH_TIMEOUT_MS,
|
|
44
|
+
firstEndpoint,
|
|
43
45
|
normalizeEndpoint,
|
|
44
46
|
resolveCloudEndpoint
|
|
45
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-2DMHQVRU.js";
|
|
46
48
|
import "./chunk-3RG5ZIWI.js";
|
|
47
49
|
|
|
48
50
|
// src/init.ts
|
|
@@ -860,7 +862,7 @@ var HASH_ROUTER_PATTERNS = [
|
|
|
860
862
|
/location\.hash\b/,
|
|
861
863
|
/addEventListener\(['"]hashchange['"]/
|
|
862
864
|
];
|
|
863
|
-
var HASH_TEMPLATE_PATTERN = /['"`]
|
|
865
|
+
var HASH_TEMPLATE_PATTERN = /['"`]\/?#\//;
|
|
864
866
|
async function scanDirForPattern(dir, patterns, maxDepth = 6, maxFiles = 2e3) {
|
|
865
867
|
const { readdir, readFile } = await import("fs/promises");
|
|
866
868
|
const { join: join3 } = await import("path");
|
|
@@ -969,6 +971,19 @@ async function collectMcpSources(root, home) {
|
|
|
969
971
|
}
|
|
970
972
|
return { sources, invalid };
|
|
971
973
|
}
|
|
974
|
+
function claudeOAuthCannotDiscover(entry, url) {
|
|
975
|
+
let host;
|
|
976
|
+
try {
|
|
977
|
+
host = new URL(url).hostname.toLowerCase();
|
|
978
|
+
} catch {
|
|
979
|
+
return false;
|
|
980
|
+
}
|
|
981
|
+
if (!host.endsWith(".supabase.co")) return false;
|
|
982
|
+
const headers = isJsonObject(entry.headers) ? Object.keys(entry.headers).map((h) => h.toLowerCase()) : [];
|
|
983
|
+
if (headers.includes("authorization") || headers.includes("x-mushi-api-key")) return false;
|
|
984
|
+
const oauth = isJsonObject(entry.oauth) ? entry.oauth : {};
|
|
985
|
+
return typeof oauth.authServerMetadataUrl !== "string" || oauth.authServerMetadataUrl.length === 0;
|
|
986
|
+
}
|
|
972
987
|
function assessMushiEntry(source, name, entry, cliKeySaved) {
|
|
973
988
|
const label = `${name} (${source.path})`;
|
|
974
989
|
if (!isJsonObject(entry)) return { usable: false, stdio: false, detail: `${label}: not an object` };
|
|
@@ -980,6 +995,13 @@ function assessMushiEntry(source, name, entry, cliKeySaved) {
|
|
|
980
995
|
detail: `${label}: has a url but no "type": "http" \u2014 Claude Code skips it`
|
|
981
996
|
};
|
|
982
997
|
}
|
|
998
|
+
if (source.claudeCode && claudeOAuthCannotDiscover(entry, entry.url)) {
|
|
999
|
+
return {
|
|
1000
|
+
usable: false,
|
|
1001
|
+
stdio: false,
|
|
1002
|
+
detail: `${label}: Claude Code sign-in cannot find OAuth metadata on a supabase.co URL ("Dynamic Client Registration rejected (HTTP 404)") \u2014 use ${CLOUD_MCP_OAUTH_URL} for Mushi Cloud, or add "oauth": { "authServerMetadataUrl": "<url>/.well-known/oauth-authorization-server" }`
|
|
1003
|
+
};
|
|
1004
|
+
}
|
|
983
1005
|
return { usable: true, stdio: false, detail: `${label}: hosted OAuth \u2014 sign in from the IDE's MCP panel` };
|
|
984
1006
|
}
|
|
985
1007
|
const env = isJsonObject(entry.env) ? entry.env : {};
|
|
@@ -1358,7 +1380,7 @@ async function runInit(options = {}) {
|
|
|
1358
1380
|
const framework = await chooseFramework(detected, options);
|
|
1359
1381
|
const consoleBase = await resolveConsoleUrl({ cwd });
|
|
1360
1382
|
const endpoint = resolveCloudEndpoint(
|
|
1361
|
-
options.endpoint
|
|
1383
|
+
firstEndpoint(options.endpoint, process.env.MUSHI_API_ENDPOINT, loadConfig().endpoint)
|
|
1362
1384
|
);
|
|
1363
1385
|
options = { ...options, endpoint };
|
|
1364
1386
|
const credentials = await acquireCredentials(options, consoleBase, endpoint);
|
|
@@ -2037,7 +2059,7 @@ async function maybeOfferConnect(credentials, options, _consoleBase) {
|
|
|
2037
2059
|
if (p.isCancel(answer) || !answer) return;
|
|
2038
2060
|
const endpoint = resolveCloudEndpoint(options.endpoint);
|
|
2039
2061
|
try {
|
|
2040
|
-
const { runConnect } = await import("./connect-
|
|
2062
|
+
const { runConnect } = await import("./connect-YDQ65VJY.js");
|
|
2041
2063
|
const saved = loadConfig();
|
|
2042
2064
|
const result = await runConnect(
|
|
2043
2065
|
{
|
package/dist/version.d.ts
CHANGED
|
@@ -14,6 +14,6 @@ declare const MUSHI_CLI_VERSION: string;
|
|
|
14
14
|
* setup refreshes the pin. Synced to packages/mcp/package.json by
|
|
15
15
|
* `scripts/sync-mcp-pin.mjs` — never hand-edit the version.
|
|
16
16
|
*/
|
|
17
|
-
declare const MUSHI_MCP_PIN_SPEC = "@mushi-mushi/mcp@0.
|
|
17
|
+
declare const MUSHI_MCP_PIN_SPEC = "@mushi-mushi/mcp@0.25.0";
|
|
18
18
|
|
|
19
19
|
export { MUSHI_CLI_VERSION, MUSHI_MCP_PIN_SPEC };
|
package/dist/version.js
CHANGED
package/package.json
CHANGED
package/dist/chunk-P7JI5H57.js
DELETED