@sk8metal/michi-cli 0.3.0 → 0.5.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 +83 -0
- package/dist/scripts/__tests__/spec-impl-workflow.test.js +4 -2
- package/dist/scripts/__tests__/spec-impl-workflow.test.js.map +1 -1
- package/dist/scripts/config/config-schema.d.ts +52 -0
- package/dist/scripts/config/config-schema.d.ts.map +1 -1
- package/dist/scripts/config/config-schema.js +25 -0
- package/dist/scripts/config/config-schema.js.map +1 -1
- package/dist/scripts/config-global.d.ts +10 -0
- package/dist/scripts/config-global.d.ts.map +1 -0
- package/dist/scripts/config-global.js +111 -0
- package/dist/scripts/config-global.js.map +1 -0
- package/dist/scripts/confluence-sync.d.ts +22 -4
- package/dist/scripts/confluence-sync.d.ts.map +1 -1
- package/dist/scripts/confluence-sync.js +22 -12
- package/dist/scripts/confluence-sync.js.map +1 -1
- package/dist/scripts/jira-sync.d.ts.map +1 -1
- package/dist/scripts/jira-sync.js +201 -167
- package/dist/scripts/jira-sync.js.map +1 -1
- package/dist/scripts/list-projects.js.map +1 -1
- package/dist/scripts/multi-project-estimate.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 +295 -522
- 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 +11 -3
- package/dist/scripts/pr-automation.js.map +1 -1
- package/dist/scripts/pre-flight-check.d.ts.map +1 -1
- package/dist/scripts/pre-flight-check.js +10 -6
- package/dist/scripts/pre-flight-check.js.map +1 -1
- package/dist/scripts/resource-dashboard.js.map +1 -1
- package/dist/scripts/spec-impl-workflow.d.ts.map +1 -1
- package/dist/scripts/spec-impl-workflow.js +23 -7
- package/dist/scripts/spec-impl-workflow.js.map +1 -1
- package/dist/scripts/template/renderer.d.ts +1 -1
- package/dist/scripts/template/renderer.d.ts.map +1 -1
- package/dist/scripts/test-interactive.d.ts.map +1 -1
- package/dist/scripts/test-interactive.js +0 -15
- package/dist/scripts/test-interactive.js.map +1 -1
- package/dist/scripts/test-new-features.js +6 -3
- package/dist/scripts/test-new-features.js.map +1 -1
- package/dist/scripts/test-spec-generator.d.ts.map +1 -1
- package/dist/scripts/test-spec-generator.js +1 -2
- package/dist/scripts/test-spec-generator.js.map +1 -1
- package/dist/scripts/utils/__tests__/config-loader.test.js +114 -1
- package/dist/scripts/utils/__tests__/config-loader.test.js.map +1 -1
- package/dist/scripts/utils/__tests__/config-validator.test.js +2 -0
- package/dist/scripts/utils/__tests__/config-validator.test.js.map +1 -1
- package/dist/scripts/utils/__tests__/env-config.test.js +0 -2
- package/dist/scripts/utils/__tests__/env-config.test.js.map +1 -1
- package/dist/scripts/utils/__tests__/project-meta.test.d.ts +6 -0
- package/dist/scripts/utils/__tests__/project-meta.test.d.ts.map +1 -0
- package/dist/scripts/utils/__tests__/project-meta.test.js +154 -0
- package/dist/scripts/utils/__tests__/project-meta.test.js.map +1 -0
- package/dist/scripts/utils/__tests__/security-validator.test.d.ts +6 -0
- package/dist/scripts/utils/__tests__/security-validator.test.d.ts.map +1 -0
- package/dist/scripts/utils/__tests__/security-validator.test.js +219 -0
- package/dist/scripts/utils/__tests__/security-validator.test.js.map +1 -0
- package/dist/scripts/utils/config-loader.d.ts +14 -3
- package/dist/scripts/utils/config-loader.d.ts.map +1 -1
- package/dist/scripts/utils/config-loader.js +284 -46
- package/dist/scripts/utils/config-loader.js.map +1 -1
- package/dist/scripts/utils/config-sections.d.ts +54 -0
- package/dist/scripts/utils/config-sections.d.ts.map +1 -0
- package/dist/scripts/utils/config-sections.js +178 -0
- package/dist/scripts/utils/config-sections.js.map +1 -0
- package/dist/scripts/utils/config-validator.d.ts +4 -0
- package/dist/scripts/utils/config-validator.d.ts.map +1 -1
- package/dist/scripts/utils/config-validator.js +57 -1
- package/dist/scripts/utils/config-validator.js.map +1 -1
- package/dist/scripts/utils/confluence-approval.d.ts.map +1 -1
- package/dist/scripts/utils/confluence-approval.js +5 -3
- package/dist/scripts/utils/confluence-approval.js.map +1 -1
- package/dist/scripts/utils/confluence-hierarchy.d.ts.map +1 -1
- package/dist/scripts/utils/confluence-hierarchy.js.map +1 -1
- package/dist/scripts/utils/env-config.d.ts +1 -1
- package/dist/scripts/utils/env-config.d.ts.map +1 -1
- package/dist/scripts/utils/env-config.js +2 -14
- package/dist/scripts/utils/env-config.js.map +1 -1
- package/dist/scripts/utils/interactive-helpers.d.ts +32 -0
- package/dist/scripts/utils/interactive-helpers.d.ts.map +1 -0
- package/dist/scripts/utils/interactive-helpers.js +92 -0
- package/dist/scripts/utils/interactive-helpers.js.map +1 -0
- package/dist/scripts/utils/jira-issue-type-fetcher.d.ts.map +1 -1
- package/dist/scripts/utils/jira-issue-type-fetcher.js +27 -18
- package/dist/scripts/utils/jira-issue-type-fetcher.js.map +1 -1
- package/dist/scripts/utils/project-meta.d.ts +9 -0
- package/dist/scripts/utils/project-meta.d.ts.map +1 -1
- package/dist/scripts/utils/project-meta.js +22 -0
- package/dist/scripts/utils/project-meta.js.map +1 -1
- package/dist/scripts/utils/release-notes-generator.d.ts.map +1 -1
- package/dist/scripts/utils/release-notes-generator.js +2 -1
- package/dist/scripts/utils/release-notes-generator.js.map +1 -1
- package/dist/scripts/utils/security-validator.d.ts +55 -0
- package/dist/scripts/utils/security-validator.d.ts.map +1 -0
- package/dist/scripts/utils/security-validator.js +232 -0
- package/dist/scripts/utils/security-validator.js.map +1 -0
- package/dist/scripts/utils/spec-updater.d.ts +19 -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.map +1 -1
- package/dist/scripts/utils/tasks-converter.js +2 -2
- package/dist/scripts/utils/tasks-converter.js.map +1 -1
- package/dist/scripts/utils/tasks-format-validator.d.ts.map +1 -1
- package/dist/scripts/utils/tasks-format-validator.js +0 -12
- package/dist/scripts/utils/tasks-format-validator.js.map +1 -1
- package/dist/scripts/utils/test-runner.d.ts.map +1 -1
- package/dist/scripts/utils/test-runner.js +3 -2
- package/dist/scripts/utils/test-runner.js.map +1 -1
- 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 +12 -62
- package/dist/scripts/validate-phase.js.map +1 -1
- package/dist/scripts/workflow-orchestrator.d.ts.map +1 -1
- package/dist/scripts/workflow-orchestrator.js +11 -16
- package/dist/scripts/workflow-orchestrator.js.map +1 -1
- package/dist/src/__tests__/integration/setup/init.test.d.ts +5 -0
- package/dist/src/__tests__/integration/setup/init.test.d.ts.map +1 -0
- package/dist/src/__tests__/integration/setup/init.test.js +352 -0
- package/dist/src/__tests__/integration/setup/init.test.js.map +1 -0
- package/dist/src/cli.d.ts.map +1 -1
- package/dist/src/cli.js +67 -21
- package/dist/src/cli.js.map +1 -1
- package/dist/src/commands/__tests__/init.test.d.ts +5 -0
- package/dist/src/commands/__tests__/init.test.d.ts.map +1 -0
- package/dist/src/commands/__tests__/init.test.js +255 -0
- package/dist/src/commands/__tests__/init.test.js.map +1 -0
- package/dist/src/commands/__tests__/migrate.test.d.ts +5 -0
- package/dist/src/commands/__tests__/migrate.test.d.ts.map +1 -0
- package/dist/src/commands/__tests__/migrate.test.js +216 -0
- package/dist/src/commands/__tests__/migrate.test.js.map +1 -0
- package/dist/src/commands/config-validate.d.ts +9 -0
- package/dist/src/commands/config-validate.d.ts.map +1 -0
- package/dist/src/commands/config-validate.js +90 -0
- package/dist/src/commands/config-validate.js.map +1 -0
- package/dist/src/commands/init.d.ts +29 -0
- package/dist/src/commands/init.d.ts.map +1 -0
- package/dist/src/commands/init.js +513 -0
- package/dist/src/commands/init.js.map +1 -0
- package/dist/src/commands/migrate.d.ts +25 -0
- package/dist/src/commands/migrate.d.ts.map +1 -0
- package/dist/src/commands/migrate.js +341 -0
- package/dist/src/commands/migrate.js.map +1 -0
- package/dist/src/commands/setup-existing.d.ts.map +1 -1
- package/dist/src/commands/setup-existing.js +0 -1
- package/dist/src/commands/setup-existing.js.map +1 -1
- package/dist/vitest.config.d.ts.map +1 -1
- package/dist/vitest.config.js +32 -8
- package/dist/vitest.config.js.map +1 -1
- package/docs/michi-development/design/config-unification.md +4789 -0
- package/docs/user-guide/getting-started/github-token-setup.md +2 -1
- package/docs/user-guide/getting-started/new-repository-setup.md +1 -1
- package/docs/user-guide/getting-started/quick-start.md +1 -1
- package/docs/user-guide/getting-started/setup.md +35 -14
- package/docs/user-guide/guides/customization.md +64 -11
- package/docs/user-guide/guides/workflow.md +35 -21
- package/docs/user-guide/hands-on/claude-agent-setup.md +2 -2
- package/docs/user-guide/hands-on/claude-setup.md +2 -2
- package/docs/user-guide/hands-on/cursor-setup.md +2 -2
- package/docs/user-guide/hands-on/workflow-walkthrough.md +4 -1
- package/docs/user-guide/reference/config.md +30 -5
- package/docs/user-guide/reference/quick-reference.md +68 -74
- package/docs/user-guide/testing/test-planning-flow.md +4 -0
- package/env.example +1 -1
- package/package.json +3 -5
- package/scripts/__tests__/spec-impl-workflow.test.ts +5 -2
- package/scripts/config/config-schema.ts +40 -0
- package/scripts/config-global.ts +160 -0
- package/scripts/confluence-sync.ts +91 -27
- package/scripts/jira-sync.ts +284 -218
- package/scripts/list-projects.ts +2 -2
- package/scripts/multi-project-estimate.ts +3 -3
- package/scripts/phase-runner.ts +391 -594
- package/scripts/pr-automation.ts +15 -5
- package/scripts/pre-flight-check.ts +20 -9
- package/scripts/pre-publish-check.sh +3 -34
- package/scripts/resource-dashboard.ts +4 -4
- package/scripts/spec-impl-workflow.ts +23 -7
- package/scripts/template/renderer.ts +1 -1
- package/scripts/test-interactive.ts +0 -19
- package/scripts/test-new-features.ts +10 -7
- package/scripts/test-npm-package.sh +3 -34
- package/scripts/test-spec-generator.ts +3 -7
- package/scripts/utils/__tests__/config-loader.test.ts +149 -0
- package/scripts/utils/__tests__/config-validator.test.ts +2 -0
- package/scripts/utils/__tests__/env-config.test.ts +0 -2
- package/scripts/utils/__tests__/project-meta.test.ts +192 -0
- package/scripts/utils/__tests__/security-validator.test.ts +272 -0
- package/scripts/utils/config-loader.ts +328 -68
- package/scripts/utils/config-sections.ts +316 -0
- package/scripts/utils/config-validator.ts +66 -1
- package/scripts/utils/confluence-approval.ts +8 -6
- package/scripts/utils/confluence-hierarchy.ts +27 -27
- package/scripts/utils/env-config.ts +2 -14
- package/scripts/utils/interactive-helpers.ts +135 -0
- package/scripts/utils/jira-issue-type-fetcher.ts +29 -21
- package/scripts/utils/project-meta.ts +27 -0
- package/scripts/utils/release-notes-generator.ts +3 -2
- package/scripts/utils/security-validator.ts +286 -0
- package/scripts/utils/spec-updater.ts +37 -15
- package/scripts/utils/tasks-converter.ts +4 -6
- package/scripts/utils/tasks-format-validator.ts +0 -13
- package/scripts/utils/test-runner.ts +4 -3
- package/scripts/validate-phase.ts +21 -80
- package/scripts/workflow-orchestrator.ts +16 -25
- package/templates/claude/commands/kiro/kiro-spec-impl.md +5 -1
- package/templates/claude/commands/kiro/kiro-spec-tasks.md +3 -1
- package/templates/claude/commands/michi/confluence-sync.md +8 -2
- package/templates/claude/commands/michi/design-review.md +4 -0
- package/templates/claude/commands/michi/e2e-plan.md +4 -0
- package/templates/claude/commands/michi/license-check.md +4 -0
- package/templates/claude/commands/michi/pr-resolve.md +4 -0
- package/templates/claude/commands/michi/project-switch.md +8 -2
- package/templates/claude/commands/michi/spec-design.md +78 -0
- package/templates/claude/commands/michi/spec-impl.md +716 -0
- package/templates/claude/commands/michi/test-planning.md +174 -0
- package/templates/claude/commands/michi/validate-design.md +58 -0
- package/templates/claude/commands/michi/version-audit.md +4 -0
- package/templates/claude-agent/commands/kiro/kiro-spec-impl.md +1 -1
- package/templates/cursor/commands/kiro/kiro-spec-impl.md +1 -1
- package/templates/michi/cc-sdd-overrides/README.md +8 -0
- package/templates/michi/cc-sdd-overrides/settings/rules/design-review-michi.md +53 -0
- package/dist/scripts/config-interactive.d.ts +0 -10
- package/dist/scripts/config-interactive.d.ts.map +0 -1
- package/dist/scripts/config-interactive.js +0 -372
- package/dist/scripts/config-interactive.js.map +0 -1
- package/dist/scripts/setup-existing-project.d.ts +0 -15
- package/dist/scripts/setup-existing-project.d.ts.map +0 -1
- package/dist/scripts/setup-existing-project.js +0 -455
- package/dist/scripts/setup-existing-project.js.map +0 -1
- package/dist/scripts/setup-interactive.d.ts +0 -10
- package/dist/scripts/setup-interactive.d.ts.map +0 -1
- package/dist/scripts/setup-interactive.js +0 -413
- package/dist/scripts/setup-interactive.js.map +0 -1
- package/scripts/config-interactive.ts +0 -550
- package/scripts/setup-existing-project.ts +0 -585
- package/scripts/setup-interactive.ts +0 -565
package/scripts/pr-automation.ts
CHANGED
|
@@ -15,13 +15,23 @@ interface PROptions {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
async function createPR(options: PROptions): Promise<void> {
|
|
18
|
+
const { getRepositoryInfo } = await import('./utils/project-meta.js');
|
|
18
19
|
const token = process.env.GITHUB_TOKEN;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
throw new Error('Missing GitHub credentials');
|
|
20
|
+
|
|
21
|
+
if (!token) {
|
|
22
|
+
throw new Error('Missing GitHub credentials. Required: GITHUB_TOKEN');
|
|
23
23
|
}
|
|
24
|
-
|
|
24
|
+
|
|
25
|
+
// .kiro/project.json から repository 情報を取得
|
|
26
|
+
let repo: string;
|
|
27
|
+
try {
|
|
28
|
+
repo = getRepositoryInfo();
|
|
29
|
+
} catch (error) {
|
|
30
|
+
throw new Error(
|
|
31
|
+
`Failed to get repository info from .kiro/project.json: ${error instanceof Error ? error.message : error}`,
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
25
35
|
const [owner, repoName] = repo.split('/');
|
|
26
36
|
const octokit = new Octokit({ auth: token });
|
|
27
37
|
|
|
@@ -16,6 +16,13 @@ interface PreFlightResult {
|
|
|
16
16
|
warnings: string[];
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
interface ProjectMeta {
|
|
20
|
+
projectId?: string;
|
|
21
|
+
projectName?: string;
|
|
22
|
+
jiraProjectKey?: string;
|
|
23
|
+
[key: string]: unknown;
|
|
24
|
+
}
|
|
25
|
+
|
|
19
26
|
/**
|
|
20
27
|
* .env設定をチェック
|
|
21
28
|
*/
|
|
@@ -78,7 +85,7 @@ function checkProjectJson(): { errors: string[], warnings: string[] } {
|
|
|
78
85
|
return { errors, warnings };
|
|
79
86
|
}
|
|
80
87
|
|
|
81
|
-
let projectMeta:
|
|
88
|
+
let projectMeta: ProjectMeta;
|
|
82
89
|
try {
|
|
83
90
|
projectMeta = JSON.parse(readFileSync(projectJsonPath, 'utf-8'));
|
|
84
91
|
} catch {
|
|
@@ -125,16 +132,18 @@ async function checkConfluenceSpace(spaceKey: string): Promise<{ errors: string[
|
|
|
125
132
|
if (response.data) {
|
|
126
133
|
console.log(` ✅ Confluenceスペース確認: ${spaceKey} (${response.data.name})`);
|
|
127
134
|
}
|
|
128
|
-
} catch (error:
|
|
129
|
-
|
|
135
|
+
} catch (error: unknown) {
|
|
136
|
+
const isAxiosError = axios.isAxiosError(error);
|
|
137
|
+
if (isAxiosError && error.response?.status === 404) {
|
|
130
138
|
errors.push(`❌ Confluenceスペースが存在しません: ${spaceKey}`);
|
|
131
139
|
errors.push(` → Confluenceで新しいスペースを作成: ${url}/wiki/spaces`);
|
|
132
140
|
errors.push(' → または、.envのCONFLUENCE_PRD_SPACEを修正してください');
|
|
133
|
-
} else if (error.response?.status === 401) {
|
|
141
|
+
} else if (isAxiosError && error.response?.status === 401) {
|
|
134
142
|
errors.push('❌ Confluence認証エラー(.envの認証情報を確認)');
|
|
135
143
|
errors.push(` → API Token管理: ${url.replace('atlassian.net', 'atlassian.net/manage/profile/security/api-tokens')}`);
|
|
136
144
|
} else {
|
|
137
|
-
|
|
145
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
146
|
+
warnings.push(`⚠️ Confluenceスペースチェック失敗: ${message}`);
|
|
138
147
|
}
|
|
139
148
|
}
|
|
140
149
|
|
|
@@ -169,18 +178,20 @@ async function checkJiraProject(projectKey: string): Promise<{ errors: string[],
|
|
|
169
178
|
if (response.data) {
|
|
170
179
|
console.log(` ✅ JIRAプロジェクト確認: ${projectKey} (${response.data.name})`);
|
|
171
180
|
}
|
|
172
|
-
} catch (error:
|
|
173
|
-
|
|
181
|
+
} catch (error: unknown) {
|
|
182
|
+
const isAxiosError = axios.isAxiosError(error);
|
|
183
|
+
if (isAxiosError && error.response?.status === 404) {
|
|
174
184
|
errors.push(`❌ JIRAプロジェクトが存在しません: ${projectKey}`);
|
|
175
185
|
errors.push(` → JIRAプロジェクト作成: ${url}/jira/projects/create`);
|
|
176
186
|
errors.push(` → プロジェクト一覧: ${url}/jira/settings/projects`);
|
|
177
187
|
errors.push(' → または、.kiro/project.jsonのjiraProjectKeyを修正してください');
|
|
178
188
|
errors.push(` 現在の設定: "${projectKey}" → 実際に存在するキーに変更`);
|
|
179
|
-
} else if (error.response?.status === 401) {
|
|
189
|
+
} else if (isAxiosError && error.response?.status === 401) {
|
|
180
190
|
errors.push('❌ JIRA認証エラー(.envの認証情報を確認)');
|
|
181
191
|
errors.push(' → API Token管理: https://id.atlassian.com/manage-profile/security/api-tokens');
|
|
182
192
|
} else {
|
|
183
|
-
|
|
193
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
194
|
+
warnings.push(`⚠️ JIRAプロジェクトチェック失敗: ${message}`);
|
|
184
195
|
}
|
|
185
196
|
}
|
|
186
197
|
|
|
@@ -142,23 +142,8 @@ echo_success "Test feature initialized"
|
|
|
142
142
|
# ========================================
|
|
143
143
|
echo_step "Testing New Phases (0.3-0.4, 1, A, B)"
|
|
144
144
|
|
|
145
|
-
# Phase 0.3:
|
|
146
|
-
|
|
147
|
-
if npm run phase:run "${TEST_FEATURE}" test-type-selection > /dev/null 2>&1; then
|
|
148
|
-
echo_success "Phase 0.3 succeeded"
|
|
149
|
-
else
|
|
150
|
-
echo_error "Phase 0.3 failed"
|
|
151
|
-
exit 1
|
|
152
|
-
fi
|
|
153
|
-
|
|
154
|
-
# Phase 0.4: テスト仕様書作成
|
|
155
|
-
echo_info "Testing Phase 0.4: test-spec"
|
|
156
|
-
if npm run phase:run "${TEST_FEATURE}" test-spec > /dev/null 2>&1; then
|
|
157
|
-
echo_success "Phase 0.4 succeeded"
|
|
158
|
-
else
|
|
159
|
-
echo_error "Phase 0.4 failed"
|
|
160
|
-
exit 1
|
|
161
|
-
fi
|
|
145
|
+
# Phase 0.3-0.4: Test planning is now handled by AI command /michi:test-planning
|
|
146
|
+
# (CLI commands removed)
|
|
162
147
|
|
|
163
148
|
# Phase 1: 環境構築
|
|
164
149
|
echo_info "Testing Phase 1: environment-setup"
|
|
@@ -192,23 +177,7 @@ fi
|
|
|
192
177
|
# ========================================
|
|
193
178
|
echo_step "Testing Phase Validations"
|
|
194
179
|
|
|
195
|
-
# Phase 0.3
|
|
196
|
-
echo_info "Validating Phase 0.3"
|
|
197
|
-
if npm run validate:phase "${TEST_FEATURE}" test-type-selection > /dev/null 2>&1; then
|
|
198
|
-
echo_success "Phase 0.3 validation passed"
|
|
199
|
-
else
|
|
200
|
-
echo_error "Phase 0.3 validation failed"
|
|
201
|
-
exit 1
|
|
202
|
-
fi
|
|
203
|
-
|
|
204
|
-
# Phase 0.4
|
|
205
|
-
echo_info "Validating Phase 0.4"
|
|
206
|
-
if npm run validate:phase "${TEST_FEATURE}" test-spec > /dev/null 2>&1; then
|
|
207
|
-
echo_success "Phase 0.4 validation passed"
|
|
208
|
-
else
|
|
209
|
-
echo_error "Phase 0.4 validation failed"
|
|
210
|
-
exit 1
|
|
211
|
-
fi
|
|
180
|
+
# Phase 0.3-0.4: Validation removed (test planning is now handled by AI command)
|
|
212
181
|
|
|
213
182
|
# Phase 1
|
|
214
183
|
echo_info "Validating Phase 1"
|
|
@@ -70,7 +70,7 @@ async function createResourceDashboard(): Promise<void> {
|
|
|
70
70
|
const { data } = await octokit.repos.getContent({
|
|
71
71
|
owner: org,
|
|
72
72
|
repo: repo.name,
|
|
73
|
-
path: `projects/${(projectEntry as
|
|
73
|
+
path: `projects/${(projectEntry as { name: string }).name}/.kiro/project.json`
|
|
74
74
|
});
|
|
75
75
|
|
|
76
76
|
if ('content' in data) {
|
|
@@ -154,16 +154,16 @@ async function createResourceDashboard(): Promise<void> {
|
|
|
154
154
|
existingPage.id,
|
|
155
155
|
pageTitle,
|
|
156
156
|
dashboardContent,
|
|
157
|
-
existingPage.version
|
|
157
|
+
existingPage.version!.number
|
|
158
158
|
);
|
|
159
159
|
const baseUrl = process.env.ATLASSIAN_URL || '';
|
|
160
|
-
pageUrl = `${baseUrl}/wiki${updated._links
|
|
160
|
+
pageUrl = `${baseUrl}/wiki${updated._links!.webui}`;
|
|
161
161
|
console.log(`✅ Dashboard page updated: ${pageUrl}`);
|
|
162
162
|
} else {
|
|
163
163
|
// 新規ページを作成
|
|
164
164
|
const created = await client.createPage(spaceKey, pageTitle, dashboardContent, ['dashboard', 'resource-management']);
|
|
165
165
|
const baseUrl = process.env.ATLASSIAN_URL || '';
|
|
166
|
-
pageUrl = `${baseUrl}/wiki${created._links
|
|
166
|
+
pageUrl = `${baseUrl}/wiki${created._links!.webui}`;
|
|
167
167
|
console.log(`✅ Dashboard page created: ${pageUrl}`);
|
|
168
168
|
}
|
|
169
169
|
} catch (error) {
|
|
@@ -258,12 +258,20 @@ ${jiraLink}
|
|
|
258
258
|
*この PR は spec-impl ワークフローで自動作成されました*`;
|
|
259
259
|
|
|
260
260
|
const { Octokit } = await import('@octokit/rest');
|
|
261
|
+
const { getRepositoryInfo } = await import('./utils/project-meta.js');
|
|
261
262
|
const token = process.env.GITHUB_TOKEN;
|
|
262
|
-
const repo = process.env.GITHUB_REPO;
|
|
263
263
|
|
|
264
|
-
if (!token
|
|
264
|
+
if (!token) {
|
|
265
|
+
throw new Error('Missing GitHub credentials. Required: GITHUB_TOKEN');
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// .kiro/project.json から repository 情報を取得
|
|
269
|
+
let repo: string;
|
|
270
|
+
try {
|
|
271
|
+
repo = getRepositoryInfo();
|
|
272
|
+
} catch (error) {
|
|
265
273
|
throw new Error(
|
|
266
|
-
|
|
274
|
+
`Failed to get repository info from .kiro/project.json: ${error instanceof Error ? error.message : error}`,
|
|
267
275
|
);
|
|
268
276
|
}
|
|
269
277
|
|
|
@@ -299,7 +307,7 @@ ${jiraLink}
|
|
|
299
307
|
// 2. Epic と Story を「レビュー待ち」に遷移
|
|
300
308
|
try {
|
|
301
309
|
await transitionEpicAndStory(jiraInfo, statusMapping.readyForReview);
|
|
302
|
-
} catch (
|
|
310
|
+
} catch (_error) {
|
|
303
311
|
console.error(
|
|
304
312
|
`⚠️ JIRA ステータス更新に失敗しましたが、PR は作成されています: ${prUrl}`,
|
|
305
313
|
);
|
|
@@ -393,12 +401,20 @@ export async function onSpecImplEnd(
|
|
|
393
401
|
|
|
394
402
|
// PR 作成
|
|
395
403
|
const { Octokit } = await import('@octokit/rest');
|
|
404
|
+
const { getRepositoryInfo } = await import('./utils/project-meta.js');
|
|
396
405
|
const token = process.env.GITHUB_TOKEN;
|
|
397
|
-
const repo = process.env.GITHUB_REPO;
|
|
398
406
|
|
|
399
|
-
if (!token
|
|
407
|
+
if (!token) {
|
|
408
|
+
throw new Error('Missing GitHub credentials. Required: GITHUB_TOKEN');
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// .kiro/project.json から repository 情報を取得
|
|
412
|
+
let repo: string;
|
|
413
|
+
try {
|
|
414
|
+
repo = getRepositoryInfo();
|
|
415
|
+
} catch (error) {
|
|
400
416
|
throw new Error(
|
|
401
|
-
|
|
417
|
+
`Failed to get repository info from .kiro/project.json: ${error instanceof Error ? error.message : error}`,
|
|
402
418
|
);
|
|
403
419
|
}
|
|
404
420
|
|
|
@@ -120,20 +120,6 @@ function question(rl: readline.Interface, query: string): Promise<string> {
|
|
|
120
120
|
});
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
/**
|
|
124
|
-
* Yes/No質問
|
|
125
|
-
*/
|
|
126
|
-
async function confirm(rl: readline.Interface, prompt: string, defaultValue: boolean = true): Promise<boolean> {
|
|
127
|
-
const defaultText = defaultValue ? '[Y/n]' : '[y/N]';
|
|
128
|
-
const answer = await question(rl, `${prompt} ${defaultText}: `);
|
|
129
|
-
|
|
130
|
-
if (!answer) {
|
|
131
|
-
return defaultValue;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
return answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes';
|
|
135
|
-
}
|
|
136
|
-
|
|
137
123
|
/**
|
|
138
124
|
* 選択肢を表示
|
|
139
125
|
*/
|
|
@@ -676,11 +662,6 @@ async function main(): Promise<number> {
|
|
|
676
662
|
console.log('Phase Bテスト(手動回帰、負荷、セキュリティ)を対話的に作成します。\n');
|
|
677
663
|
|
|
678
664
|
// テストタイプを選択
|
|
679
|
-
const testTypeChoices = TEST_TYPES.map(t => ({
|
|
680
|
-
value: t.value,
|
|
681
|
-
label: `${t.label} - ${t.description}`
|
|
682
|
-
}));
|
|
683
|
-
|
|
684
665
|
console.log('テストタイプを選択してください:');
|
|
685
666
|
TEST_TYPES.forEach((t, index) => {
|
|
686
667
|
console.log(` ${index + 1}. ${t.label}`);
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { executeTests, generateTestReport } from './utils/test-runner.js';
|
|
6
|
-
import {
|
|
6
|
+
import { getCommits, generateReleaseNotes, formatReleaseNotes } from './utils/release-notes-generator.js';
|
|
7
7
|
import { getApprovalStatus } from './utils/confluence-approval.js';
|
|
8
8
|
|
|
9
9
|
async function testTestRunner() {
|
|
@@ -32,8 +32,9 @@ async function testTestRunner() {
|
|
|
32
32
|
console.log(report.substring(0, 500) + '...');
|
|
33
33
|
|
|
34
34
|
return true;
|
|
35
|
-
} catch (error:
|
|
36
|
-
|
|
35
|
+
} catch (error: unknown) {
|
|
36
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
37
|
+
console.error('❌ テストランナーエラー:', message);
|
|
37
38
|
return false;
|
|
38
39
|
}
|
|
39
40
|
}
|
|
@@ -74,8 +75,9 @@ async function testReleaseNotesGenerator() {
|
|
|
74
75
|
console.log('⚠️ コミットが見つかりませんでした');
|
|
75
76
|
return false;
|
|
76
77
|
}
|
|
77
|
-
} catch (error:
|
|
78
|
-
|
|
78
|
+
} catch (error: unknown) {
|
|
79
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
80
|
+
console.error('❌ リリースノート生成エラー:', message);
|
|
79
81
|
return false;
|
|
80
82
|
}
|
|
81
83
|
}
|
|
@@ -123,8 +125,9 @@ async function testConfluenceApproval() {
|
|
|
123
125
|
console.log(` 承認者: ${status.approvers.join(', ') || 'なし'}`);
|
|
124
126
|
|
|
125
127
|
return true;
|
|
126
|
-
} catch (error:
|
|
127
|
-
|
|
128
|
+
} catch (error: unknown) {
|
|
129
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
130
|
+
console.error('❌ Confluence承認状態確認エラー:', message);
|
|
128
131
|
return false;
|
|
129
132
|
}
|
|
130
133
|
}
|
|
@@ -208,23 +208,8 @@ fi
|
|
|
208
208
|
|
|
209
209
|
echo_info "Testing phase:run commands..."
|
|
210
210
|
|
|
211
|
-
# Phase 0.3: test-
|
|
212
|
-
|
|
213
|
-
if "$MICHI_CMD" phase:run test-feature test-type-selection > /dev/null 2>&1; then
|
|
214
|
-
echo_success "phase:run test-type-selection succeeded"
|
|
215
|
-
else
|
|
216
|
-
echo_error "phase:run test-type-selection failed"
|
|
217
|
-
exit 1
|
|
218
|
-
fi
|
|
219
|
-
|
|
220
|
-
# Phase 0.4: test-spec
|
|
221
|
-
echo_info "Testing phase:run test-spec"
|
|
222
|
-
if "$MICHI_CMD" phase:run test-feature test-spec > /dev/null 2>&1; then
|
|
223
|
-
echo_success "phase:run test-spec succeeded"
|
|
224
|
-
else
|
|
225
|
-
echo_error "phase:run test-spec failed"
|
|
226
|
-
exit 1
|
|
227
|
-
fi
|
|
211
|
+
# Phase 0.3-0.4: test planning is now handled by AI command /michi:test-planning
|
|
212
|
+
# (CLI commands removed)
|
|
228
213
|
|
|
229
214
|
# Phase 1: environment-setup
|
|
230
215
|
echo_info "Testing phase:run environment-setup"
|
|
@@ -260,23 +245,7 @@ echo_step "Testing Validation Commands"
|
|
|
260
245
|
|
|
261
246
|
echo_info "Testing validate:phase commands..."
|
|
262
247
|
|
|
263
|
-
# Phase 0.3
|
|
264
|
-
echo_info "Validating test-type-selection"
|
|
265
|
-
if "$MICHI_CMD" validate:phase test-feature test-type-selection > /dev/null 2>&1; then
|
|
266
|
-
echo_success "validate:phase test-type-selection succeeded"
|
|
267
|
-
else
|
|
268
|
-
echo_error "validate:phase test-type-selection failed"
|
|
269
|
-
exit 1
|
|
270
|
-
fi
|
|
271
|
-
|
|
272
|
-
# Phase 0.4
|
|
273
|
-
echo_info "Validating test-spec"
|
|
274
|
-
if "$MICHI_CMD" validate:phase test-feature test-spec > /dev/null 2>&1; then
|
|
275
|
-
echo_success "validate:phase test-spec succeeded"
|
|
276
|
-
else
|
|
277
|
-
echo_error "validate:phase test-spec failed"
|
|
278
|
-
exit 1
|
|
279
|
-
fi
|
|
248
|
+
# Phase 0.3-0.4: validation removed (test planning is now handled by AI command)
|
|
280
249
|
|
|
281
250
|
# Phase 1
|
|
282
251
|
echo_info "Validating environment-setup"
|
|
@@ -8,10 +8,7 @@ import { join } from 'path';
|
|
|
8
8
|
import {
|
|
9
9
|
extractComponents,
|
|
10
10
|
extractFlows,
|
|
11
|
-
extractRequirements
|
|
12
|
-
type Component,
|
|
13
|
-
type Flow,
|
|
14
|
-
type Requirement
|
|
11
|
+
extractRequirements
|
|
15
12
|
} from './utils/markdown-parser.js';
|
|
16
13
|
import {
|
|
17
14
|
loadTestSpecTemplate,
|
|
@@ -24,9 +21,8 @@ import {
|
|
|
24
21
|
* 単体テスト仕様書を生成
|
|
25
22
|
*/
|
|
26
23
|
export async function generateUnitTestSpec(feature: string, projectRoot: string = process.cwd()): Promise<string> {
|
|
27
|
-
const requirementsPath = join(projectRoot, '.kiro', 'specs', feature, 'requirements.md');
|
|
28
24
|
const designPath = join(projectRoot, '.kiro', 'specs', feature, 'design.md');
|
|
29
|
-
|
|
25
|
+
|
|
30
26
|
if (!existsSync(designPath)) {
|
|
31
27
|
throw new Error(`design.mdが見つかりません: ${designPath}`);
|
|
32
28
|
}
|
|
@@ -229,7 +225,7 @@ export async function generateE2ETestSpec(feature: string, projectRoot: string =
|
|
|
229
225
|
'テストユーザーが作成されている',
|
|
230
226
|
'テストデータが準備されている'
|
|
231
227
|
],
|
|
232
|
-
steps: req.acceptanceCriteria.slice(0, 3).map(
|
|
228
|
+
steps: req.acceptanceCriteria.slice(0, 3).map(ac =>
|
|
233
229
|
`${ac.substring(0, 100)}...を実行`
|
|
234
230
|
),
|
|
235
231
|
expectedResults: req.acceptanceCriteria.map(ac =>
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
loadConfig,
|
|
11
11
|
getConfig,
|
|
12
12
|
getConfigPath,
|
|
13
|
+
getGlobalEnvPath,
|
|
13
14
|
clearConfigCache
|
|
14
15
|
} from '../config-loader.js';
|
|
15
16
|
|
|
@@ -32,6 +33,9 @@ describe('config-loader', () => {
|
|
|
32
33
|
// 環境変数をバックアップ
|
|
33
34
|
originalEnv = { ...process.env };
|
|
34
35
|
|
|
36
|
+
// HOMEディレクトリをテスト用に変更(グローバル設定の影響を排除)
|
|
37
|
+
process.env.HOME = testProjectRoot;
|
|
38
|
+
|
|
35
39
|
// キャッシュをクリア(クリーンな状態から開始)
|
|
36
40
|
clearConfigCache();
|
|
37
41
|
});
|
|
@@ -250,5 +254,150 @@ describe('config-loader', () => {
|
|
|
250
254
|
consoleWarnSpy.mockRestore();
|
|
251
255
|
});
|
|
252
256
|
});
|
|
257
|
+
|
|
258
|
+
describe('5層階層対応', () => {
|
|
259
|
+
describe('getGlobalEnvPath', () => {
|
|
260
|
+
it('~/.michi/.envのパスを返す', () => {
|
|
261
|
+
const envPath = getGlobalEnvPath();
|
|
262
|
+
expect(envPath).toBe(join(process.env.HOME as string, '.michi', '.env'));
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
describe('グローバル.envからの設定読み込み', () => {
|
|
267
|
+
it('グローバル.envからAtlassian設定を読み込む', () => {
|
|
268
|
+
clearConfigCache();
|
|
269
|
+
|
|
270
|
+
// ~/.michi/.env を作成
|
|
271
|
+
const globalEnvPath = join(testProjectRoot, '.michi', '.env');
|
|
272
|
+
writeFileSync(globalEnvPath, 'ATLASSIAN_URL=https://test.atlassian.net\n');
|
|
273
|
+
|
|
274
|
+
const config = loadConfig(testProjectRoot);
|
|
275
|
+
|
|
276
|
+
// グローバル.envの値が読み込まれることを確認
|
|
277
|
+
expect(config).toHaveProperty('atlassian');
|
|
278
|
+
// 注: 実装後に具体的なアサーションを追加
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
it('グローバル.envが存在しない場合でもエラーにならない', () => {
|
|
282
|
+
clearConfigCache();
|
|
283
|
+
|
|
284
|
+
// ~/.michi/.env を削除
|
|
285
|
+
const globalEnvPath = join(testProjectRoot, '.michi', '.env');
|
|
286
|
+
if (existsSync(globalEnvPath)) {
|
|
287
|
+
unlinkSync(globalEnvPath);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
expect(() => {
|
|
291
|
+
loadConfig(testProjectRoot);
|
|
292
|
+
}).not.toThrow();
|
|
293
|
+
});
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
describe('project.jsonからの設定読み込み', () => {
|
|
297
|
+
it('project.jsonからプロジェクトメタデータを読み込む', () => {
|
|
298
|
+
clearConfigCache();
|
|
299
|
+
|
|
300
|
+
// .kiro/project.json を作成
|
|
301
|
+
const projectJsonPath = join(testProjectRoot, '.kiro', 'project.json');
|
|
302
|
+
mkdirSync(join(testProjectRoot, '.kiro'), { recursive: true });
|
|
303
|
+
writeFileSync(projectJsonPath, JSON.stringify({
|
|
304
|
+
projectId: 'test-project',
|
|
305
|
+
projectName: 'Test Project',
|
|
306
|
+
jiraProjectKey: 'TP'
|
|
307
|
+
}));
|
|
308
|
+
|
|
309
|
+
const config = loadConfig(testProjectRoot);
|
|
310
|
+
|
|
311
|
+
// project.jsonの値が読み込まれることを確認
|
|
312
|
+
expect(config).toHaveProperty('project');
|
|
313
|
+
// 注: 実装後に具体的なアサーションを追加
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
it('project.jsonが存在しない場合でもエラーにならない', () => {
|
|
317
|
+
clearConfigCache();
|
|
318
|
+
|
|
319
|
+
// .kiro/project.json を削除
|
|
320
|
+
const projectJsonPath = join(testProjectRoot, '.kiro', 'project.json');
|
|
321
|
+
if (existsSync(projectJsonPath)) {
|
|
322
|
+
unlinkSync(projectJsonPath);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
expect(() => {
|
|
326
|
+
loadConfig(testProjectRoot);
|
|
327
|
+
}).not.toThrow();
|
|
328
|
+
});
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
describe('優先順位の検証', () => {
|
|
332
|
+
it('プロジェクト.envがグローバル.envより優先される', () => {
|
|
333
|
+
clearConfigCache();
|
|
334
|
+
|
|
335
|
+
// グローバル.env
|
|
336
|
+
const globalEnvPath = join(testProjectRoot, '.michi', '.env');
|
|
337
|
+
writeFileSync(globalEnvPath, 'CONFLUENCE_PRD_SPACE=GLOBAL\n');
|
|
338
|
+
|
|
339
|
+
// プロジェクト.env
|
|
340
|
+
const projectEnvPath = join(testProjectRoot, '.env');
|
|
341
|
+
writeFileSync(projectEnvPath, 'CONFLUENCE_PRD_SPACE=PROJECT\n');
|
|
342
|
+
|
|
343
|
+
const config = loadConfig(testProjectRoot);
|
|
344
|
+
|
|
345
|
+
// プロジェクト.envの値が優先されることを確認
|
|
346
|
+
expect(config.confluence?.spaces?.requirements).toBe('PROJECT');
|
|
347
|
+
});
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
describe('キャッシュ無効化', () => {
|
|
351
|
+
it('グローバル.envを変更するとキャッシュが無効化される', async () => {
|
|
352
|
+
clearConfigCache();
|
|
353
|
+
|
|
354
|
+
// 最初の設定
|
|
355
|
+
const globalEnvPath = join(testProjectRoot, '.michi', '.env');
|
|
356
|
+
writeFileSync(globalEnvPath, 'CONFLUENCE_PRD_SPACE=INITIAL\n');
|
|
357
|
+
|
|
358
|
+
const config1 = getConfig(testProjectRoot);
|
|
359
|
+
|
|
360
|
+
// ファイルシステムのmtime精度を考慮して少し待つ
|
|
361
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
362
|
+
|
|
363
|
+
// 設定を更新
|
|
364
|
+
writeFileSync(globalEnvPath, 'CONFLUENCE_PRD_SPACE=UPDATED\n');
|
|
365
|
+
|
|
366
|
+
const config2 = getConfig(testProjectRoot);
|
|
367
|
+
|
|
368
|
+
// 異なる値が返されることを確認(キャッシュが無効化された)
|
|
369
|
+
expect(config1.confluence?.spaces?.requirements).toBe('INITIAL');
|
|
370
|
+
expect(config2.confluence?.spaces?.requirements).toBe('UPDATED');
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
it('project.jsonを変更するとキャッシュが無効化される', async () => {
|
|
374
|
+
clearConfigCache();
|
|
375
|
+
|
|
376
|
+
// 最初の設定
|
|
377
|
+
const projectJsonPath = join(testProjectRoot, '.kiro', 'project.json');
|
|
378
|
+
mkdirSync(join(testProjectRoot, '.kiro'), { recursive: true });
|
|
379
|
+
writeFileSync(projectJsonPath, JSON.stringify({
|
|
380
|
+
projectId: 'initial-id',
|
|
381
|
+
projectName: 'Initial Name'
|
|
382
|
+
}));
|
|
383
|
+
|
|
384
|
+
const config1 = getConfig(testProjectRoot);
|
|
385
|
+
|
|
386
|
+
// ファイルシステムのmtime精度を考慮して少し待つ
|
|
387
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
388
|
+
|
|
389
|
+
// 設定を更新
|
|
390
|
+
writeFileSync(projectJsonPath, JSON.stringify({
|
|
391
|
+
projectId: 'updated-id',
|
|
392
|
+
projectName: 'Updated Name'
|
|
393
|
+
}));
|
|
394
|
+
|
|
395
|
+
const config2 = getConfig(testProjectRoot);
|
|
396
|
+
|
|
397
|
+
// 異なるオブジェクトが返されることを確認(キャッシュが無効化された)
|
|
398
|
+
expect(config1).not.toBe(config2);
|
|
399
|
+
});
|
|
400
|
+
});
|
|
401
|
+
});
|
|
253
402
|
});
|
|
254
403
|
|
|
@@ -185,7 +185,6 @@ URL_WITH_PARAMS=https://example.com?param1=value1¶m2=value2
|
|
|
185
185
|
['ATLASSIAN_API_TOKEN', 'token123'],
|
|
186
186
|
['GITHUB_ORG', 'myorg'],
|
|
187
187
|
['GITHUB_TOKEN', 'ghp_xxx'],
|
|
188
|
-
['GITHUB_REPO', 'myorg/myrepo'],
|
|
189
188
|
['CONFLUENCE_PRD_SPACE', 'PRD'],
|
|
190
189
|
['CONFLUENCE_QA_SPACE', 'QA'],
|
|
191
190
|
['CONFLUENCE_RELEASE_SPACE', 'RELEASE'],
|
|
@@ -217,7 +216,6 @@ ATLASSIAN_API_TOKEN=test_token_123
|
|
|
217
216
|
# GitHub設定
|
|
218
217
|
GITHUB_ORG=testorg
|
|
219
218
|
GITHUB_TOKEN=ghp_test123
|
|
220
|
-
GITHUB_REPO=testorg/testrepo
|
|
221
219
|
|
|
222
220
|
# Confluence共有スペース
|
|
223
221
|
CONFLUENCE_PRD_SPACE=PRD
|