@heytherevibin/skillforge 0.2.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 (402) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/CODE_OF_CONDUCT.md +34 -0
  3. package/CONTRIBUTING.md +38 -0
  4. package/LICENSE +21 -0
  5. package/README.md +337 -0
  6. package/RELEASING.md +93 -0
  7. package/SECURITY.md +31 -0
  8. package/STRATEGY.md +26 -0
  9. package/bin/cli.js +547 -0
  10. package/lib/packs.js +184 -0
  11. package/package.json +38 -0
  12. package/python/app/__init__.py +0 -0
  13. package/python/app/__pycache__/__init__.cpython-312.pyc +0 -0
  14. package/python/app/__pycache__/auth.cpython-312.pyc +0 -0
  15. package/python/app/__pycache__/main.cpython-312.pyc +0 -0
  16. package/python/app/auth.py +63 -0
  17. package/python/app/cli.py +78 -0
  18. package/python/app/db_paths.py +26 -0
  19. package/python/app/events_cli.py +175 -0
  20. package/python/app/main.py +647 -0
  21. package/python/app/materialize.py +138 -0
  22. package/python/app/mcp_server.py +610 -0
  23. package/python/app/route_cli.py +117 -0
  24. package/python/requirements-dev.txt +1 -0
  25. package/python/requirements.txt +7 -0
  26. package/python/tests/test_db_paths.py +41 -0
  27. package/skills/accessibility/SKILL.md +145 -0
  28. package/skills/agent-architecture-audit/SKILL.md +256 -0
  29. package/skills/agent-eval/SKILL.md +144 -0
  30. package/skills/agent-harness-construction/SKILL.md +72 -0
  31. package/skills/agent-introspection-debugging/SKILL.md +152 -0
  32. package/skills/agent-payment-x402/SKILL.md +224 -0
  33. package/skills/agent-sort/SKILL.md +214 -0
  34. package/skills/agentic-engineering/SKILL.md +62 -0
  35. package/skills/agentic-os/SKILL.md +386 -0
  36. package/skills/ai-first-engineering/SKILL.md +50 -0
  37. package/skills/ai-regression-testing/SKILL.md +384 -0
  38. package/skills/android-clean-architecture/SKILL.md +338 -0
  39. package/skills/angular-developer/SKILL.md +153 -0
  40. package/skills/angular-developer/references/angular-animations.md +160 -0
  41. package/skills/angular-developer/references/angular-aria.md +410 -0
  42. package/skills/angular-developer/references/cli.md +86 -0
  43. package/skills/angular-developer/references/component-harnesses.md +59 -0
  44. package/skills/angular-developer/references/component-styling.md +91 -0
  45. package/skills/angular-developer/references/components.md +117 -0
  46. package/skills/angular-developer/references/creating-services.md +97 -0
  47. package/skills/angular-developer/references/data-resolvers.md +69 -0
  48. package/skills/angular-developer/references/define-routes.md +67 -0
  49. package/skills/angular-developer/references/defining-providers.md +72 -0
  50. package/skills/angular-developer/references/di-fundamentals.md +120 -0
  51. package/skills/angular-developer/references/e2e-testing.md +56 -0
  52. package/skills/angular-developer/references/effects.md +83 -0
  53. package/skills/angular-developer/references/hierarchical-injectors.md +43 -0
  54. package/skills/angular-developer/references/host-elements.md +80 -0
  55. package/skills/angular-developer/references/injection-context.md +63 -0
  56. package/skills/angular-developer/references/inputs.md +101 -0
  57. package/skills/angular-developer/references/linked-signal.md +59 -0
  58. package/skills/angular-developer/references/loading-strategies.md +61 -0
  59. package/skills/angular-developer/references/mcp.md +108 -0
  60. package/skills/angular-developer/references/navigate-to-routes.md +69 -0
  61. package/skills/angular-developer/references/outputs.md +86 -0
  62. package/skills/angular-developer/references/reactive-forms.md +122 -0
  63. package/skills/angular-developer/references/rendering-strategies.md +44 -0
  64. package/skills/angular-developer/references/resource.md +77 -0
  65. package/skills/angular-developer/references/route-animations.md +56 -0
  66. package/skills/angular-developer/references/route-guards.md +52 -0
  67. package/skills/angular-developer/references/router-lifecycle.md +45 -0
  68. package/skills/angular-developer/references/router-testing.md +87 -0
  69. package/skills/angular-developer/references/show-routes-with-outlets.md +68 -0
  70. package/skills/angular-developer/references/signal-forms.md +795 -0
  71. package/skills/angular-developer/references/signals-overview.md +94 -0
  72. package/skills/angular-developer/references/tailwind-css.md +69 -0
  73. package/skills/angular-developer/references/template-driven-forms.md +114 -0
  74. package/skills/angular-developer/references/testing-fundamentals.md +65 -0
  75. package/skills/api-connector-builder/SKILL.md +120 -0
  76. package/skills/api-design/SKILL.md +522 -0
  77. package/skills/architecture-decision-records/SKILL.md +178 -0
  78. package/skills/article-writing/SKILL.md +78 -0
  79. package/skills/automation-audit-ops/SKILL.md +141 -0
  80. package/skills/autonomous-agent-harness/SKILL.md +272 -0
  81. package/skills/autonomous-loops/SKILL.md +609 -0
  82. package/skills/backend-patterns/SKILL.md +560 -0
  83. package/skills/benchmark/SKILL.md +92 -0
  84. package/skills/blueprint/SKILL.md +104 -0
  85. package/skills/browser-qa/SKILL.md +86 -0
  86. package/skills/bun-runtime/SKILL.md +83 -0
  87. package/skills/canary-watch/SKILL.md +98 -0
  88. package/skills/carrier-relationship-management/SKILL.md +211 -0
  89. package/skills/cisco-ios-patterns/SKILL.md +163 -0
  90. package/skills/ck/SKILL.md +147 -0
  91. package/skills/ck/commands/forget.mjs +44 -0
  92. package/skills/ck/commands/info.mjs +24 -0
  93. package/skills/ck/commands/init.mjs +143 -0
  94. package/skills/ck/commands/list.mjs +40 -0
  95. package/skills/ck/commands/migrate.mjs +202 -0
  96. package/skills/ck/commands/resume.mjs +36 -0
  97. package/skills/ck/commands/save.mjs +210 -0
  98. package/skills/ck/commands/shared.mjs +387 -0
  99. package/skills/ck/hooks/session-start.mjs +224 -0
  100. package/skills/claude-devfleet/SKILL.md +103 -0
  101. package/skills/click-path-audit/SKILL.md +244 -0
  102. package/skills/clickhouse-io/SKILL.md +438 -0
  103. package/skills/code-tour/SKILL.md +235 -0
  104. package/skills/codebase-onboarding/SKILL.md +232 -0
  105. package/skills/coding-standards/SKILL.md +548 -0
  106. package/skills/compose-multiplatform-patterns/SKILL.md +298 -0
  107. package/skills/connections-optimizer/SKILL.md +188 -0
  108. package/skills/content-engine/SKILL.md +126 -0
  109. package/skills/content-hash-cache-pattern/SKILL.md +160 -0
  110. package/skills/context-budget/SKILL.md +134 -0
  111. package/skills/continuous-agent-loop/SKILL.md +44 -0
  112. package/skills/continuous-learning/SKILL.md +129 -0
  113. package/skills/continuous-learning/config.json +18 -0
  114. package/skills/continuous-learning/evaluate-session.sh +69 -0
  115. package/skills/continuous-learning-v2/SKILL.md +358 -0
  116. package/skills/continuous-learning-v2/agents/observer-loop.sh +322 -0
  117. package/skills/continuous-learning-v2/agents/observer.md +198 -0
  118. package/skills/continuous-learning-v2/agents/session-guardian.sh +150 -0
  119. package/skills/continuous-learning-v2/agents/start-observer.sh +248 -0
  120. package/skills/continuous-learning-v2/config.json +8 -0
  121. package/skills/continuous-learning-v2/hooks/observe.sh +476 -0
  122. package/skills/continuous-learning-v2/scripts/detect-project.sh +288 -0
  123. package/skills/continuous-learning-v2/scripts/instinct-cli.py +1519 -0
  124. package/skills/continuous-learning-v2/scripts/lib/homunculus-dir.sh +31 -0
  125. package/skills/continuous-learning-v2/scripts/migrate-homunculus.sh +62 -0
  126. package/skills/continuous-learning-v2/scripts/test_parse_instinct.py +1018 -0
  127. package/skills/cost-aware-llm-pipeline/SKILL.md +182 -0
  128. package/skills/cost-tracking/SKILL.md +147 -0
  129. package/skills/council/SKILL.md +202 -0
  130. package/skills/cpp-coding-standards/SKILL.md +722 -0
  131. package/skills/cpp-testing/SKILL.md +323 -0
  132. package/skills/crosspost/SKILL.md +110 -0
  133. package/skills/csharp-testing/SKILL.md +320 -0
  134. package/skills/customer-billing-ops/SKILL.md +139 -0
  135. package/skills/customs-trade-compliance/SKILL.md +262 -0
  136. package/skills/dart-flutter-patterns/SKILL.md +562 -0
  137. package/skills/dashboard-builder/SKILL.md +108 -0
  138. package/skills/data-scraper-agent/SKILL.md +764 -0
  139. package/skills/database-migrations/SKILL.md +428 -0
  140. package/skills/deep-research/SKILL.md +158 -0
  141. package/skills/defi-amm-security/SKILL.md +166 -0
  142. package/skills/deployment-patterns/SKILL.md +426 -0
  143. package/skills/design-system/SKILL.md +81 -0
  144. package/skills/django-celery/SKILL.md +456 -0
  145. package/skills/django-patterns/SKILL.md +733 -0
  146. package/skills/django-security/SKILL.md +592 -0
  147. package/skills/django-tdd/SKILL.md +728 -0
  148. package/skills/django-verification/SKILL.md +468 -0
  149. package/skills/dmux-workflows/SKILL.md +190 -0
  150. package/skills/docker-patterns/SKILL.md +363 -0
  151. package/skills/documentation-lookup/SKILL.md +89 -0
  152. package/skills/dotnet-patterns/SKILL.md +320 -0
  153. package/skills/e2e-testing/SKILL.md +325 -0
  154. package/skills/email-ops/SKILL.md +120 -0
  155. package/skills/energy-procurement/SKILL.md +227 -0
  156. package/skills/enterprise-agent-ops/SKILL.md +49 -0
  157. package/skills/error-handling/SKILL.md +375 -0
  158. package/skills/eval-harness/SKILL.md +269 -0
  159. package/skills/evm-token-decimals/SKILL.md +130 -0
  160. package/skills/exa-search/SKILL.md +106 -0
  161. package/skills/fal-ai-media/SKILL.md +287 -0
  162. package/skills/fastapi-patterns/SKILL.md +327 -0
  163. package/skills/finance-billing-ops/SKILL.md +126 -0
  164. package/skills/flox-environments/SKILL.md +496 -0
  165. package/skills/flutter-dart-code-review/SKILL.md +434 -0
  166. package/skills/foundation-models-on-device/SKILL.md +243 -0
  167. package/skills/frontend-design-direction/SKILL.md +92 -0
  168. package/skills/frontend-patterns/SKILL.md +641 -0
  169. package/skills/frontend-slides/SKILL.md +183 -0
  170. package/skills/frontend-slides/STYLE_PRESETS.md +330 -0
  171. package/skills/frontend-slides/animation-patterns.md +122 -0
  172. package/skills/frontend-slides/html-template.md +419 -0
  173. package/skills/frontend-slides/scripts/export-pdf.sh +418 -0
  174. package/skills/frontend-slides/scripts/extract-pptx.py +96 -0
  175. package/skills/frontend-slides/viewport-base.css +153 -0
  176. package/skills/fsharp-testing/SKILL.md +279 -0
  177. package/skills/gan-style-harness/SKILL.md +278 -0
  178. package/skills/gateguard/SKILL.md +125 -0
  179. package/skills/git-workflow/SKILL.md +714 -0
  180. package/skills/github-ops/SKILL.md +143 -0
  181. package/skills/golang-patterns/SKILL.md +673 -0
  182. package/skills/golang-testing/SKILL.md +719 -0
  183. package/skills/google-workspace-ops/SKILL.md +94 -0
  184. package/skills/healthcare-cdss-patterns/SKILL.md +245 -0
  185. package/skills/healthcare-emr-patterns/SKILL.md +159 -0
  186. package/skills/healthcare-eval-harness/SKILL.md +207 -0
  187. package/skills/healthcare-phi-compliance/SKILL.md +145 -0
  188. package/skills/hermes-imports/SKILL.md +87 -0
  189. package/skills/hexagonal-architecture/SKILL.md +275 -0
  190. package/skills/hipaa-compliance/SKILL.md +78 -0
  191. package/skills/homelab-network-readiness/SKILL.md +169 -0
  192. package/skills/homelab-network-setup/SKILL.md +129 -0
  193. package/skills/homelab-pihole-dns/SKILL.md +274 -0
  194. package/skills/homelab-vlan-segmentation/SKILL.md +311 -0
  195. package/skills/homelab-wireguard-vpn/SKILL.md +305 -0
  196. package/skills/hookify-rules/SKILL.md +128 -0
  197. package/skills/inventory-demand-planning/SKILL.md +246 -0
  198. package/skills/investor-materials/SKILL.md +95 -0
  199. package/skills/investor-outreach/SKILL.md +90 -0
  200. package/skills/ios-icon-gen/SKILL.md +157 -0
  201. package/skills/ios-icon-gen/scripts/generate_icons.swift +258 -0
  202. package/skills/ios-icon-gen/scripts/iconify_gen.sh +235 -0
  203. package/skills/iterative-retrieval/SKILL.md +209 -0
  204. package/skills/java-coding-standards/SKILL.md +382 -0
  205. package/skills/jira-integration/SKILL.md +292 -0
  206. package/skills/jpa-patterns/SKILL.md +150 -0
  207. package/skills/knowledge-ops/SKILL.md +153 -0
  208. package/skills/kotlin-coroutines-flows/SKILL.md +283 -0
  209. package/skills/kotlin-exposed-patterns/SKILL.md +718 -0
  210. package/skills/kotlin-ktor-patterns/SKILL.md +688 -0
  211. package/skills/kotlin-patterns/SKILL.md +710 -0
  212. package/skills/kotlin-testing/SKILL.md +823 -0
  213. package/skills/laravel-patterns/SKILL.md +414 -0
  214. package/skills/laravel-plugin-discovery/SKILL.md +228 -0
  215. package/skills/laravel-security/SKILL.md +284 -0
  216. package/skills/laravel-tdd/SKILL.md +282 -0
  217. package/skills/laravel-verification/SKILL.md +178 -0
  218. package/skills/lead-intelligence/SKILL.md +320 -0
  219. package/skills/lead-intelligence/agents/enrichment-agent.md +85 -0
  220. package/skills/lead-intelligence/agents/mutual-mapper.md +75 -0
  221. package/skills/lead-intelligence/agents/outreach-drafter.md +98 -0
  222. package/skills/lead-intelligence/agents/signal-scorer.md +60 -0
  223. package/skills/liquid-glass-design/SKILL.md +279 -0
  224. package/skills/llm-trading-agent-security/SKILL.md +146 -0
  225. package/skills/logistics-exception-management/SKILL.md +221 -0
  226. package/skills/make-interfaces-feel-better/SKILL.md +151 -0
  227. package/skills/manim-video/SKILL.md +88 -0
  228. package/skills/manim-video/assets/network_graph_scene.py +52 -0
  229. package/skills/market-research/SKILL.md +74 -0
  230. package/skills/mcp-server-patterns/SKILL.md +68 -0
  231. package/skills/messages-ops/SKILL.md +103 -0
  232. package/skills/mle-workflow/SKILL.md +345 -0
  233. package/skills/motion-advanced/SKILL.md +596 -0
  234. package/skills/motion-foundations/SKILL.md +299 -0
  235. package/skills/motion-patterns/SKILL.md +435 -0
  236. package/skills/motion-ui/SKILL.md +574 -0
  237. package/skills/mysql-patterns/SKILL.md +411 -0
  238. package/skills/nanoclaw-repl/SKILL.md +32 -0
  239. package/skills/nestjs-patterns/SKILL.md +229 -0
  240. package/skills/netmiko-ssh-automation/SKILL.md +173 -0
  241. package/skills/network-bgp-diagnostics/SKILL.md +167 -0
  242. package/skills/network-config-validation/SKILL.md +210 -0
  243. package/skills/network-interface-health/SKILL.md +152 -0
  244. package/skills/nextjs-turbopack/SKILL.md +43 -0
  245. package/skills/nodejs-keccak256/SKILL.md +102 -0
  246. package/skills/nutrient-document-processing/SKILL.md +166 -0
  247. package/skills/nuxt4-patterns/SKILL.md +99 -0
  248. package/skills/openclaw-persona-forge/SKILL.md +288 -0
  249. package/skills/openclaw-persona-forge/gacha.py +224 -0
  250. package/skills/openclaw-persona-forge/gacha.sh +5 -0
  251. package/skills/openclaw-persona-forge/references/avatar-style.md +124 -0
  252. package/skills/openclaw-persona-forge/references/boundary-rules.md +53 -0
  253. package/skills/openclaw-persona-forge/references/error-handling.md +53 -0
  254. package/skills/openclaw-persona-forge/references/identity-tension.md +48 -0
  255. package/skills/openclaw-persona-forge/references/naming-system.md +39 -0
  256. package/skills/openclaw-persona-forge/references/output-template.md +166 -0
  257. package/skills/opensource-pipeline/SKILL.md +254 -0
  258. package/skills/perl-patterns/SKILL.md +503 -0
  259. package/skills/perl-security/SKILL.md +502 -0
  260. package/skills/perl-testing/SKILL.md +474 -0
  261. package/skills/plan-orchestrate/SKILL.md +253 -0
  262. package/skills/plankton-code-quality/SKILL.md +236 -0
  263. package/skills/postgres-patterns/SKILL.md +146 -0
  264. package/skills/product-capability/SKILL.md +140 -0
  265. package/skills/product-lens/SKILL.md +91 -0
  266. package/skills/production-audit/SKILL.md +206 -0
  267. package/skills/production-scheduling/SKILL.md +237 -0
  268. package/skills/project-flow-ops/SKILL.md +110 -0
  269. package/skills/prompt-optimizer/SKILL.md +398 -0
  270. package/skills/python-patterns/SKILL.md +749 -0
  271. package/skills/python-testing/SKILL.md +815 -0
  272. package/skills/pytorch-patterns/SKILL.md +395 -0
  273. package/skills/quality-nonconformance/SKILL.md +259 -0
  274. package/skills/quarkus-patterns/SKILL.md +721 -0
  275. package/skills/quarkus-security/SKILL.md +466 -0
  276. package/skills/quarkus-tdd/SKILL.md +810 -0
  277. package/skills/quarkus-verification/SKILL.md +478 -0
  278. package/skills/ralphinho-rfc-pipeline/SKILL.md +66 -0
  279. package/skills/redis-patterns/SKILL.md +402 -0
  280. package/skills/regex-vs-llm-structured-text/SKILL.md +219 -0
  281. package/skills/remotion-video-creation/SKILL.md +43 -0
  282. package/skills/remotion-video-creation/rules/3d.md +86 -0
  283. package/skills/remotion-video-creation/rules/animations.md +29 -0
  284. package/skills/remotion-video-creation/rules/assets/charts-bar-chart.tsx +173 -0
  285. package/skills/remotion-video-creation/rules/assets/text-animations-typewriter.tsx +100 -0
  286. package/skills/remotion-video-creation/rules/assets/text-animations-word-highlight.tsx +108 -0
  287. package/skills/remotion-video-creation/rules/assets.md +78 -0
  288. package/skills/remotion-video-creation/rules/audio.md +172 -0
  289. package/skills/remotion-video-creation/rules/calculate-metadata.md +104 -0
  290. package/skills/remotion-video-creation/rules/can-decode.md +75 -0
  291. package/skills/remotion-video-creation/rules/charts.md +58 -0
  292. package/skills/remotion-video-creation/rules/compositions.md +146 -0
  293. package/skills/remotion-video-creation/rules/display-captions.md +126 -0
  294. package/skills/remotion-video-creation/rules/extract-frames.md +229 -0
  295. package/skills/remotion-video-creation/rules/fonts.md +152 -0
  296. package/skills/remotion-video-creation/rules/get-audio-duration.md +58 -0
  297. package/skills/remotion-video-creation/rules/get-video-dimensions.md +68 -0
  298. package/skills/remotion-video-creation/rules/get-video-duration.md +58 -0
  299. package/skills/remotion-video-creation/rules/gifs.md +138 -0
  300. package/skills/remotion-video-creation/rules/images.md +130 -0
  301. package/skills/remotion-video-creation/rules/import-srt-captions.md +67 -0
  302. package/skills/remotion-video-creation/rules/lottie.md +67 -0
  303. package/skills/remotion-video-creation/rules/measuring-dom-nodes.md +34 -0
  304. package/skills/remotion-video-creation/rules/measuring-text.md +143 -0
  305. package/skills/remotion-video-creation/rules/sequencing.md +106 -0
  306. package/skills/remotion-video-creation/rules/tailwind.md +11 -0
  307. package/skills/remotion-video-creation/rules/text-animations.md +20 -0
  308. package/skills/remotion-video-creation/rules/timing.md +179 -0
  309. package/skills/remotion-video-creation/rules/transcribe-captions.md +19 -0
  310. package/skills/remotion-video-creation/rules/transitions.md +122 -0
  311. package/skills/remotion-video-creation/rules/trimming.md +52 -0
  312. package/skills/remotion-video-creation/rules/videos.md +171 -0
  313. package/skills/repo-scan/SKILL.md +78 -0
  314. package/skills/research-ops/SKILL.md +111 -0
  315. package/skills/returns-reverse-logistics/SKILL.md +239 -0
  316. package/skills/rules-distill/SKILL.md +263 -0
  317. package/skills/rules-distill/scripts/scan-rules.sh +58 -0
  318. package/skills/rules-distill/scripts/scan-skills.sh +129 -0
  319. package/skills/rust-patterns/SKILL.md +498 -0
  320. package/skills/rust-testing/SKILL.md +499 -0
  321. package/skills/safety-guard/SKILL.md +74 -0
  322. package/skills/santa-method/SKILL.md +306 -0
  323. package/skills/scientific-db-pubmed-database/SKILL.md +175 -0
  324. package/skills/scientific-db-uspto-database/SKILL.md +177 -0
  325. package/skills/scientific-pkg-gget/SKILL.md +166 -0
  326. package/skills/scientific-thinking-literature-review/SKILL.md +192 -0
  327. package/skills/scientific-thinking-scholar-evaluation/SKILL.md +160 -0
  328. package/skills/search-first/SKILL.md +181 -0
  329. package/skills/security-bounty-hunter/SKILL.md +99 -0
  330. package/skills/security-review/SKILL.md +502 -0
  331. package/skills/security-review/cloud-infrastructure-security.md +361 -0
  332. package/skills/seo/SKILL.md +153 -0
  333. package/skills/skill-comply/SKILL.md +57 -0
  334. package/skills/skill-comply/fixtures/compliant_trace.jsonl +5 -0
  335. package/skills/skill-comply/fixtures/noncompliant_trace.jsonl +3 -0
  336. package/skills/skill-comply/fixtures/tdd_spec.yaml +44 -0
  337. package/skills/skill-comply/prompts/classifier.md +24 -0
  338. package/skills/skill-comply/prompts/scenario_generator.md +62 -0
  339. package/skills/skill-comply/prompts/spec_generator.md +42 -0
  340. package/skills/skill-comply/pyproject.toml +15 -0
  341. package/skills/skill-comply/scripts/__init__.py +0 -0
  342. package/skills/skill-comply/scripts/classifier.py +85 -0
  343. package/skills/skill-comply/scripts/grader.py +124 -0
  344. package/skills/skill-comply/scripts/parser.py +107 -0
  345. package/skills/skill-comply/scripts/report.py +170 -0
  346. package/skills/skill-comply/scripts/run.py +127 -0
  347. package/skills/skill-comply/scripts/runner.py +186 -0
  348. package/skills/skill-comply/scripts/scenario_generator.py +70 -0
  349. package/skills/skill-comply/scripts/spec_generator.py +72 -0
  350. package/skills/skill-comply/scripts/utils.py +13 -0
  351. package/skills/skill-comply/tests/test_grader.py +197 -0
  352. package/skills/skill-comply/tests/test_parser.py +90 -0
  353. package/skills/skill-comply/tests/test_runner.py +172 -0
  354. package/skills/skill-scout/SKILL.md +139 -0
  355. package/skills/skill-stocktake/SKILL.md +193 -0
  356. package/skills/skill-stocktake/scripts/quick-diff.sh +87 -0
  357. package/skills/skill-stocktake/scripts/save-results.sh +56 -0
  358. package/skills/skill-stocktake/scripts/scan.sh +170 -0
  359. package/skills/social-graph-ranker/SKILL.md +153 -0
  360. package/skills/springboot-patterns/SKILL.md +313 -0
  361. package/skills/springboot-security/SKILL.md +271 -0
  362. package/skills/springboot-tdd/SKILL.md +157 -0
  363. package/skills/springboot-verification/SKILL.md +230 -0
  364. package/skills/strategic-compact/SKILL.md +129 -0
  365. package/skills/strategic-compact/suggest-compact.sh +54 -0
  366. package/skills/swift-actor-persistence/SKILL.md +142 -0
  367. package/skills/swift-concurrency-6-2/SKILL.md +216 -0
  368. package/skills/swift-protocol-di-testing/SKILL.md +189 -0
  369. package/skills/swiftui-patterns/SKILL.md +259 -0
  370. package/skills/tdd-workflow/SKILL.md +462 -0
  371. package/skills/team-builder/SKILL.md +166 -0
  372. package/skills/terminal-ops/SKILL.md +108 -0
  373. package/skills/tinystruct-patterns/SKILL.md +130 -0
  374. package/skills/tinystruct-patterns/references/architecture.md +77 -0
  375. package/skills/tinystruct-patterns/references/data-handling.md +35 -0
  376. package/skills/tinystruct-patterns/references/routing.md +57 -0
  377. package/skills/tinystruct-patterns/references/system-usage.md +74 -0
  378. package/skills/tinystruct-patterns/references/testing.md +59 -0
  379. package/skills/token-budget-advisor/SKILL.md +133 -0
  380. package/skills/ui-demo/SKILL.md +464 -0
  381. package/skills/ui-to-vue/SKILL.md +134 -0
  382. package/skills/unified-notifications-ops/SKILL.md +186 -0
  383. package/skills/verification-loop/SKILL.md +125 -0
  384. package/skills/video-editing/SKILL.md +309 -0
  385. package/skills/videodb/SKILL.md +373 -0
  386. package/skills/videodb/reference/api-reference.md +550 -0
  387. package/skills/videodb/reference/capture-reference.md +407 -0
  388. package/skills/videodb/reference/capture.md +101 -0
  389. package/skills/videodb/reference/editor.md +443 -0
  390. package/skills/videodb/reference/generative.md +331 -0
  391. package/skills/videodb/reference/rtstream-reference.md +564 -0
  392. package/skills/videodb/reference/rtstream.md +65 -0
  393. package/skills/videodb/reference/search.md +230 -0
  394. package/skills/videodb/reference/streaming.md +406 -0
  395. package/skills/videodb/reference/use-cases.md +118 -0
  396. package/skills/videodb/scripts/ws_listener.py +282 -0
  397. package/skills/visa-doc-translate/README.md +86 -0
  398. package/skills/visa-doc-translate/SKILL.md +117 -0
  399. package/skills/vite-patterns/SKILL.md +448 -0
  400. package/skills/windows-desktop-e2e/SKILL.md +787 -0
  401. package/skills/workspace-surface-audit/SKILL.md +124 -0
  402. package/skills/x-api/SKILL.md +233 -0
@@ -0,0 +1,384 @@
1
+ ---
2
+ name: ai-regression-testing
3
+ description: Regression testing strategies for AI-assisted development. Sandbox-mode API testing without database dependencies, automated bug-check workflows, and patterns to catch AI blind spots where the same model writes and reviews code.
4
+ ---
5
+
6
+ # AI Regression Testing
7
+
8
+ Testing patterns specifically designed for AI-assisted development, where the same model writes code and reviews it — creating systematic blind spots that only automated tests can catch.
9
+
10
+ ## When to Activate
11
+
12
+ - AI agent (Claude Code, Cursor, Codex) has modified API routes or backend logic
13
+ - A bug was found and fixed — need to prevent re-introduction
14
+ - Project has a sandbox/mock mode that can be leveraged for DB-free testing
15
+ - Running `/bug-check` or similar review commands after code changes
16
+ - Multiple code paths exist (sandbox vs production, feature flags, etc.)
17
+
18
+ ## The Core Problem
19
+
20
+ When an AI writes code and then reviews its own work, it carries the same assumptions into both steps. This creates a predictable failure pattern:
21
+
22
+ ```
23
+ AI writes fix → AI reviews fix → AI says "looks correct" → Bug still exists
24
+ ```
25
+
26
+ **Real-world example** (observed in production):
27
+
28
+ ```
29
+ Fix 1: Added notification_settings to API response
30
+ → Forgot to add it to the SELECT query
31
+ → AI reviewed and missed it (same blind spot)
32
+
33
+ Fix 2: Added it to SELECT query
34
+ → TypeScript build error (column not in generated types)
35
+ → AI reviewed Fix 1 but didn't catch the SELECT issue
36
+
37
+ Fix 3: Changed to SELECT *
38
+ → Fixed production path, forgot sandbox path
39
+ → AI reviewed and missed it AGAIN (4th occurrence)
40
+
41
+ Fix 4: Test caught it instantly on first run PASS:
42
+ ```
43
+
44
+ The pattern: **sandbox/production path inconsistency** is the #1 AI-introduced regression.
45
+
46
+ ## Sandbox-Mode API Testing
47
+
48
+ Most projects with AI-friendly architecture have a sandbox/mock mode. This is the key to fast, DB-free API testing.
49
+
50
+ ### Setup (Vitest + Next.js App Router)
51
+
52
+ ```typescript
53
+ // vitest.config.ts
54
+ import { defineConfig } from "vitest/config";
55
+ import path from "path";
56
+
57
+ export default defineConfig({
58
+ test: {
59
+ environment: "node",
60
+ globals: true,
61
+ include: ["__tests__/**/*.test.ts"],
62
+ setupFiles: ["__tests__/setup.ts"],
63
+ },
64
+ resolve: {
65
+ alias: {
66
+ "@": path.resolve(__dirname, "."),
67
+ },
68
+ },
69
+ });
70
+ ```
71
+
72
+ ```typescript
73
+ // __tests__/setup.ts
74
+ // Force sandbox mode — no database needed
75
+ process.env.SANDBOX_MODE = "true";
76
+ process.env.NEXT_PUBLIC_SUPABASE_URL = "";
77
+ process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY = "";
78
+ ```
79
+
80
+ ### Test Helper for Next.js API Routes
81
+
82
+ ```typescript
83
+ // __tests__/helpers.ts
84
+ import { NextRequest } from "next/server";
85
+
86
+ export function createTestRequest(
87
+ url: string,
88
+ options?: {
89
+ method?: string;
90
+ body?: Record<string, unknown>;
91
+ headers?: Record<string, string>;
92
+ sandboxUserId?: string;
93
+ },
94
+ ): NextRequest {
95
+ const { method = "GET", body, headers = {}, sandboxUserId } = options || {};
96
+ const fullUrl = url.startsWith("http") ? url : `http://localhost:3000${url}`;
97
+ const reqHeaders: Record<string, string> = { ...headers };
98
+
99
+ if (sandboxUserId) {
100
+ reqHeaders["x-sandbox-user-id"] = sandboxUserId;
101
+ }
102
+
103
+ const init: { method: string; headers: Record<string, string>; body?: string } = {
104
+ method,
105
+ headers: reqHeaders,
106
+ };
107
+
108
+ if (body) {
109
+ init.body = JSON.stringify(body);
110
+ reqHeaders["content-type"] = "application/json";
111
+ }
112
+
113
+ return new NextRequest(fullUrl, init);
114
+ }
115
+
116
+ export async function parseResponse(response: Response) {
117
+ const json = await response.json();
118
+ return { status: response.status, json };
119
+ }
120
+ ```
121
+
122
+ ### Writing Regression Tests
123
+
124
+ The key principle: **write tests for bugs that were found, not for code that works**.
125
+
126
+ ```typescript
127
+ // __tests__/api/user/profile.test.ts
128
+ import { describe, it, expect } from "vitest";
129
+ import { createTestRequest, parseResponse } from "../../helpers";
130
+ import { GET, PATCH } from "@/app/api/user/profile/route";
131
+
132
+ // Define the contract — what fields MUST be in the response
133
+ const REQUIRED_FIELDS = [
134
+ "id",
135
+ "email",
136
+ "full_name",
137
+ "phone",
138
+ "role",
139
+ "created_at",
140
+ "avatar_url",
141
+ "notification_settings", // ← Added after bug found it missing
142
+ ];
143
+
144
+ describe("GET /api/user/profile", () => {
145
+ it("returns all required fields", async () => {
146
+ const req = createTestRequest("/api/user/profile");
147
+ const res = await GET(req);
148
+ const { status, json } = await parseResponse(res);
149
+
150
+ expect(status).toBe(200);
151
+ for (const field of REQUIRED_FIELDS) {
152
+ expect(json.data).toHaveProperty(field);
153
+ }
154
+ });
155
+
156
+ // Regression test — this exact bug was introduced by AI 4 times
157
+ it("notification_settings is not undefined (BUG-R1 regression)", async () => {
158
+ const req = createTestRequest("/api/user/profile");
159
+ const res = await GET(req);
160
+ const { json } = await parseResponse(res);
161
+
162
+ expect("notification_settings" in json.data).toBe(true);
163
+ const ns = json.data.notification_settings;
164
+ expect(ns === null || typeof ns === "object").toBe(true);
165
+ });
166
+ });
167
+ ```
168
+
169
+ ### Testing Sandbox/Production Parity
170
+
171
+ The most common AI regression: fixing production path but forgetting sandbox path (or vice versa).
172
+
173
+ ```typescript
174
+ // Test that sandbox responses match the expected contract
175
+ describe("GET /api/user/messages (conversation list)", () => {
176
+ it("includes partner_name in sandbox mode", async () => {
177
+ const req = createTestRequest("/api/user/messages", {
178
+ sandboxUserId: "user-001",
179
+ });
180
+ const res = await GET(req);
181
+ const { json } = await parseResponse(res);
182
+
183
+ // This caught a bug where partner_name was added
184
+ // to production path but not sandbox path
185
+ if (json.data.length > 0) {
186
+ for (const conv of json.data) {
187
+ expect("partner_name" in conv).toBe(true);
188
+ }
189
+ }
190
+ });
191
+ });
192
+ ```
193
+
194
+ ## Integrating Tests into Bug-Check Workflow
195
+
196
+ ### Custom Command Definition
197
+
198
+ ```markdown
199
+ <!-- .claude/commands/bug-check.md -->
200
+ # Bug Check
201
+
202
+ ## Step 1: Automated Tests (mandatory, cannot skip)
203
+
204
+ Run these commands FIRST before any code review:
205
+
206
+ npm run test # Vitest test suite
207
+ npm run build # TypeScript type check + build
208
+
209
+ - If tests fail → report as highest priority bug
210
+ - If build fails → report type errors as highest priority
211
+ - Only proceed to Step 2 if both pass
212
+
213
+ ## Step 2: Code Review (AI review)
214
+
215
+ 1. Sandbox / production path consistency
216
+ 2. API response shape matches frontend expectations
217
+ 3. SELECT clause completeness
218
+ 4. Error handling with rollback
219
+ 5. Optimistic update race conditions
220
+
221
+ ## Step 3: For each bug fixed, propose a regression test
222
+ ```
223
+
224
+ ### The Workflow
225
+
226
+ ```
227
+ User: "バグチェックして" (or "/bug-check")
228
+
229
+ ├─ Step 1: npm run test
230
+ │ ├─ FAIL → Bug found mechanically (no AI judgment needed)
231
+ │ └─ PASS → Continue
232
+
233
+ ├─ Step 2: npm run build
234
+ │ ├─ FAIL → Type error found mechanically
235
+ │ └─ PASS → Continue
236
+
237
+ ├─ Step 3: AI code review (with known blind spots in mind)
238
+ │ └─ Findings reported
239
+
240
+ └─ Step 4: For each fix, write a regression test
241
+ └─ Next bug-check catches if fix breaks
242
+ ```
243
+
244
+ ## Common AI Regression Patterns
245
+
246
+ ### Pattern 1: Sandbox/Production Path Mismatch
247
+
248
+ **Frequency**: Most common (observed in 3 out of 4 regressions)
249
+
250
+ ```typescript
251
+ // FAIL: AI adds field to production path only
252
+ if (isSandboxMode()) {
253
+ return { data: { id, email, name } }; // Missing new field
254
+ }
255
+ // Production path
256
+ return { data: { id, email, name, notification_settings } };
257
+
258
+ // PASS: Both paths must return the same shape
259
+ if (isSandboxMode()) {
260
+ return { data: { id, email, name, notification_settings: null } };
261
+ }
262
+ return { data: { id, email, name, notification_settings } };
263
+ ```
264
+
265
+ **Test to catch it**:
266
+
267
+ ```typescript
268
+ it("sandbox and production return same fields", async () => {
269
+ // In test env, sandbox mode is forced ON
270
+ const res = await GET(createTestRequest("/api/user/profile"));
271
+ const { json } = await parseResponse(res);
272
+
273
+ for (const field of REQUIRED_FIELDS) {
274
+ expect(json.data).toHaveProperty(field);
275
+ }
276
+ });
277
+ ```
278
+
279
+ ### Pattern 2: SELECT Clause Omission
280
+
281
+ **Frequency**: Common with Supabase/Prisma when adding new columns
282
+
283
+ ```typescript
284
+ // FAIL: New column added to response but not to SELECT
285
+ const { data } = await supabase
286
+ .from("users")
287
+ .select("id, email, name") // notification_settings not here
288
+ .single();
289
+
290
+ return { data: { ...data, notification_settings: data.notification_settings } };
291
+ // → notification_settings is always undefined
292
+
293
+ // PASS: Use SELECT * or explicitly include new columns
294
+ const { data } = await supabase
295
+ .from("users")
296
+ .select("*")
297
+ .single();
298
+ ```
299
+
300
+ ### Pattern 3: Error State Leakage
301
+
302
+ **Frequency**: Moderate — when adding error handling to existing components
303
+
304
+ ```typescript
305
+ // FAIL: Error state set but old data not cleared
306
+ catch (err) {
307
+ setError("Failed to load");
308
+ // reservations still shows data from previous tab!
309
+ }
310
+
311
+ // PASS: Clear related state on error
312
+ catch (err) {
313
+ setReservations([]); // Clear stale data
314
+ setError("Failed to load");
315
+ }
316
+ ```
317
+
318
+ ### Pattern 4: Optimistic Update Without Proper Rollback
319
+
320
+ ```typescript
321
+ // FAIL: No rollback on failure
322
+ const handleRemove = async (id: string) => {
323
+ setItems(prev => prev.filter(i => i.id !== id));
324
+ await fetch(`/api/items/${id}`, { method: "DELETE" });
325
+ // If API fails, item is gone from UI but still in DB
326
+ };
327
+
328
+ // PASS: Capture previous state and rollback on failure
329
+ const handleRemove = async (id: string) => {
330
+ const prevItems = [...items];
331
+ setItems(prev => prev.filter(i => i.id !== id));
332
+ try {
333
+ const res = await fetch(`/api/items/${id}`, { method: "DELETE" });
334
+ if (!res.ok) throw new Error("API error");
335
+ } catch {
336
+ setItems(prevItems); // Rollback
337
+ alert("削除に失敗しました");
338
+ }
339
+ };
340
+ ```
341
+
342
+ ## Strategy: Test Where Bugs Were Found
343
+
344
+ Don't aim for 100% coverage. Instead:
345
+
346
+ ```
347
+ Bug found in /api/user/profile → Write test for profile API
348
+ Bug found in /api/user/messages → Write test for messages API
349
+ Bug found in /api/user/favorites → Write test for favorites API
350
+ No bug in /api/user/notifications → Don't write test (yet)
351
+ ```
352
+
353
+ **Why this works with AI development:**
354
+
355
+ 1. AI tends to make the **same category of mistake** repeatedly
356
+ 2. Bugs cluster in complex areas (auth, multi-path logic, state management)
357
+ 3. Once tested, that exact regression **cannot happen again**
358
+ 4. Test count grows organically with bug fixes — no wasted effort
359
+
360
+ ## Quick Reference
361
+
362
+ | AI Regression Pattern | Test Strategy | Priority |
363
+ |---|---|---|
364
+ | Sandbox/production mismatch | Assert same response shape in sandbox mode | High |
365
+ | SELECT clause omission | Assert all required fields in response | High |
366
+ | Error state leakage | Assert state cleanup on error | Medium |
367
+ | Missing rollback | Assert state restored on API failure | Medium |
368
+ | Type cast masking null | Assert field is not undefined | Medium |
369
+
370
+ ## DO / DON'T
371
+
372
+ **DO:**
373
+ - Write tests immediately after finding a bug (before fixing it if possible)
374
+ - Test the API response shape, not the implementation
375
+ - Run tests as the first step of every bug-check
376
+ - Keep tests fast (< 1 second total with sandbox mode)
377
+ - Name tests after the bug they prevent (e.g., "BUG-R1 regression")
378
+
379
+ **DON'T:**
380
+ - Write tests for code that has never had a bug
381
+ - Trust AI self-review as a substitute for automated tests
382
+ - Skip sandbox path testing because "it's just mock data"
383
+ - Write integration tests when unit tests suffice
384
+ - Aim for coverage percentage — aim for regression prevention
@@ -0,0 +1,338 @@
1
+ ---
2
+ name: android-clean-architecture
3
+ description: Clean Architecture patterns for Android and Kotlin Multiplatform projects — module structure, dependency rules, UseCases, Repositories, and data layer patterns.
4
+ ---
5
+
6
+ # Android Clean Architecture
7
+
8
+ Clean Architecture patterns for Android and KMP projects. Covers module boundaries, dependency inversion, UseCase/Repository patterns, and data layer design with Room, SQLDelight, and Ktor.
9
+
10
+ ## When to Activate
11
+
12
+ - Structuring Android or KMP project modules
13
+ - Implementing UseCases, Repositories, or DataSources
14
+ - Designing data flow between layers (domain, data, presentation)
15
+ - Setting up dependency injection with Koin or Hilt
16
+ - Working with Room, SQLDelight, or Ktor in a layered architecture
17
+
18
+ ## Module Structure
19
+
20
+ ### Recommended Layout
21
+
22
+ ```
23
+ project/
24
+ ├── app/ # Android entry point, DI wiring, Application class
25
+ ├── core/ # Shared utilities, base classes, error types
26
+ ├── domain/ # UseCases, domain models, repository interfaces (pure Kotlin)
27
+ ├── data/ # Repository implementations, DataSources, DB, network
28
+ ├── presentation/ # Screens, ViewModels, UI models, navigation
29
+ ├── design-system/ # Reusable Compose components, theme, typography
30
+ └── feature/ # Feature modules (optional, for larger projects)
31
+ ├── auth/
32
+ ├── settings/
33
+ └── profile/
34
+ ```
35
+
36
+ ### Dependency Rules
37
+
38
+ ```
39
+ app → presentation, domain, data, core
40
+ presentation → domain, design-system, core
41
+ data → domain, core
42
+ domain → core (or no dependencies)
43
+ core → (nothing)
44
+ ```
45
+
46
+ **Critical**: `domain` must NEVER depend on `data`, `presentation`, or any framework. It contains pure Kotlin only.
47
+
48
+ ## Domain Layer
49
+
50
+ ### UseCase Pattern
51
+
52
+ Each UseCase represents one business operation. Use `operator fun invoke` for clean call sites:
53
+
54
+ ```kotlin
55
+ class GetItemsByCategoryUseCase(
56
+ private val repository: ItemRepository
57
+ ) {
58
+ suspend operator fun invoke(category: String): Result<List<Item>> {
59
+ return repository.getItemsByCategory(category)
60
+ }
61
+ }
62
+
63
+ // Flow-based UseCase for reactive streams
64
+ class ObserveUserProgressUseCase(
65
+ private val repository: UserRepository
66
+ ) {
67
+ operator fun invoke(userId: String): Flow<UserProgress> {
68
+ return repository.observeProgress(userId)
69
+ }
70
+ }
71
+ ```
72
+
73
+ ### Domain Models
74
+
75
+ Domain models are plain Kotlin data classes — no framework annotations:
76
+
77
+ ```kotlin
78
+ data class Item(
79
+ val id: String,
80
+ val title: String,
81
+ val description: String,
82
+ val tags: List<String>,
83
+ val status: Status,
84
+ val category: String
85
+ )
86
+
87
+ enum class Status { DRAFT, ACTIVE, ARCHIVED }
88
+ ```
89
+
90
+ ### Repository Interfaces
91
+
92
+ Defined in domain, implemented in data:
93
+
94
+ ```kotlin
95
+ interface ItemRepository {
96
+ suspend fun getItemsByCategory(category: String): Result<List<Item>>
97
+ suspend fun saveItem(item: Item): Result<Unit>
98
+ fun observeItems(): Flow<List<Item>>
99
+ }
100
+ ```
101
+
102
+ ## Data Layer
103
+
104
+ ### Repository Implementation
105
+
106
+ Coordinates between local and remote data sources:
107
+
108
+ ```kotlin
109
+ class ItemRepositoryImpl(
110
+ private val localDataSource: ItemLocalDataSource,
111
+ private val remoteDataSource: ItemRemoteDataSource
112
+ ) : ItemRepository {
113
+
114
+ override suspend fun getItemsByCategory(category: String): Result<List<Item>> {
115
+ return runCatching {
116
+ val remote = remoteDataSource.fetchItems(category)
117
+ localDataSource.insertItems(remote.map { it.toEntity() })
118
+ localDataSource.getItemsByCategory(category).map { it.toDomain() }
119
+ }
120
+ }
121
+
122
+ override suspend fun saveItem(item: Item): Result<Unit> {
123
+ return runCatching {
124
+ localDataSource.insertItems(listOf(item.toEntity()))
125
+ }
126
+ }
127
+
128
+ override fun observeItems(): Flow<List<Item>> {
129
+ return localDataSource.observeAll().map { entities ->
130
+ entities.map { it.toDomain() }
131
+ }
132
+ }
133
+ }
134
+ ```
135
+
136
+ ### Mapper Pattern
137
+
138
+ Keep mappers as extension functions near the data models:
139
+
140
+ ```kotlin
141
+ // In data layer
142
+ fun ItemEntity.toDomain() = Item(
143
+ id = id,
144
+ title = title,
145
+ description = description,
146
+ tags = tags.split("|"),
147
+ status = Status.valueOf(status),
148
+ category = category
149
+ )
150
+
151
+ fun ItemDto.toEntity() = ItemEntity(
152
+ id = id,
153
+ title = title,
154
+ description = description,
155
+ tags = tags.joinToString("|"),
156
+ status = status,
157
+ category = category
158
+ )
159
+ ```
160
+
161
+ ### Room Database (Android)
162
+
163
+ ```kotlin
164
+ @Entity(tableName = "items")
165
+ data class ItemEntity(
166
+ @PrimaryKey val id: String,
167
+ val title: String,
168
+ val description: String,
169
+ val tags: String,
170
+ val status: String,
171
+ val category: String
172
+ )
173
+
174
+ @Dao
175
+ interface ItemDao {
176
+ @Query("SELECT * FROM items WHERE category = :category")
177
+ suspend fun getByCategory(category: String): List<ItemEntity>
178
+
179
+ @Upsert
180
+ suspend fun upsert(items: List<ItemEntity>)
181
+
182
+ @Query("SELECT * FROM items")
183
+ fun observeAll(): Flow<List<ItemEntity>>
184
+ }
185
+ ```
186
+
187
+ ### SQLDelight (KMP)
188
+
189
+ ```sql
190
+ -- Item.sq
191
+ CREATE TABLE ItemEntity (
192
+ id TEXT NOT NULL PRIMARY KEY,
193
+ title TEXT NOT NULL,
194
+ description TEXT NOT NULL,
195
+ tags TEXT NOT NULL,
196
+ status TEXT NOT NULL,
197
+ category TEXT NOT NULL
198
+ );
199
+
200
+ getByCategory:
201
+ SELECT * FROM ItemEntity WHERE category = ?;
202
+
203
+ upsert:
204
+ INSERT OR REPLACE INTO ItemEntity (id, title, description, tags, status, category)
205
+ VALUES (?, ?, ?, ?, ?, ?);
206
+
207
+ observeAll:
208
+ SELECT * FROM ItemEntity;
209
+ ```
210
+
211
+ ### Ktor Network Client (KMP)
212
+
213
+ ```kotlin
214
+ class ItemRemoteDataSource(private val client: HttpClient) {
215
+
216
+ suspend fun fetchItems(category: String): List<ItemDto> {
217
+ return client.get("api/items") {
218
+ parameter("category", category)
219
+ }.body()
220
+ }
221
+ }
222
+
223
+ // HttpClient setup with content negotiation
224
+ val httpClient = HttpClient {
225
+ install(ContentNegotiation) { json(Json { ignoreUnknownKeys = true }) }
226
+ install(Logging) { level = LogLevel.HEADERS }
227
+ defaultRequest { url("https://api.example.com/") }
228
+ }
229
+ ```
230
+
231
+ ## Dependency Injection
232
+
233
+ ### Koin (KMP-friendly)
234
+
235
+ ```kotlin
236
+ // Domain module
237
+ val domainModule = module {
238
+ factory { GetItemsByCategoryUseCase(get()) }
239
+ factory { ObserveUserProgressUseCase(get()) }
240
+ }
241
+
242
+ // Data module
243
+ val dataModule = module {
244
+ single<ItemRepository> { ItemRepositoryImpl(get(), get()) }
245
+ single { ItemLocalDataSource(get()) }
246
+ single { ItemRemoteDataSource(get()) }
247
+ }
248
+
249
+ // Presentation module
250
+ val presentationModule = module {
251
+ viewModelOf(::ItemListViewModel)
252
+ viewModelOf(::DashboardViewModel)
253
+ }
254
+ ```
255
+
256
+ ### Hilt (Android-only)
257
+
258
+ ```kotlin
259
+ @Module
260
+ @InstallIn(SingletonComponent::class)
261
+ abstract class RepositoryModule {
262
+ @Binds
263
+ abstract fun bindItemRepository(impl: ItemRepositoryImpl): ItemRepository
264
+ }
265
+
266
+ @HiltViewModel
267
+ class ItemListViewModel @Inject constructor(
268
+ private val getItems: GetItemsByCategoryUseCase
269
+ ) : ViewModel()
270
+ ```
271
+
272
+ ## Error Handling
273
+
274
+ ### Result/Try Pattern
275
+
276
+ Use `Result<T>` or a custom sealed type for error propagation:
277
+
278
+ ```kotlin
279
+ sealed interface Try<out T> {
280
+ data class Success<T>(val value: T) : Try<T>
281
+ data class Failure(val error: AppError) : Try<Nothing>
282
+ }
283
+
284
+ sealed interface AppError {
285
+ data class Network(val message: String) : AppError
286
+ data class Database(val message: String) : AppError
287
+ data object Unauthorized : AppError
288
+ }
289
+
290
+ // In ViewModel — map to UI state
291
+ viewModelScope.launch {
292
+ when (val result = getItems(category)) {
293
+ is Try.Success -> _state.update { it.copy(items = result.value, isLoading = false) }
294
+ is Try.Failure -> _state.update { it.copy(error = result.error.toMessage(), isLoading = false) }
295
+ }
296
+ }
297
+ ```
298
+
299
+ ## Convention Plugins (Gradle)
300
+
301
+ For KMP projects, use convention plugins to reduce build file duplication:
302
+
303
+ ```kotlin
304
+ // build-logic/src/main/kotlin/kmp-library.gradle.kts
305
+ plugins {
306
+ id("org.jetbrains.kotlin.multiplatform")
307
+ }
308
+
309
+ kotlin {
310
+ androidTarget()
311
+ iosX64(); iosArm64(); iosSimulatorArm64()
312
+ sourceSets {
313
+ commonMain.dependencies { /* shared deps */ }
314
+ commonTest.dependencies { implementation(kotlin("test")) }
315
+ }
316
+ }
317
+ ```
318
+
319
+ Apply in modules:
320
+
321
+ ```kotlin
322
+ // domain/build.gradle.kts
323
+ plugins { id("kmp-library") }
324
+ ```
325
+
326
+ ## Anti-Patterns to Avoid
327
+
328
+ - Importing Android framework classes in `domain` — keep it pure Kotlin
329
+ - Exposing database entities or DTOs to the UI layer — always map to domain models
330
+ - Putting business logic in ViewModels — extract to UseCases
331
+ - Using `GlobalScope` or unstructured coroutines — use `viewModelScope` or structured concurrency
332
+ - Fat repository implementations — split into focused DataSources
333
+ - Circular module dependencies — if A depends on B, B must not depend on A
334
+
335
+ ## References
336
+
337
+ See skill: `compose-multiplatform-patterns` for UI patterns.
338
+ See skill: `kotlin-coroutines-flows` for async patterns.