wadi 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 (294) hide show
  1. package/.agent/workflows/auto_sync.md +19 -0
  2. package/.agent/workflows/kivo_pipeline.md +27 -0
  3. package/.devcontainer/devcontainer.json +27 -0
  4. package/.github/workflows/kivo-cicd.yml +45 -0
  5. package/.github/workflows/monorepo-ci.yml +51 -0
  6. package/.github/workflows/wadi-ci.yml +38 -0
  7. package/.husky/pre-commit +2 -0
  8. package/.prettierignore +12 -0
  9. package/.prettierrc +9 -0
  10. package/.vscode/settings.json +19 -0
  11. package/CHANGELOG.md +56 -0
  12. package/CODE_OF_CONDUCT.md +43 -0
  13. package/CONTRIBUTING.md +42 -0
  14. package/DEPLOY_GUIDE.md +143 -0
  15. package/GO_LIVE_CHECKLIST.md +41 -0
  16. package/GO_LIVE_COMPLETE_REPORT.md +58 -0
  17. package/GO_LIVE_VALIDATION.md +39 -0
  18. package/LEGAL.md +38 -0
  19. package/MANIFESTO.md +40 -0
  20. package/MANUAL.md +82 -0
  21. package/OPS_PLAN.md +90 -0
  22. package/README.md +126 -0
  23. package/RELEASE_NOTES.md +51 -0
  24. package/ROADMAP.md +51 -0
  25. package/api_listado.txt +2197 -0
  26. package/apps/api/WADI_PROTOCOL.md +52 -0
  27. package/apps/api/debug-brain.js +11 -0
  28. package/apps/api/package.json +21 -0
  29. package/apps/api/src/core/analisis.js +17 -0
  30. package/apps/api/src/core/errors.js +31 -0
  31. package/apps/api/src/core/logger.js +32 -0
  32. package/apps/api/src/core/prompt-kivo.js +62 -0
  33. package/apps/api/src/index.js +212 -0
  34. package/apps/api/src/layers/human_pattern/composeResponse.js +35 -0
  35. package/apps/api/src/layers/human_pattern/detectPattern.js +39 -0
  36. package/apps/api/src/layers/human_pattern/heuristics.js +28 -0
  37. package/apps/api/src/layers/human_pattern/index.js +28 -0
  38. package/apps/api/src/layers/human_pattern/socialMemory.js +35 -0
  39. package/apps/api/src/middleware/errorHandler.js +24 -0
  40. package/apps/api/src/middleware/rateLimiter.js +38 -0
  41. package/apps/api/src/middleware/requestLogger.js +31 -0
  42. package/apps/api/src/middleware/upload.js +21 -0
  43. package/apps/api/src/middleware/validation.js +70 -0
  44. package/apps/api/src/modules/data.js +25 -0
  45. package/apps/api/src/modules/marketing.js +54 -0
  46. package/apps/api/src/modules/projects.js +40 -0
  47. package/apps/api/src/openai.js +16 -0
  48. package/apps/api/src/preferences/index.js +20 -0
  49. package/apps/api/src/register_user.js +22 -0
  50. package/apps/api/src/routes/kivo.js +58 -0
  51. package/apps/api/src/routes/monitoring.js +55 -0
  52. package/apps/api/src/routes.js +656 -0
  53. package/apps/api/src/supabase.js +17 -0
  54. package/apps/api/src/tools/index.js +57 -0
  55. package/apps/api/src/wadi-brain.js +171 -0
  56. package/apps/api/supabase/migrations/20251218_audit_logs.sql +27 -0
  57. package/apps/api/supabase/migrations/v2-chat-persistence.sql +83 -0
  58. package/apps/api/supabase/migrations/v3-cascade-delete.sql +11 -0
  59. package/apps/api/supabase/migrations/v3-security-fix.sql +90 -0
  60. package/apps/api/supabase/migrations/v3-storage.sql +36 -0
  61. package/apps/api/supabase/migrations/v4-gamification.sql +83 -0
  62. package/apps/api/supabase/migrations/v5-smoke-index.sql +6 -0
  63. package/apps/api/supabase/migrations/v6-schema-integrity-fix.sql +98 -0
  64. package/apps/api/supabase/migrations/v7-performance-indexes.sql +5 -0
  65. package/apps/api/supabase/migrations/v7-security-hardening.sql +132 -0
  66. package/apps/api/supabase/migrations/v8-security-hardening.sql +79 -0
  67. package/apps/api/test_human_pattern.js +30 -0
  68. package/apps/api/test_human_pattern_vague.js +30 -0
  69. package/apps/api/test_output.txt +76 -0
  70. package/apps/api/test_vague.js +30 -0
  71. package/apps/api/test_vague_block.js +30 -0
  72. package/apps/api/test_wadi.js +31 -0
  73. package/apps/api/tsconfig.json +13 -0
  74. package/apps/frontend/.env.local +3 -0
  75. package/apps/frontend/README.md +73 -0
  76. package/apps/frontend/eslint.config.js +27 -0
  77. package/apps/frontend/index.html +49 -0
  78. package/apps/frontend/package.json +41 -0
  79. package/apps/frontend/postcss.config.cjs +6 -0
  80. package/apps/frontend/public/cursors/wadi-neutral.svg +1 -0
  81. package/apps/frontend/public/cursors/wadi-select.svg +1 -0
  82. package/apps/frontend/public/icon-192.svg +1 -0
  83. package/apps/frontend/public/icon-512.svg +1 -0
  84. package/apps/frontend/public/manifest.webmanifest +23 -0
  85. package/apps/frontend/public/sw.js +57 -0
  86. package/apps/frontend/public/vite.svg +1 -0
  87. package/apps/frontend/public/wadi.svg +5 -0
  88. package/apps/frontend/src/assets/react.svg +1 -0
  89. package/apps/frontend/src/components/AuthLoader.tsx +50 -0
  90. package/apps/frontend/src/components/ChatInput.tsx +272 -0
  91. package/apps/frontend/src/components/ChatInterface.tsx +202 -0
  92. package/apps/frontend/src/components/ErrorBoundary.tsx +52 -0
  93. package/apps/frontend/src/components/InputArea.tsx +201 -0
  94. package/apps/frontend/src/components/Layout.tsx +73 -0
  95. package/apps/frontend/src/components/MessageBubble.tsx +66 -0
  96. package/apps/frontend/src/components/OnboardingModal.tsx +108 -0
  97. package/apps/frontend/src/components/SettingsModal.tsx +187 -0
  98. package/apps/frontend/src/components/Sidebar.tsx +171 -0
  99. package/apps/frontend/src/components/WadiOnboarding.tsx +71 -0
  100. package/apps/frontend/src/components/auditor/AuditReport.tsx +166 -0
  101. package/apps/frontend/src/components/auditor/AuditorHeader.tsx +34 -0
  102. package/apps/frontend/src/components/auditor/ContextPanel.tsx +138 -0
  103. package/apps/frontend/src/components/auditor/DataDeconstructor.tsx +85 -0
  104. package/apps/frontend/src/components/auditor/DecisionWall.tsx +65 -0
  105. package/apps/frontend/src/components/auditor/Dropzone.tsx +137 -0
  106. package/apps/frontend/src/components/common/Button.tsx +97 -0
  107. package/apps/frontend/src/components/common/Card.tsx +43 -0
  108. package/apps/frontend/src/components/common/Input.tsx +73 -0
  109. package/apps/frontend/src/components/common/Modal.tsx +53 -0
  110. package/apps/frontend/src/components/ui/Button.tsx +68 -0
  111. package/apps/frontend/src/components/ui/Card.tsx +86 -0
  112. package/apps/frontend/src/components/ui/Input.tsx +28 -0
  113. package/apps/frontend/src/components/ui/LogItem.tsx +64 -0
  114. package/apps/frontend/src/components/ui/MondayButton.tsx +40 -0
  115. package/apps/frontend/src/components/ui/MondayCard.tsx +24 -0
  116. package/apps/frontend/src/components/ui/Scouter.tsx +208 -0
  117. package/apps/frontend/src/components/ui/TerminalInput.tsx +202 -0
  118. package/apps/frontend/src/components/ui/Tooltip.tsx +67 -0
  119. package/apps/frontend/src/config/chatShortcuts.ts +20 -0
  120. package/apps/frontend/src/config/supabase.ts +6 -0
  121. package/apps/frontend/src/final_status.txt +3 -0
  122. package/apps/frontend/src/hooks/useScouter.ts +28 -0
  123. package/apps/frontend/src/hooks/useStoreHydration.ts +24 -0
  124. package/apps/frontend/src/improvement_status.txt +5 -0
  125. package/apps/frontend/src/index.css +88 -0
  126. package/apps/frontend/src/main.tsx +62 -0
  127. package/apps/frontend/src/monday_status.txt +7 -0
  128. package/apps/frontend/src/pages/ChatPage.tsx +201 -0
  129. package/apps/frontend/src/pages/DashboardPage.tsx +375 -0
  130. package/apps/frontend/src/pages/IntroWadi.tsx +114 -0
  131. package/apps/frontend/src/pages/LandingPage.tsx +103 -0
  132. package/apps/frontend/src/pages/Login.tsx +190 -0
  133. package/apps/frontend/src/pages/PrivacyPage.tsx +213 -0
  134. package/apps/frontend/src/pages/ProjectDetail.tsx +80 -0
  135. package/apps/frontend/src/pages/Projects.tsx +247 -0
  136. package/apps/frontend/src/pages/TermsPage.tsx +202 -0
  137. package/apps/frontend/src/router.tsx +83 -0
  138. package/apps/frontend/src/store/authStore.ts +152 -0
  139. package/apps/frontend/src/store/chatStore.ts +837 -0
  140. package/apps/frontend/src/store/documentStore.ts +89 -0
  141. package/apps/frontend/src/store/projectsStore.ts +111 -0
  142. package/apps/frontend/src/store/runsStore.ts +98 -0
  143. package/apps/frontend/src/utils/api.ts +34 -0
  144. package/apps/frontend/src/vite-env.d.ts +7 -0
  145. package/apps/frontend/tailwind.config.cjs +32 -0
  146. package/apps/frontend/tsconfig.app.json +27 -0
  147. package/apps/frontend/tsconfig.json +7 -0
  148. package/apps/frontend/tsconfig.node.json +26 -0
  149. package/apps/frontend/vite.config.ts +25 -0
  150. package/apps/kivo/.firebase/hosting.d3d3.cache +11 -0
  151. package/apps/kivo/.firebaserc +5 -0
  152. package/apps/kivo/BRANDING_GUIDE.md +71 -0
  153. package/apps/kivo/DEPLOYMENT_READY.md +46 -0
  154. package/apps/kivo/DEPLOY_URL.md +12 -0
  155. package/apps/kivo/IMPLEMENTATION_REPORT.md +35 -0
  156. package/apps/kivo/IMPLEMENTATION_REPORT_FINAL.md +49 -0
  157. package/apps/kivo/PLAN_MOBILE_2.0.md +44 -0
  158. package/apps/kivo/PWA_VERIFICATION_GUIDE.md +77 -0
  159. package/apps/kivo/README.md +28 -0
  160. package/apps/kivo/REBUILD_REPORT.md +34 -0
  161. package/apps/kivo/UPGRADE_REPORT.md +35 -0
  162. package/apps/kivo/android/app/build.gradle +54 -0
  163. package/apps/kivo/android/app/capacitor.build.gradle +19 -0
  164. package/apps/kivo/android/app/proguard-rules.pro +21 -0
  165. package/apps/kivo/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java +26 -0
  166. package/apps/kivo/android/app/src/main/AndroidManifest.xml +35 -0
  167. package/apps/kivo/android/app/src/main/java/com/kivo/app/MainActivity.java +5 -0
  168. package/apps/kivo/android/app/src/main/res/drawable/ic_launcher_background.xml +170 -0
  169. package/apps/kivo/android/app/src/main/res/drawable/splash.png +0 -0
  170. package/apps/kivo/android/app/src/main/res/drawable-land-hdpi/splash.png +0 -0
  171. package/apps/kivo/android/app/src/main/res/drawable-land-ldpi/splash.png +0 -0
  172. package/apps/kivo/android/app/src/main/res/drawable-land-mdpi/splash.png +0 -0
  173. package/apps/kivo/android/app/src/main/res/drawable-land-night-hdpi/splash.png +0 -0
  174. package/apps/kivo/android/app/src/main/res/drawable-land-night-ldpi/splash.png +0 -0
  175. package/apps/kivo/android/app/src/main/res/drawable-land-night-mdpi/splash.png +0 -0
  176. package/apps/kivo/android/app/src/main/res/drawable-land-night-xhdpi/splash.png +0 -0
  177. package/apps/kivo/android/app/src/main/res/drawable-land-night-xxhdpi/splash.png +0 -0
  178. package/apps/kivo/android/app/src/main/res/drawable-land-night-xxxhdpi/splash.png +0 -0
  179. package/apps/kivo/android/app/src/main/res/drawable-land-xhdpi/splash.png +0 -0
  180. package/apps/kivo/android/app/src/main/res/drawable-land-xxhdpi/splash.png +0 -0
  181. package/apps/kivo/android/app/src/main/res/drawable-land-xxxhdpi/splash.png +0 -0
  182. package/apps/kivo/android/app/src/main/res/drawable-night/splash.png +0 -0
  183. package/apps/kivo/android/app/src/main/res/drawable-port-hdpi/splash.png +0 -0
  184. package/apps/kivo/android/app/src/main/res/drawable-port-ldpi/splash.png +0 -0
  185. package/apps/kivo/android/app/src/main/res/drawable-port-mdpi/splash.png +0 -0
  186. package/apps/kivo/android/app/src/main/res/drawable-port-night-hdpi/splash.png +0 -0
  187. package/apps/kivo/android/app/src/main/res/drawable-port-night-ldpi/splash.png +0 -0
  188. package/apps/kivo/android/app/src/main/res/drawable-port-night-mdpi/splash.png +0 -0
  189. package/apps/kivo/android/app/src/main/res/drawable-port-night-xhdpi/splash.png +0 -0
  190. package/apps/kivo/android/app/src/main/res/drawable-port-night-xxhdpi/splash.png +0 -0
  191. package/apps/kivo/android/app/src/main/res/drawable-port-night-xxxhdpi/splash.png +0 -0
  192. package/apps/kivo/android/app/src/main/res/drawable-port-xhdpi/splash.png +0 -0
  193. package/apps/kivo/android/app/src/main/res/drawable-port-xxhdpi/splash.png +0 -0
  194. package/apps/kivo/android/app/src/main/res/drawable-port-xxxhdpi/splash.png +0 -0
  195. package/apps/kivo/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +34 -0
  196. package/apps/kivo/android/app/src/main/res/layout/activity_main.xml +12 -0
  197. package/apps/kivo/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +9 -0
  198. package/apps/kivo/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +9 -0
  199. package/apps/kivo/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  200. package/apps/kivo/android/app/src/main/res/mipmap-hdpi/ic_launcher_background.png +0 -0
  201. package/apps/kivo/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png +0 -0
  202. package/apps/kivo/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
  203. package/apps/kivo/android/app/src/main/res/mipmap-ldpi/ic_launcher.png +0 -0
  204. package/apps/kivo/android/app/src/main/res/mipmap-ldpi/ic_launcher_background.png +0 -0
  205. package/apps/kivo/android/app/src/main/res/mipmap-ldpi/ic_launcher_foreground.png +0 -0
  206. package/apps/kivo/android/app/src/main/res/mipmap-ldpi/ic_launcher_round.png +0 -0
  207. package/apps/kivo/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  208. package/apps/kivo/android/app/src/main/res/mipmap-mdpi/ic_launcher_background.png +0 -0
  209. package/apps/kivo/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png +0 -0
  210. package/apps/kivo/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
  211. package/apps/kivo/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  212. package/apps/kivo/android/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png +0 -0
  213. package/apps/kivo/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png +0 -0
  214. package/apps/kivo/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
  215. package/apps/kivo/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  216. package/apps/kivo/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png +0 -0
  217. package/apps/kivo/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png +0 -0
  218. package/apps/kivo/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
  219. package/apps/kivo/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  220. package/apps/kivo/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png +0 -0
  221. package/apps/kivo/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png +0 -0
  222. package/apps/kivo/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
  223. package/apps/kivo/android/app/src/main/res/values/ic_launcher_background.xml +4 -0
  224. package/apps/kivo/android/app/src/main/res/values/strings.xml +7 -0
  225. package/apps/kivo/android/app/src/main/res/values/styles.xml +22 -0
  226. package/apps/kivo/android/app/src/main/res/xml/file_paths.xml +5 -0
  227. package/apps/kivo/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java +18 -0
  228. package/apps/kivo/android/build.gradle +29 -0
  229. package/apps/kivo/android/capacitor.settings.gradle +3 -0
  230. package/apps/kivo/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  231. package/apps/kivo/android/gradle/wrapper/gradle-wrapper.properties +7 -0
  232. package/apps/kivo/android/gradle.properties +22 -0
  233. package/apps/kivo/android/gradlew +252 -0
  234. package/apps/kivo/android/gradlew.bat +94 -0
  235. package/apps/kivo/android/settings.gradle +5 -0
  236. package/apps/kivo/android/variables.gradle +16 -0
  237. package/apps/kivo/assets/icon.png +0 -0
  238. package/apps/kivo/assets/splash.png +0 -0
  239. package/apps/kivo/capacitor.config.json +16 -0
  240. package/apps/kivo/firebase.json +6 -0
  241. package/apps/kivo/jest.config.js +4 -0
  242. package/apps/kivo/package.json +26 -0
  243. package/apps/kivo/tests_disabled/logic.test.js +34 -0
  244. package/apps/kivo/www/assets/icon-192.png +0 -0
  245. package/apps/kivo/www/assets/icon-512.png +0 -0
  246. package/apps/kivo/www/assets/kivo-icon.png +0 -0
  247. package/apps/kivo/www/assets/pop.mp3 +0 -0
  248. package/apps/kivo/www/favicon.ico +0 -0
  249. package/apps/kivo/www/firebase-config.js +75 -0
  250. package/apps/kivo/www/index.html +38 -0
  251. package/apps/kivo/www/manifest.json +29 -0
  252. package/apps/kivo/www/script.js +72 -0
  253. package/apps/kivo/www/style.css +82 -0
  254. package/apps/kivo/www/sw.js +46 -0
  255. package/apps/kivo-brain-api/.env.example +2 -0
  256. package/apps/kivo-brain-api/KIVO_BACKEND_SETUP.md +27 -0
  257. package/apps/kivo-brain-api/controllers/kivoController.js +31 -0
  258. package/apps/kivo-brain-api/index.js +24 -0
  259. package/apps/kivo-brain-api/package.json +17 -0
  260. package/apps/kivo-brain-api/routes/message.js +8 -0
  261. package/apps/kivo-brain-api/services/openaiService.js +64 -0
  262. package/apps/tests/wadi-tests.js +155 -0
  263. package/apps/wadi-brain/docs/README_REMOVE_OPTIONS.md +26 -0
  264. package/cli/commands/deploy.js +10 -0
  265. package/cli/commands/docs.js +16 -0
  266. package/cli/commands/explain.js +29 -0
  267. package/cli/commands/lint.js +14 -0
  268. package/cli/index.js +26 -0
  269. package/cli/package.json +12 -0
  270. package/docs/CNAME +1 -0
  271. package/docs/README.md +38 -0
  272. package/docs/USO.md +30 -0
  273. package/docs/index.html +46 -0
  274. package/eslint.config.js +101 -0
  275. package/final_validation.json +27 -0
  276. package/frontend_listado.txt +33387 -0
  277. package/listado.txt +12591 -0
  278. package/package.json +46 -0
  279. package/packages/logger/index.js +43 -0
  280. package/packages/logger/package.json +19 -0
  281. package/packages/logger/test-logger.js +7 -0
  282. package/packages_listado.txt +801 -0
  283. package/pnpm-workspace.yaml +6 -0
  284. package/reseteador_existencial.ps1 +40 -0
  285. package/scripts/bump-version.js +26 -0
  286. package/scripts/env.ps1 +13 -0
  287. package/scripts/setup_android.ps1 +25 -0
  288. package/scripts/setup_virtual_env.ps1 +77 -0
  289. package/scripts/smoke-test.js +84 -0
  290. package/scripts/trigger_render_deploy.ps1 +3 -0
  291. package/scripts/validate-release.js +34 -0
  292. package/temp_check.js +57 -0
  293. package/tsconfig.json +5 -0
  294. package/validation_report.json +27 -0
@@ -0,0 +1,375 @@
1
+ import { Link } from "react-router-dom";
2
+ import { useChatStore } from "../store/chatStore";
3
+ import { useDocumentStore } from "../store/documentStore";
4
+ import { AuditorHeader } from "../components/auditor/AuditorHeader";
5
+ import {
6
+ LayoutDashboard,
7
+ Brain,
8
+ Files,
9
+ Activity,
10
+ Trash2,
11
+ ExternalLink,
12
+ ChevronRight,
13
+ Database,
14
+ Cpu,
15
+ Layers,
16
+ } from "lucide-react";
17
+
18
+ // Helper Card Component
19
+ const DashboardCard = ({
20
+ title,
21
+ icon: Icon,
22
+ children,
23
+ className = "",
24
+ action,
25
+ }: {
26
+ title: string;
27
+ icon: React.ElementType; // Fixed 'any' type
28
+ children: React.ReactNode;
29
+ className?: string;
30
+ action?: React.ReactNode;
31
+ }) => (
32
+ <div
33
+ className={`bg-[var(--wadi-surface)] border border-[var(--wadi-border)] rounded-lg p-5 flex flex-col h-full relative overflow-hidden group hover:border-[var(--wadi-primary)]/50 transition-colors duration-300 ${className}`}
34
+ >
35
+ <div className="flex items-center justify-between mb-4 border-b border-[var(--wadi-border)]/50 pb-2">
36
+ <div className="flex items-center gap-2 text-[var(--wadi-text)]">
37
+ <Icon size={18} className="text-[var(--wadi-primary)]" />
38
+ <h3 className="font-mono-wadi text-xs font-bold uppercase tracking-widest">
39
+ {title}
40
+ </h3>
41
+ </div>
42
+ {action && <div>{action}</div>}
43
+ </div>
44
+ <div className="flex-1 overflow-auto custom-scrollbar relative z-10">
45
+ {children}
46
+ </div>
47
+ {/* Decorative background element */}
48
+ <div className="absolute -bottom-4 -right-4 text-[var(--wadi-primary)]/5 group-hover:text-[var(--wadi-primary)]/10 transition-colors duration-500 pointer-events-none transform rotate-12">
49
+ <Icon size={120} />
50
+ </div>
51
+ </div>
52
+ );
53
+
54
+ export default function DashboardPage() {
55
+ const {
56
+ workspaces,
57
+ activeWorkspaceId,
58
+ switchWorkspace,
59
+ createWorkspace,
60
+ deleteWorkspace,
61
+ messages,
62
+ memory,
63
+ forget,
64
+ points,
65
+ } = useChatStore();
66
+
67
+ const { documents, removeDocument, clearDocuments } = useDocumentStore();
68
+
69
+ // Derived state (no need for useEffect/useState)
70
+ const memoryItems = Object.entries(memory);
71
+
72
+ const userMsgs = messages.filter((m) => m.role === "user");
73
+ const sysMsgs = messages.filter((m) => m.role === "assistant");
74
+
75
+ const stats = {
76
+ totalMessages: messages.length,
77
+ userMessages: userMsgs.length,
78
+ systemMessages: sysMsgs.length,
79
+ };
80
+
81
+ const handleDeleteWorkspace = (name: string) => {
82
+ if (
83
+ confirm(
84
+ `¿Eliminar contexto '${name}'? Perderás todo el historial asociado.`
85
+ )
86
+ ) {
87
+ deleteWorkspace(name);
88
+ }
89
+ };
90
+
91
+ const handleForget = () => {
92
+ if (
93
+ confirm(
94
+ "¿Borrar toda la memoria a largo plazo? WADI olvidará todo lo que le enseñaste."
95
+ )
96
+ ) {
97
+ forget();
98
+ }
99
+ };
100
+
101
+ return (
102
+ <div className="flex flex-col h-screen bg-[#0f111a] text-white overflow-hidden">
103
+ <AuditorHeader />
104
+
105
+ <main className="flex-1 overflow-y-auto p-4 md:p-8 custom-scrollbar">
106
+ <div className="max-w-7xl mx-auto space-y-6">
107
+ {/* Header Section */}
108
+ <div className="flex items-center justify-between">
109
+ <div>
110
+ <h1 className="text-3xl font-bold font-mono-wadi text-[var(--wadi-primary)] mb-1 flex items-center gap-3">
111
+ <LayoutDashboard className="animate-pulse-soft" /> PANEL DE
112
+ CONTROL
113
+ </h1>
114
+ <p className="text-sm text-[var(--wadi-text-muted)] max-w-2xl">
115
+ Visualización de estado interno. No rompas nada. O sí, no soy tu
116
+ padre.
117
+ </p>
118
+ </div>
119
+ <div className="flex gap-2">
120
+ <Link
121
+ to="/chat"
122
+ className="px-4 py-2 bg-[var(--wadi-primary)] text-black font-mono-wadi font-bold text-xs uppercase rounded flex items-center gap-2 hover:bg-[var(--wadi-primary)]/90 transition-all shadow-[0_0_15px_rgba(var(--wadi-primary-rgb),0.3)]"
123
+ >
124
+ Volver al Chat <ChevronRight size={14} />
125
+ </Link>
126
+ </div>
127
+ </div>
128
+
129
+ {/* KPI Grid */}
130
+ <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
131
+ <div className="bg-[var(--wadi-surface)] border border-[var(--wadi-border)] p-4 rounded flex items-center gap-4">
132
+ <div className="p-3 bg-blue-500/10 rounded-full text-blue-500">
133
+ <Activity size={24} />
134
+ </div>
135
+ <div>
136
+ <div className="text-[10px] text-[var(--wadi-text-muted)] uppercase tracking-wider font-mono-wadi">
137
+ Interacciones
138
+ </div>
139
+ <div className="text-2xl font-bold font-mono">
140
+ {stats.totalMessages}
141
+ </div>
142
+ </div>
143
+ </div>
144
+ <div className="bg-[var(--wadi-surface)] border border-[var(--wadi-border)] p-4 rounded flex items-center gap-4">
145
+ <div className="p-3 bg-purple-500/10 rounded-full text-purple-500">
146
+ <Brain size={24} />
147
+ </div>
148
+ <div>
149
+ <div className="text-[10px] text-[var(--wadi-text-muted)] uppercase tracking-wider font-mono-wadi">
150
+ Memoria (Items)
151
+ </div>
152
+ <div className="text-2xl font-bold font-mono">
153
+ {memoryItems.length}
154
+ </div>
155
+ </div>
156
+ </div>
157
+ <div className="bg-[var(--wadi-surface)] border border-[var(--wadi-border)] p-4 rounded flex items-center gap-4">
158
+ <div className="p-3 bg-green-500/10 rounded-full text-green-500">
159
+ <Files size={24} />
160
+ </div>
161
+ <div>
162
+ <div className="text-[10px] text-[var(--wadi-text-muted)] uppercase tracking-wider font-mono-wadi">
163
+ Docs Ingeridos
164
+ </div>
165
+ <div className="text-2xl font-bold font-mono">
166
+ {documents.length}
167
+ </div>
168
+ </div>
169
+ </div>
170
+ <div className="bg-[var(--wadi-surface)] border border-[var(--wadi-border)] p-4 rounded flex items-center gap-4">
171
+ <div className="p-3 bg-orange-500/10 rounded-full text-orange-500">
172
+ <Cpu size={24} />
173
+ </div>
174
+ <div>
175
+ <div className="text-[10px] text-[var(--wadi-text-muted)] uppercase tracking-wider font-mono-wadi">
176
+ Eficiencia WADI
177
+ </div>
178
+ <div className="text-2xl font-bold font-mono">
179
+ {points} <span className="text-[10px] opacity-70">PTS</span>
180
+ </div>
181
+ </div>
182
+ </div>
183
+ </div>
184
+
185
+ <div className="grid grid-cols-1 md:grid-cols-3 gap-6 h-[600px]">
186
+ {/* Workspaces Column */}
187
+ <div className="md:col-span-1 h-full">
188
+ <DashboardCard
189
+ title="Contextos (Workspaces)"
190
+ icon={Layers}
191
+ action={
192
+ <button
193
+ onClick={() => createWorkspace("Nuevo Contexto")}
194
+ className="text-[10px] text-[var(--wadi-primary)] hover:underline"
195
+ >
196
+ + NUEVO
197
+ </button>
198
+ }
199
+ >
200
+ <div className="space-y-2">
201
+ {workspaces.map((ws) => (
202
+ <div
203
+ key={ws.id}
204
+ className={`p-3 rounded border border-[var(--wadi-border)] flex items-center justify-between group transition-all ${
205
+ activeWorkspaceId === ws.id
206
+ ? "bg-[var(--wadi-primary)]/10 border-[var(--wadi-primary)]"
207
+ : "hover:bg-white/5"
208
+ }`}
209
+ >
210
+ <div className="flex-1 truncate">
211
+ <div className="font-bold text-sm truncate">
212
+ {ws.name}
213
+ </div>
214
+ <div className="text-[10px] text-[var(--wadi-text-muted)]">
215
+ ID: {ws.id.slice(0, 8)}...
216
+ </div>
217
+ </div>
218
+ <div className="flex items-center gap-2 opacity-0 group-hover:opacity-100 transition-opacity">
219
+ {activeWorkspaceId !== ws.id && (
220
+ <button
221
+ onClick={() => switchWorkspace(ws.name)}
222
+ className="p-1.5 hover:bg-white/10 rounded text-[var(--wadi-success)]"
223
+ title="Cambiar a este workspace"
224
+ >
225
+ <ExternalLink size={14} />
226
+ </button>
227
+ )}
228
+ <button
229
+ onClick={() => handleDeleteWorkspace(ws.name)}
230
+ className="p-1.5 hover:bg-white/10 rounded text-[var(--wadi-tension)]"
231
+ title="Eliminar workspace"
232
+ >
233
+ <Trash2 size={14} />
234
+ </button>
235
+ </div>
236
+ </div>
237
+ ))}
238
+ {workspaces.length === 0 && (
239
+ <div className="text-center py-8 text-[var(--wadi-text-muted)] text-sm italic">
240
+ No hay contextos definidos. Estás flotando en la nada.
241
+ </div>
242
+ )}
243
+ </div>
244
+ </DashboardCard>
245
+ </div>
246
+
247
+ {/* Memory & Docs Column */}
248
+ <div className="md:col-span-2 grid grid-rows-2 gap-6 h-full">
249
+ {/* Memory Section */}
250
+ <DashboardCard
251
+ title="Memoria Asociativa (LTM)"
252
+ icon={Database}
253
+ className="h-full"
254
+ action={
255
+ memoryItems.length > 0 && (
256
+ <button
257
+ onClick={handleForget}
258
+ className="text-[10px] text-[var(--wadi-tension)] hover:underline flex items-center gap-1"
259
+ >
260
+ <Trash2 size={10} /> PURGAR MEMORIA
261
+ </button>
262
+ )
263
+ }
264
+ >
265
+ {memoryItems.length > 0 ? (
266
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
267
+ {memoryItems.map(([key, value]) => (
268
+ <div
269
+ key={key}
270
+ className="bg-black/20 p-3 rounded border border-[var(--wadi-border)] text-sm overflow-hidden"
271
+ >
272
+ <div className="text-[var(--wadi-primary)] font-bold text-xs uppercase mb-1">
273
+ {key}
274
+ </div>
275
+ <div
276
+ className="text-[var(--wadi-text-muted)] line-clamp-2"
277
+ title={value}
278
+ >
279
+ {value}
280
+ </div>
281
+ </div>
282
+ ))}
283
+ </div>
284
+ ) : (
285
+ <div className="flex flex-col items-center justify-center h-full text-[var(--wadi-text-muted)] opacity-50">
286
+ <Brain size={48} className="mb-2" />
287
+ <p className="text-sm">Tabula Rasa. No sé nada.</p>
288
+ </div>
289
+ )}
290
+ </DashboardCard>
291
+
292
+ {/* Documents Section */}
293
+ <DashboardCard
294
+ title="Archivos Ingeridos"
295
+ icon={Files}
296
+ className="h-full"
297
+ action={
298
+ documents.length > 0 && (
299
+ <button
300
+ onClick={() => {
301
+ if (
302
+ confirm("¿Eliminar todos los documentos indexados?")
303
+ )
304
+ clearDocuments();
305
+ }}
306
+ className="text-[10px] text-[var(--wadi-tension)] hover:underline flex items-center gap-1"
307
+ >
308
+ <Trash2 size={10} /> LIMPIAR ÍNDICE
309
+ </button>
310
+ )
311
+ }
312
+ >
313
+ <div className="overflow-x-auto">
314
+ <table className="w-full text-left text-xs">
315
+ <thead className="text-[var(--wadi-text-muted)] font-mono-wadi border-b border-[var(--wadi-border)]">
316
+ <tr>
317
+ <th className="py-2 pl-2">ARCHIVO</th>
318
+ <th className="py-2">TOKENS</th>
319
+ <th className="py-2">TAMAÑO</th>
320
+ <th className="py-2">FECHA</th>
321
+ <th className="py-2 text-right pr-2">ACCIÓN</th>
322
+ </tr>
323
+ </thead>
324
+ <tbody className="divide-y divide-[var(--wadi-border)]/30">
325
+ {documents.map((doc) => (
326
+ <tr
327
+ key={doc.id}
328
+ className="hover:bg-white/5 transition-colors"
329
+ >
330
+ <td
331
+ className="py-2 pl-2 font-medium text-[var(--wadi-text)] truncate max-w-[200px]"
332
+ title={doc.filename}
333
+ >
334
+ {doc.filename}
335
+ </td>
336
+ <td className="py-2 text-[var(--wadi-text-muted)] font-mono">
337
+ {doc.tokens}
338
+ </td>
339
+ <td className="py-2 text-[var(--wadi-text-muted)] font-mono">
340
+ {(doc.size / 1024).toFixed(1)} KB
341
+ </td>
342
+ <td className="py-2 text-[var(--wadi-text-muted)]">
343
+ {new Date(doc.uploadedAt).toLocaleDateString()}
344
+ </td>
345
+ <td className="py-2 text-right pr-2">
346
+ <button
347
+ onClick={() => removeDocument(doc.id)}
348
+ className="text-[var(--wadi-tension)] hover:text-red-400 p-1"
349
+ title="Eliminar del índice"
350
+ >
351
+ <Trash2 size={14} />
352
+ </button>
353
+ </td>
354
+ </tr>
355
+ ))}
356
+ </tbody>
357
+ </table>
358
+ {documents.length === 0 && (
359
+ <div className="flex flex-col items-center justify-center py-8 text-[var(--wadi-text-muted)] opacity-50">
360
+ <Files size={32} className="mb-2" />
361
+ <p className="text-sm">
362
+ El índice está vacío. Arrastra archivos en el chat para
363
+ popular.
364
+ </p>
365
+ </div>
366
+ )}
367
+ </div>
368
+ </DashboardCard>
369
+ </div>
370
+ </div>
371
+ </div>
372
+ </main>
373
+ </div>
374
+ );
375
+ }
@@ -0,0 +1,114 @@
1
+ import { useEffect, useState } from "react";
2
+ import { useNavigate } from "react-router-dom";
3
+
4
+ export default function IntroWadi() {
5
+ const [visible] = useState(true);
6
+ const navigate = useNavigate();
7
+
8
+ useEffect(() => {
9
+ const alreadySeen = localStorage.getItem("wadi_intro_seen");
10
+ if (alreadySeen) {
11
+ navigate("/chat");
12
+ }
13
+ }, [navigate]);
14
+
15
+ const handleContinue = () => {
16
+ localStorage.setItem("wadi_intro_seen", "true");
17
+ navigate("/chat");
18
+ };
19
+
20
+ if (!visible) return null;
21
+
22
+ return (
23
+ <div
24
+ style={{
25
+ display: "flex",
26
+ flexDirection: "column",
27
+ minHeight: "100vh",
28
+ padding: "2.5rem 1.5rem",
29
+ backgroundColor: "#000",
30
+ color: "#fff",
31
+ fontFamily: "monospace",
32
+ }}
33
+ >
34
+ <h1
35
+ style={{ fontSize: "1.5rem", fontWeight: "bold", marginBottom: "1rem" }}
36
+ >
37
+ WADI no charla por charlar. WADI ordena mientras piensa.
38
+ </h1>
39
+
40
+ <div style={{ flex: 1, overflowY: "auto", fontSize: "0.875rem" }}>
41
+ <p style={{ marginBottom: "1rem" }}>
42
+ ⚠️ Esto no es una IA simpática. Tampoco es fría.
43
+ </p>
44
+ <p style={{ marginBottom: "1rem" }}>
45
+ Vas a hablar con una herramienta que:
46
+ </p>
47
+
48
+ <ul
49
+ style={{
50
+ listStyleType: "disc",
51
+ paddingLeft: "1.5rem",
52
+ marginBottom: "1rem",
53
+ }}
54
+ >
55
+ <li>Te devuelve estructura cuando estás en el aire.</li>
56
+ <li>Te acompaña si traés algo real.</li>
57
+ <li>No valida sin criterio.</li>
58
+ <li>No te deja evadir decisiones.</li>
59
+ <li>Piensa con vos, no por vos.</li>
60
+ </ul>
61
+
62
+ <p
63
+ style={{
64
+ marginTop: "1.5rem",
65
+ fontWeight: "bold",
66
+ marginBottom: "0.5rem",
67
+ }}
68
+ >
69
+ Qué frases podés esperar:
70
+ </p>
71
+ <ul
72
+ style={{
73
+ listStyleType: "disc",
74
+ paddingLeft: "1.5rem",
75
+ marginBottom: "1.5rem",
76
+ }}
77
+ >
78
+ <li>“Esto es mezcla. Hay dos líneas: A o B. Elegí.”</li>
79
+ <li>“Podemos seguir con esto, pero está flojo.”</li>
80
+ <li>“No hay foco acá. ¿Querés seguir igual o cambiar?”</li>
81
+ </ul>
82
+
83
+ <p style={{ marginBottom: "1rem" }}>
84
+ WADI va a sostener tu pensamiento, no tu zona de confort. Pero no te
85
+ deja solo si traés algo vivo.
86
+ </p>
87
+
88
+ <p style={{ marginTop: "1rem", color: "#FACC15", fontWeight: "600" }}>
89
+ Si seguís, entrás en una conversación lúcida. Y no hay vuelta atrás.
90
+ </p>
91
+ </div>
92
+
93
+ <button
94
+ onClick={handleContinue}
95
+ style={{
96
+ marginTop: "2rem",
97
+ padding: "0.75rem 1rem",
98
+ backgroundColor: "#fff",
99
+ color: "#000",
100
+ borderRadius: "0.5rem",
101
+ fontWeight: "bold",
102
+ fontSize: "0.875rem",
103
+ cursor: "pointer",
104
+ border: "none",
105
+ width: "100%",
106
+ }}
107
+ onMouseOver={(e) => (e.currentTarget.style.backgroundColor = "#FDE047")}
108
+ onMouseOut={(e) => (e.currentTarget.style.backgroundColor = "#fff")}
109
+ >
110
+ Entiendo. Vamos a ordenar.
111
+ </button>
112
+ </div>
113
+ );
114
+ }
@@ -0,0 +1,103 @@
1
+ import { useNavigate } from "react-router-dom";
2
+ import { useChatStore } from "../store/chatStore";
3
+
4
+ export default function LandingPage() {
5
+ const navigate = useNavigate();
6
+ const { resetChat } = useChatStore();
7
+
8
+ const handleStart = () => {
9
+ resetChat();
10
+ // Navigate to /chat to start fresh. The ChatPage logic handles ID creation or empty state.
11
+ // User requested "Crear conversación nueva, Navegar a /chat/:id".
12
+ // Since ChatPage handles "if (!conversationId && newId) navigate...", sending a message creates the ID.
13
+ // If I want to force a new ID immediately upon clicking "Nuevo Chat", I might need a store action for it,
14
+ // OR simply navigate to /chat and let the user type.
15
+ // User said: "👉 Al click en Nuevo chat: Crear conversación nueva, Navegar a /chat/:id, El input queda enfocado"
16
+ // If the store supports creating an empty conversation and getting an ID, I should use it.
17
+ // Looking at store: startNewConversation resets state (id=null).
18
+ // To actually GET an ID, usually a message must be sent or an endpoint called.
19
+ // However, the user demand is "Navegar a /chat/:id".
20
+ // If I cannot generate an ID without a message, I will navigate to /chat (which effectively is a new clean chat)
21
+ // and ensuring the UI looks like a "new chat".
22
+ // But let's check if we can create one. The store has `startNewConversation`.
23
+ // Let's stick to the simplest "reset and go to /chat" which functions as a new chat in this app's logic usually.
24
+ // If strict ID is required before message, I'd need backend changes or a createEmptyConversation endpoint.
25
+ // Assuming standard behavior for now: reset state -> navigate to /chat -> user types -> ID generated.
26
+ // If the user insists on "Navegar a /chat/:id" immediately, I might generate a UUID locally or call an API if available.
27
+ // But `useChatStore` doesn't seem to have `createEmptyConversation`.
28
+ // I will stick to navigate('/chat') which presents a new chat interface.
29
+
30
+ navigate("/chat");
31
+ };
32
+
33
+ return (
34
+ <div
35
+ style={{
36
+ display: "flex",
37
+ flexDirection: "column",
38
+ alignItems: "center",
39
+ justifyContent: "center",
40
+ height: "100vh",
41
+ backgroundColor: "var(--color-bg)",
42
+ color: "var(--color-text-main)",
43
+ textAlign: "center",
44
+ padding: "1rem",
45
+ }}
46
+ >
47
+ <h1
48
+ style={{
49
+ fontSize: "4rem",
50
+ fontWeight: 900,
51
+ margin: "0 0 0.5rem 0",
52
+ background: "var(--grad-main)",
53
+ WebkitBackgroundClip: "text",
54
+ WebkitTextFillColor: "transparent",
55
+ lineHeight: 1.1,
56
+ }}
57
+ >
58
+ WADI
59
+ </h1>
60
+ <h2
61
+ style={{
62
+ fontSize: "1.5rem",
63
+ fontWeight: 600,
64
+ margin: "0 0 2rem 0",
65
+ color: "var(--color-text-main)",
66
+ }}
67
+ >
68
+ Del caos al plan
69
+ </h2>
70
+
71
+ <p
72
+ style={{
73
+ fontSize: "1.2rem",
74
+ color: "var(--color-text-soft)",
75
+ marginBottom: "3rem",
76
+ maxWidth: "400px",
77
+ }}
78
+ >
79
+ Acá se piensa. No hace magia.
80
+ </p>
81
+
82
+ <button
83
+ onClick={handleStart}
84
+ style={{
85
+ background: "var(--color-primary)",
86
+ color: "#FFFFFF",
87
+ border: "none",
88
+ padding: "1rem 2.5rem",
89
+ borderRadius: "9999px",
90
+ fontSize: "1.2rem",
91
+ fontWeight: 700,
92
+ cursor: "pointer",
93
+ boxShadow: "var(--shadow-lg)",
94
+ transition: "transform 0.1s",
95
+ }}
96
+ onMouseDown={(e) => (e.currentTarget.style.transform = "scale(0.98)")}
97
+ onMouseUp={(e) => (e.currentTarget.style.transform = "scale(1)")}
98
+ >
99
+ + Nuevo chat
100
+ </button>
101
+ </div>
102
+ );
103
+ }