@sk8metal/michi-cli 0.0.3 → 0.0.5

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 (72) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +25 -25
  3. package/dist/scripts/config/config-schema.d.ts +109 -600
  4. package/dist/scripts/config/config-schema.d.ts.map +1 -1
  5. package/dist/scripts/config/config-schema.js.map +1 -1
  6. package/dist/scripts/config-interactive.d.ts +1 -1
  7. package/dist/scripts/config-interactive.d.ts.map +1 -1
  8. package/dist/scripts/config-interactive.js +7 -7
  9. package/dist/scripts/config-interactive.js.map +1 -1
  10. package/dist/scripts/confluence-sync.js +5 -5
  11. package/dist/scripts/confluence-sync.js.map +1 -1
  12. package/dist/scripts/create-project.d.ts +2 -2
  13. package/dist/scripts/create-project.js +2 -2
  14. package/dist/scripts/create-project.js.map +1 -1
  15. package/dist/scripts/jira-sync.js +8 -8
  16. package/dist/scripts/jira-sync.js.map +1 -1
  17. package/dist/scripts/markdown-to-confluence.js +1 -1
  18. package/dist/scripts/markdown-to-confluence.js.map +1 -1
  19. package/dist/scripts/multi-project-estimate.js +1 -1
  20. package/dist/scripts/phase-runner.js.map +1 -1
  21. package/dist/scripts/pre-flight-check.js +1 -1
  22. package/dist/scripts/setup-existing-project.js.map +1 -1
  23. package/dist/scripts/utils/__tests__/config-loader.test.d.ts +5 -0
  24. package/dist/scripts/utils/__tests__/config-loader.test.d.ts.map +1 -0
  25. package/dist/scripts/utils/__tests__/config-loader.test.js +201 -0
  26. package/dist/scripts/utils/__tests__/config-loader.test.js.map +1 -0
  27. package/dist/scripts/utils/__tests__/config-validator.test.js +29 -16
  28. package/dist/scripts/utils/__tests__/config-validator.test.js.map +1 -1
  29. package/dist/scripts/utils/config-loader.d.ts +4 -0
  30. package/dist/scripts/utils/config-loader.d.ts.map +1 -1
  31. package/dist/scripts/utils/config-loader.js +24 -2
  32. package/dist/scripts/utils/config-loader.js.map +1 -1
  33. package/dist/scripts/utils/config-validator.d.ts.map +1 -1
  34. package/dist/scripts/utils/config-validator.js +50 -51
  35. package/dist/scripts/utils/config-validator.js.map +1 -1
  36. package/dist/scripts/utils/confluence-hierarchy.js +7 -7
  37. package/dist/scripts/utils/confluence-hierarchy.js.map +1 -1
  38. package/dist/scripts/validate-phase.js.map +1 -1
  39. package/dist/scripts/workflow-orchestrator.js.map +1 -1
  40. package/dist/src/cli.js +2 -2
  41. package/dist/src/cli.js.map +1 -1
  42. package/dist/vitest.config.d.ts.map +1 -1
  43. package/dist/vitest.config.js +8 -4
  44. package/dist/vitest.config.js.map +1 -1
  45. package/docs/config-reference.md +76 -197
  46. package/docs/customization-guide.md +61 -9
  47. package/docs/multi-project.md +157 -25
  48. package/docs/new-project-setup.md +36 -36
  49. package/docs/quick-reference.md +23 -20
  50. package/docs/release.md +365 -0
  51. package/docs/setup.md +5 -3
  52. package/env.example +3 -1
  53. package/package.json +15 -13
  54. package/scripts/config/config-schema.ts +5 -5
  55. package/scripts/config-interactive.ts +7 -6
  56. package/scripts/confluence-sync.ts +5 -5
  57. package/scripts/create-project.ts +21 -21
  58. package/scripts/jira-sync.ts +8 -8
  59. package/scripts/markdown-to-confluence.ts +1 -1
  60. package/scripts/multi-project-estimate.ts +1 -1
  61. package/scripts/phase-runner.ts +8 -8
  62. package/scripts/pre-flight-check.ts +1 -1
  63. package/scripts/setup-existing-project.ts +9 -9
  64. package/scripts/setup-existing.sh +1 -1
  65. package/scripts/utils/__tests__/config-loader.test.ts +254 -0
  66. package/scripts/utils/__tests__/config-validator.test.ts +32 -16
  67. package/scripts/utils/config-loader.ts +30 -2
  68. package/scripts/utils/config-validator.ts +51 -50
  69. package/scripts/utils/confluence-hierarchy.ts +51 -51
  70. package/scripts/validate-phase.ts +11 -11
  71. package/scripts/workflow-orchestrator.ts +27 -27
  72. package/docs/testing.md +0 -202
@@ -5,8 +5,9 @@
5
5
  import { existsSync, readFileSync } from 'fs';
6
6
  import { resolve } from 'path';
7
7
  import { AppConfigSchema } from '../config/config-schema.js';
8
+ import type { ZodIssue } from 'zod';
8
9
  import type { AppConfig } from '../config/config-schema.js';
9
- import { getConfig } from './config-loader.js';
10
+ import { getConfig, getConfigPath } from './config-loader.js';
10
11
 
11
12
  /**
12
13
  * バリデーション結果
@@ -26,7 +27,7 @@ export function validateProjectConfig(projectRoot: string = process.cwd()): Vali
26
27
  const warnings: string[] = [];
27
28
  const info: string[] = [];
28
29
 
29
- const configPath = resolve(projectRoot, '.kiro/config.json');
30
+ const configPath = getConfigPath(projectRoot);
30
31
 
31
32
  if (!existsSync(configPath)) {
32
33
  // 設定ファイルが存在しない場合は情報メッセージ(デフォルト設定を使用)
@@ -47,8 +48,8 @@ export function validateProjectConfig(projectRoot: string = process.cwd()): Vali
47
48
  const result = AppConfigSchema.safeParse(parsed);
48
49
 
49
50
  if (!result.success) {
50
- result.error.errors.forEach(error => {
51
- const path = error.path.join('.');
51
+ result.error.issues.forEach((error: ZodIssue) => {
52
+ const path = error.path.map(String).join('.');
52
53
  errors.push(`${path}: ${error.message}`);
53
54
  });
54
55
 
@@ -183,7 +184,7 @@ export function validateForConfluenceSync(
183
184
  const info: string[] = [];
184
185
 
185
186
  const config = getConfig(projectRoot);
186
- const configPath = resolve(projectRoot, '.kiro/config.json');
187
+ const configPath = getConfigPath(projectRoot);
187
188
 
188
189
  // Confluence設定のチェック
189
190
  if (!config.confluence) {
@@ -196,15 +197,15 @@ export function validateForConfluenceSync(
196
197
  if (!process.env.CONFLUENCE_PRD_SPACE) {
197
198
  warnings.push(
198
199
  `confluence.spaces.${docType}が設定されていません。` +
199
- `環境変数CONFLUENCE_PRD_SPACEも設定されていないため、デフォルト値(PRD)を使用します。` +
200
- `\n 推奨: .kiro/config.jsonに以下を追加してください:\n` +
201
- ` {\n` +
202
- ` "confluence": {\n` +
203
- ` "spaces": {\n` +
200
+ '環境変数CONFLUENCE_PRD_SPACEも設定されていないため、デフォルト値(PRD)を使用します。' +
201
+ '\n 推奨: .michi/config.jsonに以下を追加してください:\n' +
202
+ ' {\n' +
203
+ ' "confluence": {\n' +
204
+ ' "spaces": {\n' +
204
205
  ` "${docType}": "YOUR_SPACE_KEY"\n` +
205
- ` }\n` +
206
- ` }\n` +
207
- ` }`
206
+ ' }\n' +
207
+ ' }\n' +
208
+ ' }'
208
209
  );
209
210
  } else {
210
211
  info.push(`confluence.spaces.${docType}が設定されていませんが、環境変数CONFLUENCE_PRD_SPACE(${process.env.CONFLUENCE_PRD_SPACE})を使用します。`);
@@ -215,29 +216,29 @@ export function validateForConfluenceSync(
215
216
  if (confluence.pageCreationGranularity === 'by-hierarchy' || confluence.pageCreationGranularity === 'manual') {
216
217
  if (!confluence.hierarchy) {
217
218
  errors.push(
218
- `confluence.hierarchyが設定されていません。` +
219
+ 'confluence.hierarchyが設定されていません。' +
219
220
  `pageCreationGranularityが"${confluence.pageCreationGranularity}"の場合、hierarchy設定が必須です。` +
220
- `\n 解決方法: .kiro/config.jsonに以下を追加してください:\n` +
221
- ` {\n` +
222
- ` "confluence": {\n` +
223
- ` "hierarchy": {\n` +
224
- ` "mode": "simple",\n` +
225
- ` "parentPageTitle": "[{projectName}] {featureName}"\n` +
226
- ` }\n` +
227
- ` }\n` +
228
- ` }`
221
+ '\n 解決方法: .michi/config.jsonに以下を追加してください:\n' +
222
+ ' {\n' +
223
+ ' "confluence": {\n' +
224
+ ' "hierarchy": {\n' +
225
+ ' "mode": "simple",\n' +
226
+ ' "parentPageTitle": "[{projectName}] {featureName}"\n' +
227
+ ' }\n' +
228
+ ' }\n' +
229
+ ' }'
229
230
  );
230
231
  } else if (confluence.pageCreationGranularity === 'by-hierarchy' && confluence.hierarchy && !confluence.hierarchy.parentPageTitle) {
231
232
  warnings.push(
232
- `confluence.hierarchy.parentPageTitleが設定されていません。` +
233
- `by-hierarchyモードでは推奨されます。`
233
+ 'confluence.hierarchy.parentPageTitleが設定されていません。' +
234
+ 'by-hierarchyモードでは推奨されます。'
234
235
  );
235
236
  }
236
237
 
237
238
  if (confluence.pageCreationGranularity === 'manual' && confluence.hierarchy && !confluence.hierarchy.structure) {
238
239
  errors.push(
239
- `confluence.hierarchy.structureが設定されていません。` +
240
- `pageCreationGranularityが"manual"の場合、structure設定が必須です。`
240
+ 'confluence.hierarchy.structureが設定されていません。' +
241
+ 'pageCreationGranularityが"manual"の場合、structure設定が必須です。'
241
242
  );
242
243
  }
243
244
  }
@@ -262,7 +263,7 @@ export function validateForJiraSync(projectRoot: string = process.cwd()): Valida
262
263
  const info: string[] = [];
263
264
 
264
265
  const config = getConfig(projectRoot);
265
- const configPath = resolve(projectRoot, '.kiro/config.json');
266
+ const configPath = getConfigPath(projectRoot);
266
267
 
267
268
  // JIRA設定のチェック
268
269
  if (!config.jira) {
@@ -274,20 +275,20 @@ export function validateForJiraSync(projectRoot: string = process.cwd()): Valida
274
275
  if (!jira.issueTypes) {
275
276
  if (!process.env.JIRA_ISSUE_TYPE_STORY) {
276
277
  errors.push(
277
- `jira.issueTypes.storyが設定されていません。` +
278
- `環境変数JIRA_ISSUE_TYPE_STORYも設定されていないため、JIRA同期を実行できません。` +
279
- `\n 解決方法1: 環境変数を設定:\n` +
280
- ` export JIRA_ISSUE_TYPE_STORY=10036 # JIRAインスタンス固有のID\n` +
281
- `\n 解決方法2: .kiro/config.jsonに以下を追加:\n` +
282
- ` {\n` +
283
- ` "jira": {\n` +
284
- ` "issueTypes": {\n` +
285
- ` "story": "10036",\n` +
286
- ` "subtask": "10037"\n` +
287
- ` }\n` +
288
- ` }\n` +
289
- ` }` +
290
- `\n 確認方法: JIRA管理画面(Settings > Issues > Issue types)またはREST API: GET /rest/api/3/issuetype`
278
+ 'jira.issueTypes.storyが設定されていません。' +
279
+ '環境変数JIRA_ISSUE_TYPE_STORYも設定されていないため、JIRA同期を実行できません。' +
280
+ '\n 解決方法1: 環境変数を設定:\n' +
281
+ ' export JIRA_ISSUE_TYPE_STORY=10036 # JIRAインスタンス固有のID\n' +
282
+ '\n 解決方法2: .michi/config.jsonに以下を追加:\n' +
283
+ ' {\n' +
284
+ ' "jira": {\n' +
285
+ ' "issueTypes": {\n' +
286
+ ' "story": "10036",\n' +
287
+ ' "subtask": "10037"\n' +
288
+ ' }\n' +
289
+ ' }\n' +
290
+ ' }' +
291
+ '\n 確認方法: JIRA管理画面(Settings > Issues > Issue types)またはREST API: GET /rest/api/3/issuetype'
291
292
  );
292
293
  } else {
293
294
  info.push(`jira.issueTypes.storyが設定されていませんが、環境変数JIRA_ISSUE_TYPE_STORY(${process.env.JIRA_ISSUE_TYPE_STORY})を使用します。`);
@@ -296,10 +297,10 @@ export function validateForJiraSync(projectRoot: string = process.cwd()): Valida
296
297
  if (!jira.issueTypes.story) {
297
298
  if (!process.env.JIRA_ISSUE_TYPE_STORY) {
298
299
  errors.push(
299
- `jira.issueTypes.storyが設定されていません。` +
300
- `環境変数JIRA_ISSUE_TYPE_STORYも設定されていないため、JIRA同期を実行できません。` +
301
- `\n 解決方法: .kiro/config.jsonのjira.issueTypes.storyに値を設定するか、` +
302
- `環境変数JIRA_ISSUE_TYPE_STORYを設定してください。`
300
+ 'jira.issueTypes.storyが設定されていません。' +
301
+ '環境変数JIRA_ISSUE_TYPE_STORYも設定されていないため、JIRA同期を実行できません。' +
302
+ '\n 解決方法: .michi/config.jsonのjira.issueTypes.storyに値を設定するか、' +
303
+ '環境変数JIRA_ISSUE_TYPE_STORYを設定してください。'
303
304
  );
304
305
  } else {
305
306
  info.push(`jira.issueTypes.storyが設定されていませんが、環境変数JIRA_ISSUE_TYPE_STORY(${process.env.JIRA_ISSUE_TYPE_STORY})を使用します。`);
@@ -309,8 +310,8 @@ export function validateForJiraSync(projectRoot: string = process.cwd()): Valida
309
310
  if (!jira.issueTypes.subtask) {
310
311
  if (!process.env.JIRA_ISSUE_TYPE_SUBTASK) {
311
312
  warnings.push(
312
- `jira.issueTypes.subtaskが設定されていません。` +
313
- `環境変数JIRA_ISSUE_TYPE_SUBTASKも設定されていないため、サブタスクは作成されません。`
313
+ 'jira.issueTypes.subtaskが設定されていません。' +
314
+ '環境変数JIRA_ISSUE_TYPE_SUBTASKも設定されていないため、サブタスクは作成されません。'
314
315
  );
315
316
  } else {
316
317
  info.push(`jira.issueTypes.subtaskが設定されていませんが、環境変数JIRA_ISSUE_TYPE_SUBTASK(${process.env.JIRA_ISSUE_TYPE_SUBTASK})を使用します。`);
@@ -321,8 +322,8 @@ export function validateForJiraSync(projectRoot: string = process.cwd()): Valida
321
322
  // selectedPhases設定のチェック
322
323
  if (jira.storyCreationGranularity === 'selected-phases' && !jira.selectedPhases) {
323
324
  errors.push(
324
- `jira.selectedPhasesが設定されていません。` +
325
- `storyCreationGranularityが"selected-phases"の場合、selectedPhases設定が必須です。`
325
+ 'jira.selectedPhasesが設定されていません。' +
326
+ 'storyCreationGranularityが"selected-phases"の場合、selectedPhases設定が必須です。'
326
327
  );
327
328
  }
328
329
 
@@ -401,7 +401,7 @@ export async function createByHierarchySimplePages(
401
401
 
402
402
  // タイトルに機能名が含まれていない場合、自動的に追加(重複を避けるため)
403
403
  if (!childPageTitle.includes(featureName)) {
404
- console.warn(`⚠️ Warning: pageTitleFormat does not include {featureName}. Adding feature name to ensure uniqueness.`);
404
+ console.warn('⚠️ Warning: pageTitleFormat does not include {featureName}. Adding feature name to ensure uniqueness.');
405
405
  childPageTitle = `[${featureName}] ${childPageTitle}`;
406
406
  }
407
407
 
@@ -423,7 +423,7 @@ export async function createByHierarchySimplePages(
423
423
 
424
424
  // CQLクエリで見つからない場合、親ページIDなしで検索(既存ページが別の親の下にある可能性)
425
425
  if (!existingChild) {
426
- console.log(` CQL search found nothing, trying search without parent filter`);
426
+ console.log(' CQL search found nothing, trying search without parent filter');
427
427
  existingChild = await client.searchPage(spaceKey, childPageTitle);
428
428
  if (existingChild) {
429
429
  console.log(` ⚠️ Found page with same title: ${existingChild.id}, verifying parent page ID`);
@@ -436,14 +436,14 @@ export async function createByHierarchySimplePages(
436
436
  console.log(` ✅ Parent page ID matches (${parentPageId}), proceeding with update`);
437
437
  } else {
438
438
  // 親ページIDが一致しない場合、エラーをスロー
439
- console.error(` ❌ Parent page ID mismatch!`);
439
+ console.error(' ❌ Parent page ID mismatch!');
440
440
  console.error(` Expected parent: ${parentPageId}`);
441
441
  console.error(` Actual parent: ${actualParentId || 'root (no parent)'}`);
442
442
  console.error(` Page ID: ${existingChild.id}`);
443
443
  throw new Error(
444
444
  `Page conflict: Found page "${childPageTitle}" (ID: ${existingChild.id}) ` +
445
445
  `under different parent (expected: ${parentPageId}, actual: ${actualParentId || 'root'}). ` +
446
- `Cannot update foreign page. Please rename or delete the conflicting page.`
446
+ 'Cannot update foreign page. Please rename or delete the conflicting page.'
447
447
  );
448
448
  }
449
449
  }
@@ -523,7 +523,7 @@ export async function createByHierarchyNestedPages(
523
523
 
524
524
  // タイトルに機能名が含まれていない場合、自動的に追加(重複を避けるため)
525
525
  if (!docTypeParentTitle.includes(featureName)) {
526
- console.warn(`⚠️ Warning: pageTitleFormat does not include {featureName}. Adding feature name to ensure uniqueness.`);
526
+ console.warn('⚠️ Warning: pageTitleFormat does not include {featureName}. Adding feature name to ensure uniqueness.');
527
527
  docTypeParentTitle = `[${featureName}] ${docTypeParentTitle}`;
528
528
  }
529
529
 
@@ -569,7 +569,7 @@ export async function createByHierarchyNestedPages(
569
569
 
570
570
  // タイトルに機能名が含まれていない場合、自動的に追加(重複を避けるため)
571
571
  if (!sectionPageTitle.includes(featureName)) {
572
- console.warn(`⚠️ Warning: pageTitleFormat does not include {featureName}. Adding feature name to ensure uniqueness.`);
572
+ console.warn('⚠️ Warning: pageTitleFormat does not include {featureName}. Adding feature name to ensure uniqueness.');
573
573
  sectionPageTitle = `[${featureName}] ${sectionPageTitle}`;
574
574
  }
575
575
  const confluenceContent = convertMarkdownToConfluence(section.content);
@@ -697,7 +697,7 @@ export async function createManualPages(
697
697
 
698
698
  // タイトルに機能名が含まれていない場合、自動的に追加(重複を避けるため)
699
699
  if (!pageTitle.includes(featureName)) {
700
- console.warn(`⚠️ Warning: Manual page title does not include {featureName}. Adding feature name to ensure uniqueness.`);
700
+ console.warn('⚠️ Warning: Manual page title does not include {featureName}. Adding feature name to ensure uniqueness.');
701
701
  pageTitle = `[${featureName}] ${pageTitle}`;
702
702
  }
703
703
 
@@ -785,8 +785,34 @@ export async function createPagesByGranularity(
785
785
  const granularity = config.pageCreationGranularity || 'single';
786
786
 
787
787
  switch (granularity) {
788
- case 'single':
789
- return await createSinglePage(
788
+ case 'single':
789
+ return await createSinglePage(
790
+ client,
791
+ spaceKey,
792
+ markdown,
793
+ config,
794
+ projectMeta,
795
+ featureName,
796
+ docType,
797
+ githubUrl
798
+ );
799
+
800
+ case 'by-section':
801
+ return await createBySectionPages(
802
+ client,
803
+ spaceKey,
804
+ markdown,
805
+ config,
806
+ projectMeta,
807
+ featureName,
808
+ docType,
809
+ githubUrl
810
+ );
811
+
812
+ case 'by-hierarchy': {
813
+ const hierarchyMode = config.hierarchy?.mode || 'simple';
814
+ if (hierarchyMode === 'nested') {
815
+ return await createByHierarchyNestedPages(
790
816
  client,
791
817
  spaceKey,
792
818
  markdown,
@@ -796,9 +822,8 @@ export async function createPagesByGranularity(
796
822
  docType,
797
823
  githubUrl
798
824
  );
799
-
800
- case 'by-section':
801
- return await createBySectionPages(
825
+ } else {
826
+ return await createByHierarchySimplePages(
802
827
  client,
803
828
  spaceKey,
804
829
  markdown,
@@ -808,48 +833,23 @@ export async function createPagesByGranularity(
808
833
  docType,
809
834
  githubUrl
810
835
  );
811
-
812
- case 'by-hierarchy': {
813
- const hierarchyMode = config.hierarchy?.mode || 'simple';
814
- if (hierarchyMode === 'nested') {
815
- return await createByHierarchyNestedPages(
816
- client,
817
- spaceKey,
818
- markdown,
819
- config,
820
- projectMeta,
821
- featureName,
822
- docType,
823
- githubUrl
824
- );
825
- } else {
826
- return await createByHierarchySimplePages(
827
- client,
828
- spaceKey,
829
- markdown,
830
- config,
831
- projectMeta,
832
- featureName,
833
- docType,
834
- githubUrl
835
- );
836
- }
837
836
  }
837
+ }
838
838
 
839
- case 'manual':
840
- return await createManualPages(
841
- client,
842
- spaceKey,
843
- markdown,
844
- config,
845
- projectMeta,
846
- featureName,
847
- docType,
848
- githubUrl
849
- );
839
+ case 'manual':
840
+ return await createManualPages(
841
+ client,
842
+ spaceKey,
843
+ markdown,
844
+ config,
845
+ projectMeta,
846
+ featureName,
847
+ docType,
848
+ githubUrl
849
+ );
850
850
 
851
- default:
852
- throw new Error(`Unknown page creation granularity: ${granularity}`);
851
+ default:
852
+ throw new Error(`Unknown page creation granularity: ${granularity}`);
853
853
  }
854
854
  }
855
855
 
@@ -215,17 +215,17 @@ export function validatePhase(feature: string, phase: Phase): ValidationResult {
215
215
  let result: ValidationResult;
216
216
 
217
217
  switch (phase) {
218
- case 'requirements':
219
- result = validateRequirements(feature);
220
- break;
221
- case 'design':
222
- result = validateDesign(feature);
223
- break;
224
- case 'tasks':
225
- result = validateTasks(feature);
226
- break;
227
- default:
228
- throw new Error(`Unknown phase: ${phase}`);
218
+ case 'requirements':
219
+ result = validateRequirements(feature);
220
+ break;
221
+ case 'design':
222
+ result = validateDesign(feature);
223
+ break;
224
+ case 'tasks':
225
+ result = validateTasks(feature);
226
+ break;
227
+ default:
228
+ throw new Error(`Unknown phase: ${phase}`);
229
229
  }
230
230
 
231
231
  // 結果表示
@@ -72,35 +72,35 @@ export class WorkflowOrchestrator {
72
72
  */
73
73
  private async executeStage(stage: WorkflowStage): Promise<void> {
74
74
  switch (stage) {
75
- case 'requirements':
76
- console.log(' Syncing requirements to Confluence...');
77
- await syncToConfluence(this.config.feature, 'requirements');
78
- break;
75
+ case 'requirements':
76
+ console.log(' Syncing requirements to Confluence...');
77
+ await syncToConfluence(this.config.feature, 'requirements');
78
+ break;
79
79
 
80
- case 'design':
81
- console.log(' Syncing design to Confluence...');
82
- await syncToConfluence(this.config.feature, 'design');
83
- break;
80
+ case 'design':
81
+ console.log(' Syncing design to Confluence...');
82
+ await syncToConfluence(this.config.feature, 'design');
83
+ break;
84
84
 
85
- case 'tasks':
86
- console.log(' Creating JIRA tasks...');
87
- await syncTasksToJIRA(this.config.feature);
88
- break;
85
+ case 'tasks':
86
+ console.log(' Creating JIRA tasks...');
87
+ await syncTasksToJIRA(this.config.feature);
88
+ break;
89
89
 
90
- case 'implement':
91
- console.log(' Implementation phase - manual step');
92
- console.log(' Use: /kiro:spec-impl <feature> <tasks>');
93
- break;
90
+ case 'implement':
91
+ console.log(' Implementation phase - manual step');
92
+ console.log(' Use: /kiro:spec-impl <feature> <tasks>');
93
+ break;
94
94
 
95
- case 'test':
96
- console.log(' Test phase - execute tests');
97
- // TODO: テスト実行とレポート生成
98
- break;
95
+ case 'test':
96
+ console.log(' Test phase - execute tests');
97
+ // TODO: テスト実行とレポート生成
98
+ break;
99
99
 
100
- case 'release':
101
- console.log(' Release preparation');
102
- // TODO: リリースノート生成とJIRA Release作成
103
- break;
100
+ case 'release':
101
+ console.log(' Release preparation');
102
+ // TODO: リリースノート生成とJIRA Release作成
103
+ break;
104
104
  }
105
105
  }
106
106
 
@@ -113,9 +113,9 @@ export class WorkflowOrchestrator {
113
113
 
114
114
  const gateList =
115
115
  stage === 'requirements' ? gates.requirements :
116
- stage === 'design' ? gates.design :
117
- stage === 'release' ? gates.release :
118
- undefined;
116
+ stage === 'design' ? gates.design :
117
+ stage === 'release' ? gates.release :
118
+ undefined;
119
119
 
120
120
  return Array.isArray(gateList) && gateList.length > 0;
121
121
  }
package/docs/testing.md DELETED
@@ -1,202 +0,0 @@
1
- # テスト・検証ガイド
2
-
3
- > **凡例について**: `<feature>` などの記号の意味は [README.md#凡例の記号説明](../README.md#凡例の記号説明) を参照してください。
4
-
5
- ## E2Eテストシナリオ
6
-
7
- ### シナリオ1: 単一機能の完全フロー
8
-
9
- 新機能「ユーザー認証」を要件定義からリリースまで実行:
10
-
11
- #### Step 1: 要件定義
12
- ```bash
13
- # 凡例
14
- /kiro:spec-init <機能説明>
15
- /kiro:spec-requirements <feature>
16
- jj commit -m "docs: <feature> 要件定義"
17
- jj git push
18
- npm run confluence:sync <feature> requirements
19
-
20
- # 具体例
21
- /kiro:spec-init OAuth 2.0を使ったユーザー認証機能
22
- /kiro:spec-requirements user-auth
23
- jj commit -m "docs: ユーザー認証 要件定義"
24
- jj git push
25
- npm run confluence:sync user-auth requirements
26
- ```
27
-
28
- **確認ポイント**:
29
- - [ ] `.kiro/specs/user-auth/requirements.md` が生成された
30
- - [ ] Confluenceページが作成された
31
- - [ ] ラベル `project:michi, requirements, user-auth` が付与された
32
- - [ ] 企画・部長にメンション通知が届いた
33
-
34
- #### Step 2: 設計
35
- ```bash
36
- # 凡例
37
- /kiro:spec-design <feature>
38
- jj commit -m "docs: <feature> 設計"
39
- jj git push
40
- npm run confluence:sync <feature> design
41
- npm run excel:sync <feature>
42
-
43
- # 具体例
44
- /kiro:spec-design user-auth
45
- jj commit -m "docs: ユーザー認証 設計"
46
- jj git push
47
- npm run confluence:sync user-auth design
48
- npm run excel:sync user-auth
49
- ```
50
-
51
- **確認ポイント**:
52
- - [ ] `.kiro/specs/user-auth/design.md` が生成された
53
- - [ ] 見積もりセクションが含まれている
54
- - [ ] Confluenceページが作成された(親: 要件定義)
55
- - [ ] Excelファイルが出力された
56
-
57
- #### Step 3: タスク分割
58
- ```bash
59
- # 凡例
60
- /kiro:spec-tasks <feature>
61
- jj commit -m "docs: <feature> タスク分割"
62
- jj git push
63
- npm run jira:sync <feature>
64
-
65
- # 具体例
66
- /kiro:spec-tasks user-auth
67
- jj commit -m "docs: ユーザー認証 タスク分割"
68
- jj git push
69
- npm run jira:sync user-auth
70
- ```
71
-
72
- **確認ポイント**:
73
- - [ ] `.kiro/specs/user-auth/tasks.md` が生成された
74
- - [ ] JIRA Epicが作成された
75
- - [ ] JIRA Storyが作成された(複数)
76
- - [ ] Epic-Storyリンクが設定された
77
-
78
- #### Step 4: 実装
79
- ```
80
- /kiro:spec-impl user-auth FE-1,BE-1
81
- jj commit -m "feat: ユーザー認証実装 [MICHI-123]"
82
- jj bookmark create michi/feature/user-auth -r '@-'
83
- jj git push --bookmark michi/feature/user-auth --allow-new
84
- npm run github:create-pr michi/feature/user-auth
85
- ```
86
-
87
- **確認ポイント**:
88
- - [ ] テストが先に書かれた(TDD)
89
- - [ ] コードが実装された
90
- - [ ] PRが作成された
91
- - [ ] JIRA ステータスが "In Review" に更新された
92
-
93
- ### シナリオ2: マルチプロジェクト横断テスト
94
-
95
- 3つのプロジェクトで同時に要件定義を実施:
96
-
97
- ```bash
98
- # プロジェクトA
99
- cd customer-a-service-1
100
- /kiro:spec-requirements payment-feature
101
- npm run confluence:sync payment-feature
102
-
103
- # プロジェクトB
104
- cd ../customer-b-api
105
- /kiro:spec-requirements user-api
106
- npm run confluence:sync user-api
107
-
108
- # プロジェクトC(Michi)
109
- cd ../michi
110
- /kiro:spec-requirements integration-hub
111
- npm run confluence:sync integration-hub
112
-
113
- # 横断確認
114
- npm run project:list
115
- npm run project:dashboard
116
- ```
117
-
118
- **確認ポイント**:
119
- - [ ] 3つのプロジェクトすべてでページ作成成功
120
- - [ ] Confluenceダッシュボードに3プロジェクト表示
121
- - [ ] ラベルでフィルタリング可能
122
- - [ ] JIRAダッシュボードに3プロジェクト表示
123
-
124
- ## チームフィードバック収集
125
-
126
- ### フィードバック項目
127
-
128
- #### 使いやすさ
129
- - [ ] Cursorコマンドは直感的か?
130
- - [ ] ドキュメントは理解しやすいか?
131
- - [ ] エラーメッセージは明確か?
132
-
133
- #### 効率性
134
- - [ ] 要件定義の時間短縮できたか?
135
- - [ ] Confluence/JIRA連携は手間を減らしたか?
136
- - [ ] 全体の開発スピードは向上したか?
137
-
138
- #### 品質
139
- - [ ] AIが生成する仕様書の品質は十分か?
140
- - [ ] テンプレートは実務に適しているか?
141
- - [ ] 見積もりの精度は妥当か?
142
-
143
- ### フィードバック方法
144
-
145
- GitHub Issuesで収集:
146
- ```bash
147
- gh issue create --title "フィードバック: <内容>" --body "<詳細>"
148
- ```
149
-
150
- ラベル:
151
- - `feedback:usability`: 使いやすさ
152
- - `feedback:efficiency`: 効率性
153
- - `feedback:quality`: 品質
154
-
155
- ## 継続的改善
156
-
157
- ### Week 1-2: パイロット運用
158
- - 1プロジェクトで全フロー実行
159
- - 問題点を記録
160
- - フィードバック収集
161
-
162
- ### Week 3-4: 改善
163
- - テンプレート調整
164
- - スクリプト改善
165
- - ドキュメント更新
166
-
167
- ### Week 5-6: 横展開
168
- - 2-3プロジェクトに展開
169
- - チーム全体でフィードバック
170
-
171
- ### Week 7-8: 最適化
172
- - ベストプラクティス確立
173
- - 自動化範囲の拡大
174
- - ツールの安定化
175
-
176
- ## メトリクス
177
-
178
- ### 効率化指標
179
-
180
- | 指標 | 導入前 | 導入後 | 改善率 |
181
- |------|--------|--------|--------|
182
- | 要件定義時間 | 3日 | 0.5日 | 83% |
183
- | 設計時間 | 5日 | 1日 | 80% |
184
- | タスク分割時間 | 2日 | 0.5日 | 75% |
185
- | ドキュメント作成 | 2日 | 0.2日 | 90% |
186
-
187
- ### 品質指標
188
-
189
- | 指標 | 目標値 | 測定方法 |
190
- |------|--------|---------|
191
- | 仕様書の完成度 | 90%以上 | レビュースコア |
192
- | 見積もり精度 | ±20%以内 | 実績との比較 |
193
- | テストカバレッジ | 95%以上 | 自動測定 |
194
-
195
- ## 次のステップ
196
-
197
- 1. パイロットプロジェクトでE2Eテスト実行
198
- 2. フィードバック収集
199
- 3. 改善実施
200
- 4. 他プロジェクトに横展開
201
- 5. ベストプラクティス確立
202
-