@shuffleio/shuffle-mcps 0.0.16 → 0.0.17

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.
@@ -2,7 +2,7 @@ import {
2
2
  fetchApps,
3
3
  fetchAppsViaApiConfig,
4
4
  invalidateAppsCache
5
- } from "./chunk-FHIKSRCS.mjs";
5
+ } from "./chunk-R3YLER6P.mjs";
6
6
  export {
7
7
  fetchApps,
8
8
  fetchAppsViaApiConfig,
@@ -0,0 +1,325 @@
1
+ // fetchBreaker.ts
2
+ var FAIL_THRESHOLD = 12;
3
+ var ROLLING_WINDOW_MS = 5e3;
4
+ var COOLDOWN_MS = 3e4;
5
+ var HARD_BURST_THRESHOLD = 30;
6
+ var HARD_BURST_WINDOW_MS = 1e3;
7
+ var state = /* @__PURE__ */ new Map();
8
+ var installed = false;
9
+ var allowedOrigins = /* @__PURE__ */ new Set();
10
+ var getEntry = (key) => {
11
+ let entry = state.get(key);
12
+ if (!entry) {
13
+ entry = { failures: [], attempts: [], blockedUntil: 0, warned: false };
14
+ state.set(key, entry);
15
+ }
16
+ return entry;
17
+ };
18
+ var prune = (arr, now, windowMs) => {
19
+ const cutoff = now - windowMs;
20
+ while (arr.length && arr[0] < cutoff) arr.shift();
21
+ };
22
+ var keyFor = (input, init) => {
23
+ let urlStr;
24
+ let method = (init?.method || (typeof input !== "string" && "method" in input ? input.method : "GET") || "GET").toUpperCase();
25
+ if (typeof input === "string") urlStr = input;
26
+ else if (input instanceof URL) urlStr = input.toString();
27
+ else if (input && typeof input.url === "string") urlStr = input.url;
28
+ else return null;
29
+ try {
30
+ const u = new URL(urlStr, typeof window !== "undefined" ? window.location.href : "http://localhost");
31
+ if (allowedOrigins.size && !allowedOrigins.has(u.origin)) return null;
32
+ if (!u.pathname.startsWith("/api/")) return null;
33
+ return `${method} ${u.origin}${u.pathname}`;
34
+ } catch {
35
+ return null;
36
+ }
37
+ };
38
+ var synthetic503 = (key, retryInMs) => new Response(
39
+ JSON.stringify({
40
+ error: "circuit_breaker_open",
41
+ message: `Too many failures for ${key}. Cooling down for ${Math.ceil(retryInMs / 1e3)}s.`
42
+ }),
43
+ {
44
+ status: 503,
45
+ statusText: "Service Unavailable (circuit breaker)",
46
+ headers: { "Content-Type": "application/json", "Retry-After": String(Math.ceil(retryInMs / 1e3)) }
47
+ }
48
+ );
49
+ var registerProtectedOrigin = (url) => {
50
+ if (!url) return;
51
+ try {
52
+ const origin = new URL(url, typeof window !== "undefined" ? window.location.href : "http://localhost").origin;
53
+ allowedOrigins.add(origin);
54
+ } catch {
55
+ }
56
+ };
57
+ var installFetchBreaker = () => {
58
+ if (installed) return;
59
+ if (typeof window === "undefined" || typeof window.fetch !== "function") return;
60
+ installed = true;
61
+ const original = window.fetch.bind(window);
62
+ window.fetch = (async (input, init) => {
63
+ const key = keyFor(input, init);
64
+ if (!key) return original(input, init);
65
+ const entry = getEntry(key);
66
+ const now = Date.now();
67
+ if (entry.blockedUntil > now) {
68
+ return synthetic503(key, entry.blockedUntil - now);
69
+ }
70
+ entry.attempts.push(now);
71
+ prune(entry.attempts, now, HARD_BURST_WINDOW_MS);
72
+ if (entry.attempts.length > HARD_BURST_THRESHOLD) {
73
+ entry.blockedUntil = now + COOLDOWN_MS;
74
+ if (!entry.warned) {
75
+ entry.warned = true;
76
+ console.error(
77
+ `[fetchBreaker] Burst detected on ${key} (${entry.attempts.length} calls / ${HARD_BURST_WINDOW_MS}ms). Blocking for ${COOLDOWN_MS / 1e3}s. Fix the caller \u2014 this is almost always a missing useEffect dep or a render loop.`
78
+ );
79
+ }
80
+ return synthetic503(key, COOLDOWN_MS);
81
+ }
82
+ let response;
83
+ try {
84
+ response = await original(input, init);
85
+ } catch (err) {
86
+ const ts = Date.now();
87
+ entry.failures.push(ts);
88
+ prune(entry.failures, ts, ROLLING_WINDOW_MS);
89
+ if (entry.failures.length >= FAIL_THRESHOLD) {
90
+ entry.blockedUntil = ts + COOLDOWN_MS;
91
+ if (!entry.warned) {
92
+ entry.warned = true;
93
+ console.error(
94
+ `[fetchBreaker] ${entry.failures.length} network errors on ${key} in ${ROLLING_WINDOW_MS / 1e3}s. Blocking for ${COOLDOWN_MS / 1e3}s.`
95
+ );
96
+ }
97
+ }
98
+ throw err;
99
+ }
100
+ if (response.status >= 500 || response.status === 0) {
101
+ const ts = Date.now();
102
+ entry.failures.push(ts);
103
+ prune(entry.failures, ts, ROLLING_WINDOW_MS);
104
+ if (entry.failures.length >= FAIL_THRESHOLD) {
105
+ entry.blockedUntil = ts + COOLDOWN_MS;
106
+ if (!entry.warned) {
107
+ entry.warned = true;
108
+ console.error(
109
+ `[fetchBreaker] ${entry.failures.length} ${response.status}s on ${key} in ${ROLLING_WINDOW_MS / 1e3}s. Blocking for ${COOLDOWN_MS / 1e3}s.`
110
+ );
111
+ }
112
+ }
113
+ } else if (response.status < 400) {
114
+ entry.failures.length = 0;
115
+ entry.warned = false;
116
+ }
117
+ return response;
118
+ });
119
+ };
120
+
121
+ // api.ts
122
+ installFetchBreaker();
123
+ var DEV_BACKEND = "https://tunnel.schemaless.org";
124
+ var PROD_BACKEND = "https://shuffler.io";
125
+ var CLOUD_DOMAINS = ["security.shuffler.io", "shutdown.no"];
126
+ var getEnvVar = (key) => {
127
+ try {
128
+ const meta = new Function("try { return import.meta } catch { return undefined }")();
129
+ return meta?.env?.[key];
130
+ } catch {
131
+ return void 0;
132
+ }
133
+ };
134
+ var isDevEnvironment = () => {
135
+ if (getEnvVar("VITE_SHUFFLE_API_URL")) return false;
136
+ const hostname = typeof window !== "undefined" ? window.location.hostname : "";
137
+ return hostname.includes("lovableproject.com") || hostname.includes("id-preview--");
138
+ };
139
+ var isCloudDomain = () => {
140
+ const hostname = typeof window !== "undefined" ? window.location.hostname : "";
141
+ return CLOUD_DOMAINS.includes(hostname);
142
+ };
143
+ var isCloud = () => isCloudDomain();
144
+ var isOnprem = () => !isDevEnvironment() && !isCloudDomain();
145
+ var getDefaultBaseUrl = () => {
146
+ const envUrl = getEnvVar("VITE_SHUFFLE_API_URL");
147
+ if (envUrl) {
148
+ return envUrl;
149
+ }
150
+ if (isDevEnvironment()) return DEV_BACKEND;
151
+ if (isCloudDomain()) return PROD_BACKEND;
152
+ if (typeof window !== "undefined") {
153
+ return window.location.origin;
154
+ }
155
+ return PROD_BACKEND;
156
+ };
157
+ var _regionUrl = null;
158
+ var _trackedOrgId = null;
159
+ var _hostBaseUrl = null;
160
+ var isShufflerSubdomain = (url) => {
161
+ try {
162
+ const parsed = new URL(url);
163
+ return parsed.hostname.endsWith(".shuffler.io") || parsed.hostname === "shuffler.io";
164
+ } catch {
165
+ return false;
166
+ }
167
+ };
168
+ var setRegionUrl = (regionUrl, orgId) => {
169
+ if (isDevEnvironment()) {
170
+ _trackedOrgId = orgId || null;
171
+ return;
172
+ }
173
+ _trackedOrgId = orgId || null;
174
+ if (regionUrl && isShufflerSubdomain(regionUrl)) {
175
+ const normalized = regionUrl.replace(/\/+$/, "");
176
+ if (normalized !== PROD_BACKEND) {
177
+ _regionUrl = normalized;
178
+ console.log(`[API] Region URL set to: ${_regionUrl}`);
179
+ return;
180
+ }
181
+ }
182
+ _regionUrl = null;
183
+ };
184
+ var resetRegionUrl = () => {
185
+ if (_regionUrl) {
186
+ console.log(`[API] Region URL reset to default (org changed)`);
187
+ }
188
+ _regionUrl = null;
189
+ };
190
+ var setHostBaseUrl = (url) => {
191
+ const next = url ? url.replace(/\/+$/, "") : null;
192
+ if (next === _hostBaseUrl) return;
193
+ _hostBaseUrl = next;
194
+ if (next) {
195
+ try {
196
+ registerProtectedOrigin(next);
197
+ } catch {
198
+ }
199
+ }
200
+ };
201
+ var getHostBaseUrl = () => _hostBaseUrl;
202
+ var getTrackedOrgId = () => _trackedOrgId;
203
+ var API_CONFIG = {
204
+ // Shuffle backend URL — host override beats region URL beats default.
205
+ get baseUrl() {
206
+ const url = _hostBaseUrl || _regionUrl || getDefaultBaseUrl();
207
+ try {
208
+ registerProtectedOrigin(url);
209
+ } catch {
210
+ }
211
+ return url;
212
+ },
213
+ // API version
214
+ version: "v1",
215
+ // Get API key from localStorage (for local development)
216
+ get apiKey() {
217
+ return localStorage.getItem("shuffle_api_key");
218
+ },
219
+ // Set API key in localStorage
220
+ setApiKey(key) {
221
+ if (key) {
222
+ localStorage.setItem("shuffle_api_key", key);
223
+ } else {
224
+ localStorage.removeItem("shuffle_api_key");
225
+ }
226
+ }
227
+ };
228
+ var getApiUrl = (endpoint) => {
229
+ return `${API_CONFIG.baseUrl}${endpoint}`;
230
+ };
231
+ var shuffleFetch = (url, init) => {
232
+ const { headers: extraHeaders, ...rest } = init || {};
233
+ return fetch(url, {
234
+ credentials: "include",
235
+ ...rest,
236
+ headers: {
237
+ ...getAuthHeader(),
238
+ ...extraHeaders
239
+ }
240
+ });
241
+ };
242
+ var getAuthHeader = (overrideOrgId) => {
243
+ const headers = {};
244
+ const apiKey = API_CONFIG.apiKey;
245
+ if (apiKey) {
246
+ headers["Authorization"] = `Bearer ${apiKey}`;
247
+ }
248
+ const orgId = overrideOrgId ?? _trackedOrgId;
249
+ if (orgId) {
250
+ headers["Org-Id"] = orgId;
251
+ }
252
+ return headers;
253
+ };
254
+
255
+ // appsCache.ts
256
+ var TTL_MS = 3e4;
257
+ var ERROR_TTL_MS = 3e4;
258
+ var cache = /* @__PURE__ */ new Map();
259
+ var cacheKey = (o) => `${o.baseUrl}|${o.path || "/api/v1/apps"}|${o.apiKey || ""}|${o.orgId || ""}`;
260
+ var doFetch = async (o) => {
261
+ const headers = {};
262
+ if (o.apiKey) headers["Authorization"] = `Bearer ${o.apiKey}`;
263
+ if (o.orgId) headers["Org-Id"] = o.orgId;
264
+ const response = await fetch(`${o.baseUrl}${o.path || "/api/v1/apps"}`, {
265
+ credentials: "include",
266
+ headers
267
+ });
268
+ if (!response.ok) return [];
269
+ const data = await response.json();
270
+ if (Array.isArray(data)) return data;
271
+ return Array.isArray(data?.data) ? data.data : [];
272
+ };
273
+ var fetchApps = (opts) => {
274
+ const key = cacheKey(opts);
275
+ const entry = cache.get(key) || {};
276
+ if (entry.data && entry.fetchedAt && Date.now() - entry.fetchedAt < TTL_MS) {
277
+ return Promise.resolve(entry.data);
278
+ }
279
+ if (entry.promise) return entry.promise;
280
+ const promise = doFetch(opts).then((data) => {
281
+ cache.set(key, { data, fetchedAt: Date.now() });
282
+ return data;
283
+ }).catch(() => {
284
+ cache.set(key, { data: [], fetchedAt: Date.now() - (TTL_MS - ERROR_TTL_MS) });
285
+ return [];
286
+ });
287
+ cache.set(key, { ...entry, promise });
288
+ return promise;
289
+ };
290
+ var invalidateAppsCache = (opts) => {
291
+ if (!opts) {
292
+ cache.clear();
293
+ return;
294
+ }
295
+ cache.delete(cacheKey(opts));
296
+ };
297
+ var fetchAppsViaApiConfig = () => {
298
+ const headers = getAuthHeader();
299
+ const orgId = headers["Org-Id"] || null;
300
+ return fetchApps({
301
+ baseUrl: API_CONFIG.baseUrl,
302
+ apiKey: API_CONFIG.apiKey,
303
+ orgId
304
+ });
305
+ };
306
+
307
+ export {
308
+ registerProtectedOrigin,
309
+ installFetchBreaker,
310
+ isCloudDomain,
311
+ isCloud,
312
+ isOnprem,
313
+ setRegionUrl,
314
+ resetRegionUrl,
315
+ setHostBaseUrl,
316
+ getHostBaseUrl,
317
+ getTrackedOrgId,
318
+ API_CONFIG,
319
+ getApiUrl,
320
+ shuffleFetch,
321
+ getAuthHeader,
322
+ fetchApps,
323
+ invalidateAppsCache,
324
+ fetchAppsViaApiConfig
325
+ };
package/dist/index.d.mts CHANGED
@@ -672,7 +672,7 @@ interface AgentRunDrawerProps extends ShuffleHostProps {
672
672
  /** Style overrides for the body container that wraps the active tab content. */
673
673
  bodySx?: SxProps<Theme>;
674
674
  }
675
- declare const AgentRunDrawer: ({ open, onClose, initialTab, permissionsSlot, localLLMSlot, localLLMTabBadge, permissionsDisabled, permissionsDisabledTooltip, agentUIProps, width, title, subtitle, className, paperSx, headerSx, tabsSx, bodySx, }: AgentRunDrawerProps) => react_jsx_runtime.JSX.Element;
675
+ declare const AgentRunDrawer: ({ open, onClose, initialTab, permissionsSlot, localLLMSlot, localLLMTabBadge, permissionsDisabled, permissionsDisabledTooltip, agentUIProps, width, title, subtitle, className, paperSx, headerSx, tabsSx, bodySx, globalUrl, }: AgentRunDrawerProps) => react_jsx_runtime.JSX.Element;
676
676
 
677
677
  /** Check if running on a known Shuffle Cloud domain */
678
678
  declare const isCloudDomain: () => boolean;
@@ -688,6 +688,26 @@ declare const isCloud: () => boolean;
688
688
  * True when running self-hosted (onprem) — i.e. NOT in Lovable preview AND NOT on a known cloud domain.
689
689
  */
690
690
  declare const isOnprem: () => boolean;
691
+ /**
692
+ * Set the dynamic region URL from getinfo response.
693
+ * Only applies if the URL is a shuffler.io subdomain and different from default.
694
+ */
695
+ declare const setRegionUrl: (regionUrl: string | undefined | null, orgId: string | undefined | null) => void;
696
+ /**
697
+ * Called when org changes. Resets region URL to default until next getinfo.
698
+ */
699
+ declare const resetRegionUrl: () => void;
700
+ /**
701
+ * Host override — call from a top-level component (or `useSyncHostBaseUrl`)
702
+ * with the `globalUrl` injected via `ShuffleHostProps`. When set, this beats
703
+ * region URL and the env-based default for ALL fetches that go through
704
+ * `getApiUrl()` / `API_CONFIG.baseUrl` / `shuffleFetch`.
705
+ *
706
+ * Pass `null` / `undefined` / empty string to clear the override.
707
+ */
708
+ declare const setHostBaseUrl: (url: string | undefined | null) => void;
709
+ /** Get the currently active host override, if any. */
710
+ declare const getHostBaseUrl: () => string | null;
691
711
  declare const API_CONFIG: {
692
712
  readonly baseUrl: string;
693
713
  version: string;
@@ -864,7 +884,7 @@ interface AgentsViewProps extends ShuffleHostProps {
864
884
  /** Override max content width of the inner stack. Defaults to 820. */
865
885
  maxWidth?: number;
866
886
  }
867
- declare const AgentsView: ({ onSchedule, maxWidth }: AgentsViewProps) => react_jsx_runtime.JSX.Element;
887
+ declare const AgentsView: ({ onSchedule, maxWidth, globalUrl, isLoaded, isLoggedIn, userdata, serverside }: AgentsViewProps) => react_jsx_runtime.JSX.Element;
868
888
 
869
889
  /**
870
890
  * Shared diagnosis utilities for an agent execution result.
@@ -1132,6 +1152,27 @@ declare const useAppDetail: () => AppDetailContextType;
1132
1152
  /** Safe variant: returns null if no provider is mounted. Useful for components used both inside and outside the dashboard. */
1133
1153
  declare const useAppDetailOptional: () => AppDetailContextType;
1134
1154
 
1155
+ declare const useSyncHostBaseUrl: (globalUrl: string | undefined | null) => void;
1156
+
1157
+ /**
1158
+ * Global fetch circuit breaker.
1159
+ *
1160
+ * Installs a one-time wrapper around `window.fetch` that protects the Shuffle
1161
+ * backend from infinite-loop spam. If the same endpoint (method + URL pathname,
1162
+ * scoped to a Shuffle backend origin) fails repeatedly inside a short window,
1163
+ * subsequent calls fail-fast with a synthetic 503 for a cooldown period.
1164
+ *
1165
+ * This is a safety net — components and hooks should still throttle / cache
1166
+ * their own requests. The breaker only kicks in when something has gone wrong
1167
+ * (a useEffect missing deps, a render loop, an unreachable backend).
1168
+ *
1169
+ * Both Shuffle-Core and Shuffle-MCPs install this — it is idempotent so the
1170
+ * first call wins and the second is a no-op.
1171
+ */
1172
+ /** Register a backend origin as one we should guard. Idempotent. */
1173
+ declare const registerProtectedOrigin: (url: string | undefined | null) => void;
1174
+ declare const installFetchBreaker: () => void;
1175
+
1135
1176
  /**
1136
1177
  * Tiny toast facade — library version. Mirrors the sonner-style surface
1137
1178
  * (`toast(...)`, `toast.success`, `toast.error`, `toast.info`, `toast.warning`)
@@ -1409,4 +1450,4 @@ interface UsageBarProps {
1409
1450
  }
1410
1451
  declare const UsageBar: React$1.FC<UsageBarProps>;
1411
1452
 
1412
- export { API_CONFIG, AgentActivityList, type AgentActivityListProps, type AgentActivityParams, type AgentActivityResponse, type AgentDecision, AgentExecutionDrawer, type AgentExecutionDrawerProps, AgentIcon, type AgentRun, AgentRunDiagnosisBanner, AgentRunDrawer, type AgentRunDrawerProps, type AgentRunDrawerTab, type AgentRunResult, AgentUI, type AgentUIApp, type AgentUIProps, AgentsView, type AgentsViewProps, AiAgentPromptsEditor, type AiAgentPromptsEditorProps, type AlgoliaSearchApp, type ApiAuthEntry, AppAuthCard, type AppAuthCardProps, AppAuthConfig, AppAuthSection, type AppAuthSectionProps, type AppAuthState, type AppAuthentication, AppDetailDrawer, AppDetailProvider, type AppLookupResult, AppSearchDrawer, type AppSelectedEvent, AppTitleHeader, type AppTitleHeaderProps, type AuthStatus, CASES_PATTERNS, COMMUNICATION_PATTERNS_NAMES, type CategoryAutomation, type CategoryConfig, type CustomStyles, DATASTORE_CATEGORIES, type DatastoreDiagnostics, type DatastoreItem, type DatastoreResponse, type DiagnosableRun, type DiagnosisEvidence, EDR_PATTERNS, EMAIL_APP_PATTERNS, FORWARD_TICKETS_WORKFLOW_NAME, type FetchAppsOptions, INGEST_TICKETS_WORKFLOW_NAME, type IngestionCategory, IntegrationStatus, type OutputDiagnosis, type ResolvedApp, SIEM_PATTERNS, type ShuffleHostProps, ShuffleMCP, type ShuffleMCPHandle, type ShuffleMCPProps, type ShuffleMcpColorMode, ShuffleMcpThemeProvider, type ShuffleMcpThemeProviderProps, ShufflePipelinesBanner, SingulActionsPreview, THREAT_INTEL_PATTERNS, TryMcpSection, type TryMcpSectionProps, UsageBar, type UsageBarProps, VULN_SCANNER_PATTERNS, type ValidatedIngestionApp, ShuffleMCP as default, deleteDatastoreItem, deleteDatastoreItems, diagnoseOutputWarning, extractValidatedIngestionApps, extractWorkflowAppNames, fetchApps, fetchAppsViaApiConfig, findForwardTicketsWorkflow, findIngestTicketsWorkflow, getApiUrl, getAuthHeader, getDatastoreByCategory, getDatastoreItem, getDatastoreItemPublic, getFailureInfo, getIngestionCategory, hasOutputWarning, invalidateAppsCache, invalidateResolvedApps, isCloud, isCloudDomain, isEmailApp, isIngestionApp, isOnprem, isThreatIntelApp, isVulnScannerApp, isWorkflowScheduleStopped, normalizeAppName, parseRunResult, refreshAllIntegrationStatus, resolveApp, resolveApps, searchAgentActivity, seedResolvedApp, setDatastoreItem, setDatastoreItems, setRuntimeOrgId, setToastImpl, shuffleFetch, toast, useAppAuth, useAppDetail, useAppDetailOptional, useAppLookup };
1453
+ export { API_CONFIG, AgentActivityList, type AgentActivityListProps, type AgentActivityParams, type AgentActivityResponse, type AgentDecision, AgentExecutionDrawer, type AgentExecutionDrawerProps, AgentIcon, type AgentRun, AgentRunDiagnosisBanner, AgentRunDrawer, type AgentRunDrawerProps, type AgentRunDrawerTab, type AgentRunResult, AgentUI, type AgentUIApp, type AgentUIProps, AgentsView, type AgentsViewProps, AiAgentPromptsEditor, type AiAgentPromptsEditorProps, type AlgoliaSearchApp, type ApiAuthEntry, AppAuthCard, type AppAuthCardProps, AppAuthConfig, AppAuthSection, type AppAuthSectionProps, type AppAuthState, type AppAuthentication, AppDetailDrawer, AppDetailProvider, type AppLookupResult, AppSearchDrawer, type AppSelectedEvent, AppTitleHeader, type AppTitleHeaderProps, type AuthStatus, CASES_PATTERNS, COMMUNICATION_PATTERNS_NAMES, type CategoryAutomation, type CategoryConfig, type CustomStyles, DATASTORE_CATEGORIES, type DatastoreDiagnostics, type DatastoreItem, type DatastoreResponse, type DiagnosableRun, type DiagnosisEvidence, EDR_PATTERNS, EMAIL_APP_PATTERNS, FORWARD_TICKETS_WORKFLOW_NAME, type FetchAppsOptions, INGEST_TICKETS_WORKFLOW_NAME, type IngestionCategory, IntegrationStatus, type OutputDiagnosis, type ResolvedApp, SIEM_PATTERNS, type ShuffleHostProps, ShuffleMCP, type ShuffleMCPHandle, type ShuffleMCPProps, type ShuffleMcpColorMode, ShuffleMcpThemeProvider, type ShuffleMcpThemeProviderProps, ShufflePipelinesBanner, SingulActionsPreview, THREAT_INTEL_PATTERNS, TryMcpSection, type TryMcpSectionProps, UsageBar, type UsageBarProps, VULN_SCANNER_PATTERNS, type ValidatedIngestionApp, ShuffleMCP as default, deleteDatastoreItem, deleteDatastoreItems, diagnoseOutputWarning, extractValidatedIngestionApps, extractWorkflowAppNames, fetchApps, fetchAppsViaApiConfig, findForwardTicketsWorkflow, findIngestTicketsWorkflow, getApiUrl, getAuthHeader, getDatastoreByCategory, getDatastoreItem, getDatastoreItemPublic, getFailureInfo, getHostBaseUrl, getIngestionCategory, hasOutputWarning, installFetchBreaker, invalidateAppsCache, invalidateResolvedApps, isCloud, isCloudDomain, isEmailApp, isIngestionApp, isOnprem, isThreatIntelApp, isVulnScannerApp, isWorkflowScheduleStopped, normalizeAppName, parseRunResult, refreshAllIntegrationStatus, registerProtectedOrigin, resetRegionUrl, resolveApp, resolveApps, searchAgentActivity, seedResolvedApp, setDatastoreItem, setDatastoreItems, setHostBaseUrl, setRegionUrl, setRuntimeOrgId, setToastImpl, shuffleFetch, toast, useAppAuth, useAppDetail, useAppDetailOptional, useAppLookup, useSyncHostBaseUrl };
package/dist/index.d.ts CHANGED
@@ -672,7 +672,7 @@ interface AgentRunDrawerProps extends ShuffleHostProps {
672
672
  /** Style overrides for the body container that wraps the active tab content. */
673
673
  bodySx?: SxProps<Theme>;
674
674
  }
675
- declare const AgentRunDrawer: ({ open, onClose, initialTab, permissionsSlot, localLLMSlot, localLLMTabBadge, permissionsDisabled, permissionsDisabledTooltip, agentUIProps, width, title, subtitle, className, paperSx, headerSx, tabsSx, bodySx, }: AgentRunDrawerProps) => react_jsx_runtime.JSX.Element;
675
+ declare const AgentRunDrawer: ({ open, onClose, initialTab, permissionsSlot, localLLMSlot, localLLMTabBadge, permissionsDisabled, permissionsDisabledTooltip, agentUIProps, width, title, subtitle, className, paperSx, headerSx, tabsSx, bodySx, globalUrl, }: AgentRunDrawerProps) => react_jsx_runtime.JSX.Element;
676
676
 
677
677
  /** Check if running on a known Shuffle Cloud domain */
678
678
  declare const isCloudDomain: () => boolean;
@@ -688,6 +688,26 @@ declare const isCloud: () => boolean;
688
688
  * True when running self-hosted (onprem) — i.e. NOT in Lovable preview AND NOT on a known cloud domain.
689
689
  */
690
690
  declare const isOnprem: () => boolean;
691
+ /**
692
+ * Set the dynamic region URL from getinfo response.
693
+ * Only applies if the URL is a shuffler.io subdomain and different from default.
694
+ */
695
+ declare const setRegionUrl: (regionUrl: string | undefined | null, orgId: string | undefined | null) => void;
696
+ /**
697
+ * Called when org changes. Resets region URL to default until next getinfo.
698
+ */
699
+ declare const resetRegionUrl: () => void;
700
+ /**
701
+ * Host override — call from a top-level component (or `useSyncHostBaseUrl`)
702
+ * with the `globalUrl` injected via `ShuffleHostProps`. When set, this beats
703
+ * region URL and the env-based default for ALL fetches that go through
704
+ * `getApiUrl()` / `API_CONFIG.baseUrl` / `shuffleFetch`.
705
+ *
706
+ * Pass `null` / `undefined` / empty string to clear the override.
707
+ */
708
+ declare const setHostBaseUrl: (url: string | undefined | null) => void;
709
+ /** Get the currently active host override, if any. */
710
+ declare const getHostBaseUrl: () => string | null;
691
711
  declare const API_CONFIG: {
692
712
  readonly baseUrl: string;
693
713
  version: string;
@@ -864,7 +884,7 @@ interface AgentsViewProps extends ShuffleHostProps {
864
884
  /** Override max content width of the inner stack. Defaults to 820. */
865
885
  maxWidth?: number;
866
886
  }
867
- declare const AgentsView: ({ onSchedule, maxWidth }: AgentsViewProps) => react_jsx_runtime.JSX.Element;
887
+ declare const AgentsView: ({ onSchedule, maxWidth, globalUrl, isLoaded, isLoggedIn, userdata, serverside }: AgentsViewProps) => react_jsx_runtime.JSX.Element;
868
888
 
869
889
  /**
870
890
  * Shared diagnosis utilities for an agent execution result.
@@ -1132,6 +1152,27 @@ declare const useAppDetail: () => AppDetailContextType;
1132
1152
  /** Safe variant: returns null if no provider is mounted. Useful for components used both inside and outside the dashboard. */
1133
1153
  declare const useAppDetailOptional: () => AppDetailContextType;
1134
1154
 
1155
+ declare const useSyncHostBaseUrl: (globalUrl: string | undefined | null) => void;
1156
+
1157
+ /**
1158
+ * Global fetch circuit breaker.
1159
+ *
1160
+ * Installs a one-time wrapper around `window.fetch` that protects the Shuffle
1161
+ * backend from infinite-loop spam. If the same endpoint (method + URL pathname,
1162
+ * scoped to a Shuffle backend origin) fails repeatedly inside a short window,
1163
+ * subsequent calls fail-fast with a synthetic 503 for a cooldown period.
1164
+ *
1165
+ * This is a safety net — components and hooks should still throttle / cache
1166
+ * their own requests. The breaker only kicks in when something has gone wrong
1167
+ * (a useEffect missing deps, a render loop, an unreachable backend).
1168
+ *
1169
+ * Both Shuffle-Core and Shuffle-MCPs install this — it is idempotent so the
1170
+ * first call wins and the second is a no-op.
1171
+ */
1172
+ /** Register a backend origin as one we should guard. Idempotent. */
1173
+ declare const registerProtectedOrigin: (url: string | undefined | null) => void;
1174
+ declare const installFetchBreaker: () => void;
1175
+
1135
1176
  /**
1136
1177
  * Tiny toast facade — library version. Mirrors the sonner-style surface
1137
1178
  * (`toast(...)`, `toast.success`, `toast.error`, `toast.info`, `toast.warning`)
@@ -1409,4 +1450,4 @@ interface UsageBarProps {
1409
1450
  }
1410
1451
  declare const UsageBar: React$1.FC<UsageBarProps>;
1411
1452
 
1412
- export { API_CONFIG, AgentActivityList, type AgentActivityListProps, type AgentActivityParams, type AgentActivityResponse, type AgentDecision, AgentExecutionDrawer, type AgentExecutionDrawerProps, AgentIcon, type AgentRun, AgentRunDiagnosisBanner, AgentRunDrawer, type AgentRunDrawerProps, type AgentRunDrawerTab, type AgentRunResult, AgentUI, type AgentUIApp, type AgentUIProps, AgentsView, type AgentsViewProps, AiAgentPromptsEditor, type AiAgentPromptsEditorProps, type AlgoliaSearchApp, type ApiAuthEntry, AppAuthCard, type AppAuthCardProps, AppAuthConfig, AppAuthSection, type AppAuthSectionProps, type AppAuthState, type AppAuthentication, AppDetailDrawer, AppDetailProvider, type AppLookupResult, AppSearchDrawer, type AppSelectedEvent, AppTitleHeader, type AppTitleHeaderProps, type AuthStatus, CASES_PATTERNS, COMMUNICATION_PATTERNS_NAMES, type CategoryAutomation, type CategoryConfig, type CustomStyles, DATASTORE_CATEGORIES, type DatastoreDiagnostics, type DatastoreItem, type DatastoreResponse, type DiagnosableRun, type DiagnosisEvidence, EDR_PATTERNS, EMAIL_APP_PATTERNS, FORWARD_TICKETS_WORKFLOW_NAME, type FetchAppsOptions, INGEST_TICKETS_WORKFLOW_NAME, type IngestionCategory, IntegrationStatus, type OutputDiagnosis, type ResolvedApp, SIEM_PATTERNS, type ShuffleHostProps, ShuffleMCP, type ShuffleMCPHandle, type ShuffleMCPProps, type ShuffleMcpColorMode, ShuffleMcpThemeProvider, type ShuffleMcpThemeProviderProps, ShufflePipelinesBanner, SingulActionsPreview, THREAT_INTEL_PATTERNS, TryMcpSection, type TryMcpSectionProps, UsageBar, type UsageBarProps, VULN_SCANNER_PATTERNS, type ValidatedIngestionApp, ShuffleMCP as default, deleteDatastoreItem, deleteDatastoreItems, diagnoseOutputWarning, extractValidatedIngestionApps, extractWorkflowAppNames, fetchApps, fetchAppsViaApiConfig, findForwardTicketsWorkflow, findIngestTicketsWorkflow, getApiUrl, getAuthHeader, getDatastoreByCategory, getDatastoreItem, getDatastoreItemPublic, getFailureInfo, getIngestionCategory, hasOutputWarning, invalidateAppsCache, invalidateResolvedApps, isCloud, isCloudDomain, isEmailApp, isIngestionApp, isOnprem, isThreatIntelApp, isVulnScannerApp, isWorkflowScheduleStopped, normalizeAppName, parseRunResult, refreshAllIntegrationStatus, resolveApp, resolveApps, searchAgentActivity, seedResolvedApp, setDatastoreItem, setDatastoreItems, setRuntimeOrgId, setToastImpl, shuffleFetch, toast, useAppAuth, useAppDetail, useAppDetailOptional, useAppLookup };
1453
+ export { API_CONFIG, AgentActivityList, type AgentActivityListProps, type AgentActivityParams, type AgentActivityResponse, type AgentDecision, AgentExecutionDrawer, type AgentExecutionDrawerProps, AgentIcon, type AgentRun, AgentRunDiagnosisBanner, AgentRunDrawer, type AgentRunDrawerProps, type AgentRunDrawerTab, type AgentRunResult, AgentUI, type AgentUIApp, type AgentUIProps, AgentsView, type AgentsViewProps, AiAgentPromptsEditor, type AiAgentPromptsEditorProps, type AlgoliaSearchApp, type ApiAuthEntry, AppAuthCard, type AppAuthCardProps, AppAuthConfig, AppAuthSection, type AppAuthSectionProps, type AppAuthState, type AppAuthentication, AppDetailDrawer, AppDetailProvider, type AppLookupResult, AppSearchDrawer, type AppSelectedEvent, AppTitleHeader, type AppTitleHeaderProps, type AuthStatus, CASES_PATTERNS, COMMUNICATION_PATTERNS_NAMES, type CategoryAutomation, type CategoryConfig, type CustomStyles, DATASTORE_CATEGORIES, type DatastoreDiagnostics, type DatastoreItem, type DatastoreResponse, type DiagnosableRun, type DiagnosisEvidence, EDR_PATTERNS, EMAIL_APP_PATTERNS, FORWARD_TICKETS_WORKFLOW_NAME, type FetchAppsOptions, INGEST_TICKETS_WORKFLOW_NAME, type IngestionCategory, IntegrationStatus, type OutputDiagnosis, type ResolvedApp, SIEM_PATTERNS, type ShuffleHostProps, ShuffleMCP, type ShuffleMCPHandle, type ShuffleMCPProps, type ShuffleMcpColorMode, ShuffleMcpThemeProvider, type ShuffleMcpThemeProviderProps, ShufflePipelinesBanner, SingulActionsPreview, THREAT_INTEL_PATTERNS, TryMcpSection, type TryMcpSectionProps, UsageBar, type UsageBarProps, VULN_SCANNER_PATTERNS, type ValidatedIngestionApp, ShuffleMCP as default, deleteDatastoreItem, deleteDatastoreItems, diagnoseOutputWarning, extractValidatedIngestionApps, extractWorkflowAppNames, fetchApps, fetchAppsViaApiConfig, findForwardTicketsWorkflow, findIngestTicketsWorkflow, getApiUrl, getAuthHeader, getDatastoreByCategory, getDatastoreItem, getDatastoreItemPublic, getFailureInfo, getHostBaseUrl, getIngestionCategory, hasOutputWarning, installFetchBreaker, invalidateAppsCache, invalidateResolvedApps, isCloud, isCloudDomain, isEmailApp, isIngestionApp, isOnprem, isThreatIntelApp, isVulnScannerApp, isWorkflowScheduleStopped, normalizeAppName, parseRunResult, refreshAllIntegrationStatus, registerProtectedOrigin, resetRegionUrl, resolveApp, resolveApps, searchAgentActivity, seedResolvedApp, setDatastoreItem, setDatastoreItems, setHostBaseUrl, setRegionUrl, setRuntimeOrgId, setToastImpl, shuffleFetch, toast, useAppAuth, useAppDetail, useAppDetailOptional, useAppLookup, useSyncHostBaseUrl };