@mcp-use/client 2.0.0-beta.1 → 2.0.0-beta.11
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/.tsbuildinfo +1 -1
- package/dist/auth/browser.d.ts +8 -4
- package/dist/auth/browser.d.ts.map +1 -1
- package/dist/auth/session-store.d.ts +6 -1
- package/dist/auth/session-store.d.ts.map +1 -1
- package/dist/index-browser.d.ts +1 -1
- package/dist/index-browser.d.ts.map +1 -1
- package/dist/index-browser.js +139 -166
- package/dist/index-browser.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +65 -170
- package/dist/index.js.map +1 -1
- package/dist/react/index.js +406 -233
- package/dist/react/index.js.map +1 -1
- package/dist/react/types.d.ts +9 -3
- package/dist/react/types.d.ts.map +1 -1
- package/dist/react/useMcp-helpers.d.ts.map +1 -1
- package/dist/react/useMcp-operations.d.ts.map +1 -1
- package/dist/react/useMcp.d.ts.map +1 -1
- package/dist/react/view/ViewRenderer.d.ts +2 -1
- package/dist/react/view/ViewRenderer.d.ts.map +1 -1
- package/dist/react/view/inject-openai-file-apis.d.ts +6 -0
- package/dist/react/view/inject-openai-file-apis.d.ts.map +1 -0
- package/dist/react/view/types.d.ts +16 -0
- package/dist/react/view/types.d.ts.map +1 -1
- package/dist/react/view/use-display-mode.d.ts +1 -0
- package/dist/react/view/use-display-mode.d.ts.map +1 -1
- package/dist/telemetry/index.d.ts +1 -1
- package/dist/telemetry/index.d.ts.map +1 -1
- package/dist/telemetry/tel-fetch.d.ts +0 -6
- package/dist/telemetry/tel-fetch.d.ts.map +1 -1
- package/dist/telemetry/telemetry-node.d.ts.map +1 -1
- package/dist/telemetry/telemetry.d.ts +0 -8
- package/dist/telemetry/telemetry.d.ts.map +1 -1
- package/dist/transport/http.d.ts +6 -6
- package/package.json +2 -2
package/dist/react/index.js
CHANGED
|
@@ -1473,7 +1473,7 @@ var HttpConnector = class extends BaseConnector {
|
|
|
1473
1473
|
};
|
|
1474
1474
|
|
|
1475
1475
|
// src/utils/version.ts
|
|
1476
|
-
var VERSION = "2.0.0-beta.
|
|
1476
|
+
var VERSION = "2.0.0-beta.10";
|
|
1477
1477
|
function getPackageVersion() {
|
|
1478
1478
|
return VERSION;
|
|
1479
1479
|
}
|
|
@@ -1696,29 +1696,39 @@ var OAuthSessionStore = class _OAuthSessionStore {
|
|
|
1696
1696
|
if (ctx) await this.store.set(this.credentialKey("tokens"), serialized);
|
|
1697
1697
|
await this.store.remove(this.getKey("code_verifier"));
|
|
1698
1698
|
await this.store.remove(this.getKey("last_auth_url"));
|
|
1699
|
+
await this.store.remove(this.getKey("last_auth_callback_url"));
|
|
1699
1700
|
}
|
|
1700
1701
|
async clientInformation(ctx) {
|
|
1702
|
+
if (!this.allowClientSecret) {
|
|
1703
|
+
const registeredRedirectUri = await this.store.get(
|
|
1704
|
+
this.getKey("client_info_redirect_uri")
|
|
1705
|
+
);
|
|
1706
|
+
if (registeredRedirectUri !== this.redirectUrl) {
|
|
1707
|
+
await this.invalidateCredentials("registration");
|
|
1708
|
+
console.info(
|
|
1709
|
+
`[${this.storageKeyPrefix}] Re-registering browser OAuth client after its Inspector callback changed or could not be verified.`
|
|
1710
|
+
);
|
|
1711
|
+
return void 0;
|
|
1712
|
+
}
|
|
1713
|
+
}
|
|
1701
1714
|
const stored = await this.readCredential("client_info", ctx);
|
|
1702
1715
|
if (!stored) return void 0;
|
|
1703
1716
|
const { key, value: clientInfo } = stored;
|
|
1704
1717
|
try {
|
|
1705
1718
|
if (!this.allowClientSecret && clientInfo.client_secret) {
|
|
1706
|
-
await this.
|
|
1707
|
-
if (ctx) await this.store.remove(this.credentialKey("client_info"));
|
|
1719
|
+
await this.invalidateCredentials("registration");
|
|
1708
1720
|
console.warn(
|
|
1709
|
-
`[${this.storageKeyPrefix}]
|
|
1721
|
+
`[${this.storageKeyPrefix}] Recovered stale browser OAuth credentials containing a client_secret.`
|
|
1710
1722
|
);
|
|
1711
1723
|
return void 0;
|
|
1712
1724
|
}
|
|
1713
1725
|
const storedRedirectUris = Array.isArray(clientInfo.redirect_uris) ? clientInfo.redirect_uris : [];
|
|
1714
|
-
const hasMatchingRedirect = storedRedirectUris.length === 0 || storedRedirectUris.includes(this.redirectUrl);
|
|
1726
|
+
const hasMatchingRedirect = storedRedirectUris.length === 0 && this.allowClientSecret || storedRedirectUris.includes(this.redirectUrl);
|
|
1715
1727
|
if (!hasMatchingRedirect) {
|
|
1716
1728
|
console.info(
|
|
1717
|
-
`[${this.storageKeyPrefix}]
|
|
1729
|
+
`[${this.storageKeyPrefix}] Recovering cached OAuth credentials after a redirect URI change.`
|
|
1718
1730
|
);
|
|
1719
|
-
await this.
|
|
1720
|
-
await this.store.remove(this.credentialKey("tokens", ctx));
|
|
1721
|
-
await this.store.remove(this.getKey("last_auth_url"));
|
|
1731
|
+
await this.invalidateCredentials("registration");
|
|
1722
1732
|
return void 0;
|
|
1723
1733
|
}
|
|
1724
1734
|
return clientInfo;
|
|
@@ -1736,11 +1746,20 @@ var OAuthSessionStore = class _OAuthSessionStore {
|
|
|
1736
1746
|
"Browser OAuth clients must be public clients; client_secret persistence is not allowed."
|
|
1737
1747
|
);
|
|
1738
1748
|
}
|
|
1739
|
-
const
|
|
1749
|
+
const persistedClientInformation = !this.allowClientSecret && (!("redirect_uris" in clientInformation) || !Array.isArray(
|
|
1750
|
+
clientInformation.redirect_uris
|
|
1751
|
+
) || clientInformation.redirect_uris.length === 0) ? { ...clientInformation, redirect_uris: [this.redirectUrl] } : clientInformation;
|
|
1752
|
+
const serialized = JSON.stringify(persistedClientInformation);
|
|
1740
1753
|
await this.store.set(this.credentialKey("client_info", ctx), serialized);
|
|
1741
1754
|
if (ctx) {
|
|
1742
1755
|
await this.store.set(this.credentialKey("client_info"), serialized);
|
|
1743
1756
|
}
|
|
1757
|
+
if (!this.allowClientSecret) {
|
|
1758
|
+
await this.store.set(
|
|
1759
|
+
this.getKey("client_info_redirect_uri"),
|
|
1760
|
+
this.redirectUrl
|
|
1761
|
+
);
|
|
1762
|
+
}
|
|
1744
1763
|
}
|
|
1745
1764
|
async saveCodeVerifier(codeVerifier) {
|
|
1746
1765
|
await this.store.set(this.getKey("code_verifier"), codeVerifier);
|
|
@@ -1765,11 +1784,22 @@ var OAuthSessionStore = class _OAuthSessionStore {
|
|
|
1765
1784
|
}
|
|
1766
1785
|
};
|
|
1767
1786
|
switch (scope) {
|
|
1787
|
+
case "registration":
|
|
1788
|
+
await removeCredentialKeys("tokens");
|
|
1789
|
+
await removeCredentialKeys("client_info");
|
|
1790
|
+
await this.store.remove(this.getKey("code_verifier"));
|
|
1791
|
+
await this.store.remove(this.getKey("last_auth_url"));
|
|
1792
|
+
await this.store.remove(this.getKey("last_auth_callback_url"));
|
|
1793
|
+
await this.store.remove(this.getKey("client_info_redirect_uri"));
|
|
1794
|
+
await this.store.remove(this.getKey("token_endpoint"));
|
|
1795
|
+
break;
|
|
1768
1796
|
case "all":
|
|
1769
1797
|
await removeCredentialKeys("tokens");
|
|
1770
1798
|
await removeCredentialKeys("client_info");
|
|
1771
1799
|
await this.store.remove(this.getKey("code_verifier"));
|
|
1772
1800
|
await this.store.remove(this.getKey("last_auth_url"));
|
|
1801
|
+
await this.store.remove(this.getKey("last_auth_callback_url"));
|
|
1802
|
+
await this.store.remove(this.getKey("client_info_redirect_uri"));
|
|
1773
1803
|
await this.store.remove(this.getKey("discovery_state"));
|
|
1774
1804
|
await this.store.remove(this.getKey("token_endpoint"));
|
|
1775
1805
|
break;
|
|
@@ -1839,6 +1869,10 @@ var OAuthSessionStore = class _OAuthSessionStore {
|
|
|
1839
1869
|
authorizationUrl.searchParams.set("state", state);
|
|
1840
1870
|
const sanitizedAuthUrl = sanitizeUrl(authorizationUrl.toString());
|
|
1841
1871
|
await this.store.set(stateKey, JSON.stringify(stateData));
|
|
1872
|
+
await this.store.set(
|
|
1873
|
+
this.getKey("last_auth_callback_url"),
|
|
1874
|
+
this.redirectUrl
|
|
1875
|
+
);
|
|
1842
1876
|
await this.store.set(this.getKey("last_auth_url"), sanitizedAuthUrl);
|
|
1843
1877
|
return sanitizedAuthUrl;
|
|
1844
1878
|
}
|
|
@@ -1849,6 +1883,14 @@ var OAuthSessionStore = class _OAuthSessionStore {
|
|
|
1849
1883
|
async getTokenEndpoint() {
|
|
1850
1884
|
return (await this.discoveryState())?.authorizationServerMetadata?.token_endpoint ?? null;
|
|
1851
1885
|
}
|
|
1886
|
+
/**
|
|
1887
|
+
* Return the protected-resource URL selected during OAuth discovery.
|
|
1888
|
+
* Consumers can persist it and reuse it for server-side refresh exchanges.
|
|
1889
|
+
*/
|
|
1890
|
+
async getResource() {
|
|
1891
|
+
const resource = (await this.discoveryState())?.resourceMetadata?.resource;
|
|
1892
|
+
return typeof resource === "string" ? resource : null;
|
|
1893
|
+
}
|
|
1852
1894
|
};
|
|
1853
1895
|
|
|
1854
1896
|
// src/auth/browser.ts
|
|
@@ -1966,20 +2008,19 @@ var BrowserOAuthClientProvider = class {
|
|
|
1966
2008
|
* therefore never alters fetch behavior for other servers, other
|
|
1967
2009
|
* connections, or the rest of the page.
|
|
1968
2010
|
*
|
|
1969
|
-
*
|
|
1970
|
-
*
|
|
1971
|
-
*
|
|
1972
|
-
*
|
|
2011
|
+
* OAuth metadata is always fetched with `cache: "no-store"`, including in
|
|
2012
|
+
* direct mode. Authorization servers commonly vary CORS headers by Origin;
|
|
2013
|
+
* bypassing the browser HTTP cache prevents a revalidated response cached
|
|
2014
|
+
* for another localhost origin from poisoning discovery. When OAuth proxying
|
|
2015
|
+
* is disabled or no `oauthProxyUrl` is configured, all requests still go
|
|
2016
|
+
* directly to their original URLs.
|
|
1973
2017
|
*
|
|
1974
2018
|
* @param baseFetch - The fetch used for non-OAuth requests and for the
|
|
1975
2019
|
* underlying proxy calls. Defaults to the global `fetch`.
|
|
1976
2020
|
*/
|
|
1977
2021
|
getProxyFetch(baseFetch) {
|
|
1978
|
-
if (!this.proxyOAuthRequests || !this.oauthProxyUrl) {
|
|
1979
|
-
return baseFetch;
|
|
1980
|
-
}
|
|
1981
2022
|
const base = baseFetch ?? globalThis.fetch.bind(globalThis);
|
|
1982
|
-
const oauthProxyUrl = this.oauthProxyUrl;
|
|
2023
|
+
const oauthProxyUrl = this.proxyOAuthRequests && this.oauthProxyUrl ? this.oauthProxyUrl : void 0;
|
|
1983
2024
|
const discoveredEndpoints = /* @__PURE__ */ new Set();
|
|
1984
2025
|
let restoredDiscovery = false;
|
|
1985
2026
|
return async (input, init) => {
|
|
@@ -1992,6 +2033,12 @@ var BrowserOAuthClientProvider = class {
|
|
|
1992
2033
|
return await base(input, init);
|
|
1993
2034
|
}
|
|
1994
2035
|
const isMetadata = pathname.includes("/.well-known/");
|
|
2036
|
+
if (!oauthProxyUrl) {
|
|
2037
|
+
return await base(
|
|
2038
|
+
isMetadata ? url : input,
|
|
2039
|
+
isMetadata ? { ...init, cache: "no-store" } : init
|
|
2040
|
+
);
|
|
2041
|
+
}
|
|
1995
2042
|
if (!restoredDiscovery) {
|
|
1996
2043
|
restoredDiscovery = true;
|
|
1997
2044
|
const metadata = (await this.discoveryState())?.authorizationServerMetadata;
|
|
@@ -2026,7 +2073,8 @@ var BrowserOAuthClientProvider = class {
|
|
|
2026
2073
|
if (isMetadata) {
|
|
2027
2074
|
const response2 = await base(proxyEndpoint, {
|
|
2028
2075
|
...init,
|
|
2029
|
-
method: "GET"
|
|
2076
|
+
method: "GET",
|
|
2077
|
+
cache: "no-store"
|
|
2030
2078
|
});
|
|
2031
2079
|
try {
|
|
2032
2080
|
const metadata = await response2.clone().json();
|
|
@@ -2044,23 +2092,40 @@ var BrowserOAuthClientProvider = class {
|
|
|
2044
2092
|
}
|
|
2045
2093
|
return response2;
|
|
2046
2094
|
}
|
|
2047
|
-
const
|
|
2095
|
+
const inputRequest = input instanceof Request ? input : void 0;
|
|
2096
|
+
const method = init?.method ?? inputRequest?.method ?? "POST";
|
|
2097
|
+
const requestHeaders = init?.headers ?? inputRequest?.headers;
|
|
2098
|
+
let body;
|
|
2099
|
+
if (init?.body !== void 0 && init.body !== null) {
|
|
2100
|
+
body = await serializeBody(init.body);
|
|
2101
|
+
} else if (inputRequest?.body && method !== "GET" && method !== "HEAD") {
|
|
2102
|
+
body = await inputRequest.clone().text();
|
|
2103
|
+
}
|
|
2048
2104
|
const response = await base(proxyEndpoint, {
|
|
2049
2105
|
method: "POST",
|
|
2050
2106
|
headers: { "Content-Type": "application/json" },
|
|
2051
2107
|
body: JSON.stringify({
|
|
2052
2108
|
serverUrl: this.serverUrl,
|
|
2053
2109
|
url,
|
|
2054
|
-
method
|
|
2055
|
-
headers:
|
|
2110
|
+
method,
|
|
2111
|
+
headers: requestHeaders ? Object.fromEntries(new Headers(requestHeaders)) : {},
|
|
2056
2112
|
body
|
|
2057
2113
|
})
|
|
2058
2114
|
});
|
|
2059
2115
|
const data = await response.json();
|
|
2116
|
+
if (!response.ok || typeof data.status !== "number") {
|
|
2117
|
+
return new Response(JSON.stringify(data), {
|
|
2118
|
+
status: response.status,
|
|
2119
|
+
statusText: response.statusText,
|
|
2120
|
+
headers: response.headers
|
|
2121
|
+
});
|
|
2122
|
+
}
|
|
2060
2123
|
return new Response(JSON.stringify(data.body), {
|
|
2061
2124
|
status: data.status,
|
|
2062
|
-
statusText: data.statusText,
|
|
2063
|
-
headers: new Headers(
|
|
2125
|
+
statusText: typeof data.statusText === "string" ? data.statusText : void 0,
|
|
2126
|
+
headers: new Headers(
|
|
2127
|
+
data.headers && typeof data.headers === "object" ? data.headers : void 0
|
|
2128
|
+
)
|
|
2064
2129
|
});
|
|
2065
2130
|
};
|
|
2066
2131
|
}
|
|
@@ -2083,7 +2148,16 @@ var BrowserOAuthClientProvider = class {
|
|
|
2083
2148
|
}
|
|
2084
2149
|
async saveClientInformation(clientInformation, ctx) {
|
|
2085
2150
|
if (this.staticClientInfo) return;
|
|
2086
|
-
|
|
2151
|
+
const { client_secret: discardedClientSecret, ...publicClientInformation } = clientInformation;
|
|
2152
|
+
if (discardedClientSecret) {
|
|
2153
|
+
console.info(
|
|
2154
|
+
`[${this.storageKeyPrefix}] Discarded client_secret returned for a public browser OAuth client.`
|
|
2155
|
+
);
|
|
2156
|
+
}
|
|
2157
|
+
return this.session.saveClientInformation(
|
|
2158
|
+
publicClientInformation,
|
|
2159
|
+
ctx
|
|
2160
|
+
);
|
|
2087
2161
|
}
|
|
2088
2162
|
codeVerifier() {
|
|
2089
2163
|
return this.session.codeVerifier();
|
|
@@ -2113,6 +2187,10 @@ var BrowserOAuthClientProvider = class {
|
|
|
2113
2187
|
getTokenEndpoint() {
|
|
2114
2188
|
return this.session.getTokenEndpoint();
|
|
2115
2189
|
}
|
|
2190
|
+
/** Return the protected-resource URL selected during OAuth discovery. */
|
|
2191
|
+
getResource() {
|
|
2192
|
+
return this.session.getResource();
|
|
2193
|
+
}
|
|
2116
2194
|
/**
|
|
2117
2195
|
* Return the stored public OAuth client ID. Browser providers do not retain
|
|
2118
2196
|
* client secrets.
|
|
@@ -2191,7 +2269,31 @@ var BrowserOAuthClientProvider = class {
|
|
|
2191
2269
|
getLastAttemptedAuthUrl() {
|
|
2192
2270
|
const storedUrl = localStorage.getItem(this.getKey("last_auth_url"));
|
|
2193
2271
|
if (!storedUrl) return null;
|
|
2194
|
-
|
|
2272
|
+
const storedCallbackUrl = localStorage.getItem(
|
|
2273
|
+
this.getKey("last_auth_callback_url")
|
|
2274
|
+
);
|
|
2275
|
+
if (storedCallbackUrl !== this.callbackUrl) {
|
|
2276
|
+
console.info(
|
|
2277
|
+
`[${this.storageKeyPrefix}] Recovering stale OAuth state whose callback cannot be verified.`
|
|
2278
|
+
);
|
|
2279
|
+
this.clearStorage();
|
|
2280
|
+
return null;
|
|
2281
|
+
}
|
|
2282
|
+
const sanitized = sanitizeUrl(storedUrl);
|
|
2283
|
+
try {
|
|
2284
|
+
const redirectUri = new URL(sanitized).searchParams.get("redirect_uri");
|
|
2285
|
+
if (redirectUri && new URL(redirectUri).toString() !== new URL(this.callbackUrl).toString()) {
|
|
2286
|
+
console.info(
|
|
2287
|
+
`[${this.storageKeyPrefix}] Recovering stale OAuth state after the Inspector callback path changed.`
|
|
2288
|
+
);
|
|
2289
|
+
this.clearStorage();
|
|
2290
|
+
return null;
|
|
2291
|
+
}
|
|
2292
|
+
} catch {
|
|
2293
|
+
this.clearStorage();
|
|
2294
|
+
return null;
|
|
2295
|
+
}
|
|
2296
|
+
return sanitized;
|
|
2195
2297
|
}
|
|
2196
2298
|
clearStorage() {
|
|
2197
2299
|
const prefixPattern = `${this.storageKeyPrefix}_${this.serverUrlHash}_`;
|
|
@@ -2370,62 +2472,6 @@ async function telFetch(url, init) {
|
|
|
2370
2472
|
}
|
|
2371
2473
|
var POSTHOG_HOST = "https://eu.i.posthog.com";
|
|
2372
2474
|
var POSTHOG_API_KEY = "phc_lyTtbYwvkdSbrcMQNPiKiiRWrrM1seyKIMjycSvItEI";
|
|
2373
|
-
var SCARF_GATEWAY_URL = "https://mcpuse.gateway.scarf.sh/events-ts";
|
|
2374
|
-
var SCARF_GATEWAY_BEACON_URL = "https://mcpuse.gateway.scarf.sh/simple/";
|
|
2375
|
-
var SCARF_BEACON_MAX_URL = 1800;
|
|
2376
|
-
var SCARF_BEACON_TRUNCATED_KEYS = /* @__PURE__ */ new Set(["query", "response", "messages"]);
|
|
2377
|
-
function stringifyScarfValue(value) {
|
|
2378
|
-
if (value === null || value === void 0) return "";
|
|
2379
|
-
if (typeof value === "string") return value;
|
|
2380
|
-
if (typeof value === "number" || typeof value === "boolean") {
|
|
2381
|
-
return String(value);
|
|
2382
|
-
}
|
|
2383
|
-
try {
|
|
2384
|
-
return JSON.stringify(value);
|
|
2385
|
-
} catch {
|
|
2386
|
-
return String(value);
|
|
2387
|
-
}
|
|
2388
|
-
}
|
|
2389
|
-
function buildScarfBeaconUrl(properties, baseUrl = SCARF_GATEWAY_BEACON_URL) {
|
|
2390
|
-
const params = new URLSearchParams();
|
|
2391
|
-
for (const [key, value] of Object.entries(properties)) {
|
|
2392
|
-
let serialized = stringifyScarfValue(value);
|
|
2393
|
-
if (SCARF_BEACON_TRUNCATED_KEYS.has(key) && serialized.length > 120) {
|
|
2394
|
-
serialized = `${serialized.slice(0, 117)}...`;
|
|
2395
|
-
}
|
|
2396
|
-
if (serialized !== "") params.set(key, serialized);
|
|
2397
|
-
}
|
|
2398
|
-
let url = `${baseUrl}${baseUrl.includes("?") ? "&" : "?"}${params.toString()}`;
|
|
2399
|
-
if (url.length <= SCARF_BEACON_MAX_URL) return url;
|
|
2400
|
-
const keys = [...params.keys()].sort(
|
|
2401
|
-
(a, b) => (params.get(b)?.length ?? 0) - (params.get(a)?.length ?? 0)
|
|
2402
|
-
);
|
|
2403
|
-
for (const key of keys) {
|
|
2404
|
-
if (url.length <= SCARF_BEACON_MAX_URL) break;
|
|
2405
|
-
if (key === "event" || key === "user_id") continue;
|
|
2406
|
-
params.delete(key);
|
|
2407
|
-
url = `${baseUrl}${baseUrl.includes("?") ? "&" : "?"}${params.toString()}`;
|
|
2408
|
-
}
|
|
2409
|
-
return url.slice(0, SCARF_BEACON_MAX_URL);
|
|
2410
|
-
}
|
|
2411
|
-
function captureScarfPost(properties, endpoint) {
|
|
2412
|
-
return telFetch(endpoint, {
|
|
2413
|
-
method: "POST",
|
|
2414
|
-
headers: { "Content-Type": "application/json" },
|
|
2415
|
-
keepalive: true,
|
|
2416
|
-
body: JSON.stringify(properties)
|
|
2417
|
-
});
|
|
2418
|
-
}
|
|
2419
|
-
function captureScarfBeacon(properties, endpoint) {
|
|
2420
|
-
try {
|
|
2421
|
-
const url = buildScarfBeaconUrl(properties, endpoint);
|
|
2422
|
-
const img = new Image();
|
|
2423
|
-
img.referrerPolicy = "no-referrer-when-downgrade";
|
|
2424
|
-
img.src = url;
|
|
2425
|
-
} catch {
|
|
2426
|
-
}
|
|
2427
|
-
return Promise.resolve();
|
|
2428
|
-
}
|
|
2429
2475
|
function capturePostHog(params) {
|
|
2430
2476
|
const host = params.host ?? POSTHOG_HOST;
|
|
2431
2477
|
const apiKey = params.apiKey ?? POSTHOG_API_KEY;
|
|
@@ -2442,13 +2488,6 @@ function capturePostHog(params) {
|
|
|
2442
2488
|
})
|
|
2443
2489
|
});
|
|
2444
2490
|
}
|
|
2445
|
-
function captureScarf(properties, endpoint = SCARF_GATEWAY_URL) {
|
|
2446
|
-
if (typeof window !== "undefined") {
|
|
2447
|
-
const beaconEndpoint = endpoint === SCARF_GATEWAY_URL ? SCARF_GATEWAY_BEACON_URL : endpoint;
|
|
2448
|
-
return captureScarfBeacon(properties, beaconEndpoint);
|
|
2449
|
-
}
|
|
2450
|
-
return captureScarfPost(properties, endpoint);
|
|
2451
|
-
}
|
|
2452
2491
|
|
|
2453
2492
|
// src/telemetry/telemetry.ts
|
|
2454
2493
|
function generateUUID() {
|
|
@@ -2459,18 +2498,6 @@ function secureRandomString() {
|
|
|
2459
2498
|
globalThis.crypto.getRandomValues(array);
|
|
2460
2499
|
return Array.from(array, (v) => v.toString(16).padStart(2, "0")).join("");
|
|
2461
2500
|
}
|
|
2462
|
-
function isVersionGreater(a, b) {
|
|
2463
|
-
const parse = (v) => v.split("-")[0].split(".").map((n) => parseInt(n, 10) || 0);
|
|
2464
|
-
const pa = parse(a);
|
|
2465
|
-
const pb = parse(b);
|
|
2466
|
-
const len = Math.max(pa.length, pb.length);
|
|
2467
|
-
for (let i = 0; i < len; i++) {
|
|
2468
|
-
const da = pa[i] ?? 0;
|
|
2469
|
-
const db = pb[i] ?? 0;
|
|
2470
|
-
if (da !== db) return da > db;
|
|
2471
|
-
}
|
|
2472
|
-
return false;
|
|
2473
|
-
}
|
|
2474
2501
|
var USER_ID_STORAGE_KEY = "mcp_use_user_id";
|
|
2475
2502
|
var PROJECT_API_KEY = "phc_lyTtbYwvkdSbrcMQNPiKiiRWrrM1seyKIMjycSvItEI";
|
|
2476
2503
|
var HOST = "https://eu.i.posthog.com";
|
|
@@ -2499,10 +2526,7 @@ function createLocalStorageBackend() {
|
|
|
2499
2526
|
localStorage.setItem(USER_ID_STORAGE_KEY, id);
|
|
2500
2527
|
} catch {
|
|
2501
2528
|
}
|
|
2502
|
-
}
|
|
2503
|
-
// Package-download dedup is node/Scarf-oriented; localStorage unused.
|
|
2504
|
-
getDownloadedVersion: () => null,
|
|
2505
|
-
setDownloadedVersion: () => void 0
|
|
2529
|
+
}
|
|
2506
2530
|
};
|
|
2507
2531
|
}
|
|
2508
2532
|
function detectRuntimeEnvironment() {
|
|
@@ -2570,17 +2594,13 @@ var Telemetry = class _Telemetry {
|
|
|
2570
2594
|
_currUserId = null;
|
|
2571
2595
|
_telemetryEnabled = false;
|
|
2572
2596
|
_pending = /* @__PURE__ */ new Set();
|
|
2573
|
-
_scarfEnabled = false;
|
|
2574
2597
|
_runtimeEnvironment;
|
|
2575
2598
|
_storageCapability;
|
|
2576
2599
|
_storage;
|
|
2577
|
-
/** True when node entry installed fs storage (package-download dedup). */
|
|
2578
|
-
_fsBacked;
|
|
2579
2600
|
_source;
|
|
2580
2601
|
_productVersion;
|
|
2581
2602
|
constructor() {
|
|
2582
2603
|
this._runtimeEnvironment = detectRuntimeEnvironment();
|
|
2583
|
-
this._fsBacked = configuredStorage !== null;
|
|
2584
2604
|
this._storage = configuredStorage ?? createLocalStorageBackend() ?? null;
|
|
2585
2605
|
this._storageCapability = this._storage ? "persistent" : "session-only";
|
|
2586
2606
|
this._source = readSourceHint() || this._runtimeEnvironment;
|
|
@@ -2599,14 +2619,6 @@ var Telemetry = class _Telemetry {
|
|
|
2599
2619
|
"Anonymized telemetry enabled. Set MCP_USE_ANONYMIZED_TELEMETRY=false to disable."
|
|
2600
2620
|
);
|
|
2601
2621
|
this._telemetryEnabled = true;
|
|
2602
|
-
this._scarfEnabled = true;
|
|
2603
|
-
if (this._fsBacked) {
|
|
2604
|
-
setTimeout(() => {
|
|
2605
|
-
this.trackPackageDownload({ triggered_by: "initialization" }).catch(
|
|
2606
|
-
(e) => logger.debug(`Failed to track package download: ${e}`)
|
|
2607
|
-
);
|
|
2608
|
-
}, 0);
|
|
2609
|
-
}
|
|
2610
2622
|
}
|
|
2611
2623
|
}
|
|
2612
2624
|
get runtimeEnvironment() {
|
|
@@ -2638,7 +2650,7 @@ var Telemetry = class _Telemetry {
|
|
|
2638
2650
|
this._productVersion = version;
|
|
2639
2651
|
}
|
|
2640
2652
|
get isEnabled() {
|
|
2641
|
-
return this._telemetryEnabled
|
|
2653
|
+
return this._telemetryEnabled;
|
|
2642
2654
|
}
|
|
2643
2655
|
get userId() {
|
|
2644
2656
|
if (this._currUserId) return this._currUserId;
|
|
@@ -2661,7 +2673,7 @@ var Telemetry = class _Telemetry {
|
|
|
2661
2673
|
return this._currUserId;
|
|
2662
2674
|
}
|
|
2663
2675
|
async capture(event) {
|
|
2664
|
-
if (!this._telemetryEnabled
|
|
2676
|
+
if (!this._telemetryEnabled) return;
|
|
2665
2677
|
const currentUserId = this.userId;
|
|
2666
2678
|
const properties = {
|
|
2667
2679
|
...event.properties,
|
|
@@ -2670,52 +2682,15 @@ var Telemetry = class _Telemetry {
|
|
|
2670
2682
|
source: this._source,
|
|
2671
2683
|
runtime: this._runtimeEnvironment
|
|
2672
2684
|
};
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
properties
|
|
2680
|
-
});
|
|
2681
|
-
this._pending.add(p);
|
|
2682
|
-
void p.finally(() => this._pending.delete(p));
|
|
2683
|
-
}
|
|
2684
|
-
if (this._scarfEnabled) {
|
|
2685
|
-
const p = captureScarf({
|
|
2686
|
-
...properties,
|
|
2687
|
-
user_id: currentUserId,
|
|
2688
|
-
event: event.name
|
|
2689
|
-
});
|
|
2690
|
-
this._pending.add(p);
|
|
2691
|
-
void p.finally(() => this._pending.delete(p));
|
|
2692
|
-
}
|
|
2693
|
-
}
|
|
2694
|
-
async trackPackageDownload(properties) {
|
|
2695
|
-
if (!this._scarfEnabled || !this._fsBacked || !this._storage) return;
|
|
2696
|
-
const currentVersion = getPackageVersion();
|
|
2697
|
-
const saved = this._storage.getDownloadedVersion();
|
|
2698
|
-
let firstDownload = false;
|
|
2699
|
-
let shouldTrack = false;
|
|
2700
|
-
if (!saved) {
|
|
2701
|
-
shouldTrack = true;
|
|
2702
|
-
firstDownload = true;
|
|
2703
|
-
this._storage.setDownloadedVersion(currentVersion);
|
|
2704
|
-
} else if (isVersionGreater(currentVersion, saved)) {
|
|
2705
|
-
shouldTrack = true;
|
|
2706
|
-
this._storage.setDownloadedVersion(currentVersion);
|
|
2707
|
-
}
|
|
2708
|
-
if (!shouldTrack) return;
|
|
2709
|
-
await captureScarf({
|
|
2710
|
-
...properties || {},
|
|
2711
|
-
mcp_use_version: currentVersion,
|
|
2712
|
-
user_id: this.userId,
|
|
2713
|
-
event: "package_download",
|
|
2714
|
-
first_download: firstDownload,
|
|
2715
|
-
language: "typescript",
|
|
2716
|
-
source: this._source,
|
|
2717
|
-
runtime: this._runtimeEnvironment
|
|
2685
|
+
const p = capturePostHog({
|
|
2686
|
+
host: HOST,
|
|
2687
|
+
apiKey: PROJECT_API_KEY,
|
|
2688
|
+
event: event.name,
|
|
2689
|
+
distinctId: currentUserId,
|
|
2690
|
+
properties
|
|
2718
2691
|
});
|
|
2692
|
+
this._pending.add(p);
|
|
2693
|
+
void p.finally(() => this._pending.delete(p));
|
|
2719
2694
|
}
|
|
2720
2695
|
async trackAgentExecution(data) {
|
|
2721
2696
|
if (!this.isEnabled) return;
|
|
@@ -4162,9 +4137,14 @@ function startConnectionHealthMonitoring(params) {
|
|
|
4162
4137
|
return;
|
|
4163
4138
|
}
|
|
4164
4139
|
const authHeaders = params.getAuthHeaders ? await params.getAuthHeaders() : {};
|
|
4140
|
+
const healthCheckHeaders = {
|
|
4141
|
+
...params.allHeaders,
|
|
4142
|
+
...authHeaders,
|
|
4143
|
+
...params.gatewayUrl && params.url ? { "X-Target-URL": params.url } : {}
|
|
4144
|
+
};
|
|
4165
4145
|
const response = await fetch(healthCheckUrl, {
|
|
4166
4146
|
method: "HEAD",
|
|
4167
|
-
headers:
|
|
4147
|
+
headers: healthCheckHeaders,
|
|
4168
4148
|
signal: AbortSignal.timeout(5e3)
|
|
4169
4149
|
});
|
|
4170
4150
|
if (response.status === 405 || response.status === 404) {
|
|
@@ -4384,6 +4364,7 @@ function useMcp(options) {
|
|
|
4384
4364
|
headers: headersOption,
|
|
4385
4365
|
proxyConfig,
|
|
4386
4366
|
oauthProxyUrl: oauthProxyUrlOption,
|
|
4367
|
+
connectionMode,
|
|
4387
4368
|
autoProxyFallback = false,
|
|
4388
4369
|
logLevel: logLevelOption = "silent",
|
|
4389
4370
|
autoRetry = false,
|
|
@@ -4407,6 +4388,7 @@ function useMcp(options) {
|
|
|
4407
4388
|
oauth: oauthOptions
|
|
4408
4389
|
} = options;
|
|
4409
4390
|
const transportType = "http";
|
|
4391
|
+
const requestedProxyAddress = proxyConfig?.proxyAddress;
|
|
4410
4392
|
const oauthClientId = oauthOptions?.clientId?.trim() || void 0;
|
|
4411
4393
|
const oauthClientMetadataUrl = oauthOptions?.clientMetadataUrl?.trim() || void 0;
|
|
4412
4394
|
const oauthScope = oauthOptions?.scope?.trim() || void 0;
|
|
@@ -4454,6 +4436,9 @@ function useMcp(options) {
|
|
|
4454
4436
|
);
|
|
4455
4437
|
const oauthClientConfig = derivedOAuthClientConfig;
|
|
4456
4438
|
const autoProxyFallbackConfig = useMemo(() => {
|
|
4439
|
+
if (connectionMode === "direct" || connectionMode === "proxy") {
|
|
4440
|
+
return { enabled: false, proxyAddress: void 0 };
|
|
4441
|
+
}
|
|
4457
4442
|
if (!autoProxyFallback) {
|
|
4458
4443
|
return { enabled: false, proxyAddress: void 0 };
|
|
4459
4444
|
}
|
|
@@ -4469,7 +4454,7 @@ function useMcp(options) {
|
|
|
4469
4454
|
enabled: autoProxyFallback.enabled !== false && Boolean(proxyAddress),
|
|
4470
4455
|
proxyAddress
|
|
4471
4456
|
};
|
|
4472
|
-
}, [autoProxyFallback, proxyConfig]);
|
|
4457
|
+
}, [autoProxyFallback, connectionMode, proxyConfig]);
|
|
4473
4458
|
const autoReconnectConfig = useMemo(() => {
|
|
4474
4459
|
if (autoReconnect === false) {
|
|
4475
4460
|
return {
|
|
@@ -4505,20 +4490,33 @@ function useMcp(options) {
|
|
|
4505
4490
|
const [effectiveProxyConfig, setEffectiveProxyConfig] = useState(void 0);
|
|
4506
4491
|
useEffect(() => {
|
|
4507
4492
|
setEffectiveProxyConfig(void 0);
|
|
4508
|
-
}, [
|
|
4493
|
+
}, [
|
|
4494
|
+
url,
|
|
4495
|
+
requestedProxyAddress,
|
|
4496
|
+
connectionMode,
|
|
4497
|
+
autoProxyFallbackConfig.proxyAddress
|
|
4498
|
+
]);
|
|
4509
4499
|
const activeProxyConfig = useMemo(() => {
|
|
4510
|
-
|
|
4511
|
-
|
|
4500
|
+
const hasCurrentAutoFallback = autoProxyFallbackConfig.enabled && effectiveProxyConfig?.proxyAddress === autoProxyFallbackConfig.proxyAddress;
|
|
4501
|
+
if (hasCurrentAutoFallback && effectiveProxyConfig) {
|
|
4502
|
+
const latestHeaders = proxyConfig?.headers ?? {};
|
|
4503
|
+
return {
|
|
4504
|
+
...effectiveProxyConfig,
|
|
4505
|
+
headers: {
|
|
4506
|
+
...latestHeaders,
|
|
4507
|
+
...effectiveProxyConfig.headers ?? {}
|
|
4508
|
+
}
|
|
4509
|
+
};
|
|
4512
4510
|
}
|
|
4513
|
-
const
|
|
4514
|
-
return
|
|
4515
|
-
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
|
|
4511
|
+
const startsDirect = connectionMode === "auto" || connectionMode === "direct" || connectionMode === void 0 && autoProxyFallbackConfig.enabled;
|
|
4512
|
+
return startsDirect ? void 0 : proxyConfig;
|
|
4513
|
+
}, [
|
|
4514
|
+
effectiveProxyConfig,
|
|
4515
|
+
proxyConfig,
|
|
4516
|
+
connectionMode,
|
|
4517
|
+
autoProxyFallbackConfig.enabled,
|
|
4518
|
+
autoProxyFallbackConfig.proxyAddress
|
|
4519
|
+
]);
|
|
4522
4520
|
const gatewayUrl = activeProxyConfig?.proxyAddress;
|
|
4523
4521
|
const proxyHeaders = activeProxyConfig?.headers ?? {};
|
|
4524
4522
|
const effectiveOAuthUrl = useMemo(() => {
|
|
@@ -4850,8 +4848,9 @@ function useMcp(options) {
|
|
|
4850
4848
|
clientInfo: mergedClientInfo,
|
|
4851
4849
|
// Pass a fetch that scopes OAuth-proxy routing to this server's
|
|
4852
4850
|
// transport/auth calls. getProxyFetch wraps `customFetch` (e.g. the
|
|
4853
|
-
// OAuth retry fetch for scope step-up)
|
|
4854
|
-
//
|
|
4851
|
+
// OAuth retry fetch for scope step-up), bypasses the browser cache
|
|
4852
|
+
// for OAuth metadata, and optionally routes OAuth through the BFF.
|
|
4853
|
+
// It never mutates the global fetch.
|
|
4855
4854
|
...(() => {
|
|
4856
4855
|
const scopedFetch = authProviderRef.current?.getProxyFetch?.(customFetch) ?? customFetch;
|
|
4857
4856
|
return scopedFetch ? { fetch: scopedFetch } : {};
|
|
@@ -4989,9 +4988,22 @@ function useMcp(options) {
|
|
|
4989
4988
|
});
|
|
4990
4989
|
setTools(connection.tools || []);
|
|
4991
4990
|
const [resourcesResult, promptsResult, templatesResult] = await Promise.all([
|
|
4992
|
-
connection.listAllResources()
|
|
4993
|
-
|
|
4994
|
-
|
|
4991
|
+
connection.listAllResources().catch((error2) => {
|
|
4992
|
+
addLog("warn", "Failed to load initial resources:", error2);
|
|
4993
|
+
return { resources: [] };
|
|
4994
|
+
}),
|
|
4995
|
+
connection.listPrompts().catch((error2) => {
|
|
4996
|
+
addLog("warn", "Failed to load initial prompts:", error2);
|
|
4997
|
+
return { prompts: [] };
|
|
4998
|
+
}),
|
|
4999
|
+
connection.supports("resources") ? connection.listResourceTemplates().catch((error2) => {
|
|
5000
|
+
addLog(
|
|
5001
|
+
"warn",
|
|
5002
|
+
"Failed to load initial resource templates:",
|
|
5003
|
+
error2
|
|
5004
|
+
);
|
|
5005
|
+
return { resourceTemplates: [] };
|
|
5006
|
+
}) : Promise.resolve({ resourceTemplates: [] })
|
|
4995
5007
|
]);
|
|
4996
5008
|
if (!isMountedRef.current) {
|
|
4997
5009
|
addLog(
|
|
@@ -5052,12 +5064,18 @@ function useMcp(options) {
|
|
|
5052
5064
|
if (tokens?.access_token) {
|
|
5053
5065
|
const expiresAt = tokens.expires_in ? Date.now() + tokens.expires_in * 1e3 : void 0;
|
|
5054
5066
|
let tokenEndpoint = null;
|
|
5067
|
+
let resource = null;
|
|
5055
5068
|
let clientCreds = null;
|
|
5056
5069
|
try {
|
|
5057
5070
|
tokenEndpoint = await authProviderRef.current.getTokenEndpoint?.() ?? null;
|
|
5058
5071
|
} catch {
|
|
5059
5072
|
tokenEndpoint = null;
|
|
5060
5073
|
}
|
|
5074
|
+
try {
|
|
5075
|
+
resource = await authProviderRef.current.getResource?.() ?? null;
|
|
5076
|
+
} catch {
|
|
5077
|
+
resource = null;
|
|
5078
|
+
}
|
|
5061
5079
|
try {
|
|
5062
5080
|
clientCreds = await authProviderRef.current.getClientCredentials?.() ?? null;
|
|
5063
5081
|
} catch {
|
|
@@ -5074,6 +5092,7 @@ function useMcp(options) {
|
|
|
5074
5092
|
refresh_token: tokens.refresh_token,
|
|
5075
5093
|
scope: tokens.scope,
|
|
5076
5094
|
...tokenEndpoint ? { token_endpoint: tokenEndpoint } : {},
|
|
5095
|
+
...resource ? { resource } : {},
|
|
5077
5096
|
...clientCreds?.client_id ? { client_id: clientCreds.client_id } : {},
|
|
5078
5097
|
...clientCreds?.client_secret ? { client_secret: clientCreds.client_secret } : {}
|
|
5079
5098
|
});
|
|
@@ -5318,19 +5337,20 @@ function useMcp(options) {
|
|
|
5318
5337
|
addLog("info", "Triggering fresh OAuth authorization...");
|
|
5319
5338
|
const parsedUrl = new URL(url);
|
|
5320
5339
|
const baseUrl = parsedUrl.origin + parsedUrl.pathname.replace(/\/+$/, "");
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5340
|
+
const authResult = await auth2(freshAuthProvider, {
|
|
5341
|
+
serverUrl: baseUrl,
|
|
5342
|
+
fetchFn: freshAuthProvider.getProxyFetch?.()
|
|
5343
|
+
});
|
|
5344
|
+
if (authResult === "AUTHORIZED") {
|
|
5326
5345
|
addLog("info", "OAuth flow completed (tokens obtained)");
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
|
|
5330
|
-
"OAuth flow initiated (popup/redirect):",
|
|
5331
|
-
err instanceof Error ? err.message : "Redirecting..."
|
|
5332
|
-
);
|
|
5346
|
+
connectingRef.current = false;
|
|
5347
|
+
connectRef.current?.();
|
|
5348
|
+
return;
|
|
5333
5349
|
}
|
|
5350
|
+
if (authResult !== "REDIRECT") {
|
|
5351
|
+
throw new Error(`Unexpected OAuth auth() result: ${authResult}`);
|
|
5352
|
+
}
|
|
5353
|
+
addLog("info", "OAuth authorization redirect initiated");
|
|
5334
5354
|
const newAuthUrl = freshAuthProvider.getLastAttemptedAuthUrl?.();
|
|
5335
5355
|
if (newAuthUrl) {
|
|
5336
5356
|
setAuthUrl(newAuthUrl);
|
|
@@ -5396,11 +5416,8 @@ function useMcp(options) {
|
|
|
5396
5416
|
}
|
|
5397
5417
|
} catch (authError) {
|
|
5398
5418
|
if (!isMountedRef.current) return;
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
"error",
|
|
5402
|
-
`Manual authentication failed: ${authError instanceof Error ? authError.message : String(authError)}`
|
|
5403
|
-
);
|
|
5419
|
+
const error2 = authError instanceof Error ? authError : new Error(String(authError));
|
|
5420
|
+
failConnection(`Manual authentication failed: ${error2.message}`, error2);
|
|
5404
5421
|
}
|
|
5405
5422
|
} else if (currentState === "authenticating") {
|
|
5406
5423
|
addLog(
|
|
@@ -5608,6 +5625,7 @@ function useMcp(options) {
|
|
|
5608
5625
|
// Triggers reconnection when proxy fallback changes OAuth URL
|
|
5609
5626
|
proxyConfig,
|
|
5610
5627
|
// Triggers reconnection when proxy config (including headers) changes
|
|
5628
|
+
autoProxyFallbackConfig.proxyAddress,
|
|
5611
5629
|
providedAuthProvider
|
|
5612
5630
|
]);
|
|
5613
5631
|
const retryRef = useRef(retry);
|
|
@@ -6881,6 +6899,7 @@ import React2, {
|
|
|
6881
6899
|
memo,
|
|
6882
6900
|
useCallback as useCallback6,
|
|
6883
6901
|
useEffect as useEffect5,
|
|
6902
|
+
useMemo as useMemo3,
|
|
6884
6903
|
useRef as useRef4,
|
|
6885
6904
|
useState as useState4
|
|
6886
6905
|
} from "react";
|
|
@@ -6903,6 +6922,53 @@ function parseCustomProps(customProps) {
|
|
|
6903
6922
|
return parsed;
|
|
6904
6923
|
}
|
|
6905
6924
|
|
|
6925
|
+
// src/react/view/inject-openai-file-apis.ts
|
|
6926
|
+
var OPENAI_FILE_APIS_SCRIPT = `<script>
|
|
6927
|
+
(function () {
|
|
6928
|
+
var files = new Map();
|
|
6929
|
+
window.openai = window.openai || {};
|
|
6930
|
+
window.openai.uploadFile = async function (file) {
|
|
6931
|
+
var fileId = crypto.randomUUID();
|
|
6932
|
+
files.set(fileId, file);
|
|
6933
|
+
return { fileId: fileId };
|
|
6934
|
+
};
|
|
6935
|
+
window.openai.getFileDownloadUrl = async function (ref) {
|
|
6936
|
+
var file = files.get(ref.fileId);
|
|
6937
|
+
if (!file) {
|
|
6938
|
+
throw new Error("File not found: " + ref.fileId);
|
|
6939
|
+
}
|
|
6940
|
+
return { downloadUrl: URL.createObjectURL(file) };
|
|
6941
|
+
};
|
|
6942
|
+
})();
|
|
6943
|
+
</script>`;
|
|
6944
|
+
function injectOpenAiFileApis(html) {
|
|
6945
|
+
if (html.includes("<head>")) {
|
|
6946
|
+
return html.replace("<head>", "<head>" + OPENAI_FILE_APIS_SCRIPT);
|
|
6947
|
+
}
|
|
6948
|
+
if (html.includes("<HEAD>")) {
|
|
6949
|
+
return html.replace("<HEAD>", "<HEAD>" + OPENAI_FILE_APIS_SCRIPT);
|
|
6950
|
+
}
|
|
6951
|
+
if (html.includes("<html>")) {
|
|
6952
|
+
return html.replace(
|
|
6953
|
+
"<html>",
|
|
6954
|
+
"<html><head>" + OPENAI_FILE_APIS_SCRIPT + "</head>"
|
|
6955
|
+
);
|
|
6956
|
+
}
|
|
6957
|
+
if (html.includes("<HTML>")) {
|
|
6958
|
+
return html.replace(
|
|
6959
|
+
"<HTML>",
|
|
6960
|
+
"<HTML><head>" + OPENAI_FILE_APIS_SCRIPT + "</head>"
|
|
6961
|
+
);
|
|
6962
|
+
}
|
|
6963
|
+
if (html.includes("<!DOCTYPE") || html.includes("<!doctype")) {
|
|
6964
|
+
return html.replace(
|
|
6965
|
+
/(<!DOCTYPE[^>]*>|<!doctype[^>]*>)/i,
|
|
6966
|
+
"$1<head>" + OPENAI_FILE_APIS_SCRIPT + "</head>"
|
|
6967
|
+
);
|
|
6968
|
+
}
|
|
6969
|
+
return OPENAI_FILE_APIS_SCRIPT + html;
|
|
6970
|
+
}
|
|
6971
|
+
|
|
6906
6972
|
// src/react/view/resolve-view-resource.ts
|
|
6907
6973
|
function resolveViewResource(options) {
|
|
6908
6974
|
const { resourceResult, listingResource, cspMode, resourceUri } = options;
|
|
@@ -7252,9 +7318,9 @@ function buildSandboxProxyBlobHtml(search) {
|
|
|
7252
7318
|
// src/react/view/use-display-mode.ts
|
|
7253
7319
|
import { useCallback as useCallback5, useEffect as useEffect4 } from "react";
|
|
7254
7320
|
var SHELL_BASE = "w-full h-full min-h-0 bg-background flex flex-col [&:fullscreen]:h-full [&:fullscreen]:w-full [&:fullscreen]:bg-background";
|
|
7255
|
-
var WIDGET_FULLSCREEN_OVERLAY_CLASSES = `fixed inset-0 z-[
|
|
7321
|
+
var WIDGET_FULLSCREEN_OVERLAY_CLASSES = `fixed inset-0 z-[200] ${SHELL_BASE}`;
|
|
7256
7322
|
var WIDGET_PIP_SHELL_CLASSES = [
|
|
7257
|
-
"fixed top-4 left-1/2 -translate-x-1/2 z-[
|
|
7323
|
+
"fixed top-4 left-1/2 -translate-x-1/2 z-[200]",
|
|
7258
7324
|
"rounded-3xl w-full min-w-[300px] h-[400px]",
|
|
7259
7325
|
"shadow-2xl border overflow-hidden",
|
|
7260
7326
|
"bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80",
|
|
@@ -7312,7 +7378,8 @@ function useViewDisplayModeControls({
|
|
|
7312
7378
|
}
|
|
7313
7379
|
var VIEW_DIMENSIONS = {
|
|
7314
7380
|
PIP_MAX_WIDTH: 700,
|
|
7315
|
-
DEFAULT_HEIGHT: 400
|
|
7381
|
+
DEFAULT_HEIGHT: 400,
|
|
7382
|
+
FULLSCREEN_HEADER_HEIGHT: 50
|
|
7316
7383
|
};
|
|
7317
7384
|
|
|
7318
7385
|
// src/react/view/view-detection.ts
|
|
@@ -7339,8 +7406,28 @@ var DEFAULT_HOST_CAPABILITIES = {
|
|
|
7339
7406
|
serverTools: {},
|
|
7340
7407
|
serverResources: {},
|
|
7341
7408
|
logging: {},
|
|
7342
|
-
updateModelContext: { text: {} }
|
|
7409
|
+
updateModelContext: { text: {} },
|
|
7410
|
+
// ponytail: always advertised; bridge.onmessage no-ops when onMessage unset
|
|
7411
|
+
message: { text: {} }
|
|
7343
7412
|
};
|
|
7413
|
+
function CloseIcon() {
|
|
7414
|
+
return /* @__PURE__ */ React2.createElement(
|
|
7415
|
+
"svg",
|
|
7416
|
+
{
|
|
7417
|
+
width: "14",
|
|
7418
|
+
height: "14",
|
|
7419
|
+
viewBox: "0 0 24 24",
|
|
7420
|
+
fill: "none",
|
|
7421
|
+
stroke: "currentColor",
|
|
7422
|
+
strokeWidth: "2",
|
|
7423
|
+
strokeLinecap: "round",
|
|
7424
|
+
strokeLinejoin: "round",
|
|
7425
|
+
"aria-hidden": true
|
|
7426
|
+
},
|
|
7427
|
+
/* @__PURE__ */ React2.createElement("path", { d: "M18 6 6 18" }),
|
|
7428
|
+
/* @__PURE__ */ React2.createElement("path", { d: "m6 6 12 12" })
|
|
7429
|
+
);
|
|
7430
|
+
}
|
|
7344
7431
|
function waitForSandboxProxyReady(iframe) {
|
|
7345
7432
|
return new Promise((resolve) => {
|
|
7346
7433
|
const listener = (event) => {
|
|
@@ -7401,6 +7488,10 @@ function ViewRendererBase({
|
|
|
7401
7488
|
onResourceResolved,
|
|
7402
7489
|
wrapTransport,
|
|
7403
7490
|
toolCallTimeout = DEFAULT_TOOL_CALL_TIMEOUT,
|
|
7491
|
+
mockOpenAiFileApis = false,
|
|
7492
|
+
onInlineHeightChange,
|
|
7493
|
+
fullscreenHeader,
|
|
7494
|
+
renderFullscreenClose,
|
|
7404
7495
|
className,
|
|
7405
7496
|
testId = "mcp-app-frame",
|
|
7406
7497
|
invoking,
|
|
@@ -7409,6 +7500,9 @@ function ViewRendererBase({
|
|
|
7409
7500
|
const iframeRef = useRef4(null);
|
|
7410
7501
|
const bridgeRef = useRef4(null);
|
|
7411
7502
|
const containerRef = useRef4(null);
|
|
7503
|
+
const pendingBlobRevocationsRef = useRef4(
|
|
7504
|
+
/* @__PURE__ */ new Map()
|
|
7505
|
+
);
|
|
7412
7506
|
const connectionRef = useRef4(
|
|
7413
7507
|
source.kind === "live" ? source.connection : null
|
|
7414
7508
|
);
|
|
@@ -7422,12 +7516,19 @@ function ViewRendererBase({
|
|
|
7422
7516
|
);
|
|
7423
7517
|
const [internalDisplayMode, setInternalDisplayMode] = useState4("inline");
|
|
7424
7518
|
const displayMode = displayModeProp ?? internalDisplayMode;
|
|
7425
|
-
const
|
|
7426
|
-
|
|
7519
|
+
const effectiveHostContext = useMemo3(() => {
|
|
7520
|
+
if (!hostContext) return hostContext;
|
|
7521
|
+
if (hostContext.displayMode === displayMode) return hostContext;
|
|
7522
|
+
return { ...hostContext, displayMode };
|
|
7523
|
+
}, [hostContext, displayMode]);
|
|
7524
|
+
const hostContextRef = useRef4(effectiveHostContext);
|
|
7525
|
+
hostContextRef.current = effectiveHostContext;
|
|
7427
7526
|
const onMessageRef = useRef4(onMessage);
|
|
7428
7527
|
onMessageRef.current = onMessage;
|
|
7429
7528
|
const toolInputRef = useRef4(toolInput);
|
|
7430
7529
|
toolInputRef.current = toolInput;
|
|
7530
|
+
const partialToolInputRef = useRef4(partialToolInput);
|
|
7531
|
+
partialToolInputRef.current = partialToolInput;
|
|
7431
7532
|
const toolOutputRef = useRef4(toolOutput);
|
|
7432
7533
|
toolOutputRef.current = toolOutput;
|
|
7433
7534
|
const customPropsRef = useRef4(customProps);
|
|
@@ -7446,10 +7547,14 @@ function ViewRendererBase({
|
|
|
7446
7547
|
onReadyRef.current = onReady;
|
|
7447
7548
|
const onLifecycleChangeRef = useRef4(onLifecycleChange);
|
|
7448
7549
|
onLifecycleChangeRef.current = onLifecycleChange;
|
|
7550
|
+
const onInlineHeightChangeRef = useRef4(onInlineHeightChange);
|
|
7551
|
+
onInlineHeightChangeRef.current = onInlineHeightChange;
|
|
7449
7552
|
const sandboxUrlRef = useRef4(sandboxUrl);
|
|
7450
7553
|
sandboxUrlRef.current = sandboxUrl;
|
|
7451
7554
|
const cspModeRef = useRef4(cspMode);
|
|
7452
7555
|
cspModeRef.current = cspMode;
|
|
7556
|
+
const mockOpenAiFileApisRef = useRef4(mockOpenAiFileApis);
|
|
7557
|
+
mockOpenAiFileApisRef.current = mockOpenAiFileApis;
|
|
7453
7558
|
const resolveSandboxUrl = useCallback6((next) => {
|
|
7454
7559
|
const custom = sandboxUrlRef.current;
|
|
7455
7560
|
if (custom) {
|
|
@@ -7553,10 +7658,18 @@ function ViewRendererBase({
|
|
|
7553
7658
|
}, [source.kind, liveResourceUri, preloadedHtml, cspMode, resolveSandboxUrl]);
|
|
7554
7659
|
useEffect5(() => {
|
|
7555
7660
|
const url = activeSandboxUrl;
|
|
7661
|
+
if (!url || url.protocol !== "blob:") return;
|
|
7662
|
+
const pending = pendingBlobRevocationsRef.current.get(url.href);
|
|
7663
|
+
if (pending) {
|
|
7664
|
+
clearTimeout(pending);
|
|
7665
|
+
pendingBlobRevocationsRef.current.delete(url.href);
|
|
7666
|
+
}
|
|
7556
7667
|
return () => {
|
|
7557
|
-
|
|
7668
|
+
const timer = setTimeout(() => {
|
|
7558
7669
|
URL.revokeObjectURL(url.href);
|
|
7559
|
-
|
|
7670
|
+
pendingBlobRevocationsRef.current.delete(url.href);
|
|
7671
|
+
}, 1e3);
|
|
7672
|
+
pendingBlobRevocationsRef.current.set(url.href, timer);
|
|
7560
7673
|
};
|
|
7561
7674
|
}, [activeSandboxUrl]);
|
|
7562
7675
|
const isBlobSandbox = activeSandboxUrl?.protocol === "blob:";
|
|
@@ -7617,7 +7730,14 @@ function ViewRendererBase({
|
|
|
7617
7730
|
iframe.setAttribute("allow", allowAttribute);
|
|
7618
7731
|
}
|
|
7619
7732
|
const readyPromise = waitForSandboxProxyReady(iframe);
|
|
7620
|
-
|
|
7733
|
+
if (activeSandboxUrl.protocol === "blob:") {
|
|
7734
|
+
const response = await fetch(activeSandboxUrl.href);
|
|
7735
|
+
const sandboxHtml = await response.text();
|
|
7736
|
+
if (disposed) return;
|
|
7737
|
+
iframe.srcdoc = sandboxHtml;
|
|
7738
|
+
} else {
|
|
7739
|
+
iframe.src = activeSandboxUrl.href;
|
|
7740
|
+
}
|
|
7621
7741
|
await readyPromise;
|
|
7622
7742
|
if (disposed) return;
|
|
7623
7743
|
const capabilities = {
|
|
@@ -7703,7 +7823,10 @@ function ViewRendererBase({
|
|
|
7703
7823
|
height
|
|
7704
7824
|
}) => {
|
|
7705
7825
|
if (displayModeRef.current !== "inline") return;
|
|
7706
|
-
if (height !== void 0)
|
|
7826
|
+
if (height !== void 0) {
|
|
7827
|
+
setInlineHeight(height);
|
|
7828
|
+
onInlineHeightChangeRef.current?.(height);
|
|
7829
|
+
}
|
|
7707
7830
|
};
|
|
7708
7831
|
const initPromise = hookInitialized(bridge);
|
|
7709
7832
|
let transport = new PostMessageTransport(
|
|
@@ -7716,7 +7839,7 @@ function ViewRendererBase({
|
|
|
7716
7839
|
await bridge.connect(transport);
|
|
7717
7840
|
if (disposed) return;
|
|
7718
7841
|
await bridge.sendSandboxResourceReady({
|
|
7719
|
-
html: resolved.html,
|
|
7842
|
+
html: mockOpenAiFileApisRef.current ? injectOpenAiFileApis(resolved.html) : resolved.html,
|
|
7720
7843
|
csp: resolved.csp,
|
|
7721
7844
|
permissions: resolved.permissions
|
|
7722
7845
|
});
|
|
@@ -7725,11 +7848,18 @@ function ViewRendererBase({
|
|
|
7725
7848
|
bridgeRef.current = bridge;
|
|
7726
7849
|
setInitCount((c) => c + 1);
|
|
7727
7850
|
onLifecycleChangeRef.current?.({ status: "initialized" });
|
|
7728
|
-
const
|
|
7729
|
-
|
|
7730
|
-
|
|
7731
|
-
|
|
7732
|
-
|
|
7851
|
+
const currentPartialToolInput = partialToolInputRef.current;
|
|
7852
|
+
if (currentPartialToolInput) {
|
|
7853
|
+
bridge.sendToolInputPartial({
|
|
7854
|
+
arguments: currentPartialToolInput
|
|
7855
|
+
});
|
|
7856
|
+
} else {
|
|
7857
|
+
const mergedArgs = {
|
|
7858
|
+
...toolInputRef.current,
|
|
7859
|
+
...parseCustomProps(customPropsRef.current)
|
|
7860
|
+
};
|
|
7861
|
+
bridge.sendToolInput({ arguments: mergedArgs });
|
|
7862
|
+
}
|
|
7733
7863
|
const toolResultPayload = buildToolResultPayload(
|
|
7734
7864
|
toolOutputRef.current,
|
|
7735
7865
|
customPropsRef.current
|
|
@@ -7778,13 +7908,14 @@ function ViewRendererBase({
|
|
|
7778
7908
|
cspMode,
|
|
7779
7909
|
viewId,
|
|
7780
7910
|
wrapTransport,
|
|
7781
|
-
toolCallTimeout
|
|
7911
|
+
toolCallTimeout,
|
|
7912
|
+
mockOpenAiFileApis
|
|
7782
7913
|
]);
|
|
7783
7914
|
useEffect5(() => {
|
|
7784
7915
|
const bridge = bridgeRef.current;
|
|
7785
|
-
if (!bridge || initCount === 0 || !
|
|
7786
|
-
bridge.setHostContext(
|
|
7787
|
-
}, [
|
|
7916
|
+
if (!bridge || initCount === 0 || !effectiveHostContext) return;
|
|
7917
|
+
bridge.setHostContext(effectiveHostContext);
|
|
7918
|
+
}, [effectiveHostContext, initCount]);
|
|
7788
7919
|
useEffect5(() => {
|
|
7789
7920
|
const bridge = bridgeRef.current;
|
|
7790
7921
|
if (!bridge || initCount === 0 || !partialToolInput) return;
|
|
@@ -7792,13 +7923,13 @@ function ViewRendererBase({
|
|
|
7792
7923
|
}, [initCount, partialToolInput]);
|
|
7793
7924
|
useEffect5(() => {
|
|
7794
7925
|
const bridge = bridgeRef.current;
|
|
7795
|
-
if (!bridge || initCount === 0) return;
|
|
7926
|
+
if (!bridge || initCount === 0 || partialToolInput) return;
|
|
7796
7927
|
const mergedArgs = {
|
|
7797
7928
|
...toolInput,
|
|
7798
7929
|
...parseCustomProps(customProps)
|
|
7799
7930
|
};
|
|
7800
7931
|
bridge.sendToolInput({ arguments: mergedArgs });
|
|
7801
|
-
}, [initCount, toolInput, customProps]);
|
|
7932
|
+
}, [initCount, toolInput, partialToolInput, customProps]);
|
|
7802
7933
|
useEffect5(() => {
|
|
7803
7934
|
const bridge = bridgeRef.current;
|
|
7804
7935
|
if (!bridge || initCount === 0) return;
|
|
@@ -7822,6 +7953,7 @@ function ViewRendererBase({
|
|
|
7822
7953
|
const timer = setTimeout(() => setShowSpinner(false), 300);
|
|
7823
7954
|
return () => clearTimeout(timer);
|
|
7824
7955
|
}, [initCount, showSpinner]);
|
|
7956
|
+
const showHostBorder = resolved !== null && resolved.prefersBorder && displayMode !== "fullscreen";
|
|
7825
7957
|
if (loadError) {
|
|
7826
7958
|
return /* @__PURE__ */ React2.createElement("div", { className }, /* @__PURE__ */ React2.createElement("div", { className: "border border-red-200/50 dark:border-red-800/50 bg-red-50/30 dark:bg-red-950/20 rounded-lg p-4" }, /* @__PURE__ */ React2.createElement("p", { className: "text-sm text-red-600 dark:text-red-400" }, "Failed to load view: ", loadError)));
|
|
7827
7959
|
}
|
|
@@ -7839,29 +7971,69 @@ function ViewRendererBase({
|
|
|
7839
7971
|
"div",
|
|
7840
7972
|
{
|
|
7841
7973
|
ref: containerRef,
|
|
7842
|
-
className: containerClassName,
|
|
7974
|
+
className: isFullscreen ? `${containerClassName} flex flex-col` : containerClassName,
|
|
7843
7975
|
style: isPip ? {
|
|
7844
7976
|
height: VIEW_DIMENSIONS.DEFAULT_HEIGHT,
|
|
7845
7977
|
maxWidth: VIEW_DIMENSIONS.PIP_MAX_WIDTH,
|
|
7846
7978
|
zIndex: 100
|
|
7847
7979
|
} : isFullscreen ? { zIndex: 100 } : void 0
|
|
7848
7980
|
},
|
|
7849
|
-
|
|
7981
|
+
isFullscreen && // ponytail: inspector Tailwind may not emit client arbitrary classes
|
|
7982
|
+
// (h-[50px], grid-cols-[auto_1fr_auto]) — use inline layout instead.
|
|
7983
|
+
/* @__PURE__ */ React2.createElement(
|
|
7984
|
+
"header",
|
|
7985
|
+
{
|
|
7986
|
+
className: "grid shrink-0 items-center border-b border-zinc-200 bg-background px-3 dark:border-zinc-700",
|
|
7987
|
+
style: {
|
|
7988
|
+
height: VIEW_DIMENSIONS.FULLSCREEN_HEADER_HEIGHT,
|
|
7989
|
+
gridTemplateColumns: "auto 1fr auto"
|
|
7990
|
+
}
|
|
7991
|
+
},
|
|
7992
|
+
renderFullscreenClose ? renderFullscreenClose({
|
|
7993
|
+
onClick: () => void handleDisplayModeChange("inline"),
|
|
7994
|
+
"data-testid": "debugger-exit-fullscreen-button",
|
|
7995
|
+
"aria-label": "Exit fullscreen"
|
|
7996
|
+
}) : /* @__PURE__ */ React2.createElement(
|
|
7997
|
+
"button",
|
|
7998
|
+
{
|
|
7999
|
+
type: "button",
|
|
8000
|
+
"data-testid": "debugger-exit-fullscreen-button",
|
|
8001
|
+
"aria-label": "Exit fullscreen",
|
|
8002
|
+
className: "flex size-8 cursor-pointer items-center justify-center rounded-full border border-zinc-200 bg-background text-foreground shadow-sm hover:bg-muted dark:border-zinc-700",
|
|
8003
|
+
onClick: () => void handleDisplayModeChange("inline")
|
|
8004
|
+
},
|
|
8005
|
+
/* @__PURE__ */ React2.createElement(CloseIcon, null)
|
|
8006
|
+
),
|
|
8007
|
+
/* @__PURE__ */ React2.createElement("div", { className: "flex min-w-0 items-center justify-center gap-2 px-2" }, fullscreenHeader?.iconUrl ? /* @__PURE__ */ React2.createElement(
|
|
8008
|
+
"img",
|
|
8009
|
+
{
|
|
8010
|
+
src: fullscreenHeader.iconUrl,
|
|
8011
|
+
alt: "",
|
|
8012
|
+
className: "size-6 shrink-0 rounded-md object-contain"
|
|
8013
|
+
}
|
|
8014
|
+
) : null, /* @__PURE__ */ React2.createElement("span", { className: "truncate text-sm font-medium text-foreground" }, fullscreenHeader?.title ?? toolName)),
|
|
8015
|
+
/* @__PURE__ */ React2.createElement("div", { className: "size-8 shrink-0", "aria-hidden": true })
|
|
8016
|
+
),
|
|
8017
|
+
isPip && (renderFullscreenClose ? /* @__PURE__ */ React2.createElement("div", { className: "absolute right-3 top-3", style: { zIndex: 110 } }, renderFullscreenClose({
|
|
8018
|
+
onClick: () => void handleDisplayModeChange("inline"),
|
|
8019
|
+
"data-testid": "debugger-exit-pip-button",
|
|
8020
|
+
"aria-label": "Exit picture-in-picture"
|
|
8021
|
+
})) : /* @__PURE__ */ React2.createElement(
|
|
7850
8022
|
"button",
|
|
7851
8023
|
{
|
|
7852
8024
|
type: "button",
|
|
7853
|
-
"data-testid":
|
|
7854
|
-
"aria-label":
|
|
7855
|
-
className: "absolute right-3 top-3 z-[110] flex size-8 items-center justify-center rounded-full border border-border bg-background/90 text-
|
|
8025
|
+
"data-testid": "debugger-exit-pip-button",
|
|
8026
|
+
"aria-label": "Exit picture-in-picture",
|
|
8027
|
+
className: "absolute right-3 top-3 z-[110] flex size-8 cursor-pointer items-center justify-center rounded-full border border-border bg-background/90 text-foreground shadow-sm backdrop-blur-sm hover:bg-background",
|
|
7856
8028
|
style: { zIndex: 110 },
|
|
7857
8029
|
onClick: () => void handleDisplayModeChange("inline")
|
|
7858
8030
|
},
|
|
7859
|
-
|
|
7860
|
-
),
|
|
8031
|
+
/* @__PURE__ */ React2.createElement(CloseIcon, null)
|
|
8032
|
+
)),
|
|
7861
8033
|
/* @__PURE__ */ React2.createElement(
|
|
7862
8034
|
"div",
|
|
7863
8035
|
{
|
|
7864
|
-
className: isFullscreen
|
|
8036
|
+
className: isFullscreen ? "relative flex min-h-0 w-full flex-1 flex-col" : isPip ? "relative w-full h-full min-h-0 flex flex-1 flex-col" : "relative w-full flex flex-1 justify-center items-center"
|
|
7865
8037
|
},
|
|
7866
8038
|
showSpinner && /* @__PURE__ */ React2.createElement("div", { className: "flex absolute inset-0 items-center justify-center z-10" }, /* @__PURE__ */ React2.createElement("span", { className: "text-sm text-muted-foreground" }, "Loading\u2026")),
|
|
7867
8039
|
!isPip && !isFullscreen && (invoking || invoked) && /* @__PURE__ */ React2.createElement("div", { className: "absolute -top-8 left-2 z-10 whitespace-nowrap pointer-events-none text-xs text-muted-foreground" }, invoking && !toolOutput ? invoking : invoked),
|
|
@@ -7878,10 +8050,7 @@ function ViewRendererBase({
|
|
|
7878
8050
|
{
|
|
7879
8051
|
ref: iframeRef,
|
|
7880
8052
|
title: `MCP App: ${toolName}`,
|
|
7881
|
-
className: "w-full h-full border-
|
|
7882
|
-
style: {
|
|
7883
|
-
border: resolved.prefersBorder && displayMode !== "fullscreen" ? void 0 : "none"
|
|
7884
|
-
}
|
|
8053
|
+
className: showHostBorder ? "w-full h-full bg-transparent border border-border rounded-xl" : "w-full h-full bg-transparent border-0"
|
|
7885
8054
|
}
|
|
7886
8055
|
)
|
|
7887
8056
|
)
|
|
@@ -7902,6 +8071,10 @@ function viewRendererAreEqual(prev, next) {
|
|
|
7902
8071
|
if (prev.hostContext !== next.hostContext) return false;
|
|
7903
8072
|
if (prev.hostCapabilities !== next.hostCapabilities) return false;
|
|
7904
8073
|
if (prev.cspMode !== next.cspMode) return false;
|
|
8074
|
+
if (prev.mockOpenAiFileApis !== next.mockOpenAiFileApis) return false;
|
|
8075
|
+
if (prev.onInlineHeightChange !== next.onInlineHeightChange) return false;
|
|
8076
|
+
if (prev.fullscreenHeader !== next.fullscreenHeader) return false;
|
|
8077
|
+
if (prev.renderFullscreenClose !== next.renderFullscreenClose) return false;
|
|
7905
8078
|
if (prev.className !== next.className) return false;
|
|
7906
8079
|
if (prev.onReady !== next.onReady) return false;
|
|
7907
8080
|
if (prev.onLifecycleChange !== next.onLifecycleChange) return false;
|