claude-flow-novice 2.15.5 → 2.15.7
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.
- package/.claude/cfn-extras/.gs-api-quota.json +16 -0
- package/.claude/cfn-extras/.gs-progress-state.json +22 -0
- package/.claude/cfn-extras/GOOGLE_SHEETS_IMPLEMENTATION_SUMMARY.md +414 -0
- package/.claude/cfn-extras/agents/google-sheets/README.md +114 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-advanced-analytics-specialist.md +288 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-api-integrator.md +127 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-automation-scripting-specialist.md +195 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-business-validator.md +179 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-collaboration-security-specialist.md +240 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-coordinator.md +214 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-data-transformer.md +127 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-data-validation-quality-specialist.md +177 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-data-validator.md +119 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-data-visualization-specialist.md +135 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-design-layout-specialist.md +109 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-formula-engineer.md +127 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-formula-engineering-specialist.md +138 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-formula-validator.md +128 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-generalist.md +645 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-integration-api-specialist.md +258 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-performance-analyst.md +125 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-performance-optimization-specialist.md +211 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-schema-designer.md +130 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-template-architecture-specialist.md +259 -0
- package/.claude/cfn-extras/docs/GOOGLE_SHEETS_CFN_LOOP.md +617 -0
- package/.claude/cfn-extras/skills/GOOGLE_SHEETS_SKILLS_README.md +453 -0
- package/.claude/cfn-extras/skills/google-sheets-api-coordinator/SKILL.md +272 -0
- package/.claude/cfn-extras/skills/google-sheets-api-coordinator/api-call.sh +254 -0
- package/.claude/cfn-extras/skills/google-sheets-api-coordinator/test.sh +174 -0
- package/.claude/cfn-extras/skills/google-sheets-api-coordinator/validate.sh +98 -0
- package/.claude/cfn-extras/skills/google-sheets-decomposition/SKILL.md +269 -0
- package/.claude/cfn-extras/skills/google-sheets-decomposition/decompose.sh +313 -0
- package/.claude/cfn-extras/skills/google-sheets-formula-builder/SKILL.md +237 -0
- package/.claude/cfn-extras/skills/google-sheets-formula-builder/build-formula.sh +220 -0
- package/.claude/cfn-extras/skills/google-sheets-formula-builder/test.sh +172 -0
- package/.claude/cfn-extras/skills/google-sheets-formula-builder/validate.sh +98 -0
- package/.claude/cfn-extras/skills/google-sheets-progress/SKILL.md +287 -0
- package/.claude/cfn-extras/skills/google-sheets-progress/test.sh +385 -0
- package/.claude/cfn-extras/skills/google-sheets-progress/track-progress.sh +516 -0
- package/.claude/cfn-extras/skills/google-sheets-progress/validate.sh +119 -0
- package/.claude/cfn-extras/skills/google-sheets-sprint-order/SKILL.md +277 -0
- package/.claude/cfn-extras/skills/google-sheets-sprint-order/order-sprints.sh +233 -0
- package/.claude/cfn-extras/skills/google-sheets-validation/SKILL.md +352 -0
- package/.claude/cfn-extras/skills/google-sheets-validation/test.sh +355 -0
- package/.claude/cfn-extras/skills/google-sheets-validation/validate-state.sh +374 -0
- package/.claude/cfn-extras/skills/google-sheets-validation/validate.sh +128 -0
- package/.claude/commands/cfn-context.md +10 -0
- package/.claude/commands/cfn-loop-cli.md +36 -15
- package/.claude/commands/google-sheets/google-sheets-loop.md +289 -0
- package/.claude/skills/cfn-agent-selector/SKILL.md +143 -0
- package/.claude/skills/cfn-agent-selector/select-agents.sh +94 -0
- package/.claude/skills/cfn-agent-spawning/get-agent-provider-env.sh +22 -2
- package/.claude/skills/cfn-docker-agent-spawning/spawn-agent.sh +21 -2
- package/.claude/skills/cfn-docker-loop-orchestration/orchestrate.sh +11 -5
- package/.claude/skills/cfn-docker-redis-coordination/MIGRATION_SUMMARY.md +348 -0
- package/.claude/skills/cfn-docker-redis-coordination/README.md +294 -0
- package/.claude/skills/cfn-docker-redis-coordination/jest.config.js +37 -0
- package/.claude/skills/cfn-docker-redis-coordination/package-lock.json +5259 -0
- package/.claude/skills/cfn-docker-redis-coordination/package.json +40 -0
- package/.claude/skills/cfn-docker-redis-coordination/src/coordinator.ts +801 -0
- package/.claude/skills/cfn-docker-redis-coordination/src/index.ts +42 -0
- package/.claude/skills/cfn-docker-redis-coordination/src/types.ts +351 -0
- package/.claude/skills/cfn-docker-redis-coordination/tests/coordinator.test.ts +1464 -0
- package/.claude/skills/cfn-docker-redis-coordination/tsconfig.json +30 -0
- package/.claude/skills/cfn-loop-orchestration/.eslintrc.js +56 -0
- package/.claude/skills/cfn-loop-orchestration/.prettierrc.json +18 -0
- package/.claude/skills/cfn-loop-orchestration/README.md +149 -41
- package/.claude/skills/cfn-loop-orchestration/helpers/gate-check.sh +39 -577
- package/.claude/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +49 -270
- package/.claude/skills/cfn-loop-orchestration/jest.config.js +67 -0
- package/.claude/skills/cfn-loop-orchestration/orchestrate-wrapper.sh +268 -0
- package/.claude/skills/cfn-loop-orchestration/orchestrate.sh +91 -8
- package/.claude/skills/cfn-loop-orchestration/package-lock.json +5470 -0
- package/.claude/skills/cfn-loop-orchestration/package.json +49 -0
- package/.claude/skills/cfn-loop-orchestration/src/agent-spawner/agent-spawner.ts +34 -0
- package/.claude/skills/cfn-loop-orchestration/src/gate-checker/gate-checker.ts +36 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/consensus.ts +87 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/gate-check.ts +115 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/parse-test-results.ts +372 -0
- package/.claude/skills/cfn-loop-orchestration/src/index.ts +14 -0
- package/.claude/skills/cfn-loop-orchestration/src/orchestrator/orchestrator.ts +31 -0
- package/.claude/skills/cfn-loop-orchestration/src/redis/redis-coordinator.ts +72 -0
- package/.claude/skills/cfn-loop-orchestration/src/types.ts +188 -0
- package/.claude/skills/cfn-loop-orchestration/src/utils/logger.ts +32 -0
- package/.claude/skills/cfn-loop-orchestration/tests/consensus.test.ts +142 -0
- package/.claude/skills/cfn-loop-orchestration/tests/deliverable-verifier.test.ts +199 -0
- package/.claude/skills/cfn-loop-orchestration/tests/gate-check.test.ts +325 -0
- package/.claude/skills/cfn-loop-orchestration/tests/iteration-manager.test.ts +132 -0
- package/.claude/skills/cfn-loop-orchestration/tests/parse-test-results.test.ts +382 -0
- package/.claude/skills/cfn-loop-orchestration/tests/setup.ts +22 -0
- package/.claude/skills/cfn-loop-orchestration/tests/timeout-calculator.test.ts +118 -0
- package/.claude/skills/cfn-loop-orchestration/tests/types.test.ts +132 -0
- package/.claude/skills/cfn-loop-orchestration/tsconfig.json +54 -0
- package/.claude/skills/cfn-redis-coordination/bash-wrappers/store-context.sh +23 -0
- package/.claude/skills/cfn-redis-coordination/coverage/clover.xml +1447 -0
- package/.claude/skills/cfn-redis-coordination/coverage/coverage-final.json +13 -0
- package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/agent-logger.ts.html +1423 -0
- package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/agent-recovery.ts.html +1447 -0
- package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/base.css +224 -0
- package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/block-navigation.js +87 -0
- package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/completion-reporter.ts.html +1273 -0
- package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/context-manager.ts.html +1066 -0
- package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/favicon.png +0 -0
- package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/index.html +281 -0
- package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/mode-detector.ts.html +550 -0
- package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/prettify.css +1 -0
- package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/prettify.js +2 -0
- package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/redis-client.ts.html +2047 -0
- package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/result-collector.ts.html +1396 -0
- package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/sorter.js +210 -0
- package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/swarm-manager.ts.html +1567 -0
- package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/task-analyzer.ts.html +1297 -0
- package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/task-executor.ts.html +1354 -0
- package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/types.ts.html +790 -0
- package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/waiting-coordinator.ts.html +1846 -0
- package/.claude/skills/cfn-redis-coordination/coverage/lcov.info +2650 -0
- package/.claude/skills/cfn-redis-coordination/dist/agent-logger.d.ts +92 -0
- package/.claude/skills/cfn-redis-coordination/dist/agent-logger.d.ts.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/agent-logger.js +329 -0
- package/.claude/skills/cfn-redis-coordination/dist/agent-logger.js.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/agent-recovery.d.ts +75 -0
- package/.claude/skills/cfn-redis-coordination/dist/agent-recovery.d.ts.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/agent-recovery.js +302 -0
- package/.claude/skills/cfn-redis-coordination/dist/agent-recovery.js.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/completion-reporter.d.ts +58 -0
- package/.claude/skills/cfn-redis-coordination/dist/completion-reporter.d.ts.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/completion-reporter.js +237 -0
- package/.claude/skills/cfn-redis-coordination/dist/completion-reporter.js.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/context-manager.d.ts +63 -0
- package/.claude/skills/cfn-redis-coordination/dist/context-manager.d.ts.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/context-manager.js +230 -0
- package/.claude/skills/cfn-redis-coordination/dist/context-manager.js.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/index.d.ts +45 -0
- package/.claude/skills/cfn-redis-coordination/dist/index.d.ts.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/index.js +114 -0
- package/.claude/skills/cfn-redis-coordination/dist/index.js.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/mode-detector.d.ts +31 -0
- package/.claude/skills/cfn-redis-coordination/dist/mode-detector.d.ts.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/mode-detector.js +185 -0
- package/.claude/skills/cfn-redis-coordination/dist/mode-detector.js.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/redis-client.d.ts +191 -0
- package/.claude/skills/cfn-redis-coordination/dist/redis-client.d.ts.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/redis-client.js +509 -0
- package/.claude/skills/cfn-redis-coordination/dist/redis-client.js.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/result-collector.d.ts +75 -0
- package/.claude/skills/cfn-redis-coordination/dist/result-collector.d.ts.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/result-collector.js +281 -0
- package/.claude/skills/cfn-redis-coordination/dist/result-collector.js.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/swarm-manager.d.ts +75 -0
- package/.claude/skills/cfn-redis-coordination/dist/swarm-manager.d.ts.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/swarm-manager.js +354 -0
- package/.claude/skills/cfn-redis-coordination/dist/swarm-manager.js.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/task-analyzer.d.ts +62 -0
- package/.claude/skills/cfn-redis-coordination/dist/task-analyzer.d.ts.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/task-analyzer.js +305 -0
- package/.claude/skills/cfn-redis-coordination/dist/task-analyzer.js.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/task-executor.d.ts +97 -0
- package/.claude/skills/cfn-redis-coordination/dist/task-executor.d.ts.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/task-executor.js +283 -0
- package/.claude/skills/cfn-redis-coordination/dist/task-executor.js.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/types.d.ts +176 -0
- package/.claude/skills/cfn-redis-coordination/dist/types.d.ts.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/types.js +81 -0
- package/.claude/skills/cfn-redis-coordination/dist/types.js.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/waiting-coordinator.d.ts +86 -0
- package/.claude/skills/cfn-redis-coordination/dist/waiting-coordinator.d.ts.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/waiting-coordinator.js +419 -0
- package/.claude/skills/cfn-redis-coordination/dist/waiting-coordinator.js.map +1 -0
- package/.claude/skills/cfn-redis-coordination/docs/migration/PHASE_3_REDIS_COORDINATION_COMPLETION_REPORT.md +553 -0
- package/.claude/skills/cfn-redis-coordination/jest.config.js +23 -0
- package/.claude/skills/cfn-redis-coordination/package-lock.json +5272 -0
- package/.claude/skills/cfn-redis-coordination/package.json +45 -0
- package/.claude/skills/cfn-redis-coordination/redis-cli-wrapper.sh +21 -8
- package/.claude/skills/cfn-redis-coordination/src/agent-logger.ts +446 -0
- package/.claude/skills/cfn-redis-coordination/src/agent-recovery.ts +454 -0
- package/.claude/skills/cfn-redis-coordination/src/completion-reporter.ts +396 -0
- package/.claude/skills/cfn-redis-coordination/src/context-manager.ts +327 -0
- package/.claude/skills/cfn-redis-coordination/src/index.ts +82 -0
- package/.claude/skills/cfn-redis-coordination/src/mode-detector.ts +155 -0
- package/.claude/skills/cfn-redis-coordination/src/redis/redis-client.ts +305 -0
- package/.claude/skills/cfn-redis-coordination/src/redis/redis-functions.ts +283 -0
- package/.claude/skills/cfn-redis-coordination/src/redis-client.ts +654 -0
- package/.claude/skills/cfn-redis-coordination/src/result-collector.ts +437 -0
- package/.claude/skills/cfn-redis-coordination/src/swarm-manager.ts +494 -0
- package/.claude/skills/cfn-redis-coordination/src/task-analyzer.ts +404 -0
- package/.claude/skills/cfn-redis-coordination/src/task-executor.ts +423 -0
- package/.claude/skills/cfn-redis-coordination/src/types.ts +235 -0
- package/.claude/skills/cfn-redis-coordination/src/waiting-coordinator.ts +587 -0
- package/.claude/skills/cfn-redis-coordination/test-connection-attempts.js +70 -0
- package/.claude/skills/cfn-redis-coordination/test-mode-simple.js +121 -0
- package/.claude/skills/cfn-redis-coordination/test-redis-check.js +84 -0
- package/.claude/skills/cfn-redis-coordination/test-task-mode-redis.cjs +391 -0
- package/.claude/skills/cfn-redis-coordination/tests/coordination.test.ts +788 -0
- package/.claude/skills/cfn-redis-coordination/tsconfig.json +31 -0
- package/claude-assets/agents/cfn-dev-team/coordinators/cfn-frontend-coordinator.md +13 -72
- package/claude-assets/agents/cfn-dev-team/coordinators/cfn-v3-coordinator.md +172 -62
- package/claude-assets/agents/cfn-dev-team/coordinators/consensus-builder.md +465 -508
- package/claude-assets/agents/cfn-dev-team/coordinators/handoff-coordinator.md +733 -743
- package/claude-assets/agents/cfn-dev-team/coordinators/multi-sprint-coordinator.md +13 -79
- package/claude-assets/agents/cfn-dev-team/dev-ops/docker-specialist.md +13 -18
- package/claude-assets/agents/cfn-dev-team/dev-ops/kubernetes-specialist.md +13 -18
- package/claude-assets/agents/cfn-dev-team/developers/api-gateway-specialist.md +13 -18
- package/claude-assets/agents/cfn-dev-team/developers/backend-developer.md +15 -17
- package/claude-assets/agents/cfn-dev-team/developers/data/data-engineer.md +15 -17
- package/claude-assets/agents/cfn-dev-team/developers/database/database-architect.md +15 -14
- package/claude-assets/agents/cfn-dev-team/developers/frontend/mobile-dev.md +15 -17
- package/claude-assets/agents/cfn-dev-team/developers/frontend/react-frontend-engineer.md +15 -17
- package/claude-assets/agents/cfn-dev-team/developers/frontend/typescript-specialist.md +15 -17
- package/claude-assets/agents/cfn-dev-team/developers/frontend/ui-designer.md +23 -30
- package/claude-assets/agents/cfn-dev-team/developers/graphql-specialist.md +13 -18
- package/claude-assets/agents/cfn-dev-team/developers/rust-developer.md +13 -18
- package/claude-assets/agents/cfn-dev-team/reviewers/code-reviewer.md +312 -317
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/code-quality-validator.md +23 -20
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/perf-analyzer.md +23 -20
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/performance-benchmarker.md +23 -20
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/security-specialist.md +23 -20
- package/claude-assets/agents/cfn-dev-team/testers/api-testing-specialist.md +16 -21
- package/claude-assets/agents/cfn-dev-team/testers/chaos-engineering-specialist.md +15 -20
- package/claude-assets/agents/cfn-dev-team/testers/contract-tester.md +718 -737
- package/claude-assets/agents/cfn-dev-team/testers/integration-tester.md +817 -828
- package/claude-assets/agents/cfn-dev-team/testers/interaction-tester.md +15 -20
- package/claude-assets/agents/cfn-dev-team/testers/load-testing-specialist.md +8 -9
- package/claude-assets/agents/cfn-dev-team/testers/mutation-testing-specialist.md +668 -684
- package/claude-assets/agents/cfn-dev-team/testers/playwright-tester.md +15 -20
- package/claude-assets/agents/cfn-dev-team/testers/tester.md +248 -253
- package/claude-assets/agents/cfn-dev-team/utility/epic-creator.md +13 -18
- package/claude-assets/agents/cfn-dev-team/utility/memory-leak-specialist.md +13 -18
- package/claude-assets/agents/cfn-dev-team/utility/z-ai-specialist.md +13 -18
- package/claude-assets/agents/custom/cfn-redis-operations.md +530 -0
- package/claude-assets/agents/custom/cfn-system-expert.md +77 -0
- package/claude-assets/cfn-extras/.gs-api-quota.json +16 -0
- package/claude-assets/cfn-extras/.gs-progress-state.json +22 -0
- package/claude-assets/cfn-extras/GOOGLE_SHEETS_IMPLEMENTATION_SUMMARY.md +414 -0
- package/claude-assets/cfn-extras/agents/google-sheets/README.md +114 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-advanced-analytics-specialist.md +288 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-api-integrator.md +127 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-automation-scripting-specialist.md +195 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-business-validator.md +179 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-collaboration-security-specialist.md +240 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-coordinator.md +214 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-data-transformer.md +127 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-data-validation-quality-specialist.md +177 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-data-validator.md +119 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-data-visualization-specialist.md +135 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-design-layout-specialist.md +109 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-formula-engineer.md +127 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-formula-engineering-specialist.md +138 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-formula-validator.md +128 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-generalist.md +645 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-integration-api-specialist.md +258 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-performance-analyst.md +125 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-performance-optimization-specialist.md +211 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-schema-designer.md +130 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-template-architecture-specialist.md +259 -0
- package/claude-assets/cfn-extras/docs/GOOGLE_SHEETS_CFN_LOOP.md +617 -0
- package/claude-assets/cfn-extras/skills/GOOGLE_SHEETS_SKILLS_README.md +453 -0
- package/claude-assets/cfn-extras/skills/google-sheets-api-coordinator/SKILL.md +272 -0
- package/claude-assets/cfn-extras/skills/google-sheets-api-coordinator/api-call.sh +254 -0
- package/claude-assets/cfn-extras/skills/google-sheets-api-coordinator/test.sh +174 -0
- package/claude-assets/cfn-extras/skills/google-sheets-api-coordinator/validate.sh +98 -0
- package/claude-assets/cfn-extras/skills/google-sheets-decomposition/SKILL.md +269 -0
- package/claude-assets/cfn-extras/skills/google-sheets-decomposition/decompose.sh +313 -0
- package/claude-assets/cfn-extras/skills/google-sheets-formula-builder/SKILL.md +237 -0
- package/claude-assets/cfn-extras/skills/google-sheets-formula-builder/build-formula.sh +220 -0
- package/claude-assets/cfn-extras/skills/google-sheets-formula-builder/test.sh +172 -0
- package/claude-assets/cfn-extras/skills/google-sheets-formula-builder/validate.sh +98 -0
- package/claude-assets/cfn-extras/skills/google-sheets-progress/SKILL.md +287 -0
- package/claude-assets/cfn-extras/skills/google-sheets-progress/test.sh +385 -0
- package/claude-assets/cfn-extras/skills/google-sheets-progress/track-progress.sh +516 -0
- package/claude-assets/cfn-extras/skills/google-sheets-progress/validate.sh +119 -0
- package/claude-assets/cfn-extras/skills/google-sheets-sprint-order/SKILL.md +277 -0
- package/claude-assets/cfn-extras/skills/google-sheets-sprint-order/order-sprints.sh +233 -0
- package/claude-assets/cfn-extras/skills/google-sheets-validation/SKILL.md +352 -0
- package/claude-assets/cfn-extras/skills/google-sheets-validation/test.sh +355 -0
- package/claude-assets/cfn-extras/skills/google-sheets-validation/validate-state.sh +374 -0
- package/claude-assets/cfn-extras/skills/google-sheets-validation/validate.sh +128 -0
- package/claude-assets/commands/cfn-context.md +10 -0
- package/claude-assets/commands/cfn-loop-cli.md +36 -15
- package/claude-assets/commands/google-sheets/google-sheets-loop.md +289 -0
- package/claude-assets/hooks/cfn-pre-execution/SESSION_START_README.md +87 -0
- package/claude-assets/hooks/cfn-pre-execution/TEST_SESSION_START.md +128 -0
- package/claude-assets/hooks/cfn-pre-execution/session-start-context.sh +111 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/INTEGRATION_EXAMPLE.md +209 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/README.md +130 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/SKILL.md +243 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/agent-mappings.json +142 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/select-agents.sh +173 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/task-classifier.sh +71 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/test-agent-selection.sh +282 -0
- package/claude-assets/skills/cfn-agent-selector/SKILL.md +143 -0
- package/claude-assets/skills/cfn-agent-selector/select-agents.sh +94 -0
- package/claude-assets/skills/cfn-agent-spawning/get-agent-provider-env.sh +22 -2
- package/claude-assets/skills/cfn-docker-agent-spawning/spawn-agent.sh +21 -2
- package/claude-assets/skills/cfn-docker-coordination/.eslintrc.json +33 -0
- package/claude-assets/skills/cfn-docker-coordination/README.md +349 -0
- package/claude-assets/skills/cfn-docker-coordination/docker-helpers.sh +433 -0
- package/claude-assets/skills/cfn-docker-coordination/jest.config.js +25 -0
- package/claude-assets/skills/cfn-docker-coordination/package-lock.json +6827 -0
- package/claude-assets/skills/cfn-docker-coordination/package.json +38 -0
- package/claude-assets/skills/cfn-docker-coordination/src/agent-container.ts +471 -0
- package/claude-assets/skills/cfn-docker-coordination/src/docker-client.ts +483 -0
- package/claude-assets/skills/cfn-docker-coordination/src/health-checker.ts +418 -0
- package/claude-assets/skills/cfn-docker-coordination/src/index.ts +45 -0
- package/claude-assets/skills/cfn-docker-coordination/src/network-manager.ts +377 -0
- package/claude-assets/skills/cfn-docker-coordination/src/types.ts +412 -0
- package/claude-assets/skills/cfn-docker-coordination/src/volume-manager.ts +389 -0
- package/claude-assets/skills/cfn-docker-coordination/tests/agent-container.test.ts +379 -0
- package/claude-assets/skills/cfn-docker-coordination/tests/docker-client.test.ts +345 -0
- package/claude-assets/skills/cfn-docker-coordination/tests/health-checker.test.ts +535 -0
- package/claude-assets/skills/cfn-docker-coordination/tests/integration.test.ts +193 -0
- package/claude-assets/skills/cfn-docker-coordination/tests/network-manager.test.ts +352 -0
- package/claude-assets/skills/cfn-docker-coordination/tests/setup.ts +36 -0
- package/claude-assets/skills/cfn-docker-coordination/tsconfig.json +29 -0
- package/claude-assets/skills/cfn-docker-logging/INTEGRATION.md +268 -0
- package/claude-assets/skills/cfn-docker-logging/SAMPLE_OUTPUTS.md +237 -0
- package/claude-assets/skills/cfn-docker-logging/SKILL.md +442 -0
- package/claude-assets/skills/cfn-docker-logging/capture-container-logs.sh +120 -0
- package/claude-assets/skills/cfn-docker-logging/enable-logging.sh +430 -0
- package/claude-assets/skills/cfn-docker-logging/init-hybrid-logging.sh +210 -0
- package/claude-assets/skills/cfn-docker-logging/queries/analytics-summary.sh +87 -0
- package/claude-assets/skills/cfn-docker-logging/queries/query-agent-timeline.sh +51 -0
- package/claude-assets/skills/cfn-docker-logging/queries/query-consensus-history.sh +56 -0
- package/claude-assets/skills/cfn-docker-logging/queries/query-coordination-timeline.sh +39 -0
- package/claude-assets/skills/cfn-docker-logging/queries/query-failed-containers.sh +40 -0
- package/claude-assets/skills/cfn-docker-logging/queries/query-gate-checks.sh +39 -0
- package/claude-assets/skills/cfn-docker-logging/schema.sql +111 -0
- package/claude-assets/skills/cfn-docker-logging/sqlite-helpers.sh +240 -0
- package/claude-assets/skills/cfn-docker-logging/test-hybrid-logging.sh +331 -0
- package/claude-assets/skills/cfn-docker-loop-orchestration/orchestrate.sh +11 -5
- package/claude-assets/skills/cfn-docker-redis-coordination/MIGRATION_SUMMARY.md +348 -0
- package/claude-assets/skills/cfn-docker-redis-coordination/README.md +294 -0
- package/claude-assets/skills/cfn-docker-redis-coordination/jest.config.js +37 -0
- package/claude-assets/skills/cfn-docker-redis-coordination/package-lock.json +5259 -0
- package/claude-assets/skills/cfn-docker-redis-coordination/package.json +40 -0
- package/claude-assets/skills/cfn-docker-redis-coordination/src/coordinator.ts +801 -0
- package/claude-assets/skills/cfn-docker-redis-coordination/src/index.ts +42 -0
- package/claude-assets/skills/cfn-docker-redis-coordination/src/types.ts +351 -0
- package/claude-assets/skills/cfn-docker-redis-coordination/tests/coordinator.test.ts +1464 -0
- package/claude-assets/skills/cfn-docker-redis-coordination/tsconfig.json +30 -0
- package/claude-assets/skills/cfn-error-logging/.eslintrc.json +57 -0
- package/claude-assets/skills/cfn-error-logging/.prettierrc.json +10 -0
- package/claude-assets/skills/cfn-error-logging/MIGRATION_SUMMARY.md +485 -0
- package/claude-assets/skills/cfn-error-logging/package.json +47 -0
- package/claude-assets/skills/cfn-error-logging/src/error-logger.ts +1042 -0
- package/claude-assets/skills/cfn-error-logging/src/index.ts +12 -0
- package/claude-assets/skills/cfn-error-logging/src/types.ts +456 -0
- package/claude-assets/skills/cfn-error-logging/tests/error-logger.test.ts +1302 -0
- package/claude-assets/skills/cfn-error-logging/tsconfig.json +38 -0
- package/claude-assets/skills/cfn-loop-orchestration/.eslintrc.js +56 -0
- package/claude-assets/skills/cfn-loop-orchestration/.prettierrc.json +18 -0
- package/claude-assets/skills/cfn-loop-orchestration/README.md +149 -41
- package/claude-assets/skills/cfn-loop-orchestration/helpers/gate-check.sh +39 -577
- package/claude-assets/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +49 -270
- package/claude-assets/skills/cfn-loop-orchestration/jest.config.js +67 -0
- package/claude-assets/skills/cfn-loop-orchestration/orchestrate-wrapper.sh +268 -0
- package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh +91 -8
- package/claude-assets/skills/cfn-loop-orchestration/package-lock.json +5470 -0
- package/claude-assets/skills/cfn-loop-orchestration/package.json +49 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/agent-spawner/agent-spawner.ts +34 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/gate-checker/gate-checker.ts +36 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/gate-check.ts +115 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/parse-test-results.ts +372 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/index.ts +14 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/orchestrator/orchestrator.ts +31 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/redis/redis-coordinator.ts +72 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/types.ts +188 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/utils/logger.ts +32 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/consensus.test.ts +142 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/deliverable-verifier.test.ts +199 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/gate-check.test.ts +325 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/iteration-manager.test.ts +132 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/parse-test-results.test.ts +382 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/setup.ts +22 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/timeout-calculator.test.ts +118 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/types.test.ts +132 -0
- package/claude-assets/skills/cfn-loop-orchestration/tsconfig.json +54 -0
- package/claude-assets/skills/cfn-redis-coordination/bash-wrappers/store-context.sh +23 -0
- package/claude-assets/skills/cfn-redis-coordination/coverage/clover.xml +1447 -0
- package/claude-assets/skills/cfn-redis-coordination/coverage/coverage-final.json +13 -0
- package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/agent-logger.ts.html +1423 -0
- package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/agent-recovery.ts.html +1447 -0
- package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/base.css +224 -0
- package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/block-navigation.js +87 -0
- package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/completion-reporter.ts.html +1273 -0
- package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/context-manager.ts.html +1066 -0
- package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/favicon.png +0 -0
- package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/index.html +281 -0
- package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/mode-detector.ts.html +550 -0
- package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/prettify.css +1 -0
- package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/prettify.js +2 -0
- package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/redis-client.ts.html +2047 -0
- package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/result-collector.ts.html +1396 -0
- package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/sorter.js +210 -0
- package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/swarm-manager.ts.html +1567 -0
- package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/task-analyzer.ts.html +1297 -0
- package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/task-executor.ts.html +1354 -0
- package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/types.ts.html +790 -0
- package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/waiting-coordinator.ts.html +1846 -0
- package/claude-assets/skills/cfn-redis-coordination/coverage/lcov.info +2650 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/agent-logger.d.ts +92 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/agent-logger.d.ts.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/agent-logger.js +329 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/agent-logger.js.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/agent-recovery.d.ts +75 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/agent-recovery.d.ts.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/agent-recovery.js +302 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/agent-recovery.js.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/completion-reporter.d.ts +58 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/completion-reporter.d.ts.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/completion-reporter.js +237 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/completion-reporter.js.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/context-manager.d.ts +63 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/context-manager.d.ts.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/context-manager.js +230 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/context-manager.js.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/index.d.ts +45 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/index.d.ts.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/index.js +114 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/index.js.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/mode-detector.d.ts +31 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/mode-detector.d.ts.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/mode-detector.js +185 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/mode-detector.js.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/redis-client.d.ts +191 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/redis-client.d.ts.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/redis-client.js +509 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/redis-client.js.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/result-collector.d.ts +75 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/result-collector.d.ts.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/result-collector.js +281 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/result-collector.js.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/swarm-manager.d.ts +75 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/swarm-manager.d.ts.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/swarm-manager.js +354 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/swarm-manager.js.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/task-analyzer.d.ts +62 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/task-analyzer.d.ts.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/task-analyzer.js +305 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/task-analyzer.js.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/task-executor.d.ts +97 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/task-executor.d.ts.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/task-executor.js +283 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/task-executor.js.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/types.d.ts +176 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/types.d.ts.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/types.js +81 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/types.js.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/waiting-coordinator.d.ts +86 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/waiting-coordinator.d.ts.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/waiting-coordinator.js +419 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/waiting-coordinator.js.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/docs/migration/PHASE_3_REDIS_COORDINATION_COMPLETION_REPORT.md +553 -0
- package/claude-assets/skills/cfn-redis-coordination/jest.config.js +23 -0
- package/claude-assets/skills/cfn-redis-coordination/package-lock.json +5272 -0
- package/claude-assets/skills/cfn-redis-coordination/package.json +45 -0
- package/claude-assets/skills/cfn-redis-coordination/redis-cli-wrapper.sh +21 -8
- package/claude-assets/skills/cfn-redis-coordination/src/agent-logger.ts +446 -0
- package/claude-assets/skills/cfn-redis-coordination/src/agent-recovery.ts +454 -0
- package/claude-assets/skills/cfn-redis-coordination/src/completion-reporter.ts +396 -0
- package/claude-assets/skills/cfn-redis-coordination/src/context-manager.ts +327 -0
- package/claude-assets/skills/cfn-redis-coordination/src/index.ts +82 -0
- package/claude-assets/skills/cfn-redis-coordination/src/mode-detector.ts +155 -0
- package/claude-assets/skills/cfn-redis-coordination/src/redis/redis-client.ts +305 -0
- package/claude-assets/skills/cfn-redis-coordination/src/redis/redis-functions.ts +283 -0
- package/claude-assets/skills/cfn-redis-coordination/src/redis-client.ts +654 -0
- package/claude-assets/skills/cfn-redis-coordination/src/result-collector.ts +437 -0
- package/claude-assets/skills/cfn-redis-coordination/src/swarm-manager.ts +494 -0
- package/claude-assets/skills/cfn-redis-coordination/src/task-analyzer.ts +404 -0
- package/claude-assets/skills/cfn-redis-coordination/src/task-executor.ts +423 -0
- package/claude-assets/skills/cfn-redis-coordination/src/types.ts +235 -0
- package/claude-assets/skills/cfn-redis-coordination/src/waiting-coordinator.ts +587 -0
- package/claude-assets/skills/cfn-redis-coordination/test-connection-attempts.js +70 -0
- package/claude-assets/skills/cfn-redis-coordination/test-mode-simple.js +121 -0
- package/claude-assets/skills/cfn-redis-coordination/test-redis-check.js +84 -0
- package/claude-assets/skills/cfn-redis-coordination/test-task-mode-redis.cjs +391 -0
- package/claude-assets/skills/cfn-redis-coordination/tests/coordination.test.ts +788 -0
- package/claude-assets/skills/cfn-redis-coordination/tsconfig.json +31 -0
- package/claude-assets/skills/cfn-skill-propagation/README.md +233 -0
- package/claude-assets/skills/cfn-skill-propagation/package-lock.json +5174 -0
- package/claude-assets/skills/cfn-skill-propagation/package.json +52 -0
- package/claude-assets/skills/cfn-skill-propagation/propagate-skill-update.sh +32 -0
- package/claude-assets/skills/cfn-skill-propagation/src/cli.ts +75 -0
- package/claude-assets/skills/cfn-skill-propagation/src/database-adapter.ts +239 -0
- package/claude-assets/skills/cfn-skill-propagation/src/file-system-adapter.ts +113 -0
- package/claude-assets/skills/cfn-skill-propagation/src/index.ts +72 -0
- package/claude-assets/skills/cfn-skill-propagation/src/logger.ts +43 -0
- package/claude-assets/skills/cfn-skill-propagation/src/metadata-parser.ts +154 -0
- package/claude-assets/skills/cfn-skill-propagation/src/skill-propagator.ts +274 -0
- package/claude-assets/skills/cfn-skill-propagation/src/skill-validator.ts +179 -0
- package/claude-assets/skills/cfn-skill-propagation/src/types.ts +143 -0
- package/claude-assets/skills/cfn-skill-propagation/src/version-manager.ts +118 -0
- package/claude-assets/skills/cfn-skill-propagation/tests/file-system-adapter.test.ts +91 -0
- package/claude-assets/skills/cfn-skill-propagation/tests/metadata-parser.test.ts +176 -0
- package/claude-assets/skills/cfn-skill-propagation/tests/skill-propagator.test.ts +209 -0
- package/claude-assets/skills/cfn-skill-propagation/tests/skill-validator.test.ts +203 -0
- package/claude-assets/skills/cfn-skill-propagation/tests/version-manager.test.ts +115 -0
- package/claude-assets/skills/cfn-skill-propagation/tsconfig.json +34 -0
- package/claude-assets/skills/task-classifier/SKILL.md +81 -0
- package/claude-assets/skills/task-classifier/classify-task.sh +62 -0
- package/claude-assets/skills/workflow-codification/package-lock.json +5170 -0
- package/claude-assets/skills/workflow-codification/package.json +30 -0
- package/claude-assets/skills/workflow-codification/src/index.ts +24 -0
- package/claude-assets/skills/workflow-codification/src/pattern-analyzer.ts +537 -0
- package/claude-assets/skills/workflow-codification/src/types.ts +180 -0
- package/claude-assets/skills/workflow-codification/tests/pattern-analyzer.test.ts +960 -0
- package/claude-assets/skills/workflow-codification/tsconfig.json +34 -0
- package/claude-assets/skills/workflow-codification/workflow-codification.db +0 -0
- package/dist/agent-spawner/agent-spawner.js +448 -0
- package/dist/agent-spawner/agent-spawner.js.map +1 -0
- package/dist/agent-spawner/index.js +10 -0
- package/dist/agent-spawner/index.js.map +1 -0
- package/dist/agent-spawner/types.js +14 -0
- package/dist/agent-spawner/types.js.map +1 -0
- package/dist/cli/agent-executor.js +47 -1
- package/dist/cli/agent-executor.js.map +1 -1
- package/dist/cli/agent-spawn.js +4 -1
- package/dist/cli/agent-spawn.js.map +1 -1
- package/dist/cli/config-manager.js +91 -109
- package/dist/cli/config-manager.js.map +1 -1
- package/dist/cli/tool-executor.js +3 -1
- package/dist/cli/tool-executor.js.map +1 -1
- package/dist/gate-checker/gate-checker.js +292 -0
- package/dist/gate-checker/gate-checker.js.map +1 -0
- package/dist/gate-checker/types.js +94 -0
- package/dist/gate-checker/types.js.map +1 -0
- package/dist/lib/database-service/connection-pool-manager.js +2 -1
- package/dist/lib/database-service/connection-pool-manager.js.map +1 -1
- package/dist/orchestrator/index.js +10 -0
- package/dist/orchestrator/index.js.map +1 -0
- package/dist/orchestrator/orchestrate.js +496 -0
- package/dist/orchestrator/orchestrate.js.map +1 -0
- package/dist/orchestrator/types.js +58 -0
- package/dist/orchestrator/types.js.map +1 -0
- package/package.json +1 -1
- package/scripts/clean-agent-profiles.sh +112 -0
- package/scripts/switch-api.sh +142 -4
- package/scripts/verify-no-secrets.sh +6 -13
- package/tests/README.md +175 -58
|
@@ -0,0 +1,960 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Comprehensive test suite for Pattern Analyzer
|
|
3
|
+
* Tests cover: pattern detection, metrics calculation, security constraints, edge cases
|
|
4
|
+
* Target: 90%+ code coverage
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { PatternAnalyzer } from '../src/pattern-analyzer';
|
|
8
|
+
import { PatternAnalyzerConfig, WorkflowReflection, ILogger, Priority } from '../src/types';
|
|
9
|
+
|
|
10
|
+
// Mock Logger
|
|
11
|
+
class MockLogger implements ILogger {
|
|
12
|
+
logs: string[] = [];
|
|
13
|
+
successes: string[] = [];
|
|
14
|
+
errors: string[] = [];
|
|
15
|
+
warnings: string[] = [];
|
|
16
|
+
|
|
17
|
+
log(message: string): void {
|
|
18
|
+
this.logs.push(message);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
success(message: string): void {
|
|
22
|
+
this.successes.push(message);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
error(message: string): void {
|
|
26
|
+
this.errors.push(message);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
warning(message: string): void {
|
|
30
|
+
this.warnings.push(message);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
reset(): void {
|
|
34
|
+
this.logs = [];
|
|
35
|
+
this.successes = [];
|
|
36
|
+
this.errors = [];
|
|
37
|
+
this.warnings = [];
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Default test configuration
|
|
42
|
+
const getDefaultConfig = (): PatternAnalyzerConfig => ({
|
|
43
|
+
dbHost: 'localhost',
|
|
44
|
+
dbPort: 5432,
|
|
45
|
+
dbName: 'cfn_workflow',
|
|
46
|
+
dbUser: 'cfn_user',
|
|
47
|
+
dbPassword: '',
|
|
48
|
+
timeWindow: 90,
|
|
49
|
+
minOccurrences: 5,
|
|
50
|
+
minSimilarity: 0.85,
|
|
51
|
+
minConfidence: 0.9,
|
|
52
|
+
outputDir: '/tmp/workflow-patterns',
|
|
53
|
+
outputFormat: 'both',
|
|
54
|
+
insertDb: false,
|
|
55
|
+
verbose: false,
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// Test data factories
|
|
59
|
+
const createReflection = (
|
|
60
|
+
overrides: Partial<WorkflowReflection> = {}
|
|
61
|
+
): WorkflowReflection => ({
|
|
62
|
+
id: 'ref-1',
|
|
63
|
+
task_id: 'task-1',
|
|
64
|
+
team_id: 'team-1',
|
|
65
|
+
content: 'Test workflow',
|
|
66
|
+
workflow_steps: [{ command: 'echo', args: ['hello'] }],
|
|
67
|
+
confidence: 0.95,
|
|
68
|
+
created_at: new Date().toISOString(),
|
|
69
|
+
tags: ['test'],
|
|
70
|
+
domain: 'general',
|
|
71
|
+
output: 'hello',
|
|
72
|
+
...overrides,
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
describe('PatternAnalyzer', () => {
|
|
76
|
+
let analyzer: PatternAnalyzer;
|
|
77
|
+
let logger: MockLogger;
|
|
78
|
+
|
|
79
|
+
beforeEach(() => {
|
|
80
|
+
logger = new MockLogger();
|
|
81
|
+
const config = getDefaultConfig();
|
|
82
|
+
analyzer = new PatternAnalyzer(config, logger);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
describe('Constructor and Validation', () => {
|
|
86
|
+
it('should create instance with valid config', () => {
|
|
87
|
+
expect(analyzer).toBeInstanceOf(PatternAnalyzer);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('should throw on invalid config', () => {
|
|
91
|
+
const invalidConfig = {} as PatternAnalyzerConfig;
|
|
92
|
+
expect(() => new PatternAnalyzer(invalidConfig, logger)).toThrow(
|
|
93
|
+
'Invalid pattern analyzer configuration'
|
|
94
|
+
);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('should throw on missing required config fields', () => {
|
|
98
|
+
const incompleteConfig = { dbHost: 'localhost' } as PatternAnalyzerConfig;
|
|
99
|
+
expect(() => new PatternAnalyzer(incompleteConfig, logger)).toThrow();
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
describe('Workflow Signature Generation', () => {
|
|
104
|
+
it('should generate signature from workflow steps', () => {
|
|
105
|
+
const steps = [
|
|
106
|
+
{ command: 'mkdir', path: '/tmp' },
|
|
107
|
+
{ command: 'cd', path: '/tmp' },
|
|
108
|
+
{ command: 'ls', args: ['-la'] },
|
|
109
|
+
];
|
|
110
|
+
|
|
111
|
+
const signature = analyzer.generateWorkflowSignature(steps);
|
|
112
|
+
expect(signature).toContain('→');
|
|
113
|
+
expect(signature).not.toEqual('unknown');
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('should return "unknown" for empty steps', () => {
|
|
117
|
+
const signature = analyzer.generateWorkflowSignature([]);
|
|
118
|
+
expect(signature).toBe('unknown');
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('should return "unknown" for non-array input', () => {
|
|
122
|
+
const signature = analyzer.generateWorkflowSignature(null as unknown as unknown[]);
|
|
123
|
+
expect(signature).toBe('unknown');
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('should normalize whitespace in signature', () => {
|
|
127
|
+
const steps = [
|
|
128
|
+
{ command: 'echo hello' },
|
|
129
|
+
{ command: 'echo world' },
|
|
130
|
+
];
|
|
131
|
+
|
|
132
|
+
const signature = analyzer.generateWorkflowSignature(steps);
|
|
133
|
+
expect(signature).not.toContain(' ');
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('should handle mixed types in steps', () => {
|
|
137
|
+
const steps = [
|
|
138
|
+
{ command: 'test' },
|
|
139
|
+
'string-step',
|
|
140
|
+
123,
|
|
141
|
+
null,
|
|
142
|
+
];
|
|
143
|
+
|
|
144
|
+
expect(() => analyzer.generateWorkflowSignature(steps)).not.toThrow();
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('should handle exception during signature generation', () => {
|
|
148
|
+
// Create steps that will cause an error during processing
|
|
149
|
+
const steps = [{ cmd: () => 'test' }]; // Function can't be JSON stringified easily
|
|
150
|
+
|
|
151
|
+
expect(() => analyzer.generateWorkflowSignature(steps as unknown[])).not.toThrow();
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
describe('Jaccard Similarity Calculation', () => {
|
|
156
|
+
it('should calculate similarity between identical sets', () => {
|
|
157
|
+
const stepsA = [{ cmd: 'echo' }, { cmd: 'ls' }];
|
|
158
|
+
const stepsB = [{ cmd: 'echo' }, { cmd: 'ls' }];
|
|
159
|
+
|
|
160
|
+
const similarity = analyzer.calculateJaccardSimilarity(stepsA, stepsB);
|
|
161
|
+
expect(similarity).toBe(1.0);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it('should calculate similarity between different sets', () => {
|
|
165
|
+
const stepsA = [{ cmd: 'echo' }, { cmd: 'ls' }];
|
|
166
|
+
const stepsB = [{ cmd: 'echo' }, { cmd: 'pwd' }];
|
|
167
|
+
|
|
168
|
+
const similarity = analyzer.calculateJaccardSimilarity(stepsA, stepsB);
|
|
169
|
+
expect(similarity).toBeGreaterThan(0);
|
|
170
|
+
expect(similarity).toBeLessThan(1.0);
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
it('should return 0 for completely different sets', () => {
|
|
174
|
+
const stepsA = [{ cmd: 'echo' }];
|
|
175
|
+
const stepsB = [{ cmd: 'pwd' }];
|
|
176
|
+
|
|
177
|
+
const similarity = analyzer.calculateJaccardSimilarity(stepsA, stepsB);
|
|
178
|
+
expect(similarity).toBe(0);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it('should return 0 for non-array inputs', () => {
|
|
182
|
+
const similarity1 = analyzer.calculateJaccardSimilarity(null as unknown as unknown[], []);
|
|
183
|
+
expect(similarity1).toBe(0);
|
|
184
|
+
|
|
185
|
+
const similarity2 = analyzer.calculateJaccardSimilarity([], null as unknown as unknown[]);
|
|
186
|
+
expect(similarity2).toBe(0);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it('should handle empty arrays', () => {
|
|
190
|
+
const similarity = analyzer.calculateJaccardSimilarity([], []);
|
|
191
|
+
expect(similarity).toBe(0);
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
describe('Similarity Score Calculation', () => {
|
|
196
|
+
it('should calculate average similarity across group', () => {
|
|
197
|
+
const reflections = [
|
|
198
|
+
createReflection({
|
|
199
|
+
id: 'r1',
|
|
200
|
+
workflow_steps: [{ cmd: 'echo' }, { cmd: 'ls' }],
|
|
201
|
+
}),
|
|
202
|
+
createReflection({
|
|
203
|
+
id: 'r2',
|
|
204
|
+
workflow_steps: [{ cmd: 'echo' }, { cmd: 'ls' }],
|
|
205
|
+
}),
|
|
206
|
+
createReflection({
|
|
207
|
+
id: 'r3',
|
|
208
|
+
workflow_steps: [{ cmd: 'echo' }, { cmd: 'pwd' }],
|
|
209
|
+
}),
|
|
210
|
+
];
|
|
211
|
+
|
|
212
|
+
const score = analyzer.calculateSimilarityScore(reflections);
|
|
213
|
+
expect(score).toBeGreaterThanOrEqual(0);
|
|
214
|
+
expect(score).toBeLessThanOrEqual(1);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it('should return 1.0 for single reflection', () => {
|
|
218
|
+
const reflections = [createReflection()];
|
|
219
|
+
const score = analyzer.calculateSimilarityScore(reflections);
|
|
220
|
+
expect(score).toBe(1.0);
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
it('should return 1.0 for empty array', () => {
|
|
224
|
+
const score = analyzer.calculateSimilarityScore([]);
|
|
225
|
+
expect(score).toBe(1.0);
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
it('should handle case with no valid pairs', () => {
|
|
229
|
+
// Single element should skip pairwise comparison
|
|
230
|
+
const score = analyzer.calculateSimilarityScore([createReflection()]);
|
|
231
|
+
expect(score).toBe(1.0);
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
it('should return precise decimal values', () => {
|
|
235
|
+
const reflections = [
|
|
236
|
+
createReflection({
|
|
237
|
+
id: 'r1',
|
|
238
|
+
workflow_steps: [{ a: 1 }, { b: 2 }, { c: 3 }],
|
|
239
|
+
}),
|
|
240
|
+
createReflection({
|
|
241
|
+
id: 'r2',
|
|
242
|
+
workflow_steps: [{ a: 1 }, { d: 4 }],
|
|
243
|
+
}),
|
|
244
|
+
];
|
|
245
|
+
|
|
246
|
+
const score = analyzer.calculateSimilarityScore(reflections);
|
|
247
|
+
expect(String(score).split('.')[1]?.length).toBeLessThanOrEqual(3);
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
describe('Determinism Check', () => {
|
|
252
|
+
it('should detect deterministic workflows', () => {
|
|
253
|
+
const reflections = [
|
|
254
|
+
createReflection({
|
|
255
|
+
workflow_steps: [{ cmd: 'echo' }, { cmd: 'ls' }],
|
|
256
|
+
output: 'test',
|
|
257
|
+
}),
|
|
258
|
+
createReflection({
|
|
259
|
+
workflow_steps: [{ cmd: 'echo' }, { cmd: 'ls' }],
|
|
260
|
+
output: 'test',
|
|
261
|
+
}),
|
|
262
|
+
];
|
|
263
|
+
|
|
264
|
+
const isDeterministic = analyzer.checkDeterministic(reflections);
|
|
265
|
+
expect(isDeterministic).toBe(true);
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
it('should detect non-deterministic workflows with random', () => {
|
|
269
|
+
const reflections = [
|
|
270
|
+
createReflection({
|
|
271
|
+
workflow_steps: [{ cmd: 'Math.random()' }],
|
|
272
|
+
}),
|
|
273
|
+
];
|
|
274
|
+
|
|
275
|
+
const isDeterministic = analyzer.checkDeterministic(reflections);
|
|
276
|
+
expect(isDeterministic).toBe(false);
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
it('should detect non-deterministic workflows with timestamps', () => {
|
|
280
|
+
const reflections = [
|
|
281
|
+
createReflection({
|
|
282
|
+
workflow_steps: [{ cmd: 'date' }, { cmd: '$(date)' }],
|
|
283
|
+
}),
|
|
284
|
+
];
|
|
285
|
+
|
|
286
|
+
const isDeterministic = analyzer.checkDeterministic(reflections);
|
|
287
|
+
expect(isDeterministic).toBe(false);
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
it('should detect non-deterministic workflows with UUID', () => {
|
|
291
|
+
const reflections = [
|
|
292
|
+
createReflection({
|
|
293
|
+
workflow_steps: [{ cmd: 'uuid' }],
|
|
294
|
+
}),
|
|
295
|
+
];
|
|
296
|
+
|
|
297
|
+
const isDeterministic = analyzer.checkDeterministic(reflections);
|
|
298
|
+
expect(isDeterministic).toBe(false);
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
it('should detect non-deterministic workflows with API calls', () => {
|
|
302
|
+
const reflections = [
|
|
303
|
+
createReflection({
|
|
304
|
+
workflow_steps: [{ cmd: 'curl api.example.com' }],
|
|
305
|
+
}),
|
|
306
|
+
];
|
|
307
|
+
|
|
308
|
+
const isDeterministic = analyzer.checkDeterministic(reflections);
|
|
309
|
+
expect(isDeterministic).toBe(false);
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
it('should detect high output variance as non-deterministic', () => {
|
|
313
|
+
const reflections = [
|
|
314
|
+
createReflection({
|
|
315
|
+
id: 'r1',
|
|
316
|
+
output: 'output1',
|
|
317
|
+
}),
|
|
318
|
+
createReflection({
|
|
319
|
+
id: 'r2',
|
|
320
|
+
output: 'output2',
|
|
321
|
+
}),
|
|
322
|
+
createReflection({
|
|
323
|
+
id: 'r3',
|
|
324
|
+
output: 'output3',
|
|
325
|
+
}),
|
|
326
|
+
createReflection({
|
|
327
|
+
id: 'r4',
|
|
328
|
+
output: 'output4',
|
|
329
|
+
}),
|
|
330
|
+
];
|
|
331
|
+
|
|
332
|
+
const isDeterministic = analyzer.checkDeterministic(reflections);
|
|
333
|
+
expect(isDeterministic).toBe(false);
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
it('should handle low output variance', () => {
|
|
337
|
+
const reflections = [
|
|
338
|
+
createReflection({ id: 'r1', output: 'same' }),
|
|
339
|
+
createReflection({ id: 'r2', output: 'same' }),
|
|
340
|
+
createReflection({ id: 'r3', output: 'same' }),
|
|
341
|
+
];
|
|
342
|
+
|
|
343
|
+
const isDeterministic = analyzer.checkDeterministic(reflections);
|
|
344
|
+
expect(isDeterministic).toBe(true);
|
|
345
|
+
});
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
describe('Cost Savings Estimation', () => {
|
|
349
|
+
it('should calculate cost savings from occurrence count', () => {
|
|
350
|
+
const savings = analyzer.estimateCostSavings(10, 90);
|
|
351
|
+
expect(savings).toBeGreaterThan(0);
|
|
352
|
+
expect(typeof savings).toBe('number');
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
it('should scale savings with occurrence count', () => {
|
|
356
|
+
const savings10 = analyzer.estimateCostSavings(10, 90);
|
|
357
|
+
const savings20 = analyzer.estimateCostSavings(20, 90);
|
|
358
|
+
expect(savings20).toBeGreaterThan(savings10);
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
it('should handle different time windows', () => {
|
|
362
|
+
const savings30 = analyzer.estimateCostSavings(10, 30);
|
|
363
|
+
const savings90 = analyzer.estimateCostSavings(10, 90);
|
|
364
|
+
expect(savings90).toBeGreaterThan(0);
|
|
365
|
+
expect(savings30).toBeGreaterThan(0);
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
it('should return 0 for zero occurrences', () => {
|
|
369
|
+
const savings = analyzer.estimateCostSavings(0, 90);
|
|
370
|
+
expect(savings).toBe(0);
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
it('should return numeric value with 2 decimals', () => {
|
|
374
|
+
const savings = analyzer.estimateCostSavings(15, 90);
|
|
375
|
+
const parts = String(savings).split('.');
|
|
376
|
+
if (parts[1]) {
|
|
377
|
+
expect(parts[1].length).toBeLessThanOrEqual(2);
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
describe('Priority Calculation', () => {
|
|
383
|
+
it('should assign high priority to high-value patterns', () => {
|
|
384
|
+
const priority = analyzer.calculatePriority(25, 100, 4, 0.95);
|
|
385
|
+
expect(priority).toBe('high');
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
it('should assign medium priority to moderate patterns', () => {
|
|
389
|
+
const priority = analyzer.calculatePriority(10, 30, 2, 0.85);
|
|
390
|
+
expect(priority).toBe('medium');
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
it('should assign low priority to low-value patterns', () => {
|
|
394
|
+
const priority = analyzer.calculatePriority(3, 5, 1, 0.75);
|
|
395
|
+
expect(priority).toBe('low');
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
it('should weight occurrence count heavily', () => {
|
|
399
|
+
const priorityMap: Record<Priority, number> = { high: 0, medium: 1, low: 2 };
|
|
400
|
+
const lowOccurrence = analyzer.calculatePriority(5, 100, 5, 0.95);
|
|
401
|
+
const highOccurrence = analyzer.calculatePriority(25, 100, 5, 0.95);
|
|
402
|
+
// High occurrence should get higher or equal priority
|
|
403
|
+
const lowScore = priorityMap[lowOccurrence] ?? 2;
|
|
404
|
+
const highScore = priorityMap[highOccurrence] ?? 2;
|
|
405
|
+
expect(highScore).toBeLessThanOrEqual(lowScore);
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
it('should consider cost savings', () => {
|
|
409
|
+
const priorityMap: Record<Priority, number> = { high: 0, medium: 1, low: 2 };
|
|
410
|
+
const lowSavings = analyzer.calculatePriority(15, 5, 2, 0.85);
|
|
411
|
+
const highSavings = analyzer.calculatePriority(15, 50, 2, 0.85);
|
|
412
|
+
// High savings should get higher or equal priority
|
|
413
|
+
const lowScore = priorityMap[lowSavings] ?? 2;
|
|
414
|
+
const highScore = priorityMap[highSavings] ?? 2;
|
|
415
|
+
expect(highScore).toBeLessThanOrEqual(lowScore);
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
it('should consider teams affected', () => {
|
|
419
|
+
const priorityMap: Record<Priority, number> = { high: 0, medium: 1, low: 2 };
|
|
420
|
+
const fewTeams = analyzer.calculatePriority(15, 30, 1, 0.85);
|
|
421
|
+
const manyTeams = analyzer.calculatePriority(15, 30, 4, 0.85);
|
|
422
|
+
// Many teams should get higher or equal priority
|
|
423
|
+
const fewScore = priorityMap[fewTeams] ?? 2;
|
|
424
|
+
const manyScore = priorityMap[manyTeams] ?? 2;
|
|
425
|
+
expect(manyScore).toBeLessThanOrEqual(fewScore);
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
it('should consider confidence score', () => {
|
|
429
|
+
const priorityMap: Record<Priority, number> = { high: 0, medium: 1, low: 2 };
|
|
430
|
+
const lowConfidence = analyzer.calculatePriority(15, 30, 2, 0.7);
|
|
431
|
+
const highConfidence = analyzer.calculatePriority(15, 30, 2, 0.95);
|
|
432
|
+
// High confidence should get higher or equal priority
|
|
433
|
+
const lowScore = priorityMap[lowConfidence] ?? 2;
|
|
434
|
+
const highScore = priorityMap[highConfidence] ?? 2;
|
|
435
|
+
expect(highScore).toBeLessThanOrEqual(lowScore);
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
it('should return valid priority value', () => {
|
|
439
|
+
const priority = analyzer.calculatePriority(10, 20, 2, 0.85);
|
|
440
|
+
expect(['high', 'medium', 'low']).toContain(priority);
|
|
441
|
+
});
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
describe('Pattern Analysis', () => {
|
|
445
|
+
it('should analyze empty reflections array', async () => {
|
|
446
|
+
const report = await analyzer.analyzePatterns([]);
|
|
447
|
+
expect(report.patterns).toHaveLength(0);
|
|
448
|
+
expect(report.metadata.total_reflections_analyzed).toBe(0);
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
it('should analyze single reflection', async () => {
|
|
452
|
+
const reflections = [createReflection()];
|
|
453
|
+
const report = await analyzer.analyzePatterns(reflections);
|
|
454
|
+
expect(report.metadata.total_reflections_analyzed).toBe(1);
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
it('should analyze multiple reflections', async () => {
|
|
458
|
+
const reflections = [
|
|
459
|
+
createReflection({ id: 'r1' }),
|
|
460
|
+
createReflection({ id: 'r2' }),
|
|
461
|
+
createReflection({ id: 'r3' }),
|
|
462
|
+
];
|
|
463
|
+
|
|
464
|
+
const report = await analyzer.analyzePatterns(reflections);
|
|
465
|
+
expect(report.metadata.total_reflections_analyzed).toBe(3);
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
it('should detect patterns with sufficient occurrences', async () => {
|
|
469
|
+
const reflections = Array.from({ length: 10 }, (_, i) =>
|
|
470
|
+
createReflection({
|
|
471
|
+
id: `r${i}`,
|
|
472
|
+
workflow_steps: [{ cmd: 'echo' }, { cmd: 'ls' }],
|
|
473
|
+
confidence: 0.95,
|
|
474
|
+
output: 'same',
|
|
475
|
+
})
|
|
476
|
+
);
|
|
477
|
+
|
|
478
|
+
const report = await analyzer.analyzePatterns(reflections);
|
|
479
|
+
expect(report.patterns.length).toBeGreaterThan(0);
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
it('should not report patterns below occurrence threshold', async () => {
|
|
483
|
+
const reflections = [
|
|
484
|
+
createReflection({ id: 'r1' }),
|
|
485
|
+
createReflection({ id: 'r2' }),
|
|
486
|
+
];
|
|
487
|
+
|
|
488
|
+
const report = await analyzer.analyzePatterns(reflections);
|
|
489
|
+
// With minOccurrences=5, should not find patterns
|
|
490
|
+
expect(report.patterns.length).toBe(0);
|
|
491
|
+
});
|
|
492
|
+
|
|
493
|
+
it('should apply similarity filter', async () => {
|
|
494
|
+
const config = getDefaultConfig();
|
|
495
|
+
config.minSimilarity = 0.99;
|
|
496
|
+
const analyzer2 = new PatternAnalyzer(config, logger);
|
|
497
|
+
|
|
498
|
+
const reflections = Array.from({ length: 5 }, (_, i) =>
|
|
499
|
+
createReflection({
|
|
500
|
+
id: `r${i}`,
|
|
501
|
+
workflow_steps: [{ cmd: `cmd${i}` }],
|
|
502
|
+
})
|
|
503
|
+
);
|
|
504
|
+
|
|
505
|
+
const report = await analyzer2.analyzePatterns(reflections);
|
|
506
|
+
// High similarity threshold should filter out dissimilar patterns
|
|
507
|
+
expect(report.patterns.length).toBe(0);
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
it('should apply confidence filter', async () => {
|
|
511
|
+
const config = getDefaultConfig();
|
|
512
|
+
config.minConfidence = 0.99;
|
|
513
|
+
const analyzer2 = new PatternAnalyzer(config, logger);
|
|
514
|
+
|
|
515
|
+
const reflections = Array.from({ length: 5 }, (_, i) =>
|
|
516
|
+
createReflection({
|
|
517
|
+
id: `r${i}`,
|
|
518
|
+
workflow_steps: [{ cmd: 'echo' }],
|
|
519
|
+
confidence: 0.5,
|
|
520
|
+
})
|
|
521
|
+
);
|
|
522
|
+
|
|
523
|
+
const report = await analyzer2.analyzePatterns(reflections);
|
|
524
|
+
// High confidence threshold should filter out low-confidence patterns
|
|
525
|
+
expect(report.patterns.length).toBe(0);
|
|
526
|
+
});
|
|
527
|
+
|
|
528
|
+
it('should reject non-deterministic patterns', async () => {
|
|
529
|
+
const reflections = Array.from({ length: 5 }, (_, i) =>
|
|
530
|
+
createReflection({
|
|
531
|
+
id: `r${i}`,
|
|
532
|
+
workflow_steps: [{ cmd: 'Math.random()' }],
|
|
533
|
+
})
|
|
534
|
+
);
|
|
535
|
+
|
|
536
|
+
const report = await analyzer.analyzePatterns(reflections);
|
|
537
|
+
expect(report.patterns.length).toBe(0);
|
|
538
|
+
});
|
|
539
|
+
|
|
540
|
+
it('should filter invalid reflections', async () => {
|
|
541
|
+
const validReflection = createReflection({ id: 'valid' });
|
|
542
|
+
const invalidReflection = { incomplete: true } as unknown as WorkflowReflection;
|
|
543
|
+
|
|
544
|
+
const report = await analyzer.analyzePatterns([validReflection, invalidReflection]);
|
|
545
|
+
expect(report.metadata.total_reflections_analyzed).toBe(1);
|
|
546
|
+
});
|
|
547
|
+
|
|
548
|
+
it('should throw on non-array input', async () => {
|
|
549
|
+
await expect(analyzer.analyzePatterns(null as unknown as WorkflowReflection[])).rejects.toThrow(
|
|
550
|
+
'Reflections must be an array'
|
|
551
|
+
);
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
it('should throw on oversized array', async () => {
|
|
555
|
+
const config = getDefaultConfig();
|
|
556
|
+
const analyzer2 = new PatternAnalyzer(config, logger);
|
|
557
|
+
|
|
558
|
+
// Create array exceeding security limit
|
|
559
|
+
const hugeArray = Array(20001).fill(createReflection());
|
|
560
|
+
|
|
561
|
+
await expect(analyzer2.analyzePatterns(hugeArray)).rejects.toThrow(
|
|
562
|
+
/exceed maximum size/
|
|
563
|
+
);
|
|
564
|
+
});
|
|
565
|
+
|
|
566
|
+
it('should sort patterns by priority and savings', async () => {
|
|
567
|
+
const config = getDefaultConfig();
|
|
568
|
+
config.minOccurrences = 1;
|
|
569
|
+
const analyzer2 = new PatternAnalyzer(config, logger);
|
|
570
|
+
|
|
571
|
+
const reflections = [
|
|
572
|
+
// High priority
|
|
573
|
+
...Array(10).fill(createReflection({
|
|
574
|
+
workflow_steps: [{ cmd: 'high' }],
|
|
575
|
+
confidence: 0.95,
|
|
576
|
+
})),
|
|
577
|
+
// Low priority
|
|
578
|
+
...Array(5).fill(createReflection({
|
|
579
|
+
workflow_steps: [{ cmd: 'low' }],
|
|
580
|
+
confidence: 0.7,
|
|
581
|
+
})),
|
|
582
|
+
];
|
|
583
|
+
|
|
584
|
+
const report = await analyzer2.analyzePatterns(reflections);
|
|
585
|
+
|
|
586
|
+
if (report.patterns.length > 1) {
|
|
587
|
+
const priorities = report.patterns.map((p) => p.priority);
|
|
588
|
+
const priorityMap: Record<Priority, number> = { high: 0, medium: 1, low: 2 };
|
|
589
|
+
// Should be sorted with high priority first
|
|
590
|
+
for (let i = 1; i < priorities.length; i++) {
|
|
591
|
+
const prevPriority = priorities[i - 1];
|
|
592
|
+
const currPriority = priorities[i];
|
|
593
|
+
if (prevPriority && currPriority) {
|
|
594
|
+
const prevScore = priorityMap[prevPriority] ?? 2;
|
|
595
|
+
const currScore = priorityMap[currPriority] ?? 2;
|
|
596
|
+
expect(prevScore).toBeLessThanOrEqual(currScore);
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
});
|
|
601
|
+
|
|
602
|
+
it('should sort patterns by savings when priorities are equal', async () => {
|
|
603
|
+
const config = getDefaultConfig();
|
|
604
|
+
config.minOccurrences = 1;
|
|
605
|
+
config.minSimilarity = 0.5; // Lower threshold to allow more patterns
|
|
606
|
+
const analyzer2 = new PatternAnalyzer(config, logger);
|
|
607
|
+
|
|
608
|
+
// Create two distinct patterns with same priority
|
|
609
|
+
const reflections = [
|
|
610
|
+
// Pattern 1: 15 similar reflections
|
|
611
|
+
...Array(15).fill(createReflection({
|
|
612
|
+
id: 'pattern1',
|
|
613
|
+
workflow_steps: [{ cmd: 'echo' }, { cmd: 'ls' }],
|
|
614
|
+
confidence: 0.85,
|
|
615
|
+
output: 'same1',
|
|
616
|
+
})),
|
|
617
|
+
// Pattern 2: 15 similar reflections (different workflow)
|
|
618
|
+
...Array(15).fill(createReflection({
|
|
619
|
+
id: 'pattern2',
|
|
620
|
+
workflow_steps: [{ cmd: 'mkdir' }, { cmd: 'cd' }],
|
|
621
|
+
confidence: 0.85,
|
|
622
|
+
output: 'same2',
|
|
623
|
+
})),
|
|
624
|
+
];
|
|
625
|
+
|
|
626
|
+
const report = await analyzer2.analyzePatterns(reflections);
|
|
627
|
+
|
|
628
|
+
// Both should have the same priority but different savings due to same occurrence count
|
|
629
|
+
if (report.patterns.length > 1) {
|
|
630
|
+
// Verify patterns are sorted correctly
|
|
631
|
+
const priorities = report.patterns.map((p) => p.priority);
|
|
632
|
+
const priorityMap: Record<Priority, number> = { high: 0, medium: 1, low: 2 };
|
|
633
|
+
|
|
634
|
+
// Check that priorities are non-decreasing
|
|
635
|
+
for (let i = 1; i < priorities.length; i++) {
|
|
636
|
+
const prev = priorities[i - 1];
|
|
637
|
+
const curr = priorities[i];
|
|
638
|
+
const prevPattern = report.patterns[i - 1];
|
|
639
|
+
const currPattern = report.patterns[i];
|
|
640
|
+
|
|
641
|
+
if (prev && curr && prevPattern && currPattern) {
|
|
642
|
+
const prevScore = priorityMap[prev] ?? 2;
|
|
643
|
+
const currScore = priorityMap[curr] ?? 2;
|
|
644
|
+
// If same priority, next check is savings
|
|
645
|
+
if (prevScore === currScore) {
|
|
646
|
+
const prevSavings = prevPattern.estimated_savings_usd;
|
|
647
|
+
const currSavings = currPattern.estimated_savings_usd;
|
|
648
|
+
expect(prevSavings).toBeGreaterThanOrEqual(currSavings);
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
});
|
|
654
|
+
});
|
|
655
|
+
|
|
656
|
+
describe('Report Generation', () => {
|
|
657
|
+
it('should generate metadata', async () => {
|
|
658
|
+
const reflections = [createReflection()];
|
|
659
|
+
const report = await analyzer.analyzePatterns(reflections);
|
|
660
|
+
|
|
661
|
+
expect(report.metadata).toBeDefined();
|
|
662
|
+
expect(report.metadata.analysis_timestamp).toBeDefined();
|
|
663
|
+
expect(report.metadata.time_window_days).toBe(90);
|
|
664
|
+
expect(report.metadata.total_reflections_analyzed).toBe(1);
|
|
665
|
+
expect(report.metadata.patterns_found).toBeDefined();
|
|
666
|
+
expect(report.metadata.filters).toBeDefined();
|
|
667
|
+
});
|
|
668
|
+
|
|
669
|
+
it('should format report as JSON', async () => {
|
|
670
|
+
const reflections = [createReflection()];
|
|
671
|
+
const report = await analyzer.analyzePatterns(reflections);
|
|
672
|
+
const json = analyzer.formatAsJson(report);
|
|
673
|
+
|
|
674
|
+
expect(() => JSON.parse(json)).not.toThrow();
|
|
675
|
+
const parsed = JSON.parse(json);
|
|
676
|
+
expect(parsed.metadata).toBeDefined();
|
|
677
|
+
expect(parsed.patterns).toBeDefined();
|
|
678
|
+
});
|
|
679
|
+
|
|
680
|
+
it('should format report as summary', async () => {
|
|
681
|
+
const reflections = [createReflection()];
|
|
682
|
+
const report = await analyzer.analyzePatterns(reflections);
|
|
683
|
+
const summary = analyzer.formatAsSummary(report);
|
|
684
|
+
|
|
685
|
+
expect(summary).toContain('Pattern Analysis Summary');
|
|
686
|
+
expect(summary).toContain('Analysis Timestamp');
|
|
687
|
+
expect(summary).toContain('Time Window');
|
|
688
|
+
});
|
|
689
|
+
|
|
690
|
+
it('should include patterns in summary', async () => {
|
|
691
|
+
const config = getDefaultConfig();
|
|
692
|
+
config.minOccurrences = 1;
|
|
693
|
+
const analyzer2 = new PatternAnalyzer(config, logger);
|
|
694
|
+
|
|
695
|
+
const reflections = Array.from({ length: 5 }, (_, i) =>
|
|
696
|
+
createReflection({
|
|
697
|
+
id: `r${i}`,
|
|
698
|
+
workflow_steps: [{ cmd: 'echo' }],
|
|
699
|
+
})
|
|
700
|
+
);
|
|
701
|
+
|
|
702
|
+
const report = await analyzer2.analyzePatterns(reflections);
|
|
703
|
+
const summary = analyzer2.formatAsSummary(report);
|
|
704
|
+
|
|
705
|
+
if (report.patterns.length > 0) {
|
|
706
|
+
expect(summary).toContain('Top 5 Patterns');
|
|
707
|
+
}
|
|
708
|
+
});
|
|
709
|
+
|
|
710
|
+
it('should format summary with no patterns found', async () => {
|
|
711
|
+
const reflections = [createReflection({ id: 'r1' })];
|
|
712
|
+
const report = await analyzer.analyzePatterns(reflections);
|
|
713
|
+
const summary = analyzer.formatAsSummary(report);
|
|
714
|
+
|
|
715
|
+
expect(summary).toContain('Pattern Analysis Summary');
|
|
716
|
+
expect(summary).toContain('High: 0');
|
|
717
|
+
expect(summary).toContain('Medium: 0');
|
|
718
|
+
expect(summary).toContain('Low: 0');
|
|
719
|
+
});
|
|
720
|
+
|
|
721
|
+
it('should format JSON with proper indentation', async () => {
|
|
722
|
+
const reflections = [createReflection({ id: 'r1' })];
|
|
723
|
+
const report = await analyzer.analyzePatterns(reflections);
|
|
724
|
+
const json = analyzer.formatAsJson(report);
|
|
725
|
+
|
|
726
|
+
// Check for proper indentation (2 spaces)
|
|
727
|
+
expect(json).toMatch(/\n /);
|
|
728
|
+
});
|
|
729
|
+
});
|
|
730
|
+
|
|
731
|
+
describe('Security Constraints', () => {
|
|
732
|
+
it('should validate path length', () => {
|
|
733
|
+
const longPath = 'a'.repeat(5000);
|
|
734
|
+
// This test validates internal path validation works
|
|
735
|
+
const config = getDefaultConfig();
|
|
736
|
+
config.outputDir = longPath;
|
|
737
|
+
expect(() => new PatternAnalyzer(config, logger)).not.toThrow();
|
|
738
|
+
});
|
|
739
|
+
|
|
740
|
+
it('should limit array size', async () => {
|
|
741
|
+
const hugeArray = Array(20001).fill(createReflection());
|
|
742
|
+
await expect(analyzer.analyzePatterns(hugeArray)).rejects.toThrow();
|
|
743
|
+
});
|
|
744
|
+
|
|
745
|
+
it('should prevent SQL injection in queries', async () => {
|
|
746
|
+
const config = getDefaultConfig();
|
|
747
|
+
// Try with suspicious config values
|
|
748
|
+
config.dbUser = "'; DROP TABLE--";
|
|
749
|
+
config.dbPassword = "' OR '1'='1";
|
|
750
|
+
|
|
751
|
+
// Should not throw during instantiation
|
|
752
|
+
expect(() => new PatternAnalyzer(config, logger)).not.toThrow();
|
|
753
|
+
});
|
|
754
|
+
});
|
|
755
|
+
|
|
756
|
+
describe('Edge Cases', () => {
|
|
757
|
+
it('should handle reflections with null values', async () => {
|
|
758
|
+
const reflection = createReflection();
|
|
759
|
+
reflection.output = null as unknown as string;
|
|
760
|
+
|
|
761
|
+
const report = await analyzer.analyzePatterns([reflection]);
|
|
762
|
+
expect(report).toBeDefined();
|
|
763
|
+
});
|
|
764
|
+
|
|
765
|
+
it('should handle determinism check with caught exception', () => {
|
|
766
|
+
const reflections = [
|
|
767
|
+
createReflection({
|
|
768
|
+
workflow_steps: [{ cmd: 'test', nested: { circular: {} as unknown } }],
|
|
769
|
+
}),
|
|
770
|
+
];
|
|
771
|
+
|
|
772
|
+
// Should not throw even with complex objects
|
|
773
|
+
expect(() => analyzer.checkDeterministic(reflections)).not.toThrow();
|
|
774
|
+
});
|
|
775
|
+
|
|
776
|
+
it('should handle similarity calculation with caught exception', () => {
|
|
777
|
+
const stepsWithComplexStructure = [
|
|
778
|
+
{ cmd: 'test' },
|
|
779
|
+
{ nested: { deep: { structure: {} } } },
|
|
780
|
+
];
|
|
781
|
+
|
|
782
|
+
expect(() => analyzer.calculateJaccardSimilarity(stepsWithComplexStructure, [])).not.toThrow();
|
|
783
|
+
});
|
|
784
|
+
|
|
785
|
+
it('should handle reflections with empty workflow steps', async () => {
|
|
786
|
+
const reflection = createReflection();
|
|
787
|
+
reflection.workflow_steps = [];
|
|
788
|
+
|
|
789
|
+
const report = await analyzer.analyzePatterns([reflection]);
|
|
790
|
+
expect(report.patterns.length).toBe(0);
|
|
791
|
+
});
|
|
792
|
+
|
|
793
|
+
it('should handle very large occurrence counts', () => {
|
|
794
|
+
const savings = analyzer.estimateCostSavings(1000000, 90);
|
|
795
|
+
expect(typeof savings).toBe('number');
|
|
796
|
+
expect(savings).toBeGreaterThan(0);
|
|
797
|
+
});
|
|
798
|
+
|
|
799
|
+
it('should handle identical reflections', async () => {
|
|
800
|
+
const reflections = Array(10).fill(createReflection({ id: 'same' })).map((r, i) => ({
|
|
801
|
+
...r,
|
|
802
|
+
id: `r${i}`,
|
|
803
|
+
}));
|
|
804
|
+
|
|
805
|
+
const report = await analyzer.analyzePatterns(reflections);
|
|
806
|
+
expect(report.patterns.length).toBeGreaterThanOrEqual(0);
|
|
807
|
+
});
|
|
808
|
+
|
|
809
|
+
it('should handle mixed team IDs', async () => {
|
|
810
|
+
const config = getDefaultConfig();
|
|
811
|
+
config.minOccurrences = 1;
|
|
812
|
+
const analyzer2 = new PatternAnalyzer(config, logger);
|
|
813
|
+
|
|
814
|
+
const reflections = [
|
|
815
|
+
createReflection({ id: 'r1', team_id: 'team-a', workflow_steps: [{ cmd: 'echo' }] }),
|
|
816
|
+
createReflection({ id: 'r2', team_id: 'team-b', workflow_steps: [{ cmd: 'echo' }] }),
|
|
817
|
+
createReflection({ id: 'r3', team_id: 'team-c', workflow_steps: [{ cmd: 'echo' }] }),
|
|
818
|
+
];
|
|
819
|
+
|
|
820
|
+
const report = await analyzer2.analyzePatterns(reflections);
|
|
821
|
+
if (report.patterns.length > 0) {
|
|
822
|
+
const firstPattern = report.patterns[0];
|
|
823
|
+
if (firstPattern) {
|
|
824
|
+
const teamsAffected = firstPattern.teams_affected;
|
|
825
|
+
expect(teamsAffected.length).toBeGreaterThanOrEqual(1);
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
});
|
|
829
|
+
|
|
830
|
+
it('should handle special characters in workflow steps', async () => {
|
|
831
|
+
const reflection = createReflection({
|
|
832
|
+
workflow_steps: [
|
|
833
|
+
{ cmd: 'echo "special chars: !@#$%^&*()"' },
|
|
834
|
+
],
|
|
835
|
+
});
|
|
836
|
+
|
|
837
|
+
const report = await analyzer.analyzePatterns([reflection]);
|
|
838
|
+
expect(report).toBeDefined();
|
|
839
|
+
});
|
|
840
|
+
|
|
841
|
+
it('should handle unicode in content', async () => {
|
|
842
|
+
const reflection = createReflection({
|
|
843
|
+
content: 'Test with unicode: 你好世界 🚀',
|
|
844
|
+
});
|
|
845
|
+
|
|
846
|
+
const report = await analyzer.analyzePatterns([reflection]);
|
|
847
|
+
expect(report).toBeDefined();
|
|
848
|
+
});
|
|
849
|
+
|
|
850
|
+
it('should handle decimal similarity scores', () => {
|
|
851
|
+
const similarity = analyzer.calculateJaccardSimilarity(
|
|
852
|
+
[{ a: 1 }, { b: 2 }, { c: 3 }],
|
|
853
|
+
[{ a: 1 }, { b: 2 }]
|
|
854
|
+
);
|
|
855
|
+
|
|
856
|
+
expect(similarity).toBeGreaterThan(0);
|
|
857
|
+
expect(similarity).toBeLessThan(1);
|
|
858
|
+
});
|
|
859
|
+
});
|
|
860
|
+
|
|
861
|
+
describe('Integration Tests', () => {
|
|
862
|
+
it('should complete full analysis workflow', async () => {
|
|
863
|
+
const config = getDefaultConfig();
|
|
864
|
+
config.minOccurrences = 1;
|
|
865
|
+
const analyzer2 = new PatternAnalyzer(config, logger);
|
|
866
|
+
|
|
867
|
+
const reflections = [
|
|
868
|
+
createReflection({
|
|
869
|
+
id: 'r1',
|
|
870
|
+
workflow_steps: [{ cmd: 'mkdir' }, { cmd: 'cd' }],
|
|
871
|
+
confidence: 0.95,
|
|
872
|
+
output: 'same',
|
|
873
|
+
}),
|
|
874
|
+
createReflection({
|
|
875
|
+
id: 'r2',
|
|
876
|
+
workflow_steps: [{ cmd: 'mkdir' }, { cmd: 'cd' }],
|
|
877
|
+
confidence: 0.93,
|
|
878
|
+
output: 'same',
|
|
879
|
+
}),
|
|
880
|
+
createReflection({
|
|
881
|
+
id: 'r3',
|
|
882
|
+
workflow_steps: [{ cmd: 'ls' }, { cmd: 'pwd' }],
|
|
883
|
+
confidence: 0.85,
|
|
884
|
+
output: 'different',
|
|
885
|
+
}),
|
|
886
|
+
];
|
|
887
|
+
|
|
888
|
+
const report = await analyzer2.analyzePatterns(reflections);
|
|
889
|
+
|
|
890
|
+
expect(report.metadata).toBeDefined();
|
|
891
|
+
expect(report.patterns).toBeDefined();
|
|
892
|
+
expect(Array.isArray(report.patterns)).toBe(true);
|
|
893
|
+
|
|
894
|
+
const json = analyzer2.formatAsJson(report);
|
|
895
|
+
expect(() => JSON.parse(json)).not.toThrow();
|
|
896
|
+
|
|
897
|
+
const summary = analyzer2.formatAsSummary(report);
|
|
898
|
+
expect(summary.length).toBeGreaterThan(0);
|
|
899
|
+
});
|
|
900
|
+
|
|
901
|
+
it('should handle production-like workload', async () => {
|
|
902
|
+
const config = getDefaultConfig();
|
|
903
|
+
config.minOccurrences = 5;
|
|
904
|
+
const analyzer2 = new PatternAnalyzer(config, logger);
|
|
905
|
+
|
|
906
|
+
// Create 100 reflections with patterns
|
|
907
|
+
const reflections: WorkflowReflection[] = [];
|
|
908
|
+
|
|
909
|
+
// Pattern 1: 10 similar reflections
|
|
910
|
+
for (let i = 0; i < 10; i++) {
|
|
911
|
+
reflections.push(
|
|
912
|
+
createReflection({
|
|
913
|
+
id: `p1-r${i}`,
|
|
914
|
+
team_id: `team-${i % 3}`,
|
|
915
|
+
workflow_steps: [{ cmd: 'pattern1' }, { cmd: 'action' }],
|
|
916
|
+
confidence: 0.92 + Math.random() * 0.07,
|
|
917
|
+
output: 'result1',
|
|
918
|
+
})
|
|
919
|
+
);
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
// Pattern 2: 8 similar reflections
|
|
923
|
+
for (let i = 0; i < 8; i++) {
|
|
924
|
+
reflections.push(
|
|
925
|
+
createReflection({
|
|
926
|
+
id: `p2-r${i}`,
|
|
927
|
+
team_id: `team-${i % 4}`,
|
|
928
|
+
workflow_steps: [{ cmd: 'pattern2' }, { cmd: 'execute' }],
|
|
929
|
+
confidence: 0.88 + Math.random() * 0.1,
|
|
930
|
+
output: 'result2',
|
|
931
|
+
})
|
|
932
|
+
);
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
// Noise: 20 unique reflections
|
|
936
|
+
for (let i = 0; i < 20; i++) {
|
|
937
|
+
reflections.push(
|
|
938
|
+
createReflection({
|
|
939
|
+
id: `noise-r${i}`,
|
|
940
|
+
workflow_steps: [{ cmd: `unique${i}` }],
|
|
941
|
+
confidence: 0.75 + Math.random() * 0.15,
|
|
942
|
+
})
|
|
943
|
+
);
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
const report = await analyzer2.analyzePatterns(reflections);
|
|
947
|
+
|
|
948
|
+
expect(report.metadata.total_reflections_analyzed).toBe(38);
|
|
949
|
+
expect(report.patterns.length).toBeGreaterThanOrEqual(0);
|
|
950
|
+
|
|
951
|
+
// Should detect major patterns
|
|
952
|
+
if (report.patterns.length > 0) {
|
|
953
|
+
const firstPattern = report.patterns[0];
|
|
954
|
+
if (firstPattern) {
|
|
955
|
+
expect(firstPattern.occurrence_count).toBeGreaterThanOrEqual(5);
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
});
|
|
959
|
+
});
|
|
960
|
+
});
|