javi-forge 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitignore.template +105 -0
- package/.releaserc +44 -0
- package/README.md +45 -0
- package/ai-config/.skillignore +15 -0
- package/ai-config/AUTO_INVOKE.md +300 -0
- package/ai-config/agents/_TEMPLATE.md +93 -0
- package/ai-config/agents/business/api-designer.md +1657 -0
- package/ai-config/agents/business/business-analyst.md +1331 -0
- package/ai-config/agents/business/product-strategist.md +206 -0
- package/ai-config/agents/business/project-manager.md +178 -0
- package/ai-config/agents/business/requirements-analyst.md +1277 -0
- package/ai-config/agents/business/technical-writer.md +1679 -0
- package/ai-config/agents/creative/ux-designer.md +205 -0
- package/ai-config/agents/data-ai/ai-engineer.md +487 -0
- package/ai-config/agents/data-ai/analytics-engineer.md +953 -0
- package/ai-config/agents/data-ai/data-engineer.md +173 -0
- package/ai-config/agents/data-ai/data-scientist.md +672 -0
- package/ai-config/agents/data-ai/mlops-engineer.md +814 -0
- package/ai-config/agents/data-ai/prompt-engineer.md +772 -0
- package/ai-config/agents/development/angular-expert.md +620 -0
- package/ai-config/agents/development/backend-architect.md +795 -0
- package/ai-config/agents/development/database-specialist.md +212 -0
- package/ai-config/agents/development/frontend-specialist.md +686 -0
- package/ai-config/agents/development/fullstack-engineer.md +668 -0
- package/ai-config/agents/development/golang-pro.md +338 -0
- package/ai-config/agents/development/java-enterprise.md +400 -0
- package/ai-config/agents/development/javascript-pro.md +422 -0
- package/ai-config/agents/development/nextjs-pro.md +474 -0
- package/ai-config/agents/development/python-pro.md +570 -0
- package/ai-config/agents/development/react-pro.md +487 -0
- package/ai-config/agents/development/rust-pro.md +246 -0
- package/ai-config/agents/development/spring-boot-4-expert.md +326 -0
- package/ai-config/agents/development/typescript-pro.md +336 -0
- package/ai-config/agents/development/vue-specialist.md +605 -0
- package/ai-config/agents/infrastructure/cloud-architect.md +472 -0
- package/ai-config/agents/infrastructure/deployment-manager.md +358 -0
- package/ai-config/agents/infrastructure/devops-engineer.md +455 -0
- package/ai-config/agents/infrastructure/incident-responder.md +519 -0
- package/ai-config/agents/infrastructure/kubernetes-expert.md +705 -0
- package/ai-config/agents/infrastructure/monitoring-specialist.md +674 -0
- package/ai-config/agents/infrastructure/performance-engineer.md +658 -0
- package/ai-config/agents/orchestrator.md +241 -0
- package/ai-config/agents/quality/accessibility-auditor.md +1204 -0
- package/ai-config/agents/quality/code-reviewer-compact.md +123 -0
- package/ai-config/agents/quality/code-reviewer.md +363 -0
- package/ai-config/agents/quality/dependency-manager.md +743 -0
- package/ai-config/agents/quality/e2e-test-specialist.md +1005 -0
- package/ai-config/agents/quality/performance-tester.md +1086 -0
- package/ai-config/agents/quality/security-auditor.md +133 -0
- package/ai-config/agents/quality/test-engineer.md +453 -0
- package/ai-config/agents/specialists/api-designer.md +87 -0
- package/ai-config/agents/specialists/backend-architect.md +73 -0
- package/ai-config/agents/specialists/code-reviewer.md +77 -0
- package/ai-config/agents/specialists/db-optimizer.md +75 -0
- package/ai-config/agents/specialists/devops-engineer.md +83 -0
- package/ai-config/agents/specialists/documentation-writer.md +78 -0
- package/ai-config/agents/specialists/frontend-developer.md +75 -0
- package/ai-config/agents/specialists/performance-analyst.md +82 -0
- package/ai-config/agents/specialists/refactor-specialist.md +74 -0
- package/ai-config/agents/specialists/security-auditor.md +74 -0
- package/ai-config/agents/specialists/test-engineer.md +81 -0
- package/ai-config/agents/specialists/ux-consultant.md +76 -0
- package/ai-config/agents/specialized/agent-generator.md +1190 -0
- package/ai-config/agents/specialized/blockchain-developer.md +149 -0
- package/ai-config/agents/specialized/code-migrator.md +892 -0
- package/ai-config/agents/specialized/context-manager.md +978 -0
- package/ai-config/agents/specialized/documentation-writer.md +1078 -0
- package/ai-config/agents/specialized/ecommerce-expert.md +1756 -0
- package/ai-config/agents/specialized/embedded-engineer.md +1714 -0
- package/ai-config/agents/specialized/error-detective.md +1034 -0
- package/ai-config/agents/specialized/fintech-specialist.md +1659 -0
- package/ai-config/agents/specialized/freelance-project-planner-v2.md +1988 -0
- package/ai-config/agents/specialized/freelance-project-planner-v3.md +2136 -0
- package/ai-config/agents/specialized/freelance-project-planner-v4.md +4503 -0
- package/ai-config/agents/specialized/freelance-project-planner.md +722 -0
- package/ai-config/agents/specialized/game-developer.md +1963 -0
- package/ai-config/agents/specialized/healthcare-dev.md +1620 -0
- package/ai-config/agents/specialized/mobile-developer.md +188 -0
- package/ai-config/agents/specialized/parallel-plan-executor.md +506 -0
- package/ai-config/agents/specialized/plan-executor.md +485 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/00-INDEX.md +485 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/01-CORE.md +3493 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/02-SELF-CORRECTION.md +778 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/03-PROGRESSIVE-SETUP.md +918 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/04-DEPLOYMENT.md +1537 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/05-TESTING.md +2633 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/06-OPERATIONS.md +5610 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/INSTALL.md +335 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/QUICK-REFERENCE.txt +215 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/README.md +260 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/START-HERE.md +379 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/WORKFLOW-DIAGRAM.md +355 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/solo-dev-planner.md +279 -0
- package/ai-config/agents/specialized/template-writer.md +347 -0
- package/ai-config/agents/specialized/test-runner.md +99 -0
- package/ai-config/agents/specialized/vibekanban-smart-worker.md +244 -0
- package/ai-config/agents/specialized/wave-executor.md +138 -0
- package/ai-config/agents/specialized/workflow-optimizer.md +1114 -0
- package/ai-config/commands/git/changelog.md +32 -0
- package/ai-config/commands/git/ci-local.md +70 -0
- package/ai-config/commands/git/commit.md +35 -0
- package/ai-config/commands/git/fix-issue.md +23 -0
- package/ai-config/commands/git/pr-create.md +42 -0
- package/ai-config/commands/git/pr-review.md +50 -0
- package/ai-config/commands/git/worktree.md +39 -0
- package/ai-config/commands/refactoring/cleanup.md +24 -0
- package/ai-config/commands/refactoring/dead-code.md +40 -0
- package/ai-config/commands/refactoring/extract.md +31 -0
- package/ai-config/commands/testing/e2e.md +30 -0
- package/ai-config/commands/testing/tdd.md +36 -0
- package/ai-config/commands/testing/test-coverage.md +30 -0
- package/ai-config/commands/testing/test-fix.md +24 -0
- package/ai-config/commands/workflow/generate-agents-md.md +85 -0
- package/ai-config/commands/workflow/planning.md +47 -0
- package/ai-config/commands/workflows/compound.md +89 -0
- package/ai-config/commands/workflows/plan.md +77 -0
- package/ai-config/commands/workflows/review.md +78 -0
- package/ai-config/commands/workflows/work.md +75 -0
- package/ai-config/config.yaml +18 -0
- package/ai-config/hooks/_TEMPLATE.md +96 -0
- package/ai-config/hooks/block-dangerous-commands.md +75 -0
- package/ai-config/hooks/commit-guard.md +90 -0
- package/ai-config/hooks/context-loader.md +73 -0
- package/ai-config/hooks/improve-prompt.md +91 -0
- package/ai-config/hooks/learning-log.md +72 -0
- package/ai-config/hooks/model-router.md +86 -0
- package/ai-config/hooks/secret-scanner.md +64 -0
- package/ai-config/hooks/skill-validator.md +102 -0
- package/ai-config/hooks/task-artifact.md +114 -0
- package/ai-config/hooks/validate-workflow.md +100 -0
- package/ai-config/prompts/base.md +71 -0
- package/ai-config/prompts/modes/debug.md +34 -0
- package/ai-config/prompts/modes/deploy.md +40 -0
- package/ai-config/prompts/modes/research.md +32 -0
- package/ai-config/prompts/modes/review.md +33 -0
- package/ai-config/prompts/review-policy.md +79 -0
- package/ai-config/skills/_TEMPLATE.md +157 -0
- package/ai-config/skills/backend/api-gateway/SKILL.md +254 -0
- package/ai-config/skills/backend/bff-concepts/SKILL.md +239 -0
- package/ai-config/skills/backend/bff-spring/SKILL.md +364 -0
- package/ai-config/skills/backend/chi-router/SKILL.md +396 -0
- package/ai-config/skills/backend/error-handling/SKILL.md +255 -0
- package/ai-config/skills/backend/exceptions-spring/SKILL.md +323 -0
- package/ai-config/skills/backend/fastapi/SKILL.md +302 -0
- package/ai-config/skills/backend/gateway-spring/SKILL.md +390 -0
- package/ai-config/skills/backend/go-backend/SKILL.md +457 -0
- package/ai-config/skills/backend/gradle-multimodule/SKILL.md +274 -0
- package/ai-config/skills/backend/graphql-concepts/SKILL.md +352 -0
- package/ai-config/skills/backend/graphql-spring/SKILL.md +398 -0
- package/ai-config/skills/backend/grpc-concepts/SKILL.md +283 -0
- package/ai-config/skills/backend/grpc-spring/SKILL.md +445 -0
- package/ai-config/skills/backend/jwt-auth/SKILL.md +412 -0
- package/ai-config/skills/backend/notifications-concepts/SKILL.md +259 -0
- package/ai-config/skills/backend/recommendations-concepts/SKILL.md +261 -0
- package/ai-config/skills/backend/search-concepts/SKILL.md +263 -0
- package/ai-config/skills/backend/search-spring/SKILL.md +375 -0
- package/ai-config/skills/backend/spring-boot-4/SKILL.md +172 -0
- package/ai-config/skills/backend/websockets/SKILL.md +532 -0
- package/ai-config/skills/data-ai/ai-ml/SKILL.md +423 -0
- package/ai-config/skills/data-ai/analytics-concepts/SKILL.md +195 -0
- package/ai-config/skills/data-ai/analytics-spring/SKILL.md +340 -0
- package/ai-config/skills/data-ai/duckdb-analytics/SKILL.md +440 -0
- package/ai-config/skills/data-ai/langchain/SKILL.md +238 -0
- package/ai-config/skills/data-ai/mlflow/SKILL.md +302 -0
- package/ai-config/skills/data-ai/onnx-inference/SKILL.md +290 -0
- package/ai-config/skills/data-ai/powerbi/SKILL.md +352 -0
- package/ai-config/skills/data-ai/pytorch/SKILL.md +274 -0
- package/ai-config/skills/data-ai/scikit-learn/SKILL.md +321 -0
- package/ai-config/skills/data-ai/vector-db/SKILL.md +301 -0
- package/ai-config/skills/database/graph-databases/SKILL.md +218 -0
- package/ai-config/skills/database/graph-spring/SKILL.md +361 -0
- package/ai-config/skills/database/pgx-postgres/SKILL.md +512 -0
- package/ai-config/skills/database/redis-cache/SKILL.md +343 -0
- package/ai-config/skills/database/sqlite-embedded/SKILL.md +388 -0
- package/ai-config/skills/database/timescaledb/SKILL.md +320 -0
- package/ai-config/skills/docs/api-documentation/SKILL.md +293 -0
- package/ai-config/skills/docs/docs-spring/SKILL.md +377 -0
- package/ai-config/skills/docs/mustache-templates/SKILL.md +190 -0
- package/ai-config/skills/docs/technical-docs/SKILL.md +447 -0
- package/ai-config/skills/frontend/astro-ssr/SKILL.md +441 -0
- package/ai-config/skills/frontend/frontend-design/SKILL.md +54 -0
- package/ai-config/skills/frontend/frontend-web/SKILL.md +368 -0
- package/ai-config/skills/frontend/mantine-ui/SKILL.md +396 -0
- package/ai-config/skills/frontend/tanstack-query/SKILL.md +439 -0
- package/ai-config/skills/frontend/zod-validation/SKILL.md +417 -0
- package/ai-config/skills/frontend/zustand-state/SKILL.md +350 -0
- package/ai-config/skills/infrastructure/chaos-engineering/SKILL.md +244 -0
- package/ai-config/skills/infrastructure/chaos-spring/SKILL.md +378 -0
- package/ai-config/skills/infrastructure/devops-infra/SKILL.md +435 -0
- package/ai-config/skills/infrastructure/docker-containers/SKILL.md +420 -0
- package/ai-config/skills/infrastructure/kubernetes/SKILL.md +456 -0
- package/ai-config/skills/infrastructure/opentelemetry/SKILL.md +546 -0
- package/ai-config/skills/infrastructure/traefik-proxy/SKILL.md +474 -0
- package/ai-config/skills/infrastructure/woodpecker-ci/SKILL.md +315 -0
- package/ai-config/skills/mobile/ionic-capacitor/SKILL.md +504 -0
- package/ai-config/skills/mobile/mobile-ionic/SKILL.md +448 -0
- package/ai-config/skills/prompt-improver/SKILL.md +125 -0
- package/ai-config/skills/quality/ghagga-review/SKILL.md +216 -0
- package/ai-config/skills/references/hooks-patterns/SKILL.md +238 -0
- package/ai-config/skills/references/mcp-servers/SKILL.md +275 -0
- package/ai-config/skills/references/plugins-reference/SKILL.md +110 -0
- package/ai-config/skills/references/skills-reference/SKILL.md +420 -0
- package/ai-config/skills/references/subagent-templates/SKILL.md +193 -0
- package/ai-config/skills/systems-iot/modbus-protocol/SKILL.md +410 -0
- package/ai-config/skills/systems-iot/mqtt-rumqttc/SKILL.md +408 -0
- package/ai-config/skills/systems-iot/rust-systems/SKILL.md +386 -0
- package/ai-config/skills/systems-iot/tokio-async/SKILL.md +324 -0
- package/ai-config/skills/testing/playwright-e2e/SKILL.md +289 -0
- package/ai-config/skills/testing/testcontainers/SKILL.md +299 -0
- package/ai-config/skills/testing/vitest-testing/SKILL.md +381 -0
- package/ai-config/skills/workflow/ci-local-guide/SKILL.md +118 -0
- package/ai-config/skills/workflow/claude-automation-recommender/SKILL.md +299 -0
- package/ai-config/skills/workflow/claude-md-improver/SKILL.md +158 -0
- package/ai-config/skills/workflow/finishing-a-development-branch/SKILL.md +117 -0
- package/ai-config/skills/workflow/git-github/SKILL.md +334 -0
- package/ai-config/skills/workflow/git-github/references/examples.md +160 -0
- package/ai-config/skills/workflow/git-workflow/SKILL.md +214 -0
- package/ai-config/skills/workflow/ide-plugins/SKILL.md +277 -0
- package/ai-config/skills/workflow/ide-plugins-intellij/SKILL.md +401 -0
- package/ai-config/skills/workflow/obsidian-brain-workflow/SKILL.md +199 -0
- package/ai-config/skills/workflow/using-git-worktrees/SKILL.md +100 -0
- package/ai-config/skills/workflow/verification-before-completion/SKILL.md +73 -0
- package/ai-config/skills/workflow/wave-workflow/SKILL.md +178 -0
- package/ci-local/README.md +170 -0
- package/ci-local/ci-local.sh +297 -0
- package/ci-local/hooks/commit-msg +74 -0
- package/ci-local/hooks/pre-commit +162 -0
- package/ci-local/hooks/pre-push +41 -0
- package/ci-local/install.sh +49 -0
- package/ci-local/semgrep.yml +214 -0
- package/dist/commands/analyze.d.ts +9 -0
- package/dist/commands/analyze.d.ts.map +1 -0
- package/dist/commands/analyze.js +55 -0
- package/dist/commands/analyze.js.map +1 -0
- package/dist/commands/analyze.test.d.ts +2 -0
- package/dist/commands/analyze.test.d.ts.map +1 -0
- package/dist/commands/analyze.test.js +145 -0
- package/dist/commands/analyze.test.js.map +1 -0
- package/dist/commands/doctor.d.ts +7 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +158 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/doctor.test.d.ts +2 -0
- package/dist/commands/doctor.test.d.ts.map +1 -0
- package/dist/commands/doctor.test.js +200 -0
- package/dist/commands/doctor.test.js.map +1 -0
- package/dist/commands/init.d.ts +9 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +283 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/init.test.d.ts +2 -0
- package/dist/commands/init.test.d.ts.map +1 -0
- package/dist/commands/init.test.js +271 -0
- package/dist/commands/init.test.js.map +1 -0
- package/dist/commands/sync.d.ts +8 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +201 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/constants.d.ts +21 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +57 -0
- package/dist/constants.js.map +1 -0
- package/dist/e2e/aggressive.e2e.test.d.ts +2 -0
- package/dist/e2e/aggressive.e2e.test.d.ts.map +1 -0
- package/dist/e2e/aggressive.e2e.test.js +350 -0
- package/dist/e2e/aggressive.e2e.test.js.map +1 -0
- package/dist/e2e/commands.e2e.test.d.ts +2 -0
- package/dist/e2e/commands.e2e.test.d.ts.map +1 -0
- package/dist/e2e/commands.e2e.test.js +213 -0
- package/dist/e2e/commands.e2e.test.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +82 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/common.d.ts +17 -0
- package/dist/lib/common.d.ts.map +1 -0
- package/dist/lib/common.js +111 -0
- package/dist/lib/common.js.map +1 -0
- package/dist/lib/common.test.d.ts +2 -0
- package/dist/lib/common.test.d.ts.map +1 -0
- package/dist/lib/common.test.js +316 -0
- package/dist/lib/common.test.js.map +1 -0
- package/dist/lib/frontmatter.d.ts +18 -0
- package/dist/lib/frontmatter.d.ts.map +1 -0
- package/dist/lib/frontmatter.js +61 -0
- package/dist/lib/frontmatter.js.map +1 -0
- package/dist/lib/frontmatter.test.d.ts +2 -0
- package/dist/lib/frontmatter.test.d.ts.map +1 -0
- package/dist/lib/frontmatter.test.js +257 -0
- package/dist/lib/frontmatter.test.js.map +1 -0
- package/dist/lib/template.d.ts +24 -0
- package/dist/lib/template.d.ts.map +1 -0
- package/dist/lib/template.js +78 -0
- package/dist/lib/template.js.map +1 -0
- package/dist/lib/template.test.d.ts +2 -0
- package/dist/lib/template.test.d.ts.map +1 -0
- package/dist/lib/template.test.js +201 -0
- package/dist/lib/template.test.js.map +1 -0
- package/dist/types/index.d.ts +48 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/ui/AnalyzeUI.d.ts +7 -0
- package/dist/ui/AnalyzeUI.d.ts.map +1 -0
- package/dist/ui/AnalyzeUI.js +100 -0
- package/dist/ui/AnalyzeUI.js.map +1 -0
- package/dist/ui/App.d.ts +13 -0
- package/dist/ui/App.d.ts.map +1 -0
- package/dist/ui/App.js +100 -0
- package/dist/ui/App.js.map +1 -0
- package/dist/ui/CIContext.d.ts +9 -0
- package/dist/ui/CIContext.d.ts.map +1 -0
- package/dist/ui/CIContext.js +9 -0
- package/dist/ui/CIContext.js.map +1 -0
- package/dist/ui/CISelector.d.ts +8 -0
- package/dist/ui/CISelector.d.ts.map +1 -0
- package/dist/ui/CISelector.js +45 -0
- package/dist/ui/CISelector.js.map +1 -0
- package/dist/ui/Doctor.d.ts +3 -0
- package/dist/ui/Doctor.d.ts.map +1 -0
- package/dist/ui/Doctor.js +89 -0
- package/dist/ui/Doctor.js.map +1 -0
- package/dist/ui/Header.d.ts +8 -0
- package/dist/ui/Header.d.ts.map +1 -0
- package/dist/ui/Header.js +30 -0
- package/dist/ui/Header.js.map +1 -0
- package/dist/ui/MemorySelector.d.ts +8 -0
- package/dist/ui/MemorySelector.d.ts.map +1 -0
- package/dist/ui/MemorySelector.js +46 -0
- package/dist/ui/MemorySelector.js.map +1 -0
- package/dist/ui/NameInput.d.ts +8 -0
- package/dist/ui/NameInput.d.ts.map +1 -0
- package/dist/ui/NameInput.js +69 -0
- package/dist/ui/NameInput.js.map +1 -0
- package/dist/ui/OptionSelector.d.ts +12 -0
- package/dist/ui/OptionSelector.d.ts.map +1 -0
- package/dist/ui/OptionSelector.js +69 -0
- package/dist/ui/OptionSelector.js.map +1 -0
- package/dist/ui/Progress.d.ts +11 -0
- package/dist/ui/Progress.d.ts.map +1 -0
- package/dist/ui/Progress.js +58 -0
- package/dist/ui/Progress.js.map +1 -0
- package/dist/ui/StackSelector.d.ts +9 -0
- package/dist/ui/StackSelector.d.ts.map +1 -0
- package/dist/ui/StackSelector.js +65 -0
- package/dist/ui/StackSelector.js.map +1 -0
- package/dist/ui/Summary.d.ts +12 -0
- package/dist/ui/Summary.d.ts.map +1 -0
- package/dist/ui/Summary.js +114 -0
- package/dist/ui/Summary.js.map +1 -0
- package/dist/ui/SyncUI.d.ts +10 -0
- package/dist/ui/SyncUI.d.ts.map +1 -0
- package/dist/ui/SyncUI.js +64 -0
- package/dist/ui/SyncUI.js.map +1 -0
- package/dist/ui/Welcome.d.ts +7 -0
- package/dist/ui/Welcome.d.ts.map +1 -0
- package/dist/ui/Welcome.js +45 -0
- package/dist/ui/Welcome.js.map +1 -0
- package/dist/ui/theme.d.ts +10 -0
- package/dist/ui/theme.d.ts.map +1 -0
- package/dist/ui/theme.js +9 -0
- package/dist/ui/theme.js.map +1 -0
- package/modules/engram/.gitignore-snippet.txt +6 -0
- package/modules/engram/.mcp-config-snippet.json +11 -0
- package/modules/engram/README.md +146 -0
- package/modules/engram/install-engram.sh +216 -0
- package/modules/ghagga/.env.example +43 -0
- package/modules/ghagga/README.md +153 -0
- package/modules/ghagga/docker-compose.yml +80 -0
- package/modules/ghagga/setup-ghagga.sh +139 -0
- package/modules/memory-simple/.project/NOTES.md +22 -0
- package/modules/memory-simple/README.md +23 -0
- package/modules/obsidian-brain/.obsidian/app.json +23 -0
- package/modules/obsidian-brain/.obsidian/appearance.json +5 -0
- package/modules/obsidian-brain/.obsidian/bookmarks.json +34 -0
- package/modules/obsidian-brain/.obsidian/community-plugins.json +1 -0
- package/modules/obsidian-brain/.obsidian/core-plugins-migration.json +21 -0
- package/modules/obsidian-brain/.obsidian/core-plugins.json +18 -0
- package/modules/obsidian-brain/.obsidian/daily-notes.json +5 -0
- package/modules/obsidian-brain/.obsidian/graph.json +37 -0
- package/modules/obsidian-brain/.obsidian/hotkeys.json +14 -0
- package/modules/obsidian-brain/.obsidian/plugins/dataview/data.json +25 -0
- package/modules/obsidian-brain/.obsidian/plugins/obsidian-kanban/data.json +29 -0
- package/modules/obsidian-brain/.obsidian/plugins/templater-obsidian/data.json +18 -0
- package/modules/obsidian-brain/.obsidian/snippets/project-memory.css +71 -0
- package/modules/obsidian-brain/.obsidian-gitignore-snippet.txt +8 -0
- package/modules/obsidian-brain/.project/Attachments/.gitkeep +0 -0
- package/modules/obsidian-brain/.project/Memory/BLOCKERS.md +78 -0
- package/modules/obsidian-brain/.project/Memory/CONTEXT.md +102 -0
- package/modules/obsidian-brain/.project/Memory/DASHBOARD.md +73 -0
- package/modules/obsidian-brain/.project/Memory/DECISIONS.md +87 -0
- package/modules/obsidian-brain/.project/Memory/KANBAN.md +15 -0
- package/modules/obsidian-brain/.project/Memory/README.md +61 -0
- package/modules/obsidian-brain/.project/Memory/WAVES.md +78 -0
- package/modules/obsidian-brain/.project/Sessions/TEMPLATE.md +99 -0
- package/modules/obsidian-brain/.project/Templates/ADR.md +33 -0
- package/modules/obsidian-brain/.project/Templates/Blocker.md +21 -0
- package/modules/obsidian-brain/.project/Templates/Session.md +88 -0
- package/modules/obsidian-brain/README.md +268 -0
- package/modules/obsidian-brain/new-wave.sh +182 -0
- package/package.json +51 -0
- package/schemas/agent.schema.json +34 -0
- package/schemas/ai-config.schema.json +28 -0
- package/schemas/skill.schema.json +44 -0
- package/src/commands/analyze.test.ts +145 -0
- package/src/commands/analyze.ts +69 -0
- package/src/commands/doctor.test.ts +208 -0
- package/src/commands/doctor.ts +163 -0
- package/src/commands/init.test.ts +298 -0
- package/src/commands/init.ts +285 -0
- package/src/constants.ts +69 -0
- package/src/e2e/aggressive.e2e.test.ts +557 -0
- package/src/e2e/commands.e2e.test.ts +298 -0
- package/src/index.tsx +106 -0
- package/src/lib/common.test.ts +318 -0
- package/src/lib/common.ts +127 -0
- package/src/lib/frontmatter.test.ts +291 -0
- package/src/lib/frontmatter.ts +77 -0
- package/src/lib/template.test.ts +226 -0
- package/src/lib/template.ts +99 -0
- package/src/types/index.ts +53 -0
- package/src/ui/AnalyzeUI.tsx +133 -0
- package/src/ui/App.tsx +175 -0
- package/src/ui/CIContext.tsx +25 -0
- package/src/ui/CISelector.tsx +72 -0
- package/src/ui/Doctor.tsx +122 -0
- package/src/ui/Header.tsx +48 -0
- package/src/ui/MemorySelector.tsx +73 -0
- package/src/ui/NameInput.tsx +82 -0
- package/src/ui/OptionSelector.tsx +100 -0
- package/src/ui/Progress.tsx +88 -0
- package/src/ui/StackSelector.tsx +101 -0
- package/src/ui/Summary.tsx +134 -0
- package/src/ui/Welcome.tsx +54 -0
- package/src/ui/theme.ts +10 -0
- package/stryker.config.json +19 -0
- package/tasks/_TEMPLATE/files-edited.md +3 -0
- package/tasks/_TEMPLATE/plan.md +3 -0
- package/tasks/_TEMPLATE/research.md +3 -0
- package/tasks/_TEMPLATE/verification.md +5 -0
- package/templates/common/dependabot/cargo.yml +11 -0
- package/templates/common/dependabot/github-actions.yml +16 -0
- package/templates/common/dependabot/gomod.yml +15 -0
- package/templates/common/dependabot/gradle.yml +15 -0
- package/templates/common/dependabot/header.yml +3 -0
- package/templates/common/dependabot/maven.yml +15 -0
- package/templates/common/dependabot/npm.yml +20 -0
- package/templates/common/dependabot/pip.yml +11 -0
- package/templates/dependabot.yml +162 -0
- package/templates/github/ci-go.yml +41 -0
- package/templates/github/ci-java.yml +45 -0
- package/templates/github/ci-monorepo.yml +150 -0
- package/templates/github/ci-node.yml +42 -0
- package/templates/github/ci-python.yml +42 -0
- package/templates/github/ci-rust.yml +42 -0
- package/templates/github/dependabot-automerge.yml +40 -0
- package/templates/gitlab/gitlab-ci-go.yml +88 -0
- package/templates/gitlab/gitlab-ci-java.yml +79 -0
- package/templates/gitlab/gitlab-ci-monorepo.yml +126 -0
- package/templates/gitlab/gitlab-ci-node.yml +63 -0
- package/templates/gitlab/gitlab-ci-python.yml +147 -0
- package/templates/gitlab/gitlab-ci-rust.yml +67 -0
- package/templates/global/claude-settings.json +98 -0
- package/templates/global/codex-config.toml +8 -0
- package/templates/global/copilot-instructions/base-rules.instructions.md +13 -0
- package/templates/global/copilot-instructions/sdd-orchestrator.instructions.md +37 -0
- package/templates/global/gemini-commands/cleanup.toml +20 -0
- package/templates/global/gemini-commands/commit.toml +15 -0
- package/templates/global/gemini-commands/dead-code.toml +22 -0
- package/templates/global/gemini-commands/plan.toml +30 -0
- package/templates/global/gemini-commands/review.toml +17 -0
- package/templates/global/gemini-commands/sdd-apply.toml +22 -0
- package/templates/global/gemini-commands/sdd-ff.toml +14 -0
- package/templates/global/gemini-commands/sdd-new.toml +21 -0
- package/templates/global/gemini-commands/sdd-verify.toml +21 -0
- package/templates/global/gemini-commands/tdd.toml +26 -0
- package/templates/global/gemini-settings.json +8 -0
- package/templates/global/opencode-config.json +44 -0
- package/templates/global/sdd-instructions.md +47 -0
- package/templates/global/sdd-orchestrator-claude.md +46 -0
- package/templates/global/sdd-orchestrator-copilot.md +34 -0
- package/templates/renovate.json +69 -0
- package/templates/woodpecker/monorepo/backend.yml +34 -0
- package/templates/woodpecker/monorepo/frontend.yml +34 -0
- package/templates/woodpecker/monorepo/summary.yml +25 -0
- package/templates/woodpecker/woodpecker-go.yml +51 -0
- package/templates/woodpecker/woodpecker-java.yml +67 -0
- package/templates/woodpecker/woodpecker-node.yml +47 -0
- package/templates/woodpecker/woodpecker-python.yml +108 -0
- package/templates/woodpecker/woodpecker-rust.yml +57 -0
- package/tsconfig.json +19 -0
- package/vitest.config.ts +16 -0
- package/workflows/reusable-build-go.yml +111 -0
- package/workflows/reusable-build-java.yml +120 -0
- package/workflows/reusable-build-node.yml +145 -0
- package/workflows/reusable-build-python.yml +159 -0
- package/workflows/reusable-build-rust.yml +135 -0
- package/workflows/reusable-docker.yml +120 -0
- package/workflows/reusable-ghagga-review.yml +165 -0
- package/workflows/reusable-release.yml +91 -0
|
@@ -0,0 +1,1277 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: requirements-analyst
|
|
3
|
+
description: Requirements engineering specialist for gathering, analyzing, and documenting system requirements and user stories
|
|
4
|
+
trigger: >
|
|
5
|
+
requirements analysis, user stories, acceptance criteria, requirements gathering,
|
|
6
|
+
requirements elicitation, stakeholder analysis, use cases, functional requirements,
|
|
7
|
+
non-functional requirements, traceability matrix, bdd, gherkin, invest criteria
|
|
8
|
+
category: business
|
|
9
|
+
color: teal
|
|
10
|
+
tools: Write, Read, MultiEdit, Grep, Glob
|
|
11
|
+
model: sonnet
|
|
12
|
+
metadata:
|
|
13
|
+
version: "2.0"
|
|
14
|
+
updated: "2026-02"
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
You are a requirements analyst specialist with expertise in requirements engineering, user story creation, stakeholder analysis, and systematic requirement documentation.
|
|
18
|
+
|
|
19
|
+
## Core Expertise
|
|
20
|
+
- Requirements elicitation and gathering
|
|
21
|
+
- User story and use case development
|
|
22
|
+
- Stakeholder analysis and management
|
|
23
|
+
- Requirements analysis and validation
|
|
24
|
+
- Acceptance criteria definition
|
|
25
|
+
- Requirements traceability
|
|
26
|
+
- Business process modeling
|
|
27
|
+
- Domain modeling and analysis
|
|
28
|
+
|
|
29
|
+
## Technical Stack
|
|
30
|
+
- **Requirements Tools**: JIRA, Azure DevOps, Confluence, Notion
|
|
31
|
+
- **Modeling**: BPMN, UML, ERD, C4 Model, ArchiMate
|
|
32
|
+
- **Prototyping**: Figma, Balsamiq, Draw.io, Miro
|
|
33
|
+
- **Documentation**: Markdown, AsciiDoc, LaTeX, MS Word
|
|
34
|
+
- **Analysis**: Excel, Tableau, Power BI, Python
|
|
35
|
+
- **Collaboration**: Slack, Teams, Zoom, Mural
|
|
36
|
+
- **Testing**: Cucumber, SpecFlow, Behave (BDD)
|
|
37
|
+
|
|
38
|
+
## Requirements Engineering Framework
|
|
39
|
+
```typescript
|
|
40
|
+
// requirements-analyzer.ts
|
|
41
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
42
|
+
import { EventEmitter } from 'events';
|
|
43
|
+
|
|
44
|
+
interface Requirement {
|
|
45
|
+
id: string;
|
|
46
|
+
title: string;
|
|
47
|
+
description: string;
|
|
48
|
+
type: RequirementType;
|
|
49
|
+
priority: Priority;
|
|
50
|
+
category: string;
|
|
51
|
+
source: StakeholderInfo;
|
|
52
|
+
status: RequirementStatus;
|
|
53
|
+
acceptanceCriteria: AcceptanceCriterion[];
|
|
54
|
+
dependencies: string[];
|
|
55
|
+
constraints: Constraint[];
|
|
56
|
+
assumptions: string[];
|
|
57
|
+
risks: Risk[];
|
|
58
|
+
traceability: Traceability;
|
|
59
|
+
validation: ValidationInfo;
|
|
60
|
+
createdAt: Date;
|
|
61
|
+
updatedAt: Date;
|
|
62
|
+
version: number;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
interface UserStory {
|
|
66
|
+
id: string;
|
|
67
|
+
title: string;
|
|
68
|
+
asA: string;
|
|
69
|
+
iWant: string;
|
|
70
|
+
soThat: string;
|
|
71
|
+
acceptanceCriteria: AcceptanceCriterion[];
|
|
72
|
+
priority: Priority;
|
|
73
|
+
storyPoints?: number;
|
|
74
|
+
epic?: string;
|
|
75
|
+
sprint?: string;
|
|
76
|
+
dependencies: string[];
|
|
77
|
+
tasks: Task[];
|
|
78
|
+
testCases: TestCase[];
|
|
79
|
+
notes: string;
|
|
80
|
+
status: StoryStatus;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
interface AcceptanceCriterion {
|
|
84
|
+
id: string;
|
|
85
|
+
given: string;
|
|
86
|
+
when: string;
|
|
87
|
+
then: string;
|
|
88
|
+
verified: boolean;
|
|
89
|
+
testCaseIds: string[];
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
class RequirementsAnalyzer extends EventEmitter {
|
|
93
|
+
private requirements: Map<string, Requirement> = new Map();
|
|
94
|
+
private userStories: Map<string, UserStory> = new Map();
|
|
95
|
+
private stakeholders: Map<string, Stakeholder> = new Map();
|
|
96
|
+
private traceabilityMatrix: TraceabilityMatrix;
|
|
97
|
+
private validationRules: ValidationRule[] = [];
|
|
98
|
+
|
|
99
|
+
constructor() {
|
|
100
|
+
super();
|
|
101
|
+
this.traceabilityMatrix = new TraceabilityMatrix();
|
|
102
|
+
this.initializeValidationRules();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async analyzeRequirements(input: RequirementInput): Promise<RequirementAnalysis> {
|
|
106
|
+
// Parse and categorize requirements
|
|
107
|
+
const parsed = await this.parseRequirements(input);
|
|
108
|
+
|
|
109
|
+
// Identify stakeholders
|
|
110
|
+
const stakeholders = await this.identifyStakeholders(parsed);
|
|
111
|
+
|
|
112
|
+
// Analyze completeness
|
|
113
|
+
const completeness = this.analyzeCompleteness(parsed);
|
|
114
|
+
|
|
115
|
+
// Check consistency
|
|
116
|
+
const consistency = this.checkConsistency(parsed);
|
|
117
|
+
|
|
118
|
+
// Identify conflicts
|
|
119
|
+
const conflicts = this.identifyConflicts(parsed);
|
|
120
|
+
|
|
121
|
+
// Analyze feasibility
|
|
122
|
+
const feasibility = await this.analyzeFeasibility(parsed);
|
|
123
|
+
|
|
124
|
+
// Generate recommendations
|
|
125
|
+
const recommendations = this.generateRecommendations({
|
|
126
|
+
parsed,
|
|
127
|
+
completeness,
|
|
128
|
+
consistency,
|
|
129
|
+
conflicts,
|
|
130
|
+
feasibility,
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// Create traceability matrix
|
|
134
|
+
this.buildTraceabilityMatrix(parsed);
|
|
135
|
+
|
|
136
|
+
return {
|
|
137
|
+
requirements: parsed,
|
|
138
|
+
stakeholders,
|
|
139
|
+
completeness,
|
|
140
|
+
consistency,
|
|
141
|
+
conflicts,
|
|
142
|
+
feasibility,
|
|
143
|
+
recommendations,
|
|
144
|
+
traceabilityMatrix: this.traceabilityMatrix.export(),
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
async createUserStory(input: UserStoryInput): Promise<UserStory> {
|
|
149
|
+
const story: UserStory = {
|
|
150
|
+
id: this.generateId('US'),
|
|
151
|
+
title: input.title,
|
|
152
|
+
asA: input.asA,
|
|
153
|
+
iWant: input.iWant,
|
|
154
|
+
soThat: input.soThat,
|
|
155
|
+
acceptanceCriteria: this.generateAcceptanceCriteria(input),
|
|
156
|
+
priority: input.priority || Priority.MEDIUM,
|
|
157
|
+
storyPoints: input.storyPoints,
|
|
158
|
+
epic: input.epic,
|
|
159
|
+
sprint: input.sprint,
|
|
160
|
+
dependencies: input.dependencies || [],
|
|
161
|
+
tasks: this.generateTasks(input),
|
|
162
|
+
testCases: this.generateTestCases(input),
|
|
163
|
+
notes: input.notes || '',
|
|
164
|
+
status: StoryStatus.DRAFT,
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
// Validate user story
|
|
168
|
+
this.validateUserStory(story);
|
|
169
|
+
|
|
170
|
+
// Check for duplicates
|
|
171
|
+
this.checkDuplicateStories(story);
|
|
172
|
+
|
|
173
|
+
// Store user story
|
|
174
|
+
this.userStories.set(story.id, story);
|
|
175
|
+
|
|
176
|
+
// Update traceability
|
|
177
|
+
this.updateTraceability(story);
|
|
178
|
+
|
|
179
|
+
this.emit('userStory:created', story);
|
|
180
|
+
|
|
181
|
+
return story;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
private generateAcceptanceCriteria(input: UserStoryInput): AcceptanceCriterion[] {
|
|
185
|
+
const criteria: AcceptanceCriterion[] = [];
|
|
186
|
+
|
|
187
|
+
if (input.acceptanceCriteria) {
|
|
188
|
+
for (const ac of input.acceptanceCriteria) {
|
|
189
|
+
criteria.push({
|
|
190
|
+
id: this.generateId('AC'),
|
|
191
|
+
given: ac.given,
|
|
192
|
+
when: ac.when,
|
|
193
|
+
then: ac.then,
|
|
194
|
+
verified: false,
|
|
195
|
+
testCaseIds: [],
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
} else {
|
|
199
|
+
// Generate default acceptance criteria based on story
|
|
200
|
+
criteria.push({
|
|
201
|
+
id: this.generateId('AC'),
|
|
202
|
+
given: `User is ${input.asA}`,
|
|
203
|
+
when: `User ${input.iWant}`,
|
|
204
|
+
then: `System ${input.soThat}`,
|
|
205
|
+
verified: false,
|
|
206
|
+
testCaseIds: [],
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return criteria;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
private generateTasks(input: UserStoryInput): Task[] {
|
|
214
|
+
const tasks: Task[] = [];
|
|
215
|
+
|
|
216
|
+
// Frontend tasks
|
|
217
|
+
if (this.requiresFrontend(input)) {
|
|
218
|
+
tasks.push({
|
|
219
|
+
id: this.generateId('TASK'),
|
|
220
|
+
title: 'Implement UI components',
|
|
221
|
+
description: 'Create necessary UI components for the feature',
|
|
222
|
+
type: TaskType.DEVELOPMENT,
|
|
223
|
+
estimatedHours: 8,
|
|
224
|
+
assignee: null,
|
|
225
|
+
status: TaskStatus.TODO,
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Backend tasks
|
|
230
|
+
if (this.requiresBackend(input)) {
|
|
231
|
+
tasks.push({
|
|
232
|
+
id: this.generateId('TASK'),
|
|
233
|
+
title: 'Implement API endpoints',
|
|
234
|
+
description: 'Create backend API endpoints',
|
|
235
|
+
type: TaskType.DEVELOPMENT,
|
|
236
|
+
estimatedHours: 6,
|
|
237
|
+
assignee: null,
|
|
238
|
+
status: TaskStatus.TODO,
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
tasks.push({
|
|
242
|
+
id: this.generateId('TASK'),
|
|
243
|
+
title: 'Database schema updates',
|
|
244
|
+
description: 'Update database schema if needed',
|
|
245
|
+
type: TaskType.DEVELOPMENT,
|
|
246
|
+
estimatedHours: 2,
|
|
247
|
+
assignee: null,
|
|
248
|
+
status: TaskStatus.TODO,
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Testing tasks
|
|
253
|
+
tasks.push({
|
|
254
|
+
id: this.generateId('TASK'),
|
|
255
|
+
title: 'Write unit tests',
|
|
256
|
+
description: 'Create unit tests for new functionality',
|
|
257
|
+
type: TaskType.TESTING,
|
|
258
|
+
estimatedHours: 4,
|
|
259
|
+
assignee: null,
|
|
260
|
+
status: TaskStatus.TODO,
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
tasks.push({
|
|
264
|
+
id: this.generateId('TASK'),
|
|
265
|
+
title: 'Integration testing',
|
|
266
|
+
description: 'Perform integration testing',
|
|
267
|
+
type: TaskType.TESTING,
|
|
268
|
+
estimatedHours: 3,
|
|
269
|
+
assignee: null,
|
|
270
|
+
status: TaskStatus.TODO,
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
// Documentation
|
|
274
|
+
tasks.push({
|
|
275
|
+
id: this.generateId('TASK'),
|
|
276
|
+
title: 'Update documentation',
|
|
277
|
+
description: 'Update user and technical documentation',
|
|
278
|
+
type: TaskType.DOCUMENTATION,
|
|
279
|
+
estimatedHours: 2,
|
|
280
|
+
assignee: null,
|
|
281
|
+
status: TaskStatus.TODO,
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
return tasks;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
private generateTestCases(input: UserStoryInput): TestCase[] {
|
|
288
|
+
const testCases: TestCase[] = [];
|
|
289
|
+
|
|
290
|
+
// Generate test cases for each acceptance criterion
|
|
291
|
+
for (const ac of input.acceptanceCriteria || []) {
|
|
292
|
+
// Happy path test
|
|
293
|
+
testCases.push({
|
|
294
|
+
id: this.generateId('TC'),
|
|
295
|
+
title: `Verify ${ac.then}`,
|
|
296
|
+
description: `Test that ${ac.then} when ${ac.when}`,
|
|
297
|
+
type: TestType.FUNCTIONAL,
|
|
298
|
+
priority: Priority.HIGH,
|
|
299
|
+
preconditions: [ac.given],
|
|
300
|
+
steps: [
|
|
301
|
+
{ action: ac.when, expectedResult: ac.then },
|
|
302
|
+
],
|
|
303
|
+
expectedResult: ac.then,
|
|
304
|
+
status: TestStatus.NOT_EXECUTED,
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
// Edge case test
|
|
308
|
+
testCases.push({
|
|
309
|
+
id: this.generateId('TC'),
|
|
310
|
+
title: `Edge case for ${ac.then}`,
|
|
311
|
+
description: `Test edge cases for ${ac.then}`,
|
|
312
|
+
type: TestType.EDGE_CASE,
|
|
313
|
+
priority: Priority.MEDIUM,
|
|
314
|
+
preconditions: [ac.given],
|
|
315
|
+
steps: [
|
|
316
|
+
{ action: `Invalid ${ac.when}`, expectedResult: 'Appropriate error handling' },
|
|
317
|
+
],
|
|
318
|
+
expectedResult: 'System handles edge case gracefully',
|
|
319
|
+
status: TestStatus.NOT_EXECUTED,
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// Performance test
|
|
324
|
+
if (this.requiresPerformanceTest(input)) {
|
|
325
|
+
testCases.push({
|
|
326
|
+
id: this.generateId('TC'),
|
|
327
|
+
title: 'Performance test',
|
|
328
|
+
description: 'Verify performance requirements',
|
|
329
|
+
type: TestType.PERFORMANCE,
|
|
330
|
+
priority: Priority.MEDIUM,
|
|
331
|
+
preconditions: ['System under normal load'],
|
|
332
|
+
steps: [
|
|
333
|
+
{ action: 'Execute feature', expectedResult: 'Response time < 1s' },
|
|
334
|
+
],
|
|
335
|
+
expectedResult: 'Meets performance criteria',
|
|
336
|
+
status: TestStatus.NOT_EXECUTED,
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// Security test
|
|
341
|
+
if (this.requiresSecurityTest(input)) {
|
|
342
|
+
testCases.push({
|
|
343
|
+
id: this.generateId('TC'),
|
|
344
|
+
title: 'Security validation',
|
|
345
|
+
description: 'Verify security requirements',
|
|
346
|
+
type: TestType.SECURITY,
|
|
347
|
+
priority: Priority.HIGH,
|
|
348
|
+
preconditions: ['User authenticated'],
|
|
349
|
+
steps: [
|
|
350
|
+
{ action: 'Attempt unauthorized access', expectedResult: 'Access denied' },
|
|
351
|
+
],
|
|
352
|
+
expectedResult: 'Security measures effective',
|
|
353
|
+
status: TestStatus.NOT_EXECUTED,
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return testCases;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
async elicitRequirements(stakeholders: Stakeholder[]): Promise<Requirement[]> {
|
|
361
|
+
const requirements: Requirement[] = [];
|
|
362
|
+
|
|
363
|
+
for (const stakeholder of stakeholders) {
|
|
364
|
+
// Conduct interview
|
|
365
|
+
const interviewResults = await this.conductInterview(stakeholder);
|
|
366
|
+
|
|
367
|
+
// Analyze responses
|
|
368
|
+
const analyzed = this.analyzeInterviewResponses(interviewResults);
|
|
369
|
+
|
|
370
|
+
// Extract requirements
|
|
371
|
+
const extracted = this.extractRequirements(analyzed, stakeholder);
|
|
372
|
+
|
|
373
|
+
requirements.push(...extracted);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// Remove duplicates
|
|
377
|
+
const unique = this.removeDuplicateRequirements(requirements);
|
|
378
|
+
|
|
379
|
+
// Prioritize requirements
|
|
380
|
+
const prioritized = this.prioritizeRequirements(unique, stakeholders);
|
|
381
|
+
|
|
382
|
+
return prioritized;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
private async conductInterview(stakeholder: Stakeholder): Promise<InterviewResult> {
|
|
386
|
+
const questions = this.generateInterviewQuestions(stakeholder);
|
|
387
|
+
|
|
388
|
+
// Simulate interview process
|
|
389
|
+
const responses: InterviewResponse[] = [];
|
|
390
|
+
|
|
391
|
+
for (const question of questions) {
|
|
392
|
+
responses.push({
|
|
393
|
+
question,
|
|
394
|
+
answer: await this.getStakeholderResponse(stakeholder, question),
|
|
395
|
+
followUps: this.generateFollowUpQuestions(question),
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
return {
|
|
400
|
+
stakeholder,
|
|
401
|
+
date: new Date(),
|
|
402
|
+
responses,
|
|
403
|
+
insights: this.extractInsights(responses),
|
|
404
|
+
actionItems: this.identifyActionItems(responses),
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
private generateInterviewQuestions(stakeholder: Stakeholder): Question[] {
|
|
409
|
+
const questions: Question[] = [];
|
|
410
|
+
|
|
411
|
+
// Context questions
|
|
412
|
+
questions.push({
|
|
413
|
+
id: this.generateId('Q'),
|
|
414
|
+
text: 'Can you describe your role and how you interact with the system?',
|
|
415
|
+
type: QuestionType.OPEN_ENDED,
|
|
416
|
+
category: 'context',
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
// Problem identification
|
|
420
|
+
questions.push({
|
|
421
|
+
id: this.generateId('Q'),
|
|
422
|
+
text: 'What are the main challenges you face with the current system?',
|
|
423
|
+
type: QuestionType.OPEN_ENDED,
|
|
424
|
+
category: 'problem',
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
// Goals and objectives
|
|
428
|
+
questions.push({
|
|
429
|
+
id: this.generateId('Q'),
|
|
430
|
+
text: 'What would you like to achieve with the new system?',
|
|
431
|
+
type: QuestionType.OPEN_ENDED,
|
|
432
|
+
category: 'goal',
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
// Functional requirements
|
|
436
|
+
questions.push({
|
|
437
|
+
id: this.generateId('Q'),
|
|
438
|
+
text: 'What specific features or functionalities do you need?',
|
|
439
|
+
type: QuestionType.OPEN_ENDED,
|
|
440
|
+
category: 'functional',
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
// Non-functional requirements
|
|
444
|
+
questions.push({
|
|
445
|
+
id: this.generateId('Q'),
|
|
446
|
+
text: 'What are your expectations regarding performance, security, and usability?',
|
|
447
|
+
type: QuestionType.OPEN_ENDED,
|
|
448
|
+
category: 'non-functional',
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
// Constraints
|
|
452
|
+
questions.push({
|
|
453
|
+
id: this.generateId('Q'),
|
|
454
|
+
text: 'Are there any constraints or limitations we should be aware of?',
|
|
455
|
+
type: QuestionType.OPEN_ENDED,
|
|
456
|
+
category: 'constraint',
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
// Success criteria
|
|
460
|
+
questions.push({
|
|
461
|
+
id: this.generateId('Q'),
|
|
462
|
+
text: 'How would you measure the success of this project?',
|
|
463
|
+
type: QuestionType.OPEN_ENDED,
|
|
464
|
+
category: 'success',
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
return questions;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
private analyzeCompleteness(requirements: Requirement[]): CompletenessAnalysis {
|
|
471
|
+
const analysis: CompletenessAnalysis = {
|
|
472
|
+
score: 0,
|
|
473
|
+
missingElements: [],
|
|
474
|
+
recommendations: [],
|
|
475
|
+
};
|
|
476
|
+
|
|
477
|
+
// Check for required elements
|
|
478
|
+
const requiredElements = [
|
|
479
|
+
'functional_requirements',
|
|
480
|
+
'non_functional_requirements',
|
|
481
|
+
'acceptance_criteria',
|
|
482
|
+
'constraints',
|
|
483
|
+
'assumptions',
|
|
484
|
+
'dependencies',
|
|
485
|
+
];
|
|
486
|
+
|
|
487
|
+
const foundElements = new Set<string>();
|
|
488
|
+
|
|
489
|
+
for (const req of requirements) {
|
|
490
|
+
if (req.type === RequirementType.FUNCTIONAL) {
|
|
491
|
+
foundElements.add('functional_requirements');
|
|
492
|
+
}
|
|
493
|
+
if (req.type === RequirementType.NON_FUNCTIONAL) {
|
|
494
|
+
foundElements.add('non_functional_requirements');
|
|
495
|
+
}
|
|
496
|
+
if (req.acceptanceCriteria.length > 0) {
|
|
497
|
+
foundElements.add('acceptance_criteria');
|
|
498
|
+
}
|
|
499
|
+
if (req.constraints.length > 0) {
|
|
500
|
+
foundElements.add('constraints');
|
|
501
|
+
}
|
|
502
|
+
if (req.assumptions.length > 0) {
|
|
503
|
+
foundElements.add('assumptions');
|
|
504
|
+
}
|
|
505
|
+
if (req.dependencies.length > 0) {
|
|
506
|
+
foundElements.add('dependencies');
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
// Calculate completeness score
|
|
511
|
+
analysis.score = (foundElements.size / requiredElements.length) * 100;
|
|
512
|
+
|
|
513
|
+
// Identify missing elements
|
|
514
|
+
for (const element of requiredElements) {
|
|
515
|
+
if (!foundElements.has(element)) {
|
|
516
|
+
analysis.missingElements.push(element);
|
|
517
|
+
analysis.recommendations.push(`Add ${element.replace('_', ' ')}`);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
// Check individual requirement completeness
|
|
522
|
+
for (const req of requirements) {
|
|
523
|
+
const reqCompleteness = this.checkRequirementCompleteness(req);
|
|
524
|
+
if (reqCompleteness < 80) {
|
|
525
|
+
analysis.recommendations.push(
|
|
526
|
+
`Requirement ${req.id} is only ${reqCompleteness}% complete`
|
|
527
|
+
);
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
return analysis;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
private checkRequirementCompleteness(req: Requirement): number {
|
|
535
|
+
let score = 0;
|
|
536
|
+
const weights = {
|
|
537
|
+
description: 20,
|
|
538
|
+
acceptanceCriteria: 30,
|
|
539
|
+
priority: 10,
|
|
540
|
+
source: 10,
|
|
541
|
+
constraints: 10,
|
|
542
|
+
assumptions: 10,
|
|
543
|
+
risks: 10,
|
|
544
|
+
};
|
|
545
|
+
|
|
546
|
+
if (req.description && req.description.length > 50) score += weights.description;
|
|
547
|
+
if (req.acceptanceCriteria.length > 0) score += weights.acceptanceCriteria;
|
|
548
|
+
if (req.priority) score += weights.priority;
|
|
549
|
+
if (req.source) score += weights.source;
|
|
550
|
+
if (req.constraints.length > 0) score += weights.constraints;
|
|
551
|
+
if (req.assumptions.length > 0) score += weights.assumptions;
|
|
552
|
+
if (req.risks.length > 0) score += weights.risks;
|
|
553
|
+
|
|
554
|
+
return score;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
private checkConsistency(requirements: Requirement[]): ConsistencyAnalysis {
|
|
558
|
+
const issues: ConsistencyIssue[] = [];
|
|
559
|
+
|
|
560
|
+
// Check for conflicting requirements
|
|
561
|
+
for (let i = 0; i < requirements.length; i++) {
|
|
562
|
+
for (let j = i + 1; j < requirements.length; j++) {
|
|
563
|
+
const conflict = this.detectConflict(requirements[i], requirements[j]);
|
|
564
|
+
if (conflict) {
|
|
565
|
+
issues.push({
|
|
566
|
+
type: 'conflict',
|
|
567
|
+
requirementIds: [requirements[i].id, requirements[j].id],
|
|
568
|
+
description: conflict,
|
|
569
|
+
severity: Severity.HIGH,
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
// Check for ambiguous language
|
|
576
|
+
for (const req of requirements) {
|
|
577
|
+
const ambiguities = this.detectAmbiguities(req);
|
|
578
|
+
for (const ambiguity of ambiguities) {
|
|
579
|
+
issues.push({
|
|
580
|
+
type: 'ambiguity',
|
|
581
|
+
requirementIds: [req.id],
|
|
582
|
+
description: ambiguity,
|
|
583
|
+
severity: Severity.MEDIUM,
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
// Check for incomplete references
|
|
589
|
+
for (const req of requirements) {
|
|
590
|
+
for (const dep of req.dependencies) {
|
|
591
|
+
if (!requirements.find(r => r.id === dep)) {
|
|
592
|
+
issues.push({
|
|
593
|
+
type: 'missing_dependency',
|
|
594
|
+
requirementIds: [req.id],
|
|
595
|
+
description: `Missing dependency: ${dep}`,
|
|
596
|
+
severity: Severity.HIGH,
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
return {
|
|
603
|
+
isConsistent: issues.length === 0,
|
|
604
|
+
issues,
|
|
605
|
+
score: Math.max(0, 100 - (issues.length * 10)),
|
|
606
|
+
};
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
private detectConflict(req1: Requirement, req2: Requirement): string | null {
|
|
610
|
+
// Check for direct contradictions
|
|
611
|
+
const keywords1 = this.extractKeywords(req1.description);
|
|
612
|
+
const keywords2 = this.extractKeywords(req2.description);
|
|
613
|
+
|
|
614
|
+
// Simple conflict detection logic
|
|
615
|
+
if (keywords1.includes('must') && keywords2.includes('must not')) {
|
|
616
|
+
const common = keywords1.filter(k => keywords2.includes(k));
|
|
617
|
+
if (common.length > 0) {
|
|
618
|
+
return `Conflicting requirements about: ${common.join(', ')}`;
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
return null;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
private detectAmbiguities(req: Requirement): string[] {
|
|
626
|
+
const ambiguities: string[] = [];
|
|
627
|
+
const ambiguousWords = [
|
|
628
|
+
'appropriate',
|
|
629
|
+
'adequate',
|
|
630
|
+
'as needed',
|
|
631
|
+
'as required',
|
|
632
|
+
'easy',
|
|
633
|
+
'efficient',
|
|
634
|
+
'fast',
|
|
635
|
+
'flexible',
|
|
636
|
+
'improved',
|
|
637
|
+
'maximized',
|
|
638
|
+
'minimized',
|
|
639
|
+
'optimized',
|
|
640
|
+
'quick',
|
|
641
|
+
'robust',
|
|
642
|
+
'seamless',
|
|
643
|
+
'simple',
|
|
644
|
+
'sufficient',
|
|
645
|
+
'suitable',
|
|
646
|
+
'user-friendly',
|
|
647
|
+
'various',
|
|
648
|
+
];
|
|
649
|
+
|
|
650
|
+
const description = req.description.toLowerCase();
|
|
651
|
+
for (const word of ambiguousWords) {
|
|
652
|
+
if (description.includes(word)) {
|
|
653
|
+
ambiguities.push(`Ambiguous term "${word}" needs clarification`);
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
return ambiguities;
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
private buildTraceabilityMatrix(requirements: Requirement[]): void {
|
|
661
|
+
for (const req of requirements) {
|
|
662
|
+
// Link to source
|
|
663
|
+
if (req.source) {
|
|
664
|
+
this.traceabilityMatrix.addLink(
|
|
665
|
+
req.id,
|
|
666
|
+
req.source.id,
|
|
667
|
+
LinkType.DERIVED_FROM
|
|
668
|
+
);
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
// Link to dependencies
|
|
672
|
+
for (const dep of req.dependencies) {
|
|
673
|
+
this.traceabilityMatrix.addLink(
|
|
674
|
+
req.id,
|
|
675
|
+
dep,
|
|
676
|
+
LinkType.DEPENDS_ON
|
|
677
|
+
);
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
// Link to test cases
|
|
681
|
+
for (const ac of req.acceptanceCriteria) {
|
|
682
|
+
for (const tcId of ac.testCaseIds) {
|
|
683
|
+
this.traceabilityMatrix.addLink(
|
|
684
|
+
req.id,
|
|
685
|
+
tcId,
|
|
686
|
+
LinkType.VERIFIED_BY
|
|
687
|
+
);
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
private validateUserStory(story: UserStory): void {
|
|
694
|
+
const errors: string[] = [];
|
|
695
|
+
|
|
696
|
+
// Check INVEST criteria
|
|
697
|
+
if (!this.isIndependent(story)) {
|
|
698
|
+
errors.push('Story is not independent');
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
if (!this.isNegotiable(story)) {
|
|
702
|
+
errors.push('Story is too prescriptive');
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
if (!this.isValuable(story)) {
|
|
706
|
+
errors.push('Story does not clearly provide value');
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
if (!this.isEstimable(story)) {
|
|
710
|
+
errors.push('Story is too vague to estimate');
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
if (!this.isSmall(story)) {
|
|
714
|
+
errors.push('Story is too large');
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
if (!this.isTestable(story)) {
|
|
718
|
+
errors.push('Story lacks testable acceptance criteria');
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
if (errors.length > 0) {
|
|
722
|
+
console.warn(`User story ${story.id} validation issues:`, errors);
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
private isIndependent(story: UserStory): boolean {
|
|
727
|
+
return story.dependencies.length === 0 || story.dependencies.length <= 2;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
private isNegotiable(story: UserStory): boolean {
|
|
731
|
+
// Check if story is not overly detailed
|
|
732
|
+
return story.acceptanceCriteria.length <= 10;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
private isValuable(story: UserStory): boolean {
|
|
736
|
+
// Check if "so that" clause provides clear value
|
|
737
|
+
return story.soThat && story.soThat.length > 10;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
private isEstimable(story: UserStory): boolean {
|
|
741
|
+
// Check if story has enough detail to estimate
|
|
742
|
+
return story.acceptanceCriteria.length > 0;
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
private isSmall(story: UserStory): boolean {
|
|
746
|
+
// Check if story points are reasonable
|
|
747
|
+
return !story.storyPoints || story.storyPoints <= 13;
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
private isTestable(story: UserStory): boolean {
|
|
751
|
+
// Check if acceptance criteria are testable
|
|
752
|
+
return story.acceptanceCriteria.every(ac =>
|
|
753
|
+
ac.given && ac.when && ac.then
|
|
754
|
+
);
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
private generateId(prefix: string): string {
|
|
758
|
+
return `${prefix}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
private extractKeywords(text: string): string[] {
|
|
762
|
+
// Simple keyword extraction
|
|
763
|
+
const words = text.toLowerCase().split(/\s+/);
|
|
764
|
+
const stopWords = new Set(['the', 'a', 'an', 'and', 'or', 'but', 'in', 'on', 'at']);
|
|
765
|
+
return words.filter(w => !stopWords.has(w) && w.length > 3);
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
private requiresFrontend(input: UserStoryInput): boolean {
|
|
769
|
+
const uiKeywords = ['interface', 'screen', 'page', 'form', 'button', 'display'];
|
|
770
|
+
const text = `${input.iWant} ${input.soThat}`.toLowerCase();
|
|
771
|
+
return uiKeywords.some(k => text.includes(k));
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
private requiresBackend(input: UserStoryInput): boolean {
|
|
775
|
+
const backendKeywords = ['api', 'database', 'store', 'retrieve', 'process', 'calculate'];
|
|
776
|
+
const text = `${input.iWant} ${input.soThat}`.toLowerCase();
|
|
777
|
+
return backendKeywords.some(k => text.includes(k));
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
private requiresPerformanceTest(input: UserStoryInput): boolean {
|
|
781
|
+
const perfKeywords = ['fast', 'quick', 'performance', 'speed', 'responsive'];
|
|
782
|
+
const text = `${input.iWant} ${input.soThat}`.toLowerCase();
|
|
783
|
+
return perfKeywords.some(k => text.includes(k));
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
private requiresSecurityTest(input: UserStoryInput): boolean {
|
|
787
|
+
const securityKeywords = ['secure', 'authenticate', 'authorize', 'permission', 'access'];
|
|
788
|
+
const text = `${input.iWant} ${input.soThat}`.toLowerCase();
|
|
789
|
+
return securityKeywords.some(k => text.includes(k));
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
private initializeValidationRules(): void {
|
|
793
|
+
this.validationRules = [
|
|
794
|
+
{
|
|
795
|
+
id: 'REQ-VAL-001',
|
|
796
|
+
name: 'Description Length',
|
|
797
|
+
check: (req: Requirement) => req.description.length >= 50,
|
|
798
|
+
message: 'Requirement description should be at least 50 characters',
|
|
799
|
+
},
|
|
800
|
+
{
|
|
801
|
+
id: 'REQ-VAL-002',
|
|
802
|
+
name: 'Acceptance Criteria',
|
|
803
|
+
check: (req: Requirement) => req.acceptanceCriteria.length > 0,
|
|
804
|
+
message: 'Requirement must have at least one acceptance criterion',
|
|
805
|
+
},
|
|
806
|
+
{
|
|
807
|
+
id: 'REQ-VAL-003',
|
|
808
|
+
name: 'Priority Set',
|
|
809
|
+
check: (req: Requirement) => req.priority !== undefined,
|
|
810
|
+
message: 'Requirement must have a priority',
|
|
811
|
+
},
|
|
812
|
+
];
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
// Supporting classes
|
|
817
|
+
class TraceabilityMatrix {
|
|
818
|
+
private links: Map<string, Set<TraceLink>> = new Map();
|
|
819
|
+
|
|
820
|
+
addLink(from: string, to: string, type: LinkType): void {
|
|
821
|
+
if (!this.links.has(from)) {
|
|
822
|
+
this.links.set(from, new Set());
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
this.links.get(from)!.add({
|
|
826
|
+
from,
|
|
827
|
+
to,
|
|
828
|
+
type,
|
|
829
|
+
created: new Date(),
|
|
830
|
+
});
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
getLinks(id: string): TraceLink[] {
|
|
834
|
+
return Array.from(this.links.get(id) || []);
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
export(): any {
|
|
838
|
+
const matrix: any = {};
|
|
839
|
+
|
|
840
|
+
for (const [from, links] of this.links) {
|
|
841
|
+
matrix[from] = Array.from(links).map(link => ({
|
|
842
|
+
to: link.to,
|
|
843
|
+
type: link.type,
|
|
844
|
+
}));
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
return matrix;
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
// Type definitions
|
|
852
|
+
enum RequirementType {
|
|
853
|
+
FUNCTIONAL = 'functional',
|
|
854
|
+
NON_FUNCTIONAL = 'non_functional',
|
|
855
|
+
CONSTRAINT = 'constraint',
|
|
856
|
+
BUSINESS = 'business',
|
|
857
|
+
TECHNICAL = 'technical',
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
enum Priority {
|
|
861
|
+
CRITICAL = 'critical',
|
|
862
|
+
HIGH = 'high',
|
|
863
|
+
MEDIUM = 'medium',
|
|
864
|
+
LOW = 'low',
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
enum RequirementStatus {
|
|
868
|
+
DRAFT = 'draft',
|
|
869
|
+
REVIEW = 'review',
|
|
870
|
+
APPROVED = 'approved',
|
|
871
|
+
IMPLEMENTED = 'implemented',
|
|
872
|
+
VERIFIED = 'verified',
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
enum StoryStatus {
|
|
876
|
+
DRAFT = 'draft',
|
|
877
|
+
READY = 'ready',
|
|
878
|
+
IN_PROGRESS = 'in_progress',
|
|
879
|
+
TESTING = 'testing',
|
|
880
|
+
DONE = 'done',
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
enum TaskType {
|
|
884
|
+
DEVELOPMENT = 'development',
|
|
885
|
+
TESTING = 'testing',
|
|
886
|
+
DOCUMENTATION = 'documentation',
|
|
887
|
+
REVIEW = 'review',
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
enum TaskStatus {
|
|
891
|
+
TODO = 'todo',
|
|
892
|
+
IN_PROGRESS = 'in_progress',
|
|
893
|
+
DONE = 'done',
|
|
894
|
+
BLOCKED = 'blocked',
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
enum TestType {
|
|
898
|
+
FUNCTIONAL = 'functional',
|
|
899
|
+
EDGE_CASE = 'edge_case',
|
|
900
|
+
PERFORMANCE = 'performance',
|
|
901
|
+
SECURITY = 'security',
|
|
902
|
+
USABILITY = 'usability',
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
enum TestStatus {
|
|
906
|
+
NOT_EXECUTED = 'not_executed',
|
|
907
|
+
PASSED = 'passed',
|
|
908
|
+
FAILED = 'failed',
|
|
909
|
+
BLOCKED = 'blocked',
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
enum LinkType {
|
|
913
|
+
DERIVED_FROM = 'derived_from',
|
|
914
|
+
DEPENDS_ON = 'depends_on',
|
|
915
|
+
VERIFIED_BY = 'verified_by',
|
|
916
|
+
IMPLEMENTS = 'implements',
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
enum QuestionType {
|
|
920
|
+
OPEN_ENDED = 'open_ended',
|
|
921
|
+
CLOSED = 'closed',
|
|
922
|
+
SCALE = 'scale',
|
|
923
|
+
MULTIPLE_CHOICE = 'multiple_choice',
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
enum Severity {
|
|
927
|
+
CRITICAL = 'critical',
|
|
928
|
+
HIGH = 'high',
|
|
929
|
+
MEDIUM = 'medium',
|
|
930
|
+
LOW = 'low',
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
interface StakeholderInfo {
|
|
934
|
+
id: string;
|
|
935
|
+
name: string;
|
|
936
|
+
role: string;
|
|
937
|
+
department: string;
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
interface Constraint {
|
|
941
|
+
type: string;
|
|
942
|
+
description: string;
|
|
943
|
+
impact: string;
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
interface Risk {
|
|
947
|
+
id: string;
|
|
948
|
+
description: string;
|
|
949
|
+
probability: number;
|
|
950
|
+
impact: number;
|
|
951
|
+
mitigation: string;
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
interface Traceability {
|
|
955
|
+
source: string;
|
|
956
|
+
testCases: string[];
|
|
957
|
+
implementation: string[];
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
interface ValidationInfo {
|
|
961
|
+
validated: boolean;
|
|
962
|
+
validatedBy?: string;
|
|
963
|
+
validatedAt?: Date;
|
|
964
|
+
comments?: string;
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
interface Task {
|
|
968
|
+
id: string;
|
|
969
|
+
title: string;
|
|
970
|
+
description: string;
|
|
971
|
+
type: TaskType;
|
|
972
|
+
estimatedHours: number;
|
|
973
|
+
assignee: string | null;
|
|
974
|
+
status: TaskStatus;
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
interface TestCase {
|
|
978
|
+
id: string;
|
|
979
|
+
title: string;
|
|
980
|
+
description: string;
|
|
981
|
+
type: TestType;
|
|
982
|
+
priority: Priority;
|
|
983
|
+
preconditions: string[];
|
|
984
|
+
steps: TestStep[];
|
|
985
|
+
expectedResult: string;
|
|
986
|
+
status: TestStatus;
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
interface TestStep {
|
|
990
|
+
action: string;
|
|
991
|
+
expectedResult: string;
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
interface RequirementInput {
|
|
995
|
+
text?: string;
|
|
996
|
+
documents?: string[];
|
|
997
|
+
interviews?: InterviewResult[];
|
|
998
|
+
surveys?: SurveyResult[];
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
interface UserStoryInput {
|
|
1002
|
+
title: string;
|
|
1003
|
+
asA: string;
|
|
1004
|
+
iWant: string;
|
|
1005
|
+
soThat: string;
|
|
1006
|
+
acceptanceCriteria?: Array<{
|
|
1007
|
+
given: string;
|
|
1008
|
+
when: string;
|
|
1009
|
+
then: string;
|
|
1010
|
+
}>;
|
|
1011
|
+
priority?: Priority;
|
|
1012
|
+
storyPoints?: number;
|
|
1013
|
+
epic?: string;
|
|
1014
|
+
sprint?: string;
|
|
1015
|
+
dependencies?: string[];
|
|
1016
|
+
notes?: string;
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
interface RequirementAnalysis {
|
|
1020
|
+
requirements: Requirement[];
|
|
1021
|
+
stakeholders: Stakeholder[];
|
|
1022
|
+
completeness: CompletenessAnalysis;
|
|
1023
|
+
consistency: ConsistencyAnalysis;
|
|
1024
|
+
conflicts: Conflict[];
|
|
1025
|
+
feasibility: FeasibilityAnalysis;
|
|
1026
|
+
recommendations: string[];
|
|
1027
|
+
traceabilityMatrix: any;
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
interface Stakeholder {
|
|
1031
|
+
id: string;
|
|
1032
|
+
name: string;
|
|
1033
|
+
role: string;
|
|
1034
|
+
department: string;
|
|
1035
|
+
influence: number;
|
|
1036
|
+
interest: number;
|
|
1037
|
+
requirements: string[];
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
interface CompletenessAnalysis {
|
|
1041
|
+
score: number;
|
|
1042
|
+
missingElements: string[];
|
|
1043
|
+
recommendations: string[];
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
interface ConsistencyAnalysis {
|
|
1047
|
+
isConsistent: boolean;
|
|
1048
|
+
issues: ConsistencyIssue[];
|
|
1049
|
+
score: number;
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
interface ConsistencyIssue {
|
|
1053
|
+
type: string;
|
|
1054
|
+
requirementIds: string[];
|
|
1055
|
+
description: string;
|
|
1056
|
+
severity: Severity;
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
interface Conflict {
|
|
1060
|
+
requirements: string[];
|
|
1061
|
+
description: string;
|
|
1062
|
+
resolution?: string;
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
interface FeasibilityAnalysis {
|
|
1066
|
+
isFeasible: boolean;
|
|
1067
|
+
risks: Risk[];
|
|
1068
|
+
constraints: Constraint[];
|
|
1069
|
+
recommendations: string[];
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
interface InterviewResult {
|
|
1073
|
+
stakeholder: Stakeholder;
|
|
1074
|
+
date: Date;
|
|
1075
|
+
responses: InterviewResponse[];
|
|
1076
|
+
insights: string[];
|
|
1077
|
+
actionItems: string[];
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
interface InterviewResponse {
|
|
1081
|
+
question: Question;
|
|
1082
|
+
answer: string;
|
|
1083
|
+
followUps: Question[];
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
interface Question {
|
|
1087
|
+
id: string;
|
|
1088
|
+
text: string;
|
|
1089
|
+
type: QuestionType;
|
|
1090
|
+
category: string;
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
interface SurveyResult {
|
|
1094
|
+
responses: any[];
|
|
1095
|
+
summary: any;
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
interface TraceLink {
|
|
1099
|
+
from: string;
|
|
1100
|
+
to: string;
|
|
1101
|
+
type: LinkType;
|
|
1102
|
+
created: Date;
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
interface ValidationRule {
|
|
1106
|
+
id: string;
|
|
1107
|
+
name: string;
|
|
1108
|
+
check: (req: Requirement) => boolean;
|
|
1109
|
+
message: string;
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
// Export the analyzer
|
|
1113
|
+
export { RequirementsAnalyzer, Requirement, UserStory };
|
|
1114
|
+
```
|
|
1115
|
+
|
|
1116
|
+
## User Story Templates
|
|
1117
|
+
```markdown
|
|
1118
|
+
## User Story Template
|
|
1119
|
+
|
|
1120
|
+
**ID**: US-XXXX
|
|
1121
|
+
**Title**: [Brief descriptive title]
|
|
1122
|
+
|
|
1123
|
+
### Story
|
|
1124
|
+
**As a** [type of user]
|
|
1125
|
+
**I want** [goal/desire/action]
|
|
1126
|
+
**So that** [benefit/value/reason]
|
|
1127
|
+
|
|
1128
|
+
### Acceptance Criteria
|
|
1129
|
+
```gherkin
|
|
1130
|
+
Given [precondition]
|
|
1131
|
+
When [action]
|
|
1132
|
+
Then [expected result]
|
|
1133
|
+
|
|
1134
|
+
Given [another precondition]
|
|
1135
|
+
When [another action]
|
|
1136
|
+
Then [another expected result]
|
|
1137
|
+
```
|
|
1138
|
+
|
|
1139
|
+
### Additional Information
|
|
1140
|
+
- **Priority**: [Critical/High/Medium/Low]
|
|
1141
|
+
- **Story Points**: [1, 2, 3, 5, 8, 13]
|
|
1142
|
+
- **Epic**: [Parent epic if applicable]
|
|
1143
|
+
- **Sprint**: [Target sprint]
|
|
1144
|
+
- **Dependencies**: [List of dependent stories]
|
|
1145
|
+
|
|
1146
|
+
### Technical Notes
|
|
1147
|
+
[Any technical considerations or implementation notes]
|
|
1148
|
+
|
|
1149
|
+
### Design Notes
|
|
1150
|
+
[UI/UX considerations, mockups, or wireframes]
|
|
1151
|
+
|
|
1152
|
+
### Test Scenarios
|
|
1153
|
+
1. [Test scenario 1]
|
|
1154
|
+
2. [Test scenario 2]
|
|
1155
|
+
3. [Test scenario 3]
|
|
1156
|
+
|
|
1157
|
+
### Definition of Done
|
|
1158
|
+
- [ ] Code complete and reviewed
|
|
1159
|
+
- [ ] Unit tests written and passing
|
|
1160
|
+
- [ ] Integration tests passing
|
|
1161
|
+
- [ ] Documentation updated
|
|
1162
|
+
- [ ] Acceptance criteria verified
|
|
1163
|
+
- [ ] Product owner approval
|
|
1164
|
+
```
|
|
1165
|
+
|
|
1166
|
+
## Requirements Documentation Template
|
|
1167
|
+
```markdown
|
|
1168
|
+
# Software Requirements Specification (SRS)
|
|
1169
|
+
|
|
1170
|
+
## 1. Introduction
|
|
1171
|
+
### 1.1 Purpose
|
|
1172
|
+
[Purpose of this document]
|
|
1173
|
+
|
|
1174
|
+
### 1.2 Scope
|
|
1175
|
+
[Scope of the system]
|
|
1176
|
+
|
|
1177
|
+
### 1.3 Definitions, Acronyms, and Abbreviations
|
|
1178
|
+
[Key terms and definitions]
|
|
1179
|
+
|
|
1180
|
+
### 1.4 References
|
|
1181
|
+
[Referenced documents]
|
|
1182
|
+
|
|
1183
|
+
## 2. Overall Description
|
|
1184
|
+
### 2.1 Product Perspective
|
|
1185
|
+
[How the product fits into the larger system]
|
|
1186
|
+
|
|
1187
|
+
### 2.2 Product Functions
|
|
1188
|
+
[Major functions the product will perform]
|
|
1189
|
+
|
|
1190
|
+
### 2.3 User Classes and Characteristics
|
|
1191
|
+
[Different types of users and their characteristics]
|
|
1192
|
+
|
|
1193
|
+
### 2.4 Operating Environment
|
|
1194
|
+
[Hardware, software, and network environment]
|
|
1195
|
+
|
|
1196
|
+
### 2.5 Design and Implementation Constraints
|
|
1197
|
+
[Limitations and constraints]
|
|
1198
|
+
|
|
1199
|
+
### 2.6 Assumptions and Dependencies
|
|
1200
|
+
[Assumptions made and external dependencies]
|
|
1201
|
+
|
|
1202
|
+
## 3. Functional Requirements
|
|
1203
|
+
### 3.1 Feature 1
|
|
1204
|
+
**ID**: FR-001
|
|
1205
|
+
**Description**: [Detailed description]
|
|
1206
|
+
**Priority**: [Critical/High/Medium/Low]
|
|
1207
|
+
**Acceptance Criteria**:
|
|
1208
|
+
- [Criterion 1]
|
|
1209
|
+
- [Criterion 2]
|
|
1210
|
+
|
|
1211
|
+
### 3.2 Feature 2
|
|
1212
|
+
[Continue for all features]
|
|
1213
|
+
|
|
1214
|
+
## 4. Non-Functional Requirements
|
|
1215
|
+
### 4.1 Performance Requirements
|
|
1216
|
+
[Response times, throughput, capacity]
|
|
1217
|
+
|
|
1218
|
+
### 4.2 Security Requirements
|
|
1219
|
+
[Authentication, authorization, data protection]
|
|
1220
|
+
|
|
1221
|
+
### 4.3 Usability Requirements
|
|
1222
|
+
[User interface, accessibility, documentation]
|
|
1223
|
+
|
|
1224
|
+
### 4.4 Reliability Requirements
|
|
1225
|
+
[Availability, fault tolerance, recovery]
|
|
1226
|
+
|
|
1227
|
+
## 5. System Models
|
|
1228
|
+
### 5.1 Use Case Diagrams
|
|
1229
|
+
[Use case diagrams]
|
|
1230
|
+
|
|
1231
|
+
### 5.2 Sequence Diagrams
|
|
1232
|
+
[Sequence diagrams]
|
|
1233
|
+
|
|
1234
|
+
### 5.3 Data Models
|
|
1235
|
+
[Entity relationship diagrams]
|
|
1236
|
+
|
|
1237
|
+
## 6. Traceability Matrix
|
|
1238
|
+
[Requirements to test cases mapping]
|
|
1239
|
+
|
|
1240
|
+
## 7. Appendices
|
|
1241
|
+
[Additional supporting information]
|
|
1242
|
+
```
|
|
1243
|
+
|
|
1244
|
+
## Best Practices
|
|
1245
|
+
1. **Stakeholder Engagement**: Actively involve all stakeholders
|
|
1246
|
+
2. **Clear Documentation**: Use unambiguous, testable language
|
|
1247
|
+
3. **Traceability**: Maintain complete requirement traceability
|
|
1248
|
+
4. **Validation**: Continuously validate with stakeholders
|
|
1249
|
+
5. **Version Control**: Track all requirement changes
|
|
1250
|
+
6. **Prioritization**: Use MoSCoW or similar methods
|
|
1251
|
+
7. **INVEST Criteria**: Apply to all user stories
|
|
1252
|
+
|
|
1253
|
+
## Requirements Engineering Process
|
|
1254
|
+
- Elicitation through interviews, workshops, and observations
|
|
1255
|
+
- Analysis for completeness, consistency, and feasibility
|
|
1256
|
+
- Specification using structured templates
|
|
1257
|
+
- Validation with stakeholders and prototypes
|
|
1258
|
+
- Management of changes and versions
|
|
1259
|
+
- Traceability from requirements to implementation
|
|
1260
|
+
- Continuous refinement and clarification
|
|
1261
|
+
|
|
1262
|
+
## Approach
|
|
1263
|
+
- Understand business context and goals
|
|
1264
|
+
- Identify and analyze all stakeholders
|
|
1265
|
+
- Elicit requirements systematically
|
|
1266
|
+
- Document clearly and comprehensively
|
|
1267
|
+
- Validate with all stakeholders
|
|
1268
|
+
- Maintain traceability throughout
|
|
1269
|
+
- Manage changes effectively
|
|
1270
|
+
|
|
1271
|
+
## Output Format
|
|
1272
|
+
- Provide complete requirements documentation
|
|
1273
|
+
- Include user story templates
|
|
1274
|
+
- Document acceptance criteria
|
|
1275
|
+
- Add traceability matrices
|
|
1276
|
+
- Include validation checklists
|
|
1277
|
+
- Provide stakeholder analysis
|