kenaz 0.3.3 → 0.3.6

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 (451) hide show
  1. package/core/.agents/skills/typesafe-ai/LICENSE +21 -21
  2. package/core/.agents/skills/typesafe-ai/SKILL.md +149 -149
  3. package/core/.claude/commands/Ansuz.md +15 -2
  4. package/core/.claude/hooks/__tests__/task-2395-project-registration.test.js +84 -0
  5. package/core/.claude/hooks/handoff-staleness.js +2 -2
  6. package/core/.claude/hooks/session-init.ps1 +49 -49
  7. package/core/.claude/hooks/turn-context.js +50 -2
  8. package/core/.claude/skills/ui-ux-pro-max/data/charts.csv +26 -26
  9. package/core/.claude/skills/ui-ux-pro-max/data/colors.csv +97 -97
  10. package/core/.claude/skills/ui-ux-pro-max/data/icons.csv +101 -101
  11. package/core/.claude/skills/ui-ux-pro-max/data/landing.csv +31 -31
  12. package/core/.claude/skills/ui-ux-pro-max/data/products.csv +96 -96
  13. package/core/.claude/skills/ui-ux-pro-max/data/react-performance.csv +45 -45
  14. package/core/.claude/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -54
  15. package/core/.claude/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -53
  16. package/core/.claude/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -56
  17. package/core/.claude/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -53
  18. package/core/.claude/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -53
  19. package/core/.claude/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -51
  20. package/core/.claude/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -59
  21. package/core/.claude/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -52
  22. package/core/.claude/skills/ui-ux-pro-max/data/stacks/react.csv +54 -54
  23. package/core/.claude/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -61
  24. package/core/.claude/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -54
  25. package/core/.claude/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -51
  26. package/core/.claude/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -50
  27. package/core/.claude/skills/ui-ux-pro-max/data/styles.csv +68 -68
  28. package/core/.claude/skills/ui-ux-pro-max/data/typography.csv +57 -57
  29. package/core/.claude/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -101
  30. package/core/.claude/skills/ui-ux-pro-max/data/ux-guidelines.csv +99 -99
  31. package/core/.claude/skills/ui-ux-pro-max/data/web-interface.csv +31 -31
  32. package/core/.claude/skills/ui-ux-pro-max/scripts/core.py +253 -253
  33. package/core/.claude/skills/ui-ux-pro-max/scripts/design_system.py +1067 -1067
  34. package/core/.claude/skills/ui-ux-pro-max/scripts/search.py +106 -106
  35. package/core/.collaboration/core/task-api.js +1 -4
  36. package/core/.formation/README.md +21 -146
  37. package/core/.formation/bifrost/codex-doctor.js +37 -2
  38. package/core/.formation/bifrost/codex-doctor.test.js +18 -0
  39. package/core/.formation/bifrost/launch.js +1 -1
  40. package/core/.formation/bifrost/openai/codex-hook-shim.js +6 -0
  41. package/core/.formation/bifrost/openai/codex-hook-shim.test.js +11 -1
  42. package/core/.formation/bifrost/setup-codex.js +3 -0
  43. package/core/.formation/native/claude/README.md +1 -1
  44. package/core/.formation/role-map.yaml +3 -3
  45. package/core/.formation/spec/task_operations.parity.test.js +0 -1
  46. package/core/.formation/spec/task_operations.yaml +3 -3
  47. package/core/.formation/tests/hello.txt +2 -2
  48. package/core/.formation/tools/__tests__/subagent-bifrost-guard.test.js +4 -4
  49. package/core/.formation/tools/dashboard-models-chain.test.js +0 -6
  50. package/core/.formation/tools/dispatch-detail/cross-project-worktree.md +1 -9
  51. package/core/.formation/tools/dispatch-detail/worktree-subagent-mode.md +2 -2
  52. package/core/.formation/tools/dispatch.js +33 -554
  53. package/core/.formation/tools/mcp-allowlist.test.js +0 -1
  54. package/core/.formation/tools/post-complete/task2345.test.js +0 -5
  55. package/core/.formation/tools/pre-dispatch-snapshot.test.js +0 -100
  56. package/core/.formation/tools/prompt.js +33 -1623
  57. package/core/.formation/tools/prompt.test.js +26 -594
  58. package/core/.formation/unit/do.yaml +2 -4
  59. package/core/.kenaz/knowledge/ladybug_2c51da1e_shadow_file_frame_group.patch +163 -163
  60. package/core/.kenaz/knowledge/ladybug_30cf85690e_shadow_page_read_during_checkpoint.patch +393 -393
  61. package/core/.kenaz/knowledge/ladybug_7a17858d3a_node_group_delete_lock.patch +102 -102
  62. package/core/.kenaz/knowledge/ladybug_926a0ba1_column_checkpoint.patch +412 -412
  63. package/core/.kenaz/knowledge/ladybug_a346c4c4b6_pk_index_header_pages.patch +144 -144
  64. package/core/.kenaz/knowledge/ladybug_ba5f38815b_csr_node_group.patch +86 -86
  65. package/core/.kenaz/muninn_episode_write.ps1 +17 -17
  66. package/core/.kenaz/specialist/field_report_watermark.json +1 -1
  67. package/core/.kenaz/specialist/memory_guard_fired.json +1 -1
  68. package/core/.kenaz/specialist/memory_guard_trigger_cache.json +1 -1
  69. package/core/.kenaz/specialist/t1777_probe.txt +1 -1
  70. package/core/.matrix/index.matrix +5 -5
  71. package/core/.rule/general/agent-workflow.yaml +4 -4
  72. package/core/.rule/general/file-size-threshold.yaml +16 -4
  73. package/core/.rule/general/rust-verify-target.yaml +0 -1
  74. package/core/.rule/general/system-invariants.yaml +8 -25
  75. package/core/.specialist/Ansuz/SYSTEM_DOC.md +17 -42
  76. package/core/.specialist/Ansuz/capability.yaml +7 -14
  77. package/core/.specialist/Ansuz/concepts/formation_quick_ref.yaml +4 -11
  78. package/core/.specialist/Ansuz/elixir.yaml +3 -4
  79. package/core/.specialist/Ansuz/identity_contract.yaml +1 -1
  80. package/core/.specialist/Ansuz/knowledge.yaml +7 -10
  81. package/core/.specialist/Ansuz/rule.yaml +2 -2
  82. package/core/.specialist/Ansuz/tools/verify-and-land.js +22 -0
  83. package/core/.specialist/Ansuz/tools/verify-and-land.test.js +59 -5
  84. package/core/.specialist/Ansuz/workflow.yaml +7 -11
  85. package/core/.specialist/Forseti/core.yaml +1 -1
  86. package/core/.specialist/Heimdall/SKILL.md +1 -1
  87. package/core/.specialist/Heimdall/core.yaml +2 -2
  88. package/core/.specialist/Huginn/rule.yaml +1 -1
  89. package/core/.specialist/tools/README.md +2 -2
  90. package/core/.specialist/tools/__tests__/freya-cli-contract.test.js +0 -1
  91. package/core/.system/collaboration/README.md +1 -1
  92. package/core/.system/formation/LEGACY_SKILLS.md +2 -0
  93. package/core/.system/formation/POST_COMPLETE.md +2 -0
  94. package/core/.system/formation/README.md +2 -0
  95. package/core/KENAZ_CORE_VERSION +1 -1
  96. package/core/dev/ANSUZ_STARTUP_INJECTION_REVIEW.md +355 -355
  97. package/core/dev/JEV_INTEGRATION_PLAN.md +189 -189
  98. package/core/dev/design/matrix_format_EXAMPLE_memory.matrix +13 -13
  99. package/core/dev/design/matrix_format_EXAMPLE_project_status.matrix +9 -9
  100. package/core/dev/design/matrix_format_EXAMPLE_tasks.matrix +14 -14
  101. package/core/dev/design/matrix_v2_EXAMPLE.matrix +67 -67
  102. package/core/dev/jev-eval/ACTIVE_CORRECTION.md +52 -52
  103. package/core/dev/jev-eval/CONTEXT_REVIEW.md +31 -31
  104. package/core/dev/jev-eval/EVALUATION_STATUS.md +39 -39
  105. package/core/dev/jev-eval/HISTORICAL_CORPUS.md +33 -33
  106. package/core/dev/jev-eval/README.md +99 -99
  107. package/core/dev/jev-eval/THALAMUS_RANKING.md +58 -58
  108. package/core/dev/jev-eval/reports/annotation-pilot-2026-09-20.json +32 -32
  109. package/core/dev/jev-eval/reports/context-review-2026-09-20.json +48 -48
  110. package/core/dev/jev-eval/reports/history-corpus-2026-09-20.json +52 -52
  111. package/core/dev/pipeline/SELF_ENHANCEMENT_STATUS.json.bak +47 -47
  112. package/core/dev/pipeline/tasks/.gitkeep +1 -1
  113. package/core/dev/pipeline/test_results/TASK_TEST_PARALLEL_002_result.txt +27 -27
  114. package/core/dev/scripts/check-file-size.js +44 -17
  115. package/core/dev/scripts/init_git.sh +0 -0
  116. package/core/dev/scripts/init_project.sh +0 -0
  117. package/core/dev/scripts/legacy/dev_agent_scheduler.ps1.bak +536 -536
  118. package/core/dev/scripts/legacy/multi_agent_scheduler.ps1.bak +1978 -1978
  119. package/core/dev/scripts/matrix/src/cli/commands/list-tags.ts.wip +140 -140
  120. package/core/dev/scripts/matrix/src/cli/commands/manage-tags.ts.wip +173 -173
  121. package/core/dev/scripts/matrix/src/cli/commands/stats.ts.wip +168 -168
  122. package/core/dev/scripts/matrix/src/cli/commands/tokens.ts.wip +126 -126
  123. package/core/dev/scripts/multi_agent_scheduler.sh +0 -0
  124. package/core/dev/scripts/run_once.sh +0 -0
  125. package/core/dev/scripts/setup_mcp.sh +0 -0
  126. package/core/dev/scripts/setup_rag.sh +0 -0
  127. package/core/dev/scripts/start_dev_agent.sh +0 -0
  128. package/core/dev/scripts/start_multi_agent.sh +0 -0
  129. package/core/dev/scripts/sync_task_queue.sh +0 -0
  130. package/core/k-cli/README.md +1 -94
  131. package/core/k-cli/test/TEST_SPEC.md +5 -22
  132. package/core/k-cli/test/run.sh +1 -67
  133. package/core/plugins/kenaz/commands/Amelia.md +1 -1
  134. package/core/plugins/kenaz/commands/Ansuz.md +16 -3
  135. package/core/plugins/kenaz/scripts/kenaz-mode.js +11 -1
  136. package/core/plugins/kenaz/scripts/sync.js +6 -2
  137. package/core/plugins/kenaz/scripts/ygg.js +13 -1
  138. package/core/plugins/kenaz/skills/product_manager/SKILL.md +12 -12
  139. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/charts.csv +26 -26
  140. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/colors.csv +97 -97
  141. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/icons.csv +101 -101
  142. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/landing.csv +31 -31
  143. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/products.csv +96 -96
  144. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/react-performance.csv +45 -45
  145. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -54
  146. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -53
  147. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -56
  148. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -53
  149. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -53
  150. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -51
  151. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -59
  152. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -52
  153. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/react.csv +54 -54
  154. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -61
  155. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -54
  156. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -51
  157. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -50
  158. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/styles.csv +68 -68
  159. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/typography.csv +57 -57
  160. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -101
  161. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/ux-guidelines.csv +99 -99
  162. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/web-interface.csv +31 -31
  163. package/core/plugins/kenaz/skills/ui-ux-pro-max/scripts/core.py +253 -253
  164. package/core/plugins/kenaz/skills/ui-ux-pro-max/scripts/design_system.py +1067 -1067
  165. package/core/plugins/kenaz/skills/ui-ux-pro-max/scripts/search.py +106 -106
  166. package/lib/cli.js +11 -4
  167. package/package.json +11 -7
  168. package/vendor/install-kenaz-cli.js +18 -7
  169. package/core/.formation/legion/forge.yaml +0 -299
  170. package/core/.formation/legion/hive.yaml +0 -238
  171. package/core/.formation/squad/blitz.yaml +0 -192
  172. package/core/.formation/squad/strategy-tribunal.yaml +0 -354
  173. package/core/.formation/squad/strategy.yaml +0 -349
  174. package/core/.formation/squad/sweep.yaml +0 -208
  175. package/core/.formation/tools/broadcast.js +0 -103
  176. package/core/.formation/tools/dispatch-dryrun.test.js +0 -54
  177. package/core/.formation/tools/dispatch-notifier.js +0 -84
  178. package/core/.formation/tools/formations.js +0 -1203
  179. package/core/.formation/tools/headless-branch-recovery.test.js +0 -64
  180. package/core/.formation/tools/headless-dryrun.test.js +0 -79
  181. package/core/.formation/tools/headless-v2.js +0 -659
  182. package/core/.formation/tools/headless.js +0 -1071
  183. package/core/.formation/tools/legacy-scheduler.js +0 -1994
  184. package/core/.formation/tools/logger.js +0 -273
  185. package/core/.formation/tools/memory-loader.js +0 -422
  186. package/core/.formation/tools/process-state.js +0 -33
  187. package/core/.formation/tools/remote-conflict.js +0 -98
  188. package/core/.formation/tools/runner.js +0 -1332
  189. package/core/.formation/tools/task-utils.js +0 -344
  190. package/core/.formation/tools/task2028-headless-worktree.test.js +0 -112
  191. package/core/.formation/tools/tests/headless-mcp-args-plumbing.test.js +0 -123
  192. package/core/.formation/tools/worktree-leak.test.js +0 -162
  193. package/core/k-cli/dist/alaya/run.js +0 -91
  194. package/core/k-cli/dist/core/output.js +0 -24
  195. package/core/k-cli/dist/core/process.js +0 -38
  196. package/core/k-cli/dist/core/project.js +0 -80
  197. package/core/k-cli/dist/core/spawn.js +0 -268
  198. package/core/k-cli/dist/core/types.js +0 -2
  199. package/core/k-cli/dist/dashboard/update.js +0 -53
  200. package/core/k-cli/dist/dashboard/version.js +0 -20
  201. package/core/k-cli/dist/dispatch/run.js +0 -241
  202. package/core/k-cli/dist/dispatch/status.js +0 -103
  203. package/core/k-cli/dist/index.js +0 -283
  204. package/core/k-cli/dist/project/initialize.js +0 -301
  205. package/core/k-cli/dist/project/install.js +0 -89
  206. package/core/k-cli/dist/project/status.js +0 -138
  207. package/core/k-cli/dist/specialist/list.js +0 -100
  208. package/core/k-cli/dist/specialist/run.js +0 -93
  209. package/core/k-cli/dist/task/create.js +0 -194
  210. package/core/k-cli/dist/task/delete.js +0 -98
  211. package/core/k-cli/dist/task/get.js +0 -55
  212. package/core/k-cli/dist/task/list.js +0 -58
  213. package/core/k-cli/dist/task/submit.js +0 -156
  214. package/core/k-cli/dist/ygg/run.js +0 -51
  215. package/core/k-cli/node_modules/.bin/yaml +0 -16
  216. package/core/k-cli/node_modules/.bin/yaml.cmd +0 -17
  217. package/core/k-cli/node_modules/.bin/yaml.ps1 +0 -28
  218. package/core/k-cli/node_modules/.package-lock.json +0 -23
  219. package/core/k-cli/node_modules/yaml/LICENSE +0 -13
  220. package/core/k-cli/node_modules/yaml/README.md +0 -172
  221. package/core/k-cli/node_modules/yaml/bin.mjs +0 -11
  222. package/core/k-cli/node_modules/yaml/browser/dist/compose/compose-collection.js +0 -88
  223. package/core/k-cli/node_modules/yaml/browser/dist/compose/compose-doc.js +0 -43
  224. package/core/k-cli/node_modules/yaml/browser/dist/compose/compose-node.js +0 -109
  225. package/core/k-cli/node_modules/yaml/browser/dist/compose/compose-scalar.js +0 -86
  226. package/core/k-cli/node_modules/yaml/browser/dist/compose/composer.js +0 -217
  227. package/core/k-cli/node_modules/yaml/browser/dist/compose/resolve-block-map.js +0 -115
  228. package/core/k-cli/node_modules/yaml/browser/dist/compose/resolve-block-scalar.js +0 -198
  229. package/core/k-cli/node_modules/yaml/browser/dist/compose/resolve-block-seq.js +0 -49
  230. package/core/k-cli/node_modules/yaml/browser/dist/compose/resolve-end.js +0 -37
  231. package/core/k-cli/node_modules/yaml/browser/dist/compose/resolve-flow-collection.js +0 -207
  232. package/core/k-cli/node_modules/yaml/browser/dist/compose/resolve-flow-scalar.js +0 -223
  233. package/core/k-cli/node_modules/yaml/browser/dist/compose/resolve-props.js +0 -146
  234. package/core/k-cli/node_modules/yaml/browser/dist/compose/util-contains-newline.js +0 -34
  235. package/core/k-cli/node_modules/yaml/browser/dist/compose/util-empty-scalar-position.js +0 -26
  236. package/core/k-cli/node_modules/yaml/browser/dist/compose/util-flow-indent-check.js +0 -15
  237. package/core/k-cli/node_modules/yaml/browser/dist/compose/util-map-includes.js +0 -13
  238. package/core/k-cli/node_modules/yaml/browser/dist/doc/Document.js +0 -335
  239. package/core/k-cli/node_modules/yaml/browser/dist/doc/anchors.js +0 -71
  240. package/core/k-cli/node_modules/yaml/browser/dist/doc/applyReviver.js +0 -55
  241. package/core/k-cli/node_modules/yaml/browser/dist/doc/createNode.js +0 -88
  242. package/core/k-cli/node_modules/yaml/browser/dist/doc/directives.js +0 -176
  243. package/core/k-cli/node_modules/yaml/browser/dist/errors.js +0 -57
  244. package/core/k-cli/node_modules/yaml/browser/dist/index.js +0 -17
  245. package/core/k-cli/node_modules/yaml/browser/dist/log.js +0 -11
  246. package/core/k-cli/node_modules/yaml/browser/dist/nodes/Alias.js +0 -114
  247. package/core/k-cli/node_modules/yaml/browser/dist/nodes/Collection.js +0 -147
  248. package/core/k-cli/node_modules/yaml/browser/dist/nodes/Node.js +0 -38
  249. package/core/k-cli/node_modules/yaml/browser/dist/nodes/Pair.js +0 -36
  250. package/core/k-cli/node_modules/yaml/browser/dist/nodes/Scalar.js +0 -24
  251. package/core/k-cli/node_modules/yaml/browser/dist/nodes/YAMLMap.js +0 -144
  252. package/core/k-cli/node_modules/yaml/browser/dist/nodes/YAMLSeq.js +0 -113
  253. package/core/k-cli/node_modules/yaml/browser/dist/nodes/addPairToJSMap.js +0 -63
  254. package/core/k-cli/node_modules/yaml/browser/dist/nodes/identity.js +0 -36
  255. package/core/k-cli/node_modules/yaml/browser/dist/nodes/toJS.js +0 -37
  256. package/core/k-cli/node_modules/yaml/browser/dist/parse/cst-scalar.js +0 -214
  257. package/core/k-cli/node_modules/yaml/browser/dist/parse/cst-stringify.js +0 -61
  258. package/core/k-cli/node_modules/yaml/browser/dist/parse/cst-visit.js +0 -97
  259. package/core/k-cli/node_modules/yaml/browser/dist/parse/cst.js +0 -98
  260. package/core/k-cli/node_modules/yaml/browser/dist/parse/lexer.js +0 -717
  261. package/core/k-cli/node_modules/yaml/browser/dist/parse/line-counter.js +0 -39
  262. package/core/k-cli/node_modules/yaml/browser/dist/parse/parser.js +0 -967
  263. package/core/k-cli/node_modules/yaml/browser/dist/public-api.js +0 -102
  264. package/core/k-cli/node_modules/yaml/browser/dist/schema/Schema.js +0 -37
  265. package/core/k-cli/node_modules/yaml/browser/dist/schema/common/map.js +0 -17
  266. package/core/k-cli/node_modules/yaml/browser/dist/schema/common/null.js +0 -15
  267. package/core/k-cli/node_modules/yaml/browser/dist/schema/common/seq.js +0 -17
  268. package/core/k-cli/node_modules/yaml/browser/dist/schema/common/string.js +0 -14
  269. package/core/k-cli/node_modules/yaml/browser/dist/schema/core/bool.js +0 -19
  270. package/core/k-cli/node_modules/yaml/browser/dist/schema/core/float.js +0 -43
  271. package/core/k-cli/node_modules/yaml/browser/dist/schema/core/int.js +0 -38
  272. package/core/k-cli/node_modules/yaml/browser/dist/schema/core/schema.js +0 -23
  273. package/core/k-cli/node_modules/yaml/browser/dist/schema/json/schema.js +0 -62
  274. package/core/k-cli/node_modules/yaml/browser/dist/schema/tags.js +0 -96
  275. package/core/k-cli/node_modules/yaml/browser/dist/schema/yaml-1.1/binary.js +0 -58
  276. package/core/k-cli/node_modules/yaml/browser/dist/schema/yaml-1.1/bool.js +0 -26
  277. package/core/k-cli/node_modules/yaml/browser/dist/schema/yaml-1.1/float.js +0 -46
  278. package/core/k-cli/node_modules/yaml/browser/dist/schema/yaml-1.1/int.js +0 -71
  279. package/core/k-cli/node_modules/yaml/browser/dist/schema/yaml-1.1/merge.js +0 -64
  280. package/core/k-cli/node_modules/yaml/browser/dist/schema/yaml-1.1/omap.js +0 -74
  281. package/core/k-cli/node_modules/yaml/browser/dist/schema/yaml-1.1/pairs.js +0 -78
  282. package/core/k-cli/node_modules/yaml/browser/dist/schema/yaml-1.1/schema.js +0 -39
  283. package/core/k-cli/node_modules/yaml/browser/dist/schema/yaml-1.1/set.js +0 -93
  284. package/core/k-cli/node_modules/yaml/browser/dist/schema/yaml-1.1/timestamp.js +0 -101
  285. package/core/k-cli/node_modules/yaml/browser/dist/stringify/foldFlowLines.js +0 -146
  286. package/core/k-cli/node_modules/yaml/browser/dist/stringify/stringify.js +0 -129
  287. package/core/k-cli/node_modules/yaml/browser/dist/stringify/stringifyCollection.js +0 -153
  288. package/core/k-cli/node_modules/yaml/browser/dist/stringify/stringifyComment.js +0 -20
  289. package/core/k-cli/node_modules/yaml/browser/dist/stringify/stringifyDocument.js +0 -85
  290. package/core/k-cli/node_modules/yaml/browser/dist/stringify/stringifyNumber.js +0 -24
  291. package/core/k-cli/node_modules/yaml/browser/dist/stringify/stringifyPair.js +0 -150
  292. package/core/k-cli/node_modules/yaml/browser/dist/stringify/stringifyString.js +0 -336
  293. package/core/k-cli/node_modules/yaml/browser/dist/util.js +0 -11
  294. package/core/k-cli/node_modules/yaml/browser/dist/visit.js +0 -233
  295. package/core/k-cli/node_modules/yaml/browser/index.js +0 -5
  296. package/core/k-cli/node_modules/yaml/browser/package.json +0 -3
  297. package/core/k-cli/node_modules/yaml/dist/cli.d.ts +0 -8
  298. package/core/k-cli/node_modules/yaml/dist/cli.mjs +0 -201
  299. package/core/k-cli/node_modules/yaml/dist/compose/compose-collection.d.ts +0 -11
  300. package/core/k-cli/node_modules/yaml/dist/compose/compose-collection.js +0 -90
  301. package/core/k-cli/node_modules/yaml/dist/compose/compose-doc.d.ts +0 -7
  302. package/core/k-cli/node_modules/yaml/dist/compose/compose-doc.js +0 -45
  303. package/core/k-cli/node_modules/yaml/dist/compose/compose-node.d.ts +0 -29
  304. package/core/k-cli/node_modules/yaml/dist/compose/compose-node.js +0 -112
  305. package/core/k-cli/node_modules/yaml/dist/compose/compose-scalar.d.ts +0 -5
  306. package/core/k-cli/node_modules/yaml/dist/compose/compose-scalar.js +0 -88
  307. package/core/k-cli/node_modules/yaml/dist/compose/composer.d.ts +0 -63
  308. package/core/k-cli/node_modules/yaml/dist/compose/composer.js +0 -222
  309. package/core/k-cli/node_modules/yaml/dist/compose/resolve-block-map.d.ts +0 -6
  310. package/core/k-cli/node_modules/yaml/dist/compose/resolve-block-map.js +0 -117
  311. package/core/k-cli/node_modules/yaml/dist/compose/resolve-block-scalar.d.ts +0 -11
  312. package/core/k-cli/node_modules/yaml/dist/compose/resolve-block-scalar.js +0 -200
  313. package/core/k-cli/node_modules/yaml/dist/compose/resolve-block-seq.d.ts +0 -6
  314. package/core/k-cli/node_modules/yaml/dist/compose/resolve-block-seq.js +0 -51
  315. package/core/k-cli/node_modules/yaml/dist/compose/resolve-end.d.ts +0 -6
  316. package/core/k-cli/node_modules/yaml/dist/compose/resolve-end.js +0 -39
  317. package/core/k-cli/node_modules/yaml/dist/compose/resolve-flow-collection.d.ts +0 -7
  318. package/core/k-cli/node_modules/yaml/dist/compose/resolve-flow-collection.js +0 -209
  319. package/core/k-cli/node_modules/yaml/dist/compose/resolve-flow-scalar.d.ts +0 -10
  320. package/core/k-cli/node_modules/yaml/dist/compose/resolve-flow-scalar.js +0 -225
  321. package/core/k-cli/node_modules/yaml/dist/compose/resolve-props.d.ts +0 -23
  322. package/core/k-cli/node_modules/yaml/dist/compose/resolve-props.js +0 -148
  323. package/core/k-cli/node_modules/yaml/dist/compose/util-contains-newline.d.ts +0 -2
  324. package/core/k-cli/node_modules/yaml/dist/compose/util-contains-newline.js +0 -36
  325. package/core/k-cli/node_modules/yaml/dist/compose/util-empty-scalar-position.d.ts +0 -2
  326. package/core/k-cli/node_modules/yaml/dist/compose/util-empty-scalar-position.js +0 -28
  327. package/core/k-cli/node_modules/yaml/dist/compose/util-flow-indent-check.d.ts +0 -3
  328. package/core/k-cli/node_modules/yaml/dist/compose/util-flow-indent-check.js +0 -17
  329. package/core/k-cli/node_modules/yaml/dist/compose/util-map-includes.d.ts +0 -4
  330. package/core/k-cli/node_modules/yaml/dist/compose/util-map-includes.js +0 -15
  331. package/core/k-cli/node_modules/yaml/dist/doc/Document.d.ts +0 -141
  332. package/core/k-cli/node_modules/yaml/dist/doc/Document.js +0 -337
  333. package/core/k-cli/node_modules/yaml/dist/doc/anchors.d.ts +0 -24
  334. package/core/k-cli/node_modules/yaml/dist/doc/anchors.js +0 -76
  335. package/core/k-cli/node_modules/yaml/dist/doc/applyReviver.d.ts +0 -9
  336. package/core/k-cli/node_modules/yaml/dist/doc/applyReviver.js +0 -57
  337. package/core/k-cli/node_modules/yaml/dist/doc/createNode.d.ts +0 -17
  338. package/core/k-cli/node_modules/yaml/dist/doc/createNode.js +0 -90
  339. package/core/k-cli/node_modules/yaml/dist/doc/directives.d.ts +0 -49
  340. package/core/k-cli/node_modules/yaml/dist/doc/directives.js +0 -178
  341. package/core/k-cli/node_modules/yaml/dist/errors.d.ts +0 -21
  342. package/core/k-cli/node_modules/yaml/dist/errors.js +0 -62
  343. package/core/k-cli/node_modules/yaml/dist/index.d.ts +0 -25
  344. package/core/k-cli/node_modules/yaml/dist/index.js +0 -50
  345. package/core/k-cli/node_modules/yaml/dist/log.d.ts +0 -3
  346. package/core/k-cli/node_modules/yaml/dist/log.js +0 -19
  347. package/core/k-cli/node_modules/yaml/dist/nodes/Alias.d.ts +0 -29
  348. package/core/k-cli/node_modules/yaml/dist/nodes/Alias.js +0 -116
  349. package/core/k-cli/node_modules/yaml/dist/nodes/Collection.d.ts +0 -73
  350. package/core/k-cli/node_modules/yaml/dist/nodes/Collection.js +0 -151
  351. package/core/k-cli/node_modules/yaml/dist/nodes/Node.d.ts +0 -53
  352. package/core/k-cli/node_modules/yaml/dist/nodes/Node.js +0 -40
  353. package/core/k-cli/node_modules/yaml/dist/nodes/Pair.d.ts +0 -22
  354. package/core/k-cli/node_modules/yaml/dist/nodes/Pair.js +0 -39
  355. package/core/k-cli/node_modules/yaml/dist/nodes/Scalar.d.ts +0 -43
  356. package/core/k-cli/node_modules/yaml/dist/nodes/Scalar.js +0 -27
  357. package/core/k-cli/node_modules/yaml/dist/nodes/YAMLMap.d.ts +0 -53
  358. package/core/k-cli/node_modules/yaml/dist/nodes/YAMLMap.js +0 -147
  359. package/core/k-cli/node_modules/yaml/dist/nodes/YAMLSeq.d.ts +0 -60
  360. package/core/k-cli/node_modules/yaml/dist/nodes/YAMLSeq.js +0 -115
  361. package/core/k-cli/node_modules/yaml/dist/nodes/addPairToJSMap.d.ts +0 -4
  362. package/core/k-cli/node_modules/yaml/dist/nodes/addPairToJSMap.js +0 -65
  363. package/core/k-cli/node_modules/yaml/dist/nodes/identity.d.ts +0 -23
  364. package/core/k-cli/node_modules/yaml/dist/nodes/identity.js +0 -53
  365. package/core/k-cli/node_modules/yaml/dist/nodes/toJS.d.ts +0 -29
  366. package/core/k-cli/node_modules/yaml/dist/nodes/toJS.js +0 -39
  367. package/core/k-cli/node_modules/yaml/dist/options.d.ts +0 -350
  368. package/core/k-cli/node_modules/yaml/dist/parse/cst-scalar.d.ts +0 -64
  369. package/core/k-cli/node_modules/yaml/dist/parse/cst-scalar.js +0 -218
  370. package/core/k-cli/node_modules/yaml/dist/parse/cst-stringify.d.ts +0 -8
  371. package/core/k-cli/node_modules/yaml/dist/parse/cst-stringify.js +0 -63
  372. package/core/k-cli/node_modules/yaml/dist/parse/cst-visit.d.ts +0 -39
  373. package/core/k-cli/node_modules/yaml/dist/parse/cst-visit.js +0 -99
  374. package/core/k-cli/node_modules/yaml/dist/parse/cst.d.ts +0 -109
  375. package/core/k-cli/node_modules/yaml/dist/parse/cst.js +0 -112
  376. package/core/k-cli/node_modules/yaml/dist/parse/lexer.d.ts +0 -87
  377. package/core/k-cli/node_modules/yaml/dist/parse/lexer.js +0 -719
  378. package/core/k-cli/node_modules/yaml/dist/parse/line-counter.d.ts +0 -22
  379. package/core/k-cli/node_modules/yaml/dist/parse/line-counter.js +0 -41
  380. package/core/k-cli/node_modules/yaml/dist/parse/parser.d.ts +0 -84
  381. package/core/k-cli/node_modules/yaml/dist/parse/parser.js +0 -972
  382. package/core/k-cli/node_modules/yaml/dist/public-api.d.ts +0 -44
  383. package/core/k-cli/node_modules/yaml/dist/public-api.js +0 -107
  384. package/core/k-cli/node_modules/yaml/dist/schema/Schema.d.ts +0 -17
  385. package/core/k-cli/node_modules/yaml/dist/schema/Schema.js +0 -39
  386. package/core/k-cli/node_modules/yaml/dist/schema/common/map.d.ts +0 -2
  387. package/core/k-cli/node_modules/yaml/dist/schema/common/map.js +0 -19
  388. package/core/k-cli/node_modules/yaml/dist/schema/common/null.d.ts +0 -4
  389. package/core/k-cli/node_modules/yaml/dist/schema/common/null.js +0 -17
  390. package/core/k-cli/node_modules/yaml/dist/schema/common/seq.d.ts +0 -2
  391. package/core/k-cli/node_modules/yaml/dist/schema/common/seq.js +0 -19
  392. package/core/k-cli/node_modules/yaml/dist/schema/common/string.d.ts +0 -2
  393. package/core/k-cli/node_modules/yaml/dist/schema/common/string.js +0 -16
  394. package/core/k-cli/node_modules/yaml/dist/schema/core/bool.d.ts +0 -4
  395. package/core/k-cli/node_modules/yaml/dist/schema/core/bool.js +0 -21
  396. package/core/k-cli/node_modules/yaml/dist/schema/core/float.d.ts +0 -4
  397. package/core/k-cli/node_modules/yaml/dist/schema/core/float.js +0 -47
  398. package/core/k-cli/node_modules/yaml/dist/schema/core/int.d.ts +0 -4
  399. package/core/k-cli/node_modules/yaml/dist/schema/core/int.js +0 -42
  400. package/core/k-cli/node_modules/yaml/dist/schema/core/schema.d.ts +0 -1
  401. package/core/k-cli/node_modules/yaml/dist/schema/core/schema.js +0 -25
  402. package/core/k-cli/node_modules/yaml/dist/schema/json/schema.d.ts +0 -2
  403. package/core/k-cli/node_modules/yaml/dist/schema/json/schema.js +0 -64
  404. package/core/k-cli/node_modules/yaml/dist/schema/json-schema.d.ts +0 -69
  405. package/core/k-cli/node_modules/yaml/dist/schema/tags.d.ts +0 -48
  406. package/core/k-cli/node_modules/yaml/dist/schema/tags.js +0 -99
  407. package/core/k-cli/node_modules/yaml/dist/schema/types.d.ts +0 -92
  408. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/binary.d.ts +0 -2
  409. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/binary.js +0 -70
  410. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/bool.d.ts +0 -7
  411. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/bool.js +0 -29
  412. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/float.d.ts +0 -4
  413. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/float.js +0 -50
  414. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/int.d.ts +0 -5
  415. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/int.js +0 -76
  416. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/merge.d.ts +0 -9
  417. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/merge.js +0 -68
  418. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/omap.d.ts +0 -22
  419. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/omap.js +0 -77
  420. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/pairs.d.ts +0 -10
  421. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/pairs.js +0 -82
  422. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/schema.d.ts +0 -1
  423. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/schema.js +0 -41
  424. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/set.d.ts +0 -28
  425. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/set.js +0 -96
  426. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/timestamp.d.ts +0 -6
  427. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/timestamp.js +0 -105
  428. package/core/k-cli/node_modules/yaml/dist/stringify/foldFlowLines.d.ts +0 -34
  429. package/core/k-cli/node_modules/yaml/dist/stringify/foldFlowLines.js +0 -151
  430. package/core/k-cli/node_modules/yaml/dist/stringify/stringify.d.ts +0 -21
  431. package/core/k-cli/node_modules/yaml/dist/stringify/stringify.js +0 -132
  432. package/core/k-cli/node_modules/yaml/dist/stringify/stringifyCollection.d.ts +0 -17
  433. package/core/k-cli/node_modules/yaml/dist/stringify/stringifyCollection.js +0 -155
  434. package/core/k-cli/node_modules/yaml/dist/stringify/stringifyComment.d.ts +0 -10
  435. package/core/k-cli/node_modules/yaml/dist/stringify/stringifyComment.js +0 -24
  436. package/core/k-cli/node_modules/yaml/dist/stringify/stringifyDocument.d.ts +0 -4
  437. package/core/k-cli/node_modules/yaml/dist/stringify/stringifyDocument.js +0 -87
  438. package/core/k-cli/node_modules/yaml/dist/stringify/stringifyNumber.d.ts +0 -2
  439. package/core/k-cli/node_modules/yaml/dist/stringify/stringifyNumber.js +0 -26
  440. package/core/k-cli/node_modules/yaml/dist/stringify/stringifyPair.d.ts +0 -3
  441. package/core/k-cli/node_modules/yaml/dist/stringify/stringifyPair.js +0 -152
  442. package/core/k-cli/node_modules/yaml/dist/stringify/stringifyString.d.ts +0 -9
  443. package/core/k-cli/node_modules/yaml/dist/stringify/stringifyString.js +0 -338
  444. package/core/k-cli/node_modules/yaml/dist/test-events.d.ts +0 -4
  445. package/core/k-cli/node_modules/yaml/dist/test-events.js +0 -134
  446. package/core/k-cli/node_modules/yaml/dist/util.d.ts +0 -16
  447. package/core/k-cli/node_modules/yaml/dist/util.js +0 -28
  448. package/core/k-cli/node_modules/yaml/dist/visit.d.ts +0 -102
  449. package/core/k-cli/node_modules/yaml/dist/visit.js +0 -236
  450. package/core/k-cli/node_modules/yaml/package.json +0 -97
  451. package/core/k-cli/node_modules/yaml/util.js +0 -2
@@ -1,31 +1,31 @@
1
- No,Category,Issue,Keywords,Platform,Description,Do,Don't,Code Example Good,Code Example Bad,Severity
2
- 1,Accessibility,Icon Button Labels,icon button aria-label,Web,Icon-only buttons must have accessible names,Add aria-label to icon buttons,Icon button without label,"<button aria-label='Close'><XIcon /></button>","<button><XIcon /></button>",Critical
3
- 2,Accessibility,Form Control Labels,form input label aria,Web,All form controls need labels or aria-label,Use label element or aria-label,Input without accessible name,"<label for='email'>Email</label><input id='email' />","<input placeholder='Email' />",Critical
4
- 3,Accessibility,Keyboard Handlers,keyboard onclick onkeydown,Web,Interactive elements must support keyboard interaction,Add onKeyDown alongside onClick,Click-only interaction,"<div onClick={fn} onKeyDown={fn} tabIndex={0}>","<div onClick={fn}>",High
5
- 4,Accessibility,Semantic HTML,semantic button a label,Web,Use semantic HTML before ARIA attributes,Use button/a/label elements,Div with role attribute,"<button onClick={fn}>Submit</button>","<div role='button' onClick={fn}>Submit</div>",High
6
- 5,Accessibility,Aria Live,aria-live polite async,Web,Async updates need aria-live for screen readers,Add aria-live='polite' for dynamic content,Silent async updates,"<div aria-live='polite'>{status}</div>","<div>{status}</div> // no announcement",Medium
7
- 6,Accessibility,Decorative Icons,aria-hidden decorative icon,Web,Decorative icons should be hidden from screen readers,Add aria-hidden='true' to decorative icons,Decorative icon announced,"<Icon aria-hidden='true' />","<Icon /> // announced as 'image'",Medium
8
- 7,Focus,Visible Focus States,focus-visible outline ring,Web,All interactive elements need visible focus states,Use :focus-visible with ring/outline,No focus indication,"focus-visible:ring-2 focus-visible:ring-blue-500","outline-none // no replacement",Critical
9
- 8,Focus,Never Remove Outline,outline-none focus replacement,Web,Never remove outline without providing replacement,Replace outline with visible alternative,Remove outline completely,"focus:outline-none focus:ring-2","focus:outline-none // nothing else",Critical
10
- 9,Focus,Checkbox Radio Hit Target,checkbox radio label target,Web,Checkbox/radio must share hit target with label,Wrap input and label together,Separate tiny checkbox,"<label class='flex gap-2'><input type='checkbox' /><span>Option</span></label>","<input type='checkbox' id='x' /><label for='x'>Option</label>",Medium
11
- 10,Forms,Autocomplete Attribute,autocomplete input form,Web,Inputs need autocomplete attribute for autofill,Add appropriate autocomplete value,Missing autocomplete,"<input autocomplete='email' type='email' />","<input type='email' />",High
12
- 11,Forms,Semantic Input Types,input type email tel url,Web,Use semantic input type attributes,Use email/tel/url/number types,text type for everything,"<input type='email' />","<input type='text' /> // for email",Medium
13
- 12,Forms,Never Block Paste,paste onpaste password,Web,Never prevent paste functionality,Allow paste on all inputs,Block paste on password/code,"<input type='password' />","<input onPaste={e => e.preventDefault()} />",High
14
- 13,Forms,Spellcheck Disable,spellcheck email code,Web,Disable spellcheck on emails and codes,Set spellcheck='false' on codes,Spellcheck on technical input,"<input spellCheck='false' type='email' />","<input type='email' /> // red squiggles",Low
15
- 14,Forms,Submit Button Enabled,submit button disabled loading,Web,Keep submit enabled and show spinner during requests,Show loading spinner keep enabled,Disable button during submit,"<button>{loading ? <Spinner /> : 'Submit'}</button>","<button disabled={loading}>Submit</button>",Medium
16
- 15,Forms,Inline Errors,error message inline focus,Web,Show error messages inline near the problem field,Inline error with focus on first error,Single error at top,"<input /><span class='text-red-500'>{error}</span>","<div class='error'>{allErrors}</div> // at top",High
17
- 16,Performance,Virtualize Lists,virtualize list 50 items,Web,Virtualize lists exceeding 50 items,Use virtual list for large datasets,Render all items,"<VirtualList items={items} />","items.map(item => <Item />)",High
18
- 17,Performance,Avoid Layout Reads,layout read render getboundingclientrect,Web,Avoid layout reads during render phase,Read layout in effects or callbacks,getBoundingClientRect in render,"useEffect(() => { el.getBoundingClientRect() })","const rect = el.getBoundingClientRect() // in render",Medium
19
- 18,Performance,Batch DOM Operations,batch dom write read,Web,Group DOM operations to minimize reflows,Batch writes then reads,Interleave reads and writes,"writes.forEach(w => w()); reads.forEach(r => r())","write(); read(); write(); read(); // thrashing",Medium
20
- 19,Performance,Preconnect CDN,preconnect link cdn,Web,Add preconnect links for CDN domains,Preconnect to known domains,"<link rel='preconnect' href='https://cdn.example.com' />","// no preconnect hint",Low
21
- 20,Performance,Lazy Load Images,lazy loading image below-fold,Web,Lazy-load images below the fold,Use loading='lazy' for below-fold images,Load all images eagerly,"<img loading='lazy' src='...' />","<img src='...' /> // above fold only",Medium
22
- 21,State,URL Reflects State,url state query params,Web,URL should reflect current UI state,Sync filters/tabs/pagination to URL,State only in memory,"?tab=settings&page=2","useState only // lost on refresh",High
23
- 22,State,Deep Linking,deep link stateful component,Web,Stateful components should support deep-linking,Enable sharing current view via URL,No shareable state,"router.push({ query: { ...filters } })","setFilters(f) // not in URL",Medium
24
- 23,State,Confirm Destructive Actions,confirm destructive delete modal,Web,Destructive actions require confirmation,Show confirmation dialog before delete,Delete without confirmation,"if (confirm('Delete?')) delete()","onClick={delete} // no confirmation",High
25
- 24,Typography,Proper Unicode,unicode ellipsis quotes,Web,Use proper Unicode characters,Use ... curly quotes proper dashes,ASCII approximations,"'Hello...' with proper ellipsis","'Hello...' with three dots",Low
26
- 25,Typography,Text Overflow,truncate line-clamp overflow,Web,Handle text overflow properly,Use truncate/line-clamp/break-words,Text overflows container,"<p class='truncate'>Long text...</p>","<p>Long text...</p> // overflows",Medium
27
- 26,Typography,Non-Breaking Spaces,nbsp unit brand,Web,Use non-breaking spaces for units and brand names,Use &nbsp; between number and unit,"10&nbsp;kg or Next.js&nbsp;14","10 kg // may wrap",Low
28
- 27,Anti-Pattern,No Zoom Disable,viewport zoom disable,Web,Never disable zoom in viewport meta,Allow user zoom,"<meta name='viewport' content='width=device-width'>","<meta name='viewport' content='maximum-scale=1'>",Critical
29
- 28,Anti-Pattern,No Transition All,transition all specific,Web,Avoid transition: all - specify properties,Transition specific properties,transition: all,"transition-colors duration-200","transition-all duration-200",Medium
30
- 29,Anti-Pattern,Outline Replacement,outline-none ring focus,Web,Never use outline-none without replacement,Provide visible focus replacement,Remove outline with nothing,"focus:outline-none focus:ring-2 focus:ring-blue-500","focus:outline-none // alone",Critical
31
- 30,Anti-Pattern,No Hardcoded Dates,date format intl locale,Web,Use Intl for date/number formatting,Use Intl.DateTimeFormat,Hardcoded date format,"new Intl.DateTimeFormat('en').format(date)","date.toLocaleDateString() // or manual format",Medium
1
+ No,Category,Issue,Keywords,Platform,Description,Do,Don't,Code Example Good,Code Example Bad,Severity
2
+ 1,Accessibility,Icon Button Labels,icon button aria-label,Web,Icon-only buttons must have accessible names,Add aria-label to icon buttons,Icon button without label,"<button aria-label='Close'><XIcon /></button>","<button><XIcon /></button>",Critical
3
+ 2,Accessibility,Form Control Labels,form input label aria,Web,All form controls need labels or aria-label,Use label element or aria-label,Input without accessible name,"<label for='email'>Email</label><input id='email' />","<input placeholder='Email' />",Critical
4
+ 3,Accessibility,Keyboard Handlers,keyboard onclick onkeydown,Web,Interactive elements must support keyboard interaction,Add onKeyDown alongside onClick,Click-only interaction,"<div onClick={fn} onKeyDown={fn} tabIndex={0}>","<div onClick={fn}>",High
5
+ 4,Accessibility,Semantic HTML,semantic button a label,Web,Use semantic HTML before ARIA attributes,Use button/a/label elements,Div with role attribute,"<button onClick={fn}>Submit</button>","<div role='button' onClick={fn}>Submit</div>",High
6
+ 5,Accessibility,Aria Live,aria-live polite async,Web,Async updates need aria-live for screen readers,Add aria-live='polite' for dynamic content,Silent async updates,"<div aria-live='polite'>{status}</div>","<div>{status}</div> // no announcement",Medium
7
+ 6,Accessibility,Decorative Icons,aria-hidden decorative icon,Web,Decorative icons should be hidden from screen readers,Add aria-hidden='true' to decorative icons,Decorative icon announced,"<Icon aria-hidden='true' />","<Icon /> // announced as 'image'",Medium
8
+ 7,Focus,Visible Focus States,focus-visible outline ring,Web,All interactive elements need visible focus states,Use :focus-visible with ring/outline,No focus indication,"focus-visible:ring-2 focus-visible:ring-blue-500","outline-none // no replacement",Critical
9
+ 8,Focus,Never Remove Outline,outline-none focus replacement,Web,Never remove outline without providing replacement,Replace outline with visible alternative,Remove outline completely,"focus:outline-none focus:ring-2","focus:outline-none // nothing else",Critical
10
+ 9,Focus,Checkbox Radio Hit Target,checkbox radio label target,Web,Checkbox/radio must share hit target with label,Wrap input and label together,Separate tiny checkbox,"<label class='flex gap-2'><input type='checkbox' /><span>Option</span></label>","<input type='checkbox' id='x' /><label for='x'>Option</label>",Medium
11
+ 10,Forms,Autocomplete Attribute,autocomplete input form,Web,Inputs need autocomplete attribute for autofill,Add appropriate autocomplete value,Missing autocomplete,"<input autocomplete='email' type='email' />","<input type='email' />",High
12
+ 11,Forms,Semantic Input Types,input type email tel url,Web,Use semantic input type attributes,Use email/tel/url/number types,text type for everything,"<input type='email' />","<input type='text' /> // for email",Medium
13
+ 12,Forms,Never Block Paste,paste onpaste password,Web,Never prevent paste functionality,Allow paste on all inputs,Block paste on password/code,"<input type='password' />","<input onPaste={e => e.preventDefault()} />",High
14
+ 13,Forms,Spellcheck Disable,spellcheck email code,Web,Disable spellcheck on emails and codes,Set spellcheck='false' on codes,Spellcheck on technical input,"<input spellCheck='false' type='email' />","<input type='email' /> // red squiggles",Low
15
+ 14,Forms,Submit Button Enabled,submit button disabled loading,Web,Keep submit enabled and show spinner during requests,Show loading spinner keep enabled,Disable button during submit,"<button>{loading ? <Spinner /> : 'Submit'}</button>","<button disabled={loading}>Submit</button>",Medium
16
+ 15,Forms,Inline Errors,error message inline focus,Web,Show error messages inline near the problem field,Inline error with focus on first error,Single error at top,"<input /><span class='text-red-500'>{error}</span>","<div class='error'>{allErrors}</div> // at top",High
17
+ 16,Performance,Virtualize Lists,virtualize list 50 items,Web,Virtualize lists exceeding 50 items,Use virtual list for large datasets,Render all items,"<VirtualList items={items} />","items.map(item => <Item />)",High
18
+ 17,Performance,Avoid Layout Reads,layout read render getboundingclientrect,Web,Avoid layout reads during render phase,Read layout in effects or callbacks,getBoundingClientRect in render,"useEffect(() => { el.getBoundingClientRect() })","const rect = el.getBoundingClientRect() // in render",Medium
19
+ 18,Performance,Batch DOM Operations,batch dom write read,Web,Group DOM operations to minimize reflows,Batch writes then reads,Interleave reads and writes,"writes.forEach(w => w()); reads.forEach(r => r())","write(); read(); write(); read(); // thrashing",Medium
20
+ 19,Performance,Preconnect CDN,preconnect link cdn,Web,Add preconnect links for CDN domains,Preconnect to known domains,"<link rel='preconnect' href='https://cdn.example.com' />","// no preconnect hint",Low
21
+ 20,Performance,Lazy Load Images,lazy loading image below-fold,Web,Lazy-load images below the fold,Use loading='lazy' for below-fold images,Load all images eagerly,"<img loading='lazy' src='...' />","<img src='...' /> // above fold only",Medium
22
+ 21,State,URL Reflects State,url state query params,Web,URL should reflect current UI state,Sync filters/tabs/pagination to URL,State only in memory,"?tab=settings&page=2","useState only // lost on refresh",High
23
+ 22,State,Deep Linking,deep link stateful component,Web,Stateful components should support deep-linking,Enable sharing current view via URL,No shareable state,"router.push({ query: { ...filters } })","setFilters(f) // not in URL",Medium
24
+ 23,State,Confirm Destructive Actions,confirm destructive delete modal,Web,Destructive actions require confirmation,Show confirmation dialog before delete,Delete without confirmation,"if (confirm('Delete?')) delete()","onClick={delete} // no confirmation",High
25
+ 24,Typography,Proper Unicode,unicode ellipsis quotes,Web,Use proper Unicode characters,Use ... curly quotes proper dashes,ASCII approximations,"'Hello...' with proper ellipsis","'Hello...' with three dots",Low
26
+ 25,Typography,Text Overflow,truncate line-clamp overflow,Web,Handle text overflow properly,Use truncate/line-clamp/break-words,Text overflows container,"<p class='truncate'>Long text...</p>","<p>Long text...</p> // overflows",Medium
27
+ 26,Typography,Non-Breaking Spaces,nbsp unit brand,Web,Use non-breaking spaces for units and brand names,Use &nbsp; between number and unit,"10&nbsp;kg or Next.js&nbsp;14","10 kg // may wrap",Low
28
+ 27,Anti-Pattern,No Zoom Disable,viewport zoom disable,Web,Never disable zoom in viewport meta,Allow user zoom,"<meta name='viewport' content='width=device-width'>","<meta name='viewport' content='maximum-scale=1'>",Critical
29
+ 28,Anti-Pattern,No Transition All,transition all specific,Web,Avoid transition: all - specify properties,Transition specific properties,transition: all,"transition-colors duration-200","transition-all duration-200",Medium
30
+ 29,Anti-Pattern,Outline Replacement,outline-none ring focus,Web,Never use outline-none without replacement,Provide visible focus replacement,Remove outline with nothing,"focus:outline-none focus:ring-2 focus:ring-blue-500","focus:outline-none // alone",Critical
31
+ 30,Anti-Pattern,No Hardcoded Dates,date format intl locale,Web,Use Intl for date/number formatting,Use Intl.DateTimeFormat,Hardcoded date format,"new Intl.DateTimeFormat('en').format(date)","date.toLocaleDateString() // or manual format",Medium
@@ -1,253 +1,253 @@
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", "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 (Hex)", "Secondary (Hex)", "CTA (Hex)", "Background (Hex)", "Text (Hex)", "Notes"]
27
- },
28
- "chart": {
29
- "file": "charts.csv",
30
- "search_cols": ["Data Type", "Keywords", "Best Chart Type", "Accessibility Notes"],
31
- "output_cols": ["Data Type", "Keywords", "Best Chart Type", "Secondary Options", "Color Guidance", "Accessibility Notes", "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": "web-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
- }
69
-
70
- STACK_CONFIG = {
71
- "html-tailwind": {"file": "stacks/html-tailwind.csv"},
72
- "react": {"file": "stacks/react.csv"},
73
- "nextjs": {"file": "stacks/nextjs.csv"},
74
- "astro": {"file": "stacks/astro.csv"},
75
- "vue": {"file": "stacks/vue.csv"},
76
- "nuxtjs": {"file": "stacks/nuxtjs.csv"},
77
- "nuxt-ui": {"file": "stacks/nuxt-ui.csv"},
78
- "svelte": {"file": "stacks/svelte.csv"},
79
- "swiftui": {"file": "stacks/swiftui.csv"},
80
- "react-native": {"file": "stacks/react-native.csv"},
81
- "flutter": {"file": "stacks/flutter.csv"},
82
- "shadcn": {"file": "stacks/shadcn.csv"},
83
- "jetpack-compose": {"file": "stacks/jetpack-compose.csv"}
84
- }
85
-
86
- # Common columns for all stacks
87
- _STACK_COLS = {
88
- "search_cols": ["Category", "Guideline", "Description", "Do", "Don't"],
89
- "output_cols": ["Category", "Guideline", "Description", "Do", "Don't", "Code Good", "Code Bad", "Severity", "Docs URL"]
90
- }
91
-
92
- AVAILABLE_STACKS = list(STACK_CONFIG.keys())
93
-
94
-
95
- # ============ BM25 IMPLEMENTATION ============
96
- class BM25:
97
- """BM25 ranking algorithm for text search"""
98
-
99
- def __init__(self, k1=1.5, b=0.75):
100
- self.k1 = k1
101
- self.b = b
102
- self.corpus = []
103
- self.doc_lengths = []
104
- self.avgdl = 0
105
- self.idf = {}
106
- self.doc_freqs = defaultdict(int)
107
- self.N = 0
108
-
109
- def tokenize(self, text):
110
- """Lowercase, split, remove punctuation, filter short words"""
111
- text = re.sub(r'[^\w\s]', ' ', str(text).lower())
112
- return [w for w in text.split() if len(w) > 2]
113
-
114
- def fit(self, documents):
115
- """Build BM25 index from documents"""
116
- self.corpus = [self.tokenize(doc) for doc in documents]
117
- self.N = len(self.corpus)
118
- if self.N == 0:
119
- return
120
- self.doc_lengths = [len(doc) for doc in self.corpus]
121
- self.avgdl = sum(self.doc_lengths) / self.N
122
-
123
- for doc in self.corpus:
124
- seen = set()
125
- for word in doc:
126
- if word not in seen:
127
- self.doc_freqs[word] += 1
128
- seen.add(word)
129
-
130
- for word, freq in self.doc_freqs.items():
131
- self.idf[word] = log((self.N - freq + 0.5) / (freq + 0.5) + 1)
132
-
133
- def score(self, query):
134
- """Score all documents against query"""
135
- query_tokens = self.tokenize(query)
136
- scores = []
137
-
138
- for idx, doc in enumerate(self.corpus):
139
- score = 0
140
- doc_len = self.doc_lengths[idx]
141
- term_freqs = defaultdict(int)
142
- for word in doc:
143
- term_freqs[word] += 1
144
-
145
- for token in query_tokens:
146
- if token in self.idf:
147
- tf = term_freqs[token]
148
- idf = self.idf[token]
149
- numerator = tf * (self.k1 + 1)
150
- denominator = tf + self.k1 * (1 - self.b + self.b * doc_len / self.avgdl)
151
- score += idf * numerator / denominator
152
-
153
- scores.append((idx, score))
154
-
155
- return sorted(scores, key=lambda x: x[1], reverse=True)
156
-
157
-
158
- # ============ SEARCH FUNCTIONS ============
159
- def _load_csv(filepath):
160
- """Load CSV and return list of dicts"""
161
- with open(filepath, 'r', encoding='utf-8') as f:
162
- return list(csv.DictReader(f))
163
-
164
-
165
- def _search_csv(filepath, search_cols, output_cols, query, max_results):
166
- """Core search function using BM25"""
167
- if not filepath.exists():
168
- return []
169
-
170
- data = _load_csv(filepath)
171
-
172
- # Build documents from search columns
173
- documents = [" ".join(str(row.get(col, "")) for col in search_cols) for row in data]
174
-
175
- # BM25 search
176
- bm25 = BM25()
177
- bm25.fit(documents)
178
- ranked = bm25.score(query)
179
-
180
- # Get top results with score > 0
181
- results = []
182
- for idx, score in ranked[:max_results]:
183
- if score > 0:
184
- row = data[idx]
185
- results.append({col: row.get(col, "") for col in output_cols if col in row})
186
-
187
- return results
188
-
189
-
190
- def detect_domain(query):
191
- """Auto-detect the most relevant domain from query"""
192
- query_lower = query.lower()
193
-
194
- domain_keywords = {
195
- "color": ["color", "palette", "hex", "#", "rgb"],
196
- "chart": ["chart", "graph", "visualization", "trend", "bar", "pie", "scatter", "heatmap", "funnel"],
197
- "landing": ["landing", "page", "cta", "conversion", "hero", "testimonial", "pricing", "section"],
198
- "product": ["saas", "ecommerce", "e-commerce", "fintech", "healthcare", "gaming", "portfolio", "crypto", "dashboard"],
199
- "style": ["style", "design", "ui", "minimalism", "glassmorphism", "neumorphism", "brutalism", "dark mode", "flat", "aurora", "prompt", "css", "implementation", "variable", "checklist", "tailwind"],
200
- "ux": ["ux", "usability", "accessibility", "wcag", "touch", "scroll", "animation", "keyboard", "navigation", "mobile"],
201
- "typography": ["font", "typography", "heading", "serif", "sans"],
202
- "icons": ["icon", "icons", "lucide", "heroicons", "symbol", "glyph", "pictogram", "svg icon"],
203
- "react": ["react", "next.js", "nextjs", "suspense", "memo", "usecallback", "useeffect", "rerender", "bundle", "waterfall", "barrel", "dynamic import", "rsc", "server component"],
204
- "web": ["aria", "focus", "outline", "semantic", "virtualize", "autocomplete", "form", "input type", "preconnect"]
205
- }
206
-
207
- scores = {domain: sum(1 for kw in keywords if kw in query_lower) for domain, keywords in domain_keywords.items()}
208
- best = max(scores, key=scores.get)
209
- return best if scores[best] > 0 else "style"
210
-
211
-
212
- def search(query, domain=None, max_results=MAX_RESULTS):
213
- """Main search function with auto-domain detection"""
214
- if domain is None:
215
- domain = detect_domain(query)
216
-
217
- config = CSV_CONFIG.get(domain, CSV_CONFIG["style"])
218
- filepath = DATA_DIR / config["file"]
219
-
220
- if not filepath.exists():
221
- return {"error": f"File not found: {filepath}", "domain": domain}
222
-
223
- results = _search_csv(filepath, config["search_cols"], config["output_cols"], query, max_results)
224
-
225
- return {
226
- "domain": domain,
227
- "query": query,
228
- "file": config["file"],
229
- "count": len(results),
230
- "results": results
231
- }
232
-
233
-
234
- def search_stack(query, stack, max_results=MAX_RESULTS):
235
- """Search stack-specific guidelines"""
236
- if stack not in STACK_CONFIG:
237
- return {"error": f"Unknown stack: {stack}. Available: {', '.join(AVAILABLE_STACKS)}"}
238
-
239
- filepath = DATA_DIR / STACK_CONFIG[stack]["file"]
240
-
241
- if not filepath.exists():
242
- return {"error": f"Stack file not found: {filepath}", "stack": stack}
243
-
244
- results = _search_csv(filepath, _STACK_COLS["search_cols"], _STACK_COLS["output_cols"], query, max_results)
245
-
246
- return {
247
- "domain": "stack",
248
- "stack": stack,
249
- "query": query,
250
- "file": STACK_CONFIG[stack]["file"],
251
- "count": len(results),
252
- "results": results
253
- }
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", "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 (Hex)", "Secondary (Hex)", "CTA (Hex)", "Background (Hex)", "Text (Hex)", "Notes"]
27
+ },
28
+ "chart": {
29
+ "file": "charts.csv",
30
+ "search_cols": ["Data Type", "Keywords", "Best Chart Type", "Accessibility Notes"],
31
+ "output_cols": ["Data Type", "Keywords", "Best Chart Type", "Secondary Options", "Color Guidance", "Accessibility Notes", "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": "web-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
+ }
69
+
70
+ STACK_CONFIG = {
71
+ "html-tailwind": {"file": "stacks/html-tailwind.csv"},
72
+ "react": {"file": "stacks/react.csv"},
73
+ "nextjs": {"file": "stacks/nextjs.csv"},
74
+ "astro": {"file": "stacks/astro.csv"},
75
+ "vue": {"file": "stacks/vue.csv"},
76
+ "nuxtjs": {"file": "stacks/nuxtjs.csv"},
77
+ "nuxt-ui": {"file": "stacks/nuxt-ui.csv"},
78
+ "svelte": {"file": "stacks/svelte.csv"},
79
+ "swiftui": {"file": "stacks/swiftui.csv"},
80
+ "react-native": {"file": "stacks/react-native.csv"},
81
+ "flutter": {"file": "stacks/flutter.csv"},
82
+ "shadcn": {"file": "stacks/shadcn.csv"},
83
+ "jetpack-compose": {"file": "stacks/jetpack-compose.csv"}
84
+ }
85
+
86
+ # Common columns for all stacks
87
+ _STACK_COLS = {
88
+ "search_cols": ["Category", "Guideline", "Description", "Do", "Don't"],
89
+ "output_cols": ["Category", "Guideline", "Description", "Do", "Don't", "Code Good", "Code Bad", "Severity", "Docs URL"]
90
+ }
91
+
92
+ AVAILABLE_STACKS = list(STACK_CONFIG.keys())
93
+
94
+
95
+ # ============ BM25 IMPLEMENTATION ============
96
+ class BM25:
97
+ """BM25 ranking algorithm for text search"""
98
+
99
+ def __init__(self, k1=1.5, b=0.75):
100
+ self.k1 = k1
101
+ self.b = b
102
+ self.corpus = []
103
+ self.doc_lengths = []
104
+ self.avgdl = 0
105
+ self.idf = {}
106
+ self.doc_freqs = defaultdict(int)
107
+ self.N = 0
108
+
109
+ def tokenize(self, text):
110
+ """Lowercase, split, remove punctuation, filter short words"""
111
+ text = re.sub(r'[^\w\s]', ' ', str(text).lower())
112
+ return [w for w in text.split() if len(w) > 2]
113
+
114
+ def fit(self, documents):
115
+ """Build BM25 index from documents"""
116
+ self.corpus = [self.tokenize(doc) for doc in documents]
117
+ self.N = len(self.corpus)
118
+ if self.N == 0:
119
+ return
120
+ self.doc_lengths = [len(doc) for doc in self.corpus]
121
+ self.avgdl = sum(self.doc_lengths) / self.N
122
+
123
+ for doc in self.corpus:
124
+ seen = set()
125
+ for word in doc:
126
+ if word not in seen:
127
+ self.doc_freqs[word] += 1
128
+ seen.add(word)
129
+
130
+ for word, freq in self.doc_freqs.items():
131
+ self.idf[word] = log((self.N - freq + 0.5) / (freq + 0.5) + 1)
132
+
133
+ def score(self, query):
134
+ """Score all documents against query"""
135
+ query_tokens = self.tokenize(query)
136
+ scores = []
137
+
138
+ for idx, doc in enumerate(self.corpus):
139
+ score = 0
140
+ doc_len = self.doc_lengths[idx]
141
+ term_freqs = defaultdict(int)
142
+ for word in doc:
143
+ term_freqs[word] += 1
144
+
145
+ for token in query_tokens:
146
+ if token in self.idf:
147
+ tf = term_freqs[token]
148
+ idf = self.idf[token]
149
+ numerator = tf * (self.k1 + 1)
150
+ denominator = tf + self.k1 * (1 - self.b + self.b * doc_len / self.avgdl)
151
+ score += idf * numerator / denominator
152
+
153
+ scores.append((idx, score))
154
+
155
+ return sorted(scores, key=lambda x: x[1], reverse=True)
156
+
157
+
158
+ # ============ SEARCH FUNCTIONS ============
159
+ def _load_csv(filepath):
160
+ """Load CSV and return list of dicts"""
161
+ with open(filepath, 'r', encoding='utf-8') as f:
162
+ return list(csv.DictReader(f))
163
+
164
+
165
+ def _search_csv(filepath, search_cols, output_cols, query, max_results):
166
+ """Core search function using BM25"""
167
+ if not filepath.exists():
168
+ return []
169
+
170
+ data = _load_csv(filepath)
171
+
172
+ # Build documents from search columns
173
+ documents = [" ".join(str(row.get(col, "")) for col in search_cols) for row in data]
174
+
175
+ # BM25 search
176
+ bm25 = BM25()
177
+ bm25.fit(documents)
178
+ ranked = bm25.score(query)
179
+
180
+ # Get top results with score > 0
181
+ results = []
182
+ for idx, score in ranked[:max_results]:
183
+ if score > 0:
184
+ row = data[idx]
185
+ results.append({col: row.get(col, "") for col in output_cols if col in row})
186
+
187
+ return results
188
+
189
+
190
+ def detect_domain(query):
191
+ """Auto-detect the most relevant domain from query"""
192
+ query_lower = query.lower()
193
+
194
+ domain_keywords = {
195
+ "color": ["color", "palette", "hex", "#", "rgb"],
196
+ "chart": ["chart", "graph", "visualization", "trend", "bar", "pie", "scatter", "heatmap", "funnel"],
197
+ "landing": ["landing", "page", "cta", "conversion", "hero", "testimonial", "pricing", "section"],
198
+ "product": ["saas", "ecommerce", "e-commerce", "fintech", "healthcare", "gaming", "portfolio", "crypto", "dashboard"],
199
+ "style": ["style", "design", "ui", "minimalism", "glassmorphism", "neumorphism", "brutalism", "dark mode", "flat", "aurora", "prompt", "css", "implementation", "variable", "checklist", "tailwind"],
200
+ "ux": ["ux", "usability", "accessibility", "wcag", "touch", "scroll", "animation", "keyboard", "navigation", "mobile"],
201
+ "typography": ["font", "typography", "heading", "serif", "sans"],
202
+ "icons": ["icon", "icons", "lucide", "heroicons", "symbol", "glyph", "pictogram", "svg icon"],
203
+ "react": ["react", "next.js", "nextjs", "suspense", "memo", "usecallback", "useeffect", "rerender", "bundle", "waterfall", "barrel", "dynamic import", "rsc", "server component"],
204
+ "web": ["aria", "focus", "outline", "semantic", "virtualize", "autocomplete", "form", "input type", "preconnect"]
205
+ }
206
+
207
+ scores = {domain: sum(1 for kw in keywords if kw in query_lower) for domain, keywords in domain_keywords.items()}
208
+ best = max(scores, key=scores.get)
209
+ return best if scores[best] > 0 else "style"
210
+
211
+
212
+ def search(query, domain=None, max_results=MAX_RESULTS):
213
+ """Main search function with auto-domain detection"""
214
+ if domain is None:
215
+ domain = detect_domain(query)
216
+
217
+ config = CSV_CONFIG.get(domain, CSV_CONFIG["style"])
218
+ filepath = DATA_DIR / config["file"]
219
+
220
+ if not filepath.exists():
221
+ return {"error": f"File not found: {filepath}", "domain": domain}
222
+
223
+ results = _search_csv(filepath, config["search_cols"], config["output_cols"], query, max_results)
224
+
225
+ return {
226
+ "domain": domain,
227
+ "query": query,
228
+ "file": config["file"],
229
+ "count": len(results),
230
+ "results": results
231
+ }
232
+
233
+
234
+ def search_stack(query, stack, max_results=MAX_RESULTS):
235
+ """Search stack-specific guidelines"""
236
+ if stack not in STACK_CONFIG:
237
+ return {"error": f"Unknown stack: {stack}. Available: {', '.join(AVAILABLE_STACKS)}"}
238
+
239
+ filepath = DATA_DIR / STACK_CONFIG[stack]["file"]
240
+
241
+ if not filepath.exists():
242
+ return {"error": f"Stack file not found: {filepath}", "stack": stack}
243
+
244
+ results = _search_csv(filepath, _STACK_COLS["search_cols"], _STACK_COLS["output_cols"], query, max_results)
245
+
246
+ return {
247
+ "domain": "stack",
248
+ "stack": stack,
249
+ "query": query,
250
+ "file": STACK_CONFIG[stack]["file"],
251
+ "count": len(results),
252
+ "results": results
253
+ }