claude-flow-novice 2.9.1 → 2.10.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 (349) hide show
  1. package/.claude/agents/cfn-dev-team/CLAUDE.md +1086 -0
  2. package/.claude/agents/cfn-dev-team/README.md +116 -0
  3. package/.claude/agents/cfn-dev-team/architecture/api-designer-persona.md +149 -0
  4. package/.claude/agents/cfn-dev-team/architecture/base-template-generator.md +196 -0
  5. package/.claude/agents/cfn-dev-team/architecture/goal-planner.md +183 -0
  6. package/.claude/agents/cfn-dev-team/architecture/planner.md +182 -0
  7. package/.claude/agents/cfn-dev-team/architecture/system-architect.md +162 -0
  8. package/.claude/agents/cfn-dev-team/coordinators/cfn-frontend-coordinator.md +540 -0
  9. package/.claude/agents/cfn-dev-team/coordinators/cfn-v3-coordinator.md +20 -14
  10. package/.claude/agents/cfn-dev-team/coordinators/consensus-builder.md +167 -0
  11. package/.claude/agents/cfn-dev-team/dev-ops/devops-engineer.md +148 -0
  12. package/.claude/agents/cfn-dev-team/dev-ops/github-commit-agent.md +118 -0
  13. package/.claude/agents/cfn-dev-team/dev-ops/kubernetes-specialist.md +540 -0
  14. package/.claude/agents/cfn-dev-team/developers/backend-dev.md +20 -0
  15. package/.claude/agents/cfn-dev-team/developers/data/data-engineer.md +585 -0
  16. package/.claude/agents/cfn-dev-team/developers/database/database-architect.md +276 -0
  17. package/.claude/agents/cfn-dev-team/developers/dev-backend-api.md +147 -0
  18. package/.claude/agents/cfn-dev-team/developers/frontend/mobile-dev.md +218 -0
  19. package/.claude/agents/cfn-dev-team/developers/{react-frontend-engineer.md → frontend/react-frontend-engineer.md} +53 -5
  20. package/.claude/agents/cfn-dev-team/developers/frontend/spec-mobile-react-native.md +199 -0
  21. package/.claude/agents/cfn-dev-team/developers/graphql-specialist.md +615 -0
  22. package/.claude/agents/cfn-dev-team/developers/rust-developer.md +174 -0
  23. package/.claude/agents/cfn-dev-team/documentation/README-VALIDATION.md +243 -0
  24. package/.claude/agents/cfn-dev-team/documentation/agent-type-guidelines.md +465 -0
  25. package/.claude/agents/cfn-dev-team/documentation/api-docs.md +103 -0
  26. package/.claude/agents/cfn-dev-team/documentation/docs-api-openapi.md +98 -0
  27. package/.claude/agents/cfn-dev-team/documentation/pseudocode.md +159 -0
  28. package/.claude/agents/cfn-dev-team/documentation/specification.md +157 -0
  29. package/.claude/agents/cfn-dev-team/product-owners/accessibility-advocate-persona.md +109 -0
  30. package/.claude/agents/cfn-dev-team/{coordinators → product-owners}/cto-agent.md +8 -6
  31. package/.claude/agents/cfn-dev-team/product-owners/power-user-persona.md +190 -0
  32. package/.claude/agents/cfn-dev-team/{coordinators → product-owners}/product-owner.md +85 -59
  33. package/.claude/agents/cfn-dev-team/reviewers/quality/analyze-code-quality.md +141 -0
  34. package/.claude/agents/cfn-dev-team/reviewers/quality/code-analyzer.md +200 -0
  35. package/.claude/agents/cfn-dev-team/reviewers/quality/cyclomatic-complexity-reducer.md +321 -0
  36. package/.claude/agents/cfn-dev-team/reviewers/quality/perf-analyzer.md +238 -0
  37. package/.claude/agents/cfn-dev-team/reviewers/quality/performance-benchmarker.md +101 -0
  38. package/.claude/agents/cfn-dev-team/reviewers/quality/quality-metrics.md +375 -0
  39. package/.claude/agents/cfn-dev-team/reviewers/quality/security-specialist.md +193 -0
  40. package/.claude/agents/cfn-dev-team/reviewers/reviewer.md +39 -0
  41. package/.claude/agents/cfn-dev-team/testers/interaction-tester.md +31 -0
  42. package/.claude/agents/cfn-dev-team/testers/load-testing-specialist.md +469 -0
  43. package/.claude/agents/cfn-dev-team/testers/playwright-tester.md +24 -0
  44. package/.claude/agents/cfn-dev-team/testers/tester.md +20 -0
  45. package/.claude/agents/cfn-dev-team/utility/agent-builder.md +151 -0
  46. package/.claude/agents/cfn-dev-team/utility/analyst.md +178 -0
  47. package/.claude/agents/cfn-dev-team/utility/claude-code-expert.md +1043 -0
  48. package/.claude/agents/cfn-dev-team/utility/code-booster.md +139 -0
  49. package/.claude/agents/cfn-dev-team/utility/context-curator.md +99 -0
  50. package/.claude/agents/cfn-dev-team/{developers → utility}/researcher.md +6 -4
  51. package/.claude/commands/cfn/CFN_LOOP_FRONTEND.md +741 -0
  52. package/.claude/commands/cfn/CFN_LOOP_TASK_MODE.md +353 -0
  53. package/.claude/commands/cfn/cfn-loop-frontend.md +555 -0
  54. package/.claude/commands/cfn/cfn-loop.md +168 -7
  55. package/{CFN-CLAUDE.md → .claude/root-claude-distribute/CFN-CLAUDE.md} +23 -3
  56. package/.claude/skills/cfn-ace-system/SKILL.md +364 -0
  57. package/.claude/skills/cfn-ace-system/add-bullet.sh +145 -0
  58. package/.claude/skills/cfn-ace-system/analyze-anti-pattern-effectiveness.sh +56 -0
  59. package/.claude/skills/cfn-ace-system/classify-task.sh +18 -0
  60. package/.claude/skills/cfn-ace-system/export-ace-metrics.sh +48 -0
  61. package/.claude/skills/cfn-ace-system/extract-tags.sh +385 -0
  62. package/.claude/skills/cfn-ace-system/format-negative-context.sh +180 -0
  63. package/.claude/skills/cfn-ace-system/init-indexes.sql +160 -0
  64. package/.claude/skills/cfn-ace-system/invoke-context-curate.sh +192 -0
  65. package/.claude/skills/cfn-ace-system/invoke-context-inject.sh +361 -0
  66. package/.claude/skills/cfn-ace-system/invoke-context-query.sh +139 -0
  67. package/.claude/skills/cfn-ace-system/invoke-context-reflect.sh +343 -0
  68. package/.claude/skills/cfn-ace-system/invoke-context-stats.sh +227 -0
  69. package/.claude/skills/cfn-ace-system/log-merge.sh +67 -0
  70. package/.claude/skills/cfn-ace-system/monitor-injection-performance.sh +138 -0
  71. package/.claude/skills/cfn-ace-system/optimize-injection-pipeline.sh +169 -0
  72. package/.claude/skills/cfn-ace-system/query-anti-patterns.sh +276 -0
  73. package/.claude/skills/cfn-ace-system/query-contexts.sh +150 -0
  74. package/.claude/skills/cfn-ace-system/query-reflections.sh +35 -0
  75. package/.claude/skills/cfn-ace-system/schema/001-create-context-reflections.sql +237 -0
  76. package/.claude/skills/cfn-ace-system/schema/README.md +723 -0
  77. package/.claude/skills/cfn-ace-system/schema/SCHEMA_DESIGN_SUMMARY.md +564 -0
  78. package/.claude/skills/cfn-ace-system/schema/populate-test-data-simple.sh +62 -0
  79. package/.claude/skills/cfn-ace-system/schema/populate-test-data.sh +247 -0
  80. package/.claude/skills/cfn-ace-system/schema/run-migration.sh +231 -0
  81. package/.claude/skills/cfn-ace-system/schema/validate-schema.sql +280 -0
  82. package/.claude/skills/cfn-ace-system/score-relevance-adapter.sh +138 -0
  83. package/.claude/skills/cfn-ace-system/score-relevance.sh +253 -0
  84. package/.claude/skills/cfn-ace-system/sprint-7-lessons.json +46 -0
  85. package/.claude/skills/cfn-ace-system/store-reflection.sh +46 -0
  86. package/.claude/skills/cfn-ace-system/test-ace-skill.sh +312 -0
  87. package/.claude/skills/cfn-ace-system/track-ab-test.sh +42 -0
  88. package/.claude/skills/cfn-ace-system/update-reflection.sh +41 -0
  89. package/.claude/skills/cfn-agent-discovery/SKILL.md +40 -0
  90. package/.claude/skills/cfn-agent-discovery/agents-registry-clean.json +0 -0
  91. package/.claude/skills/cfn-agent-discovery/agents-registry-fixed.json +19 -0
  92. package/.claude/skills/cfn-agent-discovery/agents-registry.json +718 -0
  93. package/.claude/skills/cfn-agent-discovery/discover-agents.py +184 -0
  94. package/.claude/skills/cfn-agent-discovery/discover-agents.sh +87 -0
  95. package/.claude/skills/cfn-agent-discovery/invoke-registry.sh +11 -0
  96. package/.claude/skills/cfn-agent-discovery/temp_script.py +0 -0
  97. package/.claude/skills/cfn-agent-execution/execute-agent.sh +126 -0
  98. package/.claude/skills/cfn-agent-output-processing/SKILL.md +359 -0
  99. package/.claude/skills/cfn-agent-selector/SKILL.md +90 -0
  100. package/.claude/skills/cfn-agent-selector/select-agents.sh +112 -0
  101. package/.claude/skills/cfn-agent-spawning/SKILL.md +135 -0
  102. package/.claude/skills/cfn-agent-spawning/agent-selection-guide.md +814 -0
  103. package/.claude/skills/cfn-agent-spawning/check-dependencies.sh +30 -0
  104. package/.claude/skills/cfn-agent-spawning/spawn-agent.sh +263 -0
  105. package/.claude/skills/cfn-agent-spawning/spawn-templates.sh +613 -0
  106. package/.claude/skills/cfn-analytics/description-refinement-guide.md +164 -0
  107. package/.claude/skills/cfn-analytics/log-skill-invocation.js +122 -0
  108. package/.claude/skills/cfn-analytics/run-production-criteria-tests.sh +126 -0
  109. package/.claude/skills/cfn-analytics/skill-analytics-dashboard.js +113 -0
  110. package/.claude/skills/cfn-analytics/skill-invocation-hook.sh +28 -0
  111. package/.claude/skills/cfn-analytics/skill-invocations.sql +58 -0
  112. package/.claude/skills/cfn-analytics/test-corpus.json +32 -0
  113. package/.claude/skills/cfn-analytics/test-data-generator.js +115 -0
  114. package/.claude/skills/cfn-analytics/test-manual-override-rate.js +285 -0
  115. package/.claude/skills/cfn-analytics/validate-skill-selection.js +188 -0
  116. package/.claude/skills/cfn-config-management/SKILL.md +34 -0
  117. package/.claude/skills/cfn-config-management/check-dependencies.sh +56 -0
  118. package/.claude/skills/cfn-config-management/config.json +32 -0
  119. package/.claude/skills/cfn-config-management/manage-config.sh +113 -0
  120. package/.claude/skills/cfn-event-bus/SKILL.md +412 -0
  121. package/.claude/skills/cfn-event-bus/config.json +111 -0
  122. package/.claude/skills/cfn-event-bus/eventbus-wrapper.cjs +69 -0
  123. package/.claude/skills/cfn-event-bus/invoke-event-publish.sh +147 -0
  124. package/.claude/skills/cfn-event-bus/invoke-event-subscribe.sh +171 -0
  125. package/.claude/skills/cfn-event-bus/invoke-lifecycle-track.sh +201 -0
  126. package/.claude/skills/cfn-event-bus/test-event-bus.sh +280 -0
  127. package/.claude/skills/cfn-fleet-manager/SKILL.md +412 -0
  128. package/.claude/skills/cfn-fleet-manager/config.json +60 -0
  129. package/.claude/skills/cfn-fleet-manager/invoke-fleet-allocate.sh +182 -0
  130. package/.claude/skills/cfn-fleet-manager/invoke-fleet-balance.sh +239 -0
  131. package/.claude/skills/cfn-fleet-manager/invoke-fleet-metrics.sh +193 -0
  132. package/.claude/skills/cfn-fleet-manager/invoke-fleet-register.sh +124 -0
  133. package/.claude/skills/cfn-fleet-manager/test-fleet-manager.sh +345 -0
  134. package/.claude/skills/cfn-hook-pipeline/SKILL.md +148 -0
  135. package/.claude/skills/cfn-hook-pipeline/auto-resolve.sh +66 -0
  136. package/.claude/skills/cfn-hook-pipeline/check-dependencies.sh +40 -0
  137. package/.claude/skills/cfn-hook-pipeline/feedback-resolver.sh +452 -0
  138. package/.claude/skills/cfn-hook-pipeline/post-edit-handler.sh +154 -0
  139. package/.claude/skills/cfn-hook-pipeline/security-scan.json +60 -0
  140. package/.claude/skills/cfn-hook-pipeline/security-scanner.sh +121 -0
  141. package/.claude/skills/cfn-hook-pipeline/test-root-warning-resolution.sh +148 -0
  142. package/.claude/skills/cfn-hybrid-routing/SKILL.md +46 -0
  143. package/.claude/skills/cfn-hybrid-routing/check-dependencies.sh +52 -0
  144. package/.claude/skills/cfn-hybrid-routing/config.json +26 -0
  145. package/.claude/skills/cfn-hybrid-routing/spawn-worker.sh +44 -0
  146. package/.claude/skills/cfn-loop-orchestration/SKILL.md +299 -0
  147. package/.claude/skills/cfn-loop-orchestration/helpers/auto-tune-timeouts.sh +228 -0
  148. package/.claude/skills/cfn-loop-orchestration/helpers/consensus.sh +84 -0
  149. package/.claude/skills/cfn-loop-orchestration/helpers/context-injection.sh +142 -0
  150. package/.claude/skills/cfn-loop-orchestration/helpers/context-lookup.sh +359 -0
  151. package/.claude/skills/cfn-loop-orchestration/helpers/deliverable-verifier.sh +71 -0
  152. package/.claude/skills/cfn-loop-orchestration/helpers/gate-check.sh +90 -0
  153. package/.claude/skills/cfn-loop-orchestration/helpers/iteration-manager.sh +87 -0
  154. package/.claude/skills/cfn-loop-orchestration/helpers/spawn-agents.sh +271 -0
  155. package/.claude/skills/cfn-loop-orchestration/helpers/timeout-calculator.sh +51 -0
  156. package/.claude/skills/cfn-loop-orchestration/inject-loop-context.sh +41 -0
  157. package/.claude/skills/cfn-loop-orchestration/monitor-execution.sh +156 -0
  158. package/.claude/skills/cfn-loop-orchestration/orchestrate.sh +884 -0
  159. package/.claude/skills/cfn-loop-orchestration/orchestrate.sh.backup +840 -0
  160. package/.claude/skills/cfn-loop-orchestration/security_utils.sh +99 -0
  161. package/.claude/skills/cfn-loop-orchestration/test-cfn-orchestration.sh +281 -0
  162. package/.claude/skills/cfn-loop-orchestration/test-edge-cases.sh +188 -0
  163. package/.claude/skills/cfn-loop-validation/SKILL.md +353 -0
  164. package/.claude/skills/cfn-loop-validation/check-dependencies.sh +31 -0
  165. package/.claude/skills/cfn-loop-validation/config.json +161 -0
  166. package/.claude/skills/cfn-loop-validation/consensus-calculator.js +477 -0
  167. package/.claude/skills/cfn-loop-validation/evidence-chain.sql +163 -0
  168. package/.claude/skills/cfn-loop-validation/examples/README.md +453 -0
  169. package/.claude/skills/cfn-loop-validation/examples/coordinator-full-cfn-loop.sh +234 -0
  170. package/.claude/skills/cfn-loop-validation/examples/coordinator-loop2-consensus.sh +132 -0
  171. package/.claude/skills/cfn-loop-validation/examples/coordinator-loop3-gate.sh +115 -0
  172. package/.claude/skills/cfn-loop-validation/examples/coordinator-redis-integration.sh +186 -0
  173. package/.claude/skills/cfn-loop-validation/orchestrate-cfn-loop.sh +252 -0
  174. package/.claude/skills/cfn-loop-validation/validate-iteration.sh +134 -0
  175. package/.claude/skills/cfn-process-lifecycle/SKILL.md +39 -0
  176. package/.claude/skills/cfn-process-lifecycle/check-dependencies.sh +58 -0
  177. package/.claude/skills/cfn-process-lifecycle/config.json +39 -0
  178. package/.claude/skills/cfn-process-lifecycle/process-manager.sh +144 -0
  179. package/.claude/skills/cfn-product-owner-decision/SKILL.md +332 -0
  180. package/.claude/skills/cfn-product-owner-decision/execute-decision.sh +176 -0
  181. package/.claude/skills/cfn-product-owner-decision/parse-decision.sh +66 -0
  182. package/.claude/skills/cfn-product-owner-decision/validate-deliverables.sh +82 -0
  183. package/.claude/skills/cfn-redis-coordination/AGENT_LOGGING.md +280 -0
  184. package/.claude/skills/cfn-redis-coordination/BZPOPMIN_FIX_SUMMARY.md +209 -0
  185. package/.claude/skills/cfn-redis-coordination/HEARTBEAT.md +57 -0
  186. package/.claude/skills/cfn-redis-coordination/HEARTBEAT_MONITORING.md +267 -0
  187. package/.claude/skills/cfn-redis-coordination/LOGGING.md +260 -0
  188. package/.claude/skills/cfn-redis-coordination/SECURITY_REVIEW.md +25 -0
  189. package/.claude/skills/cfn-redis-coordination/SHUTDOWN_HANDLING.md +164 -0
  190. package/.claude/skills/cfn-redis-coordination/SKILL.md +720 -0
  191. package/.claude/skills/cfn-redis-coordination/agent-log.sh +124 -0
  192. package/.claude/skills/cfn-redis-coordination/agent-recovery.sh +75 -0
  193. package/.claude/skills/cfn-redis-coordination/analyze-task-complexity.sh +277 -0
  194. package/.claude/skills/cfn-redis-coordination/cancel-swarm.sh +221 -0
  195. package/.claude/skills/cfn-redis-coordination/cfn-loop-exec.sh +468 -0
  196. package/.claude/skills/cfn-redis-coordination/cfn-loop-relaunch.sh +29 -0
  197. package/.claude/skills/cfn-redis-coordination/check-dependencies.sh +32 -0
  198. package/.claude/skills/cfn-redis-coordination/collect-confidence-scores.sh +179 -0
  199. package/.claude/skills/cfn-redis-coordination/collect-results.sh +75 -0
  200. package/.claude/skills/cfn-redis-coordination/complete-swarm.sh +75 -0
  201. package/.claude/skills/cfn-redis-coordination/config.json +61 -0
  202. package/.claude/skills/cfn-redis-coordination/data/cfn-loop.db +0 -0
  203. package/.claude/skills/cfn-redis-coordination/demos/phase4-wake-queue-test-report.md +82 -0
  204. package/.claude/skills/cfn-redis-coordination/demos/test-bzpopmin-fix.sh +274 -0
  205. package/.claude/skills/cfn-redis-coordination/demos/test-cancel-swarm.sh +276 -0
  206. package/.claude/skills/cfn-redis-coordination/demos/test-dlq.sh +129 -0
  207. package/.claude/skills/cfn-redis-coordination/demos/test-iteration-feedback.sh +320 -0
  208. package/.claude/skills/cfn-redis-coordination/demos/test-orchestrator.sh +249 -0
  209. package/.claude/skills/cfn-redis-coordination/demos/test-priority-wake-phase4-unix.sh +148 -0
  210. package/.claude/skills/cfn-redis-coordination/demos/test-priority-wake-phase4.sh +163 -0
  211. package/.claude/skills/cfn-redis-coordination/demos/test-priority-wake.sh +138 -0
  212. package/.claude/skills/cfn-redis-coordination/demos/test-quick-fix.sh +81 -0
  213. package/.claude/skills/cfn-redis-coordination/demos/test-quorum-absolute.sh +45 -0
  214. package/.claude/skills/cfn-redis-coordination/demos/test-quorum-fallback.sh +68 -0
  215. package/.claude/skills/cfn-redis-coordination/demos/test-quorum-percentage.sh +56 -0
  216. package/.claude/skills/cfn-redis-coordination/demos/test-quorum-with-retry.sh +81 -0
  217. package/.claude/skills/cfn-redis-coordination/demos/test-quorum.sh +57 -0
  218. package/.claude/skills/cfn-redis-coordination/demos/test-shutdown-handling.sh +187 -0
  219. package/.claude/skills/cfn-redis-coordination/demos/test-shutdown.sh +160 -0
  220. package/.claude/skills/cfn-redis-coordination/demos/test-utils-unix.sh +97 -0
  221. package/.claude/skills/cfn-redis-coordination/demos/test-utils.sh +97 -0
  222. package/.claude/skills/cfn-redis-coordination/demos/test-waiting-mode.sh +59 -0
  223. package/.claude/skills/cfn-redis-coordination/examples/README.md +73 -0
  224. package/.claude/skills/cfn-redis-coordination/examples/grafana-dashboard.json +352 -0
  225. package/.claude/skills/cfn-redis-coordination/examples/hierarchical-pattern.sh +127 -0
  226. package/.claude/skills/cfn-redis-coordination/examples/mesh-pattern.sh +171 -0
  227. package/.claude/skills/cfn-redis-coordination/examples/timeout-handling.sh +227 -0
  228. package/.claude/skills/cfn-redis-coordination/examples/waiting-mode-pattern.sh +239 -0
  229. package/.claude/skills/cfn-redis-coordination/execute-product-owner-decision.sh +258 -0
  230. package/.claude/skills/cfn-redis-coordination/get-agent-timeout.sh +177 -0
  231. package/.claude/skills/cfn-redis-coordination/heartbeat-functions.sh +137 -0
  232. package/.claude/skills/cfn-redis-coordination/heartbeat-protocol.md +106 -0
  233. package/.claude/skills/cfn-redis-coordination/heartbeat.sh +126 -0
  234. package/.claude/skills/cfn-redis-coordination/init-swarm.sh +148 -0
  235. package/.claude/skills/cfn-redis-coordination/invoke-redis-pattern.sh +220 -0
  236. package/.claude/skills/cfn-redis-coordination/invoke-waiting-mode.sh +283 -0
  237. package/.claude/skills/cfn-redis-coordination/invoke-waiting-mode.sh.backup-p7 +423 -0
  238. package/.claude/skills/cfn-redis-coordination/list-active-swarms.sh +147 -0
  239. package/.claude/skills/cfn-redis-coordination/log-event.sh +109 -0
  240. package/.claude/skills/cfn-redis-coordination/metrics-export.sh +674 -0
  241. package/.claude/skills/cfn-redis-coordination/metrics-schema.json +66 -0
  242. package/.claude/skills/cfn-redis-coordination/metrics-storage.md +31 -0
  243. package/.claude/skills/cfn-redis-coordination/monitor-cfn-violations.sh +391 -0
  244. package/.claude/skills/cfn-redis-coordination/monitor-heartbeats.sh +101 -0
  245. package/.claude/skills/cfn-redis-coordination/orchestrate-cfn-loop-v3.sh +141 -0
  246. package/.claude/skills/cfn-redis-coordination/orchestrate-cfn-loop.sh +31 -0
  247. package/.claude/skills/cfn-redis-coordination/orchestrate-cfn-loop.sh.backup +38 -0
  248. package/.claude/skills/cfn-redis-coordination/orchestrate-cfn-loop.sh.backup-1761167675 +1672 -0
  249. package/.claude/skills/cfn-redis-coordination/orchestrate-cfn-loop.sh.backup-p5 +1604 -0
  250. package/.claude/skills/cfn-redis-coordination/orchestrate-cfn-loop.sh.backup-phase1 +1550 -0
  251. package/.claude/skills/cfn-redis-coordination/orchestrate-cfn-loop.sh.backup-phase2 +1621 -0
  252. package/.claude/skills/cfn-redis-coordination/orchestrate-cfn-loop.sh.backup-phase3 +1621 -0
  253. package/.claude/skills/cfn-redis-coordination/orchestrate-cfn-loop.sh.bak +0 -0
  254. package/.claude/skills/cfn-redis-coordination/orchestrate-cfn-loop.sh.broken +1627 -0
  255. package/.claude/skills/cfn-redis-coordination/orchestrate-cfn-loop.sh.corrupted +80 -0
  256. package/.claude/skills/cfn-redis-coordination/orchestrate-cfn-loop.sh.deprecated +1864 -0
  257. package/.claude/skills/cfn-redis-coordination/priority-wake-mechanism.md +75 -0
  258. package/.claude/skills/cfn-redis-coordination/priority_wake.py +134 -0
  259. package/.claude/skills/cfn-redis-coordination/query-dlq.sh +162 -0
  260. package/.claude/skills/cfn-redis-coordination/query-logs.sh +103 -0
  261. package/.claude/skills/cfn-redis-coordination/redis-pattern.sh +619 -0
  262. package/.claude/skills/cfn-redis-coordination/retrieve-context.sh +58 -0
  263. package/.claude/skills/cfn-redis-coordination/select-specialist-agent.sh +371 -0
  264. package/.claude/skills/cfn-redis-coordination/semantic-match-tfidf.py +252 -0
  265. package/.claude/skills/cfn-redis-coordination/send-heartbeat.sh +165 -0
  266. package/.claude/skills/cfn-redis-coordination/signal.sh +38 -0
  267. package/.claude/skills/cfn-redis-coordination/store-context.sh +86 -0
  268. package/.claude/skills/cfn-redis-coordination/store-epic-context.sh +123 -0
  269. package/.claude/skills/cfn-redis-coordination/test-context-injection.sh +354 -0
  270. package/.claude/skills/cfn-redis-coordination/test-timeout-enforcement.sh +513 -0
  271. package/.claude/skills/cfn-redis-coordination/tests/convert-line-endings.sh +15 -0
  272. package/.claude/skills/cfn-redis-coordination/tests/dlq-functionality-test.sh +102 -0
  273. package/.claude/skills/cfn-redis-coordination/tests/edge-cases-test.sh +99 -0
  274. package/.claude/skills/cfn-redis-coordination/tests/integration-test.sh +170 -0
  275. package/.claude/skills/cfn-redis-coordination/tests/retry-mechanism-test.sh +82 -0
  276. package/.claude/skills/cfn-redis-coordination/tests/run-test-suite.sh +92 -0
  277. package/.claude/skills/cfn-redis-coordination/tests/run-tests.sh +4 -0
  278. package/.claude/skills/cfn-redis-coordination/tests/test-heartbeat-monitoring.sh +418 -0
  279. package/.claude/skills/cfn-redis-coordination/tests/test-heartbeat-simple.sh +124 -0
  280. package/.claude/skills/cfn-redis-coordination/tests/test-primitives.sh +166 -0
  281. package/.claude/skills/cfn-redis-coordination/tests/test-utils.sh +54 -0
  282. package/.claude/skills/cfn-redis-coordination/tests/test_coordination_primitives.sh.deprecated +20 -0
  283. package/.claude/skills/cfn-redis-coordination/tests/test_utils.sh +49 -0
  284. package/.claude/skills/cfn-redis-coordination/v2_modularization/core_orchestration.sh +76 -0
  285. package/.claude/skills/cfn-redis-coordination/validate-parameters.sh +492 -0
  286. package/.claude/skills/cfn-sqlite-memory/IMPLEMENTATION_REPORT.md +393 -0
  287. package/.claude/skills/cfn-sqlite-memory/QUICK_REFERENCE.md +204 -0
  288. package/.claude/skills/cfn-sqlite-memory/SKILL.md +415 -0
  289. package/.claude/skills/cfn-sqlite-memory/acl-queries.sql +452 -0
  290. package/.claude/skills/cfn-sqlite-memory/check-dependencies.sh +36 -0
  291. package/.claude/skills/cfn-sqlite-memory/config.json +45 -0
  292. package/.claude/skills/cfn-sqlite-memory/memory-cli.sh +88 -0
  293. package/.claude/skills/cfn-sqlite-memory/test-state-persistence.js +187 -0
  294. package/.claude/skills/cfn-sqlite-memory/ttl-cleanup.sh +274 -0
  295. package/.claude/skills/cfn-test-execution/SKILL.md +128 -0
  296. package/.claude/skills/cfn-test-execution/check-dependencies.sh +36 -0
  297. package/.claude/skills/cfn-test-execution/test-cache-reader.sh +134 -0
  298. package/.claude/skills/cfn-test-execution/test-concurrent-conflicts.sh +115 -0
  299. package/.claude/skills/cfn-test-execution/test-coordinator-pattern.sh +109 -0
  300. package/.claude/skills/cfn-transparency-middleware/Cargo.toml +18 -0
  301. package/.claude/skills/cfn-transparency-middleware/SECURITY.md +41 -0
  302. package/.claude/skills/cfn-transparency-middleware/SKILL.md +91 -0
  303. package/.claude/skills/cfn-transparency-middleware/TEST_RESULTS.md +174 -0
  304. package/.claude/skills/cfn-transparency-middleware/config.json +31 -0
  305. package/.claude/skills/cfn-transparency-middleware/examples/basic-usage.ts +39 -0
  306. package/.claude/skills/cfn-transparency-middleware/examples/batch-processing.ts +52 -0
  307. package/.claude/skills/cfn-transparency-middleware/examples/custom-filtering.ts +61 -0
  308. package/.claude/skills/cfn-transparency-middleware/invoke-transparency-filter.sh +98 -0
  309. package/.claude/skills/cfn-transparency-middleware/invoke-transparency-init.sh +224 -0
  310. package/.claude/skills/cfn-transparency-middleware/invoke-transparency-level.sh +333 -0
  311. package/.claude/skills/cfn-transparency-middleware/invoke-transparency-metrics.sh +345 -0
  312. package/.claude/skills/cfn-transparency-middleware/invoke-transparency-observe.sh +140 -0
  313. package/.claude/skills/cfn-transparency-middleware/invoke-transparency-stop.sh +235 -0
  314. package/.claude/skills/cfn-transparency-middleware/memory_query.rs +85 -0
  315. package/.claude/skills/cfn-transparency-middleware/memory_repository.rs +140 -0
  316. package/.claude/skills/cfn-transparency-middleware/memory_schema.rs +64 -0
  317. package/.claude/skills/cfn-transparency-middleware/middleware-config.sh +29 -0
  318. package/.claude/skills/cfn-transparency-middleware/performance-benchmark.sh +79 -0
  319. package/.claude/skills/cfn-transparency-middleware/test-e2e.sh +406 -0
  320. package/.claude/skills/cfn-transparency-middleware/test-integration.sh +162 -0
  321. package/.claude/skills/cfn-transparency-middleware/test-transparency-skill.sh +368 -0
  322. package/.claude/skills/cfn-transparency-middleware/test-transparency-skill.sh.unix +126 -0
  323. package/.claude/skills/cfn-transparency-middleware/tests/input-validation.sh +93 -0
  324. package/.claude/skills/cfn-transparency-middleware/wrap-agent.sh +132 -0
  325. package/.claude/skills/cfn-webapp-testing/SCREENSHOT_NAMING_CONVENTION.md +547 -0
  326. package/.claude/skills/cfn-webapp-testing/SKILL.md +877 -0
  327. package/.claude/skills/cfn-webapp-testing/capture-screenshot.sh +238 -0
  328. package/.claude/skills/cfn-webapp-testing/cfn-loop-integration.sh +265 -0
  329. package/.claude/skills/cfn-webapp-testing/compare-screenshots.sh +199 -0
  330. package/.claude/skills/cfn-webapp-testing/init-storage.sh +150 -0
  331. package/.claude/skills/cfn-webapp-testing/set-baseline.sh +196 -0
  332. package/.claude/skills/cfn-webapp-testing/test-webapp-testing.sh +233 -0
  333. package/README.md +51 -2
  334. package/dist/ace/ace-reflector.js +109 -10
  335. package/dist/ace/ace-reflector.js.map +1 -1
  336. package/dist/cli/agent-executor.js +1 -1
  337. package/dist/cli/agent-executor.js.map +1 -1
  338. package/package.json +43 -7
  339. package/readme/README.md +15 -4
  340. package/scripts/init-project.js +39 -2
  341. package/scripts/run-marketing-tests.sh +43 -0
  342. package/scripts/update_paths.sh +47 -0
  343. package/tools/install-lizard.sh +37 -0
  344. package/tools/simple-complexity.sh +44 -0
  345. package/.claude/agents/cfn-dev-team/developers/coder.md +0 -270
  346. package/.claude/agents/cfn-dev-team/developers/state-architect.md +0 -127
  347. package/.claude/agents/cfn-dev-team/reviewers/code-quality-validator.md +0 -128
  348. /package/.claude/agents/cfn-dev-team/developers/{ui-designer.md → frontend/ui-designer.md} +0 -0
  349. /package/.claude/agents/cfn-dev-team/{coordinators → product-owners}/product-owner-agent.md +0 -0
@@ -0,0 +1,238 @@
1
+ #!/bin/bash
2
+ # Webapp Testing Skill - Screenshot Capture
3
+ # Purpose: Capture screenshots with Playwright, store metadata in SQLite, coordinate via Redis
4
+
5
+ set -e
6
+
7
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
+ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.claude/skills/cfn-cfn-.claude/skills/cfn-cfn-.." && pwd)"
9
+ cd "$PROJECT_ROOT"
10
+
11
+ # Default configuration
12
+ VARIANT="default"
13
+ TIMEOUT=30000
14
+ WAIT_FOR=""
15
+ SELECTOR=""
16
+
17
+ # Parse arguments
18
+ while [[ $# -gt 0 ]]; do
19
+ case $1 in
20
+ --project) PROJECT="$2"; shift 2 ;;
21
+ --component) COMPONENT="$2"; shift 2 ;;
22
+ --viewport) VIEWPORT="$2"; shift 2 ;;
23
+ --state) STATE="$2"; shift 2 ;;
24
+ --variant) VARIANT="$2"; shift 2 ;;
25
+ --url) URL="$2"; shift 2 ;;
26
+ --task-id) TASK_ID="$2"; shift 2 ;;
27
+ --agent-id) AGENT_ID="$2"; shift 2 ;;
28
+ --selector) SELECTOR="$2"; shift 2 ;;
29
+ --wait-for) WAIT_FOR="$2"; shift 2 ;;
30
+ --timeout) TIMEOUT="$2"; shift 2 ;;
31
+ *) echo "Unknown parameter: $1"; exit 1 ;;
32
+ esac
33
+ done
34
+
35
+ # Validate required parameters
36
+ if [ -z "$PROJECT" ] || [ -z "$COMPONENT" ] || [ -z "$VIEWPORT" ] || [ -z "$STATE" ] || [ -z "$URL" ]; then
37
+ echo "Error: Missing required parameters" >&2
38
+ echo "Usage: $0 --project <project> --component <component> --viewport <viewport> --state <state> --url <url>" >&2
39
+ echo "" >&2
40
+ echo "Required:" >&2
41
+ echo " --project Application/feature namespace (e.g., 'auth-system')" >&2
42
+ echo " --component UI component or page (e.g., 'login-form')" >&2
43
+ echo " --viewport Screen dimensions (e.g., '1920x1080', '375x667')" >&2
44
+ echo " --state Interaction state (e.g., 'default', 'hover', 'error')" >&2
45
+ echo " --url Page URL (e.g., 'http://localhost:3000/login')" >&2
46
+ echo "" >&2
47
+ echo "Optional:" >&2
48
+ echo " --variant Theme/variant (default: 'default')" >&2
49
+ echo " --task-id CFN task identifier" >&2
50
+ echo " --agent-id Agent identifier" >&2
51
+ echo " --selector CSS selector for element capture" >&2
52
+ echo " --wait-for CSS selector to wait for before capture" >&2
53
+ echo " --timeout Playwright timeout in ms (default: 30000)" >&2
54
+ exit 1
55
+ fi
56
+
57
+ # Generate screenshot key and paths
58
+ TIMESTAMP=$(date +%Y%m%d%H%M%S)
59
+ SCREENSHOT_KEY="${PROJECT}/${COMPONENT}/${VIEWPORT}/${STATE}/${VARIANT}"
60
+ OUTPUT_DIR=".screenshots/current/${PROJECT}/${COMPONENT}/${VIEWPORT}/${STATE}"
61
+ OUTPUT_FILE="${OUTPUT_DIR}/${VARIANT}_${TIMESTAMP}.png"
62
+
63
+ mkdir -p "$OUTPUT_DIR"
64
+
65
+ # Parse viewport dimensions
66
+ IFS='x' read -r WIDTH HEIGHT <<< "$VIEWPORT"
67
+
68
+ # Validate viewport dimensions
69
+ if ! [[ "$WIDTH" =~ ^[0-9]+$ ]] || ! [[ "$HEIGHT" =~ ^[0-9]+$ ]]; then
70
+ echo "Error: Invalid viewport format. Expected format: WIDTHxHEIGHT (e.g., 1920x1080)" >&2
71
+ exit 1
72
+ fi
73
+
74
+ # Capture screenshot with Playwright (inline Node.js script)
75
+ echo "Capturing screenshot: $SCREENSHOT_KEY" >&2
76
+
77
+ CAPTURE_RESULT=$(node -e "
78
+ const { chromium } = require('playwright');
79
+
80
+ (async () => {
81
+ const browser = await chromium.launch({ headless: true });
82
+ const context = await browser.newContext({
83
+ viewport: { width: ${WIDTH}, height: ${HEIGHT} },
84
+ deviceScaleFactor: 1
85
+ });
86
+ const page = await context.newPage();
87
+
88
+ try {
89
+ await page.goto('${URL}', { waitUntil: 'networkidle', timeout: ${TIMEOUT} });
90
+
91
+ ${WAIT_FOR:+await page.waitForSelector('${WAIT_FOR}', { timeout: ${TIMEOUT} });}
92
+
93
+ // Simulate state if needed
94
+ ${SELECTOR:+const element = await page.locator('${SELECTOR}').first();}
95
+ if ('${STATE}' === 'hover' && '${SELECTOR}') {
96
+ await element.hover();
97
+ await page.waitForTimeout(500); // Allow hover effects to render
98
+ } else if ('${STATE}' === 'focus' && '${SELECTOR}') {
99
+ await element.focus();
100
+ await page.waitForTimeout(300);
101
+ } else if ('${STATE}' === 'hover' && !'${SELECTOR}') {
102
+ console.error('Warning: hover state requires --selector parameter');
103
+ }
104
+
105
+ const screenshotOptions = {
106
+ path: '${OUTPUT_FILE}',
107
+ type: 'png'
108
+ };
109
+
110
+ ${SELECTOR:+
111
+ const boundingBox = await element.boundingBox();
112
+ if (boundingBox) {
113
+ screenshotOptions.clip = boundingBox;
114
+ } else {
115
+ console.error('Warning: Selector element not found, capturing full page');
116
+ screenshotOptions.fullPage = true;
117
+ }
118
+ }
119
+ ${SELECTOR:-screenshotOptions.fullPage = true;}
120
+
121
+ await page.screenshot(screenshotOptions);
122
+
123
+ await browser.close();
124
+
125
+ console.log(JSON.stringify({
126
+ screenshot_key: '${SCREENSHOT_KEY}',
127
+ file_path: '${OUTPUT_FILE}',
128
+ viewport_actual: { width: ${WIDTH}, height: ${HEIGHT} },
129
+ captured_at: Math.floor(Date.now() / 1000),
130
+ url: '${URL}',
131
+ state: '${STATE}',
132
+ selector: '${SELECTOR:-null}'
133
+ }));
134
+ } catch (error) {
135
+ await browser.close();
136
+ console.error('Playwright error:', error.message);
137
+ process.exit(1);
138
+ }
139
+ })();
140
+ " 2>&1)
141
+
142
+ # Check if capture succeeded
143
+ if [ $? -ne 0 ]; then
144
+ echo "Error: Screenshot capture failed" >&2
145
+ echo "$CAPTURE_RESULT" >&2
146
+ exit 1
147
+ fi
148
+
149
+ # Extract JSON from output (ignore stderr warnings)
150
+ CAPTURE_JSON=$(echo "$CAPTURE_RESULT" | grep -E '^\{.*\}$' | tail -n 1)
151
+
152
+ if [ -z "$CAPTURE_JSON" ]; then
153
+ echo "Error: Failed to parse capture result" >&2
154
+ echo "Output: $CAPTURE_RESULT" >&2
155
+ exit 1
156
+ fi
157
+
158
+ # Calculate file hash
159
+ if [ ! -f "$OUTPUT_FILE" ]; then
160
+ echo "Error: Screenshot file not created: $OUTPUT_FILE" >&2
161
+ exit 1
162
+ fi
163
+
164
+ FILE_HASH=$(sha256sum "$OUTPUT_FILE" | awk '{print $1}')
165
+
166
+ # Check if baseline exists
167
+ DB_PATH="${HOME}/.claude/memory/adaptive-context.db"
168
+ BASELINE_EXISTS=$(sqlite3 "$DB_PATH" \
169
+ "SELECT COUNT(*) FROM webapp_screenshots WHERE screenshot_key = '${SCREENSHOT_KEY}' AND baseline = 1" 2>/dev/null || echo "0")
170
+
171
+ # Get git metadata
172
+ GIT_COMMIT=$(git rev-parse --short HEAD 2>/dev/null || echo 'unknown')
173
+ GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo 'unknown')
174
+
175
+ # Prepare metadata JSON (escape single quotes)
176
+ METADATA=$(cat <<EOF | tr '\n' ' ' | sed "s/'/\"/g"
177
+ {
178
+ "browser": "chromium",
179
+ "viewport_actual": { "width": ${WIDTH}, "height": ${HEIGHT} },
180
+ "url": "${URL}",
181
+ "state": "${STATE}",
182
+ "selector": "${SELECTOR:-null}",
183
+ "task_id": "${TASK_ID:-null}",
184
+ "agent_id": "${AGENT_ID:-null}",
185
+ "git_commit": "${GIT_COMMIT}",
186
+ "git_branch": "${GIT_BRANCH}",
187
+ "captured_by": "webapp-testing-skill"
188
+ }
189
+ EOF
190
+ )
191
+
192
+ # Store metadata in SQLite
193
+ sqlite3 "$DB_PATH" <<EOF
194
+ INSERT INTO webapp_screenshots (
195
+ screenshot_key, project, component, viewport, state, variant,
196
+ file_path, file_hash, baseline, captured_at, task_id, agent_id, metadata
197
+ ) VALUES (
198
+ '${SCREENSHOT_KEY}',
199
+ '${PROJECT}',
200
+ '${COMPONENT}',
201
+ '${VIEWPORT}',
202
+ '${STATE}',
203
+ '${VARIANT}',
204
+ '${OUTPUT_FILE}',
205
+ 'sha256:${FILE_HASH}',
206
+ 0,
207
+ $(date +%s),
208
+ '${TASK_ID:-null}',
209
+ '${AGENT_ID:-null}',
210
+ '${METADATA}'
211
+ );
212
+ EOF
213
+
214
+ if [ $? -ne 0 ]; then
215
+ echo "Warning: Failed to store metadata in SQLite" >&2
216
+ fi
217
+
218
+ # Push to Redis queue (for orchestrator tracking)
219
+ if [ -n "$TASK_ID" ]; then
220
+ redis-cli lpush "screenshot:queue:${TASK_ID}" "$SCREENSHOT_KEY" > /dev/null 2>&1 || echo "Warning: Failed to push to Redis queue" >&2
221
+ fi
222
+
223
+ # Output result (JSON)
224
+ cat <<EOF
225
+ {
226
+ "screenshot_key": "${SCREENSHOT_KEY}",
227
+ "file_path": "${OUTPUT_FILE}",
228
+ "file_hash": "sha256:${FILE_HASH}",
229
+ "viewport_actual": { "width": ${WIDTH}, "height": ${HEIGHT} },
230
+ "captured_at": $(date +%s),
231
+ "baseline_exists": $([[ "$BASELINE_EXISTS" -eq 1 ]] && echo "true" || echo "false"),
232
+ "url": "${URL}",
233
+ "state": "${STATE}",
234
+ "variant": "${VARIANT}",
235
+ "task_id": "${TASK_ID:-null}",
236
+ "agent_id": "${AGENT_ID:-null}"
237
+ }
238
+ EOF
@@ -0,0 +1,265 @@
1
+ #!/bin/bash
2
+ # Webapp Testing Skill - CFN Loop Integration Helper
3
+ # Purpose: Helper functions for integrating visual regression testing into CFN Loop workflows
4
+
5
+ set -e
6
+
7
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
+ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.claude/skills/cfn-cfn-.claude/skills/cfn-cfn-.." && pwd)"
9
+
10
+ # Function: Capture all screenshots for a component
11
+ # Usage: capture_component_screenshots <project> <component> <url> <task-id> <agent-id> [viewports...]
12
+ capture_component_screenshots() {
13
+ local PROJECT="$1"
14
+ local COMPONENT="$2"
15
+ local URL="$3"
16
+ local TASK_ID="$4"
17
+ local AGENT_ID="$5"
18
+ shift 5
19
+ local VIEWPORTS=("${@:-1920x1080}") # Default to desktop
20
+
21
+ local STATES=("default" "hover" "error")
22
+ local VARIANTS=("light-mode" "dark-mode")
23
+
24
+ echo "Capturing screenshots for component: $COMPONENT" >&2
25
+ local TOTAL=$((${#VIEWPORTS[@]} * ${#STATES[@]} * ${#VARIANTS[@]}))
26
+ local COUNT=0
27
+
28
+ for VIEWPORT in "${VIEWPORTS[@]}"; do
29
+ for STATE in "${STATES[@]}"; do
30
+ for VARIANT in "${VARIANTS[@]}"; do
31
+ COUNT=$((COUNT + 1))
32
+ echo "[$COUNT/$TOTAL] Capturing: $VIEWPORT / $STATE / $VARIANT" >&2
33
+
34
+ "$SCRIPT_DIR/capture-screenshot.sh" \
35
+ --project "$PROJECT" \
36
+ --component "$COMPONENT" \
37
+ --viewport "$VIEWPORT" \
38
+ --state "$STATE" \
39
+ --variant "$VARIANT" \
40
+ --url "$URL" \
41
+ --task-id "$TASK_ID" \
42
+ --agent-id "$AGENT_ID" || echo "Warning: Failed to capture $VIEWPORT/$STATE/$VARIANT" >&2
43
+ done
44
+ done
45
+ done
46
+
47
+ echo "✅ Captured $COUNT screenshots" >&2
48
+ }
49
+
50
+ # Function: Compare all screenshots in task queue to baselines
51
+ # Usage: compare_all_screenshots <task-id> [threshold]
52
+ compare_all_screenshots() {
53
+ local TASK_ID="$1"
54
+ local THRESHOLD="${2:-0.95}"
55
+
56
+ echo "Comparing all screenshots in task queue: $TASK_ID" >&2
57
+
58
+ # Get all screenshot keys from Redis queue
59
+ local SCREENSHOT_KEYS=$(redis-cli lrange "screenshot:queue:${TASK_ID}" 0 -1 2>/dev/null || echo "")
60
+
61
+ if [ -z "$SCREENSHOT_KEYS" ]; then
62
+ echo "Warning: No screenshots found in queue for task: $TASK_ID" >&2
63
+ return 1
64
+ fi
65
+
66
+ local TOTAL=$(echo "$SCREENSHOT_KEYS" | wc -l)
67
+ local COUNT=0
68
+ local PASSED=0
69
+ local FAILED=0
70
+ local NO_BASELINE=0
71
+
72
+ echo "$SCREENSHOT_KEYS" | while read -r SCREENSHOT_KEY; do
73
+ [ -z "$SCREENSHOT_KEY" ] && continue
74
+
75
+ COUNT=$((COUNT + 1))
76
+ echo "[$COUNT/$TOTAL] Comparing: $SCREENSHOT_KEY" >&2
77
+
78
+ RESULT=$("$SCRIPT_DIR/compare-screenshots.sh" \
79
+ --screenshot-key "$SCREENSHOT_KEY" \
80
+ --task-id "$TASK_ID" \
81
+ --threshold "$THRESHOLD" 2>/dev/null || echo '{"status":"error"}')
82
+
83
+ STATUS=$(echo "$RESULT" | jq -r '.status')
84
+
85
+ case "$STATUS" in
86
+ passed)
87
+ PASSED=$((PASSED + 1))
88
+ echo " ✅ PASSED ($(echo "$RESULT" | jq -r '.similarity_score'))" >&2
89
+ ;;
90
+ failed)
91
+ FAILED=$((FAILED + 1))
92
+ echo " ❌ FAILED ($(echo "$RESULT" | jq -r '.diff_percentage')% difference)" >&2
93
+ ;;
94
+ no-baseline)
95
+ NO_BASELINE=$((NO_BASELINE + 1))
96
+ echo " ⚠️ NO BASELINE" >&2
97
+ ;;
98
+ *)
99
+ echo " ❌ ERROR" >&2
100
+ ;;
101
+ esac
102
+ done
103
+
104
+ # Calculate overall status
105
+ if [ "$FAILED" -eq 0 ] && [ "$NO_BASELINE" -eq 0 ]; then
106
+ echo "✅ All comparisons passed: $PASSED/$TOTAL" >&2
107
+ return 0
108
+ elif [ "$NO_BASELINE" -gt 0 ]; then
109
+ echo "⚠️ Some screenshots lack baselines: $NO_BASELINE missing" >&2
110
+ return 2
111
+ else
112
+ echo "❌ Visual regressions detected: $FAILED/$TOTAL failed" >&2
113
+ return 1
114
+ fi
115
+ }
116
+
117
+ # Function: Calculate validation consensus from comparison results
118
+ # Usage: calculate_validation_consensus <task-id>
119
+ calculate_validation_consensus() {
120
+ local TASK_ID="$1"
121
+
122
+ echo "Calculating validation consensus for task: $TASK_ID" >&2
123
+
124
+ # Get all comparison results from Redis
125
+ local DIFF_KEYS=$(redis-cli keys "screenshot:diff:${TASK_ID}:*" 2>/dev/null || echo "")
126
+
127
+ if [ -z "$DIFF_KEYS" ]; then
128
+ echo '{"confidence": 0.0, "status": "no-comparisons", "message": "No comparison results found"}' | jq '.'
129
+ return 1
130
+ fi
131
+
132
+ local TOTAL=0
133
+ local PASSED=0
134
+ local FAILED=0
135
+ local TOTAL_SIMILARITY=0
136
+
137
+ echo "$DIFF_KEYS" | while read -r KEY; do
138
+ [ -z "$KEY" ] && continue
139
+
140
+ RESULT=$(redis-cli get "$KEY" 2>/dev/null || echo '{}')
141
+ STATUS=$(echo "$RESULT" | jq -r '.status // "unknown"')
142
+ SIMILARITY=$(echo "$RESULT" | jq -r '.similarity_score // 0')
143
+
144
+ TOTAL=$((TOTAL + 1))
145
+ TOTAL_SIMILARITY=$(echo "$TOTAL_SIMILARITY + $SIMILARITY" | bc -l)
146
+
147
+ if [ "$STATUS" = "passed" ]; then
148
+ PASSED=$((PASSED + 1))
149
+ elif [ "$STATUS" = "failed" ]; then
150
+ FAILED=$((FAILED + 1))
151
+ fi
152
+ done
153
+
154
+ # Calculate average similarity and confidence
155
+ AVG_SIMILARITY=$(echo "scale=4; $TOTAL_SIMILARITY / $TOTAL" | bc -l)
156
+ PASS_RATE=$(echo "scale=4; $PASSED / $TOTAL" | bc -l)
157
+
158
+ # Confidence = weighted average of pass rate and similarity
159
+ # Pass rate weighted 60%, average similarity weighted 40%
160
+ CONFIDENCE=$(echo "scale=4; ($PASS_RATE * 0.6) + ($AVG_SIMILARITY * 0.4)" | bc -l)
161
+
162
+ # Determine overall status
163
+ if [ "$FAILED" -eq 0 ]; then
164
+ STATUS="passed"
165
+ MESSAGE="All visual regression tests passed"
166
+ else
167
+ STATUS="failed"
168
+ MESSAGE="Visual regressions detected in $FAILED/$TOTAL screenshots"
169
+ fi
170
+
171
+ # Output JSON result
172
+ cat <<EOF | jq '.'
173
+ {
174
+ "confidence": ${CONFIDENCE},
175
+ "status": "${STATUS}",
176
+ "message": "${MESSAGE}",
177
+ "total_comparisons": ${TOTAL},
178
+ "passed": ${PASSED},
179
+ "failed": ${FAILED},
180
+ "average_similarity": ${AVG_SIMILARITY},
181
+ "pass_rate": ${PASS_RATE},
182
+ "task_id": "${TASK_ID}"
183
+ }
184
+ EOF
185
+ }
186
+
187
+ # Function: Update all baselines after Product Owner approval
188
+ # Usage: update_all_baselines <task-id> <reason> <approved-by>
189
+ update_all_baselines() {
190
+ local TASK_ID="$1"
191
+ local REASON="$2"
192
+ local APPROVED_BY="$3"
193
+
194
+ echo "Updating baselines for task: $TASK_ID" >&2
195
+
196
+ # Get all comparison results from Redis
197
+ local DIFF_KEYS=$(redis-cli keys "screenshot:diff:${TASK_ID}:*" 2>/dev/null || echo "")
198
+
199
+ if [ -z "$DIFF_KEYS" ]; then
200
+ echo "Error: No comparison results found for task: $TASK_ID" >&2
201
+ return 1
202
+ fi
203
+
204
+ local TOTAL=0
205
+ local UPDATED=0
206
+
207
+ echo "$DIFF_KEYS" | while read -r KEY; do
208
+ [ -z "$KEY" ] && continue
209
+
210
+ RESULT=$(redis-cli get "$KEY" 2>/dev/null || echo '{}')
211
+ SCREENSHOT_KEY=$(echo "$KEY" | sed "s|screenshot:diff:${TASK_ID}:||")
212
+ CURRENT_FILE=$(echo "$RESULT" | jq -r '.current_path')
213
+ STATUS=$(echo "$RESULT" | jq -r '.status')
214
+
215
+ TOTAL=$((TOTAL + 1))
216
+
217
+ # Only update if comparison failed (visual change detected)
218
+ if [ "$STATUS" = "failed" ]; then
219
+ echo "[$TOTAL] Updating baseline: $SCREENSHOT_KEY" >&2
220
+
221
+ "$SCRIPT_DIR/set-baseline.sh" \
222
+ --screenshot-key "$SCREENSHOT_KEY" \
223
+ --current-file "$CURRENT_FILE" \
224
+ --reason "$REASON (approved by $APPROVED_BY)" >/dev/null 2>&1 && UPDATED=$((UPDATED + 1))
225
+ else
226
+ echo "[$TOTAL] Skipping (no change): $SCREENSHOT_KEY" >&2
227
+ fi
228
+ done
229
+
230
+ echo "✅ Updated $UPDATED baselines" >&2
231
+ }
232
+
233
+ # Export functions for use in other scripts
234
+ export -f capture_component_screenshots
235
+ export -f compare_all_screenshots
236
+ export -f calculate_validation_consensus
237
+ export -f update_all_baselines
238
+
239
+ # If script is run directly, show usage
240
+ if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
241
+ cat <<EOF
242
+ CFN Loop Integration Helper Functions
243
+
244
+ Usage: source $0
245
+
246
+ Available Functions:
247
+ capture_component_screenshots <project> <component> <url> <task-id> <agent-id> [viewports...]
248
+ compare_all_screenshots <task-id> [threshold]
249
+ calculate_validation_consensus <task-id>
250
+ update_all_baselines <task-id> <reason> <approved-by>
251
+
252
+ Example (Loop 3 - Implementation):
253
+ source ./.claude/skills/cfn-webapp-testing/cfn-loop-integration.sh
254
+ capture_component_screenshots "auth-system" "login-form" "http://localhost:3000/login" "\$TASK_ID" "\$AGENT_ID" "1920x1080" "375x667"
255
+
256
+ Example (Loop 2 - Validation):
257
+ compare_all_screenshots "\$TASK_ID" 0.95
258
+ CONSENSUS=\$(calculate_validation_consensus "\$TASK_ID")
259
+ echo "\$CONSENSUS" | jq -r '.confidence'
260
+
261
+ Example (Product Owner Decision):
262
+ update_all_baselines "\$TASK_ID" "Approved visual changes from PR #123" "product-owner-agent"
263
+
264
+ EOF
265
+ fi
@@ -0,0 +1,199 @@
1
+ #!/bin/bash
2
+ # Webapp Testing Skill - Screenshot Comparison
3
+ # Purpose: Compare captured screenshot to baseline using pixelmatch, store results in Redis
4
+
5
+ set -e
6
+
7
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
+ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.claude/skills/cfn-cfn-.claude/skills/cfn-cfn-.." && pwd)"
9
+ cd "$PROJECT_ROOT"
10
+
11
+ # Default configuration
12
+ THRESHOLD=0.95
13
+ IGNORE_REGIONS=""
14
+
15
+ # Parse arguments
16
+ while [[ $# -gt 0 ]]; do
17
+ case $1 in
18
+ --screenshot-key) SCREENSHOT_KEY="$2"; shift 2 ;;
19
+ --task-id) TASK_ID="$2"; shift 2 ;;
20
+ --threshold) THRESHOLD="$2"; shift 2 ;;
21
+ --ignore-regions) IGNORE_REGIONS="$2"; shift 2 ;;
22
+ *) echo "Unknown parameter: $1"; exit 1 ;;
23
+ esac
24
+ done
25
+
26
+ # Validate required parameters
27
+ if [ -z "$SCREENSHOT_KEY" ] || [ -z "$TASK_ID" ]; then
28
+ echo "Error: Missing required parameters" >&2
29
+ echo "Usage: $0 --screenshot-key <key> --task-id <task-id>" >&2
30
+ echo "" >&2
31
+ echo "Required:" >&2
32
+ echo " --screenshot-key Screenshot identifier (e.g., 'auth-system/login-form/1920x1080/default/light-mode')" >&2
33
+ echo " --task-id CFN task identifier" >&2
34
+ echo "" >&2
35
+ echo "Optional:" >&2
36
+ echo " --threshold Similarity threshold 0.0-1.0 (default: 0.95)" >&2
37
+ echo " --ignore-regions JSON array of regions to ignore (e.g., '[{\"x\":0,\"y\":0,\"width\":100,\"height\":50}]')" >&2
38
+ exit 1
39
+ fi
40
+
41
+ DB_PATH="${HOME}/.claude/memory/adaptive-context.db"
42
+
43
+ # Get baseline path from SQLite
44
+ BASELINE_PATH=$(sqlite3 "$DB_PATH" \
45
+ "SELECT file_path FROM webapp_screenshots WHERE screenshot_key = '${SCREENSHOT_KEY}' AND baseline = 1" 2>/dev/null)
46
+
47
+ if [ -z "$BASELINE_PATH" ]; then
48
+ # No baseline exists
49
+ echo '{"status": "no-baseline", "screenshot_key": "'"$SCREENSHOT_KEY"'", "message": "No baseline found for comparison. Use set-baseline.sh to create one."}' | jq '.'
50
+ exit 0
51
+ fi
52
+
53
+ # Get current screenshot path from SQLite (most recent non-baseline)
54
+ CURRENT_PATH=$(sqlite3 "$DB_PATH" \
55
+ "SELECT file_path FROM webapp_screenshots WHERE screenshot_key = '${SCREENSHOT_KEY}' AND baseline = 0 ORDER BY captured_at DESC LIMIT 1" 2>/dev/null)
56
+
57
+ if [ -z "$CURRENT_PATH" ]; then
58
+ echo "Error: No current screenshot found for key: $SCREENSHOT_KEY" >&2
59
+ echo "Hint: Run capture-screenshot.sh first to create a capture" >&2
60
+ exit 1
61
+ fi
62
+
63
+ # Verify files exist
64
+ if [ ! -f "$BASELINE_PATH" ]; then
65
+ echo "Error: Baseline file not found: $BASELINE_PATH" >&2
66
+ exit 1
67
+ fi
68
+
69
+ if [ ! -f "$CURRENT_PATH" ]; then
70
+ echo "Error: Current screenshot file not found: $CURRENT_PATH" >&2
71
+ exit 1
72
+ fi
73
+
74
+ # Generate diff path
75
+ DIFF_DIR=".screenshots/diffs/${TASK_ID}"
76
+ mkdir -p "$DIFF_DIR"
77
+ SCREENSHOT_KEY_FLAT=$(echo "$SCREENSHOT_KEY" | tr '/' '_')
78
+ DIFF_PATH="${DIFF_DIR}/${SCREENSHOT_KEY_FLAT}_diff.png"
79
+
80
+ echo "Comparing screenshots:" >&2
81
+ echo " Baseline: $BASELINE_PATH" >&2
82
+ echo " Current: $CURRENT_PATH" >&2
83
+ echo " Diff: $DIFF_PATH" >&2
84
+
85
+ # Compare using pixelmatch (Node.js)
86
+ COMPARISON=$(node -e "
87
+ const fs = require('fs');
88
+ const PNG = require('pngjs').PNG;
89
+ const pixelmatch = require('pixelmatch');
90
+
91
+ try {
92
+ const baseline = PNG.sync.read(fs.readFileSync('${BASELINE_PATH}'));
93
+ const current = PNG.sync.read(fs.readFileSync('${CURRENT_PATH}'));
94
+
95
+ // Validate dimensions match
96
+ if (baseline.width !== current.width || baseline.height !== current.height) {
97
+ console.error(JSON.stringify({
98
+ status: 'error',
99
+ message: 'Screenshot dimensions do not match',
100
+ baseline_dimensions: { width: baseline.width, height: baseline.height },
101
+ current_dimensions: { width: current.width, height: current.height }
102
+ }));
103
+ process.exit(1);
104
+ }
105
+
106
+ const { width, height } = baseline;
107
+ const diff = new PNG({ width, height });
108
+
109
+ // Configure pixelmatch options
110
+ const options = {
111
+ threshold: 0.1, // Sensitivity (0 = strict, 1 = lenient)
112
+ includeAA: true, // Include anti-aliasing
113
+ alpha: 0.1,
114
+ aaColor: [255, 255, 0],
115
+ diffColor: [255, 0, 0]
116
+ };
117
+
118
+ ${IGNORE_REGIONS:+
119
+ // Apply ignore regions (mask pixels)
120
+ const ignoreRegions = ${IGNORE_REGIONS};
121
+ ignoreRegions.forEach(region => {
122
+ for (let y = region.y; y < region.y + region.height && y < height; y++) {
123
+ for (let x = region.x; x < region.x + region.width && x < width; x++) {
124
+ const idx = (width * y + x) * 4;
125
+ baseline.data[idx] = current.data[idx];
126
+ baseline.data[idx + 1] = current.data[idx + 1];
127
+ baseline.data[idx + 2] = current.data[idx + 2];
128
+ }
129
+ }
130
+ });
131
+ }
132
+
133
+ const numDiffPixels = pixelmatch(
134
+ baseline.data, current.data, diff.data, width, height, options
135
+ );
136
+
137
+ fs.writeFileSync('${DIFF_PATH}', PNG.sync.write(diff));
138
+
139
+ const totalPixels = width * height;
140
+ const diffPercentage = (numDiffPixels / totalPixels) * 100;
141
+ const similarityScore = 1 - (numDiffPixels / totalPixels);
142
+ const status = similarityScore >= ${THRESHOLD} ? 'passed' : 'failed';
143
+
144
+ console.log(JSON.stringify({
145
+ screenshot_key: '${SCREENSHOT_KEY}',
146
+ similarity_score: parseFloat(similarityScore.toFixed(4)),
147
+ diff_pixels: numDiffPixels,
148
+ total_pixels: totalPixels,
149
+ diff_percentage: parseFloat(diffPercentage.toFixed(2)),
150
+ threshold: ${THRESHOLD},
151
+ status: status,
152
+ diff_path: '${DIFF_PATH}',
153
+ baseline_path: '${BASELINE_PATH}',
154
+ current_path: '${CURRENT_PATH}',
155
+ compared_at: Math.floor(Date.now() / 1000)
156
+ }));
157
+ } catch (error) {
158
+ console.error(JSON.stringify({
159
+ status: 'error',
160
+ message: error.message,
161
+ screenshot_key: '${SCREENSHOT_KEY}'
162
+ }));
163
+ process.exit(1);
164
+ }
165
+ " 2>&1)
166
+
167
+ # Check if comparison succeeded
168
+ if [ $? -ne 0 ]; then
169
+ echo "Error: Screenshot comparison failed" >&2
170
+ echo "$COMPARISON" >&2
171
+ exit 1
172
+ fi
173
+
174
+ # Extract JSON from output
175
+ COMPARISON_JSON=$(echo "$COMPARISON" | grep -E '^\{.*\}$' | tail -n 1)
176
+
177
+ if [ -z "$COMPARISON_JSON" ]; then
178
+ echo "Error: Failed to parse comparison result" >&2
179
+ echo "Output: $COMPARISON" >&2
180
+ exit 1
181
+ fi
182
+
183
+ # Store in Redis (TTL: 1 hour = 3600 seconds)
184
+ redis-cli setex "screenshot:diff:${TASK_ID}:${SCREENSHOT_KEY}" 3600 "$COMPARISON_JSON" > /dev/null 2>&1 || \
185
+ echo "Warning: Failed to store comparison result in Redis" >&2
186
+
187
+ # Output result (formatted JSON)
188
+ echo "$COMPARISON_JSON" | jq '.'
189
+
190
+ # Return appropriate exit code based on status
191
+ STATUS=$(echo "$COMPARISON_JSON" | jq -r '.status')
192
+ if [ "$STATUS" = "passed" ]; then
193
+ exit 0
194
+ elif [ "$STATUS" = "failed" ]; then
195
+ echo "Visual regression detected: $(echo "$COMPARISON_JSON" | jq -r '.diff_percentage')% difference" >&2
196
+ exit 2 # Non-zero but distinct from error
197
+ else
198
+ exit 1
199
+ fi