@decido/shell 1.0.0

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 (208) hide show
  1. package/.turbo/turbo-build.log +13 -0
  2. package/package.json +65 -0
  3. package/src/AgentPlayer.tsx +105 -0
  4. package/src/DecidoPlayer.tsx +117 -0
  5. package/src/bridge/BridgeAgent.ts +443 -0
  6. package/src/components/DecidoIcon.tsx +56 -0
  7. package/src/components/JsonTreeEditor.tsx +117 -0
  8. package/src/components/PanelSplitter.tsx +71 -0
  9. package/src/components/PluginErrorBoundary.tsx +69 -0
  10. package/src/components/SafeLiquidUI.tsx +114 -0
  11. package/src/components/TransientLayer.tsx +92 -0
  12. package/src/components/agent/AgentChat.tsx +134 -0
  13. package/src/components/chat-extensions/IntentCatalogPanel.tsx +81 -0
  14. package/src/components/chat-extensions/chatSlashCommands.ts +101 -0
  15. package/src/components/controls/CreatorInputBar.tsx +144 -0
  16. package/src/components/controls/OSToolbar.tsx +90 -0
  17. package/src/components/controls/TimelineTape.tsx +43 -0
  18. package/src/components/debug/ActionTimelineTab.tsx +111 -0
  19. package/src/components/debug/CSSInspectorTab.tsx +436 -0
  20. package/src/components/debug/ExportTab.tsx +192 -0
  21. package/src/components/debug/FlowHealthTab.tsx +86 -0
  22. package/src/components/debug/LogsTab.tsx +110 -0
  23. package/src/components/debug/MorphStackTab.tsx +241 -0
  24. package/src/components/debug/NetworkTab.tsx +173 -0
  25. package/src/components/debug/PerformanceTab.tsx +171 -0
  26. package/src/components/debug/ProfilesTab.tsx +238 -0
  27. package/src/components/debug/ReplayTab.tsx +70 -0
  28. package/src/components/debug/StoresTab.tsx +255 -0
  29. package/src/components/debug/TopologyTab.tsx +59 -0
  30. package/src/components/debug/debugConfig.tsx +66 -0
  31. package/src/components/playground/DebugPanel.tsx +112 -0
  32. package/src/components/playground/HeaderCenterControls.tsx +92 -0
  33. package/src/components/playground/KeyframeListItem.tsx +70 -0
  34. package/src/components/playground/PlaygroundAppSidebar.tsx +171 -0
  35. package/src/components/playground/PlaygroundBottomControls.tsx +132 -0
  36. package/src/components/playground/PlaygroundCanvas.tsx +87 -0
  37. package/src/components/playground/PlaygroundChat.tsx +236 -0
  38. package/src/components/playground/PlaygroundErrorBoundary.tsx +63 -0
  39. package/src/components/playground/PlaygroundFloatingInput.tsx +352 -0
  40. package/src/components/playground/PlaygroundHeader.tsx +222 -0
  41. package/src/components/playground/PlaygroundSidebar.tsx +136 -0
  42. package/src/components/playground/PlaygroundTerminal.tsx +44 -0
  43. package/src/components/playground/SuggestionCards.tsx +29 -0
  44. package/src/components/playground/demos/ClinicaAINode.tsx +221 -0
  45. package/src/components/playground/demos/FinanceAINode.tsx +226 -0
  46. package/src/components/playground/demos/KiaAcademyNode.tsx +250 -0
  47. package/src/components/playground/demos/KiaBotNode.tsx +207 -0
  48. package/src/components/playground/demos/KiaCampaignNode.tsx +191 -0
  49. package/src/components/playground/demos/KiaComplianceNode.tsx +140 -0
  50. package/src/components/playground/demos/KiaCustomerJourneyNode.tsx +220 -0
  51. package/src/components/playground/demos/KiaCyberNode.tsx +203 -0
  52. package/src/components/playground/demos/KiaDashboardNode.tsx +399 -0
  53. package/src/components/playground/demos/KiaEmbudoOverviewNode.tsx +168 -0
  54. package/src/components/playground/demos/KiaExecutiveNode.tsx +169 -0
  55. package/src/components/playground/demos/KiaGamificationNode.tsx +229 -0
  56. package/src/components/playground/demos/KiaIntelligenceHubNode.tsx +165 -0
  57. package/src/components/playground/demos/KiaInventoryNode.tsx +183 -0
  58. package/src/components/playground/demos/KiaLeadScoringNode.tsx +226 -0
  59. package/src/components/playground/demos/KiaLiveSimulationNode.tsx +177 -0
  60. package/src/components/playground/demos/KiaMultiDealerNode.tsx +223 -0
  61. package/src/components/playground/demos/KiaNPSVoiceNode.tsx +214 -0
  62. package/src/components/playground/demos/KiaOmnichannelNode.tsx +162 -0
  63. package/src/components/playground/demos/KiaPBIBudgetNode.tsx +152 -0
  64. package/src/components/playground/demos/KiaPBIConversionNode.tsx +206 -0
  65. package/src/components/playground/demos/KiaPBIFunnelNode.tsx +184 -0
  66. package/src/components/playground/demos/KiaPBIOwnershipNode.tsx +113 -0
  67. package/src/components/playground/demos/KiaPBIPartnerNode.tsx +143 -0
  68. package/src/components/playground/demos/KiaPBIPreciosNode.tsx +120 -0
  69. package/src/components/playground/demos/KiaPBIRuntNode.tsx +205 -0
  70. package/src/components/playground/demos/KiaPartnerScoreNode.tsx +206 -0
  71. package/src/components/playground/demos/KiaPredictiveNode.tsx +226 -0
  72. package/src/components/playground/demos/KiaShowroomNode.tsx +194 -0
  73. package/src/components/playground/demos/KiaStoreNode.tsx +215 -0
  74. package/src/components/playground/demos/KiaSustainabilityNode.tsx +173 -0
  75. package/src/components/playground/demos/KiaUsedVehiclesNode.tsx +163 -0
  76. package/src/components/playground/demos/KiaWorkshopNode.tsx +221 -0
  77. package/src/components/playground/demos/SmartCityNode.tsx +205 -0
  78. package/src/components/playground/demos/kia_campaign_manifest.json +112 -0
  79. package/src/components/playground/input-parts/AIModelSelector.tsx +156 -0
  80. package/src/components/playground/input-parts/InputActions.tsx +80 -0
  81. package/src/components/playground/input-parts/InputToolbar.tsx +245 -0
  82. package/src/components/playground/input-parts/ResourceLibraryPanel.tsx +287 -0
  83. package/src/components/playground/sidebarDsdIO.ts +82 -0
  84. package/src/components/settings/SettingsPanel.tsx +267 -0
  85. package/src/components/shell/AppHeader.tsx +9 -0
  86. package/src/components/shell/AppShell.tsx +139 -0
  87. package/src/components/shell/ArtifactBar.tsx +97 -0
  88. package/src/components/shell/BootScreen.tsx +19 -0
  89. package/src/components/shell/CenterComposite.tsx +87 -0
  90. package/src/components/shell/CodeEditorPanel.tsx +88 -0
  91. package/src/components/shell/GlobalOverlays.tsx +228 -0
  92. package/src/components/shell/LayoutConfigurator.tsx +209 -0
  93. package/src/components/shell/LayoutGrid.tsx +178 -0
  94. package/src/components/shell/MorphShell.tsx +368 -0
  95. package/src/components/shell/PluginViewer.tsx +147 -0
  96. package/src/components/shell/ShellNexusPreview.tsx +458 -0
  97. package/src/components/shell/SlotRenderer.tsx +115 -0
  98. package/src/components/shell/TabBar.tsx +94 -0
  99. package/src/components/shell/TemplateLibrary.tsx +195 -0
  100. package/src/components/shell/layoutConstants.ts +35 -0
  101. package/src/components/shell/morphStageMeta.ts +15 -0
  102. package/src/components/shell/shells/BuiltInShells.tsx +443 -0
  103. package/src/components/shell/shells/DatawayChatShell.tsx +42 -0
  104. package/src/components/shell/shells/TokenPreview.tsx +339 -0
  105. package/src/components/shell/shells/bootShells.ts +31 -0
  106. package/src/components/shells/CreatorShell.tsx +37 -0
  107. package/src/components/shells/DecidoShell.tsx +447 -0
  108. package/src/components/shells/ExperimentalChatShell.tsx +245 -0
  109. package/src/components/shells/UserCanvas.tsx +44 -0
  110. package/src/components/studio/BlueprintManagerPanel.tsx +137 -0
  111. package/src/components/studio/DependencyTreePanel.tsx +192 -0
  112. package/src/components/studio/NodePalette.tsx +92 -0
  113. package/src/components/studio/NodePropertiesPanel.tsx +81 -0
  114. package/src/components/studio/ReactFlowEditor.tsx +242 -0
  115. package/src/components/studio/TimelineEditor.tsx +122 -0
  116. package/src/components/studio/TimelineKeyframeCard.tsx +99 -0
  117. package/src/components/studio/VariablePanel.tsx +181 -0
  118. package/src/components/studio/blueprint/BlueprintCard.tsx +82 -0
  119. package/src/components/studio/editor/CanvasContextMenu.tsx +107 -0
  120. package/src/components/studio/editor/EditorToolbar.tsx +80 -0
  121. package/src/components/studio/editor/StageContentRenderer.tsx +134 -0
  122. package/src/components/studio/editor/TrackPropertyEditors.tsx +133 -0
  123. package/src/components/studio/editor/TreeNodeItem.tsx +91 -0
  124. package/src/components/studio/editor/edgeStyles.ts +43 -0
  125. package/src/components/studio/editor/editorKeyHandler.ts +95 -0
  126. package/src/components/studio/editor/nodeTypeRegistry.ts +137 -0
  127. package/src/components/studio/editor/paletteCatalog.tsx +84 -0
  128. package/src/components/studio/nodes/shell/InteractionNodes.tsx +82 -0
  129. package/src/components/studio/nodes/shell/LayoutControlNodes.tsx +69 -0
  130. package/src/components/studio/nodes/shell/RegisterActionNode.tsx +20 -0
  131. package/src/components/studio/nodes/shell/RegisterButtonNode.tsx +22 -0
  132. package/src/components/studio/nodes/shell/RegisterPanelNode.tsx +19 -0
  133. package/src/components/studio/nodes/shell/RegisterSidebarNode.tsx +19 -0
  134. package/src/components/studio/nodes/shell/RegisterStatusBarNode.tsx +22 -0
  135. package/src/components/studio/nodes/shell/RegisterTabNode.tsx +21 -0
  136. package/src/components/studio/nodes/shell/RegisterTopBarNode.tsx +22 -0
  137. package/src/components/studio/nodes/shell/ShellConfigNode.tsx +51 -0
  138. package/src/components/studio/nodes/shell/ShellNodeBase.tsx +100 -0
  139. package/src/components/studio/nodes/shell/ThemeNodes.tsx +51 -0
  140. package/src/components/studio/nodes/shell/index.ts +12 -0
  141. package/src/components/widgets/BroadcastWidget.tsx +93 -0
  142. package/src/components/widgets/MarketplaceWidget.tsx +298 -0
  143. package/src/components/widgets/McpToolsWidget.tsx +231 -0
  144. package/src/components/widgets/OpsDashboard.tsx +59 -0
  145. package/src/components/widgets/QuickActionsWidget.tsx +60 -0
  146. package/src/components/widgets/UsageWidget.tsx +112 -0
  147. package/src/components/widgets/WidgetRenderer.tsx +892 -0
  148. package/src/components/widgets/WidgetSlotPanel.tsx +213 -0
  149. package/src/config/IconRegistry.ts +126 -0
  150. package/src/contexts/NetworkProvider.tsx +162 -0
  151. package/src/core/AIDirector.ts +71 -0
  152. package/src/core/EventBus.ts +37 -0
  153. package/src/core/PluginContext.tsx +141 -0
  154. package/src/hooks/listeners/useUIStateListener.ts +59 -0
  155. package/src/hooks/listeners/useWhatsAppListener.ts +110 -0
  156. package/src/hooks/morphBridge.ts +82 -0
  157. package/src/hooks/useAIModelSelector.ts +144 -0
  158. package/src/hooks/useAgentStream.ts +220 -0
  159. package/src/hooks/useAutoUpdater.ts +89 -0
  160. package/src/hooks/useBootSequence.ts +20 -0
  161. package/src/hooks/useExportDSD.ts +53 -0
  162. package/src/hooks/useFullscreen.ts +35 -0
  163. package/src/hooks/useGeminiStream.ts +282 -0
  164. package/src/hooks/useIntentLens.ts +224 -0
  165. package/src/hooks/useKeyboardShortcuts.ts +69 -0
  166. package/src/hooks/useLoggerBridge.ts +32 -0
  167. package/src/hooks/useMcpClient.ts +112 -0
  168. package/src/hooks/useNexusaiDeploy.ts +118 -0
  169. package/src/hooks/usePlaybackEngine.ts +21 -0
  170. package/src/hooks/usePlaygroundCommander.ts +475 -0
  171. package/src/hooks/usePluginEngine.ts +165 -0
  172. package/src/hooks/useScreenRecorder.ts +73 -0
  173. package/src/hooks/useShellKeyboard.ts +40 -0
  174. package/src/hooks/useShellShortcuts.ts +118 -0
  175. package/src/hooks/useSoundEffects.ts +35 -0
  176. package/src/hooks/useStudioConfig.ts +72 -0
  177. package/src/hooks/useSystemBoot.ts +84 -0
  178. package/src/hooks/useSystemTelemetry.ts +62 -0
  179. package/src/index.ts +97 -0
  180. package/src/lib/debugLogger.ts +80 -0
  181. package/src/lib/networkInterceptor.ts +100 -0
  182. package/src/mocks/decido.tsx +41 -0
  183. package/src/plugins/pluginAPI.ts +190 -0
  184. package/src/store/McpStore.ts +69 -0
  185. package/src/store/UpdaterStore.ts +60 -0
  186. package/src/store/engine.ts +392 -0
  187. package/src/store/index.ts +4 -0
  188. package/src/store/layoutPresets.ts +66 -0
  189. package/src/store/playgroundTypes.ts +98 -0
  190. package/src/store/useActionTimelineStore.ts +48 -0
  191. package/src/store/useDebugPanelStore.ts +98 -0
  192. package/src/store/useDebugProfileStore.ts +130 -0
  193. package/src/store/useLayoutStore.ts +205 -0
  194. package/src/store/useMorphInstanceStore.ts +289 -0
  195. package/src/store/useMorphologyStore.ts +103 -0
  196. package/src/store/usePlaygroundStore.ts +236 -0
  197. package/src/store/useShellRegistry.ts +123 -0
  198. package/src/store/useSuggestionsStore.ts +57 -0
  199. package/src/store/useThemeStore.ts +399 -0
  200. package/src/store/useUIComponentStore.ts +179 -0
  201. package/src/types/DecidoStoryDefinition.ts +43 -0
  202. package/src/utils/ai/ai-architect.ts +92 -0
  203. package/src/utils/ai/ai-code.ts +187 -0
  204. package/src/utils/ai/ai-core.ts +50 -0
  205. package/src/utils/ai/ai-media.ts +292 -0
  206. package/src/utils/layoutGraph.ts +67 -0
  207. package/tsconfig.json +17 -0
  208. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,179 @@
1
+ import { create } from 'zustand';
2
+ import { persist } from 'zustand/middleware';
3
+
4
+ // ─── Server-Driven UI Types ───
5
+ export interface ServerDrivenNode {
6
+ type: string;
7
+ props?: Record<string, any>;
8
+ children?: ServerDrivenNode[] | string;
9
+ onAction?: {
10
+ command: string;
11
+ payload?: any;
12
+ };
13
+ }
14
+
15
+ export interface UIComponentDefinition {
16
+ id: string;
17
+ name: string;
18
+ category: 'form' | 'card' | 'table' | 'chart' | 'layout' | 'alert' | 'custom';
19
+ schema: ServerDrivenNode;
20
+ dataContract: {
21
+ inputs: Record<string, { type: string; description: string }>;
22
+ outputs: Record<string, { type: string }>;
23
+ };
24
+ tags: string[];
25
+ source: 'built-in' | 'ai-generated' | 'server' | 'user';
26
+ preview?: string;
27
+ createdAt: number;
28
+ updatedAt: number;
29
+ }
30
+
31
+ interface UIComponentState {
32
+ components: Record<string, UIComponentDefinition>;
33
+ addComponent: (component: UIComponentDefinition) => void;
34
+ removeComponent: (id: string) => void;
35
+ updateComponent: (id: string, updates: Partial<UIComponentDefinition>) => void;
36
+ getByCategory: (category: string) => UIComponentDefinition[];
37
+ getBySource: (source: string) => UIComponentDefinition[];
38
+ }
39
+
40
+ // ─── Built-in UI Components (Seeds) ───
41
+ const BUILT_IN_COMPONENTS: UIComponentDefinition[] = [
42
+ {
43
+ id: 'builtin_status_card',
44
+ name: 'Status Card',
45
+ category: 'card',
46
+ schema: {
47
+ type: 'div',
48
+ props: { className: 'bg-zinc-900/80 border border-border-default rounded-xl p-4 backdrop-blur-xs' },
49
+ children: [
50
+ { type: 'div', props: { className: 'flex items-center gap-2 mb-2' }, children: [
51
+ { type: 'span', props: { className: 'w-2 h-2 rounded-full bg-emerald-400 animate-pulse' } },
52
+ { type: 'span', props: { className: 'text-xs font-mono text-text-secondary uppercase tracking-wider' }, children: '{{title}}' }
53
+ ]},
54
+ { type: 'h3', props: { className: 'text-2xl font-bold text-white' }, children: '{{value}}' },
55
+ { type: 'p', props: { className: 'text-xs text-text-muted mt-1' }, children: '{{subtitle}}' }
56
+ ]
57
+ },
58
+ dataContract: {
59
+ inputs: { title: { type: 'string', description: 'Card title' }, value: { type: 'string', description: 'Main value' }, subtitle: { type: 'string', description: 'Description' } },
60
+ outputs: {}
61
+ },
62
+ tags: ['status', 'metric', 'dashboard'],
63
+ source: 'built-in',
64
+ createdAt: Date.now(),
65
+ updatedAt: Date.now()
66
+ },
67
+ {
68
+ id: 'builtin_alert_banner',
69
+ name: 'Alert Banner',
70
+ category: 'alert',
71
+ schema: {
72
+ type: 'div',
73
+ props: { className: 'flex items-center gap-3 p-3 rounded-lg border border-amber-500/20 bg-amber-500/5' },
74
+ children: [
75
+ { type: 'span', props: { className: 'text-amber-400 text-lg' }, children: '⚠️' },
76
+ { type: 'div', children: [
77
+ { type: 'p', props: { className: 'text-sm font-semibold text-amber-200' }, children: '{{title}}' },
78
+ { type: 'p', props: { className: 'text-xs text-amber-300/70' }, children: '{{message}}' }
79
+ ]}
80
+ ]
81
+ },
82
+ dataContract: {
83
+ inputs: { title: { type: 'string', description: 'Alert title' }, message: { type: 'string', description: 'Alert message' } },
84
+ outputs: {}
85
+ },
86
+ tags: ['alert', 'warning', 'notification'],
87
+ source: 'built-in',
88
+ createdAt: Date.now(),
89
+ updatedAt: Date.now()
90
+ },
91
+ {
92
+ id: 'builtin_input_form',
93
+ name: 'Text Input Form',
94
+ category: 'form',
95
+ schema: {
96
+ type: 'div',
97
+ props: { className: 'bg-zinc-900/80 border border-border-default rounded-xl p-4 space-y-3' },
98
+ children: [
99
+ { type: 'label', props: { className: 'text-sm text-text-primary font-medium' }, children: '{{label}}' },
100
+ { type: 'input', props: { className: 'w-full bg-zinc-800 border border-border-default rounded-lg px-3 py-2 text-white text-sm focus:border-purple-500/50 outline-hidden transition-colors', placeholder: '{{placeholder}}' }, onAction: { command: 'engine:setVariable', payload: { target: '{{variableKey}}' } } },
101
+ { type: 'button', props: { className: 'w-full py-2 bg-purple-500 hover:bg-purple-400 text-white text-sm font-medium rounded-lg transition-colors' }, children: '{{buttonText}}', onAction: { command: 'engine:completeNode', payload: { handle: 'success' } } }
102
+ ]
103
+ },
104
+ dataContract: {
105
+ inputs: { label: { type: 'string', description: 'Input label' }, placeholder: { type: 'string', description: 'Placeholder text' }, variableKey: { type: 'string', description: 'Target variable key' }, buttonText: { type: 'string', description: 'Submit button text' } },
106
+ outputs: { value: { type: 'string' } }
107
+ },
108
+ tags: ['form', 'input', 'interactive'],
109
+ source: 'built-in',
110
+ createdAt: Date.now(),
111
+ updatedAt: Date.now()
112
+ },
113
+ {
114
+ id: 'builtin_data_table',
115
+ name: 'Data Table',
116
+ category: 'table',
117
+ schema: {
118
+ type: 'div',
119
+ props: { className: 'bg-zinc-900/80 border border-border-default rounded-xl overflow-hidden' },
120
+ children: [
121
+ { type: 'div', props: { className: 'px-4 py-3 border-b border-border-subtle' }, children: [
122
+ { type: 'h4', props: { className: 'text-sm font-semibold text-white' }, children: '{{title}}' }
123
+ ]},
124
+ { type: 'table', props: { className: 'w-full' }, children: [
125
+ { type: 'thead', children: [
126
+ { type: 'tr', props: { className: 'text-xs text-text-muted uppercase' }, children: '{{headers}}' }
127
+ ]},
128
+ { type: 'tbody', props: { className: 'text-sm text-text-primary' }, children: '{{rows}}' }
129
+ ]}
130
+ ]
131
+ },
132
+ dataContract: {
133
+ inputs: { title: { type: 'string', description: 'Table title' }, headers: { type: 'string', description: 'Column headers' }, rows: { type: 'string', description: 'Table rows data' } },
134
+ outputs: {}
135
+ },
136
+ tags: ['table', 'data', 'list'],
137
+ source: 'built-in',
138
+ createdAt: Date.now(),
139
+ updatedAt: Date.now()
140
+ }
141
+ ];
142
+
143
+ // ─── Store ───
144
+ export const useUIComponentStore = create<UIComponentState>()(
145
+ persist(
146
+ (set, get) => ({
147
+ components: Object.fromEntries(BUILT_IN_COMPONENTS.map(c => [c.id, c])),
148
+
149
+ addComponent: (component) => set((state) => ({
150
+ components: { ...state.components, [component.id]: component }
151
+ })),
152
+
153
+ removeComponent: (id) => set((state) => {
154
+ const { [id]: _, ...rest } = state.components;
155
+ return { components: rest };
156
+ }),
157
+
158
+ updateComponent: (id, updates) => set((state) => {
159
+ const existing = state.components[id];
160
+ if (!existing) return state;
161
+ return {
162
+ components: {
163
+ ...state.components,
164
+ [id]: { ...existing, ...updates, updatedAt: Date.now() }
165
+ }
166
+ };
167
+ }),
168
+
169
+ getByCategory: (category) => {
170
+ return Object.values(get().components).filter(c => c.category === category);
171
+ },
172
+
173
+ getBySource: (source) => {
174
+ return Object.values(get().components).filter(c => c.source === source);
175
+ }
176
+ }),
177
+ { name: 'decido-ui-components' }
178
+ )
179
+ );
@@ -0,0 +1,43 @@
1
+ export interface DSDMeta {
2
+ version: string; // e.g., '1.0'
3
+ author: string;
4
+ createdAt: number;
5
+ updatedAt: number;
6
+ title: string;
7
+ description: string;
8
+ tags: string[];
9
+ }
10
+
11
+ export interface DSDConfig {
12
+ defaultVoice: string;
13
+ defaultBgm?: string;
14
+ brandTheme: string;
15
+ environment: 'light' | 'dark' | 'auto';
16
+ }
17
+
18
+ export interface DSDActor {
19
+ id: string; // e.g., 'zephyr_ai'
20
+ name: string;
21
+ role: string;
22
+ voiceId?: string;
23
+ avatarUrl?: string; // or 3D model ref
24
+ }
25
+
26
+ export interface DSDKeyframe {
27
+ id: string;
28
+ t: number; // Time in seconds
29
+ state: string; // The morph/action state string
30
+ actorId?: string; // Who performs the action
31
+ speech?: string; // Dialogue to say
32
+ delay?: number; // Delay before next block if auto-advancing
33
+ canvas?: boolean; // Should open 3D canvas?
34
+ uiConfig?: any; // Any extra JSON config for UI morphing
35
+ }
36
+
37
+ export interface DecidoStoryDefinition {
38
+ id: string; // UUID of the document
39
+ meta: DSDMeta;
40
+ config: DSDConfig;
41
+ actors: DSDActor[];
42
+ timeline: DSDKeyframe[];
43
+ }
@@ -0,0 +1,92 @@
1
+ // ═══════════════════════════════════════════════════════
2
+ // AI Architect — System architecture analysis
3
+ // ═══════════════════════════════════════════════════════
4
+
5
+ import { Type, FunctionDeclaration } from "@google/genai";
6
+ import { getClient, logger } from './ai-core';
7
+
8
+ // Mock CodebaseContextService for shared package
9
+ const codebaseContext = {
10
+ readRealFile: async (path: string): Promise<string> => {
11
+ return `[MOCK] Reading file ${path} is not supported in the standalone package environment yet.`;
12
+ }
13
+ };
14
+
15
+ const readSourceFileTool: FunctionDeclaration = {
16
+ name: 'readSourceFile',
17
+ description: 'LEE el contenido real de un archivo del proyecto. Úsalo SIEMPRE que te pregunten sobre código específico o arquitectura actual.',
18
+ parameters: {
19
+ type: Type.OBJECT,
20
+ properties: {
21
+ fileNameOrPath: {
22
+ type: Type.STRING,
23
+ description: 'El nombre del archivo (ej: "App.tsx") o su ruta relativa (ej: "src/utils/ai.ts").'
24
+ }
25
+ },
26
+ required: ['fileNameOrPath']
27
+ }
28
+ };
29
+
30
+ export const chatWithArchitect = async (
31
+ history: { role: 'user' | 'model' | 'function'; parts: { text?: string; functionCall?: any; functionResponse?: any }[] }[],
32
+ userMessage: string
33
+ ): Promise<string> => {
34
+ const client = getClient('text');
35
+ if (!client) return "API Key Config Missing";
36
+
37
+ const systemInstruction = `
38
+ ERES: Sentinel Architect, la IA residente que vive DENTRO del código fuente.
39
+
40
+ PROTOCOLO ESPEJO ACTIVO:
41
+ 1. Tienes acceso de LECTURA al disco duro mediante la herramienta 'readSourceFile'.
42
+ 2. NO asumas cómo es el código. Si te preguntan "¿Cómo funciona el store?", LLAMA a 'readSourceFile("useSentinelStore.ts")' primero.
43
+ 3. Cuando leas código, analízalo críticamente. Sugiere mejoras reales basadas en el contenido leído.
44
+ 4. Sé conciso y técnico.
45
+ `;
46
+
47
+ const currentHistory = [...history];
48
+ currentHistory.push({ role: 'user', parts: [{ text: userMessage }] });
49
+
50
+ try {
51
+ const response = await client.models.generateContent({
52
+ model: "gemini-flash-lite-latest-exp",
53
+ contents: currentHistory,
54
+ config: {
55
+ systemInstruction: systemInstruction,
56
+ tools: [{ functionDeclarations: [readSourceFileTool] }],
57
+ }
58
+ });
59
+
60
+ const call = response.functionCalls?.[0];
61
+
62
+ if (call && call.name === 'readSourceFile') {
63
+ const args = call.args as any;
64
+ const filename = args.fileNameOrPath;
65
+
66
+ logger.log(`[ARCHITECT] Invocando lectura de disco para: ${filename}`);
67
+ const fileContent = await codebaseContext.readRealFile(filename);
68
+
69
+ const functionResponse = {
70
+ name: "readSourceFile",
71
+ response: { content: fileContent.substring(0, 30000) }
72
+ };
73
+
74
+ currentHistory.push({ role: 'model', parts: [{ functionCall: call }] });
75
+ currentHistory.push({ role: 'function', parts: [{ functionResponse: functionResponse }] });
76
+
77
+ const finalResponse = await client.models.generateContent({
78
+ model: "gemini-flash-lite-latest-exp",
79
+ contents: currentHistory,
80
+ config: { systemInstruction: systemInstruction }
81
+ });
82
+
83
+ return finalResponse.text || "No response generated.";
84
+ }
85
+
86
+ return response.text || "No response generated.";
87
+
88
+ } catch (error: any) {
89
+ logger.error("Architect Error:", error);
90
+ return `Error en Protocolo Espejo: ${error.message}`;
91
+ }
92
+ };
@@ -0,0 +1,187 @@
1
+ // ═══════════════════════════════════════════════════════
2
+ // AI Code — Code analysis, diagnostics, explanation
3
+ // ═══════════════════════════════════════════════════════
4
+
5
+ import { Type } from "@google/genai";
6
+ import { getClient, getGlobalSettings, logger } from './ai-core';
7
+ import { AIDiagnostic } from '@decido/canvas-core';
8
+
9
+ export { type AIDiagnostic };
10
+
11
+ export const analyzeCode = async (code: string, language: string): Promise<AIDiagnostic[]> => {
12
+ const client = getClient('text');
13
+ if (!client) return [];
14
+ const settings = getGlobalSettings();
15
+
16
+ try {
17
+ const response = await client.models.generateContent({
18
+ model: settings.text.model || 'gemini-3-flash-preview',
19
+ contents: `Analyze this ${language} code for Security Risks, Performance Issues, and Core Stability flaws.
20
+
21
+ CODE:
22
+ ${code}
23
+
24
+ Return a JSON array of diagnostics.
25
+ For 'godMode', provide a specific, high - level technical solution(HTML string allowed for bolding).
26
+ `,
27
+ config: {
28
+ responseMimeType: "application/json",
29
+ responseSchema: {
30
+ type: Type.ARRAY,
31
+ items: {
32
+ type: Type.OBJECT,
33
+ properties: {
34
+ type: { type: Type.STRING, enum: ['risk', 'perf', 'core'] },
35
+ lines: {
36
+ type: Type.ARRAY,
37
+ items: { type: Type.INTEGER },
38
+ minItems: 2,
39
+ maxItems: 2
40
+ },
41
+ title: { type: Type.STRING },
42
+ description: { type: Type.STRING },
43
+ godMode: { type: Type.STRING }
44
+ },
45
+ required: ['type', 'lines', 'title', 'description']
46
+ }
47
+ }
48
+ }
49
+ });
50
+
51
+ return JSON.parse(response.text || '[]');
52
+ } catch (e) {
53
+ logger.error("Code Analysis Error", e);
54
+ return [];
55
+ }
56
+ };
57
+
58
+ export const explainCode = async (code: string, language: string): Promise<string> => {
59
+ const client = getClient('text');
60
+ if (!client) return "API Key Config Missing";
61
+ const settings = getGlobalSettings();
62
+
63
+ try {
64
+ const response = await client.models.generateContent({
65
+ model: settings.text.model || 'gemini-3-flash-preview',
66
+ contents: `Explain this ${language} code concisely.Focus on architecture, logic flow, and potential side effects.Use Markdown.
67
+
68
+ CODE:
69
+ ${code} `
70
+ });
71
+ return response.text || "No explanation generated.";
72
+ } catch (e) {
73
+ logger.error("Code Explanation Error", e);
74
+ return "Failed to generate explanation.";
75
+ }
76
+ };
77
+
78
+ export const generateCodeExplanation = async (codeSnippet: string, filename: string): Promise<string> => {
79
+ const client = getClient('text');
80
+ if (!client) return "<code>API Key Missing</code>";
81
+ const settings = getGlobalSettings();
82
+
83
+ try {
84
+ const response = await client.models.generateContent({
85
+ model: settings.text.model || 'gemini-3-flash-preview',
86
+ contents: `Explain this code file("${filename}") visually.
87
+
88
+ CODE:
89
+ ${codeSnippet.slice(0, 2000)}... (truncated)
90
+
91
+ GOAL:
92
+ Return a SINGLE HTML STRING that renders a beautiful, modern "Knowledge Card" explaining the code.
93
+
94
+ DESIGN REQUIREMENTS:
95
+ - Use TailwindCSS(via CDN or inline styles / classes if allowed, assume Tailwind is present or use inline styles for safety).
96
+ - Dark mode aesthetic(bg - slate - 900 text - slate - 200).
97
+ - Include a Title(Filename).
98
+ - Include a "Purpose" section(What does this code do?).
99
+ - Include a "Key Components" list.
100
+ - Include a "Complexity Score"(1 - 10) with a visual progress bar.
101
+ - Make it look like a sci - fi / cyberpunk HUD element.
102
+ - NO Markdown.ONLY valid HTML.
103
+ `,
104
+ config: {
105
+ responseMimeType: "text/plain"
106
+ }
107
+ });
108
+
109
+ let html = response.text || "<div>No explanation generated.</div>";
110
+ html = html.replace(/```html/g, '').replace(/```/g, '');
111
+ return html;
112
+
113
+ } catch (error) {
114
+ logger.error("Explanation Error:", error);
115
+ return `<div style="color:red">Failed to generate explanation.</div>`;
116
+ }
117
+ };
118
+
119
+ export const generateHtmlAndMacros = async (history: { role: 'user' | 'model', parts: { text: string }[] }[], currentHtml: string): Promise<any> => {
120
+ const client = getClient('text');
121
+ if (!client) return null;
122
+ const settings = getGlobalSettings();
123
+
124
+ try {
125
+ const response = await client.models.generateContent({
126
+ model: settings.text.model || 'gemini-3-flash-preview',
127
+ contents: `
128
+ You are an expert Frontend Developer and QA Automation Engineer.
129
+
130
+ CONTEXT:
131
+ Current HTML:
132
+ ${currentHtml}
133
+
134
+ USER REQUEST HISTORY:
135
+ ${JSON.stringify(history)}
136
+
137
+ GOAL:
138
+ 1. Update HTML if requested.
139
+ 2. Create automation workflows (macros) if requested (e.g., "click button", "type text").
140
+
141
+ RETURN JSON:
142
+ {
143
+ "html": "Updated HTML string (optional)",
144
+ "workflow": [
145
+ { "id": "step1", "type": "click", "selector": "#btn", "label": "Click Button" },
146
+ { "type": "type", "selector": "#input", "value": "Hello", "label": "Type Hello" },
147
+ { "type": "scroll", "scrollY": 500, "label": "Scroll Down" },
148
+ { "type": "wait", "duration": 2000, "label": "Wait 2s" }
149
+ ],
150
+ "explanation": "Short summary of changes"
151
+ }
152
+ `,
153
+ config: {
154
+ responseMimeType: "application/json"
155
+ }
156
+ });
157
+
158
+ return JSON.parse(response.text || '{}');
159
+ } catch (e) {
160
+ logger.error("HTML/Macro Gen Error", e);
161
+ return null;
162
+ }
163
+ };
164
+
165
+ export const generateBrainstorm = async (context: string): Promise<string[]> => {
166
+ const client = getClient('text');
167
+ if (!client) return [];
168
+ const settings = getGlobalSettings();
169
+
170
+ try {
171
+ const response = await client.models.generateContent({
172
+ model: settings.text.model || 'gemini-3-flash-preview',
173
+ contents: `Brainstorm 5 creative ideas/expansions for this context: "${context}". Return JSON array of strings.`,
174
+ config: {
175
+ responseMimeType: "application/json",
176
+ responseSchema: {
177
+ type: Type.ARRAY,
178
+ items: { type: Type.STRING }
179
+ }
180
+ }
181
+ });
182
+ return JSON.parse(response.text || '[]');
183
+ } catch (e) {
184
+ logger.error("Brainstorm Error", e);
185
+ return [];
186
+ }
187
+ };
@@ -0,0 +1,50 @@
1
+ // ═══════════════════════════════════════════════════════
2
+ // AI Core — Shared infrastructure for all AI modules
3
+ // ═══════════════════════════════════════════════════════
4
+
5
+ import { GoogleGenAI } from "@google/genai";
6
+
7
+ // Simple Logger Mock
8
+ const logger = {
9
+ log: console.log,
10
+ warn: console.warn,
11
+ error: console.error
12
+ };
13
+
14
+ export interface AISettings {
15
+ text: { model: string; apiKey: string };
16
+ image: { model: string; apiKey: string };
17
+ video: { model: string; apiKey: string };
18
+ audio: { model: string; apiKey: string };
19
+ }
20
+
21
+ // Default configuration
22
+ let globalSettings: AISettings = {
23
+ text: { model: 'gemini-3-flash-preview', apiKey: '' },
24
+ image: { model: 'gemini-3-pro-image-preview', apiKey: '' },
25
+ video: { model: 'veo-3.1-generate-preview', apiKey: '' },
26
+ audio: { model: 'gemini-2.5-flash-preview-tts', apiKey: '' }
27
+ };
28
+
29
+ export const updateGlobalAISettings = (settings: AISettings) => {
30
+ globalSettings = settings;
31
+ };
32
+
33
+ export const getGlobalSettings = () => globalSettings;
34
+
35
+ // Helper to get client with specific config
36
+ export const getClient = (category: keyof AISettings) => {
37
+ const config = globalSettings[category];
38
+ const key = config.apiKey || process.env.VITE_API_KEY || ''; // Copia de seguridad si no se setea
39
+
40
+ if (!key) return null;
41
+
42
+ try {
43
+ return new GoogleGenAI({ apiKey: key });
44
+ } catch (e) {
45
+ logger.error("Failed to initialize GoogleGenAI client", e);
46
+ return null;
47
+ }
48
+ };
49
+
50
+ export { logger };