@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,688 @@
1
+ ---
2
+ name: kotlin-ktor-patterns
3
+ description: Ktor server patterns including routing DSL, plugins, authentication, Koin DI, kotlinx.serialization, WebSockets, and testApplication testing.
4
+ ---
5
+
6
+ # Ktor Server Patterns
7
+
8
+ Comprehensive Ktor patterns for building robust, maintainable HTTP servers with Kotlin coroutines.
9
+
10
+ ## When to Activate
11
+
12
+ - Building Ktor HTTP servers
13
+ - Configuring Ktor plugins (Auth, CORS, ContentNegotiation, StatusPages)
14
+ - Implementing REST APIs with Ktor
15
+ - Setting up dependency injection with Koin
16
+ - Writing Ktor integration tests with testApplication
17
+ - Working with WebSockets in Ktor
18
+
19
+ ## Application Structure
20
+
21
+ ### Standard Ktor Project Layout
22
+
23
+ ```text
24
+ src/main/kotlin/
25
+ ├── com/example/
26
+ │ ├── Application.kt # Entry point, module configuration
27
+ │ ├── plugins/
28
+ │ │ ├── Routing.kt # Route definitions
29
+ │ │ ├── Serialization.kt # Content negotiation setup
30
+ │ │ ├── Authentication.kt # Auth configuration
31
+ │ │ ├── StatusPages.kt # Error handling
32
+ │ │ └── CORS.kt # CORS configuration
33
+ │ ├── routes/
34
+ │ │ ├── UserRoutes.kt # /users endpoints
35
+ │ │ ├── AuthRoutes.kt # /auth endpoints
36
+ │ │ └── HealthRoutes.kt # /health endpoints
37
+ │ ├── models/
38
+ │ │ ├── User.kt # Domain models
39
+ │ │ └── ApiResponse.kt # Response envelopes
40
+ │ ├── services/
41
+ │ │ ├── UserService.kt # Business logic
42
+ │ │ └── AuthService.kt # Auth logic
43
+ │ ├── repositories/
44
+ │ │ ├── UserRepository.kt # Data access interface
45
+ │ │ └── ExposedUserRepository.kt
46
+ │ └── di/
47
+ │ └── AppModule.kt # Koin modules
48
+ src/test/kotlin/
49
+ ├── com/example/
50
+ │ ├── routes/
51
+ │ │ └── UserRoutesTest.kt
52
+ │ └── services/
53
+ │ └── UserServiceTest.kt
54
+ ```
55
+
56
+ ### Application Entry Point
57
+
58
+ ```kotlin
59
+ // Application.kt
60
+ fun main() {
61
+ embeddedServer(Netty, port = 8080, module = Application::module).start(wait = true)
62
+ }
63
+
64
+ fun Application.module() {
65
+ configureSerialization()
66
+ configureAuthentication()
67
+ configureStatusPages()
68
+ configureCORS()
69
+ configureDI()
70
+ configureRouting()
71
+ }
72
+ ```
73
+
74
+ ## Routing DSL
75
+
76
+ ### Basic Routes
77
+
78
+ ```kotlin
79
+ // plugins/Routing.kt
80
+ fun Application.configureRouting() {
81
+ routing {
82
+ userRoutes()
83
+ authRoutes()
84
+ healthRoutes()
85
+ }
86
+ }
87
+
88
+ // routes/UserRoutes.kt
89
+ fun Route.userRoutes() {
90
+ val userService by inject<UserService>()
91
+
92
+ route("/users") {
93
+ get {
94
+ val users = userService.getAll()
95
+ call.respond(users)
96
+ }
97
+
98
+ get("/{id}") {
99
+ val id = call.parameters["id"]
100
+ ?: return@get call.respond(HttpStatusCode.BadRequest, "Missing id")
101
+ val user = userService.getById(id)
102
+ ?: return@get call.respond(HttpStatusCode.NotFound)
103
+ call.respond(user)
104
+ }
105
+
106
+ post {
107
+ val request = call.receive<CreateUserRequest>()
108
+ val user = userService.create(request)
109
+ call.respond(HttpStatusCode.Created, user)
110
+ }
111
+
112
+ put("/{id}") {
113
+ val id = call.parameters["id"]
114
+ ?: return@put call.respond(HttpStatusCode.BadRequest, "Missing id")
115
+ val request = call.receive<UpdateUserRequest>()
116
+ val user = userService.update(id, request)
117
+ ?: return@put call.respond(HttpStatusCode.NotFound)
118
+ call.respond(user)
119
+ }
120
+
121
+ delete("/{id}") {
122
+ val id = call.parameters["id"]
123
+ ?: return@delete call.respond(HttpStatusCode.BadRequest, "Missing id")
124
+ val deleted = userService.delete(id)
125
+ if (deleted) call.respond(HttpStatusCode.NoContent)
126
+ else call.respond(HttpStatusCode.NotFound)
127
+ }
128
+ }
129
+ }
130
+ ```
131
+
132
+ ### Route Organization with Authenticated Routes
133
+
134
+ ```kotlin
135
+ fun Route.userRoutes() {
136
+ route("/users") {
137
+ // Public routes
138
+ get { /* list users */ }
139
+ get("/{id}") { /* get user */ }
140
+
141
+ // Protected routes
142
+ authenticate("jwt") {
143
+ post { /* create user - requires auth */ }
144
+ put("/{id}") { /* update user - requires auth */ }
145
+ delete("/{id}") { /* delete user - requires auth */ }
146
+ }
147
+ }
148
+ }
149
+ ```
150
+
151
+ ## Content Negotiation & Serialization
152
+
153
+ ### kotlinx.serialization Setup
154
+
155
+ ```kotlin
156
+ // plugins/Serialization.kt
157
+ fun Application.configureSerialization() {
158
+ install(ContentNegotiation) {
159
+ json(Json {
160
+ prettyPrint = true
161
+ isLenient = false
162
+ ignoreUnknownKeys = true
163
+ encodeDefaults = true
164
+ explicitNulls = false
165
+ })
166
+ }
167
+ }
168
+ ```
169
+
170
+ ### Serializable Models
171
+
172
+ ```kotlin
173
+ @Serializable
174
+ data class UserResponse(
175
+ val id: String,
176
+ val name: String,
177
+ val email: String,
178
+ val role: Role,
179
+ @Serializable(with = InstantSerializer::class)
180
+ val createdAt: Instant,
181
+ )
182
+
183
+ @Serializable
184
+ data class CreateUserRequest(
185
+ val name: String,
186
+ val email: String,
187
+ val role: Role = Role.USER,
188
+ )
189
+
190
+ @Serializable
191
+ data class ApiResponse<T>(
192
+ val success: Boolean,
193
+ val data: T? = null,
194
+ val error: String? = null,
195
+ ) {
196
+ companion object {
197
+ fun <T> ok(data: T): ApiResponse<T> = ApiResponse(success = true, data = data)
198
+ fun <T> error(message: String): ApiResponse<T> = ApiResponse(success = false, error = message)
199
+ }
200
+ }
201
+
202
+ @Serializable
203
+ data class PaginatedResponse<T>(
204
+ val data: List<T>,
205
+ val total: Long,
206
+ val page: Int,
207
+ val limit: Int,
208
+ )
209
+ ```
210
+
211
+ ### Custom Serializers
212
+
213
+ ```kotlin
214
+ object InstantSerializer : KSerializer<Instant> {
215
+ override val descriptor = PrimitiveSerialDescriptor("Instant", PrimitiveKind.STRING)
216
+ override fun serialize(encoder: Encoder, value: Instant) =
217
+ encoder.encodeString(value.toString())
218
+ override fun deserialize(decoder: Decoder): Instant =
219
+ Instant.parse(decoder.decodeString())
220
+ }
221
+ ```
222
+
223
+ ## Authentication
224
+
225
+ ### JWT Authentication
226
+
227
+ ```kotlin
228
+ // plugins/Authentication.kt
229
+ fun Application.configureAuthentication() {
230
+ val jwtSecret = environment.config.property("jwt.secret").getString()
231
+ val jwtIssuer = environment.config.property("jwt.issuer").getString()
232
+ val jwtAudience = environment.config.property("jwt.audience").getString()
233
+ val jwtRealm = environment.config.property("jwt.realm").getString()
234
+
235
+ install(Authentication) {
236
+ jwt("jwt") {
237
+ realm = jwtRealm
238
+ verifier(
239
+ JWT.require(Algorithm.HMAC256(jwtSecret))
240
+ .withAudience(jwtAudience)
241
+ .withIssuer(jwtIssuer)
242
+ .build()
243
+ )
244
+ validate { credential ->
245
+ if (credential.payload.audience.contains(jwtAudience)) {
246
+ JWTPrincipal(credential.payload)
247
+ } else {
248
+ null
249
+ }
250
+ }
251
+ challenge { _, _ ->
252
+ call.respond(HttpStatusCode.Unauthorized, ApiResponse.error<Unit>("Invalid or expired token"))
253
+ }
254
+ }
255
+ }
256
+ }
257
+
258
+ // Extracting user from JWT
259
+ fun ApplicationCall.userId(): String =
260
+ principal<JWTPrincipal>()
261
+ ?.payload
262
+ ?.getClaim("userId")
263
+ ?.asString()
264
+ ?: throw AuthenticationException("No userId in token")
265
+ ```
266
+
267
+ ### Auth Routes
268
+
269
+ ```kotlin
270
+ fun Route.authRoutes() {
271
+ val authService by inject<AuthService>()
272
+
273
+ route("/auth") {
274
+ post("/login") {
275
+ val request = call.receive<LoginRequest>()
276
+ val token = authService.login(request.email, request.password)
277
+ ?: return@post call.respond(
278
+ HttpStatusCode.Unauthorized,
279
+ ApiResponse.error<Unit>("Invalid credentials"),
280
+ )
281
+ call.respond(ApiResponse.ok(TokenResponse(token)))
282
+ }
283
+
284
+ post("/register") {
285
+ val request = call.receive<RegisterRequest>()
286
+ val user = authService.register(request)
287
+ call.respond(HttpStatusCode.Created, ApiResponse.ok(user))
288
+ }
289
+
290
+ authenticate("jwt") {
291
+ get("/me") {
292
+ val userId = call.userId()
293
+ val user = authService.getProfile(userId)
294
+ call.respond(ApiResponse.ok(user))
295
+ }
296
+ }
297
+ }
298
+ }
299
+ ```
300
+
301
+ ## Status Pages (Error Handling)
302
+
303
+ ```kotlin
304
+ // plugins/StatusPages.kt
305
+ fun Application.configureStatusPages() {
306
+ install(StatusPages) {
307
+ exception<ContentTransformationException> { call, cause ->
308
+ call.respond(
309
+ HttpStatusCode.BadRequest,
310
+ ApiResponse.error<Unit>("Invalid request body: ${cause.message}"),
311
+ )
312
+ }
313
+
314
+ exception<IllegalArgumentException> { call, cause ->
315
+ call.respond(
316
+ HttpStatusCode.BadRequest,
317
+ ApiResponse.error<Unit>(cause.message ?: "Bad request"),
318
+ )
319
+ }
320
+
321
+ exception<AuthenticationException> { call, _ ->
322
+ call.respond(
323
+ HttpStatusCode.Unauthorized,
324
+ ApiResponse.error<Unit>("Authentication required"),
325
+ )
326
+ }
327
+
328
+ exception<AuthorizationException> { call, _ ->
329
+ call.respond(
330
+ HttpStatusCode.Forbidden,
331
+ ApiResponse.error<Unit>("Access denied"),
332
+ )
333
+ }
334
+
335
+ exception<NotFoundException> { call, cause ->
336
+ call.respond(
337
+ HttpStatusCode.NotFound,
338
+ ApiResponse.error<Unit>(cause.message ?: "Resource not found"),
339
+ )
340
+ }
341
+
342
+ exception<Throwable> { call, cause ->
343
+ call.application.log.error("Unhandled exception", cause)
344
+ call.respond(
345
+ HttpStatusCode.InternalServerError,
346
+ ApiResponse.error<Unit>("Internal server error"),
347
+ )
348
+ }
349
+
350
+ status(HttpStatusCode.NotFound) { call, status ->
351
+ call.respond(status, ApiResponse.error<Unit>("Route not found"))
352
+ }
353
+ }
354
+ }
355
+ ```
356
+
357
+ ## CORS Configuration
358
+
359
+ ```kotlin
360
+ // plugins/CORS.kt
361
+ fun Application.configureCORS() {
362
+ install(CORS) {
363
+ allowHost("localhost:3000")
364
+ allowHost("example.com", schemes = listOf("https"))
365
+ allowHeader(HttpHeaders.ContentType)
366
+ allowHeader(HttpHeaders.Authorization)
367
+ allowMethod(HttpMethod.Put)
368
+ allowMethod(HttpMethod.Delete)
369
+ allowMethod(HttpMethod.Patch)
370
+ allowCredentials = true
371
+ maxAgeInSeconds = 3600
372
+ }
373
+ }
374
+ ```
375
+
376
+ ## Koin Dependency Injection
377
+
378
+ ### Module Definition
379
+
380
+ ```kotlin
381
+ // di/AppModule.kt
382
+ val appModule = module {
383
+ // Database
384
+ single<Database> { DatabaseFactory.create(get()) }
385
+
386
+ // Repositories
387
+ single<UserRepository> { ExposedUserRepository(get()) }
388
+ single<OrderRepository> { ExposedOrderRepository(get()) }
389
+
390
+ // Services
391
+ single { UserService(get()) }
392
+ single { OrderService(get(), get()) }
393
+ single { AuthService(get(), get()) }
394
+ }
395
+
396
+ // Application setup
397
+ fun Application.configureDI() {
398
+ install(Koin) {
399
+ modules(appModule)
400
+ }
401
+ }
402
+ ```
403
+
404
+ ### Using Koin in Routes
405
+
406
+ ```kotlin
407
+ fun Route.userRoutes() {
408
+ val userService by inject<UserService>()
409
+
410
+ route("/users") {
411
+ get {
412
+ val users = userService.getAll()
413
+ call.respond(ApiResponse.ok(users))
414
+ }
415
+ }
416
+ }
417
+ ```
418
+
419
+ ### Koin for Testing
420
+
421
+ ```kotlin
422
+ class UserServiceTest : FunSpec(), KoinTest {
423
+ override fun extensions() = listOf(KoinExtension(testModule))
424
+
425
+ private val testModule = module {
426
+ single<UserRepository> { mockk() }
427
+ single { UserService(get()) }
428
+ }
429
+
430
+ private val repository by inject<UserRepository>()
431
+ private val service by inject<UserService>()
432
+
433
+ init {
434
+ test("getUser returns user") {
435
+ coEvery { repository.findById("1") } returns testUser
436
+ service.getById("1") shouldBe testUser
437
+ }
438
+ }
439
+ }
440
+ ```
441
+
442
+ ## Request Validation
443
+
444
+ ```kotlin
445
+ // Validate request data in routes
446
+ fun Route.userRoutes() {
447
+ val userService by inject<UserService>()
448
+
449
+ post("/users") {
450
+ val request = call.receive<CreateUserRequest>()
451
+
452
+ // Validate
453
+ require(request.name.isNotBlank()) { "Name is required" }
454
+ require(request.name.length <= 100) { "Name must be 100 characters or less" }
455
+ require(request.email.matches(Regex(".+@.+\\..+"))) { "Invalid email format" }
456
+
457
+ val user = userService.create(request)
458
+ call.respond(HttpStatusCode.Created, ApiResponse.ok(user))
459
+ }
460
+ }
461
+
462
+ // Or use a validation extension
463
+ fun CreateUserRequest.validate() {
464
+ require(name.isNotBlank()) { "Name is required" }
465
+ require(name.length <= 100) { "Name must be 100 characters or less" }
466
+ require(email.matches(Regex(".+@.+\\..+"))) { "Invalid email format" }
467
+ }
468
+ ```
469
+
470
+ ## WebSockets
471
+
472
+ ```kotlin
473
+ fun Application.configureWebSockets() {
474
+ install(WebSockets) {
475
+ pingPeriod = 15.seconds
476
+ timeout = 15.seconds
477
+ maxFrameSize = 64 * 1024 // 64 KiB — increase only if your protocol requires larger frames
478
+ masking = false // Server-to-client frames are unmasked per RFC 6455; client-to-server are always masked by Ktor
479
+ }
480
+ }
481
+
482
+ fun Route.chatRoutes() {
483
+ val connections = Collections.synchronizedSet<Connection>(LinkedHashSet())
484
+
485
+ webSocket("/chat") {
486
+ val thisConnection = Connection(this)
487
+ connections += thisConnection
488
+
489
+ try {
490
+ send("Connected! Users online: ${connections.size}")
491
+
492
+ for (frame in incoming) {
493
+ frame as? Frame.Text ?: continue
494
+ val text = frame.readText()
495
+ val message = ChatMessage(thisConnection.name, text)
496
+
497
+ // Snapshot under lock to avoid ConcurrentModificationException
498
+ val snapshot = synchronized(connections) { connections.toList() }
499
+ snapshot.forEach { conn ->
500
+ conn.session.send(Json.encodeToString(message))
501
+ }
502
+ }
503
+ } catch (e: Exception) {
504
+ logger.error("WebSocket error", e)
505
+ } finally {
506
+ connections -= thisConnection
507
+ }
508
+ }
509
+ }
510
+
511
+ data class Connection(val session: DefaultWebSocketSession) {
512
+ val name: String = "User-${counter.getAndIncrement()}"
513
+
514
+ companion object {
515
+ private val counter = AtomicInteger(0)
516
+ }
517
+ }
518
+ ```
519
+
520
+ ## testApplication Testing
521
+
522
+ ### Basic Route Testing
523
+
524
+ ```kotlin
525
+ class UserRoutesTest : FunSpec({
526
+ test("GET /users returns list of users") {
527
+ testApplication {
528
+ application {
529
+ install(Koin) { modules(testModule) }
530
+ configureSerialization()
531
+ configureRouting()
532
+ }
533
+
534
+ val response = client.get("/users")
535
+
536
+ response.status shouldBe HttpStatusCode.OK
537
+ val body = response.body<ApiResponse<List<UserResponse>>>()
538
+ body.success shouldBe true
539
+ body.data.shouldNotBeNull().shouldNotBeEmpty()
540
+ }
541
+ }
542
+
543
+ test("POST /users creates a user") {
544
+ testApplication {
545
+ application {
546
+ install(Koin) { modules(testModule) }
547
+ configureSerialization()
548
+ configureStatusPages()
549
+ configureRouting()
550
+ }
551
+
552
+ val client = createClient {
553
+ install(io.ktor.client.plugins.contentnegotiation.ContentNegotiation) {
554
+ json()
555
+ }
556
+ }
557
+
558
+ val response = client.post("/users") {
559
+ contentType(ContentType.Application.Json)
560
+ setBody(CreateUserRequest("Alice", "alice@example.com"))
561
+ }
562
+
563
+ response.status shouldBe HttpStatusCode.Created
564
+ }
565
+ }
566
+
567
+ test("GET /users/{id} returns 404 for unknown id") {
568
+ testApplication {
569
+ application {
570
+ install(Koin) { modules(testModule) }
571
+ configureSerialization()
572
+ configureStatusPages()
573
+ configureRouting()
574
+ }
575
+
576
+ val response = client.get("/users/unknown-id")
577
+
578
+ response.status shouldBe HttpStatusCode.NotFound
579
+ }
580
+ }
581
+ })
582
+ ```
583
+
584
+ ### Testing Authenticated Routes
585
+
586
+ ```kotlin
587
+ class AuthenticatedRoutesTest : FunSpec({
588
+ test("protected route requires JWT") {
589
+ testApplication {
590
+ application {
591
+ install(Koin) { modules(testModule) }
592
+ configureSerialization()
593
+ configureAuthentication()
594
+ configureRouting()
595
+ }
596
+
597
+ val response = client.post("/users") {
598
+ contentType(ContentType.Application.Json)
599
+ setBody(CreateUserRequest("Alice", "alice@example.com"))
600
+ }
601
+
602
+ response.status shouldBe HttpStatusCode.Unauthorized
603
+ }
604
+ }
605
+
606
+ test("protected route succeeds with valid JWT") {
607
+ testApplication {
608
+ application {
609
+ install(Koin) { modules(testModule) }
610
+ configureSerialization()
611
+ configureAuthentication()
612
+ configureRouting()
613
+ }
614
+
615
+ val token = generateTestJWT(userId = "test-user")
616
+
617
+ val client = createClient {
618
+ install(io.ktor.client.plugins.contentnegotiation.ContentNegotiation) { json() }
619
+ }
620
+
621
+ val response = client.post("/users") {
622
+ contentType(ContentType.Application.Json)
623
+ bearerAuth(token)
624
+ setBody(CreateUserRequest("Alice", "alice@example.com"))
625
+ }
626
+
627
+ response.status shouldBe HttpStatusCode.Created
628
+ }
629
+ }
630
+ })
631
+ ```
632
+
633
+ ## Configuration
634
+
635
+ ### application.yaml
636
+
637
+ ```yaml
638
+ ktor:
639
+ application:
640
+ modules:
641
+ - com.example.ApplicationKt.module
642
+ deployment:
643
+ port: 8080
644
+
645
+ jwt:
646
+ secret: ${JWT_SECRET}
647
+ issuer: "https://example.com"
648
+ audience: "https://example.com/api"
649
+ realm: "example"
650
+
651
+ database:
652
+ url: ${DATABASE_URL}
653
+ driver: "org.postgresql.Driver"
654
+ maxPoolSize: 10
655
+ ```
656
+
657
+ ### Reading Config
658
+
659
+ ```kotlin
660
+ fun Application.configureDI() {
661
+ val dbUrl = environment.config.property("database.url").getString()
662
+ val dbDriver = environment.config.property("database.driver").getString()
663
+ val maxPoolSize = environment.config.property("database.maxPoolSize").getString().toInt()
664
+
665
+ install(Koin) {
666
+ modules(module {
667
+ single { DatabaseConfig(dbUrl, dbDriver, maxPoolSize) }
668
+ single { DatabaseFactory.create(get()) }
669
+ })
670
+ }
671
+ }
672
+ ```
673
+
674
+ ## Quick Reference: Ktor Patterns
675
+
676
+ | Pattern | Description |
677
+ |---------|-------------|
678
+ | `route("/path") { get { } }` | Route grouping with DSL |
679
+ | `call.receive<T>()` | Deserialize request body |
680
+ | `call.respond(status, body)` | Send response with status |
681
+ | `call.parameters["id"]` | Read path parameters |
682
+ | `call.request.queryParameters["q"]` | Read query parameters |
683
+ | `install(Plugin) { }` | Install and configure plugin |
684
+ | `authenticate("name") { }` | Protect routes with auth |
685
+ | `by inject<T>()` | Koin dependency injection |
686
+ | `testApplication { }` | Integration testing |
687
+
688
+ **Remember**: Ktor is designed around Kotlin coroutines and DSLs. Keep routes thin, push logic to services, and use Koin for dependency injection. Test with `testApplication` for full integration coverage.