create-einja-app 0.3.1 → 0.3.2

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 (80) hide show
  1. package/README.md +1 -1
  2. package/dist/cli.js +32 -16
  3. package/dist/cli.js.map +1 -1
  4. package/package.json +1 -1
  5. package/templates/default/.claude/hooks/einja/plan-mode-skill-loader.sh +23 -0
  6. package/templates/default/.claude/settings.json +15 -1
  7. package/templates/default/.env.personal.example +6 -2
  8. package/templates/default/.envrc +5 -0
  9. package/templates/default/.github/workflows/deploy-pr-preview.yml +23 -24
  10. package/templates/default/.github/workflows/deploy-stable-branches.yml +55 -49
  11. package/templates/default/.mcp.json +2 -12
  12. package/templates/default/.serena/project.yml +7 -0
  13. package/templates/default/CLAUDE.md +28 -4
  14. package/templates/default/README.md +2 -2
  15. package/templates/default/apps/admin/package.json +1 -1
  16. package/templates/default/apps/admin/tsconfig.json +2 -1
  17. package/templates/default/apps/web/package.json +1 -1
  18. package/templates/default/apps/web/tsconfig.json +2 -1
  19. package/templates/default/docs/plans/.gitkeep +0 -0
  20. package/templates/default/docs/plans/ancient-greeting-flamingo-agent-a87e67c.md +221 -0
  21. package/templates/default/docs/plans/ancient-greeting-flamingo-agent-ab73a1c.md +107 -0
  22. package/templates/default/docs/plans/ancient-greeting-flamingo.md +120 -0
  23. package/templates/default/docs/plans/bright-stargazing-dawn.md +87 -0
  24. package/templates/default/docs/plans/calm-stirring-bonbon.md +196 -0
  25. package/templates/default/docs/plans/calm-watching-widget.md +111 -0
  26. package/templates/default/docs/plans/cheerful-wiggling-ullman.md +164 -0
  27. package/templates/default/docs/plans/compiled-humming-cherny.md +94 -0
  28. package/templates/default/docs/plans/dapper-launching-lynx.md +81 -0
  29. package/templates/default/docs/plans/effervescent-munching-kite-agent-ac08baf.md +672 -0
  30. package/templates/default/docs/plans/effervescent-munching-kite-agent-aecc373.md +442 -0
  31. package/templates/default/docs/plans/effervescent-munching-kite.md +263 -0
  32. package/templates/default/docs/plans/fix-orphan-cleaner-review.md +25 -0
  33. package/templates/default/docs/plans/fix-sync-template-variables.md +162 -0
  34. package/templates/default/docs/plans/glimmering-giggling-sedgewick.md +126 -0
  35. package/templates/default/docs/plans/glittery-swimming-bachman.md +78 -0
  36. package/templates/default/docs/plans/happy-watching-toast.md +56 -0
  37. package/templates/default/docs/plans/harmonic-strolling-nebula.md +210 -0
  38. package/templates/default/docs/plans/import-alias-refactor.md +75 -0
  39. package/templates/default/docs/plans/lazy-percolating-sloth-agent-abda679.md +346 -0
  40. package/templates/default/docs/plans/lazy-percolating-sloth.md +151 -0
  41. package/templates/default/docs/plans/linked-greeting-llama-agent-a7a6e5b.md +345 -0
  42. package/templates/default/docs/plans/linked-greeting-llama.md +467 -0
  43. package/templates/default/docs/plans/lovely-bubbling-rose.md +80 -0
  44. package/templates/default/docs/plans/optimized-watching-sprout.md +149 -0
  45. package/templates/default/docs/plans/peaceful-beaming-toast-agent-a292da6.md +288 -0
  46. package/templates/default/docs/plans/peaceful-beaming-toast-agent-a819699.md +366 -0
  47. package/templates/default/docs/plans/peaceful-beaming-toast-agent-ac11de2.md +474 -0
  48. package/templates/default/docs/plans/peaceful-beaming-toast.md +345 -0
  49. package/templates/default/docs/plans/purrfect-spinning-hickey-agent-ae6194c.md +300 -0
  50. package/templates/default/docs/plans/purrfect-spinning-hickey-agent-ae6900e.md +444 -0
  51. package/templates/default/docs/plans/purrfect-spinning-hickey.md +361 -0
  52. package/templates/default/docs/plans/recursive-kindling-lemon-agent-a42199e.md +186 -0
  53. package/templates/default/docs/plans/recursive-kindling-lemon.md +36 -0
  54. package/templates/default/docs/plans/seed-migration-tests.md +47 -0
  55. package/templates/default/docs/plans/sprightly-leaping-manatee.md +224 -0
  56. package/templates/default/docs/plans/stateful-wishing-lerdorf.md +161 -0
  57. package/templates/default/docs/plans/streamed-purring-wreath.md +40 -0
  58. package/templates/default/docs/plans/synthetic-percolating-pearl.md +101 -0
  59. package/templates/default/docs/plans/todo-fix-sync-template-variables.md +21 -0
  60. package/templates/default/docs/plans/todo-phase4-marker-update.md +39 -0
  61. package/templates/default/docs/plans/todo-skill-creator-sync.md +23 -0
  62. package/templates/default/docs/plans/typed-snuggling-parnas-agent-a6f6391.md +476 -0
  63. package/templates/default/docs/plans/typed-snuggling-parnas-agent-adb678b.md +144 -0
  64. package/templates/default/docs/plans/typed-snuggling-parnas.md +84 -0
  65. package/templates/default/docs/plans/warm-hopping-lighthouse-agent-a30aa4f.md +534 -0
  66. package/templates/default/docs/plans/warm-hopping-lighthouse-agent-a57a278.md +508 -0
  67. package/templates/default/docs/plans/warm-hopping-lighthouse-agent-a90b809.md +421 -0
  68. package/templates/default/docs/plans/warm-hopping-lighthouse.md +199 -0
  69. package/templates/default/docs/verification-test.md +2 -0
  70. package/templates/default/gitignore +4 -0
  71. package/templates/default/package.json +2 -2
  72. package/templates/default/packages/admin-ui/package.json +1 -1
  73. package/templates/default/packages/server-core/tsconfig.json +6 -1
  74. package/templates/default/pnpm-lock.yaml +276 -57
  75. package/templates/default/scripts/ensure-serena.sh +75 -0
  76. package/templates/default/scripts/lib/worktree-config.ts +64 -0
  77. package/templates/default/scripts/stop-serena.sh +25 -0
  78. package/templates/default/scripts/worktree/dev.ts +2 -2
  79. /package/templates/default/scripts/{cli-template-update.ts → _cli-template-update.ts} +0 -0
  80. /package/templates/default/scripts/{template-update.ts → _template-update.ts} +0 -0
@@ -0,0 +1,361 @@
1
+ # Plan: infra-maintenance SKILL.md 自動化レベル強化
2
+
3
+ ## Context
4
+
5
+ 前回の修正(カテゴリ5全Secrets対応、ゼロ状態判定、Vercel新規プロジェクト作成)が適用済み。
6
+ Explore + Codex の並行調査+レビューで、以下の問題が発見された:
7
+
8
+ 1. **CLI/APIで自動取得可能な値を人間に手動操作させている箇所が5件**
9
+ 2. **Vercelプロジェクト作成がDashboard GUI操作のまま**(CLI自動化可能)
10
+ 3. **Neonプロジェクト名がハードコード**(`einja-management` 固定)
11
+ 4. **トークン有効性の検証なし**(存在確認のみ)
12
+
13
+ **設計原則**:
14
+ 1. API/CLIで取得・生成可能な値は絶対に人間に操作させない
15
+ 2. プロジェクト名は推定+確認のハイブリッド方式
16
+ 3. 人間に聞く場合は必ず取得手順を提示
17
+
18
+ ---
19
+
20
+ ## 共通: プロジェクト名推定ロジック
21
+
22
+ Vercel/Neon のプロジェクト作成時に使用:
23
+
24
+ ```bash
25
+ # 1. package.json name から推定(優先)
26
+ BASE_NAME=$(cat package.json | jq -r '.name // empty' | sed 's/@[^/]*\///' | sed 's/-monorepo$//' | sed 's/-template$//')
27
+
28
+ # 2. フォールバック: Git リポジトリ名
29
+ if [ -z "$BASE_NAME" ]; then
30
+ BASE_NAME=$(basename "$(git remote get-url origin 2>/dev/null)" .git | sed 's/-template$//')
31
+ fi
32
+
33
+ # 3. jq未インストール時のフォールバック
34
+ if [ -z "$BASE_NAME" ]; then
35
+ BASE_NAME=$(grep '"name"' package.json | head -1 | sed 's/.*"name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/' | sed 's/@[^/]*\///' | sed 's/-monorepo$//' | sed 's/-template$//')
36
+ fi
37
+ ```
38
+
39
+ 推定した `$BASE_NAME` を元に:
40
+ - **Vercel**: `${BASE_NAME}-web`, `${BASE_NAME}-admin`
41
+ - **Neon**: `${BASE_NAME}`
42
+
43
+ AskUserQuestionで推定名をデフォルト値として提示し、ユーザーに承認/変更してもらう。
44
+
45
+ ---
46
+
47
+ ## 修正計画
48
+
49
+ **対象ファイル**: `.claude/skills/einja-infra-maintenance/SKILL.md` のみ
50
+
51
+ ### 修正1: Phase 1にトークン有効性検証を追加
52
+
53
+ **修正箇所**: L52-68(Phase 1: 環境状態の自動検出)
54
+
55
+ CLI存在確認の後に追加:
56
+ ```bash
57
+ # === トークン有効性検証(.env.personal 存在時のみ) ===
58
+ if [ -f ".env.personal" ]; then
59
+ # 並行実行で高速化(各コマンドにタイムアウト設定)
60
+ timeout 5 gh auth status 2>/dev/null && echo "✅ GITHUB_TOKEN 有効" || echo "⚠️ GITHUB_TOKEN 無効/未設定" &
61
+ timeout 5 vercel whoami 2>/dev/null && echo "✅ VERCEL_TOKEN 有効" || echo "⚠️ VERCEL_TOKEN 無効/未設定" &
62
+ if [ -n "$NEON_API_KEY" ]; then
63
+ timeout 5 neonctl projects list --api-key "$NEON_API_KEY" >/dev/null 2>&1 && echo "✅ NEON_API_KEY 有効" || echo "⚠️ NEON_API_KEY 無効/期限切れ" &
64
+ else
65
+ echo "⚠️ NEON_API_KEY 未設定"
66
+ fi
67
+ wait
68
+ fi
69
+ ```
70
+
71
+ ### 修正2: Phase 2推奨ロジックにトークン無効を追加
72
+
73
+ **修正箇所**: L94-104(推奨ロジック テーブル)
74
+
75
+ テーブルに追加:
76
+ ```
77
+ | トークン無効/期限切れ | 環境変数管理(個人トークン再設定) |
78
+ ```
79
+
80
+ ### 修正3: カテゴリ1 `.env.keys` 自動コピー化
81
+
82
+ **修正箇所**: L143(エラー対処テーブル `.env.keys`不在 行)
83
+
84
+ 現状: `AskUserQuestion: 「メインworktreeからコピー or 手動配置」`
85
+
86
+ 修正後:
87
+ ```
88
+ | `.env.keys`不在 | `git worktree list` でメインworktreeを検出し、`.env.keys` が存在すれば自動コピー。不在の場合は「チームメンバーから `.env.keys` ファイルを受け取り、プロジェクトルートに配置してください」と案内 |
89
+ ```
90
+
91
+ ### 修正4: カテゴリ3 Vercelプロジェクト作成をCLI自動化
92
+
93
+ **修正箇所**: L214-223(新規プロジェクト作成セクション)
94
+
95
+ 現状: Dashboard GUIでの手動作成を案内
96
+
97
+ 修正後: CLI(`vercel link` + `vercel git connect`)+ API(Root Directory)で自動化
98
+ > **根拠**: `vercel-cli-reference.md` L280-302 の「新規アプリのセットアップ手順」に準拠
99
+
100
+ ```
101
+ #### 新規プロジェクト作成(初回のみ)
102
+ > Vercelにプロジェクトが存在しない場合(ゼロ状態)のみ実行。VERCEL_TOKEN 取得済みが前提。
103
+
104
+ 1. **プロジェクト名の推定・確認**:
105
+ 共通推定ロジックで `$BASE_NAME` を取得し、`${BASE_NAME}-web`, `${BASE_NAME}-admin` を候補として生成。
106
+ AskUserQuestionでプロジェクト名と作成対象アプリ(web / admin / 両方)を確認。
107
+
108
+ 2. **既存プロジェクトの確認**:
109
+ ```bash
110
+ vercel project ls
111
+ ```
112
+ 既にプロジェクトが存在する場合は「既にVercelに存在します。スキップしますか?」と確認。
113
+
114
+ 3. **CLIでプロジェクト作成・Git接続**:
115
+ ```bash
116
+ # チーム切り替え(必要な場合)
117
+ vercel switch <team-slug>
118
+
119
+ # アプリごとにプロジェクト作成
120
+ for APP_NAME in web admin; do
121
+ cd "apps/$APP_NAME"
122
+ vercel link --project="${BASE_NAME}-${APP_NAME}" --yes
123
+ vercel git connect "https://github.com/${GH_ORG}/${GH_REPO}" --yes
124
+ cd ../..
125
+ done
126
+ ```
127
+ > `vercel link` はプロジェクトが存在しない場合に自動作成する(`vercel-cli-reference.md` L287)
128
+
129
+ 4. **APIでRoot Directory設定**(CLIでは不可: `vercel-cli-reference.md` L112):
130
+ ```bash
131
+ for APP_NAME in web admin; do
132
+ PROJECT_ID=$(cat "apps/$APP_NAME/.vercel/project.json" | jq -r '.projectId')
133
+ VERCEL_ORG_ID=$(cat "apps/$APP_NAME/.vercel/project.json" | jq -r '.orgId')
134
+ curl -X PATCH "https://api.vercel.com/v9/projects/$PROJECT_ID?teamId=$VERCEL_ORG_ID" \
135
+ -H "Authorization: Bearer $VERCEL_TOKEN" \
136
+ -H "Content-Type: application/json" \
137
+ -d "{\"rootDirectory\": \"apps/$APP_NAME\"}"
138
+ done
139
+ ```
140
+
141
+ 5. **プロジェクトID/ORG IDを自動取得・表示**:
142
+ ```bash
143
+ for APP_NAME in web admin; do
144
+ echo "$(echo $APP_NAME | tr '[:lower:]' '[:upper:]'):"
145
+ echo " PROJECT_ID: $(cat "apps/$APP_NAME/.vercel/project.json" | jq -r '.projectId')"
146
+ echo " ORG_ID: $(cat "apps/$APP_NAME/.vercel/project.json" | jq -r '.orgId')"
147
+ done
148
+ ```
149
+ GitHub Secretsへの登録を提案(→ カテゴリ5: 一括設定 Step 2)
150
+ ```
151
+
152
+ ### 修正5: カテゴリ3 初期設定の PROJECT_ID 自動取得
153
+
154
+ **修正箇所**: L225-237(初期設定セクション)
155
+
156
+ 現状 L237: `プロジェクトID取得・表示`(手動)
157
+
158
+ 修正後:
159
+ ```
160
+ 5. `.vercel/project.json` からプロジェクトIDとORG IDを自動取得:
161
+ ```bash
162
+ VERCEL_PROJECT_ID=$(cat "apps/$APP_NAME/.vercel/project.json" | jq -r '.projectId')
163
+ VERCEL_ORG_ID=$(cat "apps/$APP_NAME/.vercel/project.json" | jq -r '.orgId')
164
+ ```
165
+ 6. 取得結果を表示し、GitHub Secretsへの登録を提案(→ カテゴリ5)
166
+ ```
167
+
168
+ ### 修正6: カテゴリ4 Neonプロジェクト作成の自動化
169
+
170
+ **修正箇所**: L269-280(Neon初期設定セクション全体)
171
+
172
+ 現状の問題:
173
+ - プロジェクト名 `einja-management` がハードコード
174
+ - 既存プロジェクトの存在チェックなし
175
+ - NEON_PROJECT_ID の `.env.preview` への設定が手動
176
+
177
+ 修正後:
178
+ ```
179
+ #### 初期設定
180
+ 1. NEON_API_KEY確認 → 未設定時はURL案内 + `.env.personal`保存
181
+ - 取得URL: https://console.neon.tech/app/settings/api-keys
182
+ - **`neonctl auth`は使用しない**(理由: `neon-cli-reference.md`「認証方式」参照)
183
+
184
+ 2. **既存プロジェクトの確認**:
185
+ ```bash
186
+ neonctl projects list --api-key $NEON_API_KEY
187
+ ```
188
+ 既存プロジェクトがあれば一覧表示し、使用するプロジェクトをAskUserQuestionで確認。
189
+ 既存プロジェクトを使用する場合 → `neonctl projects get $PROJECT_ID` でIDを取得してステップ4へ。
190
+
191
+ 3. **プロジェクト名の推定・確認・作成**:
192
+ 共通推定ロジックで `$BASE_NAME` を取得。AskUserQuestionで確認(デフォルト値として提示)。
193
+ ```bash
194
+ neonctl projects create --name "$NEON_PROJECT_NAME" --region-id aws-ap-northeast-1 --api-key $NEON_API_KEY
195
+ ```
196
+ 作成後、`neonctl projects list` でプロジェクトIDを取得:
197
+ ```bash
198
+ NEON_PROJECT_ID=$(neonctl projects list --api-key $NEON_API_KEY | jq -r ".projects[] | select(.name==\"$NEON_PROJECT_NAME\") | .id")
199
+ ```
200
+
201
+ 4. **`.env.preview` に自動設定** → dotenvx暗号化:
202
+ ```bash
203
+ dotenvx decrypt -f .env.preview --stdout > .env.preview.tmp
204
+ # 既存の同名変数を削除してから追加(重複防止)
205
+ grep -v "^NEON_PROJECT_ID=" .env.preview.tmp | grep -v "^NEON_API_KEY=" > .env.preview.clean
206
+ echo "NEON_PROJECT_ID=$NEON_PROJECT_ID" >> .env.preview.clean
207
+ echo "NEON_API_KEY=$NEON_API_KEY" >> .env.preview.clean
208
+ rm .env.preview && mv .env.preview.clean .env.preview
209
+ dotenvx encrypt -f .env.preview
210
+ ```
211
+
212
+ 5. ブランチ戦略初期設定:
213
+ - production(main)ブランチ確認
214
+ - developmentブランチ作成
215
+ ```
216
+
217
+ カテゴリ4サブメニューに追加:
218
+ ```
219
+ - **プロジェクトID取得**: 既存プロジェクトのIDを `neonctl projects list` で自動取得
220
+ ```
221
+
222
+ ### 修正7: カテゴリ5 一括設定 Step 2 を自動取得に変更
223
+
224
+ **修正箇所**: L352-365(Step 2: Vercel関連Secrets)
225
+
226
+ 現状: AskUserQuestionで4つの値を手動入力
227
+
228
+ 修正後: VERCEL_TOKEN のみ人間入力、残り3つは自動取得
229
+ ```
230
+ **Step 2: Vercel関連Secrets**
231
+
232
+ 2-a. `VERCEL_TOKEN`(人間入力が必須):
233
+ AskUserQuestionで値を入力してもらう。取得手順:
234
+ - Vercel Dashboard(https://vercel.com/account/tokens)> 「Create Token」
235
+ - Scope: Full Account を選択
236
+ - 入力後、`vercel whoami --token $TOKEN` で有効性を自動検証
237
+
238
+ 2-b. `VERCEL_ORG_ID`(自動取得):
239
+ ```bash
240
+ # apps/web/.vercel/project.json から取得(vercel link 実行済みの場合)
241
+ VERCEL_ORG_ID=$(cat apps/web/.vercel/project.json 2>/dev/null | jq -r '.orgId')
242
+ # 未取得の場合はAPI経由
243
+ if [ -z "$VERCEL_ORG_ID" ] || [ "$VERCEL_ORG_ID" = "null" ]; then
244
+ VERCEL_ORG_ID=$(curl -s "https://api.vercel.com/v2/teams" \
245
+ -H "Authorization: Bearer $VERCEL_TOKEN" | jq -r '.teams[0].id')
246
+ fi
247
+ gh secret set VERCEL_ORG_ID --body "$VERCEL_ORG_ID"
248
+ echo "✅ VERCEL_ORG_ID = $VERCEL_ORG_ID を設定しました"
249
+ ```
250
+
251
+ 2-c. `VERCEL_PROJECT_ID_WEB` / `VERCEL_PROJECT_ID_ADMIN`(自動取得):
252
+ ```bash
253
+ for APP_NAME in web admin; do
254
+ # apps/<app>/.vercel/project.json から取得(vercel link 実行済みの場合)
255
+ PROJECT_ID=$(cat "apps/$APP_NAME/.vercel/project.json" 2>/dev/null | jq -r '.projectId')
256
+ if [ -z "$PROJECT_ID" ] || [ "$PROJECT_ID" = "null" ]; then
257
+ # vercel link 未実行の場合: カテゴリ3(新規プロジェクト作成 or 初期設定)を先に実行するよう案内
258
+ echo "⚠️ apps/$APP_NAME/.vercel/project.json が見つかりません。先にカテゴリ3でVercelプロジェクトをリンクしてください"
259
+ continue
260
+ fi
261
+ SECRET_NAME="VERCEL_PROJECT_ID_$(echo $APP_NAME | tr '[:lower:]' '[:upper:]')"
262
+ gh secret set "$SECRET_NAME" --body "$PROJECT_ID"
263
+ echo "✅ $SECRET_NAME = $PROJECT_ID を設定しました"
264
+ done
265
+ ```
266
+ ```
267
+
268
+ ### 修正8: カテゴリ5 一括設定 Step 3 の TURBO_TOKEN 自動化
269
+
270
+ **修正箇所**: L367-383(Step 3: Turborepo Remote Cache)
271
+
272
+ ```
273
+ **Step 3: Turborepo Remote Cache**
274
+
275
+ 3-a. `TURBO_TOKEN`:
276
+ VERCEL_TOKEN(Step 2-a で取得済み)と同じ値を使用(別トークンを使う場合のみAskUserQuestionで入力):
277
+ ```bash
278
+ gh secret set TURBO_TOKEN --body "$VERCEL_TOKEN"
279
+ echo "✅ TURBO_TOKEN を設定しました(VERCEL_TOKENと同一値)"
280
+ ```
281
+
282
+ 3-b. `TURBO_TEAM`(自動取得):
283
+ ```bash
284
+ TURBO_TEAM=$(cat .turbo/config.json 2>/dev/null | jq -r '.teamId // empty')
285
+ if [ -z "$TURBO_TEAM" ]; then
286
+ echo "⚠️ .turbo/config.json 未生成。先に npx turbo login && npx turbo link を実行します"
287
+ npx turbo login && npx turbo link
288
+ TURBO_TEAM=$(cat .turbo/config.json | jq -r '.teamId')
289
+ fi
290
+ gh secret set TURBO_TEAM --body "$TURBO_TEAM"
291
+ echo "✅ TURBO_TEAM = $TURBO_TEAM を設定しました"
292
+ ```
293
+ ```
294
+
295
+ ### 修正9: エラーハンドリング テーブルの改善
296
+
297
+ **修正箇所**: L607-613
298
+
299
+ 修正後:
300
+ ```
301
+ | CLI未インストール | 自動インストール実行: `brew install <cli>` または `npm i -g <cli>`。Docker のみ OrbStack インストール案内(GUI必須のため) |
302
+ | トークン未設定 | 取得URL案内 → AskUserQuestionで値入力 → `.env.personal`に保存 → API検証(`vercel whoami` / `gh auth status` / `neonctl projects list`)で有効性確認 |
303
+ | トークン無効/期限切れ | 再取得URL案内 → AskUserQuestionで新しい値入力 → `.env.personal`を更新 → API検証で有効性確認 |
304
+ ```
305
+
306
+ ### 修正10: カテゴリ6 ヘルスチェックにトークン検証追加
307
+
308
+ **修正箇所**: L394-416(カテゴリ6: ローカル環境チェック)
309
+
310
+ CLIツール確認の後に、修正1と同じトークン有効性検証ブロック(タイムアウト付き並行実行)を追加。
311
+
312
+ ---
313
+
314
+ ## 修正サマリー
315
+
316
+ | # | 箇所 | 変更内容 | 効果 |
317
+ |---|------|---------|------|
318
+ | 1 | Phase 1 | トークン有効性検証追加(並行・タイムアウト付き) | 期限切れ・無効トークンを自動検知 |
319
+ | 2 | Phase 2 | 推奨ロジックにトークン無効を追加 | 無効時に自動でカテゴリ2へ誘導 |
320
+ | 3 | カテゴリ1 | `.env.keys` 自動コピー化 | worktree存在時は人間操作不要 |
321
+ | 4 | カテゴリ3 | Vercelプロジェクト作成をCLI自動化(`vercel link` + `vercel git connect` + API Root Directory) | Dashboard操作不要 |
322
+ | 5 | カテゴリ3 | PROJECT_ID/ORG_ID を `apps/<app>/.vercel/project.json` から自動取得 | 手動入力不要 |
323
+ | 6 | カテゴリ4 | Neonプロジェクト名推定+確認 / 既存チェック / ID自動取得 / `.env.preview` 自動設定(重複防止付き) | ハードコード解消 |
324
+ | 7 | カテゴリ5 Step 2 | VERCEL_ORG_ID/PROJECT_ID を `.vercel/project.json` から自動取得。VERCEL_TOKEN のみ手動 | 4値→1値のみ手動 |
325
+ | 8 | カテゴリ5 Step 3 | TURBO_TOKEN をVERCEL_TOKEN再利用で自動化 | 手動入力不要 |
326
+ | 9 | エラーハンドリング | CLI自動実行化 + トークン検証フロー | 提案→自動実行 |
327
+ | 10 | カテゴリ6 | トークン有効性検証追加 | ヘルスチェック精度向上 |
328
+
329
+ ## 人間操作が必要な場面(技術的制約で自動化不可)
330
+
331
+ | 場面 | 理由 | 提供する取得手順 |
332
+ |------|------|----------------|
333
+ | VERCEL_TOKEN 入力 | Dashboard でのトークン生成が必須 | URL(https://vercel.com/account/tokens)+ 「Create Token」手順 |
334
+ | NEON_API_KEY 入力 | Console でのキー生成が必須 | URL(https://console.neon.tech/app/settings/api-keys)+ 手順 |
335
+ | GITHUB_TOKEN 入力 | Settings ページでの生成が必須 | URL(https://github.com/settings/tokens/new)+ 必要スコープ |
336
+ | Docker インストール | GUIインストーラーが必須 | `brew install orbstack` + 公式サイトURL |
337
+ | `.env.keys` 配置 | チーム内の秘密鍵共有(worktree不在時) | 「チームメンバーから受け取りプロジェクトルートに配置」 |
338
+ | プロジェクト名確認 | 命名はプロジェクト固有の判断 | 推定名をデフォルト提示、変更可 |
339
+
340
+ **上記以外の全ての値は CLI/API で自動取得・自動設定される。**
341
+
342
+ ## レビュー指摘事項と対応
343
+
344
+ | 指摘 | 対応 |
345
+ |------|------|
346
+ | Vercel `POST /v9/projects` API未記載 | ❌廃止 → CLI `vercel link` + `vercel git connect` に変更(修正4) |
347
+ | Neon `--output json` レスポンス構造未確認 | `neonctl projects list` + `jq` パースに変更(修正6) |
348
+ | dotenvx `.env.preview` 重複追加リスク | `grep -v` で既存行を削除してから追加(修正6) |
349
+ | `.vercel/project.json` パス不統一 | 全箇所を `apps/<app>/.vercel/project.json` に統一(修正4,5,7) |
350
+ | `jq` 未インストール時のフォールバック | 共通推定ロジックに `grep` + `sed` フォールバック追加 |
351
+ | Phase 1 トークン検証のパフォーマンス | バックグラウンド並行実行 + `timeout 5` を追加(修正1) |
352
+
353
+ ## 検証方法
354
+
355
+ 1. `pnpm prepush` でlint/typecheck/testが通ることを確認
356
+ 2. 全AskUserQuestion箇所を洗い出し、CLI/APIで代替可能な値がないことをgrepで確認
357
+ 3. ゼロ状態シミュレーション:
358
+ - VERCEL_TOKEN入力 → `vercel link` でプロジェクト作成 → `apps/<app>/.vercel/project.json` から ORG_ID/PROJECT_ID 自動取得 → Secrets 自動登録
359
+ - NEON_API_KEY入力 → `neonctl projects create` → `neonctl projects list` でID取得 → `.env.preview` 自動設定(重複防止付き)
360
+ - Phase 1 でトークン有効性検証(並行・タイムアウト付き)→ 期限切れ検知 → カテゴリ2 へ自動誘導
361
+ 4. `.vercel/project.json` パスが全箇所で `apps/<app>/` 配下を参照していることを確認
@@ -0,0 +1,186 @@
1
+ # コードレビュー計画
2
+
3
+ ## 対象コミット
4
+
5
+ 1. `79b5dbb` - refactor(cli): setup/addコマンドを廃止しsyncコマンドに統合
6
+ 2. `2bdb9a7` - refactor: QAテスト構造をタスクグループ単位からユーザーストーリー(AC)単位に移行
7
+
8
+ ## レビュー観点
9
+
10
+ ### 1. 型の整合性
11
+ ### 2. 未使用コード
12
+ ### 3. 新規コード品質
13
+ ### 4. Story形式の一貫性
14
+ ### 5. テストカバレッジ
15
+ ### 6. 破壊的変更
16
+
17
+ ---
18
+
19
+ ## 🤖 Codex作業完了
20
+
21
+ ### タスク: 直近2コミットのコードレビュー(CLI統合 + QA構造移行)
22
+
23
+ ### 作業結果: ✅ SUCCESS
24
+
25
+ ### 作業モード: レビュー
26
+
27
+ ### サマリー
28
+
29
+ - **レビュー対象**: 2コミット(59ファイル変更、+1702/-5943行)
30
+ - **重大な問題**: 0件
31
+ - **警告レベル**: 2件
32
+ - **改善提案**: 5件
33
+ - **Good Point**: 4件
34
+
35
+ ---
36
+
37
+ ## 詳細レビュー
38
+
39
+ ### コミット1: CLI統合(79b5dbb)
40
+
41
+ **変更規模**: 32ファイル(+1276/-4471行)
42
+
43
+ #### ✅ Good Points
44
+
45
+ 1. **大規模リファクタリングの整合性**
46
+ - 4コマンド→2コマンド統合で3195行削除
47
+ - 型定義が全ファイルで一貫している(`ConflictStrategy`, `packageJsonSections`)
48
+ - 破壊的変更なし(既存syncコマンド利用者への影響0)
49
+
50
+ 2. **新規機能の実装品質**
51
+ - `post-sync-actions.ts`: エラーハンドリングが適切
52
+ - 型ガードが明示的(`hasEnvCategory && isEnvrcSynced`)
53
+ - テストカバレッジ100%(441行のテストコード)
54
+
55
+ 3. **コードの可読性**
56
+ - Given-When-Thenコメントが全テストに記載
57
+ - 関数名が明確(`isDirenvAvailable`, `runDirenvAllowAction`)
58
+
59
+ 4. **依存関係の整理**
60
+ - 未使用型削除(`SyncDetailConfig`, `PackageJsonSyncConfig`)
61
+ - インポート整理済み
62
+
63
+ #### ⚠️ 警告レベル
64
+
65
+ 1. **peerDependencies型不一致の修正内容が不明**
66
+ - コミットメッセージに記載あり:「peerDependenciesの型不一致を修正」
67
+ - しかし差分では `packageJsonSections` 配列に `peerDependencies` が追加されただけ
68
+ - **実際の型不一致がどこで発生していたか**が読み取れない
69
+ - 影響: 今後同じ問題が再発する可能性
70
+
71
+ 2. **dist/cli.js の2400行削除**
72
+ - ビルド成果物の差分が大きい(-2400行)
73
+ - トランスパイル結果なので正確性検証が困難
74
+ - 推奨: ビルド後の動作確認(`pnpm einja sync --dry-run`)
75
+
76
+ #### 💡 改善提案(優先度: 低)
77
+
78
+ 1. **conflictStrategy のデフォルト値**
79
+ - `mergeAndWriteFile` のデフォルトが `"merge"` で統一されている ✅
80
+ - しかし `promptSyncCategories` の初期値は変数宣言時のみ設定
81
+ - 推奨: 型レベルでデフォルトを明示(`ConflictStrategy = "merge"`)
82
+
83
+ 2. **post-sync-actions の拡張性**
84
+ - 現在2アクション(direnv, husky)のみ
85
+ - 今後アクションが増えた場合の設計: 配列ベースのアクション管理推奨
86
+ ```typescript
87
+ const actions = [
88
+ { category: 'env', file: '.envrc', handler: runDirenvAllowAction },
89
+ { category: 'git-hooks', file: '.husky/pre-commit', handler: runHuskyChmodAction },
90
+ ];
91
+ ```
92
+
93
+ 3. **テストのエッジケース**
94
+ - `post-sync-actions.test.ts` でエラー発生時のテストが不足
95
+ - 例: `chmodSync` が例外を投げた場合のエラーハンドリング
96
+ - 現在はエラーログ出力のみ(処理は継続)→ テストケース追加推奨
97
+
98
+ ---
99
+
100
+ ### コミット2: QAテスト構造移行(2bdb9a7)
101
+
102
+ **変更規模**: 27ファイル(+426/-1472行)
103
+
104
+ #### ✅ Good Points
105
+
106
+ 1. **旧形式への参照完全削除**
107
+ - `phase1/`, `phase2/` ディレクトリとファイルをすべて削除
108
+ - CLIテンプレート(`qa-test.md.template`)も新形式に更新
109
+ - 検索結果: "phase" への参照なし(`grep -r "phase{N}" .claude/ docs/` = 0件)
110
+
111
+ 2. **一貫性のある構造変更**
112
+ - `qa-tests/phase{N}/{X-Y}.md` → `qa-tests/story{N}.md`
113
+ - エビデンス配置: `phase{N}/evidence/` → `evidence/story{N}/`
114
+ - 変更記録: `modifications/phase-{N}/{X-Y}.md` → `modifications/task-{X}-{Y}.md`
115
+
116
+ 3. **入力形式の自然言語化**
117
+ - 旧: 構造化データ(JSON形式でphase/task指定)
118
+ - 新: 自然言語(「AC1.1, AC1.2のテストを実行」)
119
+ - task-qaの可読性向上
120
+
121
+ 4. **メタデータ改善**
122
+ - タスクメタデータに「実装AC」推奨項目を追加
123
+ - タスク実行時にACマッピングが明確化
124
+
125
+ #### ⚠️ 情報(影響なし)
126
+
127
+ 1. **issue999サンプルの移行**
128
+ - 旧: phase1/1-1.md(268行), 1-2.md(179行), 1-3.md(392行)
129
+ - 新: story1.md(101行), story2.md(70行), story3.md(69行)
130
+ - 行数削減(-1058行)はサンプルの簡略化による(問題なし)
131
+
132
+ #### 💡 改善提案(優先度: 低)
133
+
134
+ 1. **AC番号からStory特定ロジックの明示**
135
+ - `SKILL.md`に記載: 「AC番号の先頭数字(1)からStory 1を特定」
136
+ - エッジケース未定義: AC10.1の場合はStory 10 or Story 1?
137
+ - 推奨: 正規表現パターンを明示(`AC(\d+)\.(\d+)` → Story `$1`)
138
+
139
+ 2. **scenarios.md の実施タイミング基準**
140
+ - 旧: Phase単位(「Phase 1完了後に実施」)
141
+ - 新: AC番号基準(「AC1.3完了後に実施」)
142
+ - 問題: AC番号の順序性に依存(AC1.1→AC1.2→AC1.3の実装順序が保証されるか?)
143
+ - 推奨: 実施タイミングの依存関係を明示
144
+
145
+ ---
146
+
147
+ ## 総合評価
148
+
149
+ ### 🎯 品質スコア: 8.5/10
150
+
151
+ | 観点 | スコア | コメント |
152
+ |-----|-------|---------|
153
+ | 型の整合性 | 10/10 | 型定義が全ファイルで一貫 |
154
+ | 未使用コード | 10/10 | 削除漏れなし |
155
+ | 新規コード品質 | 9/10 | エラーハンドリング適切、テストカバレッジ100% |
156
+ | Story形式の一貫性 | 9/10 | 旧形式への参照完全削除 |
157
+ | テストカバレッジ | 8/10 | post-sync-actionsのエッジケース不足 |
158
+ | 破壊的変更 | 10/10 | 既存利用者への影響なし |
159
+
160
+ ### 📌 次のステップ
161
+
162
+ **即時対応不要(すべて低優先度)**
163
+
164
+ 1. ビルド後の動作確認(推奨)
165
+ ```bash
166
+ pnpm einja sync --dry-run --categories env,tools
167
+ ```
168
+
169
+ 2. エッジケーステスト追加(任意)
170
+ - `post-sync-actions.test.ts` にエラー発生時のテストケース追加
171
+
172
+ 3. ドキュメント改善(任意)
173
+ - AC番号パース仕様を明示
174
+
175
+ ---
176
+
177
+ ## レビュー完了
178
+
179
+ **結論**: 両コミットとも**高品質**で、即座のアクション不要。
180
+
181
+ - 設計が一貫している
182
+ - テストカバレッジが十分
183
+ - 破壊的変更がない
184
+ - ドキュメントが整備されている
185
+
186
+ **マージ推奨**: 問題なし ✅
@@ -0,0 +1,36 @@
1
+ # CLIテンプレートの旧Phase形式参照をStory形式に修正
2
+
3
+ ## Context
4
+
5
+ QAテスト構造をタスクグループ単位(`phase{N}/{N}-{M}.md`)からユーザーストーリー単位(`story{N}.md`)に移行済み。エージェント定義・Skill・コマンドはStory形式に更新済みだが、CLIテンプレート1ファイルに旧Phase形式への参照が残っている。
6
+
7
+ 完了済み実タスク(issue21, 22, 101)の旧形式QAテストは配布対象外(`.templateignore`で除外)のため放置。
8
+
9
+ ---
10
+
11
+ ## 修正対象
12
+
13
+ ### `packages/cli/templates/qa-test.md.template` L83-84
14
+
15
+ ```diff
16
+ - - ログファイル: `qa-tests/phaseX/evidence/X-Y-1-*.log`
17
+ - - スクリーンショット: `qa-tests/phaseX/evidence/X-Y-1-*.png`
18
+ + - ログファイル: `qa-tests/evidence/story{N}/AC{N}-{M}-*.log`
19
+ + - スクリーンショット: `qa-tests/evidence/story{N}/AC{N}-{M}-*.png`
20
+ ```
21
+
22
+ ---
23
+
24
+ ## 検証
25
+
26
+ ```bash
27
+ # 旧形式参照が残っていないことを確認
28
+ grep -r "phaseX\|phase{N}\|phase1/" packages/cli/templates/ --include="*.md*"
29
+ # → 出力なしなら完了
30
+ ```
31
+
32
+ ## コミット
33
+
34
+ ```
35
+ docs: CLIテンプレートのQAテストパスをStory形式に修正
36
+ ```
@@ -0,0 +1,47 @@
1
+ # Plan: seed → project-private 変換テスト追加
2
+
3
+ ## 目的
4
+ `@einja:seed` → `@einja:project-private` 変換が正しく動作することを単体テストで保証する。
5
+
6
+ ## テスト一覧
7
+
8
+ ### Group A: marker-processor.test.ts(#1, #2, #9)
9
+
10
+ | # | テスト | ケース |
11
+ |---|--------|--------|
12
+ | 1 | `parseMarkers()` legacy seed認識 | Markdown legacy seed → type: "project-private" で返る |
13
+ | 1 | `parseMarkers()` legacy seed認識 | YAML legacy seed → type: "project-private" で返る |
14
+ | 1 | `parseMarkers()` legacy seed認識 | legacy seed + managed混在 → 両方正しくパース |
15
+ | 1 | `parseMarkers()` legacy seed認識 | legacy seed ID属性保持 |
16
+ | 2 | `migrateLegacySeedMarkers()` 詳細 | managed + seed混在 → seedのみ変換、managedはそのまま |
17
+ | 2 | `migrateLegacySeedMarkers()` 詳細 | YAML形式のseed → 変換 |
18
+ | 2 | `migrateLegacySeedMarkers()` 詳細 | 空seedセクション(マーカーペアのみ) |
19
+ | 2 | `migrateLegacySeedMarkers()` 詳細 | 複数seedマーカー → すべて変換 |
20
+ | 2 | `migrateLegacySeedMarkers()` 詳細 | ID属性を含むseed → ID保持して変換 |
21
+ | 9 | `validateMarkers()` legacy seed | legacy seedでID欠落 → エラー検出 |
22
+ | 9 | `validateMarkers()` legacy seed | legacy seedのネスト → エラー検出 |
23
+
24
+ ### Group B: project-private-synchronizer.test.ts(#3, #4)
25
+
26
+ | # | テスト | ケース |
27
+ |---|--------|--------|
28
+ | 3 | `syncProjectPrivateSections()` legacy | ローカルがlegacy seed → ID認識して重複追加しない |
29
+ | 3 | `syncProjectPrivateSections()` legacy | ローカルがlegacy seed + テンプレートが新規PP → 新規のみ追加 |
30
+ | 4 | `syncProjectPrivateOnlyFile()` legacy | legacy seedファイル → PP抽出・本文マージ・PP再付加が動く |
31
+ | 4 | `syncProjectPrivateOnlyFile()` legacy | legacy seedの空セクション → 存在扱い(テンプレートでseedしない) |
32
+
33
+ ### Group C: integration.test.ts(#6, #7, #8)
34
+
35
+ | # | テスト | ケース |
36
+ |---|--------|--------|
37
+ | 6 | E2Eマイグレーション | legacy seed入力 → migrateLegacySeedMarkers → parseMarkers → replaceManaged → 正常出力 |
38
+ | 6 | E2Eマイグレーション | legacy seed + managed混在 → マイグレーション後にmanaged置換 + PP保持 |
39
+ | 6 | E2Eマイグレーション | legacy seed(managedなし)→ マイグレーション後に3方向マージ + PP保持 |
40
+ | 7 | hasMarkers() | `@einja:seed:start` を含む → true |
41
+ | 7 | hasMarkers() | `@einja:project-private:start` を含む → true |
42
+ | 7 | hasMarkers() | マーカーなし → false |
43
+ | 8 | validateMarkers() + migration | legacy seed → マイグレーション → バリデーション通過 |
44
+
45
+ ## 実装方針
46
+ - 既存テストファイルにdescribeブロックを追加(新規ファイルは作らない)
47
+ - Group A, B, Cを並行で実装可能(ファイルが異なる)