agentic-qe 3.3.3 → 3.3.4
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/agents/v3/README.md +100 -0
- package/.claude/agents/v3/qe-accessibility-auditor.md +112 -11
- package/.claude/agents/v3/qe-bdd-generator.md +40 -0
- package/.claude/agents/v3/qe-coverage-specialist.md +39 -0
- package/.claude/agents/v3/qe-defect-predictor.md +36 -0
- package/.claude/agents/v3/qe-gap-detector.md +39 -0
- package/.claude/agents/v3/qe-pattern-learner.md +31 -0
- package/.claude/agents/v3/qe-product-factors-assessor.md +34 -0
- package/.claude/agents/v3/qe-quality-criteria-recommender.md +32 -0
- package/.claude/agents/v3/qe-quality-gate.md +39 -0
- package/.claude/agents/v3/qe-requirements-validator.md +37 -0
- package/.claude/agents/v3/qe-risk-assessor.md +33 -0
- package/.claude/agents/v3/qe-tdd-specialist.md +33 -0
- package/.claude/agents/v3/qe-test-architect.md +36 -0
- package/.claude/skills/README.md +30 -104
- package/.claude/skills/a11y-ally/SKILL.md +1658 -0
- package/.claude/skills/qcsd-ideation-swarm/SKILL.md +1750 -0
- package/.claude/skills/skills-manifest.json +78 -8
- package/README.md +18 -4
- package/package.json +1 -1
- package/scripts/demo-warmup.sh +45 -0
- package/scripts/fetch-content.js +460 -0
- package/v3/CHANGELOG.md +101 -0
- package/v3/README.md +11 -6
- package/v3/assets/agents/v3/README.md +100 -0
- package/v3/assets/agents/v3/qe-accessibility-auditor.md +112 -11
- package/v3/assets/agents/v3/qe-bdd-generator.md +40 -0
- package/v3/assets/agents/v3/qe-coverage-specialist.md +39 -0
- package/v3/assets/agents/v3/qe-defect-predictor.md +36 -0
- package/v3/assets/agents/v3/qe-gap-detector.md +39 -0
- package/v3/assets/agents/v3/qe-pattern-learner.md +31 -0
- package/v3/assets/agents/v3/qe-product-factors-assessor.md +34 -0
- package/v3/assets/agents/v3/qe-quality-criteria-recommender.md +32 -0
- package/v3/assets/agents/v3/qe-quality-gate.md +39 -0
- package/v3/assets/agents/v3/qe-requirements-validator.md +37 -0
- package/v3/assets/agents/v3/qe-risk-assessor.md +33 -0
- package/v3/assets/agents/v3/qe-tdd-specialist.md +33 -0
- package/v3/assets/agents/v3/qe-test-architect.md +36 -0
- package/v3/assets/hooks/cross-phase-memory.yaml +253 -0
- package/v3/assets/skills/a11y-ally/SKILL.md +1658 -0
- package/v3/assets/skills/qcsd-ideation-swarm/SKILL.md +1750 -0
- package/v3/assets/skills/skills-manifest.json +753 -0
- package/v3/dist/adapters/claude-flow/model-router-bridge.d.ts.map +1 -1
- package/v3/dist/adapters/claude-flow/model-router-bridge.js +6 -4
- package/v3/dist/adapters/claude-flow/model-router-bridge.js.map +1 -1
- package/v3/dist/adapters/claude-flow/pretrain-bridge.d.ts.map +1 -1
- package/v3/dist/adapters/claude-flow/pretrain-bridge.js +13 -8
- package/v3/dist/adapters/claude-flow/pretrain-bridge.js.map +1 -1
- package/v3/dist/adapters/claude-flow/trajectory-bridge.d.ts.map +1 -1
- package/v3/dist/adapters/claude-flow/trajectory-bridge.js +9 -6
- package/v3/dist/adapters/claude-flow/trajectory-bridge.js.map +1 -1
- package/v3/dist/benchmarks/performance-benchmarks.d.ts.map +1 -1
- package/v3/dist/benchmarks/performance-benchmarks.js +5 -3
- package/v3/dist/benchmarks/performance-benchmarks.js.map +1 -1
- package/v3/dist/cli/bundle.js +27611 -23175
- package/v3/dist/cli/commands/hooks.d.ts.map +1 -1
- package/v3/dist/cli/commands/hooks.js +288 -0
- package/v3/dist/cli/commands/hooks.js.map +1 -1
- package/v3/dist/cli/commands/sync.d.ts.map +1 -1
- package/v3/dist/cli/commands/sync.js +0 -6
- package/v3/dist/cli/commands/sync.js.map +1 -1
- package/v3/dist/cli/handlers/init-handler.d.ts.map +1 -1
- package/v3/dist/cli/handlers/init-handler.js +11 -0
- package/v3/dist/cli/handlers/init-handler.js.map +1 -1
- package/v3/dist/cli/index.js +14 -2
- package/v3/dist/cli/index.js.map +1 -1
- package/v3/dist/cli/scheduler/persistent-scheduler.d.ts.map +1 -1
- package/v3/dist/cli/scheduler/persistent-scheduler.js +3 -2
- package/v3/dist/cli/scheduler/persistent-scheduler.js.map +1 -1
- package/v3/dist/cli/wizards/test-wizard.d.ts.map +1 -1
- package/v3/dist/cli/wizards/test-wizard.js +6 -4
- package/v3/dist/cli/wizards/test-wizard.js.map +1 -1
- package/v3/dist/coordination/consensus/providers/native-learning-provider.d.ts.map +1 -1
- package/v3/dist/coordination/consensus/providers/native-learning-provider.js +10 -8
- package/v3/dist/coordination/consensus/providers/native-learning-provider.js.map +1 -1
- package/v3/dist/coordination/consensus/providers/ollama-provider.d.ts.map +1 -1
- package/v3/dist/coordination/consensus/providers/ollama-provider.js +5 -4
- package/v3/dist/coordination/consensus/providers/ollama-provider.js.map +1 -1
- package/v3/dist/coordination/consensus/providers/openai-provider.d.ts.map +1 -1
- package/v3/dist/coordination/consensus/providers/openai-provider.js +5 -4
- package/v3/dist/coordination/consensus/providers/openai-provider.js.map +1 -1
- package/v3/dist/coordination/constants.d.ts +198 -0
- package/v3/dist/coordination/constants.d.ts.map +1 -0
- package/v3/dist/coordination/constants.js +210 -0
- package/v3/dist/coordination/constants.js.map +1 -0
- package/v3/dist/coordination/mincut/dream-integration.d.ts.map +1 -1
- package/v3/dist/coordination/mincut/dream-integration.js +5 -1
- package/v3/dist/coordination/mincut/dream-integration.js.map +1 -1
- package/v3/dist/coordination/queen-coordinator.d.ts +9 -1
- package/v3/dist/coordination/queen-coordinator.d.ts.map +1 -1
- package/v3/dist/coordination/queen-coordinator.js +49 -9
- package/v3/dist/coordination/queen-coordinator.js.map +1 -1
- package/v3/dist/coordination/task-executor.d.ts.map +1 -1
- package/v3/dist/coordination/task-executor.js +7 -8
- package/v3/dist/coordination/task-executor.js.map +1 -1
- package/v3/dist/coordination/workflow-orchestrator.d.ts.map +1 -1
- package/v3/dist/coordination/workflow-orchestrator.js +261 -0
- package/v3/dist/coordination/workflow-orchestrator.js.map +1 -1
- package/v3/dist/domains/chaos-resilience/plugin.d.ts +14 -3
- package/v3/dist/domains/chaos-resilience/plugin.d.ts.map +1 -1
- package/v3/dist/domains/chaos-resilience/plugin.js +96 -0
- package/v3/dist/domains/chaos-resilience/plugin.js.map +1 -1
- package/v3/dist/domains/chaos-resilience/services/performance-profiler.d.ts.map +1 -1
- package/v3/dist/domains/chaos-resilience/services/performance-profiler.js +12 -8
- package/v3/dist/domains/chaos-resilience/services/performance-profiler.js.map +1 -1
- package/v3/dist/domains/code-intelligence/plugin.d.ts +13 -3
- package/v3/dist/domains/code-intelligence/plugin.d.ts.map +1 -1
- package/v3/dist/domains/code-intelligence/plugin.js +85 -0
- package/v3/dist/domains/code-intelligence/plugin.js.map +1 -1
- package/v3/dist/domains/code-intelligence/services/product-factors-bridge.d.ts.map +1 -1
- package/v3/dist/domains/code-intelligence/services/product-factors-bridge.js +3 -2
- package/v3/dist/domains/code-intelligence/services/product-factors-bridge.js.map +1 -1
- package/v3/dist/domains/constants.d.ts +481 -0
- package/v3/dist/domains/constants.d.ts.map +1 -0
- package/v3/dist/domains/constants.js +503 -0
- package/v3/dist/domains/constants.js.map +1 -0
- package/v3/dist/domains/contract-testing/plugin.d.ts +6 -1
- package/v3/dist/domains/contract-testing/plugin.d.ts.map +1 -1
- package/v3/dist/domains/contract-testing/plugin.js +80 -1
- package/v3/dist/domains/contract-testing/plugin.js.map +1 -1
- package/v3/dist/domains/contract-testing/services/contract-validator.d.ts.map +1 -1
- package/v3/dist/domains/contract-testing/services/contract-validator.js +5 -4
- package/v3/dist/domains/contract-testing/services/contract-validator.js.map +1 -1
- package/v3/dist/domains/coverage-analysis/services/hnsw-index.d.ts.map +1 -1
- package/v3/dist/domains/coverage-analysis/services/hnsw-index.js +1 -0
- package/v3/dist/domains/coverage-analysis/services/hnsw-index.js.map +1 -1
- package/v3/dist/domains/defect-intelligence/coordinator.d.ts +2 -2
- package/v3/dist/domains/defect-intelligence/coordinator.d.ts.map +1 -1
- package/v3/dist/domains/defect-intelligence/coordinator.js.map +1 -1
- package/v3/dist/domains/defect-intelligence/plugin.d.ts +6 -1
- package/v3/dist/domains/defect-intelligence/plugin.d.ts.map +1 -1
- package/v3/dist/domains/defect-intelligence/plugin.js +101 -0
- package/v3/dist/domains/defect-intelligence/plugin.js.map +1 -1
- package/v3/dist/domains/defect-intelligence/services/defect-predictor.d.ts.map +1 -1
- package/v3/dist/domains/defect-intelligence/services/defect-predictor.js +3 -2
- package/v3/dist/domains/defect-intelligence/services/defect-predictor.js.map +1 -1
- package/v3/dist/domains/domain-interface.d.ts.map +1 -1
- package/v3/dist/domains/domain-interface.js +24 -9
- package/v3/dist/domains/domain-interface.js.map +1 -1
- package/v3/dist/domains/learning-optimization/plugin.d.ts +2 -1
- package/v3/dist/domains/learning-optimization/plugin.d.ts.map +1 -1
- package/v3/dist/domains/learning-optimization/plugin.js +49 -0
- package/v3/dist/domains/learning-optimization/plugin.js.map +1 -1
- package/v3/dist/domains/quality-assessment/coordinator.d.ts +90 -1
- package/v3/dist/domains/quality-assessment/coordinator.d.ts.map +1 -1
- package/v3/dist/domains/quality-assessment/coordinator.js +310 -0
- package/v3/dist/domains/quality-assessment/coordinator.js.map +1 -1
- package/v3/dist/domains/requirements-validation/index.d.ts +1 -0
- package/v3/dist/domains/requirements-validation/index.d.ts.map +1 -1
- package/v3/dist/domains/requirements-validation/index.js +2 -0
- package/v3/dist/domains/requirements-validation/index.js.map +1 -1
- package/v3/dist/domains/requirements-validation/plugin.d.ts +13 -1
- package/v3/dist/domains/requirements-validation/plugin.d.ts.map +1 -1
- package/v3/dist/domains/requirements-validation/plugin.js +94 -0
- package/v3/dist/domains/requirements-validation/plugin.js.map +1 -1
- package/v3/dist/domains/requirements-validation/qcsd-ideation-plugin.d.ts +245 -0
- package/v3/dist/domains/requirements-validation/qcsd-ideation-plugin.d.ts.map +1 -0
- package/v3/dist/domains/requirements-validation/qcsd-ideation-plugin.js +1143 -0
- package/v3/dist/domains/requirements-validation/qcsd-ideation-plugin.js.map +1 -0
- package/v3/dist/domains/requirements-validation/services/product-factors-assessment/code-intelligence/codebase-analyzer.d.ts.map +1 -1
- package/v3/dist/domains/requirements-validation/services/product-factors-assessment/code-intelligence/codebase-analyzer.js +3 -2
- package/v3/dist/domains/requirements-validation/services/product-factors-assessment/code-intelligence/codebase-analyzer.js.map +1 -1
- package/v3/dist/domains/security-compliance/plugin.d.ts +3 -2
- package/v3/dist/domains/security-compliance/plugin.d.ts.map +1 -1
- package/v3/dist/domains/security-compliance/plugin.js +64 -0
- package/v3/dist/domains/security-compliance/plugin.js.map +1 -1
- package/v3/dist/domains/security-compliance/services/scanners/dast-auth-testing.d.ts +25 -0
- package/v3/dist/domains/security-compliance/services/scanners/dast-auth-testing.d.ts.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/dast-auth-testing.js +160 -0
- package/v3/dist/domains/security-compliance/services/scanners/dast-auth-testing.js.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/dast-helpers.d.ts +48 -0
- package/v3/dist/domains/security-compliance/services/scanners/dast-helpers.d.ts.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/dast-helpers.js +385 -0
- package/v3/dist/domains/security-compliance/services/scanners/dast-helpers.js.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/dast-injection-testing.d.ts +20 -0
- package/v3/dist/domains/security-compliance/services/scanners/dast-injection-testing.d.ts.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/dast-injection-testing.js +99 -0
- package/v3/dist/domains/security-compliance/services/scanners/dast-injection-testing.js.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/dast-scanner.d.ts +62 -0
- package/v3/dist/domains/security-compliance/services/scanners/dast-scanner.d.ts.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/dast-scanner.js +329 -0
- package/v3/dist/domains/security-compliance/services/scanners/dast-scanner.js.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/dependency-scanner.d.ts +46 -0
- package/v3/dist/domains/security-compliance/services/scanners/dependency-scanner.d.ts.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/dependency-scanner.js +180 -0
- package/v3/dist/domains/security-compliance/services/scanners/dependency-scanner.js.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/index.d.ts +14 -0
- package/v3/dist/domains/security-compliance/services/scanners/index.d.ts.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/index.js +16 -0
- package/v3/dist/domains/security-compliance/services/scanners/index.js.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/sast-scanner.d.ts +92 -0
- package/v3/dist/domains/security-compliance/services/scanners/sast-scanner.d.ts.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/sast-scanner.js +440 -0
- package/v3/dist/domains/security-compliance/services/scanners/sast-scanner.js.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/scanner-orchestrator.d.ts +78 -0
- package/v3/dist/domains/security-compliance/services/scanners/scanner-orchestrator.d.ts.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/scanner-orchestrator.js +179 -0
- package/v3/dist/domains/security-compliance/services/scanners/scanner-orchestrator.js.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/scanner-types.d.ts +91 -0
- package/v3/dist/domains/security-compliance/services/scanners/scanner-types.d.ts.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/scanner-types.js +15 -0
- package/v3/dist/domains/security-compliance/services/scanners/scanner-types.js.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/security-patterns.d.ts +16 -0
- package/v3/dist/domains/security-compliance/services/scanners/security-patterns.d.ts.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/security-patterns.js +507 -0
- package/v3/dist/domains/security-compliance/services/scanners/security-patterns.js.map +1 -0
- package/v3/dist/domains/security-compliance/services/security-auditor.d.ts.map +1 -1
- package/v3/dist/domains/security-compliance/services/security-auditor.js +2 -1
- package/v3/dist/domains/security-compliance/services/security-auditor.js.map +1 -1
- package/v3/dist/domains/security-compliance/services/security-scanner.d.ts +20 -213
- package/v3/dist/domains/security-compliance/services/security-scanner.d.ts.map +1 -1
- package/v3/dist/domains/security-compliance/services/security-scanner.js +37 -2013
- package/v3/dist/domains/security-compliance/services/security-scanner.js.map +1 -1
- package/v3/dist/domains/security-compliance/services/semgrep-integration.d.ts.map +1 -1
- package/v3/dist/domains/security-compliance/services/semgrep-integration.js +7 -6
- package/v3/dist/domains/security-compliance/services/semgrep-integration.js.map +1 -1
- package/v3/dist/domains/test-execution/services/auth-state-manager.d.ts.map +1 -1
- package/v3/dist/domains/test-execution/services/auth-state-manager.js +6 -4
- package/v3/dist/domains/test-execution/services/auth-state-manager.js.map +1 -1
- package/v3/dist/domains/test-execution/services/e2e/assertion-handlers.d.ts +55 -0
- package/v3/dist/domains/test-execution/services/e2e/assertion-handlers.d.ts.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/assertion-handlers.js +407 -0
- package/v3/dist/domains/test-execution/services/e2e/assertion-handlers.js.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/browser-orchestrator.d.ts +122 -0
- package/v3/dist/domains/test-execution/services/e2e/browser-orchestrator.d.ts.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/browser-orchestrator.js +325 -0
- package/v3/dist/domains/test-execution/services/e2e/browser-orchestrator.js.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/e2e-coordinator.d.ts +97 -0
- package/v3/dist/domains/test-execution/services/e2e/e2e-coordinator.d.ts.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/e2e-coordinator.js +297 -0
- package/v3/dist/domains/test-execution/services/e2e/e2e-coordinator.js.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/index.d.ts +22 -0
- package/v3/dist/domains/test-execution/services/e2e/index.d.ts.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/index.js +52 -0
- package/v3/dist/domains/test-execution/services/e2e/index.js.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/result-collector.d.ts +51 -0
- package/v3/dist/domains/test-execution/services/e2e/result-collector.d.ts.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/result-collector.js +133 -0
- package/v3/dist/domains/test-execution/services/e2e/result-collector.js.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/step-executors.d.ts +48 -0
- package/v3/dist/domains/test-execution/services/e2e/step-executors.d.ts.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/step-executors.js +422 -0
- package/v3/dist/domains/test-execution/services/e2e/step-executors.js.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/step-retry-handler.d.ts +49 -0
- package/v3/dist/domains/test-execution/services/e2e/step-retry-handler.d.ts.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/step-retry-handler.js +146 -0
- package/v3/dist/domains/test-execution/services/e2e/step-retry-handler.js.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/types.d.ts +138 -0
- package/v3/dist/domains/test-execution/services/e2e/types.d.ts.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/types.js +65 -0
- package/v3/dist/domains/test-execution/services/e2e/types.js.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/wait-condition-handler.d.ts +33 -0
- package/v3/dist/domains/test-execution/services/e2e/wait-condition-handler.d.ts.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/wait-condition-handler.js +114 -0
- package/v3/dist/domains/test-execution/services/e2e/wait-condition-handler.js.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e-runner.d.ts +18 -392
- package/v3/dist/domains/test-execution/services/e2e-runner.d.ts.map +1 -1
- package/v3/dist/domains/test-execution/services/e2e-runner.js +25 -1757
- package/v3/dist/domains/test-execution/services/e2e-runner.js.map +1 -1
- package/v3/dist/domains/test-execution/services/flaky-detector.d.ts.map +1 -1
- package/v3/dist/domains/test-execution/services/flaky-detector.js +12 -9
- package/v3/dist/domains/test-execution/services/flaky-detector.js.map +1 -1
- package/v3/dist/domains/test-execution/services/retry-handler.d.ts.map +1 -1
- package/v3/dist/domains/test-execution/services/retry-handler.js +7 -5
- package/v3/dist/domains/test-execution/services/retry-handler.js.map +1 -1
- package/v3/dist/domains/test-execution/services/test-executor.d.ts.map +1 -1
- package/v3/dist/domains/test-execution/services/test-executor.js +4 -3
- package/v3/dist/domains/test-execution/services/test-executor.js.map +1 -1
- package/v3/dist/domains/visual-accessibility/coordinator.d.ts +70 -0
- package/v3/dist/domains/visual-accessibility/coordinator.d.ts.map +1 -1
- package/v3/dist/domains/visual-accessibility/coordinator.js +172 -0
- package/v3/dist/domains/visual-accessibility/coordinator.js.map +1 -1
- package/v3/dist/domains/visual-accessibility/plugin.d.ts +2 -1
- package/v3/dist/domains/visual-accessibility/plugin.d.ts.map +1 -1
- package/v3/dist/domains/visual-accessibility/plugin.js +63 -0
- package/v3/dist/domains/visual-accessibility/plugin.js.map +1 -1
- package/v3/dist/domains/visual-accessibility/services/accessibility-tester.d.ts.map +1 -1
- package/v3/dist/domains/visual-accessibility/services/accessibility-tester.js +3 -2
- package/v3/dist/domains/visual-accessibility/services/accessibility-tester.js.map +1 -1
- package/v3/dist/domains/visual-accessibility/services/browser-security-scanner.d.ts.map +1 -1
- package/v3/dist/domains/visual-accessibility/services/browser-security-scanner.js +22 -12
- package/v3/dist/domains/visual-accessibility/services/browser-security-scanner.js.map +1 -1
- package/v3/dist/domains/visual-accessibility/services/viewport-capture.d.ts.map +1 -1
- package/v3/dist/domains/visual-accessibility/services/viewport-capture.js +3 -2
- package/v3/dist/domains/visual-accessibility/services/viewport-capture.js.map +1 -1
- package/v3/dist/domains/visual-accessibility/services/visual-regression.d.ts.map +1 -1
- package/v3/dist/domains/visual-accessibility/services/visual-regression.js +3 -2
- package/v3/dist/domains/visual-accessibility/services/visual-regression.js.map +1 -1
- package/v3/dist/hooks/cross-phase-hooks.d.ts +42 -0
- package/v3/dist/hooks/cross-phase-hooks.d.ts.map +1 -0
- package/v3/dist/hooks/cross-phase-hooks.js +338 -0
- package/v3/dist/hooks/cross-phase-hooks.js.map +1 -0
- package/v3/dist/hooks/index.d.ts +9 -0
- package/v3/dist/hooks/index.d.ts.map +1 -0
- package/v3/dist/hooks/index.js +9 -0
- package/v3/dist/hooks/index.js.map +1 -0
- package/v3/dist/init/agents-installer.d.ts.map +1 -1
- package/v3/dist/init/agents-installer.js +6 -4
- package/v3/dist/init/agents-installer.js.map +1 -1
- package/v3/dist/init/enhancements/claude-flow-adapter.d.ts.map +1 -1
- package/v3/dist/init/enhancements/claude-flow-adapter.js +15 -9
- package/v3/dist/init/enhancements/claude-flow-adapter.js.map +1 -1
- package/v3/dist/init/enhancements/detector.js +6 -4
- package/v3/dist/init/enhancements/detector.js.map +1 -1
- package/v3/dist/init/init-wizard.d.ts +5 -0
- package/v3/dist/init/init-wizard.d.ts.map +1 -1
- package/v3/dist/init/init-wizard.js +74 -11
- package/v3/dist/init/init-wizard.js.map +1 -1
- package/v3/dist/init/migration/data-migrator.d.ts.map +1 -1
- package/v3/dist/init/migration/data-migrator.js +6 -4
- package/v3/dist/init/migration/data-migrator.js.map +1 -1
- package/v3/dist/init/phases/02-analysis.js +2 -2
- package/v3/dist/init/phases/02-analysis.js.map +1 -1
- package/v3/dist/init/phases/04-database.d.ts.map +1 -1
- package/v3/dist/init/phases/04-database.js +0 -1
- package/v3/dist/init/phases/04-database.js.map +1 -1
- package/v3/dist/init/phases/11-claude-md.d.ts.map +1 -1
- package/v3/dist/init/phases/11-claude-md.js +25 -0
- package/v3/dist/init/phases/11-claude-md.js.map +1 -1
- package/v3/dist/init/phases/12-verification.d.ts.map +1 -1
- package/v3/dist/init/phases/12-verification.js +2 -1
- package/v3/dist/init/phases/12-verification.js.map +1 -1
- package/v3/dist/init/project-analyzer.d.ts.map +1 -1
- package/v3/dist/init/project-analyzer.js +12 -8
- package/v3/dist/init/project-analyzer.js.map +1 -1
- package/v3/dist/init/skills-installer.d.ts.map +1 -1
- package/v3/dist/init/skills-installer.js +6 -4
- package/v3/dist/init/skills-installer.js.map +1 -1
- package/v3/dist/init/token-bootstrap.d.ts.map +1 -1
- package/v3/dist/init/token-bootstrap.js +2 -1
- package/v3/dist/init/token-bootstrap.js.map +1 -1
- package/v3/dist/integrations/agent-booster-wasm/index.d.ts.map +1 -1
- package/v3/dist/integrations/agent-booster-wasm/index.js +8 -4
- package/v3/dist/integrations/agent-booster-wasm/index.js.map +1 -1
- package/v3/dist/integrations/agentic-flow/model-router/signal-collector.d.ts.map +1 -1
- package/v3/dist/integrations/agentic-flow/model-router/signal-collector.js +3 -2
- package/v3/dist/integrations/agentic-flow/model-router/signal-collector.js.map +1 -1
- package/v3/dist/integrations/agentic-flow/reasoning-bank/experience-replay.d.ts.map +1 -1
- package/v3/dist/integrations/agentic-flow/reasoning-bank/experience-replay.js.map +1 -1
- package/v3/dist/integrations/agentic-flow/reasoning-bank/trajectory-tracker.d.ts.map +1 -1
- package/v3/dist/integrations/agentic-flow/reasoning-bank/trajectory-tracker.js.map +1 -1
- package/v3/dist/integrations/browser/agent-browser/client.d.ts.map +1 -1
- package/v3/dist/integrations/browser/agent-browser/client.js +9 -6
- package/v3/dist/integrations/browser/agent-browser/client.js.map +1 -1
- package/v3/dist/integrations/browser/agent-browser/command-executor.d.ts.map +1 -1
- package/v3/dist/integrations/browser/agent-browser/command-executor.js +3 -2
- package/v3/dist/integrations/browser/agent-browser/command-executor.js.map +1 -1
- package/v3/dist/integrations/browser/index.d.ts +1 -0
- package/v3/dist/integrations/browser/index.d.ts.map +1 -1
- package/v3/dist/integrations/browser/index.js +6 -0
- package/v3/dist/integrations/browser/index.js.map +1 -1
- package/v3/dist/integrations/browser/web-content-fetcher.d.ts +154 -0
- package/v3/dist/integrations/browser/web-content-fetcher.d.ts.map +1 -0
- package/v3/dist/integrations/browser/web-content-fetcher.js +529 -0
- package/v3/dist/integrations/browser/web-content-fetcher.js.map +1 -0
- package/v3/dist/integrations/coherence/threshold-tuner.d.ts.map +1 -1
- package/v3/dist/integrations/coherence/threshold-tuner.js +3 -2
- package/v3/dist/integrations/coherence/threshold-tuner.js.map +1 -1
- package/v3/dist/integrations/coherence/wasm-loader.d.ts.map +1 -1
- package/v3/dist/integrations/coherence/wasm-loader.js +3 -2
- package/v3/dist/integrations/coherence/wasm-loader.js.map +1 -1
- package/v3/dist/integrations/n8n/agent-factory.d.ts.map +1 -1
- package/v3/dist/integrations/n8n/agent-factory.js +6 -4
- package/v3/dist/integrations/n8n/agent-factory.js.map +1 -1
- package/v3/dist/integrations/rl-suite/persistence/q-value-store.d.ts.map +1 -1
- package/v3/dist/integrations/rl-suite/persistence/q-value-store.js.map +1 -1
- package/v3/dist/integrations/ruvector/sona-persistence.d.ts.map +1 -1
- package/v3/dist/integrations/ruvector/sona-persistence.js +6 -4
- package/v3/dist/integrations/ruvector/sona-persistence.js.map +1 -1
- package/v3/dist/integrations/vibium/client.d.ts.map +1 -1
- package/v3/dist/integrations/vibium/client.js +3 -2
- package/v3/dist/integrations/vibium/client.js.map +1 -1
- package/v3/dist/kernel/agent-coordinator.d.ts +1 -1
- package/v3/dist/kernel/agent-coordinator.d.ts.map +1 -1
- package/v3/dist/kernel/agent-coordinator.js +4 -4
- package/v3/dist/kernel/agent-coordinator.js.map +1 -1
- package/v3/dist/kernel/constants.d.ts +155 -0
- package/v3/dist/kernel/constants.d.ts.map +1 -0
- package/v3/dist/kernel/constants.js +169 -0
- package/v3/dist/kernel/constants.js.map +1 -0
- package/v3/dist/kernel/event-bus.d.ts +8 -0
- package/v3/dist/kernel/event-bus.d.ts.map +1 -1
- package/v3/dist/kernel/event-bus.js +79 -17
- package/v3/dist/kernel/event-bus.js.map +1 -1
- package/v3/dist/kernel/hybrid-backend.d.ts.map +1 -1
- package/v3/dist/kernel/hybrid-backend.js +4 -3
- package/v3/dist/kernel/hybrid-backend.js.map +1 -1
- package/v3/dist/kernel/kernel.d.ts.map +1 -1
- package/v3/dist/kernel/kernel.js +3 -2
- package/v3/dist/kernel/kernel.js.map +1 -1
- package/v3/dist/kernel/memory-backend.d.ts.map +1 -1
- package/v3/dist/kernel/memory-backend.js +4 -3
- package/v3/dist/kernel/memory-backend.js.map +1 -1
- package/v3/dist/kernel/unified-memory.d.ts.map +1 -1
- package/v3/dist/kernel/unified-memory.js +14 -11
- package/v3/dist/kernel/unified-memory.js.map +1 -1
- package/v3/dist/kernel/unified-persistence.js +3 -2
- package/v3/dist/kernel/unified-persistence.js.map +1 -1
- package/v3/dist/learning/aqe-learning-engine.d.ts.map +1 -1
- package/v3/dist/learning/aqe-learning-engine.js +12 -8
- package/v3/dist/learning/aqe-learning-engine.js.map +1 -1
- package/v3/dist/learning/dream/index.d.ts +1 -1
- package/v3/dist/learning/dream/index.d.ts.map +1 -1
- package/v3/dist/learning/dream/index.js +3 -1
- package/v3/dist/learning/dream/index.js.map +1 -1
- package/v3/dist/learning/dream/spreading-activation.d.ts +41 -0
- package/v3/dist/learning/dream/spreading-activation.d.ts.map +1 -1
- package/v3/dist/learning/dream/spreading-activation.js +79 -0
- package/v3/dist/learning/dream/spreading-activation.js.map +1 -1
- package/v3/dist/learning/pattern-store.d.ts.map +1 -1
- package/v3/dist/learning/pattern-store.js +16 -6
- package/v3/dist/learning/pattern-store.js.map +1 -1
- package/v3/dist/learning/real-embeddings.d.ts.map +1 -1
- package/v3/dist/learning/real-embeddings.js +7 -1
- package/v3/dist/learning/real-embeddings.js.map +1 -1
- package/v3/dist/learning/sqlite-persistence.d.ts +1 -1
- package/v3/dist/learning/sqlite-persistence.d.ts.map +1 -1
- package/v3/dist/learning/sqlite-persistence.js.map +1 -1
- package/v3/dist/logging/console-logger.d.ts +96 -0
- package/v3/dist/logging/console-logger.d.ts.map +1 -0
- package/v3/dist/logging/console-logger.js +247 -0
- package/v3/dist/logging/console-logger.js.map +1 -0
- package/v3/dist/logging/index.d.ts +42 -0
- package/v3/dist/logging/index.d.ts.map +1 -0
- package/v3/dist/logging/index.js +39 -0
- package/v3/dist/logging/index.js.map +1 -0
- package/v3/dist/logging/logger-factory.d.ts +145 -0
- package/v3/dist/logging/logger-factory.d.ts.map +1 -0
- package/v3/dist/logging/logger-factory.js +218 -0
- package/v3/dist/logging/logger-factory.js.map +1 -0
- package/v3/dist/logging/logger.d.ts +89 -0
- package/v3/dist/logging/logger.d.ts.map +1 -0
- package/v3/dist/logging/logger.js +74 -0
- package/v3/dist/logging/logger.js.map +1 -0
- package/v3/dist/mcp/bundle.js +11334 -7497
- package/v3/dist/mcp/handlers/agent-handlers.js +2 -2
- package/v3/dist/mcp/handlers/agent-handlers.js.map +1 -1
- package/v3/dist/mcp/handlers/core-handlers.d.ts +2 -0
- package/v3/dist/mcp/handlers/core-handlers.d.ts.map +1 -1
- package/v3/dist/mcp/handlers/core-handlers.js +33 -0
- package/v3/dist/mcp/handlers/core-handlers.js.map +1 -1
- package/v3/dist/mcp/handlers/cross-phase-handlers.d.ts +110 -0
- package/v3/dist/mcp/handlers/cross-phase-handlers.d.ts.map +1 -0
- package/v3/dist/mcp/handlers/cross-phase-handlers.js +216 -0
- package/v3/dist/mcp/handlers/cross-phase-handlers.js.map +1 -0
- package/v3/dist/mcp/handlers/domain-handler-configs.d.ts +151 -0
- package/v3/dist/mcp/handlers/domain-handler-configs.d.ts.map +1 -0
- package/v3/dist/mcp/handlers/domain-handler-configs.js +486 -0
- package/v3/dist/mcp/handlers/domain-handler-configs.js.map +1 -0
- package/v3/dist/mcp/handlers/domain-handlers.d.ts +174 -120
- package/v3/dist/mcp/handlers/domain-handlers.d.ts.map +1 -1
- package/v3/dist/mcp/handlers/domain-handlers.js +178 -1049
- package/v3/dist/mcp/handlers/domain-handlers.js.map +1 -1
- package/v3/dist/mcp/handlers/handler-factory.d.ts +182 -0
- package/v3/dist/mcp/handlers/handler-factory.d.ts.map +1 -0
- package/v3/dist/mcp/handlers/handler-factory.js +327 -0
- package/v3/dist/mcp/handlers/handler-factory.js.map +1 -0
- package/v3/dist/mcp/handlers/index.d.ts +1 -0
- package/v3/dist/mcp/handlers/index.d.ts.map +1 -1
- package/v3/dist/mcp/handlers/index.js +2 -0
- package/v3/dist/mcp/handlers/index.js.map +1 -1
- package/v3/dist/mcp/handlers/task-handlers.d.ts +1 -0
- package/v3/dist/mcp/handlers/task-handlers.d.ts.map +1 -1
- package/v3/dist/mcp/handlers/task-handlers.js +91 -7
- package/v3/dist/mcp/handlers/task-handlers.js.map +1 -1
- package/v3/dist/mcp/server.d.ts.map +1 -1
- package/v3/dist/mcp/server.js +107 -1
- package/v3/dist/mcp/server.js.map +1 -1
- package/v3/dist/mcp/types.d.ts +5 -3
- package/v3/dist/mcp/types.d.ts.map +1 -1
- package/v3/dist/memory/cross-phase-memory.d.ts +55 -0
- package/v3/dist/memory/cross-phase-memory.d.ts.map +1 -0
- package/v3/dist/memory/cross-phase-memory.js +265 -0
- package/v3/dist/memory/cross-phase-memory.js.map +1 -0
- package/v3/dist/memory/index.d.ts +9 -0
- package/v3/dist/memory/index.d.ts.map +1 -0
- package/v3/dist/memory/index.js +9 -0
- package/v3/dist/memory/index.js.map +1 -0
- package/v3/dist/shared/io/file-reader.d.ts.map +1 -1
- package/v3/dist/shared/io/file-reader.js +3 -2
- package/v3/dist/shared/io/file-reader.js.map +1 -1
- package/v3/dist/shared/utils/binary-insert.d.ts +85 -0
- package/v3/dist/shared/utils/binary-insert.d.ts.map +1 -0
- package/v3/dist/shared/utils/binary-insert.js +122 -0
- package/v3/dist/shared/utils/binary-insert.js.map +1 -0
- package/v3/dist/shared/utils/index.d.ts +1 -0
- package/v3/dist/shared/utils/index.d.ts.map +1 -1
- package/v3/dist/shared/utils/index.js +1 -0
- package/v3/dist/shared/utils/index.js.map +1 -1
- package/v3/dist/strange-loop/belief-reconciler.d.ts.map +1 -1
- package/v3/dist/strange-loop/belief-reconciler.js +3 -2
- package/v3/dist/strange-loop/belief-reconciler.js.map +1 -1
- package/v3/dist/sync/claude-flow-bridge.d.ts.map +1 -1
- package/v3/dist/sync/claude-flow-bridge.js +6 -4
- package/v3/dist/sync/claude-flow-bridge.js.map +1 -1
- package/v3/dist/sync/cloud/postgres-writer.d.ts.map +1 -1
- package/v3/dist/sync/cloud/postgres-writer.js +0 -1
- package/v3/dist/sync/cloud/postgres-writer.js.map +1 -1
- package/v3/dist/sync/readers/sqlite-reader.d.ts.map +1 -1
- package/v3/dist/sync/readers/sqlite-reader.js +3 -2
- package/v3/dist/sync/readers/sqlite-reader.js.map +1 -1
- package/v3/dist/test-scheduling/flaky-tracking/flaky-tracker.d.ts.map +1 -1
- package/v3/dist/test-scheduling/flaky-tracking/flaky-tracker.js +3 -2
- package/v3/dist/test-scheduling/flaky-tracking/flaky-tracker.js.map +1 -1
- package/v3/dist/test-scheduling/git-aware/test-selector.d.ts.map +1 -1
- package/v3/dist/test-scheduling/git-aware/test-selector.js +3 -2
- package/v3/dist/test-scheduling/git-aware/test-selector.js.map +1 -1
- package/v3/dist/types/cross-phase-signals.d.ts +119 -0
- package/v3/dist/types/cross-phase-signals.d.ts.map +1 -0
- package/v3/dist/types/cross-phase-signals.js +33 -0
- package/v3/dist/types/cross-phase-signals.js.map +1 -0
- package/v3/dist/types/index.d.ts +9 -0
- package/v3/dist/types/index.d.ts.map +1 -0
- package/v3/dist/types/index.js +9 -0
- package/v3/dist/types/index.js.map +1 -0
- package/v3/dist/workers/worker-manager.d.ts.map +1 -1
- package/v3/dist/workers/worker-manager.js +3 -2
- package/v3/dist/workers/worker-manager.js.map +1 -1
- package/v3/dist/workflows/browser/workflow-loader.d.ts +3 -3
- package/v3/dist/workflows/browser/workflow-loader.d.ts.map +1 -1
- package/v3/dist/workflows/browser/workflow-loader.js.map +1 -1
- package/v3/package.json +4 -1
|
@@ -0,0 +1,1143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - QCSD Ideation Swarm Plugin
|
|
3
|
+
*
|
|
4
|
+
* Implements the QCSD (Quality Conscious Software Delivery) Ideation phase
|
|
5
|
+
* using James Bach's HTSM v6.3 framework for shift-left quality engineering.
|
|
6
|
+
*
|
|
7
|
+
* This plugin registers workflow actions that enable the qcsd-ideation-swarm
|
|
8
|
+
* workflow to orchestrate multi-agent quality assessment during PI/Sprint Planning.
|
|
9
|
+
*
|
|
10
|
+
* HTSM Quality Categories:
|
|
11
|
+
* 1. Capability - Core functionality
|
|
12
|
+
* 2. Reliability - Consistency under stress
|
|
13
|
+
* 3. Usability - User experience
|
|
14
|
+
* 4. Charisma - Aesthetics and appeal
|
|
15
|
+
* 5. Security - Protection mechanisms
|
|
16
|
+
* 6. Scalability - Growth handling
|
|
17
|
+
* 7. Compatibility - Integration factors
|
|
18
|
+
* 8. Performance - Speed and efficiency
|
|
19
|
+
* 9. Installability - Deployment ease
|
|
20
|
+
* 10. Supportability - Maintenance factors
|
|
21
|
+
*/
|
|
22
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
23
|
+
import { ok, err } from '../../shared/types/index.js';
|
|
24
|
+
// ============================================================================
|
|
25
|
+
// QCSD Ideation Plugin
|
|
26
|
+
// ============================================================================
|
|
27
|
+
export class QCSDIdeationPlugin {
|
|
28
|
+
initialized = false;
|
|
29
|
+
memory;
|
|
30
|
+
constructor(memory) {
|
|
31
|
+
this.memory = memory;
|
|
32
|
+
}
|
|
33
|
+
async initialize() {
|
|
34
|
+
if (this.initialized)
|
|
35
|
+
return;
|
|
36
|
+
this.initialized = true;
|
|
37
|
+
}
|
|
38
|
+
async dispose() {
|
|
39
|
+
this.initialized = false;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Register workflow actions with the orchestrator
|
|
43
|
+
*/
|
|
44
|
+
registerWorkflowActions(orchestrator) {
|
|
45
|
+
if (!this.initialized) {
|
|
46
|
+
throw new Error('QCSDIdeationPlugin must be initialized before registering workflow actions');
|
|
47
|
+
}
|
|
48
|
+
// Register analyzeQualityCriteria action
|
|
49
|
+
orchestrator.registerAction('requirements-validation', 'analyzeQualityCriteria', this.analyzeQualityCriteria.bind(this));
|
|
50
|
+
// Register assessTestability action
|
|
51
|
+
orchestrator.registerAction('requirements-validation', 'assessTestability', this.assessTestability.bind(this));
|
|
52
|
+
// Register assessRisks action
|
|
53
|
+
orchestrator.registerAction('requirements-validation', 'assessRisks', this.assessRisks.bind(this));
|
|
54
|
+
// Register validateRequirements action
|
|
55
|
+
orchestrator.registerAction('requirements-validation', 'validateRequirements', this.validateRequirements.bind(this));
|
|
56
|
+
// Register modelSecurityThreats action
|
|
57
|
+
orchestrator.registerAction('security-compliance', 'modelSecurityThreats', this.modelSecurityThreats.bind(this));
|
|
58
|
+
// Register generateIdeationReport action
|
|
59
|
+
orchestrator.registerAction('requirements-validation', 'generateIdeationReport', this.generateIdeationReport.bind(this));
|
|
60
|
+
// Register storeIdeationLearnings action
|
|
61
|
+
orchestrator.registerAction('learning-optimization', 'storeIdeationLearnings', this.storeIdeationLearnings.bind(this));
|
|
62
|
+
// Register extractWebsiteContent action for live URL analysis
|
|
63
|
+
orchestrator.registerAction('requirements-validation', 'extractWebsiteContent', this.extractWebsiteContent.bind(this));
|
|
64
|
+
// Register auditAccessibility action for HAS_UI conditional
|
|
65
|
+
orchestrator.registerAction('visual-accessibility', 'auditAccessibility', this.auditAccessibility.bind(this));
|
|
66
|
+
// Register analyzeQualityExperience action for HAS_UX conditional
|
|
67
|
+
orchestrator.registerAction('coordination', 'analyzeQualityExperience', this.analyzeQualityExperience.bind(this));
|
|
68
|
+
}
|
|
69
|
+
// ============================================================================
|
|
70
|
+
// Workflow Actions
|
|
71
|
+
// ============================================================================
|
|
72
|
+
/**
|
|
73
|
+
* Extract content from a live website URL for QCSD analysis
|
|
74
|
+
* Converts website features into epic-like content for quality assessment
|
|
75
|
+
*/
|
|
76
|
+
async extractWebsiteContent(input, context) {
|
|
77
|
+
try {
|
|
78
|
+
const url = input.url || context.input.url;
|
|
79
|
+
if (!url) {
|
|
80
|
+
// No URL provided - pass through existing content
|
|
81
|
+
return ok({
|
|
82
|
+
url: '',
|
|
83
|
+
isWebsite: false,
|
|
84
|
+
extractedDescription: context.input.description || '',
|
|
85
|
+
extractedFeatures: [],
|
|
86
|
+
extractedAcceptanceCriteria: context.input.acceptanceCriteria || [],
|
|
87
|
+
detectedFlags: {
|
|
88
|
+
hasUI: false,
|
|
89
|
+
hasSecurity: false,
|
|
90
|
+
hasUX: false,
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
// Validate URL
|
|
95
|
+
let parsedUrl;
|
|
96
|
+
try {
|
|
97
|
+
parsedUrl = new URL(url);
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return err(new Error(`Invalid URL: ${url}`));
|
|
101
|
+
}
|
|
102
|
+
// Fetch website content
|
|
103
|
+
const fetchResult = await this.fetchWebsiteContent(parsedUrl.toString());
|
|
104
|
+
if (!fetchResult.success) {
|
|
105
|
+
return err(fetchResult.error);
|
|
106
|
+
}
|
|
107
|
+
const htmlContent = fetchResult.value;
|
|
108
|
+
// Extract features and structure from HTML
|
|
109
|
+
const extraction = this.parseWebsiteContent(htmlContent, parsedUrl);
|
|
110
|
+
// Build epic-like description from extracted content
|
|
111
|
+
const description = this.buildEpicDescription(extraction, parsedUrl);
|
|
112
|
+
// Generate acceptance criteria from detected features
|
|
113
|
+
const acceptanceCriteria = this.generateAcceptanceCriteria(extraction);
|
|
114
|
+
// Detect content flags for conditional agents
|
|
115
|
+
const detectedFlags = this.detectContentFlags(htmlContent, extraction);
|
|
116
|
+
return ok({
|
|
117
|
+
url: parsedUrl.toString(),
|
|
118
|
+
isWebsite: true,
|
|
119
|
+
extractedDescription: description,
|
|
120
|
+
extractedFeatures: extraction.features,
|
|
121
|
+
extractedAcceptanceCriteria: acceptanceCriteria,
|
|
122
|
+
detectedFlags,
|
|
123
|
+
metadata: {
|
|
124
|
+
title: extraction.title,
|
|
125
|
+
pageCount: 1,
|
|
126
|
+
extractedAt: new Date().toISOString(),
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
return err(new Error(`Website extraction failed: ${error instanceof Error ? error.message : String(error)}`));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Fetch website content via HTTP
|
|
136
|
+
*/
|
|
137
|
+
async fetchWebsiteContent(url) {
|
|
138
|
+
try {
|
|
139
|
+
const response = await fetch(url, {
|
|
140
|
+
headers: {
|
|
141
|
+
'User-Agent': 'AQE-QCSD-Ideation-Swarm/1.0 (Quality Assessment Bot)',
|
|
142
|
+
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
|
143
|
+
'Accept-Language': 'en-US,en;q=0.5',
|
|
144
|
+
},
|
|
145
|
+
signal: AbortSignal.timeout(30000), // 30 second timeout
|
|
146
|
+
});
|
|
147
|
+
if (!response.ok) {
|
|
148
|
+
return err(new Error(`HTTP ${response.status}: ${response.statusText}`));
|
|
149
|
+
}
|
|
150
|
+
const html = await response.text();
|
|
151
|
+
return ok(html);
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
return err(new Error(`Fetch failed: ${error instanceof Error ? error.message : String(error)}`));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Parse HTML content to extract website features
|
|
159
|
+
*/
|
|
160
|
+
parseWebsiteContent(html, url) {
|
|
161
|
+
const features = [];
|
|
162
|
+
const uiComponents = [];
|
|
163
|
+
const securityFeatures = [];
|
|
164
|
+
// Extract title
|
|
165
|
+
const titleMatch = html.match(/<title[^>]*>([^<]+)<\/title>/i);
|
|
166
|
+
const title = titleMatch ? titleMatch[1].trim() : url.hostname;
|
|
167
|
+
// Detect common e-commerce/web app features
|
|
168
|
+
const featurePatterns = [
|
|
169
|
+
{ pattern: /type\s*=\s*["']search["']/i, feature: 'Search functionality', ui: 'Search input' },
|
|
170
|
+
{ pattern: /shopping[-_]?cart|cart[-_]?icon|add[-_]?to[-_]?cart/i, feature: 'Shopping cart', ui: 'Cart component' },
|
|
171
|
+
{ pattern: /login|sign[-_]?in|log[-_]?in/i, feature: 'User authentication', ui: 'Login form' },
|
|
172
|
+
{ pattern: /register|sign[-_]?up|create[-_]?account/i, feature: 'User registration', ui: 'Registration form' },
|
|
173
|
+
{ pattern: /checkout|payment|pay[-_]?now/i, feature: 'Checkout process', ui: 'Checkout flow' },
|
|
174
|
+
{ pattern: /product[-_]?list|product[-_]?grid|catalog/i, feature: 'Product catalog', ui: 'Product grid' },
|
|
175
|
+
{ pattern: /filter|sort[-_]?by|refine/i, feature: 'Filtering and sorting', ui: 'Filter controls' },
|
|
176
|
+
{ pattern: /wishlist|favorites|save[-_]?for[-_]?later/i, feature: 'Wishlist functionality', ui: 'Wishlist button' },
|
|
177
|
+
{ pattern: /review|rating|stars/i, feature: 'Reviews and ratings', ui: 'Rating component' },
|
|
178
|
+
{ pattern: /newsletter|subscribe|email[-_]?signup/i, feature: 'Newsletter subscription', ui: 'Subscription form' },
|
|
179
|
+
{ pattern: /navigation|nav[-_]?menu|main[-_]?menu/i, feature: 'Site navigation', ui: 'Navigation menu' },
|
|
180
|
+
{ pattern: /footer|site[-_]?map/i, feature: 'Footer navigation', ui: 'Footer component' },
|
|
181
|
+
{ pattern: /modal|popup|dialog/i, feature: 'Modal dialogs', ui: 'Modal component' },
|
|
182
|
+
{ pattern: /carousel|slider|slideshow/i, feature: 'Image carousel', ui: 'Carousel component' },
|
|
183
|
+
{ pattern: /accordion|collapsible|expandable/i, feature: 'Accordion sections', ui: 'Accordion component' },
|
|
184
|
+
{ pattern: /tab|tabbed[-_]?content/i, feature: 'Tabbed content', ui: 'Tab component' },
|
|
185
|
+
{ pattern: /form|input|textarea|select/i, feature: 'Form interactions', ui: 'Form elements' },
|
|
186
|
+
{ pattern: /video|player|embed/i, feature: 'Video content', ui: 'Video player' },
|
|
187
|
+
{ pattern: /chat|support|help[-_]?desk/i, feature: 'Customer support', ui: 'Chat widget' },
|
|
188
|
+
{ pattern: /cookie|consent|gdpr|privacy/i, feature: 'Privacy compliance', ui: 'Consent banner' },
|
|
189
|
+
];
|
|
190
|
+
for (const { pattern, feature, ui } of featurePatterns) {
|
|
191
|
+
if (pattern.test(html)) {
|
|
192
|
+
features.push(feature);
|
|
193
|
+
if (ui)
|
|
194
|
+
uiComponents.push(ui);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
// Detect security-related features
|
|
198
|
+
const securityPatterns = [
|
|
199
|
+
{ pattern: /password|passwd/i, feature: 'Password handling' },
|
|
200
|
+
{ pattern: /https|ssl|secure/i, feature: 'Secure connection' },
|
|
201
|
+
{ pattern: /oauth|sso|single[-_]?sign[-_]?on/i, feature: 'OAuth/SSO authentication' },
|
|
202
|
+
{ pattern: /2fa|two[-_]?factor|mfa/i, feature: 'Multi-factor authentication' },
|
|
203
|
+
{ pattern: /captcha|recaptcha/i, feature: 'Bot protection' },
|
|
204
|
+
{ pattern: /csrf|token/i, feature: 'CSRF protection' },
|
|
205
|
+
{ pattern: /encrypt|crypto/i, feature: 'Data encryption' },
|
|
206
|
+
];
|
|
207
|
+
for (const { pattern, feature } of securityPatterns) {
|
|
208
|
+
if (pattern.test(html)) {
|
|
209
|
+
securityFeatures.push(feature);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
// Count interactive elements
|
|
213
|
+
const formCount = (html.match(/<form/gi) || []).length;
|
|
214
|
+
const buttonCount = (html.match(/<button/gi) || []).length;
|
|
215
|
+
const inputCount = (html.match(/<input/gi) || []).length;
|
|
216
|
+
const linkCount = (html.match(/<a\s+[^>]*href/gi) || []).length;
|
|
217
|
+
const imageCount = (html.match(/<img/gi) || []).length;
|
|
218
|
+
return {
|
|
219
|
+
title,
|
|
220
|
+
features: [...new Set(features)], // Dedupe
|
|
221
|
+
uiComponents: [...new Set(uiComponents)],
|
|
222
|
+
securityFeatures: [...new Set(securityFeatures)],
|
|
223
|
+
metrics: {
|
|
224
|
+
formCount,
|
|
225
|
+
buttonCount,
|
|
226
|
+
inputCount,
|
|
227
|
+
linkCount,
|
|
228
|
+
imageCount,
|
|
229
|
+
},
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Build epic-like description from extracted content
|
|
234
|
+
*/
|
|
235
|
+
buildEpicDescription(extraction, url) {
|
|
236
|
+
const lines = [
|
|
237
|
+
`## Website Analysis: ${extraction.title}`,
|
|
238
|
+
`**URL**: ${url.toString()}`,
|
|
239
|
+
`**Domain**: ${url.hostname}`,
|
|
240
|
+
'',
|
|
241
|
+
'### Detected Features',
|
|
242
|
+
];
|
|
243
|
+
if (extraction.features.length > 0) {
|
|
244
|
+
for (const feature of extraction.features) {
|
|
245
|
+
lines.push(`- ${feature}`);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
lines.push('- Basic web content');
|
|
250
|
+
}
|
|
251
|
+
lines.push('', '### UI Components');
|
|
252
|
+
if (extraction.uiComponents.length > 0) {
|
|
253
|
+
for (const component of extraction.uiComponents) {
|
|
254
|
+
lines.push(`- ${component}`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
lines.push('- Standard HTML elements');
|
|
259
|
+
}
|
|
260
|
+
if (extraction.securityFeatures.length > 0) {
|
|
261
|
+
lines.push('', '### Security Features');
|
|
262
|
+
for (const feature of extraction.securityFeatures) {
|
|
263
|
+
lines.push(`- ${feature}`);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
lines.push('', '### Page Metrics');
|
|
267
|
+
lines.push(`- Forms: ${extraction.metrics.formCount}`);
|
|
268
|
+
lines.push(`- Buttons: ${extraction.metrics.buttonCount}`);
|
|
269
|
+
lines.push(`- Input fields: ${extraction.metrics.inputCount}`);
|
|
270
|
+
lines.push(`- Links: ${extraction.metrics.linkCount}`);
|
|
271
|
+
lines.push(`- Images: ${extraction.metrics.imageCount}`);
|
|
272
|
+
return lines.join('\n');
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Generate acceptance criteria from detected features
|
|
276
|
+
*/
|
|
277
|
+
generateAcceptanceCriteria(extraction) {
|
|
278
|
+
const criteria = [];
|
|
279
|
+
// Map features to acceptance criteria
|
|
280
|
+
const featureToCriteria = {
|
|
281
|
+
'Search functionality': 'User can search for content and receive relevant results',
|
|
282
|
+
'Shopping cart': 'User can add items to cart and view cart contents',
|
|
283
|
+
'User authentication': 'User can log in with valid credentials',
|
|
284
|
+
'User registration': 'New user can create an account',
|
|
285
|
+
'Checkout process': 'User can complete purchase with valid payment',
|
|
286
|
+
'Product catalog': 'User can browse and view product listings',
|
|
287
|
+
'Filtering and sorting': 'User can filter and sort content by various criteria',
|
|
288
|
+
'Wishlist functionality': 'User can save items for later',
|
|
289
|
+
'Reviews and ratings': 'User can view and submit reviews',
|
|
290
|
+
'Newsletter subscription': 'User can subscribe to email updates',
|
|
291
|
+
'Site navigation': 'User can navigate between all main sections',
|
|
292
|
+
'Modal dialogs': 'Modal dialogs are accessible and dismissible',
|
|
293
|
+
'Form interactions': 'All forms validate input and show clear error messages',
|
|
294
|
+
'Video content': 'Video content is playable and accessible',
|
|
295
|
+
'Customer support': 'User can access help and support resources',
|
|
296
|
+
'Privacy compliance': 'Cookie consent is properly implemented',
|
|
297
|
+
};
|
|
298
|
+
for (const feature of extraction.features) {
|
|
299
|
+
if (featureToCriteria[feature]) {
|
|
300
|
+
criteria.push(featureToCriteria[feature]);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
// Add default criteria if none detected
|
|
304
|
+
if (criteria.length === 0) {
|
|
305
|
+
criteria.push('Page loads within acceptable time', 'Content is readable and well-structured', 'Navigation is intuitive');
|
|
306
|
+
}
|
|
307
|
+
return criteria;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Detect content flags for conditional agent spawning
|
|
311
|
+
*/
|
|
312
|
+
detectContentFlags(html, extraction) {
|
|
313
|
+
// HAS_UI: Any UI components or visual elements
|
|
314
|
+
const hasUI = extraction.uiComponents.length > 0 ||
|
|
315
|
+
extraction.metrics.formCount > 0 ||
|
|
316
|
+
extraction.metrics.buttonCount > 0 ||
|
|
317
|
+
/<(button|input|select|form|img|video|canvas)/i.test(html);
|
|
318
|
+
// HAS_SECURITY: Security-related features detected
|
|
319
|
+
const hasSecurity = extraction.securityFeatures.length > 0 ||
|
|
320
|
+
/login|password|auth|token|session|credential/i.test(html);
|
|
321
|
+
// HAS_UX: Interactive elements suggesting user experience concerns
|
|
322
|
+
const hasUX = extraction.features.length >= 3 ||
|
|
323
|
+
extraction.metrics.formCount >= 2 ||
|
|
324
|
+
/user[-_]?experience|ux|journey|onboarding|tutorial/i.test(html);
|
|
325
|
+
return { hasUI, hasSecurity, hasUX };
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Analyze quality criteria using HTSM v6.3 framework
|
|
329
|
+
*/
|
|
330
|
+
async analyzeQualityCriteria(input, context) {
|
|
331
|
+
try {
|
|
332
|
+
const targetId = input.targetId || context.input.targetId;
|
|
333
|
+
const targetType = input.targetType || context.input.targetType;
|
|
334
|
+
const description = input.description || context.input.description || '';
|
|
335
|
+
const acceptanceCriteria = input.acceptanceCriteria || context.input.acceptanceCriteria || [];
|
|
336
|
+
// Analyze each HTSM category
|
|
337
|
+
const criteria = this.analyzeHTSMCategories(targetId, targetType, description, acceptanceCriteria);
|
|
338
|
+
// Calculate overall quality score
|
|
339
|
+
const qualityScore = this.calculateQualityScore(criteria);
|
|
340
|
+
// Store intermediate result
|
|
341
|
+
await this.memory.set(`qcsd-ideation:quality-criteria:${targetId}`, { criteria, qualityScore, timestamp: new Date().toISOString() }, { namespace: 'qcsd-ideation', ttl: 3600 });
|
|
342
|
+
return ok({ qualityCriteria: criteria, qualityScore });
|
|
343
|
+
}
|
|
344
|
+
catch (error) {
|
|
345
|
+
return err(error instanceof Error ? error : new Error(String(error)));
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Assess testability using 10 principles
|
|
350
|
+
*/
|
|
351
|
+
async assessTestability(input, context) {
|
|
352
|
+
try {
|
|
353
|
+
const targetId = input.targetId || context.input.targetId;
|
|
354
|
+
const description = input.description || context.input.description || '';
|
|
355
|
+
const acceptanceCriteria = input.acceptanceCriteria || context.input.acceptanceCriteria || [];
|
|
356
|
+
// Assess each testability principle
|
|
357
|
+
const principles = this.assessTestabilityPrinciples(description, acceptanceCriteria);
|
|
358
|
+
// Calculate overall score
|
|
359
|
+
const overallScore = Math.round(Object.values(principles).reduce((sum, score) => sum + score, 0) / 10);
|
|
360
|
+
// Identify blockers and recommendations
|
|
361
|
+
const { blockers, recommendations } = this.identifyTestabilityIssues(principles);
|
|
362
|
+
const assessment = {
|
|
363
|
+
id: uuidv4(),
|
|
364
|
+
targetId,
|
|
365
|
+
overallScore,
|
|
366
|
+
principles,
|
|
367
|
+
blockers,
|
|
368
|
+
recommendations,
|
|
369
|
+
};
|
|
370
|
+
// Store intermediate result
|
|
371
|
+
await this.memory.set(`qcsd-ideation:testability:${targetId}`, assessment, { namespace: 'qcsd-ideation', ttl: 3600 });
|
|
372
|
+
return ok(assessment);
|
|
373
|
+
}
|
|
374
|
+
catch (error) {
|
|
375
|
+
return err(error instanceof Error ? error : new Error(String(error)));
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Assess risks
|
|
380
|
+
*/
|
|
381
|
+
async assessRisks(input, context) {
|
|
382
|
+
try {
|
|
383
|
+
const targetId = input.targetId || context.input.targetId;
|
|
384
|
+
const targetType = input.targetType || context.input.targetType;
|
|
385
|
+
const description = input.description || context.input.description || '';
|
|
386
|
+
// Analyze risk factors
|
|
387
|
+
const factors = this.analyzeRiskFactors(targetType, description);
|
|
388
|
+
// Calculate overall risk score
|
|
389
|
+
const riskScore = Math.round(factors.reduce((sum, f) => sum + f.score, 0) / factors.length * 4);
|
|
390
|
+
// Determine risk level
|
|
391
|
+
const overallRisk = this.determineRiskLevel(riskScore);
|
|
392
|
+
// Generate mitigations
|
|
393
|
+
const mitigations = this.generateMitigations(factors);
|
|
394
|
+
const assessment = {
|
|
395
|
+
id: uuidv4(),
|
|
396
|
+
targetId,
|
|
397
|
+
overallRisk,
|
|
398
|
+
riskScore,
|
|
399
|
+
factors,
|
|
400
|
+
mitigations,
|
|
401
|
+
};
|
|
402
|
+
// Store intermediate result
|
|
403
|
+
await this.memory.set(`qcsd-ideation:risk:${targetId}`, assessment, { namespace: 'qcsd-ideation', ttl: 3600 });
|
|
404
|
+
return ok(assessment);
|
|
405
|
+
}
|
|
406
|
+
catch (error) {
|
|
407
|
+
return err(error instanceof Error ? error : new Error(String(error)));
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Validate requirements for completeness
|
|
412
|
+
*/
|
|
413
|
+
async validateRequirements(input, context) {
|
|
414
|
+
try {
|
|
415
|
+
const targetId = input.targetId || context.input.targetId;
|
|
416
|
+
const description = input.description || context.input.description || '';
|
|
417
|
+
const acceptanceCriteria = input.acceptanceCriteria || context.input.acceptanceCriteria || [];
|
|
418
|
+
const issues = [];
|
|
419
|
+
const suggestions = [];
|
|
420
|
+
// Check description quality
|
|
421
|
+
if (description.length < 50) {
|
|
422
|
+
issues.push('Description is too short (< 50 characters)');
|
|
423
|
+
suggestions.push('Add more context about the business value and user need');
|
|
424
|
+
}
|
|
425
|
+
// Check for ambiguous language
|
|
426
|
+
const ambiguousTerms = ['should', 'could', 'might', 'maybe', 'possibly', 'etc', 'and so on'];
|
|
427
|
+
for (const term of ambiguousTerms) {
|
|
428
|
+
if (description.toLowerCase().includes(term)) {
|
|
429
|
+
issues.push(`Ambiguous term detected: "${term}"`);
|
|
430
|
+
suggestions.push(`Replace "${term}" with specific, measurable criteria`);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
// Check acceptance criteria
|
|
434
|
+
if (acceptanceCriteria.length === 0) {
|
|
435
|
+
issues.push('No acceptance criteria defined');
|
|
436
|
+
suggestions.push('Add Given/When/Then acceptance criteria');
|
|
437
|
+
}
|
|
438
|
+
else if (acceptanceCriteria.length < 3) {
|
|
439
|
+
issues.push('Too few acceptance criteria (< 3)');
|
|
440
|
+
suggestions.push('Consider adding criteria for happy path, error cases, and edge cases');
|
|
441
|
+
}
|
|
442
|
+
// Check for testable criteria
|
|
443
|
+
const hasTestable = acceptanceCriteria.some(ac => ac.toLowerCase().includes('given') ||
|
|
444
|
+
ac.toLowerCase().includes('when') ||
|
|
445
|
+
ac.toLowerCase().includes('then'));
|
|
446
|
+
if (!hasTestable && acceptanceCriteria.length > 0) {
|
|
447
|
+
suggestions.push('Consider using Given/When/Then format for clearer test scenarios');
|
|
448
|
+
}
|
|
449
|
+
const valid = issues.length === 0;
|
|
450
|
+
return ok({ valid, issues, suggestions });
|
|
451
|
+
}
|
|
452
|
+
catch (error) {
|
|
453
|
+
return err(error instanceof Error ? error : new Error(String(error)));
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Model security threats using STRIDE
|
|
458
|
+
*/
|
|
459
|
+
async modelSecurityThreats(input, context) {
|
|
460
|
+
try {
|
|
461
|
+
const targetId = input.targetId || context.input.targetId;
|
|
462
|
+
const description = input.description || context.input.description || '';
|
|
463
|
+
const securityCritical = input.securityCritical || context.input.securityCritical || false;
|
|
464
|
+
// Analyze STRIDE threats
|
|
465
|
+
const threats = this.analyzeSTRIDEThreats(description, securityCritical);
|
|
466
|
+
// Calculate overall risk
|
|
467
|
+
const maxScore = Math.max(...threats.map(t => t.likelihood * t.impact), 0);
|
|
468
|
+
const overallRisk = this.determineRiskLevel(maxScore * 4);
|
|
469
|
+
// Generate recommendations
|
|
470
|
+
const recommendations = this.generateSecurityRecommendations(threats);
|
|
471
|
+
const model = {
|
|
472
|
+
id: uuidv4(),
|
|
473
|
+
targetId,
|
|
474
|
+
threats,
|
|
475
|
+
overallRisk,
|
|
476
|
+
recommendations,
|
|
477
|
+
};
|
|
478
|
+
// Store intermediate result
|
|
479
|
+
await this.memory.set(`qcsd-ideation:threat-model:${targetId}`, model, { namespace: 'qcsd-ideation', ttl: 3600 });
|
|
480
|
+
return ok(model);
|
|
481
|
+
}
|
|
482
|
+
catch (error) {
|
|
483
|
+
return err(error instanceof Error ? error : new Error(String(error)));
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Generate aggregated ideation report
|
|
488
|
+
*/
|
|
489
|
+
async generateIdeationReport(input, context) {
|
|
490
|
+
try {
|
|
491
|
+
const targetId = input.targetId || context.input.targetId;
|
|
492
|
+
const targetType = (input.targetType || context.input.targetType || 'requirement');
|
|
493
|
+
// Retrieve all intermediate results
|
|
494
|
+
const qualityData = await this.memory.get(`qcsd-ideation:quality-criteria:${targetId}`);
|
|
495
|
+
const testability = await this.memory.get(`qcsd-ideation:testability:${targetId}`);
|
|
496
|
+
const risk = await this.memory.get(`qcsd-ideation:risk:${targetId}`);
|
|
497
|
+
const threatModel = await this.memory.get(`qcsd-ideation:threat-model:${targetId}`);
|
|
498
|
+
// Use context results if memory doesn't have them
|
|
499
|
+
// Cast results to Record<string, unknown> to access dynamic step outputs
|
|
500
|
+
const results = context.results;
|
|
501
|
+
const qualityCriteria = qualityData?.criteria || results['quality-criteria-analysis']?.qualityCriteria || [];
|
|
502
|
+
const qualityScore = qualityData?.qualityScore || results['quality-criteria-analysis']?.qualityScore || 0;
|
|
503
|
+
const testabilityResult = testability || results['testability-assessment'];
|
|
504
|
+
const riskResult = risk || results['risk-assessment'];
|
|
505
|
+
const threatModelResult = threatModel || results['security-threat-modeling'];
|
|
506
|
+
// Generate SWOT insights
|
|
507
|
+
const insights = this.generateSWOTInsights(qualityCriteria, testabilityResult, riskResult);
|
|
508
|
+
// Generate prioritized recommendations
|
|
509
|
+
const recommendations = this.generateRecommendations(qualityCriteria, testabilityResult, riskResult, threatModelResult);
|
|
510
|
+
// Generate test strategy
|
|
511
|
+
const testStrategy = this.generateTestStrategy(qualityCriteria, testabilityResult, riskResult);
|
|
512
|
+
// Determine development readiness
|
|
513
|
+
const blockers = this.identifyBlockers(testabilityResult, riskResult, threatModelResult);
|
|
514
|
+
const readyForDevelopment = blockers.length === 0;
|
|
515
|
+
const report = {
|
|
516
|
+
id: uuidv4(),
|
|
517
|
+
timestamp: new Date().toISOString(),
|
|
518
|
+
targetId,
|
|
519
|
+
targetType,
|
|
520
|
+
qualityCriteria,
|
|
521
|
+
qualityScore,
|
|
522
|
+
testability: testabilityResult,
|
|
523
|
+
risk: riskResult,
|
|
524
|
+
threatModel: threatModelResult,
|
|
525
|
+
insights,
|
|
526
|
+
recommendations,
|
|
527
|
+
testStrategy,
|
|
528
|
+
readyForDevelopment,
|
|
529
|
+
blockers,
|
|
530
|
+
};
|
|
531
|
+
// Store final report
|
|
532
|
+
await this.memory.set(`qcsd-ideation:report:${targetId}`, report, { namespace: 'qcsd-ideation', persist: true });
|
|
533
|
+
return ok(report);
|
|
534
|
+
}
|
|
535
|
+
catch (error) {
|
|
536
|
+
return err(error instanceof Error ? error : new Error(String(error)));
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* Store learnings for future pattern matching
|
|
541
|
+
*/
|
|
542
|
+
async storeIdeationLearnings(input, context) {
|
|
543
|
+
try {
|
|
544
|
+
const targetId = input.targetId || context.input.targetId;
|
|
545
|
+
const report = input.report || context.results['aggregate-ideation-report'];
|
|
546
|
+
if (!report) {
|
|
547
|
+
return err(new Error('No ideation report found to store'));
|
|
548
|
+
}
|
|
549
|
+
const patternId = `ideation-pattern-${Date.now()}`;
|
|
550
|
+
// Create learning pattern
|
|
551
|
+
const pattern = {
|
|
552
|
+
id: patternId,
|
|
553
|
+
timestamp: new Date().toISOString(),
|
|
554
|
+
targetType: report.targetType,
|
|
555
|
+
qualityScore: report.qualityScore,
|
|
556
|
+
testabilityScore: report.testability.overallScore,
|
|
557
|
+
riskLevel: report.risk.overallRisk,
|
|
558
|
+
blockerCount: report.blockers.length,
|
|
559
|
+
readyForDevelopment: report.readyForDevelopment,
|
|
560
|
+
// Key characteristics for pattern matching
|
|
561
|
+
features: {
|
|
562
|
+
hasSecurityThreats: !!report.threatModel && report.threatModel.threats.length > 0,
|
|
563
|
+
avgPrincipleScore: report.testability.overallScore,
|
|
564
|
+
riskFactorCount: report.risk.factors.length,
|
|
565
|
+
qualityCriteriaCount: report.qualityCriteria.length,
|
|
566
|
+
},
|
|
567
|
+
};
|
|
568
|
+
// Store pattern for learning
|
|
569
|
+
await this.memory.set(`qcsd-patterns:${patternId}`, pattern, { namespace: 'learning', persist: true });
|
|
570
|
+
// Store in pattern index for search
|
|
571
|
+
const patternIndex = await this.memory.get('qcsd-patterns:index') || [];
|
|
572
|
+
patternIndex.push(patternId);
|
|
573
|
+
await this.memory.set('qcsd-patterns:index', patternIndex, { namespace: 'learning', persist: true });
|
|
574
|
+
return ok({ stored: true, patternId });
|
|
575
|
+
}
|
|
576
|
+
catch (error) {
|
|
577
|
+
return err(error instanceof Error ? error : new Error(String(error)));
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
// ============================================================================
|
|
581
|
+
// Helper Methods
|
|
582
|
+
// ============================================================================
|
|
583
|
+
analyzeHTSMCategories(targetId, targetType, description, acceptanceCriteria) {
|
|
584
|
+
const categories = [
|
|
585
|
+
'capability',
|
|
586
|
+
'reliability',
|
|
587
|
+
'usability',
|
|
588
|
+
'charisma',
|
|
589
|
+
'security',
|
|
590
|
+
'scalability',
|
|
591
|
+
'compatibility',
|
|
592
|
+
'performance',
|
|
593
|
+
'installability',
|
|
594
|
+
'supportability',
|
|
595
|
+
];
|
|
596
|
+
const descLower = description.toLowerCase();
|
|
597
|
+
const acJoined = acceptanceCriteria.join(' ').toLowerCase();
|
|
598
|
+
return categories.map(category => {
|
|
599
|
+
const { weight, testabilityScore, risks, testIdeas } = this.analyzeCategory(category, descLower, acJoined);
|
|
600
|
+
return {
|
|
601
|
+
id: `${targetId}-${category}`,
|
|
602
|
+
category,
|
|
603
|
+
name: category.charAt(0).toUpperCase() + category.slice(1),
|
|
604
|
+
description: this.getCategoryDescription(category),
|
|
605
|
+
weight,
|
|
606
|
+
testabilityScore,
|
|
607
|
+
risks,
|
|
608
|
+
testIdeas,
|
|
609
|
+
};
|
|
610
|
+
});
|
|
611
|
+
}
|
|
612
|
+
analyzeCategory(category, description, acceptanceCriteria) {
|
|
613
|
+
const keywords = {
|
|
614
|
+
capability: ['function', 'feature', 'ability', 'can', 'must', 'shall'],
|
|
615
|
+
reliability: ['reliable', 'consistent', 'stable', 'fault', 'error', 'recover'],
|
|
616
|
+
usability: ['user', 'easy', 'intuitive', 'accessible', 'ux', 'interface'],
|
|
617
|
+
charisma: ['design', 'look', 'feel', 'brand', 'aesthetic', 'appeal'],
|
|
618
|
+
security: ['secure', 'auth', 'encrypt', 'protect', 'permission', 'role'],
|
|
619
|
+
scalability: ['scale', 'load', 'concurrent', 'throughput', 'capacity'],
|
|
620
|
+
compatibility: ['integrate', 'api', 'browser', 'device', 'version', 'legacy'],
|
|
621
|
+
performance: ['fast', 'response', 'latency', 'speed', 'efficient', 'optimize'],
|
|
622
|
+
installability: ['install', 'deploy', 'setup', 'configure', 'provision'],
|
|
623
|
+
supportability: ['log', 'monitor', 'debug', 'maintain', 'document', 'support'],
|
|
624
|
+
};
|
|
625
|
+
const categoryKeywords = keywords[category];
|
|
626
|
+
const mentionCount = categoryKeywords.filter(kw => description.includes(kw) || acceptanceCriteria.includes(kw)).length;
|
|
627
|
+
// Weight based on relevance
|
|
628
|
+
const weight = Math.min(10, 3 + mentionCount * 2);
|
|
629
|
+
// Testability based on specificity
|
|
630
|
+
const hasSpecificCriteria = categoryKeywords.some(kw => acceptanceCriteria.includes(kw));
|
|
631
|
+
const testabilityScore = hasSpecificCriteria ? 70 + Math.random() * 20 : 40 + Math.random() * 30;
|
|
632
|
+
// Generate risks
|
|
633
|
+
const risks = this.generateCategoryRisks(category, mentionCount === 0);
|
|
634
|
+
// Generate test ideas
|
|
635
|
+
const testIdeas = this.generateCategoryTestIdeas(category);
|
|
636
|
+
return { weight, testabilityScore: Math.round(testabilityScore), risks, testIdeas };
|
|
637
|
+
}
|
|
638
|
+
getCategoryDescription(category) {
|
|
639
|
+
const descriptions = {
|
|
640
|
+
capability: 'Core functionality and features the system must provide',
|
|
641
|
+
reliability: 'Consistency and stability under various conditions',
|
|
642
|
+
usability: 'Ease of use and user experience quality',
|
|
643
|
+
charisma: 'Visual appeal and brand alignment',
|
|
644
|
+
security: 'Protection against threats and unauthorized access',
|
|
645
|
+
scalability: 'Ability to handle growth and increased load',
|
|
646
|
+
compatibility: 'Integration with other systems and environments',
|
|
647
|
+
performance: 'Speed, responsiveness, and resource efficiency',
|
|
648
|
+
installability: 'Ease of deployment and configuration',
|
|
649
|
+
supportability: 'Maintainability and operational support',
|
|
650
|
+
};
|
|
651
|
+
return descriptions[category];
|
|
652
|
+
}
|
|
653
|
+
generateCategoryRisks(category, notMentioned) {
|
|
654
|
+
const risks = [];
|
|
655
|
+
if (notMentioned) {
|
|
656
|
+
risks.push(`${category.charAt(0).toUpperCase() + category.slice(1)} requirements not explicitly defined`);
|
|
657
|
+
}
|
|
658
|
+
const categoryRisks = {
|
|
659
|
+
capability: ['Feature gaps may emerge late', 'Edge cases not covered'],
|
|
660
|
+
reliability: ['System may fail under load', 'Error handling unclear'],
|
|
661
|
+
usability: ['User confusion possible', 'Accessibility gaps'],
|
|
662
|
+
charisma: ['Brand inconsistency risk', 'Visual regression possible'],
|
|
663
|
+
security: ['Vulnerability exposure', 'Data breach risk'],
|
|
664
|
+
scalability: ['Performance degradation at scale', 'Resource exhaustion'],
|
|
665
|
+
compatibility: ['Integration failures', 'Version conflicts'],
|
|
666
|
+
performance: ['Slow response times', 'Resource bottlenecks'],
|
|
667
|
+
installability: ['Deployment complexity', 'Configuration errors'],
|
|
668
|
+
supportability: ['Debugging difficulty', 'Maintenance burden'],
|
|
669
|
+
};
|
|
670
|
+
risks.push(...categoryRisks[category].slice(0, notMentioned ? 2 : 1));
|
|
671
|
+
return risks;
|
|
672
|
+
}
|
|
673
|
+
generateCategoryTestIdeas(category) {
|
|
674
|
+
const testIdeas = {
|
|
675
|
+
capability: ['Happy path scenarios', 'Boundary value analysis', 'State transition tests'],
|
|
676
|
+
reliability: ['Stress testing', 'Recovery testing', 'Long-running tests'],
|
|
677
|
+
usability: ['User journey tests', 'Accessibility audits', 'Heuristic evaluation'],
|
|
678
|
+
charisma: ['Visual regression tests', 'Brand guideline validation', 'A/B testing'],
|
|
679
|
+
security: ['Penetration testing', 'Auth flow tests', 'Input validation'],
|
|
680
|
+
scalability: ['Load testing', 'Capacity testing', 'Horizontal scaling tests'],
|
|
681
|
+
compatibility: ['Cross-browser tests', 'API contract tests', 'Migration tests'],
|
|
682
|
+
performance: ['Response time tests', 'Throughput tests', 'Resource monitoring'],
|
|
683
|
+
installability: ['Deployment verification', 'Configuration tests', 'Rollback tests'],
|
|
684
|
+
supportability: ['Log validation', 'Monitoring checks', 'Runbook validation'],
|
|
685
|
+
};
|
|
686
|
+
return testIdeas[category];
|
|
687
|
+
}
|
|
688
|
+
calculateQualityScore(criteria) {
|
|
689
|
+
if (criteria.length === 0)
|
|
690
|
+
return 0;
|
|
691
|
+
const totalWeight = criteria.reduce((sum, c) => sum + c.weight, 0);
|
|
692
|
+
const weightedScore = criteria.reduce((sum, c) => sum + (c.testabilityScore * c.weight) / totalWeight, 0);
|
|
693
|
+
return Math.round(weightedScore);
|
|
694
|
+
}
|
|
695
|
+
assessTestabilityPrinciples(description, acceptanceCriteria) {
|
|
696
|
+
const acCount = acceptanceCriteria.length;
|
|
697
|
+
const descLength = description.length;
|
|
698
|
+
const hasGivenWhenThen = acceptanceCriteria.some(ac => ac.toLowerCase().includes('given') || ac.toLowerCase().includes('when'));
|
|
699
|
+
return {
|
|
700
|
+
controllability: Math.min(100, 40 + acCount * 10),
|
|
701
|
+
observability: hasGivenWhenThen ? 80 : 50,
|
|
702
|
+
isolability: Math.min(100, 50 + Math.random() * 30),
|
|
703
|
+
separationOfConcerns: Math.min(100, 40 + Math.random() * 40),
|
|
704
|
+
simplicity: Math.max(30, 100 - descLength / 20),
|
|
705
|
+
stability: Math.min(100, 60 + Math.random() * 20),
|
|
706
|
+
informationCapture: hasGivenWhenThen ? 85 : 45,
|
|
707
|
+
automationSupport: hasGivenWhenThen ? 90 : 40,
|
|
708
|
+
selfDocumenting: Math.min(100, 30 + descLength / 10),
|
|
709
|
+
independence: Math.min(100, 50 + Math.random() * 30),
|
|
710
|
+
};
|
|
711
|
+
}
|
|
712
|
+
identifyTestabilityIssues(principles) {
|
|
713
|
+
const blockers = [];
|
|
714
|
+
const recommendations = [];
|
|
715
|
+
if (principles.controllability < 50) {
|
|
716
|
+
blockers.push('Low controllability - test setup may be difficult');
|
|
717
|
+
}
|
|
718
|
+
if (principles.observability < 50) {
|
|
719
|
+
blockers.push('Low observability - verifying outcomes may be challenging');
|
|
720
|
+
}
|
|
721
|
+
if (principles.automationSupport < 50) {
|
|
722
|
+
recommendations.push('Add explicit acceptance criteria in Given/When/Then format');
|
|
723
|
+
}
|
|
724
|
+
if (principles.isolability < 60) {
|
|
725
|
+
recommendations.push('Consider breaking into smaller, isolated components');
|
|
726
|
+
}
|
|
727
|
+
if (principles.simplicity < 40) {
|
|
728
|
+
recommendations.push('Simplify requirements - current description is complex');
|
|
729
|
+
}
|
|
730
|
+
return { blockers, recommendations };
|
|
731
|
+
}
|
|
732
|
+
analyzeRiskFactors(targetType, description) {
|
|
733
|
+
const factors = [];
|
|
734
|
+
const descLower = description.toLowerCase();
|
|
735
|
+
// Complexity risk
|
|
736
|
+
if (description.length > 500) {
|
|
737
|
+
factors.push({
|
|
738
|
+
category: 'Complexity',
|
|
739
|
+
description: 'High description complexity increases misunderstanding risk',
|
|
740
|
+
likelihood: 4,
|
|
741
|
+
impact: 3,
|
|
742
|
+
score: 12,
|
|
743
|
+
});
|
|
744
|
+
}
|
|
745
|
+
// Integration risk
|
|
746
|
+
if (descLower.includes('api') || descLower.includes('integrate')) {
|
|
747
|
+
factors.push({
|
|
748
|
+
category: 'Integration',
|
|
749
|
+
description: 'External dependencies may cause integration issues',
|
|
750
|
+
likelihood: 3,
|
|
751
|
+
impact: 4,
|
|
752
|
+
score: 12,
|
|
753
|
+
});
|
|
754
|
+
}
|
|
755
|
+
// Security risk
|
|
756
|
+
if (descLower.includes('user') || descLower.includes('data') || descLower.includes('auth')) {
|
|
757
|
+
factors.push({
|
|
758
|
+
category: 'Security',
|
|
759
|
+
description: 'User data handling requires security considerations',
|
|
760
|
+
likelihood: 3,
|
|
761
|
+
impact: 5,
|
|
762
|
+
score: 15,
|
|
763
|
+
});
|
|
764
|
+
}
|
|
765
|
+
// Performance risk
|
|
766
|
+
if (descLower.includes('real-time') || descLower.includes('fast') || descLower.includes('scale')) {
|
|
767
|
+
factors.push({
|
|
768
|
+
category: 'Performance',
|
|
769
|
+
description: 'Performance requirements may be challenging to meet',
|
|
770
|
+
likelihood: 3,
|
|
771
|
+
impact: 3,
|
|
772
|
+
score: 9,
|
|
773
|
+
});
|
|
774
|
+
}
|
|
775
|
+
// Default risk if none identified
|
|
776
|
+
if (factors.length === 0) {
|
|
777
|
+
factors.push({
|
|
778
|
+
category: 'General',
|
|
779
|
+
description: 'Standard development risks apply',
|
|
780
|
+
likelihood: 2,
|
|
781
|
+
impact: 2,
|
|
782
|
+
score: 4,
|
|
783
|
+
});
|
|
784
|
+
}
|
|
785
|
+
return factors;
|
|
786
|
+
}
|
|
787
|
+
determineRiskLevel(score) {
|
|
788
|
+
if (score >= 80)
|
|
789
|
+
return 'critical';
|
|
790
|
+
if (score >= 60)
|
|
791
|
+
return 'high';
|
|
792
|
+
if (score >= 40)
|
|
793
|
+
return 'medium';
|
|
794
|
+
return 'low';
|
|
795
|
+
}
|
|
796
|
+
generateMitigations(factors) {
|
|
797
|
+
const mitigations = [];
|
|
798
|
+
for (const factor of factors) {
|
|
799
|
+
switch (factor.category) {
|
|
800
|
+
case 'Complexity':
|
|
801
|
+
mitigations.push('Break down into smaller, more manageable stories');
|
|
802
|
+
break;
|
|
803
|
+
case 'Integration':
|
|
804
|
+
mitigations.push('Define API contracts early with contract testing');
|
|
805
|
+
break;
|
|
806
|
+
case 'Security':
|
|
807
|
+
mitigations.push('Conduct threat modeling and security review');
|
|
808
|
+
break;
|
|
809
|
+
case 'Performance':
|
|
810
|
+
mitigations.push('Establish performance baselines and monitoring');
|
|
811
|
+
break;
|
|
812
|
+
default:
|
|
813
|
+
mitigations.push('Apply standard QE practices');
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
return mitigations;
|
|
817
|
+
}
|
|
818
|
+
analyzeSTRIDEThreats(description, securityCritical) {
|
|
819
|
+
const threats = [];
|
|
820
|
+
const descLower = description.toLowerCase();
|
|
821
|
+
// Spoofing
|
|
822
|
+
if (descLower.includes('auth') || descLower.includes('login') || descLower.includes('user')) {
|
|
823
|
+
threats.push({
|
|
824
|
+
category: 'spoofing',
|
|
825
|
+
name: 'Identity Spoofing',
|
|
826
|
+
description: 'Attacker may impersonate legitimate users',
|
|
827
|
+
likelihood: securityCritical ? 4 : 2,
|
|
828
|
+
impact: 4,
|
|
829
|
+
mitigations: ['Implement MFA', 'Use strong session management'],
|
|
830
|
+
});
|
|
831
|
+
}
|
|
832
|
+
// Tampering
|
|
833
|
+
if (descLower.includes('data') || descLower.includes('update') || descLower.includes('edit')) {
|
|
834
|
+
threats.push({
|
|
835
|
+
category: 'tampering',
|
|
836
|
+
name: 'Data Tampering',
|
|
837
|
+
description: 'Data may be modified maliciously',
|
|
838
|
+
likelihood: securityCritical ? 3 : 2,
|
|
839
|
+
impact: 4,
|
|
840
|
+
mitigations: ['Implement input validation', 'Use integrity checks'],
|
|
841
|
+
});
|
|
842
|
+
}
|
|
843
|
+
// Information Disclosure
|
|
844
|
+
if (descLower.includes('personal') || descLower.includes('sensitive') || descLower.includes('private')) {
|
|
845
|
+
threats.push({
|
|
846
|
+
category: 'informationDisclosure',
|
|
847
|
+
name: 'Information Disclosure',
|
|
848
|
+
description: 'Sensitive information may be exposed',
|
|
849
|
+
likelihood: securityCritical ? 4 : 3,
|
|
850
|
+
impact: 5,
|
|
851
|
+
mitigations: ['Encrypt data at rest and in transit', 'Implement access controls'],
|
|
852
|
+
});
|
|
853
|
+
}
|
|
854
|
+
// Default low-risk threat
|
|
855
|
+
if (threats.length === 0 && !securityCritical) {
|
|
856
|
+
threats.push({
|
|
857
|
+
category: 'denial',
|
|
858
|
+
name: 'Service Denial',
|
|
859
|
+
description: 'Service availability may be impacted',
|
|
860
|
+
likelihood: 2,
|
|
861
|
+
impact: 3,
|
|
862
|
+
mitigations: ['Implement rate limiting', 'Add monitoring and alerts'],
|
|
863
|
+
});
|
|
864
|
+
}
|
|
865
|
+
return threats;
|
|
866
|
+
}
|
|
867
|
+
generateSecurityRecommendations(threats) {
|
|
868
|
+
const recommendations = new Set();
|
|
869
|
+
for (const threat of threats) {
|
|
870
|
+
for (const mitigation of threat.mitigations) {
|
|
871
|
+
recommendations.add(mitigation);
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
return Array.from(recommendations);
|
|
875
|
+
}
|
|
876
|
+
generateSWOTInsights(qualityCriteria, testability, risk) {
|
|
877
|
+
const strengths = [];
|
|
878
|
+
const weaknesses = [];
|
|
879
|
+
const opportunities = [];
|
|
880
|
+
const threats = [];
|
|
881
|
+
// Analyze strengths
|
|
882
|
+
const highTestability = qualityCriteria.filter(c => c.testabilityScore >= 70);
|
|
883
|
+
if (highTestability.length > 5) {
|
|
884
|
+
strengths.push(`${highTestability.length}/10 quality categories have high testability`);
|
|
885
|
+
}
|
|
886
|
+
if (testability.overallScore >= 70) {
|
|
887
|
+
strengths.push('Overall testability score is good');
|
|
888
|
+
}
|
|
889
|
+
if (risk.overallRisk === 'low') {
|
|
890
|
+
strengths.push('Risk profile is manageable');
|
|
891
|
+
}
|
|
892
|
+
// Analyze weaknesses
|
|
893
|
+
const lowTestability = qualityCriteria.filter(c => c.testabilityScore < 50);
|
|
894
|
+
if (lowTestability.length > 0) {
|
|
895
|
+
weaknesses.push(`${lowTestability.length} quality categories need more definition`);
|
|
896
|
+
}
|
|
897
|
+
if (testability.blockers.length > 0) {
|
|
898
|
+
weaknesses.push(...testability.blockers.slice(0, 2));
|
|
899
|
+
}
|
|
900
|
+
// Analyze opportunities
|
|
901
|
+
if (testability.principles.automationSupport >= 70) {
|
|
902
|
+
opportunities.push('High automation potential for test coverage');
|
|
903
|
+
}
|
|
904
|
+
opportunities.push('Early quality assessment enables shift-left testing');
|
|
905
|
+
// Analyze threats
|
|
906
|
+
if (risk.factors.some(f => f.score >= 15)) {
|
|
907
|
+
threats.push('High-severity risks require immediate attention');
|
|
908
|
+
}
|
|
909
|
+
threats.push(...risk.factors.filter(f => f.score >= 10).map(f => f.description).slice(0, 2));
|
|
910
|
+
return { strengths, weaknesses, opportunities, threats };
|
|
911
|
+
}
|
|
912
|
+
generateRecommendations(qualityCriteria, testability, risk, threatModel) {
|
|
913
|
+
const recommendations = [];
|
|
914
|
+
// Testability recommendations
|
|
915
|
+
if (testability.overallScore < 60) {
|
|
916
|
+
recommendations.push({
|
|
917
|
+
priority: 'high',
|
|
918
|
+
category: 'Testability',
|
|
919
|
+
description: 'Improve acceptance criteria with specific, measurable outcomes',
|
|
920
|
+
effort: 'low',
|
|
921
|
+
});
|
|
922
|
+
}
|
|
923
|
+
// Risk recommendations
|
|
924
|
+
for (const factor of risk.factors.filter(f => f.score >= 12)) {
|
|
925
|
+
recommendations.push({
|
|
926
|
+
priority: factor.score >= 15 ? 'critical' : 'high',
|
|
927
|
+
category: 'Risk Mitigation',
|
|
928
|
+
description: risk.mitigations[0] || `Address ${factor.category} risk`,
|
|
929
|
+
effort: 'medium',
|
|
930
|
+
});
|
|
931
|
+
}
|
|
932
|
+
// Security recommendations
|
|
933
|
+
if (threatModel && threatModel.threats.length > 0) {
|
|
934
|
+
recommendations.push({
|
|
935
|
+
priority: threatModel.overallRisk === 'critical' ? 'critical' : 'high',
|
|
936
|
+
category: 'Security',
|
|
937
|
+
description: threatModel.recommendations[0] || 'Implement security controls',
|
|
938
|
+
effort: 'high',
|
|
939
|
+
});
|
|
940
|
+
}
|
|
941
|
+
// Quality recommendations
|
|
942
|
+
const lowCategories = qualityCriteria.filter(c => c.testabilityScore < 50);
|
|
943
|
+
if (lowCategories.length > 0) {
|
|
944
|
+
recommendations.push({
|
|
945
|
+
priority: 'medium',
|
|
946
|
+
category: 'Quality Definition',
|
|
947
|
+
description: `Define clearer criteria for: ${lowCategories.map(c => c.category).join(', ')}`,
|
|
948
|
+
effort: 'low',
|
|
949
|
+
});
|
|
950
|
+
}
|
|
951
|
+
return recommendations.sort((a, b) => {
|
|
952
|
+
const priorityOrder = { critical: 0, high: 1, medium: 2, low: 3 };
|
|
953
|
+
return priorityOrder[a.priority] - priorityOrder[b.priority];
|
|
954
|
+
});
|
|
955
|
+
}
|
|
956
|
+
generateTestStrategy(qualityCriteria, testability, risk) {
|
|
957
|
+
// Determine approach based on risk and testability
|
|
958
|
+
let approach = 'Standard test pyramid with unit, integration, and E2E tests';
|
|
959
|
+
if (risk.overallRisk === 'high' || risk.overallRisk === 'critical') {
|
|
960
|
+
approach = 'Risk-based testing with enhanced coverage for high-risk areas';
|
|
961
|
+
}
|
|
962
|
+
if (testability.overallScore >= 80) {
|
|
963
|
+
approach += ' with high automation potential';
|
|
964
|
+
}
|
|
965
|
+
// Coverage areas from quality criteria
|
|
966
|
+
const coverage = qualityCriteria
|
|
967
|
+
.filter(c => c.weight >= 5)
|
|
968
|
+
.flatMap(c => c.testIdeas.slice(0, 2));
|
|
969
|
+
// Risk areas
|
|
970
|
+
const riskAreas = risk.factors
|
|
971
|
+
.filter(f => f.score >= 9)
|
|
972
|
+
.map(f => `${f.category}: ${f.description}`);
|
|
973
|
+
// Estimate effort based on complexity
|
|
974
|
+
const totalWeight = qualityCriteria.reduce((sum, c) => sum + c.weight, 0);
|
|
975
|
+
let estimatedEffort = 'Medium (3-5 days)';
|
|
976
|
+
if (totalWeight > 60) {
|
|
977
|
+
estimatedEffort = 'High (1-2 weeks)';
|
|
978
|
+
}
|
|
979
|
+
else if (totalWeight < 40) {
|
|
980
|
+
estimatedEffort = 'Low (1-2 days)';
|
|
981
|
+
}
|
|
982
|
+
return {
|
|
983
|
+
approach,
|
|
984
|
+
coverage: [...new Set(coverage)].slice(0, 8),
|
|
985
|
+
riskAreas: riskAreas.slice(0, 4),
|
|
986
|
+
estimatedEffort,
|
|
987
|
+
};
|
|
988
|
+
}
|
|
989
|
+
// ============================================================================
|
|
990
|
+
// Conditional Agent Actions (HAS_UI, HAS_UX)
|
|
991
|
+
// ============================================================================
|
|
992
|
+
/**
|
|
993
|
+
* Audit accessibility for websites with UI components (HAS_UI flag)
|
|
994
|
+
* Triggered when website extraction detects UI elements
|
|
995
|
+
*/
|
|
996
|
+
async auditAccessibility(input, context) {
|
|
997
|
+
try {
|
|
998
|
+
const targetId = input.targetId || context.input.targetId;
|
|
999
|
+
const url = input.url || context.input.url;
|
|
1000
|
+
const description = input.description || context.input.description || '';
|
|
1001
|
+
const features = input.features || context.input.features || [];
|
|
1002
|
+
// Analyze accessibility concerns based on detected features
|
|
1003
|
+
const violations = [];
|
|
1004
|
+
const recommendations = [];
|
|
1005
|
+
// Check for common accessibility issues based on features
|
|
1006
|
+
const featureAnalysis = {
|
|
1007
|
+
'Image carousel': {
|
|
1008
|
+
issue: 'Carousels may lack pause controls and keyboard navigation',
|
|
1009
|
+
rec: 'Ensure carousel has pause button, keyboard controls, and ARIA labels',
|
|
1010
|
+
},
|
|
1011
|
+
'Form interactions': {
|
|
1012
|
+
issue: 'Forms may lack proper labels and error announcements',
|
|
1013
|
+
rec: 'Add aria-describedby for errors, ensure all inputs have associated labels',
|
|
1014
|
+
},
|
|
1015
|
+
'Modal dialogs': {
|
|
1016
|
+
issue: 'Modals may trap focus or lack escape key handling',
|
|
1017
|
+
rec: 'Implement focus trap, escape key closure, and return focus on close',
|
|
1018
|
+
},
|
|
1019
|
+
'Video content': {
|
|
1020
|
+
issue: 'Videos may lack captions and audio descriptions',
|
|
1021
|
+
rec: 'Add WebVTT captions and audio description track for video content',
|
|
1022
|
+
},
|
|
1023
|
+
'Site navigation': {
|
|
1024
|
+
issue: 'Navigation may lack skip links and landmark roles',
|
|
1025
|
+
rec: 'Add skip-to-main link, use proper landmark roles (nav, main, aside)',
|
|
1026
|
+
},
|
|
1027
|
+
'Newsletter subscription': {
|
|
1028
|
+
issue: 'Signup forms may lack clear success/error feedback',
|
|
1029
|
+
rec: 'Use aria-live regions for form submission feedback',
|
|
1030
|
+
},
|
|
1031
|
+
};
|
|
1032
|
+
for (const feature of features) {
|
|
1033
|
+
const analysis = featureAnalysis[feature];
|
|
1034
|
+
if (analysis) {
|
|
1035
|
+
violations.push(analysis.issue);
|
|
1036
|
+
recommendations.push(analysis.rec);
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
// Add general WCAG recommendations
|
|
1040
|
+
recommendations.push('Verify color contrast meets WCAG 2.2 AA (4.5:1 for text)', 'Test with screen reader (NVDA/VoiceOver)', 'Verify keyboard navigation for all interactive elements', 'Check focus indicators are visible');
|
|
1041
|
+
// Determine WCAG level based on violations
|
|
1042
|
+
const wcagLevel = violations.length > 5 ? 'Likely fails AA' :
|
|
1043
|
+
violations.length > 2 ? 'Partial AA compliance' : 'Potential AA compliance';
|
|
1044
|
+
// Store result
|
|
1045
|
+
await this.memory.set(`qcsd-ideation:accessibility:${targetId}`, { wcagLevel, violations, recommendations, url, timestamp: new Date().toISOString() }, { namespace: 'qcsd-ideation', ttl: 3600 });
|
|
1046
|
+
return ok({ wcagLevel, violations, recommendations });
|
|
1047
|
+
}
|
|
1048
|
+
catch (error) {
|
|
1049
|
+
return err(error instanceof Error ? error : new Error(String(error)));
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
/**
|
|
1053
|
+
* Analyze quality experience for websites with UX concerns (HAS_UX flag)
|
|
1054
|
+
* Triggered when website extraction detects user experience patterns
|
|
1055
|
+
*/
|
|
1056
|
+
async analyzeQualityExperience(input, context) {
|
|
1057
|
+
try {
|
|
1058
|
+
const targetId = input.targetId || context.input.targetId;
|
|
1059
|
+
const url = input.url || context.input.url;
|
|
1060
|
+
const description = input.description || context.input.description || '';
|
|
1061
|
+
const features = input.features || context.input.features || [];
|
|
1062
|
+
const journeys = [];
|
|
1063
|
+
const frictionPoints = [];
|
|
1064
|
+
const recommendations = [];
|
|
1065
|
+
// Identify user journeys based on detected features
|
|
1066
|
+
const journeyMapping = {
|
|
1067
|
+
'Newsletter subscription': {
|
|
1068
|
+
journey: 'Content subscription flow: Landing -> Email signup -> Confirmation',
|
|
1069
|
+
friction: 'Multi-step signup may cause abandonment',
|
|
1070
|
+
rec: 'Implement single-field inline signup with immediate feedback',
|
|
1071
|
+
},
|
|
1072
|
+
'Search functionality': {
|
|
1073
|
+
journey: 'Content discovery flow: Search -> Filter -> Select -> Read',
|
|
1074
|
+
friction: 'Poor search results relevance frustrates users',
|
|
1075
|
+
rec: 'Add search suggestions, filters, and "no results" helpful messaging',
|
|
1076
|
+
},
|
|
1077
|
+
'User authentication': {
|
|
1078
|
+
journey: 'Account access flow: Login page -> Auth -> Dashboard',
|
|
1079
|
+
friction: 'Password requirements and recovery flow complexity',
|
|
1080
|
+
rec: 'Add social login options, clear password requirements, easy recovery',
|
|
1081
|
+
},
|
|
1082
|
+
'Shopping cart': {
|
|
1083
|
+
journey: 'Purchase flow: Browse -> Add to cart -> Checkout -> Payment',
|
|
1084
|
+
friction: 'Cart abandonment at checkout due to complexity',
|
|
1085
|
+
rec: 'Guest checkout, progress indicator, saved cart, multiple payment options',
|
|
1086
|
+
},
|
|
1087
|
+
'Comment system': {
|
|
1088
|
+
journey: 'Engagement flow: Read article -> Scroll to comments -> Write comment',
|
|
1089
|
+
friction: 'Login requirement for commenting reduces engagement',
|
|
1090
|
+
rec: 'Allow guest comments with moderation, or social login for quick auth',
|
|
1091
|
+
},
|
|
1092
|
+
'PDF downloads': {
|
|
1093
|
+
journey: 'Content access flow: Browse catalog -> Select issue -> Download PDF',
|
|
1094
|
+
friction: 'Large file sizes and unclear progress',
|
|
1095
|
+
rec: 'Show file size before download, progress indicator, resume support',
|
|
1096
|
+
},
|
|
1097
|
+
};
|
|
1098
|
+
for (const feature of features) {
|
|
1099
|
+
const mapping = journeyMapping[feature];
|
|
1100
|
+
if (mapping) {
|
|
1101
|
+
journeys.push(mapping.journey);
|
|
1102
|
+
frictionPoints.push(mapping.friction);
|
|
1103
|
+
recommendations.push(mapping.rec);
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
// Add general QX recommendations
|
|
1107
|
+
recommendations.push('Map complete user journeys with entry/exit points', 'Identify drop-off points using analytics', 'Test critical paths with real users', 'Monitor Core Web Vitals for performance impact on UX');
|
|
1108
|
+
// Store result
|
|
1109
|
+
await this.memory.set(`qcsd-ideation:qx:${targetId}`, { journeys, frictionPoints, recommendations, url, timestamp: new Date().toISOString() }, { namespace: 'qcsd-ideation', ttl: 3600 });
|
|
1110
|
+
return ok({ journeys, frictionPoints, recommendations });
|
|
1111
|
+
}
|
|
1112
|
+
catch (error) {
|
|
1113
|
+
return err(error instanceof Error ? error : new Error(String(error)));
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
// ============================================================================
|
|
1117
|
+
// Helper Methods - Continued
|
|
1118
|
+
// ============================================================================
|
|
1119
|
+
identifyBlockers(testability, risk, threatModel) {
|
|
1120
|
+
const blockers = [];
|
|
1121
|
+
// Testability blockers
|
|
1122
|
+
if (testability.overallScore < 40) {
|
|
1123
|
+
blockers.push('Testability score too low - cannot verify acceptance criteria');
|
|
1124
|
+
}
|
|
1125
|
+
blockers.push(...testability.blockers);
|
|
1126
|
+
// Risk blockers
|
|
1127
|
+
if (risk.overallRisk === 'critical') {
|
|
1128
|
+
blockers.push('Critical risk level requires risk mitigation before development');
|
|
1129
|
+
}
|
|
1130
|
+
// Security blockers
|
|
1131
|
+
if (threatModel && threatModel.overallRisk === 'critical') {
|
|
1132
|
+
blockers.push('Critical security threats must be addressed before development');
|
|
1133
|
+
}
|
|
1134
|
+
return blockers;
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
// ============================================================================
|
|
1138
|
+
// Factory Function
|
|
1139
|
+
// ============================================================================
|
|
1140
|
+
export function createQCSDIdeationPlugin(memory) {
|
|
1141
|
+
return new QCSDIdeationPlugin(memory);
|
|
1142
|
+
}
|
|
1143
|
+
//# sourceMappingURL=qcsd-ideation-plugin.js.map
|