@sk8metal/michi-cli 0.0.8 → 0.0.9

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 (104) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +202 -9
  3. package/dist/scripts/__tests__/setup-existing-project.test.js +67 -5
  4. package/dist/scripts/__tests__/setup-existing-project.test.js.map +1 -1
  5. package/dist/scripts/constants/__tests__/environments.test.d.ts +2 -0
  6. package/dist/scripts/constants/__tests__/environments.test.d.ts.map +1 -0
  7. package/dist/scripts/constants/__tests__/environments.test.js +91 -0
  8. package/dist/scripts/constants/__tests__/environments.test.js.map +1 -0
  9. package/dist/scripts/constants/__tests__/languages.test.d.ts +2 -0
  10. package/dist/scripts/constants/__tests__/languages.test.d.ts.map +1 -0
  11. package/dist/scripts/constants/__tests__/languages.test.js +82 -0
  12. package/dist/scripts/constants/__tests__/languages.test.js.map +1 -0
  13. package/dist/scripts/constants/environments.d.ts +33 -0
  14. package/dist/scripts/constants/environments.d.ts.map +1 -0
  15. package/dist/scripts/constants/environments.js +49 -0
  16. package/dist/scripts/constants/environments.js.map +1 -0
  17. package/dist/scripts/constants/languages.d.ts +23 -0
  18. package/dist/scripts/constants/languages.d.ts.map +1 -0
  19. package/dist/scripts/constants/languages.js +53 -0
  20. package/dist/scripts/constants/languages.js.map +1 -0
  21. package/dist/scripts/create-project.d.ts +4 -0
  22. package/dist/scripts/create-project.d.ts.map +1 -1
  23. package/dist/scripts/create-project.js +51 -22
  24. package/dist/scripts/create-project.js.map +1 -1
  25. package/dist/scripts/setup-existing-project.d.ts +3 -1
  26. package/dist/scripts/setup-existing-project.d.ts.map +1 -1
  27. package/dist/scripts/setup-existing-project.js +110 -55
  28. package/dist/scripts/setup-existing-project.js.map +1 -1
  29. package/dist/scripts/template/__tests__/renderer.test.d.ts +2 -0
  30. package/dist/scripts/template/__tests__/renderer.test.d.ts.map +1 -0
  31. package/dist/scripts/template/__tests__/renderer.test.js +165 -0
  32. package/dist/scripts/template/__tests__/renderer.test.js.map +1 -0
  33. package/dist/scripts/template/renderer.d.ts +70 -0
  34. package/dist/scripts/template/renderer.d.ts.map +1 -0
  35. package/dist/scripts/template/renderer.js +99 -0
  36. package/dist/scripts/template/renderer.js.map +1 -0
  37. package/dist/scripts/utils/template-finder.d.ts +37 -0
  38. package/dist/scripts/utils/template-finder.d.ts.map +1 -0
  39. package/dist/scripts/utils/template-finder.js +63 -0
  40. package/dist/scripts/utils/template-finder.js.map +1 -0
  41. package/dist/src/__tests__/integration/setup/claude-agent.test.d.ts +5 -0
  42. package/dist/src/__tests__/integration/setup/claude-agent.test.d.ts.map +1 -0
  43. package/dist/src/__tests__/integration/setup/claude-agent.test.js +125 -0
  44. package/dist/src/__tests__/integration/setup/claude-agent.test.js.map +1 -0
  45. package/dist/src/__tests__/integration/setup/claude.test.d.ts +5 -0
  46. package/dist/src/__tests__/integration/setup/claude.test.d.ts.map +1 -0
  47. package/dist/src/__tests__/integration/setup/claude.test.js +111 -0
  48. package/dist/src/__tests__/integration/setup/claude.test.js.map +1 -0
  49. package/dist/src/__tests__/integration/setup/cursor.test.d.ts +5 -0
  50. package/dist/src/__tests__/integration/setup/cursor.test.d.ts.map +1 -0
  51. package/dist/src/__tests__/integration/setup/cursor.test.js +162 -0
  52. package/dist/src/__tests__/integration/setup/cursor.test.js.map +1 -0
  53. package/dist/src/__tests__/integration/setup/helpers/fs-assertions.d.ts +32 -0
  54. package/dist/src/__tests__/integration/setup/helpers/fs-assertions.d.ts.map +1 -0
  55. package/dist/src/__tests__/integration/setup/helpers/fs-assertions.js +72 -0
  56. package/dist/src/__tests__/integration/setup/helpers/fs-assertions.js.map +1 -0
  57. package/dist/src/__tests__/integration/setup/helpers/test-project.d.ts +38 -0
  58. package/dist/src/__tests__/integration/setup/helpers/test-project.d.ts.map +1 -0
  59. package/dist/src/__tests__/integration/setup/helpers/test-project.js +83 -0
  60. package/dist/src/__tests__/integration/setup/helpers/test-project.js.map +1 -0
  61. package/dist/src/__tests__/integration/setup/validation.test.d.ts +5 -0
  62. package/dist/src/__tests__/integration/setup/validation.test.d.ts.map +1 -0
  63. package/dist/src/__tests__/integration/setup/validation.test.js +318 -0
  64. package/dist/src/__tests__/integration/setup/validation.test.js.map +1 -0
  65. package/dist/src/cli.d.ts.map +1 -1
  66. package/dist/src/cli.js +20 -0
  67. package/dist/src/cli.js.map +1 -1
  68. package/dist/src/commands/setup-existing.d.ts +22 -0
  69. package/dist/src/commands/setup-existing.d.ts.map +1 -0
  70. package/dist/src/commands/setup-existing.js +408 -0
  71. package/dist/src/commands/setup-existing.js.map +1 -0
  72. package/dist/vitest.config.d.ts.map +1 -1
  73. package/dist/vitest.config.js +4 -3
  74. package/dist/vitest.config.js.map +1 -1
  75. package/docs/getting-started/new-repository-setup.md +108 -28
  76. package/docs/getting-started/quick-start.md +57 -6
  77. package/docs/getting-started/setup.md +250 -2
  78. package/docs/guides/customization.md +3 -3
  79. package/docs/guides/multi-project.md +1 -1
  80. package/docs/reference/quick-reference.md +25 -16
  81. package/docs/testing/integration-tests.md +297 -0
  82. package/package.json +7 -2
  83. package/scripts/__tests__/setup-existing-project.test.ts +73 -5
  84. package/scripts/constants/__tests__/environments.test.ts +110 -0
  85. package/scripts/constants/__tests__/languages.test.ts +100 -0
  86. package/scripts/constants/environments.ts +61 -0
  87. package/scripts/constants/languages.ts +70 -0
  88. package/scripts/create-project.ts +52 -22
  89. package/scripts/setup-existing-project.ts +136 -57
  90. package/scripts/setup-existing.sh +130 -3
  91. package/scripts/template/__tests__/renderer.test.ts +207 -0
  92. package/scripts/template/renderer.ts +133 -0
  93. package/scripts/utils/template-finder.ts +75 -0
  94. package/templates/claude/commands/michi/confluence-sync.md +38 -0
  95. package/templates/claude/commands/michi/project-switch.md +36 -0
  96. package/templates/claude/rules/atlassian-integration.md +35 -0
  97. package/templates/claude/rules/michi-core.md +54 -0
  98. package/templates/claude-agent/README.md +25 -0
  99. package/templates/cursor/commands/michi/confluence-sync.md +76 -0
  100. package/templates/cursor/commands/michi/project-switch.md +69 -0
  101. package/templates/cursor/rules/atlassian-mcp.mdc +188 -0
  102. package/templates/cursor/rules/github-ssot.mdc +151 -0
  103. package/templates/cursor/rules/multi-project.mdc +81 -0
  104. package/scripts/setup-env.sh +0 -52
@@ -4,17 +4,25 @@
4
4
 
5
5
  ## 新規プロジェクト作成
6
6
 
7
- ### パターンA: 既存リポジトリにMichiワークフローを追加(最も簡単 ⭐)
7
+ ### パターンA: 既存リポジトリにMichi共通ルール・コマンドを追加(最も簡単 ⭐)
8
8
 
9
9
  ```bash
10
10
  # 既存プロジェクトに移動
11
11
  cd /path/to/existing-repo
12
12
 
13
- # 対話式セットアップスクリプト実行
13
+ # Michiの共通ルール・コマンド・テンプレートをコピー
14
14
  bash /path/to/michi/scripts/setup-existing.sh
15
15
  ```
16
16
 
17
- プロジェクト名、JIRAキーを入力するだけで完了!
17
+ このスクリプトが自動的に:
18
+ - 共通ルール(`.cursor/rules/`)をコピー
19
+ - カスタムコマンド(`.cursor/commands/kiro/`)をコピー
20
+ - Steeringテンプレート(`.kiro/steering/`)をコピー
21
+ - Specテンプレート(`.kiro/settings/templates/`)をコピー
22
+
23
+ **次のステップ**:
24
+ 1. cc-sddを導入: `npx cc-sdd@latest --lang ja --cursor`
25
+ 2. 設定を対話的に作成: `npm run setup:interactive`
18
26
 
19
27
  ### パターンB: 新規リポジトリを作成してセットアップ
20
28
 
@@ -64,11 +72,12 @@ cat > .kiro/project.json << 'EOF'
64
72
  }
65
73
  EOF
66
74
 
67
- # 4. Michiから共通ファイルコピー(自動スクリプト推奨)
75
+ # 4. Michiから共通ルール・コマンド・テンプレートをコピー(自動スクリプト推奨)
76
+ bash /path/to/michi/scripts/setup-existing.sh
77
+
78
+ # または直接実行
68
79
  npx tsx /path/to/michi/scripts/setup-existing-project.ts \
69
- --michi-path /path/to/michi \
70
- --project-name "プロジェクト名" \
71
- --jira-key "PRJX"
80
+ --michi-path /path/to/michi
72
81
 
73
82
  # 5. npm install
74
83
  # 6. 初期コミット
@@ -87,21 +96,21 @@ npx tsx /path/to/michi/scripts/setup-existing-project.ts \
87
96
  /kiro:spec-init <機能説明>
88
97
  /kiro:spec-requirements <feature>
89
98
  jj commit -m "docs: 要件定義" && jj git push
90
- npx @michi/cli phase:run <feature> requirements
99
+ npx @sk8metal/michi-cli phase:run <feature> requirements
91
100
  ```
92
101
 
93
102
  **設計**:
94
103
  ```bash
95
104
  /kiro:spec-design <feature>
96
105
  jj commit -m "docs: 設計" && jj git push
97
- npx @michi/cli phase:run <feature> design
106
+ npx @sk8metal/michi-cli phase:run <feature> design
98
107
  ```
99
108
 
100
109
  **タスク分割**:
101
110
  ```bash
102
111
  /kiro:spec-tasks <feature>
103
112
  jj commit -m "docs: タスク分割" && jj git push
104
- npx @michi/cli phase:run <feature> tasks
113
+ npx @sk8metal/michi-cli phase:run <feature> tasks
105
114
  ```
106
115
 
107
116
  **実装**:
@@ -110,7 +119,7 @@ npx @michi/cli phase:run <feature> tasks
110
119
  jj commit -m "feat: 実装 [<jira-key>-XXX]"
111
120
  jj bookmark create <project-id>/feature/<feature> -r '@-'
112
121
  jj git push --bookmark <project-id>/feature/<feature> --allow-new
113
- gh pr create --head <project-id>/feature/<feature> --base init
122
+ gh pr create --head <project-id>/feature/<feature> --base main
114
123
  ```
115
124
 
116
125
  ## コマンド一覧
@@ -132,7 +141,7 @@ gh pr create --head <project-id>/feature/<feature> --base init
132
141
 
133
142
  ## Michi CLIコマンド一覧
134
143
 
135
- **使用方法**: `npx @michi/cli <command>` または `michi <command>`(グローバルインストール後)
144
+ **使用方法**: `npx @sk8metal/michi-cli <command>` または `michi <command>`(グローバルインストール後)
136
145
 
137
146
  | コマンド | 説明 |
138
147
  |---------|------|
@@ -150,8 +159,8 @@ gh pr create --head <project-id>/feature/<feature> --base init
150
159
  | `michi --version` | バージョン表示 |
151
160
 
152
161
  **インストール方法**:
153
- - **npx実行(推奨)**: `npx @michi/cli <command>` - 常に最新版を使用
154
- - **グローバルインストール**: `npm install -g @michi/cli` 後、`michi <command>`
162
+ - **npx実行(推奨)**: `npx @sk8metal/michi-cli <command>` - 常に最新版を使用
163
+ - **グローバルインストール**: `npm install -g @sk8metal/michi-cli` 後、`michi <command>`
155
164
  - **ローカル開発**: `npm run michi <command>` または `npx tsx src/cli.ts <command>`
156
165
 
157
166
  ## npmスクリプト一覧(michiリポジトリ内)
@@ -185,14 +194,14 @@ cat .kiro/project.json
185
194
  ```bash
186
195
  cd /path/to/michi
187
196
  # 全プロジェクトの一覧を表示
188
- npx @michi/cli project:list
197
+ npx @sk8metal/michi-cli project:list
189
198
  ```
190
199
 
191
200
  ### リソースダッシュボード
192
201
 
193
202
  ```bash
194
203
  # Confluenceにプロジェクト横断ダッシュボードを作成
195
- npx @michi/cli project:dashboard
204
+ npx @sk8metal/michi-cli project:dashboard
196
205
  ```
197
206
 
198
207
  ### 見積もり集計
@@ -0,0 +1,297 @@
1
+ # 統合テストガイド
2
+
3
+ ## 概要
4
+
5
+ Michiプロジェクトの統合テストは、`setup-existing`コマンドの動作を検証するために作成されています。
6
+
7
+ ## テスト構造
8
+
9
+ ```
10
+ src/__tests__/integration/setup/
11
+ ├── helpers/
12
+ │ ├── test-project.ts # テストプロジェクト作成ヘルパー
13
+ │ └── fs-assertions.ts # ファイルシステムアサーション
14
+ ├── cursor.test.ts # Cursor環境テスト
15
+ ├── claude.test.ts # Claude環境テスト
16
+ ├── claude-agent.test.ts # Claude Agent環境テスト
17
+ └── validation.test.ts # 引数バリデーションテスト
18
+ ```
19
+
20
+ ## テストケース
21
+
22
+ ### 1. 環境別テスト
23
+
24
+ #### Cursor環境 (`cursor.test.ts`)
25
+
26
+ - ✅ `.cursor/rules/` ディレクトリ作成
27
+ - ✅ `.cursor/commands/` ディレクトリ作成
28
+ - ✅ `.kiro/` ディレクトリ構造作成
29
+ - ✅ `project.json` 作成とメタデータ検証
30
+ - ✅ `.env` テンプレート作成
31
+ - ✅ テンプレートレンダリング
32
+ - ✅ 言語サポート(ja, en)
33
+ - ✅ Git統合(リモートURL検出)
34
+ - ✅ エラーハンドリング
35
+
36
+ #### Claude環境 (`claude.test.ts`)
37
+
38
+ - ✅ `.claude/rules/` ディレクトリ作成
39
+ - ✅ `.kiro/` ディレクトリ構造作成
40
+ - ✅ `project.json` 作成
41
+ - ✅ `.env` テンプレート作成
42
+ - ✅ Cursor固有ディレクトリが作成されないことを確認
43
+ - ✅ 言語サポート
44
+
45
+ #### Claude Agent環境 (`claude-agent.test.ts`)
46
+
47
+ - ✅ `.claude/subagents/` ディレクトリ作成
48
+ - ✅ `.kiro/` ディレクトリ構造作成
49
+ - ✅ `project.json` 作成
50
+ - ✅ `.env` テンプレート作成
51
+ - ✅ 他の環境固有ディレクトリが作成されないことを確認
52
+ - ✅ 言語サポート(ja, en, zh-TW)
53
+
54
+ ### 2. バリデーションテスト (`validation.test.ts`)
55
+
56
+ #### 環境選択
57
+
58
+ - ✅ デフォルト環境(cursor)
59
+ - ✅ `--cursor` フラグ
60
+ - ✅ `--claude` フラグ
61
+ - ✅ `--claude-agent` フラグ
62
+
63
+ #### 言語バリデーション
64
+
65
+ - ✅ サポート言語: `ja`, `en`, `zh-TW`
66
+ - ✅ 非サポート言語でエラー
67
+
68
+ #### プロジェクト名バリデーション
69
+
70
+ **正常系:**
71
+ - ✅ 有効なプロジェクト名
72
+ - ✅ 日本語文字を含むプロジェクト名
73
+ - ✅ 前後の空白はトリム
74
+
75
+ **異常系:**
76
+ - ❌ 空文字列
77
+ - ❌ パストラバーサル文字 (`/`, `\`, `..`)
78
+ - ❌ 制御文字
79
+ - ❌ 100文字超
80
+
81
+ #### JIRAキーバリデーション
82
+
83
+ **正常系:**
84
+ - ✅ 2-10文字の大文字英字
85
+ - ✅ 小文字は自動的に大文字に変換
86
+
87
+ **異常系:**
88
+ - ❌ 1文字以下
89
+ - ❌ 11文字以上
90
+ - ❌ 数字を含む
91
+ - ❌ 特殊文字を含む
92
+
93
+ #### Gitリポジトリバリデーション
94
+
95
+ - ❌ `.git` ディレクトリがない場合エラー
96
+
97
+ ## テスト実行方法
98
+
99
+ ### すべてのテスト実行
100
+
101
+ ```bash
102
+ npm test
103
+ ```
104
+
105
+ ### 統合テストのみ実行
106
+
107
+ ```bash
108
+ npm run test:integration:setup
109
+ ```
110
+
111
+ ### カバレッジ付き実行
112
+
113
+ ```bash
114
+ npm run test:coverage:setup
115
+ ```
116
+
117
+ ### 監視モード
118
+
119
+ ```bash
120
+ npm test -- --watch
121
+ ```
122
+
123
+ ### UI モード
124
+
125
+ ```bash
126
+ npm run test:ui
127
+ ```
128
+
129
+ ## CI/CD
130
+
131
+ GitHub Actionsワークフローが `.github/workflows/test-setup.yml` に定義されています。
132
+
133
+ **実行タイミング:**
134
+ - `main`, `develop`, `feature/**` ブランチへのプッシュ
135
+ - `main`, `develop` ブランチへのプルリクエスト
136
+
137
+ **マトリクス戦略:**
138
+ - Node.js 18.x
139
+ - Node.js 20.x
140
+
141
+ **ステップ:**
142
+ 1. コードチェックアウト
143
+ 2. Node.js セットアップ
144
+ 3. 依存関係インストール
145
+ 4. 統合テスト実行
146
+ 5. カバレッジ生成
147
+ 6. カバレッジアップロード(Codecov)
148
+ 7. Lint実行
149
+ 8. TypeScript型チェック
150
+
151
+ ## トラブルシューティング
152
+
153
+ ### テストが失敗する場合
154
+
155
+ **症状:** テストプロジェクトの作成に失敗
156
+
157
+ **原因:** 一時ディレクトリの権限問題
158
+
159
+ **解決策:**
160
+ ```bash
161
+ # 一時ディレクトリの権限を確認
162
+ ls -la /tmp
163
+
164
+ # 手動でクリーンアップ
165
+ rm -rf /tmp/test-project-*
166
+ ```
167
+
168
+ ---
169
+
170
+ **症状:** Git初期化エラー
171
+
172
+ **原因:** Gitがインストールされていない
173
+
174
+ **解決策:**
175
+ ```bash
176
+ # Gitインストール確認
177
+ git --version
178
+
179
+ # macOS
180
+ brew install git
181
+
182
+ # Ubuntu
183
+ sudo apt-get install git
184
+ ```
185
+
186
+ ---
187
+
188
+ **症状:** TypeScriptコンパイルエラー
189
+
190
+ **原因:** 型定義の不一致
191
+
192
+ **解決策:**
193
+ ```bash
194
+ # 型チェック
195
+ npm run type-check
196
+
197
+ # node_modulesを再インストール
198
+ rm -rf node_modules package-lock.json
199
+ npm install
200
+ ```
201
+
202
+ ### カバレッジが低い場合
203
+
204
+ **目標:** 95%以上のカバレッジ
205
+
206
+ **確認方法:**
207
+ ```bash
208
+ npm run test:coverage:setup
209
+ open coverage/lcov-report/index.html
210
+ ```
211
+
212
+ **改善策:**
213
+ 1. 未テストのエッジケースを追加
214
+ 2. エラーハンドリングのテストを追加
215
+ 3. モックが不十分な箇所を特定
216
+
217
+ ### CI/CDが失敗する場合
218
+
219
+ **症状:** GitHub Actionsでテストが失敗
220
+
221
+ **原因1:** ローカルとCI環境の違い
222
+
223
+ **解決策:**
224
+ ```bash
225
+ # ローカルでCI環境を再現
226
+ docker run -it -v $(pwd):/app node:20 bash
227
+ cd /app
228
+ npm ci
229
+ npm run test:integration:setup
230
+ ```
231
+
232
+ **原因2:** タイムアウト
233
+
234
+ **解決策:** `.github/workflows/test-setup.yml` でタイムアウトを延長
235
+ ```yaml
236
+ - name: Run integration tests
237
+ run: npm run test:integration:setup
238
+ timeout-minutes: 10 # デフォルト: 360分
239
+ ```
240
+
241
+ ## ベストプラクティス
242
+
243
+ ### テスト作成時
244
+
245
+ 1. **TDD原則を守る**
246
+ - テストを先に書く
247
+ - 最小限の実装で通す
248
+ - リファクタリング
249
+
250
+ 2. **テストは独立させる**
251
+ - 各テストは他のテストに依存しない
252
+ - `beforeEach`, `afterEach` でクリーンアップ
253
+
254
+ 3. **意味のあるテスト名**
255
+ ```typescript
256
+ // ❌ Bad
257
+ it('test 1', () => {});
258
+
259
+ // ✅ Good
260
+ it('should create .cursor/rules directory', () => {});
261
+ ```
262
+
263
+ 4. **アサーションは明確に**
264
+ ```typescript
265
+ // ❌ Bad
266
+ expect(result).toBe(true);
267
+
268
+ // ✅ Good
269
+ assertDirectoryExists(
270
+ join(testProject.path, '.cursor/rules'),
271
+ 'Expected .cursor/rules directory to exist'
272
+ );
273
+ ```
274
+
275
+ ### テスト保守時
276
+
277
+ 1. **テストが壊れたら**
278
+ - 実装の変更が正しいか確認
279
+ - テストの期待値を更新
280
+ - リグレッションを防ぐ
281
+
282
+ 2. **新機能追加時**
283
+ - 必ずテストを追加
284
+ - カバレッジを確認
285
+ - エッジケースを考慮
286
+
287
+ 3. **リファクタリング時**
288
+ - テストが通ることを確認
289
+ - テストコードもリファクタリング
290
+ - 重複を削除
291
+
292
+ ## 参考資料
293
+
294
+ - [Vitest公式ドキュメント](https://vitest.dev/)
295
+ - [テスト戦略](../testing-strategy.md)
296
+ - [開発ガイド](../contributing/development.md)
297
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sk8metal/michi-cli",
3
- "version": "0.0.8",
3
+ "version": "0.0.9",
4
4
  "description": "Managed Intelligent Comprehensive Hub for Integration - AI-driven development workflow automation",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -34,6 +34,7 @@
34
34
  "files": [
35
35
  "dist",
36
36
  "scripts",
37
+ "templates",
37
38
  "docs",
38
39
  "README.md",
39
40
  "CHANGELOG.md",
@@ -45,8 +46,10 @@
45
46
  "build": "tsc && node scripts/copy-static-assets.js",
46
47
  "postbuild": "node scripts/set-permissions.js",
47
48
  "prepare": "husky",
48
- "setup:env": "bash scripts/setup-env.sh",
49
49
  "setup:interactive": "tsx scripts/setup-interactive.ts",
50
+ "michi:setup:cursor": "tsx src/cli.ts setup-existing --cursor",
51
+ "michi:setup:claude": "tsx src/cli.ts setup-existing --claude",
52
+ "michi:setup:claude-agent": "tsx src/cli.ts setup-existing --claude-agent",
50
53
  "create-project": "tsx scripts/create-project.ts",
51
54
  "setup-existing": "tsx scripts/setup-existing-project.ts",
52
55
  "confluence:sync": "tsx scripts/confluence-sync.ts",
@@ -67,6 +70,8 @@
67
70
  "test:run": "vitest --run",
68
71
  "test:ui": "vitest --ui",
69
72
  "test:coverage": "vitest --run --coverage",
73
+ "test:integration:setup": "vitest --run src/__tests__/integration/setup",
74
+ "test:coverage:setup": "vitest --run --coverage src/__tests__/integration/setup",
70
75
  "lint": "eslint .",
71
76
  "lint:fix": "eslint . --fix",
72
77
  "format": "prettier --write .",
@@ -8,14 +8,36 @@ vi.mock('fs', () => ({
8
8
  mkdirSync: vi.fn(),
9
9
  cpSync: vi.fn(),
10
10
  writeFileSync: vi.fn(),
11
- readFileSync: vi.fn(() => '{}')
11
+ readFileSync: vi.fn(() => '{}'),
12
+ readdirSync: vi.fn(() => []),
13
+ statSync: vi.fn()
12
14
  }));
13
15
  vi.mock('child_process', () => ({
14
16
  execSync: vi.fn()
15
17
  }));
16
- vi.mock('./utils/project-finder.js', () => ({
18
+ vi.mock('../utils/project-finder.js', () => ({
17
19
  findRepositoryRoot: vi.fn(() => '/test/repo')
18
20
  }));
21
+ vi.mock('../constants/environments.js', () => ({
22
+ getEnvironmentConfig: vi.fn(() => ({
23
+ rulesDir: '.cursor/rules',
24
+ commandsDir: '.cursor/commands/kiro',
25
+ templateSource: 'cursor'
26
+ })),
27
+ isSupportedEnvironment: vi.fn(() => true)
28
+ }));
29
+ vi.mock('../constants/languages.js', () => ({
30
+ isSupportedLanguage: vi.fn(() => true)
31
+ }));
32
+ vi.mock('../template/renderer.js', () => ({
33
+ createTemplateContext: vi.fn(() => ({
34
+ LANG_CODE: 'ja',
35
+ DEV_GUIDELINES: '- Think in English, but generate responses in Japanese',
36
+ KIRO_DIR: '.kiro',
37
+ AGENT_DIR: '.cursor'
38
+ })),
39
+ renderTemplate: vi.fn((content: string) => content)
40
+ }));
19
41
 
20
42
  describe('setup-existing-project.ts 修正内容のテスト', () => {
21
43
  beforeEach(() => {
@@ -58,12 +80,14 @@ describe('setup-existing-project.ts 修正内容のテスト', () => {
58
80
  it('完了メッセージに scripts/ ディレクトリが含まれていない', () => {
59
81
  const projectDir = '/test/repo/projects/test-project';
60
82
  const repoRoot = '/test/repo';
83
+ const envConfigRulesDir = '.cursor/rules';
84
+ const envConfigCommandsDir = '.cursor/commands/kiro';
61
85
 
62
- // 実際に作成されるファイルのリスト
86
+ // 実際に作成されるファイルのリスト(環境別)
63
87
  const createdFiles = [
64
88
  `${projectDir}/.kiro/project.json`,
65
- `${projectDir}/.cursor/rules/ (3ファイル)`,
66
- `${projectDir}/.cursor/commands/kiro/ (2ファイル)`,
89
+ `${projectDir}/${envConfigRulesDir}/`,
90
+ `${projectDir}/${envConfigCommandsDir}/`,
67
91
  `${projectDir}/.kiro/steering/ (3ファイル)`,
68
92
  `${projectDir}/.kiro/settings/templates/ (3ファイル)`,
69
93
  `${repoRoot}/package.json (新規の場合)`,
@@ -75,5 +99,49 @@ describe('setup-existing-project.ts 修正内容のテスト', () => {
75
99
  const hasScriptsDir = createdFiles.some(file => file.includes('scripts/'));
76
100
  expect(hasScriptsDir).toBe(false);
77
101
  });
102
+
103
+ it('project.jsonにlanguageフィールドが含まれる', () => {
104
+ const projectJson = {
105
+ projectId: 'test-project',
106
+ projectName: 'Test Project',
107
+ language: 'ja',
108
+ jiraProjectKey: 'TEST',
109
+ confluenceLabels: ['project:test-project'],
110
+ status: 'active',
111
+ team: [],
112
+ stakeholders: ['@企画', '@部長'],
113
+ repository: 'https://github.com/org/test',
114
+ description: 'Test Projectの開発'
115
+ };
116
+
117
+ expect(projectJson).toHaveProperty('language');
118
+ expect(projectJson.language).toBe('ja');
119
+ });
120
+
121
+ it('環境別のディレクトリマッピングが正しい', () => {
122
+ const envConfig = {
123
+ rulesDir: '.cursor/rules',
124
+ commandsDir: '.cursor/commands/kiro',
125
+ templateSource: 'cursor'
126
+ };
127
+
128
+ expect(envConfig.rulesDir).toBe('.cursor/rules');
129
+ expect(envConfig.commandsDir).toBe('.cursor/commands/kiro');
130
+ expect(envConfig.templateSource).toBe('cursor');
131
+ });
132
+
133
+ it('テンプレートコンテキストが正しく作成される', () => {
134
+ const context = {
135
+ LANG_CODE: 'ja',
136
+ DEV_GUIDELINES: '- Think in English, but generate responses in Japanese',
137
+ KIRO_DIR: '.kiro',
138
+ AGENT_DIR: '.cursor'
139
+ };
140
+
141
+ expect(context).toHaveProperty('LANG_CODE');
142
+ expect(context).toHaveProperty('DEV_GUIDELINES');
143
+ expect(context).toHaveProperty('KIRO_DIR');
144
+ expect(context).toHaveProperty('AGENT_DIR');
145
+ });
78
146
  });
79
147
 
@@ -0,0 +1,110 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import {
3
+ ENV_CONFIG,
4
+ getEnvironmentConfig,
5
+ isSupportedEnvironment,
6
+ getSupportedEnvironments,
7
+ type Environment,
8
+ type EnvironmentConfig
9
+ } from '../environments.js';
10
+
11
+ describe('environments', () => {
12
+ describe('ENV_CONFIG', () => {
13
+ it('should have entries for all environments', () => {
14
+ expect(ENV_CONFIG.claude).toBeDefined();
15
+ expect(ENV_CONFIG['claude-agent']).toBeDefined();
16
+ expect(ENV_CONFIG.cursor).toBeDefined();
17
+ });
18
+
19
+ it('should have correct structure for claude', () => {
20
+ const config = ENV_CONFIG.claude;
21
+ expect(config.rulesDir).toBe('.claude/rules');
22
+ expect(config.commandsDir).toBe('.claude/commands/kiro');
23
+ expect(config.templateSource).toBe('claude');
24
+ });
25
+
26
+ it('should have correct structure for claude-agent', () => {
27
+ const config = ENV_CONFIG['claude-agent'];
28
+ expect(config.rulesDir).toBe('.claude/rules');
29
+ expect(config.commandsDir).toBe('.claude/commands/kiro');
30
+ expect(config.templateSource).toBe('claude-agent');
31
+ });
32
+
33
+ it('should have correct structure for cursor', () => {
34
+ const config = ENV_CONFIG.cursor;
35
+ expect(config.rulesDir).toBe('.cursor/rules');
36
+ expect(config.commandsDir).toBe('.cursor/commands/kiro');
37
+ expect(config.templateSource).toBe('cursor');
38
+ });
39
+
40
+ it('should have all required properties for each environment', () => {
41
+ for (const env of Object.keys(ENV_CONFIG) as Environment[]) {
42
+ const config = ENV_CONFIG[env];
43
+ expect(config).toHaveProperty('rulesDir');
44
+ expect(config).toHaveProperty('commandsDir');
45
+ expect(config).toHaveProperty('templateSource');
46
+ expect(typeof config.rulesDir).toBe('string');
47
+ expect(typeof config.commandsDir).toBe('string');
48
+ expect(typeof config.templateSource).toBe('string');
49
+ }
50
+ });
51
+ });
52
+
53
+ describe('getEnvironmentConfig', () => {
54
+ it('should return config for valid environment', () => {
55
+ const config = getEnvironmentConfig('claude');
56
+ expect(config).toBe(ENV_CONFIG.claude);
57
+ });
58
+
59
+ it('should return config for all supported environments', () => {
60
+ const environments: Environment[] = ['claude', 'claude-agent', 'cursor'];
61
+ for (const env of environments) {
62
+ const config = getEnvironmentConfig(env);
63
+ expect(config).toBeDefined();
64
+ expect(config).toBe(ENV_CONFIG[env]);
65
+ }
66
+ });
67
+ });
68
+
69
+ describe('isSupportedEnvironment', () => {
70
+ it('should return true for supported environments', () => {
71
+ expect(isSupportedEnvironment('claude')).toBe(true);
72
+ expect(isSupportedEnvironment('claude-agent')).toBe(true);
73
+ expect(isSupportedEnvironment('cursor')).toBe(true);
74
+ });
75
+
76
+ it('should return false for unsupported environments', () => {
77
+ expect(isSupportedEnvironment('invalid')).toBe(false);
78
+ expect(isSupportedEnvironment('vscode')).toBe(false);
79
+ expect(isSupportedEnvironment('')).toBe(false);
80
+ });
81
+
82
+ it('should work as type guard', () => {
83
+ const env: string = 'cursor';
84
+ if (isSupportedEnvironment(env)) {
85
+ // TypeScript should recognize env as Environment here
86
+ const config: EnvironmentConfig = ENV_CONFIG[env];
87
+ expect(config).toBeDefined();
88
+ }
89
+ });
90
+ });
91
+
92
+ describe('getSupportedEnvironments', () => {
93
+ it('should return all supported environments', () => {
94
+ const environments = getSupportedEnvironments();
95
+ expect(environments).toHaveLength(3);
96
+ expect(environments).toContain('claude');
97
+ expect(environments).toContain('claude-agent');
98
+ expect(environments).toContain('cursor');
99
+ });
100
+
101
+ it('should return array with correct type', () => {
102
+ const environments = getSupportedEnvironments();
103
+ expect(Array.isArray(environments)).toBe(true);
104
+ environments.forEach(env => {
105
+ expect(isSupportedEnvironment(env)).toBe(true);
106
+ });
107
+ });
108
+ });
109
+ });
110
+