@shuffleio/shuffle-mcps 0.0.56 → 0.0.58

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/index.mjs CHANGED
@@ -23,7 +23,7 @@ import {
23
23
  setHostBaseUrl,
24
24
  setRegionUrl,
25
25
  shuffleFetch
26
- } from "./chunk-45B7UK6Q.mjs";
26
+ } from "./chunk-7HRNENGV.mjs";
27
27
 
28
28
  // index.ts
29
29
  import "./shuffle-mcp-SHQXQS3F.css";
@@ -240,7 +240,7 @@ var ShuffleMcpThemeProvider = ({
240
240
  };
241
241
 
242
242
  // views/ShuffleMCP.tsx
243
- import React4, { useState as useState10, useEffect as useEffect8, useRef as useRef8, useCallback as useCallback7, useMemo as useMemo6, useImperativeHandle } from "react";
243
+ import React4, { useState as useState11, useEffect as useEffect9, useRef as useRef8, useCallback as useCallback7, useMemo as useMemo6, useImperativeHandle } from "react";
244
244
  import { algoliasearch } from "algoliasearch";
245
245
  import { Tooltip as Tooltip6 } from "@mui/material";
246
246
 
@@ -1592,10 +1592,10 @@ var setRuntimeOrgId = (orgId) => {
1592
1592
  var getOrgId = () => {
1593
1593
  if (_runtimeOrgId) return _runtimeOrgId;
1594
1594
  try {
1595
- const userInfo = localStorage.getItem("shuffle_user_info");
1595
+ const userInfo = localStorage.getItem("shuffle_user_info") || localStorage.getItem("userinfo") || localStorage.getItem("user_info");
1596
1596
  if (userInfo) {
1597
1597
  const parsed = JSON.parse(userInfo);
1598
- return parsed.active_org?.id || null;
1598
+ return parsed.active_org?.id || parsed.org_id || parsed.active_org_id || parsed.orgs && parsed.orgs[0]?.id || null;
1599
1599
  }
1600
1600
  } catch {
1601
1601
  }
@@ -2411,6 +2411,7 @@ var deleteDatastoreItems = async (keys2, category) => {
2411
2411
  };
2412
2412
  var DATASTORE_CATEGORIES = {
2413
2413
  INCIDENTS: "shuffle-security_incidents",
2414
+ EVENTS: "shuffle-security_events",
2414
2415
  VULNERABILITIES: "shuffle-security_vulns",
2415
2416
  VULNS: "shuffle-security_vulns",
2416
2417
  ASSETS: "shuffle-security_assets",
@@ -2731,13 +2732,22 @@ var useSyncHostBaseUrl = (globalUrl) => {
2731
2732
  };
2732
2733
 
2733
2734
  // auth-utils.ts
2735
+ var THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1e3;
2736
+ function isValidationFresh(validation) {
2737
+ if (validation?.valid !== true) return false;
2738
+ if (!validation.last_valid) return true;
2739
+ const cutoff = Date.now() - THIRTY_DAYS_MS;
2740
+ const lastValidMs = validation.last_valid > 1e12 ? validation.last_valid : validation.last_valid * 1e3;
2741
+ return lastValidMs >= cutoff;
2742
+ }
2734
2743
  function deduplicateAuthApps(apps) {
2735
2744
  const appMap = /* @__PURE__ */ new Map();
2736
2745
  apps.forEach((auth) => {
2737
- if (!auth.active && !auth.validation?.valid) return;
2746
+ if (!auth.app?.name) return;
2747
+ if (!auth.active && !isValidationFresh(auth.validation)) return;
2738
2748
  const normalizedName = auth.app.name.toLowerCase().trim().replace(/[\s_\-]+/g, "_");
2739
2749
  const existing = appMap.get(normalizedName);
2740
- const isValidated = auth.validation?.valid === true;
2750
+ const isValidated = isValidationFresh(auth.validation);
2741
2751
  const entryImage = auth.app.large_image || "";
2742
2752
  const instance = {
2743
2753
  label: auth.label || auth.id || "Default",
@@ -2778,7 +2788,7 @@ async function backfillAppImages(dedupedApps) {
2778
2788
  let missing = dedupedApps.filter((d) => !d.bestImage && !d.app.large_image);
2779
2789
  if (missing.length === 0) return dedupedApps;
2780
2790
  try {
2781
- const { fetchAppsViaApiConfig: fetchAppsViaApiConfig2 } = await import("./appsCache-ITT5ZZQS.mjs");
2791
+ const { fetchAppsViaApiConfig: fetchAppsViaApiConfig2 } = await import("./appsCache-VD3DQH53.mjs");
2782
2792
  const apps = await fetchAppsViaApiConfig2().catch(() => []);
2783
2793
  if (Array.isArray(apps) && apps.length > 0) {
2784
2794
  const byName = /* @__PURE__ */ new Map();
@@ -2953,7 +2963,7 @@ function findForwardTicketsWorkflow(workflows) {
2953
2963
  }
2954
2964
  function extractValidatedIngestionApps(authApiResponse, workflowAppNames) {
2955
2965
  const dedupedApps = deduplicateAuthApps(
2956
- authApiResponse.filter((auth) => auth.active || auth.validation?.valid)
2966
+ authApiResponse.filter((auth) => auth.active || isValidationFresh(auth.validation))
2957
2967
  );
2958
2968
  const enabledNames = workflowAppNames || /* @__PURE__ */ new Set();
2959
2969
  const apps = [];
@@ -3056,9 +3066,9 @@ function invalidateAuthCache() {
3056
3066
  var TTL_MS = 3e4;
3057
3067
  var cache2 = /* @__PURE__ */ new Map();
3058
3068
  var cacheKey = (crossOrgId) => crossOrgId || "";
3059
- var THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1e3;
3069
+ var THIRTY_DAYS_MS2 = 30 * 24 * 60 * 60 * 1e3;
3060
3070
  var applyValidationStaleness = (data) => {
3061
- const cutoff = Date.now() - THIRTY_DAYS_MS;
3071
+ const cutoff = Date.now() - THIRTY_DAYS_MS2;
3062
3072
  return data.map((entry) => {
3063
3073
  const v = entry.validation;
3064
3074
  if (v?.valid === true && v?.last_valid) {
@@ -3071,7 +3081,7 @@ var applyValidationStaleness = (data) => {
3071
3081
  });
3072
3082
  };
3073
3083
  var doFetch2 = async (crossOrgId) => {
3074
- if (!hasShuffleAuth()) return [];
3084
+ if (!hasShuffleAuth()) return { data: [], failed: false };
3075
3085
  const headers = {
3076
3086
  ...getAuthHeader(crossOrgId ?? void 0)
3077
3087
  };
@@ -3080,12 +3090,13 @@ var doFetch2 = async (crossOrgId) => {
3080
3090
  credentials: "include",
3081
3091
  headers
3082
3092
  });
3083
- if (!resp.ok) return [];
3093
+ if (!resp.ok) return { data: [], failed: true };
3084
3094
  const result = await resp.json();
3085
3095
  const data = result?.data || result;
3086
- return Array.isArray(data) ? applyValidationStaleness(data) : [];
3096
+ if (!Array.isArray(data)) return { data: [], failed: true };
3097
+ return { data: applyValidationStaleness(data), failed: false };
3087
3098
  } catch {
3088
- return [];
3099
+ return { data: [], failed: true };
3089
3100
  }
3090
3101
  };
3091
3102
  var fetchAuthenticatedApps = (crossOrgId) => {
@@ -3095,12 +3106,17 @@ var fetchAuthenticatedApps = (crossOrgId) => {
3095
3106
  return Promise.resolve(entry.data);
3096
3107
  }
3097
3108
  if (entry.promise) return entry.promise;
3098
- const promise = doFetch2(crossOrgId).then((data) => {
3099
- cache2.set(key, { data, fetchedAt: Date.now() });
3100
- return data;
3101
- }).catch((err) => {
3109
+ const promise = doFetch2(crossOrgId).then((outcome) => {
3110
+ if (outcome.failed) {
3111
+ const previous = cache2.get(key)?.data;
3112
+ cache2.delete(key);
3113
+ return previous || [];
3114
+ }
3115
+ cache2.set(key, { data: outcome.data, fetchedAt: Date.now() });
3116
+ return outcome.data;
3117
+ }).catch(() => {
3102
3118
  cache2.delete(key);
3103
- throw err;
3119
+ return [];
3104
3120
  });
3105
3121
  cache2.set(key, { ...entry, promise });
3106
3122
  return promise;
@@ -8491,6 +8507,238 @@ function AppDetailContent({
8491
8507
  ] });
8492
8508
  }
8493
8509
 
8510
+ // drawerLayer.ts
8511
+ import { useEffect as useEffect8, useState as useState10 } from "react";
8512
+ var STACK_KEY = "__shuffleOverlayStack";
8513
+ var COUNTER_KEY = "__shuffleDrawerLayerTop";
8514
+ var AUTO_LAYER_KEY = "__shuffleOverlayAutoLayerInstalled";
8515
+ var OVERLAY_BASE = 10010;
8516
+ var DRAWER_LAYER_BASE = OVERLAY_BASE;
8517
+ var SURFACE_STEP = 20;
8518
+ var POPUP_OFFSET = 6;
8519
+ var TOOLTIP_OFFSET = 12;
8520
+ var getStore = () => globalThis;
8521
+ var getOverlayStack = () => {
8522
+ const store = getStore();
8523
+ if (!Array.isArray(store[STACK_KEY])) {
8524
+ store[STACK_KEY] = [];
8525
+ }
8526
+ return store[STACK_KEY];
8527
+ };
8528
+ var getTopSurfaceZIndex = (base3 = OVERLAY_BASE) => {
8529
+ const stack = getOverlayStack();
8530
+ const surfaces = stack.filter((r) => r.type === "surface");
8531
+ if (surfaces.length === 0) {
8532
+ const store = getStore();
8533
+ store[COUNTER_KEY] = base3;
8534
+ return base3;
8535
+ }
8536
+ let maxZ = base3;
8537
+ for (const s of surfaces) {
8538
+ if (s.zIndex > maxZ) {
8539
+ maxZ = s.zIndex;
8540
+ }
8541
+ }
8542
+ getStore()[COUNTER_KEY] = maxZ;
8543
+ return maxZ;
8544
+ };
8545
+ var syncGlobalCounter = (base3 = OVERLAY_BASE) => {
8546
+ getTopSurfaceZIndex(base3);
8547
+ };
8548
+ var allocateSurfaceLayer = (id, element2, base3 = OVERLAY_BASE) => {
8549
+ const stack = getOverlayStack();
8550
+ const existing = stack.find((r) => r.id === id || element2 && r.element === element2);
8551
+ if (existing) {
8552
+ return existing.zIndex;
8553
+ }
8554
+ const currentTop = getTopSurfaceZIndex(base3);
8555
+ const nextZ = currentTop + SURFACE_STEP;
8556
+ stack.push({ id, element: element2, zIndex: nextZ, type: "surface" });
8557
+ syncGlobalCounter(base3);
8558
+ return nextZ;
8559
+ };
8560
+ var releaseOverlayLayer = (idOrElement) => {
8561
+ const stack = getOverlayStack();
8562
+ const index = stack.findIndex(
8563
+ (r) => r.id === idOrElement || typeof idOrElement !== "string" && r.element === idOrElement
8564
+ );
8565
+ if (index !== -1) {
8566
+ stack.splice(index, 1);
8567
+ }
8568
+ syncGlobalCounter();
8569
+ };
8570
+ var bringSurfaceToFront = (idOrElement) => {
8571
+ const stack = getOverlayStack();
8572
+ const record = stack.find(
8573
+ (r) => r.id === idOrElement || typeof idOrElement !== "string" && r.element === idOrElement
8574
+ );
8575
+ if (!record || record.type !== "surface") {
8576
+ return typeof idOrElement === "string" ? allocateSurfaceLayer(idOrElement, null) : allocateSurfaceLayer("surface_" + Math.random().toString(36).substring(2, 9), idOrElement);
8577
+ }
8578
+ const currentTop = getTopSurfaceZIndex();
8579
+ if (record.zIndex >= currentTop) {
8580
+ return record.zIndex;
8581
+ }
8582
+ record.zIndex = currentTop + SURFACE_STEP;
8583
+ syncGlobalCounter();
8584
+ return record.zIndex;
8585
+ };
8586
+ var useOverlayLayer = (open, options) => {
8587
+ const base3 = options?.base ?? OVERLAY_BASE;
8588
+ const [zIndex, setZIndex] = useState10(() => open ? getTopSurfaceZIndex(base3) + SURFACE_STEP : base3);
8589
+ useEffect8(() => {
8590
+ if (!open) return;
8591
+ const id = "hook_" + Math.random().toString(36).substring(2, 9);
8592
+ const allocated = allocateSurfaceLayer(id, null, base3);
8593
+ setZIndex(allocated);
8594
+ return () => {
8595
+ releaseOverlayLayer(id);
8596
+ };
8597
+ }, [open, base3]);
8598
+ return zIndex;
8599
+ };
8600
+ var useDrawerLayer = (open, base3 = DRAWER_LAYER_BASE) => useOverlayLayer(open, { base: base3 });
8601
+ var isSurfaceElement = (el) => {
8602
+ if (!(el instanceof HTMLElement)) return false;
8603
+ return el.classList.contains("MuiDialog-root") || el.classList.contains("MuiDrawer-root") || el.classList.contains("MuiModal-root") && !el.classList.contains("MuiPopover-root") && !el.classList.contains("MuiMenu-root") || el.getAttribute("role") === "dialog" || el.getAttribute("role") === "alertdialog" || Boolean(el.closest("[data-radix-portal]"));
8604
+ };
8605
+ var isChildPopupElement = (el) => {
8606
+ if (!(el instanceof HTMLElement)) return false;
8607
+ return el.classList.contains("MuiPopover-root") || el.classList.contains("MuiMenu-root") || el.classList.contains("MuiAutocomplete-popper") || Boolean(el.closest("[data-radix-popper-content-wrapper]")) || el.classList.contains("MuiPopper-root") && !el.classList.contains("MuiTooltip-popper");
8608
+ };
8609
+ var isTooltipElement = (el) => {
8610
+ if (!(el instanceof HTMLElement)) return false;
8611
+ return el.classList.contains("MuiTooltip-popper") || el.getAttribute("role") === "tooltip";
8612
+ };
8613
+ var isElementOpen = (el) => {
8614
+ if (el.getAttribute("aria-hidden") === "true") return false;
8615
+ if (el.getAttribute("data-state") === "closed") return false;
8616
+ if (el.classList.contains("MuiModal-hidden")) return false;
8617
+ const style = el.style;
8618
+ if (style.display === "none" || style.visibility === "hidden") return false;
8619
+ return true;
8620
+ };
8621
+ var observerInstance = null;
8622
+ var installGlobalOverlayAutoLayer = () => {
8623
+ if (typeof window === "undefined" || typeof document === "undefined") return;
8624
+ const store = getStore();
8625
+ if (store[AUTO_LAYER_KEY]) return;
8626
+ store[AUTO_LAYER_KEY] = true;
8627
+ const handleElementOpen = (el) => {
8628
+ if (isSurfaceElement(el)) {
8629
+ let layerId = el.dataset.shuffleLayerId;
8630
+ if (!layerId) {
8631
+ layerId = "dom_" + Math.random().toString(36).substring(2, 9);
8632
+ el.dataset.shuffleLayerId = layerId;
8633
+ }
8634
+ const targetZ = allocateSurfaceLayer(layerId, el);
8635
+ el.dataset.shuffleLayerZ = String(targetZ);
8636
+ el.style.setProperty("z-index", String(targetZ), "important");
8637
+ const dialogContent = el.querySelector('[role="dialog"], [role="alertdialog"]');
8638
+ if (dialogContent && dialogContent !== el) {
8639
+ dialogContent.style.setProperty("z-index", String(targetZ), "important");
8640
+ }
8641
+ return;
8642
+ }
8643
+ if (isChildPopupElement(el)) {
8644
+ const topZ = getTopSurfaceZIndex();
8645
+ const popupZ = topZ + POPUP_OFFSET;
8646
+ el.dataset.shuffleLayerZ = String(popupZ);
8647
+ el.style.setProperty("z-index", String(popupZ), "important");
8648
+ return;
8649
+ }
8650
+ if (isTooltipElement(el)) {
8651
+ const topZ = getTopSurfaceZIndex();
8652
+ const tooltipZ = topZ + TOOLTIP_OFFSET;
8653
+ el.dataset.shuffleLayerZ = String(tooltipZ);
8654
+ el.style.setProperty("z-index", String(tooltipZ), "important");
8655
+ return;
8656
+ }
8657
+ };
8658
+ const handleElementClose = (el) => {
8659
+ const layerId = el.dataset.shuffleLayerId;
8660
+ if (layerId) {
8661
+ releaseOverlayLayer(layerId);
8662
+ delete el.dataset.shuffleLayerId;
8663
+ delete el.dataset.shuffleLayerZ;
8664
+ } else {
8665
+ releaseOverlayLayer(el);
8666
+ }
8667
+ };
8668
+ const scanNode = (node) => {
8669
+ if (!(node instanceof HTMLElement)) return;
8670
+ if (isSurfaceElement(node) || isChildPopupElement(node) || isTooltipElement(node)) {
8671
+ if (isElementOpen(node)) {
8672
+ handleElementOpen(node);
8673
+ } else {
8674
+ handleElementClose(node);
8675
+ }
8676
+ }
8677
+ const children2 = node.children;
8678
+ for (let i = 0; i < children2.length; i++) {
8679
+ const child = children2[i];
8680
+ if (child instanceof HTMLElement) {
8681
+ if (isSurfaceElement(child) || isChildPopupElement(child) || isTooltipElement(child)) {
8682
+ if (isElementOpen(child)) {
8683
+ handleElementOpen(child);
8684
+ } else {
8685
+ handleElementClose(child);
8686
+ }
8687
+ }
8688
+ }
8689
+ }
8690
+ };
8691
+ observerInstance = new MutationObserver((mutations) => {
8692
+ for (const m of mutations) {
8693
+ if (m.type === "childList") {
8694
+ m.addedNodes.forEach(scanNode);
8695
+ m.removedNodes.forEach((node) => {
8696
+ if (node instanceof HTMLElement) {
8697
+ handleElementClose(node);
8698
+ }
8699
+ });
8700
+ } else if (m.type === "attributes") {
8701
+ const target = m.target;
8702
+ if (target instanceof HTMLElement) {
8703
+ scanNode(target);
8704
+ }
8705
+ }
8706
+ }
8707
+ });
8708
+ const body = document.body;
8709
+ if (body) {
8710
+ observerInstance.observe(body, {
8711
+ childList: true,
8712
+ subtree: true,
8713
+ attributes: true,
8714
+ attributeFilter: ["class", "style", "aria-hidden", "data-state"]
8715
+ });
8716
+ Array.from(body.children).forEach(scanNode);
8717
+ }
8718
+ document.addEventListener(
8719
+ "pointerdown",
8720
+ (e) => {
8721
+ const target = e.target;
8722
+ if (!target) return;
8723
+ const surface = target.closest(
8724
+ '.MuiDialog-root, .MuiDrawer-root, .MuiModal-root:not(.MuiPopover-root):not(.MuiMenu-root), [role="dialog"], [role="alertdialog"]'
8725
+ );
8726
+ if (!surface || !surface.dataset.shuffleLayerId) return;
8727
+ const currentZ = Number(surface.dataset.shuffleLayerZ || 0);
8728
+ const topZ = getTopSurfaceZIndex();
8729
+ if (currentZ > 0 && currentZ < topZ) {
8730
+ const newZ = bringSurfaceToFront(surface.dataset.shuffleLayerId);
8731
+ surface.dataset.shuffleLayerZ = String(newZ);
8732
+ surface.style.setProperty("z-index", String(newZ), "important");
8733
+ }
8734
+ },
8735
+ true
8736
+ );
8737
+ };
8738
+ if (typeof window !== "undefined") {
8739
+ installGlobalOverlayAutoLayer();
8740
+ }
8741
+
8494
8742
  // views/AppDetailDrawer.tsx
8495
8743
  import { jsx as jsx17 } from "react/jsx-runtime";
8496
8744
  function AppDetailDrawer({
@@ -8520,6 +8768,7 @@ function AppDetailDrawer({
8520
8768
  const drawerWidth = `min(${width}px, 100vw)`;
8521
8769
  const drawerMinWidth = `min(${minWidth}px, 100vw)`;
8522
8770
  const drawerMaxWidth = `min(${maxWidth}px, 100vw)`;
8771
+ const drawerZIndex = useDrawerLayer(open);
8523
8772
  const handleClose = () => {
8524
8773
  onRefresh?.();
8525
8774
  onClose();
@@ -8551,7 +8800,7 @@ function AppDetailDrawer({
8551
8800
  },
8552
8801
  ...{ PaperProps: drawerPaperProps },
8553
8802
  sx: {
8554
- zIndex: 9999,
8803
+ zIndex: drawerZIndex,
8555
8804
  "& .MuiDrawer-paper": {
8556
8805
  boxSizing: "border-box",
8557
8806
  width: `${drawerWidth} !important`,
@@ -8936,23 +9185,28 @@ var ShuffleMCP = React4.forwardRef(({
8936
9185
  globalUrl
8937
9186
  }, ref) => {
8938
9187
  useSyncHostBaseUrl(globalUrl);
8939
- const [query, setQuery] = useState10(initialQuery);
8940
- const [results, setResults] = useState10([]);
8941
- const [privateApps, setPrivateApps] = useState10([]);
8942
- const [privateAppsLoading, setPrivateAppsLoading] = useState10(!disablePrivateApps);
8943
- const [sourceFilter, setSourceFilter] = useState10("all");
8944
- const [isLoading, setIsLoading] = useState10(false);
8945
- const [isLoadingMore, setIsLoadingMore] = useState10(false);
8946
- const [page, setPage] = useState10(0);
8947
- const [hasMore, setHasMore] = useState10(false);
8948
- const [searchError, setSearchError] = useState10(null);
8949
- const [isOpen, setIsOpen] = useState10(false);
8950
- const [selectedIndex, setSelectedIndex] = useState10(-1);
8951
- const [internalSelectedApps, setInternalSelectedApps] = useState10(selectedApps);
8952
- const [authenticatedApps, setAuthenticatedApps] = useState10(externalAuthenticatedApps || []);
8953
- const [authenticatedAppsLoading, setAuthenticatedAppsLoading] = useState10(!externalAuthenticatedApps);
8954
- const [drawerApp, setDrawerApp] = useState10(null);
8955
- const [initialSettled, setInitialSettled] = useState10(false);
9188
+ const [query, setQuery] = useState11(initialQuery);
9189
+ const [results, setResults] = useState11([]);
9190
+ const [privateApps, setPrivateApps] = useState11([]);
9191
+ const [privateAppsLoading, setPrivateAppsLoading] = useState11(!disablePrivateApps);
9192
+ const [sourceFilter, setSourceFilter] = useState11("all");
9193
+ const [isLoading, setIsLoading] = useState11(false);
9194
+ const [isLoadingMore, setIsLoadingMore] = useState11(false);
9195
+ const [page, setPage] = useState11(0);
9196
+ const [hasMore, setHasMore] = useState11(false);
9197
+ const [searchError, setSearchError] = useState11(null);
9198
+ const [isOpen, setIsOpen] = useState11(false);
9199
+ const [selectedIndex, setSelectedIndex] = useState11(-1);
9200
+ const [internalSelectedApps, setInternalSelectedApps] = useState11(selectedApps);
9201
+ useEffect9(() => {
9202
+ if (selectedApps) {
9203
+ setInternalSelectedApps(selectedApps);
9204
+ }
9205
+ }, [selectedApps]);
9206
+ const [authenticatedApps, setAuthenticatedApps] = useState11(externalAuthenticatedApps || []);
9207
+ const [authenticatedAppsLoading, setAuthenticatedAppsLoading] = useState11(!externalAuthenticatedApps);
9208
+ const [drawerApp, setDrawerApp] = useState11(null);
9209
+ const [initialSettled, setInitialSettled] = useState11(false);
8956
9210
  const firstSearchDoneRef = useRef8(false);
8957
9211
  const hasInitialized = useRef8(false);
8958
9212
  const containerRef = useRef8(null);
@@ -8988,10 +9242,10 @@ var ShuffleMCP = React4.forwardRef(({
8988
9242
  setAuthenticatedAppsLoading(false);
8989
9243
  }
8990
9244
  }, [apiKey, apiBaseUrl, authPath, orgId]);
8991
- useEffect8(() => {
9245
+ useEffect9(() => {
8992
9246
  fetchAuthenticatedApps2();
8993
9247
  }, [fetchAuthenticatedApps2]);
8994
- useEffect8(() => {
9248
+ useEffect9(() => {
8995
9249
  if (disablePrivateApps) {
8996
9250
  setPrivateApps([]);
8997
9251
  setPrivateAppsLoading(false);
@@ -9035,7 +9289,7 @@ var ShuffleMCP = React4.forwardRef(({
9035
9289
  };
9036
9290
  fetchPrivateApps();
9037
9291
  }, [apiKey, apiBaseUrl, privateAppsPath, disablePrivateApps, orgId]);
9038
- useEffect8(() => {
9292
+ useEffect9(() => {
9039
9293
  if (disableAutoSelectValidatedApps) return;
9040
9294
  if (authenticatedApps.length > 0 && results.length > 0) {
9041
9295
  const validatedApps = authenticatedApps.filter((auth) => auth.validation?.valid);
@@ -9056,13 +9310,13 @@ var ShuffleMCP = React4.forwardRef(({
9056
9310
  }
9057
9311
  }
9058
9312
  }, [authenticatedApps, results, disableAutoSelectValidatedApps]);
9059
- useEffect8(() => {
9313
+ useEffect9(() => {
9060
9314
  if (externalAuthenticatedApps) {
9061
9315
  setAuthenticatedApps(externalAuthenticatedApps);
9062
9316
  setAuthenticatedAppsLoading(false);
9063
9317
  }
9064
9318
  }, [externalAuthenticatedApps]);
9065
- useEffect8(() => {
9319
+ useEffect9(() => {
9066
9320
  searchClient.current = algoliasearch(algoliaAppId, algoliaApiKey);
9067
9321
  if (!hasInitialized.current) {
9068
9322
  hasInitialized.current = true;
@@ -9075,10 +9329,10 @@ var ShuffleMCP = React4.forwardRef(({
9075
9329
  }, 100);
9076
9330
  }
9077
9331
  }, []);
9078
- useEffect8(() => {
9332
+ useEffect9(() => {
9079
9333
  setInternalSelectedApps(selectedApps);
9080
9334
  }, [selectedApps]);
9081
- useEffect8(() => {
9335
+ useEffect9(() => {
9082
9336
  const handleClickOutside = (event) => {
9083
9337
  if (containerRef.current && !containerRef.current.contains(event.target)) {
9084
9338
  setIsOpen(false);
@@ -9164,13 +9418,13 @@ var ShuffleMCP = React4.forwardRef(({
9164
9418
  }
9165
9419
  }
9166
9420
  }, [hitsPerPage, algoliaIndexName, privateApps.length, results.length]);
9167
- useEffect8(() => {
9421
+ useEffect9(() => {
9168
9422
  if (initialSettled) return;
9169
9423
  if (!firstSearchDoneRef.current || isLoading || privateAppsLoading) return;
9170
9424
  initialSelectedAppsRef.current = selectedApps;
9171
9425
  setInitialSettled(true);
9172
9426
  }, [initialSettled, isLoading, privateAppsLoading, selectedApps]);
9173
- useEffect8(() => {
9427
+ useEffect9(() => {
9174
9428
  const t = setTimeout(() => setInitialSettled(true), 6e3);
9175
9429
  return () => clearTimeout(t);
9176
9430
  }, []);
@@ -9186,7 +9440,7 @@ var ShuffleMCP = React4.forwardRef(({
9186
9440
  if (distanceFromBottom < 200) loadMore();
9187
9441
  }, [canLoadMore, loadMore]);
9188
9442
  const sentinelRef = useRef8(null);
9189
- useEffect8(() => {
9443
+ useEffect9(() => {
9190
9444
  const node = sentinelRef.current;
9191
9445
  if (!node || !canLoadMore) return;
9192
9446
  const observer = new IntersectionObserver(
@@ -9607,7 +9861,7 @@ var ShuffleMCP = React4.forwardRef(({
9607
9861
  ShuffleMCP.displayName = "ShuffleMCP";
9608
9862
 
9609
9863
  // views/AppSearchDrawer.tsx
9610
- import { useState as useState12, useEffect as useEffect10 } from "react";
9864
+ import { useState as useState13, useEffect as useEffect11 } from "react";
9611
9865
  import {
9612
9866
  X as CloseIcon3,
9613
9867
  Plus as PlusIcon
@@ -9616,7 +9870,7 @@ import { Box as Box13, Typography as Typography11, IconButton as IconButton6, Dr
9616
9870
  import { motion as motion8, AnimatePresence as AnimatePresence2 } from "framer-motion";
9617
9871
 
9618
9872
  // ../Shuffle-Core/components/AddAppDialog.tsx
9619
- import { useState as useState11, useCallback as useCallback8, useEffect as useEffect9 } from "react";
9873
+ import { useState as useState12, useCallback as useCallback8, useEffect as useEffect10 } from "react";
9620
9874
  import {
9621
9875
  Dialog as Dialog2,
9622
9876
  DialogTitle as DialogTitle2,
@@ -10082,8 +10336,8 @@ var GENERATION_TIPS = [
10082
10336
  "Building the app with 100% fewer hand-wavy examples..."
10083
10337
  ];
10084
10338
  var DotsLoader = ({ message, tips }) => {
10085
- const [tipIndex, setTipIndex] = useState11(0);
10086
- useEffect9(() => {
10339
+ const [tipIndex, setTipIndex] = useState12(0);
10340
+ useEffect10(() => {
10087
10341
  if (!tips || tips.length === 0) return;
10088
10342
  const interval = setInterval(() => {
10089
10343
  setTipIndex((i) => (i + 1) % tips.length);
@@ -10144,19 +10398,20 @@ var AddAppDialog = ({
10144
10398
  maxLength = 1024,
10145
10399
  initialInput = ""
10146
10400
  }) => {
10147
- const [input, setInput] = useState11(initialInput);
10148
- const [stage, setStage] = useState11("idle");
10149
- const [spec, setSpec] = useState11(null);
10150
- const [errorMsg, setErrorMsg] = useState11("");
10151
- const [createdAppId, setCreatedAppId] = useState11("");
10152
- const [existing, setExisting] = useState11(null);
10153
- const [liveHits, setLiveHits] = useState11([]);
10154
- const [liveSearching, setLiveSearching] = useState11(false);
10155
- useEffect9(() => {
10401
+ const dialogZIndex = useOverlayLayer(open);
10402
+ const [input, setInput] = useState12(initialInput);
10403
+ const [stage, setStage] = useState12("idle");
10404
+ const [spec, setSpec] = useState12(null);
10405
+ const [errorMsg, setErrorMsg] = useState12("");
10406
+ const [createdAppId, setCreatedAppId] = useState12("");
10407
+ const [existing, setExisting] = useState12(null);
10408
+ const [liveHits, setLiveHits] = useState12([]);
10409
+ const [liveSearching, setLiveSearching] = useState12(false);
10410
+ useEffect10(() => {
10156
10411
  if (open) setInput(initialInput);
10157
10412
  }, [open, initialInput]);
10158
10413
  const title = spec?.info?.title || "";
10159
- useEffect9(() => {
10414
+ useEffect10(() => {
10160
10415
  if (stage !== "idle") return;
10161
10416
  const q = input.trim();
10162
10417
  if (!q || looksLikeUrl(q)) {
@@ -10195,7 +10450,7 @@ var AddAppDialog = ({
10195
10450
  setCreatedAppId("");
10196
10451
  setExisting(null);
10197
10452
  }, []);
10198
- useEffect9(() => {
10453
+ useEffect10(() => {
10199
10454
  if (!open) {
10200
10455
  const t = setTimeout(reset2, 250);
10201
10456
  return () => clearTimeout(t);
@@ -10310,6 +10565,12 @@ var AddAppDialog = ({
10310
10565
  onClose: () => onOpenChange(false),
10311
10566
  fullWidth: true,
10312
10567
  maxWidth: "sm",
10568
+ sx: {
10569
+ zIndex: dialogZIndex,
10570
+ "& .MuiBackdrop-root": {
10571
+ zIndex: dialogZIndex
10572
+ }
10573
+ },
10313
10574
  PaperProps: {
10314
10575
  sx: {
10315
10576
  maxWidth: 640,
@@ -10318,7 +10579,8 @@ var AddAppDialog = ({
10318
10579
  color: "hsl(var(--foreground))",
10319
10580
  border: "1px solid hsl(var(--border))",
10320
10581
  borderRadius: 2,
10321
- boxSizing: "border-box"
10582
+ boxSizing: "border-box",
10583
+ zIndex: dialogZIndex
10322
10584
  }
10323
10585
  },
10324
10586
  children: [
@@ -10759,13 +11021,13 @@ function AppSearchDrawer({
10759
11021
  }) {
10760
11022
  const themeScope = useShuffleMcpTheme();
10761
11023
  const scopeClassName = themeScope?.scopeClassName ?? (theme === "dark" ? "shuffle-mcp-scope dark" : theme === "light" ? "shuffle-mcp-scope" : void 0);
10762
- const [detailAppName, setDetailAppName] = useState12(null);
10763
- const [detailAppId, setDetailAppId] = useState12(null);
10764
- const [addAppOpen, setAddAppOpen] = useState12(false);
10765
- const [addAppQuery, setAddAppQuery] = useState12("");
10766
- const [highlightActive, setHighlightActive] = useState12(false);
10767
- const [bodyReady, setBodyReady] = useState12(false);
10768
- useEffect10(() => {
11024
+ const [detailAppName, setDetailAppName] = useState13(null);
11025
+ const [detailAppId, setDetailAppId] = useState13(null);
11026
+ const [addAppOpen, setAddAppOpen] = useState13(false);
11027
+ const [addAppQuery, setAddAppQuery] = useState13("");
11028
+ const [highlightActive, setHighlightActive] = useState13(false);
11029
+ const [bodyReady, setBodyReady] = useState13(false);
11030
+ useEffect11(() => {
10769
11031
  if (!open) {
10770
11032
  setBodyReady(false);
10771
11033
  return;
@@ -10775,7 +11037,7 @@ function AppSearchDrawer({
10775
11037
  });
10776
11038
  return () => cancelAnimationFrame(raf);
10777
11039
  }, [open]);
10778
- useEffect10(() => {
11040
+ useEffect11(() => {
10779
11041
  setHighlightActive(false);
10780
11042
  if (!open || !highlightAppName) return;
10781
11043
  const t = setTimeout(() => setHighlightActive(true), highlightDelayMs);
@@ -10784,6 +11046,7 @@ function AppSearchDrawer({
10784
11046
  const drawerWidth = `min(${width}px, 100vw)`;
10785
11047
  const drawerMinWidth = `min(${minWidth}px, 100vw)`;
10786
11048
  const drawerMaxWidth = `min(${maxWidth}px, 100vw)`;
11049
+ const drawerZIndex = useDrawerLayer(open);
10787
11050
  const handleClose = () => {
10788
11051
  setDetailAppName(null);
10789
11052
  setDetailAppId(null);
@@ -10889,7 +11152,7 @@ function AppSearchDrawer({
10889
11152
  },
10890
11153
  ...{ PaperProps: drawerPaperProps },
10891
11154
  sx: {
10892
- zIndex: 9999,
11155
+ zIndex: drawerZIndex,
10893
11156
  "& .MuiDrawer-paper": {
10894
11157
  boxSizing: "border-box",
10895
11158
  width: `${drawerWidth} !important`,
@@ -11365,6 +11628,8 @@ var AiAgentPromptsEditor = ({
11365
11628
  prompts,
11366
11629
  apps,
11367
11630
  readOnly = false,
11631
+ skillLabel,
11632
+ isBuiltInApp,
11368
11633
  onChangePrompt,
11369
11634
  onRemovePrompt,
11370
11635
  onAddPrompt,
@@ -11452,16 +11717,44 @@ var AiAgentPromptsEditor = ({
11452
11717
  ] }),
11453
11718
  /* @__PURE__ */ jsxs15(Box14, { sx: { display: "flex", alignItems: "center", gap: 1, flexWrap: "wrap" }, children: [
11454
11719
  /* @__PURE__ */ jsx22(
11455
- Typography12,
11720
+ Tooltip8,
11456
11721
  {
11457
- sx: {
11458
- fontSize: "0.65rem",
11459
- fontWeight: 600,
11460
- color: "hsl(var(--muted-foreground))",
11461
- textTransform: "uppercase",
11462
- letterSpacing: "0.05em"
11463
- },
11464
- children: "Allowed apps"
11722
+ title: skillLabel ? `Allowed apps are shared with ${skillLabel} permissions. Changes made here apply to all automations and agent runs.` : "Apps this AI Agent prompt is permitted to run.",
11723
+ children: /* @__PURE__ */ jsxs15(Box14, { sx: { display: "inline-flex", alignItems: "center", gap: 0.75 }, children: [
11724
+ /* @__PURE__ */ jsx22(
11725
+ Typography12,
11726
+ {
11727
+ sx: {
11728
+ fontSize: "0.65rem",
11729
+ fontWeight: 600,
11730
+ color: "hsl(var(--muted-foreground))",
11731
+ textTransform: "uppercase",
11732
+ letterSpacing: "0.05em"
11733
+ },
11734
+ children: "Allowed apps"
11735
+ }
11736
+ ),
11737
+ skillLabel && /* @__PURE__ */ jsxs15(
11738
+ Typography12,
11739
+ {
11740
+ component: "span",
11741
+ sx: {
11742
+ fontSize: "0.62rem",
11743
+ fontWeight: 600,
11744
+ color: "hsl(var(--primary))",
11745
+ bgcolor: "hsl(var(--primary) / 0.1)",
11746
+ px: 0.6,
11747
+ py: 0.1,
11748
+ borderRadius: 0.75,
11749
+ letterSpacing: "0.02em"
11750
+ },
11751
+ children: [
11752
+ skillLabel,
11753
+ " permissions"
11754
+ ]
11755
+ }
11756
+ )
11757
+ ] })
11465
11758
  }
11466
11759
  ),
11467
11760
  /* @__PURE__ */ jsxs15(Box14, { sx: { display: "flex", alignItems: "center", gap: 0.5, flexWrap: "wrap", flex: 1 }, children: [
@@ -11470,8 +11763,9 @@ var AiAgentPromptsEditor = ({
11470
11763
  const meta = resolveAppMeta(appKey);
11471
11764
  const displayName2 = meta.name;
11472
11765
  const img = meta.image || `https://shuffler.io/images/apps/${displayName2}.png`;
11766
+ const isBuiltIn = isBuiltInApp ? isBuiltInApp(appKey) : false;
11473
11767
  const clickable = !readOnly && !!onRemoveApp;
11474
- const tip = clickable ? `Remove ${displayName2.replace(/_/g, " ")}` : displayName2.replace(/_/g, " ");
11768
+ const tip = isBuiltIn ? `${displayName2.replace(/_/g, " ")} (Default built-in app for ${skillLabel || "skill"})` : clickable ? `Remove ${displayName2.replace(/_/g, " ")} (Assigned permission)` : displayName2.replace(/_/g, " ");
11475
11769
  return /* @__PURE__ */ jsx22(Tooltip8, { title: tip, children: /* @__PURE__ */ jsx22(
11476
11770
  IconButton7,
11477
11771
  {
@@ -11481,12 +11775,12 @@ var AiAgentPromptsEditor = ({
11481
11775
  sx: {
11482
11776
  width: 26,
11483
11777
  height: 26,
11484
- border: "1px solid hsl(var(--severity-low) / 0.3)",
11485
- bgcolor: "hsl(var(--severity-low) / 0.1)",
11778
+ border: isBuiltIn ? "1px solid hsl(var(--primary) / 0.35)" : "1px solid hsl(var(--severity-low) / 0.3)",
11779
+ bgcolor: isBuiltIn ? "hsl(var(--primary) / 0.08)" : "hsl(var(--severity-low) / 0.1)",
11486
11780
  borderRadius: 1,
11487
11781
  "&.Mui-disabled": {
11488
11782
  opacity: 1,
11489
- bgcolor: "hsl(var(--severity-low) / 0.1)"
11783
+ bgcolor: isBuiltIn ? "hsl(var(--primary) / 0.08)" : "hsl(var(--severity-low) / 0.1)"
11490
11784
  },
11491
11785
  "&:hover": clickable ? {
11492
11786
  bgcolor: "hsl(var(--destructive) / 0.15)",
@@ -11505,7 +11799,7 @@ var AiAgentPromptsEditor = ({
11505
11799
  }
11506
11800
  ) }, appKey);
11507
11801
  }),
11508
- !readOnly && onAddAppRequested && /* @__PURE__ */ jsx22(Tooltip8, { title: "Add allowed app", children: /* @__PURE__ */ jsx22(
11802
+ !readOnly && onAddAppRequested && /* @__PURE__ */ jsx22(Tooltip8, { title: skillLabel ? `Assign tools to ${skillLabel}` : "Add allowed app", children: /* @__PURE__ */ jsx22(
11509
11803
  IconButton7,
11510
11804
  {
11511
11805
  size: "small",
@@ -11618,7 +11912,7 @@ function ShufflePipelinesBanner() {
11618
11912
  var ShufflePipelinesBanner_default = ShufflePipelinesBanner;
11619
11913
 
11620
11914
  // components/AgentUI.tsx
11621
- import React6, { useCallback as useCallback10, useEffect as useEffect17, useLayoutEffect, useMemo as useMemo10, useRef as useRef11, useState as useState19 } from "react";
11915
+ import React6, { useCallback as useCallback10, useEffect as useEffect18, useLayoutEffect, useMemo as useMemo10, useRef as useRef11, useState as useState20 } from "react";
11622
11916
  import { flushSync } from "react-dom";
11623
11917
 
11624
11918
  // agentRunSync.ts
@@ -11698,7 +11992,7 @@ import {
11698
11992
  } from "lucide-react";
11699
11993
 
11700
11994
  // ../Shuffle-Core/components/WorkflowRunExplorer.tsx
11701
- import React5, { useEffect as useEffect11, useRef as useRef9, useState as useState13 } from "react";
11995
+ import React5, { useEffect as useEffect12, useRef as useRef9, useState as useState14 } from "react";
11702
11996
  import {
11703
11997
  Badge,
11704
11998
  Drawer as Drawer3,
@@ -12248,7 +12542,7 @@ function safeHandler(label, fn) {
12248
12542
  var safeHandler_default = safeHandler;
12249
12543
 
12250
12544
  // components/AgentPresets.tsx
12251
- import { useEffect as useEffect12, useMemo as useMemo7, useState as useState14 } from "react";
12545
+ import { useEffect as useEffect13, useMemo as useMemo7, useState as useState15 } from "react";
12252
12546
  import { Box as Box17, ButtonBase, ClickAwayListener, Paper, Popper, TextField as TextField5, Tooltip as Tooltip10, Typography as Typography15 } from "@mui/material";
12253
12547
  import { Workflow, ShieldAlert, LifeBuoy, Bug, Radar, Monitor, Plus as Plus2, X as CloseIcon6, BellRing } from "lucide-react";
12254
12548
  import { Fragment as Fragment9, jsx as jsx25, jsxs as jsxs18 } from "react/jsx-runtime";
@@ -12287,7 +12581,7 @@ var AGENT_PRESETS = [
12287
12581
  icon: /* @__PURE__ */ jsx25(ShieldAlert, { size: 16 }),
12288
12582
  enabled: true,
12289
12583
  tag: "Beta",
12290
- defaultApps: [{ name: "shuffle_incidents" }, { name: "shuffle_datastore" }]
12584
+ defaultApps: [{ name: "shuffle_incidents" }]
12291
12585
  },
12292
12586
  {
12293
12587
  id: "host-monitor-control",
@@ -12364,10 +12658,10 @@ var filterAgentPresets = (list, support) => {
12364
12658
  return list.map((p) => SUPPORT_ONLY_PRESET_IDS.includes(p.id) ? { ...p, enabled: false } : p);
12365
12659
  };
12366
12660
  var AgentPresets = ({ variant = "default", onSelectPreset, selectedPreset, onRemoveSelected, presets, chipRef, isSupport, sx, placement }) => {
12367
- const [anchorEl, setAnchorEl] = useState14(null);
12661
+ const [anchorEl, setAnchorEl] = useState15(null);
12368
12662
  const open = Boolean(anchorEl);
12369
- const [supportTick, setSupportTick] = useState14(0);
12370
- useEffect12(() => {
12663
+ const [supportTick, setSupportTick] = useState15(0);
12664
+ useEffect13(() => {
12371
12665
  const bump = () => setSupportTick((t) => t + 1);
12372
12666
  window.addEventListener("storage", bump);
12373
12667
  return () => window.removeEventListener("storage", bump);
@@ -12480,7 +12774,7 @@ var AgentPresets = ({ variant = "default", onSelectPreset, selectedPreset, onRem
12480
12774
  ]
12481
12775
  }
12482
12776
  );
12483
- const [query, setQuery] = useState14("");
12777
+ const [query, setQuery] = useState15("");
12484
12778
  const filtered = useMemo7(() => {
12485
12779
  const q = query.trim().toLowerCase();
12486
12780
  if (!q) return list;
@@ -12748,8 +13042,152 @@ var AgentPresets = ({ variant = "default", onSelectPreset, selectedPreset, onRem
12748
13042
  };
12749
13043
  var AgentPresets_default = AgentPresets;
12750
13044
 
13045
+ // ../lib/agentTools.ts
13046
+ var STORAGE_KEY3 = "agent_tools_config";
13047
+ var AGENT_TOOLS_CHANGED_EVENT = "agent-tools-changed";
13048
+ var DEFAULT_AGENT = "default";
13049
+ var DEFAULT_ACTION_TYPE = "timeline_reply";
13050
+ var getActiveOrgId = () => {
13051
+ if (typeof window === "undefined") return null;
13052
+ try {
13053
+ const raw = localStorage.getItem("shuffle_user_info") || localStorage.getItem("userinfo") || localStorage.getItem("user_info");
13054
+ if (!raw) return null;
13055
+ const parsed = JSON.parse(raw);
13056
+ return parsed?.active_org?.id || parsed?.org_id || parsed?.active_org_id || Array.isArray(parsed?.orgs) && parsed.orgs[0]?.id || parsed?.id || null;
13057
+ } catch {
13058
+ return null;
13059
+ }
13060
+ };
13061
+ var getStorageKey = (orgId) => {
13062
+ const resolved = orgId || getActiveOrgId();
13063
+ return resolved ? `${STORAGE_KEY3}_${resolved}` : STORAGE_KEY3;
13064
+ };
13065
+ var coerceTool = (raw) => {
13066
+ if (typeof raw === "string") {
13067
+ const trimmed = raw.trim();
13068
+ if (!trimmed) return null;
13069
+ return { name: trimmed, id: trimmed };
13070
+ }
13071
+ if (raw && typeof raw === "object") {
13072
+ const obj = raw;
13073
+ const name = typeof obj.name === "string" ? obj.name.trim() : "";
13074
+ const id = typeof obj.id === "string" && obj.id.trim() ? obj.id.trim() : name;
13075
+ if (!name) return null;
13076
+ return { name, id };
13077
+ }
13078
+ return null;
13079
+ };
13080
+ var sanitize2 = (parsed) => {
13081
+ let target = parsed;
13082
+ if (target && typeof target === "object" && !Array.isArray(target)) {
13083
+ const obj = target;
13084
+ if (Array.isArray(obj.entries)) {
13085
+ target = obj.entries;
13086
+ }
13087
+ }
13088
+ if (!Array.isArray(target)) return [];
13089
+ return target.filter((e) => e && typeof e.agent === "string" && typeof e.actionType === "string" && Array.isArray(e.tools)).map((e) => ({
13090
+ agent: e.agent,
13091
+ actionType: e.actionType,
13092
+ tools: e.tools.map(coerceTool).filter((t) => !!t),
13093
+ updatedAt: typeof e.updatedAt === "number" ? e.updatedAt : void 0
13094
+ }));
13095
+ };
13096
+ var extractUpdatedAt = (parsed) => {
13097
+ if (parsed && typeof parsed === "object") {
13098
+ const obj = parsed;
13099
+ if (typeof obj.updatedAt === "number") return obj.updatedAt;
13100
+ }
13101
+ return 0;
13102
+ };
13103
+ var readCacheRecord = () => {
13104
+ if (typeof window === "undefined") return { entries: [], updatedAt: 0 };
13105
+ try {
13106
+ const key = getStorageKey();
13107
+ let raw = localStorage.getItem(key);
13108
+ let parsed = null;
13109
+ let entries = [];
13110
+ let updatedAt = 0;
13111
+ if (raw) {
13112
+ try {
13113
+ parsed = JSON.parse(raw);
13114
+ entries = sanitize2(parsed);
13115
+ updatedAt = extractUpdatedAt(parsed) || entries.reduce((max, e) => Math.max(max, e.updatedAt || 0), 0);
13116
+ } catch {
13117
+ }
13118
+ }
13119
+ if (entries.length === 0 || entries.every((e) => e.tools.length === 0)) {
13120
+ if (key !== STORAGE_KEY3) {
13121
+ const fallbackRaw = localStorage.getItem(STORAGE_KEY3);
13122
+ if (fallbackRaw) {
13123
+ try {
13124
+ const fallbackParsed = JSON.parse(fallbackRaw);
13125
+ const fallbackEntries = sanitize2(fallbackParsed);
13126
+ if (fallbackEntries.some((e) => e.tools.length > 0)) {
13127
+ entries = fallbackEntries;
13128
+ updatedAt = extractUpdatedAt(fallbackParsed) || fallbackEntries.reduce((max, e) => Math.max(max, e.updatedAt || 0), 0) || Date.now();
13129
+ writeCache(entries, updatedAt);
13130
+ }
13131
+ } catch {
13132
+ }
13133
+ }
13134
+ }
13135
+ }
13136
+ return { entries, updatedAt };
13137
+ } catch {
13138
+ return { entries: [], updatedAt: 0 };
13139
+ }
13140
+ };
13141
+ var readAll = () => readCacheRecord().entries;
13142
+ var writeCache = (entries, explicitUpdatedAt) => {
13143
+ if (typeof window === "undefined") return;
13144
+ try {
13145
+ const updatedAt = explicitUpdatedAt ?? Date.now();
13146
+ const payload = {
13147
+ version: 1,
13148
+ updatedAt,
13149
+ entries
13150
+ };
13151
+ const serialized = JSON.stringify(payload);
13152
+ const orgKey = getStorageKey();
13153
+ localStorage.setItem(orgKey, serialized);
13154
+ if (orgKey !== STORAGE_KEY3) {
13155
+ localStorage.setItem(STORAGE_KEY3, serialized);
13156
+ }
13157
+ window.dispatchEvent(
13158
+ new CustomEvent(AGENT_TOOLS_CHANGED_EVENT, { detail: { updatedAt, entries } })
13159
+ );
13160
+ } catch {
13161
+ }
13162
+ };
13163
+ var getAgentTools = (agent = DEFAULT_AGENT, actionType = DEFAULT_ACTION_TYPE) => {
13164
+ const all = readAll();
13165
+ const entry = all.find((e) => e.agent === agent && e.actionType === actionType);
13166
+ if (entry && entry.tools && entry.tools.length > 0) {
13167
+ return entry.tools;
13168
+ }
13169
+ if (agent === "incident-handler" || agent === "incident-response" || agent === DEFAULT_AGENT) {
13170
+ const found = all.find(
13171
+ (e) => (e.agent === "incident-handler" || e.agent === "incident-response" || e.agent === DEFAULT_AGENT) && e.actionType === actionType && e.tools && e.tools.length > 0
13172
+ );
13173
+ if (found?.tools && found.tools.length > 0) return found.tools;
13174
+ }
13175
+ return [];
13176
+ };
13177
+ var getToolsForSkill = (skillOrPresetId) => {
13178
+ const normalized = (skillOrPresetId || "").toLowerCase().trim();
13179
+ if (normalized === "incident-handler" || normalized === "incident-response" || normalized === "default") {
13180
+ const ih = getAgentTools("incident-handler");
13181
+ if (ih.length > 0) return ih;
13182
+ const ir = getAgentTools("incident-response");
13183
+ if (ir.length > 0) return ir;
13184
+ return getAgentTools(DEFAULT_AGENT);
13185
+ }
13186
+ return getAgentTools(normalized);
13187
+ };
13188
+
12751
13189
  // useAgentPromptPrefix.ts
12752
- import { useCallback as useCallback9, useEffect as useEffect13, useRef as useRef10, useState as useState15 } from "react";
13190
+ import { useCallback as useCallback9, useEffect as useEffect14, useRef as useRef10, useState as useState16 } from "react";
12753
13191
  var AGENT_PROMPT_PREFIX_CATEGORY = "agent-prompt-prefix";
12754
13192
  var DEFAULT_AGENT_PROMPT_PREFIX = "";
12755
13193
  var decodePrompt = (raw) => {
@@ -12781,11 +13219,11 @@ var decodePrompt = (raw) => {
12781
13219
  var useAgentPromptPrefix = (options = {}) => {
12782
13220
  const { userId, defaultPrompt = DEFAULT_AGENT_PROMPT_PREFIX, persist = true } = options;
12783
13221
  const key = userId || "default";
12784
- const [prompt, setPrompt] = useState15(defaultPrompt);
12785
- const [hasFetched, setHasFetched] = useState15(false);
12786
- const [isSaving, setIsSaving] = useState15(false);
13222
+ const [prompt, setPrompt] = useState16(defaultPrompt);
13223
+ const [hasFetched, setHasFetched] = useState16(false);
13224
+ const [isSaving, setIsSaving] = useState16(false);
12787
13225
  const fetchedForKey = useRef10(null);
12788
- useEffect13(() => {
13226
+ useEffect14(() => {
12789
13227
  if (!persist) {
12790
13228
  setHasFetched(true);
12791
13229
  return;
@@ -12967,6 +13405,9 @@ var runAgent = async (request) => {
12967
13405
  if (request.incidentId) {
12968
13406
  input.incident_id = request.incidentId;
12969
13407
  }
13408
+ if (request.incidentContext) {
13409
+ input.incident_context = request.incidentContext;
13410
+ }
12970
13411
  if (request.vulnerabilityId) {
12971
13412
  input.vulnerability_id = request.vulnerabilityId;
12972
13413
  }
@@ -13245,16 +13686,143 @@ var getCachedGroupDocs = (groupId, folder) => {
13245
13686
  }));
13246
13687
  };
13247
13688
 
13689
+ // ../lib/incidentPromptContext.ts
13690
+ var GLOBAL_INCIDENT_KEY = "__shuffleActiveIncidentContext";
13691
+ var getGlobalScope = () => {
13692
+ if (typeof globalThis !== "undefined") return globalThis;
13693
+ if (typeof window !== "undefined") return window;
13694
+ if (typeof global !== "undefined") return global;
13695
+ return null;
13696
+ };
13697
+ var getActiveIncidentPromptContext = () => {
13698
+ const scope = getGlobalScope();
13699
+ if (!scope) return null;
13700
+ const info = scope[GLOBAL_INCIDENT_KEY];
13701
+ if (info && typeof info === "object") {
13702
+ return info;
13703
+ }
13704
+ return null;
13705
+ };
13706
+ var INCIDENT_PROMPT_DELIMITER_START = "=== INCIDENT CONTEXT ===";
13707
+ var INCIDENT_PROMPT_DELIMITER_END = "=== END INCIDENT CONTEXT ===";
13708
+ var formatObservableType = (type) => {
13709
+ if (!type) return "Indicator";
13710
+ const clean = type.toLowerCase().trim();
13711
+ switch (clean) {
13712
+ case "ip":
13713
+ case "ipv4":
13714
+ case "ip_address":
13715
+ return "IPv4";
13716
+ case "ipv6":
13717
+ return "IPv6";
13718
+ case "hash":
13719
+ case "sha256":
13720
+ case "file_hash":
13721
+ return "SHA256";
13722
+ case "md5":
13723
+ return "MD5";
13724
+ case "sha1":
13725
+ return "SHA1";
13726
+ case "hostname":
13727
+ case "host":
13728
+ case "endpoint":
13729
+ return "Hostname";
13730
+ case "domain":
13731
+ return "Domain";
13732
+ case "url":
13733
+ return "URL";
13734
+ case "user":
13735
+ case "username":
13736
+ case "account":
13737
+ return "User";
13738
+ case "email":
13739
+ return "Email";
13740
+ case "process":
13741
+ case "process_name":
13742
+ return "Process";
13743
+ case "file":
13744
+ case "filename":
13745
+ return "File";
13746
+ default:
13747
+ return type.charAt(0).toUpperCase() + type.slice(1);
13748
+ }
13749
+ };
13750
+ var isIncidentInjectedPrompt = (prompt) => {
13751
+ if (!prompt || typeof prompt !== "string") return false;
13752
+ return prompt.includes(INCIDENT_PROMPT_DELIMITER_START) || prompt.includes("OPERATIONAL DIRECTIVES:") || prompt.includes("INCIDENT OBSERVABLES / IOCs:");
13753
+ };
13754
+ var extractCleanIncidentPrompt = (prompt) => {
13755
+ if (!prompt || typeof prompt !== "string") return "";
13756
+ const trimmed = prompt.trim();
13757
+ const taskMatch = trimmed.match(/TASK TO EXECUTE:\s*\n\s*-\s*Task:\s*([^\n]+)/i);
13758
+ if (taskMatch && taskMatch[1]?.trim()) {
13759
+ return `Task: ${taskMatch[1].trim()}`;
13760
+ }
13761
+ const legacyMatch = trimmed.match(/\n\s*Task:\s*([^\n]+)/i);
13762
+ if (legacyMatch && legacyMatch[1]?.trim()) {
13763
+ return `Task: ${legacyMatch[1].trim()}`;
13764
+ }
13765
+ if (trimmed.includes(INCIDENT_PROMPT_DELIMITER_START)) {
13766
+ const before = trimmed.split(INCIDENT_PROMPT_DELIMITER_START)[0]?.trim();
13767
+ if (before) return before;
13768
+ }
13769
+ return trimmed;
13770
+ };
13771
+ var composeIncidentPromptInput = (rawInput, context) => {
13772
+ if (!rawInput || typeof rawInput !== "string") return "";
13773
+ const trimmed = rawInput.trim();
13774
+ if (isIncidentInjectedPrompt(trimmed)) {
13775
+ return trimmed;
13776
+ }
13777
+ const ctx = context || getActiveIncidentPromptContext();
13778
+ if (!ctx || !ctx.id) {
13779
+ return trimmed;
13780
+ }
13781
+ const incidentRef = ctx.id ? `#${ctx.id}` : "";
13782
+ const incidentTitle = ctx.title?.trim() || "Incident";
13783
+ const severity = ctx.severity || "Medium";
13784
+ const status = ctx.status || "In Progress";
13785
+ const description = ctx.description?.trim() || "No description provided.";
13786
+ const seenObservables = /* @__PURE__ */ new Set();
13787
+ const formattedObservables = [];
13788
+ if (Array.isArray(ctx.observables)) {
13789
+ for (const obs of ctx.observables) {
13790
+ if (!obs || obs.archived || !obs.value?.trim()) continue;
13791
+ const val = obs.value.trim();
13792
+ const typeLabel = formatObservableType(obs.type);
13793
+ const key = `${typeLabel.toLowerCase()}:${val.toLowerCase()}`;
13794
+ if (seenObservables.has(key)) continue;
13795
+ seenObservables.add(key);
13796
+ formattedObservables.push(`- ${typeLabel}: ${val}`);
13797
+ }
13798
+ }
13799
+ const observablesBlock = formattedObservables.length > 0 ? formattedObservables.slice(0, 50).join("\n") : "- None recorded yet";
13800
+ return `${trimmed}
13801
+
13802
+ ${INCIDENT_PROMPT_DELIMITER_START}
13803
+ INCIDENT CONTEXT:
13804
+ - Incident: ${incidentRef} ("${incidentTitle}")
13805
+ - Severity: ${severity} | Status: ${status}
13806
+ - Summary: ${description}
13807
+
13808
+ INCIDENT OBSERVABLES / IOCs:
13809
+ ${observablesBlock}
13810
+ ${INCIDENT_PROMPT_DELIMITER_END}
13811
+
13812
+ DIRECTIVES:
13813
+ - Relevant incident details and observables are provided above. Do not call "get_incident" unless raw external logs are required.`;
13814
+ };
13815
+
13248
13816
  // ../lib/docsPromptContext.ts
13249
13817
  var GLOBAL_DOC_KEY = "__shuffleActiveDocInfo";
13250
- var getGlobalScope = () => {
13818
+ var getGlobalScope2 = () => {
13251
13819
  if (typeof globalThis !== "undefined") return globalThis;
13252
13820
  if (typeof window !== "undefined") return window;
13253
13821
  if (typeof global !== "undefined") return global;
13254
13822
  return null;
13255
13823
  };
13256
13824
  var getActiveDocPromptContext = () => {
13257
- const scope = getGlobalScope();
13825
+ const scope = getGlobalScope2();
13258
13826
  if (!scope) return null;
13259
13827
  const info = scope[GLOBAL_DOC_KEY];
13260
13828
  if (info && typeof info === "object") {
@@ -13295,6 +13863,9 @@ var isDocInjectedPrompt = (prompt) => {
13295
13863
  var extractCleanDisplayPrompt = (prompt) => {
13296
13864
  if (!prompt || typeof prompt !== "string") return "";
13297
13865
  const trimmed = prompt.trim();
13866
+ if (isIncidentInjectedPrompt(trimmed)) {
13867
+ return extractCleanIncidentPrompt(trimmed);
13868
+ }
13298
13869
  if (!isDocInjectedPrompt(trimmed)) return trimmed;
13299
13870
  if (trimmed.includes(DOC_PROMPT_DELIMITER_END)) {
13300
13871
  const parts = trimmed.split(DOC_PROMPT_DELIMITER_END);
@@ -13334,7 +13905,7 @@ var composeDocPromptInput = (userQuestion, pathname, fallbackTitle, overrideDocI
13334
13905
  return trimmedQuestion;
13335
13906
  }
13336
13907
  const activeDoc = overrideDocInfo ?? getActiveDocPromptContext();
13337
- const rawTitle = (activeDoc?.title || fallbackTitle || getGlobalScope()?.__shuffleActiveEntityTitle || "Shuffle documentation").trim();
13908
+ const rawTitle = (activeDoc?.title || fallbackTitle || getGlobalScope2()?.__shuffleActiveEntityTitle || "Shuffle documentation").trim();
13338
13909
  const title = normalizeDocPromptTitle(rawTitle);
13339
13910
  const groupLabel = activeDoc?.groupLabel;
13340
13911
  const groupId = activeDoc?.groupId;
@@ -13400,7 +13971,7 @@ ${trimmedQuestion}`;
13400
13971
  };
13401
13972
 
13402
13973
  // ../Shuffle-Core/views/monitors/ActionOutputView.tsx
13403
- import { useMemo as useMemo8, useState as useState16, useEffect as useEffect14 } from "react";
13974
+ import { useMemo as useMemo8, useState as useState17, useEffect as useEffect15 } from "react";
13404
13975
  import { Fragment as Fragment10, jsx as jsx26, jsxs as jsxs19 } from "react/jsx-runtime";
13405
13976
  var IMAGE_SIGNATURES = [
13406
13977
  { prefix: "iVBORw0KGgo", mime: "image/png" },
@@ -13487,9 +14058,9 @@ var detectImage = (raw) => {
13487
14058
  var MAX_TEXT_CHARS = 4e3;
13488
14059
  var ActionOutputView = ({ output, className }) => {
13489
14060
  const detected = useMemo8(() => detectImage(output), [output]);
13490
- const [zoomed, setZoomed] = useState16(false);
13491
- const [showFull, setShowFull] = useState16(false);
13492
- useEffect14(() => {
14061
+ const [zoomed, setZoomed] = useState17(false);
14062
+ const [showFull, setShowFull] = useState17(false);
14063
+ useEffect15(() => {
13493
14064
  if (!zoomed) return;
13494
14065
  const onKey = (e) => {
13495
14066
  if (e.key === "Escape") {
@@ -14494,17 +15065,25 @@ var extractDecisionIndex = (path) => {
14494
15065
  };
14495
15066
  var isAiAuthText = (text2) => {
14496
15067
  if (!text2 || typeof text2 !== "string") return false;
14497
- const lower = text2.toLowerCase();
14498
- const hasAuthSignal = /\b(401|unauthori[sz]ed|invalid[_\s-]*(api[_\s-]*key|credentials?|token|auth|key)|incorrect\s+api\s+key|missing[_\s-]*(api[_\s-]*key|authorization|credentials?)|authentication[_\s-]*(failed|required|error)|ai\s+credentials)\b/.test(
14499
- lower
14500
- ) || /check\s+your\s+ai\s+credentials/.test(lower);
14501
- if (!hasAuthSignal) return false;
14502
- const hasAiSignal = /\b(failed\s+to\s+start\s+ai\s+agent|failed\s+to\s+run\s+ai(\s+(agent|query))?|failed\s+to\s+run\s+ai|ai\s+agent\s+(failed|error|crash|aborted)|ai\s+query|ai\s+credentials|shuffler\.io\/agents|runactionai|llm\s+request|failed\s+to\s+run\s+llm|no\s+llm|openai|anthropic|mistral|groq|deepseek|together\.ai|together\.xyz|openrouter|gemini|googleapis\.com|ollama|lm\s*studio|platform\.openai\.com|api\.openai\.com|local\s*llm)\b/.test(
14503
- lower
14504
- ) || /error\s+from\s+['"][^'"]*(openai|anthropic|mistral|groq|deepseek|together|openrouter|googleapis|ollama|lmstudio)/.test(
14505
- lower
14506
- ) || /incorrect\s+api\s+key\s+provided/.test(lower);
14507
- return Boolean(hasAiSignal);
15068
+ const trimmed = text2.trim();
15069
+ if (!trimmed) return false;
15070
+ const checkChunk = (chunk) => {
15071
+ const lower = chunk.toLowerCase();
15072
+ const hasAuthSignal = /\b(401|unauthori[sz]ed|invalid[_\s-]*(api[_\s-]*key|credentials?|token|auth|key)|incorrect\s+api\s+key|missing[_\s-]*(api[_\s-]*key|authorization|credentials?)|authentication[_\s-]*(failed|required|error)|ai\s+credentials)\b/.test(
15073
+ lower
15074
+ ) || /check\s+your\s+ai\s+credentials/.test(lower);
15075
+ if (!hasAuthSignal) return false;
15076
+ const hasAiSignal = /\b(failed\s+to\s+start\s+ai\s+agent|failed\s+to\s+run\s+ai(\s+(agent|query))?|failed\s+to\s+run\s+ai|ai\s+agent\s+(failed|error|crash|aborted)|ai\s+query|ai\s+credentials|shuffler\.io\/agents|runactionai|llm\s+request|failed\s+to\s+run\s+llm|no\s+llm|openai|anthropic|mistral|groq|deepseek|together\.ai|together\.xyz|openrouter|gemini|generativelanguage\.googleapis\.com|aiplatform\.googleapis\.com|ollama|lm\s*studio|platform\.openai\.com|api\.openai\.com|local\s*llm)\b/.test(
15077
+ lower
15078
+ ) || /error\s+from\s+['"][^'"]*(openai|anthropic|mistral|groq|deepseek|together|openrouter|generativelanguage|aiplatform|gemini|ollama|lmstudio)/.test(
15079
+ lower
15080
+ ) || /incorrect\s+api\s+key\s+provided/.test(lower);
15081
+ return Boolean(hasAiSignal);
15082
+ };
15083
+ if (trimmed.includes("\n")) {
15084
+ return trimmed.split(/\r?\n/).some((line) => checkChunk(line));
15085
+ }
15086
+ return checkChunk(trimmed);
14508
15087
  };
14509
15088
  var hasOutputWarning = (run) => {
14510
15089
  return diagnoseOutputWarning(run) !== null;
@@ -14538,8 +15117,15 @@ var trimEvidenceValue = (v, max = 180) => {
14538
15117
  };
14539
15118
  var TOKEN_LIMIT_PATTERN = /\b(ai[\s-]*token[\s-]*limit[\s-]*(is[\s-]*)?reach(ed)?|token[\s-]*limit[\s-]*(is[\s-]*)?reach(ed)?|context[\s-]*(window|length|limit)[\s-]*(is[\s-]*)?(reached|exceeded)|maximum[\s-]*context[\s-]*(window|length)?[\s-]*(is[\s-]*)?(reached|exceeded)|too[\s-]*many[\s-]*tokens|exceeds?[\s-]*(the[\s-]*)?(maximum[\s-]*)?(token|context))\b/;
14540
15119
  var isSentenceLike = (v) => /[a-z]/i.test(v) && v.trim().split(/\s+/).length > 1;
15120
+ var hasProducedDecisions = (run, parsed) => {
15121
+ const parsedDecisions = parsed && typeof parsed === "object" ? parsed.decisions : null;
15122
+ if (Array.isArray(parsedDecisions) && parsedDecisions.length > 0) return true;
15123
+ const directDecisions = run?.decisions;
15124
+ return Array.isArray(directDecisions) && directDecisions.length > 0;
15125
+ };
14541
15126
  var diagnoseOutputWarning = (run) => {
14542
15127
  const { parsed, raw } = parseRunResult(run);
15128
+ const producedDecisions = hasProducedDecisions(run, parsed);
14543
15129
  const tokenLimitMatch = (() => {
14544
15130
  const candidates = [];
14545
15131
  if (parsed && typeof parsed === "object") {
@@ -14574,7 +15160,7 @@ var diagnoseOutputWarning = (run) => {
14574
15160
  const category = String(last.category || "").toLowerCase();
14575
15161
  if (["finish", "finalise"].includes(action) || ["finish", "finalise"].includes(category)) {
14576
15162
  if (last.success === false || last.status === "FAILED") return false;
14577
- if (isAiAuthText(last.reason) || isAiAuthText(last.output) || isAiAuthText(last.details?.output)) return false;
15163
+ if (isAiAuthText(last.reason)) return false;
14578
15164
  const reasonStr = String(last.reason || "").toLowerCase();
14579
15165
  if (reasonStr.startsWith("failed to") || reasonStr.includes("error,")) return false;
14580
15166
  return true;
@@ -14584,28 +15170,22 @@ var diagnoseOutputWarning = (run) => {
14584
15170
  return false;
14585
15171
  })();
14586
15172
  const aiAuthMatch = (() => {
15173
+ if (producedDecisions) return null;
15174
+ if (isFinished && (!parsed?.error && parsed?.success !== false)) return null;
14587
15175
  if (isFinished && hasSuccessfulFinish) return null;
14588
15176
  const candidates = [];
14589
15177
  if (parsed && typeof parsed === "object") {
14590
15178
  if (typeof parsed.error === "string") candidates.push(parsed.error);
14591
- if (typeof parsed.reason === "string") candidates.push(parsed.reason);
14592
- if (typeof parsed.message === "string") candidates.push(parsed.message);
14593
- if (typeof parsed.output === "string") candidates.push(parsed.output);
14594
- if (Array.isArray(parsed.decisions)) {
15179
+ if (!isFinished && typeof parsed.reason === "string") candidates.push(parsed.reason);
15180
+ if (!isFinished && typeof parsed.message === "string") candidates.push(parsed.message);
15181
+ if (Array.isArray(parsed.decisions) && !isFinished) {
14595
15182
  for (const d of parsed.decisions) {
14596
15183
  if (typeof d?.run_details?.error === "string") candidates.push(d.run_details.error);
14597
- if (typeof d?.reason === "string") candidates.push(d.reason);
14598
- if (typeof d?.run_details?.result === "string") candidates.push(d.run_details.result);
14599
- if (typeof d?.output === "string") candidates.push(d.output);
14600
- if (Array.isArray(d?.fields)) {
14601
- for (const f of d.fields) {
14602
- if (typeof f?.value === "string") candidates.push(f.value);
14603
- }
14604
- }
15184
+ if (d?.status === "FAILED" && typeof d?.reason === "string") candidates.push(d.reason);
14605
15185
  }
14606
15186
  }
14607
15187
  }
14608
- if (raw) {
15188
+ if (raw && !isFinished) {
14609
15189
  candidates.push(raw);
14610
15190
  }
14611
15191
  return candidates.find((v) => isAiAuthText(v)) || null;
@@ -14720,7 +15300,7 @@ var diagnoseOutputWarning = (run) => {
14720
15300
  const dedup = ev.filter((e) => e.path !== statusEvidence.path);
14721
15301
  return [statusEvidence, ...dedup].slice(0, 3);
14722
15302
  };
14723
- if (isAiAuthText(errorHaystackLower) || isAiAuthText(raw)) {
15303
+ if (!producedDecisions && !isFinished && (isAiAuthText(errorHaystackLower) || isAiAuthText(raw))) {
14724
15304
  const ev = findEvidenceByRegex(
14725
15305
  /unauthori[sz]ed|invalid[_\s-]*(api[_\s-]*key|token|credentials?)|authentication[_\s-]*(failed|required)|missing[_\s-]*(api[_\s-]*key|token|authorization)|bearer[_\s-]*token|expired[_\s-]*token|failed\s+to\s+start\s+ai\s+agent|incorrect\s+api\s+key\s+provided|\b401\b/
14726
15306
  );
@@ -14859,39 +15439,35 @@ var diagnoseOutputWarning = (run) => {
14859
15439
  return null;
14860
15440
  };
14861
15441
  var isAiAuthFailure = (run, extraText) => {
15442
+ if (!run) return isAiAuthText(extraText);
15443
+ const { parsed } = parseRunResult(run);
15444
+ if (hasProducedDecisions(run, parsed)) return false;
14862
15445
  if (isAiAuthText(extraText)) return true;
14863
- if (!run) return false;
15446
+ const status = (run.status || "").toUpperCase();
15447
+ const isFinished = status === "FINISHED" || status === "SUCCESS";
15448
+ if (isFinished) {
15449
+ const anyRun2 = run;
15450
+ if (typeof anyRun2.error === "string" && isAiAuthText(anyRun2.error)) return true;
15451
+ return false;
15452
+ }
14864
15453
  const diagnosis = diagnoseOutputWarning(run);
14865
15454
  if (diagnosis?.kind === "ai_auth" || diagnosis?.isAiAuth) return true;
14866
15455
  const fail = getFailureInfo(run);
14867
15456
  if (fail && isAiAuthText(fail.reason)) return true;
14868
15457
  const anyRun = run;
14869
- if (typeof anyRun.result === "string" && isAiAuthText(anyRun.result)) return true;
14870
- if (typeof anyRun.output === "string" && isAiAuthText(anyRun.output)) return true;
14871
15458
  if (typeof anyRun.error === "string" && isAiAuthText(anyRun.error)) return true;
14872
15459
  if (Array.isArray(run.results)) {
14873
15460
  for (const r of run.results) {
14874
- if (typeof r?.result === "string" && isAiAuthText(r.result)) return true;
14875
15461
  if (typeof r?.error === "string" && isAiAuthText(r.error)) return true;
14876
15462
  }
14877
15463
  }
14878
15464
  const decisions = anyRun?.decisions;
14879
15465
  if (Array.isArray(decisions)) {
14880
15466
  for (const d of decisions) {
14881
- if (isAiAuthText(d?.reason)) return true;
14882
- if (typeof d?.output === "string" && isAiAuthText(d.output)) return true;
14883
15467
  if (typeof d?.run_details?.error === "string" && isAiAuthText(d.run_details.error)) return true;
14884
- if (typeof d?.run_details?.result === "string" && isAiAuthText(d.run_details.result)) return true;
14885
- if (Array.isArray(d?.fields)) {
14886
- for (const f of d.fields) {
14887
- if (isAiAuthText(f?.value)) return true;
14888
- }
14889
- }
15468
+ if (d?.status === "FAILED" && typeof d?.reason === "string" && isAiAuthText(d.reason)) return true;
14890
15469
  }
14891
15470
  }
14892
- const status = (run.status || "").toUpperCase();
14893
- const isFinished = status === "FINISHED";
14894
- if (isFinished) return false;
14895
15471
  return false;
14896
15472
  };
14897
15473
 
@@ -14985,7 +15561,7 @@ var AgentDiagnosisCtas = ({ diagnosis, compact = false, tone = "medium" }) => {
14985
15561
  var AgentDiagnosisCtas_default = AgentDiagnosisCtas;
14986
15562
 
14987
15563
  // components/AgentRunDiagnosisBanner.tsx
14988
- import { useEffect as useEffect15, useMemo as useMemo9, useState as useState17 } from "react";
15564
+ import { useEffect as useEffect16, useMemo as useMemo9, useState as useState18 } from "react";
14989
15565
  import { jsx as jsx28, jsxs as jsxs21 } from "react/jsx-runtime";
14990
15566
  var DISMISS_PREFIX = "agent-diagnosis-dismissed::";
14991
15567
  var readDismissed = (key) => {
@@ -15009,8 +15585,8 @@ var AgentRunDiagnosisBanner = ({ run, sx, onJumpToEvidence, onFocusContinue, exe
15009
15585
  const fromRun = run?.execution_id;
15010
15586
  return typeof fromRun === "string" && fromRun ? fromRun : null;
15011
15587
  }, [executionId, run]);
15012
- const [dismissed, setDismissed] = useState17(() => readDismissed(dismissKey));
15013
- useEffect15(() => {
15588
+ const [dismissed, setDismissed] = useState18(() => readDismissed(dismissKey));
15589
+ useEffect16(() => {
15014
15590
  setDismissed(readDismissed(dismissKey));
15015
15591
  }, [dismissKey]);
15016
15592
  if (!run || dismissed) return null;
@@ -15307,7 +15883,7 @@ var AiAuthSuggestion = ({
15307
15883
  var AiAuthSuggestion_default = AiAuthSuggestion;
15308
15884
 
15309
15885
  // components/AgentAttachmentsButton.tsx
15310
- import { useEffect as useEffect16, useState as useState18 } from "react";
15886
+ import { useEffect as useEffect17, useState as useState19 } from "react";
15311
15887
  import { Badge as Badge2, Box as Box21, IconButton as IconButton10, Popover, Tooltip as Tooltip13, Typography as Typography18 } from "@mui/material";
15312
15888
  import { Image as ImageIcon } from "lucide-react";
15313
15889
  import { Fragment as Fragment11, jsx as jsx30, jsxs as jsxs23 } from "react/jsx-runtime";
@@ -15318,9 +15894,9 @@ var toSrc = (url) => {
15318
15894
  return `data:image/png;base64,${s.replace(/\s+/g, "")}`;
15319
15895
  };
15320
15896
  var AgentAttachmentsButton = ({ attachments }) => {
15321
- const [anchorEl, setAnchorEl] = useState18(null);
15322
- const [zoomed, setZoomed] = useState18(null);
15323
- useEffect16(() => {
15897
+ const [anchorEl, setAnchorEl] = useState19(null);
15898
+ const [zoomed, setZoomed] = useState19(null);
15899
+ useEffect17(() => {
15324
15900
  if (!zoomed) return;
15325
15901
  const onKey = (e) => {
15326
15902
  if (e.key === "Escape") {
@@ -15980,6 +16556,7 @@ var DEFAULT_AGENT_CONTEXT_RULES = [
15980
16556
  const cleanId = formatEntityDisplayId(params.id);
15981
16557
  return `Investigate incident ${cleanId} and recommend next steps: `;
15982
16558
  },
16559
+ composeInput: (raw) => composeIncidentPromptInput(raw),
15983
16560
  placeholder: "Ask about this incident, triage observables, or correlate...",
15984
16561
  getStorageKey: (params) => `incident_${params.id}`,
15985
16562
  description: "Focused on the currently viewed incident with Shuffle Incidents MCP"
@@ -16004,6 +16581,7 @@ var DEFAULT_AGENT_CONTEXT_RULES = [
16004
16581
  const cleanId = formatEntityDisplayId(params.id);
16005
16582
  return `Investigate incident ${cleanId} and recommend next steps: `;
16006
16583
  },
16584
+ composeInput: (raw) => composeIncidentPromptInput(raw),
16007
16585
  placeholder: "Ask about this incident, triage observables, or correlate...",
16008
16586
  getStorageKey: (params) => `incident_${params.id}`,
16009
16587
  description: "Focused on the currently viewed incident with Shuffle Incidents MCP"
@@ -16015,6 +16593,7 @@ var DEFAULT_AGENT_CONTEXT_RULES = [
16015
16593
  defaultApps: [{ name: "shuffle_incidents" }],
16016
16594
  defaultPresetId: "incident-response",
16017
16595
  sourceCategory: "incidents",
16596
+ isBeta: true,
16018
16597
  title: (params, _, entityOverride) => {
16019
16598
  const cleanId = formatEntityDisplayId(params.id);
16020
16599
  const entity = entityOverride || getActivePageEntityName();
@@ -16025,6 +16604,7 @@ var DEFAULT_AGENT_CONTEXT_RULES = [
16025
16604
  const cleanId = formatEntityDisplayId(params.id);
16026
16605
  return `Investigate case ${cleanId} and recommend next steps: `;
16027
16606
  },
16607
+ composeInput: (raw) => composeIncidentPromptInput(raw),
16028
16608
  placeholder: "Review case evidence, correlate events, or recommend response actions...",
16029
16609
  getStorageKey: (params) => `case_${params.id}`,
16030
16610
  description: "Focused on the currently viewed case with Shuffle Incidents MCP"
@@ -16036,6 +16616,7 @@ var DEFAULT_AGENT_CONTEXT_RULES = [
16036
16616
  defaultApps: [{ name: "shuffle_incidents" }],
16037
16617
  defaultPresetId: "incident-response",
16038
16618
  sourceCategory: "incidents",
16619
+ isBeta: true,
16039
16620
  title: (params, _, entityOverride) => {
16040
16621
  const cleanId = formatEntityDisplayId(params.id);
16041
16622
  const entity = entityOverride || getActivePageEntityName();
@@ -16057,6 +16638,7 @@ var DEFAULT_AGENT_CONTEXT_RULES = [
16057
16638
  defaultApps: [{ name: "shuffle_incidents" }],
16058
16639
  defaultPresetId: "incident-response",
16059
16640
  sourceCategory: "incidents",
16641
+ isBeta: true,
16060
16642
  title: (params, _, entityOverride) => {
16061
16643
  const cleanId = formatEntityDisplayId(params.id);
16062
16644
  const entity = entityOverride || getActivePageEntityName();
@@ -16078,6 +16660,7 @@ var DEFAULT_AGENT_CONTEXT_RULES = [
16078
16660
  defaultApps: [{ name: "shuffle_incidents" }],
16079
16661
  defaultPresetId: "incident-response",
16080
16662
  sourceCategory: "incidents",
16663
+ isBeta: true,
16081
16664
  title: "How can we help handle incidents?",
16082
16665
  subtitle: "Shuffle Incidents MCP",
16083
16666
  defaultPrompt: "Investigate this incident and recommend next steps: ",
@@ -16092,6 +16675,7 @@ var DEFAULT_AGENT_CONTEXT_RULES = [
16092
16675
  defaultApps: [{ name: "shuffle_incidents" }],
16093
16676
  defaultPresetId: "incident-response",
16094
16677
  sourceCategory: "incidents",
16678
+ isBeta: true,
16095
16679
  title: "How can we help handle cases?",
16096
16680
  subtitle: "Shuffle Incidents MCP",
16097
16681
  defaultPrompt: "Investigate this case and recommend next steps: ",
@@ -16106,6 +16690,7 @@ var DEFAULT_AGENT_CONTEXT_RULES = [
16106
16690
  defaultApps: [{ name: "shuffle_incidents" }],
16107
16691
  defaultPresetId: "incident-response",
16108
16692
  sourceCategory: "incidents",
16693
+ isBeta: true,
16109
16694
  title: "How can we help handle tickets?",
16110
16695
  subtitle: "Shuffle Incidents MCP",
16111
16696
  defaultPrompt: "Investigate this ticket and recommend next steps: ",
@@ -16120,6 +16705,7 @@ var DEFAULT_AGENT_CONTEXT_RULES = [
16120
16705
  defaultApps: [{ name: "shuffle_incidents" }],
16121
16706
  defaultPresetId: "incident-response",
16122
16707
  sourceCategory: "incidents",
16708
+ isBeta: true,
16123
16709
  title: "How can we help handle alerts?",
16124
16710
  subtitle: "Shuffle Incidents MCP",
16125
16711
  defaultPrompt: "Investigate this alert and recommend next steps: ",
@@ -16749,6 +17335,18 @@ var readPresetAppsOverride = (presetId) => {
16749
17335
  return null;
16750
17336
  }
16751
17337
  };
17338
+ var resolvePresetApps = (preset) => {
17339
+ const baseApps = (preset.defaultApps || []).map((app2) => ({ name: app2.name, id: app2.id, icon: app2.icon }));
17340
+ const assigned = getToolsForSkill(preset.id);
17341
+ const merged = [...baseApps];
17342
+ for (const t of assigned) {
17343
+ const key = (t.id || t.name).toLowerCase();
17344
+ if (!merged.some((m) => (m.id || m.name).toLowerCase() === key)) {
17345
+ merged.push({ name: t.name, id: t.id, icon: t.icon || void 0 });
17346
+ }
17347
+ }
17348
+ return merged;
17349
+ };
16752
17350
  var writePresetAppsOverride = (presetId, apps) => {
16753
17351
  try {
16754
17352
  const raw = localStorage.getItem(PRESET_APPS_STORAGE_KEY);
@@ -17029,7 +17627,7 @@ var RunFinishedSummary = ({
17029
17627
  children: finishNote
17030
17628
  }
17031
17629
  ),
17032
- bottomContent
17630
+ status !== "FINISHED" && status !== "SUCCESS" && bottomContent
17033
17631
  ] });
17034
17632
  };
17035
17633
  var VERIFIED_BUILTIN_APPS = /* @__PURE__ */ new Set([
@@ -17127,8 +17725,12 @@ var extractAuthRequest = (decision) => {
17127
17725
  } else if (raw && typeof raw === "object") {
17128
17726
  parsed = raw;
17129
17727
  }
17130
- const needsAuth = parsed && (parsed.action === "app_authentication" || parsed.app_authentication === true);
17131
- if (!needsAuth) return null;
17728
+ const candidateObjects = [
17729
+ parsed,
17730
+ decision?.result,
17731
+ decision?.run_details,
17732
+ decision
17733
+ ].filter(Boolean);
17132
17734
  let toolAppName;
17133
17735
  let appId = null;
17134
17736
  if (typeof decision?.tool === "string") {
@@ -17141,8 +17743,36 @@ var extractAuthRequest = (decision) => {
17141
17743
  toolAppName = t;
17142
17744
  }
17143
17745
  }
17144
- let appName = parsed.app || parsed.app_name || parsed.appname;
17145
- if (!appName) appName = toolAppName;
17746
+ let needsAuth = false;
17747
+ let candidateAppName;
17748
+ for (const obj of candidateObjects) {
17749
+ if (obj.action === "app_authentication" || obj.app_authentication === true || obj.action === "authenticate" || obj.needs_auth === true || obj.auth_required === true) {
17750
+ needsAuth = true;
17751
+ }
17752
+ const candidate = obj.app || obj.app_name || obj.appname;
17753
+ if (typeof candidate === "string" && candidate.trim()) {
17754
+ candidateAppName = candidate.trim();
17755
+ }
17756
+ }
17757
+ const textSources = [
17758
+ decision?.error,
17759
+ decision?.reason,
17760
+ decision?.status_message,
17761
+ decision?.message,
17762
+ decision?.run_details?.error,
17763
+ typeof raw === "string" ? raw : ""
17764
+ ];
17765
+ const combinedText = textSources.filter(Boolean).join(" ").toLowerCase();
17766
+ if (combinedText.includes("app_authentication") || combinedText.includes("requires authentication") || combinedText.includes("missing authentication") || combinedText.includes("unauthorized") || combinedText.includes("not authenticated") || combinedText.includes("invalid credentials") || combinedText.includes("missing api key")) {
17767
+ needsAuth = true;
17768
+ }
17769
+ if (!needsAuth && (decision?.status === "WAITING" || decision?.status === "PENDING" || decision?.run_details?.status === "WAITING" || decision?.run_details?.status === "PENDING")) {
17770
+ if (toolAppName && appRequiresAuthentication(toolAppName)) {
17771
+ needsAuth = true;
17772
+ }
17773
+ }
17774
+ if (!needsAuth) return null;
17775
+ let appName = candidateAppName || toolAppName;
17146
17776
  if (!appName) {
17147
17777
  const f = (decision?.fields || []).find((x) => x?.key === "app" || x?.key === "app_name");
17148
17778
  if (f?.value) appName = f.value;
@@ -17157,12 +17787,17 @@ var STATUS_COLORS = {
17157
17787
  running: "hsl(var(--primary))"
17158
17788
  };
17159
17789
  var TERMINAL_RUN_STATUSES = ["FINISHED", "FAILURE", "ABORTED", "CANCELLED", "CANCELED"];
17160
- var resolveRunStatus = (executionStatus, agentStatus) => {
17161
- const exec = String(executionStatus || "").toUpperCase();
17162
- const agent = String(agentStatus || "").toUpperCase();
17163
- if (TERMINAL_RUN_STATUSES.includes(exec)) return exec;
17164
- if (TERMINAL_RUN_STATUSES.includes(agent)) return agent;
17165
- return exec || agent || "";
17790
+ var resolveRunStatus = (execStatus, agentStatus) => {
17791
+ const e = (execStatus || "").toUpperCase();
17792
+ const a = (agentStatus || "").toUpperCase();
17793
+ if (e === "FINISHED" || a === "FINISHED") return "FINISHED";
17794
+ if (e === "FAILURE" || a === "FAILURE") return "FAILURE";
17795
+ if (e === "ABORTED" || a === "ABORTED") return "ABORTED";
17796
+ if (e === "CANCELLED" || a === "CANCELLED" || e === "CANCELED" || a === "CANCELED") return "CANCELLED";
17797
+ if (e === "WAITING" || a === "WAITING") return "WAITING";
17798
+ if (e === "PENDING" || a === "PENDING") return "PENDING";
17799
+ if (e === "RUNNING" || a === "RUNNING" || e === "EXECUTING" || a === "EXECUTING") return "RUNNING";
17800
+ return e || a || "FINISHED";
17166
17801
  };
17167
17802
  var buildToolName = (apps) => {
17168
17803
  if (!apps.length) return "API";
@@ -17178,26 +17813,33 @@ var isBuiltinDefaultApps = (apps) => {
17178
17813
  );
17179
17814
  };
17180
17815
  var DurationCountdown = ({ resumeAtMs }) => {
17181
- const [nowMs, setNowMs] = useState19(() => Date.now());
17182
- useEffect17(() => {
17816
+ const [nowMs, setNowMs] = useState20(() => Date.now());
17817
+ useEffect18(() => {
17183
17818
  const t = setInterval(() => setNowMs(Date.now()), 1e3);
17184
17819
  return () => clearInterval(t);
17185
17820
  }, []);
17186
17821
  const remaining = resumeAtMs - nowMs;
17187
17822
  return /* @__PURE__ */ jsx31(Tooltip14, { title: `Scheduled to continue at ${new Date(resumeAtMs).toLocaleString()}`, arrow: true, children: /* @__PURE__ */ jsx31(Box22, { component: "span", sx: { whiteSpace: "nowrap", cursor: "default" }, children: remaining > 0 ? `in ${formatTimeLeft(remaining)}` : "due now" }) });
17188
17823
  };
17189
- var StatusIcon = ({ status, resumeAtMs }) => {
17824
+ var StatusIcon = ({
17825
+ status,
17826
+ resumeAtMs,
17827
+ authBlockedApp
17828
+ }) => {
17190
17829
  const s = (status || "").toUpperCase();
17191
17830
  const isScheduledWait = s === "WAITING" && !!resumeAtMs;
17192
- const [nowMs, setNowMs] = useState19(() => Date.now());
17193
- useEffect17(() => {
17831
+ const [nowMs, setNowMs] = useState20(() => Date.now());
17832
+ useEffect18(() => {
17194
17833
  if (!isScheduledWait) return;
17195
17834
  const t = setInterval(() => setNowMs(Date.now()), 1e3);
17196
17835
  return () => clearInterval(t);
17197
17836
  }, [isScheduledWait]);
17198
17837
  let node;
17199
17838
  let label;
17200
- if (s === "RUNNING" || s === "EXECUTING" || s === "") {
17839
+ if (authBlockedApp) {
17840
+ node = /* @__PURE__ */ jsx31(LockIcon3, { size: 20, color: "hsl(var(--destructive))" });
17841
+ label = `Authentication required for ${formatAppDisplayName(authBlockedApp)} \u2014 step cannot proceed until connected`;
17842
+ } else if (s === "RUNNING" || s === "EXECUTING" || s === "") {
17201
17843
  node = /* @__PURE__ */ jsx31(CircularProgress5, { size: 18, sx: { color: STATUS_COLORS.running } });
17202
17844
  label = "Running";
17203
17845
  } else if (s === "WAITING") {
@@ -17233,8 +17875,8 @@ var formatAgo = (sec) => {
17233
17875
  return `${Math.floor(diff / 86400)}d ago`;
17234
17876
  };
17235
17877
  var ScheduledLiveBar = ({ startSec, originalStartTime, totalDuration, maxWidth }) => {
17236
- const [nowSec, setNowSec] = useState19(() => Date.now() / 1e3);
17237
- useEffect17(() => {
17878
+ const [nowSec, setNowSec] = useState20(() => Date.now() / 1e3);
17879
+ useEffect18(() => {
17238
17880
  const t = setInterval(() => setNowSec(Date.now() / 1e3), 1e3);
17239
17881
  return () => clearInterval(t);
17240
17882
  }, []);
@@ -17281,7 +17923,7 @@ var TimelineRow = ({
17281
17923
  dimmedByRerun = false,
17282
17924
  optimisticContinueText
17283
17925
  }) => {
17284
- const [submitAttempted, setSubmitAttempted] = useState19(false);
17926
+ const [submitAttempted, setSubmitAttempted] = useState20(false);
17285
17927
  const validate = validateJson(item.details);
17286
17928
  const screenshotPayloads = useMemo10(
17287
17929
  () => extractScreenshotPayloads(validate.valid ? validate.result : item.details),
@@ -17396,8 +18038,10 @@ var TimelineRow = ({
17396
18038
  const s = (effectiveStatus || "").toUpperCase();
17397
18039
  return s === "WAITING" || s === "RUNNING" || s === "EXECUTING" || s === "";
17398
18040
  })();
17399
- const barColor = isProcessing ? "hsl(var(--muted-foreground) / 0.45)" : isFailed ? STATUS_COLORS.error : "hsl(var(--muted-foreground) / 0.35)";
17400
- const hoverBarColor = isProcessing ? "hsl(var(--muted-foreground) / 0.45)" : effectiveStatus === "FINISHED" || effectiveStatus === "IGNORED" ? STATUS_COLORS.finished : isFailed ? STATUS_COLORS.error : STATUS_COLORS.running;
18041
+ const rowAuthReq = extractAuthRequest(details);
18042
+ const isRowAuthBlocked = !!rowAuthReq && !isAppAuthenticated?.(rowAuthReq.appName, rowAuthReq.appId) && (effectiveStatus === "WAITING" || effectiveStatus === "PENDING" || effectiveStatus === "FAILURE" || effectiveStatus === "ABORTED");
18043
+ const barColor = isProcessing ? "hsl(var(--muted-foreground) / 0.45)" : isFailed || isRowAuthBlocked ? STATUS_COLORS.error : "hsl(var(--muted-foreground) / 0.35)";
18044
+ const hoverBarColor = isProcessing ? "hsl(var(--muted-foreground) / 0.45)" : effectiveStatus === "FINISHED" || effectiveStatus === "IGNORED" ? STATUS_COLORS.finished : isFailed || isRowAuthBlocked ? STATUS_COLORS.error : STATUS_COLORS.running;
17401
18045
  const isRerunTarget = !!rerunningDecisionId && item.type === "decision" && details?.run_details?.id === rerunningDecisionId;
17402
18046
  return /* @__PURE__ */ jsxs24(
17403
18047
  Box22,
@@ -17406,9 +18050,25 @@ var TimelineRow = ({
17406
18050
  sx: {
17407
18051
  borderTop: index === 0 ? "none" : "1px solid hsl(var(--border))",
17408
18052
  bgcolor: highlight ? "hsla(var(--severity-medium) / 0.12)" : isRerunTarget ? "hsla(var(--primary) / 0.08)" : open ? "hsl(var(--muted) / 0.3)" : "transparent",
17409
- transition: "background 0.6s ease, box-shadow 0.6s ease, opacity 0.2s ease",
17410
- scrollMarginTop: 96,
18053
+ transition: "background-color 0.2s ease",
18054
+ "&:hover": {
18055
+ bgcolor: "hsl(var(--muted) / 0.4)"
18056
+ },
17411
18057
  position: "relative",
18058
+ "&::before": {
18059
+ content: '""',
18060
+ position: "absolute",
18061
+ left: 0,
18062
+ top: 0,
18063
+ bottom: 0,
18064
+ width: 3,
18065
+ bgcolor: barColor,
18066
+ transition: "background-color 0.15s ease"
18067
+ },
18068
+ "&:hover::before": {
18069
+ bgcolor: hoverBarColor
18070
+ },
18071
+ scrollMarginTop: 96,
17412
18072
  boxShadow: highlight ? "inset 0 0 0 2px hsla(var(--severity-medium) / 0.55)" : isRerunTarget ? "inset 0 0 0 1px hsla(var(--primary) / 0.5)" : "none",
17413
18073
  opacity: dimmedByRerun ? 0.35 : 1,
17414
18074
  pointerEvents: dimmedByRerun ? "none" : "auto"
@@ -17417,22 +18077,17 @@ var TimelineRow = ({
17417
18077
  /* @__PURE__ */ jsxs24(
17418
18078
  Box22,
17419
18079
  {
17420
- onClick: isProcessing ? void 0 : onToggle,
18080
+ onClick: onToggle,
17421
18081
  sx: {
17422
18082
  display: "flex",
17423
18083
  alignItems: "center",
17424
18084
  gap: 1.5,
17425
- px: 2,
17426
- py: 1.25,
17427
- cursor: isProcessing ? "default" : "pointer",
17428
- "--timeline-bar-color": barColor,
17429
- "&:hover": isProcessing ? {} : {
17430
- bgcolor: "hsl(var(--muted) / 0.4)",
17431
- "--timeline-bar-color": hoverBarColor
17432
- }
18085
+ p: 1.5,
18086
+ cursor: "pointer",
18087
+ userSelect: "none"
17433
18088
  },
17434
18089
  children: [
17435
- /* @__PURE__ */ jsx31(Box22, { sx: { width: 24, display: "flex", justifyContent: "center" }, children: isRerunTarget ? /* @__PURE__ */ jsx31(CircularProgress5, { size: 14, sx: { color: "hsl(var(--primary))" } }) : isProcessing ? isLikelyTimedOut ? /* @__PURE__ */ jsx31(Tooltip14, { title: "No new activity for over a minute \u2014 this run has most likely timed out.", arrow: true, children: /* @__PURE__ */ jsx31(Box22, { sx: { display: "flex" }, children: /* @__PURE__ */ jsx31(WarningIcon, { size: 14, color: STATUS_COLORS.warning }) }) }) : isLiveProcessing ? /* @__PURE__ */ jsx31(CircularProgress5, { size: 12, sx: { color: "hsl(var(--muted-foreground))" } }) : /* @__PURE__ */ jsx31(Box22, { sx: { width: 6, height: 6, borderRadius: "50%", bgcolor: "hsl(var(--muted-foreground) / 0.5)" } }) : /* @__PURE__ */ jsx31(StatusIcon, { status: effectiveStatus, resumeAtMs: scheduledResumeMs }) }),
18090
+ /* @__PURE__ */ jsx31(Box22, { sx: { width: 24, display: "flex", justifyContent: "center" }, children: isRerunTarget ? /* @__PURE__ */ jsx31(CircularProgress5, { size: 14, sx: { color: "hsl(var(--primary))" } }) : isProcessing ? isLikelyTimedOut ? /* @__PURE__ */ jsx31(Tooltip14, { title: "No new activity for over a minute \u2014 this run has most likely timed out.", arrow: true, children: /* @__PURE__ */ jsx31(Box22, { sx: { display: "flex" }, children: /* @__PURE__ */ jsx31(WarningIcon, { size: 14, color: STATUS_COLORS.warning }) }) }) : isLiveProcessing ? /* @__PURE__ */ jsx31(CircularProgress5, { size: 12, sx: { color: "hsl(var(--muted-foreground))" } }) : /* @__PURE__ */ jsx31(Box22, { sx: { width: 6, height: 6, borderRadius: "50%", bgcolor: "hsl(var(--muted-foreground) / 0.5)" } }) : /* @__PURE__ */ jsx31(StatusIcon, { status: effectiveStatus, resumeAtMs: scheduledResumeMs, authBlockedApp: isRowAuthBlocked ? rowAuthReq.appName : null }) }),
17436
18091
  /* @__PURE__ */ jsx31(Box22, { sx: { width: 24, display: "flex", justifyContent: "center" }, children: isProcessing ? /* @__PURE__ */ jsx31(Box22, { sx: { width: 22 } }) : toolApp?.icon ? /* @__PURE__ */ jsx31(Tooltip14, { title: (toolApp.name || "").replace(/_/g, " "), arrow: true, children: /* @__PURE__ */ jsx31(Avatar6, { src: toolApp.icon, sx: { width: 22, height: 22, bgcolor: "transparent" }, variant: "rounded" }) }) : item.category === "finalise" || details?.action === "finish" ? /* @__PURE__ */ jsx31(Tooltip14, { title: "Final answer", arrow: true, children: /* @__PURE__ */ jsx31(CheckIcon3, { size: 18 }) }) : /* @__PURE__ */ jsx31(Box22, { sx: { width: 22 } }) }),
17437
18092
  /* @__PURE__ */ jsx31(
17438
18093
  Tooltip14,
@@ -17951,6 +18606,7 @@ var AgentUI = ({
17951
18606
  composeSubmitInput: propComposeSubmitInput,
17952
18607
  contextParams,
17953
18608
  incidentId: propIncidentId,
18609
+ incidentContext: propIncidentContext,
17954
18610
  vulnerabilityId: propVulnerabilityId,
17955
18611
  workflowId: propWorkflowId
17956
18612
  }) => {
@@ -17965,9 +18621,13 @@ var AgentUI = ({
17965
18621
  return h;
17966
18622
  }, [apiKey, orgId]);
17967
18623
  const hasApiKey = !!apiKey || !!API_CONFIG.apiKey;
18624
+ const resolvedIncidentId = propIncidentId || (contextCategory === "incidents" ? contextParams?.id : void 0) || (typeof window !== "undefined" ? window.__shuffleActiveIncidentId : void 0);
18625
+ const resolvedIncidentContext = propIncidentContext || (typeof window !== "undefined" ? window.__shuffleActiveIncidentContext : void 0);
18626
+ const resolvedVulnerabilityId = propVulnerabilityId || (contextCategory === "vulnerabilities" ? contextParams?.id : void 0) || (typeof window !== "undefined" ? window.__shuffleActiveVulnerabilityId : void 0);
18627
+ const resolvedWorkflowId = propWorkflowId || (contextCategory === "workflows" ? contextParams?.id : void 0) || (typeof window !== "undefined" ? window.__shuffleActiveWorkflowId : void 0);
17968
18628
  const isPhoneScreen = useMediaQuery("(max-width:600px)", { noSsr: true });
17969
18629
  const isPhone = mobileView !== void 0 ? mobileView : isPhoneScreen;
17970
- const [actionInput, setActionInput] = useState19(() => {
18630
+ const [actionInput, setActionInput] = useState20(() => {
17971
18631
  if (contextStorageKey) {
17972
18632
  const saved = getPageContextChoice(contextStorageKey);
17973
18633
  if (saved?.draftPrompt !== void 0 && saved.draftPrompt !== "") {
@@ -17977,7 +18637,7 @@ var AgentUI = ({
17977
18637
  return defaultInput || "";
17978
18638
  });
17979
18639
  const lastStorageKeyRef = useRef11(contextStorageKey);
17980
- useEffect17(() => {
18640
+ useEffect18(() => {
17981
18641
  if (lastStorageKeyRef.current !== contextStorageKey) {
17982
18642
  lastStorageKeyRef.current = contextStorageKey;
17983
18643
  if (contextStorageKey) {
@@ -17991,18 +18651,18 @@ var AgentUI = ({
17991
18651
  }
17992
18652
  }, [contextStorageKey, defaultInput]);
17993
18653
  const prevDefaultInputRef = useRef11(defaultInput);
17994
- useEffect17(() => {
18654
+ useEffect18(() => {
17995
18655
  if (defaultInput && defaultInput !== prevDefaultInputRef.current) {
17996
18656
  prevDefaultInputRef.current = defaultInput;
17997
18657
  setActionInput(defaultInput);
17998
18658
  }
17999
18659
  }, [defaultInput]);
18000
18660
  const { prompt: savedPromptPrefix } = useAgentPromptPrefix({ userId, persist: !disableStartTab });
18001
- const [selectedPreset, setSelectedPreset] = useState19(null);
18661
+ const [selectedPreset, setSelectedPreset] = useState20(null);
18002
18662
  const presetsChipNodeRef = useRef11(null);
18003
- const [presetsChipWidth, setPresetsChipWidth] = useState19(0);
18004
- const [inputScrolled, setInputScrolled] = useState19(false);
18005
- const [inputScrollTop, setInputScrollTop] = useState19(0);
18663
+ const [presetsChipWidth, setPresetsChipWidth] = useState20(0);
18664
+ const [inputScrolled, setInputScrolled] = useState20(false);
18665
+ const [inputScrollTop, setInputScrollTop] = useState20(0);
18006
18666
  const chipOverlayRef = useRef11(null);
18007
18667
  const applyChipScroll = useCallback10((st) => {
18008
18668
  const el = chipOverlayRef.current;
@@ -18017,9 +18677,9 @@ var AgentUI = ({
18017
18677
  el.style.opacity = st > 24 ? "0" : "1";
18018
18678
  el.style.pointerEvents = st > 4 ? "none" : "auto";
18019
18679
  }, []);
18020
- const [promptSingleLine, setPromptSingleLine] = useState19(true);
18680
+ const [promptSingleLine, setPromptSingleLine] = useState20(true);
18021
18681
  const promptMultilineBase = !promptSingleLine;
18022
- const [attachmentsRowHeight, setAttachmentsRowHeight] = useState19(0);
18682
+ const [attachmentsRowHeight, setAttachmentsRowHeight] = useState20(0);
18023
18683
  const attachmentsRowRef = useCallback10((node) => {
18024
18684
  setAttachmentsRowHeight(node ? node.getBoundingClientRect().height : 0);
18025
18685
  }, []);
@@ -18029,7 +18689,7 @@ var AgentUI = ({
18029
18689
  }, []);
18030
18690
  const inputRef = useRef11(null);
18031
18691
  const seededPresetIdRef = useRef11(null);
18032
- useEffect17(() => {
18692
+ useEffect18(() => {
18033
18693
  if (!initialPresetId && defaultInput && defaultInput.trim().length > 0) {
18034
18694
  setSelectedPreset(null);
18035
18695
  return;
@@ -18045,17 +18705,37 @@ var AgentUI = ({
18045
18705
  if (!match || match.enabled === false) return;
18046
18706
  setSelectedPreset(match);
18047
18707
  if (defaultApps === void 0 && !apps) {
18708
+ const resolved = resolvePresetApps(match);
18048
18709
  const override = readPresetAppsOverride(match.id);
18049
- if (override) {
18050
- setChosenApps(override);
18051
- } else if (match.defaultApps && match.defaultApps.length > 0) {
18052
- setChosenApps(match.defaultApps.map((app2) => ({ name: app2.name, id: app2.id, icon: app2.icon })));
18710
+ if (override && override.length > 0) {
18711
+ const merged = [...override];
18712
+ for (const app2 of resolved) {
18713
+ const key = (app2.id || app2.name).toLowerCase();
18714
+ if (!merged.some((m) => (m.id || m.name).toLowerCase() === key)) {
18715
+ merged.push(app2);
18716
+ }
18717
+ }
18718
+ setChosenApps(merged);
18719
+ } else {
18720
+ setChosenApps(resolved);
18053
18721
  }
18054
18722
  }
18055
18723
  seededPresetIdRef.current = match.id;
18056
18724
  } catch {
18057
18725
  }
18058
18726
  }, [presets, defaultInput, isEffectiveSupport, initialPresetId, defaultApps, apps]);
18727
+ useEffect18(() => {
18728
+ const handleToolsChanged = () => {
18729
+ const targetPreset = selectedPreset || AGENT_PRESETS.find((p) => p.id === "incident-response") || AGENT_PRESETS[0];
18730
+ if (targetPreset) {
18731
+ const next = resolvePresetApps(targetPreset);
18732
+ setChosenApps(next);
18733
+ writePresetAppsOverride(targetPreset.id, next);
18734
+ }
18735
+ };
18736
+ window.addEventListener(AGENT_TOOLS_CHANGED_EVENT, handleToolsChanged);
18737
+ return () => window.removeEventListener(AGENT_TOOLS_CHANGED_EVENT, handleToolsChanged);
18738
+ }, [selectedPreset]);
18059
18739
  useLayoutEffect(() => {
18060
18740
  if (hidePresets) {
18061
18741
  setPresetsChipWidth(0);
@@ -18084,7 +18764,7 @@ var AgentUI = ({
18084
18764
  ro?.disconnect();
18085
18765
  };
18086
18766
  }, [selectedPreset, hidePresets, presets, actionInput]);
18087
- useEffect17(() => {
18767
+ useEffect18(() => {
18088
18768
  const el = inputRef.current;
18089
18769
  if (!el) return;
18090
18770
  if (el.scrollTop <= 1 && inputScrolled) setInputScrolled(false);
@@ -18149,7 +18829,7 @@ var AgentUI = ({
18149
18829
  };
18150
18830
  }, [actionInput, presetsChipWidth, selectedPreset, hidePresets]);
18151
18831
  const shouldTypewrite = placeholder === void 0;
18152
- const [fullPlaceholder, setFullPlaceholder] = useState19(
18832
+ const [fullPlaceholder, setFullPlaceholder] = useState20(
18153
18833
  () => placeholder ?? getRandomAgentPromptPlaceholder()
18154
18834
  );
18155
18835
  const pickedPlaceholderRef = useRef11(null);
@@ -18180,10 +18860,10 @@ var AgentUI = ({
18180
18860
  pickedPlaceholderRef.current = picked;
18181
18861
  setFullPlaceholder(picked);
18182
18862
  }, [shouldTypewrite, presetsChipWidth, hidePresets]);
18183
- const [typedPlaceholder, setTypedPlaceholder] = useState19(
18863
+ const [typedPlaceholder, setTypedPlaceholder] = useState20(
18184
18864
  shouldTypewrite ? "" : fullPlaceholder
18185
18865
  );
18186
- useEffect17(() => {
18866
+ useEffect18(() => {
18187
18867
  if (!shouldTypewrite) {
18188
18868
  setTypedPlaceholder(fullPlaceholder);
18189
18869
  return;
@@ -18217,14 +18897,14 @@ var AgentUI = ({
18217
18897
  [propComposeSubmitInput]
18218
18898
  );
18219
18899
  const promptAnchorRef = React6.useRef(null);
18220
- const [suggestionsDismissed, setSuggestionsDismissed] = useState19(false);
18221
- const [suggestionIndex, setSuggestionIndex] = useState19(-1);
18900
+ const [suggestionsDismissed, setSuggestionsDismissed] = useState20(false);
18901
+ const [suggestionIndex, setSuggestionIndex] = useState20(-1);
18222
18902
  const promptSuggestions = useMemo10(
18223
18903
  () => matchAgentPromptSuggestions(actionInput, 8),
18224
18904
  [actionInput]
18225
18905
  );
18226
18906
  const programmaticInputRef = useRef11(false);
18227
- useEffect17(() => {
18907
+ useEffect18(() => {
18228
18908
  if (programmaticInputRef.current) {
18229
18909
  programmaticInputRef.current = false;
18230
18910
  return;
@@ -18233,7 +18913,7 @@ var AgentUI = ({
18233
18913
  setSuggestionsDismissed(false);
18234
18914
  }, [actionInput]);
18235
18915
  const suggestionsOpen = promptSuggestions.length > 0 && !suggestionsDismissed;
18236
- const [pendingCategories, setPendingCategories] = useState19([]);
18916
+ const [pendingCategories, setPendingCategories] = useState20([]);
18237
18917
  const acceptSuggestion = useCallback10((s) => {
18238
18918
  programmaticInputRef.current = true;
18239
18919
  setActionInput(s);
@@ -18266,7 +18946,7 @@ var AgentUI = ({
18266
18946
  { name: "http" },
18267
18947
  { name: "shuffle_tools" }
18268
18948
  ];
18269
- const [chosenApps, setChosenApps] = useState19(() => {
18949
+ const [chosenApps, setChosenApps] = useState20(() => {
18270
18950
  if (apps) return apps;
18271
18951
  if (defaultApps !== void 0) return defaultApps.slice(0, MAX_AUTO_ASSIGNED_TOOLS);
18272
18952
  const saved = readPresetAppsOverride(NO_PRESET_KEY);
@@ -18275,23 +18955,23 @@ var AgentUI = ({
18275
18955
  });
18276
18956
  const isInitialMountChosenAppsRef = useRef11(true);
18277
18957
  const isInitialMountPresetOverrideRef = useRef11(true);
18278
- const [availableApps, setAvailableApps] = useState19([]);
18279
- const [authAppsLoading, setAuthAppsLoading] = useState19(autoLoadApps && hasApiKey);
18280
- const [detectedLLM, setDetectedLLM] = useState19(null);
18281
- const [configuredLLMOptions, setConfiguredLLMOptions] = useState19([]);
18282
- const [llmMenuAnchor, setLlmMenuAnchor] = useState19(null);
18283
- const [executionApps, setExecutionApps] = useState19([]);
18284
- const [resolvedToolApps, setResolvedToolApps] = useState19({});
18285
- const [appSearchOpen, setAppSearchOpen] = useState19(false);
18286
- const [appSearchQuery, setAppSearchQuery] = useState19("");
18287
- const [categoryTarget, setCategoryTarget] = useState19(null);
18288
- const [authDrawerApp, setAuthDrawerApp] = useState19(null);
18289
- const [agentRequestLoading, setAgentRequestLoading] = useState19(false);
18290
- const [rerunningDecisionId, setRerunningDecisionId] = useState19(null);
18958
+ const [availableApps, setAvailableApps] = useState20([]);
18959
+ const [authAppsLoading, setAuthAppsLoading] = useState20(autoLoadApps && hasApiKey);
18960
+ const [detectedLLM, setDetectedLLM] = useState20(null);
18961
+ const [configuredLLMOptions, setConfiguredLLMOptions] = useState20([]);
18962
+ const [llmMenuAnchor, setLlmMenuAnchor] = useState20(null);
18963
+ const [executionApps, setExecutionApps] = useState20([]);
18964
+ const [resolvedToolApps, setResolvedToolApps] = useState20({});
18965
+ const [appSearchOpen, setAppSearchOpen] = useState20(false);
18966
+ const [appSearchQuery, setAppSearchQuery] = useState20("");
18967
+ const [categoryTarget, setCategoryTarget] = useState20(null);
18968
+ const [authDrawerApp, setAuthDrawerApp] = useState20(null);
18969
+ const [agentRequestLoading, setAgentRequestLoading] = useState20(false);
18970
+ const [rerunningDecisionId, setRerunningDecisionId] = useState20(null);
18291
18971
  const rerunDecisionsSigRef = useRef11("");
18292
- const [rerunAgentPending, setRerunAgentPending] = useState19(false);
18293
- const [abortLoading, setAbortLoading] = useState19(false);
18294
- const [execution, setExecution] = useState19(() => {
18972
+ const [rerunAgentPending, setRerunAgentPending] = useState20(false);
18973
+ const [abortLoading, setAbortLoading] = useState20(false);
18974
+ const [execution, setExecution] = useState20(() => {
18295
18975
  if (initialExecution) return initialExecution;
18296
18976
  if (contextStorageKey) {
18297
18977
  const saved = getPageContextChoice(contextStorageKey);
@@ -18305,13 +18985,13 @@ var AgentUI = ({
18305
18985
  }
18306
18986
  return null;
18307
18987
  });
18308
- const [agentData, setAgentData] = useState19({});
18309
- const [agentActionResult, setAgentActionResult] = useState19(null);
18988
+ const [agentData, setAgentData] = useState20({});
18989
+ const [agentActionResult, setAgentActionResult] = useState20(null);
18310
18990
  const llmImageAttachments = useMemo10(
18311
18991
  () => collectLlmImageAttachments(agentData),
18312
18992
  [agentData]
18313
18993
  );
18314
- const [showStarter, setShowStarter] = useState19(() => {
18994
+ const [showStarter, setShowStarter] = useState20(() => {
18315
18995
  if (initialExecution?.execution_id) return false;
18316
18996
  if (contextStorageKey) {
18317
18997
  const saved = getPageContextChoice(contextStorageKey);
@@ -18333,13 +19013,19 @@ var AgentUI = ({
18333
19013
  localStorage.setItem(LAST_PRESET_STORAGE_KEY, preset.id);
18334
19014
  } catch {
18335
19015
  }
19016
+ const resolved = resolvePresetApps(preset);
18336
19017
  const override = readPresetAppsOverride(preset.id);
18337
19018
  if (override && override.length > 0) {
18338
- setChosenApps(override);
18339
- } else if (preset.defaultApps && preset.defaultApps.length > 0) {
18340
- setChosenApps(preset.defaultApps.map((app2) => ({ name: app2.name, id: app2.id, icon: app2.icon })));
19019
+ const merged = [...override];
19020
+ for (const app2 of resolved) {
19021
+ const key = (app2.id || app2.name).toLowerCase();
19022
+ if (!merged.some((m) => (m.id || m.name).toLowerCase() === key)) {
19023
+ merged.push(app2);
19024
+ }
19025
+ }
19026
+ setChosenApps(merged);
18341
19027
  } else {
18342
- setChosenApps([]);
19028
+ setChosenApps(resolved);
18343
19029
  }
18344
19030
  seededPresetIdRef.current = preset.id;
18345
19031
  if (onSelectPreset) {
@@ -18355,40 +19041,40 @@ var AgentUI = ({
18355
19041
  }
18356
19042
  }, 0);
18357
19043
  }, [onSelectPreset]);
18358
- const [scheduleAnchor, setScheduleAnchor] = useState19(null);
18359
- const [mobilePlusAnchor, setMobilePlusAnchor] = useState19(null);
18360
- const [scheduleCron, setScheduleCron] = useState19("0 * * * *");
18361
- const [scheduleSaving, setScheduleSaving] = useState19(false);
18362
- const [scheduleSteps, setScheduleSteps] = useState19([
19044
+ const [scheduleAnchor, setScheduleAnchor] = useState20(null);
19045
+ const [mobilePlusAnchor, setMobilePlusAnchor] = useState20(null);
19046
+ const [scheduleCron, setScheduleCron] = useState20("0 * * * *");
19047
+ const [scheduleSaving, setScheduleSaving] = useState20(false);
19048
+ const [scheduleSteps, setScheduleSteps] = useState20([
18363
19049
  { id: "name", state: "pending" },
18364
19050
  { id: "workflow", state: "pending" },
18365
19051
  { id: "schedule", state: "pending" }
18366
19052
  ]);
18367
- const [schedFreq, setSchedFreq] = useState19("hours");
18368
- const [schedInterval, setSchedInterval] = useState19(1);
18369
- const [schedHour, setSchedHour] = useState19(9);
18370
- const [schedMinute, setSchedMinute] = useState19(0);
18371
- const [schedWeekdays, setSchedWeekdays] = useState19(() => /* @__PURE__ */ new Set([1]));
18372
- const [schedDayOfMonth, setSchedDayOfMonth] = useState19(1);
18373
- const [schedAdvancedOpen, setSchedAdvancedOpen] = useState19(false);
19053
+ const [schedFreq, setSchedFreq] = useState20("hours");
19054
+ const [schedInterval, setSchedInterval] = useState20(1);
19055
+ const [schedHour, setSchedHour] = useState20(9);
19056
+ const [schedMinute, setSchedMinute] = useState20(0);
19057
+ const [schedWeekdays, setSchedWeekdays] = useState20(() => /* @__PURE__ */ new Set([1]));
19058
+ const [schedDayOfMonth, setSchedDayOfMonth] = useState20(1);
19059
+ const [schedAdvancedOpen, setSchedAdvancedOpen] = useState20(false);
18374
19060
  const cronManualOverrideRef = useRef11(false);
18375
- const [openIndexes, setOpenIndexes] = useState19(/* @__PURE__ */ new Set());
18376
- const [highlightedIndex, setHighlightedIndex] = useState19(null);
18377
- const [continueHighlighted, setContinueHighlighted] = useState19(false);
18378
- const [questionAnswers, setQuestionAnswers] = useState19({});
18379
- const [simpleSubmitAttempted, setSimpleSubmitAttempted] = useState19(false);
18380
- const [finishAnswerRaw, setFinishAnswerRaw] = useState19(false);
18381
- const [continuationText, setContinuationText] = useState19("");
18382
- const [runComplete, setRunComplete] = useState19(false);
18383
- const [optimisticContinue, setOptimisticContinue] = useState19(null);
19061
+ const [openIndexes, setOpenIndexes] = useState20(/* @__PURE__ */ new Set());
19062
+ const [highlightedIndex, setHighlightedIndex] = useState20(null);
19063
+ const [continueHighlighted, setContinueHighlighted] = useState20(false);
19064
+ const [questionAnswers, setQuestionAnswers] = useState20({});
19065
+ const [simpleSubmitAttempted, setSimpleSubmitAttempted] = useState20(false);
19066
+ const [finishAnswerRaw, setFinishAnswerRaw] = useState20(false);
19067
+ const [continuationText, setContinuationText] = useState20("");
19068
+ const [runComplete, setRunComplete] = useState20(false);
19069
+ const [optimisticContinue, setOptimisticContinue] = useState20(null);
18384
19070
  const continuationInputRef = useRef11(null);
18385
19071
  const continuationFocusedForRef = useRef11(null);
18386
- const [error, setError] = useState19(null);
18387
- const [pollWarning, setPollWarning] = useState19(null);
19072
+ const [error, setError] = useState20(null);
19073
+ const [pollWarning, setPollWarning] = useState20(null);
18388
19074
  const hasExecutionDataRef = useRef11(false);
18389
19075
  const loadedExecutionIdRef = useRef11(null);
18390
19076
  const keepPollingUntilRef = useRef11(0);
18391
- const [runExplorerAvailable, setRunExplorerAvailable] = useState19("checking");
19077
+ const [runExplorerAvailable, setRunExplorerAvailable] = useState20("checking");
18392
19078
  const [searchParams, setSearchParams] = useSearchParams();
18393
19079
  const initialViewParam = searchParams.get("agentView");
18394
19080
  const readStoredViewMode = () => {
@@ -18407,8 +19093,8 @@ var AgentUI = ({
18407
19093
  }
18408
19094
  return "simple";
18409
19095
  };
18410
- const [viewMode, setViewMode] = useState19(readStoredViewMode);
18411
- useEffect17(() => {
19096
+ const [viewMode, setViewMode] = useState20(readStoredViewMode);
19097
+ useEffect18(() => {
18412
19098
  try {
18413
19099
  if (typeof window !== "undefined") {
18414
19100
  window.localStorage.setItem("shuffle-agents-view-mode", viewMode);
@@ -18416,15 +19102,15 @@ var AgentUI = ({
18416
19102
  } catch {
18417
19103
  }
18418
19104
  }, [viewMode]);
18419
- const [attachedImages, setAttachedImages] = useState19([]);
18420
- const [previewImage, setPreviewImage] = useState19(null);
19105
+ const [attachedImages, setAttachedImages] = useState20([]);
19106
+ const [previewImage, setPreviewImage] = useState20(null);
18421
19107
  const promptMultiline = promptMultilineBase || attachedImages.length > 0 || isPhone && Boolean(selectedPreset);
18422
19108
  const promptSingleLineLocked = !promptMultiline;
18423
- const [nowTick, setNowTick] = useState19(() => Math.floor(Date.now() / 1e3));
18424
- const [localRunStart, setLocalRunStart] = useState19(null);
19109
+ const [nowTick, setNowTick] = useState20(() => Math.floor(Date.now() / 1e3));
19110
+ const [localRunStart, setLocalRunStart] = useState20(null);
18425
19111
  const chipBarRef = useRef11(null);
18426
19112
  const chipBarResizeObserverRef = useRef11(null);
18427
- const [chipBarMultiline, setChipBarMultiline] = useState19(false);
19113
+ const [chipBarMultiline, setChipBarMultiline] = useState20(false);
18428
19114
  const fileInputRef = useRef11(null);
18429
19115
  const chipBarCallbackRef = useCallback10((node) => {
18430
19116
  chipBarRef.current = node;
@@ -18444,7 +19130,7 @@ var AgentUI = ({
18444
19130
  }
18445
19131
  }, []);
18446
19132
  const activeExecutionIdRef = useRef11(
18447
- initialExecution?.execution_id || (contextStorageKey ? getPageContextChoice(contextStorageKey)?.executionId || null : null)
19133
+ executionId || initialExecution?.execution_id || (contextStorageKey ? getPageContextChoice(contextStorageKey)?.executionId || null : null)
18448
19134
  );
18449
19135
  const executionPollGenerationRef = useRef11(0);
18450
19136
  const runAbortRef = useRef11(null);
@@ -18468,25 +19154,25 @@ var AgentUI = ({
18468
19154
  stateRef.current.continuationText = continuationText;
18469
19155
  stateRef.current.localRunStart = localRunStart;
18470
19156
  stateRef.current.showStarter = showStarter;
18471
- useEffect17(() => {
19157
+ useEffect18(() => {
18472
19158
  const el = chipBarRef.current;
18473
19159
  if (el) {
18474
19160
  setChipBarMultiline(el.clientHeight > 42 || el.scrollHeight > 42);
18475
19161
  }
18476
19162
  }, [chosenApps, availableApps, selectedPreset]);
18477
- useEffect17(() => {
19163
+ useEffect18(() => {
18478
19164
  return () => {
18479
19165
  chipBarResizeObserverRef.current?.disconnect();
18480
19166
  };
18481
19167
  }, []);
18482
- useEffect17(() => {
19168
+ useEffect18(() => {
18483
19169
  if (execution?.execution_id || agentRequestLoading) {
18484
19170
  setLocalRunStart((prev) => prev ?? Math.floor(Date.now() / 1e3));
18485
19171
  } else {
18486
19172
  setLocalRunStart(null);
18487
19173
  }
18488
19174
  }, [execution?.execution_id, agentRequestLoading]);
18489
- useEffect17(() => {
19175
+ useEffect18(() => {
18490
19176
  if (!execution?.execution_id && !agentRequestLoading) return;
18491
19177
  const status = (execution?.status || agentData?.status || "").toUpperCase();
18492
19178
  const TERMINAL = ["FINISHED", "FAILURE", "ABORTED", "CANCELLED", "CANCELED"];
@@ -18557,9 +19243,9 @@ var AgentUI = ({
18557
19243
  }, [availableApps]);
18558
19244
  const pendingAuthApps = useMemo10(() => {
18559
19245
  if (authAppsLoading) return [];
18560
- const decisions = agentData?.decisions || [];
18561
19246
  const seen = /* @__PURE__ */ new Set();
18562
19247
  const out = [];
19248
+ const decisions = agentData?.decisions || [];
18563
19249
  for (const d of decisions) {
18564
19250
  const req = extractAuthRequest(d);
18565
19251
  if (!req) continue;
@@ -18571,12 +19257,25 @@ var AgentUI = ({
18571
19257
  const icon = appsById[req.appName]?.icon || appsById[slug]?.icon || (appId ? appsById[appId]?.icon : "") || "";
18572
19258
  out.push({ appName: req.appName, appId, icon });
18573
19259
  }
19260
+ const hasAllowed = Array.isArray(agentData?.allowed_actions) && agentData.allowed_actions.length > 0;
19261
+ const activeAppList = hasAllowed ? executionApps : chosenApps;
19262
+ for (const app2 of activeAppList) {
19263
+ if (!app2?.name) continue;
19264
+ const slug = normalizeAgentAppName(app2.name);
19265
+ if (seen.has(slug)) continue;
19266
+ if (appRequiresAuthentication(slug) && !isAppAuthenticated(app2.name, app2.id || null)) {
19267
+ seen.add(slug);
19268
+ const appId = app2.id || appsById[app2.name]?.id || appsById[slug]?.id || null;
19269
+ const icon = app2.icon || appsById[app2.name]?.icon || appsById[slug]?.icon || (appId ? appsById[appId]?.icon : "") || "";
19270
+ out.push({ appName: app2.name, appId, icon });
19271
+ }
19272
+ }
18574
19273
  return out;
18575
- }, [agentData, appsById, authAppsLoading, isAppAuthenticated]);
18576
- useEffect17(() => {
19274
+ }, [agentData, executionApps, chosenApps, appsById, authAppsLoading, isAppAuthenticated]);
19275
+ useEffect18(() => {
18577
19276
  if (apps) setChosenApps(apps);
18578
19277
  }, [apps]);
18579
- useEffect17(() => {
19278
+ useEffect18(() => {
18580
19279
  const required = selectedPreset?.requiredApps;
18581
19280
  if (!required || required.length === 0) return;
18582
19281
  setChosenApps((prev) => {
@@ -18585,7 +19284,7 @@ var AgentUI = ({
18585
19284
  return [...prev, ...missing.map((name) => ({ name }))];
18586
19285
  });
18587
19286
  }, [selectedPreset]);
18588
- useEffect17(() => {
19287
+ useEffect18(() => {
18589
19288
  const decisions = agentData?.decisions || [];
18590
19289
  if (!Array.isArray(decisions) || decisions.length === 0) return;
18591
19290
  const norm4 = (s) => s.toLowerCase().replace(/[\s-]+/g, "_");
@@ -18633,7 +19332,7 @@ var AgentUI = ({
18633
19332
  cancelled = true;
18634
19333
  };
18635
19334
  }, [JSON.stringify(agentData?.decisions?.map((d) => [d?.details?.tool || d?.tool, extractAuthRequest(d)?.appName]) || []), appsById]);
18636
- useEffect17(() => {
19335
+ useEffect18(() => {
18637
19336
  const missing = chosenApps.filter((a) => !a.icon && a.name);
18638
19337
  if (missing.length === 0) return;
18639
19338
  let cancelled = false;
@@ -18792,7 +19491,7 @@ var AgentUI = ({
18792
19491
  if (!signal?.cancelled) setAuthAppsLoading(false);
18793
19492
  }
18794
19493
  }, [resolveUrl2, resolveHeaders2, contextCategory, contextStorageKey, defaultApps, onAppsChange]);
18795
- useEffect17(() => {
19494
+ useEffect18(() => {
18796
19495
  if (!autoLoadApps) return;
18797
19496
  if (!hasApiKey) return;
18798
19497
  const signal = { cancelled: false };
@@ -18801,7 +19500,7 @@ var AgentUI = ({
18801
19500
  signal.cancelled = true;
18802
19501
  };
18803
19502
  }, [autoLoadApps, hasApiKey, loadAuthenticatedApps]);
18804
- useEffect17(() => {
19503
+ useEffect18(() => {
18805
19504
  if (!hasApiKey) return;
18806
19505
  const handler = (event) => {
18807
19506
  const customEvent = event;
@@ -18816,7 +19515,7 @@ var AgentUI = ({
18816
19515
  window.addEventListener("integrations-changed", handler);
18817
19516
  return () => window.removeEventListener("integrations-changed", handler);
18818
19517
  }, [hasApiKey, loadAuthenticatedApps]);
18819
- useEffect17(() => {
19518
+ useEffect18(() => {
18820
19519
  const raw = agentData?.allowed_actions;
18821
19520
  if (!Array.isArray(raw) || raw.length === 0) {
18822
19521
  setExecutionApps([]);
@@ -19006,7 +19705,7 @@ var AgentUI = ({
19006
19705
  else setPollWarning(`Live updates are failing (${err instanceof Error ? err.message : "network error"}). Showing the last known state.`);
19007
19706
  }
19008
19707
  }, []);
19009
- useEffect17(() => {
19708
+ useEffect18(() => {
19010
19709
  const eid = execution?.execution_id;
19011
19710
  const auth = execution?.authorization;
19012
19711
  if (!eid) {
@@ -19033,19 +19732,19 @@ var AgentUI = ({
19033
19732
  cancelled = true;
19034
19733
  };
19035
19734
  }, [execution?.execution_id, execution?.authorization]);
19036
- useEffect17(() => {
19735
+ useEffect18(() => {
19037
19736
  if (execution?.authorization && (execution?.results?.length || 0) > 0) {
19038
19737
  setRunExplorerAvailable("yes");
19039
19738
  }
19040
19739
  }, [execution?.authorization, execution?.results?.length]);
19041
- useEffect17(() => {
19740
+ useEffect18(() => {
19042
19741
  let eid = null;
19043
19742
  let auth = null;
19044
19743
  let initialStatus = "EXECUTING";
19045
19744
  let savedViewMode = null;
19046
- if (executionId && authorization) {
19745
+ if (executionId) {
19047
19746
  eid = executionId;
19048
- auth = authorization;
19747
+ auth = authorization || null;
19049
19748
  } else if (readUrlParams) {
19050
19749
  const params = new URLSearchParams(window.location.search);
19051
19750
  eid = params.get("execution_id");
@@ -19074,7 +19773,7 @@ var AgentUI = ({
19074
19773
  getExecution(eid, auth || void 0);
19075
19774
  }
19076
19775
  }, [readUrlParams, executionId, authorization, getExecution, contextStorageKey]);
19077
- useEffect17(() => {
19776
+ useEffect18(() => {
19078
19777
  if (!initialExecution || !initialExecution.execution_id) return;
19079
19778
  if (!userPickedStartRef.current) setShowStarter(false);
19080
19779
  activeExecutionIdRef.current = initialExecution.execution_id;
@@ -19109,7 +19808,7 @@ var AgentUI = ({
19109
19808
  getExecution(initialExecution.execution_id, initialExecution.authorization);
19110
19809
  }
19111
19810
  }, [initialExecution?.execution_id]);
19112
- useEffect17(() => {
19811
+ useEffect18(() => {
19113
19812
  if (!execution?.execution_id) return;
19114
19813
  const status = (execution.status || "").toUpperCase();
19115
19814
  const TERMINAL = ["FINISHED", "FAILURE", "ABORTED", "CANCELLED", "CANCELED"];
@@ -19187,9 +19886,6 @@ var AgentUI = ({
19187
19886
  return next;
19188
19887
  }, { replace: true });
19189
19888
  }
19190
- const resolvedIncidentId = propIncidentId || (contextCategory === "incidents" ? contextParams?.id : void 0) || (typeof window !== "undefined" ? window.__shuffleActiveIncidentId : void 0);
19191
- const resolvedVulnerabilityId = propVulnerabilityId || (contextCategory === "vulnerabilities" ? contextParams?.id : void 0) || (typeof window !== "undefined" ? window.__shuffleActiveVulnerabilityId : void 0);
19192
- const resolvedWorkflowId = propWorkflowId || (contextCategory === "workflows" ? contextParams?.id : void 0) || (typeof window !== "undefined" ? window.__shuffleActiveWorkflowId : void 0);
19193
19889
  const result = await runAgent({
19194
19890
  input: composed.trim(),
19195
19891
  skipPolling: true,
@@ -19198,6 +19894,7 @@ var AgentUI = ({
19198
19894
  ...apiBaseUrl ? { apiBaseUrl } : {},
19199
19895
  ...orgId ? { orgId } : {},
19200
19896
  ...resolvedIncidentId ? { incidentId: resolvedIncidentId } : {},
19897
+ ...resolvedIncidentContext ? { incidentContext: resolvedIncidentContext } : {},
19201
19898
  ...resolvedVulnerabilityId ? { vulnerabilityId: resolvedVulnerabilityId } : {},
19202
19899
  ...resolvedWorkflowId ? { workflowId: resolvedWorkflowId } : {},
19203
19900
  // Send a single comma-separated `tool_name` in the format
@@ -19268,6 +19965,13 @@ var AgentUI = ({
19268
19965
  const auth = raw?.authorization;
19269
19966
  if (eid && auth) {
19270
19967
  activeExecutionIdRef.current = eid;
19968
+ if (typeof window !== "undefined") {
19969
+ window.dispatchEvent(
19970
+ new CustomEvent("shuffle:agent_execution_status", {
19971
+ detail: { executionId: eid, status: "running", incidentId: resolvedIncidentId }
19972
+ })
19973
+ );
19974
+ }
19271
19975
  if (contextStorageKey) {
19272
19976
  setPageContextChoice(contextStorageKey, {
19273
19977
  draftPrompt: "",
@@ -19313,13 +20017,13 @@ var AgentUI = ({
19313
20017
  onRun?.({ input: text2, success: true, executionId: eid });
19314
20018
  }
19315
20019
  }, [chosenApps, executionApps, getExecution, onRun, attachedImages, readUrlParams, setSearchParams, viewMode, selectedPreset, isLoggedIn]);
19316
- const autoSubmittedRef = useRef11(false);
19317
- useEffect17(() => {
19318
- if (autoSubmit && defaultInput && !autoSubmittedRef.current && !executionId) {
19319
- autoSubmittedRef.current = true;
20020
+ const lastSubmittedInputRef = useRef11(null);
20021
+ useEffect18(() => {
20022
+ if (autoSubmit && defaultInput && defaultInput !== lastSubmittedInputRef.current) {
20023
+ lastSubmittedInputRef.current = defaultInput;
19320
20024
  submitInput(defaultInput);
19321
20025
  }
19322
- }, [autoSubmit, defaultInput, executionId, submitInput]);
20026
+ }, [autoSubmit, defaultInput, submitInput]);
19323
20027
  const submitQuestions = useCallback10(async (decisionId, answers, isContinuation) => {
19324
20028
  if (!execution?.execution_id || !execution?.authorization) return;
19325
20029
  let newArgument = {};
@@ -19495,7 +20199,7 @@ var AgentUI = ({
19495
20199
  }
19496
20200
  setTimeout(() => setRerunAgentPending(false), 8e3);
19497
20201
  }, [resolveRunInput, resolveRunTemplate, actionInput, executionApps, disableStartTab, submitInput]);
19498
- useEffect17(() => {
20202
+ useEffect18(() => {
19499
20203
  if (rerunAgentPending && (agentRequestLoading || execution?.execution_id)) {
19500
20204
  setRerunAgentPending(false);
19501
20205
  }
@@ -19566,7 +20270,7 @@ var AgentUI = ({
19566
20270
  setAbortLoading(false);
19567
20271
  }
19568
20272
  }, [execution, resolveUrl2, resolveHeaders2, getExecution, setSearchParams]);
19569
- useEffect17(() => {
20273
+ useEffect18(() => {
19570
20274
  if (execution?.execution_id) setLastOpenedAgentRun(execution.execution_id);
19571
20275
  }, [execution?.execution_id]);
19572
20276
  const getFormUrl = useCallback10((decisionId) => {
@@ -19631,7 +20335,7 @@ var AgentUI = ({
19631
20335
  setAgentRequestLoading(false);
19632
20336
  }
19633
20337
  }, [execution, agentActionResult, agentData, getExecution, resolveUrl2, resolveHeaders2]);
19634
- useEffect17(() => {
20338
+ useEffect18(() => {
19635
20339
  if (!rerunningDecisionId) return;
19636
20340
  const sig = JSON.stringify(
19637
20341
  (agentData?.decisions || []).map((d) => d?.run_details?.id || "")
@@ -19646,8 +20350,8 @@ var AgentUI = ({
19646
20350
  const runStillExecuting = Boolean(execution?.execution_id || agentRequestLoading) && !TERMINAL_RUN_STATUSES.includes(
19647
20351
  resolveRunStatus(execution?.status, agentData?.status)
19648
20352
  );
19649
- const [liveNowSec, setLiveNowSec] = useState19(() => Date.now() / 1e3);
19650
- useEffect17(() => {
20353
+ const [liveNowSec, setLiveNowSec] = useState20(() => Date.now() / 1e3);
20354
+ useEffect18(() => {
19651
20355
  if (!runStillExecuting) return;
19652
20356
  setLiveNowSec(Date.now() / 1e3);
19653
20357
  const t = setInterval(() => setLiveNowSec(Date.now() / 1e3), 1e3);
@@ -19839,7 +20543,7 @@ var AgentUI = ({
19839
20543
  const total = Math.max(1, end - startSafe);
19840
20544
  return { timeline: items, originalStartTime: startSafe, totalDuration: total, finishDecisionId: finishId, finishAnswer: finishAns, finishNote: finishNote2 };
19841
20545
  }, [agentData, execution?.status, execution?.started_at, execution?.completed_at, runStillExecuting, liveNowSec]);
19842
- useEffect17(() => {
20546
+ useEffect18(() => {
19843
20547
  const status = (execution?.status || "").toUpperCase();
19844
20548
  const isTerminal = ["FINISHED", "FAILURE", "ABORTED", "CANCELLED", "CANCELED"].includes(status);
19845
20549
  const hasPendingDecision = (agentData?.decisions || []).some((d) => {
@@ -19848,7 +20552,38 @@ var AgentUI = ({
19848
20552
  });
19849
20553
  setRunComplete(Boolean(isTerminal && !hasPendingDecision && (finishAnswer || finishDecisionId)));
19850
20554
  }, [execution?.status, agentData?.decisions, finishAnswer, finishDecisionId]);
19851
- useEffect17(() => {
20555
+ useEffect18(() => {
20556
+ const eid = execution?.execution_id || activeExecutionIdRef.current;
20557
+ const status = (execution?.status || agentData?.status || "").toUpperCase();
20558
+ if (!eid || !status || typeof window === "undefined") return;
20559
+ if (status === "FINISHED" || status === "SUCCESS") {
20560
+ window.dispatchEvent(
20561
+ new CustomEvent("shuffle:agent_execution_status", {
20562
+ detail: { executionId: eid, status: "completed", incidentId: resolvedIncidentId }
20563
+ })
20564
+ );
20565
+ if (resolvedIncidentId) {
20566
+ window.dispatchEvent(
20567
+ new CustomEvent("incident:refresh", {
20568
+ detail: { id: resolvedIncidentId, incidentId: resolvedIncidentId, executionId: eid }
20569
+ })
20570
+ );
20571
+ }
20572
+ } else if (["FAILURE", "ABORTED", "CANCELLED", "CANCELED"].includes(status)) {
20573
+ window.dispatchEvent(
20574
+ new CustomEvent("shuffle:agent_execution_status", {
20575
+ detail: { executionId: eid, status: "failed", incidentId: resolvedIncidentId }
20576
+ })
20577
+ );
20578
+ } else if (["RUNNING", "EXECUTING", "IN_PROGRESS", "WAITING"].includes(status)) {
20579
+ window.dispatchEvent(
20580
+ new CustomEvent("shuffle:agent_execution_status", {
20581
+ detail: { executionId: eid, status: "running", incidentId: resolvedIncidentId }
20582
+ })
20583
+ );
20584
+ }
20585
+ }, [execution?.execution_id, execution?.status, agentData?.status, resolvedIncidentId]);
20586
+ useEffect18(() => {
19852
20587
  if (!finishDecisionId || agentRequestLoading) return;
19853
20588
  if (continuationFocusedForRef.current === finishDecisionId) return;
19854
20589
  continuationFocusedForRef.current = finishDecisionId;
@@ -19876,15 +20611,19 @@ var AgentUI = ({
19876
20611
  }
19877
20612
  }, [onChooseLLM]);
19878
20613
  const isAiAuthIssue = useMemo10(() => {
20614
+ const status = (execution?.status || agentData?.status || "").toUpperCase();
20615
+ const isFinished = status === "FINISHED" || status === "SUCCESS";
20616
+ if (isFinished && !isAiAuthText(error)) {
20617
+ return false;
20618
+ }
19879
20619
  if (finishAnswer && finishAnswer.trim().length > 0 && !isAiAuthText(finishAnswer)) {
19880
- const diagnosable2 = execution?.results?.length ? execution : agentData;
19881
- if (!isAiAuthFailure(diagnosable2, error || "")) return false;
20620
+ return false;
19882
20621
  }
19883
20622
  const diagnosable = execution?.results?.length ? execution : agentData;
19884
- return isAiAuthFailure(diagnosable, error || finishAnswer || "");
20623
+ return isAiAuthFailure(diagnosable, error || "");
19885
20624
  }, [execution, agentData, finishAnswer, error]);
19886
20625
  const aiAuthSuggestionNode = isAiAuthIssue ? /* @__PURE__ */ jsx31(Box22, { sx: { mt: 1.5 }, children: /* @__PURE__ */ jsx31(AiAuthSuggestion_default, { onOpenLocalLlm: openLocalLlmArea }) }) : null;
19887
- useEffect17(() => {
20626
+ useEffect18(() => {
19888
20627
  if (!optimisticContinue) return;
19889
20628
  const count = (agentData?.decisions || []).length;
19890
20629
  if (count > optimisticContinue.decisions) {
@@ -19935,7 +20674,7 @@ var AgentUI = ({
19935
20674
  };
19936
20675
  const timelineEndRef = useRef11(null);
19937
20676
  const followTimelineRef = useRef11(true);
19938
- useEffect17(() => {
20677
+ useEffect18(() => {
19939
20678
  if (typeof window === "undefined") return;
19940
20679
  const getScrollParent = (node) => {
19941
20680
  let el = node?.parentElement || null;
@@ -19975,7 +20714,7 @@ var AgentUI = ({
19975
20714
  const runIsLive = optimisticRunning || !["FINISHED", "FAILURE", "ABORTED", "CANCELLED", "CANCELED"].includes(
19976
20715
  (resolveRunStatus(execution?.status, agentData?.status) || "EXECUTING").toUpperCase()
19977
20716
  );
19978
- useEffect17(() => {
20717
+ useEffect18(() => {
19979
20718
  if (typeof window === "undefined") return;
19980
20719
  if (viewMode !== "detailed") return;
19981
20720
  if (!runIsLive) return;
@@ -19993,7 +20732,7 @@ var AgentUI = ({
19993
20732
  window.clearTimeout(t);
19994
20733
  };
19995
20734
  }, [timelineCount, viewMode, runIsLive]);
19996
- useEffect17(() => {
20735
+ useEffect18(() => {
19997
20736
  followTimelineRef.current = true;
19998
20737
  }, [execution?.execution_id]);
19999
20738
  const handlePrimarySubmit = useCallback10(() => {
@@ -20041,17 +20780,17 @@ var AgentUI = ({
20041
20780
  const activeTab = showStarter ? "start" : viewMode;
20042
20781
  const hasExecution = !!execution?.execution_id;
20043
20782
  const showRunSwitcher = hasExecution || agentRequestLoading;
20044
- useEffect17(() => {
20783
+ useEffect18(() => {
20045
20784
  onViewChange?.(activeTab);
20046
20785
  }, [activeTab, onViewChange]);
20047
- useEffect17(() => {
20786
+ useEffect18(() => {
20048
20787
  if (isInitialMountChosenAppsRef.current) {
20049
20788
  isInitialMountChosenAppsRef.current = false;
20050
20789
  return;
20051
20790
  }
20052
20791
  onAppsChange?.(chosenApps);
20053
20792
  }, [chosenApps, onAppsChange]);
20054
- useEffect17(() => {
20793
+ useEffect18(() => {
20055
20794
  if (isInitialMountPresetOverrideRef.current) {
20056
20795
  isInitialMountPresetOverrideRef.current = false;
20057
20796
  return;
@@ -20184,7 +20923,7 @@ var AgentUI = ({
20184
20923
  return parsed && parsed.once ? null : parsed;
20185
20924
  }, [actionInput]);
20186
20925
  const lastAppliedHintRef = useRef11(null);
20187
- useEffect17(() => {
20926
+ useEffect18(() => {
20188
20927
  if (!scheduleHint) return;
20189
20928
  if (scheduleAnchor) return;
20190
20929
  if (lastAppliedHintRef.current === scheduleHint.cron) return;
@@ -20214,7 +20953,7 @@ var AgentUI = ({
20214
20953
  return appRequiresAuthentication(slug) && !isAppAuthenticated(a.name || "", a.id || null);
20215
20954
  });
20216
20955
  }, [authAppsLoading, chosenApps, isAppAuthenticated]);
20217
- useEffect17(() => {
20956
+ useEffect18(() => {
20218
20957
  if (cronManualOverrideRef.current) return;
20219
20958
  const m = Math.max(0, Math.min(59, schedMinute));
20220
20959
  const h = Math.max(0, Math.min(23, schedHour));
@@ -22041,7 +22780,47 @@ var AgentUI = ({
22041
22780
  children: formatAppDisplayName(app2.name || "")
22042
22781
  }
22043
22782
  ),
22044
- (needsAuth || isUnavailable) && /* @__PURE__ */ jsx31(WarningIcon, { size: 14, color: "hsl(var(--severity-medium))", style: { marginRight: 2 } }),
22783
+ needsAuth ? /* @__PURE__ */ jsx31(
22784
+ Box22,
22785
+ {
22786
+ component: "span",
22787
+ sx: {
22788
+ fontSize: "0.65rem",
22789
+ fontWeight: 600,
22790
+ color: "hsl(var(--destructive))",
22791
+ bgcolor: "hsl(var(--destructive) / 0.12)",
22792
+ border: "1px solid hsl(var(--destructive) / 0.3)",
22793
+ borderRadius: 1,
22794
+ px: 0.6,
22795
+ py: 0.1,
22796
+ letterSpacing: "0.02em",
22797
+ textTransform: "uppercase",
22798
+ ml: 0.5,
22799
+ mr: 0.25
22800
+ },
22801
+ children: "Missing auth"
22802
+ }
22803
+ ) : isUnavailable ? /* @__PURE__ */ jsx31(
22804
+ Box22,
22805
+ {
22806
+ component: "span",
22807
+ sx: {
22808
+ fontSize: "0.65rem",
22809
+ fontWeight: 600,
22810
+ color: "hsl(var(--severity-medium))",
22811
+ bgcolor: "hsl(var(--severity-medium) / 0.12)",
22812
+ border: "1px solid hsl(var(--severity-medium) / 0.3)",
22813
+ borderRadius: 1,
22814
+ px: 0.6,
22815
+ py: 0.1,
22816
+ letterSpacing: "0.02em",
22817
+ textTransform: "uppercase",
22818
+ ml: 0.5,
22819
+ mr: 0.25
22820
+ },
22821
+ children: "Unavailable"
22822
+ }
22823
+ ) : null,
22045
22824
  isRequired ? /* @__PURE__ */ jsx31(
22046
22825
  LockIcon3,
22047
22826
  {
@@ -22243,43 +23022,83 @@ var AgentUI = ({
22243
23022
  return list;
22244
23023
  })().map((app2, i) => {
22245
23024
  const slug = normalizeAgentAppName(app2.name || "");
23025
+ const appNeedsAuth = !authAppsLoading && appRequiresAuthentication(slug) && !isAppAuthenticated(app2.name || "", app2.id || null);
22246
23026
  const appIcon = app2.icon || availableApps.find((a) => normalizeAgentAppName(a.name || "") === slug)?.icon || resolvedToolApps[slug]?.icon;
22247
- return /* @__PURE__ */ jsx31(Tooltip14, { title: formatAppDisplayName(app2.name || ""), children: /* @__PURE__ */ jsx31(
22248
- Box22,
23027
+ return /* @__PURE__ */ jsx31(
23028
+ Tooltip14,
22249
23029
  {
22250
- onClick: () => setAuthDrawerApp({ name: app2.name, id: app2.id || null }),
22251
- sx: {
22252
- display: "inline-flex",
22253
- alignItems: "center",
22254
- justifyContent: "center",
22255
- width: 24,
22256
- height: 24,
22257
- borderRadius: "6px",
22258
- overflow: "hidden",
22259
- bgcolor: "hsl(var(--muted))",
22260
- cursor: "pointer",
22261
- transition: "transform 0.15s ease, border-color 0.15s ease",
22262
- "&:hover": { transform: "scale(1.08)", borderColor: "hsl(var(--primary)) !important" }
22263
- },
23030
+ title: appNeedsAuth ? `${formatAppDisplayName(app2.name || "")} \u2014 Missing authentication (Click to connect)` : formatAppDisplayName(app2.name || ""),
22264
23031
  children: /* @__PURE__ */ jsx31(
22265
- AppFallbackIcon,
23032
+ Box22,
22266
23033
  {
22267
- name: app2.name,
22268
- imageUrl: appIcon,
22269
- size: 24,
22270
- style: { borderRadius: 6, objectFit: "contain" }
23034
+ onClick: () => setAuthDrawerApp({ name: app2.name, id: app2.id || null }),
23035
+ sx: {
23036
+ display: "inline-flex",
23037
+ alignItems: "center",
23038
+ justifyContent: "center",
23039
+ width: 24,
23040
+ height: 24,
23041
+ borderRadius: "6px",
23042
+ overflow: "hidden",
23043
+ bgcolor: "hsl(var(--muted))",
23044
+ cursor: "pointer",
23045
+ transition: "transform 0.15s ease, border-color 0.15s ease",
23046
+ border: appNeedsAuth ? "2px solid hsl(var(--destructive)) !important" : "none",
23047
+ boxShadow: appNeedsAuth ? "0 0 0 1px hsl(var(--destructive) / 0.4)" : "none",
23048
+ "&:hover": { transform: "scale(1.08)", borderColor: "hsl(var(--primary)) !important" }
23049
+ },
23050
+ children: /* @__PURE__ */ jsx31(
23051
+ AppFallbackIcon,
23052
+ {
23053
+ name: app2.name,
23054
+ imageUrl: appIcon,
23055
+ size: 24,
23056
+ style: { borderRadius: 6, objectFit: "contain" }
23057
+ }
23058
+ )
22271
23059
  }
22272
23060
  )
22273
- }
22274
- ) }, i);
23061
+ },
23062
+ i
23063
+ );
22275
23064
  }) }),
22276
23065
  /* @__PURE__ */ jsxs24(Box22, { sx: { flex: 1, minWidth: 0 }, children: [
22277
23066
  /* @__PURE__ */ jsx31(Typography19, { sx: { fontSize: "0.85rem", color: "hsl(var(--foreground))", fontWeight: 600, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: extractCleanDisplayPrompt(agentData?.original_input) || actionInput || "Agent run" }),
22278
- /* @__PURE__ */ jsxs24(Typography19, { sx: { fontSize: "0.7rem", color: "hsl(var(--muted-foreground))" }, children: [
22279
- "Status: ",
22280
- execution?.status || agentData?.status || "\u2014",
22281
- " \xB7 ",
22282
- execution?.execution_id?.slice(0, 8) || ""
23067
+ /* @__PURE__ */ jsxs24(Typography19, { sx: { fontSize: "0.7rem", color: "hsl(var(--muted-foreground))", display: "flex", alignItems: "center", gap: 1, flexWrap: "wrap", mt: 0.25 }, children: [
23068
+ /* @__PURE__ */ jsxs24("span", { children: [
23069
+ "Status: ",
23070
+ execution?.status || agentData?.status || "\u2014",
23071
+ " \xB7 ",
23072
+ execution?.execution_id?.slice(0, 8) || ""
23073
+ ] }),
23074
+ pendingAuthApps.length > 0 && /* @__PURE__ */ jsxs24(
23075
+ Box22,
23076
+ {
23077
+ component: "span",
23078
+ onClick: () => setAuthDrawerApp({ name: pendingAuthApps[0].appName, id: pendingAuthApps[0].appId }),
23079
+ sx: {
23080
+ display: "inline-flex",
23081
+ alignItems: "center",
23082
+ gap: 0.5,
23083
+ px: 0.75,
23084
+ py: 0.15,
23085
+ borderRadius: 1,
23086
+ bgcolor: "hsl(var(--destructive) / 0.12)",
23087
+ border: "1px solid hsl(var(--destructive) / 0.35)",
23088
+ color: "hsl(var(--destructive))",
23089
+ fontSize: "0.68rem",
23090
+ fontWeight: 600,
23091
+ cursor: "pointer",
23092
+ textTransform: "none",
23093
+ "&:hover": { bgcolor: "hsl(var(--destructive) / 0.2)" }
23094
+ },
23095
+ children: [
23096
+ "Missing Auth: ",
23097
+ pendingAuthApps.map((a) => formatAppDisplayName(a.appName)).join(", "),
23098
+ " \u2014 Connect"
23099
+ ]
23100
+ }
23101
+ )
22283
23102
  ] })
22284
23103
  ] }),
22285
23104
  /* @__PURE__ */ jsx31(AgentAttachmentsButton_default, { attachments: llmImageAttachments }),
@@ -22459,6 +23278,57 @@ var AgentUI = ({
22459
23278
  }
22460
23279
  }
22461
23280
  ),
23281
+ pendingAuthApps.length > 0 && /* @__PURE__ */ jsxs24(
23282
+ Box22,
23283
+ {
23284
+ sx: {
23285
+ mb: 2,
23286
+ p: 2,
23287
+ borderRadius: 2,
23288
+ border: "1px solid hsla(var(--severity-medium) / 0.35)",
23289
+ bgcolor: "hsla(var(--severity-medium) / 0.08)",
23290
+ display: "flex",
23291
+ alignItems: "center",
23292
+ justifyContent: "space-between",
23293
+ gap: 2,
23294
+ flexWrap: "wrap"
23295
+ },
23296
+ children: [
23297
+ /* @__PURE__ */ jsxs24(Box22, { sx: { display: "flex", alignItems: "center", gap: 1.5, flex: 1, minWidth: 260 }, children: [
23298
+ /* @__PURE__ */ jsx31(LockIcon3, { size: 22, color: "hsl(var(--severity-medium))" }),
23299
+ /* @__PURE__ */ jsxs24(Box22, { sx: { flex: 1, minWidth: 0 }, children: [
23300
+ /* @__PURE__ */ jsx31(Typography19, { sx: { fontSize: "0.875rem", fontWeight: 600, color: "hsl(var(--foreground))" }, children: pendingAuthApps.length === 1 ? `${formatAppDisplayName(pendingAuthApps[0].appName)} requires authentication` : `${pendingAuthApps.map((a) => formatAppDisplayName(a.appName)).join(", ")} require authentication` }),
23301
+ /* @__PURE__ */ jsx31(Typography19, { sx: { fontSize: "0.78rem", color: "hsl(var(--muted-foreground))" }, children: pendingAuthApps.length === 1 ? `The agent cannot complete steps using ${formatAppDisplayName(pendingAuthApps[0].appName)} and may remain pending until connected.` : `The agent cannot complete steps using these tools and may remain pending until connected.` })
23302
+ ] })
23303
+ ] }),
23304
+ /* @__PURE__ */ jsx31(Box22, { sx: { display: "flex", gap: 1, flexWrap: "wrap" }, children: pendingAuthApps.map(({ appName, appId }) => /* @__PURE__ */ jsxs24(
23305
+ Button13,
23306
+ {
23307
+ variant: "outlined",
23308
+ size: "small",
23309
+ onClick: () => setAuthDrawerApp({ name: appName, id: appId }),
23310
+ sx: {
23311
+ borderColor: "hsla(var(--severity-medium) / 0.6)",
23312
+ color: "hsl(var(--foreground))",
23313
+ textTransform: "none",
23314
+ fontSize: "0.75rem",
23315
+ fontWeight: 600,
23316
+ height: 32,
23317
+ "&:hover": {
23318
+ bgcolor: "hsla(var(--severity-medium) / 0.15)",
23319
+ borderColor: "hsl(var(--severity-medium))"
23320
+ }
23321
+ },
23322
+ children: [
23323
+ "Authenticate ",
23324
+ formatAppDisplayName(appName)
23325
+ ]
23326
+ },
23327
+ appName
23328
+ )) })
23329
+ ]
23330
+ }
23331
+ ),
22462
23332
  viewMode === "simple" && /* @__PURE__ */ jsx31(Box22, { sx: {
22463
23333
  borderRadius: 2,
22464
23334
  border: "1px solid hsl(var(--border))",
@@ -22500,7 +23370,7 @@ var AgentUI = ({
22500
23370
  }
22501
23371
  const pendingAnswered = pendingQuestions.every((q) => questionAnswers[q.question]?.value);
22502
23372
  return /* @__PURE__ */ jsxs24(Fragment12, { children: [
22503
- /* @__PURE__ */ jsxs24(
23373
+ /* @__PURE__ */ jsx31(
22504
23374
  RunFinishedSummary,
22505
23375
  {
22506
23376
  status,
@@ -22513,77 +23383,7 @@ var AgentUI = ({
22513
23383
  durationSec,
22514
23384
  showMeta: true,
22515
23385
  bottomContent: aiAuthSuggestionNode,
22516
- children: [
22517
- pendingAuthApps.map(({ appName, appId, icon }) => {
22518
- const pretty = appName.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
22519
- return /* @__PURE__ */ jsxs24(
22520
- Box22,
22521
- {
22522
- sx: {
22523
- display: "flex",
22524
- alignItems: "center",
22525
- gap: 1.5,
22526
- p: 1.5,
22527
- borderRadius: 1.5,
22528
- border: "1px solid hsla(var(--severity-medium) / 0.3)",
22529
- bgcolor: "hsla(var(--severity-medium) / 0.08)"
22530
- },
22531
- children: [
22532
- /* @__PURE__ */ jsx31(LockIcon3, { size: 22, color: "hsl(var(--severity-medium))" }),
22533
- /* @__PURE__ */ jsxs24(Box22, { sx: { flex: 1, minWidth: 0 }, children: [
22534
- /* @__PURE__ */ jsxs24(Typography19, { sx: { fontSize: "0.85rem", fontWeight: 600, color: "hsl(var(--foreground))" }, children: [
22535
- pretty,
22536
- " requires authentication"
22537
- ] }),
22538
- /* @__PURE__ */ jsxs24(Typography19, { sx: { fontSize: "0.75rem", color: "hsl(var(--muted-foreground))" }, children: [
22539
- "Connect your ",
22540
- pretty,
22541
- " account so the agent can complete this step, then rerun."
22542
- ] })
22543
- ] }),
22544
- /* @__PURE__ */ jsxs24(
22545
- Button13,
22546
- {
22547
- variant: "outlined",
22548
- size: "small",
22549
- startIcon: /* @__PURE__ */ jsx31(
22550
- Avatar6,
22551
- {
22552
- src: icon || void 0,
22553
- alt: "",
22554
- variant: "rounded",
22555
- sx: {
22556
- width: 18,
22557
- height: 18,
22558
- borderRadius: 0.5,
22559
- bgcolor: "hsl(var(--background) / 0.4)",
22560
- color: "hsl(var(--background))",
22561
- fontSize: "0.7rem",
22562
- fontWeight: 700,
22563
- "& img": { objectFit: "contain" }
22564
- },
22565
- children: pretty.charAt(0)
22566
- }
22567
- ),
22568
- onClick: () => setAuthDrawerApp({ name: appName, id: appId }),
22569
- sx: {
22570
- height: 36,
22571
- textTransform: "none",
22572
- fontWeight: 600
22573
- },
22574
- children: [
22575
- "Authenticate ",
22576
- pretty
22577
- ]
22578
- }
22579
- )
22580
- ]
22581
- },
22582
- `auth-${appName}`
22583
- );
22584
- }),
22585
- !isRunning && postRunDiscovery
22586
- ]
23386
+ children: !isRunning && postRunDiscovery
22587
23387
  }
22588
23388
  ),
22589
23389
  !finishAnswer && pendingAsk && pendingQuestions.length > 0 ? (() => {
@@ -22971,7 +23771,7 @@ var AgentUI = ({
22971
23771
  var AgentUI_default = AgentUI;
22972
23772
 
22973
23773
  // components/AgentRunDrawer.tsx
22974
- import { useEffect as useEffect19, useRef as useRef13, useState as useState21 } from "react";
23774
+ import { useEffect as useEffect20, useRef as useRef13, useState as useState22 } from "react";
22975
23775
  import {
22976
23776
  Box as Box25,
22977
23777
  Drawer as Drawer4,
@@ -22989,7 +23789,7 @@ import {
22989
23789
  } from "lucide-react";
22990
23790
 
22991
23791
  // components/LocalLLMConfig.tsx
22992
- import { useEffect as useEffect18, useMemo as useMemo11, useRef as useRef12, useState as useState20 } from "react";
23792
+ import { useEffect as useEffect19, useMemo as useMemo11, useRef as useRef12, useState as useState21 } from "react";
22993
23793
  import { Check } from "lucide-react";
22994
23794
  import {
22995
23795
  Autocomplete as Autocomplete2,
@@ -23158,7 +23958,7 @@ var PROVIDER_MODELS = {
23158
23958
  "LM Studio (localhost)": ["qwen-3.6-27b", "llama-4-16x17b-instruct", "deepseek-v4-flash", "qwen3-32b", "llama-3.3-70b-instruct", "deepseek-r1-distill-qwen-32b", "mistral-small-4", "phi-4", "gemma-3-27b"]
23159
23959
  };
23160
23960
  var ProviderLogo = ({ label, url }) => {
23161
- const [errored, setErrored] = useState20(false);
23961
+ const [errored, setErrored] = useState21(false);
23162
23962
  let domain = PROVIDER_DOMAINS[label];
23163
23963
  if (!domain && url) {
23164
23964
  try {
@@ -23174,8 +23974,8 @@ var LLM_PRESET_STORAGE_KEY = "shuffle-llm-provider";
23174
23974
  var LocalLLMConfig = ({ compact, globalUrl, userdata, isLoaded, isLoggedIn, serverside, theme, colorMode, open }) => {
23175
23975
  useSyncHostBaseUrl(globalUrl);
23176
23976
  const { authStates, authenticatedApps, handleAuthChange, handleSaveAuth, refreshAuth, loading: authLoading } = useAppAuth();
23177
- const [expanded, setExpanded] = useState20(true);
23178
- const [selectedPreset, setSelectedPreset] = useState20(() => {
23977
+ const [expanded, setExpanded] = useState21(true);
23978
+ const [selectedPreset, setSelectedPreset] = useState21(() => {
23179
23979
  try {
23180
23980
  const stored = localStorage.getItem(LLM_PRESET_STORAGE_KEY) || "";
23181
23981
  return ENDPOINT_PRESETS.some((p) => p.label === stored) ? stored : "";
@@ -23183,9 +23983,9 @@ var LocalLLMConfig = ({ compact, globalUrl, userdata, isLoaded, isLoggedIn, serv
23183
23983
  return "";
23184
23984
  }
23185
23985
  });
23186
- const [customUrl, setCustomUrl] = useState20("");
23986
+ const [customUrl, setCustomUrl] = useState21("");
23187
23987
  const activeSwitchSeqRef = useRef12(0);
23188
- const [llmTest, setLlmTest] = useState20(null);
23988
+ const [llmTest, setLlmTest] = useState21(null);
23189
23989
  const openaiEntries = authenticatedApps.filter(
23190
23990
  (a) => a.app?.name?.toLowerCase() === "openai" || a.app?.id === OPENAI_APP_ID
23191
23991
  );
@@ -23202,8 +24002,8 @@ var LocalLLMConfig = ({ compact, globalUrl, userdata, isLoaded, isLoggedIn, serv
23202
24002
  } : baseAuthState;
23203
24003
  const savedUrlFromEntry = (openaiEntries[0]?.fields || []).find((f) => (f?.key || "").toLowerCase() === "url")?.value || "";
23204
24004
  const currentUrl = (authState.credentials?.url || savedUrlFromEntry || "").trim();
23205
- const [customModel, setCustomModel] = useState20("");
23206
- const [customMode, setCustomMode] = useState20(false);
24005
+ const [customModel, setCustomModel] = useState21("");
24006
+ const [customMode, setCustomMode] = useState21(false);
23207
24007
  const hasOpenAIEntries = openaiEntries.length > 0;
23208
24008
  const providerOfEntry = (entry) => providerLabelOfAuthEntry(entry);
23209
24009
  const displayLabelOfEntry = (entry) => {
@@ -23211,7 +24011,7 @@ var LocalLLMConfig = ({ compact, globalUrl, userdata, isLoaded, isLoggedIn, serv
23211
24011
  const stripped = raw.replace(new RegExp(`^\\s*${OPENAI_APP_NAME}\\s*-\\s*`, "i"), "").trim();
23212
24012
  return stripped || raw;
23213
24013
  };
23214
- const [optimisticActiveProvider, setOptimisticActiveProvider] = useState20(null);
24014
+ const [optimisticActiveProvider, setOptimisticActiveProvider] = useState21(null);
23215
24015
  const activeEntryRaw = useMemo11(
23216
24016
  () => openaiEntries.find((e) => e?.active === true),
23217
24017
  [openaiEntries]
@@ -23402,7 +24202,7 @@ var LocalLLMConfig = ({ compact, globalUrl, userdata, isLoaded, isLoggedIn, serv
23402
24202
  };
23403
24203
  const prevOpenRef = useRef12(open);
23404
24204
  const hasInitializedPresetRef = useRef12(false);
23405
- useEffect18(() => {
24205
+ useEffect19(() => {
23406
24206
  const justOpened = Boolean(open && !prevOpenRef.current);
23407
24207
  prevOpenRef.current = open;
23408
24208
  if (authLoading) return;
@@ -23474,14 +24274,14 @@ var LocalLLMConfig = ({ compact, globalUrl, userdata, isLoaded, isLoggedIn, serv
23474
24274
  setCustomUrl(value);
23475
24275
  handleAuthChange(OPENAI_APP_ID, { ...authState.credentials, url: value });
23476
24276
  };
23477
- useEffect18(() => {
24277
+ useEffect19(() => {
23478
24278
  const preset = ENDPOINT_PRESETS.find((p) => p.label === effectivePreset);
23479
24279
  const presetUrl = effectivePreset === CUSTOM_PRESET ? customUrl : preset?.url || "";
23480
24280
  if (!presetUrl) return;
23481
24281
  if ((authState.credentials?.url || "").trim()) return;
23482
24282
  handleAuthChange(OPENAI_APP_ID, { ...authState.credentials, url: presetUrl });
23483
24283
  }, [effectivePreset, customUrl, authState.credentials?.url]);
23484
- useEffect18(() => {
24284
+ useEffect19(() => {
23485
24285
  const models = PROVIDER_MODELS[effectivePreset];
23486
24286
  if (!models?.length) return;
23487
24287
  if ((authState.credentials?.model || "").trim()) return;
@@ -23504,8 +24304,8 @@ var LocalLLMConfig = ({ compact, globalUrl, userdata, isLoaded, isLoggedIn, serv
23504
24304
  return isLocal;
23505
24305
  })();
23506
24306
  const orgId = userdata?.active_org?.id;
23507
- const [orgData, setOrgData] = useState20(null);
23508
- useEffect18(() => {
24307
+ const [orgData, setOrgData] = useState21(null);
24308
+ useEffect19(() => {
23509
24309
  if (!orgId) return;
23510
24310
  let cancelled = false;
23511
24311
  (async () => {
@@ -23788,20 +24588,20 @@ var AgentRunDrawer = ({
23788
24588
  }) => {
23789
24589
  useSyncHostBaseUrl(globalUrl);
23790
24590
  const themeScope = useShuffleMcpTheme();
23791
- const [activeTab, setActiveTab] = useState21(initialTab);
24591
+ const [activeTab, setActiveTab] = useState22(initialTab);
23792
24592
  const prevOpenRef = useRef13(open);
23793
- useEffect19(() => {
24593
+ useEffect20(() => {
23794
24594
  if (open && !prevOpenRef.current) setActiveTab(initialTab);
23795
24595
  prevOpenRef.current = open;
23796
24596
  }, [open, initialTab]);
23797
- useEffect19(() => {
24597
+ useEffect20(() => {
23798
24598
  if (typeof window === "undefined") return;
23799
24599
  window.__shuffleAgentDrawerMounted = (window.__shuffleAgentDrawerMounted || 0) + 1;
23800
24600
  return () => {
23801
24601
  window.__shuffleAgentDrawerMounted = Math.max(0, (window.__shuffleAgentDrawerMounted || 1) - 1);
23802
24602
  };
23803
24603
  }, []);
23804
- useEffect19(() => {
24604
+ useEffect20(() => {
23805
24605
  if (typeof window === "undefined") return;
23806
24606
  const onOpen = (event) => {
23807
24607
  const tab = event.detail?.tab;
@@ -23842,7 +24642,7 @@ var AgentRunDrawer = ({
23842
24642
  const showTabs = visibleTabs.length > 1;
23843
24643
  const safeActiveTab = visibleTabs.includes(activeTab) ? activeTab : "run";
23844
24644
  const paperRef = useRef13(null);
23845
- useEffect19(() => {
24645
+ useEffect20(() => {
23846
24646
  if (!open || safeActiveTab !== "run") return;
23847
24647
  const focusInput = () => {
23848
24648
  if (!paperRef.current) return false;
@@ -23868,6 +24668,7 @@ var AgentRunDrawer = ({
23868
24668
  const drawerWidth = `min(${width}px, 100vw)`;
23869
24669
  const drawerMinWidth = `min(${minWidth}px, 100vw)`;
23870
24670
  const drawerMaxWidth = `min(${maxWidth}px, 100vw)`;
24671
+ const drawerZIndex = useDrawerLayer(open);
23871
24672
  return /* @__PURE__ */ jsxs27(
23872
24673
  Drawer4,
23873
24674
  {
@@ -23875,6 +24676,7 @@ var AgentRunDrawer = ({
23875
24676
  open,
23876
24677
  onClose,
23877
24678
  sx: {
24679
+ zIndex: drawerZIndex,
23878
24680
  "& .MuiDrawer-paper": {
23879
24681
  boxSizing: "border-box",
23880
24682
  width: { xs: "100vw", sm: drawerWidth },
@@ -24030,7 +24832,7 @@ var AgentRunDrawer = ({
24030
24832
  var AgentRunDrawer_default = AgentRunDrawer;
24031
24833
 
24032
24834
  // components/AgentActivityList.tsx
24033
- import { useCallback as useCallback11, useEffect as useEffect20, useRef as useRef14, useState as useState22 } from "react";
24835
+ import { useCallback as useCallback11, useEffect as useEffect21, useRef as useRef14, useState as useState23 } from "react";
24034
24836
  import { useNavigate as useNavigate2 } from "react-router-dom";
24035
24837
  import {
24036
24838
  Avatar as Avatar7,
@@ -25025,31 +25827,31 @@ var AgentActivityList = ({
25025
25827
  initialRuns,
25026
25828
  disableFetch = false
25027
25829
  }) => {
25028
- const [appDrawer, setAppDrawer] = useState22(null);
25029
- const [runs, setRuns] = useState22(initialRuns || []);
25030
- const [cursor, setCursor] = useState22("");
25031
- const [hasMore, setHasMore] = useState22(false);
25032
- const [isLoading, setIsLoading] = useState22(false);
25033
- const [error, setError] = useState22(null);
25034
- const [statusFilter, setStatusFilter] = useState22("");
25035
- const [searchQuery, setSearchQuery] = useState22("");
25036
- const [debouncedQuery, setDebouncedQuery] = useState22("");
25037
- const [agentWorkflows, setAgentWorkflows] = useState22([]);
25038
- const [workflowFilter, setWorkflowFilter] = useState22("");
25039
- const [usecaseFilter, setUsecaseFilter] = useState22("");
25040
- const [stopOpen, setStopOpen] = useState22(false);
25041
- const [stopLoading, setStopLoading] = useState22(false);
25042
- const [appIcons, setAppIcons] = useState22({});
25043
- const [enrichedRuns, setEnrichedRuns] = useState22({});
25830
+ const [appDrawer, setAppDrawer] = useState23(null);
25831
+ const [runs, setRuns] = useState23(initialRuns || []);
25832
+ const [cursor, setCursor] = useState23("");
25833
+ const [hasMore, setHasMore] = useState23(false);
25834
+ const [isLoading, setIsLoading] = useState23(false);
25835
+ const [error, setError] = useState23(null);
25836
+ const [statusFilter, setStatusFilter] = useState23("");
25837
+ const [searchQuery, setSearchQuery] = useState23("");
25838
+ const [debouncedQuery, setDebouncedQuery] = useState23("");
25839
+ const [agentWorkflows, setAgentWorkflows] = useState23([]);
25840
+ const [workflowFilter, setWorkflowFilter] = useState23("");
25841
+ const [usecaseFilter, setUsecaseFilter] = useState23("");
25842
+ const [stopOpen, setStopOpen] = useState23(false);
25843
+ const [stopLoading, setStopLoading] = useState23(false);
25844
+ const [appIcons, setAppIcons] = useState23({});
25845
+ const [enrichedRuns, setEnrichedRuns] = useState23({});
25044
25846
  const enrichedRunsRef = useRef14({});
25045
25847
  const processedRunIdsRef = useRef14(/* @__PURE__ */ new Set());
25046
- useEffect20(() => {
25848
+ useEffect21(() => {
25047
25849
  enrichedRunsRef.current = enrichedRuns;
25048
25850
  }, [enrichedRuns]);
25049
- const [abortingIds, setAbortingIds] = useState22(/* @__PURE__ */ new Set());
25050
- const [abortedIds, setAbortedIds] = useState22(/* @__PURE__ */ new Set());
25051
- const [lastOpenedRunId, setLastOpenedRunId] = useState22(() => getLastOpenedAgentRun());
25052
- useEffect20(() => {
25851
+ const [abortingIds, setAbortingIds] = useState23(/* @__PURE__ */ new Set());
25852
+ const [abortedIds, setAbortedIds] = useState23(/* @__PURE__ */ new Set());
25853
+ const [lastOpenedRunId, setLastOpenedRunId] = useState23(() => getLastOpenedAgentRun());
25854
+ useEffect21(() => {
25053
25855
  const unsubAbort = subscribeAgentAborted((eid) => {
25054
25856
  setAbortedIds((prev) => prev.has(eid) ? prev : /* @__PURE__ */ new Set([...Array.from(prev), eid]));
25055
25857
  setRuns((prev) => prev.map((r) => r.execution_id === eid ? { ...r, status: "ABORTED" } : r));
@@ -25141,7 +25943,7 @@ var AgentActivityList = ({
25141
25943
  if (debounceRef.current) clearTimeout(debounceRef.current);
25142
25944
  debounceRef.current = setTimeout(() => setDebouncedQuery(q), 350);
25143
25945
  }, []);
25144
- useEffect20(() => () => {
25946
+ useEffect21(() => () => {
25145
25947
  if (debounceRef.current) clearTimeout(debounceRef.current);
25146
25948
  }, []);
25147
25949
  const fetchRuns = useCallback11(
@@ -25192,10 +25994,10 @@ var AgentActivityList = ({
25192
25994
  },
25193
25995
  [disableFetch, initialRuns, statusFilter, limit, top, apiKey, apiBaseUrl, orgId, workflowFilter]
25194
25996
  );
25195
- useEffect20(() => {
25997
+ useEffect21(() => {
25196
25998
  fetchRuns(false, "");
25197
25999
  }, [statusFilter, apiKey, apiBaseUrl, orgId, workflowFilter]);
25198
- useEffect20(() => {
26000
+ useEffect21(() => {
25199
26001
  let cancelled = false;
25200
26002
  listAgentScheduleWorkflows({ apiKey, apiBaseUrl, orgId }).then((items) => {
25201
26003
  if (!cancelled) setAgentWorkflows(items);
@@ -25205,7 +26007,7 @@ var AgentActivityList = ({
25205
26007
  cancelled = true;
25206
26008
  };
25207
26009
  }, [apiKey, apiBaseUrl, orgId]);
25208
- useEffect20(() => {
26010
+ useEffect21(() => {
25209
26011
  let cancelled = false;
25210
26012
  fetchAppsViaApiConfig().then((apps) => {
25211
26013
  if (cancelled || !Array.isArray(apps)) return;
@@ -25223,7 +26025,7 @@ var AgentActivityList = ({
25223
26025
  cancelled = true;
25224
26026
  };
25225
26027
  }, []);
25226
- useEffect20(() => {
26028
+ useEffect21(() => {
25227
26029
  if (!runs.length) return;
25228
26030
  let cancelled = false;
25229
26031
  const buildPatchFromRun = (r) => {
@@ -25708,7 +26510,7 @@ var AgentActivityList = ({
25708
26510
  var AgentActivityList_default = AgentActivityList;
25709
26511
 
25710
26512
  // components/AgentExecutionDrawer.tsx
25711
- import { useEffect as useEffect21, useState as useState23 } from "react";
26513
+ import { useEffect as useEffect22, useState as useState24 } from "react";
25712
26514
  import { Box as Box27, Drawer as Drawer5, IconButton as IconButton14, Tooltip as Tooltip19, Typography as Typography24 } from "@mui/material";
25713
26515
  import {
25714
26516
  X as CloseIcon9,
@@ -25741,8 +26543,8 @@ var AgentExecutionDrawer = ({
25741
26543
  colorMode
25742
26544
  }) => {
25743
26545
  const themeScope = useShuffleMcpTheme();
25744
- const [bodyReady, setBodyReady] = useState23(false);
25745
- useEffect21(() => {
26546
+ const [bodyReady, setBodyReady] = useState24(false);
26547
+ useEffect22(() => {
25746
26548
  if (!open || !run?.execution_id) {
25747
26549
  setBodyReady(false);
25748
26550
  return;
@@ -25756,6 +26558,7 @@ var AgentExecutionDrawer = ({
25756
26558
  const drawerWidth = `min(${width}px, 100vw)`;
25757
26559
  const drawerMinWidth = `min(${minWidth}px, 100vw)`;
25758
26560
  const drawerMaxWidth = `min(${maxWidth}px, 100vw)`;
26561
+ const drawerZIndex = useDrawerLayer(open);
25759
26562
  return /* @__PURE__ */ jsxs29(
25760
26563
  Drawer5,
25761
26564
  {
@@ -25765,7 +26568,7 @@ var AgentExecutionDrawer = ({
25765
26568
  keepMounted: true,
25766
26569
  transitionDuration: { enter: 120, exit: 100 },
25767
26570
  sx: {
25768
- zIndex: 10011,
26571
+ zIndex: drawerZIndex,
25769
26572
  "& .MuiDrawer-paper": {
25770
26573
  boxSizing: "border-box",
25771
26574
  width: { xs: "100vw", sm: drawerWidth },
@@ -25940,7 +26743,7 @@ var AgentExecutionDrawer = ({
25940
26743
  var AgentExecutionDrawer_default = AgentExecutionDrawer;
25941
26744
 
25942
26745
  // views/AgentsView.tsx
25943
- import { useCallback as useCallback12, useEffect as useEffect22, useMemo as useMemo12, useState as useState24 } from "react";
26746
+ import { useCallback as useCallback12, useEffect as useEffect23, useMemo as useMemo12, useState as useState25 } from "react";
25944
26747
  import { Box as Box28, Stack, Typography as Typography25 } from "@mui/material";
25945
26748
  import { jsx as jsx37, jsxs as jsxs30 } from "react/jsx-runtime";
25946
26749
  var APPS_TTL_MS = 24 * 60 * 60 * 1e3;
@@ -26000,14 +26803,14 @@ var AgentsView = ({
26000
26803
  if (disableAppsPersistence) return [];
26001
26804
  return readPersistedApps(appsStorageKey) ?? [];
26002
26805
  }, []);
26003
- const [selectedRun, setSelectedRun] = useState24(null);
26004
- const [agentView, setAgentView] = useState24("start");
26005
- const [prefill, setPrefill] = useState24({
26806
+ const [selectedRun, setSelectedRun] = useState25(null);
26807
+ const [agentView, setAgentView] = useState25("start");
26808
+ const [prefill, setPrefill] = useState25({
26006
26809
  input: "",
26007
26810
  apps: hydratedInitialApps,
26008
26811
  key: 0
26009
26812
  });
26010
- const [editing, setEditing] = useState24(null);
26813
+ const [editing, setEditing] = useState25(null);
26011
26814
  const handleAppsChange = useCallback12((apps) => {
26012
26815
  if (onAppsChange) {
26013
26816
  try {
@@ -26030,13 +26833,13 @@ var AgentsView = ({
26030
26833
  } catch {
26031
26834
  }
26032
26835
  }, [onAppsChange, disableAppsPersistence, appsStorageKey]);
26033
- useEffect22(() => {
26836
+ useEffect23(() => {
26034
26837
  }, [handleAppsChange]);
26035
- const [builtInDrawer, setBuiltInDrawer] = useState24({
26838
+ const [builtInDrawer, setBuiltInDrawer] = useState25({
26036
26839
  open: false,
26037
26840
  tab: "localLLM"
26038
26841
  });
26039
- useEffect22(() => {
26842
+ useEffect23(() => {
26040
26843
  if (typeof window === "undefined") return;
26041
26844
  const handler = (e) => {
26042
26845
  const detail = e.detail;
@@ -26075,7 +26878,7 @@ var AgentsView = ({
26075
26878
  }
26076
26879
  setBuiltInDrawer({ open: true, tab: "localLLM" });
26077
26880
  }, [onChooseLLM]);
26078
- useEffect22(() => {
26881
+ useEffect23(() => {
26079
26882
  if (typeof window === "undefined") return;
26080
26883
  if (window.location.hash !== "#agent-activity") return;
26081
26884
  const tryScroll = () => {
@@ -26234,7 +27037,7 @@ var AgentsView_default = AgentsView;
26234
27037
 
26235
27038
  // components/AddAppModal.tsx
26236
27039
  import { X as CloseIcon10, ArrowLeft as ArrowBackIcon2 } from "lucide-react";
26237
- import { useState as useState26, useEffect as useEffect23 } from "react";
27040
+ import { useState as useState27, useEffect as useEffect24 } from "react";
26238
27041
  import {
26239
27042
  Box as Box29,
26240
27043
  Typography as Typography26,
@@ -26247,16 +27050,16 @@ import {
26247
27050
  import { motion as motion9, AnimatePresence as AnimatePresence3 } from "framer-motion";
26248
27051
 
26249
27052
  // useAppAuthFlow.ts
26250
- import { useState as useState25, useCallback as useCallback13 } from "react";
27053
+ import { useState as useState26, useCallback as useCallback13 } from "react";
26251
27054
  function useAppAuthFlow() {
26252
- const [selectedApp, setSelectedApp] = useState25(null);
26253
- const [authState, setAuthState] = useState25({
27055
+ const [selectedApp, setSelectedApp] = useState26(null);
27056
+ const [authState, setAuthState] = useState26({
26254
27057
  systemId: "",
26255
27058
  status: "pending",
26256
27059
  credentials: {}
26257
27060
  });
26258
- const [authenticatedApps, setAuthenticatedApps] = useState25([]);
26259
- const [authLoading, setAuthLoading] = useState25(false);
27061
+ const [authenticatedApps, setAuthenticatedApps] = useState26([]);
27062
+ const [authLoading, setAuthLoading] = useState26(false);
26260
27063
  const fetchAuthForApp = useCallback13(async (appName, appImageUrl) => {
26261
27064
  setAuthLoading(true);
26262
27065
  try {
@@ -26466,7 +27269,7 @@ var singulStyles2 = {
26466
27269
  }
26467
27270
  };
26468
27271
  var AddAppModal = ({ open, onClose, initialQuery, categoryLabel }) => {
26469
- const [phase, setPhase] = useState26("search");
27272
+ const [phase, setPhase] = useState27("search");
26470
27273
  const {
26471
27274
  selectedApp,
26472
27275
  authState,
@@ -26479,7 +27282,7 @@ var AddAppModal = ({ open, onClose, initialQuery, categoryLabel }) => {
26479
27282
  handleSaveAuth,
26480
27283
  refreshAuth
26481
27284
  } = useAppAuthFlow();
26482
- useEffect23(() => {
27285
+ useEffect24(() => {
26483
27286
  if (!open) {
26484
27287
  setPhase("search");
26485
27288
  clearSelection();
@@ -26635,14 +27438,16 @@ var AskAiButton = ({
26635
27438
  return null;
26636
27439
  }
26637
27440
  const isEffectiveSupport = isSupport !== void 0 ? isSupport : isSupportUser();
26638
- const effectiveRequireSupport = isBeta ? false : requireSupport;
27441
+ const isIncidentOrDocs = currentPath.startsWith("/incidents") || currentPath.startsWith("/incidents-simple") || currentPath.startsWith("/cases") || currentPath.startsWith("/alerts") || currentPath.startsWith("/tickets") || currentPath.startsWith("/docs");
27442
+ const effectiveIsBeta = isBeta || isIncidentOrDocs;
27443
+ const effectiveRequireSupport = effectiveIsBeta ? false : requireSupport;
26639
27444
  if (effectiveRequireSupport && !isEffectiveSupport) {
26640
27445
  return null;
26641
27446
  }
26642
27447
  if (hideWhenOpen && isOpen) {
26643
27448
  return null;
26644
27449
  }
26645
- const effectiveTagLabel = tagLabel !== void 0 ? tagLabel : isBeta ? "Beta" : "Support";
27450
+ const effectiveTagLabel = tagLabel !== void 0 && !(tagLabel === "Support" && isIncidentOrDocs) ? tagLabel : effectiveIsBeta ? "Beta" : "Support";
26646
27451
  const effectiveTooltip = tooltipTitle !== void 0 ? tooltipTitle : label !== "Ask AI" ? label : contextHint ? `Ask AI (${contextHint})` : "Ask AI \u2022 Context-aware assistant";
26647
27452
  return /* @__PURE__ */ jsx39(
26648
27453
  Box30,
@@ -26733,9 +27538,9 @@ var AskAiButton = ({
26733
27538
  fontWeight: 700,
26734
27539
  textTransform: "uppercase",
26735
27540
  letterSpacing: "0.04em",
26736
- color: isBeta ? "hsl(var(--primary))" : "hsl(var(--muted-foreground))",
26737
- bgcolor: isBeta ? "hsla(var(--primary) / 0.12)" : "hsla(var(--muted-foreground) / 0.12)",
26738
- border: isBeta ? "1px solid hsla(var(--primary) / 0.26)" : "1px solid hsla(var(--muted-foreground) / 0.24)",
27541
+ color: effectiveIsBeta ? "hsl(var(--primary))" : "hsl(var(--muted-foreground))",
27542
+ bgcolor: effectiveIsBeta ? "hsla(var(--primary) / 0.12)" : "hsla(var(--muted-foreground) / 0.12)",
27543
+ border: effectiveIsBeta ? "1px solid hsla(var(--primary) / 0.26)" : "1px solid hsla(var(--muted-foreground) / 0.24)",
26739
27544
  px: 0.9,
26740
27545
  py: 0.25,
26741
27546
  borderRadius: "9999px",
@@ -26754,7 +27559,7 @@ var AskAiButton = ({
26754
27559
  var AskAiButton_default = AskAiButton;
26755
27560
 
26756
27561
  // components/AskAiDrawer.tsx
26757
- import { useCallback as useCallback14, useEffect as useEffect24, useMemo as useMemo13, useState as useState27 } from "react";
27562
+ import { useCallback as useCallback14, useEffect as useEffect25, useMemo as useMemo13, useState as useState28 } from "react";
26758
27563
  import { Box as Box31, ButtonBase as ButtonBase3, Typography as Typography28 } from "@mui/material";
26759
27564
  import { jsx as jsx40, jsxs as jsxs33 } from "react/jsx-runtime";
26760
27565
  var AskAiDrawer = ({
@@ -26770,13 +27575,13 @@ var AskAiDrawer = ({
26770
27575
  agentUIProps,
26771
27576
  ...drawerProps
26772
27577
  }) => {
26773
- const [internalPathname, setInternalPathname] = useState27(
27578
+ const [internalPathname, setInternalPathname] = useState28(
26774
27579
  () => typeof window !== "undefined" ? window.location.pathname : "/"
26775
27580
  );
26776
- const [internalSearch, setInternalSearch] = useState27(
27581
+ const [internalSearch, setInternalSearch] = useState28(
26777
27582
  () => typeof window !== "undefined" ? window.location.search : ""
26778
27583
  );
26779
- useEffect24(() => {
27584
+ useEffect25(() => {
26780
27585
  if (propPathname !== void 0) return;
26781
27586
  const updateLoc = () => {
26782
27587
  setInternalPathname(window.location.pathname);
@@ -26787,17 +27592,17 @@ var AskAiDrawer = ({
26787
27592
  }, [propPathname]);
26788
27593
  const activePathname = propPathname !== void 0 ? propPathname : internalPathname;
26789
27594
  const activeSearch = propSearch !== void 0 ? propSearch : internalSearch;
26790
- const [resetKey, setResetKey] = useState27(0);
27595
+ const [resetKey, setResetKey] = useState28(0);
26791
27596
  const resolvedContext = useMemo13(
26792
27597
  () => resolveAgentContext(activePathname, activeSearch, rules),
26793
27598
  // eslint-disable-next-line react-hooks/exhaustive-deps
26794
27599
  [activePathname, activeSearch, rules, resetKey]
26795
27600
  );
26796
- useEffect24(() => {
27601
+ useEffect25(() => {
26797
27602
  onContextResolved?.(resolvedContext);
26798
27603
  }, [resolvedContext, onContextResolved]);
26799
- const [isOverridden, setIsOverridden] = useState27(resolvedContext.isOverridden);
26800
- useEffect24(() => {
27604
+ const [isOverridden, setIsOverridden] = useState28(resolvedContext.isOverridden);
27605
+ useEffect25(() => {
26801
27606
  setIsOverridden(resolvedContext.isOverridden);
26802
27607
  }, [resolvedContext.isOverridden, resolvedContext.storageKey]);
26803
27608
  const handleAppsChange = useCallback14(
@@ -26880,7 +27685,7 @@ var AskAiDrawer = ({
26880
27685
  var AskAiDrawer_default = AskAiDrawer;
26881
27686
 
26882
27687
  // components/AskAiSidePanel.tsx
26883
- import React8, { useCallback as useCallback15, useEffect as useEffect25, useRef as useRef15, useState as useState28 } from "react";
27688
+ import React8, { useCallback as useCallback15, useEffect as useEffect26, useRef as useRef15, useState as useState29 } from "react";
26884
27689
  import {
26885
27690
  Box as Box32,
26886
27691
  Button as Button16,
@@ -26896,6 +27701,7 @@ import {
26896
27701
  X as CloseIcon11
26897
27702
  } from "lucide-react";
26898
27703
  import { Fragment as Fragment16, jsx as jsx41, jsxs as jsxs34 } from "react/jsx-runtime";
27704
+ import { createElement as createElement3 } from "react";
26899
27705
  var AGENT_DRAWER_OPEN_EVENT = "agent-drawer-open";
26900
27706
  var ASK_AI_PANEL_WIDTH_STORAGE_KEY = "shuffle:ask_ai_panel_width";
26901
27707
  var MIN_ASK_AI_PANEL_WIDTH = 340;
@@ -26927,13 +27733,15 @@ var AskAiSidePanel = ({
26927
27733
  defaultInput,
26928
27734
  serverside,
26929
27735
  colorMode,
27736
+ incidentId: propIncidentId,
27737
+ incidentContext: propIncidentContext,
26930
27738
  sx
26931
27739
  }) => {
26932
27740
  const themeScope = useShuffleMcpTheme();
26933
27741
  const effectiveTheme = theme || (themeScope?.isDark ? "dark" : "light");
26934
- const [currentPathname, setCurrentPathname] = useState28(pathname ?? "/");
26935
- const [currentSearch, setCurrentSearch] = useState28(search ?? "");
26936
- useEffect25(() => {
27742
+ const [currentPathname, setCurrentPathname] = useState29(pathname ?? "/");
27743
+ const [currentSearch, setCurrentSearch] = useState29(search ?? "");
27744
+ useEffect26(() => {
26937
27745
  if (pathname !== void 0) {
26938
27746
  setCurrentPathname(pathname);
26939
27747
  return;
@@ -26949,14 +27757,14 @@ var AskAiSidePanel = ({
26949
27757
  }
26950
27758
  return;
26951
27759
  }, [pathname]);
26952
- useEffect25(() => {
27760
+ useEffect26(() => {
26953
27761
  if (search !== void 0) {
26954
27762
  setCurrentSearch(search);
26955
27763
  }
26956
27764
  }, [search]);
26957
27765
  const isAgentDisabled = isAgentRoute(currentPathname);
26958
27766
  const isVisible = open && !isAgentDisabled;
26959
- useEffect25(() => {
27767
+ useEffect26(() => {
26960
27768
  if (isAgentDisabled && open) {
26961
27769
  onClose();
26962
27770
  }
@@ -26965,8 +27773,8 @@ var AskAiSidePanel = ({
26965
27773
  () => resolveAgentContext(currentPathname, currentSearch, rules),
26966
27774
  [currentPathname, currentSearch, rules]
26967
27775
  );
26968
- const [entityTitle, setEntityTitle] = useState28(() => getActivePageEntityName());
26969
- useEffect25(() => {
27776
+ const [entityTitle, setEntityTitle] = useState29(() => getActivePageEntityName());
27777
+ useEffect26(() => {
26970
27778
  if (!open) return;
26971
27779
  const current = getActivePageEntityName();
26972
27780
  if (current) setEntityTitle(current);
@@ -27011,19 +27819,22 @@ var AskAiSidePanel = ({
27011
27819
  }
27012
27820
  return context.title || "How can we help on this page?";
27013
27821
  }, [context, entityTitle]);
27014
- useEffect25(() => {
27822
+ useEffect26(() => {
27015
27823
  onContextResolved?.(context);
27016
27824
  }, [context, onContextResolved]);
27017
27825
  useSyncHostBaseUrl(globalUrl);
27018
- const [internalTab, setInternalTab] = useState28(initialTab);
27826
+ const [internalTab, setInternalTab] = useState29(initialTab);
27019
27827
  const currentTab = propActiveTab !== void 0 ? propActiveTab : internalTab;
27020
- const [controlledDefaultInput, setControlledDefaultInput] = useState28(defaultInput);
27021
- useEffect25(() => {
27828
+ const [controlledDefaultInput, setControlledDefaultInput] = useState29(defaultInput);
27829
+ const [controlledAutoSubmit, setControlledAutoSubmit] = useState29(void 0);
27830
+ useEffect26(() => {
27022
27831
  if (defaultInput !== void 0) {
27023
27832
  setControlledDefaultInput(defaultInput);
27024
27833
  }
27025
27834
  }, [defaultInput]);
27026
27835
  const effectiveDefaultInput = controlledDefaultInput ?? defaultInput ?? agentUIProps?.defaultInput;
27836
+ const effectiveAutoSubmit = controlledAutoSubmit ?? agentUIProps?.autoSubmit;
27837
+ const isBetaRoute = context.isBeta === true || currentPathname.startsWith("/incidents") || currentPathname.startsWith("/incidents-simple") || currentPathname.startsWith("/cases") || currentPathname.startsWith("/alerts") || currentPathname.startsWith("/tickets") || currentPathname.startsWith("/docs");
27027
27838
  const handleTabChange = useCallback15(
27028
27839
  (nextTab) => {
27029
27840
  setInternalTab(nextTab);
@@ -27031,20 +27842,33 @@ var AskAiSidePanel = ({
27031
27842
  },
27032
27843
  [onTabChange]
27033
27844
  );
27034
- useEffect25(() => {
27845
+ useEffect26(() => {
27035
27846
  if (initialTab) {
27036
27847
  setInternalTab(initialTab);
27037
27848
  }
27038
27849
  }, [initialTab]);
27039
27850
  const prevOpenRef = useRef15(open);
27040
- useEffect25(() => {
27851
+ useEffect26(() => {
27041
27852
  if (open && !prevOpenRef.current && initialTab) {
27042
27853
  setInternalTab(initialTab);
27043
27854
  onTabChange?.(initialTab);
27044
27855
  }
27045
27856
  prevOpenRef.current = open;
27046
27857
  }, [open, initialTab, onTabChange]);
27047
- useEffect25(() => {
27858
+ const [activeTaskId, setActiveTaskId] = useState29(null);
27859
+ const [activeExecutionId, setActiveExecutionId] = useState29(null);
27860
+ const [activeIncidentId, setActiveIncidentId] = useState29(null);
27861
+ const [activeIncidentContext, setActiveIncidentContext] = useState29(null);
27862
+ const [runResetKey, setRunResetKey] = useState29(0);
27863
+ useEffect26(() => {
27864
+ if (!open) {
27865
+ setActiveTaskId(null);
27866
+ setActiveExecutionId(null);
27867
+ setActiveIncidentId(null);
27868
+ setActiveIncidentContext(null);
27869
+ }
27870
+ }, [open]);
27871
+ useEffect26(() => {
27048
27872
  if (typeof window === "undefined") return;
27049
27873
  window.__shuffleAgentDrawerMounted = (window.__shuffleAgentDrawerMounted || 0) + 1;
27050
27874
  return () => {
@@ -27054,7 +27878,7 @@ var AskAiSidePanel = ({
27054
27878
  );
27055
27879
  };
27056
27880
  }, []);
27057
- useEffect25(() => {
27881
+ useEffect26(() => {
27058
27882
  if (typeof window === "undefined") return;
27059
27883
  const onOpen = (event) => {
27060
27884
  const detail = event.detail;
@@ -27065,12 +27889,55 @@ var AskAiSidePanel = ({
27065
27889
  if (detail?.defaultInput !== void 0) {
27066
27890
  setControlledDefaultInput(detail.defaultInput);
27067
27891
  }
27892
+ if (detail?.autoSubmit !== void 0) {
27893
+ setControlledAutoSubmit(detail.autoSubmit);
27894
+ }
27895
+ if (detail?.taskId !== void 0) {
27896
+ setActiveTaskId(detail.taskId || null);
27897
+ } else if (!detail?.tab) {
27898
+ setActiveTaskId(null);
27899
+ }
27900
+ if (detail?.incidentId !== void 0) {
27901
+ setActiveIncidentId(detail.incidentId || null);
27902
+ }
27903
+ if (detail?.incidentContext !== void 0) {
27904
+ setActiveIncidentContext(detail.incidentContext || null);
27905
+ }
27906
+ if (detail?.resetExecution) {
27907
+ setActiveExecutionId(null);
27908
+ setRunResetKey((k) => k + 1);
27909
+ } else if (detail?.executionId !== void 0) {
27910
+ setActiveExecutionId(detail.executionId || null);
27911
+ } else if (detail?.taskId) {
27912
+ setActiveExecutionId(null);
27913
+ }
27068
27914
  };
27069
27915
  window.addEventListener(AGENT_DRAWER_OPEN_EVENT, onOpen);
27070
27916
  return () => {
27071
27917
  window.removeEventListener(AGENT_DRAWER_OPEN_EVENT, onOpen);
27072
27918
  };
27073
27919
  }, [handleTabChange]);
27920
+ const handleAgentRun = useCallback15(
27921
+ (event) => {
27922
+ if (event.executionId && activeTaskId) {
27923
+ setActiveExecutionId(event.executionId);
27924
+ if (typeof window !== "undefined") {
27925
+ window.dispatchEvent(
27926
+ new CustomEvent("shuffle:task_ai_execution", {
27927
+ detail: {
27928
+ taskId: activeTaskId,
27929
+ executionId: event.executionId,
27930
+ status: event.success ? "running" : "failed"
27931
+ }
27932
+ })
27933
+ );
27934
+ }
27935
+ }
27936
+ },
27937
+ [activeTaskId]
27938
+ );
27939
+ const effectiveStorageKey = activeTaskId ? `${context.storageKey}:task:${activeTaskId}` : context.storageKey;
27940
+ const agentUiKey = activeTaskId ? `${context.storageKey}:task:${activeTaskId}:${activeExecutionId || "fresh"}:${runResetKey}` : `${context.storageKey}:${runResetKey}`;
27074
27941
  const effectiveLocalLLMSlot = localLLMSlot ?? /* @__PURE__ */ jsx41(
27075
27942
  LocalLLMConfig_default,
27076
27943
  {
@@ -27092,7 +27959,7 @@ var AskAiSidePanel = ({
27092
27959
  });
27093
27960
  const safeActiveTab = visibleTabs.includes(currentTab) ? currentTab : "run";
27094
27961
  const panelRef = useRef15(null);
27095
- useEffect25(() => {
27962
+ useEffect26(() => {
27096
27963
  if (!isVisible || safeActiveTab !== "run") return;
27097
27964
  const focusInput = () => {
27098
27965
  if (!panelRef.current) return false;
@@ -27115,7 +27982,7 @@ var AskAiSidePanel = ({
27115
27982
  clearTimeout(t3);
27116
27983
  };
27117
27984
  }, [isVisible, safeActiveTab]);
27118
- const [panelWidth, setPanelWidth] = useState28(() => {
27985
+ const [panelWidth, setPanelWidth] = useState29(() => {
27119
27986
  if (typeof window === "undefined") return width || 380;
27120
27987
  try {
27121
27988
  const stored = localStorage.getItem(ASK_AI_PANEL_WIDTH_STORAGE_KEY);
@@ -27129,9 +27996,9 @@ var AskAiSidePanel = ({
27129
27996
  }
27130
27997
  return width || 380;
27131
27998
  });
27132
- const [isResizing, setIsResizing] = useState28(false);
27999
+ const [isResizing, setIsResizing] = useState29(false);
27133
28000
  const prevWidthPropRef = useRef15(width);
27134
- useEffect25(() => {
28001
+ useEffect26(() => {
27135
28002
  if (width !== prevWidthPropRef.current) {
27136
28003
  prevWidthPropRef.current = width;
27137
28004
  setPanelWidth(width);
@@ -27208,7 +28075,7 @@ var AskAiSidePanel = ({
27208
28075
  }, [panelWidth]);
27209
28076
  const effectiveWidth = safeActiveTab === "localLLM" ? Math.max(panelWidth, 520) : panelWidth;
27210
28077
  const effectiveSideshift = sideshift !== void 0 ? sideshift : context.sideshift ?? true;
27211
- useEffect25(() => {
28078
+ useEffect26(() => {
27212
28079
  if (typeof document === "undefined") return;
27213
28080
  if (open && !isAgentDisabled && effectiveSideshift) {
27214
28081
  document.documentElement.style.setProperty(
@@ -27376,11 +28243,11 @@ var AskAiSidePanel = ({
27376
28243
  px: 0.75,
27377
28244
  py: 0.2,
27378
28245
  borderRadius: "4px",
27379
- bgcolor: context.isBeta ? "hsla(var(--primary) / 0.12)" : "hsl(var(--muted))",
27380
- color: context.isBeta ? "hsl(var(--primary))" : "hsl(var(--muted-foreground))",
27381
- border: context.isBeta ? "1px solid hsla(var(--primary) / 0.26)" : "1px solid hsl(var(--border))"
28246
+ bgcolor: isBetaRoute ? "hsla(var(--primary) / 0.12)" : "hsl(var(--muted))",
28247
+ color: isBetaRoute ? "hsl(var(--primary))" : "hsl(var(--muted-foreground))",
28248
+ border: isBetaRoute ? "1px solid hsla(var(--primary) / 0.26)" : "1px solid hsl(var(--border))"
27382
28249
  },
27383
- children: context.isBeta ? "Beta" : isLoggedIn ? isSupport ? "Support" : "Agent" : "Guest"
28250
+ children: isBetaRoute ? "Beta" : isLoggedIn ? isSupport ? "Support" : "Agent" : "Guest"
27384
28251
  }
27385
28252
  )
27386
28253
  ] }),
@@ -27638,14 +28505,16 @@ var AskAiSidePanel = ({
27638
28505
  display: "flex",
27639
28506
  flexDirection: "column"
27640
28507
  },
27641
- children: /* @__PURE__ */ jsx41(
28508
+ children: /* @__PURE__ */ createElement3(
27642
28509
  AgentUI_default,
27643
28510
  {
28511
+ ...agentUIProps,
28512
+ key: agentUiKey,
27644
28513
  sidebarLayout: true,
27645
28514
  compact: true,
27646
28515
  mobileView: true,
27647
28516
  hideHeroIcon: true,
27648
- title: displayTitle,
28517
+ title: activeTaskId ? "Task AI Agent" : displayTitle,
27649
28518
  subtitle: null,
27650
28519
  hideChooseLLM: !isLoggedIn,
27651
28520
  isLoggedIn,
@@ -27656,16 +28525,21 @@ var AskAiSidePanel = ({
27656
28525
  initialPresetId: context.presetId,
27657
28526
  placeholder: context.placeholder,
27658
28527
  contextCategory: context.sourceCategory,
27659
- contextStorageKey: context.storageKey,
28528
+ contextStorageKey: effectiveStorageKey,
27660
28529
  contextParams: context.params,
27661
28530
  composeSubmitInput: context.composeInput,
27662
28531
  defaultInput: effectiveDefaultInput,
28532
+ autoSubmit: effectiveAutoSubmit,
28533
+ executionId: activeExecutionId || void 0,
28534
+ initialExecution: activeExecutionId ? { execution_id: activeExecutionId } : void 0,
28535
+ onRun: handleAgentRun,
27663
28536
  onAppsChange: handleAppsChange,
27664
28537
  onSelectPreset: handleSelectPreset,
27665
28538
  onChooseLLM: () => handleTabChange("localLLM"),
28539
+ incidentId: activeIncidentId || propIncidentId || agentUIProps?.incidentId,
28540
+ incidentContext: activeIncidentContext || propIncidentContext || agentUIProps?.incidentContext,
27666
28541
  apiBaseUrl: globalUrl || agentUIProps?.apiBaseUrl,
27667
28542
  theme: effectiveTheme,
27668
- ...agentUIProps,
27669
28543
  sx: {
27670
28544
  flex: 1,
27671
28545
  height: "100%",
@@ -27676,8 +28550,7 @@ var AskAiSidePanel = ({
27676
28550
  pb: 0,
27677
28551
  ...agentUIProps?.sx ? Array.isArray(agentUIProps.sx) ? {} : agentUIProps.sx : {}
27678
28552
  }
27679
- },
27680
- context.storageKey
28553
+ }
27681
28554
  )
27682
28555
  }
27683
28556
  )
@@ -27690,7 +28563,7 @@ var AskAiSidePanel = ({
27690
28563
  var AskAiSidePanel_default = AskAiSidePanel;
27691
28564
 
27692
28565
  // components/AskAiWidget.tsx
27693
- import { useCallback as useCallback16, useEffect as useEffect26, useMemo as useMemo15, useState as useState29 } from "react";
28566
+ import { useCallback as useCallback16, useEffect as useEffect27, useMemo as useMemo15, useState as useState30 } from "react";
27694
28567
  import { Fragment as Fragment17, jsx as jsx42, jsxs as jsxs35 } from "react/jsx-runtime";
27695
28568
  var AGENT_DRAWER_OPEN_EVENT2 = "agent-drawer-open";
27696
28569
  var AskAiWidget = ({
@@ -27710,11 +28583,11 @@ var AskAiWidget = ({
27710
28583
  localLLMSlot,
27711
28584
  ...panelProps
27712
28585
  }) => {
27713
- const [internalOpen, setInternalOpen] = useState29(false);
27714
- const [activeTab, setActiveTab] = useState29(propInitialTab);
28586
+ const [internalOpen, setInternalOpen] = useState30(false);
28587
+ const [activeTab, setActiveTab] = useState30(propInitialTab);
27715
28588
  const isDrawerOpen = controlledOpen !== void 0 ? controlledOpen : internalOpen;
27716
- const [browserLocation, setBrowserLocation] = useState29({ path: "", search: "" });
27717
- useEffect26(() => {
28589
+ const [browserLocation, setBrowserLocation] = useState30({ path: "", search: "" });
28590
+ useEffect27(() => {
27718
28591
  if (pathname !== void 0 && search !== void 0) return;
27719
28592
  const syncLocation = () => setBrowserLocation({
27720
28593
  path: window.location.pathname,
@@ -27736,7 +28609,7 @@ var AskAiWidget = ({
27736
28609
  },
27737
28610
  [controlledOpen, isAgentDisabled, onOpenChange]
27738
28611
  );
27739
- useEffect26(() => {
28612
+ useEffect27(() => {
27740
28613
  if (isAgentDisabled && isDrawerOpen) {
27741
28614
  setDrawerOpen(false);
27742
28615
  }
@@ -27745,7 +28618,7 @@ var AskAiWidget = ({
27745
28618
  const resolvedContext = useMemo15(() => {
27746
28619
  return resolveAgentContext(currentPath, currentSearch, rules);
27747
28620
  }, [currentPath, currentSearch, rules]);
27748
- const [reportedContext, setReportedContext] = useState29(null);
28621
+ const [reportedContext, setReportedContext] = useState30(null);
27749
28622
  const activeContext = reportedContext && reportedContext.path === currentPath && reportedContext.search === currentSearch ? reportedContext.ctx : resolvedContext;
27750
28623
  const handleContextResolved = useCallback16(
27751
28624
  (ctx) => {
@@ -27754,7 +28627,7 @@ var AskAiWidget = ({
27754
28627
  },
27755
28628
  [currentPath, currentSearch, onContextResolved]
27756
28629
  );
27757
- useEffect26(() => {
28630
+ useEffect27(() => {
27758
28631
  const handleDrawerOpenEvent = (e) => {
27759
28632
  if (isAgentDisabled) return;
27760
28633
  const detail = e.detail;
@@ -27766,17 +28639,18 @@ var AskAiWidget = ({
27766
28639
  window.addEventListener(AGENT_DRAWER_OPEN_EVENT2, handleDrawerOpenEvent);
27767
28640
  return () => window.removeEventListener(AGENT_DRAWER_OPEN_EVENT2, handleDrawerOpenEvent);
27768
28641
  }, [isAgentDisabled, setDrawerOpen]);
27769
- useEffect26(() => {
28642
+ useEffect27(() => {
27770
28643
  if (propInitialTab) {
27771
28644
  setActiveTab(propInitialTab);
27772
28645
  }
27773
28646
  }, [propInitialTab]);
27774
28647
  const effectiveButtonLabel = buttonProps?.label || (activeContext.buttonLabelFn ? activeContext.buttonLabelFn() : activeContext.buttonLabel) || "Ask AI";
27775
- const isBeta = activeContext.isBeta === true;
28648
+ const isIncidentOrDocsRoute = currentPath.startsWith("/incidents") || currentPath.startsWith("/incidents-simple") || currentPath.startsWith("/cases") || currentPath.startsWith("/alerts") || currentPath.startsWith("/tickets") || currentPath.startsWith("/docs");
28649
+ const isBeta = activeContext.isBeta === true || isIncidentOrDocsRoute;
27776
28650
  const effectiveRequireSupport = isBeta ? false : requireSupport;
27777
28651
  const defaultTag = isBeta ? "Beta" : "Support";
27778
28652
  const effectiveTagLabel = buttonProps?.tagLabel !== void 0 ? buttonProps.tagLabel : defaultTag;
27779
- useEffect26(() => {
28653
+ useEffect27(() => {
27780
28654
  if (effectiveRequireSupport && !isSupport && isDrawerOpen) {
27781
28655
  setDrawerOpen(false);
27782
28656
  }
@@ -27836,10 +28710,10 @@ var AskAiWidget = ({
27836
28710
  ] });
27837
28711
  };
27838
28712
  var useContextAwareAgent = (pathname, search) => {
27839
- const [activeContext, setActiveContext] = useState29(
28713
+ const [activeContext, setActiveContext] = useState30(
27840
28714
  () => resolveAgentContext(pathname ?? "/", search ?? "")
27841
28715
  );
27842
- useEffect26(() => {
28716
+ useEffect27(() => {
27843
28717
  const p = pathname ?? (typeof window !== "undefined" ? window.location.pathname : "/");
27844
28718
  const s = search ?? (typeof window !== "undefined" ? window.location.search : "");
27845
28719
  setActiveContext(resolveAgentContext(p, s));
@@ -27849,7 +28723,7 @@ var useContextAwareAgent = (pathname, search) => {
27849
28723
  var AskAiWidget_default = AskAiWidget;
27850
28724
 
27851
28725
  // components/AgentPromptPrefixChip.tsx
27852
- import { useEffect as useEffect27, useState as useState30 } from "react";
28726
+ import { useEffect as useEffect28, useState as useState31 } from "react";
27853
28727
  import {
27854
28728
  Box as Box33,
27855
28729
  Button as Button17,
@@ -27878,9 +28752,9 @@ var AgentPromptPrefixChip = ({
27878
28752
  const managed = useAgentPromptPrefix({ userId, defaultPrompt, persist: !controlled });
27879
28753
  const prompt = controlled ? value : managed.prompt;
27880
28754
  const isSaving = controlled ? false : managed.isSaving;
27881
- const [open, setOpen] = useState30(false);
27882
- const [draft, setDraft] = useState30(prompt);
27883
- useEffect27(() => {
28755
+ const [open, setOpen] = useState31(false);
28756
+ const [draft, setDraft] = useState31(prompt);
28757
+ useEffect28(() => {
27884
28758
  if (!open) setDraft(prompt);
27885
28759
  }, [prompt, open]);
27886
28760
  const handleOpen = () => {
@@ -28888,12 +29762,12 @@ var DEMO_AGENT_RUNS = [
28888
29762
  ];
28889
29763
 
28890
29764
  // useAppLookup.ts
28891
- import { useEffect as useEffect28, useMemo as useMemo16, useState as useState31 } from "react";
29765
+ import { useEffect as useEffect29, useMemo as useMemo16, useState as useState32 } from "react";
28892
29766
  var norm3 = (s) => s.toLowerCase().replace(/[\s_\-]+/g, "_");
28893
29767
  function useAppLookup(appName) {
28894
- const [loading, setLoading] = useState31(false);
28895
- const [info, setInfo] = useState31(null);
28896
- const [algoliaId, setAlgoliaId] = useState31(null);
29768
+ const [loading, setLoading] = useState32(false);
29769
+ const [info, setInfo] = useState32(null);
29770
+ const [algoliaId, setAlgoliaId] = useState32(null);
28897
29771
  const {
28898
29772
  authStates,
28899
29773
  authenticatedApps,
@@ -28902,7 +29776,7 @@ function useAppLookup(appName) {
28902
29776
  handleSaveAuth,
28903
29777
  refreshAuth
28904
29778
  } = useAppAuth();
28905
- useEffect28(() => {
29779
+ useEffect29(() => {
28906
29780
  if (!appName) {
28907
29781
  setInfo(null);
28908
29782
  setAlgoliaId(null);