create-vasvibe 2.4.0 → 2.5.1

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 (286) hide show
  1. package/README.md +170 -167
  2. package/bin/cli.mjs +9 -9
  3. package/package.json +45 -45
  4. package/src/git.mjs +47 -47
  5. package/src/index.mjs +228 -228
  6. package/src/prompts.mjs +113 -113
  7. package/src/scaffold.mjs +74 -74
  8. package/src/upgrade.mjs +121 -121
  9. package/src/utils.mjs +91 -91
  10. package/template/.agents/agents/analyst/agent.json +43 -43
  11. package/template/.agents/agents/backend/agent.json +44 -44
  12. package/template/.agents/agents/data-architect/agent.json +43 -43
  13. package/template/.agents/agents/devops/agent.json +44 -44
  14. package/template/.agents/agents/discovery/agent.json +43 -43
  15. package/template/.agents/agents/document/agent.json +43 -43
  16. package/template/.agents/agents/explorer/agent.json +43 -43
  17. package/template/.agents/agents/fixer/agent.json +44 -44
  18. package/template/.agents/agents/frontend/agent.json +44 -44
  19. package/template/.agents/agents/fullstack/agent.json +44 -44
  20. package/template/.agents/agents/initiator/agent.json +41 -41
  21. package/template/.agents/agents/logger/agent.json +43 -43
  22. package/template/.agents/agents/manual-tester/agent.json +44 -0
  23. package/template/.agents/agents/orchestrator/agent.json +44 -44
  24. package/template/.agents/agents/pm/agent.json +42 -42
  25. package/template/.agents/agents/qa/agent.json +44 -44
  26. package/template/.agents/agents/reliability/agent.json +44 -44
  27. package/template/.agents/agents/security/agent.json +44 -44
  28. package/template/.agents/agents/sysarch/agent.json +44 -44
  29. package/template/.agents/agents/tester/agent.json +44 -44
  30. package/template/.agents/agents/toolsmith/agent.json +44 -44
  31. package/template/.agents/agents/ux-designer/agent.json +43 -43
  32. package/template/.agents/skills/find-skills/SKILL.md +142 -142
  33. package/template/.agents/skills/fullstack/SKILL.md +89 -89
  34. package/template/.agents/skills/penetration-testing/SKILL.md +94 -94
  35. package/template/.agents/skills/penetration-testing/references/automated-penetration-testing-framework.md +328 -328
  36. package/template/.agents/skills/penetration-testing/references/burp-suite-automation-script.md +135 -135
  37. package/template/.agents/skills/penetration-testing/scripts/security-checklist.sh +30 -30
  38. package/template/.agents/skills/pm/SKILL.md +170 -170
  39. package/template/.agents/skills/ui-ux-pro-max/SKILL.md +658 -658
  40. package/template/.agents/skills/ui-ux-pro-max/data/_sync_all.py +414 -414
  41. package/template/.agents/skills/ui-ux-pro-max/data/app-interface.csv +30 -30
  42. package/template/.agents/skills/ui-ux-pro-max/data/design.csv +1775 -1775
  43. package/template/.agents/skills/ui-ux-pro-max/data/draft.csv +1778 -1778
  44. package/template/.agents/skills/ui-ux-pro-max/data/icons.csv +105 -105
  45. package/template/.agents/skills/ui-ux-pro-max/data/products.csv +162 -162
  46. package/template/.agents/skills/ui-ux-pro-max/data/react-performance.csv +45 -45
  47. package/template/.agents/skills/ui-ux-pro-max/data/stacks/angular.csv +51 -51
  48. package/template/.agents/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -54
  49. package/template/.agents/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -53
  50. package/template/.agents/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -56
  51. package/template/.agents/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -53
  52. package/template/.agents/skills/ui-ux-pro-max/data/stacks/laravel.csv +51 -51
  53. package/template/.agents/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -53
  54. package/template/.agents/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -51
  55. package/template/.agents/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -59
  56. package/template/.agents/skills/ui-ux-pro-max/data/stacks/react.csv +54 -54
  57. package/template/.agents/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -61
  58. package/template/.agents/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -54
  59. package/template/.agents/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -51
  60. package/template/.agents/skills/ui-ux-pro-max/data/stacks/threejs.csv +54 -54
  61. package/template/.agents/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -50
  62. package/template/.agents/skills/ui-ux-pro-max/data/typography.csv +74 -74
  63. package/template/.agents/skills/ui-ux-pro-max/scripts/core.py +262 -262
  64. package/template/.agents/skills/ui-ux-pro-max/scripts/design_system.py +1148 -1148
  65. package/template/.agents/workflows/build-feature.md +21 -21
  66. package/template/.agents/workflows/build-prototype.md +32 -32
  67. package/template/.agents/workflows/daily-standup.md +16 -16
  68. package/template/.agents/workflows/deliver-feature.md +16 -16
  69. package/template/.agents/workflows/explorer.md +78 -78
  70. package/template/.agents/workflows/harden-release.md +21 -21
  71. package/template/.agents/workflows/logger.md +117 -117
  72. package/template/.agents/workflows/plan-feature.md +30 -30
  73. package/template/.agents/workflows/plan-project.md +25 -25
  74. package/template/.agents/workflows/release.md +18 -18
  75. package/template/.agents/workflows/security-audit.md +19 -19
  76. package/template/.agents/workflows/setup-workspace.md +21 -21
  77. package/template/.agents/workflows/start-fix.md +18 -18
  78. package/template/.agents/workflows/test-feature.md +17 -17
  79. package/template/.claude/agents/analyst.md +109 -109
  80. package/template/.claude/agents/backend.md +61 -61
  81. package/template/.claude/agents/data-architect.md +43 -43
  82. package/template/.claude/agents/devops.md +44 -43
  83. package/template/.claude/agents/discovery.md +51 -51
  84. package/template/.claude/agents/document.md +51 -51
  85. package/template/.claude/agents/explorer.md +138 -138
  86. package/template/.claude/agents/fixer.md +87 -86
  87. package/template/.claude/agents/frontend.md +65 -65
  88. package/template/.claude/agents/fullstack.md +91 -90
  89. package/template/.claude/agents/initiator.md +74 -74
  90. package/template/.claude/agents/logger.md +143 -143
  91. package/template/.claude/agents/manual-tester.md +108 -0
  92. package/template/.claude/agents/orchestrator.md +138 -137
  93. package/template/.claude/agents/pm.md +199 -199
  94. package/template/.claude/agents/qa.md +66 -65
  95. package/template/.claude/agents/reliability.md +48 -47
  96. package/template/.claude/agents/security.md +107 -106
  97. package/template/.claude/agents/sysarch.md +301 -301
  98. package/template/.claude/agents/tester.md +100 -100
  99. package/template/.claude/agents/toolsmith.md +77 -76
  100. package/template/.claude/agents/ux-designer.md +45 -45
  101. package/template/.claude/commands/build-feature.md +22 -22
  102. package/template/.claude/commands/build-prototype.md +33 -33
  103. package/template/.claude/commands/daily-standup.md +16 -16
  104. package/template/.claude/commands/deliver-feature.md +17 -17
  105. package/template/.claude/commands/harden-release.md +22 -22
  106. package/template/.claude/commands/manual-test.md +19 -0
  107. package/template/.claude/commands/plan-feature.md +31 -31
  108. package/template/.claude/commands/plan-project.md +26 -26
  109. package/template/.claude/commands/release.md +19 -19
  110. package/template/.claude/commands/security-audit.md +20 -20
  111. package/template/.claude/commands/setup-workspace.md +22 -22
  112. package/template/.claude/commands/start-fix.md +19 -19
  113. package/template/.claude/commands/test-feature.md +18 -18
  114. package/template/.claude/skills/find-skills/SKILL.md +142 -142
  115. package/template/.claude/skills/penetration-testing/SKILL.md +94 -94
  116. package/template/.claude/skills/penetration-testing/references/automated-penetration-testing-framework.md +328 -328
  117. package/template/.claude/skills/penetration-testing/references/burp-suite-automation-script.md +135 -135
  118. package/template/.claude/skills/penetration-testing/scripts/security-checklist.sh +30 -30
  119. package/template/.claude/skills/ui-ux-pro-max/SKILL.md +658 -658
  120. package/template/.claude/skills/ui-ux-pro-max/data/_sync_all.py +414 -414
  121. package/template/.claude/skills/ui-ux-pro-max/data/app-interface.csv +30 -30
  122. package/template/.claude/skills/ui-ux-pro-max/data/design.csv +1775 -1775
  123. package/template/.claude/skills/ui-ux-pro-max/data/draft.csv +1778 -1778
  124. package/template/.claude/skills/ui-ux-pro-max/data/icons.csv +105 -105
  125. package/template/.claude/skills/ui-ux-pro-max/data/products.csv +162 -162
  126. package/template/.claude/skills/ui-ux-pro-max/data/react-performance.csv +45 -45
  127. package/template/.claude/skills/ui-ux-pro-max/data/stacks/angular.csv +51 -51
  128. package/template/.claude/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -54
  129. package/template/.claude/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -53
  130. package/template/.claude/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -56
  131. package/template/.claude/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -53
  132. package/template/.claude/skills/ui-ux-pro-max/data/stacks/laravel.csv +51 -51
  133. package/template/.claude/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -53
  134. package/template/.claude/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -51
  135. package/template/.claude/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -59
  136. package/template/.claude/skills/ui-ux-pro-max/data/stacks/react.csv +54 -54
  137. package/template/.claude/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -61
  138. package/template/.claude/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -54
  139. package/template/.claude/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -51
  140. package/template/.claude/skills/ui-ux-pro-max/data/stacks/threejs.csv +54 -54
  141. package/template/.claude/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -50
  142. package/template/.claude/skills/ui-ux-pro-max/data/typography.csv +74 -74
  143. package/template/.claude/skills/ui-ux-pro-max/scripts/core.py +262 -262
  144. package/template/.claude/skills/ui-ux-pro-max/scripts/design_system.py +1148 -1148
  145. package/template/.github/prompts/analyst.prompt.md +104 -104
  146. package/template/.github/prompts/backend.prompt.md +44 -44
  147. package/template/.github/prompts/data-architect.prompt.md +38 -38
  148. package/template/.github/prompts/devops.prompt.md +32 -32
  149. package/template/.github/prompts/discovery.prompt.md +39 -39
  150. package/template/.github/prompts/document.prompt.md +14 -14
  151. package/template/.github/prompts/explorer.prompt.md +133 -133
  152. package/template/.github/prompts/fixer.prompt.md +82 -81
  153. package/template/.github/prompts/frontend.prompt.md +60 -60
  154. package/template/.github/prompts/fullstack.prompt.md +86 -86
  155. package/template/.github/prompts/initiator.prompt.md +55 -55
  156. package/template/.github/prompts/logger.prompt.md +138 -138
  157. package/template/.github/prompts/manual-tester.prompt.md +103 -0
  158. package/template/.github/prompts/orchestrator.prompt.md +133 -133
  159. package/template/.github/prompts/pm.prompt.md +186 -186
  160. package/template/.github/prompts/qa.prompt.md +57 -57
  161. package/template/.github/prompts/reliability.prompt.md +44 -44
  162. package/template/.github/prompts/security.prompt.md +41 -41
  163. package/template/.github/prompts/sysarch.prompt.md +351 -351
  164. package/template/.github/prompts/tester.prompt.md +107 -107
  165. package/template/.github/prompts/toolsmith.prompt.md +46 -46
  166. package/template/.github/prompts/ux-designer.prompt.md +41 -41
  167. package/template/.opencode/agents/analyst.md +108 -108
  168. package/template/.opencode/agents/backend.md +61 -61
  169. package/template/.opencode/agents/data-architect.md +43 -43
  170. package/template/.opencode/agents/devops.md +44 -44
  171. package/template/.opencode/agents/discovery.md +51 -51
  172. package/template/.opencode/agents/document.md +51 -51
  173. package/template/.opencode/agents/explorer.md +137 -137
  174. package/template/.opencode/agents/fixer.md +86 -85
  175. package/template/.opencode/agents/frontend.md +64 -64
  176. package/template/.opencode/agents/fullstack.md +90 -89
  177. package/template/.opencode/agents/initiator.md +74 -74
  178. package/template/.opencode/agents/logger.md +142 -142
  179. package/template/.opencode/agents/manual-tester.md +107 -0
  180. package/template/.opencode/agents/orchestrator.md +137 -133
  181. package/template/.opencode/agents/pm.md +199 -199
  182. package/template/.opencode/agents/qa.md +66 -65
  183. package/template/.opencode/agents/reliability.md +48 -48
  184. package/template/.opencode/agents/security.md +107 -107
  185. package/template/.opencode/agents/sysarch.md +301 -301
  186. package/template/.opencode/agents/tester.md +100 -100
  187. package/template/.opencode/agents/toolsmith.md +77 -77
  188. package/template/.opencode/agents/ux-designer.md +45 -45
  189. package/template/.opencode/commands/build-feature.md +21 -21
  190. package/template/.opencode/commands/build-prototype.md +32 -32
  191. package/template/.opencode/commands/daily-standup.md +16 -16
  192. package/template/.opencode/commands/deliver-feature.md +16 -16
  193. package/template/.opencode/commands/harden-release.md +21 -21
  194. package/template/.opencode/commands/manual-test.md +18 -0
  195. package/template/.opencode/commands/plan-feature.md +30 -30
  196. package/template/.opencode/commands/plan-project.md +25 -25
  197. package/template/.opencode/commands/release.md +18 -18
  198. package/template/.opencode/commands/security-audit.md +19 -19
  199. package/template/.opencode/commands/setup-workspace.md +21 -21
  200. package/template/.opencode/commands/start-fix.md +18 -18
  201. package/template/.opencode/commands/test-feature.md +17 -17
  202. package/template/.opencode/skills/penetration-testing/SKILL.md +94 -94
  203. package/template/.opencode/skills/penetration-testing/references/automated-penetration-testing-framework.md +328 -328
  204. package/template/.opencode/skills/penetration-testing/references/burp-suite-automation-script.md +135 -135
  205. package/template/.opencode/skills/penetration-testing/scripts/security-checklist.sh +30 -30
  206. package/template/.opencode/skills/ui-ux-pro-max/SKILL.md +658 -658
  207. package/template/.opencode/skills/ui-ux-pro-max/data/_sync_all.py +414 -414
  208. package/template/.opencode/skills/ui-ux-pro-max/data/app-interface.csv +30 -30
  209. package/template/.opencode/skills/ui-ux-pro-max/data/design.csv +1775 -1775
  210. package/template/.opencode/skills/ui-ux-pro-max/data/draft.csv +1778 -1778
  211. package/template/.opencode/skills/ui-ux-pro-max/data/icons.csv +105 -105
  212. package/template/.opencode/skills/ui-ux-pro-max/data/products.csv +162 -162
  213. package/template/.opencode/skills/ui-ux-pro-max/data/react-performance.csv +45 -45
  214. package/template/.opencode/skills/ui-ux-pro-max/data/stacks/angular.csv +51 -51
  215. package/template/.opencode/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -54
  216. package/template/.opencode/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -53
  217. package/template/.opencode/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -56
  218. package/template/.opencode/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -53
  219. package/template/.opencode/skills/ui-ux-pro-max/data/stacks/laravel.csv +51 -51
  220. package/template/.opencode/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -53
  221. package/template/.opencode/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -51
  222. package/template/.opencode/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -59
  223. package/template/.opencode/skills/ui-ux-pro-max/data/stacks/react.csv +54 -54
  224. package/template/.opencode/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -61
  225. package/template/.opencode/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -54
  226. package/template/.opencode/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -51
  227. package/template/.opencode/skills/ui-ux-pro-max/data/stacks/threejs.csv +54 -54
  228. package/template/.opencode/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -50
  229. package/template/.opencode/skills/ui-ux-pro-max/data/typography.csv +74 -74
  230. package/template/.opencode/skills/ui-ux-pro-max/scripts/core.py +262 -262
  231. package/template/.opencode/skills/ui-ux-pro-max/scripts/design_system.py +1148 -1148
  232. package/template/AGENT_PERSONAS.md +595 -551
  233. package/template/GIT_STRUCTURE_GUIDE.md +270 -270
  234. package/template/PROJECT_README.example.md +81 -81
  235. package/template/QUICK-START.md +134 -131
  236. package/template/README.md +1942 -1919
  237. package/template/_gitignore +138 -138
  238. package/template/agent/workflows/_shared/change-management.md +70 -70
  239. package/template/agent/workflows/_shared/git-branch-management.md +25 -25
  240. package/template/agent/workflows/_shared/phases.md +88 -88
  241. package/template/agent/workflows/_shared/state-management.md +87 -87
  242. package/template/agent/workflows/_shared/work-depth.md +46 -46
  243. package/template/agent/workflows/analyst.md +104 -104
  244. package/template/agent/workflows/backend.md +61 -61
  245. package/template/agent/workflows/data-architect.md +43 -43
  246. package/template/agent/workflows/devops.md +44 -44
  247. package/template/agent/workflows/discovery.md +51 -51
  248. package/template/agent/workflows/document.md +51 -51
  249. package/template/agent/workflows/explorer.md +133 -133
  250. package/template/agent/workflows/fixer.md +82 -81
  251. package/template/agent/workflows/frontend.md +60 -60
  252. package/template/agent/workflows/fullstack.md +86 -86
  253. package/template/agent/workflows/initiator.md +74 -74
  254. package/template/agent/workflows/logger.md +138 -138
  255. package/template/agent/workflows/manual-tester.md +103 -0
  256. package/template/agent/workflows/orchestrator.md +133 -133
  257. package/template/agent/workflows/pm.md +199 -199
  258. package/template/agent/workflows/qa.md +66 -66
  259. package/template/agent/workflows/reliability.md +48 -48
  260. package/template/agent/workflows/security.md +107 -107
  261. package/template/agent/workflows/sysarch.md +301 -301
  262. package/template/agent/workflows/tester.md +100 -100
  263. package/template/agent/workflows/toolsmith.md +77 -77
  264. package/template/agent/workflows/ux-designer.md +45 -45
  265. package/template/codes/.gitkeep +1 -1
  266. package/template/project_overview_example.md +54 -54
  267. package/template/schemas/adr.template.md +36 -36
  268. package/template/schemas/changelog.template.md +34 -34
  269. package/template/schemas/data-model.template.md +57 -57
  270. package/template/schemas/design-system.template.md +63 -63
  271. package/template/schemas/dev_log.template.md +20 -20
  272. package/template/schemas/product-ci.template.yml +50 -50
  273. package/template/schemas/requirements.template.md +64 -64
  274. package/template/schemas/security-standards.template.md +58 -58
  275. package/template/schemas/security_report.template.md +89 -89
  276. package/template/schemas/specification.template.md +71 -71
  277. package/template/schemas/style_guide.template.md +29 -29
  278. package/template/schemas/task_list.template.md +28 -28
  279. package/template/schemas/workspace-manifest.template.json +24 -24
  280. package/template/schemas/workspace-registry.json +95 -95
  281. package/template/skills-lock.json +11 -11
  282. package/template/specifications/.gitkeep +3 -3
  283. package/template/state/knowledge_base/.gitkeep +1 -1
  284. package/template/state/knowledge_base/requirements/.gitkeep +1 -1
  285. package/template/tests/.gitkeep +1 -1
  286. package/template/.claude/settings.local.json +0 -44
@@ -1,262 +1,262 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
- """
4
- UI/UX Pro Max Core - BM25 search engine for UI/UX style guides
5
- """
6
-
7
- import csv
8
- import re
9
- from pathlib import Path
10
- from math import log
11
- from collections import defaultdict
12
-
13
- # ============ CONFIGURATION ============
14
- DATA_DIR = Path(__file__).parent.parent / "data"
15
- MAX_RESULTS = 3
16
-
17
- CSV_CONFIG = {
18
- "style": {
19
- "file": "styles.csv",
20
- "search_cols": ["Style Category", "Keywords", "Best For", "Type", "AI Prompt Keywords"],
21
- "output_cols": ["Style Category", "Type", "Keywords", "Primary Colors", "Effects & Animation", "Best For", "Light Mode ✓", "Dark Mode ✓", "Performance", "Accessibility", "Framework Compatibility", "Complexity", "AI Prompt Keywords", "CSS/Technical Keywords", "Implementation Checklist", "Design System Variables"]
22
- },
23
- "color": {
24
- "file": "colors.csv",
25
- "search_cols": ["Product Type", "Notes"],
26
- "output_cols": ["Product Type", "Primary", "On Primary", "Secondary", "On Secondary", "Accent", "On Accent", "Background", "Foreground", "Card", "Card Foreground", "Muted", "Muted Foreground", "Border", "Destructive", "On Destructive", "Ring", "Notes"]
27
- },
28
- "chart": {
29
- "file": "charts.csv",
30
- "search_cols": ["Data Type", "Keywords", "Best Chart Type", "When to Use", "When NOT to Use", "Accessibility Notes"],
31
- "output_cols": ["Data Type", "Keywords", "Best Chart Type", "Secondary Options", "When to Use", "When NOT to Use", "Data Volume Threshold", "Color Guidance", "Accessibility Grade", "Accessibility Notes", "A11y Fallback", "Library Recommendation", "Interactive Level"]
32
- },
33
- "landing": {
34
- "file": "landing.csv",
35
- "search_cols": ["Pattern Name", "Keywords", "Conversion Optimization", "Section Order"],
36
- "output_cols": ["Pattern Name", "Keywords", "Section Order", "Primary CTA Placement", "Color Strategy", "Conversion Optimization"]
37
- },
38
- "product": {
39
- "file": "products.csv",
40
- "search_cols": ["Product Type", "Keywords", "Primary Style Recommendation", "Key Considerations"],
41
- "output_cols": ["Product Type", "Keywords", "Primary Style Recommendation", "Secondary Styles", "Landing Page Pattern", "Dashboard Style (if applicable)", "Color Palette Focus"]
42
- },
43
- "ux": {
44
- "file": "ux-guidelines.csv",
45
- "search_cols": ["Category", "Issue", "Description", "Platform"],
46
- "output_cols": ["Category", "Issue", "Platform", "Description", "Do", "Don't", "Code Example Good", "Code Example Bad", "Severity"]
47
- },
48
- "typography": {
49
- "file": "typography.csv",
50
- "search_cols": ["Font Pairing Name", "Category", "Mood/Style Keywords", "Best For", "Heading Font", "Body Font"],
51
- "output_cols": ["Font Pairing Name", "Category", "Heading Font", "Body Font", "Mood/Style Keywords", "Best For", "Google Fonts URL", "CSS Import", "Tailwind Config", "Notes"]
52
- },
53
- "icons": {
54
- "file": "icons.csv",
55
- "search_cols": ["Category", "Icon Name", "Keywords", "Best For"],
56
- "output_cols": ["Category", "Icon Name", "Keywords", "Library", "Import Code", "Usage", "Best For", "Style"]
57
- },
58
- "react": {
59
- "file": "react-performance.csv",
60
- "search_cols": ["Category", "Issue", "Keywords", "Description"],
61
- "output_cols": ["Category", "Issue", "Platform", "Description", "Do", "Don't", "Code Example Good", "Code Example Bad", "Severity"]
62
- },
63
- "web": {
64
- "file": "app-interface.csv",
65
- "search_cols": ["Category", "Issue", "Keywords", "Description"],
66
- "output_cols": ["Category", "Issue", "Platform", "Description", "Do", "Don't", "Code Example Good", "Code Example Bad", "Severity"]
67
- },
68
- "google-fonts": {
69
- "file": "google-fonts.csv",
70
- "search_cols": ["Family", "Category", "Stroke", "Classifications", "Keywords", "Subsets", "Designers"],
71
- "output_cols": ["Family", "Category", "Stroke", "Classifications", "Styles", "Variable Axes", "Subsets", "Designers", "Popularity Rank", "Google Fonts URL"]
72
- }
73
- }
74
-
75
- STACK_CONFIG = {
76
- "react": {"file": "stacks/react.csv"},
77
- "nextjs": {"file": "stacks/nextjs.csv"},
78
- "vue": {"file": "stacks/vue.csv"},
79
- "svelte": {"file": "stacks/svelte.csv"},
80
- "astro": {"file": "stacks/astro.csv"},
81
- "swiftui": {"file": "stacks/swiftui.csv"},
82
- "react-native": {"file": "stacks/react-native.csv"},
83
- "flutter": {"file": "stacks/flutter.csv"},
84
- "nuxtjs": {"file": "stacks/nuxtjs.csv"},
85
- "nuxt-ui": {"file": "stacks/nuxt-ui.csv"},
86
- "html-tailwind": {"file": "stacks/html-tailwind.csv"},
87
- "shadcn": {"file": "stacks/shadcn.csv"},
88
- "jetpack-compose": {"file": "stacks/jetpack-compose.csv"},
89
- "threejs": {"file": "stacks/threejs.csv"},
90
- "angular": {"file": "stacks/angular.csv"},
91
- "laravel": {"file": "stacks/laravel.csv"},
92
- }
93
-
94
- # Common columns for all stacks
95
- _STACK_COLS = {
96
- "search_cols": ["Category", "Guideline", "Description", "Do", "Don't"],
97
- "output_cols": ["Category", "Guideline", "Description", "Do", "Don't", "Code Good", "Code Bad", "Severity", "Docs URL"]
98
- }
99
-
100
- AVAILABLE_STACKS = list(STACK_CONFIG.keys())
101
-
102
-
103
- # ============ BM25 IMPLEMENTATION ============
104
- class BM25:
105
- """BM25 ranking algorithm for text search"""
106
-
107
- def __init__(self, k1=1.5, b=0.75):
108
- self.k1 = k1
109
- self.b = b
110
- self.corpus = []
111
- self.doc_lengths = []
112
- self.avgdl = 0
113
- self.idf = {}
114
- self.doc_freqs = defaultdict(int)
115
- self.N = 0
116
-
117
- def tokenize(self, text):
118
- """Lowercase, split, remove punctuation, filter short words"""
119
- text = re.sub(r'[^\w\s]', ' ', str(text).lower())
120
- return [w for w in text.split() if len(w) > 2]
121
-
122
- def fit(self, documents):
123
- """Build BM25 index from documents"""
124
- self.corpus = [self.tokenize(doc) for doc in documents]
125
- self.N = len(self.corpus)
126
- if self.N == 0:
127
- return
128
- self.doc_lengths = [len(doc) for doc in self.corpus]
129
- self.avgdl = sum(self.doc_lengths) / self.N
130
-
131
- for doc in self.corpus:
132
- seen = set()
133
- for word in doc:
134
- if word not in seen:
135
- self.doc_freqs[word] += 1
136
- seen.add(word)
137
-
138
- for word, freq in self.doc_freqs.items():
139
- self.idf[word] = log((self.N - freq + 0.5) / (freq + 0.5) + 1)
140
-
141
- def score(self, query):
142
- """Score all documents against query"""
143
- query_tokens = self.tokenize(query)
144
- scores = []
145
-
146
- for idx, doc in enumerate(self.corpus):
147
- score = 0
148
- doc_len = self.doc_lengths[idx]
149
- term_freqs = defaultdict(int)
150
- for word in doc:
151
- term_freqs[word] += 1
152
-
153
- for token in query_tokens:
154
- if token in self.idf:
155
- tf = term_freqs[token]
156
- idf = self.idf[token]
157
- numerator = tf * (self.k1 + 1)
158
- denominator = tf + self.k1 * (1 - self.b + self.b * doc_len / self.avgdl)
159
- score += idf * numerator / denominator
160
-
161
- scores.append((idx, score))
162
-
163
- return sorted(scores, key=lambda x: x[1], reverse=True)
164
-
165
-
166
- # ============ SEARCH FUNCTIONS ============
167
- def _load_csv(filepath):
168
- """Load CSV and return list of dicts"""
169
- with open(filepath, 'r', encoding='utf-8') as f:
170
- return list(csv.DictReader(f))
171
-
172
-
173
- def _search_csv(filepath, search_cols, output_cols, query, max_results):
174
- """Core search function using BM25"""
175
- if not filepath.exists():
176
- return []
177
-
178
- data = _load_csv(filepath)
179
-
180
- # Build documents from search columns
181
- documents = [" ".join(str(row.get(col, "")) for col in search_cols) for row in data]
182
-
183
- # BM25 search
184
- bm25 = BM25()
185
- bm25.fit(documents)
186
- ranked = bm25.score(query)
187
-
188
- # Get top results with score > 0
189
- results = []
190
- for idx, score in ranked[:max_results]:
191
- if score > 0:
192
- row = data[idx]
193
- results.append({col: row.get(col, "") for col in output_cols if col in row})
194
-
195
- return results
196
-
197
-
198
- def detect_domain(query):
199
- """Auto-detect the most relevant domain from query"""
200
- query_lower = query.lower()
201
-
202
- domain_keywords = {
203
- "color": ["color", "palette", "hex", "#", "rgb", "token", "semantic", "accent", "destructive", "muted", "foreground"],
204
- "chart": ["chart", "graph", "visualization", "trend", "bar", "pie", "scatter", "heatmap", "funnel"],
205
- "landing": ["landing", "page", "cta", "conversion", "hero", "testimonial", "pricing", "section"],
206
- "product": ["saas", "ecommerce", "e-commerce", "fintech", "healthcare", "gaming", "portfolio", "crypto", "dashboard", "fitness", "restaurant", "hotel", "travel", "music", "education", "learning", "legal", "insurance", "medical", "beauty", "pharmacy", "dental", "pet", "dating", "wedding", "recipe", "delivery", "ride", "booking", "calendar", "timer", "tracker", "diary", "note", "chat", "messenger", "crm", "invoice", "parking", "transit", "vpn", "alarm", "weather", "sleep", "meditation", "fasting", "habit", "grocery", "meme", "wardrobe", "plant care", "reading", "flashcard", "puzzle", "trivia", "arcade", "photography", "streaming", "podcast", "newsletter", "marketplace", "freelancer", "coworking", "airline", "museum", "theater", "church", "non-profit", "charity", "kindergarten", "daycare", "senior care", "veterinary", "florist", "bakery", "brewery", "construction", "automotive", "real estate", "logistics", "agriculture", "coding bootcamp"],
207
- "style": ["style", "design", "ui", "minimalism", "glassmorphism", "neumorphism", "brutalism", "dark mode", "flat", "aurora", "prompt", "css", "implementation", "variable", "checklist", "tailwind"],
208
- "ux": ["ux", "usability", "accessibility", "wcag", "touch", "scroll", "animation", "keyboard", "navigation", "mobile"],
209
- "typography": ["font pairing", "typography pairing", "heading font", "body font"],
210
- "google-fonts": ["google font", "font family", "font weight", "font style", "variable font", "noto", "font for", "find font", "font subset", "font language", "monospace font", "serif font", "sans serif font", "display font", "handwriting font", "font", "typography", "serif", "sans"],
211
- "icons": ["icon", "icons", "lucide", "heroicons", "symbol", "glyph", "pictogram", "svg icon"],
212
- "react": ["react", "next.js", "nextjs", "suspense", "memo", "usecallback", "useeffect", "rerender", "bundle", "waterfall", "barrel", "dynamic import", "rsc", "server component"],
213
- "web": ["aria", "focus", "outline", "semantic", "virtualize", "autocomplete", "form", "input type", "preconnect"]
214
- }
215
-
216
- scores = {domain: sum(1 for kw in keywords if re.search(r'\b' + re.escape(kw) + r'\b', query_lower)) for domain, keywords in domain_keywords.items()}
217
- best = max(scores, key=scores.get)
218
- return best if scores[best] > 0 else "style"
219
-
220
-
221
- def search(query, domain=None, max_results=MAX_RESULTS):
222
- """Main search function with auto-domain detection"""
223
- if domain is None:
224
- domain = detect_domain(query)
225
-
226
- config = CSV_CONFIG.get(domain, CSV_CONFIG["style"])
227
- filepath = DATA_DIR / config["file"]
228
-
229
- if not filepath.exists():
230
- return {"error": f"File not found: {filepath}", "domain": domain}
231
-
232
- results = _search_csv(filepath, config["search_cols"], config["output_cols"], query, max_results)
233
-
234
- return {
235
- "domain": domain,
236
- "query": query,
237
- "file": config["file"],
238
- "count": len(results),
239
- "results": results
240
- }
241
-
242
-
243
- def search_stack(query, stack, max_results=MAX_RESULTS):
244
- """Search stack-specific guidelines"""
245
- if stack not in STACK_CONFIG:
246
- return {"error": f"Unknown stack: {stack}. Available: {', '.join(AVAILABLE_STACKS)}"}
247
-
248
- filepath = DATA_DIR / STACK_CONFIG[stack]["file"]
249
-
250
- if not filepath.exists():
251
- return {"error": f"Stack file not found: {filepath}", "stack": stack}
252
-
253
- results = _search_csv(filepath, _STACK_COLS["search_cols"], _STACK_COLS["output_cols"], query, max_results)
254
-
255
- return {
256
- "domain": "stack",
257
- "stack": stack,
258
- "query": query,
259
- "file": STACK_CONFIG[stack]["file"],
260
- "count": len(results),
261
- "results": results
262
- }
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ UI/UX Pro Max Core - BM25 search engine for UI/UX style guides
5
+ """
6
+
7
+ import csv
8
+ import re
9
+ from pathlib import Path
10
+ from math import log
11
+ from collections import defaultdict
12
+
13
+ # ============ CONFIGURATION ============
14
+ DATA_DIR = Path(__file__).parent.parent / "data"
15
+ MAX_RESULTS = 3
16
+
17
+ CSV_CONFIG = {
18
+ "style": {
19
+ "file": "styles.csv",
20
+ "search_cols": ["Style Category", "Keywords", "Best For", "Type", "AI Prompt Keywords"],
21
+ "output_cols": ["Style Category", "Type", "Keywords", "Primary Colors", "Effects & Animation", "Best For", "Light Mode ✓", "Dark Mode ✓", "Performance", "Accessibility", "Framework Compatibility", "Complexity", "AI Prompt Keywords", "CSS/Technical Keywords", "Implementation Checklist", "Design System Variables"]
22
+ },
23
+ "color": {
24
+ "file": "colors.csv",
25
+ "search_cols": ["Product Type", "Notes"],
26
+ "output_cols": ["Product Type", "Primary", "On Primary", "Secondary", "On Secondary", "Accent", "On Accent", "Background", "Foreground", "Card", "Card Foreground", "Muted", "Muted Foreground", "Border", "Destructive", "On Destructive", "Ring", "Notes"]
27
+ },
28
+ "chart": {
29
+ "file": "charts.csv",
30
+ "search_cols": ["Data Type", "Keywords", "Best Chart Type", "When to Use", "When NOT to Use", "Accessibility Notes"],
31
+ "output_cols": ["Data Type", "Keywords", "Best Chart Type", "Secondary Options", "When to Use", "When NOT to Use", "Data Volume Threshold", "Color Guidance", "Accessibility Grade", "Accessibility Notes", "A11y Fallback", "Library Recommendation", "Interactive Level"]
32
+ },
33
+ "landing": {
34
+ "file": "landing.csv",
35
+ "search_cols": ["Pattern Name", "Keywords", "Conversion Optimization", "Section Order"],
36
+ "output_cols": ["Pattern Name", "Keywords", "Section Order", "Primary CTA Placement", "Color Strategy", "Conversion Optimization"]
37
+ },
38
+ "product": {
39
+ "file": "products.csv",
40
+ "search_cols": ["Product Type", "Keywords", "Primary Style Recommendation", "Key Considerations"],
41
+ "output_cols": ["Product Type", "Keywords", "Primary Style Recommendation", "Secondary Styles", "Landing Page Pattern", "Dashboard Style (if applicable)", "Color Palette Focus"]
42
+ },
43
+ "ux": {
44
+ "file": "ux-guidelines.csv",
45
+ "search_cols": ["Category", "Issue", "Description", "Platform"],
46
+ "output_cols": ["Category", "Issue", "Platform", "Description", "Do", "Don't", "Code Example Good", "Code Example Bad", "Severity"]
47
+ },
48
+ "typography": {
49
+ "file": "typography.csv",
50
+ "search_cols": ["Font Pairing Name", "Category", "Mood/Style Keywords", "Best For", "Heading Font", "Body Font"],
51
+ "output_cols": ["Font Pairing Name", "Category", "Heading Font", "Body Font", "Mood/Style Keywords", "Best For", "Google Fonts URL", "CSS Import", "Tailwind Config", "Notes"]
52
+ },
53
+ "icons": {
54
+ "file": "icons.csv",
55
+ "search_cols": ["Category", "Icon Name", "Keywords", "Best For"],
56
+ "output_cols": ["Category", "Icon Name", "Keywords", "Library", "Import Code", "Usage", "Best For", "Style"]
57
+ },
58
+ "react": {
59
+ "file": "react-performance.csv",
60
+ "search_cols": ["Category", "Issue", "Keywords", "Description"],
61
+ "output_cols": ["Category", "Issue", "Platform", "Description", "Do", "Don't", "Code Example Good", "Code Example Bad", "Severity"]
62
+ },
63
+ "web": {
64
+ "file": "app-interface.csv",
65
+ "search_cols": ["Category", "Issue", "Keywords", "Description"],
66
+ "output_cols": ["Category", "Issue", "Platform", "Description", "Do", "Don't", "Code Example Good", "Code Example Bad", "Severity"]
67
+ },
68
+ "google-fonts": {
69
+ "file": "google-fonts.csv",
70
+ "search_cols": ["Family", "Category", "Stroke", "Classifications", "Keywords", "Subsets", "Designers"],
71
+ "output_cols": ["Family", "Category", "Stroke", "Classifications", "Styles", "Variable Axes", "Subsets", "Designers", "Popularity Rank", "Google Fonts URL"]
72
+ }
73
+ }
74
+
75
+ STACK_CONFIG = {
76
+ "react": {"file": "stacks/react.csv"},
77
+ "nextjs": {"file": "stacks/nextjs.csv"},
78
+ "vue": {"file": "stacks/vue.csv"},
79
+ "svelte": {"file": "stacks/svelte.csv"},
80
+ "astro": {"file": "stacks/astro.csv"},
81
+ "swiftui": {"file": "stacks/swiftui.csv"},
82
+ "react-native": {"file": "stacks/react-native.csv"},
83
+ "flutter": {"file": "stacks/flutter.csv"},
84
+ "nuxtjs": {"file": "stacks/nuxtjs.csv"},
85
+ "nuxt-ui": {"file": "stacks/nuxt-ui.csv"},
86
+ "html-tailwind": {"file": "stacks/html-tailwind.csv"},
87
+ "shadcn": {"file": "stacks/shadcn.csv"},
88
+ "jetpack-compose": {"file": "stacks/jetpack-compose.csv"},
89
+ "threejs": {"file": "stacks/threejs.csv"},
90
+ "angular": {"file": "stacks/angular.csv"},
91
+ "laravel": {"file": "stacks/laravel.csv"},
92
+ }
93
+
94
+ # Common columns for all stacks
95
+ _STACK_COLS = {
96
+ "search_cols": ["Category", "Guideline", "Description", "Do", "Don't"],
97
+ "output_cols": ["Category", "Guideline", "Description", "Do", "Don't", "Code Good", "Code Bad", "Severity", "Docs URL"]
98
+ }
99
+
100
+ AVAILABLE_STACKS = list(STACK_CONFIG.keys())
101
+
102
+
103
+ # ============ BM25 IMPLEMENTATION ============
104
+ class BM25:
105
+ """BM25 ranking algorithm for text search"""
106
+
107
+ def __init__(self, k1=1.5, b=0.75):
108
+ self.k1 = k1
109
+ self.b = b
110
+ self.corpus = []
111
+ self.doc_lengths = []
112
+ self.avgdl = 0
113
+ self.idf = {}
114
+ self.doc_freqs = defaultdict(int)
115
+ self.N = 0
116
+
117
+ def tokenize(self, text):
118
+ """Lowercase, split, remove punctuation, filter short words"""
119
+ text = re.sub(r'[^\w\s]', ' ', str(text).lower())
120
+ return [w for w in text.split() if len(w) > 2]
121
+
122
+ def fit(self, documents):
123
+ """Build BM25 index from documents"""
124
+ self.corpus = [self.tokenize(doc) for doc in documents]
125
+ self.N = len(self.corpus)
126
+ if self.N == 0:
127
+ return
128
+ self.doc_lengths = [len(doc) for doc in self.corpus]
129
+ self.avgdl = sum(self.doc_lengths) / self.N
130
+
131
+ for doc in self.corpus:
132
+ seen = set()
133
+ for word in doc:
134
+ if word not in seen:
135
+ self.doc_freqs[word] += 1
136
+ seen.add(word)
137
+
138
+ for word, freq in self.doc_freqs.items():
139
+ self.idf[word] = log((self.N - freq + 0.5) / (freq + 0.5) + 1)
140
+
141
+ def score(self, query):
142
+ """Score all documents against query"""
143
+ query_tokens = self.tokenize(query)
144
+ scores = []
145
+
146
+ for idx, doc in enumerate(self.corpus):
147
+ score = 0
148
+ doc_len = self.doc_lengths[idx]
149
+ term_freqs = defaultdict(int)
150
+ for word in doc:
151
+ term_freqs[word] += 1
152
+
153
+ for token in query_tokens:
154
+ if token in self.idf:
155
+ tf = term_freqs[token]
156
+ idf = self.idf[token]
157
+ numerator = tf * (self.k1 + 1)
158
+ denominator = tf + self.k1 * (1 - self.b + self.b * doc_len / self.avgdl)
159
+ score += idf * numerator / denominator
160
+
161
+ scores.append((idx, score))
162
+
163
+ return sorted(scores, key=lambda x: x[1], reverse=True)
164
+
165
+
166
+ # ============ SEARCH FUNCTIONS ============
167
+ def _load_csv(filepath):
168
+ """Load CSV and return list of dicts"""
169
+ with open(filepath, 'r', encoding='utf-8') as f:
170
+ return list(csv.DictReader(f))
171
+
172
+
173
+ def _search_csv(filepath, search_cols, output_cols, query, max_results):
174
+ """Core search function using BM25"""
175
+ if not filepath.exists():
176
+ return []
177
+
178
+ data = _load_csv(filepath)
179
+
180
+ # Build documents from search columns
181
+ documents = [" ".join(str(row.get(col, "")) for col in search_cols) for row in data]
182
+
183
+ # BM25 search
184
+ bm25 = BM25()
185
+ bm25.fit(documents)
186
+ ranked = bm25.score(query)
187
+
188
+ # Get top results with score > 0
189
+ results = []
190
+ for idx, score in ranked[:max_results]:
191
+ if score > 0:
192
+ row = data[idx]
193
+ results.append({col: row.get(col, "") for col in output_cols if col in row})
194
+
195
+ return results
196
+
197
+
198
+ def detect_domain(query):
199
+ """Auto-detect the most relevant domain from query"""
200
+ query_lower = query.lower()
201
+
202
+ domain_keywords = {
203
+ "color": ["color", "palette", "hex", "#", "rgb", "token", "semantic", "accent", "destructive", "muted", "foreground"],
204
+ "chart": ["chart", "graph", "visualization", "trend", "bar", "pie", "scatter", "heatmap", "funnel"],
205
+ "landing": ["landing", "page", "cta", "conversion", "hero", "testimonial", "pricing", "section"],
206
+ "product": ["saas", "ecommerce", "e-commerce", "fintech", "healthcare", "gaming", "portfolio", "crypto", "dashboard", "fitness", "restaurant", "hotel", "travel", "music", "education", "learning", "legal", "insurance", "medical", "beauty", "pharmacy", "dental", "pet", "dating", "wedding", "recipe", "delivery", "ride", "booking", "calendar", "timer", "tracker", "diary", "note", "chat", "messenger", "crm", "invoice", "parking", "transit", "vpn", "alarm", "weather", "sleep", "meditation", "fasting", "habit", "grocery", "meme", "wardrobe", "plant care", "reading", "flashcard", "puzzle", "trivia", "arcade", "photography", "streaming", "podcast", "newsletter", "marketplace", "freelancer", "coworking", "airline", "museum", "theater", "church", "non-profit", "charity", "kindergarten", "daycare", "senior care", "veterinary", "florist", "bakery", "brewery", "construction", "automotive", "real estate", "logistics", "agriculture", "coding bootcamp"],
207
+ "style": ["style", "design", "ui", "minimalism", "glassmorphism", "neumorphism", "brutalism", "dark mode", "flat", "aurora", "prompt", "css", "implementation", "variable", "checklist", "tailwind"],
208
+ "ux": ["ux", "usability", "accessibility", "wcag", "touch", "scroll", "animation", "keyboard", "navigation", "mobile"],
209
+ "typography": ["font pairing", "typography pairing", "heading font", "body font"],
210
+ "google-fonts": ["google font", "font family", "font weight", "font style", "variable font", "noto", "font for", "find font", "font subset", "font language", "monospace font", "serif font", "sans serif font", "display font", "handwriting font", "font", "typography", "serif", "sans"],
211
+ "icons": ["icon", "icons", "lucide", "heroicons", "symbol", "glyph", "pictogram", "svg icon"],
212
+ "react": ["react", "next.js", "nextjs", "suspense", "memo", "usecallback", "useeffect", "rerender", "bundle", "waterfall", "barrel", "dynamic import", "rsc", "server component"],
213
+ "web": ["aria", "focus", "outline", "semantic", "virtualize", "autocomplete", "form", "input type", "preconnect"]
214
+ }
215
+
216
+ scores = {domain: sum(1 for kw in keywords if re.search(r'\b' + re.escape(kw) + r'\b', query_lower)) for domain, keywords in domain_keywords.items()}
217
+ best = max(scores, key=scores.get)
218
+ return best if scores[best] > 0 else "style"
219
+
220
+
221
+ def search(query, domain=None, max_results=MAX_RESULTS):
222
+ """Main search function with auto-domain detection"""
223
+ if domain is None:
224
+ domain = detect_domain(query)
225
+
226
+ config = CSV_CONFIG.get(domain, CSV_CONFIG["style"])
227
+ filepath = DATA_DIR / config["file"]
228
+
229
+ if not filepath.exists():
230
+ return {"error": f"File not found: {filepath}", "domain": domain}
231
+
232
+ results = _search_csv(filepath, config["search_cols"], config["output_cols"], query, max_results)
233
+
234
+ return {
235
+ "domain": domain,
236
+ "query": query,
237
+ "file": config["file"],
238
+ "count": len(results),
239
+ "results": results
240
+ }
241
+
242
+
243
+ def search_stack(query, stack, max_results=MAX_RESULTS):
244
+ """Search stack-specific guidelines"""
245
+ if stack not in STACK_CONFIG:
246
+ return {"error": f"Unknown stack: {stack}. Available: {', '.join(AVAILABLE_STACKS)}"}
247
+
248
+ filepath = DATA_DIR / STACK_CONFIG[stack]["file"]
249
+
250
+ if not filepath.exists():
251
+ return {"error": f"Stack file not found: {filepath}", "stack": stack}
252
+
253
+ results = _search_csv(filepath, _STACK_COLS["search_cols"], _STACK_COLS["output_cols"], query, max_results)
254
+
255
+ return {
256
+ "domain": "stack",
257
+ "stack": stack,
258
+ "query": query,
259
+ "file": STACK_CONFIG[stack]["file"],
260
+ "count": len(results),
261
+ "results": results
262
+ }