@sk8metal/michi-cli 0.0.9 → 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/CHANGELOG.md +27 -0
- package/README.md +235 -57
- package/dist/scripts/__tests__/create-project.test.js +24 -28
- package/dist/scripts/__tests__/create-project.test.js.map +1 -1
- package/dist/scripts/__tests__/jira-transitions.test.d.ts +5 -0
- package/dist/scripts/__tests__/jira-transitions.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/jira-transitions.test.js +172 -0
- package/dist/scripts/__tests__/jira-transitions.test.js.map +1 -0
- package/dist/scripts/__tests__/multi-project-estimate.test.js +14 -15
- package/dist/scripts/__tests__/multi-project-estimate.test.js.map +1 -1
- package/dist/scripts/__tests__/setup-existing-project.test.js +79 -0
- package/dist/scripts/__tests__/setup-existing-project.test.js.map +1 -1
- package/dist/scripts/__tests__/setup-interactive.test.js +23 -17
- package/dist/scripts/__tests__/setup-interactive.test.js.map +1 -1
- package/dist/scripts/__tests__/spec-impl-workflow.test.d.ts +5 -0
- package/dist/scripts/__tests__/spec-impl-workflow.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/spec-impl-workflow.test.js +321 -0
- package/dist/scripts/__tests__/spec-impl-workflow.test.js.map +1 -0
- package/dist/scripts/__tests__/spec-loader.test.d.ts +5 -0
- package/dist/scripts/__tests__/spec-loader.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/spec-loader.test.js +153 -0
- package/dist/scripts/__tests__/spec-loader.test.js.map +1 -0
- package/dist/scripts/__tests__/validate-phase.test.js +26 -22
- package/dist/scripts/__tests__/validate-phase.test.js.map +1 -1
- package/dist/scripts/config/config-schema.d.ts +17 -0
- package/dist/scripts/config/config-schema.d.ts.map +1 -1
- package/dist/scripts/config/config-schema.js +55 -26
- package/dist/scripts/config/config-schema.js.map +1 -1
- package/dist/scripts/config-interactive.d.ts.map +1 -1
- package/dist/scripts/config-interactive.js +53 -38
- package/dist/scripts/config-interactive.js.map +1 -1
- package/dist/scripts/confluence-sync.d.ts.map +1 -1
- package/dist/scripts/confluence-sync.js +0 -11
- package/dist/scripts/confluence-sync.js.map +1 -1
- package/dist/scripts/constants/__tests__/environments.test.js +39 -5
- package/dist/scripts/constants/__tests__/environments.test.js.map +1 -1
- package/dist/scripts/constants/environments.d.ts +1 -1
- package/dist/scripts/constants/environments.d.ts.map +1 -1
- package/dist/scripts/constants/environments.js +22 -7
- package/dist/scripts/constants/environments.js.map +1 -1
- package/dist/scripts/constants/test-commands.d.ts +36 -0
- package/dist/scripts/constants/test-commands.d.ts.map +1 -0
- package/dist/scripts/constants/test-commands.js +70 -0
- package/dist/scripts/constants/test-commands.js.map +1 -0
- package/dist/scripts/jira-sync.d.ts +89 -3
- package/dist/scripts/jira-sync.d.ts.map +1 -1
- package/dist/scripts/jira-sync.js +366 -96
- package/dist/scripts/jira-sync.js.map +1 -1
- package/dist/scripts/markdown-to-confluence.js +1 -1
- package/dist/scripts/markdown-to-confluence.js.map +1 -1
- package/dist/scripts/phase-runner.d.ts +1 -1
- package/dist/scripts/phase-runner.d.ts.map +1 -1
- package/dist/scripts/phase-runner.js +809 -13
- package/dist/scripts/phase-runner.js.map +1 -1
- package/dist/scripts/pr-automation.d.ts.map +1 -1
- package/dist/scripts/pr-automation.js.map +1 -1
- package/dist/scripts/pre-flight-check.js +1 -1
- package/dist/scripts/pre-flight-check.js.map +1 -1
- package/dist/scripts/setup-existing-project.js +61 -29
- package/dist/scripts/setup-existing-project.js.map +1 -1
- package/dist/scripts/setup-interactive.js +3 -3
- package/dist/scripts/setup-interactive.js.map +1 -1
- package/dist/scripts/spec-impl-workflow.d.ts +94 -0
- package/dist/scripts/spec-impl-workflow.d.ts.map +1 -0
- package/dist/scripts/spec-impl-workflow.js +354 -0
- package/dist/scripts/spec-impl-workflow.js.map +1 -0
- package/dist/scripts/template/__tests__/renderer.test.js.map +1 -1
- package/dist/scripts/test-execution-generator.d.ts +52 -0
- package/dist/scripts/test-execution-generator.d.ts.map +1 -0
- package/dist/scripts/test-execution-generator.js +576 -0
- package/dist/scripts/test-execution-generator.js.map +1 -0
- package/dist/scripts/test-interactive.d.ts +10 -0
- package/dist/scripts/test-interactive.d.ts.map +1 -0
- package/dist/scripts/test-interactive.js +627 -0
- package/dist/scripts/test-interactive.js.map +1 -0
- package/dist/scripts/test-new-features.d.ts +5 -0
- package/dist/scripts/test-new-features.d.ts.map +1 -0
- package/dist/scripts/test-new-features.js +145 -0
- package/dist/scripts/test-new-features.js.map +1 -0
- package/dist/scripts/test-spec-generator.d.ts +29 -0
- package/dist/scripts/test-spec-generator.d.ts.map +1 -0
- package/dist/scripts/test-spec-generator.js +494 -0
- package/dist/scripts/test-spec-generator.js.map +1 -0
- package/dist/scripts/test-workflow-stages.d.ts +6 -0
- package/dist/scripts/test-workflow-stages.d.ts.map +1 -0
- package/dist/scripts/test-workflow-stages.js +43 -0
- package/dist/scripts/test-workflow-stages.js.map +1 -0
- package/dist/scripts/utils/__tests__/aidlc-parser.test.d.ts +5 -0
- package/dist/scripts/utils/__tests__/aidlc-parser.test.d.ts.map +1 -0
- package/dist/scripts/utils/__tests__/aidlc-parser.test.js +315 -0
- package/dist/scripts/utils/__tests__/aidlc-parser.test.js.map +1 -0
- package/dist/scripts/utils/__tests__/business-days.test.d.ts +5 -0
- package/dist/scripts/utils/__tests__/business-days.test.d.ts.map +1 -0
- package/dist/scripts/utils/__tests__/business-days.test.js +171 -0
- package/dist/scripts/utils/__tests__/business-days.test.js.map +1 -0
- package/dist/scripts/utils/__tests__/config-loader.test.js +1 -1
- package/dist/scripts/utils/__tests__/config-loader.test.js.map +1 -1
- package/dist/scripts/utils/__tests__/config-validator.test.js +164 -35
- package/dist/scripts/utils/__tests__/config-validator.test.js.map +1 -1
- package/dist/scripts/utils/__tests__/env-config.test.d.ts +5 -0
- package/dist/scripts/utils/__tests__/env-config.test.d.ts.map +1 -0
- package/dist/scripts/utils/__tests__/env-config.test.js +218 -0
- package/dist/scripts/utils/__tests__/env-config.test.js.map +1 -0
- package/dist/scripts/utils/__tests__/jira-issue-type-fetcher.test.d.ts +5 -0
- package/dist/scripts/utils/__tests__/jira-issue-type-fetcher.test.d.ts.map +1 -0
- package/dist/scripts/utils/__tests__/jira-issue-type-fetcher.test.js +202 -0
- package/dist/scripts/utils/__tests__/jira-issue-type-fetcher.test.js.map +1 -0
- package/dist/scripts/utils/__tests__/tasks-converter.test.d.ts +5 -0
- package/dist/scripts/utils/__tests__/tasks-converter.test.d.ts.map +1 -0
- package/dist/scripts/utils/__tests__/tasks-converter.test.js +500 -0
- package/dist/scripts/utils/__tests__/tasks-converter.test.js.map +1 -0
- package/dist/scripts/utils/__tests__/tasks-format-validator.test.d.ts +5 -0
- package/dist/scripts/utils/__tests__/tasks-format-validator.test.d.ts.map +1 -0
- package/dist/scripts/utils/__tests__/tasks-format-validator.test.js +314 -0
- package/dist/scripts/utils/__tests__/tasks-format-validator.test.js.map +1 -0
- package/dist/scripts/utils/__tests__/test-runner.test.d.ts +5 -0
- package/dist/scripts/utils/__tests__/test-runner.test.d.ts.map +1 -0
- package/dist/scripts/utils/__tests__/test-runner.test.js +64 -0
- package/dist/scripts/utils/__tests__/test-runner.test.js.map +1 -0
- package/dist/scripts/utils/aidlc-parser.d.ts +86 -0
- package/dist/scripts/utils/aidlc-parser.d.ts.map +1 -0
- package/dist/scripts/utils/aidlc-parser.js +208 -0
- package/dist/scripts/utils/aidlc-parser.js.map +1 -0
- package/dist/scripts/utils/business-days.d.ts +52 -0
- package/dist/scripts/utils/business-days.d.ts.map +1 -0
- package/dist/scripts/utils/business-days.js +98 -0
- package/dist/scripts/utils/business-days.js.map +1 -0
- package/dist/scripts/utils/ci-generator.d.ts +14 -0
- package/dist/scripts/utils/ci-generator.d.ts.map +1 -0
- package/dist/scripts/utils/ci-generator.js +61 -0
- package/dist/scripts/utils/ci-generator.js.map +1 -0
- package/dist/scripts/utils/config-loader.js +2 -2
- package/dist/scripts/utils/config-loader.js.map +1 -1
- package/dist/scripts/utils/config-validator.d.ts +7 -1
- package/dist/scripts/utils/config-validator.d.ts.map +1 -1
- package/dist/scripts/utils/config-validator.js +136 -23
- package/dist/scripts/utils/config-validator.js.map +1 -1
- package/dist/scripts/utils/confluence-approval.d.ts +46 -0
- package/dist/scripts/utils/confluence-approval.d.ts.map +1 -0
- package/dist/scripts/utils/confluence-approval.js +118 -0
- package/dist/scripts/utils/confluence-approval.js.map +1 -0
- package/dist/scripts/utils/confluence-hierarchy.d.ts.map +1 -1
- package/dist/scripts/utils/confluence-hierarchy.js +1 -1
- package/dist/scripts/utils/confluence-hierarchy.js.map +1 -1
- package/dist/scripts/utils/docker-generator.d.ts +9 -0
- package/dist/scripts/utils/docker-generator.d.ts.map +1 -0
- package/dist/scripts/utils/docker-generator.js +132 -0
- package/dist/scripts/utils/docker-generator.js.map +1 -0
- package/dist/scripts/utils/docker-requirement-detector.d.ts +15 -0
- package/dist/scripts/utils/docker-requirement-detector.d.ts.map +1 -0
- package/dist/scripts/utils/docker-requirement-detector.js +124 -0
- package/dist/scripts/utils/docker-requirement-detector.js.map +1 -0
- package/dist/scripts/utils/env-config.d.ts +54 -0
- package/dist/scripts/utils/env-config.d.ts.map +1 -0
- package/dist/scripts/utils/env-config.js +414 -0
- package/dist/scripts/utils/env-config.js.map +1 -0
- package/dist/scripts/utils/jira-issue-type-fetcher.d.ts +70 -0
- package/dist/scripts/utils/jira-issue-type-fetcher.d.ts.map +1 -0
- package/dist/scripts/utils/jira-issue-type-fetcher.js +147 -0
- package/dist/scripts/utils/jira-issue-type-fetcher.js.map +1 -0
- package/dist/scripts/utils/language-detector.d.ts +14 -0
- package/dist/scripts/utils/language-detector.d.ts.map +1 -0
- package/dist/scripts/utils/language-detector.js +119 -0
- package/dist/scripts/utils/language-detector.js.map +1 -0
- package/dist/scripts/utils/markdown-parser.d.ts +55 -0
- package/dist/scripts/utils/markdown-parser.d.ts.map +1 -0
- package/dist/scripts/utils/markdown-parser.js +289 -0
- package/dist/scripts/utils/markdown-parser.js.map +1 -0
- package/dist/scripts/utils/project-detector.d.ts +17 -0
- package/dist/scripts/utils/project-detector.d.ts.map +1 -0
- package/dist/scripts/utils/project-detector.js +166 -0
- package/dist/scripts/utils/project-detector.js.map +1 -0
- package/dist/scripts/utils/project-finder.js +2 -2
- package/dist/scripts/utils/project-finder.js.map +1 -1
- package/dist/scripts/utils/release-notes-generator.d.ts +56 -0
- package/dist/scripts/utils/release-notes-generator.d.ts.map +1 -0
- package/dist/scripts/utils/release-notes-generator.js +162 -0
- package/dist/scripts/utils/release-notes-generator.js.map +1 -0
- package/dist/scripts/utils/spec-loader.d.ts +79 -0
- package/dist/scripts/utils/spec-loader.d.ts.map +1 -0
- package/dist/scripts/utils/spec-loader.js +80 -0
- package/dist/scripts/utils/spec-loader.js.map +1 -0
- package/dist/scripts/utils/spec-updater.d.ts +7 -0
- package/dist/scripts/utils/spec-updater.d.ts.map +1 -1
- package/dist/scripts/utils/spec-updater.js.map +1 -1
- package/dist/scripts/utils/tasks-converter.d.ts +57 -0
- package/dist/scripts/utils/tasks-converter.d.ts.map +1 -0
- package/dist/scripts/utils/tasks-converter.js +322 -0
- package/dist/scripts/utils/tasks-converter.js.map +1 -0
- package/dist/scripts/utils/tasks-format-validator.d.ts +36 -0
- package/dist/scripts/utils/tasks-format-validator.d.ts.map +1 -0
- package/dist/scripts/utils/tasks-format-validator.js +158 -0
- package/dist/scripts/utils/tasks-format-validator.js.map +1 -0
- package/dist/scripts/utils/template-applier.d.ts +37 -0
- package/dist/scripts/utils/template-applier.d.ts.map +1 -0
- package/dist/scripts/utils/template-applier.js +129 -0
- package/dist/scripts/utils/template-applier.js.map +1 -0
- package/dist/scripts/utils/test-config-generator.d.ts +12 -0
- package/dist/scripts/utils/test-config-generator.d.ts.map +1 -0
- package/dist/scripts/utils/test-config-generator.js +185 -0
- package/dist/scripts/utils/test-config-generator.js.map +1 -0
- package/dist/scripts/utils/test-runner.d.ts +31 -0
- package/dist/scripts/utils/test-runner.d.ts.map +1 -0
- package/dist/scripts/utils/test-runner.js +103 -0
- package/dist/scripts/utils/test-runner.js.map +1 -0
- package/dist/scripts/validate-phase.d.ts +1 -1
- package/dist/scripts/validate-phase.d.ts.map +1 -1
- package/dist/scripts/validate-phase.js +153 -5
- package/dist/scripts/validate-phase.js.map +1 -1
- package/dist/scripts/workflow-orchestrator.d.ts +8 -0
- package/dist/scripts/workflow-orchestrator.d.ts.map +1 -1
- package/dist/scripts/workflow-orchestrator.js +108 -7
- package/dist/scripts/workflow-orchestrator.js.map +1 -1
- package/dist/src/__tests__/integration/internationalization.test.d.ts +8 -0
- package/dist/src/__tests__/integration/internationalization.test.d.ts.map +1 -0
- package/dist/src/__tests__/integration/internationalization.test.js +333 -0
- package/dist/src/__tests__/integration/internationalization.test.js.map +1 -0
- package/dist/src/__tests__/integration/setup/claude-agent.test.d.ts +1 -1
- package/dist/src/__tests__/integration/setup/claude-agent.test.js +17 -20
- package/dist/src/__tests__/integration/setup/claude-agent.test.js.map +1 -1
- package/dist/src/__tests__/integration/setup/cursor.test.js +23 -19
- package/dist/src/__tests__/integration/setup/cursor.test.js.map +1 -1
- package/dist/src/__tests__/integration/setup/validation.test.js +41 -58
- package/dist/src/__tests__/integration/setup/validation.test.js.map +1 -1
- package/dist/src/cli.d.ts.map +1 -1
- package/dist/src/cli.js +208 -18
- package/dist/src/cli.js.map +1 -1
- package/dist/src/commands/setup-existing.d.ts +3 -0
- package/dist/src/commands/setup-existing.d.ts.map +1 -1
- package/dist/src/commands/setup-existing.js +334 -47
- package/dist/src/commands/setup-existing.js.map +1 -1
- package/docs/README.md +3 -1
- package/docs/context.md +59 -0
- package/docs/design-issue-55.md +240 -0
- package/docs/design-issue-56.md +181 -0
- package/docs/michi-development/testing/manual-verification-flow.md +2242 -0
- package/docs/michi-development/testing/pre-publish-checklist.md +560 -0
- package/docs/plan.md +275 -0
- package/docs/user-guide/getting-started/github-token-setup.md +509 -0
- package/docs/{getting-started → user-guide/getting-started}/quick-start.md +16 -0
- package/docs/{getting-started → user-guide/getting-started}/setup.md +28 -1
- package/docs/user-guide/guides/internationalization.md +540 -0
- package/docs/{guides → user-guide/guides}/multi-project.md +1 -1
- package/docs/{guides → user-guide/guides}/phase-automation.md +67 -9
- package/docs/user-guide/guides/workflow.md +582 -0
- package/docs/user-guide/hands-on/README.md +142 -0
- package/docs/user-guide/hands-on/claude-agent-setup.md +455 -0
- package/docs/user-guide/hands-on/claude-setup.md +398 -0
- package/docs/user-guide/hands-on/cursor-setup.md +352 -0
- package/docs/user-guide/hands-on/troubleshooting.md +964 -0
- package/docs/user-guide/hands-on/verification-checklist.md +438 -0
- package/docs/user-guide/hands-on/workflow-walkthrough.md +906 -0
- package/docs/user-guide/reference/config.md +564 -0
- package/docs/{reference → user-guide/reference}/quick-reference.md +53 -40
- package/docs/user-guide/release/ci-setup.md +541 -0
- package/docs/user-guide/release/release-flow.md +476 -0
- package/docs/user-guide/templates/test-specs/README.md +173 -0
- package/docs/user-guide/templates/test-specs/e2e-test-spec-template.md +547 -0
- package/docs/user-guide/templates/test-specs/integration-test-spec-template.md +435 -0
- package/docs/user-guide/templates/test-specs/performance-test-spec-template.md +454 -0
- package/docs/user-guide/templates/test-specs/security-test-spec-template.md +664 -0
- package/docs/user-guide/templates/test-specs/unit-test-spec-template.md +328 -0
- package/docs/{testing → user-guide/testing}/integration-tests.md +24 -9
- package/docs/user-guide/testing/tdd-cycle.md +349 -0
- package/docs/user-guide/testing/test-execution-flow.md +396 -0
- package/docs/user-guide/testing/test-failure-handling.md +521 -0
- package/docs/user-guide/testing/test-planning-flow.md +181 -0
- package/docs/user-guide/testing-strategy.md +185 -0
- package/docs/verification-guide.md +518 -0
- package/package.json +7 -2
- package/scripts/__tests__/create-project.test.ts +67 -49
- package/scripts/__tests__/jira-transitions.test.ts +225 -0
- package/scripts/__tests__/multi-project-estimate.test.ts +36 -30
- package/scripts/__tests__/setup-existing-project.test.ts +98 -1
- package/scripts/__tests__/setup-interactive.test.ts +52 -46
- package/scripts/__tests__/spec-impl-workflow.test.ts +429 -0
- package/scripts/__tests__/spec-loader.test.ts +199 -0
- package/scripts/__tests__/validate-phase.test.ts +78 -54
- package/scripts/config/config-schema.ts +89 -50
- package/scripts/config-interactive.ts +191 -136
- package/scripts/confluence-sync.ts +0 -12
- package/scripts/constants/__tests__/environments.test.ts +42 -6
- package/scripts/constants/environments.ts +33 -13
- package/scripts/constants/test-commands.ts +96 -0
- package/scripts/jira-sync.ts +767 -232
- package/scripts/markdown-to-confluence.ts +1 -1
- package/scripts/phase-runner.ts +1056 -63
- package/scripts/pr-automation.ts +0 -1
- package/scripts/pre-flight-check.ts +1 -1
- package/scripts/pre-publish-check.sh +311 -0
- package/scripts/quick-verify.sh +115 -0
- package/scripts/setup-existing-project.ts +201 -117
- package/scripts/setup-interactive.ts +4 -4
- package/scripts/spec-impl-workflow.ts +505 -0
- package/scripts/template/__tests__/renderer.test.ts +1 -2
- package/scripts/test-execution-generator.ts +695 -0
- package/scripts/test-interactive.ts +779 -0
- package/scripts/test-new-features.ts +168 -0
- package/scripts/test-npm-package.sh +345 -0
- package/scripts/test-spec-generator.ts +574 -0
- package/scripts/test-workflow-stages.ts +53 -0
- package/scripts/utils/__tests__/aidlc-parser.test.ts +349 -0
- package/scripts/utils/__tests__/business-days.test.ts +214 -0
- package/scripts/utils/__tests__/config-loader.test.ts +1 -1
- package/scripts/utils/__tests__/config-validator.test.ts +309 -88
- package/scripts/utils/__tests__/env-config.test.ts +259 -0
- package/scripts/utils/__tests__/jira-issue-type-fetcher.test.ts +272 -0
- package/scripts/utils/__tests__/tasks-converter.test.ts +582 -0
- package/scripts/utils/__tests__/tasks-format-validator.test.ts +338 -0
- package/scripts/utils/__tests__/test-runner.test.ts +77 -0
- package/scripts/utils/aidlc-parser.ts +289 -0
- package/scripts/utils/business-days.ts +115 -0
- package/scripts/utils/ci-generator.ts +84 -0
- package/scripts/utils/config-loader.ts +2 -2
- package/scripts/utils/config-validator.ts +304 -117
- package/scripts/utils/confluence-approval.ts +167 -0
- package/scripts/utils/confluence-hierarchy.ts +2 -4
- package/scripts/utils/docker-generator.ts +151 -0
- package/scripts/utils/docker-requirement-detector.ts +153 -0
- package/scripts/utils/env-config.ts +526 -0
- package/scripts/utils/jira-issue-type-fetcher.ts +199 -0
- package/scripts/utils/language-detector.ts +139 -0
- package/scripts/utils/markdown-parser.ts +376 -0
- package/scripts/utils/project-detector.ts +192 -0
- package/scripts/utils/project-finder.ts +2 -2
- package/scripts/utils/release-notes-generator.ts +210 -0
- package/scripts/utils/spec-loader.ts +125 -0
- package/scripts/utils/spec-updater.ts +8 -1
- package/scripts/utils/tasks-converter.ts +601 -0
- package/scripts/utils/tasks-format-validator.ts +193 -0
- package/scripts/utils/template-applier.ts +202 -0
- package/scripts/utils/test-config-generator.ts +210 -0
- package/scripts/utils/test-runner.ts +133 -0
- package/scripts/validate-phase.ts +186 -9
- package/scripts/workflow-orchestrator.ts +130 -12
- package/templates/ci/github-actions/java.yml +54 -0
- package/templates/ci/github-actions/nodejs.yml +46 -0
- package/templates/ci/github-actions/php.yml +52 -0
- package/templates/ci/screwdriver/java.yaml +17 -0
- package/templates/ci/screwdriver/nodejs.yaml +17 -0
- package/templates/ci/screwdriver/php.yaml +20 -0
- package/templates/claude/commands/kiro/kiro-spec-impl.md +244 -0
- package/templates/claude/commands/kiro/kiro-spec-tasks.md +354 -0
- package/templates/claude-agent/README.md +7 -1
- package/templates/claude-agent/agents/.gitkeep +0 -0
- package/templates/claude-agent/agents/designer.md +79 -0
- package/templates/claude-agent/agents/developer.md +68 -0
- package/templates/claude-agent/agents/manager-agent.md +59 -0
- package/templates/claude-agent/agents/tester.md +101 -0
- package/templates/claude-agent/commands/kiro/.gitkeep +0 -0
- package/templates/claude-agent/commands/kiro/kiro-spec-impl.md +244 -0
- package/templates/claude-agent/commands/kiro/kiro-spec-tasks.md +354 -0
- package/templates/cline/rules/atlassian-integration.md +36 -0
- package/templates/cline/rules/michi-core.md +56 -0
- package/templates/codex/AGENTS.override.md +277 -0
- package/templates/codex/prompts/confluence-sync.md +177 -0
- package/templates/codex/rules/README.md +210 -0
- package/templates/common/.kiro/project.json.template +21 -0
- package/templates/cursor/commands/kiro/kiro-spec-impl.md +244 -0
- package/templates/cursor/commands/kiro/kiro-spec-tasks.md +354 -0
- package/templates/gemini/commands/README.md +41 -0
- package/templates/gemini/rules/GEMINI.md +80 -0
- package/docs/guides/workflow.md +0 -342
- package/docs/reference/config.md +0 -545
- package/scripts/setup-existing.sh +0 -279
- /package/docs/{contributing → michi-development/contributing}/development.md +0 -0
- /package/docs/{contributing → michi-development/contributing}/release.md +0 -0
- /package/docs/{testing-strategy.md → michi-development/testing-strategy.md} +0 -0
- /package/docs/{getting-started → user-guide/getting-started}/new-repository-setup.md +0 -0
- /package/docs/{guides → user-guide/guides}/customization.md +0 -0
- /package/docs/{reference → user-guide/reference}/tasks-template.md +0 -0
|
@@ -2,13 +2,16 @@
|
|
|
2
2
|
* フェーズランナー
|
|
3
3
|
* 各フェーズを実行し、Confluence/JIRA作成を確実に実行
|
|
4
4
|
*/
|
|
5
|
-
import { existsSync } from 'fs';
|
|
6
|
-
import { join } from 'path';
|
|
5
|
+
import { existsSync, writeFileSync, readFileSync, mkdirSync } from 'fs';
|
|
6
|
+
import { join, relative } from 'path';
|
|
7
7
|
import { syncToConfluence } from './confluence-sync.js';
|
|
8
8
|
import { syncTasksToJIRA } from './jira-sync.js';
|
|
9
9
|
import { validatePhase } from './validate-phase.js';
|
|
10
10
|
import { runPreFlightCheck } from './pre-flight-check.js';
|
|
11
11
|
import { validateFeatureNameOrThrow } from './utils/feature-name-validator.js';
|
|
12
|
+
import { getTestCommands } from './constants/test-commands.js';
|
|
13
|
+
import { loadSpecJson } from './utils/spec-updater.js';
|
|
14
|
+
import inquirer from 'inquirer';
|
|
12
15
|
/**
|
|
13
16
|
* 要件定義フェーズを実行
|
|
14
17
|
*/
|
|
@@ -28,7 +31,7 @@ async function runRequirementsPhase(feature) {
|
|
|
28
31
|
confluenceCreated: false,
|
|
29
32
|
jiraCreated: false,
|
|
30
33
|
validationPassed: false,
|
|
31
|
-
errors
|
|
34
|
+
errors,
|
|
32
35
|
};
|
|
33
36
|
}
|
|
34
37
|
console.log('✅ requirements.md 存在確認');
|
|
@@ -70,7 +73,7 @@ async function runRequirementsPhase(feature) {
|
|
|
70
73
|
confluenceCreated,
|
|
71
74
|
jiraCreated: false,
|
|
72
75
|
validationPassed: validation.valid,
|
|
73
|
-
errors
|
|
76
|
+
errors,
|
|
74
77
|
};
|
|
75
78
|
}
|
|
76
79
|
/**
|
|
@@ -92,7 +95,7 @@ async function runDesignPhase(feature) {
|
|
|
92
95
|
confluenceCreated: false,
|
|
93
96
|
jiraCreated: false,
|
|
94
97
|
validationPassed: false,
|
|
95
|
-
errors
|
|
98
|
+
errors,
|
|
96
99
|
};
|
|
97
100
|
}
|
|
98
101
|
console.log('✅ design.md 存在確認');
|
|
@@ -134,7 +137,7 @@ async function runDesignPhase(feature) {
|
|
|
134
137
|
confluenceCreated,
|
|
135
138
|
jiraCreated: false,
|
|
136
139
|
validationPassed: validation.valid,
|
|
137
|
-
errors
|
|
140
|
+
errors,
|
|
138
141
|
};
|
|
139
142
|
}
|
|
140
143
|
/**
|
|
@@ -150,14 +153,14 @@ async function runTasksPhase(feature) {
|
|
|
150
153
|
const preFlightResult = await runPreFlightCheck('jira');
|
|
151
154
|
if (!preFlightResult.valid) {
|
|
152
155
|
console.log('\n❌ プリフライトチェック失敗:');
|
|
153
|
-
preFlightResult.errors.forEach(e => console.log(` ${e}`));
|
|
156
|
+
preFlightResult.errors.forEach((e) => console.log(` ${e}`));
|
|
154
157
|
return {
|
|
155
158
|
phase: 'tasks',
|
|
156
159
|
success: false,
|
|
157
160
|
confluenceCreated: false,
|
|
158
161
|
jiraCreated: false,
|
|
159
162
|
validationPassed: false,
|
|
160
|
-
errors: preFlightResult.errors
|
|
163
|
+
errors: preFlightResult.errors,
|
|
161
164
|
};
|
|
162
165
|
}
|
|
163
166
|
console.log('✅ プリフライトチェック成功');
|
|
@@ -171,10 +174,92 @@ async function runTasksPhase(feature) {
|
|
|
171
174
|
confluenceCreated: false,
|
|
172
175
|
jiraCreated: false,
|
|
173
176
|
validationPassed: false,
|
|
174
|
-
errors
|
|
177
|
+
errors,
|
|
175
178
|
};
|
|
176
179
|
}
|
|
177
180
|
console.log('✅ tasks.md 存在確認');
|
|
181
|
+
// Step 1.5: AI-DLC形式検出と変換提案
|
|
182
|
+
console.log('\n🔍 tasks.mdフォーマット検証中...');
|
|
183
|
+
const { isAIDLCFormat } = await import('./utils/aidlc-parser.js');
|
|
184
|
+
const tasksContent = readFileSync(tasksPath, 'utf-8');
|
|
185
|
+
if (isAIDLCFormat(tasksContent)) {
|
|
186
|
+
console.log('\n⚠️ AI-DLC形式が検出されました');
|
|
187
|
+
console.log(' tasks.mdはMichiワークフロー形式ではなくAI-DLC形式です。');
|
|
188
|
+
console.log('');
|
|
189
|
+
console.log('🔄 変換オプション:');
|
|
190
|
+
console.log(` michi tasks:convert ${feature} --dry-run # プレビュー`);
|
|
191
|
+
console.log(` michi tasks:convert ${feature} --backup # バックアップ付きで変換`);
|
|
192
|
+
console.log(` michi tasks:convert ${feature} # 直接変換`);
|
|
193
|
+
console.log('');
|
|
194
|
+
// 対話的に変換を提案
|
|
195
|
+
const shouldConvert = await inquirer.prompt([
|
|
196
|
+
{
|
|
197
|
+
type: 'confirm',
|
|
198
|
+
name: 'convert',
|
|
199
|
+
message: 'AI-DLC形式をMichiワークフロー形式に変換しますか?',
|
|
200
|
+
default: true,
|
|
201
|
+
},
|
|
202
|
+
]);
|
|
203
|
+
if (shouldConvert.convert) {
|
|
204
|
+
console.log('\n🔄 AI-DLC形式をMichiワークフロー形式に変換中...');
|
|
205
|
+
const { convertTasksFile } = await import('./utils/tasks-converter.js');
|
|
206
|
+
const result = convertTasksFile(tasksPath, undefined, {
|
|
207
|
+
backup: true,
|
|
208
|
+
language: 'ja',
|
|
209
|
+
projectName: feature,
|
|
210
|
+
});
|
|
211
|
+
if (result.success) {
|
|
212
|
+
console.log('✅ 変換成功!');
|
|
213
|
+
console.log(` 元ファイル: ${result.backupPath}`);
|
|
214
|
+
console.log(` 変換後: ${tasksPath}`);
|
|
215
|
+
console.log(` 統計: ${result.stats.originalTasks}タスク → ${result.stats.convertedStories}ストーリー`);
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
errors.push('AI-DLC形式の変換に失敗しました');
|
|
219
|
+
result.warnings.forEach((w) => errors.push(w));
|
|
220
|
+
console.error('❌ 変換失敗');
|
|
221
|
+
return {
|
|
222
|
+
phase: 'tasks',
|
|
223
|
+
success: false,
|
|
224
|
+
confluenceCreated: false,
|
|
225
|
+
jiraCreated: false,
|
|
226
|
+
validationPassed: false,
|
|
227
|
+
errors,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
console.log('\n⏭️ 変換をスキップしました');
|
|
233
|
+
console.log(' AI-DLC形式のままではJIRA連携が正常に動作しない可能性があります。');
|
|
234
|
+
errors.push('tasks.mdがAI-DLC形式のため、フォーマット検証をスキップしました');
|
|
235
|
+
return {
|
|
236
|
+
phase: 'tasks',
|
|
237
|
+
success: false,
|
|
238
|
+
confluenceCreated: false,
|
|
239
|
+
jiraCreated: false,
|
|
240
|
+
validationPassed: false,
|
|
241
|
+
errors,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
// Step 1.6: tasks.mdフォーマット検証
|
|
246
|
+
const { validateTasksFormat } = await import('./utils/tasks-format-validator.js');
|
|
247
|
+
try {
|
|
248
|
+
validateTasksFormat(tasksPath);
|
|
249
|
+
console.log('✅ tasks.mdフォーマット検証成功');
|
|
250
|
+
}
|
|
251
|
+
catch (error) {
|
|
252
|
+
errors.push(`フォーマット検証失敗: ${error.message}`);
|
|
253
|
+
console.error('❌ フォーマット検証失敗:', error.message);
|
|
254
|
+
return {
|
|
255
|
+
phase: 'tasks',
|
|
256
|
+
success: false,
|
|
257
|
+
confluenceCreated: false,
|
|
258
|
+
jiraCreated: false,
|
|
259
|
+
validationPassed: false,
|
|
260
|
+
errors,
|
|
261
|
+
};
|
|
262
|
+
}
|
|
178
263
|
// Step 2: JIRA Epic/Story作成
|
|
179
264
|
console.log('\n📤 JIRA Epic/Story作成中...');
|
|
180
265
|
try {
|
|
@@ -207,7 +292,689 @@ async function runTasksPhase(feature) {
|
|
|
207
292
|
confluenceCreated: false,
|
|
208
293
|
jiraCreated,
|
|
209
294
|
validationPassed: validation.valid,
|
|
210
|
-
errors
|
|
295
|
+
errors,
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* テストタイプ選択フェーズを実行(Phase 0.3)
|
|
300
|
+
* 対話的にテストタイプを選択
|
|
301
|
+
*/
|
|
302
|
+
async function runTestTypeSelectionPhase(feature) {
|
|
303
|
+
console.log('\n🧪 Phase 0.3: Test Type Selection(テストタイプ選択)');
|
|
304
|
+
console.log('='.repeat(60));
|
|
305
|
+
const errors = [];
|
|
306
|
+
const specDir = join(process.cwd(), '.kiro', 'specs', feature);
|
|
307
|
+
const selectionPath = join(specDir, 'test-type-selection.json');
|
|
308
|
+
// 既存の選択を読み込む(存在する場合)
|
|
309
|
+
let existingSelection = null;
|
|
310
|
+
if (existsSync(selectionPath)) {
|
|
311
|
+
try {
|
|
312
|
+
existingSelection = JSON.parse(readFileSync(selectionPath, 'utf-8'));
|
|
313
|
+
console.log('\n📋 既存の選択が見つかりました:');
|
|
314
|
+
console.log(` 選択済みテストタイプ: ${existingSelection.selectedTypes?.join(', ') || 'なし'}`);
|
|
315
|
+
}
|
|
316
|
+
catch {
|
|
317
|
+
console.warn('⚠️ 既存の選択ファイルの読み込みに失敗しました');
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
console.log('\n📚 プロジェクト要件に応じてテストタイプを選択してください\n');
|
|
321
|
+
// 対話的な質問
|
|
322
|
+
const answers = await inquirer.prompt([
|
|
323
|
+
{
|
|
324
|
+
type: 'checkbox',
|
|
325
|
+
name: 'testTypes',
|
|
326
|
+
message: '実施するテストタイプを選択してください(スペースキーで選択/解除、Enterで確定):',
|
|
327
|
+
choices: [
|
|
328
|
+
{
|
|
329
|
+
name: '単体テスト (Unit Tests) - 必須 [Phase A]',
|
|
330
|
+
value: 'unit',
|
|
331
|
+
checked: true, // 必須のためデフォルトで選択
|
|
332
|
+
disabled: true, // 必須のため変更不可
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
name: 'Lint実行 - 必須 [Phase A]',
|
|
336
|
+
value: 'lint',
|
|
337
|
+
checked: true,
|
|
338
|
+
disabled: true,
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
name: 'ビルド実行 - 必須 [Phase A]',
|
|
342
|
+
value: 'build',
|
|
343
|
+
checked: true,
|
|
344
|
+
disabled: true,
|
|
345
|
+
},
|
|
346
|
+
new inquirer.Separator('--- 推奨テスト ---'),
|
|
347
|
+
{
|
|
348
|
+
name: '統合テスト (Integration Tests) - 推奨 [Phase 3/B]',
|
|
349
|
+
value: 'integration',
|
|
350
|
+
checked: existingSelection?.selectedTypes?.includes('integration') || false,
|
|
351
|
+
},
|
|
352
|
+
{
|
|
353
|
+
name: 'E2Eテスト (End-to-End Tests) - 推奨 [Phase 3/B]',
|
|
354
|
+
value: 'e2e',
|
|
355
|
+
checked: existingSelection?.selectedTypes?.includes('e2e') || false,
|
|
356
|
+
},
|
|
357
|
+
new inquirer.Separator('--- 任意テスト ---'),
|
|
358
|
+
{
|
|
359
|
+
name: '性能テスト (Performance Tests) - 任意 [Phase B]',
|
|
360
|
+
value: 'performance',
|
|
361
|
+
checked: existingSelection?.selectedTypes?.includes('performance') || false,
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
name: 'セキュリティテスト (Security Tests) - 任意 [Phase B]',
|
|
365
|
+
value: 'security',
|
|
366
|
+
checked: existingSelection?.selectedTypes?.includes('security') || false,
|
|
367
|
+
},
|
|
368
|
+
],
|
|
369
|
+
validate: () => {
|
|
370
|
+
// disabled項目は自動的に含まれるため、バリデーションは常に成功
|
|
371
|
+
return true;
|
|
372
|
+
},
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
type: 'confirm',
|
|
376
|
+
name: 'confirm',
|
|
377
|
+
message: (answers) => {
|
|
378
|
+
// 必須テストを自動的に追加
|
|
379
|
+
const required = ['unit', 'lint', 'build'];
|
|
380
|
+
const selected = [...new Set([...required, ...answers.testTypes])];
|
|
381
|
+
const optional = selected.filter((t) => !required.includes(t));
|
|
382
|
+
if (optional.length === 0) {
|
|
383
|
+
return '必須テストのみが選択されています。この選択で進めますか?';
|
|
384
|
+
}
|
|
385
|
+
return `選択したテストタイプ: ${selected.join(', ')}\nこの選択で進めますか?`;
|
|
386
|
+
},
|
|
387
|
+
default: true,
|
|
388
|
+
},
|
|
389
|
+
]);
|
|
390
|
+
// 必須テストを自動的に追加(disabled項目はanswers.testTypesに含まれないため)
|
|
391
|
+
const requiredTests = ['unit', 'lint', 'build'];
|
|
392
|
+
answers.testTypes = [...new Set([...requiredTests, ...answers.testTypes])];
|
|
393
|
+
if (!answers.confirm) {
|
|
394
|
+
console.log('\n❌ 選択がキャンセルされました');
|
|
395
|
+
return {
|
|
396
|
+
phase: 'test-type-selection',
|
|
397
|
+
success: false,
|
|
398
|
+
confluenceCreated: false,
|
|
399
|
+
jiraCreated: false,
|
|
400
|
+
validationPassed: false,
|
|
401
|
+
errors: ['ユーザーが選択をキャンセルしました'],
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
// 選択結果を保存
|
|
405
|
+
const selection = {
|
|
406
|
+
feature,
|
|
407
|
+
selectedTypes: answers.testTypes,
|
|
408
|
+
selectedAt: new Date().toISOString(),
|
|
409
|
+
testTypes: {
|
|
410
|
+
unit: {
|
|
411
|
+
enabled: true,
|
|
412
|
+
required: true,
|
|
413
|
+
phase: 'A',
|
|
414
|
+
description: '単体テスト',
|
|
415
|
+
},
|
|
416
|
+
lint: {
|
|
417
|
+
enabled: true,
|
|
418
|
+
required: true,
|
|
419
|
+
phase: 'A',
|
|
420
|
+
description: 'Lint実行',
|
|
421
|
+
},
|
|
422
|
+
build: {
|
|
423
|
+
enabled: true,
|
|
424
|
+
required: true,
|
|
425
|
+
phase: 'A',
|
|
426
|
+
description: 'ビルド実行',
|
|
427
|
+
},
|
|
428
|
+
integration: {
|
|
429
|
+
enabled: answers.testTypes.includes('integration'),
|
|
430
|
+
required: false,
|
|
431
|
+
phase: 'B',
|
|
432
|
+
description: '統合テスト',
|
|
433
|
+
},
|
|
434
|
+
e2e: {
|
|
435
|
+
enabled: answers.testTypes.includes('e2e'),
|
|
436
|
+
required: false,
|
|
437
|
+
phase: 'B',
|
|
438
|
+
description: 'E2Eテスト',
|
|
439
|
+
},
|
|
440
|
+
performance: {
|
|
441
|
+
enabled: answers.testTypes.includes('performance'),
|
|
442
|
+
required: false,
|
|
443
|
+
phase: 'B',
|
|
444
|
+
description: '性能テスト',
|
|
445
|
+
},
|
|
446
|
+
security: {
|
|
447
|
+
enabled: answers.testTypes.includes('security'),
|
|
448
|
+
required: false,
|
|
449
|
+
phase: 'B',
|
|
450
|
+
description: 'セキュリティテスト',
|
|
451
|
+
},
|
|
452
|
+
},
|
|
453
|
+
};
|
|
454
|
+
// ディレクトリが存在しない場合は作成
|
|
455
|
+
if (!existsSync(specDir)) {
|
|
456
|
+
mkdirSync(specDir, { recursive: true });
|
|
457
|
+
}
|
|
458
|
+
// 選択結果を保存
|
|
459
|
+
writeFileSync(selectionPath, JSON.stringify(selection, null, 2), 'utf-8');
|
|
460
|
+
console.log(`\n✅ テストタイプ選択を保存しました: ${selectionPath}`);
|
|
461
|
+
// spec.jsonを更新
|
|
462
|
+
try {
|
|
463
|
+
const specPath = join(specDir, 'spec.json');
|
|
464
|
+
if (existsSync(specPath)) {
|
|
465
|
+
const spec = JSON.parse(readFileSync(specPath, 'utf-8'));
|
|
466
|
+
spec.testTypeSelection = {
|
|
467
|
+
completed: true,
|
|
468
|
+
selectedTypes: answers.testTypes,
|
|
469
|
+
selectedAt: selection.selectedAt,
|
|
470
|
+
};
|
|
471
|
+
spec.lastUpdated = new Date().toISOString();
|
|
472
|
+
writeFileSync(specPath, JSON.stringify(spec, null, 2), 'utf-8');
|
|
473
|
+
console.log('✅ spec.jsonを更新しました');
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
catch (error) {
|
|
477
|
+
errors.push(`spec.json更新失敗: ${error.message}`);
|
|
478
|
+
console.warn(`⚠️ spec.json更新失敗: ${error.message}`);
|
|
479
|
+
}
|
|
480
|
+
// 選択結果のサマリーを表示
|
|
481
|
+
console.log('\n' + '='.repeat(60));
|
|
482
|
+
console.log('📊 選択結果サマリー:');
|
|
483
|
+
console.log(` 必須テスト: ${['unit', 'lint', 'build'].join(', ')}`);
|
|
484
|
+
const optional = answers.testTypes.filter((t) => !['unit', 'lint', 'build'].includes(t));
|
|
485
|
+
if (optional.length > 0) {
|
|
486
|
+
console.log(` 追加テスト: ${optional.join(', ')}`);
|
|
487
|
+
}
|
|
488
|
+
else {
|
|
489
|
+
console.log(' 追加テスト: なし');
|
|
490
|
+
}
|
|
491
|
+
console.log('\n📖 次のステップ:');
|
|
492
|
+
console.log(' 1. Phase 0.4: テスト仕様書作成へ進む');
|
|
493
|
+
console.log(' michi phase:run ' + feature + ' test-spec');
|
|
494
|
+
console.log(' 2. 詳細ガイド: docs/user-guide/testing/test-planning-flow.md');
|
|
495
|
+
console.log('\n' + '='.repeat(60));
|
|
496
|
+
console.log('✅ Phase 0.3: テストタイプ選択が完了しました');
|
|
497
|
+
return {
|
|
498
|
+
phase: 'test-type-selection',
|
|
499
|
+
success: true,
|
|
500
|
+
confluenceCreated: false,
|
|
501
|
+
jiraCreated: false,
|
|
502
|
+
validationPassed: true,
|
|
503
|
+
errors,
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* テスト仕様書作成フェーズを実行(Phase 0.4)
|
|
508
|
+
* 自動生成: test-type-selectionから選択されたテストタイプの仕様書を生成
|
|
509
|
+
*/
|
|
510
|
+
async function runTestSpecPhase(feature) {
|
|
511
|
+
console.log('\n📝 Phase 0.4: Test Specification(テスト仕様書作成)');
|
|
512
|
+
console.log('='.repeat(60));
|
|
513
|
+
const errors = [];
|
|
514
|
+
// Step 1: テストタイプ選択の読み込み
|
|
515
|
+
const selectionPath = join(process.cwd(), '.kiro', 'specs', feature, 'test-type-selection.json');
|
|
516
|
+
if (!existsSync(selectionPath)) {
|
|
517
|
+
errors.push('test-type-selection.jsonが存在しません。先にtest-type-selectionフェーズを実行してください');
|
|
518
|
+
return {
|
|
519
|
+
phase: 'test-spec',
|
|
520
|
+
success: false,
|
|
521
|
+
confluenceCreated: false,
|
|
522
|
+
jiraCreated: false,
|
|
523
|
+
validationPassed: false,
|
|
524
|
+
errors,
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
let selection;
|
|
528
|
+
let testTypes = [];
|
|
529
|
+
try {
|
|
530
|
+
selection = JSON.parse(readFileSync(selectionPath, 'utf-8'));
|
|
531
|
+
testTypes = selection.selectedTypes || [];
|
|
532
|
+
}
|
|
533
|
+
catch (error) {
|
|
534
|
+
errors.push(`test-type-selection.jsonの読み込みまたはパースに失敗しました: ${error instanceof Error ? error.message : String(error)}`);
|
|
535
|
+
return {
|
|
536
|
+
phase: 'test-spec',
|
|
537
|
+
success: false,
|
|
538
|
+
confluenceCreated: false,
|
|
539
|
+
jiraCreated: false,
|
|
540
|
+
validationPassed: false,
|
|
541
|
+
errors,
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
console.log(`\n✅ 選択されたテストタイプ: ${testTypes.join(', ')}`);
|
|
545
|
+
// Step 2: 各テストタイプのテスト仕様書を生成
|
|
546
|
+
console.log('\n🤖 テスト仕様書を自動生成中...');
|
|
547
|
+
const specDir = join(process.cwd(), '.kiro', 'specs', feature, 'test-specs');
|
|
548
|
+
mkdirSync(specDir, { recursive: true });
|
|
549
|
+
const { generateTestSpec } = await import('./test-spec-generator.js');
|
|
550
|
+
const generatedSpecs = [];
|
|
551
|
+
for (const testType of testTypes) {
|
|
552
|
+
// lint/buildはテスト仕様書不要(CI設定で対応)
|
|
553
|
+
if (testType === 'lint' || testType === 'build') {
|
|
554
|
+
console.log(` ⏭️ ${testType}: スキップ(CI設定で対応)`);
|
|
555
|
+
continue;
|
|
556
|
+
}
|
|
557
|
+
try {
|
|
558
|
+
await generateTestSpec(feature, testType);
|
|
559
|
+
console.log(` ✅ ${testType}テスト仕様書: ${testType}-test-spec.md`);
|
|
560
|
+
generatedSpecs.push(testType);
|
|
561
|
+
}
|
|
562
|
+
catch (error) {
|
|
563
|
+
errors.push(`${testType}テスト仕様書生成失敗: ${error.message}`);
|
|
564
|
+
console.error(` ❌ ${testType}テスト仕様書生成失敗: ${error.message}`);
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
// Step 3: spec.json更新
|
|
568
|
+
const specPath = join(process.cwd(), '.kiro', 'specs', feature, 'spec.json');
|
|
569
|
+
if (existsSync(specPath)) {
|
|
570
|
+
try {
|
|
571
|
+
const spec = JSON.parse(readFileSync(specPath, 'utf-8'));
|
|
572
|
+
spec.testSpecification = {
|
|
573
|
+
completed: true,
|
|
574
|
+
generatedAt: new Date().toISOString(),
|
|
575
|
+
testTypes: testTypes,
|
|
576
|
+
generatedSpecs: generatedSpecs,
|
|
577
|
+
};
|
|
578
|
+
spec.lastUpdated = new Date().toISOString();
|
|
579
|
+
writeFileSync(specPath, JSON.stringify(spec, null, 2), 'utf-8');
|
|
580
|
+
console.log('\n✅ spec.jsonを更新しました');
|
|
581
|
+
}
|
|
582
|
+
catch (error) {
|
|
583
|
+
errors.push(`spec.json更新失敗: ${error.message}`);
|
|
584
|
+
console.warn(`⚠️ spec.json更新失敗: ${error.message}`);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
// Step 4: サマリー表示
|
|
588
|
+
console.log('\n' + '='.repeat(60));
|
|
589
|
+
console.log('📊 テスト仕様書作成完了:');
|
|
590
|
+
console.log(` 生成されたファイル: ${generatedSpecs.length}件`);
|
|
591
|
+
console.log(` 保存先: .kiro/specs/${feature}/test-specs/`);
|
|
592
|
+
if (generatedSpecs.length > 0) {
|
|
593
|
+
console.log('\n📄 生成されたファイル:');
|
|
594
|
+
generatedSpecs.forEach((type) => {
|
|
595
|
+
console.log(` - ${type}-test-spec.md`);
|
|
596
|
+
});
|
|
597
|
+
}
|
|
598
|
+
console.log('\n📖 次のステップ:');
|
|
599
|
+
console.log(' 1. Phase 0.5: タスク分割へ進む');
|
|
600
|
+
console.log(` michi phase:run ${feature} tasks`);
|
|
601
|
+
console.log('\n' + '='.repeat(60));
|
|
602
|
+
console.log('✅ Phase 0.4: テスト仕様書作成が完了しました');
|
|
603
|
+
return {
|
|
604
|
+
phase: 'test-spec',
|
|
605
|
+
success: errors.length === 0 && generatedSpecs.length > 0,
|
|
606
|
+
confluenceCreated: false,
|
|
607
|
+
jiraCreated: false,
|
|
608
|
+
validationPassed: true,
|
|
609
|
+
errors,
|
|
610
|
+
};
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* 環境構築フェーズを実行(Phase 1)
|
|
614
|
+
* 対話的に環境を構築し、必要な設定ファイルを生成
|
|
615
|
+
*/
|
|
616
|
+
async function runEnvironmentSetupPhase(feature) {
|
|
617
|
+
console.log('\n⚙️ Phase 1: Environment Setup(環境構築)');
|
|
618
|
+
console.log('='.repeat(60));
|
|
619
|
+
const errors = [];
|
|
620
|
+
// Step 1: プロジェクト検出
|
|
621
|
+
const { detectProject } = await import('./utils/project-detector.js');
|
|
622
|
+
const detected = detectProject();
|
|
623
|
+
console.log(`\n🔍 検出されたプロジェクト: ${detected.language}`);
|
|
624
|
+
console.log(` ビルドツール: ${detected.buildTool}`);
|
|
625
|
+
if (detected.testFramework) {
|
|
626
|
+
console.log(` テストフレームワーク: ${detected.testFramework}`);
|
|
627
|
+
}
|
|
628
|
+
if (detected.hasCI) {
|
|
629
|
+
console.log(' CI/CD: 既存の設定あり');
|
|
630
|
+
}
|
|
631
|
+
// Step 2: 実装言語を分析
|
|
632
|
+
const { analyzeLanguage } = await import('./utils/language-detector.js');
|
|
633
|
+
const languageAnalysis = analyzeLanguage(feature);
|
|
634
|
+
if (languageAnalysis.confidence !== 'low') {
|
|
635
|
+
console.log(`\n💡 実装言語を推奨します: ${languageAnalysis.language}(信頼度: ${languageAnalysis.confidence})`);
|
|
636
|
+
console.log(' 理由:');
|
|
637
|
+
languageAnalysis.reasons.forEach((reason) => console.log(` - ${reason}`));
|
|
638
|
+
}
|
|
639
|
+
// Step 3: Docker Compose要件を分析
|
|
640
|
+
const { analyzeDockerRequirement } = await import('./utils/docker-requirement-detector.js');
|
|
641
|
+
const dockerAnalysis = analyzeDockerRequirement(feature);
|
|
642
|
+
if (dockerAnalysis.recommended) {
|
|
643
|
+
console.log(`\n💡 Docker Composeを推奨します(信頼度: ${dockerAnalysis.confidence})`);
|
|
644
|
+
console.log(' 理由:');
|
|
645
|
+
dockerAnalysis.reasons.forEach((reason) => console.log(` - ${reason}`));
|
|
646
|
+
if (dockerAnalysis.suggestedServices.length > 0) {
|
|
647
|
+
console.log(` 推奨サービス: ${dockerAnalysis.suggestedServices.join(', ')}`);
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
// Step 4: 対話的質問
|
|
651
|
+
console.log('\n📚 環境構築を対話的に設定します\n');
|
|
652
|
+
const languageMap = {
|
|
653
|
+
nodejs: 'Node.js/TypeScript',
|
|
654
|
+
java: 'Java',
|
|
655
|
+
php: 'PHP',
|
|
656
|
+
python: 'Python',
|
|
657
|
+
go: 'Go',
|
|
658
|
+
rust: 'Rust',
|
|
659
|
+
other: 'その他',
|
|
660
|
+
};
|
|
661
|
+
// 言語のデフォルト値を決定(分析結果 > プロジェクト検出)
|
|
662
|
+
const defaultLanguage = languageAnalysis.confidence !== 'low'
|
|
663
|
+
? languageAnalysis.language
|
|
664
|
+
: languageMap[detected.language] || 'その他';
|
|
665
|
+
const answers = await inquirer.prompt([
|
|
666
|
+
{
|
|
667
|
+
type: 'list',
|
|
668
|
+
name: 'language',
|
|
669
|
+
message: languageAnalysis.confidence !== 'low'
|
|
670
|
+
? `プロジェクトの言語を選択してください(推奨: ${languageAnalysis.language}):`
|
|
671
|
+
: 'プロジェクトの言語を選択してください:',
|
|
672
|
+
choices: [
|
|
673
|
+
'Node.js/TypeScript',
|
|
674
|
+
'Java',
|
|
675
|
+
'PHP',
|
|
676
|
+
'Python',
|
|
677
|
+
'Go',
|
|
678
|
+
'Rust',
|
|
679
|
+
'その他',
|
|
680
|
+
],
|
|
681
|
+
default: defaultLanguage,
|
|
682
|
+
},
|
|
683
|
+
{
|
|
684
|
+
type: 'list',
|
|
685
|
+
name: 'ciTool',
|
|
686
|
+
message: 'CI/CDツールを選択してください:',
|
|
687
|
+
choices: ['GitHub Actions', 'Screwdriver', 'GitLab CI', 'なし'],
|
|
688
|
+
default: detected.hasCI ? 'GitHub Actions' : 'GitHub Actions',
|
|
689
|
+
},
|
|
690
|
+
{
|
|
691
|
+
type: 'confirm',
|
|
692
|
+
name: 'needsDocker',
|
|
693
|
+
message: dockerAnalysis.recommended
|
|
694
|
+
? `Docker Composeを使用しますか?(推奨: ${dockerAnalysis.confidence})`
|
|
695
|
+
: 'Docker Composeが必要ですか?(データベース・モックサーバー用)',
|
|
696
|
+
default: dockerAnalysis.recommended,
|
|
697
|
+
},
|
|
698
|
+
{
|
|
699
|
+
type: 'confirm',
|
|
700
|
+
name: 'installDeps',
|
|
701
|
+
message: '依存関係を自動インストールしますか?',
|
|
702
|
+
default: true,
|
|
703
|
+
when: () => detected.hasDependencies,
|
|
704
|
+
},
|
|
705
|
+
]);
|
|
706
|
+
// Docker Composeの推奨サービスを保存
|
|
707
|
+
answers.suggestedServices = dockerAnalysis.suggestedServices;
|
|
708
|
+
// Step 3: 設定ファイル生成
|
|
709
|
+
console.log('\n🤖 設定ファイルを生成中...');
|
|
710
|
+
try {
|
|
711
|
+
const { generateCIConfig } = await import('./utils/ci-generator.js');
|
|
712
|
+
await generateCIConfig(feature, answers);
|
|
713
|
+
}
|
|
714
|
+
catch (error) {
|
|
715
|
+
errors.push(`CI/CD設定生成失敗: ${error.message}`);
|
|
716
|
+
console.error(` ❌ CI/CD設定生成失敗: ${error.message}`);
|
|
717
|
+
}
|
|
718
|
+
try {
|
|
719
|
+
const { generateTestConfig } = await import('./utils/test-config-generator.js');
|
|
720
|
+
await generateTestConfig(feature, answers);
|
|
721
|
+
}
|
|
722
|
+
catch (error) {
|
|
723
|
+
errors.push(`テスト設定生成失敗: ${error.message}`);
|
|
724
|
+
console.error(` ❌ テスト設定生成失敗: ${error.message}`);
|
|
725
|
+
}
|
|
726
|
+
if (answers.needsDocker) {
|
|
727
|
+
try {
|
|
728
|
+
const { generateDockerCompose } = await import('./utils/docker-generator.js');
|
|
729
|
+
await generateDockerCompose(feature, answers.suggestedServices || []);
|
|
730
|
+
}
|
|
731
|
+
catch (error) {
|
|
732
|
+
errors.push(`Docker Compose生成失敗: ${error.message}`);
|
|
733
|
+
console.error(` ❌ Docker Compose生成失敗: ${error.message}`);
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
// Step 4: 依存関係インストール(オプション)
|
|
737
|
+
if (answers.installDeps) {
|
|
738
|
+
console.log('\n📦 依存関係をインストール中...');
|
|
739
|
+
const { execSync } = await import('child_process');
|
|
740
|
+
// 言語別のビルドファイル存在確認
|
|
741
|
+
const buildFileChecks = {
|
|
742
|
+
'Node.js/TypeScript': 'package.json',
|
|
743
|
+
Java: 'build.gradle',
|
|
744
|
+
PHP: 'composer.json',
|
|
745
|
+
Python: 'requirements.txt',
|
|
746
|
+
Go: 'go.mod',
|
|
747
|
+
Rust: 'Cargo.toml',
|
|
748
|
+
};
|
|
749
|
+
const buildFile = buildFileChecks[answers.language];
|
|
750
|
+
if (!buildFile || !existsSync(buildFile)) {
|
|
751
|
+
console.log(` ℹ️ ${buildFile || 'ビルドファイル'}が見つかりません(スキップ)`);
|
|
752
|
+
console.log(' 💡 実際のプロジェクトでは、先にプロジェクトを初期化してください');
|
|
753
|
+
}
|
|
754
|
+
else {
|
|
755
|
+
const commands = {
|
|
756
|
+
'Node.js/TypeScript': detected.packageManager === 'pnpm'
|
|
757
|
+
? 'pnpm install'
|
|
758
|
+
: detected.packageManager === 'yarn'
|
|
759
|
+
? 'yarn install'
|
|
760
|
+
: 'npm install',
|
|
761
|
+
Java: existsSync('./gradlew')
|
|
762
|
+
? './gradlew build --no-daemon'
|
|
763
|
+
: 'gradle build',
|
|
764
|
+
PHP: 'composer install',
|
|
765
|
+
Python: 'pip install -r requirements.txt',
|
|
766
|
+
Go: 'go mod download',
|
|
767
|
+
Rust: 'cargo fetch',
|
|
768
|
+
};
|
|
769
|
+
const command = commands[answers.language];
|
|
770
|
+
if (command) {
|
|
771
|
+
try {
|
|
772
|
+
execSync(command, { stdio: 'inherit', cwd: process.cwd() });
|
|
773
|
+
console.log(' ✅ 依存関係のインストール完了');
|
|
774
|
+
}
|
|
775
|
+
catch (error) {
|
|
776
|
+
console.warn(` ⚠️ 依存関係インストール失敗: ${error.message}`);
|
|
777
|
+
console.warn(' 💡 プロジェクト初期化後に手動でインストールしてください');
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
// Step 5: spec.json更新
|
|
783
|
+
const specPath = join(process.cwd(), '.kiro', 'specs', feature, 'spec.json');
|
|
784
|
+
if (existsSync(specPath)) {
|
|
785
|
+
try {
|
|
786
|
+
const spec = JSON.parse(readFileSync(specPath, 'utf-8'));
|
|
787
|
+
spec.environmentSetup = {
|
|
788
|
+
completed: true,
|
|
789
|
+
language: answers.language,
|
|
790
|
+
ciTool: answers.ciTool,
|
|
791
|
+
dockerCompose: answers.needsDocker,
|
|
792
|
+
completedAt: new Date().toISOString(),
|
|
793
|
+
};
|
|
794
|
+
spec.lastUpdated = new Date().toISOString();
|
|
795
|
+
writeFileSync(specPath, JSON.stringify(spec, null, 2), 'utf-8');
|
|
796
|
+
console.log('\n✅ spec.jsonを更新しました');
|
|
797
|
+
}
|
|
798
|
+
catch (error) {
|
|
799
|
+
errors.push(`spec.json更新失敗: ${error.message}`);
|
|
800
|
+
console.warn(`⚠️ spec.json更新失敗: ${error.message}`);
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
// Step 6: サマリー表示
|
|
804
|
+
console.log('\n' + '='.repeat(60));
|
|
805
|
+
console.log('📊 環境構築完了:');
|
|
806
|
+
console.log(` 言語: ${answers.language}`);
|
|
807
|
+
console.log(` CI/CD: ${answers.ciTool}`);
|
|
808
|
+
console.log(` Docker Compose: ${answers.needsDocker ? 'あり' : 'なし'}`);
|
|
809
|
+
console.log('\n📖 次のステップ:');
|
|
810
|
+
console.log(' 1. Phase 2: TDD実装へ進む');
|
|
811
|
+
console.log(` /kiro:spec-impl ${feature}`);
|
|
812
|
+
console.log('\n' + '='.repeat(60));
|
|
813
|
+
console.log('✅ Phase 1: 環境構築が完了しました');
|
|
814
|
+
return {
|
|
815
|
+
phase: 'environment-setup',
|
|
816
|
+
success: errors.length === 0,
|
|
817
|
+
confluenceCreated: false,
|
|
818
|
+
jiraCreated: false,
|
|
819
|
+
validationPassed: true,
|
|
820
|
+
errors,
|
|
821
|
+
};
|
|
822
|
+
}
|
|
823
|
+
/**
|
|
824
|
+
* PR前自動テストフェーズを実行(Phase A)
|
|
825
|
+
* マニュアル対応:CI/CD案内を表示
|
|
826
|
+
*/
|
|
827
|
+
async function runPhaseAPhase(feature) {
|
|
828
|
+
console.log('\n🤖 Phase A: PR前自動テスト(PR Tests)');
|
|
829
|
+
console.log('='.repeat(60));
|
|
830
|
+
const errors = [];
|
|
831
|
+
// spec.jsonから言語を読み取る
|
|
832
|
+
const spec = loadSpecJson(feature);
|
|
833
|
+
const language = spec.environmentSetup?.language || 'Node.js/TypeScript';
|
|
834
|
+
const commands = getTestCommands(language);
|
|
835
|
+
console.log('\n📚 このフェーズはCI/CD自動実行です');
|
|
836
|
+
console.log('PR作成時に以下のテストが自動実行されます:\n');
|
|
837
|
+
console.log('自動実行テスト:');
|
|
838
|
+
console.log(` - 単体テスト (${commands.test})`);
|
|
839
|
+
console.log(` - Lint実行 (${commands.lint})`);
|
|
840
|
+
console.log(` - ビルド実行 (${commands.build})\n`);
|
|
841
|
+
console.log('CI/CD設定ファイル:');
|
|
842
|
+
console.log(' - .github/workflows/ci.yml');
|
|
843
|
+
console.log(' - .github/workflows/test.yml\n');
|
|
844
|
+
console.log('📖 詳細ガイド:');
|
|
845
|
+
console.log(' docs/user-guide/testing/test-execution-flow.md\n');
|
|
846
|
+
console.log('確認事項:');
|
|
847
|
+
console.log(' [ ] CI/CDパイプラインが正常に動作している');
|
|
848
|
+
console.log(' [ ] すべての自動テストが成功している');
|
|
849
|
+
console.log(' [ ] テストカバレッジが95%以上');
|
|
850
|
+
console.log('\n' + '='.repeat(60));
|
|
851
|
+
console.log('✅ Phase A: PR前自動テスト案内を表示しました');
|
|
852
|
+
console.log('📢 CI/CDが自動実行します。Phase 3に進んでください');
|
|
853
|
+
return {
|
|
854
|
+
phase: 'phase-a',
|
|
855
|
+
success: true,
|
|
856
|
+
confluenceCreated: false,
|
|
857
|
+
jiraCreated: false,
|
|
858
|
+
validationPassed: true,
|
|
859
|
+
errors,
|
|
860
|
+
};
|
|
861
|
+
}
|
|
862
|
+
/**
|
|
863
|
+
* リリース準備テストフェーズを実行(Phase B)
|
|
864
|
+
* テスト実行ファイルを自動生成し、手動テストチェックリストを表示
|
|
865
|
+
*/
|
|
866
|
+
async function runPhaseBPhase(feature) {
|
|
867
|
+
console.log('\n🔍 Phase B: リリース準備テスト(Release Tests)');
|
|
868
|
+
console.log('='.repeat(60));
|
|
869
|
+
const errors = [];
|
|
870
|
+
const generatedFiles = [];
|
|
871
|
+
// Step 1: テストタイプ選択の読み込み
|
|
872
|
+
const selectionPath = join(process.cwd(), '.kiro', 'specs', feature, 'test-type-selection.json');
|
|
873
|
+
let selectedTypes = [];
|
|
874
|
+
if (existsSync(selectionPath)) {
|
|
875
|
+
try {
|
|
876
|
+
const selection = JSON.parse(readFileSync(selectionPath, 'utf-8'));
|
|
877
|
+
selectedTypes = selection.selectedTypes || [];
|
|
878
|
+
console.log(`\n✅ 選択されたテストタイプ: ${selectedTypes.join(', ')}`);
|
|
879
|
+
}
|
|
880
|
+
catch {
|
|
881
|
+
console.warn('⚠️ test-type-selection.jsonの読み込みに失敗しました');
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
else {
|
|
885
|
+
console.log('\n⚠️ test-type-selection.jsonが存在しません');
|
|
886
|
+
console.log(' デフォルトのテストタイプを使用します');
|
|
887
|
+
selectedTypes = [
|
|
888
|
+
'unit',
|
|
889
|
+
'lint',
|
|
890
|
+
'build',
|
|
891
|
+
'integration',
|
|
892
|
+
'performance',
|
|
893
|
+
'security',
|
|
894
|
+
];
|
|
895
|
+
}
|
|
896
|
+
// Step 2: Phase B対象のテストタイプを抽出
|
|
897
|
+
const phaseBTypes = selectedTypes.filter((t) => !['unit', 'lint', 'build'].includes(t));
|
|
898
|
+
if (phaseBTypes.length > 0) {
|
|
899
|
+
console.log(`\n📝 Phase B対象テスト: ${phaseBTypes.join(', ')}`);
|
|
900
|
+
// Step 3: テスト実行ファイルを生成
|
|
901
|
+
console.log('\n🤖 テスト実行ファイルを自動生成中...');
|
|
902
|
+
const { generateTestExecution } = await import('./test-execution-generator.js');
|
|
903
|
+
for (const testType of phaseBTypes) {
|
|
904
|
+
try {
|
|
905
|
+
const result = await generateTestExecution(feature, testType);
|
|
906
|
+
if (result.success) {
|
|
907
|
+
console.log(` ✅ ${result.testType}: ${result.files.length}ファイル生成`);
|
|
908
|
+
generatedFiles.push(...result.files);
|
|
909
|
+
}
|
|
910
|
+
else {
|
|
911
|
+
console.error(` ❌ ${result.testType}: ${result.error}`);
|
|
912
|
+
errors.push(`${result.testType}テスト生成失敗: ${result.error}`);
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
catch (error) {
|
|
916
|
+
errors.push(`${testType}テスト生成失敗: ${error.message}`);
|
|
917
|
+
console.error(`❌ ${testType}テスト生成失敗:`, error.message);
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
// Step 4: 生成されたファイルのサマリー
|
|
922
|
+
const testExecutionDir = join(process.cwd(), '.kiro', 'specs', feature, 'test-execution');
|
|
923
|
+
if (generatedFiles.length > 0) {
|
|
924
|
+
console.log('\n📄 生成されたファイル:');
|
|
925
|
+
generatedFiles.forEach((file) => {
|
|
926
|
+
const relativePath = relative(testExecutionDir, file);
|
|
927
|
+
console.log(` - ${relativePath}`);
|
|
928
|
+
});
|
|
929
|
+
}
|
|
930
|
+
// Step 5: チェックリスト表示
|
|
931
|
+
console.log('\n' + '='.repeat(60));
|
|
932
|
+
console.log('📋 リリース準備テストチェックリスト:\n');
|
|
933
|
+
if (phaseBTypes.includes('performance')) {
|
|
934
|
+
console.log(' [ ] 性能テスト実行');
|
|
935
|
+
console.log(` 📁 .kiro/specs/${feature}/test-execution/performance/`);
|
|
936
|
+
console.log(' 📖 詳細はディレクトリ内のREADME/計画書を参照');
|
|
937
|
+
}
|
|
938
|
+
if (phaseBTypes.includes('security')) {
|
|
939
|
+
console.log(' [ ] セキュリティテスト実行');
|
|
940
|
+
console.log(` 📁 .kiro/specs/${feature}/test-execution/security/`);
|
|
941
|
+
console.log(' 📖 詳細はディレクトリ内のREADME/計画書を参照');
|
|
942
|
+
}
|
|
943
|
+
if (phaseBTypes.includes('integration')) {
|
|
944
|
+
console.log(' [ ] 統合テスト実行');
|
|
945
|
+
console.log(` 📁 .kiro/specs/${feature}/test-execution/integration/`);
|
|
946
|
+
}
|
|
947
|
+
if (phaseBTypes.includes('e2e')) {
|
|
948
|
+
console.log(' [ ] E2Eテスト実行');
|
|
949
|
+
console.log(` 📁 .kiro/specs/${feature}/test-execution/e2e/`);
|
|
950
|
+
}
|
|
951
|
+
console.log('\n参考ドキュメント:');
|
|
952
|
+
console.log(` - .kiro/specs/${feature}/test-specs/ (テスト仕様書)`);
|
|
953
|
+
console.log(' - docs/user-guide/testing/test-execution-flow.md');
|
|
954
|
+
console.log('\n次のステップ:');
|
|
955
|
+
console.log(' 1. 生成されたテストファイルを確認・編集');
|
|
956
|
+
console.log(' 2. 各テストを実行');
|
|
957
|
+
console.log(' 3. テスト結果をドキュメント化');
|
|
958
|
+
console.log(' 4. Phase 4: リリース準備へ進む');
|
|
959
|
+
console.log('\n' + '='.repeat(60));
|
|
960
|
+
const success = errors.length === 0;
|
|
961
|
+
if (success) {
|
|
962
|
+
console.log('✅ Phase B: テスト実行ファイル生成が完了しました');
|
|
963
|
+
console.log('📢 テストを実行してPhase 4に進んでください');
|
|
964
|
+
}
|
|
965
|
+
else {
|
|
966
|
+
console.log('⚠️ Phase B: テスト実行ファイル生成が部分的に完了しました');
|
|
967
|
+
console.log(`❌ ${errors.length}件のエラーが発生しています`);
|
|
968
|
+
errors.forEach((err) => console.log(` - ${err}`));
|
|
969
|
+
console.log('📢 エラーを修正してから再実行してください');
|
|
970
|
+
}
|
|
971
|
+
return {
|
|
972
|
+
phase: 'phase-b',
|
|
973
|
+
success,
|
|
974
|
+
confluenceCreated: false,
|
|
975
|
+
jiraCreated: false,
|
|
976
|
+
validationPassed: true,
|
|
977
|
+
errors,
|
|
211
978
|
};
|
|
212
979
|
}
|
|
213
980
|
/**
|
|
@@ -221,8 +988,18 @@ export async function runPhase(feature, phase) {
|
|
|
221
988
|
return await runRequirementsPhase(feature);
|
|
222
989
|
case 'design':
|
|
223
990
|
return await runDesignPhase(feature);
|
|
991
|
+
case 'test-type-selection':
|
|
992
|
+
return await runTestTypeSelectionPhase(feature);
|
|
993
|
+
case 'test-spec':
|
|
994
|
+
return await runTestSpecPhase(feature);
|
|
224
995
|
case 'tasks':
|
|
225
996
|
return await runTasksPhase(feature);
|
|
997
|
+
case 'environment-setup':
|
|
998
|
+
return await runEnvironmentSetupPhase(feature);
|
|
999
|
+
case 'phase-a':
|
|
1000
|
+
return await runPhaseAPhase(feature);
|
|
1001
|
+
case 'phase-b':
|
|
1002
|
+
return await runPhaseBPhase(feature);
|
|
226
1003
|
default:
|
|
227
1004
|
throw new Error(`Unknown phase: ${phase}`);
|
|
228
1005
|
}
|
|
@@ -233,12 +1010,31 @@ if (import.meta.url === `file://${process.argv[1]}`) {
|
|
|
233
1010
|
if (args.length < 2) {
|
|
234
1011
|
console.error('Usage: npm run phase:run <feature> <phase>');
|
|
235
1012
|
console.error('Example: npm run phase:run calculator-app requirements');
|
|
236
|
-
console.error('Phases:
|
|
1013
|
+
console.error('\nAvailable Phases:');
|
|
1014
|
+
console.error(' requirements - Phase 0.1: 要件定義');
|
|
1015
|
+
console.error(' design - Phase 0.2: 設計');
|
|
1016
|
+
console.error(' test-type-selection- Phase 0.3: テストタイプ選択(任意)');
|
|
1017
|
+
console.error(' test-spec - Phase 0.4: テスト仕様書作成(任意)');
|
|
1018
|
+
console.error(' tasks - Phase 0.5-0.6: タスク分割・JIRA同期');
|
|
1019
|
+
console.error(' environment-setup - Phase 1: 環境構築(任意)');
|
|
1020
|
+
console.error(' phase-a - Phase A: PR前自動テスト(任意)');
|
|
1021
|
+
console.error(' phase-b - Phase B: リリース準備テスト(任意)');
|
|
237
1022
|
process.exit(1);
|
|
238
1023
|
}
|
|
239
1024
|
const [feature, phase] = args;
|
|
240
|
-
|
|
241
|
-
|
|
1025
|
+
const validPhases = [
|
|
1026
|
+
'requirements',
|
|
1027
|
+
'design',
|
|
1028
|
+
'test-type-selection',
|
|
1029
|
+
'test-spec',
|
|
1030
|
+
'tasks',
|
|
1031
|
+
'environment-setup',
|
|
1032
|
+
'phase-a',
|
|
1033
|
+
'phase-b',
|
|
1034
|
+
];
|
|
1035
|
+
if (!validPhases.includes(phase)) {
|
|
1036
|
+
console.error(`Invalid phase: ${phase}`);
|
|
1037
|
+
console.error('Must be one of: requirements, design, test-type-selection, test-spec, tasks, environment-setup, phase-a, phase-b');
|
|
242
1038
|
process.exit(1);
|
|
243
1039
|
}
|
|
244
1040
|
runPhase(feature, phase)
|