@ketecode/loom 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (851) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +616 -2
  3. package/agents/accessibility-reviewer/AGENT.md +70 -0
  4. package/agents/accessibility-reviewer/evals/triggers.json +15 -0
  5. package/agents/agent-evaluator/AGENT.md +74 -0
  6. package/agents/agent-evaluator/evals/triggers.json +15 -0
  7. package/agents/architect/AGENT.md +82 -0
  8. package/agents/architect/evals/triggers.json +17 -0
  9. package/agents/billing-reviewer/AGENT.md +68 -0
  10. package/agents/billing-reviewer/evals/triggers.json +16 -0
  11. package/agents/code-reviewer/AGENT.md +51 -0
  12. package/agents/code-reviewer/evals/behavior.json +60 -0
  13. package/agents/code-reviewer/evals/triggers.json +14 -0
  14. package/agents/code-simplifier/AGENT.md +74 -0
  15. package/agents/code-simplifier/evals/triggers.json +15 -0
  16. package/agents/cpp-build-resolver/AGENT.md +73 -0
  17. package/agents/cpp-build-resolver/evals/triggers.json +16 -0
  18. package/agents/cpp-reviewer/AGENT.md +59 -0
  19. package/agents/cpp-reviewer/evals/triggers.json +16 -0
  20. package/agents/csharp-build-resolver/AGENT.md +84 -0
  21. package/agents/csharp-build-resolver/evals/triggers.json +17 -0
  22. package/agents/csharp-reviewer/AGENT.md +88 -0
  23. package/agents/csharp-reviewer/evals/triggers.json +17 -0
  24. package/agents/dart-build-resolver/AGENT.md +80 -0
  25. package/agents/dart-build-resolver/evals/triggers.json +17 -0
  26. package/agents/dart-reviewer/AGENT.md +66 -0
  27. package/agents/dart-reviewer/evals/triggers.json +17 -0
  28. package/agents/database-reviewer/AGENT.md +72 -0
  29. package/agents/database-reviewer/evals/triggers.json +16 -0
  30. package/agents/django-reviewer/AGENT.md +61 -0
  31. package/agents/django-reviewer/evals/triggers.json +15 -0
  32. package/agents/doc-updater/AGENT.md +92 -0
  33. package/agents/doc-updater/evals/triggers.json +14 -0
  34. package/agents/e2e-runner/AGENT.md +88 -0
  35. package/agents/e2e-runner/evals/triggers.json +16 -0
  36. package/agents/fastapi-reviewer/AGENT.md +63 -0
  37. package/agents/fastapi-reviewer/evals/triggers.json +15 -0
  38. package/agents/flutter-reviewer/AGENT.md +70 -0
  39. package/agents/flutter-reviewer/evals/triggers.json +15 -0
  40. package/agents/fsharp-build-resolver/AGENT.md +81 -0
  41. package/agents/fsharp-build-resolver/evals/triggers.json +15 -0
  42. package/agents/fsharp-reviewer/AGENT.md +77 -0
  43. package/agents/fsharp-reviewer/evals/triggers.json +15 -0
  44. package/agents/go-build-resolver/AGENT.md +85 -0
  45. package/agents/go-build-resolver/evals/triggers.json +16 -0
  46. package/agents/go-reviewer/AGENT.md +66 -0
  47. package/agents/go-reviewer/evals/triggers.json +16 -0
  48. package/agents/healthcare-reviewer/AGENT.md +65 -0
  49. package/agents/healthcare-reviewer/evals/triggers.json +16 -0
  50. package/agents/i18n-reviewer/AGENT.md +64 -0
  51. package/agents/i18n-reviewer/evals/triggers.json +16 -0
  52. package/agents/inbox-triager/AGENT.md +98 -0
  53. package/agents/inbox-triager/evals/triggers.json +16 -0
  54. package/agents/infra-reviewer/AGENT.md +93 -0
  55. package/agents/infra-reviewer/evals/triggers.json +15 -0
  56. package/agents/java-build-resolver/AGENT.md +82 -0
  57. package/agents/java-build-resolver/evals/triggers.json +16 -0
  58. package/agents/java-reviewer/AGENT.md +64 -0
  59. package/agents/java-reviewer/evals/triggers.json +16 -0
  60. package/agents/kotlin-build-resolver/AGENT.md +89 -0
  61. package/agents/kotlin-build-resolver/evals/triggers.json +16 -0
  62. package/agents/kotlin-reviewer/AGENT.md +75 -0
  63. package/agents/kotlin-reviewer/evals/triggers.json +16 -0
  64. package/agents/mle-reviewer/AGENT.md +68 -0
  65. package/agents/mle-reviewer/evals/triggers.json +16 -0
  66. package/agents/network-config-reviewer/AGENT.md +68 -0
  67. package/agents/network-config-reviewer/evals/triggers.json +17 -0
  68. package/agents/payments-reviewer/AGENT.md +64 -0
  69. package/agents/payments-reviewer/evals/triggers.json +16 -0
  70. package/agents/performance-optimizer/AGENT.md +86 -0
  71. package/agents/performance-optimizer/evals/triggers.json +16 -0
  72. package/agents/perl-build-resolver/AGENT.md +84 -0
  73. package/agents/perl-build-resolver/evals/triggers.json +15 -0
  74. package/agents/perl-reviewer/AGENT.md +77 -0
  75. package/agents/perl-reviewer/evals/triggers.json +15 -0
  76. package/agents/php-build-resolver/AGENT.md +88 -0
  77. package/agents/php-build-resolver/evals/triggers.json +16 -0
  78. package/agents/php-reviewer/AGENT.md +61 -0
  79. package/agents/php-reviewer/evals/triggers.json +15 -0
  80. package/agents/planner/AGENT.md +75 -0
  81. package/agents/planner/evals/triggers.json +17 -0
  82. package/agents/pr-test-analyzer/AGENT.md +82 -0
  83. package/agents/pr-test-analyzer/evals/triggers.json +16 -0
  84. package/agents/python-build-resolver/AGENT.md +87 -0
  85. package/agents/python-build-resolver/evals/triggers.json +16 -0
  86. package/agents/python-reviewer/AGENT.md +63 -0
  87. package/agents/python-reviewer/evals/triggers.json +15 -0
  88. package/agents/rag-reviewer/AGENT.md +71 -0
  89. package/agents/rag-reviewer/evals/triggers.json +16 -0
  90. package/agents/react-reviewer/AGENT.md +70 -0
  91. package/agents/react-reviewer/evals/triggers.json +16 -0
  92. package/agents/refactor-cleaner/AGENT.md +82 -0
  93. package/agents/refactor-cleaner/evals/triggers.json +16 -0
  94. package/agents/ruby-build-resolver/AGENT.md +93 -0
  95. package/agents/ruby-build-resolver/evals/triggers.json +16 -0
  96. package/agents/ruby-reviewer/AGENT.md +62 -0
  97. package/agents/ruby-reviewer/evals/triggers.json +16 -0
  98. package/agents/rust-build-resolver/AGENT.md +98 -0
  99. package/agents/rust-build-resolver/evals/triggers.json +16 -0
  100. package/agents/rust-reviewer/AGENT.md +78 -0
  101. package/agents/rust-reviewer/evals/triggers.json +15 -0
  102. package/agents/security-reviewer/AGENT.md +84 -0
  103. package/agents/security-reviewer/evals/triggers.json +16 -0
  104. package/agents/silent-failure-hunter/AGENT.md +66 -0
  105. package/agents/silent-failure-hunter/evals/triggers.json +16 -0
  106. package/agents/solidity-reviewer/AGENT.md +70 -0
  107. package/agents/solidity-reviewer/evals/triggers.json +16 -0
  108. package/agents/spec-reviewer/AGENT.md +95 -0
  109. package/agents/spec-reviewer/evals/behavior.json +57 -0
  110. package/agents/spec-reviewer/evals/triggers.json +16 -0
  111. package/agents/swift-build-resolver/AGENT.md +85 -0
  112. package/agents/swift-build-resolver/evals/triggers.json +15 -0
  113. package/agents/swift-reviewer/AGENT.md +75 -0
  114. package/agents/swift-reviewer/evals/triggers.json +15 -0
  115. package/agents/task-implementer/AGENT.md +89 -0
  116. package/agents/task-implementer/evals/behavior.json +47 -0
  117. package/agents/task-implementer/evals/triggers.json +16 -0
  118. package/agents/typescript-build-resolver/AGENT.md +76 -0
  119. package/agents/typescript-build-resolver/evals/triggers.json +15 -0
  120. package/agents/typescript-reviewer/AGENT.md +76 -0
  121. package/agents/typescript-reviewer/evals/triggers.json +15 -0
  122. package/agents/vue-reviewer/AGENT.md +75 -0
  123. package/agents/vue-reviewer/evals/triggers.json +15 -0
  124. package/bin/kete-loom.js +723 -0
  125. package/commands/aside.md +19 -0
  126. package/commands/brainstorm.md +25 -0
  127. package/commands/build-fix.md +26 -0
  128. package/commands/campaign.md +19 -0
  129. package/commands/changelog.md +36 -0
  130. package/commands/checkpoint.md +26 -0
  131. package/commands/codemap.md +25 -0
  132. package/commands/commit.md +26 -0
  133. package/commands/debug.md +27 -0
  134. package/commands/deps-audit.md +32 -0
  135. package/commands/dual-review.md +34 -0
  136. package/commands/epic-decompose.md +21 -0
  137. package/commands/explain.md +37 -0
  138. package/commands/feature-dev.md +23 -0
  139. package/commands/finish-branch.md +26 -0
  140. package/commands/fix-bug.md +38 -0
  141. package/commands/hookify.md +23 -0
  142. package/commands/i18n-check.md +39 -0
  143. package/commands/issue-sync.md +22 -0
  144. package/commands/jira.md +19 -0
  145. package/commands/learn.md +23 -0
  146. package/commands/loom.md +21 -0
  147. package/commands/loop.md +20 -0
  148. package/commands/model-route.md +27 -0
  149. package/commands/onboard.md +35 -0
  150. package/commands/orchestrate.md +21 -0
  151. package/commands/plan-feature.md +36 -0
  152. package/commands/postmortem.md +42 -0
  153. package/commands/pr-describe.md +39 -0
  154. package/commands/pr.md +22 -0
  155. package/commands/prd.md +41 -0
  156. package/commands/production-readiness.md +45 -0
  157. package/commands/project-init.md +21 -0
  158. package/commands/refactor-clean.md +24 -0
  159. package/commands/resume-session.md +22 -0
  160. package/commands/review.md +35 -0
  161. package/commands/save-session.md +37 -0
  162. package/commands/security-scan.md +32 -0
  163. package/commands/sessions.md +21 -0
  164. package/commands/skill-create.md +21 -0
  165. package/commands/tdd.md +36 -0
  166. package/commands/test-coverage.md +24 -0
  167. package/commands/threat-model.md +36 -0
  168. package/commands/update-docs.md +25 -0
  169. package/commands/usage-report.md +43 -0
  170. package/commands/verify.md +21 -0
  171. package/hooks/block-dangerous-commands/HOOK.md +30 -0
  172. package/hooks/block-dangerous-commands/cases.json +50 -0
  173. package/hooks/block-dangerous-commands/hook.js +75 -0
  174. package/hooks/block-foreground-servers/HOOK.md +34 -0
  175. package/hooks/block-foreground-servers/cases.json +31 -0
  176. package/hooks/block-foreground-servers/hook.js +41 -0
  177. package/hooks/block-no-verify/HOOK.md +25 -0
  178. package/hooks/block-no-verify/cases.json +30 -0
  179. package/hooks/block-no-verify/hook.js +43 -0
  180. package/hooks/capture-lessons/HOOK.md +24 -0
  181. package/hooks/capture-lessons/hook.js +48 -0
  182. package/hooks/format-on-edit/HOOK.md +24 -0
  183. package/hooks/format-on-edit/hook.js +89 -0
  184. package/hooks/guard-secrets/HOOK.md +19 -0
  185. package/hooks/guard-secrets/cases.json +110 -0
  186. package/hooks/guard-secrets/hook.js +44 -0
  187. package/hooks/load-session-context/HOOK.md +20 -0
  188. package/hooks/load-session-context/hook.js +56 -0
  189. package/hooks/notify-on-stop/HOOK.md +25 -0
  190. package/hooks/notify-on-stop/hook.js +27 -0
  191. package/hooks/protect-files/HOOK.md +24 -0
  192. package/hooks/protect-files/cases.json +27 -0
  193. package/hooks/protect-files/hook.js +39 -0
  194. package/hooks/protect-lint-config/HOOK.md +29 -0
  195. package/hooks/protect-lint-config/cases.json +18 -0
  196. package/hooks/protect-lint-config/fixtures/.eslintrc.json +1 -0
  197. package/hooks/protect-lint-config/fixtures/.golangci.yml +1 -0
  198. package/hooks/protect-lint-config/fixtures/.prettierrc +1 -0
  199. package/hooks/protect-lint-config/fixtures/.rubocop.yml +1 -0
  200. package/hooks/protect-lint-config/fixtures/biome.json +1 -0
  201. package/hooks/protect-lint-config/fixtures/eslint.config.mjs +1 -0
  202. package/hooks/protect-lint-config/fixtures/ruff.toml +1 -0
  203. package/hooks/protect-lint-config/hook.js +25 -0
  204. package/hooks/read-before-edit/HOOK.md +26 -0
  205. package/hooks/read-before-edit/cases.json +15 -0
  206. package/hooks/read-before-edit/hook.js +50 -0
  207. package/hooks/run.js +148 -0
  208. package/hooks/verify-before-stop/HOOK.md +32 -0
  209. package/hooks/verify-before-stop/hook.js +70 -0
  210. package/mcp/atlassian.json +11 -0
  211. package/mcp/chrome-devtools.json +18 -0
  212. package/mcp/clickhouse.json +11 -0
  213. package/mcp/cloudflare.json +11 -0
  214. package/mcp/context7.json +11 -0
  215. package/mcp/exa.json +11 -0
  216. package/mcp/fetch.json +17 -0
  217. package/mcp/figma.json +11 -0
  218. package/mcp/firecrawl.json +11 -0
  219. package/mcp/git.json +17 -0
  220. package/mcp/github.json +11 -0
  221. package/mcp/linear.json +11 -0
  222. package/mcp/memory.json +18 -0
  223. package/mcp/notion.json +11 -0
  224. package/mcp/playwright.json +18 -0
  225. package/mcp/sentry.json +11 -0
  226. package/mcp/stripe.json +11 -0
  227. package/mcp/supabase.json +11 -0
  228. package/mcp/time.json +17 -0
  229. package/mcp/vercel.json +11 -0
  230. package/package.json +61 -4
  231. package/profiles.json +214 -0
  232. package/rules/common.md +21 -0
  233. package/rules/cpp.md +29 -0
  234. package/rules/csharp.md +25 -0
  235. package/rules/dart.md +29 -0
  236. package/rules/fsharp.md +28 -0
  237. package/rules/git.md +26 -0
  238. package/rules/go.md +29 -0
  239. package/rules/java.md +29 -0
  240. package/rules/kotlin.md +27 -0
  241. package/rules/perl.md +26 -0
  242. package/rules/php.md +28 -0
  243. package/rules/python.md +30 -0
  244. package/rules/ruby.md +27 -0
  245. package/rules/rust.md +26 -0
  246. package/rules/security.md +29 -0
  247. package/rules/swift.md +28 -0
  248. package/rules/testing.md +25 -0
  249. package/rules/typescript.md +29 -0
  250. package/rules/use-skills.md +23 -0
  251. package/schemas/skill-frontmatter.schema.json +52 -0
  252. package/scripts/lib/audit.js +96 -0
  253. package/scripts/lib/behavior.js +52 -0
  254. package/scripts/lib/frontmatter.js +65 -0
  255. package/scripts/lib/hooks-install.js +294 -0
  256. package/scripts/lib/i18n.js +51 -0
  257. package/scripts/lib/inventory.js +85 -0
  258. package/scripts/lib/lint.js +180 -0
  259. package/scripts/lib/mcp-install.js +288 -0
  260. package/scripts/lib/profiles.js +128 -0
  261. package/scripts/lib/render.js +92 -0
  262. package/scripts/lib/rules-install.js +118 -0
  263. package/scripts/lib/skills.js +87 -0
  264. package/scripts/lib/targets.js +123 -0
  265. package/skills/accounting-api-integration/SKILL.md +81 -0
  266. package/skills/accounting-api-integration/evals/triggers.json +17 -0
  267. package/skills/accounting-api-integration/references/quickbooks.md +48 -0
  268. package/skills/accounting-api-integration/references/xero.md +45 -0
  269. package/skills/agent-failure-debugging/SKILL.md +92 -0
  270. package/skills/agent-failure-debugging/evals/triggers.json +16 -0
  271. package/skills/agent-harness-design/SKILL.md +125 -0
  272. package/skills/agent-harness-design/evals/triggers.json +21 -0
  273. package/skills/agent-outbound-messaging/SKILL.md +92 -0
  274. package/skills/agent-outbound-messaging/evals/triggers.json +16 -0
  275. package/skills/agent-security/SKILL.md +117 -0
  276. package/skills/agent-security/evals/triggers.json +16 -0
  277. package/skills/agent-security/references/host-configs.md +37 -0
  278. package/skills/ai-media-generation/SKILL.md +89 -0
  279. package/skills/ai-media-generation/evals/triggers.json +16 -0
  280. package/skills/ai-media-generation/references/job-pipeline.md +76 -0
  281. package/skills/angular-patterns/SKILL.md +122 -0
  282. package/skills/angular-patterns/evals/triggers.json +16 -0
  283. package/skills/api-client-integration/SKILL.md +86 -0
  284. package/skills/api-client-integration/evals/triggers.json +16 -0
  285. package/skills/api-client-integration/references/resilience.md +57 -0
  286. package/skills/api-design/SKILL.md +96 -0
  287. package/skills/api-design/evals/triggers.json +18 -0
  288. package/skills/api-design/references/conventions.md +133 -0
  289. package/skills/architecture-decision-records/SKILL.md +98 -0
  290. package/skills/architecture-decision-records/evals/triggers.json +17 -0
  291. package/skills/article-writing/SKILL.md +108 -0
  292. package/skills/article-writing/evals/triggers.json +16 -0
  293. package/skills/aspnet-core-patterns/SKILL.md +149 -0
  294. package/skills/aspnet-core-patterns/evals/triggers.json +16 -0
  295. package/skills/auth-patterns/SKILL.md +104 -0
  296. package/skills/auth-patterns/evals/triggers.json +17 -0
  297. package/skills/auth-patterns/references/oauth-oidc.md +64 -0
  298. package/skills/autonomous-loops/SKILL.md +99 -0
  299. package/skills/autonomous-loops/evals/triggers.json +14 -0
  300. package/skills/aws-patterns/SKILL.md +91 -0
  301. package/skills/aws-patterns/evals/triggers.json +16 -0
  302. package/skills/azure-patterns/SKILL.md +86 -0
  303. package/skills/azure-patterns/evals/triggers.json +16 -0
  304. package/skills/benchmark-methodology/SKILL.md +88 -0
  305. package/skills/benchmark-methodology/evals/triggers.json +16 -0
  306. package/skills/benchmark-methodology/references/language-harnesses.md +130 -0
  307. package/skills/bgp-diagnostics/SKILL.md +84 -0
  308. package/skills/bgp-diagnostics/evals/triggers.json +18 -0
  309. package/skills/bgp-diagnostics/references/bgp-reference.md +81 -0
  310. package/skills/bioinformatics-workflows/SKILL.md +108 -0
  311. package/skills/bioinformatics-workflows/evals/triggers.json +16 -0
  312. package/skills/bioinformatics-workflows/references/commands.md +71 -0
  313. package/skills/bioinformatics-workflows/references/formats.md +24 -0
  314. package/skills/bioinformatics-workflows/references/workflow-managers.md +107 -0
  315. package/skills/blender-automation/SKILL.md +100 -0
  316. package/skills/blender-automation/evals/triggers.json +16 -0
  317. package/skills/blender-automation/references/batch-and-render.md +77 -0
  318. package/skills/blender-automation/references/bpy-inspection.md +91 -0
  319. package/skills/blender-automation/references/rig-and-retarget-checks.md +23 -0
  320. package/skills/brand-strategy/SKILL.md +83 -0
  321. package/skills/brand-strategy/evals/triggers.json +16 -0
  322. package/skills/brand-voice/SKILL.md +112 -0
  323. package/skills/brand-voice/evals/triggers.json +16 -0
  324. package/skills/browser-qa/SKILL.md +99 -0
  325. package/skills/browser-qa/evals/triggers.json +16 -0
  326. package/skills/bun-runtime/SKILL.md +93 -0
  327. package/skills/bun-runtime/evals/triggers.json +16 -0
  328. package/skills/change-impact-analysis/SKILL.md +89 -0
  329. package/skills/change-impact-analysis/evals/triggers.json +16 -0
  330. package/skills/change-impact-analysis/references/graph-commands.md +28 -0
  331. package/skills/cisco-ios-config/SKILL.md +101 -0
  332. package/skills/cisco-ios-config/evals/triggers.json +18 -0
  333. package/skills/cisco-ios-config/references/verification.md +63 -0
  334. package/skills/clickhouse-patterns/SKILL.md +101 -0
  335. package/skills/clickhouse-patterns/evals/triggers.json +18 -0
  336. package/skills/clickhouse-patterns/references/engines-and-views.md +138 -0
  337. package/skills/clinical-decision-support/SKILL.md +90 -0
  338. package/skills/clinical-decision-support/evals/triggers.json +16 -0
  339. package/skills/clinical-decision-support/references/cds-hooks.md +76 -0
  340. package/skills/clinical-decision-support/references/regulatory-boundaries.md +37 -0
  341. package/skills/code-tour/SKILL.md +97 -0
  342. package/skills/code-tour/evals/triggers.json +14 -0
  343. package/skills/codebase-onboarding/SKILL.md +112 -0
  344. package/skills/codebase-onboarding/evals/triggers.json +14 -0
  345. package/skills/cold-outreach-sequences/SKILL.md +90 -0
  346. package/skills/cold-outreach-sequences/evals/triggers.json +16 -0
  347. package/skills/content-repurposing/SKILL.md +82 -0
  348. package/skills/content-repurposing/evals/triggers.json +16 -0
  349. package/skills/context-budget/SKILL.md +84 -0
  350. package/skills/context-budget/evals/triggers.json +14 -0
  351. package/skills/contract-drafting/SKILL.md +96 -0
  352. package/skills/contract-drafting/evals/triggers.json +16 -0
  353. package/skills/contract-drafting/references/term-sheets.md +68 -0
  354. package/skills/contract-first-development/SKILL.md +86 -0
  355. package/skills/contract-first-development/evals/triggers.json +16 -0
  356. package/skills/contract-first-development/references/tooling.md +46 -0
  357. package/skills/conventional-commits/SKILL.md +144 -0
  358. package/skills/conventional-commits/evals/triggers.json +16 -0
  359. package/skills/cpp-patterns/SKILL.md +129 -0
  360. package/skills/cpp-patterns/evals/triggers.json +16 -0
  361. package/skills/cpp-patterns/references/cmake-and-tooling.md +88 -0
  362. package/skills/cpp-patterns/references/undefined-behaviour.md +75 -0
  363. package/skills/cpp-testing/SKILL.md +131 -0
  364. package/skills/cpp-testing/evals/triggers.json +16 -0
  365. package/skills/csharp-patterns/SKILL.md +110 -0
  366. package/skills/csharp-patterns/evals/triggers.json +17 -0
  367. package/skills/csharp-patterns/references/analyzers.md +59 -0
  368. package/skills/csharp-testing/SKILL.md +85 -0
  369. package/skills/csharp-testing/evals/triggers.json +17 -0
  370. package/skills/csharp-testing/references/integration-tests.md +77 -0
  371. package/skills/css-architecture/SKILL.md +143 -0
  372. package/skills/css-architecture/evals/triggers.json +16 -0
  373. package/skills/customs-trade-compliance/SKILL.md +95 -0
  374. package/skills/customs-trade-compliance/evals/triggers.json +16 -0
  375. package/skills/customs-trade-compliance/references/incoterms-2020.md +42 -0
  376. package/skills/dart-patterns/SKILL.md +157 -0
  377. package/skills/dart-patterns/evals/triggers.json +18 -0
  378. package/skills/dart-testing/SKILL.md +164 -0
  379. package/skills/dart-testing/evals/triggers.json +18 -0
  380. package/skills/data-analysis-notebooks/SKILL.md +113 -0
  381. package/skills/data-analysis-notebooks/evals/triggers.json +16 -0
  382. package/skills/data-analysis-notebooks/references/dataframe-pitfalls.md +49 -0
  383. package/skills/data-analysis-notebooks/references/statistics-pitfalls.md +24 -0
  384. package/skills/data-pipelines/SKILL.md +90 -0
  385. package/skills/data-pipelines/evals/triggers.json +16 -0
  386. package/skills/data-pipelines/references/orchestrators.md +64 -0
  387. package/skills/database-migrations/SKILL.md +102 -0
  388. package/skills/database-migrations/evals/triggers.json +16 -0
  389. package/skills/database-migrations/references/recipes.md +98 -0
  390. package/skills/database-migrations/references/tools.md +21 -0
  391. package/skills/dbt-patterns/SKILL.md +96 -0
  392. package/skills/dbt-patterns/evals/triggers.json +16 -0
  393. package/skills/dbt-patterns/references/yaml-examples.md +114 -0
  394. package/skills/decision-council/SKILL.md +98 -0
  395. package/skills/decision-council/evals/triggers.json +16 -0
  396. package/skills/deep-research/SKILL.md +107 -0
  397. package/skills/deep-research/evals/triggers.json +14 -0
  398. package/skills/dependency-audit/SKILL.md +103 -0
  399. package/skills/dependency-audit/evals/triggers.json +16 -0
  400. package/skills/dependency-audit/references/tools.md +124 -0
  401. package/skills/deployment-strategies/SKILL.md +108 -0
  402. package/skills/deployment-strategies/evals/triggers.json +16 -0
  403. package/skills/design-brainstorming/SKILL.md +132 -0
  404. package/skills/design-brainstorming/evals/behavior.json +55 -0
  405. package/skills/design-brainstorming/evals/triggers.json +16 -0
  406. package/skills/design-brainstorming/references/visual-mockups.md +34 -0
  407. package/skills/desktop-app-testing/SKILL.md +104 -0
  408. package/skills/desktop-app-testing/evals/triggers.json +16 -0
  409. package/skills/desktop-app-testing/references/drivers.md +81 -0
  410. package/skills/django-patterns/SKILL.md +123 -0
  411. package/skills/django-patterns/evals/triggers.json +16 -0
  412. package/skills/docker-patterns/SKILL.md +132 -0
  413. package/skills/docker-patterns/evals/triggers.json +16 -0
  414. package/skills/docker-patterns/references/dockerfiles.md +105 -0
  415. package/skills/document-processing/SKILL.md +100 -0
  416. package/skills/document-processing/evals/triggers.json +17 -0
  417. package/skills/document-processing/references/extraction-and-ocr.md +71 -0
  418. package/skills/document-processing/references/forms-and-conversion.md +69 -0
  419. package/skills/document-processing/references/redaction.md +61 -0
  420. package/skills/e2e-testing-playwright/SKILL.md +94 -0
  421. package/skills/e2e-testing-playwright/evals/triggers.json +16 -0
  422. package/skills/e2e-testing-playwright/references/config-and-ci.md +129 -0
  423. package/skills/ef-core-patterns/SKILL.md +117 -0
  424. package/skills/ef-core-patterns/evals/triggers.json +16 -0
  425. package/skills/email-deliverability/SKILL.md +99 -0
  426. package/skills/email-deliverability/evals/triggers.json +17 -0
  427. package/skills/email-deliverability/references/dns-records.md +85 -0
  428. package/skills/energy-procurement/SKILL.md +106 -0
  429. package/skills/energy-procurement/evals/triggers.json +16 -0
  430. package/skills/error-handling-patterns/SKILL.md +112 -0
  431. package/skills/error-handling-patterns/evals/triggers.json +18 -0
  432. package/skills/error-handling-patterns/references/language-idioms.md +49 -0
  433. package/skills/estimation-and-scoping/SKILL.md +97 -0
  434. package/skills/estimation-and-scoping/evals/triggers.json +14 -0
  435. package/skills/evm-dapp-integration/SKILL.md +73 -0
  436. package/skills/evm-dapp-integration/evals/triggers.json +16 -0
  437. package/skills/fastapi-patterns/SKILL.md +127 -0
  438. package/skills/fastapi-patterns/evals/triggers.json +16 -0
  439. package/skills/ffmpeg-media-processing/SKILL.md +94 -0
  440. package/skills/ffmpeg-media-processing/evals/triggers.json +16 -0
  441. package/skills/ffmpeg-media-processing/references/recipes.md +112 -0
  442. package/skills/fhir-integration/SKILL.md +81 -0
  443. package/skills/fhir-integration/evals/triggers.json +16 -0
  444. package/skills/fhir-integration/references/search-and-bundles.md +73 -0
  445. package/skills/fhir-integration/references/smart-on-fhir.md +50 -0
  446. package/skills/finishing-a-branch/SKILL.md +127 -0
  447. package/skills/finishing-a-branch/evals/behavior.json +49 -0
  448. package/skills/finishing-a-branch/evals/triggers.json +16 -0
  449. package/skills/flask-patterns/SKILL.md +132 -0
  450. package/skills/flask-patterns/evals/triggers.json +16 -0
  451. package/skills/flutter-patterns/SKILL.md +99 -0
  452. package/skills/flutter-patterns/evals/triggers.json +16 -0
  453. package/skills/flutterwave-integration/SKILL.md +75 -0
  454. package/skills/flutterwave-integration/evals/triggers.json +16 -0
  455. package/skills/flutterwave-integration/references/api.md +73 -0
  456. package/skills/flutterwave-integration/references/webhooks.md +49 -0
  457. package/skills/freight-carrier-management/SKILL.md +107 -0
  458. package/skills/freight-carrier-management/evals/triggers.json +16 -0
  459. package/skills/fsharp-patterns/SKILL.md +133 -0
  460. package/skills/fsharp-patterns/evals/triggers.json +16 -0
  461. package/skills/fsharp-testing/SKILL.md +136 -0
  462. package/skills/fsharp-testing/evals/triggers.json +16 -0
  463. package/skills/gcp-patterns/SKILL.md +86 -0
  464. package/skills/gcp-patterns/evals/triggers.json +16 -0
  465. package/skills/git-workflow/SKILL.md +114 -0
  466. package/skills/git-workflow/evals/triggers.json +16 -0
  467. package/skills/git-worktrees/SKILL.md +130 -0
  468. package/skills/git-worktrees/evals/behavior.json +56 -0
  469. package/skills/git-worktrees/evals/triggers.json +16 -0
  470. package/skills/github-actions-ci/SKILL.md +117 -0
  471. package/skills/github-actions-ci/evals/triggers.json +16 -0
  472. package/skills/github-api-automation/SKILL.md +101 -0
  473. package/skills/github-api-automation/evals/triggers.json +17 -0
  474. package/skills/go-patterns/SKILL.md +118 -0
  475. package/skills/go-patterns/evals/triggers.json +17 -0
  476. package/skills/go-patterns/references/concurrency.md +162 -0
  477. package/skills/go-testing/SKILL.md +154 -0
  478. package/skills/go-testing/evals/triggers.json +17 -0
  479. package/skills/google-workspace-integration/SKILL.md +65 -0
  480. package/skills/google-workspace-integration/evals/triggers.json +17 -0
  481. package/skills/google-workspace-integration/references/api.md +121 -0
  482. package/skills/harmonyos-arkts/SKILL.md +117 -0
  483. package/skills/harmonyos-arkts/evals/triggers.json +16 -0
  484. package/skills/harmonyos-arkts/references/build-errors.md +42 -0
  485. package/skills/hexagonal-architecture/SKILL.md +89 -0
  486. package/skills/hexagonal-architecture/evals/triggers.json +17 -0
  487. package/skills/hipaa-compliance/SKILL.md +91 -0
  488. package/skills/hipaa-compliance/evals/triggers.json +18 -0
  489. package/skills/hipaa-compliance/references/safeguards.md +68 -0
  490. package/skills/hl7v2-integration/SKILL.md +69 -0
  491. package/skills/hl7v2-integration/evals/triggers.json +16 -0
  492. package/skills/hl7v2-integration/references/messages-and-ack.md +78 -0
  493. package/skills/homelab-network-setup/SKILL.md +125 -0
  494. package/skills/homelab-network-setup/evals/triggers.json +18 -0
  495. package/skills/homelab-network-setup/references/firewall-and-dns.md +45 -0
  496. package/skills/homelab-network-setup/references/wireguard.md +72 -0
  497. package/skills/hubtel-integration/SKILL.md +77 -0
  498. package/skills/hubtel-integration/evals/triggers.json +16 -0
  499. package/skills/hubtel-integration/references/api.md +92 -0
  500. package/skills/i18n-localization/SKILL.md +114 -0
  501. package/skills/i18n-localization/evals/triggers.json +16 -0
  502. package/skills/i18n-localization/references/libraries.md +52 -0
  503. package/skills/implementation-plans/SKILL.md +117 -0
  504. package/skills/implementation-plans/evals/behavior.json +54 -0
  505. package/skills/implementation-plans/evals/triggers.json +16 -0
  506. package/skills/incident-postmortem/SKILL.md +118 -0
  507. package/skills/incident-postmortem/evals/triggers.json +14 -0
  508. package/skills/inventory-demand-planning/SKILL.md +89 -0
  509. package/skills/inventory-demand-planning/evals/triggers.json +16 -0
  510. package/skills/inventory-demand-planning/references/formulas.md +62 -0
  511. package/skills/investor-materials/SKILL.md +127 -0
  512. package/skills/investor-materials/evals/triggers.json +16 -0
  513. package/skills/investor-materials/references/templates.md +74 -0
  514. package/skills/invoicing-and-tax/SKILL.md +84 -0
  515. package/skills/invoicing-and-tax/evals/triggers.json +17 -0
  516. package/skills/invoicing-and-tax/references/e-invoicing.md +24 -0
  517. package/skills/invoicing-and-tax/references/invoice-fields.md +38 -0
  518. package/skills/invoicing-and-tax/references/rounding.md +26 -0
  519. package/skills/ios-platform-features/SKILL.md +99 -0
  520. package/skills/ios-platform-features/evals/triggers.json +16 -0
  521. package/skills/ios-platform-features/references/foundation-models.md +90 -0
  522. package/skills/java-patterns/SKILL.md +141 -0
  523. package/skills/java-patterns/evals/triggers.json +17 -0
  524. package/skills/java-testing/SKILL.md +142 -0
  525. package/skills/java-testing/evals/triggers.json +16 -0
  526. package/skills/jetpack-compose-patterns/SKILL.md +88 -0
  527. package/skills/jetpack-compose-patterns/evals/triggers.json +16 -0
  528. package/skills/jira-integration/SKILL.md +92 -0
  529. package/skills/jira-integration/evals/triggers.json +17 -0
  530. package/skills/jpa-hibernate/SKILL.md +92 -0
  531. package/skills/jpa-hibernate/evals/triggers.json +18 -0
  532. package/skills/jpa-hibernate/references/mapping.md +99 -0
  533. package/skills/jvm-sql-mappers/SKILL.md +98 -0
  534. package/skills/jvm-sql-mappers/evals/triggers.json +16 -0
  535. package/skills/jvm-sql-mappers/references/examples.md +129 -0
  536. package/skills/kotlin-multiplatform/SKILL.md +97 -0
  537. package/skills/kotlin-multiplatform/evals/triggers.json +16 -0
  538. package/skills/kotlin-patterns/SKILL.md +128 -0
  539. package/skills/kotlin-patterns/evals/triggers.json +16 -0
  540. package/skills/kotlin-testing/SKILL.md +117 -0
  541. package/skills/kotlin-testing/evals/triggers.json +16 -0
  542. package/skills/ktor-patterns/SKILL.md +135 -0
  543. package/skills/ktor-patterns/evals/triggers.json +18 -0
  544. package/skills/kubernetes-patterns/SKILL.md +106 -0
  545. package/skills/kubernetes-patterns/evals/triggers.json +16 -0
  546. package/skills/kubernetes-patterns/references/manifests.md +115 -0
  547. package/skills/laravel-patterns/SKILL.md +136 -0
  548. package/skills/laravel-patterns/evals/triggers.json +16 -0
  549. package/skills/linear-integration/SKILL.md +98 -0
  550. package/skills/linear-integration/evals/triggers.json +17 -0
  551. package/skills/literature-review/SKILL.md +109 -0
  552. package/skills/literature-review/evals/triggers.json +16 -0
  553. package/skills/literature-review/references/appraisal.md +41 -0
  554. package/skills/literature-review/references/search-sources.md +39 -0
  555. package/skills/llm-app-patterns/SKILL.md +97 -0
  556. package/skills/llm-app-patterns/evals/triggers.json +17 -0
  557. package/skills/llm-evals/SKILL.md +98 -0
  558. package/skills/llm-evals/evals/triggers.json +16 -0
  559. package/skills/llm-evals/references/graders.md +66 -0
  560. package/skills/logistics-exception-management/SKILL.md +90 -0
  561. package/skills/logistics-exception-management/evals/triggers.json +16 -0
  562. package/skills/manim-animations/SKILL.md +106 -0
  563. package/skills/manim-animations/evals/triggers.json +16 -0
  564. package/skills/market-research/SKILL.md +117 -0
  565. package/skills/market-research/evals/triggers.json +16 -0
  566. package/skills/marketing-campaign/SKILL.md +111 -0
  567. package/skills/marketing-campaign/evals/triggers.json +16 -0
  568. package/skills/mcp-server-patterns/SKILL.md +127 -0
  569. package/skills/mcp-server-patterns/evals/triggers.json +18 -0
  570. package/skills/mcp-server-patterns/references/protocol-notes.md +68 -0
  571. package/skills/metrics-dashboards/SKILL.md +113 -0
  572. package/skills/metrics-dashboards/evals/triggers.json +16 -0
  573. package/skills/ml-experiment-workflow/SKILL.md +125 -0
  574. package/skills/ml-experiment-workflow/evals/triggers.json +16 -0
  575. package/skills/mobile-accessibility/SKILL.md +94 -0
  576. package/skills/mobile-accessibility/evals/triggers.json +16 -0
  577. package/skills/mongodb-patterns/SKILL.md +115 -0
  578. package/skills/mongodb-patterns/evals/triggers.json +18 -0
  579. package/skills/mongodb-patterns/references/indexes-and-aggregation.md +94 -0
  580. package/skills/mpesa-daraja-integration/SKILL.md +70 -0
  581. package/skills/mpesa-daraja-integration/evals/triggers.json +16 -0
  582. package/skills/mpesa-daraja-integration/references/api.md +103 -0
  583. package/skills/mpesa-daraja-integration/references/callbacks.md +74 -0
  584. package/skills/mtn-momo-integration/SKILL.md +66 -0
  585. package/skills/mtn-momo-integration/evals/triggers.json +16 -0
  586. package/skills/mtn-momo-integration/references/api.md +153 -0
  587. package/skills/mtn-momo-integration/references/callbacks.md +92 -0
  588. package/skills/mtn-momo-integration/references/sandbox-and-go-live.md +51 -0
  589. package/skills/mtn-momo-integration/scripts/sandbox-setup.js +79 -0
  590. package/skills/mysql-patterns/SKILL.md +96 -0
  591. package/skills/mysql-patterns/evals/triggers.json +16 -0
  592. package/skills/mysql-patterns/references/explain.md +34 -0
  593. package/skills/mysql-patterns/references/online-ddl.md +41 -0
  594. package/skills/nestjs-patterns/SKILL.md +114 -0
  595. package/skills/nestjs-patterns/evals/triggers.json +16 -0
  596. package/skills/nestjs-patterns/references/testing.md +68 -0
  597. package/skills/network-automation/SKILL.md +107 -0
  598. package/skills/network-automation/evals/triggers.json +18 -0
  599. package/skills/network-automation/references/tool-snippets.md +153 -0
  600. package/skills/network-design/SKILL.md +98 -0
  601. package/skills/network-design/evals/triggers.json +16 -0
  602. package/skills/network-troubleshooting/SKILL.md +152 -0
  603. package/skills/network-troubleshooting/evals/triggers.json +18 -0
  604. package/skills/network-troubleshooting/references/commands.md +33 -0
  605. package/skills/nextjs-patterns/SKILL.md +150 -0
  606. package/skills/nextjs-patterns/evals/triggers.json +18 -0
  607. package/skills/nextjs-patterns/references/caching.md +87 -0
  608. package/skills/node-backend-patterns/SKILL.md +103 -0
  609. package/skills/node-backend-patterns/evals/triggers.json +16 -0
  610. package/skills/node-backend-patterns/references/templates.md +122 -0
  611. package/skills/nuxt-patterns/SKILL.md +103 -0
  612. package/skills/nuxt-patterns/evals/triggers.json +16 -0
  613. package/skills/observability/SKILL.md +125 -0
  614. package/skills/observability/evals/triggers.json +17 -0
  615. package/skills/observability/references/otel-setup.md +87 -0
  616. package/skills/observability/references/slo-alerts.md +70 -0
  617. package/skills/open-source-release/SKILL.md +107 -0
  618. package/skills/open-source-release/evals/triggers.json +15 -0
  619. package/skills/open-source-release/references/history-scrub.md +65 -0
  620. package/skills/parallel-agent-orchestration/SKILL.md +106 -0
  621. package/skills/parallel-agent-orchestration/evals/triggers.json +14 -0
  622. package/skills/patent-research/SKILL.md +94 -0
  623. package/skills/patent-research/evals/triggers.json +16 -0
  624. package/skills/patent-research/references/databases-and-queries.md +52 -0
  625. package/skills/paystack-integration/SKILL.md +59 -0
  626. package/skills/paystack-integration/evals/triggers.json +14 -0
  627. package/skills/paystack-integration/references/api.md +73 -0
  628. package/skills/paystack-integration/references/mobile-money.md +50 -0
  629. package/skills/paystack-integration/references/webhooks.md +80 -0
  630. package/skills/pci-dss-scope/SKILL.md +103 -0
  631. package/skills/pci-dss-scope/evals/triggers.json +18 -0
  632. package/skills/pci-dss-scope/references/saq-and-data.md +36 -0
  633. package/skills/perl-patterns/SKILL.md +135 -0
  634. package/skills/perl-patterns/evals/triggers.json +18 -0
  635. package/skills/perl-testing/SKILL.md +126 -0
  636. package/skills/perl-testing/evals/triggers.json +17 -0
  637. package/skills/php-patterns/SKILL.md +116 -0
  638. package/skills/php-patterns/evals/triggers.json +16 -0
  639. package/skills/php-testing/SKILL.md +123 -0
  640. package/skills/php-testing/evals/triggers.json +16 -0
  641. package/skills/postgres-patterns/SKILL.md +103 -0
  642. package/skills/postgres-patterns/evals/triggers.json +17 -0
  643. package/skills/postgres-patterns/references/explain.md +59 -0
  644. package/skills/postgres-patterns/references/locks.md +53 -0
  645. package/skills/prd-writing/SKILL.md +124 -0
  646. package/skills/prd-writing/evals/triggers.json +15 -0
  647. package/skills/prisma-patterns/SKILL.md +83 -0
  648. package/skills/prisma-patterns/evals/triggers.json +18 -0
  649. package/skills/prisma-patterns/references/prisma-8.md +46 -0
  650. package/skills/prisma-patterns/references/workflow.md +50 -0
  651. package/skills/privacy-compliance/SKILL.md +121 -0
  652. package/skills/privacy-compliance/evals/triggers.json +18 -0
  653. package/skills/privacy-compliance/references/jurisdictions.md +51 -0
  654. package/skills/production-scheduling/SKILL.md +98 -0
  655. package/skills/production-scheduling/evals/triggers.json +16 -0
  656. package/skills/prompt-engineering/SKILL.md +92 -0
  657. package/skills/prompt-engineering/evals/triggers.json +16 -0
  658. package/skills/prospect-research/SKILL.md +87 -0
  659. package/skills/prospect-research/evals/triggers.json +16 -0
  660. package/skills/python-app-distribution/SKILL.md +107 -0
  661. package/skills/python-app-distribution/evals/triggers.json +16 -0
  662. package/skills/python-app-distribution/references/pypi-trusted-publishing.md +55 -0
  663. package/skills/python-app-distribution/references/windows-macos-signing.md +70 -0
  664. package/skills/python-patterns/SKILL.md +107 -0
  665. package/skills/python-patterns/evals/triggers.json +16 -0
  666. package/skills/python-patterns/references/tooling.md +101 -0
  667. package/skills/python-testing/SKILL.md +126 -0
  668. package/skills/python-testing/evals/triggers.json +16 -0
  669. package/skills/python-testing/references/mocking.md +71 -0
  670. package/skills/pytorch-patterns/SKILL.md +139 -0
  671. package/skills/pytorch-patterns/evals/triggers.json +16 -0
  672. package/skills/pytorch-patterns/references/debugging.md +39 -0
  673. package/skills/quality-nonconformance/SKILL.md +107 -0
  674. package/skills/quality-nonconformance/evals/triggers.json +16 -0
  675. package/skills/quality-nonconformance/references/8d-and-capa.md +46 -0
  676. package/skills/quarkus-patterns/SKILL.md +93 -0
  677. package/skills/quarkus-patterns/evals/triggers.json +18 -0
  678. package/skills/rag-pipeline-patterns/SKILL.md +117 -0
  679. package/skills/rag-pipeline-patterns/evals/triggers.json +18 -0
  680. package/skills/rag-pipeline-patterns/references/evaluation.md +37 -0
  681. package/skills/rag-pipeline-patterns/references/retrieval-recipes.md +78 -0
  682. package/skills/rails-patterns/SKILL.md +132 -0
  683. package/skills/rails-patterns/evals/triggers.json +16 -0
  684. package/skills/react-native-patterns/SKILL.md +101 -0
  685. package/skills/react-native-patterns/evals/triggers.json +16 -0
  686. package/skills/react-patterns/SKILL.md +140 -0
  687. package/skills/react-patterns/evals/triggers.json +18 -0
  688. package/skills/react-performance/SKILL.md +107 -0
  689. package/skills/react-performance/evals/triggers.json +18 -0
  690. package/skills/react-testing/SKILL.md +121 -0
  691. package/skills/react-testing/evals/triggers.json +18 -0
  692. package/skills/react-testing/references/msw.md +64 -0
  693. package/skills/react-testing/references/queries.md +41 -0
  694. package/skills/react-testing/references/setup.md +74 -0
  695. package/skills/recommender-systems/SKILL.md +119 -0
  696. package/skills/recommender-systems/evals/triggers.json +16 -0
  697. package/skills/recommender-systems/references/evaluation.md +39 -0
  698. package/skills/redis-patterns/SKILL.md +109 -0
  699. package/skills/redis-patterns/evals/triggers.json +18 -0
  700. package/skills/redis-patterns/references/operations.md +61 -0
  701. package/skills/refactoring-safely/SKILL.md +107 -0
  702. package/skills/refactoring-safely/evals/behavior.json +57 -0
  703. package/skills/refactoring-safely/evals/triggers.json +17 -0
  704. package/skills/release-management/SKILL.md +141 -0
  705. package/skills/release-management/evals/triggers.json +16 -0
  706. package/skills/remotion-video/SKILL.md +91 -0
  707. package/skills/remotion-video/evals/triggers.json +16 -0
  708. package/skills/remotion-video/references/lambda.md +66 -0
  709. package/skills/reproducible-dev-environments/SKILL.md +132 -0
  710. package/skills/reproducible-dev-environments/evals/triggers.json +16 -0
  711. package/skills/responding-to-code-review/SKILL.md +124 -0
  712. package/skills/responding-to-code-review/evals/behavior.json +54 -0
  713. package/skills/responding-to-code-review/evals/triggers.json +16 -0
  714. package/skills/returns-reverse-logistics/SKILL.md +97 -0
  715. package/skills/returns-reverse-logistics/evals/triggers.json +16 -0
  716. package/skills/ruby-patterns/SKILL.md +127 -0
  717. package/skills/ruby-patterns/evals/triggers.json +18 -0
  718. package/skills/ruby-testing/SKILL.md +113 -0
  719. package/skills/ruby-testing/evals/triggers.json +18 -0
  720. package/skills/runbook-writing/SKILL.md +101 -0
  721. package/skills/runbook-writing/evals/triggers.json +14 -0
  722. package/skills/rust-patterns/SKILL.md +118 -0
  723. package/skills/rust-patterns/evals/triggers.json +16 -0
  724. package/skills/rust-patterns/references/cargo-and-clippy.md +105 -0
  725. package/skills/rust-patterns/references/errors-and-traits.md +97 -0
  726. package/skills/rust-testing/SKILL.md +148 -0
  727. package/skills/rust-testing/evals/triggers.json +16 -0
  728. package/skills/rust-testing/references/fakes-proptest-async.md +113 -0
  729. package/skills/search-first/SKILL.md +73 -0
  730. package/skills/search-first/evals/triggers.json +14 -0
  731. package/skills/security-review/SKILL.md +58 -0
  732. package/skills/security-review/evals/behavior.json +56 -0
  733. package/skills/security-review/evals/triggers.json +14 -0
  734. package/skills/security-review/references/checklist.md +54 -0
  735. package/skills/security-review/scripts/scan-secrets.js +79 -0
  736. package/skills/seo-audit/SKILL.md +111 -0
  737. package/skills/seo-audit/evals/triggers.json +16 -0
  738. package/skills/seo-audit/references/checks.md +65 -0
  739. package/skills/session-handoff/SKILL.md +101 -0
  740. package/skills/session-handoff/evals/behavior.json +55 -0
  741. package/skills/session-handoff/evals/triggers.json +14 -0
  742. package/skills/skill-authoring/SKILL.md +98 -0
  743. package/skills/skill-authoring/evals/triggers.json +15 -0
  744. package/skills/skill-authoring/references/frontmatter.md +40 -0
  745. package/skills/skill-authoring/references/pressure-testing.md +87 -0
  746. package/skills/slack-app-integration/SKILL.md +108 -0
  747. package/skills/slack-app-integration/evals/triggers.json +17 -0
  748. package/skills/slide-decks/SKILL.md +107 -0
  749. package/skills/slide-decks/evals/triggers.json +18 -0
  750. package/skills/slide-decks/references/html-decks.md +86 -0
  751. package/skills/slide-decks/references/layouts.md +45 -0
  752. package/skills/slide-decks/references/pptx.md +87 -0
  753. package/skills/smart-contract-security/SKILL.md +110 -0
  754. package/skills/smart-contract-security/evals/triggers.json +16 -0
  755. package/skills/smart-contract-security/references/vulnerability-checklist.md +79 -0
  756. package/skills/social-media-publishing/SKILL.md +84 -0
  757. package/skills/social-media-publishing/evals/triggers.json +17 -0
  758. package/skills/social-media-publishing/references/platform-apis.md +116 -0
  759. package/skills/solidity-patterns/SKILL.md +95 -0
  760. package/skills/solidity-patterns/evals/triggers.json +16 -0
  761. package/skills/spring-boot-patterns/SKILL.md +128 -0
  762. package/skills/spring-boot-patterns/evals/triggers.json +18 -0
  763. package/skills/spring-boot-patterns/references/testing.md +72 -0
  764. package/skills/stripe-integration/SKILL.md +69 -0
  765. package/skills/stripe-integration/evals/triggers.json +16 -0
  766. package/skills/stripe-integration/references/api.md +71 -0
  767. package/skills/stripe-integration/references/billing.md +58 -0
  768. package/skills/stripe-integration/references/webhooks.md +76 -0
  769. package/skills/subagent-driven-development/SKILL.md +109 -0
  770. package/skills/subagent-driven-development/evals/behavior.json +53 -0
  771. package/skills/subagent-driven-development/evals/triggers.json +15 -0
  772. package/skills/subagent-driven-development/references/implementer-brief.md +60 -0
  773. package/skills/subagent-driven-development/references/reviewer-briefs.md +52 -0
  774. package/skills/subscription-billing-ops/SKILL.md +118 -0
  775. package/skills/subscription-billing-ops/evals/triggers.json +17 -0
  776. package/skills/subscription-billing-ops/references/proration.md +47 -0
  777. package/skills/subscription-billing-ops/references/revenue-metrics.md +38 -0
  778. package/skills/svelte-patterns/SKILL.md +122 -0
  779. package/skills/svelte-patterns/evals/triggers.json +16 -0
  780. package/skills/swift-patterns/SKILL.md +113 -0
  781. package/skills/swift-patterns/evals/triggers.json +16 -0
  782. package/skills/swift-patterns/references/concurrency-migration.md +40 -0
  783. package/skills/swift-testing/SKILL.md +121 -0
  784. package/skills/swift-testing/evals/triggers.json +16 -0
  785. package/skills/swift-testing/references/swift-testing-cheatsheet.md +81 -0
  786. package/skills/swiftui-patterns/SKILL.md +102 -0
  787. package/skills/swiftui-patterns/evals/triggers.json +16 -0
  788. package/skills/systematic-debugging/SKILL.md +92 -0
  789. package/skills/systematic-debugging/evals/behavior.json +59 -0
  790. package/skills/systematic-debugging/evals/triggers.json +16 -0
  791. package/skills/systematic-debugging/references/condition-waiting.md +52 -0
  792. package/skills/systematic-debugging/references/root-cause-tracing.md +49 -0
  793. package/skills/systematic-debugging/references/test-pollution.md +46 -0
  794. package/skills/tdd-workflow/SKILL.md +69 -0
  795. package/skills/tdd-workflow/evals/behavior.json +55 -0
  796. package/skills/tdd-workflow/evals/triggers.json +15 -0
  797. package/skills/tdd-workflow/references/testing-anti-patterns.md +87 -0
  798. package/skills/technical-writing/SKILL.md +95 -0
  799. package/skills/technical-writing/evals/triggers.json +14 -0
  800. package/skills/terraform-patterns/SKILL.md +122 -0
  801. package/skills/terraform-patterns/evals/triggers.json +16 -0
  802. package/skills/terraform-patterns/references/backends.md +67 -0
  803. package/skills/test-coverage-improvement/SKILL.md +107 -0
  804. package/skills/test-coverage-improvement/evals/triggers.json +16 -0
  805. package/skills/threat-modeling/SKILL.md +113 -0
  806. package/skills/threat-modeling/evals/triggers.json +16 -0
  807. package/skills/transactional-email/SKILL.md +68 -0
  808. package/skills/transactional-email/evals/triggers.json +17 -0
  809. package/skills/transactional-email/references/providers.md +63 -0
  810. package/skills/typescript-patterns/SKILL.md +122 -0
  811. package/skills/typescript-patterns/evals/triggers.json +16 -0
  812. package/skills/typescript-testing/SKILL.md +101 -0
  813. package/skills/typescript-testing/evals/triggers.json +16 -0
  814. package/skills/ui-demo-recording/SKILL.md +93 -0
  815. package/skills/ui-demo-recording/evals/triggers.json +16 -0
  816. package/skills/ui-demo-recording/references/cursor-and-captions.md +48 -0
  817. package/skills/ui-demo-recording/references/playwright-recording.md +63 -0
  818. package/skills/ui-demo-recording/references/post-processing.md +57 -0
  819. package/skills/ui-design-polish/SKILL.md +113 -0
  820. package/skills/ui-design-polish/evals/triggers.json +18 -0
  821. package/skills/ui-design-polish/references/detail-checklist.md +45 -0
  822. package/skills/ui-design-polish/references/tokens.md +68 -0
  823. package/skills/ui-flow-audit/SKILL.md +112 -0
  824. package/skills/ui-flow-audit/evals/triggers.json +17 -0
  825. package/skills/ui-motion/SKILL.md +103 -0
  826. package/skills/ui-motion/evals/triggers.json +18 -0
  827. package/skills/ui-motion/references/patterns.md +138 -0
  828. package/skills/ui-motion/references/tokens.md +52 -0
  829. package/skills/unicode-text-processing/SKILL.md +103 -0
  830. package/skills/unicode-text-processing/evals/triggers.json +17 -0
  831. package/skills/unicode-text-processing/references/apis.md +89 -0
  832. package/skills/unicode-text-processing/references/script-notes.md +50 -0
  833. package/skills/verification-loop/SKILL.md +70 -0
  834. package/skills/verification-loop/evals/behavior.json +52 -0
  835. package/skills/verification-loop/evals/triggers.json +14 -0
  836. package/skills/verification-loop/scripts/detect-checks.js +102 -0
  837. package/skills/video-editing/SKILL.md +111 -0
  838. package/skills/video-editing/evals/triggers.json +16 -0
  839. package/skills/video-editing/references/edl-and-logging.md +44 -0
  840. package/skills/video-editing/references/ffmpeg-edit-recipes.md +92 -0
  841. package/skills/video-editing/references/resolve-scripting.md +53 -0
  842. package/skills/vite-patterns/SKILL.md +117 -0
  843. package/skills/vite-patterns/evals/triggers.json +16 -0
  844. package/skills/vue-patterns/SKILL.md +104 -0
  845. package/skills/vue-patterns/evals/triggers.json +16 -0
  846. package/skills/web-accessibility/SKILL.md +119 -0
  847. package/skills/web-accessibility/evals/triggers.json +16 -0
  848. package/skills/web-performance/SKILL.md +107 -0
  849. package/skills/web-performance/evals/triggers.json +16 -0
  850. package/skills/web-scraping/SKILL.md +80 -0
  851. package/skills/web-scraping/evals/triggers.json +16 -0
@@ -0,0 +1,94 @@
1
+ ---
2
+ name: mobile-accessibility
3
+ description: Makes native iOS and Android screens usable with VoiceOver and TalkBack by fixing labels, traits and roles, grouping and reading order, focus moves after navigation, Dynamic Type and sp font scaling, 44pt and 48dp touch targets and colour contrast, across SwiftUI, UIKit, Jetpack Compose and Android Views, then proving it with Accessibility Inspector, Accessibility Scanner and automated audits in UI tests. Use when a native mobile screen must work with a screen reader, large text or switch access, an app store or customer audit flagged accessibility issues, or accessibility checks need adding to XCUITest, Espresso or Compose tests.
4
+ license: MIT
5
+ compatibility: Any Agent Skills host. Testing needs Xcode (Accessibility Inspector, XCUITest) or Android Studio with an emulator or device (Accessibility Scanner, Espresso or Compose UI tests).
6
+ metadata:
7
+ kete-loom/version: "0.1.0"
8
+ kete-loom/category: coding
9
+ kete-loom/risk: writes-files
10
+ kete-loom/owner: "Kete-org"
11
+ ---
12
+
13
+ # Mobile accessibility
14
+
15
+ Fix native iOS and Android UI so people using a screen reader, large text, switch control or low vision can finish every task. For web pages use the web accessibility skill; for React Native or Flutter, apply the same rules through that framework's accessibility props.
16
+
17
+ ## 0. Before you start
18
+
19
+ 1. Find the UI toolkit per screen: SwiftUI, UIKit, Jetpack Compose or Android Views. Many apps mix them.
20
+ 2. List the critical journeys (sign in, search, checkout, settings). Audit those first, not every screen.
21
+ 3. Ask the user whether a target standard applies (WCAG 2.2 AA is the usual reference for mobile, and some contracts or laws name it). Do not claim legal compliance; report findings against the criteria.
22
+
23
+ ## 1. Audit each screen in this order
24
+
25
+ For every screen, check and record each item:
26
+
27
+ 1. **Every control has a name.** Icon-only buttons, images that carry meaning and custom views need a label. Decorative images are hidden from assistive tech.
28
+ 2. **Role and state are announced.** A tappable row says "button", a toggle says on/off, a selected tab says selected, a heading is a heading.
29
+ 3. **Grouping.** A card with title, price and rating is read as one element, not five swipes.
30
+ 4. **Reading and focus order** follows the visual order. After a screen change, sheet or error, focus moves to the new content.
31
+ 5. **Text scales.** At the largest accessibility text size nothing is clipped or overlapped; layouts wrap or scroll instead of truncating.
32
+ 6. **Touch targets** are at least 44 x 44 pt on iOS (Human Interface Guidelines) and 48 x 48 dp on Android (Material). Expand the hit area rather than the visible icon if needed.
33
+ 7. **Contrast** is at least 4.5:1 for body text and 3:1 for large text and essential icons or control borders (WCAG 1.4.3, 1.4.11). Never convey state by colour alone.
34
+ 8. **Motion and transparency** respect Reduce Motion and Reduce Transparency (iOS) and Remove animations (Android).
35
+ 9. **Custom gestures** (swipe to delete, long press) also have an accessible action.
36
+
37
+ ## 2. Fix with the platform API
38
+
39
+ Use the native control first: a real `Button`/`Toggle` gets role, state and focus for free. Add modifiers only where a native control is not possible.
40
+
41
+ | Need | SwiftUI | UIKit | Compose | Android Views |
42
+ |---|---|---|---|---|
43
+ | Name | `.accessibilityLabel("Delete")` | `accessibilityLabel` | `Modifier.semantics { contentDescription = "Delete" }` or `Icon(contentDescription=)` | `android:contentDescription` |
44
+ | Hide decorative | `.accessibilityHidden(true)`, `Image(decorative:)` | `isAccessibilityElement = false` | `contentDescription = null` | `importantForAccessibility="no"` |
45
+ | Role/state | `.accessibilityAddTraits(.isButton)`, `.accessibilityValue` | `accessibilityTraits`, `accessibilityValue` | `Modifier.semantics { role = Role.Button; stateDescription = "On" }`, `Modifier.toggleable` | `ViewCompat.setAccessibilityDelegate`, `stateDescription` |
46
+ | Heading | `.accessibilityAddTraits(.isHeader)` | `.header` trait | `Modifier.semantics { heading() }` | `android:accessibilityHeading="true"` |
47
+ | Group | `.accessibilityElement(children: .combine)` | container view as one element with a combined label | `Modifier.semantics(mergeDescendants = true) {}` or `clickable` on the row | `android:focusable="true"` on the parent, `screenReaderFocusable` |
48
+ | Order | `.accessibilitySortPriority` | `accessibilityElements` array | `Modifier.semantics { traversalIndex = 1f; isTraversalGroup = true }` | `android:accessibilityTraversalBefore/After` |
49
+ | Move focus | `@AccessibilityFocusState` | `UIAccessibility.post(notification: .screenChanged, argument: view)` | `Modifier.semantics { paneTitle = "..." }` on the new pane; `FocusRequester` moves input focus, which TalkBack may not follow, so check on a device | `view.sendAccessibilityEvent` or `performAccessibilityAction(ACTION_ACCESSIBILITY_FOCUS)` |
50
+ | Announce | `AccessibilityNotification.Announcement("Saved").post()` | `UIAccessibility.post(notification: .announcement, argument:)` | `Modifier.semantics { liveRegion = LiveRegionMode.Polite }` | `android:accessibilityLiveRegion="polite"` |
51
+ | Custom action | `.accessibilityAction(named: "Delete") {}` | `accessibilityCustomActions` | `Modifier.semantics { customActions = listOf(...) }` | `ViewCompat.addAccessibilityAction` |
52
+ | Text scaling | `.font(.body)` text styles, `@ScaledMetric` | `UIFont.preferredFont(forTextStyle:)` + `adjustsFontForContentSizeCategory = true` | `sp` units via `MaterialTheme.typography` | `sp` for `textSize`, avoid fixed `dp` heights on text |
53
+ | Touch target | `.frame(minWidth: 44, minHeight: 44)` + `.contentShape(Rectangle())` | override `point(inside:with:)` or larger frame | `Modifier.minimumInteractiveComponentSize()` (Material 3 does this for its components) | `minWidth`/`minHeight` 48dp or `TouchDelegate` |
54
+
55
+ Label rules:
56
+
57
+ - Say what it does, not what it looks like: "Delete message", not "trash can". Do not add "button" to a label; the role says it.
58
+ - Keep labels short and put the important word first. Put extra guidance in a hint (`accessibilityHint`) only when the action is not obvious.
59
+ - Localise labels with the rest of the strings.
60
+
61
+ ## 3. Verify
62
+
63
+ 1. **Manual screen reader pass** of each critical journey: VoiceOver on iOS (Settings, Accessibility, VoiceOver, or the Accessibility Shortcut), TalkBack on Android. Swipe through every element; activate every control; complete the task without looking.
64
+ 2. **Largest text size**: iOS Settings, Accessibility, Display and Text Size, Larger Text; Android Settings, Display, Font size (and Display size). Use Xcode's Environment Overrides or the Compose `@Preview(fontScale = 2f)` while iterating.
65
+ 3. **Inspectors**: Xcode's Accessibility Inspector (Audit tab, and inspect an element's label, traits and frame); Android's Accessibility Scanner app on a device or emulator.
66
+ 4. **Automated checks in UI tests**, so regressions fail CI:
67
+ - iOS 17+ XCUITest: `try app.performAccessibilityAudit()` on each critical screen; narrow with `for: [.contrast, .dynamicType, .hitRegion]` and filter known false positives in the issue handler (return `true` to ignore an issue), with a comment why.
68
+ - Espresso: add `androidx.test.espresso:espresso-accessibility` and call `AccessibilityChecks.enable()` in the test setup.
69
+ - Compose 1.8+: add `androidx.compose.ui:ui-test-junit4-accessibility`, call `composeTestRule.enableAccessibilityChecks()` on an `AndroidComposeTestRule`; checks run on actions, or call `onRoot().tryPerformAccessibilityChecks()`.
70
+ 5. Rerun the tests and the manual pass after every fix.
71
+
72
+ Automated audits catch only part of the real problems (they cannot judge whether a label makes sense or a journey can be finished). A clean audit never replaces the screen reader pass.
73
+
74
+ ## Stop and ask the user
75
+
76
+ - A fix would change the visual design (bigger targets, colours that pass contrast, text wrapping onto more lines). Show the before and after and let design decide how, not whether.
77
+ - A custom control (chart, canvas, game view, map) has no obvious accessible equivalent; propose a text summary or alternative view first.
78
+ - The project has no UI test target and adding one is a large change.
79
+
80
+ ## Never
81
+
82
+ - Never hide a focusable, interactive element from assistive tech to silence an audit warning.
83
+ - Never cap or disable Dynamic Type or font scaling (`maximumContentSizeCategory`, fixed `dp` text) to save a layout, unless the user agrees for that specific element and the content stays readable another way.
84
+ - Never put the same label on several different controls in one screen ("Button", "Image", "More").
85
+ - Never rely on a tooltip, colour or position alone to convey meaning.
86
+
87
+ ## Report back
88
+
89
+ ```
90
+ Screens audited: <list>
91
+ Issues: <id> | <screen> | <criterion, e.g. name, order, target size> | <severity: blocker/major/minor> | <fix or status>
92
+ Verified with: <VoiceOver/TalkBack pass, largest text, Inspector/Scanner, UI test audits added (test names)>
93
+ Open: <items needing design decisions or not fixed>
94
+ ```
@@ -0,0 +1,16 @@
1
+ {
2
+ "should_trigger": [
3
+ "VoiceOver reads our SwiftUI product card as five separate items, make it one element with a sensible label",
4
+ "TalkBack just says 'unlabelled button' on all the icon buttons in our Compose toolbar",
5
+ "At the largest Dynamic Type size our UIKit settings screen clips text, fix it so it scales",
6
+ "Add automated accessibility audits to our XCUITest and Espresso suites so regressions fail CI",
7
+ "Accessibility Scanner flags touch target too small and low contrast on our Android login screen"
8
+ ],
9
+ "should_not_trigger": [
10
+ "Make our React web checkout pass WCAG 2.2 AA with keyboard navigation and axe",
11
+ "Our Compose LazyColumn janks when scrolling, reduce recomposition",
12
+ "Migrate this SwiftUI screen from ObservableObject to @Observable",
13
+ "Write XCTest unit tests for the login view model with a fake network client",
14
+ "Translate the Android app strings into Arabic and support right-to-left layouts"
15
+ ]
16
+ }
@@ -0,0 +1,115 @@
1
+ ---
2
+ name: mongodb-patterns
3
+ description: MongoDB document modelling and query tuning, from embed-versus-reference decisions and unbounded-array traps to compound indexes ordered by the ESR rule, reading explain executionStats, aggregation pipelines, multi-document transactions on replica sets, and $jsonSchema collection validation. Use when designing or changing MongoDB collections, a MongoDB query or aggregation is slow, adding indexes or validators, or deciding whether a write needs a transaction, with the native driver, Mongoose or another ODM.
4
+ license: MIT
5
+ compatibility: Any Agent Skills host. Commands are mongosh syntax; the same options exist in every official driver. Atlas-only features (Atlas Search, Performance Advisor) are noted as such.
6
+ metadata:
7
+ kete-loom/version: "0.1.0"
8
+ kete-loom/category: data
9
+ kete-loom/risk: runs-commands
10
+ kete-loom/requires: "mongosh"
11
+ kete-loom/owner: "Kete-org"
12
+ ---
13
+
14
+ # MongoDB patterns
15
+
16
+ Model documents around how the application reads them, index for the queries it actually runs, and prove every performance claim with `explain`. The detailed recipes live in `references/indexes-and-aggregation.md`.
17
+
18
+ ## 0. Before you start
19
+
20
+ 1. Find the driver or ODM (native driver, Mongoose, Motor, Spring Data, Prisma) and where the connection string comes from. Search for `MongoClient`, `mongoose.connect` or the `mongodb://` / `mongodb+srv://` variable.
21
+ 2. Get the server version and topology with `db.version()` and `db.hello()` (look for `setName` for a replica set, `msg: "isdbgrid"` for mongos). Transactions and change streams need a replica set or sharded cluster.
22
+ 3. List the queries the feature will run: filter fields, sort, projection, and how many documents each returns. If you can't list them, **stop and ask the user**; a model can't be judged without them.
23
+ 4. Never run `dropDatabase`, `drop`, `deleteMany({})`, `updateMany` without a tight filter, or a `collMod` that tightens validation on a shared or production database without the user's explicit approval. Build indexes on large production collections only after the user has agreed on timing; they consume I/O while they build.
24
+
25
+ ## 1. Embed or reference
26
+
27
+ Embed when the data is read together, owned by the parent, and bounded in size. Reference when it is shared, updated on its own, or grows without limit.
28
+
29
+ | Relationship | Default |
30
+ |---|---|
31
+ | One-to-few, read with the parent (addresses, line items of an order) | Embed an array |
32
+ | One-to-many, unbounded (comments on a post, events of a device) | Separate collection with the parent's `_id` indexed on the child |
33
+ | Many-to-many (students and courses) | Array of IDs on the side queried most, or a link collection |
34
+ | Data shared by many parents and edited (product name in old orders) | Reference; copy only fields that should freeze at write time (the price paid) |
35
+
36
+ Rules:
37
+
38
+ - A document is at most 16 MiB. Any array that grows with user activity must have a hard cap or live in its own collection. Large, frequently rewritten arrays also make every update expensive.
39
+ - Design so the common page loads with **one query**. If it needs `$lookup` on every request, reconsider the model (or accept it knowingly for low-traffic paths).
40
+ - Duplicating a field is fine when you know who updates the copies. Write it down in the code next to the update.
41
+ - Use the **bucket** pattern for time series on older servers (one document per device per hour), or a native time series collection (`db.createCollection(name, { timeseries: { timeField, metaField } })`).
42
+ - Use the **subset** pattern for large related lists: embed the latest N, keep the rest in a separate collection.
43
+
44
+ ## 2. Indexes
45
+
46
+ - Every query in a request path needs an index that supports its filter and sort. A `COLLSCAN` in `explain` on a large collection is a bug.
47
+ - Order compound index keys by **ESR**: **E**quality fields first, then **S**ort fields, then **R**ange fields (`$gt`, `$lt`, `$in` with many values, regex).
48
+ - One compound index can serve its prefixes: `{ tenantId: 1, status: 1, createdAt: -1 }` also serves `{ tenantId: 1 }`. Drop indexes that are a prefix of another.
49
+ - Use partial indexes (`partialFilterExpression`) for queries that only touch a subset, unique indexes for invariants, and TTL indexes (`expireAfterSeconds`) for expiring data.
50
+ - Each index costs RAM and slows every write. Check usage with `db.coll.aggregate([{ $indexStats: {} }])` before adding more, and propose removing unused ones (hide them first with `db.coll.hideIndex(name)` to test safely).
51
+
52
+ Verify with:
53
+
54
+ ```js
55
+ db.orders.find({ tenantId: t, status: "open" }).sort({ createdAt: -1 }).explain("executionStats")
56
+ ```
57
+
58
+ Read `winningPlan` (want `IXSCAN`, no in-memory `SORT` stage), `totalKeysExamined` and `totalDocsExamined` against `nReturned` (want them close), and `executionTimeMillis`. Report these numbers before and after.
59
+
60
+ ## 3. Aggregation
61
+
62
+ - Put `$match` first and `$project`/`$unset` early so later stages see fewer, smaller documents; only the leading `$match` and `$sort` can use an index.
63
+ - `$lookup` needs an index on the foreign field. Avoid `$lookup` inside hot request paths when an embed would do.
64
+ - Each blocking stage (`$group`, `$sort` without an index, `$bucket`) has a 100 MB memory limit before it spills to disk or errors, depending on `allowDiskUse` and the server default. Spilling is slow; prefer narrowing earlier.
65
+ - Use `$facet` for several counts over one result set instead of several round trips, and `$merge`/`$out` to precompute heavy reports on a schedule.
66
+ - Paginate with a range on an indexed key (`_id > lastSeenId`), not large `skip` values.
67
+
68
+ ## 4. Transactions
69
+
70
+ - A single-document write is already atomic, including its embedded arrays. Model so most invariants live in one document; reach for a transaction only when several documents must change together.
71
+ - Transactions need a replica set or sharded cluster, and by default must finish within 60 seconds (`transactionLifetimeLimitSeconds`). Keep them short and touch few documents.
72
+ - Use the driver's callback API (`session.withTransaction(fn)`), which retries on `TransientTransactionError` and `UnknownTransactionCommitResult`. Pass the session to **every** operation inside, or that operation runs outside the transaction.
73
+ - Use `writeConcern: { w: "majority" }` and `readConcern: "snapshot"` for transactions whose result must survive failover.
74
+ - Outside transactions, guard concurrent updates with conditional filters (`updateOne({ _id, version: 3 }, { $set: {...}, $inc: { version: 1 } })`) and check `matchedCount`.
75
+
76
+ ## 5. Schema validation
77
+
78
+ Keep the database honest even if one service skips the ODM's checks:
79
+
80
+ ```js
81
+ db.runCommand({
82
+ collMod: "orders",
83
+ validator: { $jsonSchema: {
84
+ bsonType: "object",
85
+ required: ["tenantId", "status", "total"],
86
+ properties: {
87
+ status: { enum: ["open", "paid", "cancelled"] },
88
+ total: { bsonType: "decimal" }
89
+ }
90
+ }},
91
+ validationLevel: "moderate",
92
+ validationAction: "error"
93
+ })
94
+ ```
95
+
96
+ - Roll out on an existing collection with `validationAction: "warn"` first, check the logs for violations, fix the data, then switch to `"error"`. `validationLevel: "moderate"` checks inserts and updates to documents that are already valid; updates to documents that were already invalid are not checked, so fix those in a backfill.
97
+ - Store money as `Decimal128` or integer minor units, never as a double. Store dates as BSON dates, not strings.
98
+
99
+ ## Never
100
+
101
+ - Build query filters from raw request JSON; a body like `{ "$ne": null }` becomes an operator. Validate types or use a sanitiser, and reject keys starting with `$`.
102
+ - Use `$where` or server-side JavaScript on user input.
103
+ - Let arrays grow without a limit inside a document.
104
+ - Claim a query is fast without `explain("executionStats")` output.
105
+
106
+ ## Report format (when reviewing)
107
+
108
+ ```
109
+ MongoDB review: <collections or feature>
110
+ Topology/version: <replica set | sharded | standalone>, <version>
111
+ Findings:
112
+ 1. [severity] <file:line or collection>: <problem> → <fix>
113
+ Explain evidence: <query> keys/docs examined vs returned, before → after
114
+ Not verified: <anything you could not run>
115
+ ```
@@ -0,0 +1,18 @@
1
+ {
2
+ "should_trigger": [
3
+ "Should I embed comments inside the post document or put them in their own MongoDB collection?",
4
+ "This Mongo aggregation with $lookup and $group takes 8 seconds, help me speed it up",
5
+ "explain() shows COLLSCAN on our orders collection, what compound index do we need?",
6
+ "Add a $jsonSchema validator to the users collection without breaking existing documents",
7
+ "Do I need a transaction in Mongoose to move credits between two wallet documents?",
8
+ "Design the document model for a multi-tenant SaaS on MongoDB Atlas"
9
+ ],
10
+ "should_not_trigger": [
11
+ "Cache the user profile in Redis with a five minute TTL",
12
+ "Write a Prisma schema for users and posts on Postgres",
13
+ "Design a ClickHouse table for billions of analytics events",
14
+ "Normalise this Postgres schema and add foreign keys",
15
+ "Write a zero-downtime migration that renames a column in MySQL",
16
+ "Review this pull request for SQL injection and auth bugs"
17
+ ]
18
+ }
@@ -0,0 +1,94 @@
1
+ # MongoDB indexes and aggregation recipes
2
+
3
+ Read this when designing an index for a specific query, debugging a slow aggregation, or writing a migration that reshapes documents. Confirm option names against the MongoDB manual for the server version in use.
4
+
5
+ ## ESR worked example
6
+
7
+ Query:
8
+
9
+ ```js
10
+ db.orders.find({ tenantId: t, status: "open", total: { $gte: 100 } }).sort({ createdAt: -1 })
11
+ ```
12
+
13
+ - Equality: `tenantId`, `status`
14
+ - Sort: `createdAt`
15
+ - Range: `total`
16
+
17
+ Index: `{ tenantId: 1, status: 1, createdAt: -1, total: 1 }`. Putting `total` before `createdAt` forces an in-memory sort.
18
+
19
+ A covered query (only indexed fields in filter and projection, `_id: 0` unless `_id` is indexed in that index) shows `totalDocsExamined: 0`.
20
+
21
+ ## Reading explain
22
+
23
+ ```js
24
+ db.coll.find(filter).sort(sort).explain("executionStats")
25
+ db.coll.aggregate(pipeline, { explain: true }) // or .explain("executionStats") on the cursor
26
+ ```
27
+
28
+ | Field | Good sign | Bad sign |
29
+ |---|---|---|
30
+ | `winningPlan.stage` tree | `IXSCAN` → `FETCH` | `COLLSCAN`; `SORT` stage (in-memory sort) |
31
+ | `totalKeysExamined` / `nReturned` | close to 1 | much larger: index not selective or wrong order |
32
+ | `totalDocsExamined` / `nReturned` | close to 1 | large: filter applied after fetch |
33
+ | `rejectedPlans` | few | many similar indexes competing |
34
+
35
+ Use the profiler only with the user's agreement on shared servers: `db.setProfilingLevel(1, { slowms: 100 })`, then `db.system.profile.find().sort({ ts: -1 }).limit(10)`. Turn it off afterwards with `db.setProfilingLevel(0)`. On Atlas, the Query Profiler and Performance Advisor show the same without changing settings.
36
+
37
+ ## Index options
38
+
39
+ ```js
40
+ db.users.createIndex({ email: 1 }, { unique: true, collation: { locale: "en", strength: 2 } }) // case-insensitive unique
41
+ db.sessions.createIndex({ expiresAt: 1 }, { expireAfterSeconds: 0 }) // TTL at the stored date
42
+ db.orders.createIndex({ status: 1, createdAt: -1 }, { partialFilterExpression: { status: "open" } })
43
+ db.coll.hideIndex("old_index_name") // test dropping without losing it
44
+ db.coll.unhideIndex("old_index_name")
45
+ ```
46
+
47
+ - A query uses a collation-specific index only if it specifies the same collation.
48
+ - A partial index is used only when the query filter implies the partial expression.
49
+ - The TTL monitor runs periodically, so expired documents disappear with some delay; don't rely on it for exact expiry.
50
+ - A multikey index (on an array field) can't be compound with a second array field.
51
+
52
+ ## Aggregation patterns
53
+
54
+ Top N per group:
55
+
56
+ ```js
57
+ db.orders.aggregate([
58
+ { $match: { tenantId: t, createdAt: { $gte: since } } },
59
+ { $sort: { customerId: 1, total: -1 } },
60
+ { $group: { _id: "$customerId", top: { $firstN: { input: "$$ROOT", n: 3 } } } }
61
+ ])
62
+ ```
63
+
64
+ (`$firstN` needs MongoDB 5.2 or later; on older servers use `$push` then `$slice`.)
65
+
66
+ Indexed `$lookup` with a sub-pipeline (combining `localField`/`foreignField` with `pipeline` needs MongoDB 5.0 or later; older servers need `let` and `$expr`):
67
+
68
+ ```js
69
+ { $lookup: {
70
+ from: "customers",
71
+ localField: "customerId",
72
+ foreignField: "_id",
73
+ pipeline: [{ $project: { name: 1, tier: 1 } }],
74
+ as: "customer"
75
+ }}
76
+ ```
77
+
78
+ Several counts in one pass:
79
+
80
+ ```js
81
+ { $facet: {
82
+ byStatus: [{ $group: { _id: "$status", n: { $sum: 1 } } }],
83
+ total: [{ $count: "n" }]
84
+ }}
85
+ ```
86
+
87
+ Precompute a report: end the pipeline with `{ $merge: { into: "daily_sales", on: "_id", whenMatched: "replace" } }` and run it from a scheduled job.
88
+
89
+ ## Reshaping documents safely
90
+
91
+ 1. Add the new field in code that writes both shapes; read with a fallback.
92
+ 2. Backfill in batches with `bulkWrite` filtered on documents missing the new field, so the job can be re-run.
93
+ 3. Switch reads to the new field, then stop writing the old one, then remove it with `$unset` in batches.
94
+ 4. Tighten the `$jsonSchema` validator last.
@@ -0,0 +1,70 @@
1
+ ---
2
+ name: mpesa-daraja-integration
3
+ description: Implements and audits direct Safaricom M-Pesa integrations on the Daraja API in Kenya, including the OAuth client-credentials token, Lipa na M-Pesa Online (STK Push) with the base64 shortcode+passkey+timestamp password, stkCallback parsing, confirmation through the STK Push Query endpoint, C2B URL registration with validation and confirmation, B2C payouts with SecurityCredential, and the sandbox-to-production go-live path. Use when calling Daraja endpoints yourself rather than via Flutterwave or another aggregator, wiring an M-Pesa paybill or till into an app, or debugging Daraja errors such as invalid access token, wrong credentials or ResultCode 1032.
4
+ license: MIT
5
+ compatibility: Any Agent Skills host. Live calls need network access to sandbox.safaricom.co.ke or api.safaricom.co.ke. Examples are TypeScript (Node 18+); the rules apply to any backend language.
6
+ metadata:
7
+ kete-loom/version: "0.1.0"
8
+ kete-loom/category: integrations
9
+ kete-loom/risk: network
10
+ kete-loom/owner: "Kete-org"
11
+ ---
12
+
13
+ # M-Pesa Daraja integration
14
+
15
+ Build an M-Pesa flow where a forged callback can't mark an order paid, a lost callback still settles, and a payout is never sent twice. This skill is for Safaricom's Daraja API called directly. If the project collects M-Pesa through Flutterwave, Paystack or another aggregator, follow that provider's flow instead.
16
+
17
+ ## Ground rules
18
+
19
+ 1. **Credentials stay on the server.** Consumer key and secret, passkey, initiator name and initiator password are secrets in the environment. Sandbox and production have different keys, shortcodes, passkeys and base URLs (`https://sandbox.safaricom.co.ke` vs `https://api.safaricom.co.ke`).
20
+ 2. **Cache the access token.** `GET /oauth/v1/generate?grant_type=client_credentials` with Basic auth (`consumerKey:consumerSecret`) returns a token valid for about an hour (`expires_in` 3599 or 3600). Refresh before expiry; don't request one per payment.
21
+ 3. **The server sets the amount.** Daraja `Amount` is whole shillings. Compute it from your own order; never accept it from the client.
22
+ 4. **`ResponseCode: "0"` means accepted, not paid.** The STK Push response only says the prompt was queued. Store `CheckoutRequestID` and `MerchantRequestID` against the order straight away.
23
+ 5. **Callbacks are unsigned.** Daraja does not sign `stkCallback`, C2B or B2C results. Never give value from the callback body alone. Put an unguessable per-payment token in the callback path, match `CheckoutRequestID` to a stored pending payment, and confirm with STK Push Query (or Transaction Status) before fulfilling. If Safaricom gives you its callback IP range, allow-list it as an extra layer.
24
+ 6. **Fulfilment is idempotent.** Guarded update keyed on `CheckoutRequestID` (`... WHERE status = 'pending'`), and a unique constraint on `MpesaReceiptNumber`. Callbacks, queries and retries can all arrive.
25
+ 7. **Payouts are never sent blind twice.** Generate and store a unique `OriginatorConversationID` per payout before the call. Daraja is not documented to reject a repeated ID, so after a timeout or lost result check Transaction Status first and retry only when it shows the payout did not happen.
26
+
27
+ ## STK Push flow
28
+
29
+ ```
30
+ client ──(order id, phone 2547XXXXXXXX)──▶ server: create pending payment
31
+ server ──POST /mpesa/stkpush/v1/processrequest──▶ Daraja: ResponseCode "0", CheckoutRequestID
32
+ customer enters M-Pesa PIN on the phone
33
+ Daraja ──POST CallBackURL {Body.stkCallback}──▶ server: 200 at once, queue a check
34
+ server ──POST /mpesa/stkpushquery/v1/query──▶ ResultCode 0 + amount matches → fulfil once
35
+ background job: query payments still pending after ~1-2 minutes; expire them later
36
+ ```
37
+
38
+ ## Implementation steps
39
+
40
+ 1. **Configure** environment variables: base URL, consumer key/secret, `BusinessShortCode`, passkey, callback base URL, and for B2C the initiator name and production certificate. Shapes and samples: `references/api.md`.
41
+ 2. **Build the password**: `Timestamp` is `YYYYMMDDHHmmss` in Kenyan time (EAT, UTC+3); `Password = base64(BusinessShortCode + Passkey + Timestamp)`. Generate both per request; a stale timestamp or one in the wrong timezone causes "Wrong credentials".
42
+ 3. **Send STK Push** with `TransactionType` `CustomerPayBillOnline` (paybill) or `CustomerBuyGoodsOnline` (till; then `PartyB` is the till number while `BusinessShortCode` is the store/HO number). Normalise the phone to `2547XXXXXXXX` or `2541XXXXXXXX`. `AccountReference` is at most 12 characters, `TransactionDesc` at most 13.
43
+ 4. **Handle the callback** as in `references/callbacks.md`: respond quickly, match on `CheckoutRequestID`, read `ResultCode` and `CallbackMetadata`, then confirm with STK Push Query.
44
+ 5. **Map result codes** to customer messages: `1032` cancelled, `1037` phone unreachable, `1` insufficient balance, `2001` wrong PIN, `1019` expired, `17` duplicate request within 2 minutes. Let the customer retry with a new STK Push.
45
+ 6. **C2B (customer pays your paybill/till from their phone)**: register Confirmation and Validation URLs once with `/mpesa/c2b/v2/registerurl`; see `references/callbacks.md`. Match payments to orders by `BillRefNumber` (the account number the customer typed) and dedupe on `TransID`.
46
+ 7. **B2C payouts**: `/mpesa/b2c/v3/paymentrequest` with `SecurityCredential` (initiator password RSA-encrypted with Safaricom's certificate for that environment, base64). The result arrives at `ResultURL`; a timeout at `QueueTimeOutURL`. Treat a queue timeout as unknown, not failed: check Transaction Status before retrying.
47
+ 8. **Persist** per payment: order id, phone, amount, `MerchantRequestID`, `CheckoutRequestID`, `MpesaReceiptNumber`, `ResultCode`, `ResultDesc`, status, timestamps.
48
+
49
+ ## Reviewing an existing integration
50
+
51
+ Check each ground rule, then look for:
52
+
53
+ - Order marked paid when the STK Push request returns `ResponseCode "0"`.
54
+ - Callback body trusted with no match to a stored `CheckoutRequestID` and no query.
55
+ - `Amount` read from `CallbackMetadata` without comparing it to the stored order amount.
56
+ - Token fetched on every request, causing spike-arrest or quota errors (`500.003.02`, `500.003.03`).
57
+ - Timestamp built from server UTC or local time instead of EAT.
58
+ - Callback URL that is not public HTTPS, uses a tunnel URL in production, or contains blocked words such as `mpesa`, `safaricom`, `sql`, `exec`, `cmd` or `query`.
59
+ - Sandbox shortcode `174379` or sandbox passkey left in production config.
60
+ - B2C retried after a timeout or missing result without a Transaction Status check first.
61
+
62
+ ## Stop and ask the user
63
+
64
+ - Paybill or till, and which shortcode is used on go-live.
65
+ - Whether C2B validation is needed; it is off by default and Safaricom has to enable it.
66
+ - Before writing any B2C code: payouts move real money and need a B2C shortcode and an API initiator created on the M-Pesa org portal.
67
+
68
+ ## Before you finish
69
+
70
+ Daraja's docs at developer.safaricom.co.ke are the final word on fields and endpoints; this skill gives the rules and the shape. Production endpoints and the production passkey are issued at go-live. Then test in the sandbox: a successful STK Push, a cancelled prompt (1032), a phone that never answers, a callback that never arrives (the query job must settle it), a forged callback with a known `CheckoutRequestID` but a failed query (must not fulfil), and the same callback twice.
@@ -0,0 +1,16 @@
1
+ {
2
+ "should_trigger": [
3
+ "Implement Lipa na M-Pesa STK push for our Kenyan delivery app using Daraja",
4
+ "Daraja keeps returning Wrong credentials for my STK push password, what's wrong?",
5
+ "Register C2B confirmation and validation URLs for our paybill number",
6
+ "Pay out refunds to customers' M-Pesa numbers with the B2C API",
7
+ "Our stkCallback never arrives in production, how do we still confirm the payment?"
8
+ ],
9
+ "should_not_trigger": [
10
+ "Charge a Kenyan customer's M-Pesa wallet through Flutterwave from our backend",
11
+ "Integrate MTN MoMo request to pay for Ugandan customers",
12
+ "Accept Telecel Cash payments through Hubtel in our Ghana app",
13
+ "Check our checkout code for client-trusted amounts and missing idempotency",
14
+ "Add Stripe Checkout for card payments in Kenya"
15
+ ]
16
+ }
@@ -0,0 +1,103 @@
1
+ # Daraja API shapes used by this skill
2
+
3
+ Base URLs: sandbox `https://sandbox.safaricom.co.ke`, production `https://api.safaricom.co.ke`. Every call except the token call sends `Authorization: Bearer <token>` and `Content-Type: application/json` (a missing content type gives "Bad Request - Invalid BusinessShortCode").
4
+
5
+ Confirm fields against developer.safaricom.co.ke before shipping; this is a working summary.
6
+
7
+ ## Access token
8
+
9
+ `GET /oauth/v1/generate?grant_type=client_credentials` with `Authorization: Basic base64(consumerKey:consumerSecret)`.
10
+
11
+ Response: `{ "access_token": "...", "expires_in": "3599" }`. `404.001.03 Invalid Access Token` means expired or from the wrong app.
12
+
13
+ ## STK Push (M-Pesa Express)
14
+
15
+ `POST /mpesa/stkpush/v1/processrequest`
16
+
17
+ ```json
18
+ {
19
+ "BusinessShortCode": "174379",
20
+ "Password": "<base64(BusinessShortCode + Passkey + Timestamp)>",
21
+ "Timestamp": "20260618092408",
22
+ "TransactionType": "CustomerPayBillOnline",
23
+ "Amount": "150",
24
+ "PartyA": "254712345678",
25
+ "PartyB": "174379",
26
+ "PhoneNumber": "254712345678",
27
+ "CallBackURL": "https://api.example.com/hooks/daraja/stk/<per-payment-token>",
28
+ "AccountReference": "ORD8F2C1A",
29
+ "TransactionDesc": "Order"
30
+ }
31
+ ```
32
+
33
+ Response: `MerchantRequestID`, `CheckoutRequestID`, `ResponseCode` (`"0"` = accepted), `ResponseDescription`, `CustomerMessage`.
34
+
35
+ Limits from the Daraja FAQ: minimum KES 1, up to KES 250,000 per transaction, daily KES 500,000. Only one prompt can be live per subscriber; "Unable to lock subscriber" means wait about a minute.
36
+
37
+ ## STK Push Query
38
+
39
+ `POST /mpesa/stkpushquery/v1/query`
40
+
41
+ ```json
42
+ { "BusinessShortCode": "174379", "Password": "<fresh>", "Timestamp": "<fresh>", "CheckoutRequestID": "ws_CO_..." }
43
+ ```
44
+
45
+ Response has `ResultCode` and `ResultDesc`. `ResultCode` `"0"` = paid. While the customer has not answered, the query returns an error rather than a final code; retry with backoff.
46
+
47
+ ## Result codes (STK)
48
+
49
+ | Code | Meaning |
50
+ |---|---|
51
+ | 0 | Paid |
52
+ | 1 | Insufficient balance |
53
+ | 17 | Same amount to same customer within 2 minutes |
54
+ | 1019 | Transaction expired |
55
+ | 1025 | Push failed (prompt over 182 characters; shorten AccountReference) |
56
+ | 1032 | Cancelled by user |
57
+ | 1037 | Phone unreachable |
58
+ | 2001 | Wrong PIN |
59
+ | 2028 | TransactionType / PartyB don't match the shortcode type |
60
+
61
+ ## C2B register URLs
62
+
63
+ `POST /mpesa/c2b/v2/registerurl`
64
+
65
+ ```json
66
+ { "ShortCode": "600638", "ResponseType": "Completed", "ConfirmationURL": "https://api.example.com/hooks/daraja/c2b/confirm", "ValidationURL": "https://api.example.com/hooks/daraja/c2b/validate" }
67
+ ```
68
+
69
+ `ResponseType` (`Completed` or `Cancelled`) is what M-Pesa does when your validation URL is unreachable. In production, registration is one-time; change URLs by deleting them in the URL management self-service and re-registering. Sandbox has `/mpesa/c2b/v2/simulate` for test payments.
70
+
71
+ ## B2C payment
72
+
73
+ `POST /mpesa/b2c/v3/paymentrequest`
74
+
75
+ ```json
76
+ {
77
+ "OriginatorConversationID": "payout_7d1e9b",
78
+ "InitiatorName": "apiop",
79
+ "SecurityCredential": "<RSA-encrypt(initiator password, Safaricom cert) as base64>",
80
+ "CommandID": "BusinessPayment",
81
+ "Amount": "500",
82
+ "PartyA": "600997",
83
+ "PartyB": "254712345678",
84
+ "Remarks": "Refund ORD8F2C1A",
85
+ "QueueTimeOutURL": "https://api.example.com/hooks/daraja/b2c/timeout/<token>",
86
+ "ResultURL": "https://api.example.com/hooks/daraja/b2c/result/<token>",
87
+ "Occassion": "Refund"
88
+ }
89
+ ```
90
+
91
+ `CommandID`: `BusinessPayment`, `SalaryPayment` or `PromotionPayment`. Note the API's spelling `Occassion`. The sandbox and production certificates differ. The response (`ConversationID`, `OriginatorConversationID`, `ResponseCode`) only means accepted; the outcome is the `Result` posted to `ResultURL` (`ResultCode`, `TransactionID`, `ResultParameters.ResultParameter[]`).
92
+
93
+ ## Password and timestamp (TypeScript)
94
+
95
+ ```ts
96
+ export function stkPassword(shortCode: string, passkey: string, now = new Date()) {
97
+ // Daraja expects Kenyan time (EAT, UTC+3), formatted YYYYMMDDHHmmss
98
+ const eat = new Date(now.getTime() + 3 * 60 * 60 * 1000).toISOString();
99
+ const timestamp = eat.slice(0, 19).replace(/[-T:]/g, '');
100
+ const password = Buffer.from(shortCode + passkey + timestamp).toString('base64');
101
+ return { timestamp, password };
102
+ }
103
+ ```
@@ -0,0 +1,74 @@
1
+ # Daraja callbacks
2
+
3
+ None of these are signed. Treat every body as untrusted: match it to a record you created, then confirm with a query before giving value.
4
+
5
+ ## STK Push callback
6
+
7
+ `POST` to your `CallBackURL`:
8
+
9
+ ```json
10
+ {
11
+ "Body": {
12
+ "stkCallback": {
13
+ "MerchantRequestID": "29115-34620561-1",
14
+ "CheckoutRequestID": "ws_CO_191220191020363925",
15
+ "ResultCode": 0,
16
+ "ResultDesc": "The service request is processed successfully.",
17
+ "CallbackMetadata": {
18
+ "Item": [
19
+ { "Name": "Amount", "Value": 1.0 },
20
+ { "Name": "MpesaReceiptNumber", "Value": "NLJ7RT61SV" },
21
+ { "Name": "TransactionDate", "Value": 20191219102115 },
22
+ { "Name": "PhoneNumber", "Value": 254708374149 }
23
+ ]
24
+ }
25
+ }
26
+ }
27
+ }
28
+ ```
29
+
30
+ A failed or cancelled payment has `ResultCode` other than `0` and no `CallbackMetadata`. Read items by `Name`, not by position; `Balance` sometimes appears and shifts the order.
31
+
32
+ ### Handler rules
33
+
34
+ 1. Check the per-payment token in the path, then find the pending payment by `CheckoutRequestID`. Unknown → log and return 200; never create an order from a callback.
35
+ 2. Respond `200` with `{ "ResultCode": 0, "ResultDesc": "Accepted" }` quickly and queue the work.
36
+ 3. In the worker: if `ResultCode !== 0`, mark failed with the code. If `0`, run STK Push Query; fulfil only if the query says `0` **and** `Amount` equals the stored amount. Guarded update on status, unique `MpesaReceiptNumber`.
37
+
38
+ ```ts
39
+ app.post('/hooks/daraja/stk/:token', express.json(), async (req, res) => {
40
+ const cb = req.body?.Body?.stkCallback;
41
+ const payment = cb && (await payments.findPending(cb.CheckoutRequestID, req.params.token));
42
+ res.json({ ResultCode: 0, ResultDesc: 'Accepted' });
43
+ if (payment) await queue.add('daraja-confirm', { checkoutRequestId: cb.CheckoutRequestID, resultCode: cb.ResultCode });
44
+ });
45
+ ```
46
+
47
+ ## C2B validation and confirmation
48
+
49
+ Both URLs receive the same shape:
50
+
51
+ ```json
52
+ {
53
+ "TransactionType": "Pay Bill",
54
+ "TransID": "RKTQDM7W6S",
55
+ "TransTime": "20191122063845",
56
+ "TransAmount": "10",
57
+ "BusinessShortCode": "600638",
58
+ "BillRefNumber": "invoice008",
59
+ "InvoiceNumber": "",
60
+ "OrgAccountBalance": "",
61
+ "ThirdPartyTransID": "",
62
+ "MSISDN": "25470****149",
63
+ "FirstName": "John",
64
+ "MiddleName": "",
65
+ "LastName": "Doe"
66
+ }
67
+ ```
68
+
69
+ - **Validation** (only if Safaricom enabled external validation on your shortcode): reply `{ "ResultCode": "0", "ResultDesc": "Accepted" }` to accept, or `{ "ResultCode": "C2B00012", "ResultDesc": "Rejected" }` to reject (`C2B00011` invalid MSISDN, `C2B00012` invalid account number, `C2B00013` invalid amount, `C2B00014` invalid KYC, `C2B00015` invalid shortcode, `C2B00016` other). Reply fast; if it is unreachable M-Pesa applies the registered `ResponseType`.
70
+ - **Confirmation**: the payment is complete. Dedupe on `TransID`, match `BillRefNumber` to an open invoice, compare `TransAmount`, and park anything that doesn't match for manual review instead of dropping it: the customer's money has already moved. `MSISDN` may be masked or hashed, so don't rely on it to identify the payer.
71
+
72
+ ## B2C result
73
+
74
+ `POST` to `ResultURL` with `{ "Result": { "ResultType", "ResultCode", "ResultDesc", "OriginatorConversationID", "ConversationID", "TransactionID", "ResultParameters": { "ResultParameter": [ { "Key", "Value" } ] } } }`. Match on `OriginatorConversationID`. `ResultCode` `0` = paid. A post to `QueueTimeOutURL` means the outcome is unknown: run Transaction Status (`/mpesa/transactionstatus/v1/query`) before any retry.