@macpaw/cctk 1.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (415) hide show
  1. package/License +21 -0
  2. package/README.md +142 -0
  3. package/bin/index.js +5 -0
  4. package/dist/index.js +1 -0
  5. package/package.json +65 -0
  6. package/templates/claude/agents/brainstormer.md +113 -0
  7. package/templates/claude/agents/code-reviewer.md +157 -0
  8. package/templates/claude/agents/copywriter.md +110 -0
  9. package/templates/claude/agents/database-admin.md +92 -0
  10. package/templates/claude/agents/debugger.md +137 -0
  11. package/templates/claude/agents/docs-manager.md +208 -0
  12. package/templates/claude/agents/fullstack-developer.md +95 -0
  13. package/templates/claude/agents/git-manager.md +394 -0
  14. package/templates/claude/agents/journal-writer.md +113 -0
  15. package/templates/claude/agents/mcp-manager.md +89 -0
  16. package/templates/claude/agents/planner.md +108 -0
  17. package/templates/claude/agents/project-manager.md +125 -0
  18. package/templates/claude/agents/registry.json +304 -0
  19. package/templates/claude/agents/researcher.md +37 -0
  20. package/templates/claude/agents/scout-external.md +140 -0
  21. package/templates/claude/agents/scout.md +106 -0
  22. package/templates/claude/agents/tester.md +105 -0
  23. package/templates/claude/agents/ui-ux-designer.md +208 -0
  24. package/templates/claude/commands/ask.md +56 -0
  25. package/templates/claude/commands/bootstrap/auto/fast.md +106 -0
  26. package/templates/claude/commands/bootstrap/auto/parallel.md +64 -0
  27. package/templates/claude/commands/bootstrap/auto.md +110 -0
  28. package/templates/claude/commands/bootstrap.md +130 -0
  29. package/templates/claude/commands/brainstorm.md +75 -0
  30. package/templates/claude/commands/code/auto.md +198 -0
  31. package/templates/claude/commands/code/no-test.md +172 -0
  32. package/templates/claude/commands/code/parallel.md +100 -0
  33. package/templates/claude/commands/code.md +197 -0
  34. package/templates/claude/commands/coding-level.md +37 -0
  35. package/templates/claude/commands/content/cro.md +41 -0
  36. package/templates/claude/commands/content/enhance.md +12 -0
  37. package/templates/claude/commands/content/fast.md +11 -0
  38. package/templates/claude/commands/content/good.md +14 -0
  39. package/templates/claude/commands/cook/auto/fast.md +26 -0
  40. package/templates/claude/commands/cook/auto/parallel.md +49 -0
  41. package/templates/claude/commands/cook/auto.md +15 -0
  42. package/templates/claude/commands/cook.md +101 -0
  43. package/templates/claude/commands/debug.md +13 -0
  44. package/templates/claude/commands/docs/init.md +37 -0
  45. package/templates/claude/commands/docs/summarize.md +22 -0
  46. package/templates/claude/commands/docs/update.md +78 -0
  47. package/templates/claude/commands/fix/ci.md +17 -0
  48. package/templates/claude/commands/fix/fast.md +18 -0
  49. package/templates/claude/commands/fix/hard.md +35 -0
  50. package/templates/claude/commands/fix/logs.md +26 -0
  51. package/templates/claude/commands/fix/parallel.md +54 -0
  52. package/templates/claude/commands/fix/test.md +20 -0
  53. package/templates/claude/commands/fix/types.md +9 -0
  54. package/templates/claude/commands/fix/ui.md +33 -0
  55. package/templates/claude/commands/fix.md +43 -0
  56. package/templates/claude/commands/git/cm.md +5 -0
  57. package/templates/claude/commands/git/cp.md +4 -0
  58. package/templates/claude/commands/git/merge.md +40 -0
  59. package/templates/claude/commands/git/pr.md +50 -0
  60. package/templates/claude/commands/journal.md +7 -0
  61. package/templates/claude/commands/kanban.md +99 -0
  62. package/templates/claude/commands/plan/archive.md +57 -0
  63. package/templates/claude/commands/plan/ci.md +33 -0
  64. package/templates/claude/commands/plan/cro.md +67 -0
  65. package/templates/claude/commands/plan/fast.md +66 -0
  66. package/templates/claude/commands/plan/hard.md +92 -0
  67. package/templates/claude/commands/plan/parallel.md +129 -0
  68. package/templates/claude/commands/plan/two.md +45 -0
  69. package/templates/claude/commands/plan/validate.md +117 -0
  70. package/templates/claude/commands/plan.md +30 -0
  71. package/templates/claude/commands/preview.md +87 -0
  72. package/templates/claude/commands/registry.json +313 -0
  73. package/templates/claude/commands/review/codebase/parallel.md +122 -0
  74. package/templates/claude/commands/review/codebase.md +47 -0
  75. package/templates/claude/commands/scout/ext.md +35 -0
  76. package/templates/claude/commands/scout.md +28 -0
  77. package/templates/claude/commands/skill/add.md +36 -0
  78. package/templates/claude/commands/skill/create.md +29 -0
  79. package/templates/claude/commands/skill/fix-logs.md +22 -0
  80. package/templates/claude/commands/skill/optimize/auto.md +25 -0
  81. package/templates/claude/commands/skill/optimize.md +34 -0
  82. package/templates/claude/commands/skill/plan.md +45 -0
  83. package/templates/claude/commands/test/ui.md +91 -0
  84. package/templates/claude/commands/test.md +8 -0
  85. package/templates/claude/commands/use-mcp.md +34 -0
  86. package/templates/claude/commands/watzup.md +8 -0
  87. package/templates/claude/commands/worktree.md +126 -0
  88. package/templates/claude/hooks/dev-rules-reminder.cjs +258 -0
  89. package/templates/claude/hooks/docs/README.md +42 -0
  90. package/templates/claude/hooks/lib/cctk-config-utils.cjs +751 -0
  91. package/templates/claude/hooks/lib/cctk-paths.cjs +106 -0
  92. package/templates/claude/hooks/lib/context-tracker.cjs +346 -0
  93. package/templates/claude/hooks/privacy-block.cjs +289 -0
  94. package/templates/claude/hooks/registry.json +77 -0
  95. package/templates/claude/hooks/scout-block/broad-pattern-detector.cjs +293 -0
  96. package/templates/claude/hooks/scout-block/error-formatter.cjs +156 -0
  97. package/templates/claude/hooks/scout-block/path-extractor.cjs +359 -0
  98. package/templates/claude/hooks/scout-block/pattern-matcher.cjs +184 -0
  99. package/templates/claude/hooks/scout-block/vendor/ignore.js +626 -0
  100. package/templates/claude/hooks/scout-block.cjs +167 -0
  101. package/templates/claude/hooks/session-end.cjs +35 -0
  102. package/templates/claude/hooks/session-init.cjs +214 -0
  103. package/templates/claude/hooks/subagent-init.cjs +161 -0
  104. package/templates/claude/hooks/write-compact-marker.cjs +153 -0
  105. package/templates/claude/output-styles/coding-level-1.md +148 -0
  106. package/templates/claude/output-styles/coding-level-2.md +159 -0
  107. package/templates/claude/output-styles/coding-level-3.md +91 -0
  108. package/templates/claude/scripts/README.md +33 -0
  109. package/templates/claude/scripts/generate-catalogs.cjs +318 -0
  110. package/templates/claude/scripts/registry.json +48 -0
  111. package/templates/claude/scripts/set-active-plan.cjs +45 -0
  112. package/templates/claude/scripts/validate-docs.cjs +447 -0
  113. package/templates/claude/scripts/worktree.cjs +658 -0
  114. package/templates/claude/skills/README.md +112 -0
  115. package/templates/claude/skills/ai-artist/SKILL.md +75 -0
  116. package/templates/claude/skills/ai-artist/references/advanced-techniques.md +184 -0
  117. package/templates/claude/skills/ai-artist/references/domain-code.md +66 -0
  118. package/templates/claude/skills/ai-artist/references/domain-data.md +72 -0
  119. package/templates/claude/skills/ai-artist/references/domain-marketing.md +66 -0
  120. package/templates/claude/skills/ai-artist/references/domain-patterns.md +33 -0
  121. package/templates/claude/skills/ai-artist/references/domain-writing.md +68 -0
  122. package/templates/claude/skills/ai-artist/references/image-prompting.md +141 -0
  123. package/templates/claude/skills/ai-artist/references/llm-prompting.md +165 -0
  124. package/templates/claude/skills/ai-artist/references/nano-banana.md +59 -0
  125. package/templates/claude/skills/ai-artist/references/reasoning-techniques.md +201 -0
  126. package/templates/claude/skills/backend-development/SKILL.md +95 -0
  127. package/templates/claude/skills/backend-development/references/backend-api-design.md +495 -0
  128. package/templates/claude/skills/backend-development/references/backend-architecture.md +454 -0
  129. package/templates/claude/skills/backend-development/references/backend-authentication.md +338 -0
  130. package/templates/claude/skills/backend-development/references/backend-code-quality.md +659 -0
  131. package/templates/claude/skills/backend-development/references/backend-debugging.md +904 -0
  132. package/templates/claude/skills/backend-development/references/backend-devops.md +494 -0
  133. package/templates/claude/skills/backend-development/references/backend-mindset.md +387 -0
  134. package/templates/claude/skills/backend-development/references/backend-performance.md +397 -0
  135. package/templates/claude/skills/backend-development/references/backend-security.md +290 -0
  136. package/templates/claude/skills/backend-development/references/backend-technologies.md +256 -0
  137. package/templates/claude/skills/backend-development/references/backend-testing.md +429 -0
  138. package/templates/claude/skills/better-auth/SKILL.md +204 -0
  139. package/templates/claude/skills/better-auth/references/advanced-features.md +553 -0
  140. package/templates/claude/skills/better-auth/references/database-integration.md +577 -0
  141. package/templates/claude/skills/better-auth/references/email-password-auth.md +416 -0
  142. package/templates/claude/skills/better-auth/references/oauth-providers.md +430 -0
  143. package/templates/claude/skills/better-auth/scripts/better_auth_init.py +521 -0
  144. package/templates/claude/skills/chrome-devtools/SKILL.md +473 -0
  145. package/templates/claude/skills/chrome-devtools/references/cdp-domains.md +694 -0
  146. package/templates/claude/skills/chrome-devtools/references/performance-guide.md +940 -0
  147. package/templates/claude/skills/chrome-devtools/references/puppeteer-reference.md +953 -0
  148. package/templates/claude/skills/chrome-devtools/scripts/README.md +288 -0
  149. package/templates/claude/skills/chrome-devtools/scripts/aria-snapshot.js +368 -0
  150. package/templates/claude/skills/chrome-devtools/scripts/click.js +92 -0
  151. package/templates/claude/skills/chrome-devtools/scripts/console.js +85 -0
  152. package/templates/claude/skills/chrome-devtools/scripts/evaluate.js +59 -0
  153. package/templates/claude/skills/chrome-devtools/scripts/fill.js +84 -0
  154. package/templates/claude/skills/chrome-devtools/scripts/inject-auth.js +247 -0
  155. package/templates/claude/skills/chrome-devtools/scripts/install-deps.sh +11 -0
  156. package/templates/claude/skills/chrome-devtools/scripts/install.sh +36 -0
  157. package/templates/claude/skills/chrome-devtools/scripts/lib/browser.js +335 -0
  158. package/templates/claude/skills/chrome-devtools/scripts/lib/selector.js +183 -0
  159. package/templates/claude/skills/chrome-devtools/scripts/navigate.js +60 -0
  160. package/templates/claude/skills/chrome-devtools/scripts/network.js +113 -0
  161. package/templates/claude/skills/chrome-devtools/scripts/package.json +16 -0
  162. package/templates/claude/skills/chrome-devtools/scripts/performance.js +159 -0
  163. package/templates/claude/skills/chrome-devtools/scripts/screenshot.js +212 -0
  164. package/templates/claude/skills/chrome-devtools/scripts/select-ref.js +151 -0
  165. package/templates/claude/skills/chrome-devtools/scripts/snapshot.js +143 -0
  166. package/templates/claude/skills/chrome-devtools/scripts/ws-debug.js +47 -0
  167. package/templates/claude/skills/chrome-devtools/scripts/ws-full-debug.js +115 -0
  168. package/templates/claude/skills/claude-code/references/advanced-features.md +399 -0
  169. package/templates/claude/skills/claude-code/references/agent-skills.md +399 -0
  170. package/templates/claude/skills/claude-code/references/api-reference.md +498 -0
  171. package/templates/claude/skills/claude-code/references/best-practices.md +447 -0
  172. package/templates/claude/skills/claude-code/references/cicd-integration.md +428 -0
  173. package/templates/claude/skills/claude-code/references/common-workflows.md +107 -0
  174. package/templates/claude/skills/claude-code/references/configuration.md +480 -0
  175. package/templates/claude/skills/claude-code/references/enterprise-features.md +472 -0
  176. package/templates/claude/skills/claude-code/references/getting-started.md +244 -0
  177. package/templates/claude/skills/claude-code/references/hooks-and-plugins.md +444 -0
  178. package/templates/claude/skills/claude-code/references/hooks-comprehensive.md +622 -0
  179. package/templates/claude/skills/claude-code/references/ide-integration.md +316 -0
  180. package/templates/claude/skills/claude-code/references/mcp-integration.md +386 -0
  181. package/templates/claude/skills/claude-code/references/slash-commands.md +460 -0
  182. package/templates/claude/skills/claude-code/references/troubleshooting.md +455 -0
  183. package/templates/claude/skills/claude-code/skill.md +60 -0
  184. package/templates/claude/skills/code-review/SKILL.md +143 -0
  185. package/templates/claude/skills/code-review/references/code-review-reception.md +209 -0
  186. package/templates/claude/skills/code-review/references/requesting-code-review.md +105 -0
  187. package/templates/claude/skills/code-review/references/verification-before-completion.md +139 -0
  188. package/templates/claude/skills/context-engineering/SKILL.md +86 -0
  189. package/templates/claude/skills/context-engineering/references/context-compression.md +84 -0
  190. package/templates/claude/skills/context-engineering/references/context-degradation.md +93 -0
  191. package/templates/claude/skills/context-engineering/references/context-fundamentals.md +75 -0
  192. package/templates/claude/skills/context-engineering/references/context-optimization.md +82 -0
  193. package/templates/claude/skills/context-engineering/references/evaluation.md +89 -0
  194. package/templates/claude/skills/context-engineering/references/memory-systems.md +88 -0
  195. package/templates/claude/skills/context-engineering/references/multi-agent-patterns.md +90 -0
  196. package/templates/claude/skills/context-engineering/references/project-development.md +97 -0
  197. package/templates/claude/skills/context-engineering/references/tool-design.md +86 -0
  198. package/templates/claude/skills/context-engineering/scripts/compression_evaluator.py +329 -0
  199. package/templates/claude/skills/context-engineering/scripts/context_analyzer.py +294 -0
  200. package/templates/claude/skills/databases/SKILL.md +232 -0
  201. package/templates/claude/skills/databases/references/mongodb-aggregation.md +447 -0
  202. package/templates/claude/skills/databases/references/mongodb-atlas.md +465 -0
  203. package/templates/claude/skills/databases/references/mongodb-crud.md +408 -0
  204. package/templates/claude/skills/databases/references/mongodb-indexing.md +442 -0
  205. package/templates/claude/skills/databases/references/postgresql-administration.md +594 -0
  206. package/templates/claude/skills/databases/references/postgresql-performance.md +527 -0
  207. package/templates/claude/skills/databases/references/postgresql-psql-cli.md +467 -0
  208. package/templates/claude/skills/databases/references/postgresql-queries.md +475 -0
  209. package/templates/claude/skills/databases/scripts/db_backup.py +502 -0
  210. package/templates/claude/skills/databases/scripts/db_migrate.py +414 -0
  211. package/templates/claude/skills/databases/scripts/db_performance_check.py +445 -0
  212. package/templates/claude/skills/debugging/SKILL.md +84 -0
  213. package/templates/claude/skills/debugging/references/defense-in-depth.md +124 -0
  214. package/templates/claude/skills/debugging/references/root-cause-tracing.md +122 -0
  215. package/templates/claude/skills/debugging/references/systematic-debugging.md +102 -0
  216. package/templates/claude/skills/debugging/references/verification.md +123 -0
  217. package/templates/claude/skills/debugging/scripts/find-polluter.sh +63 -0
  218. package/templates/claude/skills/debugging/scripts/find-polluter.test.md +102 -0
  219. package/templates/claude/skills/devops/SKILL.md +293 -0
  220. package/templates/claude/skills/devops/references/browser-rendering.md +305 -0
  221. package/templates/claude/skills/devops/references/cloudflare-d1-kv.md +123 -0
  222. package/templates/claude/skills/devops/references/cloudflare-platform.md +271 -0
  223. package/templates/claude/skills/devops/references/cloudflare-r2-storage.md +280 -0
  224. package/templates/claude/skills/devops/references/cloudflare-workers-advanced.md +312 -0
  225. package/templates/claude/skills/devops/references/cloudflare-workers-apis.md +309 -0
  226. package/templates/claude/skills/devops/references/cloudflare-workers-basics.md +418 -0
  227. package/templates/claude/skills/devops/references/docker-basics.md +297 -0
  228. package/templates/claude/skills/devops/references/docker-compose.md +292 -0
  229. package/templates/claude/skills/devops/references/gcloud-platform.md +307 -0
  230. package/templates/claude/skills/devops/references/gcloud-services.md +304 -0
  231. package/templates/claude/skills/devops/scripts/cloudflare_deploy.py +269 -0
  232. package/templates/claude/skills/devops/scripts/docker_optimize.py +320 -0
  233. package/templates/claude/skills/docs-seeker/SKILL.md +95 -0
  234. package/templates/claude/skills/docs-seeker/package.json +24 -0
  235. package/templates/claude/skills/docs-seeker/references/advanced.md +78 -0
  236. package/templates/claude/skills/docs-seeker/references/context7-patterns.md +68 -0
  237. package/templates/claude/skills/docs-seeker/references/errors.md +68 -0
  238. package/templates/claude/skills/docs-seeker/scripts/analyze-llms-txt.js +245 -0
  239. package/templates/claude/skills/docs-seeker/scripts/detect-topic.js +172 -0
  240. package/templates/claude/skills/docs-seeker/scripts/fetch-docs.js +212 -0
  241. package/templates/claude/skills/docs-seeker/workflows/library-search.md +87 -0
  242. package/templates/claude/skills/docs-seeker/workflows/repo-analysis.md +91 -0
  243. package/templates/claude/skills/docs-seeker/workflows/topic-search.md +77 -0
  244. package/templates/claude/skills/frontend-design/SKILL.md +85 -0
  245. package/templates/claude/skills/frontend-design/references/analysis-best-practices.md +80 -0
  246. package/templates/claude/skills/frontend-design/references/analysis-prompts.md +141 -0
  247. package/templates/claude/skills/frontend-design/references/analysis-techniques.md +118 -0
  248. package/templates/claude/skills/frontend-design/references/animejs.md +396 -0
  249. package/templates/claude/skills/frontend-design/references/design-extraction-overview.md +71 -0
  250. package/templates/claude/skills/frontend-design/references/extraction-best-practices.md +141 -0
  251. package/templates/claude/skills/frontend-design/references/extraction-output-templates.md +162 -0
  252. package/templates/claude/skills/frontend-design/references/extraction-prompts.md +127 -0
  253. package/templates/claude/skills/frontend-design/references/technical-accessibility.md +119 -0
  254. package/templates/claude/skills/frontend-design/references/technical-best-practices.md +97 -0
  255. package/templates/claude/skills/frontend-design/references/technical-optimization.md +44 -0
  256. package/templates/claude/skills/frontend-design/references/technical-overview.md +90 -0
  257. package/templates/claude/skills/frontend-design/references/technical-workflows.md +150 -0
  258. package/templates/claude/skills/frontend-design/references/visual-analysis-overview.md +95 -0
  259. package/templates/claude/skills/frontend-development/SKILL.md +399 -0
  260. package/templates/claude/skills/frontend-development/resources/common-patterns.md +331 -0
  261. package/templates/claude/skills/frontend-development/resources/complete-examples.md +872 -0
  262. package/templates/claude/skills/frontend-development/resources/component-patterns.md +502 -0
  263. package/templates/claude/skills/frontend-development/resources/data-fetching.md +767 -0
  264. package/templates/claude/skills/frontend-development/resources/file-organization.md +502 -0
  265. package/templates/claude/skills/frontend-development/resources/loading-and-error-states.md +501 -0
  266. package/templates/claude/skills/frontend-development/resources/performance.md +406 -0
  267. package/templates/claude/skills/frontend-development/resources/routing-guide.md +364 -0
  268. package/templates/claude/skills/frontend-development/resources/styling-guide.md +428 -0
  269. package/templates/claude/skills/frontend-development/resources/typescript-standards.md +418 -0
  270. package/templates/claude/skills/markdown-novel-viewer/SKILL.md +272 -0
  271. package/templates/claude/skills/markdown-novel-viewer/assets/directory-browser.css +215 -0
  272. package/templates/claude/skills/markdown-novel-viewer/assets/favicon.png +0 -0
  273. package/templates/claude/skills/markdown-novel-viewer/assets/novel-theme.css +872 -0
  274. package/templates/claude/skills/markdown-novel-viewer/assets/reader.js +378 -0
  275. package/templates/claude/skills/markdown-novel-viewer/assets/template.html +85 -0
  276. package/templates/claude/skills/markdown-novel-viewer/package.json +15 -0
  277. package/templates/claude/skills/markdown-novel-viewer/scripts/lib/http-server.cjs +434 -0
  278. package/templates/claude/skills/markdown-novel-viewer/scripts/lib/markdown-renderer.cjs +335 -0
  279. package/templates/claude/skills/markdown-novel-viewer/scripts/lib/plan-navigator.cjs +509 -0
  280. package/templates/claude/skills/markdown-novel-viewer/scripts/lib/port-finder.cjs +49 -0
  281. package/templates/claude/skills/markdown-novel-viewer/scripts/lib/process-mgr.cjs +150 -0
  282. package/templates/claude/skills/markdown-novel-viewer/scripts/server.cjs +398 -0
  283. package/templates/claude/skills/mcp-builder/SKILL.md +328 -0
  284. package/templates/claude/skills/mcp-builder/reference/evaluation.md +602 -0
  285. package/templates/claude/skills/mcp-builder/reference/mcp_best_practices.md +915 -0
  286. package/templates/claude/skills/mcp-builder/reference/node_mcp_server.md +916 -0
  287. package/templates/claude/skills/mcp-builder/reference/python_mcp_server.md +752 -0
  288. package/templates/claude/skills/mcp-builder/scripts/connections.py +151 -0
  289. package/templates/claude/skills/mcp-builder/scripts/evaluation.py +381 -0
  290. package/templates/claude/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
  291. package/templates/claude/skills/mcp-builder/scripts/requirements.txt +2 -0
  292. package/templates/claude/skills/mcp-management/README.md +219 -0
  293. package/templates/claude/skills/mcp-management/SKILL.md +209 -0
  294. package/templates/claude/skills/mcp-management/assets/tools.json +3146 -0
  295. package/templates/claude/skills/mcp-management/references/configuration.md +114 -0
  296. package/templates/claude/skills/mcp-management/references/gemini-cli-integration.md +209 -0
  297. package/templates/claude/skills/mcp-management/references/mcp-protocol.md +116 -0
  298. package/templates/claude/skills/mcp-management/scripts/.env.example +10 -0
  299. package/templates/claude/skills/mcp-management/scripts/cli.ts +202 -0
  300. package/templates/claude/skills/mcp-management/scripts/mcp-client.ts +247 -0
  301. package/templates/claude/skills/mcp-management/scripts/package.json +20 -0
  302. package/templates/claude/skills/mcp-management/scripts/tsconfig.json +15 -0
  303. package/templates/claude/skills/media-processing/SKILL.md +91 -0
  304. package/templates/claude/skills/media-processing/references/common-workflows.md +132 -0
  305. package/templates/claude/skills/media-processing/references/ffmpeg-encoding.md +358 -0
  306. package/templates/claude/skills/media-processing/references/ffmpeg-filters.md +503 -0
  307. package/templates/claude/skills/media-processing/references/ffmpeg-streaming.md +395 -0
  308. package/templates/claude/skills/media-processing/references/format-compatibility.md +375 -0
  309. package/templates/claude/skills/media-processing/references/imagemagick-batch.md +612 -0
  310. package/templates/claude/skills/media-processing/references/imagemagick-editing.md +623 -0
  311. package/templates/claude/skills/media-processing/references/rmbg-background-removal.md +66 -0
  312. package/templates/claude/skills/media-processing/references/troubleshooting.md +109 -0
  313. package/templates/claude/skills/media-processing/scripts/README.md +102 -0
  314. package/templates/claude/skills/media-processing/scripts/batch-remove-background.sh +124 -0
  315. package/templates/claude/skills/media-processing/scripts/batch_resize.py +342 -0
  316. package/templates/claude/skills/media-processing/scripts/media_convert.py +311 -0
  317. package/templates/claude/skills/media-processing/scripts/remove-background.sh +96 -0
  318. package/templates/claude/skills/media-processing/scripts/remove-bg-node.js +181 -0
  319. package/templates/claude/skills/mermaidjs-v11/SKILL.md +115 -0
  320. package/templates/claude/skills/mermaidjs-v11/references/cli-usage.md +228 -0
  321. package/templates/claude/skills/mermaidjs-v11/references/configuration.md +232 -0
  322. package/templates/claude/skills/mermaidjs-v11/references/diagram-types.md +315 -0
  323. package/templates/claude/skills/mermaidjs-v11/references/examples.md +344 -0
  324. package/templates/claude/skills/mermaidjs-v11/references/integration.md +310 -0
  325. package/templates/claude/skills/planning/SKILL.md +115 -0
  326. package/templates/claude/skills/planning/references/codebase-understanding.md +62 -0
  327. package/templates/claude/skills/planning/references/output-standards.md +127 -0
  328. package/templates/claude/skills/planning/references/plan-organization.md +150 -0
  329. package/templates/claude/skills/planning/references/research-phase.md +49 -0
  330. package/templates/claude/skills/planning/references/solution-design.md +63 -0
  331. package/templates/claude/skills/plans-kanban/SKILL.md +157 -0
  332. package/templates/claude/skills/plans-kanban/assets/dashboard-template.html +119 -0
  333. package/templates/claude/skills/plans-kanban/assets/dashboard.css +1594 -0
  334. package/templates/claude/skills/plans-kanban/assets/dashboard.js +659 -0
  335. package/templates/claude/skills/plans-kanban/assets/favicon.png +0 -0
  336. package/templates/claude/skills/plans-kanban/package.json +13 -0
  337. package/templates/claude/skills/plans-kanban/scripts/lib/dashboard-renderer.cjs +941 -0
  338. package/templates/claude/skills/plans-kanban/scripts/lib/http-server.cjs +310 -0
  339. package/templates/claude/skills/plans-kanban/scripts/lib/plan-metadata-extractor.cjs +489 -0
  340. package/templates/claude/skills/plans-kanban/scripts/lib/plan-parser.cjs +194 -0
  341. package/templates/claude/skills/plans-kanban/scripts/lib/plan-scanner.cjs +277 -0
  342. package/templates/claude/skills/plans-kanban/scripts/lib/port-finder.cjs +49 -0
  343. package/templates/claude/skills/plans-kanban/scripts/lib/process-mgr.cjs +128 -0
  344. package/templates/claude/skills/plans-kanban/scripts/server.cjs +249 -0
  345. package/templates/claude/skills/problem-solving/SKILL.md +96 -0
  346. package/templates/claude/skills/problem-solving/references/attribution.md +69 -0
  347. package/templates/claude/skills/problem-solving/references/collision-zone-thinking.md +79 -0
  348. package/templates/claude/skills/problem-solving/references/inversion-exercise.md +91 -0
  349. package/templates/claude/skills/problem-solving/references/meta-pattern-recognition.md +87 -0
  350. package/templates/claude/skills/problem-solving/references/scale-game.md +95 -0
  351. package/templates/claude/skills/problem-solving/references/simplification-cascades.md +80 -0
  352. package/templates/claude/skills/problem-solving/references/when-stuck.md +72 -0
  353. package/templates/claude/skills/registry.json +258 -0
  354. package/templates/claude/skills/repomix/SKILL.md +247 -0
  355. package/templates/claude/skills/repomix/references/configuration.md +211 -0
  356. package/templates/claude/skills/repomix/references/usage-patterns.md +232 -0
  357. package/templates/claude/skills/repomix/scripts/README.md +179 -0
  358. package/templates/claude/skills/repomix/scripts/repomix_batch.py +455 -0
  359. package/templates/claude/skills/repomix/scripts/repos.example.json +15 -0
  360. package/templates/claude/skills/research/SKILL.md +168 -0
  361. package/templates/claude/skills/sequential-thinking/.env.example +8 -0
  362. package/templates/claude/skills/sequential-thinking/README.md +183 -0
  363. package/templates/claude/skills/sequential-thinking/SKILL.md +94 -0
  364. package/templates/claude/skills/sequential-thinking/package.json +31 -0
  365. package/templates/claude/skills/sequential-thinking/references/advanced-strategies.md +79 -0
  366. package/templates/claude/skills/sequential-thinking/references/advanced-techniques.md +76 -0
  367. package/templates/claude/skills/sequential-thinking/references/core-patterns.md +95 -0
  368. package/templates/claude/skills/sequential-thinking/references/examples-api.md +88 -0
  369. package/templates/claude/skills/sequential-thinking/references/examples-architecture.md +94 -0
  370. package/templates/claude/skills/sequential-thinking/references/examples-debug.md +90 -0
  371. package/templates/claude/skills/sequential-thinking/scripts/format-thought.js +182 -0
  372. package/templates/claude/skills/sequential-thinking/scripts/process-thought.js +252 -0
  373. package/templates/claude/skills/skill-creator/LICENSE.txt +202 -0
  374. package/templates/claude/skills/skill-creator/SKILL.md +266 -0
  375. package/templates/claude/skills/skill-creator/references/agent-skills-spec.md +51 -0
  376. package/templates/claude/skills/skill-creator/scripts/encoding_utils.py +21 -0
  377. package/templates/claude/skills/skill-creator/scripts/init_skill.py +304 -0
  378. package/templates/claude/skills/skill-creator/scripts/package_skill.py +110 -0
  379. package/templates/claude/skills/skill-creator/scripts/quick_validate.py +66 -0
  380. package/templates/claude/skills/template-skill/SKILL.md +6 -0
  381. package/templates/claude/skills/vitest/SKILL.md +595 -0
  382. package/templates/claude/skills/vitest/references/async-patterns.md +82 -0
  383. package/templates/claude/skills/vitest/references/mock-patterns.md +78 -0
  384. package/templates/claude/skills/vitest/references/monorepo-setup.md +185 -0
  385. package/templates/claude/skills/vitest/references/turborepo-setup.md +332 -0
  386. package/templates/claude/skills/web-frameworks/SKILL.md +324 -0
  387. package/templates/claude/skills/web-frameworks/references/nextjs-app-router.md +465 -0
  388. package/templates/claude/skills/web-frameworks/references/nextjs-data-fetching.md +459 -0
  389. package/templates/claude/skills/web-frameworks/references/nextjs-optimization.md +511 -0
  390. package/templates/claude/skills/web-frameworks/references/nextjs-server-components.md +495 -0
  391. package/templates/claude/skills/web-frameworks/references/remix-icon-integration.md +603 -0
  392. package/templates/claude/skills/web-frameworks/references/turborepo-caching.md +551 -0
  393. package/templates/claude/skills/web-frameworks/references/turborepo-pipelines.md +517 -0
  394. package/templates/claude/skills/web-frameworks/references/turborepo-setup.md +542 -0
  395. package/templates/claude/skills/web-frameworks/scripts/nextjs_init.py +547 -0
  396. package/templates/claude/skills/web-frameworks/scripts/turborepo_migrate.py +394 -0
  397. package/templates/claude/workflows/development-rules.md +40 -0
  398. package/templates/claude/workflows/documentation-management.md +121 -0
  399. package/templates/claude/workflows/orchestration-protocol.md +16 -0
  400. package/templates/claude/workflows/primary-workflow.md +45 -0
  401. package/templates/claude/workflows/registry.json +37 -0
  402. package/templates/common/.cct.json +41 -0
  403. package/templates/common/.cctkignore +22 -0
  404. package/templates/common/.env.example +39 -0
  405. package/templates/common/.mcp.json.example +16 -0
  406. package/templates/common/metadata.json +15 -0
  407. package/templates/common/settings.json +79 -0
  408. package/templates/common/statusline.cjs +271 -0
  409. package/templates/config/.repomixignore +22 -0
  410. package/templates/config/AGENTS.md +55 -0
  411. package/templates/config/CLAUDE.md +87 -0
  412. package/templates/plans/bug-fix-template.md +69 -0
  413. package/templates/plans/feature-implementation-template.md +84 -0
  414. package/templates/plans/refactor-template.md +82 -0
  415. package/templates/plans/template-usage-guide.md +58 -0
@@ -0,0 +1,595 @@
1
+ ---
2
+ name: vitest
3
+ description: >
4
+ Write high-quality Vitest tests for Next.js applications and shared monorepo packages
5
+ (hooks, utilities, components). Use this skill whenever the user asks to write, fix,
6
+ generate, or improve tests using Vitest — including unit tests, component tests, hook
7
+ tests, mocking strategies, test setup, and coverage. Trigger for any request involving
8
+ "test", "spec", "vitest", "testing-library", or "mock" in a TypeScript/React/Next.js context.
9
+ Also trigger when the user shares a source file and asks "write tests for this" or
10
+ "how do I test this".
11
+ license: MIT
12
+ version: 1.0.0
13
+ ---
14
+
15
+ # Vitest Testing Skill
16
+
17
+ A guide for writing production-quality Vitest tests in Next.js monorepos with shared
18
+ packages (components, hooks, utilities).
19
+
20
+ ---
21
+
22
+ ## Detect the Repo Context First
23
+
24
+ **Before giving any setup advice or config examples, check which environment you're in.** The right configuration differs significantly across setups.
25
+
26
+ ### Step 1 — Identify the repo type
27
+
28
+ Look for these signals (check files the user shares, or ask them to run `ls` at the root):
29
+
30
+ | Signal | Conclusion |
31
+ |---|---|
32
+ | `turbo.json` present at root | **Turborepo monorepo** → follow [Turborepo section](#turborepo-monorepo) |
33
+ | `pnpm-workspace.yaml` or `lerna.json` or `nx.json` but no `turbo.json` | **Other monorepo** → follow [Generic Monorepo section](#generic-monorepo) |
34
+ | Single `package.json` at root, no workspace config | **Standalone project** → follow [Standalone section](#standalone-project) |
35
+
36
+ If unsure, ask: *"Does your project have a `turbo.json` at the root? Or is it a single-package project?"*
37
+
38
+ ### Step 2 — Jump to the right config section
39
+
40
+ - Turborepo → [Turborepo Monorepo](#turborepo-monorepo)
41
+ - Other monorepo → [Generic Monorepo](#generic-monorepo)
42
+ - Single project → [Standalone Project](#standalone-project)
43
+
44
+ ---
45
+
46
+ ## Stack Assumptions
47
+
48
+ Unless told otherwise, assume:
49
+ - **Vitest** as the test runner
50
+ - **@testing-library/react** + **@testing-library/user-event** for component/hook tests
51
+ - **@testing-library/jest-dom** for DOM matchers (`toBeInTheDocument`, etc.)
52
+ - **MSW v2** for API mocking (when network calls are involved)
53
+ - **TypeScript** throughout
54
+
55
+ If the user's stack differs from any of the above, adapt accordingly.
56
+
57
+ ---
58
+
59
+ ## Quick Decision Tree
60
+
61
+ Before writing any test, identify what you're testing:
62
+
63
+ | Subject | Strategy | Reference |
64
+ |---|---|---|
65
+ | Pure function / utility | Unit test, no rendering | [→ Utilities](#utilities) |
66
+ | Custom React hook | `renderHook` from testing-library | [→ Hooks](#hooks) |
67
+ | React component (presentational) | `render` + assertions | [→ Components](#components) |
68
+ | React component (with data fetching) | MSW + `render` | [→ Async Components](#async-components) |
69
+ | Next.js page / route handler | Per-file mocking of `next/*` | [→ Next.js Specifics](#nextjs-specifics) |
70
+ | Context / Provider | Wrap with provider in `render` | [→ Components](#components) |
71
+
72
+ ---
73
+
74
+ ## Standalone Project
75
+
76
+ A single `package.json`, no workspaces. Simple and self-contained.
77
+
78
+ ```ts
79
+ // vitest.config.ts
80
+ import { defineConfig } from 'vitest/config'
81
+ import react from '@vitejs/plugin-react'
82
+ import tsconfigPaths from 'vite-tsconfig-paths'
83
+
84
+ export default defineConfig({
85
+ plugins: [react(), tsconfigPaths()],
86
+ test: {
87
+ environment: 'jsdom',
88
+ globals: true,
89
+ setupFiles: ['./src/test/setup.ts'],
90
+ coverage: {
91
+ provider: 'v8',
92
+ reporter: ['text', 'lcov'],
93
+ },
94
+ },
95
+ })
96
+ ```
97
+
98
+ ```ts
99
+ // src/test/setup.ts
100
+ import '@testing-library/jest-dom'
101
+ import { afterEach } from 'vitest'
102
+ import { cleanup } from '@testing-library/react'
103
+
104
+ afterEach(() => cleanup())
105
+ ```
106
+
107
+ Run: `vitest` / `vitest run --coverage`
108
+
109
+ ---
110
+
111
+ ## Generic Monorepo
112
+
113
+ A monorepo without Turborepo (Lerna, Nx, bare pnpm workspaces, etc.). Each package has its own `vitest.config.ts`; a root `vitest.workspace.ts` ties them together.
114
+
115
+ ```ts
116
+ // vitest.workspace.ts (root)
117
+ import { defineWorkspace } from 'vitest/config'
118
+
119
+ export default defineWorkspace([
120
+ 'packages/*/vitest.config.ts',
121
+ 'apps/*/vitest.config.ts',
122
+ ])
123
+ ```
124
+
125
+ Per-package config and shared `test-utils` setup: see [`references/monorepo-setup.md`](./references/monorepo-setup.md).
126
+
127
+ Run all: `vitest --workspace` | Single package: `vitest --project ui`
128
+
129
+ ---
130
+
131
+ ## Turborepo Monorepo
132
+
133
+ > **Use this section when `turbo.json` is present at the root.**
134
+
135
+ For the complete Turborepo setup guide, read [`references/turborepo-setup.md`](./references/turborepo-setup.md).
136
+
137
+ **Key differences from a generic monorepo:**
138
+
139
+ - Tests are run **per-package** via `turbo run test` — Turborepo caches results and only re-runs packages affected by changes
140
+ - Each package must declare a `"test"` script in its `package.json`
141
+ - A root `vitest.workspace.ts` is **optional** — Turborepo orchestrates runs itself, so you may not need it
142
+ - `turbo.json` must declare `test` as a task with correct `inputs` so caching works correctly
143
+
144
+ **Minimal `turbo.json` task definition:**
145
+
146
+ ```json
147
+ {
148
+ "$schema": "https://turbo.build/schema.json",
149
+ "tasks": {
150
+ "test": {
151
+ "dependsOn": ["^build"],
152
+ "inputs": ["src/**/*.ts", "src/**/*.tsx", "**/*.test.ts", "**/*.test.tsx"],
153
+ "outputs": ["coverage/**"],
154
+ "cache": true
155
+ },
156
+ "test:watch": {
157
+ "cache": false,
158
+ "persistent": true
159
+ }
160
+ }
161
+ }
162
+ ```
163
+
164
+ **Each package's `package.json`:**
165
+
166
+ ```json
167
+ {
168
+ "scripts": {
169
+ "test": "vitest run",
170
+ "test:watch": "vitest",
171
+ "test:coverage": "vitest run --coverage"
172
+ }
173
+ }
174
+ ```
175
+
176
+ **Running tests:**
177
+
178
+ ```bash
179
+ # All packages (respects cache — skips unchanged packages)
180
+ turbo run test
181
+
182
+ # Force re-run everything, ignore cache
183
+ turbo run test --force
184
+
185
+ # Only packages affected by current git changes
186
+ turbo run test --filter=...[HEAD^1]
187
+
188
+ # Single package by name
189
+ turbo run test --filter=@acme/ui
190
+
191
+ # Single package + its dependents
192
+ turbo run test --filter=@acme/ui...
193
+
194
+ # Watch mode (not cached — use directly in the package)
195
+ cd packages/ui && pnpm test:watch
196
+ ```
197
+
198
+ > ⚠️ Don't run `vitest --workspace` from the root in a Turborepo project — it bypasses Turborepo's cache and task graph. Always go through `turbo run test`.
199
+
200
+ ---
201
+
202
+ ## Utilities
203
+
204
+ Pure functions are the easiest to test. Be exhaustive: happy path, edge cases, error cases.
205
+
206
+ ```ts
207
+ // packages/utils/src/format.test.ts
208
+ import { describe, it, expect } from 'vitest'
209
+ import { formatCurrency } from './format'
210
+
211
+ describe('formatCurrency', () => {
212
+ it('formats a positive number', () => {
213
+ expect(formatCurrency(1234.5)).toBe('$1,234.50')
214
+ })
215
+
216
+ it('handles zero', () => {
217
+ expect(formatCurrency(0)).toBe('$0.00')
218
+ })
219
+
220
+ it('handles negative numbers', () => {
221
+ expect(formatCurrency(-50)).toBe('-$50.00')
222
+ })
223
+
224
+ it('throws for non-numeric input', () => {
225
+ expect(() => formatCurrency(NaN)).toThrow()
226
+ })
227
+ })
228
+ ```
229
+
230
+ **Checklist:**
231
+ - [ ] Happy path
232
+ - [ ] Boundary / edge values (0, empty string, null, undefined)
233
+ - [ ] Error / invalid input
234
+ - [ ] All significant branches of logic
235
+
236
+ ---
237
+
238
+ ## Hooks
239
+
240
+ Use `renderHook` + `act` for custom hooks. Never test implementation details — test observable behavior.
241
+
242
+ ```ts
243
+ // packages/hooks/src/useCounter.test.ts
244
+ import { describe, it, expect } from 'vitest'
245
+ import { renderHook, act } from '@testing-library/react'
246
+ import { useCounter } from './useCounter'
247
+
248
+ describe('useCounter', () => {
249
+ it('initializes with the given value', () => {
250
+ const { result } = renderHook(() => useCounter(5))
251
+ expect(result.current.count).toBe(5)
252
+ })
253
+
254
+ it('increments the count', () => {
255
+ const { result } = renderHook(() => useCounter(0))
256
+ act(() => result.current.increment())
257
+ expect(result.current.count).toBe(1)
258
+ })
259
+
260
+ it('does not go below 0 when decrementing', () => {
261
+ const { result } = renderHook(() => useCounter(0))
262
+ act(() => result.current.decrement())
263
+ expect(result.current.count).toBe(0)
264
+ })
265
+ })
266
+ ```
267
+
268
+ ### Hooks that use context
269
+
270
+ ```ts
271
+ import { renderHook } from '@testing-library/react'
272
+ import { ThemeProvider } from '../ThemeProvider'
273
+
274
+ const wrapper = ({ children }: { children: React.ReactNode }) => (
275
+ <ThemeProvider defaultTheme="dark">{children}</ThemeProvider>
276
+ )
277
+
278
+ const { result } = renderHook(() => useTheme(), { wrapper })
279
+ ```
280
+
281
+ ### Hooks with async operations
282
+
283
+ ```ts
284
+ import { waitFor } from '@testing-library/react'
285
+
286
+ it('fetches user data', async () => {
287
+ const { result } = renderHook(() => useUser('user-1'))
288
+ await waitFor(() => expect(result.current.isLoading).toBe(false))
289
+ expect(result.current.data?.name).toBe('Alice')
290
+ })
291
+ ```
292
+
293
+ ---
294
+
295
+ ## Components
296
+
297
+ ### Basic rendering and interactions
298
+
299
+ ```ts
300
+ // packages/ui/src/Button.test.tsx
301
+ import { describe, it, expect, vi } from 'vitest'
302
+ import { render, screen } from '@testing-library/react'
303
+ import userEvent from '@testing-library/user-event'
304
+ import { Button } from './Button'
305
+
306
+ describe('Button', () => {
307
+ it('renders its label', () => {
308
+ render(<Button>Save</Button>)
309
+ expect(screen.getByRole('button', { name: 'Save' })).toBeInTheDocument()
310
+ })
311
+
312
+ it('calls onClick when clicked', async () => {
313
+ const user = userEvent.setup()
314
+ const handleClick = vi.fn()
315
+ render(<Button onClick={handleClick}>Save</Button>)
316
+ await user.click(screen.getByRole('button', { name: 'Save' }))
317
+ expect(handleClick).toHaveBeenCalledOnce()
318
+ })
319
+
320
+ it('is disabled when the disabled prop is set', () => {
321
+ render(<Button disabled>Save</Button>)
322
+ expect(screen.getByRole('button')).toBeDisabled()
323
+ })
324
+ })
325
+ ```
326
+
327
+ ### Query priority (in order of preference)
328
+
329
+ 1. `getByRole` — mirrors how assistive tech sees the page
330
+ 2. `getByLabelText` — for form elements
331
+ 3. `getByPlaceholderText` — fallback for inputs
332
+ 4. `getByText` — for non-interactive text
333
+ 5. `getByTestId` — last resort only
334
+
335
+ Avoid `getByClassName` or DOM traversal — tests will break on refactors.
336
+
337
+ ### Form interactions
338
+
339
+ ```ts
340
+ it('submits with the entered email', async () => {
341
+ const user = userEvent.setup()
342
+ const onSubmit = vi.fn()
343
+ render(<LoginForm onSubmit={onSubmit} />)
344
+
345
+ await user.type(screen.getByLabelText('Email'), 'alice@example.com')
346
+ await user.type(screen.getByLabelText('Password'), 'secret123')
347
+ await user.click(screen.getByRole('button', { name: /sign in/i }))
348
+
349
+ expect(onSubmit).toHaveBeenCalledWith({
350
+ email: 'alice@example.com',
351
+ password: 'secret123',
352
+ })
353
+ })
354
+ ```
355
+
356
+ ### Testing error states and conditional rendering
357
+
358
+ ```ts
359
+ it('shows validation error for an empty email', async () => {
360
+ const user = userEvent.setup()
361
+ render(<LoginForm onSubmit={vi.fn()} />)
362
+ await user.click(screen.getByRole('button', { name: /sign in/i }))
363
+ expect(screen.getByText('Email is required')).toBeInTheDocument()
364
+ })
365
+ ```
366
+
367
+ ---
368
+
369
+ ## Async Components
370
+
371
+ Use **MSW v2** to intercept fetch/axios calls at the network level.
372
+
373
+ ### MSW setup (`src/test/server.ts`)
374
+
375
+ ```ts
376
+ import { setupServer } from 'msw/node'
377
+ import { http, HttpResponse } from 'msw'
378
+
379
+ export const handlers = [
380
+ http.get('/api/users/:id', ({ params }) => {
381
+ return HttpResponse.json({ id: params.id, name: 'Alice' })
382
+ }),
383
+ ]
384
+
385
+ export const server = setupServer(...handlers)
386
+ ```
387
+
388
+ ### Wire up MSW in `setup.ts`
389
+
390
+ ```ts
391
+ import { server } from './server'
392
+ import { beforeAll, afterEach, afterAll } from 'vitest'
393
+
394
+ beforeAll(() => server.listen({ onUnhandledRequest: 'error' }))
395
+ afterEach(() => server.resetHandlers())
396
+ afterAll(() => server.close())
397
+ ```
398
+
399
+ ### Override handlers per-test
400
+
401
+ ```ts
402
+ import { http, HttpResponse } from 'msw'
403
+ import { server } from '@/test/server'
404
+
405
+ it('shows an error on API failure', async () => {
406
+ server.use(
407
+ http.get('/api/users/:id', () => HttpResponse.json({ message: 'Not found' }, { status: 404 }))
408
+ )
409
+ render(<UserProfile userId="user-1" />)
410
+ expect(await screen.findByText('User not found')).toBeInTheDocument()
411
+ })
412
+ ```
413
+
414
+ ---
415
+
416
+ ## Mocking
417
+
418
+ ### Module mocks (`vi.mock`)
419
+
420
+ ```ts
421
+ // Mock an entire module
422
+ vi.mock('@/lib/analytics', () => ({
423
+ track: vi.fn(),
424
+ identify: vi.fn(),
425
+ }))
426
+
427
+ // Access the mock in tests
428
+ import { track } from '@/lib/analytics'
429
+ expect(vi.mocked(track)).toHaveBeenCalledWith('button_clicked', { label: 'Save' })
430
+ ```
431
+
432
+ ### Partial mocks
433
+
434
+ ```ts
435
+ vi.mock('@/lib/date', async (importOriginal) => {
436
+ const actual = await importOriginal<typeof import('@/lib/date')>()
437
+ return { ...actual, now: vi.fn(() => new Date('2024-01-01')) }
438
+ })
439
+ ```
440
+
441
+ ### Spying on methods
442
+
443
+ ```ts
444
+ import * as storageModule from '@/lib/storage'
445
+
446
+ it('calls localStorage.setItem', () => {
447
+ const spy = vi.spyOn(storageModule, 'saveToStorage')
448
+ render(<SettingsForm />)
449
+ // ... interact
450
+ expect(spy).toHaveBeenCalled()
451
+ })
452
+ ```
453
+
454
+ ### Mocking `next/navigation`
455
+
456
+ ```ts
457
+ vi.mock('next/navigation', () => ({
458
+ useRouter: () => ({ push: vi.fn(), replace: vi.fn(), back: vi.fn() }),
459
+ usePathname: () => '/dashboard',
460
+ useSearchParams: () => new URLSearchParams(),
461
+ }))
462
+ ```
463
+
464
+ ### Mocking `next/image` and `next/link`
465
+
466
+ ```ts
467
+ vi.mock('next/image', () => ({
468
+ default: (props: React.ImgHTMLAttributes<HTMLImageElement>) => <img {...props} />,
469
+ }))
470
+
471
+ vi.mock('next/link', () => ({
472
+ default: ({ href, children }: { href: string; children: React.ReactNode }) => (
473
+ <a href={href}>{children}</a>
474
+ ),
475
+ }))
476
+ ```
477
+
478
+ ---
479
+
480
+ ## Next.js Specifics
481
+
482
+ ### Server Components
483
+
484
+ Server Components can't be rendered with testing-library directly. Two strategies:
485
+
486
+ 1. **Extract logic** into a utility or hook and test that instead (preferred)
487
+ 2. **Integration test** via Playwright/Cypress for full page behavior
488
+
489
+ ### Route Handlers (`app/api/*/route.ts`)
490
+
491
+ ```ts
492
+ // app/api/hello/route.test.ts
493
+ import { GET } from './route'
494
+ import { NextRequest } from 'next/server'
495
+
496
+ it('returns 200 with a greeting', async () => {
497
+ const req = new NextRequest('http://localhost/api/hello')
498
+ const res = await GET(req)
499
+ const body = await res.json()
500
+
501
+ expect(res.status).toBe(200)
502
+ expect(body.message).toBe('Hello')
503
+ })
504
+ ```
505
+
506
+ ### Middleware
507
+
508
+ Test middleware by importing the function directly and passing a mock `NextRequest`:
509
+
510
+ ```ts
511
+ import { middleware } from './middleware'
512
+ import { NextRequest } from 'next/server'
513
+
514
+ it('redirects unauthenticated users', async () => {
515
+ const req = new NextRequest('http://localhost/dashboard')
516
+ const res = await middleware(req)
517
+ expect(res.status).toBe(307)
518
+ expect(res.headers.get('location')).toContain('/login')
519
+ })
520
+ ```
521
+
522
+ ---
523
+
524
+ ## Shared Packages (Monorepo Patterns)
525
+
526
+ ### Path aliases across packages
527
+
528
+ In each package's `vitest.config.ts`, use `vite-tsconfig-paths` so `@/` aliases resolve correctly:
529
+
530
+ ```ts
531
+ import tsconfigPaths from 'vite-tsconfig-paths'
532
+ // add to plugins: [tsconfigPaths()]
533
+ ```
534
+
535
+ ### Shared test utilities
536
+
537
+ Create a `packages/test-utils` package (works for both Turborepo and generic monorepos):
538
+
539
+ ```ts
540
+ // packages/test-utils/src/render.tsx
541
+ import { render as rtlRender, RenderOptions } from '@testing-library/react'
542
+ import { AllProviders } from './AllProviders' // QueryClient, Theme, etc.
543
+
544
+ export function render(ui: React.ReactElement, options?: RenderOptions) {
545
+ return rtlRender(ui, { wrapper: AllProviders, ...options })
546
+ }
547
+
548
+ export * from '@testing-library/react'
549
+ ```
550
+
551
+ Import this custom `render` in all tests to avoid boilerplate provider wrapping.
552
+
553
+ **In Turborepo:** make sure `@acme/test-utils` is listed as a `devDependency` in each package that uses it, and that `turbo.json` includes `"^build"` in the `test` task's `dependsOn` so the test-utils package is built before tests run.
554
+
555
+ ---
556
+
557
+ ## Best Practices
558
+
559
+ **DO:**
560
+ - Test behavior, not implementation (no asserting on internal state or private methods)
561
+ - Use `screen` queries over destructured render results
562
+ - Use `userEvent` over `fireEvent` (more realistic)
563
+ - Use `findBy*` for async elements (it automatically waits)
564
+ - Group related tests with `describe`
565
+ - Name tests as sentences: `it('shows an error when the email is invalid')`
566
+ - Clean up mocks in `afterEach` or use `vi.restoreAllMocks()`
567
+
568
+ **DON'T:**
569
+ - Assert on CSS classes or styles (fragile)
570
+ - Use `getByTestId` unless absolutely necessary
571
+ - Test third-party library behavior
572
+ - Snapshot test large component trees (hard to maintain)
573
+ - Use `waitFor` just to delay — prefer `findBy*` for element appearance
574
+
575
+ ---
576
+
577
+ ## Coverage Targets (suggested)
578
+
579
+ | Package type | Line coverage target |
580
+ |---|---|
581
+ | Utilities / pure functions | 95%+ |
582
+ | Hooks | 85%+ |
583
+ | UI components | 75%+ |
584
+ | Next.js pages | 60%+ (supplement with e2e) |
585
+
586
+ Run coverage: `vitest run --coverage`
587
+
588
+ ---
589
+
590
+ ## Reference Files
591
+
592
+ - [→ `references/mock-patterns.md`](./references/mock-patterns.md) — Advanced mocking patterns (timers, globals, env vars)
593
+ - [→ `references/async-patterns.md`](./references/async-patterns.md) — Async testing, loading states, error boundaries
594
+ - [→ `references/monorepo-setup.md`](./references/monorepo-setup.md) — Generic monorepo config (shared test-utils, path aliases, workspace setup)
595
+ - [→ `references/turborepo-setup.md`](./references/turborepo-setup.md) — Full Turborepo setup (task config, caching, pipeline, CI)
@@ -0,0 +1,82 @@
1
+ # Async Testing Patterns
2
+
3
+ ## Loading states
4
+
5
+ ```ts
6
+ it('shows a spinner while loading', () => {
7
+ render(<UserProfile userId="1" />)
8
+ expect(screen.getByRole('progressbar')).toBeInTheDocument()
9
+ })
10
+
11
+ it('shows user data after loading', async () => {
12
+ render(<UserProfile userId="1" />)
13
+ expect(await screen.findByText('Alice')).toBeInTheDocument()
14
+ expect(screen.queryByRole('progressbar')).not.toBeInTheDocument()
15
+ })
16
+ ```
17
+
18
+ ## Error boundaries
19
+
20
+ ```ts
21
+ // Suppress the React error boundary console output
22
+ const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
23
+
24
+ it('renders the fallback on error', () => {
25
+ const ThrowingComponent = () => { throw new Error('Boom') }
26
+ render(
27
+ <ErrorBoundary fallback={<p>Something went wrong</p>}>
28
+ <ThrowingComponent />
29
+ </ErrorBoundary>
30
+ )
31
+ expect(screen.getByText('Something went wrong')).toBeInTheDocument()
32
+ consoleSpy.mockRestore()
33
+ })
34
+ ```
35
+
36
+ ## Polling / intervals
37
+
38
+ ```ts
39
+ beforeEach(() => vi.useFakeTimers())
40
+ afterEach(() => vi.useRealTimers())
41
+
42
+ it('re-fetches every 5 seconds', async () => {
43
+ render(<LivePriceWidget />)
44
+ expect(fetch).toHaveBeenCalledTimes(1)
45
+ vi.advanceTimersByTime(5000)
46
+ expect(fetch).toHaveBeenCalledTimes(2)
47
+ })
48
+ ```
49
+
50
+ ## Waiting for element removal
51
+
52
+ ```ts
53
+ it('removes the toast after 3 seconds', async () => {
54
+ render(<App />)
55
+ userEvent.click(screen.getByRole('button', { name: /notify/i }))
56
+ expect(screen.getByRole('alert')).toBeInTheDocument()
57
+ await waitForElementToBeRemoved(() => screen.queryByRole('alert'), { timeout: 4000 })
58
+ })
59
+ ```
60
+
61
+ ## React Query / SWR
62
+
63
+ Wrap with a fresh QueryClient per test to avoid cache bleed:
64
+
65
+ ```ts
66
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
67
+
68
+ function createWrapper() {
69
+ const queryClient = new QueryClient({
70
+ defaultOptions: { queries: { retry: false } },
71
+ })
72
+ return ({ children }: { children: React.ReactNode }) => (
73
+ <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
74
+ )
75
+ }
76
+
77
+ it('fetches and displays the user', async () => {
78
+ const { result } = renderHook(() => useUser('1'), { wrapper: createWrapper() })
79
+ await waitFor(() => expect(result.current.isSuccess).toBe(true))
80
+ expect(result.current.data?.name).toBe('Alice')
81
+ })
82
+ ```