@shuffleio/shuffle-mcps 0.0.27 → 0.0.29

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.d.mts CHANGED
@@ -810,10 +810,14 @@ interface AgentsViewProps extends ShuffleHostProps {
810
810
  localLLMSlot?: React.ReactNode;
811
811
  /** Content for the built-in AgentRunDrawer's Permissions tab. Optional. */
812
812
  permissionsSlot?: React.ReactNode;
813
- /** Pre-fill the starter chip row on mount (e.g. from persisted host state). */
813
+ /** Pre-fill the starter chip row on mount (e.g. from persisted host state). When omitted, AgentsView restores its own persisted selection from localStorage (24h TTL). */
814
814
  initialApps?: AgentUIApp[];
815
- /** Called whenever the chip row under the prompt changes. */
815
+ /** Called whenever the chip row under the prompt changes. When omitted, AgentsView still persists internally. */
816
816
  onAppsChange?: (apps: AgentUIApp[]) => void;
817
+ /** Disable AgentsView's internal localStorage persistence of the chip row. */
818
+ disableAppsPersistence?: boolean;
819
+ /** Storage key for internal chip-row persistence. Defaults to `shuffle-agents-selected-apps`. */
820
+ appsStorageKey?: string;
817
821
  }
818
822
 
819
823
  interface AgentLocalModel {
package/dist/index.d.ts CHANGED
@@ -810,10 +810,14 @@ interface AgentsViewProps extends ShuffleHostProps {
810
810
  localLLMSlot?: React.ReactNode;
811
811
  /** Content for the built-in AgentRunDrawer's Permissions tab. Optional. */
812
812
  permissionsSlot?: React.ReactNode;
813
- /** Pre-fill the starter chip row on mount (e.g. from persisted host state). */
813
+ /** Pre-fill the starter chip row on mount (e.g. from persisted host state). When omitted, AgentsView restores its own persisted selection from localStorage (24h TTL). */
814
814
  initialApps?: AgentUIApp[];
815
- /** Called whenever the chip row under the prompt changes. */
815
+ /** Called whenever the chip row under the prompt changes. When omitted, AgentsView still persists internally. */
816
816
  onAppsChange?: (apps: AgentUIApp[]) => void;
817
+ /** Disable AgentsView's internal localStorage persistence of the chip row. */
818
+ disableAppsPersistence?: boolean;
819
+ /** Storage key for internal chip-row persistence. Defaults to `shuffle-agents-selected-apps`. */
820
+ appsStorageKey?: string;
817
821
  }
818
822
 
819
823
  interface AgentLocalModel {
package/dist/index.js CHANGED
@@ -14182,7 +14182,35 @@ var AgentExecutionDrawer_default = AgentExecutionDrawer;
14182
14182
  // views/AgentsView.tsx
14183
14183
  var import_react20 = require("react");
14184
14184
  var import_material22 = require("@mui/material");
14185
+ init_api();
14185
14186
  var import_jsx_runtime26 = require("react/jsx-runtime");
14187
+ var APPS_TTL_MS = 24 * 60 * 60 * 1e3;
14188
+ var DEFAULT_APPS_STORAGE_KEY = "shuffle-agents-selected-apps";
14189
+ var readPersistedApps = (storageKey) => {
14190
+ try {
14191
+ if (typeof window === "undefined") return void 0;
14192
+ const raw = window.localStorage.getItem(storageKey);
14193
+ if (!raw) return void 0;
14194
+ const parsed = JSON.parse(raw);
14195
+ if (!parsed?.savedAt || !Array.isArray(parsed.apps) || parsed.apps.length === 0) return void 0;
14196
+ if (Date.now() - parsed.savedAt > APPS_TTL_MS) {
14197
+ window.localStorage.removeItem(storageKey);
14198
+ return void 0;
14199
+ }
14200
+ return parsed.apps.filter((a) => a && typeof a.name === "string");
14201
+ } catch {
14202
+ return void 0;
14203
+ }
14204
+ };
14205
+ var resolveTheme = (theme) => {
14206
+ if (theme === "light" || theme === "dark") return theme;
14207
+ if (typeof window === "undefined" || !window.matchMedia) return theme;
14208
+ try {
14209
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
14210
+ } catch {
14211
+ return void 0;
14212
+ }
14213
+ };
14186
14214
  var AgentsView = ({
14187
14215
  onSchedule,
14188
14216
  maxWidth = 820,
@@ -14192,7 +14220,9 @@ var AgentsView = ({
14192
14220
  permissionsSlot,
14193
14221
  initialApps,
14194
14222
  onAppsChange,
14195
- globalUrl,
14223
+ disableAppsPersistence,
14224
+ appsStorageKey = DEFAULT_APPS_STORAGE_KEY,
14225
+ globalUrl = API_CONFIG.baseUrl,
14196
14226
  isLoaded,
14197
14227
  isLoggedIn,
14198
14228
  userdata,
@@ -14203,14 +14233,44 @@ var AgentsView = ({
14203
14233
  orgId
14204
14234
  }) => {
14205
14235
  useSyncHostBaseUrl(globalUrl);
14236
+ const resolvedTheme = (0, import_react20.useMemo)(() => resolveTheme(theme), [theme]);
14237
+ const hydratedInitialApps = (0, import_react20.useMemo)(() => {
14238
+ if (initialApps && initialApps.length > 0) return initialApps;
14239
+ if (disableAppsPersistence) return [];
14240
+ return readPersistedApps(appsStorageKey) ?? [];
14241
+ }, []);
14206
14242
  const [selectedRun, setSelectedRun] = (0, import_react20.useState)(null);
14207
14243
  const [agentView, setAgentView] = (0, import_react20.useState)("start");
14208
14244
  const [prefill, setPrefill] = (0, import_react20.useState)({
14209
14245
  input: "",
14210
- apps: initialApps && initialApps.length > 0 ? initialApps : [],
14246
+ apps: hydratedInitialApps,
14211
14247
  key: 0
14212
14248
  });
14213
14249
  const [editing, setEditing] = (0, import_react20.useState)(null);
14250
+ const handleAppsChange = (0, import_react20.useCallback)((apps) => {
14251
+ if (onAppsChange) {
14252
+ try {
14253
+ onAppsChange(apps);
14254
+ } catch {
14255
+ }
14256
+ }
14257
+ if (disableAppsPersistence) return;
14258
+ try {
14259
+ if (typeof window === "undefined") return;
14260
+ if (!apps || apps.length === 0) {
14261
+ window.localStorage.removeItem(appsStorageKey);
14262
+ return;
14263
+ }
14264
+ const slim = apps.filter((a) => a && typeof a.name === "string").map((a) => ({ name: a.name, id: a.id, icon: a.icon }));
14265
+ window.localStorage.setItem(
14266
+ appsStorageKey,
14267
+ JSON.stringify({ savedAt: Date.now(), apps: slim })
14268
+ );
14269
+ } catch {
14270
+ }
14271
+ }, [onAppsChange, disableAppsPersistence, appsStorageKey]);
14272
+ (0, import_react20.useEffect)(() => {
14273
+ }, [handleAppsChange]);
14214
14274
  const [builtInDrawer, setBuiltInDrawer] = (0, import_react20.useState)({
14215
14275
  open: false,
14216
14276
  tab: "localLLM"
@@ -14231,11 +14291,11 @@ var AgentsView = ({
14231
14291
  isLoaded,
14232
14292
  isLoggedIn,
14233
14293
  serverside,
14234
- theme,
14294
+ theme: resolvedTheme,
14235
14295
  colorMode
14236
14296
  }
14237
14297
  ),
14238
- [localLLMSlot, globalUrl, userdata, isLoaded, isLoggedIn, serverside, theme, colorMode]
14298
+ [localLLMSlot, globalUrl, userdata, isLoaded, isLoggedIn, serverside, resolvedTheme, colorMode]
14239
14299
  );
14240
14300
  const handleChooseLLM = (0, import_react20.useCallback)(() => {
14241
14301
  if (onChooseLLM) {
@@ -14341,9 +14401,9 @@ var AgentsView = ({
14341
14401
  submitTooltip: editing ? "\u2318+Enter to save" : void 0,
14342
14402
  disableSchedule: Boolean(editing),
14343
14403
  disableScheduleTooltip: editing ? "Scheduling is disabled while editing an existing schedule" : void 0,
14344
- theme,
14404
+ theme: resolvedTheme,
14345
14405
  colorMode,
14346
- onAppsChange
14406
+ onAppsChange: handleAppsChange
14347
14407
  },
14348
14408
  prefill.key
14349
14409
  ),
@@ -14368,7 +14428,7 @@ var AgentsView = ({
14368
14428
  onSchedule: effectiveSchedule,
14369
14429
  apiKey,
14370
14430
  orgId,
14371
- theme,
14431
+ theme: resolvedTheme,
14372
14432
  colorMode
14373
14433
  }
14374
14434
  ),
@@ -14381,9 +14441,9 @@ var AgentsView = ({
14381
14441
  globalUrl,
14382
14442
  localLLMSlot: effectiveLocalLLMSlot,
14383
14443
  permissionsSlot,
14384
- theme,
14444
+ theme: resolvedTheme,
14385
14445
  colorMode,
14386
- agentUIProps: { onSchedule: effectiveSchedule, apiBaseUrl: globalUrl, apiKey, orgId, theme, colorMode }
14446
+ agentUIProps: { onSchedule: effectiveSchedule, apiBaseUrl: globalUrl, apiKey, orgId, theme: resolvedTheme, colorMode }
14387
14447
  }
14388
14448
  )
14389
14449
  ] });
package/dist/index.mjs CHANGED
@@ -13879,9 +13879,36 @@ var AgentExecutionDrawer = ({
13879
13879
  var AgentExecutionDrawer_default = AgentExecutionDrawer;
13880
13880
 
13881
13881
  // views/AgentsView.tsx
13882
- import { useCallback as useCallback10, useMemo as useMemo8, useState as useState16 } from "react";
13882
+ import { useCallback as useCallback10, useEffect as useEffect15, useMemo as useMemo8, useState as useState16 } from "react";
13883
13883
  import { Box as Box20, Stack, Typography as Typography19 } from "@mui/material";
13884
13884
  import { jsx as jsx26, jsxs as jsxs23 } from "react/jsx-runtime";
13885
+ var APPS_TTL_MS = 24 * 60 * 60 * 1e3;
13886
+ var DEFAULT_APPS_STORAGE_KEY = "shuffle-agents-selected-apps";
13887
+ var readPersistedApps = (storageKey) => {
13888
+ try {
13889
+ if (typeof window === "undefined") return void 0;
13890
+ const raw = window.localStorage.getItem(storageKey);
13891
+ if (!raw) return void 0;
13892
+ const parsed = JSON.parse(raw);
13893
+ if (!parsed?.savedAt || !Array.isArray(parsed.apps) || parsed.apps.length === 0) return void 0;
13894
+ if (Date.now() - parsed.savedAt > APPS_TTL_MS) {
13895
+ window.localStorage.removeItem(storageKey);
13896
+ return void 0;
13897
+ }
13898
+ return parsed.apps.filter((a) => a && typeof a.name === "string");
13899
+ } catch {
13900
+ return void 0;
13901
+ }
13902
+ };
13903
+ var resolveTheme = (theme) => {
13904
+ if (theme === "light" || theme === "dark") return theme;
13905
+ if (typeof window === "undefined" || !window.matchMedia) return theme;
13906
+ try {
13907
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
13908
+ } catch {
13909
+ return void 0;
13910
+ }
13911
+ };
13885
13912
  var AgentsView = ({
13886
13913
  onSchedule,
13887
13914
  maxWidth = 820,
@@ -13891,7 +13918,9 @@ var AgentsView = ({
13891
13918
  permissionsSlot,
13892
13919
  initialApps,
13893
13920
  onAppsChange,
13894
- globalUrl,
13921
+ disableAppsPersistence,
13922
+ appsStorageKey = DEFAULT_APPS_STORAGE_KEY,
13923
+ globalUrl = API_CONFIG.baseUrl,
13895
13924
  isLoaded,
13896
13925
  isLoggedIn,
13897
13926
  userdata,
@@ -13902,14 +13931,44 @@ var AgentsView = ({
13902
13931
  orgId
13903
13932
  }) => {
13904
13933
  useSyncHostBaseUrl(globalUrl);
13934
+ const resolvedTheme = useMemo8(() => resolveTheme(theme), [theme]);
13935
+ const hydratedInitialApps = useMemo8(() => {
13936
+ if (initialApps && initialApps.length > 0) return initialApps;
13937
+ if (disableAppsPersistence) return [];
13938
+ return readPersistedApps(appsStorageKey) ?? [];
13939
+ }, []);
13905
13940
  const [selectedRun, setSelectedRun] = useState16(null);
13906
13941
  const [agentView, setAgentView] = useState16("start");
13907
13942
  const [prefill, setPrefill] = useState16({
13908
13943
  input: "",
13909
- apps: initialApps && initialApps.length > 0 ? initialApps : [],
13944
+ apps: hydratedInitialApps,
13910
13945
  key: 0
13911
13946
  });
13912
13947
  const [editing, setEditing] = useState16(null);
13948
+ const handleAppsChange = useCallback10((apps) => {
13949
+ if (onAppsChange) {
13950
+ try {
13951
+ onAppsChange(apps);
13952
+ } catch {
13953
+ }
13954
+ }
13955
+ if (disableAppsPersistence) return;
13956
+ try {
13957
+ if (typeof window === "undefined") return;
13958
+ if (!apps || apps.length === 0) {
13959
+ window.localStorage.removeItem(appsStorageKey);
13960
+ return;
13961
+ }
13962
+ const slim = apps.filter((a) => a && typeof a.name === "string").map((a) => ({ name: a.name, id: a.id, icon: a.icon }));
13963
+ window.localStorage.setItem(
13964
+ appsStorageKey,
13965
+ JSON.stringify({ savedAt: Date.now(), apps: slim })
13966
+ );
13967
+ } catch {
13968
+ }
13969
+ }, [onAppsChange, disableAppsPersistence, appsStorageKey]);
13970
+ useEffect15(() => {
13971
+ }, [handleAppsChange]);
13913
13972
  const [builtInDrawer, setBuiltInDrawer] = useState16({
13914
13973
  open: false,
13915
13974
  tab: "localLLM"
@@ -13930,11 +13989,11 @@ var AgentsView = ({
13930
13989
  isLoaded,
13931
13990
  isLoggedIn,
13932
13991
  serverside,
13933
- theme,
13992
+ theme: resolvedTheme,
13934
13993
  colorMode
13935
13994
  }
13936
13995
  ),
13937
- [localLLMSlot, globalUrl, userdata, isLoaded, isLoggedIn, serverside, theme, colorMode]
13996
+ [localLLMSlot, globalUrl, userdata, isLoaded, isLoggedIn, serverside, resolvedTheme, colorMode]
13938
13997
  );
13939
13998
  const handleChooseLLM = useCallback10(() => {
13940
13999
  if (onChooseLLM) {
@@ -14040,9 +14099,9 @@ var AgentsView = ({
14040
14099
  submitTooltip: editing ? "\u2318+Enter to save" : void 0,
14041
14100
  disableSchedule: Boolean(editing),
14042
14101
  disableScheduleTooltip: editing ? "Scheduling is disabled while editing an existing schedule" : void 0,
14043
- theme,
14102
+ theme: resolvedTheme,
14044
14103
  colorMode,
14045
- onAppsChange
14104
+ onAppsChange: handleAppsChange
14046
14105
  },
14047
14106
  prefill.key
14048
14107
  ),
@@ -14067,7 +14126,7 @@ var AgentsView = ({
14067
14126
  onSchedule: effectiveSchedule,
14068
14127
  apiKey,
14069
14128
  orgId,
14070
- theme,
14129
+ theme: resolvedTheme,
14071
14130
  colorMode
14072
14131
  }
14073
14132
  ),
@@ -14080,9 +14139,9 @@ var AgentsView = ({
14080
14139
  globalUrl,
14081
14140
  localLLMSlot: effectiveLocalLLMSlot,
14082
14141
  permissionsSlot,
14083
- theme,
14142
+ theme: resolvedTheme,
14084
14143
  colorMode,
14085
- agentUIProps: { onSchedule: effectiveSchedule, apiBaseUrl: globalUrl, apiKey, orgId, theme, colorMode }
14144
+ agentUIProps: { onSchedule: effectiveSchedule, apiBaseUrl: globalUrl, apiKey, orgId, theme: resolvedTheme, colorMode }
14086
14145
  }
14087
14146
  )
14088
14147
  ] });
@@ -14090,7 +14149,7 @@ var AgentsView = ({
14090
14149
  var AgentsView_default = AgentsView;
14091
14150
 
14092
14151
  // useAppLookup.ts
14093
- import { useEffect as useEffect15, useMemo as useMemo9, useState as useState17 } from "react";
14152
+ import { useEffect as useEffect16, useMemo as useMemo9, useState as useState17 } from "react";
14094
14153
  var norm3 = (s) => s.toLowerCase().replace(/[\s_\-]+/g, "_");
14095
14154
  function useAppLookup(appName) {
14096
14155
  const [loading, setLoading] = useState17(false);
@@ -14104,7 +14163,7 @@ function useAppLookup(appName) {
14104
14163
  handleSaveAuth,
14105
14164
  refreshAuth
14106
14165
  } = useAppAuth();
14107
- useEffect15(() => {
14166
+ useEffect16(() => {
14108
14167
  if (!appName) {
14109
14168
  setInfo(null);
14110
14169
  setAlgoliaId(null);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shuffleio/shuffle-mcps",
3
- "version": "0.0.27",
3
+ "version": "0.0.29",
4
4
  "description": "Turn 3,000+ SaaS tools into MCP servers your agents can use. Headless React component for search, selection, and OAuth handoff.",
5
5
  "license": "MIT",
6
6
  "repository": {