specweave 0.18.1 → 0.20.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 (384) hide show
  1. package/CLAUDE.md +229 -1817
  2. package/README.md +68 -0
  3. package/bin/specweave.js +62 -6
  4. package/dist/plugins/specweave/lib/hooks/sync-living-docs.d.ts.map +1 -1
  5. package/dist/plugins/specweave/lib/hooks/sync-living-docs.js +3 -0
  6. package/dist/plugins/specweave/lib/hooks/sync-living-docs.js.map +1 -1
  7. package/dist/plugins/specweave/lib/hooks/update-ac-status.d.ts +21 -0
  8. package/dist/plugins/specweave/lib/hooks/update-ac-status.d.ts.map +1 -0
  9. package/dist/plugins/specweave/lib/hooks/update-ac-status.js +162 -0
  10. package/dist/plugins/specweave/lib/hooks/update-ac-status.js.map +1 -0
  11. package/dist/plugins/specweave-ado/lib/ado-spec-content-sync.d.ts.map +1 -1
  12. package/dist/plugins/specweave-ado/lib/ado-spec-content-sync.js +65 -6
  13. package/dist/plugins/specweave-ado/lib/ado-spec-content-sync.js.map +1 -1
  14. package/dist/plugins/specweave-github/lib/completion-calculator.d.ts +112 -0
  15. package/dist/plugins/specweave-github/lib/completion-calculator.d.ts.map +1 -0
  16. package/dist/plugins/specweave-github/lib/completion-calculator.js +301 -0
  17. package/dist/plugins/specweave-github/lib/completion-calculator.js.map +1 -0
  18. package/dist/plugins/specweave-github/lib/duplicate-detector.d.ts +3 -3
  19. package/dist/plugins/specweave-github/lib/duplicate-detector.js +3 -3
  20. package/dist/plugins/specweave-github/lib/epic-content-builder.d.ts +7 -0
  21. package/dist/plugins/specweave-github/lib/epic-content-builder.d.ts.map +1 -1
  22. package/dist/plugins/specweave-github/lib/epic-content-builder.js +42 -0
  23. package/dist/plugins/specweave-github/lib/epic-content-builder.js.map +1 -1
  24. package/dist/plugins/specweave-github/lib/github-client-v2.d.ts +14 -0
  25. package/dist/plugins/specweave-github/lib/github-client-v2.d.ts.map +1 -1
  26. package/dist/plugins/specweave-github/lib/github-client-v2.js +51 -0
  27. package/dist/plugins/specweave-github/lib/github-client-v2.js.map +1 -1
  28. package/dist/plugins/specweave-github/lib/github-epic-sync.js +1 -1
  29. package/dist/plugins/specweave-github/lib/github-epic-sync.js.map +1 -1
  30. package/dist/plugins/specweave-github/lib/github-feature-sync.d.ts +87 -0
  31. package/dist/plugins/specweave-github/lib/github-feature-sync.d.ts.map +1 -0
  32. package/dist/plugins/specweave-github/lib/github-feature-sync.js +412 -0
  33. package/dist/plugins/specweave-github/lib/github-feature-sync.js.map +1 -0
  34. package/dist/plugins/specweave-github/lib/github-spec-content-sync.d.ts.map +1 -1
  35. package/dist/plugins/specweave-github/lib/github-spec-content-sync.js +64 -13
  36. package/dist/plugins/specweave-github/lib/github-spec-content-sync.js.map +1 -1
  37. package/dist/plugins/specweave-github/lib/progress-comment-builder.d.ts +78 -0
  38. package/dist/plugins/specweave-github/lib/progress-comment-builder.d.ts.map +1 -0
  39. package/dist/plugins/specweave-github/lib/progress-comment-builder.js +237 -0
  40. package/dist/plugins/specweave-github/lib/progress-comment-builder.js.map +1 -0
  41. package/dist/plugins/specweave-github/lib/user-story-content-builder.d.ts +97 -0
  42. package/dist/plugins/specweave-github/lib/user-story-content-builder.d.ts.map +1 -0
  43. package/dist/plugins/specweave-github/lib/user-story-content-builder.js +301 -0
  44. package/dist/plugins/specweave-github/lib/user-story-content-builder.js.map +1 -0
  45. package/dist/plugins/specweave-github/lib/user-story-issue-builder.d.ts +83 -0
  46. package/dist/plugins/specweave-github/lib/user-story-issue-builder.d.ts.map +1 -0
  47. package/dist/plugins/specweave-github/lib/user-story-issue-builder.js +386 -0
  48. package/dist/plugins/specweave-github/lib/user-story-issue-builder.js.map +1 -0
  49. package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.d.ts +8 -6
  50. package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.d.ts.map +1 -1
  51. package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.js +78 -117
  52. package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.js.map +1 -1
  53. package/dist/plugins/specweave-kafka/lib/cli/kcat-wrapper.d.ts +57 -0
  54. package/dist/plugins/specweave-kafka/lib/cli/kcat-wrapper.d.ts.map +1 -0
  55. package/dist/plugins/specweave-kafka/lib/cli/kcat-wrapper.js +248 -0
  56. package/dist/plugins/specweave-kafka/lib/cli/kcat-wrapper.js.map +1 -0
  57. package/dist/plugins/specweave-kafka/lib/cli/types.d.ts +82 -0
  58. package/dist/plugins/specweave-kafka/lib/cli/types.d.ts.map +1 -0
  59. package/dist/plugins/specweave-kafka/lib/cli/types.js +13 -0
  60. package/dist/plugins/specweave-kafka/lib/cli/types.js.map +1 -0
  61. package/dist/plugins/specweave-kafka/lib/mcp/detector.d.ts +49 -0
  62. package/dist/plugins/specweave-kafka/lib/mcp/detector.d.ts.map +1 -0
  63. package/dist/plugins/specweave-kafka/lib/mcp/detector.js +316 -0
  64. package/dist/plugins/specweave-kafka/lib/mcp/detector.js.map +1 -0
  65. package/dist/plugins/specweave-kafka/lib/mcp/types.d.ts +70 -0
  66. package/dist/plugins/specweave-kafka/lib/mcp/types.d.ts.map +1 -0
  67. package/dist/plugins/specweave-kafka/lib/mcp/types.js +23 -0
  68. package/dist/plugins/specweave-kafka/lib/mcp/types.js.map +1 -0
  69. package/dist/plugins/specweave-kafka/lib/utils/partitioning.d.ts +85 -0
  70. package/dist/plugins/specweave-kafka/lib/utils/partitioning.d.ts.map +1 -0
  71. package/dist/plugins/specweave-kafka/lib/utils/partitioning.js +281 -0
  72. package/dist/plugins/specweave-kafka/lib/utils/partitioning.js.map +1 -0
  73. package/dist/plugins/specweave-kafka/lib/utils/sizing.d.ts +75 -0
  74. package/dist/plugins/specweave-kafka/lib/utils/sizing.d.ts.map +1 -0
  75. package/dist/plugins/specweave-kafka/lib/utils/sizing.js +238 -0
  76. package/dist/plugins/specweave-kafka/lib/utils/sizing.js.map +1 -0
  77. package/dist/src/cli/commands/import-docs.js +4 -4
  78. package/dist/src/cli/commands/import-docs.js.map +1 -1
  79. package/dist/src/cli/commands/init-multiproject.d.ts.map +1 -1
  80. package/dist/src/cli/commands/init-multiproject.js +17 -18
  81. package/dist/src/cli/commands/init-multiproject.js.map +1 -1
  82. package/dist/src/cli/commands/migrate-to-multiproject.d.ts.map +1 -1
  83. package/dist/src/cli/commands/migrate-to-multiproject.js +8 -4
  84. package/dist/src/cli/commands/migrate-to-multiproject.js.map +1 -1
  85. package/dist/src/cli/commands/switch-project.d.ts.map +1 -1
  86. package/dist/src/cli/commands/switch-project.js +9 -26
  87. package/dist/src/cli/commands/switch-project.js.map +1 -1
  88. package/dist/src/cli/commands/sync-spec-content.js +3 -0
  89. package/dist/src/cli/commands/sync-spec-content.js.map +1 -1
  90. package/dist/src/core/deduplication/command-deduplicator.d.ts +166 -0
  91. package/dist/src/core/deduplication/command-deduplicator.d.ts.map +1 -0
  92. package/dist/src/core/deduplication/command-deduplicator.js +254 -0
  93. package/dist/src/core/deduplication/command-deduplicator.js.map +1 -0
  94. package/dist/src/core/increment/active-increment-manager.d.ts +42 -15
  95. package/dist/src/core/increment/active-increment-manager.d.ts.map +1 -1
  96. package/dist/src/core/increment/active-increment-manager.js +113 -46
  97. package/dist/src/core/increment/active-increment-manager.js.map +1 -1
  98. package/dist/src/core/increment/conflict-resolver.d.ts +40 -0
  99. package/dist/src/core/increment/conflict-resolver.d.ts.map +1 -0
  100. package/dist/src/core/increment/conflict-resolver.js +219 -0
  101. package/dist/src/core/increment/conflict-resolver.js.map +1 -0
  102. package/dist/src/core/increment/discipline-checker.d.ts.map +1 -1
  103. package/dist/src/core/increment/discipline-checker.js +7 -1
  104. package/dist/src/core/increment/discipline-checker.js.map +1 -1
  105. package/dist/src/core/increment/duplicate-detector.d.ts +52 -0
  106. package/dist/src/core/increment/duplicate-detector.d.ts.map +1 -0
  107. package/dist/src/core/increment/duplicate-detector.js +276 -0
  108. package/dist/src/core/increment/duplicate-detector.js.map +1 -0
  109. package/dist/src/core/increment/increment-archiver.d.ts +90 -0
  110. package/dist/src/core/increment/increment-archiver.d.ts.map +1 -0
  111. package/dist/src/core/increment/increment-archiver.js +368 -0
  112. package/dist/src/core/increment/increment-archiver.js.map +1 -0
  113. package/dist/src/core/increment/increment-reopener.d.ts +165 -0
  114. package/dist/src/core/increment/increment-reopener.d.ts.map +1 -0
  115. package/dist/src/core/increment/increment-reopener.js +390 -0
  116. package/dist/src/core/increment/increment-reopener.js.map +1 -0
  117. package/dist/src/core/increment/metadata-manager.d.ts +26 -1
  118. package/dist/src/core/increment/metadata-manager.d.ts.map +1 -1
  119. package/dist/src/core/increment/metadata-manager.js +143 -5
  120. package/dist/src/core/increment/metadata-manager.js.map +1 -1
  121. package/dist/src/core/increment/recent-work-scanner.d.ts +121 -0
  122. package/dist/src/core/increment/recent-work-scanner.d.ts.map +1 -0
  123. package/dist/src/core/increment/recent-work-scanner.js +303 -0
  124. package/dist/src/core/increment/recent-work-scanner.js.map +1 -0
  125. package/dist/src/core/increment/types.d.ts +1 -0
  126. package/dist/src/core/increment/types.d.ts.map +1 -1
  127. package/dist/src/core/increment-utils.d.ts +112 -0
  128. package/dist/src/core/increment-utils.d.ts.map +1 -0
  129. package/dist/src/core/increment-utils.js +210 -0
  130. package/dist/src/core/increment-utils.js.map +1 -0
  131. package/dist/src/core/living-docs/ac-project-specific-generator.d.ts +65 -0
  132. package/dist/src/core/living-docs/ac-project-specific-generator.d.ts.map +1 -0
  133. package/dist/src/core/living-docs/ac-project-specific-generator.js +175 -0
  134. package/dist/src/core/living-docs/ac-project-specific-generator.js.map +1 -0
  135. package/dist/src/core/living-docs/feature-archiver.d.ts +130 -0
  136. package/dist/src/core/living-docs/feature-archiver.d.ts.map +1 -0
  137. package/dist/src/core/living-docs/feature-archiver.js +549 -0
  138. package/dist/src/core/living-docs/feature-archiver.js.map +1 -0
  139. package/dist/src/core/living-docs/feature-id-manager.d.ts +81 -0
  140. package/dist/src/core/living-docs/feature-id-manager.d.ts.map +1 -0
  141. package/dist/src/core/living-docs/feature-id-manager.js +339 -0
  142. package/dist/src/core/living-docs/feature-id-manager.js.map +1 -0
  143. package/dist/src/core/living-docs/hierarchy-mapper.d.ts +144 -83
  144. package/dist/src/core/living-docs/hierarchy-mapper.d.ts.map +1 -1
  145. package/dist/src/core/living-docs/hierarchy-mapper.js +488 -270
  146. package/dist/src/core/living-docs/hierarchy-mapper.js.map +1 -1
  147. package/dist/src/core/living-docs/index.d.ts +6 -0
  148. package/dist/src/core/living-docs/index.d.ts.map +1 -1
  149. package/dist/src/core/living-docs/index.js +6 -0
  150. package/dist/src/core/living-docs/index.js.map +1 -1
  151. package/dist/src/core/living-docs/project-detector.d.ts +6 -0
  152. package/dist/src/core/living-docs/project-detector.d.ts.map +1 -1
  153. package/dist/src/core/living-docs/project-detector.js +35 -1
  154. package/dist/src/core/living-docs/project-detector.js.map +1 -1
  155. package/dist/src/core/living-docs/spec-distributor.d.ts +100 -26
  156. package/dist/src/core/living-docs/spec-distributor.d.ts.map +1 -1
  157. package/dist/src/core/living-docs/spec-distributor.js +1275 -258
  158. package/dist/src/core/living-docs/spec-distributor.js.map +1 -1
  159. package/dist/src/core/living-docs/task-project-specific-generator.d.ts +109 -0
  160. package/dist/src/core/living-docs/task-project-specific-generator.d.ts.map +1 -0
  161. package/dist/src/core/living-docs/task-project-specific-generator.js +221 -0
  162. package/dist/src/core/living-docs/task-project-specific-generator.js.map +1 -0
  163. package/dist/src/core/living-docs/types.d.ts +143 -0
  164. package/dist/src/core/living-docs/types.d.ts.map +1 -1
  165. package/dist/src/core/project-manager.d.ts +2 -17
  166. package/dist/src/core/project-manager.d.ts.map +1 -1
  167. package/dist/src/core/project-manager.js +68 -48
  168. package/dist/src/core/project-manager.js.map +1 -1
  169. package/dist/src/core/spec-content-sync.d.ts +1 -1
  170. package/dist/src/core/spec-content-sync.d.ts.map +1 -1
  171. package/dist/src/core/sync/enhanced-content-builder.d.ts.map +1 -1
  172. package/dist/src/core/sync/enhanced-content-builder.js +2 -1
  173. package/dist/src/core/sync/enhanced-content-builder.js.map +1 -1
  174. package/dist/src/core/sync/performance-optimizer.d.ts +153 -0
  175. package/dist/src/core/sync/performance-optimizer.d.ts.map +1 -0
  176. package/dist/src/core/sync/performance-optimizer.js +220 -0
  177. package/dist/src/core/sync/performance-optimizer.js.map +1 -0
  178. package/dist/src/core/sync/retry-handler.d.ts +98 -0
  179. package/dist/src/core/sync/retry-handler.d.ts.map +1 -0
  180. package/dist/src/core/sync/retry-handler.js +196 -0
  181. package/dist/src/core/sync/retry-handler.js.map +1 -0
  182. package/dist/src/core/types/config.d.ts +94 -0
  183. package/dist/src/core/types/config.d.ts.map +1 -1
  184. package/dist/src/core/types/config.js +16 -0
  185. package/dist/src/core/types/config.js.map +1 -1
  186. package/dist/src/core/types/increment-metadata.d.ts +6 -0
  187. package/dist/src/core/types/increment-metadata.d.ts.map +1 -1
  188. package/dist/src/core/types/increment-metadata.js +10 -1
  189. package/dist/src/core/types/increment-metadata.js.map +1 -1
  190. package/dist/src/integrations/jira/jira-incremental-mapper.d.ts.map +1 -1
  191. package/dist/src/integrations/jira/jira-incremental-mapper.js +4 -8
  192. package/dist/src/integrations/jira/jira-incremental-mapper.js.map +1 -1
  193. package/dist/src/integrations/jira/jira-mapper.d.ts.map +1 -1
  194. package/dist/src/integrations/jira/jira-mapper.js +4 -8
  195. package/dist/src/integrations/jira/jira-mapper.js.map +1 -1
  196. package/package.json +1 -1
  197. package/plugins/specweave/COMMANDS.md +13 -4
  198. package/plugins/specweave/commands/specweave-abandon.md +22 -20
  199. package/plugins/specweave/commands/specweave-archive-features.md +121 -0
  200. package/plugins/specweave/commands/specweave-archive-increments.md +82 -0
  201. package/plugins/specweave/commands/specweave-archive.md +363 -0
  202. package/plugins/specweave/commands/specweave-backlog.md +211 -0
  203. package/plugins/specweave/commands/specweave-fix-duplicates.md +517 -0
  204. package/plugins/specweave/commands/specweave-increment.md +4 -3
  205. package/plugins/specweave/commands/specweave-progress.md +176 -27
  206. package/plugins/specweave/commands/specweave-reopen.md +391 -0
  207. package/plugins/specweave/commands/specweave-restore-feature.md +90 -0
  208. package/plugins/specweave/commands/specweave-restore.md +309 -0
  209. package/plugins/specweave/commands/specweave-resume.md +51 -23
  210. package/plugins/specweave/commands/specweave-status.md +41 -7
  211. package/plugins/specweave/commands/specweave-sync-specs.md +425 -0
  212. package/plugins/specweave/hooks/hooks.json +4 -0
  213. package/plugins/specweave/hooks/lib/sync-spec-content.sh +2 -2
  214. package/plugins/specweave/hooks/post-task-completion.sh +39 -0
  215. package/plugins/specweave/hooks/pre-command-deduplication.sh +83 -0
  216. package/plugins/specweave/hooks/user-prompt-submit.sh +1 -1
  217. package/plugins/specweave/lib/hooks/sync-living-docs.js +2 -0
  218. package/plugins/specweave/lib/hooks/sync-living-docs.ts +4 -0
  219. package/plugins/specweave/lib/hooks/update-ac-status.js +102 -0
  220. package/plugins/specweave/lib/hooks/update-ac-status.ts +192 -0
  221. package/plugins/specweave/skills/archive-increments/SKILL.md +198 -0
  222. package/plugins/specweave/skills/increment-planner/scripts/feature-utils.js +14 -0
  223. package/plugins/specweave/skills/smart-reopen-detector/SKILL.md +244 -0
  224. package/plugins/specweave-ado/lib/ado-spec-content-sync.js +49 -5
  225. package/plugins/specweave-ado/lib/ado-spec-content-sync.ts +72 -6
  226. package/plugins/specweave-confluent/.claude-plugin/plugin.json +23 -0
  227. package/plugins/specweave-confluent/README.md +375 -0
  228. package/plugins/specweave-confluent/agents/confluent-architect/AGENT.md +306 -0
  229. package/plugins/specweave-confluent/skills/confluent-kafka-connect/SKILL.md +453 -0
  230. package/plugins/specweave-confluent/skills/confluent-ksqldb/SKILL.md +470 -0
  231. package/plugins/specweave-confluent/skills/confluent-schema-registry/SKILL.md +316 -0
  232. package/plugins/specweave-github/agents/github-task-splitter/AGENT.md +2 -2
  233. package/plugins/specweave-github/agents/user-story-updater/AGENT.md +148 -0
  234. package/plugins/specweave-github/commands/specweave-github-cleanup-duplicates.md +1 -1
  235. package/plugins/specweave-github/commands/specweave-github-update-user-story.md +156 -0
  236. package/plugins/specweave-github/hooks/post-task-completion.sh +10 -9
  237. package/plugins/specweave-github/lib/completion-calculator.js +262 -0
  238. package/plugins/specweave-github/lib/completion-calculator.ts +434 -0
  239. package/plugins/specweave-github/lib/duplicate-detector.js +3 -3
  240. package/plugins/specweave-github/lib/duplicate-detector.ts +4 -4
  241. package/plugins/specweave-github/lib/epic-content-builder.js +38 -0
  242. package/plugins/specweave-github/lib/epic-content-builder.ts +59 -0
  243. package/plugins/specweave-github/lib/github-client-v2.js +49 -0
  244. package/plugins/specweave-github/lib/github-client-v2.ts +59 -0
  245. package/plugins/specweave-github/lib/github-epic-sync.ts +1 -1
  246. package/plugins/specweave-github/lib/github-feature-sync.js +381 -0
  247. package/plugins/specweave-github/lib/github-feature-sync.ts +568 -0
  248. package/plugins/specweave-github/lib/github-spec-content-sync.js +40 -10
  249. package/plugins/specweave-github/lib/github-spec-content-sync.ts +82 -14
  250. package/plugins/specweave-github/lib/progress-comment-builder.js +229 -0
  251. package/plugins/specweave-github/lib/progress-comment-builder.ts +324 -0
  252. package/plugins/specweave-github/lib/user-story-content-builder.js +299 -0
  253. package/plugins/specweave-github/lib/user-story-content-builder.ts +413 -0
  254. package/plugins/specweave-github/lib/user-story-issue-builder.js +344 -0
  255. package/plugins/specweave-github/lib/user-story-issue-builder.ts +543 -0
  256. package/plugins/specweave-github/skills/github-issue-standard/SKILL.md +189 -0
  257. package/plugins/specweave-jira/lib/enhanced-jira-sync.js +134 -0
  258. package/plugins/specweave-jira/lib/{enhanced-jira-sync.ts.disabled → enhanced-jira-sync.ts} +26 -52
  259. package/plugins/specweave-kafka/.claude-plugin/plugin.json +26 -0
  260. package/plugins/specweave-kafka/IMPLEMENTATION-COMPLETE.md +483 -0
  261. package/plugins/specweave-kafka/README.md +242 -0
  262. package/plugins/specweave-kafka/agents/kafka-architect/AGENT.md +235 -0
  263. package/plugins/specweave-kafka/agents/kafka-devops/AGENT.md +209 -0
  264. package/plugins/specweave-kafka/agents/kafka-observability/AGENT.md +266 -0
  265. package/plugins/specweave-kafka/commands/deploy.md +99 -0
  266. package/plugins/specweave-kafka/commands/dev-env.md +176 -0
  267. package/plugins/specweave-kafka/commands/mcp-configure.md +101 -0
  268. package/plugins/specweave-kafka/commands/monitor-setup.md +96 -0
  269. package/plugins/specweave-kafka/docker/kafka-local/docker-compose.yml +187 -0
  270. package/plugins/specweave-kafka/docker/redpanda/docker-compose.yml +199 -0
  271. package/plugins/specweave-kafka/docker/templates/consumer-nodejs.js +225 -0
  272. package/plugins/specweave-kafka/docker/templates/consumer-python.py +220 -0
  273. package/plugins/specweave-kafka/docker/templates/producer-nodejs.js +168 -0
  274. package/plugins/specweave-kafka/docker/templates/producer-python.py +167 -0
  275. package/plugins/specweave-kafka/lib/adapters/apache-kafka-adapter.js +438 -0
  276. package/plugins/specweave-kafka/lib/adapters/apache-kafka-adapter.ts +541 -0
  277. package/plugins/specweave-kafka/lib/adapters/platform-adapter.js +47 -0
  278. package/plugins/specweave-kafka/lib/adapters/platform-adapter.ts +343 -0
  279. package/plugins/specweave-kafka/lib/cli/kcat-wrapper.js +258 -0
  280. package/plugins/specweave-kafka/lib/cli/kcat-wrapper.ts +298 -0
  281. package/plugins/specweave-kafka/lib/cli/types.js +10 -0
  282. package/plugins/specweave-kafka/lib/cli/types.ts +92 -0
  283. package/plugins/specweave-kafka/lib/connectors/connector-catalog.js +305 -0
  284. package/plugins/specweave-kafka/lib/connectors/connector-catalog.ts +528 -0
  285. package/plugins/specweave-kafka/lib/documentation/diagram-generator.js +114 -0
  286. package/plugins/specweave-kafka/lib/documentation/diagram-generator.ts +195 -0
  287. package/plugins/specweave-kafka/lib/documentation/exporter.js +210 -0
  288. package/plugins/specweave-kafka/lib/documentation/exporter.ts +338 -0
  289. package/plugins/specweave-kafka/lib/documentation/schema-catalog-generator.js +60 -0
  290. package/plugins/specweave-kafka/lib/documentation/schema-catalog-generator.ts +130 -0
  291. package/plugins/specweave-kafka/lib/documentation/topology-generator.js +143 -0
  292. package/plugins/specweave-kafka/lib/documentation/topology-generator.ts +290 -0
  293. package/plugins/specweave-kafka/lib/mcp/detector.js +298 -0
  294. package/plugins/specweave-kafka/lib/mcp/detector.ts +352 -0
  295. package/plugins/specweave-kafka/lib/mcp/types.js +21 -0
  296. package/plugins/specweave-kafka/lib/mcp/types.ts +77 -0
  297. package/plugins/specweave-kafka/lib/multi-cluster/cluster-config-manager.js +193 -0
  298. package/plugins/specweave-kafka/lib/multi-cluster/cluster-config-manager.ts +362 -0
  299. package/plugins/specweave-kafka/lib/multi-cluster/cluster-switcher.js +188 -0
  300. package/plugins/specweave-kafka/lib/multi-cluster/cluster-switcher.ts +359 -0
  301. package/plugins/specweave-kafka/lib/multi-cluster/health-aggregator.js +195 -0
  302. package/plugins/specweave-kafka/lib/multi-cluster/health-aggregator.ts +380 -0
  303. package/plugins/specweave-kafka/lib/observability/opentelemetry-kafka.js +209 -0
  304. package/plugins/specweave-kafka/lib/observability/opentelemetry-kafka.ts +358 -0
  305. package/plugins/specweave-kafka/lib/patterns/advanced-ksqldb-patterns.js +354 -0
  306. package/plugins/specweave-kafka/lib/patterns/advanced-ksqldb-patterns.ts +563 -0
  307. package/plugins/specweave-kafka/lib/patterns/circuit-breaker-resilience.js +259 -0
  308. package/plugins/specweave-kafka/lib/patterns/circuit-breaker-resilience.ts +516 -0
  309. package/plugins/specweave-kafka/lib/patterns/dead-letter-queue.js +233 -0
  310. package/plugins/specweave-kafka/lib/patterns/dead-letter-queue.ts +423 -0
  311. package/plugins/specweave-kafka/lib/patterns/exactly-once-semantics.js +266 -0
  312. package/plugins/specweave-kafka/lib/patterns/exactly-once-semantics.ts +445 -0
  313. package/plugins/specweave-kafka/lib/patterns/flink-kafka-integration.js +312 -0
  314. package/plugins/specweave-kafka/lib/patterns/flink-kafka-integration.ts +561 -0
  315. package/plugins/specweave-kafka/lib/patterns/multi-dc-replication.js +289 -0
  316. package/plugins/specweave-kafka/lib/patterns/multi-dc-replication.ts +607 -0
  317. package/plugins/specweave-kafka/lib/patterns/rate-limiting-backpressure.js +264 -0
  318. package/plugins/specweave-kafka/lib/patterns/rate-limiting-backpressure.ts +498 -0
  319. package/plugins/specweave-kafka/lib/patterns/stream-processing-optimization.js +263 -0
  320. package/plugins/specweave-kafka/lib/patterns/stream-processing-optimization.ts +549 -0
  321. package/plugins/specweave-kafka/lib/patterns/tiered-storage-compaction.js +205 -0
  322. package/plugins/specweave-kafka/lib/patterns/tiered-storage-compaction.ts +399 -0
  323. package/plugins/specweave-kafka/lib/performance/performance-optimizer.js +249 -0
  324. package/plugins/specweave-kafka/lib/performance/performance-optimizer.ts +427 -0
  325. package/plugins/specweave-kafka/lib/security/kafka-security.js +252 -0
  326. package/plugins/specweave-kafka/lib/security/kafka-security.ts +494 -0
  327. package/plugins/specweave-kafka/lib/utils/capacity-planner.js +203 -0
  328. package/plugins/specweave-kafka/lib/utils/capacity-planner.ts +469 -0
  329. package/plugins/specweave-kafka/lib/utils/config-validator.js +419 -0
  330. package/plugins/specweave-kafka/lib/utils/config-validator.ts +564 -0
  331. package/plugins/specweave-kafka/lib/utils/partitioning.js +329 -0
  332. package/plugins/specweave-kafka/lib/utils/partitioning.ts +473 -0
  333. package/plugins/specweave-kafka/lib/utils/sizing.js +221 -0
  334. package/plugins/specweave-kafka/lib/utils/sizing.ts +374 -0
  335. package/plugins/specweave-kafka/monitoring/grafana/dashboards/kafka-broker-metrics.json +628 -0
  336. package/plugins/specweave-kafka/monitoring/grafana/dashboards/kafka-cluster-overview.json +564 -0
  337. package/plugins/specweave-kafka/monitoring/grafana/dashboards/kafka-consumer-lag.json +509 -0
  338. package/plugins/specweave-kafka/monitoring/grafana/dashboards/kafka-jvm-metrics.json +674 -0
  339. package/plugins/specweave-kafka/monitoring/grafana/dashboards/kafka-topic-metrics.json +578 -0
  340. package/plugins/specweave-kafka/monitoring/grafana/provisioning/dashboards/kafka.yml +17 -0
  341. package/plugins/specweave-kafka/monitoring/grafana/provisioning/datasources/prometheus.yml +17 -0
  342. package/plugins/specweave-kafka/monitoring/prometheus/kafka-alerts.yml +415 -0
  343. package/plugins/specweave-kafka/monitoring/prometheus/kafka-jmx-exporter.yml +256 -0
  344. package/plugins/specweave-kafka/package.json +41 -0
  345. package/plugins/specweave-kafka/skills/kafka-architecture/SKILL.md +647 -0
  346. package/plugins/specweave-kafka/skills/kafka-cli-tools/SKILL.md +433 -0
  347. package/plugins/specweave-kafka/skills/kafka-iac-deployment/SKILL.md +449 -0
  348. package/plugins/specweave-kafka/skills/kafka-kubernetes/SKILL.md +667 -0
  349. package/plugins/specweave-kafka/skills/kafka-mcp-integration/SKILL.md +273 -0
  350. package/plugins/specweave-kafka/skills/kafka-observability/SKILL.md +576 -0
  351. package/plugins/specweave-kafka/templates/config/broker-production.properties +254 -0
  352. package/plugins/specweave-kafka/templates/config/consumer-low-latency.properties +112 -0
  353. package/plugins/specweave-kafka/templates/config/producer-high-throughput.properties +120 -0
  354. package/plugins/specweave-kafka/templates/migration/mirrormaker2-config.properties +234 -0
  355. package/plugins/specweave-kafka/templates/monitoring/grafana/multi-cluster-dashboard.json +686 -0
  356. package/plugins/specweave-kafka/terraform/apache-kafka/main.tf +347 -0
  357. package/plugins/specweave-kafka/terraform/apache-kafka/outputs.tf +107 -0
  358. package/plugins/specweave-kafka/terraform/apache-kafka/templates/kafka-broker-init.sh.tpl +216 -0
  359. package/plugins/specweave-kafka/terraform/apache-kafka/variables.tf +156 -0
  360. package/plugins/specweave-kafka/terraform/aws-msk/main.tf +362 -0
  361. package/plugins/specweave-kafka/terraform/aws-msk/outputs.tf +93 -0
  362. package/plugins/specweave-kafka/terraform/aws-msk/templates/server.properties.tpl +32 -0
  363. package/plugins/specweave-kafka/terraform/aws-msk/variables.tf +235 -0
  364. package/plugins/specweave-kafka/terraform/azure-event-hubs/main.tf +281 -0
  365. package/plugins/specweave-kafka/terraform/azure-event-hubs/outputs.tf +118 -0
  366. package/plugins/specweave-kafka/terraform/azure-event-hubs/variables.tf +148 -0
  367. package/plugins/specweave-kafka/tsconfig.json +21 -0
  368. package/plugins/specweave-kafka-streams/.claude-plugin/plugin.json +23 -0
  369. package/plugins/specweave-kafka-streams/README.md +310 -0
  370. package/plugins/specweave-kafka-streams/skills/kafka-streams-topology/SKILL.md +539 -0
  371. package/plugins/specweave-n8n/.claude-plugin/plugin.json +22 -0
  372. package/plugins/specweave-n8n/README.md +354 -0
  373. package/plugins/specweave-n8n/skills/n8n-kafka-workflows/SKILL.md +504 -0
  374. package/plugins/specweave-release/commands/specweave-release-platform.md +1 -1
  375. package/plugins/specweave-release/hooks/post-task-completion.sh +2 -2
  376. package/src/templates/AGENTS.md.template +601 -7
  377. package/src/templates/CLAUDE.md.template +188 -88
  378. package/plugins/specweave-ado/commands/specweave-ado-sync-spec.md +0 -255
  379. package/plugins/specweave-github/commands/specweave-github-sync-epic.md +0 -248
  380. package/plugins/specweave-github/commands/specweave-github-sync-from.md +0 -147
  381. package/plugins/specweave-github/commands/specweave-github-sync-spec.md +0 -208
  382. package/plugins/specweave-github/commands/specweave-github-sync-tasks.md +0 -530
  383. package/plugins/specweave-jira/commands/specweave-jira-sync-epic.md +0 -267
  384. package/plugins/specweave-jira/commands/specweave-jira-sync-spec.md +0 -240
@@ -0,0 +1,539 @@
1
+ ---
2
+ name: kafka-streams-topology
3
+ description: Kafka Streams topology design expert. Covers KStream vs KTable vs GlobalKTable, topology patterns, stream operations (filter, map, flatMap, branch), joins, windowing strategies, and exactly-once semantics. Activates for kafka streams topology, kstream, ktable, globalkTable, stream operations, stream joins, windowing, exactly-once, topology design.
4
+ ---
5
+
6
+ # Kafka Streams Topology Skill
7
+
8
+ Expert knowledge of Kafka Streams library for building stream processing topologies in Java/Kotlin.
9
+
10
+ ## What I Know
11
+
12
+ ### Core Abstractions
13
+
14
+ **KStream** (Event Stream - Unbounded, Append-Only):
15
+ - Represents immutable event sequences
16
+ - Each record is an independent event
17
+ - Use for: Clickstreams, transactions, sensor readings
18
+
19
+ **KTable** (Changelog Stream - Latest State by Key):
20
+ - Represents mutable state (compacted topic)
21
+ - Updates override previous values (by key)
22
+ - Use for: User profiles, product catalog, account balances
23
+
24
+ **GlobalKTable** (Replicated Table - Available on All Instances):
25
+ - Full table replicated to every stream instance
26
+ - No partitioning (broadcast)
27
+ - Use for: Reference data (countries, products), lookups
28
+
29
+ **Key Differences**:
30
+ ```java
31
+ // KStream: Every event is independent
32
+ KStream<Long, Click> clicks = builder.stream("clicks");
33
+ clicks.foreach((key, value) -> {
34
+ System.out.println(value); // Prints every click event
35
+ });
36
+
37
+ // KTable: Latest value wins (by key)
38
+ KTable<Long, User> users = builder.table("users");
39
+ users.toStream().foreach((key, value) -> {
40
+ System.out.println(value); // Prints only current user state
41
+ });
42
+
43
+ // GlobalKTable: Replicated to all instances (no partitioning)
44
+ GlobalKTable<Long, Product> products = builder.globalTable("products");
45
+ // Available for lookups on any instance (no repartitioning needed)
46
+ ```
47
+
48
+ ## When to Use This Skill
49
+
50
+ Activate me when you need help with:
51
+ - Topology design ("How to design Kafka Streams topology?")
52
+ - KStream vs KTable ("When to use KStream vs KTable?")
53
+ - Stream operations ("Filter and transform events")
54
+ - Joins ("Join KStream with KTable")
55
+ - Windowing ("Tumbling vs hopping vs session windows")
56
+ - Exactly-once semantics ("Enable EOS")
57
+ - Topology optimization ("Optimize stream processing")
58
+
59
+ ## Common Patterns
60
+
61
+ ### Pattern 1: Filter and Transform
62
+
63
+ **Use Case**: Clean and enrich events
64
+
65
+ ```java
66
+ StreamsBuilder builder = new StreamsBuilder();
67
+
68
+ // Input stream
69
+ KStream<Long, ClickEvent> clicks = builder.stream("clicks");
70
+
71
+ // Filter out bot clicks
72
+ KStream<Long, ClickEvent> humanClicks = clicks
73
+ .filter((key, value) -> !value.isBot());
74
+
75
+ // Transform: Extract page from URL
76
+ KStream<Long, String> pages = humanClicks
77
+ .mapValues(click -> extractPage(click.getUrl()));
78
+
79
+ // Write to output topic
80
+ pages.to("pages");
81
+ ```
82
+
83
+ ### Pattern 2: Branch by Condition
84
+
85
+ **Use Case**: Route events to different paths
86
+
87
+ ```java
88
+ Map<String, KStream<Long, Order>> branches = orders
89
+ .split(Named.as("order-"))
90
+ .branch((key, order) -> order.getTotal() > 1000, Branched.as("high-value"))
91
+ .branch((key, order) -> order.getTotal() > 100, Branched.as("medium-value"))
92
+ .defaultBranch(Branched.as("low-value"));
93
+
94
+ // High-value orders → priority processing
95
+ branches.get("order-high-value").to("priority-orders");
96
+
97
+ // Low-value orders → standard processing
98
+ branches.get("order-low-value").to("standard-orders");
99
+ ```
100
+
101
+ ### Pattern 3: Enrich Stream with Table (Stream-Table Join)
102
+
103
+ **Use Case**: Add user details to click events
104
+
105
+ ```java
106
+ // Users table (current state)
107
+ KTable<Long, User> users = builder.table("users");
108
+
109
+ // Clicks stream
110
+ KStream<Long, ClickEvent> clicks = builder.stream("clicks");
111
+
112
+ // Enrich clicks with user data (left join)
113
+ KStream<Long, EnrichedClick> enriched = clicks.leftJoin(
114
+ users,
115
+ (click, user) -> new EnrichedClick(
116
+ click.getPage(),
117
+ user != null ? user.getName() : "unknown",
118
+ user != null ? user.getEmail() : "unknown"
119
+ ),
120
+ Joined.with(Serdes.Long(), clickSerde, userSerde)
121
+ );
122
+
123
+ enriched.to("enriched-clicks");
124
+ ```
125
+
126
+ ### Pattern 4: Aggregate with Windowing
127
+
128
+ **Use Case**: Count clicks per user, per 5-minute window
129
+
130
+ ```java
131
+ KTable<Windowed<Long>, Long> clickCounts = clicks
132
+ .groupByKey()
133
+ .windowedBy(TimeWindows.of(Duration.ofMinutes(5)))
134
+ .count(Materialized.as("click-counts-store"));
135
+
136
+ // Convert to stream for output
137
+ clickCounts.toStream()
138
+ .map((windowedKey, count) -> {
139
+ Long userId = windowedKey.key();
140
+ Instant start = windowedKey.window().startTime();
141
+ Instant end = windowedKey.window().endTime();
142
+ return KeyValue.pair(userId, new WindowedCount(userId, start, end, count));
143
+ })
144
+ .to("click-counts");
145
+ ```
146
+
147
+ ### Pattern 5: Stateful Processing with State Store
148
+
149
+ **Use Case**: Detect duplicate events within 10 minutes
150
+
151
+ ```java
152
+ // Define state store
153
+ StoreBuilder<KeyValueStore<Long, Long>> storeBuilder =
154
+ Stores.keyValueStoreBuilder(
155
+ Stores.persistentKeyValueStore("dedup-store"),
156
+ Serdes.Long(),
157
+ Serdes.Long()
158
+ );
159
+
160
+ builder.addStateStore(storeBuilder);
161
+
162
+ // Deduplicate events
163
+ KStream<Long, Event> deduplicated = events.transformValues(
164
+ () -> new ValueTransformerWithKey<Long, Event, Event>() {
165
+ private KeyValueStore<Long, Long> store;
166
+
167
+ @Override
168
+ public void init(ProcessorContext context) {
169
+ this.store = context.getStateStore("dedup-store");
170
+ }
171
+
172
+ @Override
173
+ public Event transform(Long key, Event value) {
174
+ Long lastSeen = store.get(key);
175
+ long now = System.currentTimeMillis();
176
+
177
+ // Duplicate detected (within 10 minutes)
178
+ if (lastSeen != null && (now - lastSeen) < 600_000) {
179
+ return null; // Drop duplicate
180
+ }
181
+
182
+ // Not duplicate, store timestamp
183
+ store.put(key, now);
184
+ return value;
185
+ }
186
+ },
187
+ "dedup-store"
188
+ ).filter((key, value) -> value != null); // Remove nulls
189
+
190
+ deduplicated.to("unique-events");
191
+ ```
192
+
193
+ ## Join Types
194
+
195
+ ### 1. Stream-Stream Join (Inner)
196
+
197
+ **Use Case**: Correlate related events within time window
198
+
199
+ ```java
200
+ // Page views and clicks within 10 minutes
201
+ KStream<Long, PageView> views = builder.stream("page-views");
202
+ KStream<Long, Click> clicks = builder.stream("clicks");
203
+
204
+ KStream<Long, ClickWithView> joined = clicks.join(
205
+ views,
206
+ (click, view) -> new ClickWithView(click, view),
207
+ JoinWindows.of(Duration.ofMinutes(10)),
208
+ StreamJoined.with(Serdes.Long(), clickSerde, viewSerde)
209
+ );
210
+ ```
211
+
212
+ ### 2. Stream-Table Join (Left)
213
+
214
+ **Use Case**: Enrich events with current state
215
+
216
+ ```java
217
+ // Add product details to order items
218
+ KTable<Long, Product> products = builder.table("products");
219
+ KStream<Long, OrderItem> items = builder.stream("order-items");
220
+
221
+ KStream<Long, EnrichedOrderItem> enriched = items.leftJoin(
222
+ products,
223
+ (item, product) -> new EnrichedOrderItem(
224
+ item,
225
+ product != null ? product.getName() : "Unknown",
226
+ product != null ? product.getPrice() : 0.0
227
+ )
228
+ );
229
+ ```
230
+
231
+ ### 3. Table-Table Join (Inner)
232
+
233
+ **Use Case**: Combine two tables (latest state)
234
+
235
+ ```java
236
+ // Join users with their current shopping cart
237
+ KTable<Long, User> users = builder.table("users");
238
+ KTable<Long, Cart> carts = builder.table("shopping-carts");
239
+
240
+ KTable<Long, UserWithCart> joined = users.join(
241
+ carts,
242
+ (user, cart) -> new UserWithCart(user.getName(), cart.getTotal())
243
+ );
244
+ ```
245
+
246
+ ### 4. Stream-GlobalKTable Join
247
+
248
+ **Use Case**: Enrich with reference data (no repartitioning)
249
+
250
+ ```java
251
+ // Add country details to user registrations
252
+ GlobalKTable<String, Country> countries = builder.globalTable("countries");
253
+ KStream<Long, UserRegistration> registrations = builder.stream("registrations");
254
+
255
+ KStream<Long, EnrichedRegistration> enriched = registrations.leftJoin(
256
+ countries,
257
+ (userId, registration) -> registration.getCountryCode(), // Key extractor
258
+ (registration, country) -> new EnrichedRegistration(
259
+ registration,
260
+ country != null ? country.getName() : "Unknown"
261
+ )
262
+ );
263
+ ```
264
+
265
+ ## Windowing Strategies
266
+
267
+ ### Tumbling Windows (Non-Overlapping)
268
+
269
+ **Use Case**: Aggregate per fixed time period
270
+
271
+ ```java
272
+ // Count events every 5 minutes
273
+ KTable<Windowed<Long>, Long> counts = events
274
+ .groupByKey()
275
+ .windowedBy(TimeWindows.ofSizeWithNoGrace(Duration.ofMinutes(5)))
276
+ .count();
277
+
278
+ // Windows: [0:00-0:05), [0:05-0:10), [0:10-0:15)
279
+ ```
280
+
281
+ ### Hopping Windows (Overlapping)
282
+
283
+ **Use Case**: Moving average or overlapping aggregates
284
+
285
+ ```java
286
+ // Count events in 10-minute windows, advancing every 5 minutes
287
+ KTable<Windowed<Long>, Long> counts = events
288
+ .groupByKey()
289
+ .windowedBy(TimeWindows.ofSizeAndGrace(
290
+ Duration.ofMinutes(10),
291
+ Duration.ofMinutes(5)
292
+ ).advanceBy(Duration.ofMinutes(5)))
293
+ .count();
294
+
295
+ // Windows: [0:00-0:10), [0:05-0:15), [0:10-0:20)
296
+ ```
297
+
298
+ ### Session Windows (Event-Based)
299
+
300
+ **Use Case**: User sessions with inactivity gap
301
+
302
+ ```java
303
+ // Session ends after 30 minutes of inactivity
304
+ KTable<Windowed<Long>, Long> sessionCounts = events
305
+ .groupByKey()
306
+ .windowedBy(SessionWindows.ofInactivityGapWithNoGrace(Duration.ofMinutes(30)))
307
+ .count();
308
+ ```
309
+
310
+ ### Sliding Windows (Continuous)
311
+
312
+ **Use Case**: Anomaly detection over sliding time window
313
+
314
+ ```java
315
+ // Detect >100 events in any 1-minute period
316
+ KTable<Windowed<Long>, Long> slidingCounts = events
317
+ .groupByKey()
318
+ .windowedBy(SlidingWindows.ofTimeDifferenceWithNoGrace(Duration.ofMinutes(1)))
319
+ .count();
320
+ ```
321
+
322
+ ## Best Practices
323
+
324
+ ### 1. Partition Keys Correctly
325
+
326
+ ✅ **DO**:
327
+ ```java
328
+ // Repartition by user_id before aggregation
329
+ KStream<Long, Event> byUser = events
330
+ .selectKey((key, value) -> value.getUserId());
331
+
332
+ // Now aggregation is efficient
333
+ KTable<Long, Long> userCounts = byUser
334
+ .groupByKey()
335
+ .count();
336
+ ```
337
+
338
+ ❌ **DON'T**:
339
+ ```java
340
+ // WRONG: groupBy with different key (triggers repartitioning!)
341
+ KTable<Long, Long> userCounts = events
342
+ .groupBy((key, value) -> KeyValue.pair(value.getUserId(), value))
343
+ .count();
344
+ ```
345
+
346
+ ### 2. Use Appropriate Serdes
347
+
348
+ ✅ **DO**:
349
+ ```java
350
+ // Define custom serde for complex types
351
+ Serde<User> userSerde = new JsonSerde<>(User.class);
352
+
353
+ KStream<Long, User> users = builder.stream(
354
+ "users",
355
+ Consumed.with(Serdes.Long(), userSerde)
356
+ );
357
+ ```
358
+
359
+ ❌ **DON'T**:
360
+ ```java
361
+ // WRONG: No serde specified (uses default String serde!)
362
+ KStream<Long, User> users = builder.stream("users");
363
+ ```
364
+
365
+ ### 3. Enable Exactly-Once Semantics
366
+
367
+ ✅ **DO**:
368
+ ```java
369
+ Properties props = new Properties();
370
+ props.put(StreamsConfig.PROCESSING_GUARANTEE_CONFIG,
371
+ StreamsConfig.EXACTLY_ONCE_V2); // EOS v2 (recommended)
372
+ props.put(StreamsConfig.COMMIT_INTERVAL_MS_CONFIG, 100); // Commit frequently
373
+ ```
374
+
375
+ ### 4. Use Materialized Stores for Queries
376
+
377
+ ✅ **DO**:
378
+ ```java
379
+ // Named store for interactive queries
380
+ KTable<Long, Long> counts = events
381
+ .groupByKey()
382
+ .count(Materialized.<Long, Long, KeyValueStore<Bytes, byte[]>>as("user-counts")
383
+ .withKeySerde(Serdes.Long())
384
+ .withValueSerde(Serdes.Long()));
385
+
386
+ // Query store from REST API
387
+ ReadOnlyKeyValueStore<Long, Long> store =
388
+ streams.store(StoreQueryParameters.fromNameAndType(
389
+ "user-counts",
390
+ QueryableStoreTypes.keyValueStore()
391
+ ));
392
+
393
+ Long count = store.get(userId);
394
+ ```
395
+
396
+ ## Topology Optimization
397
+
398
+ ### 1. Combine Operations
399
+
400
+ **GOOD** (Single pass):
401
+ ```java
402
+ KStream<Long, String> result = events
403
+ .filter((key, value) -> value.isValid())
404
+ .mapValues(value -> value.toUpperCase())
405
+ .filterNot((key, value) -> value.contains("test"));
406
+ ```
407
+
408
+ **BAD** (Multiple intermediate topics):
409
+ ```java
410
+ KStream<Long, Event> valid = events.filter((key, value) -> value.isValid());
411
+ valid.to("valid-events"); // Unnecessary write
412
+
413
+ KStream<Long, Event> fromValid = builder.stream("valid-events");
414
+ KStream<Long, String> upper = fromValid.mapValues(v -> v.toUpperCase());
415
+ ```
416
+
417
+ ### 2. Reuse KTables
418
+
419
+ **GOOD** (Shared table):
420
+ ```java
421
+ KTable<Long, User> users = builder.table("users");
422
+
423
+ KStream<Long, EnrichedClick> enrichedClicks = clicks.leftJoin(users, ...);
424
+ KStream<Long, EnrichedOrder> enrichedOrders = orders.leftJoin(users, ...);
425
+ ```
426
+
427
+ **BAD** (Duplicate tables):
428
+ ```java
429
+ KTable<Long, User> users1 = builder.table("users");
430
+ KTable<Long, User> users2 = builder.table("users"); // Duplicate!
431
+ ```
432
+
433
+ ## Testing Topologies
434
+
435
+ ### Topology Test Driver
436
+
437
+ ```java
438
+ @Test
439
+ public void testClickFilter() {
440
+ // Setup topology
441
+ StreamsBuilder builder = new StreamsBuilder();
442
+ KStream<Long, Click> clicks = builder.stream("clicks");
443
+ clicks.filter((key, value) -> !value.isBot())
444
+ .to("human-clicks");
445
+
446
+ Topology topology = builder.build();
447
+
448
+ // Create test driver
449
+ TopologyTestDriver testDriver = new TopologyTestDriver(topology);
450
+
451
+ // Input topic
452
+ TestInputTopic<Long, Click> inputTopic = testDriver.createInputTopic(
453
+ "clicks",
454
+ Serdes.Long().serializer(),
455
+ clickSerde.serializer()
456
+ );
457
+
458
+ // Output topic
459
+ TestOutputTopic<Long, Click> outputTopic = testDriver.createOutputTopic(
460
+ "human-clicks",
461
+ Serdes.Long().deserializer(),
462
+ clickSerde.deserializer()
463
+ );
464
+
465
+ // Send test data
466
+ inputTopic.pipeInput(1L, new Click(1L, "page1", false)); // Human
467
+ inputTopic.pipeInput(2L, new Click(2L, "page2", true)); // Bot
468
+
469
+ // Assert output
470
+ List<Click> output = outputTopic.readValuesToList();
471
+ assertEquals(1, output.size()); // Only human click
472
+ assertFalse(output.get(0).isBot());
473
+
474
+ testDriver.close();
475
+ }
476
+ ```
477
+
478
+ ## Common Issues & Solutions
479
+
480
+ ### Issue 1: StreamsException - Not Co-Partitioned
481
+
482
+ **Error**: Topics not co-partitioned for join
483
+
484
+ **Root Cause**: Joined streams/tables have different partition counts
485
+
486
+ **Solution**: Repartition to match:
487
+ ```java
488
+ // Ensure same partition count
489
+ KStream<Long, Event> repartitioned = events
490
+ .through("events-repartitioned",
491
+ Produced.with(Serdes.Long(), eventSerde)
492
+ .withStreamPartitioner((topic, key, value, numPartitions) ->
493
+ (int) (key % 12) // Match target partition count
494
+ )
495
+ );
496
+ ```
497
+
498
+ ### Issue 2: Out of Memory (Large State Store)
499
+
500
+ **Error**: Java heap space
501
+
502
+ **Root Cause**: State store too large, windowing not used
503
+
504
+ **Solution**: Add time-based cleanup:
505
+ ```java
506
+ // Use windowing to limit state size
507
+ KTable<Windowed<Long>, Long> counts = events
508
+ .groupByKey()
509
+ .windowedBy(TimeWindows.ofSizeAndGrace(
510
+ Duration.ofHours(24), // Window size
511
+ Duration.ofHours(1) // Grace period
512
+ ))
513
+ .count();
514
+ ```
515
+
516
+ ### Issue 3: High Lag, Slow Processing
517
+
518
+ **Root Cause**: Blocking operations, inefficient transformations
519
+
520
+ **Solution**: Use async processing:
521
+ ```java
522
+ // BAD: Blocking HTTP call
523
+ events.mapValues(value -> {
524
+ return httpClient.get(value.getUrl()); // BLOCKS!
525
+ });
526
+
527
+ // GOOD: Async processing with state store
528
+ events.transformValues(() -> new AsyncEnricher());
529
+ ```
530
+
531
+ ## References
532
+
533
+ - Kafka Streams Documentation: https://kafka.apache.org/documentation/streams/
534
+ - Kafka Streams Tutorial: https://kafka.apache.org/documentation/streams/tutorial
535
+ - Testing Guide: https://kafka.apache.org/documentation/streams/developer-guide/testing.html
536
+
537
+ ---
538
+
539
+ **Invoke me when you need topology design, joins, windowing, or exactly-once semantics expertise!**
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "specweave-n8n",
3
+ "description": "n8n workflow automation integration with Kafka - Event-driven workflows, Kafka triggers, producers, consumers, and workflow patterns for no-code/low-code event processing",
4
+ "version": "1.0.0",
5
+ "author": {
6
+ "name": "SpecWeave Team",
7
+ "url": "https://spec-weave.com"
8
+ },
9
+ "repository": "https://github.com/anton-abyzov/specweave",
10
+ "homepage": "https://spec-weave.com/docs/plugins/n8n",
11
+ "license": "MIT",
12
+ "keywords": [
13
+ "n8n",
14
+ "workflow-automation",
15
+ "kafka-integration",
16
+ "event-driven",
17
+ "no-code",
18
+ "low-code",
19
+ "kafka-trigger",
20
+ "kafka-producer"
21
+ ]
22
+ }