REDROOM
PHP 8.2.31
Path:
Logout
Edit File
Size: 4.25 KB
Close
/home/nshryvcy/radiantskinclinics.org/wp-content/plugins/extendify_old/src/Agent/state/suggestions.js
Text
Base64
import { create } from 'zustand'; import { devtools, persist } from 'zustand/middleware'; const pluginSuggestions = window.extAgentData?.suggestions || []; const state = (set, get) => ({ suggestions: pluginSuggestions, addSuggestions: (suggestions) => { const mapped = (Array.isArray(suggestions) ? suggestions : []) .filter((s) => s.workflowId && s.label) .map((s) => ({ workflowId: s.workflowId, message: s.label, icon: s.icon ?? 'sparkle', source: s.source ?? 'workflow', available: s.available, addedAt: Date.now(), seenAt: null, clickedAt: null, })); if (mapped.length === 0) return; set((prev) => { // Remove any duplicated suggestions based on the message. const messagesSet = new Set(mapped.map((s) => s.message)); const filtered = prev.suggestions.filter( (item) => !messagesSet.has(item.message), ); return { suggestions: [...mapped, ...filtered] }; }); }, // Returns sorted suggestions for display. // Note: workflow suggestions are not persistent by design, they are removed from the state when seen. // Sort order: workflow first (newest added), then plugin (unseen first, then oldest seen). getNextSuggestions: ({ exclude = [] } = {}) => { const excludeIds = new Set(exclude.map((s) => s.workflowId)); const { suggestions } = get(); return ( suggestions // Exclude any passed in .filter((i) => !excludeIds.has(i.workflowId)) // Remove any that arent available .filter((s) => get().isAvailable(s)) // Oldest seen first. .toSorted((a, b) => (a.seenAt ?? 0) - (b.seenAt ?? 0)) // Unseen before seen. .toSorted((a, b) => (a.seenAt ? 1 : 0) - (b.seenAt ? 1 : 0)) // Workflows sorted by newest added. .toSorted((a, b) => { if ([a.source, b.source].includes('plugin')) return 0; return (b.addedAt ?? 0) - (a.addedAt ?? 0); }) // Workflows before plugins. .toSorted( (a, b) => (a.source === 'plugin' ? 1 : 0) - (b.source === 'plugin' ? 1 : 0), ) ); }, // Returns the top N suggestions and marks them as seen. getSuggestions: ({ slice = 3, exclude = [] } = {}) => { const results = get().getNextSuggestions({ exclude }).slice(0, slice); get().markAsSeen(results); return results; }, isAvailable: (s) => { const { context, abilities } = window.extAgentData ?? {}; const { context: reqContext, abilities: reqAbilities } = s.available ?? {}; // Skip ability checks if abilities are not yet known. if (reqAbilities && !reqAbilities.every((key) => abilities?.[key])) { return false; } // If not context check were good. if (!reqContext) return true; const checks = Array.isArray(reqContext) ? // If it's an array, truthy check reqContext.every((key) => context?.[key]) : // If it's an object, check the value Object.entries(reqContext).every( ([key, val]) => context?.[key] === val, ); return checks; }, markAsSeen: (items) => { const messages = new Set(items.map((s) => s.message)); set((prev) => ({ suggestions: prev.suggestions.map((s) => { if (s.seenAt || !messages.has(s.message)) return s; return { ...s, seenAt: Date.now() }; }), })); }, markAsClicked: (suggestion) => set((prev) => ({ suggestions: prev.suggestions.map((item) => { if (item.message !== suggestion.message) return item; return { ...item, clickedAt: Date.now() }; }), })), }); export const useSuggestionsStore = create()( persist( devtools(state, { name: 'Extendify Agent Suggestions', enabled: window.extSharedData.devbuild, }), { name: `extendify-agent-suggestions-${window.extSharedData.siteId}`, // Reconcile persisted state with fresh plugin suggestions on hydration. merge: (persisted, current) => { const persistedSuggestions = persisted?.suggestions ?? []; // 1. for plugin suggestions, the plugin is the source of truth, // but we keep any dynamic state // 2. This also filters out the workflow suggestions and any others // which we might want to have an expire prop instead const suggestions = pluginSuggestions.map((s) => { const p = persistedSuggestions.find((ps) => ps.id === s.id); return { ...s, seenAt: p?.seenAt, clickedAt: p?.clickedAt, }; }); return { ...current, suggestions }; }, }, ), );
Save
Close
Exit & Reset
Text mode: syntax highlighting auto-detects file type.
Directory Contents
Dirs: 0 × Files: 6
Delete Selected
Select All
Select None
Sort:
Name
Size
Modified
Enable drag-to-move
Name
Size
Perms
Modified
Actions
chat.js
3.15 KB
lrw-r--r--
2026-03-19 23:35:18
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
global.js
2.37 KB
lrw-r--r--
2026-03-19 23:35:18
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
position.js
721 B
lrw-r--r--
2026-02-19 03:27:14
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
suggestions.js
4.25 KB
lrw-r--r--
2026-04-09 23:45:00
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
tours.js
6.52 KB
lrw-r--r--
2026-02-19 03:27:14
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
workflows.js
4.91 KB
lrw-r--r--
2026-03-19 23:35:18
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
Zip Selected
If ZipArchive is unavailable, a
.tar
will be created (no compression).