@decido/shell 1.0.0 → 4.0.2

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.
Files changed (209) hide show
  1. package/README.md +31 -0
  2. package/package.json +27 -18
  3. package/.turbo/turbo-build.log +0 -13
  4. package/src/AgentPlayer.tsx +0 -105
  5. package/src/DecidoPlayer.tsx +0 -117
  6. package/src/bridge/BridgeAgent.ts +0 -443
  7. package/src/components/DecidoIcon.tsx +0 -56
  8. package/src/components/JsonTreeEditor.tsx +0 -117
  9. package/src/components/PanelSplitter.tsx +0 -71
  10. package/src/components/PluginErrorBoundary.tsx +0 -69
  11. package/src/components/SafeLiquidUI.tsx +0 -114
  12. package/src/components/TransientLayer.tsx +0 -92
  13. package/src/components/agent/AgentChat.tsx +0 -134
  14. package/src/components/chat-extensions/IntentCatalogPanel.tsx +0 -81
  15. package/src/components/chat-extensions/chatSlashCommands.ts +0 -101
  16. package/src/components/controls/CreatorInputBar.tsx +0 -144
  17. package/src/components/controls/OSToolbar.tsx +0 -90
  18. package/src/components/controls/TimelineTape.tsx +0 -43
  19. package/src/components/debug/ActionTimelineTab.tsx +0 -111
  20. package/src/components/debug/CSSInspectorTab.tsx +0 -436
  21. package/src/components/debug/ExportTab.tsx +0 -192
  22. package/src/components/debug/FlowHealthTab.tsx +0 -86
  23. package/src/components/debug/LogsTab.tsx +0 -110
  24. package/src/components/debug/MorphStackTab.tsx +0 -241
  25. package/src/components/debug/NetworkTab.tsx +0 -173
  26. package/src/components/debug/PerformanceTab.tsx +0 -171
  27. package/src/components/debug/ProfilesTab.tsx +0 -238
  28. package/src/components/debug/ReplayTab.tsx +0 -70
  29. package/src/components/debug/StoresTab.tsx +0 -255
  30. package/src/components/debug/TopologyTab.tsx +0 -59
  31. package/src/components/debug/debugConfig.tsx +0 -66
  32. package/src/components/playground/DebugPanel.tsx +0 -112
  33. package/src/components/playground/HeaderCenterControls.tsx +0 -92
  34. package/src/components/playground/KeyframeListItem.tsx +0 -70
  35. package/src/components/playground/PlaygroundAppSidebar.tsx +0 -171
  36. package/src/components/playground/PlaygroundBottomControls.tsx +0 -132
  37. package/src/components/playground/PlaygroundCanvas.tsx +0 -87
  38. package/src/components/playground/PlaygroundChat.tsx +0 -236
  39. package/src/components/playground/PlaygroundErrorBoundary.tsx +0 -63
  40. package/src/components/playground/PlaygroundFloatingInput.tsx +0 -352
  41. package/src/components/playground/PlaygroundHeader.tsx +0 -222
  42. package/src/components/playground/PlaygroundSidebar.tsx +0 -136
  43. package/src/components/playground/PlaygroundTerminal.tsx +0 -44
  44. package/src/components/playground/SuggestionCards.tsx +0 -29
  45. package/src/components/playground/demos/ClinicaAINode.tsx +0 -221
  46. package/src/components/playground/demos/FinanceAINode.tsx +0 -226
  47. package/src/components/playground/demos/KiaAcademyNode.tsx +0 -250
  48. package/src/components/playground/demos/KiaBotNode.tsx +0 -207
  49. package/src/components/playground/demos/KiaCampaignNode.tsx +0 -191
  50. package/src/components/playground/demos/KiaComplianceNode.tsx +0 -140
  51. package/src/components/playground/demos/KiaCustomerJourneyNode.tsx +0 -220
  52. package/src/components/playground/demos/KiaCyberNode.tsx +0 -203
  53. package/src/components/playground/demos/KiaDashboardNode.tsx +0 -399
  54. package/src/components/playground/demos/KiaEmbudoOverviewNode.tsx +0 -168
  55. package/src/components/playground/demos/KiaExecutiveNode.tsx +0 -169
  56. package/src/components/playground/demos/KiaGamificationNode.tsx +0 -229
  57. package/src/components/playground/demos/KiaIntelligenceHubNode.tsx +0 -165
  58. package/src/components/playground/demos/KiaInventoryNode.tsx +0 -183
  59. package/src/components/playground/demos/KiaLeadScoringNode.tsx +0 -226
  60. package/src/components/playground/demos/KiaLiveSimulationNode.tsx +0 -177
  61. package/src/components/playground/demos/KiaMultiDealerNode.tsx +0 -223
  62. package/src/components/playground/demos/KiaNPSVoiceNode.tsx +0 -214
  63. package/src/components/playground/demos/KiaOmnichannelNode.tsx +0 -162
  64. package/src/components/playground/demos/KiaPBIBudgetNode.tsx +0 -152
  65. package/src/components/playground/demos/KiaPBIConversionNode.tsx +0 -206
  66. package/src/components/playground/demos/KiaPBIFunnelNode.tsx +0 -184
  67. package/src/components/playground/demos/KiaPBIOwnershipNode.tsx +0 -113
  68. package/src/components/playground/demos/KiaPBIPartnerNode.tsx +0 -143
  69. package/src/components/playground/demos/KiaPBIPreciosNode.tsx +0 -120
  70. package/src/components/playground/demos/KiaPBIRuntNode.tsx +0 -205
  71. package/src/components/playground/demos/KiaPartnerScoreNode.tsx +0 -206
  72. package/src/components/playground/demos/KiaPredictiveNode.tsx +0 -226
  73. package/src/components/playground/demos/KiaShowroomNode.tsx +0 -194
  74. package/src/components/playground/demos/KiaStoreNode.tsx +0 -215
  75. package/src/components/playground/demos/KiaSustainabilityNode.tsx +0 -173
  76. package/src/components/playground/demos/KiaUsedVehiclesNode.tsx +0 -163
  77. package/src/components/playground/demos/KiaWorkshopNode.tsx +0 -221
  78. package/src/components/playground/demos/SmartCityNode.tsx +0 -205
  79. package/src/components/playground/demos/kia_campaign_manifest.json +0 -112
  80. package/src/components/playground/input-parts/AIModelSelector.tsx +0 -156
  81. package/src/components/playground/input-parts/InputActions.tsx +0 -80
  82. package/src/components/playground/input-parts/InputToolbar.tsx +0 -245
  83. package/src/components/playground/input-parts/ResourceLibraryPanel.tsx +0 -287
  84. package/src/components/playground/sidebarDsdIO.ts +0 -82
  85. package/src/components/settings/SettingsPanel.tsx +0 -267
  86. package/src/components/shell/AppHeader.tsx +0 -9
  87. package/src/components/shell/AppShell.tsx +0 -139
  88. package/src/components/shell/ArtifactBar.tsx +0 -97
  89. package/src/components/shell/BootScreen.tsx +0 -19
  90. package/src/components/shell/CenterComposite.tsx +0 -87
  91. package/src/components/shell/CodeEditorPanel.tsx +0 -88
  92. package/src/components/shell/GlobalOverlays.tsx +0 -228
  93. package/src/components/shell/LayoutConfigurator.tsx +0 -209
  94. package/src/components/shell/LayoutGrid.tsx +0 -178
  95. package/src/components/shell/MorphShell.tsx +0 -368
  96. package/src/components/shell/PluginViewer.tsx +0 -147
  97. package/src/components/shell/ShellNexusPreview.tsx +0 -458
  98. package/src/components/shell/SlotRenderer.tsx +0 -115
  99. package/src/components/shell/TabBar.tsx +0 -94
  100. package/src/components/shell/TemplateLibrary.tsx +0 -195
  101. package/src/components/shell/layoutConstants.ts +0 -35
  102. package/src/components/shell/morphStageMeta.ts +0 -15
  103. package/src/components/shell/shells/BuiltInShells.tsx +0 -443
  104. package/src/components/shell/shells/DatawayChatShell.tsx +0 -42
  105. package/src/components/shell/shells/TokenPreview.tsx +0 -339
  106. package/src/components/shell/shells/bootShells.ts +0 -31
  107. package/src/components/shells/CreatorShell.tsx +0 -37
  108. package/src/components/shells/DecidoShell.tsx +0 -447
  109. package/src/components/shells/ExperimentalChatShell.tsx +0 -245
  110. package/src/components/shells/UserCanvas.tsx +0 -44
  111. package/src/components/studio/BlueprintManagerPanel.tsx +0 -137
  112. package/src/components/studio/DependencyTreePanel.tsx +0 -192
  113. package/src/components/studio/NodePalette.tsx +0 -92
  114. package/src/components/studio/NodePropertiesPanel.tsx +0 -81
  115. package/src/components/studio/ReactFlowEditor.tsx +0 -242
  116. package/src/components/studio/TimelineEditor.tsx +0 -122
  117. package/src/components/studio/TimelineKeyframeCard.tsx +0 -99
  118. package/src/components/studio/VariablePanel.tsx +0 -181
  119. package/src/components/studio/blueprint/BlueprintCard.tsx +0 -82
  120. package/src/components/studio/editor/CanvasContextMenu.tsx +0 -107
  121. package/src/components/studio/editor/EditorToolbar.tsx +0 -80
  122. package/src/components/studio/editor/StageContentRenderer.tsx +0 -134
  123. package/src/components/studio/editor/TrackPropertyEditors.tsx +0 -133
  124. package/src/components/studio/editor/TreeNodeItem.tsx +0 -91
  125. package/src/components/studio/editor/edgeStyles.ts +0 -43
  126. package/src/components/studio/editor/editorKeyHandler.ts +0 -95
  127. package/src/components/studio/editor/nodeTypeRegistry.ts +0 -137
  128. package/src/components/studio/editor/paletteCatalog.tsx +0 -84
  129. package/src/components/studio/nodes/shell/InteractionNodes.tsx +0 -82
  130. package/src/components/studio/nodes/shell/LayoutControlNodes.tsx +0 -69
  131. package/src/components/studio/nodes/shell/RegisterActionNode.tsx +0 -20
  132. package/src/components/studio/nodes/shell/RegisterButtonNode.tsx +0 -22
  133. package/src/components/studio/nodes/shell/RegisterPanelNode.tsx +0 -19
  134. package/src/components/studio/nodes/shell/RegisterSidebarNode.tsx +0 -19
  135. package/src/components/studio/nodes/shell/RegisterStatusBarNode.tsx +0 -22
  136. package/src/components/studio/nodes/shell/RegisterTabNode.tsx +0 -21
  137. package/src/components/studio/nodes/shell/RegisterTopBarNode.tsx +0 -22
  138. package/src/components/studio/nodes/shell/ShellConfigNode.tsx +0 -51
  139. package/src/components/studio/nodes/shell/ShellNodeBase.tsx +0 -100
  140. package/src/components/studio/nodes/shell/ThemeNodes.tsx +0 -51
  141. package/src/components/studio/nodes/shell/index.ts +0 -12
  142. package/src/components/widgets/BroadcastWidget.tsx +0 -93
  143. package/src/components/widgets/MarketplaceWidget.tsx +0 -298
  144. package/src/components/widgets/McpToolsWidget.tsx +0 -231
  145. package/src/components/widgets/OpsDashboard.tsx +0 -59
  146. package/src/components/widgets/QuickActionsWidget.tsx +0 -60
  147. package/src/components/widgets/UsageWidget.tsx +0 -112
  148. package/src/components/widgets/WidgetRenderer.tsx +0 -892
  149. package/src/components/widgets/WidgetSlotPanel.tsx +0 -213
  150. package/src/config/IconRegistry.ts +0 -126
  151. package/src/contexts/NetworkProvider.tsx +0 -162
  152. package/src/core/AIDirector.ts +0 -71
  153. package/src/core/EventBus.ts +0 -37
  154. package/src/core/PluginContext.tsx +0 -141
  155. package/src/hooks/listeners/useUIStateListener.ts +0 -59
  156. package/src/hooks/listeners/useWhatsAppListener.ts +0 -110
  157. package/src/hooks/morphBridge.ts +0 -82
  158. package/src/hooks/useAIModelSelector.ts +0 -144
  159. package/src/hooks/useAgentStream.ts +0 -220
  160. package/src/hooks/useAutoUpdater.ts +0 -89
  161. package/src/hooks/useBootSequence.ts +0 -20
  162. package/src/hooks/useExportDSD.ts +0 -53
  163. package/src/hooks/useFullscreen.ts +0 -35
  164. package/src/hooks/useGeminiStream.ts +0 -282
  165. package/src/hooks/useIntentLens.ts +0 -224
  166. package/src/hooks/useKeyboardShortcuts.ts +0 -69
  167. package/src/hooks/useLoggerBridge.ts +0 -32
  168. package/src/hooks/useMcpClient.ts +0 -112
  169. package/src/hooks/useNexusaiDeploy.ts +0 -118
  170. package/src/hooks/usePlaybackEngine.ts +0 -21
  171. package/src/hooks/usePlaygroundCommander.ts +0 -475
  172. package/src/hooks/usePluginEngine.ts +0 -165
  173. package/src/hooks/useScreenRecorder.ts +0 -73
  174. package/src/hooks/useShellKeyboard.ts +0 -40
  175. package/src/hooks/useShellShortcuts.ts +0 -118
  176. package/src/hooks/useSoundEffects.ts +0 -35
  177. package/src/hooks/useStudioConfig.ts +0 -72
  178. package/src/hooks/useSystemBoot.ts +0 -84
  179. package/src/hooks/useSystemTelemetry.ts +0 -62
  180. package/src/index.ts +0 -97
  181. package/src/lib/debugLogger.ts +0 -80
  182. package/src/lib/networkInterceptor.ts +0 -100
  183. package/src/mocks/decido.tsx +0 -41
  184. package/src/plugins/pluginAPI.ts +0 -190
  185. package/src/store/McpStore.ts +0 -69
  186. package/src/store/UpdaterStore.ts +0 -60
  187. package/src/store/engine.ts +0 -392
  188. package/src/store/index.ts +0 -4
  189. package/src/store/layoutPresets.ts +0 -66
  190. package/src/store/playgroundTypes.ts +0 -98
  191. package/src/store/useActionTimelineStore.ts +0 -48
  192. package/src/store/useDebugPanelStore.ts +0 -98
  193. package/src/store/useDebugProfileStore.ts +0 -130
  194. package/src/store/useLayoutStore.ts +0 -205
  195. package/src/store/useMorphInstanceStore.ts +0 -289
  196. package/src/store/useMorphologyStore.ts +0 -103
  197. package/src/store/usePlaygroundStore.ts +0 -236
  198. package/src/store/useShellRegistry.ts +0 -123
  199. package/src/store/useSuggestionsStore.ts +0 -57
  200. package/src/store/useThemeStore.ts +0 -399
  201. package/src/store/useUIComponentStore.ts +0 -179
  202. package/src/types/DecidoStoryDefinition.ts +0 -43
  203. package/src/utils/ai/ai-architect.ts +0 -92
  204. package/src/utils/ai/ai-code.ts +0 -187
  205. package/src/utils/ai/ai-core.ts +0 -50
  206. package/src/utils/ai/ai-media.ts +0 -292
  207. package/src/utils/layoutGraph.ts +0 -67
  208. package/tsconfig.json +0 -17
  209. package/tsconfig.tsbuildinfo +0 -1
@@ -1,298 +0,0 @@
1
- import React, { useState, useEffect } from 'react';
2
- import { usePluginStore } from '@decido/plugin-engine';
3
- import { Trash2, Power, Puzzle, Code, RefreshCcw, DownloadCloud, AlertCircle, LayoutDashboard, ChevronLeft, Info, Box } from 'lucide-react';
4
-
5
- export const MarketplaceWidget: React.FC = () => {
6
- const registry = usePluginStore(state => state.registry);
7
- const availablePlugins = usePluginStore(state => state.availablePlugins);
8
- const addRegistryEntry = usePluginStore(state => state.addRegistryEntry);
9
- const removeRegistryEntry = usePluginStore(state => state.removeRegistryEntry);
10
- const toggleRegistryEntry = usePluginStore(state => state.toggleRegistryEntry);
11
-
12
- const [catalog, setCatalog] = useState<any[]>([]);
13
- const [isLoading, setIsLoading] = useState(true);
14
- const [error, setError] = useState<string | null>(null);
15
- const [isCatalogView, setIsCatalogView] = useState(false);
16
- const [selectedPlugin, setSelectedPlugin] = useState<any | null>(null);
17
-
18
- useEffect(() => {
19
- const fetchCatalog = async () => {
20
- try {
21
- setIsLoading(true);
22
- const baseUrl = (import.meta as any).env?.VITE_MARKETPLACE_URL || 'http://localhost:5010/api/marketplace';
23
- const res = await fetch(`${baseUrl}/catalog`);
24
- if (!res.ok) throw new Error('Catalog request failed');
25
- const data = await res.json();
26
- setCatalog(data);
27
- setError(null);
28
- } catch (err: any) {
29
- setError(err.message || 'Failed to connect to Decido Hub');
30
- } finally {
31
- setIsLoading(false);
32
- }
33
- };
34
- fetchCatalog();
35
- }, []);
36
-
37
- const handleInstall = (plugin: any) => {
38
- addRegistryEntry({
39
- name: plugin.name,
40
- url: plugin.url,
41
- exposedModule: plugin.exposedModule,
42
- signature: plugin.signature
43
- });
44
- };
45
-
46
- const isInstalled = (name: string) => {
47
- return registry.some(p => p.name === name);
48
- };
49
-
50
- return (
51
- <div className="w-full h-full flex flex-col bg-surface-primary text-text-primary font-sans overflow-hidden border-r border-border-subtle">
52
- {/* Header */}
53
- <div className="p-4 border-b border-border-subtle bg-surface-secondary/50 flex justify-between items-center shrink-0">
54
- <div className="flex items-center gap-2">
55
- <Puzzle className="w-5 h-5 text-cyan-400" />
56
- <h2 className="font-bold text-sm tracking-wide">Decido Hub</h2>
57
- </div>
58
- <div className="flex bg-surface-primary p-1 rounded-lg border border-border-subtle">
59
- <button
60
- onClick={() => { setIsCatalogView(false); setSelectedPlugin(null); }}
61
- className={`px-3 py-1 text-xs rounded-md transition-colors ${!isCatalogView ? 'bg-cyan-500/20 text-cyan-400' : 'text-text-muted hover:text-text-primary'}`}
62
- >
63
- Installed
64
- </button>
65
- <button
66
- onClick={() => { setIsCatalogView(true); setSelectedPlugin(null); }}
67
- className={`px-3 py-1 flex items-center gap-1 text-xs rounded-md transition-colors ${isCatalogView ? 'bg-cyan-500/20 text-cyan-400' : 'text-text-muted hover:text-text-primary'}`}
68
- >
69
- <DownloadCloud className="w-3 h-3" /> Catalog
70
- </button>
71
- </div>
72
- </div>
73
-
74
- {/* Content */}
75
- <div className="flex-1 overflow-y-auto p-4 space-y-4">
76
-
77
- {!selectedPlugin && !isCatalogView && (
78
- <div className="bg-cyan-500/10 border border-cyan-500/20 p-3 rounded-lg flex items-start gap-3">
79
- <RefreshCcw className="w-4 h-4 text-cyan-400 shrink-0 mt-0.5" />
80
- <p className="text-xs text-cyan-200/70 leading-relaxed">
81
- Changes to the Federation Registry require a hard reload to apply securely to the OS Kernel context. (cmd+R)
82
- </p>
83
- </div>
84
- )}
85
-
86
- {/* DETAILS VIEW */}
87
- {selectedPlugin && (
88
- <div className="space-y-4 animate-in fade-in slide-in-from-right-4 duration-300">
89
- <button
90
- onClick={() => setSelectedPlugin(null)}
91
- className="flex items-center gap-1 text-xs text-text-secondary hover:text-text-primary transition-colors mb-2"
92
- >
93
- <ChevronLeft className="w-4 h-4" /> Volver
94
- </button>
95
-
96
- <div className="flex items-start gap-4 pb-4 border-b border-border-subtle">
97
- <div className="w-16 h-16 rounded-2xl bg-linear-to-br from-cyan-500/20 to-blue-500/20 border border-cyan-500/30 flex items-center justify-center shrink-0">
98
- <Box className="w-8 h-8 text-cyan-400" />
99
- </div>
100
- <div className="flex-1">
101
- <h2 className="text-xl font-bold text-text-primary mb-1">{selectedPlugin.title || selectedPlugin.name}</h2>
102
- <p className="text-sm text-cyan-400 font-mono mb-2">{selectedPlugin.author || 'Decido Publisher'} • v{selectedPlugin.version || '1.0.0'}</p>
103
-
104
- {isInstalled(selectedPlugin.name) ? (
105
- <div className="flex items-center gap-2">
106
- <span className="bg-emerald-500/10 text-emerald-400 text-xs px-3 py-1.5 rounded-full font-medium flex items-center gap-1">
107
- <div className="w-2 h-2 rounded-full bg-emerald-400 animate-pulse"></div>
108
- Installed
109
- </span>
110
- <button
111
- onClick={() => removeRegistryEntry(selectedPlugin.name)}
112
- className="bg-surface-tertiary hover:bg-red-500/20 hover:text-red-400 text-text-primary text-xs px-3 py-1.5 rounded transition-colors"
113
- >
114
- Uninstall
115
- </button>
116
- </div>
117
- ) : (
118
- <button
119
- onClick={() => handleInstall(selectedPlugin)}
120
- className="bg-cyan-600 hover:bg-cyan-500 text-text-primary text-sm px-6 py-2 rounded-lg transition-colors shadow-lg shadow-cyan-500/20 font-medium"
121
- >
122
- Install Plugin
123
- </button>
124
- )}
125
- </div>
126
- </div>
127
-
128
- <div className="space-y-6 pt-2">
129
- <div>
130
- <h3 className="text-sm font-semibold text-text-primary mb-2 flex items-center gap-2">
131
- <Info className="w-4 h-4 text-text-muted" /> General Description
132
- </h3>
133
- <p className="text-sm text-text-secondary leading-relaxed bg-surface-glass p-4 rounded-xl border border-border-subtle/50">
134
- {selectedPlugin.description || 'No README.md currently available for this plugin. This is a technical expansion module for Decido OS.'}
135
- </p>
136
- </div>
137
-
138
- {/* Renderizar CortexManifest Data si está instalado y en memoria */}
139
- {(() => {
140
- const manifest = availablePlugins.find(p => p.id === selectedPlugin.name || p.name === selectedPlugin.name);
141
- if (!manifest) return (
142
- <div className="text-xs text-text-muted italic bg-surface-glass p-4 rounded-xl border border-border-subtle/30 text-center">
143
- Install and activate this plugin to view its provided Architecture bounds (Widgets & Intents).
144
- </div>
145
- );
146
-
147
- return (
148
- <div className="space-y-4">
149
- {manifest.widgets && manifest.widgets.length > 0 && (
150
- <div>
151
- <h3 className="text-sm font-semibold text-text-primary mb-2 flex items-center gap-2">
152
- <LayoutDashboard className="w-4 h-4 text-cyan-400" /> Provisioned Widgets
153
- </h3>
154
- <div className="grid gap-2">
155
- {manifest.widgets.map((w: any) => (
156
- <div key={w.id} className="bg-surface-secondary border border-border-subtle p-3 rounded-lg flex items-center justify-between">
157
- <div className="flex flex-col">
158
- <span className="text-sm font-medium text-text-primary">{w.name}</span>
159
- <span className="text-xs text-text-muted font-mono">ID: {w.id}</span>
160
- </div>
161
- <span className="text-xs bg-surface-primary text-emerald-400/80 border border-emerald-500/20 px-2 py-1 rounded">
162
- Zone: {w.defaultZone}
163
- </span>
164
- </div>
165
- ))}
166
- </div>
167
- </div>
168
- )}
169
-
170
- {manifest.intents && manifest.intents.length > 0 && (
171
- <div>
172
- <h3 className="text-sm font-semibold text-text-primary mb-2 flex items-center gap-2">
173
- <Code className="w-4 h-4 text-purple-400" /> Registered AI Intents
174
- </h3>
175
- <div className="bg-surface-secondary border border-border-subtle rounded-lg p-3 flex flex-wrap gap-2">
176
- {manifest.intents.map((intent: string) => (
177
- <span key={intent} className="bg-surface-primary text-purple-400/90 text-xs px-2 py-1 rounded border border-purple-500/20 font-mono">
178
- "{intent}"
179
- </span>
180
- ))}
181
- </div>
182
- </div>
183
- )}
184
- </div>
185
- );
186
- })()}
187
- </div>
188
- </div>
189
- )}
190
-
191
- {/* CATALOG VIEW */}
192
- {!selectedPlugin && isCatalogView && (
193
- <div className="space-y-4">
194
- {isLoading && <div className="text-xs text-text-muted text-center py-8 animate-pulse">Connecting to Decido Hub...</div>}
195
- {error && (
196
- <div className="bg-red-500/10 border border-red-500/20 p-4 rounded-xl flex items-center gap-3 text-red-400 text-xs">
197
- <AlertCircle className="w-4 h-4" /> {error}
198
- </div>
199
- )}
200
- {!isLoading && !error && catalog.map(plugin => {
201
- const installed = isInstalled(plugin.name);
202
- return (
203
- <div key={plugin.id} onClick={() => setSelectedPlugin(plugin)} className="bg-surface-secondary border border-border-subtle hover:border-cyan-500/30 focus:border-cyan-500/30 cursor-pointer p-4 rounded-xl flex flex-col gap-3 transition-colors group">
204
- <div className="flex justify-between items-start">
205
- <div className="flex gap-3 items-center">
206
- <div className="w-10 h-10 rounded-lg bg-surface-primary border border-border-subtle flex items-center justify-center group-hover:border-cyan-500/30 transition-colors">
207
- <Box className="w-5 h-5 text-text-muted group-hover:text-cyan-400 transition-colors" />
208
- </div>
209
- <div>
210
- <h3 className="font-bold text-sm text-text-primary group-hover:text-cyan-300 transition-colors">{plugin.title}</h3>
211
- <p className="text-xs text-text-muted font-mono mt-0.5">{plugin.author} • v{plugin.version}</p>
212
- </div>
213
- </div>
214
- {installed && (
215
- <span className="bg-emerald-500/10 text-emerald-400 text-[10px] px-2 py-1 rounded-full uppercase font-bold tracking-wider">Installed</span>
216
- )}
217
- </div>
218
- <p className="text-xs text-text-secondary leading-relaxed border-l-2 border-border-subtle pl-2 line-clamp-2">
219
- {plugin.description}
220
- </p>
221
- <div className="flex gap-2 mt-1">
222
- <button className="text-[10px] text-text-secondary hover:text-text-primary bg-surface-glass px-2 py-1 rounded uppercase font-bold tracking-wide">
223
- Details
224
- </button>
225
- {plugin.tags?.map((tag: string) => (
226
- <span key={tag} className="text-[10px] bg-surface-primary text-text-muted px-2 py-1 rounded-full border border-border-subtle">
227
- {tag}
228
- </span>
229
- ))}
230
- </div>
231
- </div>
232
- );
233
- })}
234
- </div>
235
- )}
236
-
237
- {/* INSTALLED VIEW */}
238
- {!selectedPlugin && !isCatalogView && (
239
- <div className="space-y-3">
240
- {registry.map(plugin => (
241
- <div key={plugin.name} onClick={() => setSelectedPlugin(plugin)} className={`bg-surface-secondary border ${plugin.enabled ? 'border-border-default/50' : 'border-border-subtle opacity-60'} hover:border-cyan-500/30 cursor-pointer p-4 rounded-xl transition-all group`}>
242
- <div className="flex justify-between items-start mb-2">
243
- <div className="flex items-center gap-3">
244
- <div className="w-10 h-10 rounded-lg bg-surface-primary border border-border-subtle flex items-center justify-center group-hover:border-cyan-500/30 transition-colors">
245
- <Box className="w-5 h-5 text-text-muted group-hover:text-cyan-400 transition-colors" />
246
- </div>
247
- <div>
248
- <div className="flex items-center gap-2">
249
- <div className={`w-2 h-2 rounded-full ${plugin.enabled ? 'bg-emerald-400 shadow-[0_0_8px_rgba(52,211,153,0.5)]' : 'bg-surface-elevated'}`}></div>
250
- <h3 className="font-bold text-sm tracking-wide text-text-primary group-hover:text-cyan-300 transition-colors">{plugin.name}</h3>
251
- </div>
252
- <div className="text-xs font-mono text-text-muted mt-1">
253
- module: <span className="text-cyan-300/80">{plugin.exposedModule}</span>
254
- </div>
255
- </div>
256
- </div>
257
- <div className="flex items-center gap-1" onClick={e => e.stopPropagation()}>
258
- <button
259
- onClick={() => toggleRegistryEntry(plugin.name)}
260
- className={`w-7 h-7 flex items-center justify-center rounded transition-colors ${plugin.enabled ? 'text-emerald-400 hover:bg-emerald-400/10' : 'text-text-muted hover:bg-surface-tertiary'}`}
261
- title={plugin.enabled ? 'Disable Plugin' : 'Enable Plugin'}
262
- >
263
- <Power className="w-4 h-4" />
264
- </button>
265
- <button
266
- onClick={() => removeRegistryEntry(plugin.name)}
267
- className="w-7 h-7 flex items-center justify-center rounded transition-colors text-text-muted hover:bg-red-500/20 hover:text-red-400"
268
- title="Uninstall Plugin"
269
- >
270
- <Trash2 className="w-4 h-4" />
271
- </button>
272
- </div>
273
- </div>
274
-
275
- <div className="bg-surface-glass p-2 border border-border-subtle/50 rounded flex gap-2 items-center mt-3">
276
- <Code className="w-3.5 h-3.5 text-text-muted shrink-0" />
277
- <span className="font-mono text-[10px] text-text-secondary truncate" title={plugin.url}>
278
- {plugin.url}
279
- </span>
280
- </div>
281
- </div>
282
- ))}
283
-
284
- {registry.length === 0 && (
285
- <div className="text-center py-12 text-text-muted text-sm">
286
- <Puzzle className="w-8 h-8 mx-auto text-text-muted mb-3" />
287
- No local modules installed.<br />
288
- <button onClick={() => setIsCatalogView(true)} className="mt-3 text-cyan-400 hover:text-cyan-300 underline underline-offset-4 decoration-zinc-800">
289
- Browse Decido Hub
290
- </button>
291
- </div>
292
- )}
293
- </div>
294
- )}
295
- </div>
296
- </div>
297
- );
298
- };
@@ -1,231 +0,0 @@
1
- import React, { useState, useEffect } from 'react';
2
- import { kernel } from '@decido/kernel-bridge';
3
- import { useMcpStore } from '../../store/McpStore';
4
-
5
- export const McpToolsWidget = () => {
6
- const { mcpServers, setMcpServerStatus } = useMcpStore();
7
- const [tools, setTools] = useState<any[]>([]);
8
- const [isLoading, setIsLoading] = useState<string | null>(null);
9
-
10
- // Playground state
11
- const [activePlayground, setActivePlayground] = useState<string | null>(null);
12
- const [playgroundArgs, setPlaygroundArgs] = useState<string>('{}');
13
- const [playgroundOutput, setPlaygroundOutput] = useState<string | null>(null);
14
- const [isPlaygroundLoading, setIsPlaygroundLoading] = useState(false);
15
-
16
- const fetchTools = async () => {
17
- try {
18
- const data = await kernel.execute<any[]>('list_mcp_tools');
19
- setTools(data || []);
20
- } catch (e) {
21
- console.error("Failed to fetch MCP tools", e);
22
- }
23
- };
24
-
25
- useEffect(() => {
26
- fetchTools();
27
- // Option to refresh periodically or manually
28
- const interval = setInterval(fetchTools, 10000);
29
- return () => clearInterval(interval);
30
- }, []);
31
-
32
- const handleConnect = async (serverName: string, serverCommand: string, serverArgs: string) => {
33
- setIsLoading(serverName);
34
- try {
35
- const parsedArgs = serverArgs.split(' ').filter(a => a.trim() !== '');
36
- await kernel.execute('connect_mcp_server', {
37
- name: serverName,
38
- command: serverCommand,
39
- args: parsedArgs
40
- });
41
- kernel.notify('MCP Connected', `Server ${serverName} connected successfully.`);
42
- setMcpServerStatus(serverName, true);
43
- await fetchTools();
44
- } catch (e: any) {
45
- kernel.notify('MCP Connection Failed', e.toString());
46
- } finally {
47
- setIsLoading(null);
48
- }
49
- };
50
-
51
- const handleDisconnect = async (serverName: string) => {
52
- setIsLoading(serverName);
53
- try {
54
- await kernel.execute('disconnect_mcp_server', { name: serverName });
55
- kernel.notify('MCP Disconnected', `Server ${serverName} disconnected.`);
56
- setMcpServerStatus(serverName, false);
57
- await fetchTools();
58
- } catch (e: any) {
59
- kernel.notify('Disconnect Failed', e.toString());
60
- } finally {
61
- setIsLoading(null);
62
- }
63
- };
64
-
65
- const handleOpenPlayground = (tool: any) => {
66
- if (activePlayground === tool.name) {
67
- setActivePlayground(null);
68
- return;
69
- }
70
- setActivePlayground(tool.name);
71
- setPlaygroundOutput(null);
72
-
73
- // Generate default args based on schema
74
- let defaultArgs: any = {};
75
- if (tool.inputSchema?.properties) {
76
- Object.keys(tool.inputSchema.properties).forEach(key => {
77
- const prop = tool.inputSchema.properties[key];
78
- if (prop.type === 'string') defaultArgs[key] = "";
79
- else if (prop.type === 'number') defaultArgs[key] = 0;
80
- else if (prop.type === 'boolean') defaultArgs[key] = false;
81
- else if (prop.type === 'object') defaultArgs[key] = {};
82
- else if (prop.type === 'array') defaultArgs[key] = [];
83
- });
84
- }
85
- setPlaygroundArgs(JSON.stringify(defaultArgs, null, 2));
86
- };
87
-
88
- const handleRunPlayground = async (toolName: string) => {
89
- setIsPlaygroundLoading(true);
90
- setPlaygroundOutput(null);
91
- try {
92
- let parsedArgs = {};
93
- try {
94
- // Sanitize macOS smart quotes
95
- const sanitizedJson = playgroundArgs
96
- .replace(/[\u2018\u2019]/g, "'")
97
- .replace(/[\u201C\u201D]/g, '"');
98
- parsedArgs = JSON.parse(sanitizedJson);
99
- } catch (e) {
100
- setPlaygroundOutput("Invalid JSON format in arguments.");
101
- setIsPlaygroundLoading(false);
102
- return;
103
- }
104
-
105
- const parts = toolName.split(':');
106
- let srvName = '';
107
- let tName = toolName;
108
-
109
- if (parts.length >= 3 && parts[0] === 'mcp') {
110
- srvName = parts[1];
111
- tName = parts.slice(2).join(':');
112
- } else if (parts.length === 2 && parts[0] !== 'mcp') {
113
- srvName = parts[0];
114
- tName = parts[1];
115
- } else {
116
- srvName = parts[0] || 'frubeala-mcp';
117
- }
118
-
119
- const res = await kernel.execute<any>('call_mcp_tool', {
120
- serverName: srvName,
121
- toolName: tName,
122
- arguments: parsedArgs
123
- });
124
-
125
- if (res && res.content) {
126
- const texts = res.content.filter((c: any) => c.type === 'text').map((c: any) => c.text).join('\\n');
127
- setPlaygroundOutput(texts);
128
- } else {
129
- setPlaygroundOutput(JSON.stringify(res, null, 2));
130
- }
131
- } catch (e: any) {
132
- setPlaygroundOutput(`Error: ${e.toString()}`);
133
- } finally {
134
- setIsPlaygroundLoading(false);
135
- }
136
- };
137
-
138
- return (
139
- <div className="space-y-4">
140
- <div className="space-y-2">
141
- <h4 className="text-xs font-bold text-text-secondary uppercase tracking-widest mb-3">Conexiones Activas</h4>
142
- {mcpServers.length === 0 && (
143
- <div className="text-text-muted text-xs text-center py-4 bg-surface-glass rounded-xl border border-border-subtle">
144
- Sin servidores conectados.
145
- </div>
146
- )}
147
- {mcpServers.map((server, i) => (
148
- <div key={i} className="flex flex-col p-3 bg-surface-glass rounded-xl border border-border-subtle">
149
- <div className="flex items-center justify-between">
150
- <span className="text-sm font-medium text-text-primary">{server.name}</span>
151
- {server.isConnected ? (
152
- <button
153
- onClick={() => handleDisconnect(server.name)}
154
- disabled={isLoading === server.name}
155
- className="px-2 py-1 bg-red-900/30 hover:bg-red-900/60 text-red-400 border border-red-500/30 rounded text-xs transition-colors"
156
- >
157
- {isLoading === server.name ? 'Disconnecting...' : 'Disconnect'}
158
- </button>
159
- ) : (
160
- <button
161
- onClick={() => handleConnect(server.name, server.command, server.args)}
162
- disabled={isLoading === server.name}
163
- className="px-2 py-1 bg-emerald-900/30 hover:bg-emerald-900/60 text-emerald-400 border border-emerald-500/30 rounded text-xs transition-colors"
164
- >
165
- {isLoading === server.name ? 'Connecting...' : 'Connect'}
166
- </button>
167
- )}
168
- </div>
169
- <div className="text-[10px] text-text-muted font-mono mt-1">{server.command} {server.args}</div>
170
- </div>
171
- ))}
172
- </div>
173
-
174
- <div className="space-y-2 mt-6">
175
- <h4 className="text-xs font-bold text-text-secondary uppercase tracking-widest mb-3 border-t border-border-subtle pt-4">Tools Playground</h4>
176
- {tools.length === 0 && (
177
- <div className="text-text-muted text-xs text-center py-4 bg-surface-glass rounded-xl border border-border-subtle">
178
- No hay herramientas disponibles. Asegúrate de que un servidor MCP esté online.
179
- </div>
180
- )}
181
- <div className="space-y-2 pb-10">
182
- {tools.map((tool: any) => (
183
- <div key={tool.name} className="bg-surface-overlay border border-border-subtle rounded-xl p-3 overflow-hidden">
184
- <div className="flex items-center justify-between">
185
- <div>
186
- <h4 className="text-cyan-400 font-bold text-sm">{tool.name.split(':').pop() || tool.name}</h4>
187
- <p className="text-xs text-text-muted line-clamp-1">{tool.description}</p>
188
- </div>
189
- <button
190
- onClick={() => handleOpenPlayground(tool)}
191
- className="px-3 py-1 bg-cyan-900/30 hover:bg-cyan-900/60 text-cyan-400 border border-cyan-500/30 rounded text-xs transition-colors"
192
- >
193
- Test
194
- </button>
195
- </div>
196
-
197
- {activePlayground === tool.name && (
198
- <div className="mt-4 border-t border-border-default pt-4 flex flex-col gap-3 animate-in slide-in-from-top-4 duration-200">
199
- <div>
200
- <label className="text-[10px] text-text-muted font-bold uppercase tracking-wider mb-1 block">Arguments (JSON)</label>
201
- <textarea
202
- value={playgroundArgs}
203
- onChange={e => setPlaygroundArgs(e.target.value)}
204
- className="w-full h-24 bg-surface-overlay border border-border-default rounded p-2 text-cyan-300 font-mono text-xs focus:border-cyan-400 outline-hidden resize-none"
205
- />
206
- </div>
207
- <button
208
- onClick={() => handleRunPlayground(tool.name)}
209
- disabled={isPlaygroundLoading}
210
- className="w-full py-2 bg-linear-to-r from-cyan-600 to-indigo-600 text-text-primary rounded font-bold text-xs hover:from-cyan-500 hover:to-indigo-500 transition-all shadow-[0_0_15px_rgba(6,182,212,0.3)] disabled:opacity-50"
211
- >
212
- {isPlaygroundLoading ? 'Executing...' : 'Execute Tool'}
213
- </button>
214
-
215
- {playgroundOutput && (
216
- <div className="mt-2">
217
- <label className="text-[10px] text-text-muted font-bold uppercase tracking-wider mb-1 block">Output</label>
218
- <div className="w-full max-h-48 overflow-y-auto bg-surface-primary border border-border-default rounded p-2 text-emerald-400 font-mono text-xs whitespace-pre-wrap">
219
- {playgroundOutput}
220
- </div>
221
- </div>
222
- )}
223
- </div>
224
- )}
225
- </div>
226
- ))}
227
- </div>
228
- </div>
229
- </div>
230
- );
231
- };
@@ -1,59 +0,0 @@
1
- import { BroadcastWidget } from './BroadcastWidget';
2
- import { QuickActionsWidget } from './QuickActionsWidget';
3
- import { UsageWidget } from './UsageWidget';
4
- import { Activity, Server, Users } from 'lucide-react';
5
-
6
- export const OpsDashboard = () => {
7
- return (
8
- <div className="min-h-screen bg-surface-primary p-8 text-text-primary">
9
- <header className="mb-8 flex items-center justify-between">
10
- <div>
11
- <h1 className="text-3xl font-black text-transparent bg-clip-text bg-linear-to-r from-purple-400 to-pink-600">
12
- MISSION CONTROL
13
- </h1>
14
- <p className="text-text-muted font-mono text-sm mt-1">System Operations & Real-time Command</p>
15
- </div>
16
- <div className="flex gap-4">
17
- <div className="bg-surface-secondary px-4 py-2 rounded-lg border border-border-subtle flex items-center gap-3">
18
- <Users size={16} className="text-blue-400" />
19
- <span className="font-mono font-bold">12 Active</span>
20
- </div>
21
- <div className="bg-surface-secondary px-4 py-2 rounded-lg border border-border-subtle flex items-center gap-3">
22
- <Server size={16} className="text-emerald-400" />
23
- <span className="font-mono font-bold">Healthy</span>
24
- <div className="w-2 h-2 rounded-full bg-emerald-500 animate-pulse" />
25
- </div>
26
- </div>
27
- </header>
28
-
29
- <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
30
- {/* Column 1: Comms */}
31
- <div className="space-y-6">
32
- <BroadcastWidget />
33
- </div>
34
-
35
- {/* Column 2: Safety & Actions */}
36
- <div className="space-y-6">
37
- <QuickActionsWidget />
38
-
39
- {/* Cost & Resource Usage */}
40
- <UsageWidget />
41
- </div>
42
-
43
- {/* Column 3: Live Feed */}
44
- <div className="bg-surface-secondary rounded-xl border border-border-subtle p-6 font-mono text-xs h-[500px] flex flex-col">
45
- <h3 className="font-bold text-text-secondary mb-4 flex items-center gap-2">
46
- <Activity size={16} /> Live Event Stream
47
- </h3>
48
- <div className="flex-1 overflow-y-auto space-y-2 text-text-muted">
49
- <p><span className="text-emerald-500">[10:00:01]</span> System Init</p>
50
- <p><span className="text-blue-500">[10:05:23]</span> User 'Julio' connected</p>
51
- <p><span className="text-yellow-500">[10:12:45]</span> AI Graph Analysis triggered</p>
52
- <p><span className="text-purple-500">[10:15:00]</span> Order #1234 staged to PRODUCTION</p>
53
- <div className="opacity-30 italic mt-4">Listening for events...</div>
54
- </div>
55
- </div>
56
- </div>
57
- </div>
58
- );
59
- };
@@ -1,60 +0,0 @@
1
- import { RefreshCw, Zap, ShieldAlert } from 'lucide-react';
2
-
3
-
4
- export const QuickActionsWidget = () => {
5
-
6
- const triggerAction = async (action: string) => {
7
- if (!confirm('Are you sure you want to execute this global action?')) return;
8
- try {
9
- const baseUrl = (import.meta as any).env?.VITE_API_URL || 'http://localhost:3001/api';
10
- if (action === 'FORCE_RELOAD') {
11
- await fetch(`${baseUrl}/admin/broadcast`, {
12
- method: 'POST',
13
- headers: { 'Content-Type': 'application/json' },
14
- body: JSON.stringify({
15
- message: 'System Integrity Check: Reloading...',
16
- type: 'WARNING',
17
- action: 'RELOAD'
18
- })
19
- });
20
- } else if (action === 'CLEAR_ALERTS') {
21
- await fetch(`${baseUrl}/admin/broadcast`, {
22
- method: 'POST',
23
- headers: { 'Content-Type': 'application/json' },
24
- body: JSON.stringify({
25
- message: 'System Normal',
26
- type: 'SUCCESS'
27
- })
28
- });
29
- }
30
- } catch (e) {
31
- alert('Action Failed');
32
- }
33
- };
34
-
35
- return (
36
- <div className="bg-surface-tertiary rounded-xl border border-border-default p-6 shadow-lg">
37
- <h3 className="text-lg font-bold text-text-primary mb-4 flex items-center gap-2">
38
- <ShieldAlert size={20} className="text-red-400" /> Panic Room
39
- </h3>
40
-
41
- <div className="grid grid-cols-2 gap-3">
42
- <button
43
- onClick={() => triggerAction('FORCE_RELOAD')}
44
- className="flex flex-col items-center justify-center p-4 bg-red-900/20 hover:bg-red-900/40 border border-red-800/50 rounded-lg transition-colors group"
45
- >
46
- <RefreshCw size={24} className="text-red-500 mb-2 group-hover:rotate-180 transition-transform duration-500" />
47
- <span className="text-xs font-bold text-red-400">Force Reload All</span>
48
- </button>
49
-
50
- <button
51
- onClick={() => triggerAction('CLEAR_ALERTS')}
52
- className="flex flex-col items-center justify-center p-4 bg-emerald-900/20 hover:bg-emerald-900/40 border border-emerald-800/50 rounded-lg transition-colors"
53
- >
54
- <Zap size={24} className="text-emerald-500 mb-2" />
55
- <span className="text-xs font-bold text-emerald-400">System Normal</span>
56
- </button>
57
- </div>
58
- </div>
59
- );
60
- };