@shuffleio/shuffle-mcps 0.0.39 → 0.0.40
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/{appsCache-32FX7WJE.mjs → appsCache-EFH5WV4I.mjs} +1 -1
- package/dist/{chunk-DCHKGFML.mjs → chunk-5LZ5IZ2O.mjs} +185 -26
- package/dist/index.d.mts +336 -7
- package/dist/index.d.ts +336 -7
- package/dist/index.js +2687 -364
- package/dist/index.mjs +2483 -331
- package/dist/{shuffle-mcp-3U5AFQDK.css → shuffle-mcp-S6QOJJG4.css} +34 -13
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -30,7 +30,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
30
30
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
31
31
|
|
|
32
32
|
// fetchBreaker.ts
|
|
33
|
-
var FAIL_THRESHOLD, ROLLING_WINDOW_MS, COOLDOWN_MS, PROBE_AFTER_MS, MAX_PROBE_BACKOFF_MS, HARD_BURST_THRESHOLD, HARD_BURST_WINDOW_MS, state, installed, allowedOrigins, getEntry, trip, reset, prune, keyFor,
|
|
33
|
+
var FAIL_THRESHOLD, ROLLING_WINDOW_MS, COOLDOWN_MS, PROBE_AFTER_MS, MAX_PROBE_BACKOFF_MS, HARD_BURST_THRESHOLD, HARD_BURST_WINDOW_MS, state, installed, allowedOrigins, getEntry, trip, reset, prune, keyFor, withStoredAuth, synthetic503, registerProtectedOrigin, installFetchBreaker;
|
|
34
34
|
var init_fetchBreaker = __esm({
|
|
35
35
|
"fetchBreaker.ts"() {
|
|
36
36
|
FAIL_THRESHOLD = 12;
|
|
@@ -84,7 +84,7 @@ var init_fetchBreaker = __esm({
|
|
|
84
84
|
return null;
|
|
85
85
|
}
|
|
86
86
|
};
|
|
87
|
-
|
|
87
|
+
withStoredAuth = (input, init) => {
|
|
88
88
|
if (typeof window === "undefined") return init;
|
|
89
89
|
let urlStr;
|
|
90
90
|
if (typeof input === "string") urlStr = input;
|
|
@@ -93,17 +93,35 @@ var init_fetchBreaker = __esm({
|
|
|
93
93
|
else return init;
|
|
94
94
|
try {
|
|
95
95
|
const url = new URL(urlStr, window.location.href);
|
|
96
|
-
const isKnownShuffleOrigin = allowedOrigins.has(url.origin) || url.origin === window.location.origin || url.hostname === "shuffler.io" || url.hostname.endsWith(".shuffler.io") || url.hostname === "tunnel.schemaless.org";
|
|
96
|
+
const isKnownShuffleOrigin = allowedOrigins.has(url.origin) || url.origin === window.location.origin || url.hostname === "shuffler.io" || url.hostname.endsWith(".shuffler.io") || url.hostname === "tunnel.schemaless.org" || url.hostname === "shuffle.security" || url.hostname.endsWith(".shuffle.security");
|
|
97
97
|
if (!url.pathname.startsWith("/api/") || !isKnownShuffleOrigin) return init;
|
|
98
|
-
|
|
99
|
-
|
|
98
|
+
if (url.pathname === "/api/v1/login" || url.pathname === "/api/v1/users/register") return init;
|
|
99
|
+
const sessionToken = window.localStorage.getItem("session_token");
|
|
100
|
+
const token = sessionToken && sessionToken.trim().length > 0 ? sessionToken.trim() : null;
|
|
100
101
|
const requestHeaders = typeof Request !== "undefined" && input instanceof Request ? input.headers : void 0;
|
|
101
102
|
const headers = new Headers(requestHeaders);
|
|
102
103
|
if (init?.headers) {
|
|
103
104
|
new Headers(init.headers).forEach((value, name) => headers.set(name, value));
|
|
104
105
|
}
|
|
105
|
-
if (!headers.has("Authorization"))
|
|
106
|
-
|
|
106
|
+
if (token && !headers.has("Authorization")) {
|
|
107
|
+
headers.set("Authorization", `Bearer ${token}`);
|
|
108
|
+
}
|
|
109
|
+
if (!headers.has("Org-Id")) {
|
|
110
|
+
try {
|
|
111
|
+
const raw = window.localStorage.getItem("shuffle_user_info");
|
|
112
|
+
if (raw) {
|
|
113
|
+
const parsed = JSON.parse(raw);
|
|
114
|
+
const orgId = parsed?.active_org?.id;
|
|
115
|
+
if (orgId) headers.set("Org-Id", orgId);
|
|
116
|
+
}
|
|
117
|
+
} catch {
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
...init,
|
|
122
|
+
credentials: init?.credentials || "include",
|
|
123
|
+
headers
|
|
124
|
+
};
|
|
107
125
|
} catch {
|
|
108
126
|
return init;
|
|
109
127
|
}
|
|
@@ -133,7 +151,7 @@ var init_fetchBreaker = __esm({
|
|
|
133
151
|
installed = true;
|
|
134
152
|
const original = window.fetch.bind(window);
|
|
135
153
|
window.fetch = (async (input, init) => {
|
|
136
|
-
const authenticatedInit =
|
|
154
|
+
const authenticatedInit = withStoredAuth(input, init);
|
|
137
155
|
const key = keyFor(input, authenticatedInit);
|
|
138
156
|
if (!key) return original(input, authenticatedInit);
|
|
139
157
|
const entry = getEntry(key);
|
|
@@ -211,6 +229,89 @@ var init_fetchBreaker = __esm({
|
|
|
211
229
|
}
|
|
212
230
|
});
|
|
213
231
|
|
|
232
|
+
// ../lib/shuffleUrls.ts
|
|
233
|
+
var readEnv, isManagedDomain, getShuffleCoreBaseUrl, getShuffleCoreUrl;
|
|
234
|
+
var init_shuffleUrls = __esm({
|
|
235
|
+
"../lib/shuffleUrls.ts"() {
|
|
236
|
+
readEnv = (key) => {
|
|
237
|
+
try {
|
|
238
|
+
const meta = new Function("try { return import.meta } catch { return undefined }")();
|
|
239
|
+
const val = meta?.env?.[key];
|
|
240
|
+
if (val && typeof val === "string" && val.trim().length > 0) {
|
|
241
|
+
return val.trim();
|
|
242
|
+
}
|
|
243
|
+
} catch {
|
|
244
|
+
}
|
|
245
|
+
if (typeof window !== "undefined") {
|
|
246
|
+
const win = window;
|
|
247
|
+
const runtimeConfig = win.__SHUFFLE_CONFIG__ || win._env_ || win.__ENV__;
|
|
248
|
+
if (runtimeConfig && typeof runtimeConfig === "object") {
|
|
249
|
+
const val = runtimeConfig[key] || runtimeConfig[key.replace(/^VITE_/, "")];
|
|
250
|
+
if (val && typeof val === "string" && val.trim().length > 0) {
|
|
251
|
+
return val.trim();
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
try {
|
|
256
|
+
if (typeof process !== "undefined" && process.env) {
|
|
257
|
+
const val = process.env[key] || process.env[key.replace(/^VITE_/, "")];
|
|
258
|
+
if (val && typeof val === "string" && val.trim().length > 0) {
|
|
259
|
+
return val.trim();
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
} catch {
|
|
263
|
+
}
|
|
264
|
+
return void 0;
|
|
265
|
+
};
|
|
266
|
+
isManagedDomain = () => {
|
|
267
|
+
if (typeof window === "undefined") return false;
|
|
268
|
+
const hostname = window.location.hostname.toLowerCase();
|
|
269
|
+
return hostname.includes("lovable") || hostname.includes("shuffler.io") || hostname.includes("shutdown.no") || hostname.includes("shuffle.security");
|
|
270
|
+
};
|
|
271
|
+
getShuffleCoreBaseUrl = () => {
|
|
272
|
+
const envUrl = readEnv("VITE_SHUFFLE_CORE_URL") || readEnv("SHUFFLE_CORE_URL") || readEnv("VITE_SHUFFLE_AUTOMATION_URL") || readEnv("VITE_SHUFFLE_URL");
|
|
273
|
+
if (envUrl) {
|
|
274
|
+
return envUrl.replace(/\/+$/, "");
|
|
275
|
+
}
|
|
276
|
+
if (typeof window !== "undefined") {
|
|
277
|
+
try {
|
|
278
|
+
const savedCore = localStorage.getItem("shuffle_core_url");
|
|
279
|
+
if (savedCore && savedCore.trim().length > 0) {
|
|
280
|
+
return savedCore.trim().replace(/\/+$/, "");
|
|
281
|
+
}
|
|
282
|
+
const customHost = localStorage.getItem("shuffle_custom_host_url");
|
|
283
|
+
if (customHost && customHost.trim().length > 0) {
|
|
284
|
+
const cleaned = customHost.trim().replace(/\/+$/, "");
|
|
285
|
+
if (cleaned.includes(":5001")) {
|
|
286
|
+
return cleaned.replace(":5001", ":3001");
|
|
287
|
+
}
|
|
288
|
+
return cleaned;
|
|
289
|
+
}
|
|
290
|
+
} catch {
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
if (typeof window !== "undefined") {
|
|
294
|
+
const hostname = window.location.hostname;
|
|
295
|
+
const isManaged = isManagedDomain();
|
|
296
|
+
if (isManaged) {
|
|
297
|
+
return "https://shuffler.io";
|
|
298
|
+
}
|
|
299
|
+
if (window.location.port === "3001") {
|
|
300
|
+
return window.location.origin;
|
|
301
|
+
}
|
|
302
|
+
return `${window.location.protocol}//${hostname}:3001`;
|
|
303
|
+
}
|
|
304
|
+
return "https://shuffler.io";
|
|
305
|
+
};
|
|
306
|
+
getShuffleCoreUrl = (path) => {
|
|
307
|
+
const base3 = getShuffleCoreBaseUrl();
|
|
308
|
+
if (!path) return base3;
|
|
309
|
+
const cleanPath = path.startsWith("/") ? path : `/${path}`;
|
|
310
|
+
return `${base3}${cleanPath}`;
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
|
|
214
315
|
// ../lib/platform.ts
|
|
215
316
|
var getPlatform, isCapacitorNative, isIosWebView, isAndroidWebView;
|
|
216
317
|
var init_platform = __esm({
|
|
@@ -271,14 +372,16 @@ var init_platform = __esm({
|
|
|
271
372
|
});
|
|
272
373
|
|
|
273
374
|
// api.ts
|
|
274
|
-
var DEV_BACKEND, PROD_BACKEND, CLOUD_DOMAINS, getEnvVar, isDevEnvironment, isCloudDomain, isCloud, isOnprem, getDefaultBaseUrl, REGION_STORAGE_KEY, readCachedRegion, cached, _regionUrl, readCachedCustomHost, _trackedOrgId, _hostBaseUrl, REGION_EVENT, _lastBroadcastUrl, persistRegion, isShufflerSubdomain, setRegionUrl, applyRegionFromPayload, resetRegionUrl, SHUFFLE_HOST_BASE_URL_EVENT, setHostBaseUrl, getHostBaseUrl, getTrackedOrgId, API_CONFIG, getApiUrl, shuffleFetch, getAuthHeader, hasShuffleAuth;
|
|
375
|
+
var DEV_BACKEND, PROD_BACKEND, SHUFFLE_AUTOMATION_URL, CLOUD_DOMAINS, getEnvVar, isDevEnvironment, isCloudDomain, isCloud, isOnprem, getDefaultBaseUrl, REGION_STORAGE_KEY, readCachedRegion, cached, _regionUrl, readCachedCustomHost, _trackedOrgId, _hostBaseUrl, REGION_EVENT, _lastBroadcastUrl, persistRegion, isShufflerSubdomain, setRegionUrl, applyRegionFromPayload, resetRegionUrl, SHUFFLE_HOST_BASE_URL_EVENT, setHostBaseUrl, getHostBaseUrl, getTrackedOrgId, LEGACY_API_KEY_STORAGE_KEY, clearAuthTokens, getSessionToken, setSessionToken, API_CONFIG, getApiUrl, shuffleFetch, getAuthHeader, hasShuffleAuth;
|
|
275
376
|
var init_api = __esm({
|
|
276
377
|
"api.ts"() {
|
|
277
378
|
init_fetchBreaker();
|
|
379
|
+
init_shuffleUrls();
|
|
278
380
|
init_platform();
|
|
279
381
|
installFetchBreaker();
|
|
280
382
|
DEV_BACKEND = "https://tunnel.schemaless.org";
|
|
281
|
-
PROD_BACKEND = "https://shuffler.io";
|
|
383
|
+
PROD_BACKEND = "https://uk.shuffler.io";
|
|
384
|
+
SHUFFLE_AUTOMATION_URL = getShuffleCoreUrl("/new-dashboard");
|
|
282
385
|
CLOUD_DOMAINS = ["shuffle.security", "www.shuffle.security", "security.shuffler.io", "shutdown.no", "www.shutdown.no"];
|
|
283
386
|
getEnvVar = (key) => {
|
|
284
387
|
try {
|
|
@@ -320,7 +423,11 @@ var init_api = __esm({
|
|
|
320
423
|
const raw = localStorage.getItem(REGION_STORAGE_KEY);
|
|
321
424
|
if (!raw) return { url: null, orgId: null };
|
|
322
425
|
const parsed = JSON.parse(raw);
|
|
323
|
-
|
|
426
|
+
const url = parsed?.url ? parsed.url.replace(/\/+$/, "") : null;
|
|
427
|
+
if (url === "https://shuffler.io" || url === PROD_BACKEND) {
|
|
428
|
+
return { url: null, orgId: parsed?.orgId || null };
|
|
429
|
+
}
|
|
430
|
+
return { url, orgId: parsed?.orgId || null };
|
|
324
431
|
} catch {
|
|
325
432
|
return { url: null, orgId: null };
|
|
326
433
|
}
|
|
@@ -330,8 +437,20 @@ var init_api = __esm({
|
|
|
330
437
|
readCachedCustomHost = () => {
|
|
331
438
|
if (typeof window === "undefined") return null;
|
|
332
439
|
try {
|
|
440
|
+
const mode = localStorage.getItem("shuffle_selected_server_mode");
|
|
441
|
+
if (mode && mode !== "self-hosted") return null;
|
|
333
442
|
const raw = localStorage.getItem("shuffle_custom_host_url");
|
|
334
|
-
|
|
443
|
+
const cleaned = raw ? raw.trim().replace(/\/+$/, "") : null;
|
|
444
|
+
if (!cleaned) return null;
|
|
445
|
+
if (cleaned === DEV_BACKEND && !isDevEnvironment() && mode !== "self-hosted") {
|
|
446
|
+
try {
|
|
447
|
+
localStorage.removeItem("shuffle_custom_host_url");
|
|
448
|
+
localStorage.removeItem("shuffle_selected_server_mode");
|
|
449
|
+
} catch {
|
|
450
|
+
}
|
|
451
|
+
return null;
|
|
452
|
+
}
|
|
453
|
+
return cleaned;
|
|
335
454
|
} catch {
|
|
336
455
|
return null;
|
|
337
456
|
}
|
|
@@ -382,7 +501,8 @@ var init_api = __esm({
|
|
|
382
501
|
_trackedOrgId = orgId || null;
|
|
383
502
|
if (regionUrl && isShufflerSubdomain(regionUrl)) {
|
|
384
503
|
const normalized = regionUrl.replace(/\/+$/, "");
|
|
385
|
-
|
|
504
|
+
const isDefaultCloud = normalized === PROD_BACKEND || normalized === "https://shuffler.io";
|
|
505
|
+
if (!isDefaultCloud) {
|
|
386
506
|
_regionUrl = normalized;
|
|
387
507
|
persistRegion(_regionUrl, _trackedOrgId);
|
|
388
508
|
console.log(`[API] Region URL set to: ${_regionUrl}`);
|
|
@@ -435,6 +555,38 @@ var init_api = __esm({
|
|
|
435
555
|
}
|
|
436
556
|
getHostBaseUrl = () => _hostBaseUrl;
|
|
437
557
|
getTrackedOrgId = () => _trackedOrgId;
|
|
558
|
+
LEGACY_API_KEY_STORAGE_KEY = "shuffle_api_key";
|
|
559
|
+
clearAuthTokens = () => {
|
|
560
|
+
try {
|
|
561
|
+
localStorage.removeItem("session_token");
|
|
562
|
+
localStorage.removeItem(LEGACY_API_KEY_STORAGE_KEY);
|
|
563
|
+
} catch {
|
|
564
|
+
}
|
|
565
|
+
};
|
|
566
|
+
getSessionToken = () => {
|
|
567
|
+
try {
|
|
568
|
+
if (typeof localStorage === "undefined") return null;
|
|
569
|
+
if (localStorage.getItem(LEGACY_API_KEY_STORAGE_KEY) !== null) {
|
|
570
|
+
localStorage.removeItem(LEGACY_API_KEY_STORAGE_KEY);
|
|
571
|
+
}
|
|
572
|
+
const stored = localStorage.getItem("session_token");
|
|
573
|
+
if (stored && stored.trim().length > 0 && stored !== "null" && stored !== "undefined") {
|
|
574
|
+
return stored.trim();
|
|
575
|
+
}
|
|
576
|
+
return null;
|
|
577
|
+
} catch {
|
|
578
|
+
return null;
|
|
579
|
+
}
|
|
580
|
+
};
|
|
581
|
+
setSessionToken = (token) => {
|
|
582
|
+
clearAuthTokens();
|
|
583
|
+
if (token && token.trim().length > 0) {
|
|
584
|
+
try {
|
|
585
|
+
localStorage.setItem("session_token", token.trim());
|
|
586
|
+
} catch {
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
};
|
|
438
590
|
API_CONFIG = {
|
|
439
591
|
// Shuffle backend URL — host override beats region URL beats default.
|
|
440
592
|
get baseUrl() {
|
|
@@ -447,17 +599,16 @@ var init_api = __esm({
|
|
|
447
599
|
},
|
|
448
600
|
// API version
|
|
449
601
|
version: "v1",
|
|
450
|
-
|
|
602
|
+
/**
|
|
603
|
+
* DEPRECATED alias for the single session token. There is no separate
|
|
604
|
+
* API-key auth any more: exactly one session token may exist at a time.
|
|
605
|
+
*/
|
|
451
606
|
get apiKey() {
|
|
452
|
-
return
|
|
607
|
+
return getSessionToken();
|
|
453
608
|
},
|
|
454
|
-
|
|
609
|
+
/** DEPRECATED: writes/clears the single session token. */
|
|
455
610
|
setApiKey(key) {
|
|
456
|
-
|
|
457
|
-
localStorage.setItem("shuffle_api_key", key);
|
|
458
|
-
} else {
|
|
459
|
-
localStorage.removeItem("shuffle_api_key");
|
|
460
|
-
}
|
|
611
|
+
setSessionToken(key);
|
|
461
612
|
}
|
|
462
613
|
};
|
|
463
614
|
getApiUrl = (endpoint) => {
|
|
@@ -476,11 +627,21 @@ var init_api = __esm({
|
|
|
476
627
|
};
|
|
477
628
|
getAuthHeader = (overrideOrgId) => {
|
|
478
629
|
const headers = {};
|
|
479
|
-
const
|
|
480
|
-
if (
|
|
481
|
-
headers["Authorization"] = `Bearer ${
|
|
630
|
+
const token = getSessionToken();
|
|
631
|
+
if (token) {
|
|
632
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
633
|
+
}
|
|
634
|
+
let orgId = overrideOrgId ?? _trackedOrgId;
|
|
635
|
+
if (!orgId && typeof localStorage !== "undefined") {
|
|
636
|
+
try {
|
|
637
|
+
const raw = localStorage.getItem("shuffle_user_info");
|
|
638
|
+
if (raw) {
|
|
639
|
+
const parsed = JSON.parse(raw);
|
|
640
|
+
orgId = parsed?.active_org?.id || parsed?.org_id || null;
|
|
641
|
+
}
|
|
642
|
+
} catch {
|
|
643
|
+
}
|
|
482
644
|
}
|
|
483
|
-
const orgId = overrideOrgId ?? _trackedOrgId;
|
|
484
645
|
if (orgId) {
|
|
485
646
|
headers["Org-Id"] = orgId;
|
|
486
647
|
}
|
|
@@ -488,8 +649,10 @@ var init_api = __esm({
|
|
|
488
649
|
};
|
|
489
650
|
hasShuffleAuth = () => {
|
|
490
651
|
try {
|
|
491
|
-
if (
|
|
492
|
-
|
|
652
|
+
if (getSessionToken()) return true;
|
|
653
|
+
const info = localStorage.getItem("shuffle_user_info");
|
|
654
|
+
if (info && info.trim().length > 0 && info !== "null" && info !== "undefined") return true;
|
|
655
|
+
return false;
|
|
493
656
|
} catch {
|
|
494
657
|
return false;
|
|
495
658
|
}
|
|
@@ -513,7 +676,9 @@ var init_appsCache = __esm({
|
|
|
513
676
|
cache = /* @__PURE__ */ new Map();
|
|
514
677
|
cacheKey = (o) => `${o.baseUrl}|${o.path || "/api/v1/apps"}|${o.apiKey || ""}|${o.orgId || ""}`;
|
|
515
678
|
doFetch = async (o) => {
|
|
516
|
-
const headers = {
|
|
679
|
+
const headers = {
|
|
680
|
+
...getAuthHeader(o.orgId || void 0)
|
|
681
|
+
};
|
|
517
682
|
if (o.apiKey) headers["Authorization"] = `Bearer ${o.apiKey}`;
|
|
518
683
|
if (o.orgId) headers["Org-Id"] = o.orgId;
|
|
519
684
|
const response = await fetch(`${o.baseUrl}${o.path || "/api/v1/apps"}`, {
|
|
@@ -585,9 +750,14 @@ __export(index_exports, {
|
|
|
585
750
|
AppDetailProvider: () => AppDetailProvider,
|
|
586
751
|
AppSearchDrawer: () => AppSearchDrawer2,
|
|
587
752
|
AppTitleHeader: () => AppTitleHeader2,
|
|
753
|
+
AskAiButton: () => AskAiButton2,
|
|
754
|
+
AskAiDrawer: () => AskAiDrawer2,
|
|
755
|
+
AskAiSidePanel: () => AskAiSidePanel2,
|
|
756
|
+
AskAiWidget: () => AskAiWidget2,
|
|
588
757
|
CASES_PATTERNS: () => CASES_PATTERNS,
|
|
589
758
|
COMMUNICATION_PATTERNS_NAMES: () => COMMUNICATION_PATTERNS_NAMES,
|
|
590
759
|
DATASTORE_CATEGORIES: () => DATASTORE_CATEGORIES,
|
|
760
|
+
DEFAULT_AGENT_CONTEXT_RULES: () => DEFAULT_AGENT_CONTEXT_RULES,
|
|
591
761
|
DEFAULT_AGENT_PROMPT_PREFIX: () => DEFAULT_AGENT_PROMPT_PREFIX,
|
|
592
762
|
EDR_PATTERNS: () => EDR_PATTERNS,
|
|
593
763
|
EMAIL_APP_PATTERNS: () => EMAIL_APP_PATTERNS,
|
|
@@ -609,6 +779,7 @@ __export(index_exports, {
|
|
|
609
779
|
VULN_SCANNER_PATTERNS: () => VULN_SCANNER_PATTERNS,
|
|
610
780
|
VideoEmbed: () => VideoEmbed,
|
|
611
781
|
applyRegionFromPayload: () => applyRegionFromPayload,
|
|
782
|
+
clearPageContextChoice: () => clearPageContextChoice,
|
|
612
783
|
default: () => index_default,
|
|
613
784
|
deleteDatastoreItem: () => deleteDatastoreItem,
|
|
614
785
|
deleteDatastoreItems: () => deleteDatastoreItems,
|
|
@@ -621,6 +792,8 @@ __export(index_exports, {
|
|
|
621
792
|
fetchAppsViaApiConfig: () => fetchAppsViaApiConfig,
|
|
622
793
|
findForwardTicketsWorkflow: () => findForwardTicketsWorkflow,
|
|
623
794
|
findIngestTicketsWorkflow: () => findIngestTicketsWorkflow,
|
|
795
|
+
getActivePageEntityName: () => getActivePageEntityName,
|
|
796
|
+
getAgentContextRules: () => getAgentContextRules,
|
|
624
797
|
getApiUrl: () => getApiUrl,
|
|
625
798
|
getAuthHeader: () => getAuthHeader,
|
|
626
799
|
getDatastoreByCategory: () => getDatastoreByCategory,
|
|
@@ -630,10 +803,12 @@ __export(index_exports, {
|
|
|
630
803
|
getFailureInfo: () => getFailureInfo,
|
|
631
804
|
getHostBaseUrl: () => getHostBaseUrl,
|
|
632
805
|
getIngestionCategory: () => getIngestionCategory,
|
|
806
|
+
getPageContextChoice: () => getPageContextChoice,
|
|
633
807
|
hasOutputWarning: () => hasOutputWarning,
|
|
634
808
|
installFetchBreaker: () => installFetchBreaker,
|
|
635
809
|
invalidateAppsCache: () => invalidateAppsCache,
|
|
636
810
|
invalidateResolvedApps: () => invalidateResolvedApps,
|
|
811
|
+
isAgentRoute: () => isAgentRoute,
|
|
637
812
|
isCloud: () => isCloud,
|
|
638
813
|
isCloudDomain: () => isCloudDomain,
|
|
639
814
|
isEmailApp: () => isEmailApp,
|
|
@@ -642,11 +817,14 @@ __export(index_exports, {
|
|
|
642
817
|
isThreatIntelApp: () => isThreatIntelApp,
|
|
643
818
|
isVulnScannerApp: () => isVulnScannerApp,
|
|
644
819
|
isWorkflowScheduleStopped: () => isWorkflowScheduleStopped,
|
|
820
|
+
matchRoutePattern: () => matchRoutePattern,
|
|
645
821
|
normalizeAppName: () => normalizeAppName,
|
|
646
822
|
parseRunResult: () => parseRunResult,
|
|
647
823
|
refreshAllIntegrationStatus: () => refreshAllIntegrationStatus,
|
|
824
|
+
registerAgentContextRule: () => registerAgentContextRule,
|
|
648
825
|
registerProtectedOrigin: () => registerProtectedOrigin,
|
|
649
826
|
resetRegionUrl: () => resetRegionUrl,
|
|
827
|
+
resolveAgentContext: () => resolveAgentContext,
|
|
650
828
|
resolveApp: () => resolveApp,
|
|
651
829
|
resolveApps: () => resolveApps,
|
|
652
830
|
resolveVideoUrl: () => resolveVideoUrl,
|
|
@@ -656,6 +834,7 @@ __export(index_exports, {
|
|
|
656
834
|
setDatastoreItem: () => setDatastoreItem,
|
|
657
835
|
setDatastoreItems: () => setDatastoreItems,
|
|
658
836
|
setHostBaseUrl: () => setHostBaseUrl,
|
|
837
|
+
setPageContextChoice: () => setPageContextChoice,
|
|
659
838
|
setRegionUrl: () => setRegionUrl,
|
|
660
839
|
setRuntimeOrgId: () => setRuntimeOrgId,
|
|
661
840
|
setToastImpl: () => setToastImpl,
|
|
@@ -667,24 +846,26 @@ __export(index_exports, {
|
|
|
667
846
|
useAppDetail: () => useAppDetail,
|
|
668
847
|
useAppDetailOptional: () => useAppDetailOptional,
|
|
669
848
|
useAppLookup: () => useAppLookup,
|
|
849
|
+
useContextAwareAgent: () => useContextAwareAgent,
|
|
670
850
|
useSyncHostBaseUrl: () => useSyncHostBaseUrl
|
|
671
851
|
});
|
|
672
852
|
module.exports = __toCommonJS(index_exports);
|
|
673
|
-
var import_shuffle_mcp3 = require("./shuffle-mcp-
|
|
674
|
-
var
|
|
853
|
+
var import_shuffle_mcp3 = require("./shuffle-mcp-S6QOJJG4.css");
|
|
854
|
+
var import_react36 = __toESM(require("react"));
|
|
675
855
|
|
|
676
856
|
// ShuffleMcpThemeProvider.tsx
|
|
677
857
|
var import_react = __toESM(require("react"));
|
|
678
858
|
var import_material = require("@mui/material");
|
|
679
|
-
var import_shuffle_mcp = require("./shuffle-mcp-
|
|
859
|
+
var import_shuffle_mcp = require("./shuffle-mcp-S6QOJJG4.css");
|
|
680
860
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
681
861
|
var readHtmlDarkClass = () => {
|
|
682
862
|
if (typeof document === "undefined") return false;
|
|
683
|
-
return document.documentElement.classList.contains("dark");
|
|
863
|
+
return document.documentElement.classList.contains("dark") || Boolean(document.body) && document.body.classList.contains("dark");
|
|
684
864
|
};
|
|
685
865
|
var readAncestorDark = (anchor) => {
|
|
686
866
|
if (!anchor || typeof document === "undefined") return null;
|
|
687
|
-
const
|
|
867
|
+
const ownRoot = anchor.closest("[data-shuffle-core-root], [data-shuffle-mcp-root]");
|
|
868
|
+
const start = ownRoot ? ownRoot.parentElement : anchor.parentElement;
|
|
688
869
|
if (!start) return null;
|
|
689
870
|
const scoped = start.closest('[data-shuffle-mode="dark"], [data-shuffle-mode="light"]');
|
|
690
871
|
if (scoped) return scoped.getAttribute("data-shuffle-mode") === "dark";
|
|
@@ -703,12 +884,20 @@ var useAutoDarkClass = (enabled, anchorRef) => {
|
|
|
703
884
|
recompute();
|
|
704
885
|
const observer = new MutationObserver(recompute);
|
|
705
886
|
observer.observe(document.documentElement, { attributes: true, attributeFilter: ["class"] });
|
|
706
|
-
|
|
887
|
+
if (document.body) {
|
|
888
|
+
observer.observe(document.body, { attributes: true, attributeFilter: ["class"] });
|
|
889
|
+
}
|
|
890
|
+
const ownRoot = anchorRef.current?.closest("[data-shuffle-core-root], [data-shuffle-mcp-root]");
|
|
891
|
+
let node = ownRoot ? ownRoot.parentElement : anchorRef.current?.parentElement ?? null;
|
|
707
892
|
while (node) {
|
|
708
893
|
observer.observe(node, { attributes: true, attributeFilter: ["class", "data-shuffle-mode"] });
|
|
709
894
|
node = node.parentElement;
|
|
710
895
|
}
|
|
711
|
-
|
|
896
|
+
window.addEventListener("shuffle:theme-change", recompute);
|
|
897
|
+
return () => {
|
|
898
|
+
observer.disconnect();
|
|
899
|
+
window.removeEventListener("shuffle:theme-change", recompute);
|
|
900
|
+
};
|
|
712
901
|
}, [enabled, anchorRef]);
|
|
713
902
|
return isDark;
|
|
714
903
|
};
|
|
@@ -763,11 +952,26 @@ var buildComponentOverrides = (scopeClassName) => ({
|
|
|
763
952
|
},
|
|
764
953
|
// ---- Portaled surfaces: stamp scopeClassName so HSL tokens resolve ----
|
|
765
954
|
MuiDrawer: {
|
|
766
|
-
defaultProps: { slotProps: { paper: { className: scopeClassName } } }
|
|
955
|
+
defaultProps: { slotProps: { paper: { className: scopeClassName } } },
|
|
956
|
+
styleOverrides: {
|
|
957
|
+
paper: {
|
|
958
|
+
backgroundColor: "hsl(var(--sidebar-background, var(--card)))",
|
|
959
|
+
color: "hsl(var(--sidebar-foreground, var(--foreground)))",
|
|
960
|
+
borderRight: "1px solid hsl(var(--sidebar-border, var(--border)))"
|
|
961
|
+
}
|
|
962
|
+
}
|
|
767
963
|
},
|
|
768
964
|
MuiDialog: {
|
|
769
965
|
defaultProps: { slotProps: { paper: { className: scopeClassName } } },
|
|
770
|
-
styleOverrides: {
|
|
966
|
+
styleOverrides: {
|
|
967
|
+
root: { zIndex: 10010 },
|
|
968
|
+
paper: {
|
|
969
|
+
backgroundColor: "hsl(var(--card))",
|
|
970
|
+
color: "hsl(var(--card-foreground))",
|
|
971
|
+
border: "1px solid hsl(var(--border))",
|
|
972
|
+
boxShadow: "0 12px 32px rgba(0, 0, 0, 0.2)"
|
|
973
|
+
}
|
|
974
|
+
}
|
|
771
975
|
},
|
|
772
976
|
MuiMenu: {
|
|
773
977
|
defaultProps: { slotProps: { paper: { className: scopeClassName } } },
|
|
@@ -776,7 +980,8 @@ var buildComponentOverrides = (scopeClassName) => ({
|
|
|
776
980
|
paper: {
|
|
777
981
|
backgroundColor: "hsl(var(--popover))",
|
|
778
982
|
color: "hsl(var(--popover-foreground))",
|
|
779
|
-
border: "1px solid hsl(var(--border))"
|
|
983
|
+
border: "1px solid hsl(var(--border))",
|
|
984
|
+
boxShadow: "0 4px 14px rgba(0, 0, 0, 0.12)"
|
|
780
985
|
}
|
|
781
986
|
}
|
|
782
987
|
},
|
|
@@ -787,7 +992,8 @@ var buildComponentOverrides = (scopeClassName) => ({
|
|
|
787
992
|
paper: {
|
|
788
993
|
backgroundColor: "hsl(var(--popover))",
|
|
789
994
|
color: "hsl(var(--popover-foreground))",
|
|
790
|
-
border: "1px solid hsl(var(--border))"
|
|
995
|
+
border: "1px solid hsl(var(--border))",
|
|
996
|
+
boxShadow: "0 4px 14px rgba(0, 0, 0, 0.12)"
|
|
791
997
|
}
|
|
792
998
|
}
|
|
793
999
|
},
|
|
@@ -798,6 +1004,23 @@ var buildComponentOverrides = (scopeClassName) => ({
|
|
|
798
1004
|
// Render above app drawers, dialogs, menus, and popovers.
|
|
799
1005
|
popper: { sx: { zIndex: 10030 } }
|
|
800
1006
|
}
|
|
1007
|
+
},
|
|
1008
|
+
styleOverrides: {
|
|
1009
|
+
tooltip: {
|
|
1010
|
+
backgroundColor: "hsl(var(--popover))",
|
|
1011
|
+
color: "hsl(var(--popover-foreground))",
|
|
1012
|
+
border: "1px solid hsl(var(--border))",
|
|
1013
|
+
boxShadow: "0 4px 14px rgba(0, 0, 0, 0.12)",
|
|
1014
|
+
fontSize: "0.75rem",
|
|
1015
|
+
borderRadius: 8
|
|
1016
|
+
},
|
|
1017
|
+
arrow: {
|
|
1018
|
+
color: "hsl(var(--popover))",
|
|
1019
|
+
"&::before": {
|
|
1020
|
+
border: "1px solid hsl(var(--border))",
|
|
1021
|
+
boxSizing: "border-box"
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
801
1024
|
}
|
|
802
1025
|
},
|
|
803
1026
|
MuiDivider: {
|
|
@@ -814,7 +1037,7 @@ var ShuffleMcpThemeProvider = ({
|
|
|
814
1037
|
const autoIsDark = useAutoDarkClass(mode === "auto", anchorRef);
|
|
815
1038
|
const effectiveDark = mode === "auto" ? autoIsDark : mode === "dark";
|
|
816
1039
|
const sameAsParent = parentCtx !== null && parentCtx.isDark === effectiveDark;
|
|
817
|
-
const scopeClassName = effectiveDark ? "shuffle-mcp-scope dark" : "shuffle-mcp-scope";
|
|
1040
|
+
const scopeClassName = effectiveDark ? "shuffle-mcp-scope dark" : "shuffle-mcp-scope light";
|
|
818
1041
|
const resolvedModeAttr = effectiveDark ? "dark" : "light";
|
|
819
1042
|
const merged = import_react.default.useMemo(
|
|
820
1043
|
() => (0, import_material.createTheme)({
|
|
@@ -1221,7 +1444,7 @@ var keyFor2 = (input, init) => {
|
|
|
1221
1444
|
return null;
|
|
1222
1445
|
}
|
|
1223
1446
|
};
|
|
1224
|
-
var
|
|
1447
|
+
var withStoredAuth2 = (input, init) => {
|
|
1225
1448
|
if (typeof window === "undefined") return init;
|
|
1226
1449
|
let urlStr;
|
|
1227
1450
|
if (typeof input === "string") urlStr = input;
|
|
@@ -1230,17 +1453,35 @@ var withStoredApiKey2 = (input, init) => {
|
|
|
1230
1453
|
else return init;
|
|
1231
1454
|
try {
|
|
1232
1455
|
const url = new URL(urlStr, window.location.href);
|
|
1233
|
-
const isKnownShuffleOrigin = allowedOrigins2.has(url.origin) || url.origin === window.location.origin || url.hostname === "shuffler.io" || url.hostname.endsWith(".shuffler.io") || url.hostname === "tunnel.schemaless.org";
|
|
1456
|
+
const isKnownShuffleOrigin = allowedOrigins2.has(url.origin) || url.origin === window.location.origin || url.hostname === "shuffler.io" || url.hostname.endsWith(".shuffler.io") || url.hostname === "tunnel.schemaless.org" || url.hostname === "shuffle.security" || url.hostname.endsWith(".shuffle.security");
|
|
1234
1457
|
if (!url.pathname.startsWith("/api/") || !isKnownShuffleOrigin) return init;
|
|
1235
|
-
|
|
1236
|
-
|
|
1458
|
+
if (url.pathname === "/api/v1/login" || url.pathname === "/api/v1/users/register") return init;
|
|
1459
|
+
const sessionToken = window.localStorage.getItem("session_token");
|
|
1460
|
+
const token = sessionToken && sessionToken.trim().length > 0 ? sessionToken.trim() : null;
|
|
1237
1461
|
const requestHeaders = typeof Request !== "undefined" && input instanceof Request ? input.headers : void 0;
|
|
1238
1462
|
const headers = new Headers(requestHeaders);
|
|
1239
1463
|
if (init?.headers) {
|
|
1240
1464
|
new Headers(init.headers).forEach((value, name) => headers.set(name, value));
|
|
1241
1465
|
}
|
|
1242
|
-
if (!headers.has("Authorization"))
|
|
1243
|
-
|
|
1466
|
+
if (token && !headers.has("Authorization")) {
|
|
1467
|
+
headers.set("Authorization", `Bearer ${token}`);
|
|
1468
|
+
}
|
|
1469
|
+
if (!headers.has("Org-Id")) {
|
|
1470
|
+
try {
|
|
1471
|
+
const raw = window.localStorage.getItem("shuffle_user_info");
|
|
1472
|
+
if (raw) {
|
|
1473
|
+
const parsed = JSON.parse(raw);
|
|
1474
|
+
const orgId = parsed?.active_org?.id;
|
|
1475
|
+
if (orgId) headers.set("Org-Id", orgId);
|
|
1476
|
+
}
|
|
1477
|
+
} catch {
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
return {
|
|
1481
|
+
...init,
|
|
1482
|
+
credentials: init?.credentials || "include",
|
|
1483
|
+
headers
|
|
1484
|
+
};
|
|
1244
1485
|
} catch {
|
|
1245
1486
|
return init;
|
|
1246
1487
|
}
|
|
@@ -1279,7 +1520,7 @@ var installFetchBreaker2 = () => {
|
|
|
1279
1520
|
installed2 = true;
|
|
1280
1521
|
const original = window.fetch.bind(window);
|
|
1281
1522
|
window.fetch = (async (input, init) => {
|
|
1282
|
-
const authenticatedInit =
|
|
1523
|
+
const authenticatedInit = withStoredAuth2(input, init);
|
|
1283
1524
|
const key = keyFor2(input, authenticatedInit);
|
|
1284
1525
|
if (!key) return original(input, authenticatedInit);
|
|
1285
1526
|
const entry = getEntry2(key);
|
|
@@ -2545,10 +2786,10 @@ async function backfillAppImages(dedupedApps) {
|
|
|
2545
2786
|
}
|
|
2546
2787
|
|
|
2547
2788
|
// ingestionDetection.ts
|
|
2548
|
-
var EMAIL_APP_PATTERNS = ["gmail", "outlook", "email", "microsoft_graph", "office365", "exchange", "imap", "smtp"];
|
|
2789
|
+
var EMAIL_APP_PATTERNS = ["gmail", "outlook", "email", "microsoft_graph", "office365", "exchange", "imap", "smtp", "proofpoint", "mimecast", "phishing"];
|
|
2549
2790
|
var CASES_PATTERNS = ["jira", "servicenow", "zendesk", "freshdesk", "pagerduty", "opsgenie", "ticket", "itsm", "salesforce", "thehive", "cortex"];
|
|
2550
|
-
var EDR_PATTERNS = ["crowdstrike", "sentinelone", "carbon black", "defender", "cylance", "sophos", "trellix", "
|
|
2551
|
-
var SIEM_PATTERNS = ["splunk", "elastic", "qradar", "sentinel", "chronicle", "logrhythm", "sumo logic", "graylog", "wazuh", "siem", "arcsight"];
|
|
2791
|
+
var EDR_PATTERNS = ["crowdstrike", "sentinelone", "carbon black", "cybereason", "microsoft defender", "defender for endpoint", "defender", "cylance", "sophos", "trellix", "tanium", "crowdstrike falcon", "falcon", "vmware", "edr", "xdr"];
|
|
2792
|
+
var SIEM_PATTERNS = ["splunk", "elastic", "qradar", "microsoft sentinel", "azure sentinel", "sentinel", "chronicle", "logrhythm", "sumo logic", "graylog", "wazuh", "siem", "arcsight"];
|
|
2552
2793
|
var THREAT_INTEL_PATTERNS = ["virustotal", "shodan", "alienvault", "otx", "threatcrowd", "urlscan", "hybrid-analysis", "abuseipdb", "greynoise", "urlhaus", "malwarebazaar", "threatfox", "misp", "opencti", "recorded future", "mandiant", "crowdstrike intel", "intel471", "flashpoint", "domaintools"];
|
|
2553
2794
|
var COMMUNICATION_PATTERNS_NAMES = ["slack", "teams", "discord", "mattermost", "telegram", "webhook"];
|
|
2554
2795
|
var VULN_SCANNER_PATTERNS = ["qualys", "tenable", "nessus", "rapid7", "nexpose", "snyk", "sonarqube", "trivy", "grype", "anchore", "dependabot", "aws_inspector", "azure_defender", "gcp_scc", "scout", "prowler", "checkov", "wiz", "orca", "lacework", "prisma"];
|
|
@@ -2745,6 +2986,67 @@ var fetchAppConfig = (appId) => {
|
|
|
2745
2986
|
|
|
2746
2987
|
// authenticatedApps.ts
|
|
2747
2988
|
init_api();
|
|
2989
|
+
|
|
2990
|
+
// ../Shuffle-Core/views/appsFetchCache.ts
|
|
2991
|
+
var JSON_CACHE_TTL_MS = 12e4;
|
|
2992
|
+
var WORKFLOWS_TTL_MS = 5 * 60 * 1e3;
|
|
2993
|
+
var _jsonCache = /* @__PURE__ */ new Map();
|
|
2994
|
+
var _inFlightPromises = /* @__PURE__ */ new Map();
|
|
2995
|
+
function normalizeEndpointKey(url, init) {
|
|
2996
|
+
let pathname = url;
|
|
2997
|
+
let search = "";
|
|
2998
|
+
try {
|
|
2999
|
+
const parsed = new URL(url, "https://shuffle.internal");
|
|
3000
|
+
pathname = parsed.pathname;
|
|
3001
|
+
search = parsed.search;
|
|
3002
|
+
} catch {
|
|
3003
|
+
}
|
|
3004
|
+
let orgId = "";
|
|
3005
|
+
if (init?.headers) {
|
|
3006
|
+
if (init.headers instanceof Headers) {
|
|
3007
|
+
orgId = init.headers.get("Org-Id") || "";
|
|
3008
|
+
} else if (Array.isArray(init.headers)) {
|
|
3009
|
+
const match = init.headers.find(([k]) => k.toLowerCase() === "org-id");
|
|
3010
|
+
if (match) orgId = match[1];
|
|
3011
|
+
} else if (typeof init.headers === "object") {
|
|
3012
|
+
orgId = init.headers["Org-Id"] || init.headers["org-id"] || "";
|
|
3013
|
+
}
|
|
3014
|
+
}
|
|
3015
|
+
return `${pathname}${search}${orgId ? `::org:${orgId}` : ""}`;
|
|
3016
|
+
}
|
|
3017
|
+
async function fetchJsonCached(url, init, ttlMs = JSON_CACHE_TTL_MS, force = false) {
|
|
3018
|
+
const cacheKey3 = normalizeEndpointKey(url, init);
|
|
3019
|
+
const now = Date.now();
|
|
3020
|
+
if (!force) {
|
|
3021
|
+
const cached2 = _jsonCache.get(cacheKey3);
|
|
3022
|
+
if (cached2 && now - cached2.ts < ttlMs) {
|
|
3023
|
+
return cached2.data;
|
|
3024
|
+
}
|
|
3025
|
+
const inFlight = _inFlightPromises.get(cacheKey3);
|
|
3026
|
+
if (inFlight) {
|
|
3027
|
+
return inFlight;
|
|
3028
|
+
}
|
|
3029
|
+
}
|
|
3030
|
+
const p = (async () => {
|
|
3031
|
+
try {
|
|
3032
|
+
const res = await fetch(url, init);
|
|
3033
|
+
if (!res.ok) {
|
|
3034
|
+
const prev = _jsonCache.get(cacheKey3);
|
|
3035
|
+
if (prev) return prev.data;
|
|
3036
|
+
throw new Error(`HTTP ${res.status}`);
|
|
3037
|
+
}
|
|
3038
|
+
const data = await res.json();
|
|
3039
|
+
_jsonCache.set(cacheKey3, { ts: Date.now(), data });
|
|
3040
|
+
return data;
|
|
3041
|
+
} finally {
|
|
3042
|
+
_inFlightPromises.delete(cacheKey3);
|
|
3043
|
+
}
|
|
3044
|
+
})();
|
|
3045
|
+
_inFlightPromises.set(cacheKey3, p);
|
|
3046
|
+
return p;
|
|
3047
|
+
}
|
|
3048
|
+
|
|
3049
|
+
// authenticatedApps.ts
|
|
2748
3050
|
var TTL_MS2 = 3e4;
|
|
2749
3051
|
var cache3 = /* @__PURE__ */ new Map();
|
|
2750
3052
|
var cacheKey2 = (crossOrgId) => crossOrgId || "";
|
|
@@ -2767,14 +3069,16 @@ var doFetch3 = async (crossOrgId) => {
|
|
|
2767
3069
|
const headers = {
|
|
2768
3070
|
...getAuthHeader(crossOrgId ?? void 0)
|
|
2769
3071
|
};
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
3072
|
+
try {
|
|
3073
|
+
const result = await fetchJsonCached(getApiUrl("/api/v1/apps/authentication"), {
|
|
3074
|
+
credentials: "include",
|
|
3075
|
+
headers
|
|
3076
|
+
});
|
|
3077
|
+
const data = result?.data || result;
|
|
3078
|
+
return Array.isArray(data) ? applyValidationStaleness(data) : [];
|
|
3079
|
+
} catch {
|
|
3080
|
+
return [];
|
|
3081
|
+
}
|
|
2778
3082
|
};
|
|
2779
3083
|
var fetchAuthenticatedApps = (crossOrgId) => {
|
|
2780
3084
|
const key = cacheKey2(crossOrgId);
|
|
@@ -4775,6 +5079,14 @@ var NO_AUTH_APPS = /* @__PURE__ */ new Set([
|
|
|
4775
5079
|
"shuffle_files",
|
|
4776
5080
|
"shuffles_app_management",
|
|
4777
5081
|
"shuffle_tools",
|
|
5082
|
+
"shuffle_assets",
|
|
5083
|
+
"shuffle_software",
|
|
5084
|
+
"shuffle_packages",
|
|
5085
|
+
"shuffle_vulnerabilities",
|
|
5086
|
+
"assets",
|
|
5087
|
+
"software",
|
|
5088
|
+
"packages",
|
|
5089
|
+
"vulnerabilities",
|
|
4778
5090
|
"tools",
|
|
4779
5091
|
"http",
|
|
4780
5092
|
"singul",
|
|
@@ -7686,7 +7998,7 @@ function AppDetailDrawer({
|
|
|
7686
7998
|
}
|
|
7687
7999
|
|
|
7688
8000
|
// views/ShuffleMCP.tsx
|
|
7689
|
-
var import_shuffle_mcp2 = require("./shuffle-mcp-
|
|
8001
|
+
var import_shuffle_mcp2 = require("./shuffle-mcp-S6QOJJG4.css");
|
|
7690
8002
|
init_appsCache();
|
|
7691
8003
|
|
|
7692
8004
|
// components/SegmentedControl.tsx
|
|
@@ -8713,11 +9025,90 @@ var import_react14 = require("react");
|
|
|
8713
9025
|
var import_material14 = require("@mui/material");
|
|
8714
9026
|
var import_lucide_react7 = require("lucide-react");
|
|
8715
9027
|
|
|
9028
|
+
// ../Shuffle-Core/lib/shuffleUrls.ts
|
|
9029
|
+
var readEnv2 = (key) => {
|
|
9030
|
+
try {
|
|
9031
|
+
const meta = new Function("try { return import.meta } catch { return undefined }")();
|
|
9032
|
+
const val = meta?.env?.[key];
|
|
9033
|
+
if (val && typeof val === "string" && val.trim().length > 0) {
|
|
9034
|
+
return val.trim();
|
|
9035
|
+
}
|
|
9036
|
+
} catch {
|
|
9037
|
+
}
|
|
9038
|
+
if (typeof window !== "undefined") {
|
|
9039
|
+
const win = window;
|
|
9040
|
+
const runtimeConfig = win.__SHUFFLE_CONFIG__ || win._env_ || win.__ENV__;
|
|
9041
|
+
if (runtimeConfig && typeof runtimeConfig === "object") {
|
|
9042
|
+
const val = runtimeConfig[key] || runtimeConfig[key.replace(/^VITE_/, "")];
|
|
9043
|
+
if (val && typeof val === "string" && val.trim().length > 0) {
|
|
9044
|
+
return val.trim();
|
|
9045
|
+
}
|
|
9046
|
+
}
|
|
9047
|
+
}
|
|
9048
|
+
try {
|
|
9049
|
+
if (typeof process !== "undefined" && process.env) {
|
|
9050
|
+
const val = process.env[key] || process.env[key.replace(/^VITE_/, "")];
|
|
9051
|
+
if (val && typeof val === "string" && val.trim().length > 0) {
|
|
9052
|
+
return val.trim();
|
|
9053
|
+
}
|
|
9054
|
+
}
|
|
9055
|
+
} catch {
|
|
9056
|
+
}
|
|
9057
|
+
return void 0;
|
|
9058
|
+
};
|
|
9059
|
+
var isManagedDomain2 = () => {
|
|
9060
|
+
if (typeof window === "undefined") return false;
|
|
9061
|
+
const hostname = window.location.hostname.toLowerCase();
|
|
9062
|
+
return hostname.includes("lovable") || hostname.includes("shuffler.io") || hostname.includes("shutdown.no") || hostname.includes("shuffle.security");
|
|
9063
|
+
};
|
|
9064
|
+
var getShuffleCoreBaseUrl2 = () => {
|
|
9065
|
+
const envUrl = readEnv2("VITE_SHUFFLE_CORE_URL") || readEnv2("SHUFFLE_CORE_URL") || readEnv2("VITE_SHUFFLE_AUTOMATION_URL") || readEnv2("VITE_SHUFFLE_URL");
|
|
9066
|
+
if (envUrl) {
|
|
9067
|
+
return envUrl.replace(/\/+$/, "");
|
|
9068
|
+
}
|
|
9069
|
+
if (typeof window !== "undefined") {
|
|
9070
|
+
try {
|
|
9071
|
+
const savedCore = localStorage.getItem("shuffle_core_url");
|
|
9072
|
+
if (savedCore && savedCore.trim().length > 0) {
|
|
9073
|
+
return savedCore.trim().replace(/\/+$/, "");
|
|
9074
|
+
}
|
|
9075
|
+
const customHost = localStorage.getItem("shuffle_custom_host_url");
|
|
9076
|
+
if (customHost && customHost.trim().length > 0) {
|
|
9077
|
+
const cleaned = customHost.trim().replace(/\/+$/, "");
|
|
9078
|
+
if (cleaned.includes(":5001")) {
|
|
9079
|
+
return cleaned.replace(":5001", ":3001");
|
|
9080
|
+
}
|
|
9081
|
+
return cleaned;
|
|
9082
|
+
}
|
|
9083
|
+
} catch {
|
|
9084
|
+
}
|
|
9085
|
+
}
|
|
9086
|
+
if (typeof window !== "undefined") {
|
|
9087
|
+
const hostname = window.location.hostname;
|
|
9088
|
+
const isManaged = isManagedDomain2();
|
|
9089
|
+
if (isManaged) {
|
|
9090
|
+
return "https://shuffler.io";
|
|
9091
|
+
}
|
|
9092
|
+
if (window.location.port === "3001") {
|
|
9093
|
+
return window.location.origin;
|
|
9094
|
+
}
|
|
9095
|
+
return `${window.location.protocol}//${hostname}:3001`;
|
|
9096
|
+
}
|
|
9097
|
+
return "https://shuffler.io";
|
|
9098
|
+
};
|
|
9099
|
+
var getShuffleCoreUrl2 = (path) => {
|
|
9100
|
+
const base3 = getShuffleCoreBaseUrl2();
|
|
9101
|
+
if (!path) return base3;
|
|
9102
|
+
const cleanPath = path.startsWith("/") ? path : `/${path}`;
|
|
9103
|
+
return `${base3}${cleanPath}`;
|
|
9104
|
+
};
|
|
9105
|
+
|
|
8716
9106
|
// ../Shuffle-Core/api.ts
|
|
8717
9107
|
init_platform();
|
|
8718
9108
|
installFetchBreaker2();
|
|
8719
9109
|
var DEV_BACKEND2 = "https://tunnel.schemaless.org";
|
|
8720
|
-
var PROD_BACKEND2 = "https://shuffler.io";
|
|
9110
|
+
var PROD_BACKEND2 = "https://uk.shuffler.io";
|
|
9111
|
+
var SHUFFLE_AUTOMATION_URL2 = getShuffleCoreUrl2("/new-dashboard");
|
|
8721
9112
|
var CLOUD_DOMAINS2 = ["shuffle.security", "www.shuffle.security", "security.shuffler.io", "shutdown.no", "www.shutdown.no"];
|
|
8722
9113
|
var getEnvVar2 = (key) => {
|
|
8723
9114
|
try {
|
|
@@ -8753,7 +9144,11 @@ var _cachedRegion = (() => {
|
|
|
8753
9144
|
const raw = localStorage.getItem(REGION_STORAGE_KEY2);
|
|
8754
9145
|
if (!raw) return { url: null, orgId: null };
|
|
8755
9146
|
const parsed = JSON.parse(raw);
|
|
8756
|
-
|
|
9147
|
+
const url = parsed?.url ? parsed.url.replace(/\/+$/, "") : null;
|
|
9148
|
+
if (url === "https://shuffler.io" || url === PROD_BACKEND2) {
|
|
9149
|
+
return { url: null, orgId: parsed?.orgId || null };
|
|
9150
|
+
}
|
|
9151
|
+
return { url, orgId: parsed?.orgId || null };
|
|
8757
9152
|
} catch {
|
|
8758
9153
|
return { url: null, orgId: null };
|
|
8759
9154
|
}
|
|
@@ -8761,8 +9156,20 @@ var _cachedRegion = (() => {
|
|
|
8761
9156
|
var _readCachedCustomHost = () => {
|
|
8762
9157
|
if (typeof window === "undefined") return null;
|
|
8763
9158
|
try {
|
|
9159
|
+
const mode = localStorage.getItem("shuffle_selected_server_mode");
|
|
9160
|
+
if (mode && mode !== "self-hosted") return null;
|
|
8764
9161
|
const raw = localStorage.getItem("shuffle_custom_host_url");
|
|
8765
|
-
|
|
9162
|
+
const cleaned = raw ? raw.trim().replace(/\/+$/, "") : null;
|
|
9163
|
+
if (!cleaned) return null;
|
|
9164
|
+
if (cleaned === DEV_BACKEND2 && !isDevEnvironment3() && mode !== "self-hosted") {
|
|
9165
|
+
try {
|
|
9166
|
+
localStorage.removeItem("shuffle_custom_host_url");
|
|
9167
|
+
localStorage.removeItem("shuffle_selected_server_mode");
|
|
9168
|
+
} catch {
|
|
9169
|
+
}
|
|
9170
|
+
return null;
|
|
9171
|
+
}
|
|
9172
|
+
return cleaned;
|
|
8766
9173
|
} catch {
|
|
8767
9174
|
return null;
|
|
8768
9175
|
}
|
|
@@ -8815,6 +9222,38 @@ if (typeof window !== "undefined") {
|
|
|
8815
9222
|
} catch {
|
|
8816
9223
|
}
|
|
8817
9224
|
}
|
|
9225
|
+
var LEGACY_API_KEY_STORAGE_KEY2 = "shuffle_api_key";
|
|
9226
|
+
var clearAuthTokens2 = () => {
|
|
9227
|
+
try {
|
|
9228
|
+
localStorage.removeItem("session_token");
|
|
9229
|
+
localStorage.removeItem(LEGACY_API_KEY_STORAGE_KEY2);
|
|
9230
|
+
} catch {
|
|
9231
|
+
}
|
|
9232
|
+
};
|
|
9233
|
+
var getSessionToken2 = () => {
|
|
9234
|
+
try {
|
|
9235
|
+
if (typeof localStorage === "undefined") return null;
|
|
9236
|
+
if (localStorage.getItem(LEGACY_API_KEY_STORAGE_KEY2) !== null) {
|
|
9237
|
+
localStorage.removeItem(LEGACY_API_KEY_STORAGE_KEY2);
|
|
9238
|
+
}
|
|
9239
|
+
const stored = localStorage.getItem("session_token");
|
|
9240
|
+
if (stored && stored.trim().length > 0 && stored !== "null" && stored !== "undefined") {
|
|
9241
|
+
return stored.trim();
|
|
9242
|
+
}
|
|
9243
|
+
return null;
|
|
9244
|
+
} catch {
|
|
9245
|
+
return null;
|
|
9246
|
+
}
|
|
9247
|
+
};
|
|
9248
|
+
var setSessionToken2 = (token) => {
|
|
9249
|
+
clearAuthTokens2();
|
|
9250
|
+
if (token && token.trim().length > 0) {
|
|
9251
|
+
try {
|
|
9252
|
+
localStorage.setItem("session_token", token.trim());
|
|
9253
|
+
} catch {
|
|
9254
|
+
}
|
|
9255
|
+
}
|
|
9256
|
+
};
|
|
8818
9257
|
var API_CONFIG5 = {
|
|
8819
9258
|
get baseUrl() {
|
|
8820
9259
|
const url = _hostBaseUrl2 || (isDevEnvironment3() || getEnvVar2("VITE_SHUFFLE_API_URL") ? getDefaultBaseUrl2() : _regionUrl2 || getDefaultBaseUrl2());
|
|
@@ -8825,28 +9264,36 @@ var API_CONFIG5 = {
|
|
|
8825
9264
|
return url;
|
|
8826
9265
|
},
|
|
8827
9266
|
version: "v1",
|
|
9267
|
+
/** DEPRECATED alias for the single session token. */
|
|
8828
9268
|
get apiKey() {
|
|
8829
|
-
|
|
8830
|
-
return typeof localStorage !== "undefined" ? localStorage.getItem("shuffle_api_key") : null;
|
|
8831
|
-
} catch {
|
|
8832
|
-
return null;
|
|
8833
|
-
}
|
|
9269
|
+
return getSessionToken2();
|
|
8834
9270
|
},
|
|
9271
|
+
/** DEPRECATED: writes/clears the single session token. */
|
|
8835
9272
|
setApiKey(key) {
|
|
8836
|
-
|
|
8837
|
-
if (key) localStorage.setItem("shuffle_api_key", key);
|
|
8838
|
-
else localStorage.removeItem("shuffle_api_key");
|
|
8839
|
-
} catch {
|
|
8840
|
-
}
|
|
9273
|
+
setSessionToken2(key);
|
|
8841
9274
|
}
|
|
8842
9275
|
};
|
|
8843
9276
|
var getApiUrl2 = (endpoint) => `${API_CONFIG5.baseUrl}${endpoint}`;
|
|
8844
9277
|
var getAuthHeader2 = (overrideOrgId) => {
|
|
8845
9278
|
const headers = {};
|
|
8846
|
-
const
|
|
8847
|
-
if (
|
|
8848
|
-
|
|
8849
|
-
|
|
9279
|
+
const token = getSessionToken2();
|
|
9280
|
+
if (token) {
|
|
9281
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
9282
|
+
}
|
|
9283
|
+
let orgId = overrideOrgId ?? _trackedOrgId2;
|
|
9284
|
+
if (!orgId && typeof localStorage !== "undefined") {
|
|
9285
|
+
try {
|
|
9286
|
+
const raw = localStorage.getItem("shuffle_user_info");
|
|
9287
|
+
if (raw) {
|
|
9288
|
+
const parsed = JSON.parse(raw);
|
|
9289
|
+
orgId = parsed?.active_org?.id || parsed?.org_id || null;
|
|
9290
|
+
}
|
|
9291
|
+
} catch {
|
|
9292
|
+
}
|
|
9293
|
+
}
|
|
9294
|
+
if (orgId) {
|
|
9295
|
+
headers["Org-Id"] = orgId;
|
|
9296
|
+
}
|
|
8850
9297
|
return headers;
|
|
8851
9298
|
};
|
|
8852
9299
|
|
|
@@ -10823,8 +11270,8 @@ var prettyAppName = (name) => name.replace(/[_-]+/g, " ").trim().split(/\s+/).ma
|
|
|
10823
11270
|
var AGENT_PRESETS = [
|
|
10824
11271
|
{
|
|
10825
11272
|
id: "build-workflows",
|
|
10826
|
-
label: "Build
|
|
10827
|
-
description: "Designs and
|
|
11273
|
+
label: "Build Workflow",
|
|
11274
|
+
description: "Designs and builds Shuffle workflows for you \u2014 pick apps, wire actions, and iterate on automations from a description.",
|
|
10828
11275
|
defaultPrompt: "Build a Shuffle workflow that ",
|
|
10829
11276
|
icon: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Workflow, { size: 16 }),
|
|
10830
11277
|
enabled: true,
|
|
@@ -10833,8 +11280,8 @@ var AGENT_PRESETS = [
|
|
|
10833
11280
|
},
|
|
10834
11281
|
{
|
|
10835
11282
|
id: "incident-response",
|
|
10836
|
-
label: "Incident
|
|
10837
|
-
description: "
|
|
11283
|
+
label: "Incident Handler",
|
|
11284
|
+
description: "Supports your incident investigation \u2014 extracts observables, correlates related alerts, analyzes attack scope, and proposes tiered containment options with human confirmation.",
|
|
10838
11285
|
defaultPrompt: "Investigate this incident and recommend next steps: ",
|
|
10839
11286
|
icon: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.ShieldAlert, { size: 16 }),
|
|
10840
11287
|
enabled: true,
|
|
@@ -10855,28 +11302,41 @@ var AGENT_PRESETS = [
|
|
|
10855
11302
|
label: "Support Agent",
|
|
10856
11303
|
description: 'Uses the platform on your behalf \u2014 navigates settings, runs diagnostics, and answers "how do I\u2026" questions.',
|
|
10857
11304
|
defaultPrompt: "Help me with the following on the Shuffle platform: ",
|
|
10858
|
-
icon: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.LifeBuoy, { size: 16 })
|
|
11305
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.LifeBuoy, { size: 16 }),
|
|
11306
|
+
enabled: true,
|
|
11307
|
+
defaultApps: [{ name: "shuffle_tools" }]
|
|
10859
11308
|
},
|
|
10860
11309
|
{
|
|
10861
11310
|
id: "vulnerability",
|
|
10862
|
-
label: "Vulnerability
|
|
10863
|
-
description: "
|
|
10864
|
-
defaultPrompt: "
|
|
10865
|
-
icon: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Bug, { size: 16 })
|
|
11311
|
+
label: "Vulnerability Management",
|
|
11312
|
+
description: "Helps you solve vulnerabilities \u2014 demystifies CVEs in plain language, analyzes realistic exploitability (EPSS/KEV), and guides you through exact remediation steps and fixes.",
|
|
11313
|
+
defaultPrompt: "Help me review and solve this vulnerability: ",
|
|
11314
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Bug, { size: 16 }),
|
|
11315
|
+
enabled: true,
|
|
11316
|
+
defaultApps: [
|
|
11317
|
+
{ name: "shuffle_vulnerabilities" },
|
|
11318
|
+
{ name: "shuffle_assets" },
|
|
11319
|
+
{ name: "shuffle_software" },
|
|
11320
|
+
{ name: "shuffle_packages" }
|
|
11321
|
+
]
|
|
10866
11322
|
},
|
|
10867
11323
|
{
|
|
10868
11324
|
id: "detection",
|
|
10869
11325
|
label: "Detection Agent",
|
|
10870
11326
|
description: "Creates and tunes detection rules (Sigma, pipelines) \u2014 adjusts logic, filters false positives, and validates coverage.",
|
|
10871
11327
|
defaultPrompt: "Modify my detections to ",
|
|
10872
|
-
icon: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Radar, { size: 16 })
|
|
11328
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Radar, { size: 16 }),
|
|
11329
|
+
enabled: true,
|
|
11330
|
+
defaultApps: [{ name: "shuffle_detection" }]
|
|
10873
11331
|
},
|
|
10874
11332
|
{
|
|
10875
11333
|
id: "handle-notifications",
|
|
10876
11334
|
label: "Handle Notifications",
|
|
10877
11335
|
description: "Automatically handles incoming incidents for you \u2014 triages, enriches, and resolves or escalates based on your rules.",
|
|
10878
11336
|
defaultPrompt: "Automatically handle incoming incidents by ",
|
|
10879
|
-
icon: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.BellRing, { size: 16 })
|
|
11337
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.BellRing, { size: 16 }),
|
|
11338
|
+
enabled: true,
|
|
11339
|
+
defaultApps: [{ name: "shuffle_incidents" }]
|
|
10880
11340
|
}
|
|
10881
11341
|
];
|
|
10882
11342
|
var isSupportUser = () => {
|
|
@@ -10899,7 +11359,7 @@ var filterAgentPresets = (list, support) => {
|
|
|
10899
11359
|
if (support === true || support === void 0 && isSupportUser()) return list;
|
|
10900
11360
|
return list.map((p) => SUPPORT_ONLY_PRESET_IDS.includes(p.id) ? { ...p, enabled: false } : p);
|
|
10901
11361
|
};
|
|
10902
|
-
var AgentPresets = ({ variant = "default", onSelectPreset, selectedPreset, onRemoveSelected, presets, chipRef, isSupport }) => {
|
|
11362
|
+
var AgentPresets = ({ variant = "default", onSelectPreset, selectedPreset, onRemoveSelected, presets, chipRef, isSupport, sx, placement }) => {
|
|
10903
11363
|
const [anchorEl, setAnchorEl] = (0, import_react17.useState)(null);
|
|
10904
11364
|
const open = Boolean(anchorEl);
|
|
10905
11365
|
const [supportTick, setSupportTick] = (0, import_react17.useState)(0);
|
|
@@ -10914,67 +11374,129 @@ var AgentPresets = ({ variant = "default", onSelectPreset, selectedPreset, onRem
|
|
|
10914
11374
|
[presets, supportTick, open, isSupport]
|
|
10915
11375
|
);
|
|
10916
11376
|
const MAX_LABEL_CHARS = 18;
|
|
10917
|
-
const
|
|
10918
|
-
const
|
|
10919
|
-
|
|
11377
|
+
const cleanLabel = selectedPreset?.label?.replace(/\s+Agent$/i, "") || "";
|
|
11378
|
+
const displayLabel = selectedPreset ? cleanLabel.length > MAX_LABEL_CHARS ? `${cleanLabel.slice(0, MAX_LABEL_CHARS - 1).trimEnd()}\u2026` : cleanLabel : "Skills";
|
|
11379
|
+
const trigger = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
11380
|
+
import_material19.ButtonBase,
|
|
10920
11381
|
{
|
|
10921
11382
|
ref: chipRef,
|
|
10922
|
-
size: "small",
|
|
10923
11383
|
onClick: (e) => setAnchorEl(e.currentTarget),
|
|
10924
|
-
|
|
10925
|
-
|
|
10926
|
-
import_material19.Box,
|
|
11384
|
+
"aria-label": selectedPreset ? `Skill: ${selectedPreset.label}` : "Select skill",
|
|
11385
|
+
sx: [
|
|
10927
11386
|
{
|
|
10928
|
-
|
|
10929
|
-
|
|
10930
|
-
|
|
10931
|
-
|
|
10932
|
-
|
|
10933
|
-
|
|
10934
|
-
|
|
10935
|
-
|
|
10936
|
-
|
|
10937
|
-
|
|
10938
|
-
|
|
10939
|
-
|
|
10940
|
-
|
|
10941
|
-
|
|
10942
|
-
|
|
10943
|
-
|
|
10944
|
-
|
|
10945
|
-
|
|
10946
|
-
|
|
10947
|
-
|
|
10948
|
-
|
|
10949
|
-
|
|
10950
|
-
|
|
10951
|
-
|
|
10952
|
-
|
|
10953
|
-
|
|
10954
|
-
|
|
10955
|
-
|
|
10956
|
-
|
|
10957
|
-
|
|
10958
|
-
|
|
10959
|
-
|
|
10960
|
-
|
|
10961
|
-
|
|
10962
|
-
|
|
10963
|
-
|
|
10964
|
-
|
|
10965
|
-
|
|
10966
|
-
|
|
10967
|
-
|
|
10968
|
-
|
|
10969
|
-
|
|
10970
|
-
|
|
10971
|
-
|
|
10972
|
-
|
|
10973
|
-
|
|
10974
|
-
|
|
10975
|
-
|
|
10976
|
-
|
|
10977
|
-
|
|
11387
|
+
display: "inline-flex",
|
|
11388
|
+
alignItems: "center",
|
|
11389
|
+
gap: "5px",
|
|
11390
|
+
height: variant === "floating" ? 30 : variant === "inline" ? 38 : 32,
|
|
11391
|
+
px: variant === "floating" ? "9px" : "12px",
|
|
11392
|
+
py: 0,
|
|
11393
|
+
borderRadius: 999,
|
|
11394
|
+
border: "1px solid hsl(var(--border))",
|
|
11395
|
+
color: selectedPreset ? "hsl(var(--foreground))" : "hsl(var(--muted-foreground))",
|
|
11396
|
+
bgcolor: selectedPreset ? "hsl(var(--muted) / 0.7)" : "transparent",
|
|
11397
|
+
fontSize: variant === "floating" ? "0.75rem" : "0.78rem",
|
|
11398
|
+
fontWeight: 500,
|
|
11399
|
+
flexShrink: 0,
|
|
11400
|
+
boxSizing: "border-box",
|
|
11401
|
+
cursor: "pointer",
|
|
11402
|
+
transition: "background-color 120ms ease, border-color 120ms ease, box-shadow 120ms ease",
|
|
11403
|
+
"&:hover": {
|
|
11404
|
+
bgcolor: selectedPreset ? "hsl(var(--muted) / 0.9)" : "hsl(var(--muted) / 0.5)",
|
|
11405
|
+
borderColor: selectedPreset ? "hsl(var(--muted-foreground) / 0.35)" : "hsl(var(--border))",
|
|
11406
|
+
boxShadow: selectedPreset ? "0 1px 4px hsl(var(--background) / 0.35)" : "none"
|
|
11407
|
+
}
|
|
11408
|
+
},
|
|
11409
|
+
...Array.isArray(sx) ? sx : sx ? [sx] : []
|
|
11410
|
+
],
|
|
11411
|
+
children: [
|
|
11412
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
11413
|
+
import_material19.Box,
|
|
11414
|
+
{
|
|
11415
|
+
component: "span",
|
|
11416
|
+
sx: {
|
|
11417
|
+
display: "inline-flex",
|
|
11418
|
+
alignItems: "center",
|
|
11419
|
+
justifyContent: "center",
|
|
11420
|
+
flexShrink: 0,
|
|
11421
|
+
color: selectedPreset ? "hsl(var(--primary))" : "inherit",
|
|
11422
|
+
"& svg": {
|
|
11423
|
+
width: variant === "floating" ? 14 : 16,
|
|
11424
|
+
height: variant === "floating" ? 14 : 16
|
|
11425
|
+
}
|
|
11426
|
+
},
|
|
11427
|
+
children: selectedPreset ? selectedPreset.icon ?? void 0 : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Plus, { size: variant === "floating" ? 12 : 14 })
|
|
11428
|
+
}
|
|
11429
|
+
),
|
|
11430
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
11431
|
+
import_material19.Typography,
|
|
11432
|
+
{
|
|
11433
|
+
component: "span",
|
|
11434
|
+
sx: {
|
|
11435
|
+
fontSize: "inherit",
|
|
11436
|
+
fontWeight: "inherit",
|
|
11437
|
+
color: "inherit",
|
|
11438
|
+
lineHeight: 1,
|
|
11439
|
+
whiteSpace: "nowrap",
|
|
11440
|
+
overflow: "hidden",
|
|
11441
|
+
textOverflow: "ellipsis",
|
|
11442
|
+
maxWidth: 150
|
|
11443
|
+
},
|
|
11444
|
+
children: displayLabel
|
|
11445
|
+
}
|
|
11446
|
+
),
|
|
11447
|
+
selectedPreset && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
11448
|
+
import_material19.Box,
|
|
11449
|
+
{
|
|
11450
|
+
component: "span",
|
|
11451
|
+
role: "button",
|
|
11452
|
+
"aria-label": "Remove skill",
|
|
11453
|
+
onClick: (e) => {
|
|
11454
|
+
e.stopPropagation();
|
|
11455
|
+
onRemoveSelected?.();
|
|
11456
|
+
},
|
|
11457
|
+
sx: {
|
|
11458
|
+
display: "inline-flex",
|
|
11459
|
+
alignItems: "center",
|
|
11460
|
+
justifyContent: "center",
|
|
11461
|
+
ml: "1px",
|
|
11462
|
+
p: "2px",
|
|
11463
|
+
borderRadius: "50%",
|
|
11464
|
+
cursor: "pointer",
|
|
11465
|
+
flexShrink: 0,
|
|
11466
|
+
color: "hsl(var(--muted-foreground))",
|
|
11467
|
+
transition: "background-color 120ms ease, color 120ms ease",
|
|
11468
|
+
"&:hover": {
|
|
11469
|
+
bgcolor: "hsl(var(--foreground) / 0.12)",
|
|
11470
|
+
color: "hsl(var(--foreground))"
|
|
11471
|
+
}
|
|
11472
|
+
},
|
|
11473
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.X, { size: variant === "floating" ? 11 : 12 })
|
|
11474
|
+
}
|
|
11475
|
+
)
|
|
11476
|
+
]
|
|
11477
|
+
}
|
|
11478
|
+
);
|
|
11479
|
+
const [query, setQuery] = (0, import_react17.useState)("");
|
|
11480
|
+
const filtered = (0, import_react17.useMemo)(() => {
|
|
11481
|
+
const q = query.trim().toLowerCase();
|
|
11482
|
+
if (!q) return list;
|
|
11483
|
+
return list.filter(
|
|
11484
|
+
(p) => p.label.toLowerCase().includes(q) || p.description.toLowerCase().includes(q)
|
|
11485
|
+
);
|
|
11486
|
+
}, [list, query]);
|
|
11487
|
+
const menu = open ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
11488
|
+
import_material19.Popper,
|
|
11489
|
+
{
|
|
11490
|
+
open,
|
|
11491
|
+
anchorEl,
|
|
11492
|
+
placement: placement || "bottom-start",
|
|
11493
|
+
style: { zIndex: 1400 },
|
|
11494
|
+
modifiers: [
|
|
11495
|
+
{ name: "offset", options: { offset: [0, 6] } },
|
|
11496
|
+
{ name: "preventOverflow", options: { padding: 8 } }
|
|
11497
|
+
],
|
|
11498
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material19.ClickAwayListener, { onClickAway: () => {
|
|
11499
|
+
setAnchorEl(null);
|
|
10978
11500
|
setQuery("");
|
|
10979
11501
|
}, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
10980
11502
|
import_material19.Paper,
|
|
@@ -11210,13 +11732,7 @@ var AgentPresets = ({ variant = "default", onSelectPreset, selectedPreset, onRem
|
|
|
11210
11732
|
) })
|
|
11211
11733
|
}
|
|
11212
11734
|
) : null;
|
|
11213
|
-
|
|
11214
|
-
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
11215
|
-
trigger,
|
|
11216
|
-
menu
|
|
11217
|
-
] });
|
|
11218
|
-
}
|
|
11219
|
-
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_material19.Box, { sx: { width: "100%", display: "flex", justifyContent: "flex-end" }, children: [
|
|
11735
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
11220
11736
|
trigger,
|
|
11221
11737
|
menu
|
|
11222
11738
|
] });
|
|
@@ -11896,12 +12412,15 @@ var runAgent = async (request) => {
|
|
|
11896
12412
|
params.tool_ids = request.toolIds;
|
|
11897
12413
|
}
|
|
11898
12414
|
const PRESET_PATHS = {
|
|
11899
|
-
"build-workflows": "workflow
|
|
12415
|
+
"build-workflows": "edit-workflow",
|
|
12416
|
+
"edit-workflow": "edit-workflow",
|
|
11900
12417
|
"handle-notifications": "handle-notifications",
|
|
11901
|
-
"incident-response": "incident-
|
|
12418
|
+
"incident-response": "incident-handler",
|
|
12419
|
+
"incident-handler": "incident-handler",
|
|
11902
12420
|
"host-monitor-control": "computer-use",
|
|
11903
12421
|
support: "support",
|
|
11904
12422
|
vulnerability: "vulnerability",
|
|
12423
|
+
"vulnerability-management": "vulnerability",
|
|
11905
12424
|
detection: "detection"
|
|
11906
12425
|
};
|
|
11907
12426
|
const presetSlug = request.presetId ? PRESET_PATHS[request.presetId] : void 0;
|
|
@@ -11998,7 +12517,7 @@ var resolveAgentContinuationTargets = async (executionId, authorization) => {
|
|
|
11998
12517
|
const resp = await fetch(getApiUrl("/api/v1/streams/results"), {
|
|
11999
12518
|
method: "POST",
|
|
12000
12519
|
credentials: "include",
|
|
12001
|
-
headers: { "Content-Type": "application/json" },
|
|
12520
|
+
headers: { "Content-Type": "application/json", ...getAuthHeader() },
|
|
12002
12521
|
body: JSON.stringify({ execution_id: executionId, authorization })
|
|
12003
12522
|
});
|
|
12004
12523
|
if (!resp.ok) return empty;
|
|
@@ -13315,6 +13834,716 @@ var collectLlmImageAttachments = (root, maxDepth = 10) => {
|
|
|
13315
13834
|
return deduped;
|
|
13316
13835
|
};
|
|
13317
13836
|
|
|
13837
|
+
// connectedSourcesService.ts
|
|
13838
|
+
var CACHE_PREFIX = "shuffle:connected_tools:";
|
|
13839
|
+
function getCachedConnectedTools(category) {
|
|
13840
|
+
if (!category) return [];
|
|
13841
|
+
try {
|
|
13842
|
+
if (typeof localStorage === "undefined") return [];
|
|
13843
|
+
const raw = localStorage.getItem(`${CACHE_PREFIX}${category}`);
|
|
13844
|
+
if (!raw) return [];
|
|
13845
|
+
const parsed = JSON.parse(raw);
|
|
13846
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
13847
|
+
} catch {
|
|
13848
|
+
return [];
|
|
13849
|
+
}
|
|
13850
|
+
}
|
|
13851
|
+
function setCachedConnectedTools(category, tools) {
|
|
13852
|
+
if (!category) return;
|
|
13853
|
+
try {
|
|
13854
|
+
if (typeof localStorage === "undefined") return;
|
|
13855
|
+
localStorage.setItem(`${CACHE_PREFIX}${category}`, JSON.stringify(tools));
|
|
13856
|
+
} catch {
|
|
13857
|
+
}
|
|
13858
|
+
}
|
|
13859
|
+
function mergeConnectedTools(baseApps, connectedTools) {
|
|
13860
|
+
if (!connectedTools || connectedTools.length === 0) return baseApps;
|
|
13861
|
+
const seen = /* @__PURE__ */ new Set();
|
|
13862
|
+
const merged = [];
|
|
13863
|
+
for (const app2 of baseApps) {
|
|
13864
|
+
if (!app2?.name) continue;
|
|
13865
|
+
const norm4 = normalizeAppName(app2.name);
|
|
13866
|
+
if (!seen.has(norm4)) {
|
|
13867
|
+
seen.add(norm4);
|
|
13868
|
+
merged.push(app2);
|
|
13869
|
+
}
|
|
13870
|
+
}
|
|
13871
|
+
for (const app2 of connectedTools) {
|
|
13872
|
+
if (!app2?.name) continue;
|
|
13873
|
+
const norm4 = normalizeAppName(app2.name);
|
|
13874
|
+
if (!seen.has(norm4) && !isIgnoredWorkflowAppName(norm4)) {
|
|
13875
|
+
seen.add(norm4);
|
|
13876
|
+
merged.push(app2);
|
|
13877
|
+
}
|
|
13878
|
+
}
|
|
13879
|
+
return merged;
|
|
13880
|
+
}
|
|
13881
|
+
function resolveConnectedTools(category, authApiResponse = [], workflowsResponse = []) {
|
|
13882
|
+
const tools = [];
|
|
13883
|
+
const seen = /* @__PURE__ */ new Set();
|
|
13884
|
+
const authList = Array.isArray(authApiResponse) ? authApiResponse : authApiResponse?.data || [];
|
|
13885
|
+
const workflows = Array.isArray(workflowsResponse) ? workflowsResponse : workflowsResponse?.workflows || [];
|
|
13886
|
+
const addTool = (name, id, icon) => {
|
|
13887
|
+
if (!name || typeof name !== "string") return;
|
|
13888
|
+
const trimmed = name.trim();
|
|
13889
|
+
if (!trimmed) return;
|
|
13890
|
+
const norm4 = normalizeAppName(trimmed);
|
|
13891
|
+
if (!norm4 || seen.has(norm4) || isIgnoredWorkflowAppName(norm4)) return;
|
|
13892
|
+
seen.add(norm4);
|
|
13893
|
+
tools.push({ name: trimmed, id: id || void 0, icon: icon || void 0 });
|
|
13894
|
+
};
|
|
13895
|
+
const authByName = /* @__PURE__ */ new Map();
|
|
13896
|
+
for (const entry of authList) {
|
|
13897
|
+
const app2 = entry?.app || entry;
|
|
13898
|
+
const rawName = app2?.name;
|
|
13899
|
+
if (!rawName) continue;
|
|
13900
|
+
const norm4 = normalizeAppName(rawName);
|
|
13901
|
+
const isValid = entry?.active === true || entry?.validation?.valid === true || entry?.hasValidAuth === true || app2?.is_valid === true || app2?.tested === true;
|
|
13902
|
+
const img = app2?.large_image || app2?.image_url || app2?.image || entry?.bestImage || "";
|
|
13903
|
+
if (!authByName.has(norm4) || isValid) {
|
|
13904
|
+
authByName.set(norm4, {
|
|
13905
|
+
name: rawName,
|
|
13906
|
+
id: app2?.id || entry?.id,
|
|
13907
|
+
icon: img,
|
|
13908
|
+
active: Boolean(entry?.active),
|
|
13909
|
+
valid: isValid
|
|
13910
|
+
});
|
|
13911
|
+
}
|
|
13912
|
+
}
|
|
13913
|
+
if (category === "incidents") {
|
|
13914
|
+
const ingestWf = findIngestTicketsWorkflow(workflows);
|
|
13915
|
+
const ingestAppNames = ingestWf ? extractWorkflowAppNames(ingestWf) : /* @__PURE__ */ new Set();
|
|
13916
|
+
const forwardWf = findForwardTicketsWorkflow(workflows);
|
|
13917
|
+
const forwardAppNames = forwardWf ? extractWorkflowAppNames(forwardWf) : /* @__PURE__ */ new Set();
|
|
13918
|
+
ingestAppNames.forEach((norm4) => {
|
|
13919
|
+
const auth = authByName.get(norm4);
|
|
13920
|
+
if (auth) {
|
|
13921
|
+
addTool(auth.name, auth.id, auth.icon);
|
|
13922
|
+
} else {
|
|
13923
|
+
const formatted = norm4.split("_").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
13924
|
+
addTool(formatted);
|
|
13925
|
+
}
|
|
13926
|
+
});
|
|
13927
|
+
forwardAppNames.forEach((norm4) => {
|
|
13928
|
+
const auth = authByName.get(norm4);
|
|
13929
|
+
if (auth) {
|
|
13930
|
+
addTool(auth.name, auth.id, auth.icon);
|
|
13931
|
+
} else {
|
|
13932
|
+
const formatted = norm4.split("_").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
13933
|
+
addTool(formatted);
|
|
13934
|
+
}
|
|
13935
|
+
});
|
|
13936
|
+
for (const [norm4, auth] of authByName.entries()) {
|
|
13937
|
+
if (!auth.valid && !auth.active) continue;
|
|
13938
|
+
const isSiem = SIEM_PATTERNS.some((p) => norm4.includes(p));
|
|
13939
|
+
const isEdr = EDR_PATTERNS.some((p) => norm4.includes(p));
|
|
13940
|
+
const isEmail = EMAIL_APP_PATTERNS.some((p) => norm4.includes(p));
|
|
13941
|
+
const isCases = CASES_PATTERNS.some((p) => norm4.includes(p));
|
|
13942
|
+
const isComms = COMMUNICATION_PATTERNS_NAMES.some((p) => norm4.includes(p));
|
|
13943
|
+
if (isSiem || isEdr || isEmail || isCases || isComms) {
|
|
13944
|
+
addTool(auth.name, auth.id, auth.icon);
|
|
13945
|
+
}
|
|
13946
|
+
}
|
|
13947
|
+
} else if (category === "vulnerabilities") {
|
|
13948
|
+
const ingestVulnWf = workflows.find(
|
|
13949
|
+
(w) => typeof w?.name === "string" && (w.name === "Ingest Vulnerabilities" || w.name.toLowerCase().includes("ingest vulnerabilit"))
|
|
13950
|
+
);
|
|
13951
|
+
const vulnAppNames = ingestVulnWf ? extractWorkflowAppNames(ingestVulnWf) : /* @__PURE__ */ new Set();
|
|
13952
|
+
vulnAppNames.forEach((norm4) => {
|
|
13953
|
+
const auth = authByName.get(norm4);
|
|
13954
|
+
if (auth) {
|
|
13955
|
+
addTool(auth.name, auth.id, auth.icon);
|
|
13956
|
+
} else {
|
|
13957
|
+
const formatted = norm4.split("_").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
13958
|
+
addTool(formatted);
|
|
13959
|
+
}
|
|
13960
|
+
});
|
|
13961
|
+
for (const [norm4, auth] of authByName.entries()) {
|
|
13962
|
+
if (!auth.valid && !auth.active) continue;
|
|
13963
|
+
const isScanner = isVulnScannerApp(auth.name) || VULN_SCANNER_PATTERNS.some((p) => norm4.includes(p));
|
|
13964
|
+
if (isScanner) {
|
|
13965
|
+
addTool(auth.name, auth.id, auth.icon);
|
|
13966
|
+
}
|
|
13967
|
+
}
|
|
13968
|
+
}
|
|
13969
|
+
return tools;
|
|
13970
|
+
}
|
|
13971
|
+
|
|
13972
|
+
// agentContextRegistry.ts
|
|
13973
|
+
var STORAGE_PREFIX = "shuffle_agent_context_choice_";
|
|
13974
|
+
var matchRoutePattern = (pattern, pathname) => {
|
|
13975
|
+
const normPattern = pattern.replace(/\/+$/, "") || "/";
|
|
13976
|
+
const normPath = pathname.replace(/\/+$/, "") || "/";
|
|
13977
|
+
if (normPattern === normPath) return {};
|
|
13978
|
+
const patternSegments = normPattern.split("/");
|
|
13979
|
+
const pathSegments = normPath.split("/");
|
|
13980
|
+
if (patternSegments.length !== pathSegments.length) {
|
|
13981
|
+
if (patternSegments[patternSegments.length - 1] === "*" && pathSegments.length >= patternSegments.length - 1) {
|
|
13982
|
+
const params2 = {};
|
|
13983
|
+
for (let i = 0; i < patternSegments.length - 1; i++) {
|
|
13984
|
+
if (patternSegments[i].startsWith(":")) {
|
|
13985
|
+
params2[patternSegments[i].slice(1)] = decodeURIComponent(pathSegments[i]);
|
|
13986
|
+
} else if (patternSegments[i] !== pathSegments[i]) {
|
|
13987
|
+
return null;
|
|
13988
|
+
}
|
|
13989
|
+
}
|
|
13990
|
+
params2["*"] = pathSegments.slice(patternSegments.length - 1).join("/");
|
|
13991
|
+
return params2;
|
|
13992
|
+
}
|
|
13993
|
+
return null;
|
|
13994
|
+
}
|
|
13995
|
+
const params = {};
|
|
13996
|
+
for (let i = 0; i < patternSegments.length; i++) {
|
|
13997
|
+
const pSeg = patternSegments[i];
|
|
13998
|
+
const uSeg = pathSegments[i];
|
|
13999
|
+
if (pSeg.startsWith(":")) {
|
|
14000
|
+
params[pSeg.slice(1)] = decodeURIComponent(uSeg);
|
|
14001
|
+
} else if (pSeg !== uSeg) {
|
|
14002
|
+
return null;
|
|
14003
|
+
}
|
|
14004
|
+
}
|
|
14005
|
+
return params;
|
|
14006
|
+
};
|
|
14007
|
+
var isAgentRoute = (pathname) => {
|
|
14008
|
+
const norm4 = pathname.toLowerCase().replace(/\/+$/, "") || "/";
|
|
14009
|
+
return norm4 === "/agents" || norm4 === "/agent" || norm4.startsWith("/agents/") || norm4.startsWith("/agent/");
|
|
14010
|
+
};
|
|
14011
|
+
var getActivePageEntityName = () => {
|
|
14012
|
+
if (typeof document === "undefined") return void 0;
|
|
14013
|
+
try {
|
|
14014
|
+
const titleInput = document.querySelector(
|
|
14015
|
+
'[data-incident-field="title"] input, [data-case-field="title"] input, [data-ticket-field="title"] input, [data-alert-field="title"] input, [data-host-field="name"] input, [data-monitor-field="name"] input, [data-asset-field="name"] input, [data-software-field="name"] input, [data-package-field="name"] input'
|
|
14016
|
+
);
|
|
14017
|
+
if (titleInput?.value && titleInput.value.trim().length > 0) {
|
|
14018
|
+
return titleInput.value.trim();
|
|
14019
|
+
}
|
|
14020
|
+
const heading = document.querySelector("h1, h2, [data-entity-title]");
|
|
14021
|
+
if (heading?.textContent && heading.textContent.trim().length > 0 && heading.textContent.trim().length < 90) {
|
|
14022
|
+
return heading.textContent.trim();
|
|
14023
|
+
}
|
|
14024
|
+
} catch {
|
|
14025
|
+
}
|
|
14026
|
+
return void 0;
|
|
14027
|
+
};
|
|
14028
|
+
var DEFAULT_AGENT_CONTEXT_RULES = [
|
|
14029
|
+
// ==========================================
|
|
14030
|
+
// 1. Incidents, Cases, Tickets, Alerts (Grouped)
|
|
14031
|
+
// ==========================================
|
|
14032
|
+
// Specific Incident Detail
|
|
14033
|
+
{
|
|
14034
|
+
id: "incident-detail",
|
|
14035
|
+
match: "/incidents/:id",
|
|
14036
|
+
defaultApps: [{ name: "shuffle_incidents" }],
|
|
14037
|
+
defaultPresetId: "incident-response",
|
|
14038
|
+
sourceCategory: "incidents",
|
|
14039
|
+
title: (params) => {
|
|
14040
|
+
const entity = getActivePageEntityName();
|
|
14041
|
+
return entity ? `How can we help handle incident "${entity}"?` : `How can we help handle incident #${params.id}?`;
|
|
14042
|
+
},
|
|
14043
|
+
subtitle: () => "Shuffle Incidents MCP",
|
|
14044
|
+
defaultPrompt: (params) => `Investigate incident ${params.id} and recommend next steps: `,
|
|
14045
|
+
placeholder: "Ask about this incident, triage observables, or correlate...",
|
|
14046
|
+
getStorageKey: (params) => `incident_${params.id}`,
|
|
14047
|
+
description: "Focused on the currently viewed incident with Shuffle Incidents MCP"
|
|
14048
|
+
},
|
|
14049
|
+
// Simplified Incident Detail
|
|
14050
|
+
{
|
|
14051
|
+
id: "incident-simple-detail",
|
|
14052
|
+
match: "/incidents-simple/:id",
|
|
14053
|
+
defaultApps: [{ name: "shuffle_incidents" }],
|
|
14054
|
+
defaultPresetId: "incident-response",
|
|
14055
|
+
sourceCategory: "incidents",
|
|
14056
|
+
title: (params) => {
|
|
14057
|
+
const entity = getActivePageEntityName();
|
|
14058
|
+
return entity ? `How can we help handle incident "${entity}"?` : `How can we help handle incident #${params.id}?`;
|
|
14059
|
+
},
|
|
14060
|
+
subtitle: () => "Shuffle Incidents MCP",
|
|
14061
|
+
defaultPrompt: (params) => `Investigate incident ${params.id} and recommend next steps: `,
|
|
14062
|
+
placeholder: "Ask about this incident, triage observables, or correlate...",
|
|
14063
|
+
getStorageKey: (params) => `incident_${params.id}`,
|
|
14064
|
+
description: "Focused on the currently viewed incident with Shuffle Incidents MCP"
|
|
14065
|
+
},
|
|
14066
|
+
// Specific Case Detail
|
|
14067
|
+
{
|
|
14068
|
+
id: "case-detail",
|
|
14069
|
+
match: "/cases/:id",
|
|
14070
|
+
defaultApps: [{ name: "shuffle_incidents" }],
|
|
14071
|
+
defaultPresetId: "incident-response",
|
|
14072
|
+
sourceCategory: "incidents",
|
|
14073
|
+
title: (params) => {
|
|
14074
|
+
const entity = getActivePageEntityName();
|
|
14075
|
+
return entity ? `How can we help handle case "${entity}"?` : `How can we help handle case #${params.id}?`;
|
|
14076
|
+
},
|
|
14077
|
+
subtitle: () => "Shuffle Incidents MCP",
|
|
14078
|
+
defaultPrompt: (params) => `Investigate case ${params.id} and recommend next steps: `,
|
|
14079
|
+
placeholder: "Review case evidence, correlate events, or recommend response actions...",
|
|
14080
|
+
getStorageKey: (params) => `case_${params.id}`,
|
|
14081
|
+
description: "Focused on the currently viewed case with Shuffle Incidents MCP"
|
|
14082
|
+
},
|
|
14083
|
+
// Specific Ticket Detail
|
|
14084
|
+
{
|
|
14085
|
+
id: "ticket-detail",
|
|
14086
|
+
match: "/tickets/:id",
|
|
14087
|
+
defaultApps: [{ name: "shuffle_incidents" }],
|
|
14088
|
+
defaultPresetId: "incident-response",
|
|
14089
|
+
sourceCategory: "incidents",
|
|
14090
|
+
title: (params) => {
|
|
14091
|
+
const entity = getActivePageEntityName();
|
|
14092
|
+
return entity ? `How can we help handle ticket "${entity}"?` : `How can we help handle ticket #${params.id}?`;
|
|
14093
|
+
},
|
|
14094
|
+
subtitle: () => "Shuffle Incidents MCP",
|
|
14095
|
+
defaultPrompt: (params) => `Investigate ticket ${params.id} and recommend next steps: `,
|
|
14096
|
+
placeholder: "Investigate ticket, draft reply, or correlate related incidents...",
|
|
14097
|
+
getStorageKey: (params) => `ticket_${params.id}`,
|
|
14098
|
+
description: "Focused on the currently viewed ticket with Shuffle Incidents MCP"
|
|
14099
|
+
},
|
|
14100
|
+
// Specific Alert Detail
|
|
14101
|
+
{
|
|
14102
|
+
id: "alert-detail",
|
|
14103
|
+
match: "/alerts/:id",
|
|
14104
|
+
defaultApps: [{ name: "shuffle_incidents" }],
|
|
14105
|
+
defaultPresetId: "incident-response",
|
|
14106
|
+
sourceCategory: "incidents",
|
|
14107
|
+
title: (params) => {
|
|
14108
|
+
const entity = getActivePageEntityName();
|
|
14109
|
+
return entity ? `How can we help handle alert "${entity}"?` : `How can we help handle alert #${params.id}?`;
|
|
14110
|
+
},
|
|
14111
|
+
subtitle: () => "Shuffle Incidents MCP",
|
|
14112
|
+
defaultPrompt: (params) => `Investigate alert ${params.id} and recommend next steps: `,
|
|
14113
|
+
placeholder: "Analyze alert telemetry, assess false positive probability, or escalate...",
|
|
14114
|
+
getStorageKey: (params) => `alert_${params.id}`,
|
|
14115
|
+
description: "Focused on the currently viewed alert with Shuffle Incidents MCP"
|
|
14116
|
+
},
|
|
14117
|
+
// Incidents Overview & Subpages (/incidents/*)
|
|
14118
|
+
{
|
|
14119
|
+
id: "incidents-group",
|
|
14120
|
+
match: (pathname) => pathname.startsWith("/incidents") || pathname.startsWith("/incidents-simple"),
|
|
14121
|
+
defaultApps: [{ name: "shuffle_incidents" }],
|
|
14122
|
+
defaultPresetId: "incident-response",
|
|
14123
|
+
sourceCategory: "incidents",
|
|
14124
|
+
title: "How can we help handle incidents?",
|
|
14125
|
+
subtitle: "Shuffle Incidents MCP",
|
|
14126
|
+
defaultPrompt: "Investigate this incident and recommend next steps: ",
|
|
14127
|
+
placeholder: "Triage incidents, correlate alerts, or search threat intelligence...",
|
|
14128
|
+
getStorageKey: () => "incidents_list",
|
|
14129
|
+
description: "Incidents overview with Shuffle Incidents MCP"
|
|
14130
|
+
},
|
|
14131
|
+
// Cases Overview & Subpages (/cases/*)
|
|
14132
|
+
{
|
|
14133
|
+
id: "cases-group",
|
|
14134
|
+
match: (pathname) => pathname.startsWith("/cases"),
|
|
14135
|
+
defaultApps: [{ name: "shuffle_incidents" }],
|
|
14136
|
+
defaultPresetId: "incident-response",
|
|
14137
|
+
sourceCategory: "incidents",
|
|
14138
|
+
title: "How can we help handle cases?",
|
|
14139
|
+
subtitle: "Shuffle Incidents MCP",
|
|
14140
|
+
defaultPrompt: "Investigate this case and recommend next steps: ",
|
|
14141
|
+
placeholder: "Review active cases, correlate investigations, or log evidence...",
|
|
14142
|
+
getStorageKey: () => "cases_list",
|
|
14143
|
+
description: "Cases overview with Shuffle Incidents MCP"
|
|
14144
|
+
},
|
|
14145
|
+
// Tickets Overview & Subpages (/tickets/*)
|
|
14146
|
+
{
|
|
14147
|
+
id: "tickets-group",
|
|
14148
|
+
match: (pathname) => pathname.startsWith("/tickets"),
|
|
14149
|
+
defaultApps: [{ name: "shuffle_incidents" }],
|
|
14150
|
+
defaultPresetId: "incident-response",
|
|
14151
|
+
sourceCategory: "incidents",
|
|
14152
|
+
title: "How can we help handle tickets?",
|
|
14153
|
+
subtitle: "Shuffle Incidents MCP",
|
|
14154
|
+
defaultPrompt: "Investigate this ticket and recommend next steps: ",
|
|
14155
|
+
placeholder: "Triage incoming tickets, automate assignments, or resolve issues...",
|
|
14156
|
+
getStorageKey: () => "tickets_list",
|
|
14157
|
+
description: "Tickets overview with Shuffle Incidents MCP"
|
|
14158
|
+
},
|
|
14159
|
+
// Alerts Overview & Subpages (/alerts/*, /notifications/*)
|
|
14160
|
+
{
|
|
14161
|
+
id: "alerts-group",
|
|
14162
|
+
match: (pathname) => pathname.startsWith("/alerts") || pathname.startsWith("/notifications"),
|
|
14163
|
+
defaultApps: [{ name: "shuffle_incidents" }],
|
|
14164
|
+
defaultPresetId: "incident-response",
|
|
14165
|
+
sourceCategory: "incidents",
|
|
14166
|
+
title: "How can we help handle alerts?",
|
|
14167
|
+
subtitle: "Shuffle Incidents MCP",
|
|
14168
|
+
defaultPrompt: "Investigate this alert and recommend next steps: ",
|
|
14169
|
+
placeholder: "Triage incoming security alerts, filter noise, or escalate to incident...",
|
|
14170
|
+
getStorageKey: () => "alerts_list",
|
|
14171
|
+
description: "Alert and notification triage with Shuffle Incidents MCP"
|
|
14172
|
+
},
|
|
14173
|
+
// ==========================================
|
|
14174
|
+
// 2. Vulnerabilities (shuffle_vulnerabilities, shuffle_assets, shuffle_software, shuffle_packages)
|
|
14175
|
+
// ==========================================
|
|
14176
|
+
// Specific Vulnerability Detail
|
|
14177
|
+
{
|
|
14178
|
+
id: "vulnerability-detail",
|
|
14179
|
+
match: "/vulnerabilities/:id",
|
|
14180
|
+
defaultApps: [
|
|
14181
|
+
{ name: "shuffle_vulnerabilities" },
|
|
14182
|
+
{ name: "shuffle_assets" },
|
|
14183
|
+
{ name: "shuffle_software" },
|
|
14184
|
+
{ name: "shuffle_packages" }
|
|
14185
|
+
],
|
|
14186
|
+
defaultPresetId: "vulnerability",
|
|
14187
|
+
sourceCategory: "vulnerabilities",
|
|
14188
|
+
title: (params) => {
|
|
14189
|
+
const entity = getActivePageEntityName();
|
|
14190
|
+
return entity ? `How can we help with ${entity}?` : `How can we help with vulnerability ${params.id}?`;
|
|
14191
|
+
},
|
|
14192
|
+
subtitle: () => "Shuffle Vulnerabilities, Assets, Software & Packages",
|
|
14193
|
+
defaultPrompt: (params) => `Review vulnerability ${params.id} and draft remediation plan: `,
|
|
14194
|
+
placeholder: "Analyze this CVE, check affected hosts, and draft remediation...",
|
|
14195
|
+
getStorageKey: (params) => `vulnerability_${params.id}`,
|
|
14196
|
+
description: "Focused on the selected vulnerability with Shuffle Vulnerabilities, Assets, Software & Packages"
|
|
14197
|
+
},
|
|
14198
|
+
// Vulnerabilities List & Subpages
|
|
14199
|
+
{
|
|
14200
|
+
id: "vulnerabilities-list",
|
|
14201
|
+
match: (pathname) => pathname.startsWith("/vulnerabilities"),
|
|
14202
|
+
defaultApps: [
|
|
14203
|
+
{ name: "shuffle_vulnerabilities" },
|
|
14204
|
+
{ name: "shuffle_assets" },
|
|
14205
|
+
{ name: "shuffle_software" },
|
|
14206
|
+
{ name: "shuffle_packages" }
|
|
14207
|
+
],
|
|
14208
|
+
defaultPresetId: "vulnerability",
|
|
14209
|
+
sourceCategory: "vulnerabilities",
|
|
14210
|
+
title: "How can we help review vulnerabilities?",
|
|
14211
|
+
subtitle: () => "Shuffle Vulnerabilities, Assets, Software & Packages",
|
|
14212
|
+
defaultPrompt: "Review my current vulnerabilities and prioritize them by ",
|
|
14213
|
+
placeholder: "Review CVEs, prioritize by exploitability, or draft patch workflows...",
|
|
14214
|
+
getStorageKey: () => "vulnerabilities_list",
|
|
14215
|
+
description: "Vulnerabilities overview with Shuffle Vulnerabilities, Assets, Software & Packages"
|
|
14216
|
+
},
|
|
14217
|
+
// ==========================================
|
|
14218
|
+
// 3. Monitors & Computer Use (shuffle_host_monitors for all)
|
|
14219
|
+
// ==========================================
|
|
14220
|
+
// Specific Host Terminal (/monitors/:id/terminal)
|
|
14221
|
+
{
|
|
14222
|
+
id: "monitor-terminal-detail",
|
|
14223
|
+
match: "/monitors/:id/terminal",
|
|
14224
|
+
defaultApps: [{ name: "shuffle_host_monitors" }],
|
|
14225
|
+
defaultPresetId: "host-monitor-control",
|
|
14226
|
+
title: (params) => {
|
|
14227
|
+
const entity = getActivePageEntityName();
|
|
14228
|
+
return entity ? `How can we help in terminal for "${entity}"?` : `How can we help in terminal on host #${params.id}?`;
|
|
14229
|
+
},
|
|
14230
|
+
subtitle: () => "Shuffle Host Monitors MCP",
|
|
14231
|
+
defaultPrompt: (params) => `Run commands on host ${params.id} to `,
|
|
14232
|
+
placeholder: "Ask the agent to execute shell commands, inspect logs, or debug...",
|
|
14233
|
+
getStorageKey: (params) => `monitor_terminal_${params.id}`,
|
|
14234
|
+
description: "Interactive terminal control with Shuffle Host Monitors MCP"
|
|
14235
|
+
},
|
|
14236
|
+
// General Host Terminal (/monitors/terminal)
|
|
14237
|
+
{
|
|
14238
|
+
id: "monitor-terminal",
|
|
14239
|
+
match: "/monitors/terminal",
|
|
14240
|
+
defaultApps: [{ name: "shuffle_host_monitors" }],
|
|
14241
|
+
defaultPresetId: "host-monitor-control",
|
|
14242
|
+
title: "How can we help in the host terminal?",
|
|
14243
|
+
subtitle: "Shuffle Host Monitors MCP",
|
|
14244
|
+
defaultPrompt: "Run terminal commands on this host to ",
|
|
14245
|
+
placeholder: "Ask the agent to execute shell commands, inspect files, or debug...",
|
|
14246
|
+
getStorageKey: () => "monitors_terminal",
|
|
14247
|
+
description: "Interactive terminal control with Shuffle Host Monitors MCP"
|
|
14248
|
+
},
|
|
14249
|
+
// Host Response Actions (/monitors/response)
|
|
14250
|
+
{
|
|
14251
|
+
id: "monitor-response",
|
|
14252
|
+
match: "/monitors/response",
|
|
14253
|
+
defaultApps: [{ name: "shuffle_host_monitors" }],
|
|
14254
|
+
defaultPresetId: "host-monitor-control",
|
|
14255
|
+
title: "How can we help with host response?",
|
|
14256
|
+
subtitle: "Shuffle Host Monitors MCP",
|
|
14257
|
+
defaultPrompt: "Take response actions on this host to ",
|
|
14258
|
+
placeholder: "Isolate host, terminate suspicious processes, or run remediation...",
|
|
14259
|
+
getStorageKey: () => "monitors_response",
|
|
14260
|
+
description: "Host response actions with Shuffle Host Monitors MCP"
|
|
14261
|
+
},
|
|
14262
|
+
// Specific Host Overview (/monitors/:id)
|
|
14263
|
+
{
|
|
14264
|
+
id: "monitor-detail",
|
|
14265
|
+
match: "/monitors/:id",
|
|
14266
|
+
defaultApps: [{ name: "shuffle_host_monitors" }],
|
|
14267
|
+
defaultPresetId: "host-monitor-control",
|
|
14268
|
+
title: (params) => {
|
|
14269
|
+
const entity = getActivePageEntityName();
|
|
14270
|
+
return entity ? `How can we help with host "${entity}"?` : `How can we help with host #${params.id}?`;
|
|
14271
|
+
},
|
|
14272
|
+
subtitle: () => "Shuffle Host Monitors MCP",
|
|
14273
|
+
defaultPrompt: (params) => `Take control of host ${params.id} and help me with: `,
|
|
14274
|
+
placeholder: "Inspect host telemetry, running processes, network connections, or remediate...",
|
|
14275
|
+
getStorageKey: (params) => `monitor_${params.id}`,
|
|
14276
|
+
description: "Host detail view with Shuffle Host Monitors MCP"
|
|
14277
|
+
},
|
|
14278
|
+
// Monitors Fleet Overview & Subpages (/monitors, /monitors/*)
|
|
14279
|
+
{
|
|
14280
|
+
id: "host-monitors-group",
|
|
14281
|
+
match: (pathname) => pathname.startsWith("/monitors"),
|
|
14282
|
+
defaultApps: [{ name: "shuffle_host_monitors" }],
|
|
14283
|
+
defaultPresetId: "host-monitor-control",
|
|
14284
|
+
title: "How can we help with host monitors?",
|
|
14285
|
+
subtitle: "Shuffle Host Monitors MCP",
|
|
14286
|
+
defaultPrompt: "Take control of this host and help me with: ",
|
|
14287
|
+
placeholder: "Ask the agent to run terminal commands, inspect files, or remediate...",
|
|
14288
|
+
getStorageKey: () => "host_monitors",
|
|
14289
|
+
description: "Computer use and host monitors control with Shuffle Host Monitors MCP"
|
|
14290
|
+
},
|
|
14291
|
+
// ==========================================
|
|
14292
|
+
// 4. Workflows & Automations
|
|
14293
|
+
// ==========================================
|
|
14294
|
+
// Specific Workflow Detail (/workflows/:id)
|
|
14295
|
+
{
|
|
14296
|
+
id: "workflow-detail",
|
|
14297
|
+
match: "/workflows/:id",
|
|
14298
|
+
defaultApps: [{ name: "shuffle_workflows_builder" }, { name: "shuffle_apps" }],
|
|
14299
|
+
defaultPresetId: "build-workflows",
|
|
14300
|
+
title: (params) => {
|
|
14301
|
+
const entity = getActivePageEntityName();
|
|
14302
|
+
return entity ? `How can we help edit "${entity}"?` : `How can we help edit workflow #${params.id}?`;
|
|
14303
|
+
},
|
|
14304
|
+
subtitle: () => "Shuffle Workflows Builder & Shuffle Apps",
|
|
14305
|
+
defaultPrompt: (params) => `Edit workflow ${params.id} to `,
|
|
14306
|
+
placeholder: "Describe the changes, new actions, or logic to add...",
|
|
14307
|
+
getStorageKey: (params) => `workflow_${params.id}`,
|
|
14308
|
+
description: "Focused on editing the selected workflow with Shuffle Workflows Builder and Shuffle Apps"
|
|
14309
|
+
},
|
|
14310
|
+
// Workflows Overview & Subpages (/workflows, /workflows/*)
|
|
14311
|
+
{
|
|
14312
|
+
id: "workflows-group",
|
|
14313
|
+
match: (pathname) => pathname === "/workflows" || pathname.startsWith("/workflows") || pathname.startsWith("/infrastructure/flows"),
|
|
14314
|
+
defaultApps: [{ name: "shuffle_workflows_builder" }, { name: "shuffle_apps" }],
|
|
14315
|
+
defaultPresetId: "build-workflows",
|
|
14316
|
+
title: "How can we help edit workflows?",
|
|
14317
|
+
subtitle: "Shuffle Workflows Builder & Shuffle Apps",
|
|
14318
|
+
defaultPrompt: "Edit this Shuffle workflow to ",
|
|
14319
|
+
placeholder: "Describe the workflow you want to build or edit...",
|
|
14320
|
+
getStorageKey: () => "workflows_builder",
|
|
14321
|
+
description: "Workflow builder with Shuffle Workflows Builder and Shuffle Apps"
|
|
14322
|
+
},
|
|
14323
|
+
// ==========================================
|
|
14324
|
+
// 5. Assets, Software & Packages
|
|
14325
|
+
// ==========================================
|
|
14326
|
+
// Specific Asset Tab (/assets/:tab)
|
|
14327
|
+
{
|
|
14328
|
+
id: "assets-tab",
|
|
14329
|
+
match: "/assets/:tab",
|
|
14330
|
+
defaultApps: [{ name: "shuffle_assets" }, { name: "shuffle_vulnerabilities" }],
|
|
14331
|
+
defaultPresetId: "vulnerability",
|
|
14332
|
+
sourceCategory: "vulnerabilities",
|
|
14333
|
+
title: (params) => {
|
|
14334
|
+
const entity = getActivePageEntityName();
|
|
14335
|
+
if (entity) return `How can we help with "${entity}"?`;
|
|
14336
|
+
const tabName = (params.tab || "assets").replace(/[-_]+/g, " ");
|
|
14337
|
+
return `How can we help with ${tabName}?`;
|
|
14338
|
+
},
|
|
14339
|
+
subtitle: () => "Shuffle Assets & Shuffle Vulnerabilities",
|
|
14340
|
+
defaultPrompt: (params) => `Inspect ${params.tab || "assets"} and review vulnerabilities: `,
|
|
14341
|
+
placeholder: "Search assets, inspect hosts, or check security posture...",
|
|
14342
|
+
getStorageKey: (params) => `assets_tab_${params.tab}`,
|
|
14343
|
+
description: "Assets tab view with Shuffle Assets and Shuffle Vulnerabilities MCPs"
|
|
14344
|
+
},
|
|
14345
|
+
// Assets Overview (/assets, /assets/*)
|
|
14346
|
+
{
|
|
14347
|
+
id: "assets-overview",
|
|
14348
|
+
match: (pathname) => pathname === "/assets" || pathname.startsWith("/assets"),
|
|
14349
|
+
defaultApps: [{ name: "shuffle_assets" }, { name: "shuffle_vulnerabilities" }],
|
|
14350
|
+
defaultPresetId: "vulnerability",
|
|
14351
|
+
sourceCategory: "vulnerabilities",
|
|
14352
|
+
title: "How can we help with assets?",
|
|
14353
|
+
subtitle: "Shuffle Assets & Shuffle Vulnerabilities",
|
|
14354
|
+
defaultPrompt: "Audit assets and review vulnerabilities for ",
|
|
14355
|
+
placeholder: "Search assets, inspect hosts, or check security posture...",
|
|
14356
|
+
getStorageKey: () => "assets_overview",
|
|
14357
|
+
description: "Assets overview with Shuffle Assets and Shuffle Vulnerabilities MCPs"
|
|
14358
|
+
},
|
|
14359
|
+
// Software Inventory (/software, /software/*)
|
|
14360
|
+
{
|
|
14361
|
+
id: "software-inventory",
|
|
14362
|
+
match: (pathname) => pathname === "/software" || pathname.startsWith("/software"),
|
|
14363
|
+
defaultApps: [{ name: "shuffle_software" }, { name: "shuffle_vulnerabilities" }],
|
|
14364
|
+
defaultPresetId: "vulnerability",
|
|
14365
|
+
sourceCategory: "vulnerabilities",
|
|
14366
|
+
title: (params) => {
|
|
14367
|
+
const entity = getActivePageEntityName();
|
|
14368
|
+
return entity ? `How can we help with "${entity}"?` : "How can we help with software inventory?";
|
|
14369
|
+
},
|
|
14370
|
+
subtitle: () => "Shuffle Software & Shuffle Vulnerabilities",
|
|
14371
|
+
defaultPrompt: "Inspect software inventory and check for vulnerabilities in ",
|
|
14372
|
+
placeholder: "Search installed software, verify versions, or scan for CVEs...",
|
|
14373
|
+
getStorageKey: () => "software_inventory",
|
|
14374
|
+
description: "Software inventory with Shuffle Software and Shuffle Vulnerabilities MCPs"
|
|
14375
|
+
},
|
|
14376
|
+
// Packages Inventory (/packages, /packages/*)
|
|
14377
|
+
{
|
|
14378
|
+
id: "packages-inventory",
|
|
14379
|
+
match: (pathname) => pathname === "/packages" || pathname.startsWith("/packages"),
|
|
14380
|
+
defaultApps: [{ name: "shuffle_packages" }, { name: "shuffle_vulnerabilities" }],
|
|
14381
|
+
defaultPresetId: "vulnerability",
|
|
14382
|
+
sourceCategory: "vulnerabilities",
|
|
14383
|
+
title: (params) => {
|
|
14384
|
+
const entity = getActivePageEntityName();
|
|
14385
|
+
return entity ? `How can we help with "${entity}"?` : "How can we help with packages?";
|
|
14386
|
+
},
|
|
14387
|
+
subtitle: () => "Shuffle Packages & Shuffle Vulnerabilities",
|
|
14388
|
+
defaultPrompt: "Analyze package dependencies and known vulnerabilities for ",
|
|
14389
|
+
placeholder: "Search package dependencies, verify licenses, or check CVEs...",
|
|
14390
|
+
getStorageKey: () => "packages_inventory",
|
|
14391
|
+
description: "Package dependencies with Shuffle Packages and Shuffle Vulnerabilities MCPs"
|
|
14392
|
+
},
|
|
14393
|
+
// ==========================================
|
|
14394
|
+
// 6. Detection & Sigma
|
|
14395
|
+
// ==========================================
|
|
14396
|
+
{
|
|
14397
|
+
id: "detection",
|
|
14398
|
+
match: (pathname) => pathname.startsWith("/detection"),
|
|
14399
|
+
defaultApps: [{ name: "shuffle_detection" }],
|
|
14400
|
+
defaultPresetId: "detection",
|
|
14401
|
+
title: "How can we help tune detections?",
|
|
14402
|
+
subtitle: "Shuffle Detection MCP",
|
|
14403
|
+
defaultPrompt: "Modify my detections to ",
|
|
14404
|
+
placeholder: "Create Sigma rules, tune detection pipelines, or filter false positives...",
|
|
14405
|
+
getStorageKey: () => "detection",
|
|
14406
|
+
description: "Detection engineering with Shuffle Detection MCP"
|
|
14407
|
+
},
|
|
14408
|
+
// ==========================================
|
|
14409
|
+
// 7. Documentation (/docs, /docs/*)
|
|
14410
|
+
// ==========================================
|
|
14411
|
+
{
|
|
14412
|
+
id: "docs",
|
|
14413
|
+
match: (pathname) => pathname === "/docs" || pathname.startsWith("/docs/"),
|
|
14414
|
+
defaultApps: [{ name: "shuffle_tools" }],
|
|
14415
|
+
defaultPresetId: "support",
|
|
14416
|
+
title: "How can we help with documentation?",
|
|
14417
|
+
subtitle: "Documentation & Knowledge Assistant",
|
|
14418
|
+
defaultPrompt: "Help me understand or find information about ",
|
|
14419
|
+
placeholder: "Ask questions about Shuffle features, guides, or API...",
|
|
14420
|
+
getStorageKey: (params, pathname) => `docs_${pathname.replace(/[^a-zA-Z0-9_-]/g, "_")}`,
|
|
14421
|
+
description: "Documentation assistant for Shuffle guides, features, and API references",
|
|
14422
|
+
sideshift: true
|
|
14423
|
+
},
|
|
14424
|
+
// ==========================================
|
|
14425
|
+
// 8. Default Fallback (Support)
|
|
14426
|
+
// ==========================================
|
|
14427
|
+
{
|
|
14428
|
+
id: "default",
|
|
14429
|
+
match: () => true,
|
|
14430
|
+
defaultApps: [{ name: "shuffle_tools" }],
|
|
14431
|
+
defaultPresetId: "support",
|
|
14432
|
+
title: "How can we help on this page?",
|
|
14433
|
+
subtitle: "General Platform Assistant",
|
|
14434
|
+
defaultPrompt: "Help me with the following on this page: ",
|
|
14435
|
+
placeholder: "Ask anything about Shuffle, integrations, or workflows...",
|
|
14436
|
+
getStorageKey: (params, pathname) => `page_${pathname.replace(/[^a-zA-Z0-9_-]/g, "_")}`,
|
|
14437
|
+
description: "General support agent for the platform",
|
|
14438
|
+
missingConfig: true
|
|
14439
|
+
}
|
|
14440
|
+
];
|
|
14441
|
+
var customRuleRegistry = [];
|
|
14442
|
+
var registerAgentContextRule = (rule, prepend = true) => {
|
|
14443
|
+
if (prepend) {
|
|
14444
|
+
customRuleRegistry.unshift(rule);
|
|
14445
|
+
} else {
|
|
14446
|
+
customRuleRegistry.push(rule);
|
|
14447
|
+
}
|
|
14448
|
+
return () => {
|
|
14449
|
+
const idx = customRuleRegistry.indexOf(rule);
|
|
14450
|
+
if (idx !== -1) customRuleRegistry.splice(idx, 1);
|
|
14451
|
+
};
|
|
14452
|
+
};
|
|
14453
|
+
var getAgentContextRules = (customRules) => {
|
|
14454
|
+
return [...customRules ?? [], ...customRuleRegistry, ...DEFAULT_AGENT_CONTEXT_RULES];
|
|
14455
|
+
};
|
|
14456
|
+
var getPageContextChoice = (storageKey) => {
|
|
14457
|
+
try {
|
|
14458
|
+
const raw = localStorage.getItem(`${STORAGE_PREFIX}${storageKey}`);
|
|
14459
|
+
if (!raw) return null;
|
|
14460
|
+
return JSON.parse(raw);
|
|
14461
|
+
} catch {
|
|
14462
|
+
return null;
|
|
14463
|
+
}
|
|
14464
|
+
};
|
|
14465
|
+
var setPageContextChoice = (storageKey, choice) => {
|
|
14466
|
+
try {
|
|
14467
|
+
const existing = getPageContextChoice(storageKey) || { updatedAt: Date.now() };
|
|
14468
|
+
const payload = {
|
|
14469
|
+
...existing,
|
|
14470
|
+
...choice,
|
|
14471
|
+
updatedAt: Date.now()
|
|
14472
|
+
};
|
|
14473
|
+
localStorage.setItem(`${STORAGE_PREFIX}${storageKey}`, JSON.stringify(payload));
|
|
14474
|
+
} catch {
|
|
14475
|
+
}
|
|
14476
|
+
};
|
|
14477
|
+
var clearPageContextChoice = (storageKey) => {
|
|
14478
|
+
try {
|
|
14479
|
+
localStorage.removeItem(`${STORAGE_PREFIX}${storageKey}`);
|
|
14480
|
+
} catch {
|
|
14481
|
+
}
|
|
14482
|
+
};
|
|
14483
|
+
var resolveAgentContext = (pathname, search = "", customRules) => {
|
|
14484
|
+
const normPath = pathname.replace(/\/+$/, "") || "/";
|
|
14485
|
+
const searchParams = new URLSearchParams(search.startsWith("?") ? search.slice(1) : search);
|
|
14486
|
+
const rules = getAgentContextRules(customRules);
|
|
14487
|
+
let matchedRule = null;
|
|
14488
|
+
let matchedParams = {};
|
|
14489
|
+
for (const rule of rules) {
|
|
14490
|
+
if (typeof rule.match === "string") {
|
|
14491
|
+
const params = matchRoutePattern(rule.match, normPath);
|
|
14492
|
+
if (params !== null) {
|
|
14493
|
+
matchedRule = rule;
|
|
14494
|
+
matchedParams = params;
|
|
14495
|
+
break;
|
|
14496
|
+
}
|
|
14497
|
+
} else if (rule.match instanceof RegExp) {
|
|
14498
|
+
if (rule.match.test(normPath)) {
|
|
14499
|
+
matchedRule = rule;
|
|
14500
|
+
break;
|
|
14501
|
+
}
|
|
14502
|
+
} else if (typeof rule.match === "function") {
|
|
14503
|
+
const res = rule.match(normPath, searchParams);
|
|
14504
|
+
if (res) {
|
|
14505
|
+
matchedRule = rule;
|
|
14506
|
+
if (typeof res === "object") {
|
|
14507
|
+
matchedParams = res;
|
|
14508
|
+
}
|
|
14509
|
+
break;
|
|
14510
|
+
}
|
|
14511
|
+
}
|
|
14512
|
+
}
|
|
14513
|
+
if (!matchedRule) {
|
|
14514
|
+
matchedRule = DEFAULT_AGENT_CONTEXT_RULES[DEFAULT_AGENT_CONTEXT_RULES.length - 1];
|
|
14515
|
+
}
|
|
14516
|
+
const storageKey = matchedRule.getStorageKey ? matchedRule.getStorageKey(matchedParams, normPath) : matchedRule.id;
|
|
14517
|
+
const savedChoice = getPageContextChoice(storageKey);
|
|
14518
|
+
const isOverridden = !!savedChoice && (savedChoice.apps !== void 0 || savedChoice.presetId !== void 0);
|
|
14519
|
+
const cachedConnected = matchedRule.sourceCategory ? getCachedConnectedTools(matchedRule.sourceCategory) : [];
|
|
14520
|
+
const baseDefaultApps = mergeConnectedTools(matchedRule.defaultApps, cachedConnected);
|
|
14521
|
+
const effectiveApps = savedChoice?.apps ?? baseDefaultApps;
|
|
14522
|
+
const effectivePresetId = savedChoice?.presetId !== void 0 ? savedChoice.presetId ?? void 0 : matchedRule.defaultPresetId;
|
|
14523
|
+
const title = typeof matchedRule.title === "function" ? matchedRule.title(matchedParams, normPath) : matchedRule.title ?? "Agent";
|
|
14524
|
+
const subtitle = typeof matchedRule.subtitle === "function" ? matchedRule.subtitle(matchedParams, normPath) : matchedRule.subtitle ?? "Context aware assistant";
|
|
14525
|
+
const defaultPrompt = typeof matchedRule.defaultPrompt === "function" ? matchedRule.defaultPrompt(matchedParams, normPath) : matchedRule.defaultPrompt ?? "";
|
|
14526
|
+
const missingConfig = Boolean(matchedRule.missingConfig ?? matchedRule.id === "default");
|
|
14527
|
+
return {
|
|
14528
|
+
ruleId: matchedRule.id,
|
|
14529
|
+
apps: effectiveApps,
|
|
14530
|
+
presetId: effectivePresetId,
|
|
14531
|
+
title,
|
|
14532
|
+
subtitle,
|
|
14533
|
+
defaultPrompt,
|
|
14534
|
+
placeholder: matchedRule.placeholder,
|
|
14535
|
+
storageKey,
|
|
14536
|
+
params: matchedParams,
|
|
14537
|
+
pathname: normPath,
|
|
14538
|
+
sourceCategory: matchedRule.sourceCategory,
|
|
14539
|
+
isOverridden,
|
|
14540
|
+
originalDefaultApps: baseDefaultApps,
|
|
14541
|
+
originalDefaultPresetId: matchedRule.defaultPresetId,
|
|
14542
|
+
missingConfig,
|
|
14543
|
+
sideshift: matchedRule.sideshift
|
|
14544
|
+
};
|
|
14545
|
+
};
|
|
14546
|
+
|
|
13318
14547
|
// components/AgentUI.tsx
|
|
13319
14548
|
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
13320
14549
|
var normalizeMarkdown = (raw) => {
|
|
@@ -13339,14 +14568,27 @@ var LAST_PRESET_STORAGE_KEY = "agent_last_preset_id";
|
|
|
13339
14568
|
var PRESET_APPS_STORAGE_KEY = "agent_preset_apps_overrides";
|
|
13340
14569
|
var NO_PRESET_KEY = "__none__";
|
|
13341
14570
|
var PRESET_TEMPLATE_SLUGS = {
|
|
13342
|
-
"build-workflows": "workflow
|
|
14571
|
+
"build-workflows": "edit-workflow",
|
|
13343
14572
|
"handle-notifications": "handle-notifications",
|
|
13344
|
-
"incident-response": "incident-
|
|
14573
|
+
"incident-response": "incident-handler",
|
|
13345
14574
|
"host-monitor-control": "computer-use",
|
|
13346
14575
|
support: "support",
|
|
13347
14576
|
vulnerability: "vulnerability",
|
|
13348
14577
|
detection: "detection"
|
|
13349
14578
|
};
|
|
14579
|
+
var TEMPLATE_SLUG_TO_PRESET_ID = {
|
|
14580
|
+
"workflow-edit": "build-workflows",
|
|
14581
|
+
"edit-workflow": "build-workflows",
|
|
14582
|
+
"build-workflows": "build-workflows",
|
|
14583
|
+
"incident-response": "incident-response",
|
|
14584
|
+
"incident-handler": "incident-response",
|
|
14585
|
+
"vulnerability": "vulnerability",
|
|
14586
|
+
"vulnerability-management": "vulnerability",
|
|
14587
|
+
"computer-use": "host-monitor-control",
|
|
14588
|
+
support: "support",
|
|
14589
|
+
"handle-notifications": "handle-notifications",
|
|
14590
|
+
detection: "detection"
|
|
14591
|
+
};
|
|
13350
14592
|
var readPresetAppsOverride = (presetId) => {
|
|
13351
14593
|
try {
|
|
13352
14594
|
const raw = localStorage.getItem(PRESET_APPS_STORAGE_KEY);
|
|
@@ -14478,6 +15720,7 @@ var AgentUI = ({
|
|
|
14478
15720
|
heroIconSize = 84,
|
|
14479
15721
|
maxWidth = 850,
|
|
14480
15722
|
compact = false,
|
|
15723
|
+
mobileView,
|
|
14481
15724
|
hideAppPicker = false,
|
|
14482
15725
|
hideAttach = false,
|
|
14483
15726
|
disableStartTab = false,
|
|
@@ -14512,10 +15755,14 @@ var AgentUI = ({
|
|
|
14512
15755
|
userId,
|
|
14513
15756
|
hidePresets = false,
|
|
14514
15757
|
presets,
|
|
15758
|
+
initialPresetId,
|
|
14515
15759
|
onSelectPreset,
|
|
15760
|
+
contextCategory,
|
|
15761
|
+
contextStorageKey,
|
|
14516
15762
|
isSupport,
|
|
14517
15763
|
presetCtas
|
|
14518
15764
|
}) => {
|
|
15765
|
+
const isEffectiveSupport = isSupport !== void 0 ? isSupport : isSupportUser();
|
|
14519
15766
|
const resolveUrl2 = (0, import_react22.useCallback)(
|
|
14520
15767
|
(path) => apiBaseUrl ? `${apiBaseUrl.replace(/\/+$/, "")}${path}` : getApiUrl(path),
|
|
14521
15768
|
[apiBaseUrl]
|
|
@@ -14526,7 +15773,8 @@ var AgentUI = ({
|
|
|
14526
15773
|
return h;
|
|
14527
15774
|
}, [apiKey, orgId]);
|
|
14528
15775
|
const hasApiKey = !!apiKey || !!API_CONFIG.apiKey;
|
|
14529
|
-
const
|
|
15776
|
+
const isPhoneScreen = (0, import_material23.useMediaQuery)("(max-width:600px)", { noSsr: true });
|
|
15777
|
+
const isPhone = mobileView !== void 0 ? mobileView : isPhoneScreen;
|
|
14530
15778
|
const navigate = (0, import_router_compat2.useNavigate)();
|
|
14531
15779
|
const [actionInput, setActionInput] = (0, import_react22.useState)(defaultInput);
|
|
14532
15780
|
const { prompt: savedPromptPrefix } = useAgentPromptPrefix({ userId, persist: !disableStartTab });
|
|
@@ -14562,27 +15810,32 @@ var AgentUI = ({
|
|
|
14562
15810
|
const inputRef = (0, import_react22.useRef)(null);
|
|
14563
15811
|
const seededPresetIdRef = (0, import_react22.useRef)(null);
|
|
14564
15812
|
(0, import_react22.useEffect)(() => {
|
|
14565
|
-
if (defaultInput && defaultInput.trim().length > 0) {
|
|
15813
|
+
if (!initialPresetId && defaultInput && defaultInput.trim().length > 0) {
|
|
14566
15814
|
setSelectedPreset(null);
|
|
14567
15815
|
return;
|
|
14568
15816
|
}
|
|
14569
15817
|
try {
|
|
14570
|
-
const lastId = localStorage.getItem(LAST_PRESET_STORAGE_KEY);
|
|
14571
|
-
if (!lastId)
|
|
14572
|
-
|
|
15818
|
+
const lastId = initialPresetId !== void 0 ? initialPresetId : localStorage.getItem(LAST_PRESET_STORAGE_KEY);
|
|
15819
|
+
if (!lastId) {
|
|
15820
|
+
if (initialPresetId === null) setSelectedPreset(null);
|
|
15821
|
+
return;
|
|
15822
|
+
}
|
|
15823
|
+
const list = filterAgentPresets(presets && presets.length > 0 ? presets : AGENT_PRESETS, isEffectiveSupport);
|
|
14573
15824
|
const match = list.find((p) => p.id === lastId);
|
|
14574
15825
|
if (!match || match.enabled === false) return;
|
|
14575
15826
|
setSelectedPreset(match);
|
|
14576
|
-
|
|
14577
|
-
|
|
14578
|
-
|
|
14579
|
-
|
|
14580
|
-
|
|
15827
|
+
if (!defaultApps && !apps) {
|
|
15828
|
+
const override = readPresetAppsOverride(match.id);
|
|
15829
|
+
if (override) {
|
|
15830
|
+
setChosenApps(override);
|
|
15831
|
+
} else if (match.defaultApps && match.defaultApps.length > 0) {
|
|
15832
|
+
setChosenApps(match.defaultApps.map((app2) => ({ name: app2.name, id: app2.id, icon: app2.icon })));
|
|
15833
|
+
}
|
|
14581
15834
|
}
|
|
14582
15835
|
seededPresetIdRef.current = match.id;
|
|
14583
15836
|
} catch {
|
|
14584
15837
|
}
|
|
14585
|
-
}, [presets, defaultInput,
|
|
15838
|
+
}, [presets, defaultInput, isEffectiveSupport, initialPresetId, defaultApps, apps]);
|
|
14586
15839
|
(0, import_react22.useLayoutEffect)(() => {
|
|
14587
15840
|
if (hidePresets) {
|
|
14588
15841
|
setPresetsChipWidth(0);
|
|
@@ -14807,21 +16060,55 @@ var AgentUI = ({
|
|
|
14807
16060
|
[agentData]
|
|
14808
16061
|
);
|
|
14809
16062
|
const [showStarter, setShowStarter] = (0, import_react22.useState)(true);
|
|
14810
|
-
const
|
|
14811
|
-
|
|
14812
|
-
|
|
14813
|
-
|
|
14814
|
-
|
|
14815
|
-
|
|
14816
|
-
|
|
14817
|
-
|
|
14818
|
-
|
|
14819
|
-
|
|
14820
|
-
|
|
14821
|
-
|
|
14822
|
-
|
|
14823
|
-
|
|
14824
|
-
|
|
16063
|
+
const handleRemovePreset = (0, import_react22.useCallback)(() => {
|
|
16064
|
+
try {
|
|
16065
|
+
localStorage.removeItem(LAST_PRESET_STORAGE_KEY);
|
|
16066
|
+
} catch {
|
|
16067
|
+
}
|
|
16068
|
+
setSelectedPreset(null);
|
|
16069
|
+
}, []);
|
|
16070
|
+
const handleSelectPresetInternal = (0, import_react22.useCallback)((preset) => {
|
|
16071
|
+
try {
|
|
16072
|
+
localStorage.setItem(LAST_PRESET_STORAGE_KEY, preset.id);
|
|
16073
|
+
} catch {
|
|
16074
|
+
}
|
|
16075
|
+
const override = readPresetAppsOverride(preset.id);
|
|
16076
|
+
if (override && override.length > 0) {
|
|
16077
|
+
setChosenApps(override);
|
|
16078
|
+
} else if (preset.defaultApps && preset.defaultApps.length > 0) {
|
|
16079
|
+
setChosenApps(preset.defaultApps.map((app2) => ({ name: app2.name, id: app2.id, icon: app2.icon })));
|
|
16080
|
+
} else {
|
|
16081
|
+
setChosenApps([]);
|
|
16082
|
+
}
|
|
16083
|
+
seededPresetIdRef.current = preset.id;
|
|
16084
|
+
if (onSelectPreset) {
|
|
16085
|
+
onSelectPreset(preset);
|
|
16086
|
+
return;
|
|
16087
|
+
}
|
|
16088
|
+
setSelectedPreset(preset);
|
|
16089
|
+
setTimeout(() => {
|
|
16090
|
+
const el = inputRef.current;
|
|
16091
|
+
try {
|
|
16092
|
+
el?.focus();
|
|
16093
|
+
} catch {
|
|
16094
|
+
}
|
|
16095
|
+
}, 0);
|
|
16096
|
+
}, [onSelectPreset]);
|
|
16097
|
+
const [scheduleAnchor, setScheduleAnchor] = (0, import_react22.useState)(null);
|
|
16098
|
+
const [mobilePlusAnchor, setMobilePlusAnchor] = (0, import_react22.useState)(null);
|
|
16099
|
+
const [scheduleCron, setScheduleCron] = (0, import_react22.useState)("0 * * * *");
|
|
16100
|
+
const [scheduleSaving, setScheduleSaving] = (0, import_react22.useState)(false);
|
|
16101
|
+
const [scheduleSteps, setScheduleSteps] = (0, import_react22.useState)([
|
|
16102
|
+
{ id: "name", state: "pending" },
|
|
16103
|
+
{ id: "workflow", state: "pending" },
|
|
16104
|
+
{ id: "schedule", state: "pending" }
|
|
16105
|
+
]);
|
|
16106
|
+
const [schedFreq, setSchedFreq] = (0, import_react22.useState)("hours");
|
|
16107
|
+
const [schedInterval, setSchedInterval] = (0, import_react22.useState)(1);
|
|
16108
|
+
const [schedHour, setSchedHour] = (0, import_react22.useState)(9);
|
|
16109
|
+
const [schedMinute, setSchedMinute] = (0, import_react22.useState)(0);
|
|
16110
|
+
const [schedWeekdays, setSchedWeekdays] = (0, import_react22.useState)(() => /* @__PURE__ */ new Set([1]));
|
|
16111
|
+
const [schedDayOfMonth, setSchedDayOfMonth] = (0, import_react22.useState)(1);
|
|
14825
16112
|
const [schedAdvancedOpen, setSchedAdvancedOpen] = (0, import_react22.useState)(false);
|
|
14826
16113
|
const cronManualOverrideRef = (0, import_react22.useRef)(false);
|
|
14827
16114
|
const [openIndexes, setOpenIndexes] = (0, import_react22.useState)(/* @__PURE__ */ new Set());
|
|
@@ -14864,7 +16151,7 @@ var AgentUI = ({
|
|
|
14864
16151
|
}, [viewMode]);
|
|
14865
16152
|
const [attachedImages, setAttachedImages] = (0, import_react22.useState)([]);
|
|
14866
16153
|
const [previewImage, setPreviewImage] = (0, import_react22.useState)(null);
|
|
14867
|
-
const promptMultiline = promptMultilineBase || attachedImages.length > 0;
|
|
16154
|
+
const promptMultiline = promptMultilineBase || attachedImages.length > 0 || isPhone && Boolean(selectedPreset);
|
|
14868
16155
|
const promptSingleLineLocked = !promptMultiline;
|
|
14869
16156
|
const [nowTick, setNowTick] = (0, import_react22.useState)(() => Math.floor(Date.now() / 1e3));
|
|
14870
16157
|
const [localRunStart, setLocalRunStart] = (0, import_react22.useState)(null);
|
|
@@ -15118,11 +16405,18 @@ var AgentUI = ({
|
|
|
15118
16405
|
const loadAuthenticatedApps = (0, import_react22.useCallback)(async (signal) => {
|
|
15119
16406
|
setAuthAppsLoading(true);
|
|
15120
16407
|
try {
|
|
15121
|
-
const
|
|
15122
|
-
|
|
15123
|
-
|
|
15124
|
-
|
|
15125
|
-
|
|
16408
|
+
const [authRes, wfRes] = await Promise.allSettled([
|
|
16409
|
+
fetch(resolveUrl2("/api/v1/apps/authentication"), {
|
|
16410
|
+
credentials: "include",
|
|
16411
|
+
headers: { ...resolveHeaders2() }
|
|
16412
|
+
}),
|
|
16413
|
+
fetch(resolveUrl2("/api/v1/workflows"), {
|
|
16414
|
+
credentials: "include",
|
|
16415
|
+
headers: { ...resolveHeaders2() }
|
|
16416
|
+
})
|
|
16417
|
+
]);
|
|
16418
|
+
const resp = authRes.status === "fulfilled" ? authRes.value : null;
|
|
16419
|
+
if (!resp || !resp.ok) {
|
|
15126
16420
|
if (!signal?.cancelled) setAvailableApps([]);
|
|
15127
16421
|
return;
|
|
15128
16422
|
}
|
|
@@ -15147,12 +16441,53 @@ var AgentUI = ({
|
|
|
15147
16441
|
}
|
|
15148
16442
|
if (signal?.cancelled) return;
|
|
15149
16443
|
setAvailableApps(loaded);
|
|
16444
|
+
const wfResp = wfRes.status === "fulfilled" ? wfRes.value : null;
|
|
16445
|
+
const wfResult = wfResp && wfResp.ok ? await wfResp.json() : [];
|
|
16446
|
+
const effectiveCategory = contextCategory || ((defaultApps || chosenApps).some((a) => normalizeAgentAppName(a.name || "").includes("incident")) ? "incidents" : (defaultApps || chosenApps).some((a) => normalizeAgentAppName(a.name || "").includes("vulnerabilit")) ? "vulnerabilities" : void 0);
|
|
16447
|
+
let connectedTools = [];
|
|
16448
|
+
if (effectiveCategory) {
|
|
16449
|
+
connectedTools = resolveConnectedTools(effectiveCategory, list, wfResult);
|
|
16450
|
+
if (connectedTools.length > 0) {
|
|
16451
|
+
setCachedConnectedTools(effectiveCategory, connectedTools);
|
|
16452
|
+
}
|
|
16453
|
+
}
|
|
16454
|
+
setChosenApps((prev) => {
|
|
16455
|
+
let changed = false;
|
|
16456
|
+
const savedChoice = contextStorageKey ? getPageContextChoice(contextStorageKey) : null;
|
|
16457
|
+
let baseList = prev;
|
|
16458
|
+
if (!savedChoice?.apps && connectedTools.length > 0) {
|
|
16459
|
+
const merged = mergeConnectedTools(prev, connectedTools);
|
|
16460
|
+
if (merged.length !== prev.length || merged.some((m, idx) => prev[idx]?.name !== m.name)) {
|
|
16461
|
+
baseList = merged;
|
|
16462
|
+
changed = true;
|
|
16463
|
+
}
|
|
16464
|
+
}
|
|
16465
|
+
const updated = baseList.map((app2) => {
|
|
16466
|
+
if (app2.icon && app2.id) return app2;
|
|
16467
|
+
const slug = normalizeAgentAppName(app2.name || "");
|
|
16468
|
+
const match = loaded.find((a) => normalizeAgentAppName(a.name || "") === slug);
|
|
16469
|
+
if (!match) return app2;
|
|
16470
|
+
if (!app2.icon && match.icon || !app2.id && match.id) {
|
|
16471
|
+
changed = true;
|
|
16472
|
+
return {
|
|
16473
|
+
...app2,
|
|
16474
|
+
id: app2.id || match.id,
|
|
16475
|
+
icon: app2.icon || match.icon
|
|
16476
|
+
};
|
|
16477
|
+
}
|
|
16478
|
+
return app2;
|
|
16479
|
+
});
|
|
16480
|
+
if (changed && onAppsChange) {
|
|
16481
|
+
onAppsChange(updated);
|
|
16482
|
+
}
|
|
16483
|
+
return changed ? updated : prev;
|
|
16484
|
+
});
|
|
15150
16485
|
setDetectedLLM(resolveActiveLLMProvider(list));
|
|
15151
16486
|
} catch {
|
|
15152
16487
|
} finally {
|
|
15153
16488
|
if (!signal?.cancelled) setAuthAppsLoading(false);
|
|
15154
16489
|
}
|
|
15155
|
-
}, [resolveUrl2, resolveHeaders2]);
|
|
16490
|
+
}, [resolveUrl2, resolveHeaders2, contextCategory, contextStorageKey, defaultApps, onAppsChange]);
|
|
15156
16491
|
(0, import_react22.useEffect)(() => {
|
|
15157
16492
|
if (!autoLoadApps) return;
|
|
15158
16493
|
if (!hasApiKey) return;
|
|
@@ -15757,7 +17092,9 @@ var AgentUI = ({
|
|
|
15757
17092
|
if (!raw) return null;
|
|
15758
17093
|
const slug = String(raw).trim().toLowerCase();
|
|
15759
17094
|
const list = presets && presets.length > 0 ? presets : AGENT_PRESETS;
|
|
15760
|
-
return list.find(
|
|
17095
|
+
return list.find(
|
|
17096
|
+
(p) => p.id === slug || PRESET_TEMPLATE_SLUGS[p.id] === slug || TEMPLATE_SLUG_TO_PRESET_ID[slug] === p.id
|
|
17097
|
+
) ?? null;
|
|
15761
17098
|
}, [agentData, agentActionResult, execution, presets]);
|
|
15762
17099
|
const rerunAgent = (0, import_react22.useCallback)(() => {
|
|
15763
17100
|
const resolved = resolveRunInput();
|
|
@@ -16504,14 +17841,13 @@ var AgentUI = ({
|
|
|
16504
17841
|
gap: 1,
|
|
16505
17842
|
width: isPhone ? "100%" : "fit-content",
|
|
16506
17843
|
alignSelf: "center",
|
|
16507
|
-
position:
|
|
17844
|
+
position: "sticky",
|
|
16508
17845
|
top: isPhone ? 0 : 8,
|
|
16509
|
-
left:
|
|
16510
|
-
right:
|
|
16511
|
-
zIndex: isPhone ?
|
|
17846
|
+
left: "auto",
|
|
17847
|
+
right: "auto",
|
|
17848
|
+
zIndex: isPhone ? 20 : 5,
|
|
16512
17849
|
bgcolor: isPhone ? "hsl(var(--background))" : "hsl(var(--card))",
|
|
16513
17850
|
borderRadius: isPhone ? 0 : 9999,
|
|
16514
|
-
borderBottom: isPhone ? "1px solid hsl(var(--border))" : "none",
|
|
16515
17851
|
boxShadow: isPhone ? "0 4px 16px rgba(0,0,0,0.12)" : "none",
|
|
16516
17852
|
px: isPhone ? 1 : 0,
|
|
16517
17853
|
py: isPhone ? 1 : 0
|
|
@@ -16964,7 +18300,7 @@ var AgentUI = ({
|
|
|
16964
18300
|
]
|
|
16965
18301
|
}
|
|
16966
18302
|
);
|
|
16967
|
-
const postRunDiscovery = Boolean(postRunScheduleHint) && !scheduleDisabledReason || postRunAppReqs.length > 0 || postRunUnauthedApps.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
18303
|
+
const postRunDiscovery = isEffectiveSupport && (Boolean(postRunScheduleHint) && !scheduleDisabledReason || postRunAppReqs.length > 0 || postRunUnauthedApps.length > 0) ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
16968
18304
|
import_material23.Box,
|
|
16969
18305
|
{
|
|
16970
18306
|
sx: {
|
|
@@ -16978,7 +18314,47 @@ var AgentUI = ({
|
|
|
16978
18314
|
bgcolor: "hsl(var(--muted) / 0.35)"
|
|
16979
18315
|
},
|
|
16980
18316
|
children: [
|
|
16981
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
18317
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
18318
|
+
import_material23.Tooltip,
|
|
18319
|
+
{
|
|
18320
|
+
title: "Visible to support users only \u2014 this helps guide us towards things working better over time.",
|
|
18321
|
+
arrow: true,
|
|
18322
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
18323
|
+
import_material23.Box,
|
|
18324
|
+
{
|
|
18325
|
+
sx: {
|
|
18326
|
+
display: "inline-flex",
|
|
18327
|
+
alignItems: "center",
|
|
18328
|
+
gap: 0.75,
|
|
18329
|
+
mr: 0.5,
|
|
18330
|
+
cursor: "help"
|
|
18331
|
+
},
|
|
18332
|
+
children: [
|
|
18333
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_material23.Typography, { sx: { fontSize: "0.78rem", color: "hsl(var(--muted-foreground))" }, children: "Set this up to run on its own" }),
|
|
18334
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
18335
|
+
import_material23.Box,
|
|
18336
|
+
{
|
|
18337
|
+
component: "span",
|
|
18338
|
+
sx: {
|
|
18339
|
+
fontSize: "0.64rem",
|
|
18340
|
+
fontWeight: 600,
|
|
18341
|
+
textTransform: "uppercase",
|
|
18342
|
+
letterSpacing: "0.04em",
|
|
18343
|
+
px: 0.75,
|
|
18344
|
+
py: 0.15,
|
|
18345
|
+
borderRadius: "4px",
|
|
18346
|
+
bgcolor: "hsl(var(--muted))",
|
|
18347
|
+
color: "hsl(var(--muted-foreground))",
|
|
18348
|
+
border: "1px solid hsl(var(--border))"
|
|
18349
|
+
},
|
|
18350
|
+
children: "Support only"
|
|
18351
|
+
}
|
|
18352
|
+
)
|
|
18353
|
+
]
|
|
18354
|
+
}
|
|
18355
|
+
)
|
|
18356
|
+
}
|
|
18357
|
+
),
|
|
16982
18358
|
postRunScheduleHint && !scheduleDisabledReason && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_material23.Tooltip, { title: `Detected schedule: ${postRunScheduleHint.label}. Click to review and save.`, arrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
16983
18359
|
import_material23.Box,
|
|
16984
18360
|
{
|
|
@@ -17073,22 +18449,46 @@ var AgentUI = ({
|
|
|
17073
18449
|
) : null;
|
|
17074
18450
|
const mobilePlusCanSchedule = (hasExecution || showStarter) && !scheduleDisabledReason && !disableSchedule && (actionInput || "").trim().length >= 1;
|
|
17075
18451
|
const mobilePlusButton = isPhone ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
17076
|
-
import_material23.
|
|
18452
|
+
import_material23.Tooltip,
|
|
18453
|
+
{
|
|
18454
|
+
title: selectedPreset ? `Skill: ${selectedPreset.label} (click to change)` : "Add skill, schedule, or attachments",
|
|
18455
|
+
arrow: true,
|
|
18456
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
18457
|
+
import_material23.IconButton,
|
|
18458
|
+
{
|
|
18459
|
+
type: "button",
|
|
18460
|
+
"aria-label": "Skills, schedule and attachments",
|
|
18461
|
+
onClick: (e) => setMobilePlusAnchor(e.currentTarget),
|
|
18462
|
+
sx: {
|
|
18463
|
+
width: 32,
|
|
18464
|
+
height: 32,
|
|
18465
|
+
flexShrink: 0,
|
|
18466
|
+
alignSelf: "center",
|
|
18467
|
+
border: "1px solid hsl(var(--border))",
|
|
18468
|
+
color: selectedPreset ? "hsl(var(--foreground))" : "hsl(var(--muted-foreground))",
|
|
18469
|
+
bgcolor: selectedPreset ? "hsl(var(--muted))" : "transparent",
|
|
18470
|
+
"&:hover": { bgcolor: "hsl(var(--muted))", color: "hsl(var(--foreground))" }
|
|
18471
|
+
},
|
|
18472
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react14.Plus, { size: 16 })
|
|
18473
|
+
}
|
|
18474
|
+
)
|
|
18475
|
+
}
|
|
18476
|
+
) : null;
|
|
18477
|
+
const mobileSkillChip = isPhone && selectedPreset && !hidePresets ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
18478
|
+
AgentPresets_default,
|
|
17077
18479
|
{
|
|
17078
|
-
|
|
17079
|
-
|
|
17080
|
-
|
|
18480
|
+
variant: "floating",
|
|
18481
|
+
chipRef: presetsChipRef,
|
|
18482
|
+
presets,
|
|
18483
|
+
isSupport: isEffectiveSupport,
|
|
18484
|
+
selectedPreset,
|
|
18485
|
+
onRemoveSelected: handleRemovePreset,
|
|
18486
|
+
onSelectPreset: handleSelectPresetInternal,
|
|
18487
|
+
placement: "bottom-start",
|
|
17081
18488
|
sx: {
|
|
17082
|
-
width: 32,
|
|
17083
18489
|
height: 32,
|
|
17084
|
-
|
|
17085
|
-
|
|
17086
|
-
border: "1px solid hsl(var(--border))",
|
|
17087
|
-
color: selectedPreset ? "hsl(var(--foreground))" : "hsl(var(--muted-foreground))",
|
|
17088
|
-
bgcolor: selectedPreset ? "hsl(var(--muted))" : "transparent",
|
|
17089
|
-
"&:hover": { bgcolor: "hsl(var(--muted))", color: "hsl(var(--foreground))" }
|
|
17090
|
-
},
|
|
17091
|
-
children: selectedPreset?.icon ?? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react14.Plus, { size: 16 })
|
|
18490
|
+
alignSelf: "center"
|
|
18491
|
+
}
|
|
17092
18492
|
}
|
|
17093
18493
|
) : null;
|
|
17094
18494
|
const mobilePlusMenu = isPhone ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
@@ -17148,7 +18548,7 @@ var AgentUI = ({
|
|
|
17148
18548
|
]
|
|
17149
18549
|
}
|
|
17150
18550
|
),
|
|
17151
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
18551
|
+
!disableSchedule && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
17152
18552
|
import_material23.MenuItem,
|
|
17153
18553
|
{
|
|
17154
18554
|
disabled: !mobilePlusCanSchedule || agentRequestLoading,
|
|
@@ -17211,8 +18611,7 @@ var AgentUI = ({
|
|
|
17211
18611
|
...Array.isArray(contentSx) ? contentSx : contentSx ? [contentSx] : []
|
|
17212
18612
|
],
|
|
17213
18613
|
children: [
|
|
17214
|
-
|
|
17215
|
-
isPhone && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_material23.Box, { sx: { height: 52, flexShrink: 0, flexGrow: 0 } }),
|
|
18614
|
+
showRunSwitcher && tabBar,
|
|
17216
18615
|
schedulePopover,
|
|
17217
18616
|
mobilePlusMenu,
|
|
17218
18617
|
showStarter ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
@@ -17230,7 +18629,7 @@ var AgentUI = ({
|
|
|
17230
18629
|
gap: isPhone ? 1.5 : compact ? 2 : 3,
|
|
17231
18630
|
py: isPhone ? 1 : compact ? 2 : 4,
|
|
17232
18631
|
width: "100%",
|
|
17233
|
-
...isPhone ? { flex: 1, justifyContent: "center" } : {}
|
|
18632
|
+
...isPhone ? { flex: 1, justifyContent: "center", marginTop: compact ? "-16px" : "-50px" } : {}
|
|
17234
18633
|
},
|
|
17235
18634
|
children: [
|
|
17236
18635
|
!hideHeroIcon && !compact && !isPhone && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_material23.Box, { sx: {
|
|
@@ -17244,13 +18643,13 @@ var AgentUI = ({
|
|
|
17244
18643
|
justifyContent: "center",
|
|
17245
18644
|
boxShadow: "0 8px 24px rgba(0,0,0,0.25)"
|
|
17246
18645
|
}, children: heroIcon ?? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(AgentIcon_default, { size: Math.round(heroIconSize * 0.67) }) }),
|
|
17247
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_material23.Typography, { component: "h1", sx: {
|
|
17248
|
-
fontSize: compact ? { xs: "1.1rem", md: "1.5rem" } : { xs: "1.35rem", md: "2.25rem" },
|
|
18646
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_material23.Typography, { component: "h1", sx: {
|
|
18647
|
+
fontSize: isPhone ? "1.35rem" : compact ? { xs: "1.1rem", md: "1.5rem" } : { xs: "1.35rem", md: "2.25rem" },
|
|
17249
18648
|
fontWeight: 600,
|
|
17250
18649
|
color: "hsl(var(--foreground))",
|
|
17251
18650
|
textAlign: "center",
|
|
17252
18651
|
letterSpacing: "-0.01em"
|
|
17253
|
-
}, children: title }),
|
|
18652
|
+
}, children: title }) : null,
|
|
17254
18653
|
subtitle && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_material23.Typography, { sx: {
|
|
17255
18654
|
fontSize: { xs: "0.8rem", sm: "0.95rem" },
|
|
17256
18655
|
color: "hsl(var(--muted-foreground))",
|
|
@@ -17265,11 +18664,11 @@ var AgentUI = ({
|
|
|
17265
18664
|
gap: 0.5,
|
|
17266
18665
|
// Keep the same radius in both states so growing to multiple
|
|
17267
18666
|
// lines does not visually snap from a pill to a boxy card.
|
|
17268
|
-
borderRadius: "28px",
|
|
18667
|
+
borderRadius: isPhone ? promptMultiline ? "20px" : "28px" : "28px",
|
|
17269
18668
|
border: "1.5px solid hsl(var(--border))",
|
|
17270
18669
|
bgcolor: "hsl(var(--card))",
|
|
17271
|
-
px: isPhone ? 1 : 2.25,
|
|
17272
|
-
py: 1,
|
|
18670
|
+
px: isPhone ? 1.5 : 2.25,
|
|
18671
|
+
py: isPhone ? promptMultiline ? 1.25 : 1 : 1,
|
|
17273
18672
|
boxSizing: "border-box",
|
|
17274
18673
|
// A one-line prompt is a fixed-size control. Lock all three
|
|
17275
18674
|
// dimensions so TextareaAutosize cannot retain a stale
|
|
@@ -17302,7 +18701,10 @@ var AgentUI = ({
|
|
|
17302
18701
|
maxHeight: "33px"
|
|
17303
18702
|
} : {}
|
|
17304
18703
|
}, children: [
|
|
17305
|
-
isPhone && !promptMultiline &&
|
|
18704
|
+
isPhone && !promptMultiline && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_material23.Box, { sx: { display: "inline-flex", alignItems: "center", gap: 0.5, flexShrink: 0 }, children: [
|
|
18705
|
+
mobilePlusButton,
|
|
18706
|
+
mobileSkillChip
|
|
18707
|
+
] }),
|
|
17306
18708
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
17307
18709
|
import_material23.InputBase,
|
|
17308
18710
|
{
|
|
@@ -17412,9 +18814,8 @@ var AgentUI = ({
|
|
|
17412
18814
|
ref: chipOverlayRef,
|
|
17413
18815
|
"data-static": promptMultiline ? "1" : "0",
|
|
17414
18816
|
sx: isPhone ? {
|
|
17415
|
-
// Mobile:
|
|
17416
|
-
//
|
|
17417
|
-
// be opened programmatically and anchored correctly.
|
|
18817
|
+
// Mobile: when no preset is selected, keep an invisible trigger mounted
|
|
18818
|
+
// so the "+" menu can programmatically open the skills picker.
|
|
17418
18819
|
position: "absolute",
|
|
17419
18820
|
left: 0,
|
|
17420
18821
|
bottom: 0,
|
|
@@ -17466,48 +18867,16 @@ var AgentUI = ({
|
|
|
17466
18867
|
to: { transform: "translateY(0)", opacity: 1 }
|
|
17467
18868
|
}
|
|
17468
18869
|
},
|
|
17469
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
18870
|
+
children: (!isPhone || !selectedPreset) && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
17470
18871
|
AgentPresets_default,
|
|
17471
18872
|
{
|
|
17472
18873
|
variant: "floating",
|
|
17473
|
-
chipRef: presetsChipRef,
|
|
18874
|
+
chipRef: !isPhone || !selectedPreset ? presetsChipRef : void 0,
|
|
17474
18875
|
presets,
|
|
17475
|
-
isSupport,
|
|
18876
|
+
isSupport: isEffectiveSupport,
|
|
17476
18877
|
selectedPreset,
|
|
17477
|
-
onRemoveSelected:
|
|
17478
|
-
|
|
17479
|
-
localStorage.removeItem(LAST_PRESET_STORAGE_KEY);
|
|
17480
|
-
} catch {
|
|
17481
|
-
}
|
|
17482
|
-
setSelectedPreset(null);
|
|
17483
|
-
},
|
|
17484
|
-
onSelectPreset: (preset) => {
|
|
17485
|
-
try {
|
|
17486
|
-
localStorage.setItem(LAST_PRESET_STORAGE_KEY, preset.id);
|
|
17487
|
-
} catch {
|
|
17488
|
-
}
|
|
17489
|
-
const override = readPresetAppsOverride(preset.id);
|
|
17490
|
-
if (override && override.length > 0) {
|
|
17491
|
-
setChosenApps(override);
|
|
17492
|
-
} else if (preset.defaultApps && preset.defaultApps.length > 0) {
|
|
17493
|
-
setChosenApps(preset.defaultApps.map((app2) => ({ name: app2.name, id: app2.id, icon: app2.icon })));
|
|
17494
|
-
} else {
|
|
17495
|
-
setChosenApps([]);
|
|
17496
|
-
}
|
|
17497
|
-
seededPresetIdRef.current = preset.id;
|
|
17498
|
-
if (onSelectPreset) {
|
|
17499
|
-
onSelectPreset(preset);
|
|
17500
|
-
return;
|
|
17501
|
-
}
|
|
17502
|
-
setSelectedPreset(preset);
|
|
17503
|
-
setTimeout(() => {
|
|
17504
|
-
const el = inputRef.current;
|
|
17505
|
-
try {
|
|
17506
|
-
el?.focus();
|
|
17507
|
-
} catch {
|
|
17508
|
-
}
|
|
17509
|
-
}, 0);
|
|
17510
|
-
}
|
|
18878
|
+
onRemoveSelected: handleRemovePreset,
|
|
18879
|
+
onSelectPreset: handleSelectPresetInternal
|
|
17511
18880
|
}
|
|
17512
18881
|
)
|
|
17513
18882
|
}
|
|
@@ -17545,7 +18914,10 @@ var AgentUI = ({
|
|
|
17545
18914
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_material23.Typography, { sx: { fontSize: "0.7rem", color: "hsl(var(--foreground))", maxWidth: 140, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: img.name }),
|
|
17546
18915
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_material23.IconButton, { size: "small", onClick: () => setAttachedImages((prev) => prev.filter((_, i) => i !== idx)), sx: { p: 0.125, color: "hsl(var(--muted-foreground))", "&:hover": { color: "hsl(var(--destructive))" } }, "aria-label": "Remove attached image", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react14.X, { size: 11 }) })
|
|
17547
18916
|
] }, `${img.name}-${idx}`)) }),
|
|
17548
|
-
isPhone && promptMultiline &&
|
|
18917
|
+
isPhone && promptMultiline && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_material23.Box, { sx: { display: "inline-flex", alignItems: "center", gap: 0.5, flexShrink: 0, minWidth: 0, maxWidth: "calc(100% - 60px)" }, children: [
|
|
18918
|
+
mobilePlusButton,
|
|
18919
|
+
mobileSkillChip
|
|
18920
|
+
] }),
|
|
17549
18921
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_material23.Box, { sx: {
|
|
17550
18922
|
display: "flex",
|
|
17551
18923
|
alignItems: "center",
|
|
@@ -17933,7 +19305,7 @@ var AgentUI = ({
|
|
|
17933
19305
|
]
|
|
17934
19306
|
}
|
|
17935
19307
|
) }),
|
|
17936
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
19308
|
+
!hideChooseLLM && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
17937
19309
|
import_material23.Box,
|
|
17938
19310
|
{
|
|
17939
19311
|
component: "span",
|
|
@@ -18010,15 +19382,18 @@ var AgentUI = ({
|
|
|
18010
19382
|
"&:hover": !agentRequestLoading ? { bgcolor: needsAuth ? "hsl(var(--severity-medium) / 0.18)" : "hsl(var(--muted) / 0.9)" } : {}
|
|
18011
19383
|
},
|
|
18012
19384
|
children: [
|
|
18013
|
-
|
|
18014
|
-
|
|
18015
|
-
{
|
|
18016
|
-
|
|
18017
|
-
|
|
18018
|
-
|
|
18019
|
-
|
|
18020
|
-
|
|
18021
|
-
|
|
19385
|
+
(() => {
|
|
19386
|
+
const appIcon = app2.icon || availableApps.find((a) => normalizeAgentAppName(a.name || "") === slug)?.icon || resolvedToolApps[slug]?.icon;
|
|
19387
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_material23.Box, { sx: { display: "inline-flex", alignItems: "center", justifyContent: "center", width: 18, height: 18, flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
19388
|
+
AppFallbackIcon,
|
|
19389
|
+
{
|
|
19390
|
+
name: app2.name,
|
|
19391
|
+
imageUrl: appIcon,
|
|
19392
|
+
size: 18,
|
|
19393
|
+
style: { borderRadius: 3, objectFit: "contain" }
|
|
19394
|
+
}
|
|
19395
|
+
) });
|
|
19396
|
+
})(),
|
|
18022
19397
|
!isPhone && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_material23.Typography, { sx: { fontSize: "0.8rem", mx: 0.25, textTransform: "capitalize" }, children: app2.name.replace(/_/g, " ") }),
|
|
18023
19398
|
needsAuth && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react14.AlertTriangle, { size: 14, color: "hsl(var(--severity-medium))", style: { marginRight: 2 } }),
|
|
18024
19399
|
isRequired ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
@@ -18183,21 +19558,38 @@ var AgentUI = ({
|
|
|
18183
19558
|
const hasAllowed = Array.isArray(agentData?.allowed_actions) && agentData.allowed_actions.length > 0;
|
|
18184
19559
|
const list = hasAllowed ? executionApps : chosenApps;
|
|
18185
19560
|
return list;
|
|
18186
|
-
})().map((app2, i) =>
|
|
18187
|
-
|
|
18188
|
-
|
|
18189
|
-
|
|
18190
|
-
|
|
18191
|
-
|
|
18192
|
-
|
|
18193
|
-
|
|
18194
|
-
|
|
18195
|
-
|
|
18196
|
-
|
|
18197
|
-
|
|
19561
|
+
})().map((app2, i) => {
|
|
19562
|
+
const slug = normalizeAgentAppName(app2.name || "");
|
|
19563
|
+
const appIcon = app2.icon || availableApps.find((a) => normalizeAgentAppName(a.name || "") === slug)?.icon || resolvedToolApps[slug]?.icon;
|
|
19564
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_material23.Tooltip, { title: (app2.name || "").replace(/_/g, " "), children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
19565
|
+
import_material23.Box,
|
|
19566
|
+
{
|
|
19567
|
+
onClick: () => setAuthDrawerApp({ name: app2.name, id: app2.id || null }),
|
|
19568
|
+
sx: {
|
|
19569
|
+
display: "inline-flex",
|
|
19570
|
+
alignItems: "center",
|
|
19571
|
+
justifyContent: "center",
|
|
19572
|
+
width: 24,
|
|
19573
|
+
height: 24,
|
|
19574
|
+
borderRadius: "6px",
|
|
19575
|
+
overflow: "hidden",
|
|
19576
|
+
bgcolor: "hsl(var(--muted))",
|
|
19577
|
+
cursor: "pointer",
|
|
19578
|
+
transition: "transform 0.15s ease, border-color 0.15s ease",
|
|
19579
|
+
"&:hover": { transform: "scale(1.08)", borderColor: "hsl(var(--primary)) !important" }
|
|
19580
|
+
},
|
|
19581
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
19582
|
+
AppFallbackIcon,
|
|
19583
|
+
{
|
|
19584
|
+
name: app2.name,
|
|
19585
|
+
imageUrl: appIcon,
|
|
19586
|
+
size: 24,
|
|
19587
|
+
style: { borderRadius: 6, objectFit: "contain" }
|
|
19588
|
+
}
|
|
19589
|
+
)
|
|
18198
19590
|
}
|
|
18199
|
-
}
|
|
18200
|
-
|
|
19591
|
+
) }, i);
|
|
19592
|
+
}) }),
|
|
18201
19593
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_material23.Box, { sx: { flex: 1, minWidth: 0 }, children: [
|
|
18202
19594
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_material23.Typography, { sx: { fontSize: "0.85rem", color: "hsl(var(--foreground))", fontWeight: 600, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: agentData?.original_input || actionInput || "Agent run" }),
|
|
18203
19595
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_material23.Typography, { sx: { fontSize: "0.7rem", color: "hsl(var(--muted-foreground))" }, children: [
|
|
@@ -21447,6 +22839,7 @@ var AgentExecutionDrawer = ({
|
|
|
21447
22839
|
bodySx,
|
|
21448
22840
|
topBanner,
|
|
21449
22841
|
onSchedule,
|
|
22842
|
+
isSupport,
|
|
21450
22843
|
theme,
|
|
21451
22844
|
colorMode
|
|
21452
22845
|
}) => {
|
|
@@ -21623,6 +23016,7 @@ var AgentExecutionDrawer = ({
|
|
|
21623
23016
|
apiBaseUrl,
|
|
21624
23017
|
orgId,
|
|
21625
23018
|
onSchedule,
|
|
23019
|
+
isSupport,
|
|
21626
23020
|
theme,
|
|
21627
23021
|
colorMode
|
|
21628
23022
|
},
|
|
@@ -21906,6 +23300,7 @@ var AgentsView = ({
|
|
|
21906
23300
|
onSchedule: effectiveSchedule,
|
|
21907
23301
|
apiKey,
|
|
21908
23302
|
orgId,
|
|
23303
|
+
isSupport: userdata?.support === true || userdata?.support === "true",
|
|
21909
23304
|
theme: resolvedTheme,
|
|
21910
23305
|
colorMode
|
|
21911
23306
|
}
|
|
@@ -22302,55 +23697,964 @@ var AddAppModal = ({ open, onClose, initialQuery, categoryLabel }) => {
|
|
|
22302
23697
|
};
|
|
22303
23698
|
var AddAppModal_default = AddAppModal;
|
|
22304
23699
|
|
|
22305
|
-
// components/
|
|
22306
|
-
var import_react31 = require("react");
|
|
23700
|
+
// components/AskAiButton.tsx
|
|
22307
23701
|
var import_material31 = require("@mui/material");
|
|
22308
|
-
var import_lucide_react21 = require("lucide-react");
|
|
22309
23702
|
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
22310
|
-
var
|
|
22311
|
-
|
|
22312
|
-
|
|
22313
|
-
|
|
22314
|
-
|
|
22315
|
-
|
|
22316
|
-
|
|
22317
|
-
|
|
22318
|
-
|
|
23703
|
+
var AskAiButton = ({
|
|
23704
|
+
onClick,
|
|
23705
|
+
isOpen = false,
|
|
23706
|
+
isSupport,
|
|
23707
|
+
requireSupport = true,
|
|
23708
|
+
pathname,
|
|
23709
|
+
label = "Ask AI",
|
|
23710
|
+
tagLabel = "Support only",
|
|
23711
|
+
contextHint,
|
|
23712
|
+
tooltipTitle,
|
|
23713
|
+
sx,
|
|
23714
|
+
hideWhenOpen = true
|
|
22319
23715
|
}) => {
|
|
22320
|
-
const
|
|
22321
|
-
const
|
|
22322
|
-
|
|
22323
|
-
|
|
22324
|
-
|
|
22325
|
-
const
|
|
22326
|
-
(
|
|
22327
|
-
|
|
22328
|
-
}
|
|
22329
|
-
|
|
22330
|
-
|
|
22331
|
-
|
|
22332
|
-
|
|
22333
|
-
|
|
22334
|
-
|
|
22335
|
-
|
|
22336
|
-
|
|
22337
|
-
|
|
22338
|
-
|
|
23716
|
+
const themeScope = useShuffleMcpTheme();
|
|
23717
|
+
const currentPath = pathname !== void 0 ? pathname : typeof window !== "undefined" ? window.location.pathname : "";
|
|
23718
|
+
if (isAgentRoute(currentPath)) {
|
|
23719
|
+
return null;
|
|
23720
|
+
}
|
|
23721
|
+
const isEffectiveSupport = isSupport !== void 0 ? isSupport : isSupportUser();
|
|
23722
|
+
if (requireSupport && !isEffectiveSupport) {
|
|
23723
|
+
return null;
|
|
23724
|
+
}
|
|
23725
|
+
if (hideWhenOpen && isOpen) {
|
|
23726
|
+
return null;
|
|
23727
|
+
}
|
|
23728
|
+
const effectiveTooltip = tooltipTitle !== void 0 ? tooltipTitle : contextHint ? `Ask AI (${contextHint})` : "Ask AI \u2022 Context-aware assistant";
|
|
23729
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
23730
|
+
import_material31.Box,
|
|
23731
|
+
{
|
|
23732
|
+
className: themeScope?.scopeClassName,
|
|
23733
|
+
sx: {
|
|
23734
|
+
position: "fixed",
|
|
23735
|
+
bottom: "calc(24px + env(safe-area-inset-bottom, 0px))",
|
|
23736
|
+
right: "calc(24px + env(safe-area-inset-right, 0px))",
|
|
23737
|
+
zIndex: 1250
|
|
23738
|
+
},
|
|
23739
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_material31.Tooltip, { title: effectiveTooltip, arrow: true, placement: "top-end", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
23740
|
+
import_material31.ButtonBase,
|
|
23741
|
+
{
|
|
23742
|
+
onClick,
|
|
23743
|
+
focusRipple: true,
|
|
23744
|
+
"aria-label": `${label}${tagLabel ? ` (${tagLabel})` : ""}`,
|
|
23745
|
+
sx: [
|
|
23746
|
+
{
|
|
23747
|
+
display: "inline-flex",
|
|
23748
|
+
alignItems: "center",
|
|
23749
|
+
gap: 1.25,
|
|
23750
|
+
px: 2.25,
|
|
23751
|
+
py: 1.25,
|
|
23752
|
+
borderRadius: "9999px",
|
|
23753
|
+
bgcolor: "hsl(var(--card))",
|
|
23754
|
+
color: "hsl(var(--foreground))",
|
|
23755
|
+
border: "1px solid hsl(var(--border))",
|
|
23756
|
+
boxShadow: "0 4px 20px -2px rgba(0, 0, 0, 0.35), 0 2px 6px -1px rgba(0, 0, 0, 0.16)",
|
|
23757
|
+
backdropFilter: "blur(10px)",
|
|
23758
|
+
cursor: "pointer",
|
|
23759
|
+
userSelect: "none",
|
|
23760
|
+
transition: "transform 160ms cubic-bezier(0.16, 1, 0.3, 1), box-shadow 160ms ease, border-color 160ms ease, background-color 160ms ease",
|
|
23761
|
+
"&:hover": {
|
|
23762
|
+
transform: "translateY(-2px)",
|
|
23763
|
+
bgcolor: "hsl(var(--card) / 0.95)",
|
|
23764
|
+
borderColor: "hsla(var(--primary) / 0.45)",
|
|
23765
|
+
boxShadow: "0 8px 26px -4px hsla(var(--primary) / 0.25), 0 4px 10px -2px rgba(0, 0, 0, 0.2)"
|
|
23766
|
+
},
|
|
23767
|
+
"&:active": {
|
|
23768
|
+
transform: "translateY(0)",
|
|
23769
|
+
boxShadow: "0 2px 10px -2px rgba(0, 0, 0, 0.25)"
|
|
23770
|
+
}
|
|
23771
|
+
},
|
|
23772
|
+
...Array.isArray(sx) ? sx : sx ? [sx] : []
|
|
23773
|
+
],
|
|
23774
|
+
children: [
|
|
23775
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
23776
|
+
import_material31.Box,
|
|
23777
|
+
{
|
|
23778
|
+
sx: {
|
|
23779
|
+
display: "flex",
|
|
23780
|
+
alignItems: "center",
|
|
23781
|
+
justifyContent: "center",
|
|
23782
|
+
width: 24,
|
|
23783
|
+
height: 24,
|
|
23784
|
+
borderRadius: "50%",
|
|
23785
|
+
bgcolor: "hsla(var(--primary) / 0.14)",
|
|
23786
|
+
color: "hsl(var(--primary))",
|
|
23787
|
+
flexShrink: 0
|
|
23788
|
+
},
|
|
23789
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(AgentIcon_default, { size: 16 })
|
|
23790
|
+
}
|
|
23791
|
+
),
|
|
23792
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
23793
|
+
import_material31.Typography,
|
|
23794
|
+
{
|
|
23795
|
+
sx: {
|
|
23796
|
+
fontSize: "0.86rem",
|
|
23797
|
+
fontWeight: 600,
|
|
23798
|
+
letterSpacing: "-0.01em",
|
|
23799
|
+
lineHeight: 1,
|
|
23800
|
+
color: "inherit"
|
|
23801
|
+
},
|
|
23802
|
+
children: label
|
|
23803
|
+
}
|
|
23804
|
+
),
|
|
23805
|
+
tagLabel && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
23806
|
+
import_material31.Box,
|
|
23807
|
+
{
|
|
23808
|
+
component: "span",
|
|
23809
|
+
sx: {
|
|
23810
|
+
fontSize: "0.64rem",
|
|
23811
|
+
fontWeight: 700,
|
|
23812
|
+
textTransform: "uppercase",
|
|
23813
|
+
letterSpacing: "0.04em",
|
|
23814
|
+
color: "hsl(var(--primary))",
|
|
23815
|
+
bgcolor: "hsla(var(--primary) / 0.12)",
|
|
23816
|
+
border: "1px solid hsla(var(--primary) / 0.26)",
|
|
23817
|
+
px: 0.9,
|
|
23818
|
+
py: 0.25,
|
|
23819
|
+
borderRadius: "9999px",
|
|
23820
|
+
lineHeight: 1.1,
|
|
23821
|
+
flexShrink: 0
|
|
23822
|
+
},
|
|
23823
|
+
children: tagLabel
|
|
23824
|
+
}
|
|
23825
|
+
)
|
|
23826
|
+
]
|
|
23827
|
+
}
|
|
23828
|
+
) })
|
|
22339
23829
|
}
|
|
22340
|
-
|
|
22341
|
-
|
|
22342
|
-
|
|
22343
|
-
|
|
22344
|
-
|
|
22345
|
-
|
|
22346
|
-
|
|
23830
|
+
);
|
|
23831
|
+
};
|
|
23832
|
+
var AskAiButton_default = AskAiButton;
|
|
23833
|
+
|
|
23834
|
+
// components/AskAiDrawer.tsx
|
|
23835
|
+
var import_react31 = require("react");
|
|
23836
|
+
var import_material32 = require("@mui/material");
|
|
23837
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
23838
|
+
var AskAiDrawer = ({
|
|
23839
|
+
open,
|
|
23840
|
+
onClose,
|
|
23841
|
+
title,
|
|
23842
|
+
subtitle,
|
|
23843
|
+
pathname: propPathname,
|
|
23844
|
+
search: propSearch,
|
|
23845
|
+
rules,
|
|
23846
|
+
onContextResolved,
|
|
23847
|
+
hideResetAction = true,
|
|
23848
|
+
agentUIProps,
|
|
23849
|
+
...drawerProps
|
|
23850
|
+
}) => {
|
|
23851
|
+
const [internalPathname, setInternalPathname] = (0, import_react31.useState)(
|
|
23852
|
+
() => typeof window !== "undefined" ? window.location.pathname : "/"
|
|
23853
|
+
);
|
|
23854
|
+
const [internalSearch, setInternalSearch] = (0, import_react31.useState)(
|
|
23855
|
+
() => typeof window !== "undefined" ? window.location.search : ""
|
|
23856
|
+
);
|
|
23857
|
+
(0, import_react31.useEffect)(() => {
|
|
23858
|
+
if (propPathname !== void 0) return;
|
|
23859
|
+
const updateLoc = () => {
|
|
23860
|
+
setInternalPathname(window.location.pathname);
|
|
23861
|
+
setInternalSearch(window.location.search);
|
|
23862
|
+
};
|
|
23863
|
+
window.addEventListener("popstate", updateLoc);
|
|
23864
|
+
return () => window.removeEventListener("popstate", updateLoc);
|
|
23865
|
+
}, [propPathname]);
|
|
23866
|
+
const activePathname = propPathname !== void 0 ? propPathname : internalPathname;
|
|
23867
|
+
const activeSearch = propSearch !== void 0 ? propSearch : internalSearch;
|
|
23868
|
+
const [resetKey, setResetKey] = (0, import_react31.useState)(0);
|
|
23869
|
+
const resolvedContext = (0, import_react31.useMemo)(
|
|
23870
|
+
() => resolveAgentContext(activePathname, activeSearch, rules),
|
|
23871
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
23872
|
+
[activePathname, activeSearch, rules, resetKey]
|
|
23873
|
+
);
|
|
23874
|
+
(0, import_react31.useEffect)(() => {
|
|
23875
|
+
onContextResolved?.(resolvedContext);
|
|
23876
|
+
}, [resolvedContext, onContextResolved]);
|
|
23877
|
+
const [isOverridden, setIsOverridden] = (0, import_react31.useState)(resolvedContext.isOverridden);
|
|
23878
|
+
(0, import_react31.useEffect)(() => {
|
|
23879
|
+
setIsOverridden(resolvedContext.isOverridden);
|
|
23880
|
+
}, [resolvedContext.isOverridden, resolvedContext.storageKey]);
|
|
23881
|
+
const handleAppsChange = (0, import_react31.useCallback)(
|
|
23882
|
+
(apps) => {
|
|
23883
|
+
setPageContextChoice(resolvedContext.storageKey, {
|
|
23884
|
+
apps: apps.map((a) => ({ name: a.name, id: a.id, icon: a.icon }))
|
|
23885
|
+
});
|
|
23886
|
+
setIsOverridden(true);
|
|
23887
|
+
},
|
|
23888
|
+
[resolvedContext.storageKey]
|
|
23889
|
+
);
|
|
23890
|
+
const handleSelectPreset = (0, import_react31.useCallback)(
|
|
23891
|
+
(preset) => {
|
|
23892
|
+
setPageContextChoice(resolvedContext.storageKey, {
|
|
23893
|
+
presetId: preset.id
|
|
23894
|
+
});
|
|
23895
|
+
setIsOverridden(true);
|
|
23896
|
+
},
|
|
23897
|
+
[resolvedContext.storageKey]
|
|
23898
|
+
);
|
|
23899
|
+
const handleResetToDefaults = (0, import_react31.useCallback)(() => {
|
|
23900
|
+
clearPageContextChoice(resolvedContext.storageKey);
|
|
23901
|
+
setIsOverridden(false);
|
|
23902
|
+
setResetKey((k) => k + 1);
|
|
23903
|
+
}, [resolvedContext.storageKey]);
|
|
23904
|
+
const effectiveTitle = title !== void 0 ? title : resolvedContext.title;
|
|
23905
|
+
const effectiveSubtitle = subtitle !== void 0 ? subtitle : /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_material32.Box, { sx: { display: "flex", alignItems: "center", gap: 1, flexWrap: "wrap", mt: 0.25 }, children: [
|
|
23906
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_material32.Typography, { component: "span", sx: { fontSize: "0.78rem", color: "hsl(var(--muted-foreground))" }, children: resolvedContext.subtitle }),
|
|
23907
|
+
isOverridden && !hideResetAction && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
23908
|
+
import_material32.ButtonBase,
|
|
22347
23909
|
{
|
|
23910
|
+
onClick: handleResetToDefaults,
|
|
22348
23911
|
sx: {
|
|
22349
|
-
|
|
22350
|
-
|
|
22351
|
-
|
|
22352
|
-
|
|
22353
|
-
|
|
23912
|
+
fontSize: "0.68rem",
|
|
23913
|
+
fontWeight: 600,
|
|
23914
|
+
color: "hsl(var(--primary))",
|
|
23915
|
+
textDecoration: "underline",
|
|
23916
|
+
cursor: "pointer",
|
|
23917
|
+
py: 0.1,
|
|
23918
|
+
px: 0.4,
|
|
23919
|
+
borderRadius: 0.5,
|
|
23920
|
+
transition: "opacity 120ms ease",
|
|
23921
|
+
"&:hover": { opacity: 0.75 }
|
|
23922
|
+
},
|
|
23923
|
+
children: "Reset to defaults"
|
|
23924
|
+
}
|
|
23925
|
+
)
|
|
23926
|
+
] });
|
|
23927
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
23928
|
+
AgentRunDrawer_default,
|
|
23929
|
+
{
|
|
23930
|
+
...drawerProps,
|
|
23931
|
+
open,
|
|
23932
|
+
onClose,
|
|
23933
|
+
title: effectiveTitle,
|
|
23934
|
+
subtitle: effectiveSubtitle,
|
|
23935
|
+
agentUIProps: {
|
|
23936
|
+
...agentUIProps,
|
|
23937
|
+
key: `ask_ai_${resolvedContext.storageKey}_${resetKey}`,
|
|
23938
|
+
defaultApps: resolvedContext.apps,
|
|
23939
|
+
initialPresetId: resolvedContext.presetId,
|
|
23940
|
+
defaultInput: agentUIProps?.defaultInput ?? resolvedContext.defaultPrompt,
|
|
23941
|
+
placeholder: agentUIProps?.placeholder ?? resolvedContext.placeholder,
|
|
23942
|
+
contextCategory: resolvedContext.sourceCategory,
|
|
23943
|
+
contextStorageKey: resolvedContext.storageKey,
|
|
23944
|
+
onAppsChange: (apps) => {
|
|
23945
|
+
handleAppsChange(apps);
|
|
23946
|
+
agentUIProps?.onAppsChange?.(apps);
|
|
23947
|
+
},
|
|
23948
|
+
onSelectPreset: (preset) => {
|
|
23949
|
+
handleSelectPreset(preset);
|
|
23950
|
+
agentUIProps?.onSelectPreset?.(preset);
|
|
23951
|
+
}
|
|
23952
|
+
}
|
|
23953
|
+
}
|
|
23954
|
+
);
|
|
23955
|
+
};
|
|
23956
|
+
var AskAiDrawer_default = AskAiDrawer;
|
|
23957
|
+
|
|
23958
|
+
// components/AskAiSidePanel.tsx
|
|
23959
|
+
var import_react32 = __toESM(require("react"));
|
|
23960
|
+
var import_material33 = require("@mui/material");
|
|
23961
|
+
var import_lucide_react21 = require("lucide-react");
|
|
23962
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
23963
|
+
var AGENT_DRAWER_OPEN_EVENT = "agent-drawer-open";
|
|
23964
|
+
var AskAiSidePanel = ({
|
|
23965
|
+
open,
|
|
23966
|
+
onClose,
|
|
23967
|
+
initialTab = "run",
|
|
23968
|
+
activeTab: propActiveTab,
|
|
23969
|
+
onTabChange,
|
|
23970
|
+
permissionsSlot,
|
|
23971
|
+
localLLMSlot,
|
|
23972
|
+
localLLMTabBadge,
|
|
23973
|
+
permissionsDisabled = false,
|
|
23974
|
+
permissionsDisabledTooltip,
|
|
23975
|
+
pathname,
|
|
23976
|
+
search,
|
|
23977
|
+
rules,
|
|
23978
|
+
isSupport,
|
|
23979
|
+
width = 380,
|
|
23980
|
+
theme,
|
|
23981
|
+
globalUrl,
|
|
23982
|
+
agentUIProps,
|
|
23983
|
+
onContextResolved,
|
|
23984
|
+
sideshift,
|
|
23985
|
+
userdata,
|
|
23986
|
+
isLoaded,
|
|
23987
|
+
isLoggedIn,
|
|
23988
|
+
serverside,
|
|
23989
|
+
colorMode,
|
|
23990
|
+
sx
|
|
23991
|
+
}) => {
|
|
23992
|
+
const themeScope = useShuffleMcpTheme();
|
|
23993
|
+
const effectiveTheme = theme || (themeScope?.isDark ? "dark" : "light");
|
|
23994
|
+
const [currentPathname, setCurrentPathname] = (0, import_react32.useState)(() => {
|
|
23995
|
+
if (pathname !== void 0) return pathname;
|
|
23996
|
+
if (typeof window !== "undefined") return window.location.pathname;
|
|
23997
|
+
return "/";
|
|
23998
|
+
});
|
|
23999
|
+
const [currentSearch, setCurrentSearch] = (0, import_react32.useState)(() => {
|
|
24000
|
+
if (search !== void 0) return search;
|
|
24001
|
+
if (typeof window !== "undefined") return window.location.search;
|
|
24002
|
+
return "";
|
|
24003
|
+
});
|
|
24004
|
+
(0, import_react32.useEffect)(() => {
|
|
24005
|
+
if (pathname !== void 0) {
|
|
24006
|
+
setCurrentPathname(pathname);
|
|
24007
|
+
return;
|
|
24008
|
+
}
|
|
24009
|
+
if (typeof window !== "undefined") {
|
|
24010
|
+
const handleLocationChange = () => {
|
|
24011
|
+
setCurrentPathname(window.location.pathname);
|
|
24012
|
+
setCurrentSearch(window.location.search);
|
|
24013
|
+
};
|
|
24014
|
+
window.addEventListener("popstate", handleLocationChange);
|
|
24015
|
+
return () => window.removeEventListener("popstate", handleLocationChange);
|
|
24016
|
+
}
|
|
24017
|
+
return;
|
|
24018
|
+
}, [pathname]);
|
|
24019
|
+
(0, import_react32.useEffect)(() => {
|
|
24020
|
+
if (search !== void 0) {
|
|
24021
|
+
setCurrentSearch(search);
|
|
24022
|
+
}
|
|
24023
|
+
}, [search]);
|
|
24024
|
+
const isAgentDisabled = isAgentRoute(currentPathname);
|
|
24025
|
+
(0, import_react32.useEffect)(() => {
|
|
24026
|
+
if (isAgentDisabled && open) {
|
|
24027
|
+
onClose();
|
|
24028
|
+
}
|
|
24029
|
+
}, [isAgentDisabled, open, onClose]);
|
|
24030
|
+
const context = import_react32.default.useMemo(
|
|
24031
|
+
() => resolveAgentContext(currentPathname, currentSearch, rules),
|
|
24032
|
+
[currentPathname, currentSearch, rules]
|
|
24033
|
+
);
|
|
24034
|
+
(0, import_react32.useEffect)(() => {
|
|
24035
|
+
onContextResolved?.(context);
|
|
24036
|
+
}, [context, onContextResolved]);
|
|
24037
|
+
useSyncHostBaseUrl(globalUrl);
|
|
24038
|
+
const [internalTab, setInternalTab] = (0, import_react32.useState)(initialTab);
|
|
24039
|
+
const currentTab = propActiveTab !== void 0 ? propActiveTab : internalTab;
|
|
24040
|
+
const handleTabChange = (0, import_react32.useCallback)(
|
|
24041
|
+
(nextTab) => {
|
|
24042
|
+
setInternalTab(nextTab);
|
|
24043
|
+
onTabChange?.(nextTab);
|
|
24044
|
+
},
|
|
24045
|
+
[onTabChange]
|
|
24046
|
+
);
|
|
24047
|
+
(0, import_react32.useEffect)(() => {
|
|
24048
|
+
if (initialTab) {
|
|
24049
|
+
setInternalTab(initialTab);
|
|
24050
|
+
}
|
|
24051
|
+
}, [initialTab]);
|
|
24052
|
+
const prevOpenRef = (0, import_react32.useRef)(open);
|
|
24053
|
+
(0, import_react32.useEffect)(() => {
|
|
24054
|
+
if (open && !prevOpenRef.current && initialTab) {
|
|
24055
|
+
setInternalTab(initialTab);
|
|
24056
|
+
onTabChange?.(initialTab);
|
|
24057
|
+
}
|
|
24058
|
+
prevOpenRef.current = open;
|
|
24059
|
+
}, [open, initialTab, onTabChange]);
|
|
24060
|
+
(0, import_react32.useEffect)(() => {
|
|
24061
|
+
if (typeof window === "undefined") return;
|
|
24062
|
+
window.__shuffleAgentDrawerMounted = (window.__shuffleAgentDrawerMounted || 0) + 1;
|
|
24063
|
+
return () => {
|
|
24064
|
+
window.__shuffleAgentDrawerMounted = Math.max(
|
|
24065
|
+
0,
|
|
24066
|
+
(window.__shuffleAgentDrawerMounted || 1) - 1
|
|
24067
|
+
);
|
|
24068
|
+
};
|
|
24069
|
+
}, []);
|
|
24070
|
+
(0, import_react32.useEffect)(() => {
|
|
24071
|
+
if (typeof window === "undefined") return;
|
|
24072
|
+
const onOpen = (event) => {
|
|
24073
|
+
const tab = event.detail?.tab;
|
|
24074
|
+
if (tab) {
|
|
24075
|
+
handleTabChange(tab);
|
|
24076
|
+
}
|
|
24077
|
+
};
|
|
24078
|
+
window.addEventListener(AGENT_DRAWER_OPEN_EVENT, onOpen);
|
|
24079
|
+
return () => {
|
|
24080
|
+
window.removeEventListener(AGENT_DRAWER_OPEN_EVENT, onOpen);
|
|
24081
|
+
};
|
|
24082
|
+
}, [handleTabChange]);
|
|
24083
|
+
const effectiveLocalLLMSlot = localLLMSlot ?? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
24084
|
+
LocalLLMConfig_default,
|
|
24085
|
+
{
|
|
24086
|
+
open,
|
|
24087
|
+
globalUrl,
|
|
24088
|
+
userdata,
|
|
24089
|
+
isLoaded,
|
|
24090
|
+
isLoggedIn,
|
|
24091
|
+
serverside,
|
|
24092
|
+
theme: effectiveTheme,
|
|
24093
|
+
colorMode
|
|
24094
|
+
}
|
|
24095
|
+
);
|
|
24096
|
+
const TAB_ORDER2 = ["run", "localLLM"];
|
|
24097
|
+
const visibleTabs = TAB_ORDER2.filter((t) => {
|
|
24098
|
+
if (t === "run") return true;
|
|
24099
|
+
if (t === "localLLM") return !!effectiveLocalLLMSlot;
|
|
24100
|
+
return false;
|
|
24101
|
+
});
|
|
24102
|
+
const safeActiveTab = visibleTabs.includes(currentTab) ? currentTab : "run";
|
|
24103
|
+
const effectiveWidth = safeActiveTab === "localLLM" ? Math.max(width, 520) : width;
|
|
24104
|
+
const effectiveSideshift = sideshift !== void 0 ? sideshift : context.sideshift ?? true;
|
|
24105
|
+
(0, import_react32.useEffect)(() => {
|
|
24106
|
+
if (typeof document === "undefined") return;
|
|
24107
|
+
if (open && !isAgentDisabled && effectiveSideshift) {
|
|
24108
|
+
document.documentElement.style.setProperty(
|
|
24109
|
+
"--ask-ai-panel-width",
|
|
24110
|
+
`${effectiveWidth}px`
|
|
24111
|
+
);
|
|
24112
|
+
} else {
|
|
24113
|
+
document.documentElement.style.setProperty("--ask-ai-panel-width", "0px");
|
|
24114
|
+
}
|
|
24115
|
+
return () => {
|
|
24116
|
+
document.documentElement.style.setProperty("--ask-ai-panel-width", "0px");
|
|
24117
|
+
};
|
|
24118
|
+
}, [open, isAgentDisabled, effectiveWidth, effectiveSideshift]);
|
|
24119
|
+
const handleAppsChange = (0, import_react32.useCallback)(
|
|
24120
|
+
(nextApps) => {
|
|
24121
|
+
setPageContextChoice(context.storageKey, {
|
|
24122
|
+
apps: nextApps.map((a) => ({ name: a.name, id: a.id, icon: a.icon }))
|
|
24123
|
+
});
|
|
24124
|
+
agentUIProps?.onAppsChange?.(nextApps);
|
|
24125
|
+
},
|
|
24126
|
+
[context.storageKey, agentUIProps]
|
|
24127
|
+
);
|
|
24128
|
+
const handleSelectPreset = (0, import_react32.useCallback)(
|
|
24129
|
+
(preset) => {
|
|
24130
|
+
setPageContextChoice(context.storageKey, {
|
|
24131
|
+
presetId: preset?.id ?? null
|
|
24132
|
+
});
|
|
24133
|
+
},
|
|
24134
|
+
[context.storageKey]
|
|
24135
|
+
);
|
|
24136
|
+
if (isAgentDisabled) {
|
|
24137
|
+
return null;
|
|
24138
|
+
}
|
|
24139
|
+
const isVisible = open && !isAgentDisabled;
|
|
24140
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_jsx_runtime38.Fragment, { children: [
|
|
24141
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
24142
|
+
import_material33.Box,
|
|
24143
|
+
{
|
|
24144
|
+
onClick: onClose,
|
|
24145
|
+
"aria-hidden": "true",
|
|
24146
|
+
sx: {
|
|
24147
|
+
position: "fixed",
|
|
24148
|
+
inset: 0,
|
|
24149
|
+
bgcolor: "rgba(0, 0, 0, 0.45)",
|
|
24150
|
+
zIndex: 1199,
|
|
24151
|
+
display: { xs: isVisible ? "block" : "none", sm: "none" },
|
|
24152
|
+
backdropFilter: "blur(2px)",
|
|
24153
|
+
transition: "opacity 0.2s ease"
|
|
24154
|
+
}
|
|
24155
|
+
}
|
|
24156
|
+
),
|
|
24157
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
24158
|
+
import_material33.Box,
|
|
24159
|
+
{
|
|
24160
|
+
component: "aside",
|
|
24161
|
+
"aria-label": "Ask AI",
|
|
24162
|
+
"aria-hidden": !isVisible,
|
|
24163
|
+
className: themeScope?.scopeClassName,
|
|
24164
|
+
sx: [
|
|
24165
|
+
{
|
|
24166
|
+
position: "fixed",
|
|
24167
|
+
top: 0,
|
|
24168
|
+
right: 0,
|
|
24169
|
+
bottom: 0,
|
|
24170
|
+
width: { xs: "100%", sm: effectiveWidth },
|
|
24171
|
+
maxWidth: "100vw",
|
|
24172
|
+
height: "100dvh",
|
|
24173
|
+
bgcolor: "hsl(var(--card))",
|
|
24174
|
+
borderLeft: "1px solid hsl(var(--border))",
|
|
24175
|
+
boxShadow: isVisible ? "-6px 0 24px rgba(0, 0, 0, 0.16)" : "none",
|
|
24176
|
+
zIndex: 1200,
|
|
24177
|
+
display: "flex",
|
|
24178
|
+
flexDirection: "column",
|
|
24179
|
+
transform: isVisible ? "translateX(0)" : "translateX(100%)",
|
|
24180
|
+
transition: "transform 0.22s cubic-bezier(0.16, 1, 0.3, 1), width 0.2s ease",
|
|
24181
|
+
pointerEvents: isVisible ? "auto" : "none",
|
|
24182
|
+
visibility: isVisible ? "visible" : "hidden",
|
|
24183
|
+
boxSizing: "border-box",
|
|
24184
|
+
overflow: "hidden"
|
|
24185
|
+
},
|
|
24186
|
+
...Array.isArray(sx) ? sx : [sx]
|
|
24187
|
+
],
|
|
24188
|
+
children: [
|
|
24189
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
24190
|
+
import_material33.Box,
|
|
24191
|
+
{
|
|
24192
|
+
sx: {
|
|
24193
|
+
display: "flex",
|
|
24194
|
+
alignItems: "center",
|
|
24195
|
+
justifyContent: "space-between",
|
|
24196
|
+
px: 2,
|
|
24197
|
+
pt: 1.5,
|
|
24198
|
+
pb: 1,
|
|
24199
|
+
borderBottom: "1px solid hsl(var(--border) / 0.6)",
|
|
24200
|
+
flexShrink: 0
|
|
24201
|
+
},
|
|
24202
|
+
children: [
|
|
24203
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_material33.Box, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
|
|
24204
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
24205
|
+
import_material33.Box,
|
|
24206
|
+
{
|
|
24207
|
+
sx: {
|
|
24208
|
+
width: 24,
|
|
24209
|
+
height: 24,
|
|
24210
|
+
borderRadius: "6px",
|
|
24211
|
+
bgcolor: "hsl(var(--primary) / 0.12)",
|
|
24212
|
+
border: "1px solid hsl(var(--primary) / 0.3)",
|
|
24213
|
+
display: "flex",
|
|
24214
|
+
alignItems: "center",
|
|
24215
|
+
justifyContent: "center",
|
|
24216
|
+
color: "hsl(var(--primary))",
|
|
24217
|
+
flexShrink: 0
|
|
24218
|
+
},
|
|
24219
|
+
children: safeActiveTab === "permissions" ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_lucide_react21.ShieldCheck, { size: 14 }) : safeActiveTab === "localLLM" ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_lucide_react21.Server, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(AgentIcon_default, { size: 14 })
|
|
24220
|
+
}
|
|
24221
|
+
),
|
|
24222
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
24223
|
+
import_material33.Typography,
|
|
24224
|
+
{
|
|
24225
|
+
sx: {
|
|
24226
|
+
fontWeight: 700,
|
|
24227
|
+
fontSize: "0.86rem",
|
|
24228
|
+
color: "hsl(var(--foreground))",
|
|
24229
|
+
letterSpacing: "-0.01em"
|
|
24230
|
+
},
|
|
24231
|
+
children: safeActiveTab === "permissions" ? "Agent Permissions" : safeActiveTab === "localLLM" ? "Local LLM Settings" : "Ask AI"
|
|
24232
|
+
}
|
|
24233
|
+
),
|
|
24234
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
24235
|
+
import_material33.Box,
|
|
24236
|
+
{
|
|
24237
|
+
sx: {
|
|
24238
|
+
fontSize: "0.66rem",
|
|
24239
|
+
fontWeight: 600,
|
|
24240
|
+
textTransform: "uppercase",
|
|
24241
|
+
letterSpacing: "0.04em",
|
|
24242
|
+
px: 0.75,
|
|
24243
|
+
py: 0.2,
|
|
24244
|
+
borderRadius: "4px",
|
|
24245
|
+
bgcolor: "hsl(var(--muted))",
|
|
24246
|
+
color: "hsl(var(--muted-foreground))",
|
|
24247
|
+
border: "1px solid hsl(var(--border))"
|
|
24248
|
+
},
|
|
24249
|
+
children: "Support only"
|
|
24250
|
+
}
|
|
24251
|
+
)
|
|
24252
|
+
] }),
|
|
24253
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_material33.Box, { sx: { display: "flex", alignItems: "center", gap: 0.5 }, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
24254
|
+
import_material33.IconButton,
|
|
24255
|
+
{
|
|
24256
|
+
onClick: onClose,
|
|
24257
|
+
size: "small",
|
|
24258
|
+
"aria-label": "Close Ask AI panel",
|
|
24259
|
+
sx: {
|
|
24260
|
+
color: "hsl(var(--muted-foreground))",
|
|
24261
|
+
p: 0.75,
|
|
24262
|
+
borderRadius: "8px",
|
|
24263
|
+
"&:hover": {
|
|
24264
|
+
color: "hsl(var(--foreground))",
|
|
24265
|
+
bgcolor: "hsl(var(--muted))"
|
|
24266
|
+
}
|
|
24267
|
+
},
|
|
24268
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_lucide_react21.X, { size: 16 })
|
|
24269
|
+
}
|
|
24270
|
+
) })
|
|
24271
|
+
]
|
|
24272
|
+
}
|
|
24273
|
+
),
|
|
24274
|
+
safeActiveTab === "localLLM" && effectiveLocalLLMSlot && /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
24275
|
+
import_material33.Box,
|
|
24276
|
+
{
|
|
24277
|
+
sx: {
|
|
24278
|
+
flex: 1,
|
|
24279
|
+
display: "flex",
|
|
24280
|
+
flexDirection: "column",
|
|
24281
|
+
minHeight: 0,
|
|
24282
|
+
overflow: "hidden"
|
|
24283
|
+
},
|
|
24284
|
+
children: [
|
|
24285
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
24286
|
+
import_material33.Box,
|
|
24287
|
+
{
|
|
24288
|
+
sx: {
|
|
24289
|
+
display: "flex",
|
|
24290
|
+
alignItems: "center",
|
|
24291
|
+
justifyContent: "space-between",
|
|
24292
|
+
px: 2,
|
|
24293
|
+
py: 1.25,
|
|
24294
|
+
borderBottom: "1px solid hsl(var(--border) / 0.6)",
|
|
24295
|
+
bgcolor: "hsl(var(--card))",
|
|
24296
|
+
flexShrink: 0
|
|
24297
|
+
},
|
|
24298
|
+
children: [
|
|
24299
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
24300
|
+
import_material33.ButtonBase,
|
|
24301
|
+
{
|
|
24302
|
+
onClick: () => handleTabChange("run"),
|
|
24303
|
+
sx: {
|
|
24304
|
+
display: "inline-flex",
|
|
24305
|
+
alignItems: "center",
|
|
24306
|
+
gap: 0.75,
|
|
24307
|
+
fontSize: "0.82rem",
|
|
24308
|
+
fontWeight: 600,
|
|
24309
|
+
color: "hsl(var(--primary))",
|
|
24310
|
+
py: 0.5,
|
|
24311
|
+
px: 1,
|
|
24312
|
+
borderRadius: 1,
|
|
24313
|
+
transition: "background-color 120ms ease",
|
|
24314
|
+
"&:hover": {
|
|
24315
|
+
bgcolor: "hsl(var(--muted))"
|
|
24316
|
+
}
|
|
24317
|
+
},
|
|
24318
|
+
children: [
|
|
24319
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_lucide_react21.ArrowLeft, { size: 14 }),
|
|
24320
|
+
"Back to chat"
|
|
24321
|
+
]
|
|
24322
|
+
}
|
|
24323
|
+
),
|
|
24324
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
24325
|
+
import_material33.Box,
|
|
24326
|
+
{
|
|
24327
|
+
sx: {
|
|
24328
|
+
display: "flex",
|
|
24329
|
+
alignItems: "center",
|
|
24330
|
+
gap: 0.5,
|
|
24331
|
+
fontSize: "0.78rem",
|
|
24332
|
+
color: "hsl(var(--muted-foreground))",
|
|
24333
|
+
fontWeight: 500
|
|
24334
|
+
},
|
|
24335
|
+
children: [
|
|
24336
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_lucide_react21.Server, { size: 13 }),
|
|
24337
|
+
"Local LLM",
|
|
24338
|
+
localLLMTabBadge
|
|
24339
|
+
]
|
|
24340
|
+
}
|
|
24341
|
+
)
|
|
24342
|
+
]
|
|
24343
|
+
}
|
|
24344
|
+
),
|
|
24345
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
24346
|
+
import_material33.Box,
|
|
24347
|
+
{
|
|
24348
|
+
sx: {
|
|
24349
|
+
flex: 1,
|
|
24350
|
+
overflowY: "auto",
|
|
24351
|
+
overflowX: "hidden",
|
|
24352
|
+
p: 2,
|
|
24353
|
+
minHeight: 0
|
|
24354
|
+
},
|
|
24355
|
+
children: effectiveLocalLLMSlot
|
|
24356
|
+
}
|
|
24357
|
+
)
|
|
24358
|
+
]
|
|
24359
|
+
}
|
|
24360
|
+
),
|
|
24361
|
+
safeActiveTab === "run" && /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_jsx_runtime38.Fragment, { children: [
|
|
24362
|
+
context.missingConfig && /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
24363
|
+
import_material33.Box,
|
|
24364
|
+
{
|
|
24365
|
+
sx: {
|
|
24366
|
+
mx: 2,
|
|
24367
|
+
mt: 1.5,
|
|
24368
|
+
mb: 0.5,
|
|
24369
|
+
p: 1.25,
|
|
24370
|
+
borderRadius: 1.5,
|
|
24371
|
+
bgcolor: "hsl(var(--warning) / 0.1)",
|
|
24372
|
+
border: "1px solid hsl(var(--warning) / 0.3)",
|
|
24373
|
+
color: "hsl(var(--warning))",
|
|
24374
|
+
display: "flex",
|
|
24375
|
+
flexDirection: "column",
|
|
24376
|
+
gap: 0.5,
|
|
24377
|
+
flexShrink: 0
|
|
24378
|
+
},
|
|
24379
|
+
children: [
|
|
24380
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
24381
|
+
import_material33.Box,
|
|
24382
|
+
{
|
|
24383
|
+
sx: {
|
|
24384
|
+
display: "flex",
|
|
24385
|
+
alignItems: "center",
|
|
24386
|
+
gap: 0.75,
|
|
24387
|
+
fontWeight: 600,
|
|
24388
|
+
fontSize: "0.78rem"
|
|
24389
|
+
},
|
|
24390
|
+
children: [
|
|
24391
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_lucide_react21.AlertTriangle, { size: 14 }),
|
|
24392
|
+
"Missing page configuration"
|
|
24393
|
+
]
|
|
24394
|
+
}
|
|
24395
|
+
),
|
|
24396
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
24397
|
+
import_material33.Typography,
|
|
24398
|
+
{
|
|
24399
|
+
sx: {
|
|
24400
|
+
fontSize: "0.72rem",
|
|
24401
|
+
color: "hsl(var(--muted-foreground))",
|
|
24402
|
+
lineHeight: 1.35
|
|
24403
|
+
},
|
|
24404
|
+
children: [
|
|
24405
|
+
"No specific MCP apps or skills mapped for",
|
|
24406
|
+
" ",
|
|
24407
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("code", { children: currentPathname }),
|
|
24408
|
+
". Using default platform tools. Support users: add a route mapping in",
|
|
24409
|
+
" ",
|
|
24410
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("code", { children: "agentContextRegistry.ts" }),
|
|
24411
|
+
" or manually choose tools below."
|
|
24412
|
+
]
|
|
24413
|
+
}
|
|
24414
|
+
)
|
|
24415
|
+
]
|
|
24416
|
+
}
|
|
24417
|
+
),
|
|
24418
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
24419
|
+
import_material33.Box,
|
|
24420
|
+
{
|
|
24421
|
+
sx: {
|
|
24422
|
+
flex: 1,
|
|
24423
|
+
overflowY: "auto",
|
|
24424
|
+
overflowX: "hidden",
|
|
24425
|
+
px: 1.5,
|
|
24426
|
+
pb: 2,
|
|
24427
|
+
minHeight: 0,
|
|
24428
|
+
display: "flex",
|
|
24429
|
+
flexDirection: "column"
|
|
24430
|
+
},
|
|
24431
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
24432
|
+
AgentUI_default,
|
|
24433
|
+
{
|
|
24434
|
+
compact: true,
|
|
24435
|
+
mobileView: true,
|
|
24436
|
+
hideHeroIcon: true,
|
|
24437
|
+
title: context.title || "How can we help on this page?",
|
|
24438
|
+
subtitle: null,
|
|
24439
|
+
hideChooseLLM: false,
|
|
24440
|
+
disableSchedule: true,
|
|
24441
|
+
hideAttach: false,
|
|
24442
|
+
maxWidth: effectiveWidth - 32,
|
|
24443
|
+
defaultApps: context.apps,
|
|
24444
|
+
initialPresetId: context.presetId,
|
|
24445
|
+
placeholder: context.placeholder,
|
|
24446
|
+
contextCategory: context.sourceCategory,
|
|
24447
|
+
contextStorageKey: context.storageKey,
|
|
24448
|
+
onAppsChange: handleAppsChange,
|
|
24449
|
+
onSelectPreset: handleSelectPreset,
|
|
24450
|
+
onChooseLLM: () => handleTabChange("localLLM"),
|
|
24451
|
+
apiBaseUrl: globalUrl || agentUIProps?.apiBaseUrl,
|
|
24452
|
+
theme: effectiveTheme,
|
|
24453
|
+
...agentUIProps,
|
|
24454
|
+
sx: {
|
|
24455
|
+
flex: 1,
|
|
24456
|
+
minHeight: "100%",
|
|
24457
|
+
display: "flex",
|
|
24458
|
+
flexDirection: "column",
|
|
24459
|
+
justifyContent: "center",
|
|
24460
|
+
pt: 0,
|
|
24461
|
+
pb: 2,
|
|
24462
|
+
...agentUIProps?.sx ? Array.isArray(agentUIProps.sx) ? {} : agentUIProps.sx : {}
|
|
24463
|
+
}
|
|
24464
|
+
},
|
|
24465
|
+
context.storageKey
|
|
24466
|
+
)
|
|
24467
|
+
}
|
|
24468
|
+
)
|
|
24469
|
+
] })
|
|
24470
|
+
]
|
|
24471
|
+
}
|
|
24472
|
+
)
|
|
24473
|
+
] });
|
|
24474
|
+
};
|
|
24475
|
+
var AskAiSidePanel_default = AskAiSidePanel;
|
|
24476
|
+
|
|
24477
|
+
// components/AskAiWidget.tsx
|
|
24478
|
+
var import_react33 = require("react");
|
|
24479
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
24480
|
+
var AGENT_DRAWER_OPEN_EVENT2 = "agent-drawer-open";
|
|
24481
|
+
var AskAiWidget = ({
|
|
24482
|
+
open: controlledOpen,
|
|
24483
|
+
onOpenChange,
|
|
24484
|
+
mode = "panel",
|
|
24485
|
+
isSupport,
|
|
24486
|
+
requireSupport = true,
|
|
24487
|
+
buttonProps,
|
|
24488
|
+
hideButton = false,
|
|
24489
|
+
pathname,
|
|
24490
|
+
search,
|
|
24491
|
+
rules,
|
|
24492
|
+
initialTab: propInitialTab = "run",
|
|
24493
|
+
onContextResolved,
|
|
24494
|
+
permissionsSlot,
|
|
24495
|
+
localLLMSlot,
|
|
24496
|
+
...panelProps
|
|
24497
|
+
}) => {
|
|
24498
|
+
const [internalOpen, setInternalOpen] = (0, import_react33.useState)(false);
|
|
24499
|
+
const [activeTab, setActiveTab] = (0, import_react33.useState)(propInitialTab);
|
|
24500
|
+
const isDrawerOpen = controlledOpen !== void 0 ? controlledOpen : internalOpen;
|
|
24501
|
+
const currentPath = pathname !== void 0 ? pathname : typeof window !== "undefined" ? window.location.pathname : "";
|
|
24502
|
+
const isAgentDisabled = isAgentRoute(currentPath);
|
|
24503
|
+
const setDrawerOpen = (0, import_react33.useCallback)(
|
|
24504
|
+
(nextOpen) => {
|
|
24505
|
+
if (isAgentDisabled && nextOpen) return;
|
|
24506
|
+
if (controlledOpen === void 0) {
|
|
24507
|
+
setInternalOpen(nextOpen);
|
|
24508
|
+
}
|
|
24509
|
+
onOpenChange?.(nextOpen);
|
|
24510
|
+
},
|
|
24511
|
+
[controlledOpen, isAgentDisabled, onOpenChange]
|
|
24512
|
+
);
|
|
24513
|
+
(0, import_react33.useEffect)(() => {
|
|
24514
|
+
if (isAgentDisabled && isDrawerOpen) {
|
|
24515
|
+
setDrawerOpen(false);
|
|
24516
|
+
}
|
|
24517
|
+
}, [isAgentDisabled, isDrawerOpen, setDrawerOpen]);
|
|
24518
|
+
const [currentContext, setCurrentContext] = (0, import_react33.useState)(null);
|
|
24519
|
+
const handleContextResolved = (0, import_react33.useCallback)(
|
|
24520
|
+
(ctx) => {
|
|
24521
|
+
setCurrentContext(ctx);
|
|
24522
|
+
onContextResolved?.(ctx);
|
|
24523
|
+
},
|
|
24524
|
+
[onContextResolved]
|
|
24525
|
+
);
|
|
24526
|
+
(0, import_react33.useEffect)(() => {
|
|
24527
|
+
const handleDrawerOpenEvent = (e) => {
|
|
24528
|
+
if (isAgentDisabled) return;
|
|
24529
|
+
const detail = e.detail;
|
|
24530
|
+
if (detail?.tab) {
|
|
24531
|
+
setActiveTab(detail.tab);
|
|
24532
|
+
}
|
|
24533
|
+
setDrawerOpen(true);
|
|
24534
|
+
};
|
|
24535
|
+
window.addEventListener(AGENT_DRAWER_OPEN_EVENT2, handleDrawerOpenEvent);
|
|
24536
|
+
return () => window.removeEventListener(AGENT_DRAWER_OPEN_EVENT2, handleDrawerOpenEvent);
|
|
24537
|
+
}, [isAgentDisabled, setDrawerOpen]);
|
|
24538
|
+
(0, import_react33.useEffect)(() => {
|
|
24539
|
+
if (propInitialTab) {
|
|
24540
|
+
setActiveTab(propInitialTab);
|
|
24541
|
+
}
|
|
24542
|
+
}, [propInitialTab]);
|
|
24543
|
+
const contextHint = currentContext?.apps && currentContext.apps.length > 0 ? currentContext.apps.map((a) => a.name.replace(/^shuffle_/, "").replace(/_/g, " ")).join(", ") : void 0;
|
|
24544
|
+
if (isAgentDisabled) {
|
|
24545
|
+
return null;
|
|
24546
|
+
}
|
|
24547
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_jsx_runtime39.Fragment, { children: [
|
|
24548
|
+
!hideButton && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
24549
|
+
AskAiButton,
|
|
24550
|
+
{
|
|
24551
|
+
onClick: () => setDrawerOpen(!isDrawerOpen),
|
|
24552
|
+
isOpen: isDrawerOpen,
|
|
24553
|
+
isSupport,
|
|
24554
|
+
requireSupport,
|
|
24555
|
+
pathname,
|
|
24556
|
+
contextHint,
|
|
24557
|
+
...buttonProps
|
|
24558
|
+
}
|
|
24559
|
+
),
|
|
24560
|
+
mode === "drawer" ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
24561
|
+
AskAiDrawer,
|
|
24562
|
+
{
|
|
24563
|
+
open: isDrawerOpen,
|
|
24564
|
+
onClose: () => setDrawerOpen(false),
|
|
24565
|
+
initialTab: activeTab,
|
|
24566
|
+
pathname,
|
|
24567
|
+
search,
|
|
24568
|
+
rules,
|
|
24569
|
+
permissionsSlot,
|
|
24570
|
+
localLLMSlot,
|
|
24571
|
+
onContextResolved: handleContextResolved,
|
|
24572
|
+
...panelProps
|
|
24573
|
+
}
|
|
24574
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
24575
|
+
AskAiSidePanel,
|
|
24576
|
+
{
|
|
24577
|
+
open: isDrawerOpen,
|
|
24578
|
+
onClose: () => setDrawerOpen(false),
|
|
24579
|
+
initialTab: activeTab,
|
|
24580
|
+
activeTab,
|
|
24581
|
+
onTabChange: setActiveTab,
|
|
24582
|
+
permissionsSlot,
|
|
24583
|
+
localLLMSlot,
|
|
24584
|
+
pathname,
|
|
24585
|
+
search,
|
|
24586
|
+
rules,
|
|
24587
|
+
isSupport,
|
|
24588
|
+
onContextResolved: handleContextResolved,
|
|
24589
|
+
...panelProps
|
|
24590
|
+
}
|
|
24591
|
+
)
|
|
24592
|
+
] });
|
|
24593
|
+
};
|
|
24594
|
+
var useContextAwareAgent = (pathname, search) => {
|
|
24595
|
+
const [activeContext, setActiveContext] = (0, import_react33.useState)(() => {
|
|
24596
|
+
const p = pathname ?? (typeof window !== "undefined" ? window.location.pathname : "/");
|
|
24597
|
+
const s = search ?? (typeof window !== "undefined" ? window.location.search : "");
|
|
24598
|
+
return resolveAgentContext(p, s);
|
|
24599
|
+
});
|
|
24600
|
+
(0, import_react33.useEffect)(() => {
|
|
24601
|
+
const p = pathname ?? (typeof window !== "undefined" ? window.location.pathname : "/");
|
|
24602
|
+
const s = search ?? (typeof window !== "undefined" ? window.location.search : "");
|
|
24603
|
+
setActiveContext(resolveAgentContext(p, s));
|
|
24604
|
+
}, [pathname, search]);
|
|
24605
|
+
return activeContext;
|
|
24606
|
+
};
|
|
24607
|
+
var AskAiWidget_default = AskAiWidget;
|
|
24608
|
+
|
|
24609
|
+
// components/AgentPromptPrefixChip.tsx
|
|
24610
|
+
var import_react34 = require("react");
|
|
24611
|
+
var import_material34 = require("@mui/material");
|
|
24612
|
+
var import_lucide_react22 = require("lucide-react");
|
|
24613
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
24614
|
+
var AgentPromptPrefixChip = ({
|
|
24615
|
+
label = "Shuffle Tools MCP",
|
|
24616
|
+
userId,
|
|
24617
|
+
value,
|
|
24618
|
+
onChange,
|
|
24619
|
+
onRemove,
|
|
24620
|
+
defaultPrompt,
|
|
24621
|
+
dialogTitle,
|
|
24622
|
+
readOnly
|
|
24623
|
+
}) => {
|
|
24624
|
+
const controlled = value !== void 0;
|
|
24625
|
+
const managed = useAgentPromptPrefix({ userId, defaultPrompt, persist: !controlled });
|
|
24626
|
+
const prompt = controlled ? value : managed.prompt;
|
|
24627
|
+
const isSaving = controlled ? false : managed.isSaving;
|
|
24628
|
+
const [open, setOpen] = (0, import_react34.useState)(false);
|
|
24629
|
+
const [draft, setDraft] = (0, import_react34.useState)(prompt);
|
|
24630
|
+
(0, import_react34.useEffect)(() => {
|
|
24631
|
+
if (!open) setDraft(prompt);
|
|
24632
|
+
}, [prompt, open]);
|
|
24633
|
+
const handleOpen = () => {
|
|
24634
|
+
if (readOnly) return;
|
|
24635
|
+
setDraft(prompt);
|
|
24636
|
+
setOpen(true);
|
|
24637
|
+
};
|
|
24638
|
+
const handleSave = async () => {
|
|
24639
|
+
if (controlled) {
|
|
24640
|
+
await onChange?.(draft);
|
|
24641
|
+
} else {
|
|
24642
|
+
await managed.savePrompt(draft);
|
|
24643
|
+
}
|
|
24644
|
+
setOpen(false);
|
|
24645
|
+
};
|
|
24646
|
+
const MAX_LABEL_CHARS = 15;
|
|
24647
|
+
const displayLabel = label.length > MAX_LABEL_CHARS ? `${label.slice(0, MAX_LABEL_CHARS - 1).trimEnd()}\u2026` : label;
|
|
24648
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_jsx_runtime40.Fragment, { children: [
|
|
24649
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_material34.Tooltip, { title: readOnly ? `${label} \u2014 preset handled by the backend` : "Click to edit the default prompt sent with your message", placement: "top", arrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
24650
|
+
import_material34.Box,
|
|
24651
|
+
{
|
|
24652
|
+
sx: {
|
|
24653
|
+
display: "inline-flex",
|
|
24654
|
+
alignItems: "center",
|
|
24655
|
+
gap: 0.25,
|
|
24656
|
+
px: 0.5,
|
|
24657
|
+
borderRadius: 0.5,
|
|
22354
24658
|
bgcolor: "transparent",
|
|
22355
24659
|
flexShrink: 0,
|
|
22356
24660
|
userSelect: "none",
|
|
@@ -22358,8 +24662,8 @@ var AgentPromptPrefixChip = ({
|
|
|
22358
24662
|
"&:hover": readOnly ? void 0 : { bgcolor: "hsl(var(--muted))" }
|
|
22359
24663
|
},
|
|
22360
24664
|
children: [
|
|
22361
|
-
/* @__PURE__ */ (0,
|
|
22362
|
-
|
|
24665
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
24666
|
+
import_material34.Box,
|
|
22363
24667
|
{
|
|
22364
24668
|
onClick: handleOpen,
|
|
22365
24669
|
role: readOnly ? void 0 : "button",
|
|
@@ -22376,8 +24680,8 @@ var AgentPromptPrefixChip = ({
|
|
|
22376
24680
|
cursor: readOnly ? "default" : "pointer"
|
|
22377
24681
|
},
|
|
22378
24682
|
"aria-label": readOnly ? `${label} preset selected` : `Edit default prompt for ${label}`,
|
|
22379
|
-
children: /* @__PURE__ */ (0,
|
|
22380
|
-
|
|
24683
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
24684
|
+
import_material34.Typography,
|
|
22381
24685
|
{
|
|
22382
24686
|
component: "span",
|
|
22383
24687
|
sx: {
|
|
@@ -22392,8 +24696,8 @@ var AgentPromptPrefixChip = ({
|
|
|
22392
24696
|
)
|
|
22393
24697
|
}
|
|
22394
24698
|
),
|
|
22395
|
-
onRemove && /* @__PURE__ */ (0,
|
|
22396
|
-
|
|
24699
|
+
onRemove && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
24700
|
+
import_material34.IconButton,
|
|
22397
24701
|
{
|
|
22398
24702
|
size: "small",
|
|
22399
24703
|
onClick: (e) => {
|
|
@@ -22408,14 +24712,14 @@ var AgentPromptPrefixChip = ({
|
|
|
22408
24712
|
"&:hover": { color: "hsl(var(--destructive))", bgcolor: "transparent" }
|
|
22409
24713
|
},
|
|
22410
24714
|
"aria-label": `Remove ${label} preset`,
|
|
22411
|
-
children: /* @__PURE__ */ (0,
|
|
24715
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react22.X, { size: 12 })
|
|
22412
24716
|
}
|
|
22413
24717
|
)
|
|
22414
24718
|
]
|
|
22415
24719
|
}
|
|
22416
24720
|
) }),
|
|
22417
|
-
/* @__PURE__ */ (0,
|
|
22418
|
-
|
|
24721
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
24722
|
+
import_material34.Dialog,
|
|
22419
24723
|
{
|
|
22420
24724
|
open,
|
|
22421
24725
|
onClose: () => setOpen(false),
|
|
@@ -22431,15 +24735,15 @@ var AgentPromptPrefixChip = ({
|
|
|
22431
24735
|
}
|
|
22432
24736
|
},
|
|
22433
24737
|
children: [
|
|
22434
|
-
/* @__PURE__ */ (0,
|
|
22435
|
-
/* @__PURE__ */ (0,
|
|
22436
|
-
/* @__PURE__ */ (0,
|
|
22437
|
-
/* @__PURE__ */ (0,
|
|
24738
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_material34.DialogTitle, { sx: { display: "flex", alignItems: "center", justifyContent: "space-between", pr: 1.5, borderBottom: "1px solid hsl(var(--border))" }, children: [
|
|
24739
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_material34.Box, { children: [
|
|
24740
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_material34.Typography, { sx: { fontSize: "1rem", fontWeight: 600, color: "hsl(var(--foreground))" }, children: dialogTitle || `Edit default prompt \u2014 ${label}` }),
|
|
24741
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_material34.Typography, { sx: { fontSize: "0.75rem", color: "hsl(var(--muted-foreground))", mt: 0.25 }, children: isSaving ? "Saving\u2026" : "This text is prepended to every message you send from this prompt box. Saved to your user preferences." })
|
|
22438
24742
|
] }),
|
|
22439
|
-
/* @__PURE__ */ (0,
|
|
24743
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_material34.IconButton, { size: "small", onClick: () => setOpen(false), sx: { color: "hsl(var(--muted-foreground))" }, "aria-label": "Close", children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react22.X, { size: 16 }) })
|
|
22440
24744
|
] }),
|
|
22441
|
-
/* @__PURE__ */ (0,
|
|
22442
|
-
|
|
24745
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_material34.DialogContent, { sx: { pt: 2 }, children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
24746
|
+
import_material34.TextField,
|
|
22443
24747
|
{
|
|
22444
24748
|
autoFocus: true,
|
|
22445
24749
|
fullWidth: true,
|
|
@@ -22460,10 +24764,10 @@ var AgentPromptPrefixChip = ({
|
|
|
22460
24764
|
}
|
|
22461
24765
|
}
|
|
22462
24766
|
) }),
|
|
22463
|
-
/* @__PURE__ */ (0,
|
|
22464
|
-
/* @__PURE__ */ (0,
|
|
22465
|
-
/* @__PURE__ */ (0,
|
|
22466
|
-
|
|
24767
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_material34.DialogActions, { sx: { px: 3, py: 2, borderTop: "1px solid hsl(var(--border))" }, children: [
|
|
24768
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_material34.Button, { onClick: () => setOpen(false), sx: { textTransform: "none", color: "hsl(var(--muted-foreground))" }, children: "Cancel" }),
|
|
24769
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
24770
|
+
import_material34.Button,
|
|
22467
24771
|
{
|
|
22468
24772
|
onClick: handleSave,
|
|
22469
24773
|
variant: "contained",
|
|
@@ -22485,14 +24789,14 @@ var AgentPromptPrefixChip = ({
|
|
|
22485
24789
|
};
|
|
22486
24790
|
|
|
22487
24791
|
// useAppLookup.ts
|
|
22488
|
-
var
|
|
24792
|
+
var import_react35 = require("react");
|
|
22489
24793
|
init_api();
|
|
22490
24794
|
init_appsCache();
|
|
22491
24795
|
var norm3 = (s) => s.toLowerCase().replace(/[\s_\-]+/g, "_");
|
|
22492
24796
|
function useAppLookup(appName) {
|
|
22493
|
-
const [loading, setLoading] = (0,
|
|
22494
|
-
const [info, setInfo] = (0,
|
|
22495
|
-
const [algoliaId, setAlgoliaId] = (0,
|
|
24797
|
+
const [loading, setLoading] = (0, import_react35.useState)(false);
|
|
24798
|
+
const [info, setInfo] = (0, import_react35.useState)(null);
|
|
24799
|
+
const [algoliaId, setAlgoliaId] = (0, import_react35.useState)(null);
|
|
22496
24800
|
const {
|
|
22497
24801
|
authStates,
|
|
22498
24802
|
authenticatedApps,
|
|
@@ -22501,7 +24805,7 @@ function useAppLookup(appName) {
|
|
|
22501
24805
|
handleSaveAuth,
|
|
22502
24806
|
refreshAuth
|
|
22503
24807
|
} = useAppAuth();
|
|
22504
|
-
(0,
|
|
24808
|
+
(0, import_react35.useEffect)(() => {
|
|
22505
24809
|
if (!appName) {
|
|
22506
24810
|
setInfo(null);
|
|
22507
24811
|
setAlgoliaId(null);
|
|
@@ -22572,13 +24876,13 @@ function useAppLookup(appName) {
|
|
|
22572
24876
|
setLoading(false);
|
|
22573
24877
|
})();
|
|
22574
24878
|
}, [appName]);
|
|
22575
|
-
const matchingEntries = (0,
|
|
24879
|
+
const matchingEntries = (0, import_react35.useMemo)(() => {
|
|
22576
24880
|
if (!appName) return [];
|
|
22577
24881
|
return authenticatedApps.filter(
|
|
22578
24882
|
(auth) => auth.app?.name && norm3(auth.app.name) === norm3(appName)
|
|
22579
24883
|
);
|
|
22580
24884
|
}, [appName, authenticatedApps]);
|
|
22581
|
-
const image = (0,
|
|
24885
|
+
const image = (0, import_react35.useMemo)(() => {
|
|
22582
24886
|
if (info?.image) return info.image;
|
|
22583
24887
|
for (const entry of matchingEntries) {
|
|
22584
24888
|
const img = entry.app?.large_image || entry.large_image;
|
|
@@ -22586,7 +24890,7 @@ function useAppLookup(appName) {
|
|
|
22586
24890
|
}
|
|
22587
24891
|
return "";
|
|
22588
24892
|
}, [info, matchingEntries]);
|
|
22589
|
-
const algoliaApp = (0,
|
|
24893
|
+
const algoliaApp = (0, import_react35.useMemo)(() => {
|
|
22590
24894
|
if (!appName) return null;
|
|
22591
24895
|
return {
|
|
22592
24896
|
objectID: algoliaId || appName,
|
|
@@ -22625,23 +24929,23 @@ var resolveMode = (theme, colorMode) => {
|
|
|
22625
24929
|
if (theme === "light" || theme === "dark") return theme;
|
|
22626
24930
|
if (theme === "system") return "auto";
|
|
22627
24931
|
if (colorMode) return colorMode;
|
|
22628
|
-
return "
|
|
24932
|
+
return "auto";
|
|
22629
24933
|
};
|
|
22630
24934
|
var withMcpTheme = (Inner, displayName2) => {
|
|
22631
|
-
const Wrapped = ({ theme, colorMode, ...rest }) =>
|
|
24935
|
+
const Wrapped = ({ theme, colorMode, ...rest }) => import_react36.default.createElement(
|
|
22632
24936
|
ShuffleMcpThemeProvider,
|
|
22633
24937
|
{ mode: resolveMode(theme, colorMode) },
|
|
22634
|
-
|
|
24938
|
+
import_react36.default.createElement(Inner, { ...rest, theme, colorMode })
|
|
22635
24939
|
);
|
|
22636
24940
|
Wrapped.displayName = `ShuffleMCPs(${displayName2})`;
|
|
22637
24941
|
return Wrapped;
|
|
22638
24942
|
};
|
|
22639
24943
|
var withMcpThemeRef = (Inner, displayName2) => {
|
|
22640
|
-
const Wrapped =
|
|
22641
|
-
({ theme, colorMode, ...rest }, ref) =>
|
|
24944
|
+
const Wrapped = import_react36.default.forwardRef(
|
|
24945
|
+
({ theme, colorMode, ...rest }, ref) => import_react36.default.createElement(
|
|
22642
24946
|
ShuffleMcpThemeProvider,
|
|
22643
24947
|
{ mode: resolveMode(theme, colorMode) },
|
|
22644
|
-
|
|
24948
|
+
import_react36.default.createElement(Inner, { ...rest, theme, colorMode, ref })
|
|
22645
24949
|
)
|
|
22646
24950
|
);
|
|
22647
24951
|
Wrapped.displayName = `ShuffleMCPs(${displayName2})`;
|
|
@@ -22659,6 +24963,10 @@ var TryMcpSection2 = withMcpTheme(TryMcpSection, "TryMcpSection");
|
|
|
22659
24963
|
var SingulActionsPreview2 = withMcpTheme(SingulActionsPreview_default, "SingulActionsPreview");
|
|
22660
24964
|
var AgentUI2 = withMcpTheme(AgentUI_default, "AgentUI");
|
|
22661
24965
|
var AgentRunDrawer2 = withMcpTheme(AgentRunDrawer_default, "AgentRunDrawer");
|
|
24966
|
+
var AskAiButton2 = withMcpTheme(AskAiButton_default, "AskAiButton");
|
|
24967
|
+
var AskAiDrawer2 = withMcpTheme(AskAiDrawer_default, "AskAiDrawer");
|
|
24968
|
+
var AskAiSidePanel2 = withMcpTheme(AskAiSidePanel_default, "AskAiSidePanel");
|
|
24969
|
+
var AskAiWidget2 = withMcpTheme(AskAiWidget_default, "AskAiWidget");
|
|
22662
24970
|
var AgentActivityList2 = withMcpTheme(AgentActivityList_default, "AgentActivityList");
|
|
22663
24971
|
var AgentExecutionDrawer2 = withMcpTheme(AgentExecutionDrawer_default, "AgentExecutionDrawer");
|
|
22664
24972
|
var AgentsView2 = withMcpTheme(AgentsView_default, "AgentsView");
|
|
@@ -22688,9 +24996,14 @@ var AddAppModal2 = withMcpTheme(AddAppModal_default, "AddAppModal");
|
|
|
22688
24996
|
AppDetailProvider,
|
|
22689
24997
|
AppSearchDrawer,
|
|
22690
24998
|
AppTitleHeader,
|
|
24999
|
+
AskAiButton,
|
|
25000
|
+
AskAiDrawer,
|
|
25001
|
+
AskAiSidePanel,
|
|
25002
|
+
AskAiWidget,
|
|
22691
25003
|
CASES_PATTERNS,
|
|
22692
25004
|
COMMUNICATION_PATTERNS_NAMES,
|
|
22693
25005
|
DATASTORE_CATEGORIES,
|
|
25006
|
+
DEFAULT_AGENT_CONTEXT_RULES,
|
|
22694
25007
|
DEFAULT_AGENT_PROMPT_PREFIX,
|
|
22695
25008
|
EDR_PATTERNS,
|
|
22696
25009
|
EMAIL_APP_PATTERNS,
|
|
@@ -22712,6 +25025,7 @@ var AddAppModal2 = withMcpTheme(AddAppModal_default, "AddAppModal");
|
|
|
22712
25025
|
VULN_SCANNER_PATTERNS,
|
|
22713
25026
|
VideoEmbed,
|
|
22714
25027
|
applyRegionFromPayload,
|
|
25028
|
+
clearPageContextChoice,
|
|
22715
25029
|
deleteDatastoreItem,
|
|
22716
25030
|
deleteDatastoreItems,
|
|
22717
25031
|
diagnoseOutputWarning,
|
|
@@ -22723,6 +25037,8 @@ var AddAppModal2 = withMcpTheme(AddAppModal_default, "AddAppModal");
|
|
|
22723
25037
|
fetchAppsViaApiConfig,
|
|
22724
25038
|
findForwardTicketsWorkflow,
|
|
22725
25039
|
findIngestTicketsWorkflow,
|
|
25040
|
+
getActivePageEntityName,
|
|
25041
|
+
getAgentContextRules,
|
|
22726
25042
|
getApiUrl,
|
|
22727
25043
|
getAuthHeader,
|
|
22728
25044
|
getDatastoreByCategory,
|
|
@@ -22732,10 +25048,12 @@ var AddAppModal2 = withMcpTheme(AddAppModal_default, "AddAppModal");
|
|
|
22732
25048
|
getFailureInfo,
|
|
22733
25049
|
getHostBaseUrl,
|
|
22734
25050
|
getIngestionCategory,
|
|
25051
|
+
getPageContextChoice,
|
|
22735
25052
|
hasOutputWarning,
|
|
22736
25053
|
installFetchBreaker,
|
|
22737
25054
|
invalidateAppsCache,
|
|
22738
25055
|
invalidateResolvedApps,
|
|
25056
|
+
isAgentRoute,
|
|
22739
25057
|
isCloud,
|
|
22740
25058
|
isCloudDomain,
|
|
22741
25059
|
isEmailApp,
|
|
@@ -22744,11 +25062,14 @@ var AddAppModal2 = withMcpTheme(AddAppModal_default, "AddAppModal");
|
|
|
22744
25062
|
isThreatIntelApp,
|
|
22745
25063
|
isVulnScannerApp,
|
|
22746
25064
|
isWorkflowScheduleStopped,
|
|
25065
|
+
matchRoutePattern,
|
|
22747
25066
|
normalizeAppName,
|
|
22748
25067
|
parseRunResult,
|
|
22749
25068
|
refreshAllIntegrationStatus,
|
|
25069
|
+
registerAgentContextRule,
|
|
22750
25070
|
registerProtectedOrigin,
|
|
22751
25071
|
resetRegionUrl,
|
|
25072
|
+
resolveAgentContext,
|
|
22752
25073
|
resolveApp,
|
|
22753
25074
|
resolveApps,
|
|
22754
25075
|
resolveVideoUrl,
|
|
@@ -22758,6 +25079,7 @@ var AddAppModal2 = withMcpTheme(AddAppModal_default, "AddAppModal");
|
|
|
22758
25079
|
setDatastoreItem,
|
|
22759
25080
|
setDatastoreItems,
|
|
22760
25081
|
setHostBaseUrl,
|
|
25082
|
+
setPageContextChoice,
|
|
22761
25083
|
setRegionUrl,
|
|
22762
25084
|
setRuntimeOrgId,
|
|
22763
25085
|
setToastImpl,
|
|
@@ -22769,5 +25091,6 @@ var AddAppModal2 = withMcpTheme(AddAppModal_default, "AddAppModal");
|
|
|
22769
25091
|
useAppDetail,
|
|
22770
25092
|
useAppDetailOptional,
|
|
22771
25093
|
useAppLookup,
|
|
25094
|
+
useContextAwareAgent,
|
|
22772
25095
|
useSyncHostBaseUrl
|
|
22773
25096
|
});
|