opencode-agent-kit 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (361) hide show
  1. package/README.md +796 -0
  2. package/bin/commands/init.mjs +221 -0
  3. package/bin/init.mjs +21 -0
  4. package/package.json +22 -0
  5. package/template/.opencode/agent-docs/backend/README.md +0 -0
  6. package/template/.opencode/agent-docs/backend/node/BACKEND_PATTERNS.md +82 -0
  7. package/template/.opencode/agent-docs/backend/node/BACKEND_QUICK_START.md +49 -0
  8. package/template/.opencode/agent-docs/frontend/next/README.md +0 -0
  9. package/template/.opencode/agent-docs/frontend/nuxt/API_PATTERNS.md +807 -0
  10. package/template/.opencode/agent-docs/frontend/nuxt/CHEATSHEET.md +676 -0
  11. package/template/.opencode/agent-docs/frontend/nuxt/COMPLETION_REPORT.md +613 -0
  12. package/template/.opencode/agent-docs/frontend/nuxt/EXAMPLES.md +956 -0
  13. package/template/.opencode/agent-docs/frontend/nuxt/INDEX.md +596 -0
  14. package/template/.opencode/agent-docs/frontend/nuxt/MCP_GUIDE.md +881 -0
  15. package/template/.opencode/agent-docs/frontend/nuxt/MENTOR_CURRICULUM_30_DAYS.md +256 -0
  16. package/template/.opencode/agent-docs/frontend/nuxt/MENTOR_CURRICULUM_CHECKLIST.md +156 -0
  17. package/template/.opencode/agent-docs/frontend/nuxt/MENTOR_WEEKLY_ASSIGNMENTS.md +191 -0
  18. package/template/.opencode/agent-docs/frontend/nuxt/QUICK_START.md +509 -0
  19. package/template/.opencode/agent-docs/frontend/nuxt/README.md +506 -0
  20. package/template/.opencode/agent-docs/frontend/nuxt/README_AGENTS.md +140 -0
  21. package/template/.opencode/agent-docs/frontend/nuxt/README_DOCS.md +65 -0
  22. package/template/.opencode/agent-docs/frontend/nuxt/SUMMARY.md +474 -0
  23. package/template/.opencode/agent-docs/frontend/nuxt/TEAM_OPERATING_GUIDE.md +54 -0
  24. package/template/.opencode/agent-docs/frontend/nuxt/TESTING_GUIDE.md +904 -0
  25. package/template/.opencode/agent-docs/frontend/nuxt/WORKFLOWS.md +758 -0
  26. package/template/.opencode/agent-docs/frontend/react/API_PATTERNS.md +187 -0
  27. package/template/.opencode/agent-docs/frontend/react/CHEATSHEET.md +87 -0
  28. package/template/.opencode/agent-docs/frontend/react/INDEX.md +45 -0
  29. package/template/.opencode/agent-docs/frontend/react/QUICK_START.md +43 -0
  30. package/template/.opencode/agent-docs/frontend/react/README.md +159 -0
  31. package/template/.opencode/agent-docs/frontend/vue/README.md +0 -0
  32. package/template/.opencode/agent-docs/mobile/android/README.md +45 -0
  33. package/template/.opencode/agent-docs/mobile/flutter/README.md +44 -0
  34. package/template/.opencode/agents/android-developer.md +418 -0
  35. package/template/.opencode/agents/code-igniter-3-fullstack.md +345 -0
  36. package/template/.opencode/agents/code-reviewer.md +517 -0
  37. package/template/.opencode/agents/database-specialist.md +455 -0
  38. package/template/.opencode/agents/devops-specialist.md +562 -0
  39. package/template/.opencode/agents/flutter-developer.md +556 -0
  40. package/template/.opencode/agents/it-leader.md +911 -0
  41. package/template/.opencode/agents/laravel-advanced.md +691 -0
  42. package/template/.opencode/agents/node-backend-developer.md +343 -0
  43. package/template/.opencode/agents/nuxt-frontend-developer-mentor.md +402 -0
  44. package/template/.opencode/agents/nuxt-frontend-developer.md +1573 -0
  45. package/template/.opencode/agents/react-frontend-developer.md +1017 -0
  46. package/template/.opencode/agents/seo-specialist.md +681 -0
  47. package/template/.opencode/agents/ui-ux-designer.md +783 -0
  48. package/template/.opencode/commands/android-build/command.md +25 -0
  49. package/template/.opencode/commands/android-test/command.md +23 -0
  50. package/template/.opencode/commands/build-fix.md +29 -0
  51. package/template/.opencode/commands/checkpoint.md +74 -0
  52. package/template/.opencode/commands/code-review.md +40 -0
  53. package/template/.opencode/commands/e2e.md +363 -0
  54. package/template/.opencode/commands/eval.md +120 -0
  55. package/template/.opencode/commands/evolve.md +193 -0
  56. package/template/.opencode/commands/flutter-build/command.md +25 -0
  57. package/template/.opencode/commands/flutter-test/command.md +24 -0
  58. package/template/.opencode/commands/go-build.md +183 -0
  59. package/template/.opencode/commands/go-review.md +148 -0
  60. package/template/.opencode/commands/go-test.md +268 -0
  61. package/template/.opencode/commands/gpc-release/command.md +30 -0
  62. package/template/.opencode/commands/instinct-export.md +91 -0
  63. package/template/.opencode/commands/instinct-import.md +142 -0
  64. package/template/.opencode/commands/instinct-status.md +86 -0
  65. package/template/.opencode/commands/learn.md +70 -0
  66. package/template/.opencode/commands/multi-backend.md +158 -0
  67. package/template/.opencode/commands/multi-execute.md +310 -0
  68. package/template/.opencode/commands/multi-frontend.md +158 -0
  69. package/template/.opencode/commands/multi-plan.md +261 -0
  70. package/template/.opencode/commands/multi-workflow.md +183 -0
  71. package/template/.opencode/commands/orchestrate.md +172 -0
  72. package/template/.opencode/commands/plan.md +113 -0
  73. package/template/.opencode/commands/pm2.md +271 -0
  74. package/template/.opencode/commands/python-review.md +297 -0
  75. package/template/.opencode/commands/refactor-clean.md +28 -0
  76. package/template/.opencode/commands/sessions.md +305 -0
  77. package/template/.opencode/commands/setup-pm.md +80 -0
  78. package/template/.opencode/commands/skill-create.md +174 -0
  79. package/template/.opencode/commands/tdd.md +326 -0
  80. package/template/.opencode/commands/test-coverage.md +27 -0
  81. package/template/.opencode/commands/update-codemaps.md +17 -0
  82. package/template/.opencode/commands/update-docs.md +31 -0
  83. package/template/.opencode/commands/verify.md +59 -0
  84. package/template/.opencode/config.example.json +309 -0
  85. package/template/.opencode/config.json +341 -0
  86. package/template/.opencode/contexts/dev.md +20 -0
  87. package/template/.opencode/contexts/research.md +26 -0
  88. package/template/.opencode/contexts/review.md +22 -0
  89. package/template/.opencode/hooks/hooks.json +169 -0
  90. package/template/.opencode/instructions/INSTRUCTIONS.md +388 -0
  91. package/template/.opencode/package.json +5 -0
  92. package/template/.opencode/rules/README.md +82 -0
  93. package/template/.opencode/rules/android/gradle.md +62 -0
  94. package/template/.opencode/rules/android/testing.md +27 -0
  95. package/template/.opencode/rules/common/agents.md +49 -0
  96. package/template/.opencode/rules/common/coding-style.md +48 -0
  97. package/template/.opencode/rules/common/git-workflow.md +45 -0
  98. package/template/.opencode/rules/common/hooks.md +30 -0
  99. package/template/.opencode/rules/common/patterns.md +31 -0
  100. package/template/.opencode/rules/common/performance.md +55 -0
  101. package/template/.opencode/rules/common/security.md +29 -0
  102. package/template/.opencode/rules/common/testing.md +29 -0
  103. package/template/.opencode/rules/flutter/state-management.md +57 -0
  104. package/template/.opencode/rules/flutter/testing.md +42 -0
  105. package/template/.opencode/rules/golang/coding-style.md +26 -0
  106. package/template/.opencode/rules/golang/hooks.md +11 -0
  107. package/template/.opencode/rules/golang/patterns.md +39 -0
  108. package/template/.opencode/rules/golang/security.md +28 -0
  109. package/template/.opencode/rules/golang/testing.md +25 -0
  110. package/template/.opencode/rules/mobile/performance.md +36 -0
  111. package/template/.opencode/rules/python/coding-style.md +37 -0
  112. package/template/.opencode/rules/python/hooks.md +14 -0
  113. package/template/.opencode/rules/python/patterns.md +34 -0
  114. package/template/.opencode/rules/python/security.md +25 -0
  115. package/template/.opencode/rules/python/testing.md +33 -0
  116. package/template/.opencode/rules/typescript/coding-style.md +58 -0
  117. package/template/.opencode/rules/typescript/hooks.md +15 -0
  118. package/template/.opencode/rules/typescript/patterns.md +45 -0
  119. package/template/.opencode/rules/typescript/security.md +21 -0
  120. package/template/.opencode/rules/typescript/testing.md +11 -0
  121. package/template/.opencode/skills/api-documentation/SKILL.md +188 -0
  122. package/template/.opencode/skills/backend-patterns/SKILL.md +587 -0
  123. package/template/.opencode/skills/building-components/SKILL.md +37 -0
  124. package/template/.opencode/skills/building-components/references/accessibility.mdx +819 -0
  125. package/template/.opencode/skills/building-components/references/as-child.mdx +324 -0
  126. package/template/.opencode/skills/building-components/references/composition.mdx +239 -0
  127. package/template/.opencode/skills/building-components/references/data-attributes.mdx +413 -0
  128. package/template/.opencode/skills/building-components/references/definitions.mdx +258 -0
  129. package/template/.opencode/skills/building-components/references/design-tokens.mdx +57 -0
  130. package/template/.opencode/skills/building-components/references/docs.mdx +155 -0
  131. package/template/.opencode/skills/building-components/references/marketplaces.mdx +144 -0
  132. package/template/.opencode/skills/building-components/references/npm.mdx +166 -0
  133. package/template/.opencode/skills/building-components/references/polymorphism.mdx +583 -0
  134. package/template/.opencode/skills/building-components/references/principles.mdx +61 -0
  135. package/template/.opencode/skills/building-components/references/registry.mdx +169 -0
  136. package/template/.opencode/skills/building-components/references/state.mdx +99 -0
  137. package/template/.opencode/skills/building-components/references/styling.mdx +286 -0
  138. package/template/.opencode/skills/building-components/references/types.mdx +191 -0
  139. package/template/.opencode/skills/clickhouse-io/SKILL.md +429 -0
  140. package/template/.opencode/skills/coding-standards/SKILL.md +520 -0
  141. package/template/.opencode/skills/configure-ecc/SKILL.md +298 -0
  142. package/template/.opencode/skills/continuous-learning/SKILL.md +110 -0
  143. package/template/.opencode/skills/continuous-learning/config.json +18 -0
  144. package/template/.opencode/skills/continuous-learning/evaluate-session.sh +60 -0
  145. package/template/.opencode/skills/continuous-learning-v2/SKILL.md +284 -0
  146. package/template/.opencode/skills/continuous-learning-v2/agents/observer.md +137 -0
  147. package/template/.opencode/skills/continuous-learning-v2/agents/start-observer.sh +134 -0
  148. package/template/.opencode/skills/continuous-learning-v2/config.json +41 -0
  149. package/template/.opencode/skills/continuous-learning-v2/hooks/observe.sh +153 -0
  150. package/template/.opencode/skills/continuous-learning-v2/scripts/instinct-cli.py +489 -0
  151. package/template/.opencode/skills/continuous-learning-v2/scripts/test_parse_instinct.py +82 -0
  152. package/template/.opencode/skills/dart-add-unit-test/SKILL.md +122 -0
  153. package/template/.opencode/skills/dart-build-cli-app/SKILL.md +185 -0
  154. package/template/.opencode/skills/dart-collect-coverage/SKILL.md +141 -0
  155. package/template/.opencode/skills/dart-fix-runtime-errors/SKILL.md +166 -0
  156. package/template/.opencode/skills/dart-generate-test-mocks/SKILL.md +155 -0
  157. package/template/.opencode/skills/dart-migrate-to-checks-package/SKILL.md +126 -0
  158. package/template/.opencode/skills/dart-resolve-package-conflicts/SKILL.md +116 -0
  159. package/template/.opencode/skills/dart-run-static-analysis/SKILL.md +104 -0
  160. package/template/.opencode/skills/dart-use-pattern-matching/SKILL.md +146 -0
  161. package/template/.opencode/skills/django-patterns/SKILL.md +733 -0
  162. package/template/.opencode/skills/django-security/SKILL.md +592 -0
  163. package/template/.opencode/skills/django-tdd/SKILL.md +728 -0
  164. package/template/.opencode/skills/django-verification/SKILL.md +460 -0
  165. package/template/.opencode/skills/eval-harness/SKILL.md +227 -0
  166. package/template/.opencode/skills/firebase-basics/SKILL.md +103 -0
  167. package/template/.opencode/skills/firebase-basics/references/additional-skills.md +113 -0
  168. package/template/.opencode/skills/firebase-basics/references/cli-usage.md +31 -0
  169. package/template/.opencode/skills/firebase-basics/references/client-library-usage.md +45 -0
  170. package/template/.opencode/skills/firebase-basics/references/core-concepts.md +61 -0
  171. package/template/.opencode/skills/firebase-basics/references/iac-usage.md +40 -0
  172. package/template/.opencode/skills/firebase-basics/references/iam-security.md +74 -0
  173. package/template/.opencode/skills/firebase-basics/references/mcp-usage.md +63 -0
  174. package/template/.opencode/skills/flutter/SKILL.md +292 -0
  175. package/template/.opencode/skills/flutter-add-integration-test/SKILL.md +163 -0
  176. package/template/.opencode/skills/flutter-add-widget-preview/SKILL.md +145 -0
  177. package/template/.opencode/skills/flutter-add-widget-test/SKILL.md +154 -0
  178. package/template/.opencode/skills/flutter-apply-architecture-best-practices/SKILL.md +162 -0
  179. package/template/.opencode/skills/flutter-build-responsive-layout/SKILL.md +139 -0
  180. package/template/.opencode/skills/flutter-fix-layout-issues/SKILL.md +130 -0
  181. package/template/.opencode/skills/flutter-implement-json-serialization/SKILL.md +153 -0
  182. package/template/.opencode/skills/flutter-setup-declarative-routing/SKILL.md +255 -0
  183. package/template/.opencode/skills/flutter-setup-localization/SKILL.md +210 -0
  184. package/template/.opencode/skills/flutter-use-http-package/SKILL.md +174 -0
  185. package/template/.opencode/skills/frontend-design/SKILL.md +89 -0
  186. package/template/.opencode/skills/frontend-patterns/SKILL.md +631 -0
  187. package/template/.opencode/skills/golang-patterns/SKILL.md +673 -0
  188. package/template/.opencode/skills/golang-testing/SKILL.md +719 -0
  189. package/template/.opencode/skills/impeccable/SKILL.md +165 -0
  190. package/template/.opencode/skills/impeccable/agents/impeccable-asset-producer.md +101 -0
  191. package/template/.opencode/skills/impeccable/reference/adapt.md +190 -0
  192. package/template/.opencode/skills/impeccable/reference/animate.md +175 -0
  193. package/template/.opencode/skills/impeccable/reference/audit.md +133 -0
  194. package/template/.opencode/skills/impeccable/reference/bolder.md +113 -0
  195. package/template/.opencode/skills/impeccable/reference/brand.md +118 -0
  196. package/template/.opencode/skills/impeccable/reference/clarify.md +174 -0
  197. package/template/.opencode/skills/impeccable/reference/codex.md +105 -0
  198. package/template/.opencode/skills/impeccable/reference/cognitive-load.md +106 -0
  199. package/template/.opencode/skills/impeccable/reference/color-and-contrast.md +105 -0
  200. package/template/.opencode/skills/impeccable/reference/colorize.md +154 -0
  201. package/template/.opencode/skills/impeccable/reference/craft.md +123 -0
  202. package/template/.opencode/skills/impeccable/reference/critique.md +273 -0
  203. package/template/.opencode/skills/impeccable/reference/delight.md +302 -0
  204. package/template/.opencode/skills/impeccable/reference/distill.md +111 -0
  205. package/template/.opencode/skills/impeccable/reference/document.md +427 -0
  206. package/template/.opencode/skills/impeccable/reference/extract.md +69 -0
  207. package/template/.opencode/skills/impeccable/reference/harden.md +347 -0
  208. package/template/.opencode/skills/impeccable/reference/heuristics-scoring.md +234 -0
  209. package/template/.opencode/skills/impeccable/reference/interaction-design.md +195 -0
  210. package/template/.opencode/skills/impeccable/reference/layout.md +141 -0
  211. package/template/.opencode/skills/impeccable/reference/live.md +622 -0
  212. package/template/.opencode/skills/impeccable/reference/motion-design.md +109 -0
  213. package/template/.opencode/skills/impeccable/reference/onboard.md +234 -0
  214. package/template/.opencode/skills/impeccable/reference/optimize.md +258 -0
  215. package/template/.opencode/skills/impeccable/reference/overdrive.md +130 -0
  216. package/template/.opencode/skills/impeccable/reference/personas.md +179 -0
  217. package/template/.opencode/skills/impeccable/reference/polish.md +242 -0
  218. package/template/.opencode/skills/impeccable/reference/product.md +62 -0
  219. package/template/.opencode/skills/impeccable/reference/quieter.md +99 -0
  220. package/template/.opencode/skills/impeccable/reference/responsive-design.md +114 -0
  221. package/template/.opencode/skills/impeccable/reference/shape.md +165 -0
  222. package/template/.opencode/skills/impeccable/reference/spatial-design.md +100 -0
  223. package/template/.opencode/skills/impeccable/reference/teach.md +156 -0
  224. package/template/.opencode/skills/impeccable/reference/typeset.md +124 -0
  225. package/template/.opencode/skills/impeccable/reference/typography.md +159 -0
  226. package/template/.opencode/skills/impeccable/reference/ux-writing.md +107 -0
  227. package/template/.opencode/skills/impeccable/scripts/cleanup-deprecated.mjs +284 -0
  228. package/template/.opencode/skills/impeccable/scripts/command-metadata.json +94 -0
  229. package/template/.opencode/skills/impeccable/scripts/critique-storage.mjs +242 -0
  230. package/template/.opencode/skills/impeccable/scripts/design-parser.mjs +820 -0
  231. package/template/.opencode/skills/impeccable/scripts/detect-csp.mjs +198 -0
  232. package/template/.opencode/skills/impeccable/scripts/detect.mjs +21 -0
  233. package/template/.opencode/skills/impeccable/scripts/impeccable-paths.mjs +110 -0
  234. package/template/.opencode/skills/impeccable/scripts/is-generated.mjs +69 -0
  235. package/template/.opencode/skills/impeccable/scripts/live-accept.mjs +595 -0
  236. package/template/.opencode/skills/impeccable/scripts/live-browser-session.js +123 -0
  237. package/template/.opencode/skills/impeccable/scripts/live-browser.js +4860 -0
  238. package/template/.opencode/skills/impeccable/scripts/live-complete.mjs +75 -0
  239. package/template/.opencode/skills/impeccable/scripts/live-completion.mjs +18 -0
  240. package/template/.opencode/skills/impeccable/scripts/live-inject.mjs +446 -0
  241. package/template/.opencode/skills/impeccable/scripts/live-poll.mjs +200 -0
  242. package/template/.opencode/skills/impeccable/scripts/live-resume.mjs +48 -0
  243. package/template/.opencode/skills/impeccable/scripts/live-server.mjs +838 -0
  244. package/template/.opencode/skills/impeccable/scripts/live-session-store.mjs +254 -0
  245. package/template/.opencode/skills/impeccable/scripts/live-status.mjs +47 -0
  246. package/template/.opencode/skills/impeccable/scripts/live-wrap.mjs +632 -0
  247. package/template/.opencode/skills/impeccable/scripts/live.mjs +247 -0
  248. package/template/.opencode/skills/impeccable/scripts/load-context.mjs +141 -0
  249. package/template/.opencode/skills/impeccable/scripts/modern-screenshot.umd.js +14 -0
  250. package/template/.opencode/skills/impeccable/scripts/pin.mjs +214 -0
  251. package/template/.opencode/skills/iterative-retrieval/SKILL.md +202 -0
  252. package/template/.opencode/skills/java-coding-standards/SKILL.md +138 -0
  253. package/template/.opencode/skills/jetpack-compose/.skillfish.json +10 -0
  254. package/template/.opencode/skills/jetpack-compose/SKILL.md +420 -0
  255. package/template/.opencode/skills/jpa-patterns/SKILL.md +141 -0
  256. package/template/.opencode/skills/nutrient-document-processing/SKILL.md +165 -0
  257. package/template/.opencode/skills/nuxt-ui/SKILL.md +334 -0
  258. package/template/.opencode/skills/nuxt-ui/references/components.md +377 -0
  259. package/template/.opencode/skills/nuxt-ui/references/composables.md +127 -0
  260. package/template/.opencode/skills/nuxt-ui/references/layouts/chat.md +266 -0
  261. package/template/.opencode/skills/nuxt-ui/references/layouts/dashboard.md +220 -0
  262. package/template/.opencode/skills/nuxt-ui/references/layouts/docs.md +141 -0
  263. package/template/.opencode/skills/nuxt-ui/references/layouts/editor.md +168 -0
  264. package/template/.opencode/skills/nuxt-ui/references/layouts/page.md +260 -0
  265. package/template/.opencode/skills/nuxt-ui/references/theming.md +427 -0
  266. package/template/.opencode/skills/postgres-patterns/SKILL.md +146 -0
  267. package/template/.opencode/skills/project-guidelines-example/SKILL.md +345 -0
  268. package/template/.opencode/skills/python-patterns/SKILL.md +749 -0
  269. package/template/.opencode/skills/python-testing/SKILL.md +815 -0
  270. package/template/.opencode/skills/security-review/SKILL.md +494 -0
  271. package/template/.opencode/skills/security-review/cloud-infrastructure-security.md +361 -0
  272. package/template/.opencode/skills/shadcn-ui/README.md +248 -0
  273. package/template/.opencode/skills/shadcn-ui/SKILL.md +326 -0
  274. package/template/.opencode/skills/shadcn-ui/examples/auth-layout.tsx +177 -0
  275. package/template/.opencode/skills/shadcn-ui/examples/data-table.tsx +313 -0
  276. package/template/.opencode/skills/shadcn-ui/examples/form-pattern.tsx +177 -0
  277. package/template/.opencode/skills/shadcn-ui/resources/component-catalog.md +481 -0
  278. package/template/.opencode/skills/shadcn-ui/resources/customization-guide.md +516 -0
  279. package/template/.opencode/skills/shadcn-ui/resources/migration-guide.md +463 -0
  280. package/template/.opencode/skills/shadcn-ui/resources/setup-guide.md +412 -0
  281. package/template/.opencode/skills/shadcn-ui/scripts/verify-setup.sh +134 -0
  282. package/template/.opencode/skills/springboot-patterns/SKILL.md +304 -0
  283. package/template/.opencode/skills/springboot-security/SKILL.md +119 -0
  284. package/template/.opencode/skills/springboot-tdd/SKILL.md +157 -0
  285. package/template/.opencode/skills/springboot-verification/SKILL.md +100 -0
  286. package/template/.opencode/skills/strategic-compact/SKILL.md +63 -0
  287. package/template/.opencode/skills/strategic-compact/suggest-compact.sh +52 -0
  288. package/template/.opencode/skills/tdd-workflow/SKILL.md +409 -0
  289. package/template/.opencode/skills/vercel-composition-patterns/AGENTS.md +946 -0
  290. package/template/.opencode/skills/vercel-composition-patterns/SKILL.md +89 -0
  291. package/template/.opencode/skills/vercel-composition-patterns/rules/architecture-avoid-boolean-props.md +100 -0
  292. package/template/.opencode/skills/vercel-composition-patterns/rules/architecture-compound-components.md +112 -0
  293. package/template/.opencode/skills/vercel-composition-patterns/rules/patterns-children-over-render-props.md +87 -0
  294. package/template/.opencode/skills/vercel-composition-patterns/rules/patterns-explicit-variants.md +100 -0
  295. package/template/.opencode/skills/vercel-composition-patterns/rules/react19-no-forwardref.md +42 -0
  296. package/template/.opencode/skills/vercel-composition-patterns/rules/state-context-interface.md +191 -0
  297. package/template/.opencode/skills/vercel-composition-patterns/rules/state-decouple-implementation.md +113 -0
  298. package/template/.opencode/skills/vercel-composition-patterns/rules/state-lift-state.md +125 -0
  299. package/template/.opencode/skills/vercel-react-best-practices/AGENTS.md +2934 -0
  300. package/template/.opencode/skills/vercel-react-best-practices/SKILL.md +136 -0
  301. package/template/.opencode/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +55 -0
  302. package/template/.opencode/skills/vercel-react-best-practices/rules/advanced-init-once.md +42 -0
  303. package/template/.opencode/skills/vercel-react-best-practices/rules/advanced-use-latest.md +39 -0
  304. package/template/.opencode/skills/vercel-react-best-practices/rules/async-api-routes.md +38 -0
  305. package/template/.opencode/skills/vercel-react-best-practices/rules/async-defer-await.md +80 -0
  306. package/template/.opencode/skills/vercel-react-best-practices/rules/async-dependencies.md +51 -0
  307. package/template/.opencode/skills/vercel-react-best-practices/rules/async-parallel.md +28 -0
  308. package/template/.opencode/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +99 -0
  309. package/template/.opencode/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +59 -0
  310. package/template/.opencode/skills/vercel-react-best-practices/rules/bundle-conditional.md +31 -0
  311. package/template/.opencode/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +49 -0
  312. package/template/.opencode/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +35 -0
  313. package/template/.opencode/skills/vercel-react-best-practices/rules/bundle-preload.md +50 -0
  314. package/template/.opencode/skills/vercel-react-best-practices/rules/client-event-listeners.md +74 -0
  315. package/template/.opencode/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +71 -0
  316. package/template/.opencode/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +48 -0
  317. package/template/.opencode/skills/vercel-react-best-practices/rules/client-swr-dedup.md +56 -0
  318. package/template/.opencode/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +107 -0
  319. package/template/.opencode/skills/vercel-react-best-practices/rules/js-cache-function-results.md +80 -0
  320. package/template/.opencode/skills/vercel-react-best-practices/rules/js-cache-property-access.md +28 -0
  321. package/template/.opencode/skills/vercel-react-best-practices/rules/js-cache-storage.md +70 -0
  322. package/template/.opencode/skills/vercel-react-best-practices/rules/js-combine-iterations.md +32 -0
  323. package/template/.opencode/skills/vercel-react-best-practices/rules/js-early-exit.md +50 -0
  324. package/template/.opencode/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +45 -0
  325. package/template/.opencode/skills/vercel-react-best-practices/rules/js-index-maps.md +37 -0
  326. package/template/.opencode/skills/vercel-react-best-practices/rules/js-length-check-first.md +49 -0
  327. package/template/.opencode/skills/vercel-react-best-practices/rules/js-min-max-loop.md +82 -0
  328. package/template/.opencode/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +24 -0
  329. package/template/.opencode/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +57 -0
  330. package/template/.opencode/skills/vercel-react-best-practices/rules/rendering-activity.md +26 -0
  331. package/template/.opencode/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
  332. package/template/.opencode/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +40 -0
  333. package/template/.opencode/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +38 -0
  334. package/template/.opencode/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +46 -0
  335. package/template/.opencode/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
  336. package/template/.opencode/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -0
  337. package/template/.opencode/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +28 -0
  338. package/template/.opencode/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +75 -0
  339. package/template/.opencode/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +39 -0
  340. package/template/.opencode/skills/vercel-react-best-practices/rules/rerender-dependencies.md +45 -0
  341. package/template/.opencode/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
  342. package/template/.opencode/skills/vercel-react-best-practices/rules/rerender-derived-state.md +29 -0
  343. package/template/.opencode/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +74 -0
  344. package/template/.opencode/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +58 -0
  345. package/template/.opencode/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
  346. package/template/.opencode/skills/vercel-react-best-practices/rules/rerender-memo.md +44 -0
  347. package/template/.opencode/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
  348. package/template/.opencode/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
  349. package/template/.opencode/skills/vercel-react-best-practices/rules/rerender-transitions.md +40 -0
  350. package/template/.opencode/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
  351. package/template/.opencode/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +73 -0
  352. package/template/.opencode/skills/vercel-react-best-practices/rules/server-auth-actions.md +96 -0
  353. package/template/.opencode/skills/vercel-react-best-practices/rules/server-cache-lru.md +41 -0
  354. package/template/.opencode/skills/vercel-react-best-practices/rules/server-cache-react.md +76 -0
  355. package/template/.opencode/skills/vercel-react-best-practices/rules/server-dedup-props.md +65 -0
  356. package/template/.opencode/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +83 -0
  357. package/template/.opencode/skills/vercel-react-best-practices/rules/server-serialization.md +38 -0
  358. package/template/.opencode/skills/verification-loop/SKILL.md +120 -0
  359. package/template/.opencode/skills/web-design-guidelines/SKILL.md +39 -0
  360. package/template/AGENTS.md +32 -0
  361. package/template/opencode.json +354 -0
@@ -0,0 +1,191 @@
1
+ ---
2
+ title: Types
3
+ description: Extending the browser's native HTML elements for maximum customization.
4
+ type: reference
5
+ summary: Patterns for extending native HTML attributes, single-element wrapping, exporting prop types, and avoiding prop name conflicts.
6
+ prerequisites:
7
+ - /composition
8
+ related:
9
+ - /as-child
10
+ - /polymorphism
11
+ - /state
12
+ ---
13
+
14
+ When building reusable components, proper typing is essential for creating flexible, customizable, and type-safe interfaces. By following established patterns for component types, you can ensure your components are both powerful and easy to use.
15
+
16
+ ## Single Element Wrapping
17
+
18
+ Each exported component should ideally wrap a single HTML or JSX element. This principle is fundamental to creating composable, customizable components.
19
+
20
+ When a component wraps multiple elements, it becomes difficult to customize specific parts without prop drilling or complex APIs. Consider this anti-pattern:
21
+
22
+ ```tsx title="@/components/ui/card.tsx"
23
+ const Card = ({ title, description, footer, ...props }) => (
24
+ <div {...props}>
25
+ <div className="card-header">
26
+ <h2>{title}</h2>
27
+ <p>{description}</p>
28
+ </div>
29
+ <div className="card-footer">{footer}</div>
30
+ </div>
31
+ );
32
+ ```
33
+
34
+ As we discussed in [Composition](/composition), this approach creates several problems:
35
+
36
+ - You can't customize the header styling without adding more props
37
+ - You can't control the HTML elements used for title and description
38
+ - You're forced into a specific DOM structure
39
+
40
+ Instead, each layer should be its own component. This allows you to customize each layer independently, and to control the exact HTML elements used for the title and description.
41
+
42
+ The benefits of this approach are:
43
+
44
+ - **Maximum customization** - Users can style and modify each layer independently
45
+ - **No prop drilling** - Props go directly to the element that needs them
46
+ - **Semantic HTML** - Users can see and control the exact DOM structure
47
+ - **Better accessibility** - Direct control over ARIA attributes and semantic elements
48
+ - **Simpler mental model** - One component = one element
49
+
50
+ ## Extending HTML Attributes
51
+
52
+ Every component should extend the native HTML attributes of the element it wraps. This ensures users have full control over the underlying HTML element.
53
+
54
+ ### Basic Pattern
55
+
56
+ ```tsx
57
+ export type CardRootProps = React.ComponentProps<"div"> & {
58
+ // Add your custom props here
59
+ variant?: "default" | "outlined";
60
+ };
61
+
62
+ export const CardRoot = ({ variant = "default", ...props }: CardRootProps) => (
63
+ <div {...props} />
64
+ );
65
+ ```
66
+
67
+ ### Common HTML Attribute Types
68
+
69
+ React provides type definitions for all HTML elements. Use the appropriate one for your component:
70
+
71
+ ```tsx
72
+ // For div elements
73
+ type DivProps = React.ComponentProps<"div">;
74
+
75
+ // For button elements
76
+ type ButtonProps = React.ComponentProps<"button">;
77
+
78
+ // For input elements
79
+ type InputProps = React.ComponentProps<"input">;
80
+
81
+ // For form elements
82
+ type FormProps = React.ComponentProps<"form">;
83
+
84
+ // For anchor elements
85
+ type LinkProps = React.ComponentProps<"a">;
86
+ ```
87
+
88
+ ### Handling Different Element Types
89
+
90
+ When a component can render as different elements, use generics or union types:
91
+
92
+ ```tsx
93
+ // Using discriminated unions
94
+ export type ButtonProps =
95
+ | (React.ComponentProps<"button"> & { asChild?: false })
96
+ | (React.ComponentProps<"div"> & { asChild: true });
97
+
98
+ // Or with a polymorphic approach
99
+ export type PolymorphicProps<T extends React.ElementType> = {
100
+ as?: T;
101
+ } & React.ComponentPropsWithoutRef<T>;
102
+ ```
103
+
104
+ ### Extending custom components
105
+
106
+ If you're extending an existing component, you can use the `ComponentProps` type to get the props of the component.
107
+
108
+ ```tsx title="@/components/ui/share-button.tsx"
109
+ import type { ComponentProps } from "react";
110
+
111
+ export type ShareButtonProps = ComponentProps<"button">;
112
+
113
+ export const ShareButton = (props: ShareButtonProps) => <button {...props} />;
114
+ ```
115
+
116
+ ## Exporting Types
117
+
118
+ Always export your component prop types. This makes them accessible to consumers for various use cases.
119
+
120
+ Exporting types enables several important patterns:
121
+
122
+ ```tsx
123
+ // 1. Extracting specific prop types
124
+ import type { CardRootProps } from "@/components/ui/card";
125
+ type variant = CardRootProps["variant"];
126
+
127
+ // 2. Extending components
128
+ export type ExtendedCardProps = CardRootProps & {
129
+ isLoading?: boolean;
130
+ };
131
+
132
+ // 3. Creating wrapper components
133
+ const MyCard = (props: CardRootProps) => (
134
+ <CardRoot {...props} className={cn("my-custom-class", props.className)} />
135
+ );
136
+
137
+ // 4. Type-safe prop forwarding
138
+ function useCardProps(): Partial<CardRootProps> {
139
+ return {
140
+ variant: "outlined",
141
+ className: "custom-card",
142
+ };
143
+ }
144
+ ```
145
+
146
+ Your exported types should be named `<ComponentName>Props`. This is a convention that helps other developers understand the purpose of the type.
147
+
148
+ ## Best Practices
149
+
150
+ ### 1. Always Spread Props Last
151
+
152
+ Ensure users can override any default props:
153
+
154
+ ```tsx
155
+ // ✅ Good - user props override defaults
156
+ <div className="default-class" {...props} />
157
+
158
+ // ❌ Bad - defaults override user props
159
+ <div {...props} className="default-class" />
160
+ ```
161
+
162
+ ### 2. Avoid Prop Name Conflicts
163
+
164
+ Don't use prop names that conflict with HTML attributes unless intentionally overriding:
165
+
166
+ ```tsx
167
+ // ❌ Bad - conflicts with HTML title attribute
168
+ export type CardProps = React.ComponentProps<"div"> & {
169
+ title: string; // This conflicts with the HTML title attribute
170
+ };
171
+
172
+ // ✅ Good - use a different name
173
+ export type CardProps = React.ComponentProps<"div"> & {
174
+ heading: string;
175
+ };
176
+ ```
177
+
178
+ ### 3. Document Custom Props
179
+
180
+ Add JSDoc comments to custom props for better developer experience:
181
+
182
+ ```tsx
183
+ export type DialogProps = React.ComponentProps<"div"> & {
184
+ /** Whether the dialog is currently open */
185
+ open: boolean;
186
+ /** Callback when the dialog requests to be closed */
187
+ onOpenChange: (open: boolean) => void;
188
+ /** Whether to render the dialog in a portal */
189
+ modal?: boolean;
190
+ };
191
+ ```
@@ -0,0 +1,429 @@
1
+ ---
2
+ name: clickhouse-io
3
+ description: ClickHouse database patterns, query optimization, analytics, and data engineering best practices for high-performance analytical workloads.
4
+ ---
5
+
6
+ # ClickHouse Analytics Patterns
7
+
8
+ ClickHouse-specific patterns for high-performance analytics and data engineering.
9
+
10
+ ## Overview
11
+
12
+ ClickHouse is a column-oriented database management system (DBMS) for online analytical processing (OLAP). It's optimized for fast analytical queries on large datasets.
13
+
14
+ **Key Features:**
15
+ - Column-oriented storage
16
+ - Data compression
17
+ - Parallel query execution
18
+ - Distributed queries
19
+ - Real-time analytics
20
+
21
+ ## Table Design Patterns
22
+
23
+ ### MergeTree Engine (Most Common)
24
+
25
+ ```sql
26
+ CREATE TABLE markets_analytics (
27
+ date Date,
28
+ market_id String,
29
+ market_name String,
30
+ volume UInt64,
31
+ trades UInt32,
32
+ unique_traders UInt32,
33
+ avg_trade_size Float64,
34
+ created_at DateTime
35
+ ) ENGINE = MergeTree()
36
+ PARTITION BY toYYYYMM(date)
37
+ ORDER BY (date, market_id)
38
+ SETTINGS index_granularity = 8192;
39
+ ```
40
+
41
+ ### ReplacingMergeTree (Deduplication)
42
+
43
+ ```sql
44
+ -- For data that may have duplicates (e.g., from multiple sources)
45
+ CREATE TABLE user_events (
46
+ event_id String,
47
+ user_id String,
48
+ event_type String,
49
+ timestamp DateTime,
50
+ properties String
51
+ ) ENGINE = ReplacingMergeTree()
52
+ PARTITION BY toYYYYMM(timestamp)
53
+ ORDER BY (user_id, event_id, timestamp)
54
+ PRIMARY KEY (user_id, event_id);
55
+ ```
56
+
57
+ ### AggregatingMergeTree (Pre-aggregation)
58
+
59
+ ```sql
60
+ -- For maintaining aggregated metrics
61
+ CREATE TABLE market_stats_hourly (
62
+ hour DateTime,
63
+ market_id String,
64
+ total_volume AggregateFunction(sum, UInt64),
65
+ total_trades AggregateFunction(count, UInt32),
66
+ unique_users AggregateFunction(uniq, String)
67
+ ) ENGINE = AggregatingMergeTree()
68
+ PARTITION BY toYYYYMM(hour)
69
+ ORDER BY (hour, market_id);
70
+
71
+ -- Query aggregated data
72
+ SELECT
73
+ hour,
74
+ market_id,
75
+ sumMerge(total_volume) AS volume,
76
+ countMerge(total_trades) AS trades,
77
+ uniqMerge(unique_users) AS users
78
+ FROM market_stats_hourly
79
+ WHERE hour >= toStartOfHour(now() - INTERVAL 24 HOUR)
80
+ GROUP BY hour, market_id
81
+ ORDER BY hour DESC;
82
+ ```
83
+
84
+ ## Query Optimization Patterns
85
+
86
+ ### Efficient Filtering
87
+
88
+ ```sql
89
+ -- ✅ GOOD: Use indexed columns first
90
+ SELECT *
91
+ FROM markets_analytics
92
+ WHERE date >= '2025-01-01'
93
+ AND market_id = 'market-123'
94
+ AND volume > 1000
95
+ ORDER BY date DESC
96
+ LIMIT 100;
97
+
98
+ -- ❌ BAD: Filter on non-indexed columns first
99
+ SELECT *
100
+ FROM markets_analytics
101
+ WHERE volume > 1000
102
+ AND market_name LIKE '%election%'
103
+ AND date >= '2025-01-01';
104
+ ```
105
+
106
+ ### Aggregations
107
+
108
+ ```sql
109
+ -- ✅ GOOD: Use ClickHouse-specific aggregation functions
110
+ SELECT
111
+ toStartOfDay(created_at) AS day,
112
+ market_id,
113
+ sum(volume) AS total_volume,
114
+ count() AS total_trades,
115
+ uniq(trader_id) AS unique_traders,
116
+ avg(trade_size) AS avg_size
117
+ FROM trades
118
+ WHERE created_at >= today() - INTERVAL 7 DAY
119
+ GROUP BY day, market_id
120
+ ORDER BY day DESC, total_volume DESC;
121
+
122
+ -- ✅ Use quantile for percentiles (more efficient than percentile)
123
+ SELECT
124
+ quantile(0.50)(trade_size) AS median,
125
+ quantile(0.95)(trade_size) AS p95,
126
+ quantile(0.99)(trade_size) AS p99
127
+ FROM trades
128
+ WHERE created_at >= now() - INTERVAL 1 HOUR;
129
+ ```
130
+
131
+ ### Window Functions
132
+
133
+ ```sql
134
+ -- Calculate running totals
135
+ SELECT
136
+ date,
137
+ market_id,
138
+ volume,
139
+ sum(volume) OVER (
140
+ PARTITION BY market_id
141
+ ORDER BY date
142
+ ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
143
+ ) AS cumulative_volume
144
+ FROM markets_analytics
145
+ WHERE date >= today() - INTERVAL 30 DAY
146
+ ORDER BY market_id, date;
147
+ ```
148
+
149
+ ## Data Insertion Patterns
150
+
151
+ ### Bulk Insert (Recommended)
152
+
153
+ ```typescript
154
+ import { ClickHouse } from 'clickhouse'
155
+
156
+ const clickhouse = new ClickHouse({
157
+ url: process.env.CLICKHOUSE_URL,
158
+ port: 8123,
159
+ basicAuth: {
160
+ username: process.env.CLICKHOUSE_USER,
161
+ password: process.env.CLICKHOUSE_PASSWORD
162
+ }
163
+ })
164
+
165
+ // ✅ Batch insert (efficient)
166
+ async function bulkInsertTrades(trades: Trade[]) {
167
+ const values = trades.map(trade => `(
168
+ '${trade.id}',
169
+ '${trade.market_id}',
170
+ '${trade.user_id}',
171
+ ${trade.amount},
172
+ '${trade.timestamp.toISOString()}'
173
+ )`).join(',')
174
+
175
+ await clickhouse.query(`
176
+ INSERT INTO trades (id, market_id, user_id, amount, timestamp)
177
+ VALUES ${values}
178
+ `).toPromise()
179
+ }
180
+
181
+ // ❌ Individual inserts (slow)
182
+ async function insertTrade(trade: Trade) {
183
+ // Don't do this in a loop!
184
+ await clickhouse.query(`
185
+ INSERT INTO trades VALUES ('${trade.id}', ...)
186
+ `).toPromise()
187
+ }
188
+ ```
189
+
190
+ ### Streaming Insert
191
+
192
+ ```typescript
193
+ // For continuous data ingestion
194
+ import { createWriteStream } from 'fs'
195
+ import { pipeline } from 'stream/promises'
196
+
197
+ async function streamInserts() {
198
+ const stream = clickhouse.insert('trades').stream()
199
+
200
+ for await (const batch of dataSource) {
201
+ stream.write(batch)
202
+ }
203
+
204
+ await stream.end()
205
+ }
206
+ ```
207
+
208
+ ## Materialized Views
209
+
210
+ ### Real-time Aggregations
211
+
212
+ ```sql
213
+ -- Create materialized view for hourly stats
214
+ CREATE MATERIALIZED VIEW market_stats_hourly_mv
215
+ TO market_stats_hourly
216
+ AS SELECT
217
+ toStartOfHour(timestamp) AS hour,
218
+ market_id,
219
+ sumState(amount) AS total_volume,
220
+ countState() AS total_trades,
221
+ uniqState(user_id) AS unique_users
222
+ FROM trades
223
+ GROUP BY hour, market_id;
224
+
225
+ -- Query the materialized view
226
+ SELECT
227
+ hour,
228
+ market_id,
229
+ sumMerge(total_volume) AS volume,
230
+ countMerge(total_trades) AS trades,
231
+ uniqMerge(unique_users) AS users
232
+ FROM market_stats_hourly
233
+ WHERE hour >= now() - INTERVAL 24 HOUR
234
+ GROUP BY hour, market_id;
235
+ ```
236
+
237
+ ## Performance Monitoring
238
+
239
+ ### Query Performance
240
+
241
+ ```sql
242
+ -- Check slow queries
243
+ SELECT
244
+ query_id,
245
+ user,
246
+ query,
247
+ query_duration_ms,
248
+ read_rows,
249
+ read_bytes,
250
+ memory_usage
251
+ FROM system.query_log
252
+ WHERE type = 'QueryFinish'
253
+ AND query_duration_ms > 1000
254
+ AND event_time >= now() - INTERVAL 1 HOUR
255
+ ORDER BY query_duration_ms DESC
256
+ LIMIT 10;
257
+ ```
258
+
259
+ ### Table Statistics
260
+
261
+ ```sql
262
+ -- Check table sizes
263
+ SELECT
264
+ database,
265
+ table,
266
+ formatReadableSize(sum(bytes)) AS size,
267
+ sum(rows) AS rows,
268
+ max(modification_time) AS latest_modification
269
+ FROM system.parts
270
+ WHERE active
271
+ GROUP BY database, table
272
+ ORDER BY sum(bytes) DESC;
273
+ ```
274
+
275
+ ## Common Analytics Queries
276
+
277
+ ### Time Series Analysis
278
+
279
+ ```sql
280
+ -- Daily active users
281
+ SELECT
282
+ toDate(timestamp) AS date,
283
+ uniq(user_id) AS daily_active_users
284
+ FROM events
285
+ WHERE timestamp >= today() - INTERVAL 30 DAY
286
+ GROUP BY date
287
+ ORDER BY date;
288
+
289
+ -- Retention analysis
290
+ SELECT
291
+ signup_date,
292
+ countIf(days_since_signup = 0) AS day_0,
293
+ countIf(days_since_signup = 1) AS day_1,
294
+ countIf(days_since_signup = 7) AS day_7,
295
+ countIf(days_since_signup = 30) AS day_30
296
+ FROM (
297
+ SELECT
298
+ user_id,
299
+ min(toDate(timestamp)) AS signup_date,
300
+ toDate(timestamp) AS activity_date,
301
+ dateDiff('day', signup_date, activity_date) AS days_since_signup
302
+ FROM events
303
+ GROUP BY user_id, activity_date
304
+ )
305
+ GROUP BY signup_date
306
+ ORDER BY signup_date DESC;
307
+ ```
308
+
309
+ ### Funnel Analysis
310
+
311
+ ```sql
312
+ -- Conversion funnel
313
+ SELECT
314
+ countIf(step = 'viewed_market') AS viewed,
315
+ countIf(step = 'clicked_trade') AS clicked,
316
+ countIf(step = 'completed_trade') AS completed,
317
+ round(clicked / viewed * 100, 2) AS view_to_click_rate,
318
+ round(completed / clicked * 100, 2) AS click_to_completion_rate
319
+ FROM (
320
+ SELECT
321
+ user_id,
322
+ session_id,
323
+ event_type AS step
324
+ FROM events
325
+ WHERE event_date = today()
326
+ )
327
+ GROUP BY session_id;
328
+ ```
329
+
330
+ ### Cohort Analysis
331
+
332
+ ```sql
333
+ -- User cohorts by signup month
334
+ SELECT
335
+ toStartOfMonth(signup_date) AS cohort,
336
+ toStartOfMonth(activity_date) AS month,
337
+ dateDiff('month', cohort, month) AS months_since_signup,
338
+ count(DISTINCT user_id) AS active_users
339
+ FROM (
340
+ SELECT
341
+ user_id,
342
+ min(toDate(timestamp)) OVER (PARTITION BY user_id) AS signup_date,
343
+ toDate(timestamp) AS activity_date
344
+ FROM events
345
+ )
346
+ GROUP BY cohort, month, months_since_signup
347
+ ORDER BY cohort, months_since_signup;
348
+ ```
349
+
350
+ ## Data Pipeline Patterns
351
+
352
+ ### ETL Pattern
353
+
354
+ ```typescript
355
+ // Extract, Transform, Load
356
+ async function etlPipeline() {
357
+ // 1. Extract from source
358
+ const rawData = await extractFromPostgres()
359
+
360
+ // 2. Transform
361
+ const transformed = rawData.map(row => ({
362
+ date: new Date(row.created_at).toISOString().split('T')[0],
363
+ market_id: row.market_slug,
364
+ volume: parseFloat(row.total_volume),
365
+ trades: parseInt(row.trade_count)
366
+ }))
367
+
368
+ // 3. Load to ClickHouse
369
+ await bulkInsertToClickHouse(transformed)
370
+ }
371
+
372
+ // Run periodically
373
+ setInterval(etlPipeline, 60 * 60 * 1000) // Every hour
374
+ ```
375
+
376
+ ### Change Data Capture (CDC)
377
+
378
+ ```typescript
379
+ // Listen to PostgreSQL changes and sync to ClickHouse
380
+ import { Client } from 'pg'
381
+
382
+ const pgClient = new Client({ connectionString: process.env.DATABASE_URL })
383
+
384
+ pgClient.query('LISTEN market_updates')
385
+
386
+ pgClient.on('notification', async (msg) => {
387
+ const update = JSON.parse(msg.payload)
388
+
389
+ await clickhouse.insert('market_updates', [
390
+ {
391
+ market_id: update.id,
392
+ event_type: update.operation, // INSERT, UPDATE, DELETE
393
+ timestamp: new Date(),
394
+ data: JSON.stringify(update.new_data)
395
+ }
396
+ ])
397
+ })
398
+ ```
399
+
400
+ ## Best Practices
401
+
402
+ ### 1. Partitioning Strategy
403
+ - Partition by time (usually month or day)
404
+ - Avoid too many partitions (performance impact)
405
+ - Use DATE type for partition key
406
+
407
+ ### 2. Ordering Key
408
+ - Put most frequently filtered columns first
409
+ - Consider cardinality (high cardinality first)
410
+ - Order impacts compression
411
+
412
+ ### 3. Data Types
413
+ - Use smallest appropriate type (UInt32 vs UInt64)
414
+ - Use LowCardinality for repeated strings
415
+ - Use Enum for categorical data
416
+
417
+ ### 4. Avoid
418
+ - SELECT * (specify columns)
419
+ - FINAL (merge data before query instead)
420
+ - Too many JOINs (denormalize for analytics)
421
+ - Small frequent inserts (batch instead)
422
+
423
+ ### 5. Monitoring
424
+ - Track query performance
425
+ - Monitor disk usage
426
+ - Check merge operations
427
+ - Review slow query log
428
+
429
+ **Remember**: ClickHouse excels at analytical workloads. Design tables for your query patterns, batch inserts, and leverage materialized views for real-time aggregations.