@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.js CHANGED
@@ -1024,10 +1024,10 @@ var init_api = __esm({
1024
1024
  let orgId = overrideOrgId ?? _trackedOrgId;
1025
1025
  if (!orgId && typeof localStorage !== "undefined") {
1026
1026
  try {
1027
- const raw = localStorage.getItem("shuffle_user_info");
1027
+ const raw = localStorage.getItem("shuffle_user_info") || localStorage.getItem("userinfo") || localStorage.getItem("user_info");
1028
1028
  if (raw) {
1029
1029
  const parsed = JSON.parse(raw);
1030
- orgId = parsed?.active_org?.id || parsed?.org_id || null;
1030
+ orgId = parsed?.active_org?.id || parsed?.org_id || parsed?.active_org_id || parsed?.orgs && parsed.orgs[0]?.id || null;
1031
1031
  }
1032
1032
  } catch {
1033
1033
  }
@@ -1257,7 +1257,7 @@ __export(index_exports, {
1257
1257
  });
1258
1258
  module.exports = __toCommonJS(index_exports);
1259
1259
  var import_shuffle_mcp3 = require("./shuffle-mcp-SHQXQS3F.css");
1260
- var import_react37 = __toESM(require("react"));
1260
+ var import_react39 = __toESM(require("react"));
1261
1261
 
1262
1262
  // ShuffleMcpThemeProvider.tsx
1263
1263
  var import_react = __toESM(require("react"));
@@ -1470,7 +1470,7 @@ var ShuffleMcpThemeProvider = ({
1470
1470
  };
1471
1471
 
1472
1472
  // views/ShuffleMCP.tsx
1473
- var import_react14 = __toESM(require("react"));
1473
+ var import_react15 = __toESM(require("react"));
1474
1474
  var import_algoliasearch = require("algoliasearch");
1475
1475
  var import_material15 = require("@mui/material");
1476
1476
 
@@ -2819,10 +2819,10 @@ var setRuntimeOrgId = (orgId) => {
2819
2819
  var getOrgId = () => {
2820
2820
  if (_runtimeOrgId) return _runtimeOrgId;
2821
2821
  try {
2822
- const userInfo = localStorage.getItem("shuffle_user_info");
2822
+ const userInfo = localStorage.getItem("shuffle_user_info") || localStorage.getItem("userinfo") || localStorage.getItem("user_info");
2823
2823
  if (userInfo) {
2824
2824
  const parsed = JSON.parse(userInfo);
2825
- return parsed.active_org?.id || null;
2825
+ return parsed.active_org?.id || parsed.org_id || parsed.active_org_id || parsed.orgs && parsed.orgs[0]?.id || null;
2826
2826
  }
2827
2827
  } catch {
2828
2828
  }
@@ -3638,6 +3638,7 @@ var deleteDatastoreItems = async (keys2, category) => {
3638
3638
  };
3639
3639
  var DATASTORE_CATEGORIES = {
3640
3640
  INCIDENTS: "shuffle-security_incidents",
3641
+ EVENTS: "shuffle-security_events",
3641
3642
  VULNERABILITIES: "shuffle-security_vulns",
3642
3643
  VULNS: "shuffle-security_vulns",
3643
3644
  ASSETS: "shuffle-security_assets",
@@ -3920,13 +3921,22 @@ var useSyncHostBaseUrl = (globalUrl) => {
3920
3921
  };
3921
3922
 
3922
3923
  // auth-utils.ts
3924
+ var THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1e3;
3925
+ function isValidationFresh(validation) {
3926
+ if (validation?.valid !== true) return false;
3927
+ if (!validation.last_valid) return true;
3928
+ const cutoff = Date.now() - THIRTY_DAYS_MS;
3929
+ const lastValidMs = validation.last_valid > 1e12 ? validation.last_valid : validation.last_valid * 1e3;
3930
+ return lastValidMs >= cutoff;
3931
+ }
3923
3932
  function deduplicateAuthApps(apps) {
3924
3933
  const appMap = /* @__PURE__ */ new Map();
3925
3934
  apps.forEach((auth) => {
3926
- if (!auth.active && !auth.validation?.valid) return;
3935
+ if (!auth.app?.name) return;
3936
+ if (!auth.active && !isValidationFresh(auth.validation)) return;
3927
3937
  const normalizedName = auth.app.name.toLowerCase().trim().replace(/[\s_\-]+/g, "_");
3928
3938
  const existing = appMap.get(normalizedName);
3929
- const isValidated = auth.validation?.valid === true;
3939
+ const isValidated = isValidationFresh(auth.validation);
3930
3940
  const entryImage = auth.app.large_image || "";
3931
3941
  const instance = {
3932
3942
  label: auth.label || auth.id || "Default",
@@ -4142,7 +4152,7 @@ function findForwardTicketsWorkflow(workflows) {
4142
4152
  }
4143
4153
  function extractValidatedIngestionApps(authApiResponse, workflowAppNames) {
4144
4154
  const dedupedApps = deduplicateAuthApps(
4145
- authApiResponse.filter((auth) => auth.active || auth.validation?.valid)
4155
+ authApiResponse.filter((auth) => auth.active || isValidationFresh(auth.validation))
4146
4156
  );
4147
4157
  const enabledNames = workflowAppNames || /* @__PURE__ */ new Set();
4148
4158
  const apps = [];
@@ -4249,9 +4259,9 @@ function invalidateAuthCache() {
4249
4259
  var TTL_MS2 = 3e4;
4250
4260
  var cache3 = /* @__PURE__ */ new Map();
4251
4261
  var cacheKey2 = (crossOrgId) => crossOrgId || "";
4252
- var THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1e3;
4262
+ var THIRTY_DAYS_MS2 = 30 * 24 * 60 * 60 * 1e3;
4253
4263
  var applyValidationStaleness = (data) => {
4254
- const cutoff = Date.now() - THIRTY_DAYS_MS;
4264
+ const cutoff = Date.now() - THIRTY_DAYS_MS2;
4255
4265
  return data.map((entry) => {
4256
4266
  const v = entry.validation;
4257
4267
  if (v?.valid === true && v?.last_valid) {
@@ -4264,7 +4274,7 @@ var applyValidationStaleness = (data) => {
4264
4274
  });
4265
4275
  };
4266
4276
  var doFetch3 = async (crossOrgId) => {
4267
- if (!hasShuffleAuth()) return [];
4277
+ if (!hasShuffleAuth()) return { data: [], failed: false };
4268
4278
  const headers = {
4269
4279
  ...getAuthHeader(crossOrgId ?? void 0)
4270
4280
  };
@@ -4273,12 +4283,13 @@ var doFetch3 = async (crossOrgId) => {
4273
4283
  credentials: "include",
4274
4284
  headers
4275
4285
  });
4276
- if (!resp.ok) return [];
4286
+ if (!resp.ok) return { data: [], failed: true };
4277
4287
  const result = await resp.json();
4278
4288
  const data = result?.data || result;
4279
- return Array.isArray(data) ? applyValidationStaleness(data) : [];
4289
+ if (!Array.isArray(data)) return { data: [], failed: true };
4290
+ return { data: applyValidationStaleness(data), failed: false };
4280
4291
  } catch {
4281
- return [];
4292
+ return { data: [], failed: true };
4282
4293
  }
4283
4294
  };
4284
4295
  var fetchAuthenticatedApps = (crossOrgId) => {
@@ -4288,12 +4299,17 @@ var fetchAuthenticatedApps = (crossOrgId) => {
4288
4299
  return Promise.resolve(entry.data);
4289
4300
  }
4290
4301
  if (entry.promise) return entry.promise;
4291
- const promise = doFetch3(crossOrgId).then((data) => {
4292
- cache3.set(key, { data, fetchedAt: Date.now() });
4293
- return data;
4294
- }).catch((err) => {
4302
+ const promise = doFetch3(crossOrgId).then((outcome) => {
4303
+ if (outcome.failed) {
4304
+ const previous = cache3.get(key)?.data;
4305
+ cache3.delete(key);
4306
+ return previous || [];
4307
+ }
4308
+ cache3.set(key, { data: outcome.data, fetchedAt: Date.now() });
4309
+ return outcome.data;
4310
+ }).catch(() => {
4295
4311
  cache3.delete(key);
4296
- throw err;
4312
+ return [];
4297
4313
  });
4298
4314
  cache3.set(key, { ...entry, promise });
4299
4315
  return promise;
@@ -9645,6 +9661,238 @@ function AppDetailContent({
9645
9661
  ] });
9646
9662
  }
9647
9663
 
9664
+ // drawerLayer.ts
9665
+ var import_react14 = require("react");
9666
+ var STACK_KEY = "__shuffleOverlayStack";
9667
+ var COUNTER_KEY = "__shuffleDrawerLayerTop";
9668
+ var AUTO_LAYER_KEY = "__shuffleOverlayAutoLayerInstalled";
9669
+ var OVERLAY_BASE = 10010;
9670
+ var DRAWER_LAYER_BASE = OVERLAY_BASE;
9671
+ var SURFACE_STEP = 20;
9672
+ var POPUP_OFFSET = 6;
9673
+ var TOOLTIP_OFFSET = 12;
9674
+ var getStore = () => globalThis;
9675
+ var getOverlayStack = () => {
9676
+ const store = getStore();
9677
+ if (!Array.isArray(store[STACK_KEY])) {
9678
+ store[STACK_KEY] = [];
9679
+ }
9680
+ return store[STACK_KEY];
9681
+ };
9682
+ var getTopSurfaceZIndex = (base3 = OVERLAY_BASE) => {
9683
+ const stack = getOverlayStack();
9684
+ const surfaces = stack.filter((r) => r.type === "surface");
9685
+ if (surfaces.length === 0) {
9686
+ const store = getStore();
9687
+ store[COUNTER_KEY] = base3;
9688
+ return base3;
9689
+ }
9690
+ let maxZ = base3;
9691
+ for (const s of surfaces) {
9692
+ if (s.zIndex > maxZ) {
9693
+ maxZ = s.zIndex;
9694
+ }
9695
+ }
9696
+ getStore()[COUNTER_KEY] = maxZ;
9697
+ return maxZ;
9698
+ };
9699
+ var syncGlobalCounter = (base3 = OVERLAY_BASE) => {
9700
+ getTopSurfaceZIndex(base3);
9701
+ };
9702
+ var allocateSurfaceLayer = (id, element2, base3 = OVERLAY_BASE) => {
9703
+ const stack = getOverlayStack();
9704
+ const existing = stack.find((r) => r.id === id || element2 && r.element === element2);
9705
+ if (existing) {
9706
+ return existing.zIndex;
9707
+ }
9708
+ const currentTop = getTopSurfaceZIndex(base3);
9709
+ const nextZ = currentTop + SURFACE_STEP;
9710
+ stack.push({ id, element: element2, zIndex: nextZ, type: "surface" });
9711
+ syncGlobalCounter(base3);
9712
+ return nextZ;
9713
+ };
9714
+ var releaseOverlayLayer = (idOrElement) => {
9715
+ const stack = getOverlayStack();
9716
+ const index = stack.findIndex(
9717
+ (r) => r.id === idOrElement || typeof idOrElement !== "string" && r.element === idOrElement
9718
+ );
9719
+ if (index !== -1) {
9720
+ stack.splice(index, 1);
9721
+ }
9722
+ syncGlobalCounter();
9723
+ };
9724
+ var bringSurfaceToFront = (idOrElement) => {
9725
+ const stack = getOverlayStack();
9726
+ const record = stack.find(
9727
+ (r) => r.id === idOrElement || typeof idOrElement !== "string" && r.element === idOrElement
9728
+ );
9729
+ if (!record || record.type !== "surface") {
9730
+ return typeof idOrElement === "string" ? allocateSurfaceLayer(idOrElement, null) : allocateSurfaceLayer("surface_" + Math.random().toString(36).substring(2, 9), idOrElement);
9731
+ }
9732
+ const currentTop = getTopSurfaceZIndex();
9733
+ if (record.zIndex >= currentTop) {
9734
+ return record.zIndex;
9735
+ }
9736
+ record.zIndex = currentTop + SURFACE_STEP;
9737
+ syncGlobalCounter();
9738
+ return record.zIndex;
9739
+ };
9740
+ var useOverlayLayer = (open, options) => {
9741
+ const base3 = options?.base ?? OVERLAY_BASE;
9742
+ const [zIndex, setZIndex] = (0, import_react14.useState)(() => open ? getTopSurfaceZIndex(base3) + SURFACE_STEP : base3);
9743
+ (0, import_react14.useEffect)(() => {
9744
+ if (!open) return;
9745
+ const id = "hook_" + Math.random().toString(36).substring(2, 9);
9746
+ const allocated = allocateSurfaceLayer(id, null, base3);
9747
+ setZIndex(allocated);
9748
+ return () => {
9749
+ releaseOverlayLayer(id);
9750
+ };
9751
+ }, [open, base3]);
9752
+ return zIndex;
9753
+ };
9754
+ var useDrawerLayer = (open, base3 = DRAWER_LAYER_BASE) => useOverlayLayer(open, { base: base3 });
9755
+ var isSurfaceElement = (el) => {
9756
+ if (!(el instanceof HTMLElement)) return false;
9757
+ 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]"));
9758
+ };
9759
+ var isChildPopupElement = (el) => {
9760
+ if (!(el instanceof HTMLElement)) return false;
9761
+ 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");
9762
+ };
9763
+ var isTooltipElement = (el) => {
9764
+ if (!(el instanceof HTMLElement)) return false;
9765
+ return el.classList.contains("MuiTooltip-popper") || el.getAttribute("role") === "tooltip";
9766
+ };
9767
+ var isElementOpen = (el) => {
9768
+ if (el.getAttribute("aria-hidden") === "true") return false;
9769
+ if (el.getAttribute("data-state") === "closed") return false;
9770
+ if (el.classList.contains("MuiModal-hidden")) return false;
9771
+ const style = el.style;
9772
+ if (style.display === "none" || style.visibility === "hidden") return false;
9773
+ return true;
9774
+ };
9775
+ var observerInstance = null;
9776
+ var installGlobalOverlayAutoLayer = () => {
9777
+ if (typeof window === "undefined" || typeof document === "undefined") return;
9778
+ const store = getStore();
9779
+ if (store[AUTO_LAYER_KEY]) return;
9780
+ store[AUTO_LAYER_KEY] = true;
9781
+ const handleElementOpen = (el) => {
9782
+ if (isSurfaceElement(el)) {
9783
+ let layerId = el.dataset.shuffleLayerId;
9784
+ if (!layerId) {
9785
+ layerId = "dom_" + Math.random().toString(36).substring(2, 9);
9786
+ el.dataset.shuffleLayerId = layerId;
9787
+ }
9788
+ const targetZ = allocateSurfaceLayer(layerId, el);
9789
+ el.dataset.shuffleLayerZ = String(targetZ);
9790
+ el.style.setProperty("z-index", String(targetZ), "important");
9791
+ const dialogContent = el.querySelector('[role="dialog"], [role="alertdialog"]');
9792
+ if (dialogContent && dialogContent !== el) {
9793
+ dialogContent.style.setProperty("z-index", String(targetZ), "important");
9794
+ }
9795
+ return;
9796
+ }
9797
+ if (isChildPopupElement(el)) {
9798
+ const topZ = getTopSurfaceZIndex();
9799
+ const popupZ = topZ + POPUP_OFFSET;
9800
+ el.dataset.shuffleLayerZ = String(popupZ);
9801
+ el.style.setProperty("z-index", String(popupZ), "important");
9802
+ return;
9803
+ }
9804
+ if (isTooltipElement(el)) {
9805
+ const topZ = getTopSurfaceZIndex();
9806
+ const tooltipZ = topZ + TOOLTIP_OFFSET;
9807
+ el.dataset.shuffleLayerZ = String(tooltipZ);
9808
+ el.style.setProperty("z-index", String(tooltipZ), "important");
9809
+ return;
9810
+ }
9811
+ };
9812
+ const handleElementClose = (el) => {
9813
+ const layerId = el.dataset.shuffleLayerId;
9814
+ if (layerId) {
9815
+ releaseOverlayLayer(layerId);
9816
+ delete el.dataset.shuffleLayerId;
9817
+ delete el.dataset.shuffleLayerZ;
9818
+ } else {
9819
+ releaseOverlayLayer(el);
9820
+ }
9821
+ };
9822
+ const scanNode = (node) => {
9823
+ if (!(node instanceof HTMLElement)) return;
9824
+ if (isSurfaceElement(node) || isChildPopupElement(node) || isTooltipElement(node)) {
9825
+ if (isElementOpen(node)) {
9826
+ handleElementOpen(node);
9827
+ } else {
9828
+ handleElementClose(node);
9829
+ }
9830
+ }
9831
+ const children2 = node.children;
9832
+ for (let i = 0; i < children2.length; i++) {
9833
+ const child = children2[i];
9834
+ if (child instanceof HTMLElement) {
9835
+ if (isSurfaceElement(child) || isChildPopupElement(child) || isTooltipElement(child)) {
9836
+ if (isElementOpen(child)) {
9837
+ handleElementOpen(child);
9838
+ } else {
9839
+ handleElementClose(child);
9840
+ }
9841
+ }
9842
+ }
9843
+ }
9844
+ };
9845
+ observerInstance = new MutationObserver((mutations) => {
9846
+ for (const m of mutations) {
9847
+ if (m.type === "childList") {
9848
+ m.addedNodes.forEach(scanNode);
9849
+ m.removedNodes.forEach((node) => {
9850
+ if (node instanceof HTMLElement) {
9851
+ handleElementClose(node);
9852
+ }
9853
+ });
9854
+ } else if (m.type === "attributes") {
9855
+ const target = m.target;
9856
+ if (target instanceof HTMLElement) {
9857
+ scanNode(target);
9858
+ }
9859
+ }
9860
+ }
9861
+ });
9862
+ const body = document.body;
9863
+ if (body) {
9864
+ observerInstance.observe(body, {
9865
+ childList: true,
9866
+ subtree: true,
9867
+ attributes: true,
9868
+ attributeFilter: ["class", "style", "aria-hidden", "data-state"]
9869
+ });
9870
+ Array.from(body.children).forEach(scanNode);
9871
+ }
9872
+ document.addEventListener(
9873
+ "pointerdown",
9874
+ (e) => {
9875
+ const target = e.target;
9876
+ if (!target) return;
9877
+ const surface = target.closest(
9878
+ '.MuiDialog-root, .MuiDrawer-root, .MuiModal-root:not(.MuiPopover-root):not(.MuiMenu-root), [role="dialog"], [role="alertdialog"]'
9879
+ );
9880
+ if (!surface || !surface.dataset.shuffleLayerId) return;
9881
+ const currentZ = Number(surface.dataset.shuffleLayerZ || 0);
9882
+ const topZ = getTopSurfaceZIndex();
9883
+ if (currentZ > 0 && currentZ < topZ) {
9884
+ const newZ = bringSurfaceToFront(surface.dataset.shuffleLayerId);
9885
+ surface.dataset.shuffleLayerZ = String(newZ);
9886
+ surface.style.setProperty("z-index", String(newZ), "important");
9887
+ }
9888
+ },
9889
+ true
9890
+ );
9891
+ };
9892
+ if (typeof window !== "undefined") {
9893
+ installGlobalOverlayAutoLayer();
9894
+ }
9895
+
9648
9896
  // views/AppDetailDrawer.tsx
9649
9897
  var import_jsx_runtime17 = require("react/jsx-runtime");
9650
9898
  function AppDetailDrawer({
@@ -9674,6 +9922,7 @@ function AppDetailDrawer({
9674
9922
  const drawerWidth = `min(${width}px, 100vw)`;
9675
9923
  const drawerMinWidth = `min(${minWidth}px, 100vw)`;
9676
9924
  const drawerMaxWidth = `min(${maxWidth}px, 100vw)`;
9925
+ const drawerZIndex = useDrawerLayer(open);
9677
9926
  const handleClose = () => {
9678
9927
  onRefresh?.();
9679
9928
  onClose();
@@ -9705,7 +9954,7 @@ function AppDetailDrawer({
9705
9954
  },
9706
9955
  ...{ PaperProps: drawerPaperProps },
9707
9956
  sx: {
9708
- zIndex: 9999,
9957
+ zIndex: drawerZIndex,
9709
9958
  "& .MuiDrawer-paper": {
9710
9959
  boxSizing: "border-box",
9711
9960
  width: `${drawerWidth} !important`,
@@ -10046,7 +10295,7 @@ var SearchErrorMessage = ({ rateLimited, message }) => {
10046
10295
  }
10047
10296
  );
10048
10297
  };
10049
- var ShuffleMCP = import_react14.default.forwardRef(({
10298
+ var ShuffleMCP = import_react15.default.forwardRef(({
10050
10299
  authToken,
10051
10300
  orgId,
10052
10301
  placeholder = "Search apps...",
@@ -10091,33 +10340,38 @@ var ShuffleMCP = import_react14.default.forwardRef(({
10091
10340
  globalUrl
10092
10341
  }, ref) => {
10093
10342
  useSyncHostBaseUrl(globalUrl);
10094
- const [query, setQuery] = (0, import_react14.useState)(initialQuery);
10095
- const [results, setResults] = (0, import_react14.useState)([]);
10096
- const [privateApps, setPrivateApps] = (0, import_react14.useState)([]);
10097
- const [privateAppsLoading, setPrivateAppsLoading] = (0, import_react14.useState)(!disablePrivateApps);
10098
- const [sourceFilter, setSourceFilter] = (0, import_react14.useState)("all");
10099
- const [isLoading, setIsLoading] = (0, import_react14.useState)(false);
10100
- const [isLoadingMore, setIsLoadingMore] = (0, import_react14.useState)(false);
10101
- const [page, setPage] = (0, import_react14.useState)(0);
10102
- const [hasMore, setHasMore] = (0, import_react14.useState)(false);
10103
- const [searchError, setSearchError] = (0, import_react14.useState)(null);
10104
- const [isOpen, setIsOpen] = (0, import_react14.useState)(false);
10105
- const [selectedIndex, setSelectedIndex] = (0, import_react14.useState)(-1);
10106
- const [internalSelectedApps, setInternalSelectedApps] = (0, import_react14.useState)(selectedApps);
10107
- const [authenticatedApps, setAuthenticatedApps] = (0, import_react14.useState)(externalAuthenticatedApps || []);
10108
- const [authenticatedAppsLoading, setAuthenticatedAppsLoading] = (0, import_react14.useState)(!externalAuthenticatedApps);
10109
- const [drawerApp, setDrawerApp] = (0, import_react14.useState)(null);
10110
- const [initialSettled, setInitialSettled] = (0, import_react14.useState)(false);
10111
- const firstSearchDoneRef = (0, import_react14.useRef)(false);
10112
- const hasInitialized = (0, import_react14.useRef)(false);
10113
- const containerRef = (0, import_react14.useRef)(null);
10114
- const resultsScrollRef = (0, import_react14.useRef)(null);
10115
- const inputRef = (0, import_react14.useRef)(null);
10116
- const debounceTimer = (0, import_react14.useRef)(null);
10117
- const searchClient = (0, import_react14.useRef)(null);
10118
- const activeQueryRef = (0, import_react14.useRef)("");
10119
- const initialSelectedAppsRef = (0, import_react14.useRef)(selectedApps);
10120
- const fetchAuthenticatedApps2 = (0, import_react14.useCallback)(async () => {
10343
+ const [query, setQuery] = (0, import_react15.useState)(initialQuery);
10344
+ const [results, setResults] = (0, import_react15.useState)([]);
10345
+ const [privateApps, setPrivateApps] = (0, import_react15.useState)([]);
10346
+ const [privateAppsLoading, setPrivateAppsLoading] = (0, import_react15.useState)(!disablePrivateApps);
10347
+ const [sourceFilter, setSourceFilter] = (0, import_react15.useState)("all");
10348
+ const [isLoading, setIsLoading] = (0, import_react15.useState)(false);
10349
+ const [isLoadingMore, setIsLoadingMore] = (0, import_react15.useState)(false);
10350
+ const [page, setPage] = (0, import_react15.useState)(0);
10351
+ const [hasMore, setHasMore] = (0, import_react15.useState)(false);
10352
+ const [searchError, setSearchError] = (0, import_react15.useState)(null);
10353
+ const [isOpen, setIsOpen] = (0, import_react15.useState)(false);
10354
+ const [selectedIndex, setSelectedIndex] = (0, import_react15.useState)(-1);
10355
+ const [internalSelectedApps, setInternalSelectedApps] = (0, import_react15.useState)(selectedApps);
10356
+ (0, import_react15.useEffect)(() => {
10357
+ if (selectedApps) {
10358
+ setInternalSelectedApps(selectedApps);
10359
+ }
10360
+ }, [selectedApps]);
10361
+ const [authenticatedApps, setAuthenticatedApps] = (0, import_react15.useState)(externalAuthenticatedApps || []);
10362
+ const [authenticatedAppsLoading, setAuthenticatedAppsLoading] = (0, import_react15.useState)(!externalAuthenticatedApps);
10363
+ const [drawerApp, setDrawerApp] = (0, import_react15.useState)(null);
10364
+ const [initialSettled, setInitialSettled] = (0, import_react15.useState)(false);
10365
+ const firstSearchDoneRef = (0, import_react15.useRef)(false);
10366
+ const hasInitialized = (0, import_react15.useRef)(false);
10367
+ const containerRef = (0, import_react15.useRef)(null);
10368
+ const resultsScrollRef = (0, import_react15.useRef)(null);
10369
+ const inputRef = (0, import_react15.useRef)(null);
10370
+ const debounceTimer = (0, import_react15.useRef)(null);
10371
+ const searchClient = (0, import_react15.useRef)(null);
10372
+ const activeQueryRef = (0, import_react15.useRef)("");
10373
+ const initialSelectedAppsRef = (0, import_react15.useRef)(selectedApps);
10374
+ const fetchAuthenticatedApps2 = (0, import_react15.useCallback)(async () => {
10121
10375
  if (!apiKey) {
10122
10376
  setAuthenticatedAppsLoading(false);
10123
10377
  return;
@@ -10143,10 +10397,10 @@ var ShuffleMCP = import_react14.default.forwardRef(({
10143
10397
  setAuthenticatedAppsLoading(false);
10144
10398
  }
10145
10399
  }, [apiKey, apiBaseUrl, authPath, orgId]);
10146
- (0, import_react14.useEffect)(() => {
10400
+ (0, import_react15.useEffect)(() => {
10147
10401
  fetchAuthenticatedApps2();
10148
10402
  }, [fetchAuthenticatedApps2]);
10149
- (0, import_react14.useEffect)(() => {
10403
+ (0, import_react15.useEffect)(() => {
10150
10404
  if (disablePrivateApps) {
10151
10405
  setPrivateApps([]);
10152
10406
  setPrivateAppsLoading(false);
@@ -10190,7 +10444,7 @@ var ShuffleMCP = import_react14.default.forwardRef(({
10190
10444
  };
10191
10445
  fetchPrivateApps();
10192
10446
  }, [apiKey, apiBaseUrl, privateAppsPath, disablePrivateApps, orgId]);
10193
- (0, import_react14.useEffect)(() => {
10447
+ (0, import_react15.useEffect)(() => {
10194
10448
  if (disableAutoSelectValidatedApps) return;
10195
10449
  if (authenticatedApps.length > 0 && results.length > 0) {
10196
10450
  const validatedApps = authenticatedApps.filter((auth) => auth.validation?.valid);
@@ -10211,13 +10465,13 @@ var ShuffleMCP = import_react14.default.forwardRef(({
10211
10465
  }
10212
10466
  }
10213
10467
  }, [authenticatedApps, results, disableAutoSelectValidatedApps]);
10214
- (0, import_react14.useEffect)(() => {
10468
+ (0, import_react15.useEffect)(() => {
10215
10469
  if (externalAuthenticatedApps) {
10216
10470
  setAuthenticatedApps(externalAuthenticatedApps);
10217
10471
  setAuthenticatedAppsLoading(false);
10218
10472
  }
10219
10473
  }, [externalAuthenticatedApps]);
10220
- (0, import_react14.useEffect)(() => {
10474
+ (0, import_react15.useEffect)(() => {
10221
10475
  searchClient.current = (0, import_algoliasearch.algoliasearch)(algoliaAppId, algoliaApiKey);
10222
10476
  if (!hasInitialized.current) {
10223
10477
  hasInitialized.current = true;
@@ -10230,10 +10484,10 @@ var ShuffleMCP = import_react14.default.forwardRef(({
10230
10484
  }, 100);
10231
10485
  }
10232
10486
  }, []);
10233
- (0, import_react14.useEffect)(() => {
10487
+ (0, import_react15.useEffect)(() => {
10234
10488
  setInternalSelectedApps(selectedApps);
10235
10489
  }, [selectedApps]);
10236
- (0, import_react14.useEffect)(() => {
10490
+ (0, import_react15.useEffect)(() => {
10237
10491
  const handleClickOutside = (event) => {
10238
10492
  if (containerRef.current && !containerRef.current.contains(event.target)) {
10239
10493
  setIsOpen(false);
@@ -10243,23 +10497,23 @@ var ShuffleMCP = import_react14.default.forwardRef(({
10243
10497
  document.addEventListener("click", handleClickOutside);
10244
10498
  return () => document.removeEventListener("click", handleClickOutside);
10245
10499
  }, []);
10246
- const isAppConfigured = (0, import_react14.useCallback)((app2) => {
10500
+ const isAppConfigured = (0, import_react15.useCallback)((app2) => {
10247
10501
  return authenticatedApps.some(
10248
10502
  (auth) => auth.app.name.toLowerCase() === app2.name.toLowerCase() && auth.active === true
10249
10503
  );
10250
10504
  }, [authenticatedApps]);
10251
- const isAppValidated = (0, import_react14.useCallback)((app2) => {
10505
+ const isAppValidated = (0, import_react15.useCallback)((app2) => {
10252
10506
  return authenticatedApps.some(
10253
10507
  (auth) => auth.app.name.toLowerCase() === app2.name.toLowerCase() && auth.validation?.valid === true
10254
10508
  );
10255
10509
  }, [authenticatedApps]);
10256
- const getAppAuthState = (0, import_react14.useCallback)((app2) => {
10510
+ const getAppAuthState = (0, import_react15.useCallback)((app2) => {
10257
10511
  return {
10258
10512
  configured: isAppConfigured(app2),
10259
10513
  validated: isAppValidated(app2)
10260
10514
  };
10261
10515
  }, [isAppConfigured, isAppValidated]);
10262
- const performSearch = (0, import_react14.useCallback)(async (searchQuery, pageIndex = 0) => {
10516
+ const performSearch = (0, import_react15.useCallback)(async (searchQuery, pageIndex = 0) => {
10263
10517
  if (!searchClient.current) {
10264
10518
  return;
10265
10519
  }
@@ -10319,29 +10573,29 @@ var ShuffleMCP = import_react14.default.forwardRef(({
10319
10573
  }
10320
10574
  }
10321
10575
  }, [hitsPerPage, algoliaIndexName, privateApps.length, results.length]);
10322
- (0, import_react14.useEffect)(() => {
10576
+ (0, import_react15.useEffect)(() => {
10323
10577
  if (initialSettled) return;
10324
10578
  if (!firstSearchDoneRef.current || isLoading || privateAppsLoading) return;
10325
10579
  initialSelectedAppsRef.current = selectedApps;
10326
10580
  setInitialSettled(true);
10327
10581
  }, [initialSettled, isLoading, privateAppsLoading, selectedApps]);
10328
- (0, import_react14.useEffect)(() => {
10582
+ (0, import_react15.useEffect)(() => {
10329
10583
  const t = setTimeout(() => setInitialSettled(true), 6e3);
10330
10584
  return () => clearTimeout(t);
10331
10585
  }, []);
10332
10586
  const canLoadMore = hasMore && !isLoading && !isLoadingMore && results.length < MAX_RESULTS;
10333
- const loadMore = (0, import_react14.useCallback)(() => {
10587
+ const loadMore = (0, import_react15.useCallback)(() => {
10334
10588
  if (!canLoadMore) return;
10335
10589
  performSearch(activeQueryRef.current, page + 1);
10336
10590
  }, [canLoadMore, page, performSearch]);
10337
- const handleResultsScroll = (0, import_react14.useCallback)((e) => {
10591
+ const handleResultsScroll = (0, import_react15.useCallback)((e) => {
10338
10592
  if (!canLoadMore) return;
10339
10593
  const el = e.currentTarget;
10340
10594
  const distanceFromBottom = el.scrollHeight - el.scrollTop - el.clientHeight;
10341
10595
  if (distanceFromBottom < 200) loadMore();
10342
10596
  }, [canLoadMore, loadMore]);
10343
- const sentinelRef = (0, import_react14.useRef)(null);
10344
- (0, import_react14.useEffect)(() => {
10597
+ const sentinelRef = (0, import_react15.useRef)(null);
10598
+ (0, import_react15.useEffect)(() => {
10345
10599
  const node = sentinelRef.current;
10346
10600
  if (!node || !canLoadMore) return;
10347
10601
  const observer = new IntersectionObserver(
@@ -10354,7 +10608,7 @@ var ShuffleMCP = import_react14.default.forwardRef(({
10354
10608
  return () => observer.disconnect();
10355
10609
  }, [canLoadMore, loadMore, results.length]);
10356
10610
  const renderLoadMoreSentinel = () => canLoadMore ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { ref: sentinelRef, style: { height: 1, gridColumn: "1 / -1" } }) : null;
10357
- (0, import_react14.useImperativeHandle)(ref, () => ({
10611
+ (0, import_react15.useImperativeHandle)(ref, () => ({
10358
10612
  search: (searchQuery) => {
10359
10613
  setQuery(searchQuery);
10360
10614
  onSearchChange?.(searchQuery);
@@ -10377,7 +10631,7 @@ var ShuffleMCP = import_react14.default.forwardRef(({
10377
10631
  },
10378
10632
  getQuery: () => query
10379
10633
  }), [performSearch, onSearchChange, query]);
10380
- const handleInputChange = (0, import_react14.useCallback)((event) => {
10634
+ const handleInputChange = (0, import_react15.useCallback)((event) => {
10381
10635
  const value = event.target.value;
10382
10636
  setQuery(value);
10383
10637
  setSelectedIndex(-1);
@@ -10389,7 +10643,7 @@ var ShuffleMCP = import_react14.default.forwardRef(({
10389
10643
  performSearch(value);
10390
10644
  }, 300);
10391
10645
  }, [performSearch, onSearchChange]);
10392
- const selectApp = (0, import_react14.useCallback)((app2) => {
10646
+ const selectApp = (0, import_react15.useCallback)((app2) => {
10393
10647
  const handoffToken = apiKey || authToken || "";
10394
10648
  const authUrl = `${apiBaseUrl}${appAuthPath}?app_id=${app2.objectID}&auth=${handoffToken}&source=shuffle${orgId ? `&org_id=${encodeURIComponent(orgId)}` : ""}`;
10395
10649
  if (multiSelect) {
@@ -10412,7 +10666,7 @@ var ShuffleMCP = import_react14.default.forwardRef(({
10412
10666
  setIsOpen(false);
10413
10667
  }
10414
10668
  }, [authToken, apiKey, apiBaseUrl, appAuthPath, orgId, multiSelect, internalSelectedApps, onAppSelected, onSelectionChange, preventDefault]);
10415
- const handleKeyDown = (0, import_react14.useCallback)((event) => {
10669
+ const handleKeyDown = (0, import_react15.useCallback)((event) => {
10416
10670
  if (!isOpen) return;
10417
10671
  switch (event.key) {
10418
10672
  case "ArrowDown":
@@ -10437,14 +10691,14 @@ var ShuffleMCP = import_react14.default.forwardRef(({
10437
10691
  break;
10438
10692
  }
10439
10693
  }, [isOpen, results, selectedIndex, selectApp]);
10440
- const isAppSelected = (0, import_react14.useCallback)((app2) => {
10694
+ const isAppSelected = (0, import_react15.useCallback)((app2) => {
10441
10695
  const norm4 = (s) => (s || "").toLowerCase().replace(/[\s_\-]+/g, "");
10442
10696
  const target = norm4(app2.name);
10443
10697
  return internalSelectedApps.some(
10444
10698
  (a) => a.objectID === app2.objectID || target && norm4(a.name) === target
10445
10699
  );
10446
10700
  }, [internalSelectedApps]);
10447
- const filteredPrivateApps = (0, import_react14.useMemo)(() => {
10701
+ const filteredPrivateApps = (0, import_react15.useMemo)(() => {
10448
10702
  if (privateApps.length === 0) return [];
10449
10703
  const normalize2 = (s) => (s || "").toLowerCase().replace(/[\s_\-]+/g, "");
10450
10704
  const q = normalize2(query.trim());
@@ -10453,7 +10707,7 @@ var ShuffleMCP = import_react14.default.forwardRef(({
10453
10707
  (a) => normalize2(a.name).includes(q) || normalize2(a.description || "").includes(q) || (a.categories || []).some((c) => normalize2(c).includes(q))
10454
10708
  );
10455
10709
  }, [privateApps, query]);
10456
- const displayResults = (0, import_react14.useMemo)(() => {
10710
+ const displayResults = (0, import_react15.useMemo)(() => {
10457
10711
  const norm4 = (n) => (n || "").toLowerCase().replace(/[\s_\-]+/g, "");
10458
10712
  let merged;
10459
10713
  if (sourceFilter === "public") {
@@ -10483,7 +10737,7 @@ var ShuffleMCP = import_react14.default.forwardRef(({
10483
10737
  const pinnedNames = new Set(pinnedApps.map((a) => norm4(a.name)));
10484
10738
  return [...pinnedApps, ...sorted.filter((a) => !pinnedNames.has(norm4(a.name)))];
10485
10739
  }, [pinnedApps, results, filteredPrivateApps, sourceFilter, isAppConfigured]);
10486
- const getGridColumnsStyle = (0, import_react14.useMemo)(() => {
10740
+ const getGridColumnsStyle = (0, import_react15.useMemo)(() => {
10487
10741
  if (layout !== "grid") return {};
10488
10742
  const cols = typeof gridColumns === "number" ? gridColumns : gridColumns.md || 3;
10489
10743
  return { "--singul-grid-columns": cols };
@@ -10762,13 +11016,13 @@ var ShuffleMCP = import_react14.default.forwardRef(({
10762
11016
  ShuffleMCP.displayName = "ShuffleMCP";
10763
11017
 
10764
11018
  // views/AppSearchDrawer.tsx
10765
- var import_react16 = require("react");
11019
+ var import_react17 = require("react");
10766
11020
  var import_lucide_react9 = require("lucide-react");
10767
11021
  var import_material17 = require("@mui/material");
10768
11022
  var import_framer_motion8 = require("framer-motion");
10769
11023
 
10770
11024
  // ../Shuffle-Core/components/AddAppDialog.tsx
10771
- var import_react15 = require("react");
11025
+ var import_react16 = require("react");
10772
11026
  var import_material16 = require("@mui/material");
10773
11027
  var import_lucide_react8 = require("lucide-react");
10774
11028
 
@@ -11226,8 +11480,8 @@ var GENERATION_TIPS = [
11226
11480
  "Building the app with 100% fewer hand-wavy examples..."
11227
11481
  ];
11228
11482
  var DotsLoader = ({ message, tips }) => {
11229
- const [tipIndex, setTipIndex] = (0, import_react15.useState)(0);
11230
- (0, import_react15.useEffect)(() => {
11483
+ const [tipIndex, setTipIndex] = (0, import_react16.useState)(0);
11484
+ (0, import_react16.useEffect)(() => {
11231
11485
  if (!tips || tips.length === 0) return;
11232
11486
  const interval = setInterval(() => {
11233
11487
  setTipIndex((i) => (i + 1) % tips.length);
@@ -11288,19 +11542,20 @@ var AddAppDialog = ({
11288
11542
  maxLength = 1024,
11289
11543
  initialInput = ""
11290
11544
  }) => {
11291
- const [input, setInput] = (0, import_react15.useState)(initialInput);
11292
- const [stage, setStage] = (0, import_react15.useState)("idle");
11293
- const [spec, setSpec] = (0, import_react15.useState)(null);
11294
- const [errorMsg, setErrorMsg] = (0, import_react15.useState)("");
11295
- const [createdAppId, setCreatedAppId] = (0, import_react15.useState)("");
11296
- const [existing, setExisting] = (0, import_react15.useState)(null);
11297
- const [liveHits, setLiveHits] = (0, import_react15.useState)([]);
11298
- const [liveSearching, setLiveSearching] = (0, import_react15.useState)(false);
11299
- (0, import_react15.useEffect)(() => {
11545
+ const dialogZIndex = useOverlayLayer(open);
11546
+ const [input, setInput] = (0, import_react16.useState)(initialInput);
11547
+ const [stage, setStage] = (0, import_react16.useState)("idle");
11548
+ const [spec, setSpec] = (0, import_react16.useState)(null);
11549
+ const [errorMsg, setErrorMsg] = (0, import_react16.useState)("");
11550
+ const [createdAppId, setCreatedAppId] = (0, import_react16.useState)("");
11551
+ const [existing, setExisting] = (0, import_react16.useState)(null);
11552
+ const [liveHits, setLiveHits] = (0, import_react16.useState)([]);
11553
+ const [liveSearching, setLiveSearching] = (0, import_react16.useState)(false);
11554
+ (0, import_react16.useEffect)(() => {
11300
11555
  if (open) setInput(initialInput);
11301
11556
  }, [open, initialInput]);
11302
11557
  const title = spec?.info?.title || "";
11303
- (0, import_react15.useEffect)(() => {
11558
+ (0, import_react16.useEffect)(() => {
11304
11559
  if (stage !== "idle") return;
11305
11560
  const q = input.trim();
11306
11561
  if (!q || looksLikeUrl(q)) {
@@ -11331,7 +11586,7 @@ var AddAppDialog = ({
11331
11586
  clearTimeout(t);
11332
11587
  };
11333
11588
  }, [input, stage, algoliaAppId, algoliaApiKey, algoliaIndexName]);
11334
- const reset3 = (0, import_react15.useCallback)(() => {
11589
+ const reset3 = (0, import_react16.useCallback)(() => {
11335
11590
  setInput("");
11336
11591
  setStage("idle");
11337
11592
  setSpec(null);
@@ -11339,14 +11594,14 @@ var AddAppDialog = ({
11339
11594
  setCreatedAppId("");
11340
11595
  setExisting(null);
11341
11596
  }, []);
11342
- (0, import_react15.useEffect)(() => {
11597
+ (0, import_react16.useEffect)(() => {
11343
11598
  if (!open) {
11344
11599
  const t = setTimeout(reset3, 250);
11345
11600
  return () => clearTimeout(t);
11346
11601
  }
11347
11602
  return void 0;
11348
11603
  }, [open, reset3]);
11349
- const verifyAndCreate = (0, import_react15.useCallback)(
11604
+ const verifyAndCreate = (0, import_react16.useCallback)(
11350
11605
  async (openapiSpec) => {
11351
11606
  setStage("verifying");
11352
11607
  setErrorMsg("");
@@ -11383,7 +11638,7 @@ var AddAppDialog = ({
11383
11638
  },
11384
11639
  [verifyOpenapiPath, onCreated, onOpenChange]
11385
11640
  );
11386
- const runGeneration = (0, import_react15.useCallback)(
11641
+ const runGeneration = (0, import_react16.useCallback)(
11387
11642
  async (value) => {
11388
11643
  setStage("generating");
11389
11644
  setErrorMsg("");
@@ -11454,6 +11709,12 @@ var AddAppDialog = ({
11454
11709
  onClose: () => onOpenChange(false),
11455
11710
  fullWidth: true,
11456
11711
  maxWidth: "sm",
11712
+ sx: {
11713
+ zIndex: dialogZIndex,
11714
+ "& .MuiBackdrop-root": {
11715
+ zIndex: dialogZIndex
11716
+ }
11717
+ },
11457
11718
  PaperProps: {
11458
11719
  sx: {
11459
11720
  maxWidth: 640,
@@ -11462,7 +11723,8 @@ var AddAppDialog = ({
11462
11723
  color: "hsl(var(--foreground))",
11463
11724
  border: "1px solid hsl(var(--border))",
11464
11725
  borderRadius: 2,
11465
- boxSizing: "border-box"
11726
+ boxSizing: "border-box",
11727
+ zIndex: dialogZIndex
11466
11728
  }
11467
11729
  },
11468
11730
  children: [
@@ -11904,13 +12166,13 @@ function AppSearchDrawer({
11904
12166
  }) {
11905
12167
  const themeScope = useShuffleMcpTheme();
11906
12168
  const scopeClassName = themeScope?.scopeClassName ?? (theme === "dark" ? "shuffle-mcp-scope dark" : theme === "light" ? "shuffle-mcp-scope" : void 0);
11907
- const [detailAppName, setDetailAppName] = (0, import_react16.useState)(null);
11908
- const [detailAppId, setDetailAppId] = (0, import_react16.useState)(null);
11909
- const [addAppOpen, setAddAppOpen] = (0, import_react16.useState)(false);
11910
- const [addAppQuery, setAddAppQuery] = (0, import_react16.useState)("");
11911
- const [highlightActive, setHighlightActive] = (0, import_react16.useState)(false);
11912
- const [bodyReady, setBodyReady] = (0, import_react16.useState)(false);
11913
- (0, import_react16.useEffect)(() => {
12169
+ const [detailAppName, setDetailAppName] = (0, import_react17.useState)(null);
12170
+ const [detailAppId, setDetailAppId] = (0, import_react17.useState)(null);
12171
+ const [addAppOpen, setAddAppOpen] = (0, import_react17.useState)(false);
12172
+ const [addAppQuery, setAddAppQuery] = (0, import_react17.useState)("");
12173
+ const [highlightActive, setHighlightActive] = (0, import_react17.useState)(false);
12174
+ const [bodyReady, setBodyReady] = (0, import_react17.useState)(false);
12175
+ (0, import_react17.useEffect)(() => {
11914
12176
  if (!open) {
11915
12177
  setBodyReady(false);
11916
12178
  return;
@@ -11920,7 +12182,7 @@ function AppSearchDrawer({
11920
12182
  });
11921
12183
  return () => cancelAnimationFrame(raf);
11922
12184
  }, [open]);
11923
- (0, import_react16.useEffect)(() => {
12185
+ (0, import_react17.useEffect)(() => {
11924
12186
  setHighlightActive(false);
11925
12187
  if (!open || !highlightAppName) return;
11926
12188
  const t = setTimeout(() => setHighlightActive(true), highlightDelayMs);
@@ -11929,6 +12191,7 @@ function AppSearchDrawer({
11929
12191
  const drawerWidth = `min(${width}px, 100vw)`;
11930
12192
  const drawerMinWidth = `min(${minWidth}px, 100vw)`;
11931
12193
  const drawerMaxWidth = `min(${maxWidth}px, 100vw)`;
12194
+ const drawerZIndex = useDrawerLayer(open);
11932
12195
  const handleClose = () => {
11933
12196
  setDetailAppName(null);
11934
12197
  setDetailAppId(null);
@@ -12034,7 +12297,7 @@ function AppSearchDrawer({
12034
12297
  },
12035
12298
  ...{ PaperProps: drawerPaperProps },
12036
12299
  sx: {
12037
- zIndex: 9999,
12300
+ zIndex: drawerZIndex,
12038
12301
  "& .MuiDrawer-paper": {
12039
12302
  boxSizing: "border-box",
12040
12303
  width: `${drawerWidth} !important`,
@@ -12510,6 +12773,8 @@ var AiAgentPromptsEditor = ({
12510
12773
  prompts,
12511
12774
  apps,
12512
12775
  readOnly = false,
12776
+ skillLabel,
12777
+ isBuiltInApp,
12513
12778
  onChangePrompt,
12514
12779
  onRemovePrompt,
12515
12780
  onAddPrompt,
@@ -12597,16 +12862,44 @@ var AiAgentPromptsEditor = ({
12597
12862
  ] }),
12598
12863
  /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_material18.Box, { sx: { display: "flex", alignItems: "center", gap: 1, flexWrap: "wrap" }, children: [
12599
12864
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
12600
- import_material18.Typography,
12865
+ import_material18.Tooltip,
12601
12866
  {
12602
- sx: {
12603
- fontSize: "0.65rem",
12604
- fontWeight: 600,
12605
- color: "hsl(var(--muted-foreground))",
12606
- textTransform: "uppercase",
12607
- letterSpacing: "0.05em"
12608
- },
12609
- children: "Allowed apps"
12867
+ 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.",
12868
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_material18.Box, { sx: { display: "inline-flex", alignItems: "center", gap: 0.75 }, children: [
12869
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
12870
+ import_material18.Typography,
12871
+ {
12872
+ sx: {
12873
+ fontSize: "0.65rem",
12874
+ fontWeight: 600,
12875
+ color: "hsl(var(--muted-foreground))",
12876
+ textTransform: "uppercase",
12877
+ letterSpacing: "0.05em"
12878
+ },
12879
+ children: "Allowed apps"
12880
+ }
12881
+ ),
12882
+ skillLabel && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
12883
+ import_material18.Typography,
12884
+ {
12885
+ component: "span",
12886
+ sx: {
12887
+ fontSize: "0.62rem",
12888
+ fontWeight: 600,
12889
+ color: "hsl(var(--primary))",
12890
+ bgcolor: "hsl(var(--primary) / 0.1)",
12891
+ px: 0.6,
12892
+ py: 0.1,
12893
+ borderRadius: 0.75,
12894
+ letterSpacing: "0.02em"
12895
+ },
12896
+ children: [
12897
+ skillLabel,
12898
+ " permissions"
12899
+ ]
12900
+ }
12901
+ )
12902
+ ] })
12610
12903
  }
12611
12904
  ),
12612
12905
  /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_material18.Box, { sx: { display: "flex", alignItems: "center", gap: 0.5, flexWrap: "wrap", flex: 1 }, children: [
@@ -12615,8 +12908,9 @@ var AiAgentPromptsEditor = ({
12615
12908
  const meta = resolveAppMeta(appKey);
12616
12909
  const displayName2 = meta.name;
12617
12910
  const img = meta.image || `https://shuffler.io/images/apps/${displayName2}.png`;
12911
+ const isBuiltIn = isBuiltInApp ? isBuiltInApp(appKey) : false;
12618
12912
  const clickable = !readOnly && !!onRemoveApp;
12619
- const tip = clickable ? `Remove ${displayName2.replace(/_/g, " ")}` : displayName2.replace(/_/g, " ");
12913
+ const tip = isBuiltIn ? `${displayName2.replace(/_/g, " ")} (Default built-in app for ${skillLabel || "skill"})` : clickable ? `Remove ${displayName2.replace(/_/g, " ")} (Assigned permission)` : displayName2.replace(/_/g, " ");
12620
12914
  return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_material18.Tooltip, { title: tip, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
12621
12915
  import_material18.IconButton,
12622
12916
  {
@@ -12626,12 +12920,12 @@ var AiAgentPromptsEditor = ({
12626
12920
  sx: {
12627
12921
  width: 26,
12628
12922
  height: 26,
12629
- border: "1px solid hsl(var(--severity-low) / 0.3)",
12630
- bgcolor: "hsl(var(--severity-low) / 0.1)",
12923
+ border: isBuiltIn ? "1px solid hsl(var(--primary) / 0.35)" : "1px solid hsl(var(--severity-low) / 0.3)",
12924
+ bgcolor: isBuiltIn ? "hsl(var(--primary) / 0.08)" : "hsl(var(--severity-low) / 0.1)",
12631
12925
  borderRadius: 1,
12632
12926
  "&.Mui-disabled": {
12633
12927
  opacity: 1,
12634
- bgcolor: "hsl(var(--severity-low) / 0.1)"
12928
+ bgcolor: isBuiltIn ? "hsl(var(--primary) / 0.08)" : "hsl(var(--severity-low) / 0.1)"
12635
12929
  },
12636
12930
  "&:hover": clickable ? {
12637
12931
  bgcolor: "hsl(var(--destructive) / 0.15)",
@@ -12650,7 +12944,7 @@ var AiAgentPromptsEditor = ({
12650
12944
  }
12651
12945
  ) }, appKey);
12652
12946
  }),
12653
- !readOnly && onAddAppRequested && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_material18.Tooltip, { title: "Add allowed app", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
12947
+ !readOnly && onAddAppRequested && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_material18.Tooltip, { title: skillLabel ? `Assign tools to ${skillLabel}` : "Add allowed app", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
12654
12948
  import_material18.IconButton,
12655
12949
  {
12656
12950
  size: "small",
@@ -12763,7 +13057,7 @@ function ShufflePipelinesBanner() {
12763
13057
  var ShufflePipelinesBanner_default = ShufflePipelinesBanner;
12764
13058
 
12765
13059
  // components/AgentUI.tsx
12766
- var import_react23 = __toESM(require("react"));
13060
+ var import_react24 = __toESM(require("react"));
12767
13061
  var import_react_dom = require("react-dom");
12768
13062
 
12769
13063
  // agentRunSync.ts
@@ -12818,7 +13112,7 @@ var subscribeLastOpenedAgentRun = (cb) => {
12818
13112
  var import_lucide_react15 = require("lucide-react");
12819
13113
 
12820
13114
  // ../Shuffle-Core/components/WorkflowRunExplorer.tsx
12821
- var import_react17 = __toESM(require("react"));
13115
+ var import_react18 = __toESM(require("react"));
12822
13116
  var import_material20 = require("@mui/material");
12823
13117
  var import_icons_material = require("@mui/icons-material");
12824
13118
 
@@ -13320,7 +13614,7 @@ function safeHandler(label, fn) {
13320
13614
  var safeHandler_default = safeHandler;
13321
13615
 
13322
13616
  // components/AgentPresets.tsx
13323
- var import_react18 = require("react");
13617
+ var import_react19 = require("react");
13324
13618
  var import_material21 = require("@mui/material");
13325
13619
  var import_lucide_react11 = require("lucide-react");
13326
13620
  var import_jsx_runtime25 = require("react/jsx-runtime");
@@ -13359,7 +13653,7 @@ var AGENT_PRESETS = [
13359
13653
  icon: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react11.ShieldAlert, { size: 16 }),
13360
13654
  enabled: true,
13361
13655
  tag: "Beta",
13362
- defaultApps: [{ name: "shuffle_incidents" }, { name: "shuffle_datastore" }]
13656
+ defaultApps: [{ name: "shuffle_incidents" }]
13363
13657
  },
13364
13658
  {
13365
13659
  id: "host-monitor-control",
@@ -13436,15 +13730,15 @@ var filterAgentPresets = (list, support) => {
13436
13730
  return list.map((p) => SUPPORT_ONLY_PRESET_IDS.includes(p.id) ? { ...p, enabled: false } : p);
13437
13731
  };
13438
13732
  var AgentPresets = ({ variant = "default", onSelectPreset, selectedPreset, onRemoveSelected, presets, chipRef, isSupport, sx, placement }) => {
13439
- const [anchorEl, setAnchorEl] = (0, import_react18.useState)(null);
13733
+ const [anchorEl, setAnchorEl] = (0, import_react19.useState)(null);
13440
13734
  const open = Boolean(anchorEl);
13441
- const [supportTick, setSupportTick] = (0, import_react18.useState)(0);
13442
- (0, import_react18.useEffect)(() => {
13735
+ const [supportTick, setSupportTick] = (0, import_react19.useState)(0);
13736
+ (0, import_react19.useEffect)(() => {
13443
13737
  const bump = () => setSupportTick((t) => t + 1);
13444
13738
  window.addEventListener("storage", bump);
13445
13739
  return () => window.removeEventListener("storage", bump);
13446
13740
  }, []);
13447
- const list = (0, import_react18.useMemo)(
13741
+ const list = (0, import_react19.useMemo)(
13448
13742
  () => filterAgentPresets(presets && presets.length > 0 ? presets : AGENT_PRESETS, isSupport),
13449
13743
  // eslint-disable-next-line react-hooks/exhaustive-deps
13450
13744
  [presets, supportTick, open, isSupport]
@@ -13552,8 +13846,8 @@ var AgentPresets = ({ variant = "default", onSelectPreset, selectedPreset, onRem
13552
13846
  ]
13553
13847
  }
13554
13848
  );
13555
- const [query, setQuery] = (0, import_react18.useState)("");
13556
- const filtered = (0, import_react18.useMemo)(() => {
13849
+ const [query, setQuery] = (0, import_react19.useState)("");
13850
+ const filtered = (0, import_react19.useMemo)(() => {
13557
13851
  const q = query.trim().toLowerCase();
13558
13852
  if (!q) return list;
13559
13853
  return list.filter(
@@ -13820,8 +14114,152 @@ var AgentPresets = ({ variant = "default", onSelectPreset, selectedPreset, onRem
13820
14114
  };
13821
14115
  var AgentPresets_default = AgentPresets;
13822
14116
 
14117
+ // ../lib/agentTools.ts
14118
+ var STORAGE_KEY3 = "agent_tools_config";
14119
+ var AGENT_TOOLS_CHANGED_EVENT = "agent-tools-changed";
14120
+ var DEFAULT_AGENT = "default";
14121
+ var DEFAULT_ACTION_TYPE = "timeline_reply";
14122
+ var getActiveOrgId = () => {
14123
+ if (typeof window === "undefined") return null;
14124
+ try {
14125
+ const raw = localStorage.getItem("shuffle_user_info") || localStorage.getItem("userinfo") || localStorage.getItem("user_info");
14126
+ if (!raw) return null;
14127
+ const parsed = JSON.parse(raw);
14128
+ return parsed?.active_org?.id || parsed?.org_id || parsed?.active_org_id || Array.isArray(parsed?.orgs) && parsed.orgs[0]?.id || parsed?.id || null;
14129
+ } catch {
14130
+ return null;
14131
+ }
14132
+ };
14133
+ var getStorageKey = (orgId) => {
14134
+ const resolved = orgId || getActiveOrgId();
14135
+ return resolved ? `${STORAGE_KEY3}_${resolved}` : STORAGE_KEY3;
14136
+ };
14137
+ var coerceTool = (raw) => {
14138
+ if (typeof raw === "string") {
14139
+ const trimmed = raw.trim();
14140
+ if (!trimmed) return null;
14141
+ return { name: trimmed, id: trimmed };
14142
+ }
14143
+ if (raw && typeof raw === "object") {
14144
+ const obj = raw;
14145
+ const name = typeof obj.name === "string" ? obj.name.trim() : "";
14146
+ const id = typeof obj.id === "string" && obj.id.trim() ? obj.id.trim() : name;
14147
+ if (!name) return null;
14148
+ return { name, id };
14149
+ }
14150
+ return null;
14151
+ };
14152
+ var sanitize2 = (parsed) => {
14153
+ let target = parsed;
14154
+ if (target && typeof target === "object" && !Array.isArray(target)) {
14155
+ const obj = target;
14156
+ if (Array.isArray(obj.entries)) {
14157
+ target = obj.entries;
14158
+ }
14159
+ }
14160
+ if (!Array.isArray(target)) return [];
14161
+ return target.filter((e) => e && typeof e.agent === "string" && typeof e.actionType === "string" && Array.isArray(e.tools)).map((e) => ({
14162
+ agent: e.agent,
14163
+ actionType: e.actionType,
14164
+ tools: e.tools.map(coerceTool).filter((t) => !!t),
14165
+ updatedAt: typeof e.updatedAt === "number" ? e.updatedAt : void 0
14166
+ }));
14167
+ };
14168
+ var extractUpdatedAt = (parsed) => {
14169
+ if (parsed && typeof parsed === "object") {
14170
+ const obj = parsed;
14171
+ if (typeof obj.updatedAt === "number") return obj.updatedAt;
14172
+ }
14173
+ return 0;
14174
+ };
14175
+ var readCacheRecord = () => {
14176
+ if (typeof window === "undefined") return { entries: [], updatedAt: 0 };
14177
+ try {
14178
+ const key = getStorageKey();
14179
+ let raw = localStorage.getItem(key);
14180
+ let parsed = null;
14181
+ let entries = [];
14182
+ let updatedAt = 0;
14183
+ if (raw) {
14184
+ try {
14185
+ parsed = JSON.parse(raw);
14186
+ entries = sanitize2(parsed);
14187
+ updatedAt = extractUpdatedAt(parsed) || entries.reduce((max, e) => Math.max(max, e.updatedAt || 0), 0);
14188
+ } catch {
14189
+ }
14190
+ }
14191
+ if (entries.length === 0 || entries.every((e) => e.tools.length === 0)) {
14192
+ if (key !== STORAGE_KEY3) {
14193
+ const fallbackRaw = localStorage.getItem(STORAGE_KEY3);
14194
+ if (fallbackRaw) {
14195
+ try {
14196
+ const fallbackParsed = JSON.parse(fallbackRaw);
14197
+ const fallbackEntries = sanitize2(fallbackParsed);
14198
+ if (fallbackEntries.some((e) => e.tools.length > 0)) {
14199
+ entries = fallbackEntries;
14200
+ updatedAt = extractUpdatedAt(fallbackParsed) || fallbackEntries.reduce((max, e) => Math.max(max, e.updatedAt || 0), 0) || Date.now();
14201
+ writeCache(entries, updatedAt);
14202
+ }
14203
+ } catch {
14204
+ }
14205
+ }
14206
+ }
14207
+ }
14208
+ return { entries, updatedAt };
14209
+ } catch {
14210
+ return { entries: [], updatedAt: 0 };
14211
+ }
14212
+ };
14213
+ var readAll = () => readCacheRecord().entries;
14214
+ var writeCache = (entries, explicitUpdatedAt) => {
14215
+ if (typeof window === "undefined") return;
14216
+ try {
14217
+ const updatedAt = explicitUpdatedAt ?? Date.now();
14218
+ const payload = {
14219
+ version: 1,
14220
+ updatedAt,
14221
+ entries
14222
+ };
14223
+ const serialized = JSON.stringify(payload);
14224
+ const orgKey = getStorageKey();
14225
+ localStorage.setItem(orgKey, serialized);
14226
+ if (orgKey !== STORAGE_KEY3) {
14227
+ localStorage.setItem(STORAGE_KEY3, serialized);
14228
+ }
14229
+ window.dispatchEvent(
14230
+ new CustomEvent(AGENT_TOOLS_CHANGED_EVENT, { detail: { updatedAt, entries } })
14231
+ );
14232
+ } catch {
14233
+ }
14234
+ };
14235
+ var getAgentTools = (agent = DEFAULT_AGENT, actionType = DEFAULT_ACTION_TYPE) => {
14236
+ const all = readAll();
14237
+ const entry = all.find((e) => e.agent === agent && e.actionType === actionType);
14238
+ if (entry && entry.tools && entry.tools.length > 0) {
14239
+ return entry.tools;
14240
+ }
14241
+ if (agent === "incident-handler" || agent === "incident-response" || agent === DEFAULT_AGENT) {
14242
+ const found = all.find(
14243
+ (e) => (e.agent === "incident-handler" || e.agent === "incident-response" || e.agent === DEFAULT_AGENT) && e.actionType === actionType && e.tools && e.tools.length > 0
14244
+ );
14245
+ if (found?.tools && found.tools.length > 0) return found.tools;
14246
+ }
14247
+ return [];
14248
+ };
14249
+ var getToolsForSkill = (skillOrPresetId) => {
14250
+ const normalized = (skillOrPresetId || "").toLowerCase().trim();
14251
+ if (normalized === "incident-handler" || normalized === "incident-response" || normalized === "default") {
14252
+ const ih = getAgentTools("incident-handler");
14253
+ if (ih.length > 0) return ih;
14254
+ const ir = getAgentTools("incident-response");
14255
+ if (ir.length > 0) return ir;
14256
+ return getAgentTools(DEFAULT_AGENT);
14257
+ }
14258
+ return getAgentTools(normalized);
14259
+ };
14260
+
13823
14261
  // useAgentPromptPrefix.ts
13824
- var import_react19 = require("react");
14262
+ var import_react20 = require("react");
13825
14263
  var AGENT_PROMPT_PREFIX_CATEGORY = "agent-prompt-prefix";
13826
14264
  var DEFAULT_AGENT_PROMPT_PREFIX = "";
13827
14265
  var decodePrompt = (raw) => {
@@ -13853,11 +14291,11 @@ var decodePrompt = (raw) => {
13853
14291
  var useAgentPromptPrefix = (options = {}) => {
13854
14292
  const { userId, defaultPrompt = DEFAULT_AGENT_PROMPT_PREFIX, persist = true } = options;
13855
14293
  const key = userId || "default";
13856
- const [prompt, setPrompt] = (0, import_react19.useState)(defaultPrompt);
13857
- const [hasFetched, setHasFetched] = (0, import_react19.useState)(false);
13858
- const [isSaving, setIsSaving] = (0, import_react19.useState)(false);
13859
- const fetchedForKey = (0, import_react19.useRef)(null);
13860
- (0, import_react19.useEffect)(() => {
14294
+ const [prompt, setPrompt] = (0, import_react20.useState)(defaultPrompt);
14295
+ const [hasFetched, setHasFetched] = (0, import_react20.useState)(false);
14296
+ const [isSaving, setIsSaving] = (0, import_react20.useState)(false);
14297
+ const fetchedForKey = (0, import_react20.useRef)(null);
14298
+ (0, import_react20.useEffect)(() => {
13861
14299
  if (!persist) {
13862
14300
  setHasFetched(true);
13863
14301
  return;
@@ -13884,7 +14322,7 @@ var useAgentPromptPrefix = (options = {}) => {
13884
14322
  cancelled = true;
13885
14323
  };
13886
14324
  }, [key, persist]);
13887
- const savePrompt = (0, import_react19.useCallback)(async (next) => {
14325
+ const savePrompt = (0, import_react20.useCallback)(async (next) => {
13888
14326
  const prev = prompt;
13889
14327
  setPrompt(next);
13890
14328
  if (!persist) return true;
@@ -14040,6 +14478,9 @@ var runAgent = async (request) => {
14040
14478
  if (request.incidentId) {
14041
14479
  input.incident_id = request.incidentId;
14042
14480
  }
14481
+ if (request.incidentContext) {
14482
+ input.incident_context = request.incidentContext;
14483
+ }
14043
14484
  if (request.vulnerabilityId) {
14044
14485
  input.vulnerability_id = request.vulnerabilityId;
14045
14486
  }
@@ -14318,16 +14759,143 @@ var getCachedGroupDocs = (groupId, folder) => {
14318
14759
  }));
14319
14760
  };
14320
14761
 
14762
+ // ../lib/incidentPromptContext.ts
14763
+ var GLOBAL_INCIDENT_KEY = "__shuffleActiveIncidentContext";
14764
+ var getGlobalScope = () => {
14765
+ if (typeof globalThis !== "undefined") return globalThis;
14766
+ if (typeof window !== "undefined") return window;
14767
+ if (typeof global !== "undefined") return global;
14768
+ return null;
14769
+ };
14770
+ var getActiveIncidentPromptContext = () => {
14771
+ const scope = getGlobalScope();
14772
+ if (!scope) return null;
14773
+ const info = scope[GLOBAL_INCIDENT_KEY];
14774
+ if (info && typeof info === "object") {
14775
+ return info;
14776
+ }
14777
+ return null;
14778
+ };
14779
+ var INCIDENT_PROMPT_DELIMITER_START = "=== INCIDENT CONTEXT ===";
14780
+ var INCIDENT_PROMPT_DELIMITER_END = "=== END INCIDENT CONTEXT ===";
14781
+ var formatObservableType = (type) => {
14782
+ if (!type) return "Indicator";
14783
+ const clean = type.toLowerCase().trim();
14784
+ switch (clean) {
14785
+ case "ip":
14786
+ case "ipv4":
14787
+ case "ip_address":
14788
+ return "IPv4";
14789
+ case "ipv6":
14790
+ return "IPv6";
14791
+ case "hash":
14792
+ case "sha256":
14793
+ case "file_hash":
14794
+ return "SHA256";
14795
+ case "md5":
14796
+ return "MD5";
14797
+ case "sha1":
14798
+ return "SHA1";
14799
+ case "hostname":
14800
+ case "host":
14801
+ case "endpoint":
14802
+ return "Hostname";
14803
+ case "domain":
14804
+ return "Domain";
14805
+ case "url":
14806
+ return "URL";
14807
+ case "user":
14808
+ case "username":
14809
+ case "account":
14810
+ return "User";
14811
+ case "email":
14812
+ return "Email";
14813
+ case "process":
14814
+ case "process_name":
14815
+ return "Process";
14816
+ case "file":
14817
+ case "filename":
14818
+ return "File";
14819
+ default:
14820
+ return type.charAt(0).toUpperCase() + type.slice(1);
14821
+ }
14822
+ };
14823
+ var isIncidentInjectedPrompt = (prompt) => {
14824
+ if (!prompt || typeof prompt !== "string") return false;
14825
+ return prompt.includes(INCIDENT_PROMPT_DELIMITER_START) || prompt.includes("OPERATIONAL DIRECTIVES:") || prompt.includes("INCIDENT OBSERVABLES / IOCs:");
14826
+ };
14827
+ var extractCleanIncidentPrompt = (prompt) => {
14828
+ if (!prompt || typeof prompt !== "string") return "";
14829
+ const trimmed = prompt.trim();
14830
+ const taskMatch = trimmed.match(/TASK TO EXECUTE:\s*\n\s*-\s*Task:\s*([^\n]+)/i);
14831
+ if (taskMatch && taskMatch[1]?.trim()) {
14832
+ return `Task: ${taskMatch[1].trim()}`;
14833
+ }
14834
+ const legacyMatch = trimmed.match(/\n\s*Task:\s*([^\n]+)/i);
14835
+ if (legacyMatch && legacyMatch[1]?.trim()) {
14836
+ return `Task: ${legacyMatch[1].trim()}`;
14837
+ }
14838
+ if (trimmed.includes(INCIDENT_PROMPT_DELIMITER_START)) {
14839
+ const before = trimmed.split(INCIDENT_PROMPT_DELIMITER_START)[0]?.trim();
14840
+ if (before) return before;
14841
+ }
14842
+ return trimmed;
14843
+ };
14844
+ var composeIncidentPromptInput = (rawInput, context) => {
14845
+ if (!rawInput || typeof rawInput !== "string") return "";
14846
+ const trimmed = rawInput.trim();
14847
+ if (isIncidentInjectedPrompt(trimmed)) {
14848
+ return trimmed;
14849
+ }
14850
+ const ctx = context || getActiveIncidentPromptContext();
14851
+ if (!ctx || !ctx.id) {
14852
+ return trimmed;
14853
+ }
14854
+ const incidentRef = ctx.id ? `#${ctx.id}` : "";
14855
+ const incidentTitle = ctx.title?.trim() || "Incident";
14856
+ const severity = ctx.severity || "Medium";
14857
+ const status = ctx.status || "In Progress";
14858
+ const description = ctx.description?.trim() || "No description provided.";
14859
+ const seenObservables = /* @__PURE__ */ new Set();
14860
+ const formattedObservables = [];
14861
+ if (Array.isArray(ctx.observables)) {
14862
+ for (const obs of ctx.observables) {
14863
+ if (!obs || obs.archived || !obs.value?.trim()) continue;
14864
+ const val = obs.value.trim();
14865
+ const typeLabel = formatObservableType(obs.type);
14866
+ const key = `${typeLabel.toLowerCase()}:${val.toLowerCase()}`;
14867
+ if (seenObservables.has(key)) continue;
14868
+ seenObservables.add(key);
14869
+ formattedObservables.push(`- ${typeLabel}: ${val}`);
14870
+ }
14871
+ }
14872
+ const observablesBlock = formattedObservables.length > 0 ? formattedObservables.slice(0, 50).join("\n") : "- None recorded yet";
14873
+ return `${trimmed}
14874
+
14875
+ ${INCIDENT_PROMPT_DELIMITER_START}
14876
+ INCIDENT CONTEXT:
14877
+ - Incident: ${incidentRef} ("${incidentTitle}")
14878
+ - Severity: ${severity} | Status: ${status}
14879
+ - Summary: ${description}
14880
+
14881
+ INCIDENT OBSERVABLES / IOCs:
14882
+ ${observablesBlock}
14883
+ ${INCIDENT_PROMPT_DELIMITER_END}
14884
+
14885
+ DIRECTIVES:
14886
+ - Relevant incident details and observables are provided above. Do not call "get_incident" unless raw external logs are required.`;
14887
+ };
14888
+
14321
14889
  // ../lib/docsPromptContext.ts
14322
14890
  var GLOBAL_DOC_KEY = "__shuffleActiveDocInfo";
14323
- var getGlobalScope = () => {
14891
+ var getGlobalScope2 = () => {
14324
14892
  if (typeof globalThis !== "undefined") return globalThis;
14325
14893
  if (typeof window !== "undefined") return window;
14326
14894
  if (typeof global !== "undefined") return global;
14327
14895
  return null;
14328
14896
  };
14329
14897
  var getActiveDocPromptContext = () => {
14330
- const scope = getGlobalScope();
14898
+ const scope = getGlobalScope2();
14331
14899
  if (!scope) return null;
14332
14900
  const info = scope[GLOBAL_DOC_KEY];
14333
14901
  if (info && typeof info === "object") {
@@ -14368,6 +14936,9 @@ var isDocInjectedPrompt = (prompt) => {
14368
14936
  var extractCleanDisplayPrompt = (prompt) => {
14369
14937
  if (!prompt || typeof prompt !== "string") return "";
14370
14938
  const trimmed = prompt.trim();
14939
+ if (isIncidentInjectedPrompt(trimmed)) {
14940
+ return extractCleanIncidentPrompt(trimmed);
14941
+ }
14371
14942
  if (!isDocInjectedPrompt(trimmed)) return trimmed;
14372
14943
  if (trimmed.includes(DOC_PROMPT_DELIMITER_END)) {
14373
14944
  const parts = trimmed.split(DOC_PROMPT_DELIMITER_END);
@@ -14407,7 +14978,7 @@ var composeDocPromptInput = (userQuestion, pathname, fallbackTitle, overrideDocI
14407
14978
  return trimmedQuestion;
14408
14979
  }
14409
14980
  const activeDoc = overrideDocInfo ?? getActiveDocPromptContext();
14410
- const rawTitle = (activeDoc?.title || fallbackTitle || getGlobalScope()?.__shuffleActiveEntityTitle || "Shuffle documentation").trim();
14981
+ const rawTitle = (activeDoc?.title || fallbackTitle || getGlobalScope2()?.__shuffleActiveEntityTitle || "Shuffle documentation").trim();
14411
14982
  const title = normalizeDocPromptTitle(rawTitle);
14412
14983
  const groupLabel = activeDoc?.groupLabel;
14413
14984
  const groupId = activeDoc?.groupId;
@@ -14473,7 +15044,7 @@ ${trimmedQuestion}`;
14473
15044
  };
14474
15045
 
14475
15046
  // ../Shuffle-Core/views/monitors/ActionOutputView.tsx
14476
- var import_react20 = require("react");
15047
+ var import_react21 = require("react");
14477
15048
  var import_jsx_runtime26 = require("react/jsx-runtime");
14478
15049
  var IMAGE_SIGNATURES = [
14479
15050
  { prefix: "iVBORw0KGgo", mime: "image/png" },
@@ -14559,10 +15130,10 @@ var detectImage = (raw) => {
14559
15130
  };
14560
15131
  var MAX_TEXT_CHARS = 4e3;
14561
15132
  var ActionOutputView = ({ output, className }) => {
14562
- const detected = (0, import_react20.useMemo)(() => detectImage(output), [output]);
14563
- const [zoomed, setZoomed] = (0, import_react20.useState)(false);
14564
- const [showFull, setShowFull] = (0, import_react20.useState)(false);
14565
- (0, import_react20.useEffect)(() => {
15133
+ const detected = (0, import_react21.useMemo)(() => detectImage(output), [output]);
15134
+ const [zoomed, setZoomed] = (0, import_react21.useState)(false);
15135
+ const [showFull, setShowFull] = (0, import_react21.useState)(false);
15136
+ (0, import_react21.useEffect)(() => {
14566
15137
  if (!zoomed) return;
14567
15138
  const onKey = (e) => {
14568
15139
  if (e.key === "Escape") {
@@ -15573,17 +16144,25 @@ var extractDecisionIndex = (path) => {
15573
16144
  };
15574
16145
  var isAiAuthText = (text2) => {
15575
16146
  if (!text2 || typeof text2 !== "string") return false;
15576
- const lower = text2.toLowerCase();
15577
- 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(
15578
- lower
15579
- ) || /check\s+your\s+ai\s+credentials/.test(lower);
15580
- if (!hasAuthSignal) return false;
15581
- 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(
15582
- lower
15583
- ) || /error\s+from\s+['"][^'"]*(openai|anthropic|mistral|groq|deepseek|together|openrouter|googleapis|ollama|lmstudio)/.test(
15584
- lower
15585
- ) || /incorrect\s+api\s+key\s+provided/.test(lower);
15586
- return Boolean(hasAiSignal);
16147
+ const trimmed = text2.trim();
16148
+ if (!trimmed) return false;
16149
+ const checkChunk = (chunk) => {
16150
+ const lower = chunk.toLowerCase();
16151
+ 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(
16152
+ lower
16153
+ ) || /check\s+your\s+ai\s+credentials/.test(lower);
16154
+ if (!hasAuthSignal) return false;
16155
+ 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(
16156
+ lower
16157
+ ) || /error\s+from\s+['"][^'"]*(openai|anthropic|mistral|groq|deepseek|together|openrouter|generativelanguage|aiplatform|gemini|ollama|lmstudio)/.test(
16158
+ lower
16159
+ ) || /incorrect\s+api\s+key\s+provided/.test(lower);
16160
+ return Boolean(hasAiSignal);
16161
+ };
16162
+ if (trimmed.includes("\n")) {
16163
+ return trimmed.split(/\r?\n/).some((line) => checkChunk(line));
16164
+ }
16165
+ return checkChunk(trimmed);
15587
16166
  };
15588
16167
  var hasOutputWarning = (run) => {
15589
16168
  return diagnoseOutputWarning(run) !== null;
@@ -15617,8 +16196,15 @@ var trimEvidenceValue = (v, max = 180) => {
15617
16196
  };
15618
16197
  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/;
15619
16198
  var isSentenceLike = (v) => /[a-z]/i.test(v) && v.trim().split(/\s+/).length > 1;
16199
+ var hasProducedDecisions = (run, parsed) => {
16200
+ const parsedDecisions = parsed && typeof parsed === "object" ? parsed.decisions : null;
16201
+ if (Array.isArray(parsedDecisions) && parsedDecisions.length > 0) return true;
16202
+ const directDecisions = run?.decisions;
16203
+ return Array.isArray(directDecisions) && directDecisions.length > 0;
16204
+ };
15620
16205
  var diagnoseOutputWarning = (run) => {
15621
16206
  const { parsed, raw } = parseRunResult(run);
16207
+ const producedDecisions = hasProducedDecisions(run, parsed);
15622
16208
  const tokenLimitMatch = (() => {
15623
16209
  const candidates = [];
15624
16210
  if (parsed && typeof parsed === "object") {
@@ -15653,7 +16239,7 @@ var diagnoseOutputWarning = (run) => {
15653
16239
  const category = String(last.category || "").toLowerCase();
15654
16240
  if (["finish", "finalise"].includes(action) || ["finish", "finalise"].includes(category)) {
15655
16241
  if (last.success === false || last.status === "FAILED") return false;
15656
- if (isAiAuthText(last.reason) || isAiAuthText(last.output) || isAiAuthText(last.details?.output)) return false;
16242
+ if (isAiAuthText(last.reason)) return false;
15657
16243
  const reasonStr = String(last.reason || "").toLowerCase();
15658
16244
  if (reasonStr.startsWith("failed to") || reasonStr.includes("error,")) return false;
15659
16245
  return true;
@@ -15663,28 +16249,22 @@ var diagnoseOutputWarning = (run) => {
15663
16249
  return false;
15664
16250
  })();
15665
16251
  const aiAuthMatch = (() => {
16252
+ if (producedDecisions) return null;
16253
+ if (isFinished && (!parsed?.error && parsed?.success !== false)) return null;
15666
16254
  if (isFinished && hasSuccessfulFinish) return null;
15667
16255
  const candidates = [];
15668
16256
  if (parsed && typeof parsed === "object") {
15669
16257
  if (typeof parsed.error === "string") candidates.push(parsed.error);
15670
- if (typeof parsed.reason === "string") candidates.push(parsed.reason);
15671
- if (typeof parsed.message === "string") candidates.push(parsed.message);
15672
- if (typeof parsed.output === "string") candidates.push(parsed.output);
15673
- if (Array.isArray(parsed.decisions)) {
16258
+ if (!isFinished && typeof parsed.reason === "string") candidates.push(parsed.reason);
16259
+ if (!isFinished && typeof parsed.message === "string") candidates.push(parsed.message);
16260
+ if (Array.isArray(parsed.decisions) && !isFinished) {
15674
16261
  for (const d of parsed.decisions) {
15675
16262
  if (typeof d?.run_details?.error === "string") candidates.push(d.run_details.error);
15676
- if (typeof d?.reason === "string") candidates.push(d.reason);
15677
- if (typeof d?.run_details?.result === "string") candidates.push(d.run_details.result);
15678
- if (typeof d?.output === "string") candidates.push(d.output);
15679
- if (Array.isArray(d?.fields)) {
15680
- for (const f of d.fields) {
15681
- if (typeof f?.value === "string") candidates.push(f.value);
15682
- }
15683
- }
16263
+ if (d?.status === "FAILED" && typeof d?.reason === "string") candidates.push(d.reason);
15684
16264
  }
15685
16265
  }
15686
16266
  }
15687
- if (raw) {
16267
+ if (raw && !isFinished) {
15688
16268
  candidates.push(raw);
15689
16269
  }
15690
16270
  return candidates.find((v) => isAiAuthText(v)) || null;
@@ -15799,7 +16379,7 @@ var diagnoseOutputWarning = (run) => {
15799
16379
  const dedup = ev.filter((e) => e.path !== statusEvidence.path);
15800
16380
  return [statusEvidence, ...dedup].slice(0, 3);
15801
16381
  };
15802
- if (isAiAuthText(errorHaystackLower) || isAiAuthText(raw)) {
16382
+ if (!producedDecisions && !isFinished && (isAiAuthText(errorHaystackLower) || isAiAuthText(raw))) {
15803
16383
  const ev = findEvidenceByRegex(
15804
16384
  /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/
15805
16385
  );
@@ -15938,39 +16518,35 @@ var diagnoseOutputWarning = (run) => {
15938
16518
  return null;
15939
16519
  };
15940
16520
  var isAiAuthFailure = (run, extraText) => {
16521
+ if (!run) return isAiAuthText(extraText);
16522
+ const { parsed } = parseRunResult(run);
16523
+ if (hasProducedDecisions(run, parsed)) return false;
15941
16524
  if (isAiAuthText(extraText)) return true;
15942
- if (!run) return false;
16525
+ const status = (run.status || "").toUpperCase();
16526
+ const isFinished = status === "FINISHED" || status === "SUCCESS";
16527
+ if (isFinished) {
16528
+ const anyRun2 = run;
16529
+ if (typeof anyRun2.error === "string" && isAiAuthText(anyRun2.error)) return true;
16530
+ return false;
16531
+ }
15943
16532
  const diagnosis = diagnoseOutputWarning(run);
15944
16533
  if (diagnosis?.kind === "ai_auth" || diagnosis?.isAiAuth) return true;
15945
16534
  const fail = getFailureInfo(run);
15946
16535
  if (fail && isAiAuthText(fail.reason)) return true;
15947
16536
  const anyRun = run;
15948
- if (typeof anyRun.result === "string" && isAiAuthText(anyRun.result)) return true;
15949
- if (typeof anyRun.output === "string" && isAiAuthText(anyRun.output)) return true;
15950
16537
  if (typeof anyRun.error === "string" && isAiAuthText(anyRun.error)) return true;
15951
16538
  if (Array.isArray(run.results)) {
15952
16539
  for (const r of run.results) {
15953
- if (typeof r?.result === "string" && isAiAuthText(r.result)) return true;
15954
16540
  if (typeof r?.error === "string" && isAiAuthText(r.error)) return true;
15955
16541
  }
15956
16542
  }
15957
16543
  const decisions = anyRun?.decisions;
15958
16544
  if (Array.isArray(decisions)) {
15959
16545
  for (const d of decisions) {
15960
- if (isAiAuthText(d?.reason)) return true;
15961
- if (typeof d?.output === "string" && isAiAuthText(d.output)) return true;
15962
16546
  if (typeof d?.run_details?.error === "string" && isAiAuthText(d.run_details.error)) return true;
15963
- if (typeof d?.run_details?.result === "string" && isAiAuthText(d.run_details.result)) return true;
15964
- if (Array.isArray(d?.fields)) {
15965
- for (const f of d.fields) {
15966
- if (isAiAuthText(f?.value)) return true;
15967
- }
15968
- }
16547
+ if (d?.status === "FAILED" && typeof d?.reason === "string" && isAiAuthText(d.reason)) return true;
15969
16548
  }
15970
16549
  }
15971
- const status = (run.status || "").toUpperCase();
15972
- const isFinished = status === "FINISHED";
15973
- if (isFinished) return false;
15974
16550
  return false;
15975
16551
  };
15976
16552
 
@@ -16064,7 +16640,7 @@ var AgentDiagnosisCtas = ({ diagnosis, compact = false, tone = "medium" }) => {
16064
16640
  var AgentDiagnosisCtas_default = AgentDiagnosisCtas;
16065
16641
 
16066
16642
  // components/AgentRunDiagnosisBanner.tsx
16067
- var import_react21 = require("react");
16643
+ var import_react22 = require("react");
16068
16644
  var import_jsx_runtime28 = require("react/jsx-runtime");
16069
16645
  var DISMISS_PREFIX = "agent-diagnosis-dismissed::";
16070
16646
  var readDismissed = (key) => {
@@ -16083,13 +16659,13 @@ var writeDismissed = (key) => {
16083
16659
  }
16084
16660
  };
16085
16661
  var AgentRunDiagnosisBanner = ({ run, sx, onJumpToEvidence, onFocusContinue, executionId }) => {
16086
- const dismissKey = (0, import_react21.useMemo)(() => {
16662
+ const dismissKey = (0, import_react22.useMemo)(() => {
16087
16663
  if (executionId) return executionId;
16088
16664
  const fromRun = run?.execution_id;
16089
16665
  return typeof fromRun === "string" && fromRun ? fromRun : null;
16090
16666
  }, [executionId, run]);
16091
- const [dismissed, setDismissed] = (0, import_react21.useState)(() => readDismissed(dismissKey));
16092
- (0, import_react21.useEffect)(() => {
16667
+ const [dismissed, setDismissed] = (0, import_react22.useState)(() => readDismissed(dismissKey));
16668
+ (0, import_react22.useEffect)(() => {
16093
16669
  setDismissed(readDismissed(dismissKey));
16094
16670
  }, [dismissKey]);
16095
16671
  if (!run || dismissed) return null;
@@ -16386,7 +16962,7 @@ var AiAuthSuggestion = ({
16386
16962
  var AiAuthSuggestion_default = AiAuthSuggestion;
16387
16963
 
16388
16964
  // components/AgentAttachmentsButton.tsx
16389
- var import_react22 = require("react");
16965
+ var import_react23 = require("react");
16390
16966
  var import_material25 = require("@mui/material");
16391
16967
  var import_lucide_react14 = require("lucide-react");
16392
16968
  var import_jsx_runtime30 = require("react/jsx-runtime");
@@ -16397,9 +16973,9 @@ var toSrc = (url) => {
16397
16973
  return `data:image/png;base64,${s.replace(/\s+/g, "")}`;
16398
16974
  };
16399
16975
  var AgentAttachmentsButton = ({ attachments }) => {
16400
- const [anchorEl, setAnchorEl] = (0, import_react22.useState)(null);
16401
- const [zoomed, setZoomed] = (0, import_react22.useState)(null);
16402
- (0, import_react22.useEffect)(() => {
16976
+ const [anchorEl, setAnchorEl] = (0, import_react23.useState)(null);
16977
+ const [zoomed, setZoomed] = (0, import_react23.useState)(null);
16978
+ (0, import_react23.useEffect)(() => {
16403
16979
  if (!zoomed) return;
16404
16980
  const onKey = (e) => {
16405
16981
  if (e.key === "Escape") {
@@ -17059,6 +17635,7 @@ var DEFAULT_AGENT_CONTEXT_RULES = [
17059
17635
  const cleanId = formatEntityDisplayId(params.id);
17060
17636
  return `Investigate incident ${cleanId} and recommend next steps: `;
17061
17637
  },
17638
+ composeInput: (raw) => composeIncidentPromptInput(raw),
17062
17639
  placeholder: "Ask about this incident, triage observables, or correlate...",
17063
17640
  getStorageKey: (params) => `incident_${params.id}`,
17064
17641
  description: "Focused on the currently viewed incident with Shuffle Incidents MCP"
@@ -17083,6 +17660,7 @@ var DEFAULT_AGENT_CONTEXT_RULES = [
17083
17660
  const cleanId = formatEntityDisplayId(params.id);
17084
17661
  return `Investigate incident ${cleanId} and recommend next steps: `;
17085
17662
  },
17663
+ composeInput: (raw) => composeIncidentPromptInput(raw),
17086
17664
  placeholder: "Ask about this incident, triage observables, or correlate...",
17087
17665
  getStorageKey: (params) => `incident_${params.id}`,
17088
17666
  description: "Focused on the currently viewed incident with Shuffle Incidents MCP"
@@ -17094,6 +17672,7 @@ var DEFAULT_AGENT_CONTEXT_RULES = [
17094
17672
  defaultApps: [{ name: "shuffle_incidents" }],
17095
17673
  defaultPresetId: "incident-response",
17096
17674
  sourceCategory: "incidents",
17675
+ isBeta: true,
17097
17676
  title: (params, _, entityOverride) => {
17098
17677
  const cleanId = formatEntityDisplayId(params.id);
17099
17678
  const entity = entityOverride || getActivePageEntityName();
@@ -17104,6 +17683,7 @@ var DEFAULT_AGENT_CONTEXT_RULES = [
17104
17683
  const cleanId = formatEntityDisplayId(params.id);
17105
17684
  return `Investigate case ${cleanId} and recommend next steps: `;
17106
17685
  },
17686
+ composeInput: (raw) => composeIncidentPromptInput(raw),
17107
17687
  placeholder: "Review case evidence, correlate events, or recommend response actions...",
17108
17688
  getStorageKey: (params) => `case_${params.id}`,
17109
17689
  description: "Focused on the currently viewed case with Shuffle Incidents MCP"
@@ -17115,6 +17695,7 @@ var DEFAULT_AGENT_CONTEXT_RULES = [
17115
17695
  defaultApps: [{ name: "shuffle_incidents" }],
17116
17696
  defaultPresetId: "incident-response",
17117
17697
  sourceCategory: "incidents",
17698
+ isBeta: true,
17118
17699
  title: (params, _, entityOverride) => {
17119
17700
  const cleanId = formatEntityDisplayId(params.id);
17120
17701
  const entity = entityOverride || getActivePageEntityName();
@@ -17136,6 +17717,7 @@ var DEFAULT_AGENT_CONTEXT_RULES = [
17136
17717
  defaultApps: [{ name: "shuffle_incidents" }],
17137
17718
  defaultPresetId: "incident-response",
17138
17719
  sourceCategory: "incidents",
17720
+ isBeta: true,
17139
17721
  title: (params, _, entityOverride) => {
17140
17722
  const cleanId = formatEntityDisplayId(params.id);
17141
17723
  const entity = entityOverride || getActivePageEntityName();
@@ -17157,6 +17739,7 @@ var DEFAULT_AGENT_CONTEXT_RULES = [
17157
17739
  defaultApps: [{ name: "shuffle_incidents" }],
17158
17740
  defaultPresetId: "incident-response",
17159
17741
  sourceCategory: "incidents",
17742
+ isBeta: true,
17160
17743
  title: "How can we help handle incidents?",
17161
17744
  subtitle: "Shuffle Incidents MCP",
17162
17745
  defaultPrompt: "Investigate this incident and recommend next steps: ",
@@ -17171,6 +17754,7 @@ var DEFAULT_AGENT_CONTEXT_RULES = [
17171
17754
  defaultApps: [{ name: "shuffle_incidents" }],
17172
17755
  defaultPresetId: "incident-response",
17173
17756
  sourceCategory: "incidents",
17757
+ isBeta: true,
17174
17758
  title: "How can we help handle cases?",
17175
17759
  subtitle: "Shuffle Incidents MCP",
17176
17760
  defaultPrompt: "Investigate this case and recommend next steps: ",
@@ -17185,6 +17769,7 @@ var DEFAULT_AGENT_CONTEXT_RULES = [
17185
17769
  defaultApps: [{ name: "shuffle_incidents" }],
17186
17770
  defaultPresetId: "incident-response",
17187
17771
  sourceCategory: "incidents",
17772
+ isBeta: true,
17188
17773
  title: "How can we help handle tickets?",
17189
17774
  subtitle: "Shuffle Incidents MCP",
17190
17775
  defaultPrompt: "Investigate this ticket and recommend next steps: ",
@@ -17199,6 +17784,7 @@ var DEFAULT_AGENT_CONTEXT_RULES = [
17199
17784
  defaultApps: [{ name: "shuffle_incidents" }],
17200
17785
  defaultPresetId: "incident-response",
17201
17786
  sourceCategory: "incidents",
17787
+ isBeta: true,
17202
17788
  title: "How can we help handle alerts?",
17203
17789
  subtitle: "Shuffle Incidents MCP",
17204
17790
  defaultPrompt: "Investigate this alert and recommend next steps: ",
@@ -17828,6 +18414,18 @@ var readPresetAppsOverride = (presetId) => {
17828
18414
  return null;
17829
18415
  }
17830
18416
  };
18417
+ var resolvePresetApps = (preset) => {
18418
+ const baseApps = (preset.defaultApps || []).map((app2) => ({ name: app2.name, id: app2.id, icon: app2.icon }));
18419
+ const assigned = getToolsForSkill(preset.id);
18420
+ const merged = [...baseApps];
18421
+ for (const t of assigned) {
18422
+ const key = (t.id || t.name).toLowerCase();
18423
+ if (!merged.some((m) => (m.id || m.name).toLowerCase() === key)) {
18424
+ merged.push({ name: t.name, id: t.id, icon: t.icon || void 0 });
18425
+ }
18426
+ }
18427
+ return merged;
18428
+ };
17831
18429
  var writePresetAppsOverride = (presetId, apps) => {
17832
18430
  try {
17833
18431
  const raw = localStorage.getItem(PRESET_APPS_STORAGE_KEY);
@@ -17966,7 +18564,7 @@ var truncateReason = (reason, maxLength = 280) => {
17966
18564
  return reason.slice(0, maxLength).replace(/\s+\S*$/, "") + "\u2026";
17967
18565
  };
17968
18566
  var FinishAnswerMarkdown = ({ text: text2 }) => {
17969
- const wholeJson = (0, import_react23.useMemo)(() => tryParseJsonObject(stripSingleCodeFence(text2)), [text2]);
18567
+ const wholeJson = (0, import_react24.useMemo)(() => tryParseJsonObject(stripSingleCodeFence(text2)), [text2]);
17970
18568
  if (wholeJson !== null) {
17971
18569
  return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.Box, { sx: { "& .json-view": { backgroundColor: "transparent !important", fontSize: "0.82rem" } }, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_react18_json_view4.default, { src: wholeJson, collapsed: defaultCollapsed, enableClipboard: true, displaySize: true, theme: "default" }) });
17972
18570
  }
@@ -18108,7 +18706,7 @@ var RunFinishedSummary = ({
18108
18706
  children: finishNote
18109
18707
  }
18110
18708
  ),
18111
- bottomContent
18709
+ status !== "FINISHED" && status !== "SUCCESS" && bottomContent
18112
18710
  ] });
18113
18711
  };
18114
18712
  var VERIFIED_BUILTIN_APPS = /* @__PURE__ */ new Set([
@@ -18206,8 +18804,12 @@ var extractAuthRequest = (decision) => {
18206
18804
  } else if (raw && typeof raw === "object") {
18207
18805
  parsed = raw;
18208
18806
  }
18209
- const needsAuth = parsed && (parsed.action === "app_authentication" || parsed.app_authentication === true);
18210
- if (!needsAuth) return null;
18807
+ const candidateObjects = [
18808
+ parsed,
18809
+ decision?.result,
18810
+ decision?.run_details,
18811
+ decision
18812
+ ].filter(Boolean);
18211
18813
  let toolAppName;
18212
18814
  let appId = null;
18213
18815
  if (typeof decision?.tool === "string") {
@@ -18220,12 +18822,40 @@ var extractAuthRequest = (decision) => {
18220
18822
  toolAppName = t;
18221
18823
  }
18222
18824
  }
18223
- let appName = parsed.app || parsed.app_name || parsed.appname;
18224
- if (!appName) appName = toolAppName;
18225
- if (!appName) {
18226
- const f = (decision?.fields || []).find((x) => x?.key === "app" || x?.key === "app_name");
18227
- if (f?.value) appName = f.value;
18228
- }
18825
+ let needsAuth = false;
18826
+ let candidateAppName;
18827
+ for (const obj of candidateObjects) {
18828
+ if (obj.action === "app_authentication" || obj.app_authentication === true || obj.action === "authenticate" || obj.needs_auth === true || obj.auth_required === true) {
18829
+ needsAuth = true;
18830
+ }
18831
+ const candidate = obj.app || obj.app_name || obj.appname;
18832
+ if (typeof candidate === "string" && candidate.trim()) {
18833
+ candidateAppName = candidate.trim();
18834
+ }
18835
+ }
18836
+ const textSources = [
18837
+ decision?.error,
18838
+ decision?.reason,
18839
+ decision?.status_message,
18840
+ decision?.message,
18841
+ decision?.run_details?.error,
18842
+ typeof raw === "string" ? raw : ""
18843
+ ];
18844
+ const combinedText = textSources.filter(Boolean).join(" ").toLowerCase();
18845
+ 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")) {
18846
+ needsAuth = true;
18847
+ }
18848
+ if (!needsAuth && (decision?.status === "WAITING" || decision?.status === "PENDING" || decision?.run_details?.status === "WAITING" || decision?.run_details?.status === "PENDING")) {
18849
+ if (toolAppName && appRequiresAuthentication(toolAppName)) {
18850
+ needsAuth = true;
18851
+ }
18852
+ }
18853
+ if (!needsAuth) return null;
18854
+ let appName = candidateAppName || toolAppName;
18855
+ if (!appName) {
18856
+ const f = (decision?.fields || []).find((x) => x?.key === "app" || x?.key === "app_name");
18857
+ if (f?.value) appName = f.value;
18858
+ }
18229
18859
  if (!appName) return null;
18230
18860
  return { appName, appId };
18231
18861
  };
@@ -18236,12 +18866,17 @@ var STATUS_COLORS = {
18236
18866
  running: "hsl(var(--primary))"
18237
18867
  };
18238
18868
  var TERMINAL_RUN_STATUSES = ["FINISHED", "FAILURE", "ABORTED", "CANCELLED", "CANCELED"];
18239
- var resolveRunStatus = (executionStatus, agentStatus) => {
18240
- const exec = String(executionStatus || "").toUpperCase();
18241
- const agent = String(agentStatus || "").toUpperCase();
18242
- if (TERMINAL_RUN_STATUSES.includes(exec)) return exec;
18243
- if (TERMINAL_RUN_STATUSES.includes(agent)) return agent;
18244
- return exec || agent || "";
18869
+ var resolveRunStatus = (execStatus, agentStatus) => {
18870
+ const e = (execStatus || "").toUpperCase();
18871
+ const a = (agentStatus || "").toUpperCase();
18872
+ if (e === "FINISHED" || a === "FINISHED") return "FINISHED";
18873
+ if (e === "FAILURE" || a === "FAILURE") return "FAILURE";
18874
+ if (e === "ABORTED" || a === "ABORTED") return "ABORTED";
18875
+ if (e === "CANCELLED" || a === "CANCELLED" || e === "CANCELED" || a === "CANCELED") return "CANCELLED";
18876
+ if (e === "WAITING" || a === "WAITING") return "WAITING";
18877
+ if (e === "PENDING" || a === "PENDING") return "PENDING";
18878
+ if (e === "RUNNING" || a === "RUNNING" || e === "EXECUTING" || a === "EXECUTING") return "RUNNING";
18879
+ return e || a || "FINISHED";
18245
18880
  };
18246
18881
  var buildToolName = (apps) => {
18247
18882
  if (!apps.length) return "API";
@@ -18257,26 +18892,33 @@ var isBuiltinDefaultApps = (apps) => {
18257
18892
  );
18258
18893
  };
18259
18894
  var DurationCountdown = ({ resumeAtMs }) => {
18260
- const [nowMs, setNowMs] = (0, import_react23.useState)(() => Date.now());
18261
- (0, import_react23.useEffect)(() => {
18895
+ const [nowMs, setNowMs] = (0, import_react24.useState)(() => Date.now());
18896
+ (0, import_react24.useEffect)(() => {
18262
18897
  const t = setInterval(() => setNowMs(Date.now()), 1e3);
18263
18898
  return () => clearInterval(t);
18264
18899
  }, []);
18265
18900
  const remaining = resumeAtMs - nowMs;
18266
18901
  return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.Tooltip, { title: `Scheduled to continue at ${new Date(resumeAtMs).toLocaleString()}`, arrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.Box, { component: "span", sx: { whiteSpace: "nowrap", cursor: "default" }, children: remaining > 0 ? `in ${formatTimeLeft(remaining)}` : "due now" }) });
18267
18902
  };
18268
- var StatusIcon = ({ status, resumeAtMs }) => {
18903
+ var StatusIcon = ({
18904
+ status,
18905
+ resumeAtMs,
18906
+ authBlockedApp
18907
+ }) => {
18269
18908
  const s = (status || "").toUpperCase();
18270
18909
  const isScheduledWait = s === "WAITING" && !!resumeAtMs;
18271
- const [nowMs, setNowMs] = (0, import_react23.useState)(() => Date.now());
18272
- (0, import_react23.useEffect)(() => {
18910
+ const [nowMs, setNowMs] = (0, import_react24.useState)(() => Date.now());
18911
+ (0, import_react24.useEffect)(() => {
18273
18912
  if (!isScheduledWait) return;
18274
18913
  const t = setInterval(() => setNowMs(Date.now()), 1e3);
18275
18914
  return () => clearInterval(t);
18276
18915
  }, [isScheduledWait]);
18277
18916
  let node;
18278
18917
  let label;
18279
- if (s === "RUNNING" || s === "EXECUTING" || s === "") {
18918
+ if (authBlockedApp) {
18919
+ node = /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_lucide_react15.Lock, { size: 20, color: "hsl(var(--destructive))" });
18920
+ label = `Authentication required for ${formatAppDisplayName(authBlockedApp)} \u2014 step cannot proceed until connected`;
18921
+ } else if (s === "RUNNING" || s === "EXECUTING" || s === "") {
18280
18922
  node = /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.CircularProgress, { size: 18, sx: { color: STATUS_COLORS.running } });
18281
18923
  label = "Running";
18282
18924
  } else if (s === "WAITING") {
@@ -18312,8 +18954,8 @@ var formatAgo = (sec) => {
18312
18954
  return `${Math.floor(diff / 86400)}d ago`;
18313
18955
  };
18314
18956
  var ScheduledLiveBar = ({ startSec, originalStartTime, totalDuration, maxWidth }) => {
18315
- const [nowSec, setNowSec] = (0, import_react23.useState)(() => Date.now() / 1e3);
18316
- (0, import_react23.useEffect)(() => {
18957
+ const [nowSec, setNowSec] = (0, import_react24.useState)(() => Date.now() / 1e3);
18958
+ (0, import_react24.useEffect)(() => {
18317
18959
  const t = setInterval(() => setNowSec(Date.now() / 1e3), 1e3);
18318
18960
  return () => clearInterval(t);
18319
18961
  }, []);
@@ -18360,9 +19002,9 @@ var TimelineRow = ({
18360
19002
  dimmedByRerun = false,
18361
19003
  optimisticContinueText
18362
19004
  }) => {
18363
- const [submitAttempted, setSubmitAttempted] = (0, import_react23.useState)(false);
19005
+ const [submitAttempted, setSubmitAttempted] = (0, import_react24.useState)(false);
18364
19006
  const validate = validateJson(item.details);
18365
- const screenshotPayloads = (0, import_react23.useMemo)(
19007
+ const screenshotPayloads = (0, import_react24.useMemo)(
18366
19008
  () => extractScreenshotPayloads(validate.valid ? validate.result : item.details),
18367
19009
  [validate.valid, validate.result, item.details]
18368
19010
  );
@@ -18475,8 +19117,10 @@ var TimelineRow = ({
18475
19117
  const s = (effectiveStatus || "").toUpperCase();
18476
19118
  return s === "WAITING" || s === "RUNNING" || s === "EXECUTING" || s === "";
18477
19119
  })();
18478
- const barColor = isProcessing ? "hsl(var(--muted-foreground) / 0.45)" : isFailed ? STATUS_COLORS.error : "hsl(var(--muted-foreground) / 0.35)";
18479
- const hoverBarColor = isProcessing ? "hsl(var(--muted-foreground) / 0.45)" : effectiveStatus === "FINISHED" || effectiveStatus === "IGNORED" ? STATUS_COLORS.finished : isFailed ? STATUS_COLORS.error : STATUS_COLORS.running;
19120
+ const rowAuthReq = extractAuthRequest(details);
19121
+ const isRowAuthBlocked = !!rowAuthReq && !isAppAuthenticated?.(rowAuthReq.appName, rowAuthReq.appId) && (effectiveStatus === "WAITING" || effectiveStatus === "PENDING" || effectiveStatus === "FAILURE" || effectiveStatus === "ABORTED");
19122
+ const barColor = isProcessing ? "hsl(var(--muted-foreground) / 0.45)" : isFailed || isRowAuthBlocked ? STATUS_COLORS.error : "hsl(var(--muted-foreground) / 0.35)";
19123
+ const hoverBarColor = isProcessing ? "hsl(var(--muted-foreground) / 0.45)" : effectiveStatus === "FINISHED" || effectiveStatus === "IGNORED" ? STATUS_COLORS.finished : isFailed || isRowAuthBlocked ? STATUS_COLORS.error : STATUS_COLORS.running;
18480
19124
  const isRerunTarget = !!rerunningDecisionId && item.type === "decision" && details?.run_details?.id === rerunningDecisionId;
18481
19125
  return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
18482
19126
  import_material26.Box,
@@ -18485,9 +19129,25 @@ var TimelineRow = ({
18485
19129
  sx: {
18486
19130
  borderTop: index === 0 ? "none" : "1px solid hsl(var(--border))",
18487
19131
  bgcolor: highlight ? "hsla(var(--severity-medium) / 0.12)" : isRerunTarget ? "hsla(var(--primary) / 0.08)" : open ? "hsl(var(--muted) / 0.3)" : "transparent",
18488
- transition: "background 0.6s ease, box-shadow 0.6s ease, opacity 0.2s ease",
18489
- scrollMarginTop: 96,
19132
+ transition: "background-color 0.2s ease",
19133
+ "&:hover": {
19134
+ bgcolor: "hsl(var(--muted) / 0.4)"
19135
+ },
18490
19136
  position: "relative",
19137
+ "&::before": {
19138
+ content: '""',
19139
+ position: "absolute",
19140
+ left: 0,
19141
+ top: 0,
19142
+ bottom: 0,
19143
+ width: 3,
19144
+ bgcolor: barColor,
19145
+ transition: "background-color 0.15s ease"
19146
+ },
19147
+ "&:hover::before": {
19148
+ bgcolor: hoverBarColor
19149
+ },
19150
+ scrollMarginTop: 96,
18491
19151
  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",
18492
19152
  opacity: dimmedByRerun ? 0.35 : 1,
18493
19153
  pointerEvents: dimmedByRerun ? "none" : "auto"
@@ -18496,22 +19156,17 @@ var TimelineRow = ({
18496
19156
  /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
18497
19157
  import_material26.Box,
18498
19158
  {
18499
- onClick: isProcessing ? void 0 : onToggle,
19159
+ onClick: onToggle,
18500
19160
  sx: {
18501
19161
  display: "flex",
18502
19162
  alignItems: "center",
18503
19163
  gap: 1.5,
18504
- px: 2,
18505
- py: 1.25,
18506
- cursor: isProcessing ? "default" : "pointer",
18507
- "--timeline-bar-color": barColor,
18508
- "&:hover": isProcessing ? {} : {
18509
- bgcolor: "hsl(var(--muted) / 0.4)",
18510
- "--timeline-bar-color": hoverBarColor
18511
- }
19164
+ p: 1.5,
19165
+ cursor: "pointer",
19166
+ userSelect: "none"
18512
19167
  },
18513
19168
  children: [
18514
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.Box, { sx: { width: 24, display: "flex", justifyContent: "center" }, children: isRerunTarget ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.CircularProgress, { size: 14, sx: { color: "hsl(var(--primary))" } }) : isProcessing ? isLikelyTimedOut ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.Tooltip, { title: "No new activity for over a minute \u2014 this run has most likely timed out.", arrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.Box, { sx: { display: "flex" }, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_lucide_react15.AlertTriangle, { size: 14, color: STATUS_COLORS.warning }) }) }) : isLiveProcessing ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.CircularProgress, { size: 12, sx: { color: "hsl(var(--muted-foreground))" } }) : /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.Box, { sx: { width: 6, height: 6, borderRadius: "50%", bgcolor: "hsl(var(--muted-foreground) / 0.5)" } }) : /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(StatusIcon, { status: effectiveStatus, resumeAtMs: scheduledResumeMs }) }),
19169
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.Box, { sx: { width: 24, display: "flex", justifyContent: "center" }, children: isRerunTarget ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.CircularProgress, { size: 14, sx: { color: "hsl(var(--primary))" } }) : isProcessing ? isLikelyTimedOut ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.Tooltip, { title: "No new activity for over a minute \u2014 this run has most likely timed out.", arrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.Box, { sx: { display: "flex" }, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_lucide_react15.AlertTriangle, { size: 14, color: STATUS_COLORS.warning }) }) }) : isLiveProcessing ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.CircularProgress, { size: 12, sx: { color: "hsl(var(--muted-foreground))" } }) : /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.Box, { sx: { width: 6, height: 6, borderRadius: "50%", bgcolor: "hsl(var(--muted-foreground) / 0.5)" } }) : /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(StatusIcon, { status: effectiveStatus, resumeAtMs: scheduledResumeMs, authBlockedApp: isRowAuthBlocked ? rowAuthReq.appName : null }) }),
18515
19170
  /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.Box, { sx: { width: 24, display: "flex", justifyContent: "center" }, children: isProcessing ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.Box, { sx: { width: 22 } }) : toolApp?.icon ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.Tooltip, { title: (toolApp.name || "").replace(/_/g, " "), arrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.Avatar, { src: toolApp.icon, sx: { width: 22, height: 22, bgcolor: "transparent" }, variant: "rounded" }) }) : item.category === "finalise" || details?.action === "finish" ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.Tooltip, { title: "Final answer", arrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_lucide_react15.Check, { size: 18 }) }) : /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.Box, { sx: { width: 22 } }) }),
18516
19171
  /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
18517
19172
  import_material26.Tooltip,
@@ -19030,23 +19685,28 @@ var AgentUI = ({
19030
19685
  composeSubmitInput: propComposeSubmitInput,
19031
19686
  contextParams,
19032
19687
  incidentId: propIncidentId,
19688
+ incidentContext: propIncidentContext,
19033
19689
  vulnerabilityId: propVulnerabilityId,
19034
19690
  workflowId: propWorkflowId
19035
19691
  }) => {
19036
19692
  const isEffectiveSupport = isSupport !== void 0 ? isSupport : isSupportUser();
19037
- const resolveUrl2 = (0, import_react23.useCallback)(
19693
+ const resolveUrl2 = (0, import_react24.useCallback)(
19038
19694
  (path) => apiBaseUrl ? `${apiBaseUrl.replace(/\/+$/, "")}${path}` : getApiUrl(path),
19039
19695
  [apiBaseUrl]
19040
19696
  );
19041
- const resolveHeaders2 = (0, import_react23.useCallback)(() => {
19697
+ const resolveHeaders2 = (0, import_react24.useCallback)(() => {
19042
19698
  const h = apiKey ? { Authorization: `Bearer ${apiKey}` } : { ...getAuthHeader() };
19043
19699
  if (orgId) h["Org-Id"] = orgId;
19044
19700
  return h;
19045
19701
  }, [apiKey, orgId]);
19046
19702
  const hasApiKey = !!apiKey || !!API_CONFIG.apiKey;
19703
+ const resolvedIncidentId = propIncidentId || (contextCategory === "incidents" ? contextParams?.id : void 0) || (typeof window !== "undefined" ? window.__shuffleActiveIncidentId : void 0);
19704
+ const resolvedIncidentContext = propIncidentContext || (typeof window !== "undefined" ? window.__shuffleActiveIncidentContext : void 0);
19705
+ const resolvedVulnerabilityId = propVulnerabilityId || (contextCategory === "vulnerabilities" ? contextParams?.id : void 0) || (typeof window !== "undefined" ? window.__shuffleActiveVulnerabilityId : void 0);
19706
+ const resolvedWorkflowId = propWorkflowId || (contextCategory === "workflows" ? contextParams?.id : void 0) || (typeof window !== "undefined" ? window.__shuffleActiveWorkflowId : void 0);
19047
19707
  const isPhoneScreen = (0, import_material26.useMediaQuery)("(max-width:600px)", { noSsr: true });
19048
19708
  const isPhone = mobileView !== void 0 ? mobileView : isPhoneScreen;
19049
- const [actionInput, setActionInput] = (0, import_react23.useState)(() => {
19709
+ const [actionInput, setActionInput] = (0, import_react24.useState)(() => {
19050
19710
  if (contextStorageKey) {
19051
19711
  const saved = getPageContextChoice(contextStorageKey);
19052
19712
  if (saved?.draftPrompt !== void 0 && saved.draftPrompt !== "") {
@@ -19055,8 +19715,8 @@ var AgentUI = ({
19055
19715
  }
19056
19716
  return defaultInput || "";
19057
19717
  });
19058
- const lastStorageKeyRef = (0, import_react23.useRef)(contextStorageKey);
19059
- (0, import_react23.useEffect)(() => {
19718
+ const lastStorageKeyRef = (0, import_react24.useRef)(contextStorageKey);
19719
+ (0, import_react24.useEffect)(() => {
19060
19720
  if (lastStorageKeyRef.current !== contextStorageKey) {
19061
19721
  lastStorageKeyRef.current = contextStorageKey;
19062
19722
  if (contextStorageKey) {
@@ -19069,21 +19729,21 @@ var AgentUI = ({
19069
19729
  }
19070
19730
  }
19071
19731
  }, [contextStorageKey, defaultInput]);
19072
- const prevDefaultInputRef = (0, import_react23.useRef)(defaultInput);
19073
- (0, import_react23.useEffect)(() => {
19732
+ const prevDefaultInputRef = (0, import_react24.useRef)(defaultInput);
19733
+ (0, import_react24.useEffect)(() => {
19074
19734
  if (defaultInput && defaultInput !== prevDefaultInputRef.current) {
19075
19735
  prevDefaultInputRef.current = defaultInput;
19076
19736
  setActionInput(defaultInput);
19077
19737
  }
19078
19738
  }, [defaultInput]);
19079
19739
  const { prompt: savedPromptPrefix } = useAgentPromptPrefix({ userId, persist: !disableStartTab });
19080
- const [selectedPreset, setSelectedPreset] = (0, import_react23.useState)(null);
19081
- const presetsChipNodeRef = (0, import_react23.useRef)(null);
19082
- const [presetsChipWidth, setPresetsChipWidth] = (0, import_react23.useState)(0);
19083
- const [inputScrolled, setInputScrolled] = (0, import_react23.useState)(false);
19084
- const [inputScrollTop, setInputScrollTop] = (0, import_react23.useState)(0);
19085
- const chipOverlayRef = (0, import_react23.useRef)(null);
19086
- const applyChipScroll = (0, import_react23.useCallback)((st) => {
19740
+ const [selectedPreset, setSelectedPreset] = (0, import_react24.useState)(null);
19741
+ const presetsChipNodeRef = (0, import_react24.useRef)(null);
19742
+ const [presetsChipWidth, setPresetsChipWidth] = (0, import_react24.useState)(0);
19743
+ const [inputScrolled, setInputScrolled] = (0, import_react24.useState)(false);
19744
+ const [inputScrollTop, setInputScrollTop] = (0, import_react24.useState)(0);
19745
+ const chipOverlayRef = (0, import_react24.useRef)(null);
19746
+ const applyChipScroll = (0, import_react24.useCallback)((st) => {
19087
19747
  const el = chipOverlayRef.current;
19088
19748
  if (!el) return;
19089
19749
  if (el.dataset.static === "1") {
@@ -19096,19 +19756,19 @@ var AgentUI = ({
19096
19756
  el.style.opacity = st > 24 ? "0" : "1";
19097
19757
  el.style.pointerEvents = st > 4 ? "none" : "auto";
19098
19758
  }, []);
19099
- const [promptSingleLine, setPromptSingleLine] = (0, import_react23.useState)(true);
19759
+ const [promptSingleLine, setPromptSingleLine] = (0, import_react24.useState)(true);
19100
19760
  const promptMultilineBase = !promptSingleLine;
19101
- const [attachmentsRowHeight, setAttachmentsRowHeight] = (0, import_react23.useState)(0);
19102
- const attachmentsRowRef = (0, import_react23.useCallback)((node) => {
19761
+ const [attachmentsRowHeight, setAttachmentsRowHeight] = (0, import_react24.useState)(0);
19762
+ const attachmentsRowRef = (0, import_react24.useCallback)((node) => {
19103
19763
  setAttachmentsRowHeight(node ? node.getBoundingClientRect().height : 0);
19104
19764
  }, []);
19105
- const presetsChipRef = (0, import_react23.useCallback)((node) => {
19765
+ const presetsChipRef = (0, import_react24.useCallback)((node) => {
19106
19766
  presetsChipNodeRef.current = node;
19107
19767
  if (node) setPresetsChipWidth(node.getBoundingClientRect().width);
19108
19768
  }, []);
19109
- const inputRef = (0, import_react23.useRef)(null);
19110
- const seededPresetIdRef = (0, import_react23.useRef)(null);
19111
- (0, import_react23.useEffect)(() => {
19769
+ const inputRef = (0, import_react24.useRef)(null);
19770
+ const seededPresetIdRef = (0, import_react24.useRef)(null);
19771
+ (0, import_react24.useEffect)(() => {
19112
19772
  if (!initialPresetId && defaultInput && defaultInput.trim().length > 0) {
19113
19773
  setSelectedPreset(null);
19114
19774
  return;
@@ -19124,18 +19784,38 @@ var AgentUI = ({
19124
19784
  if (!match || match.enabled === false) return;
19125
19785
  setSelectedPreset(match);
19126
19786
  if (defaultApps === void 0 && !apps) {
19787
+ const resolved = resolvePresetApps(match);
19127
19788
  const override = readPresetAppsOverride(match.id);
19128
- if (override) {
19129
- setChosenApps(override);
19130
- } else if (match.defaultApps && match.defaultApps.length > 0) {
19131
- setChosenApps(match.defaultApps.map((app2) => ({ name: app2.name, id: app2.id, icon: app2.icon })));
19789
+ if (override && override.length > 0) {
19790
+ const merged = [...override];
19791
+ for (const app2 of resolved) {
19792
+ const key = (app2.id || app2.name).toLowerCase();
19793
+ if (!merged.some((m) => (m.id || m.name).toLowerCase() === key)) {
19794
+ merged.push(app2);
19795
+ }
19796
+ }
19797
+ setChosenApps(merged);
19798
+ } else {
19799
+ setChosenApps(resolved);
19132
19800
  }
19133
19801
  }
19134
19802
  seededPresetIdRef.current = match.id;
19135
19803
  } catch {
19136
19804
  }
19137
19805
  }, [presets, defaultInput, isEffectiveSupport, initialPresetId, defaultApps, apps]);
19138
- (0, import_react23.useLayoutEffect)(() => {
19806
+ (0, import_react24.useEffect)(() => {
19807
+ const handleToolsChanged = () => {
19808
+ const targetPreset = selectedPreset || AGENT_PRESETS.find((p) => p.id === "incident-response") || AGENT_PRESETS[0];
19809
+ if (targetPreset) {
19810
+ const next = resolvePresetApps(targetPreset);
19811
+ setChosenApps(next);
19812
+ writePresetAppsOverride(targetPreset.id, next);
19813
+ }
19814
+ };
19815
+ window.addEventListener(AGENT_TOOLS_CHANGED_EVENT, handleToolsChanged);
19816
+ return () => window.removeEventListener(AGENT_TOOLS_CHANGED_EVENT, handleToolsChanged);
19817
+ }, [selectedPreset]);
19818
+ (0, import_react24.useLayoutEffect)(() => {
19139
19819
  if (hidePresets) {
19140
19820
  setPresetsChipWidth(0);
19141
19821
  return;
@@ -19163,14 +19843,14 @@ var AgentUI = ({
19163
19843
  ro?.disconnect();
19164
19844
  };
19165
19845
  }, [selectedPreset, hidePresets, presets, actionInput]);
19166
- (0, import_react23.useEffect)(() => {
19846
+ (0, import_react24.useEffect)(() => {
19167
19847
  const el = inputRef.current;
19168
19848
  if (!el) return;
19169
19849
  if (el.scrollTop <= 1 && inputScrolled) setInputScrolled(false);
19170
19850
  setInputScrollTop(el.scrollTop || 0);
19171
19851
  applyChipScroll(el.scrollTop || 0);
19172
19852
  }, [actionInput, inputScrolled, applyChipScroll]);
19173
- (0, import_react23.useLayoutEffect)(() => {
19853
+ (0, import_react24.useLayoutEffect)(() => {
19174
19854
  const el = inputRef.current;
19175
19855
  if (!el) {
19176
19856
  setPromptSingleLine(true);
@@ -19228,11 +19908,11 @@ var AgentUI = ({
19228
19908
  };
19229
19909
  }, [actionInput, presetsChipWidth, selectedPreset, hidePresets]);
19230
19910
  const shouldTypewrite = placeholder === void 0;
19231
- const [fullPlaceholder, setFullPlaceholder] = (0, import_react23.useState)(
19911
+ const [fullPlaceholder, setFullPlaceholder] = (0, import_react24.useState)(
19232
19912
  () => placeholder ?? getRandomAgentPromptPlaceholder()
19233
19913
  );
19234
- const pickedPlaceholderRef = (0, import_react23.useRef)(null);
19235
- (0, import_react23.useLayoutEffect)(() => {
19914
+ const pickedPlaceholderRef = (0, import_react24.useRef)(null);
19915
+ (0, import_react24.useLayoutEffect)(() => {
19236
19916
  if (!shouldTypewrite) return;
19237
19917
  const el = inputRef.current;
19238
19918
  if (!el) return;
@@ -19259,10 +19939,10 @@ var AgentUI = ({
19259
19939
  pickedPlaceholderRef.current = picked;
19260
19940
  setFullPlaceholder(picked);
19261
19941
  }, [shouldTypewrite, presetsChipWidth, hidePresets]);
19262
- const [typedPlaceholder, setTypedPlaceholder] = (0, import_react23.useState)(
19942
+ const [typedPlaceholder, setTypedPlaceholder] = (0, import_react24.useState)(
19263
19943
  shouldTypewrite ? "" : fullPlaceholder
19264
19944
  );
19265
- (0, import_react23.useEffect)(() => {
19945
+ (0, import_react24.useEffect)(() => {
19266
19946
  if (!shouldTypewrite) {
19267
19947
  setTypedPlaceholder(fullPlaceholder);
19268
19948
  return;
@@ -19286,7 +19966,7 @@ var AgentUI = ({
19286
19966
  return () => window.clearInterval(id);
19287
19967
  }, [fullPlaceholder, shouldTypewrite]);
19288
19968
  const activePromptPrefix = savedPromptPrefix;
19289
- const composeSubmitInput = (0, import_react23.useCallback)(
19969
+ const composeSubmitInput = (0, import_react24.useCallback)(
19290
19970
  (raw) => {
19291
19971
  if (typeof propComposeSubmitInput === "function") {
19292
19972
  return propComposeSubmitInput(raw);
@@ -19295,15 +19975,15 @@ var AgentUI = ({
19295
19975
  },
19296
19976
  [propComposeSubmitInput]
19297
19977
  );
19298
- const promptAnchorRef = import_react23.default.useRef(null);
19299
- const [suggestionsDismissed, setSuggestionsDismissed] = (0, import_react23.useState)(false);
19300
- const [suggestionIndex, setSuggestionIndex] = (0, import_react23.useState)(-1);
19301
- const promptSuggestions = (0, import_react23.useMemo)(
19978
+ const promptAnchorRef = import_react24.default.useRef(null);
19979
+ const [suggestionsDismissed, setSuggestionsDismissed] = (0, import_react24.useState)(false);
19980
+ const [suggestionIndex, setSuggestionIndex] = (0, import_react24.useState)(-1);
19981
+ const promptSuggestions = (0, import_react24.useMemo)(
19302
19982
  () => matchAgentPromptSuggestions(actionInput, 8),
19303
19983
  [actionInput]
19304
19984
  );
19305
- const programmaticInputRef = (0, import_react23.useRef)(false);
19306
- (0, import_react23.useEffect)(() => {
19985
+ const programmaticInputRef = (0, import_react24.useRef)(false);
19986
+ (0, import_react24.useEffect)(() => {
19307
19987
  if (programmaticInputRef.current) {
19308
19988
  programmaticInputRef.current = false;
19309
19989
  return;
@@ -19312,8 +19992,8 @@ var AgentUI = ({
19312
19992
  setSuggestionsDismissed(false);
19313
19993
  }, [actionInput]);
19314
19994
  const suggestionsOpen = promptSuggestions.length > 0 && !suggestionsDismissed;
19315
- const [pendingCategories, setPendingCategories] = (0, import_react23.useState)([]);
19316
- const acceptSuggestion = (0, import_react23.useCallback)((s) => {
19995
+ const [pendingCategories, setPendingCategories] = (0, import_react24.useState)([]);
19996
+ const acceptSuggestion = (0, import_react24.useCallback)((s) => {
19317
19997
  programmaticInputRef.current = true;
19318
19998
  setActionInput(s);
19319
19999
  if (contextStorageKey) {
@@ -19345,32 +20025,32 @@ var AgentUI = ({
19345
20025
  { name: "http" },
19346
20026
  { name: "shuffle_tools" }
19347
20027
  ];
19348
- const [chosenApps, setChosenApps] = (0, import_react23.useState)(() => {
20028
+ const [chosenApps, setChosenApps] = (0, import_react24.useState)(() => {
19349
20029
  if (apps) return apps;
19350
20030
  if (defaultApps !== void 0) return defaultApps.slice(0, MAX_AUTO_ASSIGNED_TOOLS);
19351
20031
  const saved = readPresetAppsOverride(NO_PRESET_KEY);
19352
20032
  if (saved) return saved;
19353
20033
  return BUILTIN_DEFAULT_APPS;
19354
20034
  });
19355
- const isInitialMountChosenAppsRef = (0, import_react23.useRef)(true);
19356
- const isInitialMountPresetOverrideRef = (0, import_react23.useRef)(true);
19357
- const [availableApps, setAvailableApps] = (0, import_react23.useState)([]);
19358
- const [authAppsLoading, setAuthAppsLoading] = (0, import_react23.useState)(autoLoadApps && hasApiKey);
19359
- const [detectedLLM, setDetectedLLM] = (0, import_react23.useState)(null);
19360
- const [configuredLLMOptions, setConfiguredLLMOptions] = (0, import_react23.useState)([]);
19361
- const [llmMenuAnchor, setLlmMenuAnchor] = (0, import_react23.useState)(null);
19362
- const [executionApps, setExecutionApps] = (0, import_react23.useState)([]);
19363
- const [resolvedToolApps, setResolvedToolApps] = (0, import_react23.useState)({});
19364
- const [appSearchOpen, setAppSearchOpen] = (0, import_react23.useState)(false);
19365
- const [appSearchQuery, setAppSearchQuery] = (0, import_react23.useState)("");
19366
- const [categoryTarget, setCategoryTarget] = (0, import_react23.useState)(null);
19367
- const [authDrawerApp, setAuthDrawerApp] = (0, import_react23.useState)(null);
19368
- const [agentRequestLoading, setAgentRequestLoading] = (0, import_react23.useState)(false);
19369
- const [rerunningDecisionId, setRerunningDecisionId] = (0, import_react23.useState)(null);
19370
- const rerunDecisionsSigRef = (0, import_react23.useRef)("");
19371
- const [rerunAgentPending, setRerunAgentPending] = (0, import_react23.useState)(false);
19372
- const [abortLoading, setAbortLoading] = (0, import_react23.useState)(false);
19373
- const [execution, setExecution] = (0, import_react23.useState)(() => {
20035
+ const isInitialMountChosenAppsRef = (0, import_react24.useRef)(true);
20036
+ const isInitialMountPresetOverrideRef = (0, import_react24.useRef)(true);
20037
+ const [availableApps, setAvailableApps] = (0, import_react24.useState)([]);
20038
+ const [authAppsLoading, setAuthAppsLoading] = (0, import_react24.useState)(autoLoadApps && hasApiKey);
20039
+ const [detectedLLM, setDetectedLLM] = (0, import_react24.useState)(null);
20040
+ const [configuredLLMOptions, setConfiguredLLMOptions] = (0, import_react24.useState)([]);
20041
+ const [llmMenuAnchor, setLlmMenuAnchor] = (0, import_react24.useState)(null);
20042
+ const [executionApps, setExecutionApps] = (0, import_react24.useState)([]);
20043
+ const [resolvedToolApps, setResolvedToolApps] = (0, import_react24.useState)({});
20044
+ const [appSearchOpen, setAppSearchOpen] = (0, import_react24.useState)(false);
20045
+ const [appSearchQuery, setAppSearchQuery] = (0, import_react24.useState)("");
20046
+ const [categoryTarget, setCategoryTarget] = (0, import_react24.useState)(null);
20047
+ const [authDrawerApp, setAuthDrawerApp] = (0, import_react24.useState)(null);
20048
+ const [agentRequestLoading, setAgentRequestLoading] = (0, import_react24.useState)(false);
20049
+ const [rerunningDecisionId, setRerunningDecisionId] = (0, import_react24.useState)(null);
20050
+ const rerunDecisionsSigRef = (0, import_react24.useRef)("");
20051
+ const [rerunAgentPending, setRerunAgentPending] = (0, import_react24.useState)(false);
20052
+ const [abortLoading, setAbortLoading] = (0, import_react24.useState)(false);
20053
+ const [execution, setExecution] = (0, import_react24.useState)(() => {
19374
20054
  if (initialExecution) return initialExecution;
19375
20055
  if (contextStorageKey) {
19376
20056
  const saved = getPageContextChoice(contextStorageKey);
@@ -19384,13 +20064,13 @@ var AgentUI = ({
19384
20064
  }
19385
20065
  return null;
19386
20066
  });
19387
- const [agentData, setAgentData] = (0, import_react23.useState)({});
19388
- const [agentActionResult, setAgentActionResult] = (0, import_react23.useState)(null);
19389
- const llmImageAttachments = (0, import_react23.useMemo)(
20067
+ const [agentData, setAgentData] = (0, import_react24.useState)({});
20068
+ const [agentActionResult, setAgentActionResult] = (0, import_react24.useState)(null);
20069
+ const llmImageAttachments = (0, import_react24.useMemo)(
19390
20070
  () => collectLlmImageAttachments(agentData),
19391
20071
  [agentData]
19392
20072
  );
19393
- const [showStarter, setShowStarter] = (0, import_react23.useState)(() => {
20073
+ const [showStarter, setShowStarter] = (0, import_react24.useState)(() => {
19394
20074
  if (initialExecution?.execution_id) return false;
19395
20075
  if (contextStorageKey) {
19396
20076
  const saved = getPageContextChoice(contextStorageKey);
@@ -19400,25 +20080,31 @@ var AgentUI = ({
19400
20080
  }
19401
20081
  return true;
19402
20082
  });
19403
- const handleRemovePreset = (0, import_react23.useCallback)(() => {
20083
+ const handleRemovePreset = (0, import_react24.useCallback)(() => {
19404
20084
  try {
19405
20085
  localStorage.removeItem(LAST_PRESET_STORAGE_KEY);
19406
20086
  } catch {
19407
20087
  }
19408
20088
  setSelectedPreset(null);
19409
20089
  }, []);
19410
- const handleSelectPresetInternal = (0, import_react23.useCallback)((preset) => {
20090
+ const handleSelectPresetInternal = (0, import_react24.useCallback)((preset) => {
19411
20091
  try {
19412
20092
  localStorage.setItem(LAST_PRESET_STORAGE_KEY, preset.id);
19413
20093
  } catch {
19414
20094
  }
20095
+ const resolved = resolvePresetApps(preset);
19415
20096
  const override = readPresetAppsOverride(preset.id);
19416
20097
  if (override && override.length > 0) {
19417
- setChosenApps(override);
19418
- } else if (preset.defaultApps && preset.defaultApps.length > 0) {
19419
- setChosenApps(preset.defaultApps.map((app2) => ({ name: app2.name, id: app2.id, icon: app2.icon })));
20098
+ const merged = [...override];
20099
+ for (const app2 of resolved) {
20100
+ const key = (app2.id || app2.name).toLowerCase();
20101
+ if (!merged.some((m) => (m.id || m.name).toLowerCase() === key)) {
20102
+ merged.push(app2);
20103
+ }
20104
+ }
20105
+ setChosenApps(merged);
19420
20106
  } else {
19421
- setChosenApps([]);
20107
+ setChosenApps(resolved);
19422
20108
  }
19423
20109
  seededPresetIdRef.current = preset.id;
19424
20110
  if (onSelectPreset) {
@@ -19434,40 +20120,40 @@ var AgentUI = ({
19434
20120
  }
19435
20121
  }, 0);
19436
20122
  }, [onSelectPreset]);
19437
- const [scheduleAnchor, setScheduleAnchor] = (0, import_react23.useState)(null);
19438
- const [mobilePlusAnchor, setMobilePlusAnchor] = (0, import_react23.useState)(null);
19439
- const [scheduleCron, setScheduleCron] = (0, import_react23.useState)("0 * * * *");
19440
- const [scheduleSaving, setScheduleSaving] = (0, import_react23.useState)(false);
19441
- const [scheduleSteps, setScheduleSteps] = (0, import_react23.useState)([
20123
+ const [scheduleAnchor, setScheduleAnchor] = (0, import_react24.useState)(null);
20124
+ const [mobilePlusAnchor, setMobilePlusAnchor] = (0, import_react24.useState)(null);
20125
+ const [scheduleCron, setScheduleCron] = (0, import_react24.useState)("0 * * * *");
20126
+ const [scheduleSaving, setScheduleSaving] = (0, import_react24.useState)(false);
20127
+ const [scheduleSteps, setScheduleSteps] = (0, import_react24.useState)([
19442
20128
  { id: "name", state: "pending" },
19443
20129
  { id: "workflow", state: "pending" },
19444
20130
  { id: "schedule", state: "pending" }
19445
20131
  ]);
19446
- const [schedFreq, setSchedFreq] = (0, import_react23.useState)("hours");
19447
- const [schedInterval, setSchedInterval] = (0, import_react23.useState)(1);
19448
- const [schedHour, setSchedHour] = (0, import_react23.useState)(9);
19449
- const [schedMinute, setSchedMinute] = (0, import_react23.useState)(0);
19450
- const [schedWeekdays, setSchedWeekdays] = (0, import_react23.useState)(() => /* @__PURE__ */ new Set([1]));
19451
- const [schedDayOfMonth, setSchedDayOfMonth] = (0, import_react23.useState)(1);
19452
- const [schedAdvancedOpen, setSchedAdvancedOpen] = (0, import_react23.useState)(false);
19453
- const cronManualOverrideRef = (0, import_react23.useRef)(false);
19454
- const [openIndexes, setOpenIndexes] = (0, import_react23.useState)(/* @__PURE__ */ new Set());
19455
- const [highlightedIndex, setHighlightedIndex] = (0, import_react23.useState)(null);
19456
- const [continueHighlighted, setContinueHighlighted] = (0, import_react23.useState)(false);
19457
- const [questionAnswers, setQuestionAnswers] = (0, import_react23.useState)({});
19458
- const [simpleSubmitAttempted, setSimpleSubmitAttempted] = (0, import_react23.useState)(false);
19459
- const [finishAnswerRaw, setFinishAnswerRaw] = (0, import_react23.useState)(false);
19460
- const [continuationText, setContinuationText] = (0, import_react23.useState)("");
19461
- const [runComplete, setRunComplete] = (0, import_react23.useState)(false);
19462
- const [optimisticContinue, setOptimisticContinue] = (0, import_react23.useState)(null);
19463
- const continuationInputRef = (0, import_react23.useRef)(null);
19464
- const continuationFocusedForRef = (0, import_react23.useRef)(null);
19465
- const [error, setError] = (0, import_react23.useState)(null);
19466
- const [pollWarning, setPollWarning] = (0, import_react23.useState)(null);
19467
- const hasExecutionDataRef = (0, import_react23.useRef)(false);
19468
- const loadedExecutionIdRef = (0, import_react23.useRef)(null);
19469
- const keepPollingUntilRef = (0, import_react23.useRef)(0);
19470
- const [runExplorerAvailable, setRunExplorerAvailable] = (0, import_react23.useState)("checking");
20132
+ const [schedFreq, setSchedFreq] = (0, import_react24.useState)("hours");
20133
+ const [schedInterval, setSchedInterval] = (0, import_react24.useState)(1);
20134
+ const [schedHour, setSchedHour] = (0, import_react24.useState)(9);
20135
+ const [schedMinute, setSchedMinute] = (0, import_react24.useState)(0);
20136
+ const [schedWeekdays, setSchedWeekdays] = (0, import_react24.useState)(() => /* @__PURE__ */ new Set([1]));
20137
+ const [schedDayOfMonth, setSchedDayOfMonth] = (0, import_react24.useState)(1);
20138
+ const [schedAdvancedOpen, setSchedAdvancedOpen] = (0, import_react24.useState)(false);
20139
+ const cronManualOverrideRef = (0, import_react24.useRef)(false);
20140
+ const [openIndexes, setOpenIndexes] = (0, import_react24.useState)(/* @__PURE__ */ new Set());
20141
+ const [highlightedIndex, setHighlightedIndex] = (0, import_react24.useState)(null);
20142
+ const [continueHighlighted, setContinueHighlighted] = (0, import_react24.useState)(false);
20143
+ const [questionAnswers, setQuestionAnswers] = (0, import_react24.useState)({});
20144
+ const [simpleSubmitAttempted, setSimpleSubmitAttempted] = (0, import_react24.useState)(false);
20145
+ const [finishAnswerRaw, setFinishAnswerRaw] = (0, import_react24.useState)(false);
20146
+ const [continuationText, setContinuationText] = (0, import_react24.useState)("");
20147
+ const [runComplete, setRunComplete] = (0, import_react24.useState)(false);
20148
+ const [optimisticContinue, setOptimisticContinue] = (0, import_react24.useState)(null);
20149
+ const continuationInputRef = (0, import_react24.useRef)(null);
20150
+ const continuationFocusedForRef = (0, import_react24.useRef)(null);
20151
+ const [error, setError] = (0, import_react24.useState)(null);
20152
+ const [pollWarning, setPollWarning] = (0, import_react24.useState)(null);
20153
+ const hasExecutionDataRef = (0, import_react24.useRef)(false);
20154
+ const loadedExecutionIdRef = (0, import_react24.useRef)(null);
20155
+ const keepPollingUntilRef = (0, import_react24.useRef)(0);
20156
+ const [runExplorerAvailable, setRunExplorerAvailable] = (0, import_react24.useState)("checking");
19471
20157
  const [searchParams, setSearchParams] = (0, import_router_compat3.useSearchParams)();
19472
20158
  const initialViewParam = searchParams.get("agentView");
19473
20159
  const readStoredViewMode = () => {
@@ -19486,8 +20172,8 @@ var AgentUI = ({
19486
20172
  }
19487
20173
  return "simple";
19488
20174
  };
19489
- const [viewMode, setViewMode] = (0, import_react23.useState)(readStoredViewMode);
19490
- (0, import_react23.useEffect)(() => {
20175
+ const [viewMode, setViewMode] = (0, import_react24.useState)(readStoredViewMode);
20176
+ (0, import_react24.useEffect)(() => {
19491
20177
  try {
19492
20178
  if (typeof window !== "undefined") {
19493
20179
  window.localStorage.setItem("shuffle-agents-view-mode", viewMode);
@@ -19495,17 +20181,17 @@ var AgentUI = ({
19495
20181
  } catch {
19496
20182
  }
19497
20183
  }, [viewMode]);
19498
- const [attachedImages, setAttachedImages] = (0, import_react23.useState)([]);
19499
- const [previewImage, setPreviewImage] = (0, import_react23.useState)(null);
20184
+ const [attachedImages, setAttachedImages] = (0, import_react24.useState)([]);
20185
+ const [previewImage, setPreviewImage] = (0, import_react24.useState)(null);
19500
20186
  const promptMultiline = promptMultilineBase || attachedImages.length > 0 || isPhone && Boolean(selectedPreset);
19501
20187
  const promptSingleLineLocked = !promptMultiline;
19502
- const [nowTick, setNowTick] = (0, import_react23.useState)(() => Math.floor(Date.now() / 1e3));
19503
- const [localRunStart, setLocalRunStart] = (0, import_react23.useState)(null);
19504
- const chipBarRef = (0, import_react23.useRef)(null);
19505
- const chipBarResizeObserverRef = (0, import_react23.useRef)(null);
19506
- const [chipBarMultiline, setChipBarMultiline] = (0, import_react23.useState)(false);
19507
- const fileInputRef = (0, import_react23.useRef)(null);
19508
- const chipBarCallbackRef = (0, import_react23.useCallback)((node) => {
20188
+ const [nowTick, setNowTick] = (0, import_react24.useState)(() => Math.floor(Date.now() / 1e3));
20189
+ const [localRunStart, setLocalRunStart] = (0, import_react24.useState)(null);
20190
+ const chipBarRef = (0, import_react24.useRef)(null);
20191
+ const chipBarResizeObserverRef = (0, import_react24.useRef)(null);
20192
+ const [chipBarMultiline, setChipBarMultiline] = (0, import_react24.useState)(false);
20193
+ const fileInputRef = (0, import_react24.useRef)(null);
20194
+ const chipBarCallbackRef = (0, import_react24.useCallback)((node) => {
19509
20195
  chipBarRef.current = node;
19510
20196
  chipBarResizeObserverRef.current?.disconnect();
19511
20197
  if (!node) return;
@@ -19522,14 +20208,14 @@ var AgentUI = ({
19522
20208
  chipBarResizeObserverRef.current = ro;
19523
20209
  }
19524
20210
  }, []);
19525
- const activeExecutionIdRef = (0, import_react23.useRef)(
19526
- initialExecution?.execution_id || (contextStorageKey ? getPageContextChoice(contextStorageKey)?.executionId || null : null)
20211
+ const activeExecutionIdRef = (0, import_react24.useRef)(
20212
+ executionId || initialExecution?.execution_id || (contextStorageKey ? getPageContextChoice(contextStorageKey)?.executionId || null : null)
19527
20213
  );
19528
- const executionPollGenerationRef = (0, import_react23.useRef)(0);
19529
- const runAbortRef = (0, import_react23.useRef)(null);
19530
- const runGenerationRef = (0, import_react23.useRef)(0);
19531
- const userPickedStartRef = (0, import_react23.useRef)(false);
19532
- const stateRef = (0, import_react23.useRef)({
20214
+ const executionPollGenerationRef = (0, import_react24.useRef)(0);
20215
+ const runAbortRef = (0, import_react24.useRef)(null);
20216
+ const runGenerationRef = (0, import_react24.useRef)(0);
20217
+ const userPickedStartRef = (0, import_react24.useRef)(false);
20218
+ const stateRef = (0, import_react24.useRef)({
19533
20219
  execution: null,
19534
20220
  agentData: {},
19535
20221
  agentActionResult: null,
@@ -19547,25 +20233,25 @@ var AgentUI = ({
19547
20233
  stateRef.current.continuationText = continuationText;
19548
20234
  stateRef.current.localRunStart = localRunStart;
19549
20235
  stateRef.current.showStarter = showStarter;
19550
- (0, import_react23.useEffect)(() => {
20236
+ (0, import_react24.useEffect)(() => {
19551
20237
  const el = chipBarRef.current;
19552
20238
  if (el) {
19553
20239
  setChipBarMultiline(el.clientHeight > 42 || el.scrollHeight > 42);
19554
20240
  }
19555
20241
  }, [chosenApps, availableApps, selectedPreset]);
19556
- (0, import_react23.useEffect)(() => {
20242
+ (0, import_react24.useEffect)(() => {
19557
20243
  return () => {
19558
20244
  chipBarResizeObserverRef.current?.disconnect();
19559
20245
  };
19560
20246
  }, []);
19561
- (0, import_react23.useEffect)(() => {
20247
+ (0, import_react24.useEffect)(() => {
19562
20248
  if (execution?.execution_id || agentRequestLoading) {
19563
20249
  setLocalRunStart((prev) => prev ?? Math.floor(Date.now() / 1e3));
19564
20250
  } else {
19565
20251
  setLocalRunStart(null);
19566
20252
  }
19567
20253
  }, [execution?.execution_id, agentRequestLoading]);
19568
- (0, import_react23.useEffect)(() => {
20254
+ (0, import_react24.useEffect)(() => {
19569
20255
  if (!execution?.execution_id && !agentRequestLoading) return;
19570
20256
  const status = (execution?.status || agentData?.status || "").toUpperCase();
19571
20257
  const TERMINAL = ["FINISHED", "FAILURE", "ABORTED", "CANCELLED", "CANCELED"];
@@ -19607,7 +20293,7 @@ var AgentUI = ({
19607
20293
  setError(null);
19608
20294
  }
19609
20295
  };
19610
- const appsById = (0, import_react23.useMemo)(() => {
20296
+ const appsById = (0, import_react24.useMemo)(() => {
19611
20297
  const m = {};
19612
20298
  const add = (a) => {
19613
20299
  if (!a?.name) return;
@@ -19625,7 +20311,7 @@ var AgentUI = ({
19625
20311
  }
19626
20312
  return m;
19627
20313
  }, [chosenApps, executionApps, resolvedToolApps]);
19628
- const isAppAuthenticated = (0, import_react23.useCallback)((appName, appId) => {
20314
+ const isAppAuthenticated = (0, import_react24.useCallback)((appName, appId) => {
19629
20315
  if (!appName && !appId) return false;
19630
20316
  const target = normalizeAgentAppName(appName);
19631
20317
  if (isNoAuthApp(target)) return true;
@@ -19634,11 +20320,11 @@ var AgentUI = ({
19634
20320
  return !!appName && normalizeAgentAppName(a.name || "") === target;
19635
20321
  });
19636
20322
  }, [availableApps]);
19637
- const pendingAuthApps = (0, import_react23.useMemo)(() => {
20323
+ const pendingAuthApps = (0, import_react24.useMemo)(() => {
19638
20324
  if (authAppsLoading) return [];
19639
- const decisions = agentData?.decisions || [];
19640
20325
  const seen = /* @__PURE__ */ new Set();
19641
20326
  const out = [];
20327
+ const decisions = agentData?.decisions || [];
19642
20328
  for (const d of decisions) {
19643
20329
  const req = extractAuthRequest(d);
19644
20330
  if (!req) continue;
@@ -19650,12 +20336,25 @@ var AgentUI = ({
19650
20336
  const icon = appsById[req.appName]?.icon || appsById[slug]?.icon || (appId ? appsById[appId]?.icon : "") || "";
19651
20337
  out.push({ appName: req.appName, appId, icon });
19652
20338
  }
20339
+ const hasAllowed = Array.isArray(agentData?.allowed_actions) && agentData.allowed_actions.length > 0;
20340
+ const activeAppList = hasAllowed ? executionApps : chosenApps;
20341
+ for (const app2 of activeAppList) {
20342
+ if (!app2?.name) continue;
20343
+ const slug = normalizeAgentAppName(app2.name);
20344
+ if (seen.has(slug)) continue;
20345
+ if (appRequiresAuthentication(slug) && !isAppAuthenticated(app2.name, app2.id || null)) {
20346
+ seen.add(slug);
20347
+ const appId = app2.id || appsById[app2.name]?.id || appsById[slug]?.id || null;
20348
+ const icon = app2.icon || appsById[app2.name]?.icon || appsById[slug]?.icon || (appId ? appsById[appId]?.icon : "") || "";
20349
+ out.push({ appName: app2.name, appId, icon });
20350
+ }
20351
+ }
19653
20352
  return out;
19654
- }, [agentData, appsById, authAppsLoading, isAppAuthenticated]);
19655
- (0, import_react23.useEffect)(() => {
20353
+ }, [agentData, executionApps, chosenApps, appsById, authAppsLoading, isAppAuthenticated]);
20354
+ (0, import_react24.useEffect)(() => {
19656
20355
  if (apps) setChosenApps(apps);
19657
20356
  }, [apps]);
19658
- (0, import_react23.useEffect)(() => {
20357
+ (0, import_react24.useEffect)(() => {
19659
20358
  const required = selectedPreset?.requiredApps;
19660
20359
  if (!required || required.length === 0) return;
19661
20360
  setChosenApps((prev) => {
@@ -19664,7 +20363,7 @@ var AgentUI = ({
19664
20363
  return [...prev, ...missing.map((name) => ({ name }))];
19665
20364
  });
19666
20365
  }, [selectedPreset]);
19667
- (0, import_react23.useEffect)(() => {
20366
+ (0, import_react24.useEffect)(() => {
19668
20367
  const decisions = agentData?.decisions || [];
19669
20368
  if (!Array.isArray(decisions) || decisions.length === 0) return;
19670
20369
  const norm4 = (s) => s.toLowerCase().replace(/[\s-]+/g, "_");
@@ -19712,7 +20411,7 @@ var AgentUI = ({
19712
20411
  cancelled = true;
19713
20412
  };
19714
20413
  }, [JSON.stringify(agentData?.decisions?.map((d) => [d?.details?.tool || d?.tool, extractAuthRequest(d)?.appName]) || []), appsById]);
19715
- (0, import_react23.useEffect)(() => {
20414
+ (0, import_react24.useEffect)(() => {
19716
20415
  const missing = chosenApps.filter((a) => !a.icon && a.name);
19717
20416
  if (missing.length === 0) return;
19718
20417
  let cancelled = false;
@@ -19770,7 +20469,7 @@ var AgentUI = ({
19770
20469
  cancelled = true;
19771
20470
  };
19772
20471
  }, [chosenApps, availableApps, resolveUrl2, resolveHeaders2]);
19773
- const loadAuthenticatedApps = (0, import_react23.useCallback)(async (signal) => {
20472
+ const loadAuthenticatedApps = (0, import_react24.useCallback)(async (signal) => {
19774
20473
  setAuthAppsLoading(true);
19775
20474
  try {
19776
20475
  const [authRes, wfRes] = await Promise.allSettled([
@@ -19871,7 +20570,7 @@ var AgentUI = ({
19871
20570
  if (!signal?.cancelled) setAuthAppsLoading(false);
19872
20571
  }
19873
20572
  }, [resolveUrl2, resolveHeaders2, contextCategory, contextStorageKey, defaultApps, onAppsChange]);
19874
- (0, import_react23.useEffect)(() => {
20573
+ (0, import_react24.useEffect)(() => {
19875
20574
  if (!autoLoadApps) return;
19876
20575
  if (!hasApiKey) return;
19877
20576
  const signal = { cancelled: false };
@@ -19880,7 +20579,7 @@ var AgentUI = ({
19880
20579
  signal.cancelled = true;
19881
20580
  };
19882
20581
  }, [autoLoadApps, hasApiKey, loadAuthenticatedApps]);
19883
- (0, import_react23.useEffect)(() => {
20582
+ (0, import_react24.useEffect)(() => {
19884
20583
  if (!hasApiKey) return;
19885
20584
  const handler = (event) => {
19886
20585
  const customEvent = event;
@@ -19895,7 +20594,7 @@ var AgentUI = ({
19895
20594
  window.addEventListener("integrations-changed", handler);
19896
20595
  return () => window.removeEventListener("integrations-changed", handler);
19897
20596
  }, [hasApiKey, loadAuthenticatedApps]);
19898
- (0, import_react23.useEffect)(() => {
20597
+ (0, import_react24.useEffect)(() => {
19899
20598
  const raw = agentData?.allowed_actions;
19900
20599
  if (!Array.isArray(raw) || raw.length === 0) {
19901
20600
  setExecutionApps([]);
@@ -20008,7 +20707,7 @@ var AgentUI = ({
20008
20707
  cancelled = true;
20009
20708
  };
20010
20709
  }, [JSON.stringify(agentData?.allowed_actions || []), availableApps]);
20011
- const getExecution = (0, import_react23.useCallback)(async (executionId2, authorization2) => {
20710
+ const getExecution = (0, import_react24.useCallback)(async (executionId2, authorization2) => {
20012
20711
  const pollGeneration = executionPollGenerationRef.current;
20013
20712
  if (loadedExecutionIdRef.current !== executionId2) hasExecutionDataRef.current = false;
20014
20713
  if (!executionId2 || executionId2.startsWith("demo-") || executionId2.startsWith("dummy-")) return;
@@ -20085,7 +20784,7 @@ var AgentUI = ({
20085
20784
  else setPollWarning(`Live updates are failing (${err instanceof Error ? err.message : "network error"}). Showing the last known state.`);
20086
20785
  }
20087
20786
  }, []);
20088
- (0, import_react23.useEffect)(() => {
20787
+ (0, import_react24.useEffect)(() => {
20089
20788
  const eid = execution?.execution_id;
20090
20789
  const auth = execution?.authorization;
20091
20790
  if (!eid) {
@@ -20112,19 +20811,19 @@ var AgentUI = ({
20112
20811
  cancelled = true;
20113
20812
  };
20114
20813
  }, [execution?.execution_id, execution?.authorization]);
20115
- (0, import_react23.useEffect)(() => {
20814
+ (0, import_react24.useEffect)(() => {
20116
20815
  if (execution?.authorization && (execution?.results?.length || 0) > 0) {
20117
20816
  setRunExplorerAvailable("yes");
20118
20817
  }
20119
20818
  }, [execution?.authorization, execution?.results?.length]);
20120
- (0, import_react23.useEffect)(() => {
20819
+ (0, import_react24.useEffect)(() => {
20121
20820
  let eid = null;
20122
20821
  let auth = null;
20123
20822
  let initialStatus = "EXECUTING";
20124
20823
  let savedViewMode = null;
20125
- if (executionId && authorization) {
20824
+ if (executionId) {
20126
20825
  eid = executionId;
20127
- auth = authorization;
20826
+ auth = authorization || null;
20128
20827
  } else if (readUrlParams) {
20129
20828
  const params = new URLSearchParams(window.location.search);
20130
20829
  eid = params.get("execution_id");
@@ -20153,7 +20852,7 @@ var AgentUI = ({
20153
20852
  getExecution(eid, auth || void 0);
20154
20853
  }
20155
20854
  }, [readUrlParams, executionId, authorization, getExecution, contextStorageKey]);
20156
- (0, import_react23.useEffect)(() => {
20855
+ (0, import_react24.useEffect)(() => {
20157
20856
  if (!initialExecution || !initialExecution.execution_id) return;
20158
20857
  if (!userPickedStartRef.current) setShowStarter(false);
20159
20858
  activeExecutionIdRef.current = initialExecution.execution_id;
@@ -20188,7 +20887,7 @@ var AgentUI = ({
20188
20887
  getExecution(initialExecution.execution_id, initialExecution.authorization);
20189
20888
  }
20190
20889
  }, [initialExecution?.execution_id]);
20191
- (0, import_react23.useEffect)(() => {
20890
+ (0, import_react24.useEffect)(() => {
20192
20891
  if (!execution?.execution_id) return;
20193
20892
  const status = (execution.status || "").toUpperCase();
20194
20893
  const TERMINAL = ["FINISHED", "FAILURE", "ABORTED", "CANCELLED", "CANCELED"];
@@ -20205,7 +20904,7 @@ var AgentUI = ({
20205
20904
  }, intervalMs);
20206
20905
  return () => clearInterval(id);
20207
20906
  }, [execution?.execution_id, execution?.authorization, execution?.status, agentData?.decisions, runComplete, getExecution]);
20208
- const submitInput = (0, import_react23.useCallback)(async (text2, presetOverride, appsOverride) => {
20907
+ const submitInput = (0, import_react24.useCallback)(async (text2, presetOverride, appsOverride) => {
20209
20908
  if (!text2.trim()) return;
20210
20909
  if (isLoggedIn === false) {
20211
20910
  setError("Authentication required. Please log in to run AI agents.");
@@ -20266,9 +20965,6 @@ var AgentUI = ({
20266
20965
  return next;
20267
20966
  }, { replace: true });
20268
20967
  }
20269
- const resolvedIncidentId = propIncidentId || (contextCategory === "incidents" ? contextParams?.id : void 0) || (typeof window !== "undefined" ? window.__shuffleActiveIncidentId : void 0);
20270
- const resolvedVulnerabilityId = propVulnerabilityId || (contextCategory === "vulnerabilities" ? contextParams?.id : void 0) || (typeof window !== "undefined" ? window.__shuffleActiveVulnerabilityId : void 0);
20271
- const resolvedWorkflowId = propWorkflowId || (contextCategory === "workflows" ? contextParams?.id : void 0) || (typeof window !== "undefined" ? window.__shuffleActiveWorkflowId : void 0);
20272
20968
  const result = await runAgent({
20273
20969
  input: composed.trim(),
20274
20970
  skipPolling: true,
@@ -20277,6 +20973,7 @@ var AgentUI = ({
20277
20973
  ...apiBaseUrl ? { apiBaseUrl } : {},
20278
20974
  ...orgId ? { orgId } : {},
20279
20975
  ...resolvedIncidentId ? { incidentId: resolvedIncidentId } : {},
20976
+ ...resolvedIncidentContext ? { incidentContext: resolvedIncidentContext } : {},
20280
20977
  ...resolvedVulnerabilityId ? { vulnerabilityId: resolvedVulnerabilityId } : {},
20281
20978
  ...resolvedWorkflowId ? { workflowId: resolvedWorkflowId } : {},
20282
20979
  // Send a single comma-separated `tool_name` in the format
@@ -20347,6 +21044,13 @@ var AgentUI = ({
20347
21044
  const auth = raw?.authorization;
20348
21045
  if (eid && auth) {
20349
21046
  activeExecutionIdRef.current = eid;
21047
+ if (typeof window !== "undefined") {
21048
+ window.dispatchEvent(
21049
+ new CustomEvent("shuffle:agent_execution_status", {
21050
+ detail: { executionId: eid, status: "running", incidentId: resolvedIncidentId }
21051
+ })
21052
+ );
21053
+ }
20350
21054
  if (contextStorageKey) {
20351
21055
  setPageContextChoice(contextStorageKey, {
20352
21056
  draftPrompt: "",
@@ -20392,14 +21096,14 @@ var AgentUI = ({
20392
21096
  onRun?.({ input: text2, success: true, executionId: eid });
20393
21097
  }
20394
21098
  }, [chosenApps, executionApps, getExecution, onRun, attachedImages, readUrlParams, setSearchParams, viewMode, selectedPreset, isLoggedIn]);
20395
- const autoSubmittedRef = (0, import_react23.useRef)(false);
20396
- (0, import_react23.useEffect)(() => {
20397
- if (autoSubmit && defaultInput && !autoSubmittedRef.current && !executionId) {
20398
- autoSubmittedRef.current = true;
21099
+ const lastSubmittedInputRef = (0, import_react24.useRef)(null);
21100
+ (0, import_react24.useEffect)(() => {
21101
+ if (autoSubmit && defaultInput && defaultInput !== lastSubmittedInputRef.current) {
21102
+ lastSubmittedInputRef.current = defaultInput;
20399
21103
  submitInput(defaultInput);
20400
21104
  }
20401
- }, [autoSubmit, defaultInput, executionId, submitInput]);
20402
- const submitQuestions = (0, import_react23.useCallback)(async (decisionId, answers, isContinuation) => {
21105
+ }, [autoSubmit, defaultInput, submitInput]);
21106
+ const submitQuestions = (0, import_react24.useCallback)(async (decisionId, answers, isContinuation) => {
20403
21107
  if (!execution?.execution_id || !execution?.authorization) return;
20404
21108
  let newArgument = {};
20405
21109
  if (isContinuation) {
@@ -20457,7 +21161,7 @@ var AgentUI = ({
20457
21161
  setAgentRequestLoading(false);
20458
21162
  }
20459
21163
  }, [execution, getExecution, agentData?.decisions]);
20460
- const resolveRunInput = (0, import_react23.useCallback)(() => {
21164
+ const resolveRunInput = (0, import_react24.useCallback)(() => {
20461
21165
  const fromData = agentData?.original_input;
20462
21166
  if (fromData && typeof fromData === "string") return fromData;
20463
21167
  if (actionInput && typeof actionInput === "string" && actionInput.trim()) return actionInput;
@@ -20525,7 +21229,7 @@ var AgentUI = ({
20525
21229
  };
20526
21230
  return deepFind(agentData) || deepFind(agentActionResult) || deepFind(execution) || "";
20527
21231
  }, [agentData, actionInput, agentActionResult, execution]);
20528
- const resolveRunTemplate = (0, import_react23.useCallback)(() => {
21232
+ const resolveRunTemplate = (0, import_react24.useCallback)(() => {
20529
21233
  const candidates = [
20530
21234
  agentData?.template,
20531
21235
  agentData?.input?.template,
@@ -20546,7 +21250,7 @@ var AgentUI = ({
20546
21250
  (p) => p.id === slug || PRESET_TEMPLATE_SLUGS[p.id] === slug || TEMPLATE_SLUG_TO_PRESET_ID[slug] === p.id
20547
21251
  ) ?? null;
20548
21252
  }, [agentData, agentActionResult, execution, presets]);
20549
- const rerunAgent = (0, import_react23.useCallback)(() => {
21253
+ const rerunAgent = (0, import_react24.useCallback)(() => {
20550
21254
  const resolved = resolveRunInput();
20551
21255
  const input = (typeof resolved === "string" && resolved.trim() ? resolved : actionInput) || "";
20552
21256
  const template = resolveRunTemplate();
@@ -20574,12 +21278,12 @@ var AgentUI = ({
20574
21278
  }
20575
21279
  setTimeout(() => setRerunAgentPending(false), 8e3);
20576
21280
  }, [resolveRunInput, resolveRunTemplate, actionInput, executionApps, disableStartTab, submitInput]);
20577
- (0, import_react23.useEffect)(() => {
21281
+ (0, import_react24.useEffect)(() => {
20578
21282
  if (rerunAgentPending && (agentRequestLoading || execution?.execution_id)) {
20579
21283
  setRerunAgentPending(false);
20580
21284
  }
20581
21285
  }, [rerunAgentPending, agentRequestLoading, execution?.execution_id]);
20582
- const abortAgent = (0, import_react23.useCallback)(async () => {
21286
+ const abortAgent = (0, import_react24.useCallback)(async () => {
20583
21287
  (0, import_react_dom.flushSync)(() => setAbortLoading(true));
20584
21288
  const execId = execution?.execution_id;
20585
21289
  const auth = execution?.authorization;
@@ -20645,10 +21349,10 @@ var AgentUI = ({
20645
21349
  setAbortLoading(false);
20646
21350
  }
20647
21351
  }, [execution, resolveUrl2, resolveHeaders2, getExecution, setSearchParams]);
20648
- (0, import_react23.useEffect)(() => {
21352
+ (0, import_react24.useEffect)(() => {
20649
21353
  if (execution?.execution_id) setLastOpenedAgentRun(execution.execution_id);
20650
21354
  }, [execution?.execution_id]);
20651
- const getFormUrl = (0, import_react23.useCallback)((decisionId) => {
21355
+ const getFormUrl = (0, import_react24.useCallback)((decisionId) => {
20652
21356
  const wfId = execution?.workflow?.id;
20653
21357
  const auth = execution?.authorization;
20654
21358
  const execId = execution?.execution_id;
@@ -20664,7 +21368,7 @@ var AgentUI = ({
20664
21368
  });
20665
21369
  return `/forms/${wfId}?${params.toString()}`;
20666
21370
  }, [execution, agentActionResult, apiBaseUrl]);
20667
- const rerunDecision = (0, import_react23.useCallback)(async (decision) => {
21371
+ const rerunDecision = (0, import_react24.useCallback)(async (decision) => {
20668
21372
  if (!execution?.execution_id) {
20669
21373
  toast({ title: "No execution loaded", description: "Cannot rerun this decision.", variant: "destructive" });
20670
21374
  return;
@@ -20710,7 +21414,7 @@ var AgentUI = ({
20710
21414
  setAgentRequestLoading(false);
20711
21415
  }
20712
21416
  }, [execution, agentActionResult, agentData, getExecution, resolveUrl2, resolveHeaders2]);
20713
- (0, import_react23.useEffect)(() => {
21417
+ (0, import_react24.useEffect)(() => {
20714
21418
  if (!rerunningDecisionId) return;
20715
21419
  const sig = JSON.stringify(
20716
21420
  (agentData?.decisions || []).map((d) => d?.run_details?.id || "")
@@ -20725,14 +21429,14 @@ var AgentUI = ({
20725
21429
  const runStillExecuting = Boolean(execution?.execution_id || agentRequestLoading) && !TERMINAL_RUN_STATUSES.includes(
20726
21430
  resolveRunStatus(execution?.status, agentData?.status)
20727
21431
  );
20728
- const [liveNowSec, setLiveNowSec] = (0, import_react23.useState)(() => Date.now() / 1e3);
20729
- (0, import_react23.useEffect)(() => {
21432
+ const [liveNowSec, setLiveNowSec] = (0, import_react24.useState)(() => Date.now() / 1e3);
21433
+ (0, import_react24.useEffect)(() => {
20730
21434
  if (!runStillExecuting) return;
20731
21435
  setLiveNowSec(Date.now() / 1e3);
20732
21436
  const t = setInterval(() => setLiveNowSec(Date.now() / 1e3), 1e3);
20733
21437
  return () => clearInterval(t);
20734
21438
  }, [runStillExecuting]);
20735
- const { timeline, originalStartTime, totalDuration, finishDecisionId, finishAnswer, finishNote } = (0, import_react23.useMemo)(() => {
21439
+ const { timeline, originalStartTime, totalDuration, finishDecisionId, finishAnswer, finishNote } = (0, import_react24.useMemo)(() => {
20736
21440
  const toSec = (t) => {
20737
21441
  const n = Number(t) || 0;
20738
21442
  return n > 1e12 ? n / 1e3 : n;
@@ -20918,7 +21622,7 @@ var AgentUI = ({
20918
21622
  const total = Math.max(1, end - startSafe);
20919
21623
  return { timeline: items, originalStartTime: startSafe, totalDuration: total, finishDecisionId: finishId, finishAnswer: finishAns, finishNote: finishNote2 };
20920
21624
  }, [agentData, execution?.status, execution?.started_at, execution?.completed_at, runStillExecuting, liveNowSec]);
20921
- (0, import_react23.useEffect)(() => {
21625
+ (0, import_react24.useEffect)(() => {
20922
21626
  const status = (execution?.status || "").toUpperCase();
20923
21627
  const isTerminal = ["FINISHED", "FAILURE", "ABORTED", "CANCELLED", "CANCELED"].includes(status);
20924
21628
  const hasPendingDecision = (agentData?.decisions || []).some((d) => {
@@ -20927,7 +21631,38 @@ var AgentUI = ({
20927
21631
  });
20928
21632
  setRunComplete(Boolean(isTerminal && !hasPendingDecision && (finishAnswer || finishDecisionId)));
20929
21633
  }, [execution?.status, agentData?.decisions, finishAnswer, finishDecisionId]);
20930
- (0, import_react23.useEffect)(() => {
21634
+ (0, import_react24.useEffect)(() => {
21635
+ const eid = execution?.execution_id || activeExecutionIdRef.current;
21636
+ const status = (execution?.status || agentData?.status || "").toUpperCase();
21637
+ if (!eid || !status || typeof window === "undefined") return;
21638
+ if (status === "FINISHED" || status === "SUCCESS") {
21639
+ window.dispatchEvent(
21640
+ new CustomEvent("shuffle:agent_execution_status", {
21641
+ detail: { executionId: eid, status: "completed", incidentId: resolvedIncidentId }
21642
+ })
21643
+ );
21644
+ if (resolvedIncidentId) {
21645
+ window.dispatchEvent(
21646
+ new CustomEvent("incident:refresh", {
21647
+ detail: { id: resolvedIncidentId, incidentId: resolvedIncidentId, executionId: eid }
21648
+ })
21649
+ );
21650
+ }
21651
+ } else if (["FAILURE", "ABORTED", "CANCELLED", "CANCELED"].includes(status)) {
21652
+ window.dispatchEvent(
21653
+ new CustomEvent("shuffle:agent_execution_status", {
21654
+ detail: { executionId: eid, status: "failed", incidentId: resolvedIncidentId }
21655
+ })
21656
+ );
21657
+ } else if (["RUNNING", "EXECUTING", "IN_PROGRESS", "WAITING"].includes(status)) {
21658
+ window.dispatchEvent(
21659
+ new CustomEvent("shuffle:agent_execution_status", {
21660
+ detail: { executionId: eid, status: "running", incidentId: resolvedIncidentId }
21661
+ })
21662
+ );
21663
+ }
21664
+ }, [execution?.execution_id, execution?.status, agentData?.status, resolvedIncidentId]);
21665
+ (0, import_react24.useEffect)(() => {
20931
21666
  if (!finishDecisionId || agentRequestLoading) return;
20932
21667
  if (continuationFocusedForRef.current === finishDecisionId) return;
20933
21668
  continuationFocusedForRef.current = finishDecisionId;
@@ -20937,7 +21672,7 @@ var AgentUI = ({
20937
21672
  }, 150);
20938
21673
  return () => clearTimeout(t);
20939
21674
  }, [finishDecisionId, agentRequestLoading]);
20940
- const openLocalLlmArea = (0, import_react23.useCallback)(() => {
21675
+ const openLocalLlmArea = (0, import_react24.useCallback)(() => {
20941
21676
  if (onChooseLLM) {
20942
21677
  onChooseLLM();
20943
21678
  return;
@@ -20954,16 +21689,20 @@ var AgentUI = ({
20954
21689
  );
20955
21690
  }
20956
21691
  }, [onChooseLLM]);
20957
- const isAiAuthIssue = (0, import_react23.useMemo)(() => {
21692
+ const isAiAuthIssue = (0, import_react24.useMemo)(() => {
21693
+ const status = (execution?.status || agentData?.status || "").toUpperCase();
21694
+ const isFinished = status === "FINISHED" || status === "SUCCESS";
21695
+ if (isFinished && !isAiAuthText(error)) {
21696
+ return false;
21697
+ }
20958
21698
  if (finishAnswer && finishAnswer.trim().length > 0 && !isAiAuthText(finishAnswer)) {
20959
- const diagnosable2 = execution?.results?.length ? execution : agentData;
20960
- if (!isAiAuthFailure(diagnosable2, error || "")) return false;
21699
+ return false;
20961
21700
  }
20962
21701
  const diagnosable = execution?.results?.length ? execution : agentData;
20963
- return isAiAuthFailure(diagnosable, error || finishAnswer || "");
21702
+ return isAiAuthFailure(diagnosable, error || "");
20964
21703
  }, [execution, agentData, finishAnswer, error]);
20965
21704
  const aiAuthSuggestionNode = isAiAuthIssue ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.Box, { sx: { mt: 1.5 }, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(AiAuthSuggestion_default, { onOpenLocalLlm: openLocalLlmArea }) }) : null;
20966
- (0, import_react23.useEffect)(() => {
21705
+ (0, import_react24.useEffect)(() => {
20967
21706
  if (!optimisticContinue) return;
20968
21707
  const count = (agentData?.decisions || []).length;
20969
21708
  if (count > optimisticContinue.decisions) {
@@ -20975,7 +21714,7 @@ var AgentUI = ({
20975
21714
  }, [optimisticContinue, agentData?.decisions]);
20976
21715
  const optimisticRunning = Boolean(optimisticContinue);
20977
21716
  const optimisticContinueText = optimisticContinue?.text || void 0;
20978
- const stuckDecision = (0, import_react23.useMemo)(() => {
21717
+ const stuckDecision = (0, import_react24.useMemo)(() => {
20979
21718
  const list = (agentData?.decisions || []).filter((d) => {
20980
21719
  if (!d?.run_details?.id) return false;
20981
21720
  const s = String(d?.run_details?.status || "").toUpperCase();
@@ -21012,9 +21751,9 @@ var AgentUI = ({
21012
21751
  requestAnimationFrame(() => requestAnimationFrame(scrollRowIntoView));
21013
21752
  window.setTimeout(scrollRowIntoView, 260);
21014
21753
  };
21015
- const timelineEndRef = (0, import_react23.useRef)(null);
21016
- const followTimelineRef = (0, import_react23.useRef)(true);
21017
- (0, import_react23.useEffect)(() => {
21754
+ const timelineEndRef = (0, import_react24.useRef)(null);
21755
+ const followTimelineRef = (0, import_react24.useRef)(true);
21756
+ (0, import_react24.useEffect)(() => {
21018
21757
  if (typeof window === "undefined") return;
21019
21758
  const getScrollParent = (node) => {
21020
21759
  let el = node?.parentElement || null;
@@ -21054,7 +21793,7 @@ var AgentUI = ({
21054
21793
  const runIsLive = optimisticRunning || !["FINISHED", "FAILURE", "ABORTED", "CANCELLED", "CANCELED"].includes(
21055
21794
  (resolveRunStatus(execution?.status, agentData?.status) || "EXECUTING").toUpperCase()
21056
21795
  );
21057
- (0, import_react23.useEffect)(() => {
21796
+ (0, import_react24.useEffect)(() => {
21058
21797
  if (typeof window === "undefined") return;
21059
21798
  if (viewMode !== "detailed") return;
21060
21799
  if (!runIsLive) return;
@@ -21072,10 +21811,10 @@ var AgentUI = ({
21072
21811
  window.clearTimeout(t);
21073
21812
  };
21074
21813
  }, [timelineCount, viewMode, runIsLive]);
21075
- (0, import_react23.useEffect)(() => {
21814
+ (0, import_react24.useEffect)(() => {
21076
21815
  followTimelineRef.current = true;
21077
21816
  }, [execution?.execution_id]);
21078
- const handlePrimarySubmit = (0, import_react23.useCallback)(() => {
21817
+ const handlePrimarySubmit = (0, import_react24.useCallback)(() => {
21079
21818
  const composed = composeSubmitInput(actionInput);
21080
21819
  if (submitOverride) {
21081
21820
  submitOverride({ input: composed, apps: chosenApps });
@@ -21120,17 +21859,17 @@ var AgentUI = ({
21120
21859
  const activeTab = showStarter ? "start" : viewMode;
21121
21860
  const hasExecution = !!execution?.execution_id;
21122
21861
  const showRunSwitcher = hasExecution || agentRequestLoading;
21123
- (0, import_react23.useEffect)(() => {
21862
+ (0, import_react24.useEffect)(() => {
21124
21863
  onViewChange?.(activeTab);
21125
21864
  }, [activeTab, onViewChange]);
21126
- (0, import_react23.useEffect)(() => {
21865
+ (0, import_react24.useEffect)(() => {
21127
21866
  if (isInitialMountChosenAppsRef.current) {
21128
21867
  isInitialMountChosenAppsRef.current = false;
21129
21868
  return;
21130
21869
  }
21131
21870
  onAppsChange?.(chosenApps);
21132
21871
  }, [chosenApps, onAppsChange]);
21133
- (0, import_react23.useEffect)(() => {
21872
+ (0, import_react24.useEffect)(() => {
21134
21873
  if (isInitialMountPresetOverrideRef.current) {
21135
21874
  isInitialMountPresetOverrideRef.current = false;
21136
21875
  return;
@@ -21189,7 +21928,7 @@ var AgentUI = ({
21189
21928
  }
21190
21929
  }
21191
21930
  };
21192
- const { scheduleDisabledReasons, scheduleWarnings } = (0, import_react23.useMemo)(() => {
21931
+ const { scheduleDisabledReasons, scheduleWarnings } = (0, import_react24.useMemo)(() => {
21193
21932
  const decisions = agentData?.decisions || [];
21194
21933
  const runStatus = resolveRunStatus(execution?.status, agentData?.status);
21195
21934
  const isNotFinished = runStatus !== "" && !["FINISHED", "FAILURE", "ABORTED", "CANCELLED", "CANCELED"].includes(runStatus);
@@ -21258,24 +21997,24 @@ var AgentUI = ({
21258
21997
  }
21259
21998
  return { scheduleDisabledReasons: reasons, scheduleWarnings: warnings };
21260
21999
  }, [agentData, execution?.status]);
21261
- const scheduleHint = (0, import_react23.useMemo)(() => {
22000
+ const scheduleHint = (0, import_react24.useMemo)(() => {
21262
22001
  const parsed = parseScheduleHint(actionInput);
21263
22002
  return parsed && parsed.once ? null : parsed;
21264
22003
  }, [actionInput]);
21265
- const lastAppliedHintRef = (0, import_react23.useRef)(null);
21266
- (0, import_react23.useEffect)(() => {
22004
+ const lastAppliedHintRef = (0, import_react24.useRef)(null);
22005
+ (0, import_react24.useEffect)(() => {
21267
22006
  if (!scheduleHint) return;
21268
22007
  if (scheduleAnchor) return;
21269
22008
  if (lastAppliedHintRef.current === scheduleHint.cron) return;
21270
22009
  setScheduleCron(scheduleHint.cron);
21271
22010
  lastAppliedHintRef.current = scheduleHint.cron;
21272
22011
  }, [scheduleHint, scheduleAnchor]);
21273
- const finishedRunInput = (0, import_react23.useMemo)(() => extractCleanDisplayPrompt(resolveRunInput()), [resolveRunInput]);
21274
- const postRunScheduleHint = (0, import_react23.useMemo)(() => {
22012
+ const finishedRunInput = (0, import_react24.useMemo)(() => extractCleanDisplayPrompt(resolveRunInput()), [resolveRunInput]);
22013
+ const postRunScheduleHint = (0, import_react24.useMemo)(() => {
21275
22014
  const parsed = parseScheduleHint(finishedRunInput);
21276
22015
  return parsed && parsed.once ? null : parsed;
21277
22016
  }, [finishedRunInput]);
21278
- const postRunAppReqs = (0, import_react23.useMemo)(() => {
22017
+ const postRunAppReqs = (0, import_react24.useMemo)(() => {
21279
22018
  const text2 = (finishedRunInput || "").trim();
21280
22019
  if (text2.length < 4) return [];
21281
22020
  const reqs = getSuggestionAppRequirements(text2, 4);
@@ -21286,14 +22025,14 @@ var AgentUI = ({
21286
22025
  return !chosen.some((c) => c && (c === target || c.includes(target) || target.includes(c)));
21287
22026
  });
21288
22027
  }, [finishedRunInput, chosenApps]);
21289
- const postRunUnauthedApps = (0, import_react23.useMemo)(() => {
22028
+ const postRunUnauthedApps = (0, import_react24.useMemo)(() => {
21290
22029
  if (authAppsLoading) return [];
21291
22030
  return chosenApps.filter((a) => {
21292
22031
  const slug = normalizeAgentAppName(a.name || "");
21293
22032
  return appRequiresAuthentication(slug) && !isAppAuthenticated(a.name || "", a.id || null);
21294
22033
  });
21295
22034
  }, [authAppsLoading, chosenApps, isAppAuthenticated]);
21296
- (0, import_react23.useEffect)(() => {
22035
+ (0, import_react24.useEffect)(() => {
21297
22036
  if (cronManualOverrideRef.current) return;
21298
22037
  const m = Math.max(0, Math.min(59, schedMinute));
21299
22038
  const h = Math.max(0, Math.min(23, schedHour));
@@ -21335,7 +22074,7 @@ var AgentUI = ({
21335
22074
  /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.Box, { component: "span", children: r })
21336
22075
  ] }, i)) })
21337
22076
  ] }) : "";
21338
- const tabBarRef = (0, import_react23.useRef)(null);
22077
+ const tabBarRef = (0, import_react24.useRef)(null);
21339
22078
  const runStatusUpper = resolveRunStatus(execution?.status, agentData?.status);
21340
22079
  const runIsActive = hasExecution && !["FINISHED", "FAILURE", "ABORTED", "CANCELLED", "CANCELED"].includes(runStatusUpper);
21341
22080
  const tabBar = /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
@@ -23120,7 +23859,47 @@ var AgentUI = ({
23120
23859
  children: formatAppDisplayName(app2.name || "")
23121
23860
  }
23122
23861
  ),
23123
- (needsAuth || isUnavailable) && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_lucide_react15.AlertTriangle, { size: 14, color: "hsl(var(--severity-medium))", style: { marginRight: 2 } }),
23862
+ needsAuth ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
23863
+ import_material26.Box,
23864
+ {
23865
+ component: "span",
23866
+ sx: {
23867
+ fontSize: "0.65rem",
23868
+ fontWeight: 600,
23869
+ color: "hsl(var(--destructive))",
23870
+ bgcolor: "hsl(var(--destructive) / 0.12)",
23871
+ border: "1px solid hsl(var(--destructive) / 0.3)",
23872
+ borderRadius: 1,
23873
+ px: 0.6,
23874
+ py: 0.1,
23875
+ letterSpacing: "0.02em",
23876
+ textTransform: "uppercase",
23877
+ ml: 0.5,
23878
+ mr: 0.25
23879
+ },
23880
+ children: "Missing auth"
23881
+ }
23882
+ ) : isUnavailable ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
23883
+ import_material26.Box,
23884
+ {
23885
+ component: "span",
23886
+ sx: {
23887
+ fontSize: "0.65rem",
23888
+ fontWeight: 600,
23889
+ color: "hsl(var(--severity-medium))",
23890
+ bgcolor: "hsl(var(--severity-medium) / 0.12)",
23891
+ border: "1px solid hsl(var(--severity-medium) / 0.3)",
23892
+ borderRadius: 1,
23893
+ px: 0.6,
23894
+ py: 0.1,
23895
+ letterSpacing: "0.02em",
23896
+ textTransform: "uppercase",
23897
+ ml: 0.5,
23898
+ mr: 0.25
23899
+ },
23900
+ children: "Unavailable"
23901
+ }
23902
+ ) : null,
23124
23903
  isRequired ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
23125
23904
  import_lucide_react15.Lock,
23126
23905
  {
@@ -23322,43 +24101,83 @@ var AgentUI = ({
23322
24101
  return list;
23323
24102
  })().map((app2, i) => {
23324
24103
  const slug = normalizeAgentAppName(app2.name || "");
24104
+ const appNeedsAuth = !authAppsLoading && appRequiresAuthentication(slug) && !isAppAuthenticated(app2.name || "", app2.id || null);
23325
24105
  const appIcon = app2.icon || availableApps.find((a) => normalizeAgentAppName(a.name || "") === slug)?.icon || resolvedToolApps[slug]?.icon;
23326
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.Tooltip, { title: formatAppDisplayName(app2.name || ""), children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
23327
- import_material26.Box,
24106
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
24107
+ import_material26.Tooltip,
23328
24108
  {
23329
- onClick: () => setAuthDrawerApp({ name: app2.name, id: app2.id || null }),
23330
- sx: {
23331
- display: "inline-flex",
23332
- alignItems: "center",
23333
- justifyContent: "center",
23334
- width: 24,
23335
- height: 24,
23336
- borderRadius: "6px",
23337
- overflow: "hidden",
23338
- bgcolor: "hsl(var(--muted))",
23339
- cursor: "pointer",
23340
- transition: "transform 0.15s ease, border-color 0.15s ease",
23341
- "&:hover": { transform: "scale(1.08)", borderColor: "hsl(var(--primary)) !important" }
23342
- },
24109
+ title: appNeedsAuth ? `${formatAppDisplayName(app2.name || "")} \u2014 Missing authentication (Click to connect)` : formatAppDisplayName(app2.name || ""),
23343
24110
  children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
23344
- AppFallbackIcon,
24111
+ import_material26.Box,
23345
24112
  {
23346
- name: app2.name,
23347
- imageUrl: appIcon,
23348
- size: 24,
23349
- style: { borderRadius: 6, objectFit: "contain" }
24113
+ onClick: () => setAuthDrawerApp({ name: app2.name, id: app2.id || null }),
24114
+ sx: {
24115
+ display: "inline-flex",
24116
+ alignItems: "center",
24117
+ justifyContent: "center",
24118
+ width: 24,
24119
+ height: 24,
24120
+ borderRadius: "6px",
24121
+ overflow: "hidden",
24122
+ bgcolor: "hsl(var(--muted))",
24123
+ cursor: "pointer",
24124
+ transition: "transform 0.15s ease, border-color 0.15s ease",
24125
+ border: appNeedsAuth ? "2px solid hsl(var(--destructive)) !important" : "none",
24126
+ boxShadow: appNeedsAuth ? "0 0 0 1px hsl(var(--destructive) / 0.4)" : "none",
24127
+ "&:hover": { transform: "scale(1.08)", borderColor: "hsl(var(--primary)) !important" }
24128
+ },
24129
+ children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
24130
+ AppFallbackIcon,
24131
+ {
24132
+ name: app2.name,
24133
+ imageUrl: appIcon,
24134
+ size: 24,
24135
+ style: { borderRadius: 6, objectFit: "contain" }
24136
+ }
24137
+ )
23350
24138
  }
23351
24139
  )
23352
- }
23353
- ) }, i);
24140
+ },
24141
+ i
24142
+ );
23354
24143
  }) }),
23355
24144
  /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_material26.Box, { sx: { flex: 1, minWidth: 0 }, children: [
23356
24145
  /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.Typography, { sx: { fontSize: "0.85rem", color: "hsl(var(--foreground))", fontWeight: 600, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: extractCleanDisplayPrompt(agentData?.original_input) || actionInput || "Agent run" }),
23357
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_material26.Typography, { sx: { fontSize: "0.7rem", color: "hsl(var(--muted-foreground))" }, children: [
23358
- "Status: ",
23359
- execution?.status || agentData?.status || "\u2014",
23360
- " \xB7 ",
23361
- execution?.execution_id?.slice(0, 8) || ""
24146
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_material26.Typography, { sx: { fontSize: "0.7rem", color: "hsl(var(--muted-foreground))", display: "flex", alignItems: "center", gap: 1, flexWrap: "wrap", mt: 0.25 }, children: [
24147
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("span", { children: [
24148
+ "Status: ",
24149
+ execution?.status || agentData?.status || "\u2014",
24150
+ " \xB7 ",
24151
+ execution?.execution_id?.slice(0, 8) || ""
24152
+ ] }),
24153
+ pendingAuthApps.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
24154
+ import_material26.Box,
24155
+ {
24156
+ component: "span",
24157
+ onClick: () => setAuthDrawerApp({ name: pendingAuthApps[0].appName, id: pendingAuthApps[0].appId }),
24158
+ sx: {
24159
+ display: "inline-flex",
24160
+ alignItems: "center",
24161
+ gap: 0.5,
24162
+ px: 0.75,
24163
+ py: 0.15,
24164
+ borderRadius: 1,
24165
+ bgcolor: "hsl(var(--destructive) / 0.12)",
24166
+ border: "1px solid hsl(var(--destructive) / 0.35)",
24167
+ color: "hsl(var(--destructive))",
24168
+ fontSize: "0.68rem",
24169
+ fontWeight: 600,
24170
+ cursor: "pointer",
24171
+ textTransform: "none",
24172
+ "&:hover": { bgcolor: "hsl(var(--destructive) / 0.2)" }
24173
+ },
24174
+ children: [
24175
+ "Missing Auth: ",
24176
+ pendingAuthApps.map((a) => formatAppDisplayName(a.appName)).join(", "),
24177
+ " \u2014 Connect"
24178
+ ]
24179
+ }
24180
+ )
23362
24181
  ] })
23363
24182
  ] }),
23364
24183
  /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(AgentAttachmentsButton_default, { attachments: llmImageAttachments }),
@@ -23538,6 +24357,57 @@ var AgentUI = ({
23538
24357
  }
23539
24358
  }
23540
24359
  ),
24360
+ pendingAuthApps.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
24361
+ import_material26.Box,
24362
+ {
24363
+ sx: {
24364
+ mb: 2,
24365
+ p: 2,
24366
+ borderRadius: 2,
24367
+ border: "1px solid hsla(var(--severity-medium) / 0.35)",
24368
+ bgcolor: "hsla(var(--severity-medium) / 0.08)",
24369
+ display: "flex",
24370
+ alignItems: "center",
24371
+ justifyContent: "space-between",
24372
+ gap: 2,
24373
+ flexWrap: "wrap"
24374
+ },
24375
+ children: [
24376
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_material26.Box, { sx: { display: "flex", alignItems: "center", gap: 1.5, flex: 1, minWidth: 260 }, children: [
24377
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_lucide_react15.Lock, { size: 22, color: "hsl(var(--severity-medium))" }),
24378
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_material26.Box, { sx: { flex: 1, minWidth: 0 }, children: [
24379
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.Typography, { 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` }),
24380
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.Typography, { 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.` })
24381
+ ] })
24382
+ ] }),
24383
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.Box, { sx: { display: "flex", gap: 1, flexWrap: "wrap" }, children: pendingAuthApps.map(({ appName, appId }) => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
24384
+ import_material26.Button,
24385
+ {
24386
+ variant: "outlined",
24387
+ size: "small",
24388
+ onClick: () => setAuthDrawerApp({ name: appName, id: appId }),
24389
+ sx: {
24390
+ borderColor: "hsla(var(--severity-medium) / 0.6)",
24391
+ color: "hsl(var(--foreground))",
24392
+ textTransform: "none",
24393
+ fontSize: "0.75rem",
24394
+ fontWeight: 600,
24395
+ height: 32,
24396
+ "&:hover": {
24397
+ bgcolor: "hsla(var(--severity-medium) / 0.15)",
24398
+ borderColor: "hsl(var(--severity-medium))"
24399
+ }
24400
+ },
24401
+ children: [
24402
+ "Authenticate ",
24403
+ formatAppDisplayName(appName)
24404
+ ]
24405
+ },
24406
+ appName
24407
+ )) })
24408
+ ]
24409
+ }
24410
+ ),
23541
24411
  viewMode === "simple" && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.Box, { sx: {
23542
24412
  borderRadius: 2,
23543
24413
  border: "1px solid hsl(var(--border))",
@@ -23579,7 +24449,7 @@ var AgentUI = ({
23579
24449
  }
23580
24450
  const pendingAnswered = pendingQuestions.every((q) => questionAnswers[q.question]?.value);
23581
24451
  return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_jsx_runtime31.Fragment, { children: [
23582
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
24452
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
23583
24453
  RunFinishedSummary,
23584
24454
  {
23585
24455
  status,
@@ -23592,77 +24462,7 @@ var AgentUI = ({
23592
24462
  durationSec,
23593
24463
  showMeta: true,
23594
24464
  bottomContent: aiAuthSuggestionNode,
23595
- children: [
23596
- pendingAuthApps.map(({ appName, appId, icon }) => {
23597
- const pretty = appName.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
23598
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
23599
- import_material26.Box,
23600
- {
23601
- sx: {
23602
- display: "flex",
23603
- alignItems: "center",
23604
- gap: 1.5,
23605
- p: 1.5,
23606
- borderRadius: 1.5,
23607
- border: "1px solid hsla(var(--severity-medium) / 0.3)",
23608
- bgcolor: "hsla(var(--severity-medium) / 0.08)"
23609
- },
23610
- children: [
23611
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_lucide_react15.Lock, { size: 22, color: "hsl(var(--severity-medium))" }),
23612
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_material26.Box, { sx: { flex: 1, minWidth: 0 }, children: [
23613
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_material26.Typography, { sx: { fontSize: "0.85rem", fontWeight: 600, color: "hsl(var(--foreground))" }, children: [
23614
- pretty,
23615
- " requires authentication"
23616
- ] }),
23617
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_material26.Typography, { sx: { fontSize: "0.75rem", color: "hsl(var(--muted-foreground))" }, children: [
23618
- "Connect your ",
23619
- pretty,
23620
- " account so the agent can complete this step, then rerun."
23621
- ] })
23622
- ] }),
23623
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
23624
- import_material26.Button,
23625
- {
23626
- variant: "outlined",
23627
- size: "small",
23628
- startIcon: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
23629
- import_material26.Avatar,
23630
- {
23631
- src: icon || void 0,
23632
- alt: "",
23633
- variant: "rounded",
23634
- sx: {
23635
- width: 18,
23636
- height: 18,
23637
- borderRadius: 0.5,
23638
- bgcolor: "hsl(var(--background) / 0.4)",
23639
- color: "hsl(var(--background))",
23640
- fontSize: "0.7rem",
23641
- fontWeight: 700,
23642
- "& img": { objectFit: "contain" }
23643
- },
23644
- children: pretty.charAt(0)
23645
- }
23646
- ),
23647
- onClick: () => setAuthDrawerApp({ name: appName, id: appId }),
23648
- sx: {
23649
- height: 36,
23650
- textTransform: "none",
23651
- fontWeight: 600
23652
- },
23653
- children: [
23654
- "Authenticate ",
23655
- pretty
23656
- ]
23657
- }
23658
- )
23659
- ]
23660
- },
23661
- `auth-${appName}`
23662
- );
23663
- }),
23664
- !isRunning && postRunDiscovery
23665
- ]
24465
+ children: !isRunning && postRunDiscovery
23666
24466
  }
23667
24467
  ),
23668
24468
  !finishAnswer && pendingAsk && pendingQuestions.length > 0 ? (() => {
@@ -24050,12 +24850,12 @@ var AgentUI = ({
24050
24850
  var AgentUI_default = AgentUI;
24051
24851
 
24052
24852
  // components/AgentRunDrawer.tsx
24053
- var import_react26 = require("react");
24853
+ var import_react27 = require("react");
24054
24854
  var import_material29 = require("@mui/material");
24055
24855
  var import_lucide_react17 = require("lucide-react");
24056
24856
 
24057
24857
  // components/LocalLLMConfig.tsx
24058
- var import_react24 = require("react");
24858
+ var import_react25 = require("react");
24059
24859
  var import_lucide_react16 = require("lucide-react");
24060
24860
  var import_material28 = require("@mui/material");
24061
24861
  init_api();
@@ -24148,7 +24948,7 @@ var UsageBar = ({
24148
24948
 
24149
24949
  // components/LocalLLMConfig.tsx
24150
24950
  var import_jsx_runtime33 = require("react/jsx-runtime");
24151
- var import_react25 = require("react");
24951
+ var import_react26 = require("react");
24152
24952
  var OPENAI_APP_NAME = "OpenAI";
24153
24953
  var OPENAI_APP_ID = "5d19dd82517870c68d40cacad9b5ca91";
24154
24954
  var OPENAI_ALGOLIA_APP = {
@@ -24218,7 +25018,7 @@ var PROVIDER_MODELS = {
24218
25018
  "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"]
24219
25019
  };
24220
25020
  var ProviderLogo = ({ label, url }) => {
24221
- const [errored, setErrored] = (0, import_react24.useState)(false);
25021
+ const [errored, setErrored] = (0, import_react25.useState)(false);
24222
25022
  let domain = PROVIDER_DOMAINS[label];
24223
25023
  if (!domain && url) {
24224
25024
  try {
@@ -24234,8 +25034,8 @@ var LLM_PRESET_STORAGE_KEY = "shuffle-llm-provider";
24234
25034
  var LocalLLMConfig = ({ compact, globalUrl, userdata, isLoaded, isLoggedIn, serverside, theme, colorMode, open }) => {
24235
25035
  useSyncHostBaseUrl(globalUrl);
24236
25036
  const { authStates, authenticatedApps, handleAuthChange, handleSaveAuth, refreshAuth, loading: authLoading } = useAppAuth();
24237
- const [expanded, setExpanded] = (0, import_react24.useState)(true);
24238
- const [selectedPreset, setSelectedPreset] = (0, import_react24.useState)(() => {
25037
+ const [expanded, setExpanded] = (0, import_react25.useState)(true);
25038
+ const [selectedPreset, setSelectedPreset] = (0, import_react25.useState)(() => {
24239
25039
  try {
24240
25040
  const stored = localStorage.getItem(LLM_PRESET_STORAGE_KEY) || "";
24241
25041
  return ENDPOINT_PRESETS.some((p) => p.label === stored) ? stored : "";
@@ -24243,9 +25043,9 @@ var LocalLLMConfig = ({ compact, globalUrl, userdata, isLoaded, isLoggedIn, serv
24243
25043
  return "";
24244
25044
  }
24245
25045
  });
24246
- const [customUrl, setCustomUrl] = (0, import_react24.useState)("");
24247
- const activeSwitchSeqRef = (0, import_react24.useRef)(0);
24248
- const [llmTest, setLlmTest] = (0, import_react24.useState)(null);
25046
+ const [customUrl, setCustomUrl] = (0, import_react25.useState)("");
25047
+ const activeSwitchSeqRef = (0, import_react25.useRef)(0);
25048
+ const [llmTest, setLlmTest] = (0, import_react25.useState)(null);
24249
25049
  const openaiEntries = authenticatedApps.filter(
24250
25050
  (a) => a.app?.name?.toLowerCase() === "openai" || a.app?.id === OPENAI_APP_ID
24251
25051
  );
@@ -24262,8 +25062,8 @@ var LocalLLMConfig = ({ compact, globalUrl, userdata, isLoaded, isLoggedIn, serv
24262
25062
  } : baseAuthState;
24263
25063
  const savedUrlFromEntry = (openaiEntries[0]?.fields || []).find((f) => (f?.key || "").toLowerCase() === "url")?.value || "";
24264
25064
  const currentUrl = (authState.credentials?.url || savedUrlFromEntry || "").trim();
24265
- const [customModel, setCustomModel] = (0, import_react24.useState)("");
24266
- const [customMode, setCustomMode] = (0, import_react24.useState)(false);
25065
+ const [customModel, setCustomModel] = (0, import_react25.useState)("");
25066
+ const [customMode, setCustomMode] = (0, import_react25.useState)(false);
24267
25067
  const hasOpenAIEntries = openaiEntries.length > 0;
24268
25068
  const providerOfEntry = (entry) => providerLabelOfAuthEntry(entry);
24269
25069
  const displayLabelOfEntry = (entry) => {
@@ -24271,20 +25071,20 @@ var LocalLLMConfig = ({ compact, globalUrl, userdata, isLoaded, isLoggedIn, serv
24271
25071
  const stripped = raw.replace(new RegExp(`^\\s*${OPENAI_APP_NAME}\\s*-\\s*`, "i"), "").trim();
24272
25072
  return stripped || raw;
24273
25073
  };
24274
- const [optimisticActiveProvider, setOptimisticActiveProvider] = (0, import_react24.useState)(null);
24275
- const activeEntryRaw = (0, import_react24.useMemo)(
25074
+ const [optimisticActiveProvider, setOptimisticActiveProvider] = (0, import_react25.useState)(null);
25075
+ const activeEntryRaw = (0, import_react25.useMemo)(
24276
25076
  () => openaiEntries.find((e) => e?.active === true),
24277
25077
  [openaiEntries]
24278
25078
  );
24279
25079
  const activeEntry = activeEntryRaw || null;
24280
- const activeProviderLabel = (0, import_react24.useMemo)(() => {
25080
+ const activeProviderLabel = (0, import_react25.useMemo)(() => {
24281
25081
  if (optimisticActiveProvider !== null) {
24282
25082
  return optimisticActiveProvider === SHUFFLE_AI_PRESET ? null : optimisticActiveProvider;
24283
25083
  }
24284
25084
  if (!activeEntryRaw) return null;
24285
25085
  return providerOfEntry(activeEntryRaw);
24286
25086
  }, [optimisticActiveProvider, activeEntryRaw, providerOfEntry]);
24287
- const effectivePreset = (0, import_react24.useMemo)(() => {
25087
+ const effectivePreset = (0, import_react25.useMemo)(() => {
24288
25088
  if (selectedPreset) return selectedPreset;
24289
25089
  if (optimisticActiveProvider !== null) return optimisticActiveProvider;
24290
25090
  if (activeEntryRaw) return providerOfEntry(activeEntryRaw);
@@ -24292,12 +25092,12 @@ var LocalLLMConfig = ({ compact, globalUrl, userdata, isLoaded, isLoggedIn, serv
24292
25092
  if (currentUrl) return detectLLMProvider(currentUrl)?.label || CUSTOM_PRESET;
24293
25093
  return SHUFFLE_AI_PRESET;
24294
25094
  }, [selectedPreset, optimisticActiveProvider, currentUrl, hasOpenAIEntries, activeEntryRaw]);
24295
- const providerEntries = (0, import_react24.useMemo)(
25095
+ const providerEntries = (0, import_react25.useMemo)(
24296
25096
  () => openaiEntries.filter((e) => providerOfEntry(e) === effectivePreset).map((e) => ({ ...e, label: displayLabelOfEntry(e) })),
24297
25097
  // eslint-disable-next-line react-hooks/exhaustive-deps
24298
25098
  [openaiEntries, effectivePreset]
24299
25099
  );
24300
- const validatedProviderLabels = (0, import_react24.useMemo)(() => {
25100
+ const validatedProviderLabels = (0, import_react25.useMemo)(() => {
24301
25101
  const set = /* @__PURE__ */ new Set();
24302
25102
  const remembered = getValidatedAuthIds();
24303
25103
  for (const entry of openaiEntries) {
@@ -24460,9 +25260,9 @@ var LocalLLMConfig = ({ compact, globalUrl, userdata, isLoaded, isLoggedIn, serv
24460
25260
  } catch {
24461
25261
  }
24462
25262
  };
24463
- const prevOpenRef = (0, import_react24.useRef)(open);
24464
- const hasInitializedPresetRef = (0, import_react24.useRef)(false);
24465
- (0, import_react24.useEffect)(() => {
25263
+ const prevOpenRef = (0, import_react25.useRef)(open);
25264
+ const hasInitializedPresetRef = (0, import_react25.useRef)(false);
25265
+ (0, import_react25.useEffect)(() => {
24466
25266
  const justOpened = Boolean(open && !prevOpenRef.current);
24467
25267
  prevOpenRef.current = open;
24468
25268
  if (authLoading) return;
@@ -24534,14 +25334,14 @@ var LocalLLMConfig = ({ compact, globalUrl, userdata, isLoaded, isLoggedIn, serv
24534
25334
  setCustomUrl(value);
24535
25335
  handleAuthChange(OPENAI_APP_ID, { ...authState.credentials, url: value });
24536
25336
  };
24537
- (0, import_react24.useEffect)(() => {
25337
+ (0, import_react25.useEffect)(() => {
24538
25338
  const preset = ENDPOINT_PRESETS.find((p) => p.label === effectivePreset);
24539
25339
  const presetUrl = effectivePreset === CUSTOM_PRESET ? customUrl : preset?.url || "";
24540
25340
  if (!presetUrl) return;
24541
25341
  if ((authState.credentials?.url || "").trim()) return;
24542
25342
  handleAuthChange(OPENAI_APP_ID, { ...authState.credentials, url: presetUrl });
24543
25343
  }, [effectivePreset, customUrl, authState.credentials?.url]);
24544
- (0, import_react24.useEffect)(() => {
25344
+ (0, import_react25.useEffect)(() => {
24545
25345
  const models = PROVIDER_MODELS[effectivePreset];
24546
25346
  if (!models?.length) return;
24547
25347
  if ((authState.credentials?.model || "").trim()) return;
@@ -24564,8 +25364,8 @@ var LocalLLMConfig = ({ compact, globalUrl, userdata, isLoaded, isLoggedIn, serv
24564
25364
  return isLocal;
24565
25365
  })();
24566
25366
  const orgId = userdata?.active_org?.id;
24567
- const [orgData, setOrgData] = (0, import_react24.useState)(null);
24568
- (0, import_react24.useEffect)(() => {
25367
+ const [orgData, setOrgData] = (0, import_react25.useState)(null);
25368
+ (0, import_react25.useEffect)(() => {
24569
25369
  if (!orgId) return;
24570
25370
  let cancelled = false;
24571
25371
  (async () => {
@@ -24652,7 +25452,7 @@ var LocalLLMConfig = ({ compact, globalUrl, userdata, isLoaded, isLoggedIn, serv
24652
25452
  const activeProvider = optimisticActiveProvider ?? (activeEntryRaw ? providerOfEntry(activeEntryRaw) : SHUFFLE_AI_PRESET);
24653
25453
  const isSelected = option === activeProvider;
24654
25454
  const isValidated = option !== SHUFFLE_AI_PRESET && validatedProviderLabels.has(option);
24655
- return /* @__PURE__ */ (0, import_react25.createElement)("li", { ...props, key: option }, /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_material28.Box, { sx: { display: "flex", alignItems: "center", gap: 1.25, width: "100%", minWidth: 0 }, children: [
25455
+ return /* @__PURE__ */ (0, import_react26.createElement)("li", { ...props, key: option }, /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_material28.Box, { sx: { display: "flex", alignItems: "center", gap: 1.25, width: "100%", minWidth: 0 }, children: [
24656
25456
  /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ProviderLogo, { label: option, url: preset?.url }),
24657
25457
  /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_material28.Typography, { sx: { fontSize: "0.85rem", color: "hsl(var(--popover-foreground))", flexShrink: 0 }, children: option }),
24658
25458
  /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_material28.Box, { sx: { flex: 1, minWidth: 0 } }),
@@ -24848,20 +25648,20 @@ var AgentRunDrawer = ({
24848
25648
  }) => {
24849
25649
  useSyncHostBaseUrl(globalUrl);
24850
25650
  const themeScope = useShuffleMcpTheme();
24851
- const [activeTab, setActiveTab] = (0, import_react26.useState)(initialTab);
24852
- const prevOpenRef = (0, import_react26.useRef)(open);
24853
- (0, import_react26.useEffect)(() => {
25651
+ const [activeTab, setActiveTab] = (0, import_react27.useState)(initialTab);
25652
+ const prevOpenRef = (0, import_react27.useRef)(open);
25653
+ (0, import_react27.useEffect)(() => {
24854
25654
  if (open && !prevOpenRef.current) setActiveTab(initialTab);
24855
25655
  prevOpenRef.current = open;
24856
25656
  }, [open, initialTab]);
24857
- (0, import_react26.useEffect)(() => {
25657
+ (0, import_react27.useEffect)(() => {
24858
25658
  if (typeof window === "undefined") return;
24859
25659
  window.__shuffleAgentDrawerMounted = (window.__shuffleAgentDrawerMounted || 0) + 1;
24860
25660
  return () => {
24861
25661
  window.__shuffleAgentDrawerMounted = Math.max(0, (window.__shuffleAgentDrawerMounted || 1) - 1);
24862
25662
  };
24863
25663
  }, []);
24864
- (0, import_react26.useEffect)(() => {
25664
+ (0, import_react27.useEffect)(() => {
24865
25665
  if (typeof window === "undefined") return;
24866
25666
  const onOpen = (event) => {
24867
25667
  const tab = event.detail?.tab;
@@ -24901,8 +25701,8 @@ var AgentRunDrawer = ({
24901
25701
  });
24902
25702
  const showTabs = visibleTabs.length > 1;
24903
25703
  const safeActiveTab = visibleTabs.includes(activeTab) ? activeTab : "run";
24904
- const paperRef = (0, import_react26.useRef)(null);
24905
- (0, import_react26.useEffect)(() => {
25704
+ const paperRef = (0, import_react27.useRef)(null);
25705
+ (0, import_react27.useEffect)(() => {
24906
25706
  if (!open || safeActiveTab !== "run") return;
24907
25707
  const focusInput = () => {
24908
25708
  if (!paperRef.current) return false;
@@ -24928,6 +25728,7 @@ var AgentRunDrawer = ({
24928
25728
  const drawerWidth = `min(${width}px, 100vw)`;
24929
25729
  const drawerMinWidth = `min(${minWidth}px, 100vw)`;
24930
25730
  const drawerMaxWidth = `min(${maxWidth}px, 100vw)`;
25731
+ const drawerZIndex = useDrawerLayer(open);
24931
25732
  return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
24932
25733
  import_material29.Drawer,
24933
25734
  {
@@ -24935,6 +25736,7 @@ var AgentRunDrawer = ({
24935
25736
  open,
24936
25737
  onClose,
24937
25738
  sx: {
25739
+ zIndex: drawerZIndex,
24938
25740
  "& .MuiDrawer-paper": {
24939
25741
  boxSizing: "border-box",
24940
25742
  width: { xs: "100vw", sm: drawerWidth },
@@ -25090,7 +25892,7 @@ var AgentRunDrawer = ({
25090
25892
  var AgentRunDrawer_default = AgentRunDrawer;
25091
25893
 
25092
25894
  // components/AgentActivityList.tsx
25093
- var import_react27 = require("react");
25895
+ var import_react28 = require("react");
25094
25896
  var import_router_compat4 = require("react-router-dom");
25095
25897
  var import_material30 = require("@mui/material");
25096
25898
  var import_lucide_react18 = require("lucide-react");
@@ -26054,31 +26856,31 @@ var AgentActivityList = ({
26054
26856
  initialRuns,
26055
26857
  disableFetch = false
26056
26858
  }) => {
26057
- const [appDrawer, setAppDrawer] = (0, import_react27.useState)(null);
26058
- const [runs, setRuns] = (0, import_react27.useState)(initialRuns || []);
26059
- const [cursor, setCursor] = (0, import_react27.useState)("");
26060
- const [hasMore, setHasMore] = (0, import_react27.useState)(false);
26061
- const [isLoading, setIsLoading] = (0, import_react27.useState)(false);
26062
- const [error, setError] = (0, import_react27.useState)(null);
26063
- const [statusFilter, setStatusFilter] = (0, import_react27.useState)("");
26064
- const [searchQuery, setSearchQuery] = (0, import_react27.useState)("");
26065
- const [debouncedQuery, setDebouncedQuery] = (0, import_react27.useState)("");
26066
- const [agentWorkflows, setAgentWorkflows] = (0, import_react27.useState)([]);
26067
- const [workflowFilter, setWorkflowFilter] = (0, import_react27.useState)("");
26068
- const [usecaseFilter, setUsecaseFilter] = (0, import_react27.useState)("");
26069
- const [stopOpen, setStopOpen] = (0, import_react27.useState)(false);
26070
- const [stopLoading, setStopLoading] = (0, import_react27.useState)(false);
26071
- const [appIcons, setAppIcons] = (0, import_react27.useState)({});
26072
- const [enrichedRuns, setEnrichedRuns] = (0, import_react27.useState)({});
26073
- const enrichedRunsRef = (0, import_react27.useRef)({});
26074
- const processedRunIdsRef = (0, import_react27.useRef)(/* @__PURE__ */ new Set());
26075
- (0, import_react27.useEffect)(() => {
26859
+ const [appDrawer, setAppDrawer] = (0, import_react28.useState)(null);
26860
+ const [runs, setRuns] = (0, import_react28.useState)(initialRuns || []);
26861
+ const [cursor, setCursor] = (0, import_react28.useState)("");
26862
+ const [hasMore, setHasMore] = (0, import_react28.useState)(false);
26863
+ const [isLoading, setIsLoading] = (0, import_react28.useState)(false);
26864
+ const [error, setError] = (0, import_react28.useState)(null);
26865
+ const [statusFilter, setStatusFilter] = (0, import_react28.useState)("");
26866
+ const [searchQuery, setSearchQuery] = (0, import_react28.useState)("");
26867
+ const [debouncedQuery, setDebouncedQuery] = (0, import_react28.useState)("");
26868
+ const [agentWorkflows, setAgentWorkflows] = (0, import_react28.useState)([]);
26869
+ const [workflowFilter, setWorkflowFilter] = (0, import_react28.useState)("");
26870
+ const [usecaseFilter, setUsecaseFilter] = (0, import_react28.useState)("");
26871
+ const [stopOpen, setStopOpen] = (0, import_react28.useState)(false);
26872
+ const [stopLoading, setStopLoading] = (0, import_react28.useState)(false);
26873
+ const [appIcons, setAppIcons] = (0, import_react28.useState)({});
26874
+ const [enrichedRuns, setEnrichedRuns] = (0, import_react28.useState)({});
26875
+ const enrichedRunsRef = (0, import_react28.useRef)({});
26876
+ const processedRunIdsRef = (0, import_react28.useRef)(/* @__PURE__ */ new Set());
26877
+ (0, import_react28.useEffect)(() => {
26076
26878
  enrichedRunsRef.current = enrichedRuns;
26077
26879
  }, [enrichedRuns]);
26078
- const [abortingIds, setAbortingIds] = (0, import_react27.useState)(/* @__PURE__ */ new Set());
26079
- const [abortedIds, setAbortedIds] = (0, import_react27.useState)(/* @__PURE__ */ new Set());
26080
- const [lastOpenedRunId, setLastOpenedRunId] = (0, import_react27.useState)(() => getLastOpenedAgentRun());
26081
- (0, import_react27.useEffect)(() => {
26880
+ const [abortingIds, setAbortingIds] = (0, import_react28.useState)(/* @__PURE__ */ new Set());
26881
+ const [abortedIds, setAbortedIds] = (0, import_react28.useState)(/* @__PURE__ */ new Set());
26882
+ const [lastOpenedRunId, setLastOpenedRunId] = (0, import_react28.useState)(() => getLastOpenedAgentRun());
26883
+ (0, import_react28.useEffect)(() => {
26082
26884
  const unsubAbort = subscribeAgentAborted((eid) => {
26083
26885
  setAbortedIds((prev) => prev.has(eid) ? prev : /* @__PURE__ */ new Set([...Array.from(prev), eid]));
26084
26886
  setRuns((prev) => prev.map((r) => r.execution_id === eid ? { ...r, status: "ABORTED" } : r));
@@ -26089,9 +26891,9 @@ var AgentActivityList = ({
26089
26891
  unsubOpened();
26090
26892
  };
26091
26893
  }, []);
26092
- const debounceRef = (0, import_react27.useRef)(void 0);
26894
+ const debounceRef = (0, import_react28.useRef)(void 0);
26093
26895
  const selectedAgentWorkflow = agentWorkflows.find((w) => w.id === workflowFilter) || null;
26094
- const openEditPrompt = (0, import_react27.useCallback)(async () => {
26896
+ const openEditPrompt = (0, import_react28.useCallback)(async () => {
26095
26897
  if (!workflowFilter) return;
26096
26898
  try {
26097
26899
  const { prompt, apps } = await getAgentScheduleConfig(workflowFilter, { apiKey, apiBaseUrl, orgId });
@@ -26105,7 +26907,7 @@ var AgentActivityList = ({
26105
26907
  setError(e instanceof Error ? e.message : "Failed to load workflow");
26106
26908
  }
26107
26909
  }, [workflowFilter, selectedAgentWorkflow, apiKey, apiBaseUrl, orgId, onEditWorkflow]);
26108
- const confirmStop = (0, import_react27.useCallback)(async () => {
26910
+ const confirmStop = (0, import_react28.useCallback)(async () => {
26109
26911
  if (!workflowFilter) return;
26110
26912
  setStopLoading(true);
26111
26913
  try {
@@ -26120,7 +26922,7 @@ var AgentActivityList = ({
26120
26922
  setStopLoading(false);
26121
26923
  }
26122
26924
  }, [workflowFilter, apiKey, apiBaseUrl, orgId]);
26123
- const handleAbort = (0, import_react27.useCallback)(
26925
+ const handleAbort = (0, import_react28.useCallback)(
26124
26926
  async (run) => {
26125
26927
  const eid = run.execution_id;
26126
26928
  const wfId = run.workflow_id || run?.workflow?.id;
@@ -26165,15 +26967,15 @@ var AgentActivityList = ({
26165
26967
  },
26166
26968
  [apiKey, apiBaseUrl, orgId]
26167
26969
  );
26168
- const updateSearchQuery = (0, import_react27.useCallback)((q) => {
26970
+ const updateSearchQuery = (0, import_react28.useCallback)((q) => {
26169
26971
  setSearchQuery(q);
26170
26972
  if (debounceRef.current) clearTimeout(debounceRef.current);
26171
26973
  debounceRef.current = setTimeout(() => setDebouncedQuery(q), 350);
26172
26974
  }, []);
26173
- (0, import_react27.useEffect)(() => () => {
26975
+ (0, import_react28.useEffect)(() => () => {
26174
26976
  if (debounceRef.current) clearTimeout(debounceRef.current);
26175
26977
  }, []);
26176
- const fetchRuns = (0, import_react27.useCallback)(
26978
+ const fetchRuns = (0, import_react28.useCallback)(
26177
26979
  async (append = false, cursorParam = "") => {
26178
26980
  if (disableFetch) {
26179
26981
  if (initialRuns && !append) {
@@ -26221,10 +27023,10 @@ var AgentActivityList = ({
26221
27023
  },
26222
27024
  [disableFetch, initialRuns, statusFilter, limit, top, apiKey, apiBaseUrl, orgId, workflowFilter]
26223
27025
  );
26224
- (0, import_react27.useEffect)(() => {
27026
+ (0, import_react28.useEffect)(() => {
26225
27027
  fetchRuns(false, "");
26226
27028
  }, [statusFilter, apiKey, apiBaseUrl, orgId, workflowFilter]);
26227
- (0, import_react27.useEffect)(() => {
27029
+ (0, import_react28.useEffect)(() => {
26228
27030
  let cancelled = false;
26229
27031
  listAgentScheduleWorkflows({ apiKey, apiBaseUrl, orgId }).then((items) => {
26230
27032
  if (!cancelled) setAgentWorkflows(items);
@@ -26234,7 +27036,7 @@ var AgentActivityList = ({
26234
27036
  cancelled = true;
26235
27037
  };
26236
27038
  }, [apiKey, apiBaseUrl, orgId]);
26237
- (0, import_react27.useEffect)(() => {
27039
+ (0, import_react28.useEffect)(() => {
26238
27040
  let cancelled = false;
26239
27041
  fetchAppsViaApiConfig().then((apps) => {
26240
27042
  if (cancelled || !Array.isArray(apps)) return;
@@ -26252,7 +27054,7 @@ var AgentActivityList = ({
26252
27054
  cancelled = true;
26253
27055
  };
26254
27056
  }, []);
26255
- (0, import_react27.useEffect)(() => {
27057
+ (0, import_react28.useEffect)(() => {
26256
27058
  if (!runs.length) return;
26257
27059
  let cancelled = false;
26258
27060
  const buildPatchFromRun = (r) => {
@@ -26391,7 +27193,7 @@ var AgentActivityList = ({
26391
27193
  const merged = patch2 ? { ...r, ...patch2 } : r;
26392
27194
  return r.execution_id && abortedIds.has(r.execution_id) ? { ...merged, status: "ABORTED" } : merged;
26393
27195
  });
26394
- const loadMore = (0, import_react27.useCallback)(() => {
27196
+ const loadMore = (0, import_react28.useCallback)(() => {
26395
27197
  if (cursor && !isLoading) fetchRuns(true, cursor);
26396
27198
  }, [cursor, isLoading, fetchRuns]);
26397
27199
  const activeUsecase = usecaseFilters.find((u) => u.id === usecaseFilter) || null;
@@ -26737,7 +27539,7 @@ var AgentActivityList = ({
26737
27539
  var AgentActivityList_default = AgentActivityList;
26738
27540
 
26739
27541
  // components/AgentExecutionDrawer.tsx
26740
- var import_react28 = require("react");
27542
+ var import_react29 = require("react");
26741
27543
  var import_material31 = require("@mui/material");
26742
27544
  var import_lucide_react20 = require("lucide-react");
26743
27545
  var import_jsx_runtime36 = require("react/jsx-runtime");
@@ -26767,8 +27569,8 @@ var AgentExecutionDrawer = ({
26767
27569
  colorMode
26768
27570
  }) => {
26769
27571
  const themeScope = useShuffleMcpTheme();
26770
- const [bodyReady, setBodyReady] = (0, import_react28.useState)(false);
26771
- (0, import_react28.useEffect)(() => {
27572
+ const [bodyReady, setBodyReady] = (0, import_react29.useState)(false);
27573
+ (0, import_react29.useEffect)(() => {
26772
27574
  if (!open || !run?.execution_id) {
26773
27575
  setBodyReady(false);
26774
27576
  return;
@@ -26782,6 +27584,7 @@ var AgentExecutionDrawer = ({
26782
27584
  const drawerWidth = `min(${width}px, 100vw)`;
26783
27585
  const drawerMinWidth = `min(${minWidth}px, 100vw)`;
26784
27586
  const drawerMaxWidth = `min(${maxWidth}px, 100vw)`;
27587
+ const drawerZIndex = useDrawerLayer(open);
26785
27588
  return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
26786
27589
  import_material31.Drawer,
26787
27590
  {
@@ -26791,7 +27594,7 @@ var AgentExecutionDrawer = ({
26791
27594
  keepMounted: true,
26792
27595
  transitionDuration: { enter: 120, exit: 100 },
26793
27596
  sx: {
26794
- zIndex: 10011,
27597
+ zIndex: drawerZIndex,
26795
27598
  "& .MuiDrawer-paper": {
26796
27599
  boxSizing: "border-box",
26797
27600
  width: { xs: "100vw", sm: drawerWidth },
@@ -26966,7 +27769,7 @@ var AgentExecutionDrawer = ({
26966
27769
  var AgentExecutionDrawer_default = AgentExecutionDrawer;
26967
27770
 
26968
27771
  // views/AgentsView.tsx
26969
- var import_react29 = require("react");
27772
+ var import_react30 = require("react");
26970
27773
  var import_material32 = require("@mui/material");
26971
27774
  init_api();
26972
27775
  var import_jsx_runtime37 = require("react/jsx-runtime");
@@ -27021,21 +27824,21 @@ var AgentsView = ({
27021
27824
  orgId
27022
27825
  }) => {
27023
27826
  useSyncHostBaseUrl(globalUrl);
27024
- const resolvedTheme = (0, import_react29.useMemo)(() => resolveTheme(theme), [theme]);
27025
- const hydratedInitialApps = (0, import_react29.useMemo)(() => {
27827
+ const resolvedTheme = (0, import_react30.useMemo)(() => resolveTheme(theme), [theme]);
27828
+ const hydratedInitialApps = (0, import_react30.useMemo)(() => {
27026
27829
  if (initialApps && initialApps.length > 0) return initialApps;
27027
27830
  if (disableAppsPersistence) return [];
27028
27831
  return readPersistedApps(appsStorageKey) ?? [];
27029
27832
  }, []);
27030
- const [selectedRun, setSelectedRun] = (0, import_react29.useState)(null);
27031
- const [agentView, setAgentView] = (0, import_react29.useState)("start");
27032
- const [prefill, setPrefill] = (0, import_react29.useState)({
27833
+ const [selectedRun, setSelectedRun] = (0, import_react30.useState)(null);
27834
+ const [agentView, setAgentView] = (0, import_react30.useState)("start");
27835
+ const [prefill, setPrefill] = (0, import_react30.useState)({
27033
27836
  input: "",
27034
27837
  apps: hydratedInitialApps,
27035
27838
  key: 0
27036
27839
  });
27037
- const [editing, setEditing] = (0, import_react29.useState)(null);
27038
- const handleAppsChange = (0, import_react29.useCallback)((apps) => {
27840
+ const [editing, setEditing] = (0, import_react30.useState)(null);
27841
+ const handleAppsChange = (0, import_react30.useCallback)((apps) => {
27039
27842
  if (onAppsChange) {
27040
27843
  try {
27041
27844
  onAppsChange(apps);
@@ -27057,13 +27860,13 @@ var AgentsView = ({
27057
27860
  } catch {
27058
27861
  }
27059
27862
  }, [onAppsChange, disableAppsPersistence, appsStorageKey]);
27060
- (0, import_react29.useEffect)(() => {
27863
+ (0, import_react30.useEffect)(() => {
27061
27864
  }, [handleAppsChange]);
27062
- const [builtInDrawer, setBuiltInDrawer] = (0, import_react29.useState)({
27865
+ const [builtInDrawer, setBuiltInDrawer] = (0, import_react30.useState)({
27063
27866
  open: false,
27064
27867
  tab: "localLLM"
27065
27868
  });
27066
- (0, import_react29.useEffect)(() => {
27869
+ (0, import_react30.useEffect)(() => {
27067
27870
  if (typeof window === "undefined") return;
27068
27871
  const handler = (e) => {
27069
27872
  const detail = e.detail;
@@ -27072,14 +27875,14 @@ var AgentsView = ({
27072
27875
  window.addEventListener("agent-drawer-open", handler);
27073
27876
  return () => window.removeEventListener("agent-drawer-open", handler);
27074
27877
  }, []);
27075
- const effectiveSchedule = (0, import_react29.useCallback)(
27878
+ const effectiveSchedule = (0, import_react30.useCallback)(
27076
27879
  async (info) => {
27077
27880
  if (onSchedule) return onSchedule(info);
27078
27881
  await scheduleAgentRun({ ...info, apiKey, apiBaseUrl: globalUrl, orgId });
27079
27882
  },
27080
27883
  [onSchedule, apiKey, globalUrl, orgId]
27081
27884
  );
27082
- const effectiveLocalLLMSlot = (0, import_react29.useMemo)(
27885
+ const effectiveLocalLLMSlot = (0, import_react30.useMemo)(
27083
27886
  () => localLLMSlot ?? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27084
27887
  LocalLLMConfig_default,
27085
27888
  {
@@ -27095,14 +27898,14 @@ var AgentsView = ({
27095
27898
  ),
27096
27899
  [localLLMSlot, builtInDrawer.open, globalUrl, userdata, isLoaded, isLoggedIn, serverside, resolvedTheme, colorMode]
27097
27900
  );
27098
- const handleChooseLLM = (0, import_react29.useCallback)(() => {
27901
+ const handleChooseLLM = (0, import_react30.useCallback)(() => {
27099
27902
  if (onChooseLLM) {
27100
27903
  onChooseLLM();
27101
27904
  return;
27102
27905
  }
27103
27906
  setBuiltInDrawer({ open: true, tab: "localLLM" });
27104
27907
  }, [onChooseLLM]);
27105
- (0, import_react29.useEffect)(() => {
27908
+ (0, import_react30.useEffect)(() => {
27106
27909
  if (typeof window === "undefined") return;
27107
27910
  if (window.location.hash !== "#agent-activity") return;
27108
27911
  const tryScroll = () => {
@@ -27112,7 +27915,7 @@ var AgentsView = ({
27112
27915
  const t = window.setTimeout(tryScroll, 150);
27113
27916
  return () => window.clearTimeout(t);
27114
27917
  }, []);
27115
- const handleEditWorkflow = (0, import_react29.useCallback)(
27918
+ const handleEditWorkflow = (0, import_react30.useCallback)(
27116
27919
  ({ workflowId, name, prompt, apps }) => {
27117
27920
  setEditing({ workflowId, name });
27118
27921
  setPrefill((prev) => ({
@@ -27124,7 +27927,7 @@ var AgentsView = ({
27124
27927
  },
27125
27928
  []
27126
27929
  );
27127
- const handleSaveEdit = (0, import_react29.useCallback)(
27930
+ const handleSaveEdit = (0, import_react30.useCallback)(
27128
27931
  async ({ input, apps }) => {
27129
27932
  if (!editing) return;
27130
27933
  try {
@@ -27261,24 +28064,24 @@ var AgentsView_default = AgentsView;
27261
28064
 
27262
28065
  // components/AddAppModal.tsx
27263
28066
  var import_lucide_react21 = require("lucide-react");
27264
- var import_react31 = require("react");
28067
+ var import_react32 = require("react");
27265
28068
  var import_material33 = require("@mui/material");
27266
28069
  var import_framer_motion9 = require("framer-motion");
27267
28070
  init_api();
27268
28071
 
27269
28072
  // useAppAuthFlow.ts
27270
- var import_react30 = require("react");
28073
+ var import_react31 = require("react");
27271
28074
  init_api();
27272
28075
  function useAppAuthFlow() {
27273
- const [selectedApp, setSelectedApp] = (0, import_react30.useState)(null);
27274
- const [authState, setAuthState] = (0, import_react30.useState)({
28076
+ const [selectedApp, setSelectedApp] = (0, import_react31.useState)(null);
28077
+ const [authState, setAuthState] = (0, import_react31.useState)({
27275
28078
  systemId: "",
27276
28079
  status: "pending",
27277
28080
  credentials: {}
27278
28081
  });
27279
- const [authenticatedApps, setAuthenticatedApps] = (0, import_react30.useState)([]);
27280
- const [authLoading, setAuthLoading] = (0, import_react30.useState)(false);
27281
- const fetchAuthForApp = (0, import_react30.useCallback)(async (appName, appImageUrl) => {
28082
+ const [authenticatedApps, setAuthenticatedApps] = (0, import_react31.useState)([]);
28083
+ const [authLoading, setAuthLoading] = (0, import_react31.useState)(false);
28084
+ const fetchAuthForApp = (0, import_react31.useCallback)(async (appName, appImageUrl) => {
27282
28085
  setAuthLoading(true);
27283
28086
  try {
27284
28087
  const authData = await fetchAuthenticatedApps();
@@ -27299,20 +28102,20 @@ function useAppAuthFlow() {
27299
28102
  setAuthLoading(false);
27300
28103
  }
27301
28104
  }, []);
27302
- const selectApp = (0, import_react30.useCallback)((app2) => {
28105
+ const selectApp = (0, import_react31.useCallback)((app2) => {
27303
28106
  setSelectedApp(app2);
27304
28107
  setAuthState({ systemId: app2.objectID, status: "pending", credentials: {} });
27305
28108
  fetchAuthForApp(app2.name, app2.image_url);
27306
28109
  }, [fetchAuthForApp]);
27307
- const clearSelection = (0, import_react30.useCallback)(() => {
28110
+ const clearSelection = (0, import_react31.useCallback)(() => {
27308
28111
  setSelectedApp(null);
27309
28112
  setAuthState({ systemId: "", status: "pending", credentials: {} });
27310
28113
  setAuthenticatedApps([]);
27311
28114
  }, []);
27312
- const handleAuthChange = (0, import_react30.useCallback)((_appId, credentials) => {
28115
+ const handleAuthChange = (0, import_react31.useCallback)((_appId, credentials) => {
27313
28116
  setAuthState((prev) => ({ ...prev, credentials }));
27314
28117
  }, []);
27315
- const handleTestConnection = (0, import_react30.useCallback)(async (systemId, authenticationId) => {
28118
+ const handleTestConnection = (0, import_react31.useCallback)(async (systemId, authenticationId) => {
27316
28119
  if (!selectedApp) return;
27317
28120
  setAuthState((prev) => ({ ...prev, status: "testing" }));
27318
28121
  try {
@@ -27353,7 +28156,7 @@ function useAppAuthFlow() {
27353
28156
  }));
27354
28157
  }
27355
28158
  }, [selectedApp, fetchAuthForApp]);
27356
- const handleSaveAuth = (0, import_react30.useCallback)(async (appId, credentials) => {
28159
+ const handleSaveAuth = (0, import_react31.useCallback)(async (appId, credentials) => {
27357
28160
  if (!selectedApp) return false;
27358
28161
  const fields = Object.entries(credentials).filter(([key, value]) => key?.trim() && value?.trim()).map(([key, value]) => ({ key, value }));
27359
28162
  const payload = {
@@ -27388,7 +28191,7 @@ function useAppAuthFlow() {
27388
28191
  return false;
27389
28192
  }
27390
28193
  }, [selectedApp, fetchAuthForApp]);
27391
- const refreshAuth = (0, import_react30.useCallback)(async () => {
28194
+ const refreshAuth = (0, import_react31.useCallback)(async () => {
27392
28195
  if (selectedApp) {
27393
28196
  await fetchAuthForApp(selectedApp.name, selectedApp.image_url);
27394
28197
  }
@@ -27487,7 +28290,7 @@ var singulStyles2 = {
27487
28290
  }
27488
28291
  };
27489
28292
  var AddAppModal = ({ open, onClose, initialQuery, categoryLabel }) => {
27490
- const [phase, setPhase] = (0, import_react31.useState)("search");
28293
+ const [phase, setPhase] = (0, import_react32.useState)("search");
27491
28294
  const {
27492
28295
  selectedApp,
27493
28296
  authState,
@@ -27500,7 +28303,7 @@ var AddAppModal = ({ open, onClose, initialQuery, categoryLabel }) => {
27500
28303
  handleSaveAuth,
27501
28304
  refreshAuth
27502
28305
  } = useAppAuthFlow();
27503
- (0, import_react31.useEffect)(() => {
28306
+ (0, import_react32.useEffect)(() => {
27504
28307
  if (!open) {
27505
28308
  setPhase("search");
27506
28309
  clearSelection();
@@ -27656,14 +28459,16 @@ var AskAiButton = ({
27656
28459
  return null;
27657
28460
  }
27658
28461
  const isEffectiveSupport = isSupport !== void 0 ? isSupport : isSupportUser();
27659
- const effectiveRequireSupport = isBeta ? false : requireSupport;
28462
+ const isIncidentOrDocs = currentPath.startsWith("/incidents") || currentPath.startsWith("/incidents-simple") || currentPath.startsWith("/cases") || currentPath.startsWith("/alerts") || currentPath.startsWith("/tickets") || currentPath.startsWith("/docs");
28463
+ const effectiveIsBeta = isBeta || isIncidentOrDocs;
28464
+ const effectiveRequireSupport = effectiveIsBeta ? false : requireSupport;
27660
28465
  if (effectiveRequireSupport && !isEffectiveSupport) {
27661
28466
  return null;
27662
28467
  }
27663
28468
  if (hideWhenOpen && isOpen) {
27664
28469
  return null;
27665
28470
  }
27666
- const effectiveTagLabel = tagLabel !== void 0 ? tagLabel : isBeta ? "Beta" : "Support";
28471
+ const effectiveTagLabel = tagLabel !== void 0 && !(tagLabel === "Support" && isIncidentOrDocs) ? tagLabel : effectiveIsBeta ? "Beta" : "Support";
27667
28472
  const effectiveTooltip = tooltipTitle !== void 0 ? tooltipTitle : label !== "Ask AI" ? label : contextHint ? `Ask AI (${contextHint})` : "Ask AI \u2022 Context-aware assistant";
27668
28473
  return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
27669
28474
  import_material34.Box,
@@ -27754,9 +28559,9 @@ var AskAiButton = ({
27754
28559
  fontWeight: 700,
27755
28560
  textTransform: "uppercase",
27756
28561
  letterSpacing: "0.04em",
27757
- color: isBeta ? "hsl(var(--primary))" : "hsl(var(--muted-foreground))",
27758
- bgcolor: isBeta ? "hsla(var(--primary) / 0.12)" : "hsla(var(--muted-foreground) / 0.12)",
27759
- border: isBeta ? "1px solid hsla(var(--primary) / 0.26)" : "1px solid hsla(var(--muted-foreground) / 0.24)",
28562
+ color: effectiveIsBeta ? "hsl(var(--primary))" : "hsl(var(--muted-foreground))",
28563
+ bgcolor: effectiveIsBeta ? "hsla(var(--primary) / 0.12)" : "hsla(var(--muted-foreground) / 0.12)",
28564
+ border: effectiveIsBeta ? "1px solid hsla(var(--primary) / 0.26)" : "1px solid hsla(var(--muted-foreground) / 0.24)",
27760
28565
  px: 0.9,
27761
28566
  py: 0.25,
27762
28567
  borderRadius: "9999px",
@@ -27775,7 +28580,7 @@ var AskAiButton = ({
27775
28580
  var AskAiButton_default = AskAiButton;
27776
28581
 
27777
28582
  // components/AskAiDrawer.tsx
27778
- var import_react32 = require("react");
28583
+ var import_react33 = require("react");
27779
28584
  var import_material35 = require("@mui/material");
27780
28585
  var import_jsx_runtime40 = require("react/jsx-runtime");
27781
28586
  var AskAiDrawer = ({
@@ -27791,13 +28596,13 @@ var AskAiDrawer = ({
27791
28596
  agentUIProps,
27792
28597
  ...drawerProps
27793
28598
  }) => {
27794
- const [internalPathname, setInternalPathname] = (0, import_react32.useState)(
28599
+ const [internalPathname, setInternalPathname] = (0, import_react33.useState)(
27795
28600
  () => typeof window !== "undefined" ? window.location.pathname : "/"
27796
28601
  );
27797
- const [internalSearch, setInternalSearch] = (0, import_react32.useState)(
28602
+ const [internalSearch, setInternalSearch] = (0, import_react33.useState)(
27798
28603
  () => typeof window !== "undefined" ? window.location.search : ""
27799
28604
  );
27800
- (0, import_react32.useEffect)(() => {
28605
+ (0, import_react33.useEffect)(() => {
27801
28606
  if (propPathname !== void 0) return;
27802
28607
  const updateLoc = () => {
27803
28608
  setInternalPathname(window.location.pathname);
@@ -27808,20 +28613,20 @@ var AskAiDrawer = ({
27808
28613
  }, [propPathname]);
27809
28614
  const activePathname = propPathname !== void 0 ? propPathname : internalPathname;
27810
28615
  const activeSearch = propSearch !== void 0 ? propSearch : internalSearch;
27811
- const [resetKey, setResetKey] = (0, import_react32.useState)(0);
27812
- const resolvedContext = (0, import_react32.useMemo)(
28616
+ const [resetKey, setResetKey] = (0, import_react33.useState)(0);
28617
+ const resolvedContext = (0, import_react33.useMemo)(
27813
28618
  () => resolveAgentContext(activePathname, activeSearch, rules),
27814
28619
  // eslint-disable-next-line react-hooks/exhaustive-deps
27815
28620
  [activePathname, activeSearch, rules, resetKey]
27816
28621
  );
27817
- (0, import_react32.useEffect)(() => {
28622
+ (0, import_react33.useEffect)(() => {
27818
28623
  onContextResolved?.(resolvedContext);
27819
28624
  }, [resolvedContext, onContextResolved]);
27820
- const [isOverridden, setIsOverridden] = (0, import_react32.useState)(resolvedContext.isOverridden);
27821
- (0, import_react32.useEffect)(() => {
28625
+ const [isOverridden, setIsOverridden] = (0, import_react33.useState)(resolvedContext.isOverridden);
28626
+ (0, import_react33.useEffect)(() => {
27822
28627
  setIsOverridden(resolvedContext.isOverridden);
27823
28628
  }, [resolvedContext.isOverridden, resolvedContext.storageKey]);
27824
- const handleAppsChange = (0, import_react32.useCallback)(
28629
+ const handleAppsChange = (0, import_react33.useCallback)(
27825
28630
  (apps) => {
27826
28631
  setPageContextChoice(resolvedContext.storageKey, {
27827
28632
  apps: apps.map((a) => ({ name: a.name, id: a.id, icon: a.icon }))
@@ -27830,7 +28635,7 @@ var AskAiDrawer = ({
27830
28635
  },
27831
28636
  [resolvedContext.storageKey]
27832
28637
  );
27833
- const handleSelectPreset = (0, import_react32.useCallback)(
28638
+ const handleSelectPreset = (0, import_react33.useCallback)(
27834
28639
  (preset) => {
27835
28640
  setPageContextChoice(resolvedContext.storageKey, {
27836
28641
  presetId: preset.id
@@ -27839,7 +28644,7 @@ var AskAiDrawer = ({
27839
28644
  },
27840
28645
  [resolvedContext.storageKey]
27841
28646
  );
27842
- const handleResetToDefaults = (0, import_react32.useCallback)(() => {
28647
+ const handleResetToDefaults = (0, import_react33.useCallback)(() => {
27843
28648
  clearPageContextChoice(resolvedContext.storageKey);
27844
28649
  setIsOverridden(false);
27845
28650
  setResetKey((k) => k + 1);
@@ -27901,10 +28706,11 @@ var AskAiDrawer = ({
27901
28706
  var AskAiDrawer_default = AskAiDrawer;
27902
28707
 
27903
28708
  // components/AskAiSidePanel.tsx
27904
- var import_react33 = __toESM(require("react"));
28709
+ var import_react34 = __toESM(require("react"));
27905
28710
  var import_material36 = require("@mui/material");
27906
28711
  var import_lucide_react22 = require("lucide-react");
27907
28712
  var import_jsx_runtime41 = require("react/jsx-runtime");
28713
+ var import_react35 = require("react");
27908
28714
  var AGENT_DRAWER_OPEN_EVENT = "agent-drawer-open";
27909
28715
  var ASK_AI_PANEL_WIDTH_STORAGE_KEY = "shuffle:ask_ai_panel_width";
27910
28716
  var MIN_ASK_AI_PANEL_WIDTH = 340;
@@ -27936,13 +28742,15 @@ var AskAiSidePanel = ({
27936
28742
  defaultInput,
27937
28743
  serverside,
27938
28744
  colorMode,
28745
+ incidentId: propIncidentId,
28746
+ incidentContext: propIncidentContext,
27939
28747
  sx
27940
28748
  }) => {
27941
28749
  const themeScope = useShuffleMcpTheme();
27942
28750
  const effectiveTheme = theme || (themeScope?.isDark ? "dark" : "light");
27943
- const [currentPathname, setCurrentPathname] = (0, import_react33.useState)(pathname ?? "/");
27944
- const [currentSearch, setCurrentSearch] = (0, import_react33.useState)(search ?? "");
27945
- (0, import_react33.useEffect)(() => {
28751
+ const [currentPathname, setCurrentPathname] = (0, import_react34.useState)(pathname ?? "/");
28752
+ const [currentSearch, setCurrentSearch] = (0, import_react34.useState)(search ?? "");
28753
+ (0, import_react34.useEffect)(() => {
27946
28754
  if (pathname !== void 0) {
27947
28755
  setCurrentPathname(pathname);
27948
28756
  return;
@@ -27958,24 +28766,24 @@ var AskAiSidePanel = ({
27958
28766
  }
27959
28767
  return;
27960
28768
  }, [pathname]);
27961
- (0, import_react33.useEffect)(() => {
28769
+ (0, import_react34.useEffect)(() => {
27962
28770
  if (search !== void 0) {
27963
28771
  setCurrentSearch(search);
27964
28772
  }
27965
28773
  }, [search]);
27966
28774
  const isAgentDisabled = isAgentRoute(currentPathname);
27967
28775
  const isVisible = open && !isAgentDisabled;
27968
- (0, import_react33.useEffect)(() => {
28776
+ (0, import_react34.useEffect)(() => {
27969
28777
  if (isAgentDisabled && open) {
27970
28778
  onClose();
27971
28779
  }
27972
28780
  }, [isAgentDisabled, open, onClose]);
27973
- const context = import_react33.default.useMemo(
28781
+ const context = import_react34.default.useMemo(
27974
28782
  () => resolveAgentContext(currentPathname, currentSearch, rules),
27975
28783
  [currentPathname, currentSearch, rules]
27976
28784
  );
27977
- const [entityTitle, setEntityTitle] = (0, import_react33.useState)(() => getActivePageEntityName());
27978
- (0, import_react33.useEffect)(() => {
28785
+ const [entityTitle, setEntityTitle] = (0, import_react34.useState)(() => getActivePageEntityName());
28786
+ (0, import_react34.useEffect)(() => {
27979
28787
  if (!open) return;
27980
28788
  const current = getActivePageEntityName();
27981
28789
  if (current) setEntityTitle(current);
@@ -28014,46 +28822,62 @@ var AskAiSidePanel = ({
28014
28822
  observer?.disconnect();
28015
28823
  };
28016
28824
  }, [open, currentPathname]);
28017
- const displayTitle = import_react33.default.useMemo(() => {
28825
+ const displayTitle = import_react34.default.useMemo(() => {
28018
28826
  if (context.titleFn) {
28019
28827
  return context.titleFn(entityTitle);
28020
28828
  }
28021
28829
  return context.title || "How can we help on this page?";
28022
28830
  }, [context, entityTitle]);
28023
- (0, import_react33.useEffect)(() => {
28831
+ (0, import_react34.useEffect)(() => {
28024
28832
  onContextResolved?.(context);
28025
28833
  }, [context, onContextResolved]);
28026
28834
  useSyncHostBaseUrl(globalUrl);
28027
- const [internalTab, setInternalTab] = (0, import_react33.useState)(initialTab);
28835
+ const [internalTab, setInternalTab] = (0, import_react34.useState)(initialTab);
28028
28836
  const currentTab = propActiveTab !== void 0 ? propActiveTab : internalTab;
28029
- const [controlledDefaultInput, setControlledDefaultInput] = (0, import_react33.useState)(defaultInput);
28030
- (0, import_react33.useEffect)(() => {
28837
+ const [controlledDefaultInput, setControlledDefaultInput] = (0, import_react34.useState)(defaultInput);
28838
+ const [controlledAutoSubmit, setControlledAutoSubmit] = (0, import_react34.useState)(void 0);
28839
+ (0, import_react34.useEffect)(() => {
28031
28840
  if (defaultInput !== void 0) {
28032
28841
  setControlledDefaultInput(defaultInput);
28033
28842
  }
28034
28843
  }, [defaultInput]);
28035
28844
  const effectiveDefaultInput = controlledDefaultInput ?? defaultInput ?? agentUIProps?.defaultInput;
28036
- const handleTabChange = (0, import_react33.useCallback)(
28845
+ const effectiveAutoSubmit = controlledAutoSubmit ?? agentUIProps?.autoSubmit;
28846
+ const isBetaRoute = context.isBeta === true || currentPathname.startsWith("/incidents") || currentPathname.startsWith("/incidents-simple") || currentPathname.startsWith("/cases") || currentPathname.startsWith("/alerts") || currentPathname.startsWith("/tickets") || currentPathname.startsWith("/docs");
28847
+ const handleTabChange = (0, import_react34.useCallback)(
28037
28848
  (nextTab) => {
28038
28849
  setInternalTab(nextTab);
28039
28850
  onTabChange?.(nextTab);
28040
28851
  },
28041
28852
  [onTabChange]
28042
28853
  );
28043
- (0, import_react33.useEffect)(() => {
28854
+ (0, import_react34.useEffect)(() => {
28044
28855
  if (initialTab) {
28045
28856
  setInternalTab(initialTab);
28046
28857
  }
28047
28858
  }, [initialTab]);
28048
- const prevOpenRef = (0, import_react33.useRef)(open);
28049
- (0, import_react33.useEffect)(() => {
28859
+ const prevOpenRef = (0, import_react34.useRef)(open);
28860
+ (0, import_react34.useEffect)(() => {
28050
28861
  if (open && !prevOpenRef.current && initialTab) {
28051
28862
  setInternalTab(initialTab);
28052
28863
  onTabChange?.(initialTab);
28053
28864
  }
28054
28865
  prevOpenRef.current = open;
28055
28866
  }, [open, initialTab, onTabChange]);
28056
- (0, import_react33.useEffect)(() => {
28867
+ const [activeTaskId, setActiveTaskId] = (0, import_react34.useState)(null);
28868
+ const [activeExecutionId, setActiveExecutionId] = (0, import_react34.useState)(null);
28869
+ const [activeIncidentId, setActiveIncidentId] = (0, import_react34.useState)(null);
28870
+ const [activeIncidentContext, setActiveIncidentContext] = (0, import_react34.useState)(null);
28871
+ const [runResetKey, setRunResetKey] = (0, import_react34.useState)(0);
28872
+ (0, import_react34.useEffect)(() => {
28873
+ if (!open) {
28874
+ setActiveTaskId(null);
28875
+ setActiveExecutionId(null);
28876
+ setActiveIncidentId(null);
28877
+ setActiveIncidentContext(null);
28878
+ }
28879
+ }, [open]);
28880
+ (0, import_react34.useEffect)(() => {
28057
28881
  if (typeof window === "undefined") return;
28058
28882
  window.__shuffleAgentDrawerMounted = (window.__shuffleAgentDrawerMounted || 0) + 1;
28059
28883
  return () => {
@@ -28063,7 +28887,7 @@ var AskAiSidePanel = ({
28063
28887
  );
28064
28888
  };
28065
28889
  }, []);
28066
- (0, import_react33.useEffect)(() => {
28890
+ (0, import_react34.useEffect)(() => {
28067
28891
  if (typeof window === "undefined") return;
28068
28892
  const onOpen = (event) => {
28069
28893
  const detail = event.detail;
@@ -28074,12 +28898,55 @@ var AskAiSidePanel = ({
28074
28898
  if (detail?.defaultInput !== void 0) {
28075
28899
  setControlledDefaultInput(detail.defaultInput);
28076
28900
  }
28901
+ if (detail?.autoSubmit !== void 0) {
28902
+ setControlledAutoSubmit(detail.autoSubmit);
28903
+ }
28904
+ if (detail?.taskId !== void 0) {
28905
+ setActiveTaskId(detail.taskId || null);
28906
+ } else if (!detail?.tab) {
28907
+ setActiveTaskId(null);
28908
+ }
28909
+ if (detail?.incidentId !== void 0) {
28910
+ setActiveIncidentId(detail.incidentId || null);
28911
+ }
28912
+ if (detail?.incidentContext !== void 0) {
28913
+ setActiveIncidentContext(detail.incidentContext || null);
28914
+ }
28915
+ if (detail?.resetExecution) {
28916
+ setActiveExecutionId(null);
28917
+ setRunResetKey((k) => k + 1);
28918
+ } else if (detail?.executionId !== void 0) {
28919
+ setActiveExecutionId(detail.executionId || null);
28920
+ } else if (detail?.taskId) {
28921
+ setActiveExecutionId(null);
28922
+ }
28077
28923
  };
28078
28924
  window.addEventListener(AGENT_DRAWER_OPEN_EVENT, onOpen);
28079
28925
  return () => {
28080
28926
  window.removeEventListener(AGENT_DRAWER_OPEN_EVENT, onOpen);
28081
28927
  };
28082
28928
  }, [handleTabChange]);
28929
+ const handleAgentRun = (0, import_react34.useCallback)(
28930
+ (event) => {
28931
+ if (event.executionId && activeTaskId) {
28932
+ setActiveExecutionId(event.executionId);
28933
+ if (typeof window !== "undefined") {
28934
+ window.dispatchEvent(
28935
+ new CustomEvent("shuffle:task_ai_execution", {
28936
+ detail: {
28937
+ taskId: activeTaskId,
28938
+ executionId: event.executionId,
28939
+ status: event.success ? "running" : "failed"
28940
+ }
28941
+ })
28942
+ );
28943
+ }
28944
+ }
28945
+ },
28946
+ [activeTaskId]
28947
+ );
28948
+ const effectiveStorageKey = activeTaskId ? `${context.storageKey}:task:${activeTaskId}` : context.storageKey;
28949
+ const agentUiKey = activeTaskId ? `${context.storageKey}:task:${activeTaskId}:${activeExecutionId || "fresh"}:${runResetKey}` : `${context.storageKey}:${runResetKey}`;
28083
28950
  const effectiveLocalLLMSlot = localLLMSlot ?? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
28084
28951
  LocalLLMConfig_default,
28085
28952
  {
@@ -28100,8 +28967,8 @@ var AskAiSidePanel = ({
28100
28967
  return false;
28101
28968
  });
28102
28969
  const safeActiveTab = visibleTabs.includes(currentTab) ? currentTab : "run";
28103
- const panelRef = (0, import_react33.useRef)(null);
28104
- (0, import_react33.useEffect)(() => {
28970
+ const panelRef = (0, import_react34.useRef)(null);
28971
+ (0, import_react34.useEffect)(() => {
28105
28972
  if (!isVisible || safeActiveTab !== "run") return;
28106
28973
  const focusInput = () => {
28107
28974
  if (!panelRef.current) return false;
@@ -28124,7 +28991,7 @@ var AskAiSidePanel = ({
28124
28991
  clearTimeout(t3);
28125
28992
  };
28126
28993
  }, [isVisible, safeActiveTab]);
28127
- const [panelWidth, setPanelWidth] = (0, import_react33.useState)(() => {
28994
+ const [panelWidth, setPanelWidth] = (0, import_react34.useState)(() => {
28128
28995
  if (typeof window === "undefined") return width || 380;
28129
28996
  try {
28130
28997
  const stored = localStorage.getItem(ASK_AI_PANEL_WIDTH_STORAGE_KEY);
@@ -28138,15 +29005,15 @@ var AskAiSidePanel = ({
28138
29005
  }
28139
29006
  return width || 380;
28140
29007
  });
28141
- const [isResizing, setIsResizing] = (0, import_react33.useState)(false);
28142
- const prevWidthPropRef = (0, import_react33.useRef)(width);
28143
- (0, import_react33.useEffect)(() => {
29008
+ const [isResizing, setIsResizing] = (0, import_react34.useState)(false);
29009
+ const prevWidthPropRef = (0, import_react34.useRef)(width);
29010
+ (0, import_react34.useEffect)(() => {
28144
29011
  if (width !== prevWidthPropRef.current) {
28145
29012
  prevWidthPropRef.current = width;
28146
29013
  setPanelWidth(width);
28147
29014
  }
28148
29015
  }, [width]);
28149
- const handleResizeStart = (0, import_react33.useCallback)((e) => {
29016
+ const handleResizeStart = (0, import_react34.useCallback)((e) => {
28150
29017
  e.preventDefault();
28151
29018
  e.stopPropagation();
28152
29019
  setIsResizing(true);
@@ -28180,7 +29047,7 @@ var AskAiSidePanel = ({
28180
29047
  window.addEventListener("mousemove", handleMouseMove);
28181
29048
  window.addEventListener("mouseup", handleMouseUp);
28182
29049
  }, [panelWidth]);
28183
- const handleTouchResizeStart = (0, import_react33.useCallback)((e) => {
29050
+ const handleTouchResizeStart = (0, import_react34.useCallback)((e) => {
28184
29051
  if (e.touches.length !== 1) return;
28185
29052
  setIsResizing(true);
28186
29053
  const startX = e.touches[0].clientX;
@@ -28217,7 +29084,7 @@ var AskAiSidePanel = ({
28217
29084
  }, [panelWidth]);
28218
29085
  const effectiveWidth = safeActiveTab === "localLLM" ? Math.max(panelWidth, 520) : panelWidth;
28219
29086
  const effectiveSideshift = sideshift !== void 0 ? sideshift : context.sideshift ?? true;
28220
- (0, import_react33.useEffect)(() => {
29087
+ (0, import_react34.useEffect)(() => {
28221
29088
  if (typeof document === "undefined") return;
28222
29089
  if (open && !isAgentDisabled && effectiveSideshift) {
28223
29090
  document.documentElement.style.setProperty(
@@ -28231,7 +29098,7 @@ var AskAiSidePanel = ({
28231
29098
  document.documentElement.style.setProperty("--ask-ai-panel-width", "0px");
28232
29099
  };
28233
29100
  }, [open, isAgentDisabled, effectiveWidth, effectiveSideshift]);
28234
- const handleAppsChange = (0, import_react33.useCallback)(
29101
+ const handleAppsChange = (0, import_react34.useCallback)(
28235
29102
  (nextApps) => {
28236
29103
  setPageContextChoice(context.storageKey, {
28237
29104
  apps: nextApps.map((a) => ({ name: a.name, id: a.id, icon: a.icon }))
@@ -28240,7 +29107,7 @@ var AskAiSidePanel = ({
28240
29107
  },
28241
29108
  [context.storageKey, agentUIProps]
28242
29109
  );
28243
- const handleSelectPreset = (0, import_react33.useCallback)(
29110
+ const handleSelectPreset = (0, import_react34.useCallback)(
28244
29111
  (preset) => {
28245
29112
  setPageContextChoice(context.storageKey, {
28246
29113
  presetId: preset?.id ?? null
@@ -28385,11 +29252,11 @@ var AskAiSidePanel = ({
28385
29252
  px: 0.75,
28386
29253
  py: 0.2,
28387
29254
  borderRadius: "4px",
28388
- bgcolor: context.isBeta ? "hsla(var(--primary) / 0.12)" : "hsl(var(--muted))",
28389
- color: context.isBeta ? "hsl(var(--primary))" : "hsl(var(--muted-foreground))",
28390
- border: context.isBeta ? "1px solid hsla(var(--primary) / 0.26)" : "1px solid hsl(var(--border))"
29255
+ bgcolor: isBetaRoute ? "hsla(var(--primary) / 0.12)" : "hsl(var(--muted))",
29256
+ color: isBetaRoute ? "hsl(var(--primary))" : "hsl(var(--muted-foreground))",
29257
+ border: isBetaRoute ? "1px solid hsla(var(--primary) / 0.26)" : "1px solid hsl(var(--border))"
28391
29258
  },
28392
- children: context.isBeta ? "Beta" : isLoggedIn ? isSupport ? "Support" : "Agent" : "Guest"
29259
+ children: isBetaRoute ? "Beta" : isLoggedIn ? isSupport ? "Support" : "Agent" : "Guest"
28393
29260
  }
28394
29261
  )
28395
29262
  ] }),
@@ -28647,14 +29514,16 @@ var AskAiSidePanel = ({
28647
29514
  display: "flex",
28648
29515
  flexDirection: "column"
28649
29516
  },
28650
- children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
29517
+ children: /* @__PURE__ */ (0, import_react35.createElement)(
28651
29518
  AgentUI_default,
28652
29519
  {
29520
+ ...agentUIProps,
29521
+ key: agentUiKey,
28653
29522
  sidebarLayout: true,
28654
29523
  compact: true,
28655
29524
  mobileView: true,
28656
29525
  hideHeroIcon: true,
28657
- title: displayTitle,
29526
+ title: activeTaskId ? "Task AI Agent" : displayTitle,
28658
29527
  subtitle: null,
28659
29528
  hideChooseLLM: !isLoggedIn,
28660
29529
  isLoggedIn,
@@ -28665,16 +29534,21 @@ var AskAiSidePanel = ({
28665
29534
  initialPresetId: context.presetId,
28666
29535
  placeholder: context.placeholder,
28667
29536
  contextCategory: context.sourceCategory,
28668
- contextStorageKey: context.storageKey,
29537
+ contextStorageKey: effectiveStorageKey,
28669
29538
  contextParams: context.params,
28670
29539
  composeSubmitInput: context.composeInput,
28671
29540
  defaultInput: effectiveDefaultInput,
29541
+ autoSubmit: effectiveAutoSubmit,
29542
+ executionId: activeExecutionId || void 0,
29543
+ initialExecution: activeExecutionId ? { execution_id: activeExecutionId } : void 0,
29544
+ onRun: handleAgentRun,
28672
29545
  onAppsChange: handleAppsChange,
28673
29546
  onSelectPreset: handleSelectPreset,
28674
29547
  onChooseLLM: () => handleTabChange("localLLM"),
29548
+ incidentId: activeIncidentId || propIncidentId || agentUIProps?.incidentId,
29549
+ incidentContext: activeIncidentContext || propIncidentContext || agentUIProps?.incidentContext,
28675
29550
  apiBaseUrl: globalUrl || agentUIProps?.apiBaseUrl,
28676
29551
  theme: effectiveTheme,
28677
- ...agentUIProps,
28678
29552
  sx: {
28679
29553
  flex: 1,
28680
29554
  height: "100%",
@@ -28685,8 +29559,7 @@ var AskAiSidePanel = ({
28685
29559
  pb: 0,
28686
29560
  ...agentUIProps?.sx ? Array.isArray(agentUIProps.sx) ? {} : agentUIProps.sx : {}
28687
29561
  }
28688
- },
28689
- context.storageKey
29562
+ }
28690
29563
  )
28691
29564
  }
28692
29565
  )
@@ -28699,7 +29572,7 @@ var AskAiSidePanel = ({
28699
29572
  var AskAiSidePanel_default = AskAiSidePanel;
28700
29573
 
28701
29574
  // components/AskAiWidget.tsx
28702
- var import_react34 = require("react");
29575
+ var import_react36 = require("react");
28703
29576
  var import_jsx_runtime42 = require("react/jsx-runtime");
28704
29577
  var AGENT_DRAWER_OPEN_EVENT2 = "agent-drawer-open";
28705
29578
  var AskAiWidget = ({
@@ -28719,11 +29592,11 @@ var AskAiWidget = ({
28719
29592
  localLLMSlot,
28720
29593
  ...panelProps
28721
29594
  }) => {
28722
- const [internalOpen, setInternalOpen] = (0, import_react34.useState)(false);
28723
- const [activeTab, setActiveTab] = (0, import_react34.useState)(propInitialTab);
29595
+ const [internalOpen, setInternalOpen] = (0, import_react36.useState)(false);
29596
+ const [activeTab, setActiveTab] = (0, import_react36.useState)(propInitialTab);
28724
29597
  const isDrawerOpen = controlledOpen !== void 0 ? controlledOpen : internalOpen;
28725
- const [browserLocation, setBrowserLocation] = (0, import_react34.useState)({ path: "", search: "" });
28726
- (0, import_react34.useEffect)(() => {
29598
+ const [browserLocation, setBrowserLocation] = (0, import_react36.useState)({ path: "", search: "" });
29599
+ (0, import_react36.useEffect)(() => {
28727
29600
  if (pathname !== void 0 && search !== void 0) return;
28728
29601
  const syncLocation = () => setBrowserLocation({
28729
29602
  path: window.location.pathname,
@@ -28735,7 +29608,7 @@ var AskAiWidget = ({
28735
29608
  }, [pathname, search]);
28736
29609
  const currentPath = pathname ?? browserLocation.path;
28737
29610
  const isAgentDisabled = isAgentRoute(currentPath);
28738
- const setDrawerOpen = (0, import_react34.useCallback)(
29611
+ const setDrawerOpen = (0, import_react36.useCallback)(
28739
29612
  (nextOpen) => {
28740
29613
  if (isAgentDisabled && nextOpen) return;
28741
29614
  if (controlledOpen === void 0) {
@@ -28745,25 +29618,25 @@ var AskAiWidget = ({
28745
29618
  },
28746
29619
  [controlledOpen, isAgentDisabled, onOpenChange]
28747
29620
  );
28748
- (0, import_react34.useEffect)(() => {
29621
+ (0, import_react36.useEffect)(() => {
28749
29622
  if (isAgentDisabled && isDrawerOpen) {
28750
29623
  setDrawerOpen(false);
28751
29624
  }
28752
29625
  }, [isAgentDisabled, isDrawerOpen, setDrawerOpen]);
28753
29626
  const currentSearch = search ?? browserLocation.search;
28754
- const resolvedContext = (0, import_react34.useMemo)(() => {
29627
+ const resolvedContext = (0, import_react36.useMemo)(() => {
28755
29628
  return resolveAgentContext(currentPath, currentSearch, rules);
28756
29629
  }, [currentPath, currentSearch, rules]);
28757
- const [reportedContext, setReportedContext] = (0, import_react34.useState)(null);
29630
+ const [reportedContext, setReportedContext] = (0, import_react36.useState)(null);
28758
29631
  const activeContext = reportedContext && reportedContext.path === currentPath && reportedContext.search === currentSearch ? reportedContext.ctx : resolvedContext;
28759
- const handleContextResolved = (0, import_react34.useCallback)(
29632
+ const handleContextResolved = (0, import_react36.useCallback)(
28760
29633
  (ctx) => {
28761
29634
  setReportedContext({ path: currentPath, search: currentSearch, ctx });
28762
29635
  onContextResolved?.(ctx);
28763
29636
  },
28764
29637
  [currentPath, currentSearch, onContextResolved]
28765
29638
  );
28766
- (0, import_react34.useEffect)(() => {
29639
+ (0, import_react36.useEffect)(() => {
28767
29640
  const handleDrawerOpenEvent = (e) => {
28768
29641
  if (isAgentDisabled) return;
28769
29642
  const detail = e.detail;
@@ -28775,17 +29648,18 @@ var AskAiWidget = ({
28775
29648
  window.addEventListener(AGENT_DRAWER_OPEN_EVENT2, handleDrawerOpenEvent);
28776
29649
  return () => window.removeEventListener(AGENT_DRAWER_OPEN_EVENT2, handleDrawerOpenEvent);
28777
29650
  }, [isAgentDisabled, setDrawerOpen]);
28778
- (0, import_react34.useEffect)(() => {
29651
+ (0, import_react36.useEffect)(() => {
28779
29652
  if (propInitialTab) {
28780
29653
  setActiveTab(propInitialTab);
28781
29654
  }
28782
29655
  }, [propInitialTab]);
28783
29656
  const effectiveButtonLabel = buttonProps?.label || (activeContext.buttonLabelFn ? activeContext.buttonLabelFn() : activeContext.buttonLabel) || "Ask AI";
28784
- const isBeta = activeContext.isBeta === true;
29657
+ const isIncidentOrDocsRoute = currentPath.startsWith("/incidents") || currentPath.startsWith("/incidents-simple") || currentPath.startsWith("/cases") || currentPath.startsWith("/alerts") || currentPath.startsWith("/tickets") || currentPath.startsWith("/docs");
29658
+ const isBeta = activeContext.isBeta === true || isIncidentOrDocsRoute;
28785
29659
  const effectiveRequireSupport = isBeta ? false : requireSupport;
28786
29660
  const defaultTag = isBeta ? "Beta" : "Support";
28787
29661
  const effectiveTagLabel = buttonProps?.tagLabel !== void 0 ? buttonProps.tagLabel : defaultTag;
28788
- (0, import_react34.useEffect)(() => {
29662
+ (0, import_react36.useEffect)(() => {
28789
29663
  if (effectiveRequireSupport && !isSupport && isDrawerOpen) {
28790
29664
  setDrawerOpen(false);
28791
29665
  }
@@ -28845,10 +29719,10 @@ var AskAiWidget = ({
28845
29719
  ] });
28846
29720
  };
28847
29721
  var useContextAwareAgent = (pathname, search) => {
28848
- const [activeContext, setActiveContext] = (0, import_react34.useState)(
29722
+ const [activeContext, setActiveContext] = (0, import_react36.useState)(
28849
29723
  () => resolveAgentContext(pathname ?? "/", search ?? "")
28850
29724
  );
28851
- (0, import_react34.useEffect)(() => {
29725
+ (0, import_react36.useEffect)(() => {
28852
29726
  const p = pathname ?? (typeof window !== "undefined" ? window.location.pathname : "/");
28853
29727
  const s = search ?? (typeof window !== "undefined" ? window.location.search : "");
28854
29728
  setActiveContext(resolveAgentContext(p, s));
@@ -28858,7 +29732,7 @@ var useContextAwareAgent = (pathname, search) => {
28858
29732
  var AskAiWidget_default = AskAiWidget;
28859
29733
 
28860
29734
  // components/AgentPromptPrefixChip.tsx
28861
- var import_react35 = require("react");
29735
+ var import_react37 = require("react");
28862
29736
  var import_material37 = require("@mui/material");
28863
29737
  var import_lucide_react23 = require("lucide-react");
28864
29738
  var import_jsx_runtime43 = require("react/jsx-runtime");
@@ -28876,9 +29750,9 @@ var AgentPromptPrefixChip = ({
28876
29750
  const managed = useAgentPromptPrefix({ userId, defaultPrompt, persist: !controlled });
28877
29751
  const prompt = controlled ? value : managed.prompt;
28878
29752
  const isSaving = controlled ? false : managed.isSaving;
28879
- const [open, setOpen] = (0, import_react35.useState)(false);
28880
- const [draft, setDraft] = (0, import_react35.useState)(prompt);
28881
- (0, import_react35.useEffect)(() => {
29753
+ const [open, setOpen] = (0, import_react37.useState)(false);
29754
+ const [draft, setDraft] = (0, import_react37.useState)(prompt);
29755
+ (0, import_react37.useEffect)(() => {
28882
29756
  if (!open) setDraft(prompt);
28883
29757
  }, [prompt, open]);
28884
29758
  const handleOpen = () => {
@@ -29886,14 +30760,14 @@ var DEMO_AGENT_RUNS = [
29886
30760
  ];
29887
30761
 
29888
30762
  // useAppLookup.ts
29889
- var import_react36 = require("react");
30763
+ var import_react38 = require("react");
29890
30764
  init_api();
29891
30765
  init_appsCache();
29892
30766
  var norm3 = (s) => s.toLowerCase().replace(/[\s_\-]+/g, "_");
29893
30767
  function useAppLookup(appName) {
29894
- const [loading, setLoading] = (0, import_react36.useState)(false);
29895
- const [info, setInfo] = (0, import_react36.useState)(null);
29896
- const [algoliaId, setAlgoliaId] = (0, import_react36.useState)(null);
30768
+ const [loading, setLoading] = (0, import_react38.useState)(false);
30769
+ const [info, setInfo] = (0, import_react38.useState)(null);
30770
+ const [algoliaId, setAlgoliaId] = (0, import_react38.useState)(null);
29897
30771
  const {
29898
30772
  authStates,
29899
30773
  authenticatedApps,
@@ -29902,7 +30776,7 @@ function useAppLookup(appName) {
29902
30776
  handleSaveAuth,
29903
30777
  refreshAuth
29904
30778
  } = useAppAuth();
29905
- (0, import_react36.useEffect)(() => {
30779
+ (0, import_react38.useEffect)(() => {
29906
30780
  if (!appName) {
29907
30781
  setInfo(null);
29908
30782
  setAlgoliaId(null);
@@ -29973,13 +30847,13 @@ function useAppLookup(appName) {
29973
30847
  setLoading(false);
29974
30848
  })();
29975
30849
  }, [appName]);
29976
- const matchingEntries = (0, import_react36.useMemo)(() => {
30850
+ const matchingEntries = (0, import_react38.useMemo)(() => {
29977
30851
  if (!appName) return [];
29978
30852
  return authenticatedApps.filter(
29979
30853
  (auth) => auth.app?.name && norm3(auth.app.name) === norm3(appName)
29980
30854
  );
29981
30855
  }, [appName, authenticatedApps]);
29982
- const image = (0, import_react36.useMemo)(() => {
30856
+ const image = (0, import_react38.useMemo)(() => {
29983
30857
  if (info?.image) return info.image;
29984
30858
  for (const entry of matchingEntries) {
29985
30859
  const img = entry.app?.large_image || entry.large_image;
@@ -29987,7 +30861,7 @@ function useAppLookup(appName) {
29987
30861
  }
29988
30862
  return "";
29989
30863
  }, [info, matchingEntries]);
29990
- const algoliaApp = (0, import_react36.useMemo)(() => {
30864
+ const algoliaApp = (0, import_react38.useMemo)(() => {
29991
30865
  if (!appName) return null;
29992
30866
  return {
29993
30867
  objectID: algoliaId || appName,
@@ -30029,20 +30903,20 @@ var resolveMode = (theme, colorMode) => {
30029
30903
  return "auto";
30030
30904
  };
30031
30905
  var withMcpTheme = (Inner, displayName2) => {
30032
- const Wrapped = ({ theme, colorMode, ...rest }) => import_react37.default.createElement(
30906
+ const Wrapped = ({ theme, colorMode, ...rest }) => import_react39.default.createElement(
30033
30907
  ShuffleMcpThemeProvider,
30034
30908
  { mode: resolveMode(theme, colorMode) },
30035
- import_react37.default.createElement(Inner, { ...rest, theme, colorMode })
30909
+ import_react39.default.createElement(Inner, { ...rest, theme, colorMode })
30036
30910
  );
30037
30911
  Wrapped.displayName = `ShuffleMCPs(${displayName2})`;
30038
30912
  return Wrapped;
30039
30913
  };
30040
30914
  var withMcpThemeRef = (Inner, displayName2) => {
30041
- const Wrapped = import_react37.default.forwardRef(
30042
- ({ theme, colorMode, ...rest }, ref) => import_react37.default.createElement(
30915
+ const Wrapped = import_react39.default.forwardRef(
30916
+ ({ theme, colorMode, ...rest }, ref) => import_react39.default.createElement(
30043
30917
  ShuffleMcpThemeProvider,
30044
30918
  { mode: resolveMode(theme, colorMode) },
30045
- import_react37.default.createElement(Inner, { ...rest, theme, colorMode, ref })
30919
+ import_react39.default.createElement(Inner, { ...rest, theme, colorMode, ref })
30046
30920
  )
30047
30921
  );
30048
30922
  Wrapped.displayName = `ShuffleMCPs(${displayName2})`;