@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.
Files changed (237) hide show
  1. package/CHANGELOG.md +83 -0
  2. package/dist/scripts/__tests__/spec-impl-workflow.test.js +4 -2
  3. package/dist/scripts/__tests__/spec-impl-workflow.test.js.map +1 -1
  4. package/dist/scripts/config/config-schema.d.ts +52 -0
  5. package/dist/scripts/config/config-schema.d.ts.map +1 -1
  6. package/dist/scripts/config/config-schema.js +25 -0
  7. package/dist/scripts/config/config-schema.js.map +1 -1
  8. package/dist/scripts/config-global.d.ts +10 -0
  9. package/dist/scripts/config-global.d.ts.map +1 -0
  10. package/dist/scripts/config-global.js +111 -0
  11. package/dist/scripts/config-global.js.map +1 -0
  12. package/dist/scripts/confluence-sync.d.ts +22 -4
  13. package/dist/scripts/confluence-sync.d.ts.map +1 -1
  14. package/dist/scripts/confluence-sync.js +22 -12
  15. package/dist/scripts/confluence-sync.js.map +1 -1
  16. package/dist/scripts/jira-sync.d.ts.map +1 -1
  17. package/dist/scripts/jira-sync.js +201 -167
  18. package/dist/scripts/jira-sync.js.map +1 -1
  19. package/dist/scripts/list-projects.js.map +1 -1
  20. package/dist/scripts/multi-project-estimate.js.map +1 -1
  21. package/dist/scripts/phase-runner.d.ts +1 -1
  22. package/dist/scripts/phase-runner.d.ts.map +1 -1
  23. package/dist/scripts/phase-runner.js +295 -522
  24. package/dist/scripts/phase-runner.js.map +1 -1
  25. package/dist/scripts/pr-automation.d.ts.map +1 -1
  26. package/dist/scripts/pr-automation.js +11 -3
  27. package/dist/scripts/pr-automation.js.map +1 -1
  28. package/dist/scripts/pre-flight-check.d.ts.map +1 -1
  29. package/dist/scripts/pre-flight-check.js +10 -6
  30. package/dist/scripts/pre-flight-check.js.map +1 -1
  31. package/dist/scripts/resource-dashboard.js.map +1 -1
  32. package/dist/scripts/spec-impl-workflow.d.ts.map +1 -1
  33. package/dist/scripts/spec-impl-workflow.js +23 -7
  34. package/dist/scripts/spec-impl-workflow.js.map +1 -1
  35. package/dist/scripts/template/renderer.d.ts +1 -1
  36. package/dist/scripts/template/renderer.d.ts.map +1 -1
  37. package/dist/scripts/test-interactive.d.ts.map +1 -1
  38. package/dist/scripts/test-interactive.js +0 -15
  39. package/dist/scripts/test-interactive.js.map +1 -1
  40. package/dist/scripts/test-new-features.js +6 -3
  41. package/dist/scripts/test-new-features.js.map +1 -1
  42. package/dist/scripts/test-spec-generator.d.ts.map +1 -1
  43. package/dist/scripts/test-spec-generator.js +1 -2
  44. package/dist/scripts/test-spec-generator.js.map +1 -1
  45. package/dist/scripts/utils/__tests__/config-loader.test.js +114 -1
  46. package/dist/scripts/utils/__tests__/config-loader.test.js.map +1 -1
  47. package/dist/scripts/utils/__tests__/config-validator.test.js +2 -0
  48. package/dist/scripts/utils/__tests__/config-validator.test.js.map +1 -1
  49. package/dist/scripts/utils/__tests__/env-config.test.js +0 -2
  50. package/dist/scripts/utils/__tests__/env-config.test.js.map +1 -1
  51. package/dist/scripts/utils/__tests__/project-meta.test.d.ts +6 -0
  52. package/dist/scripts/utils/__tests__/project-meta.test.d.ts.map +1 -0
  53. package/dist/scripts/utils/__tests__/project-meta.test.js +154 -0
  54. package/dist/scripts/utils/__tests__/project-meta.test.js.map +1 -0
  55. package/dist/scripts/utils/__tests__/security-validator.test.d.ts +6 -0
  56. package/dist/scripts/utils/__tests__/security-validator.test.d.ts.map +1 -0
  57. package/dist/scripts/utils/__tests__/security-validator.test.js +219 -0
  58. package/dist/scripts/utils/__tests__/security-validator.test.js.map +1 -0
  59. package/dist/scripts/utils/config-loader.d.ts +14 -3
  60. package/dist/scripts/utils/config-loader.d.ts.map +1 -1
  61. package/dist/scripts/utils/config-loader.js +284 -46
  62. package/dist/scripts/utils/config-loader.js.map +1 -1
  63. package/dist/scripts/utils/config-sections.d.ts +54 -0
  64. package/dist/scripts/utils/config-sections.d.ts.map +1 -0
  65. package/dist/scripts/utils/config-sections.js +178 -0
  66. package/dist/scripts/utils/config-sections.js.map +1 -0
  67. package/dist/scripts/utils/config-validator.d.ts +4 -0
  68. package/dist/scripts/utils/config-validator.d.ts.map +1 -1
  69. package/dist/scripts/utils/config-validator.js +57 -1
  70. package/dist/scripts/utils/config-validator.js.map +1 -1
  71. package/dist/scripts/utils/confluence-approval.d.ts.map +1 -1
  72. package/dist/scripts/utils/confluence-approval.js +5 -3
  73. package/dist/scripts/utils/confluence-approval.js.map +1 -1
  74. package/dist/scripts/utils/confluence-hierarchy.d.ts.map +1 -1
  75. package/dist/scripts/utils/confluence-hierarchy.js.map +1 -1
  76. package/dist/scripts/utils/env-config.d.ts +1 -1
  77. package/dist/scripts/utils/env-config.d.ts.map +1 -1
  78. package/dist/scripts/utils/env-config.js +2 -14
  79. package/dist/scripts/utils/env-config.js.map +1 -1
  80. package/dist/scripts/utils/interactive-helpers.d.ts +32 -0
  81. package/dist/scripts/utils/interactive-helpers.d.ts.map +1 -0
  82. package/dist/scripts/utils/interactive-helpers.js +92 -0
  83. package/dist/scripts/utils/interactive-helpers.js.map +1 -0
  84. package/dist/scripts/utils/jira-issue-type-fetcher.d.ts.map +1 -1
  85. package/dist/scripts/utils/jira-issue-type-fetcher.js +27 -18
  86. package/dist/scripts/utils/jira-issue-type-fetcher.js.map +1 -1
  87. package/dist/scripts/utils/project-meta.d.ts +9 -0
  88. package/dist/scripts/utils/project-meta.d.ts.map +1 -1
  89. package/dist/scripts/utils/project-meta.js +22 -0
  90. package/dist/scripts/utils/project-meta.js.map +1 -1
  91. package/dist/scripts/utils/release-notes-generator.d.ts.map +1 -1
  92. package/dist/scripts/utils/release-notes-generator.js +2 -1
  93. package/dist/scripts/utils/release-notes-generator.js.map +1 -1
  94. package/dist/scripts/utils/security-validator.d.ts +55 -0
  95. package/dist/scripts/utils/security-validator.d.ts.map +1 -0
  96. package/dist/scripts/utils/security-validator.js +232 -0
  97. package/dist/scripts/utils/security-validator.js.map +1 -0
  98. package/dist/scripts/utils/spec-updater.d.ts +19 -0
  99. package/dist/scripts/utils/spec-updater.d.ts.map +1 -1
  100. package/dist/scripts/utils/spec-updater.js.map +1 -1
  101. package/dist/scripts/utils/tasks-converter.d.ts.map +1 -1
  102. package/dist/scripts/utils/tasks-converter.js +2 -2
  103. package/dist/scripts/utils/tasks-converter.js.map +1 -1
  104. package/dist/scripts/utils/tasks-format-validator.d.ts.map +1 -1
  105. package/dist/scripts/utils/tasks-format-validator.js +0 -12
  106. package/dist/scripts/utils/tasks-format-validator.js.map +1 -1
  107. package/dist/scripts/utils/test-runner.d.ts.map +1 -1
  108. package/dist/scripts/utils/test-runner.js +3 -2
  109. package/dist/scripts/utils/test-runner.js.map +1 -1
  110. package/dist/scripts/validate-phase.d.ts +1 -1
  111. package/dist/scripts/validate-phase.d.ts.map +1 -1
  112. package/dist/scripts/validate-phase.js +12 -62
  113. package/dist/scripts/validate-phase.js.map +1 -1
  114. package/dist/scripts/workflow-orchestrator.d.ts.map +1 -1
  115. package/dist/scripts/workflow-orchestrator.js +11 -16
  116. package/dist/scripts/workflow-orchestrator.js.map +1 -1
  117. package/dist/src/__tests__/integration/setup/init.test.d.ts +5 -0
  118. package/dist/src/__tests__/integration/setup/init.test.d.ts.map +1 -0
  119. package/dist/src/__tests__/integration/setup/init.test.js +352 -0
  120. package/dist/src/__tests__/integration/setup/init.test.js.map +1 -0
  121. package/dist/src/cli.d.ts.map +1 -1
  122. package/dist/src/cli.js +67 -21
  123. package/dist/src/cli.js.map +1 -1
  124. package/dist/src/commands/__tests__/init.test.d.ts +5 -0
  125. package/dist/src/commands/__tests__/init.test.d.ts.map +1 -0
  126. package/dist/src/commands/__tests__/init.test.js +255 -0
  127. package/dist/src/commands/__tests__/init.test.js.map +1 -0
  128. package/dist/src/commands/__tests__/migrate.test.d.ts +5 -0
  129. package/dist/src/commands/__tests__/migrate.test.d.ts.map +1 -0
  130. package/dist/src/commands/__tests__/migrate.test.js +216 -0
  131. package/dist/src/commands/__tests__/migrate.test.js.map +1 -0
  132. package/dist/src/commands/config-validate.d.ts +9 -0
  133. package/dist/src/commands/config-validate.d.ts.map +1 -0
  134. package/dist/src/commands/config-validate.js +90 -0
  135. package/dist/src/commands/config-validate.js.map +1 -0
  136. package/dist/src/commands/init.d.ts +29 -0
  137. package/dist/src/commands/init.d.ts.map +1 -0
  138. package/dist/src/commands/init.js +513 -0
  139. package/dist/src/commands/init.js.map +1 -0
  140. package/dist/src/commands/migrate.d.ts +25 -0
  141. package/dist/src/commands/migrate.d.ts.map +1 -0
  142. package/dist/src/commands/migrate.js +341 -0
  143. package/dist/src/commands/migrate.js.map +1 -0
  144. package/dist/src/commands/setup-existing.d.ts.map +1 -1
  145. package/dist/src/commands/setup-existing.js +0 -1
  146. package/dist/src/commands/setup-existing.js.map +1 -1
  147. package/dist/vitest.config.d.ts.map +1 -1
  148. package/dist/vitest.config.js +32 -8
  149. package/dist/vitest.config.js.map +1 -1
  150. package/docs/michi-development/design/config-unification.md +4789 -0
  151. package/docs/user-guide/getting-started/github-token-setup.md +2 -1
  152. package/docs/user-guide/getting-started/new-repository-setup.md +1 -1
  153. package/docs/user-guide/getting-started/quick-start.md +1 -1
  154. package/docs/user-guide/getting-started/setup.md +35 -14
  155. package/docs/user-guide/guides/customization.md +64 -11
  156. package/docs/user-guide/guides/workflow.md +35 -21
  157. package/docs/user-guide/hands-on/claude-agent-setup.md +2 -2
  158. package/docs/user-guide/hands-on/claude-setup.md +2 -2
  159. package/docs/user-guide/hands-on/cursor-setup.md +2 -2
  160. package/docs/user-guide/hands-on/workflow-walkthrough.md +4 -1
  161. package/docs/user-guide/reference/config.md +30 -5
  162. package/docs/user-guide/reference/quick-reference.md +68 -74
  163. package/docs/user-guide/testing/test-planning-flow.md +4 -0
  164. package/env.example +1 -1
  165. package/package.json +3 -5
  166. package/scripts/__tests__/spec-impl-workflow.test.ts +5 -2
  167. package/scripts/config/config-schema.ts +40 -0
  168. package/scripts/config-global.ts +160 -0
  169. package/scripts/confluence-sync.ts +91 -27
  170. package/scripts/jira-sync.ts +284 -218
  171. package/scripts/list-projects.ts +2 -2
  172. package/scripts/multi-project-estimate.ts +3 -3
  173. package/scripts/phase-runner.ts +391 -594
  174. package/scripts/pr-automation.ts +15 -5
  175. package/scripts/pre-flight-check.ts +20 -9
  176. package/scripts/pre-publish-check.sh +3 -34
  177. package/scripts/resource-dashboard.ts +4 -4
  178. package/scripts/spec-impl-workflow.ts +23 -7
  179. package/scripts/template/renderer.ts +1 -1
  180. package/scripts/test-interactive.ts +0 -19
  181. package/scripts/test-new-features.ts +10 -7
  182. package/scripts/test-npm-package.sh +3 -34
  183. package/scripts/test-spec-generator.ts +3 -7
  184. package/scripts/utils/__tests__/config-loader.test.ts +149 -0
  185. package/scripts/utils/__tests__/config-validator.test.ts +2 -0
  186. package/scripts/utils/__tests__/env-config.test.ts +0 -2
  187. package/scripts/utils/__tests__/project-meta.test.ts +192 -0
  188. package/scripts/utils/__tests__/security-validator.test.ts +272 -0
  189. package/scripts/utils/config-loader.ts +328 -68
  190. package/scripts/utils/config-sections.ts +316 -0
  191. package/scripts/utils/config-validator.ts +66 -1
  192. package/scripts/utils/confluence-approval.ts +8 -6
  193. package/scripts/utils/confluence-hierarchy.ts +27 -27
  194. package/scripts/utils/env-config.ts +2 -14
  195. package/scripts/utils/interactive-helpers.ts +135 -0
  196. package/scripts/utils/jira-issue-type-fetcher.ts +29 -21
  197. package/scripts/utils/project-meta.ts +27 -0
  198. package/scripts/utils/release-notes-generator.ts +3 -2
  199. package/scripts/utils/security-validator.ts +286 -0
  200. package/scripts/utils/spec-updater.ts +37 -15
  201. package/scripts/utils/tasks-converter.ts +4 -6
  202. package/scripts/utils/tasks-format-validator.ts +0 -13
  203. package/scripts/utils/test-runner.ts +4 -3
  204. package/scripts/validate-phase.ts +21 -80
  205. package/scripts/workflow-orchestrator.ts +16 -25
  206. package/templates/claude/commands/kiro/kiro-spec-impl.md +5 -1
  207. package/templates/claude/commands/kiro/kiro-spec-tasks.md +3 -1
  208. package/templates/claude/commands/michi/confluence-sync.md +8 -2
  209. package/templates/claude/commands/michi/design-review.md +4 -0
  210. package/templates/claude/commands/michi/e2e-plan.md +4 -0
  211. package/templates/claude/commands/michi/license-check.md +4 -0
  212. package/templates/claude/commands/michi/pr-resolve.md +4 -0
  213. package/templates/claude/commands/michi/project-switch.md +8 -2
  214. package/templates/claude/commands/michi/spec-design.md +78 -0
  215. package/templates/claude/commands/michi/spec-impl.md +716 -0
  216. package/templates/claude/commands/michi/test-planning.md +174 -0
  217. package/templates/claude/commands/michi/validate-design.md +58 -0
  218. package/templates/claude/commands/michi/version-audit.md +4 -0
  219. package/templates/claude-agent/commands/kiro/kiro-spec-impl.md +1 -1
  220. package/templates/cursor/commands/kiro/kiro-spec-impl.md +1 -1
  221. package/templates/michi/cc-sdd-overrides/README.md +8 -0
  222. package/templates/michi/cc-sdd-overrides/settings/rules/design-review-michi.md +53 -0
  223. package/dist/scripts/config-interactive.d.ts +0 -10
  224. package/dist/scripts/config-interactive.d.ts.map +0 -1
  225. package/dist/scripts/config-interactive.js +0 -372
  226. package/dist/scripts/config-interactive.js.map +0 -1
  227. package/dist/scripts/setup-existing-project.d.ts +0 -15
  228. package/dist/scripts/setup-existing-project.d.ts.map +0 -1
  229. package/dist/scripts/setup-existing-project.js +0 -455
  230. package/dist/scripts/setup-existing-project.js.map +0 -1
  231. package/dist/scripts/setup-interactive.d.ts +0 -10
  232. package/dist/scripts/setup-interactive.d.ts.map +0 -1
  233. package/dist/scripts/setup-interactive.js +0 -413
  234. package/dist/scripts/setup-interactive.js.map +0 -1
  235. package/scripts/config-interactive.ts +0 -550
  236. package/scripts/setup-existing-project.ts +0 -585
  237. package/scripts/setup-interactive.ts +0 -565
@@ -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
- const repo = process.env.GITHUB_REPO;
20
-
21
- if (!token || !repo) {
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: any;
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: any) {
129
- if (error.response?.status === 404) {
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
- warnings.push(`⚠️ Confluenceスペースチェック失敗: ${error.message}`);
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: any) {
173
- if (error.response?.status === 404) {
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
- warnings.push(`⚠️ JIRAプロジェクトチェック失敗: ${error.message}`);
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
- echo_info "Testing Phase 0.3: test-type-selection"
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 any).name}/.kiro/project.json`
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.number
157
+ existingPage.version!.number
158
158
  );
159
159
  const baseUrl = process.env.ATLASSIAN_URL || '';
160
- pageUrl = `${baseUrl}/wiki${updated._links.webui}`;
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.webui}`;
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 || !repo) {
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
- 'Missing GitHub credentials. Required: GITHUB_TOKEN, GITHUB_REPO',
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 (error) {
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 || !repo) {
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
- 'Missing GitHub credentials. Required: GITHUB_TOKEN, GITHUB_REPO',
417
+ `Failed to get repository info from .kiro/project.json: ${error instanceof Error ? error.message : error}`,
402
418
  );
403
419
  }
404
420
 
@@ -80,7 +80,7 @@ export const renderTemplate = (
80
80
  * // Result: { lang: "ja", dir: ".kiro" }
81
81
  * ```
82
82
  */
83
- export const renderJsonTemplate = <T = any>(
83
+ export const renderJsonTemplate = <T = unknown>(
84
84
  template: string,
85
85
  context: TemplateContext
86
86
  ): T => {
@@ -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 { createReleaseNotes, getCommits, generateReleaseNotes, formatReleaseNotes } from './utils/release-notes-generator.js';
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: any) {
36
- console.error('❌ テストランナーエラー:', error.message);
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: any) {
78
- console.error('❌ リリースノート生成エラー:', error.message);
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: any) {
127
- console.error('❌ Confluence承認状態確認エラー:', error.message);
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-type-selection
212
- echo_info "Testing phase:run test-type-selection"
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((ac, idx) =>
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
 
@@ -393,6 +393,8 @@ describe('config-validator', () => {
393
393
  writeFileSync(
394
394
  projectJsonPath,
395
395
  JSON.stringify({
396
+ projectId: 'test-project',
397
+ projectName: 'Test Project',
396
398
  jiraProjectKey: 'TEST',
397
399
  }),
398
400
  );
@@ -185,7 +185,6 @@ URL_WITH_PARAMS=https://example.com?param1=value1&param2=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