create-einja-app 0.3.2 → 0.3.3

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 (53) hide show
  1. package/README.md +33 -0
  2. package/dist/cli.js +60 -64
  3. package/dist/cli.js.map +1 -1
  4. package/package.json +1 -1
  5. package/templates/default/.changeset/config.json +11 -0
  6. package/templates/default/.claude/hooks/einja/plan-mode-skill-loader.sh +5 -1
  7. package/templates/default/.claude/settings.json +14 -0
  8. package/templates/default/.claude/skills/cli-package-specs/SKILL.md +247 -0
  9. package/templates/default/.einja-sync.json +1 -1
  10. package/templates/default/.github/release.yml +10 -0
  11. package/templates/default/.github/workflows/changeset-status.yml +60 -0
  12. package/templates/default/.github/workflows/deploy-stable-branches.yml +289 -59
  13. package/templates/default/CLAUDE.md +35 -8
  14. package/templates/default/README.md +20 -8
  15. package/templates/default/docs/plans/agile-munching-knuth.md +161 -0
  16. package/templates/default/docs/plans/agile-riding-nova.md +158 -0
  17. package/templates/default/docs/plans/agile-wibbling-dusk.md +91 -0
  18. package/templates/default/docs/plans/ancient-watching-otter.md +152 -0
  19. package/templates/default/docs/plans/bright-sauteeing-bumblebee.md +30 -0
  20. package/templates/default/docs/plans/composed-doodling-mountain.md +362 -0
  21. package/templates/default/docs/plans/dazzling-foraging-cascade.md +32 -0
  22. package/templates/default/docs/plans/enchanted-wiggling-ember-agent-a5befd57d0ca4c7c7.md +177 -0
  23. package/templates/default/docs/plans/enchanted-wiggling-ember.md +170 -0
  24. package/templates/default/docs/plans/federated-questing-kahan.md +47 -0
  25. package/templates/default/docs/plans/flickering-pondering-hearth.md +26 -0
  26. package/templates/default/docs/plans/fluttering-snuggling-sprout.md +172 -0
  27. package/templates/default/docs/plans/generic-sleeping-snowglobe-agent-a41d8da.md +179 -0
  28. package/templates/default/docs/plans/generic-sleeping-snowglobe.md +108 -0
  29. package/templates/default/docs/plans/generic-snuggling-pudding.md +57 -0
  30. package/templates/default/docs/plans/idempotent-wiggling-cherny.md +122 -0
  31. package/templates/default/docs/plans/recursive-fluttering-mitten.md +176 -0
  32. package/templates/default/docs/plans/todo-create-einja-app-ux-fix.md +16 -0
  33. package/templates/default/docs/plans/todo-direnv-hang-fix.md +12 -0
  34. package/templates/default/docs/plans/todo-github-actions-release-workflow.md +34 -0
  35. package/templates/default/docs/plans/todo-issue-spec-rename.md +24 -0
  36. package/templates/default/docs/plans/todo-skill-creator-upgrade.md +18 -0
  37. package/templates/default/docs/plans/velvety-chasing-spark.md +28 -0
  38. package/templates/default/docs/plans/wondrous-strolling-crystal-agent-a0615fc.md +215 -0
  39. package/templates/default/docs/plans/wondrous-strolling-crystal.md +182 -0
  40. package/templates/default/docs/plans/zesty-roaming-steele.md +74 -0
  41. package/templates/default/gitignore +6 -2
  42. package/templates/default/package.json +6 -2
  43. package/templates/default/pnpm-lock.yaml +547 -0
  44. package/templates/default/scripts/ensure-serena.sh +2 -2
  45. package/templates/default/scripts/env-rotate-secrets.ts +66 -6
  46. package/templates/default/scripts/init-github.ts +363 -0
  47. package/templates/default/scripts/init.sh +11 -5
  48. package/templates/default/scripts/setup-dev.ts +16 -1
  49. package/templates/default/.claude/skills/create-einja-app-release/SKILL.md +0 -186
  50. package/templates/default/.claude/skills/dev-cli-release/SKILL.md +0 -173
  51. package/templates/default/.cursor/commands/spec-create.md +0 -227
  52. package/templates/default/.cursor/commands/task-exec.md +0 -287
  53. package/templates/default/.cursor/commands/update-docs-by-task-specs.md +0 -448
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-einja-app",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "CLI tool to create new projects with Einja Management Template",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,11 @@
1
+ {
2
+ "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json",
3
+ "changelog": ["@changesets/changelog-github", { "repo": "einja-inc/einja-management-template" }],
4
+ "commit": false,
5
+ "fixed": [],
6
+ "linked": [],
7
+ "access": "restricted",
8
+ "baseBranch": "main",
9
+ "updateInternalDependencies": "patch",
10
+ "ignore": ["@einja/dev-cli", "create-einja-app"]
11
+ }
@@ -18,6 +18,10 @@ if [[ "$permission_mode" != "plan" ]]; then
18
18
  fi
19
19
 
20
20
  # 軽量リマインダーを注入
21
+ # UserPromptSubmit の additionalContext は hookSpecificOutput 内に配置する必要がある
21
22
  jq -n '{
22
- "additionalContext": "【Plan mode自動リマインダー】計画作成前にeinja-skill-firstの評価を実施してください。.claude/skills/einja-skill-first/SKILL.mdを参照し、スキップ基準に該当しない場合はSkill作成の必要性を評価してください。スキップ基準(単発の小規模修正、既存キーワードトリガー一致、具体的かつ限定的な作業指示、1回限りの作業)に該当する場合は省略可。"
23
+ "hookSpecificOutput": {
24
+ "hookEventName": "UserPromptSubmit",
25
+ "additionalContext": "【Plan mode自動リマインダー】計画作成前にeinja-skill-firstの評価を実施してください。.claude/skills/einja-skill-first/SKILL.mdを参照し、スキップ基準に該当しない場合はSkill作成の必要性を評価してください。スキップ基準(単発の小規模修正、既存キーワードトリガー一致、具体的かつ限定的な作業指示、1回限りの作業)に該当する場合は省略可。"
26
+ }
23
27
  }'
@@ -78,6 +78,20 @@
78
78
  "mcp__playwright__browser_network_requests",
79
79
  "mcp__playwright__browser_close",
80
80
  "mcp__playwright__browser_resize",
81
+ "mcp__pencil__batch_design",
82
+ "mcp__pencil__batch_get",
83
+ "mcp__pencil__find_empty_space_on_canvas",
84
+ "mcp__pencil__get_editor_state",
85
+ "mcp__pencil__get_guidelines",
86
+ "mcp__pencil__get_screenshot",
87
+ "mcp__pencil__get_style_guide",
88
+ "mcp__pencil__get_style_guide_tags",
89
+ "mcp__pencil__get_variables",
90
+ "mcp__pencil__open_document",
91
+ "mcp__pencil__replace_all_matching_properties",
92
+ "mcp__pencil__search_all_unique_properties",
93
+ "mcp__pencil__set_variables",
94
+ "mcp__pencil__snapshot_layout",
81
95
  "mcp__serena",
82
96
  "mcp__serena__activate_project",
83
97
  "mcp__serena__check_onboarding_performed",
@@ -0,0 +1,247 @@
1
+ ---
2
+ name: cli-package-specs
3
+ description: "@einja/dev-cli と create-einja-app のビルド・テンプレート仕様リファレンス。ファイルマッピング、マーカー仕様、コピーフィルタ条件を集約"
4
+ ---
5
+
6
+ # CLI パッケージ ビルド・テンプレート仕様リファレンス
7
+
8
+ ## 概要
9
+
10
+ このSkillは、2つのCLIパッケージのビルドパイプライン・テンプレート仕様を集約したリファレンスです。
11
+ `einja-` プレフィックスを持たないため、`presets/default/` にはコピーされません。
12
+
13
+ | パッケージ | 役割 |
14
+ |-----------|------|
15
+ | `@einja/dev-cli` (`packages/cli`) | 既存プロジェクトへの `.claude/` 設定・`docs/einja/` 同期。`einja init` / `einja sync` コマンドを提供 |
16
+ | `create-einja-app` (`packages/create-einja-app`) | 新規プロジェクトのスキャフォールディング。テンプレートからプロジェクト全体を生成 |
17
+
18
+ ---
19
+
20
+ ## 1. ビルドパイプライン
21
+
22
+ ### 1.1 `@einja/dev-cli` ビルド
23
+
24
+ `packages/cli/package.json` L21:
25
+ ```
26
+ "prebuild": "node ./scripts/generate-template.mjs && node ./scripts/copy-presets.mjs"
27
+ ```
28
+
29
+ #### Step 1: CLAUDE.md.template 生成
30
+ - **スクリプト**: `packages/cli/scripts/generate-template.mjs`
31
+ - **入力**: プロジェクトルートの `CLAUDE.md`
32
+ - **出力**: `packages/cli/presets/default/CLAUDE.md.template`
33
+ - **処理**:
34
+ 1. `@einja:excluded` マーカー内を除去(L53-56)
35
+ 2. `pnpm install` 等のコマンドをプレースホルダー(`{{INSTALL_COMMAND}}`等)に変換(L25-35, L62-69)
36
+
37
+ #### Step 2: プリセットファイルコピー + マーカーバリデーション
38
+ - **スクリプト**: `packages/cli/scripts/copy-presets.mjs`
39
+ - **処理順序**:
40
+ 1. `docs/einja/` 配下のマーカーバリデーション(L303-317)
41
+ 2. ディレクトリマッピングに基づくコピー(L47-122)
42
+ 3. 単一ファイルのコピー(L125-156)
43
+ 4. シンボリックリンク情報の `symlinks.json` 出力(L284-295)
44
+
45
+ ### 1.2 `create-einja-app` テンプレート更新
46
+
47
+ - **スクリプト**: `scripts/_template-update.ts`(ルート)
48
+ - **出力先**: `packages/create-einja-app/templates/default/`
49
+ - **処理**:
50
+ 1. `.templateignore` でフィルタリング(L93-103)
51
+ 2. `README.md` の `@einja:excluded` マーカー除去(L173-185)
52
+ 3. `package.json` の `name` → `{{projectName}}`、`description` → `{{description}}`(L108-131)
53
+ 4. `tsconfig.json` の `@repo/` → `{{packageName}}/`(L136-161)
54
+ 5. `.ts/.tsx/.js/.jsx` の import文 `@repo/` → `{{packageName}}/`(L166-168)
55
+
56
+ ### 1.3 `@einja/dev-cli` プリセット更新(開発用)
57
+
58
+ - **スクリプト**: `scripts/_cli-template-update.ts`
59
+ - **実行**: `pnpm preset:update`(`packages/cli/package.json` L30)
60
+ - **処理**: `FileCopier` クラスを使用してプロジェクト原本をCLIプリセットにコピー
61
+
62
+ ---
63
+
64
+ ## 2. ファイルマッピング
65
+
66
+ ### 2.1 `@einja/dev-cli` コピー対象(`copy-presets.mjs`)
67
+
68
+ #### ディレクトリマッピング(L47-122)
69
+
70
+ | 原本 | コピー先(`presets/default/` 配下) | 備考 |
71
+ |------|--------------------------------------|------|
72
+ | `.claude/agents/einja/` | `.claude/agents/einja/` | |
73
+ | `.claude/commands/einja/` | `.claude/commands/einja/` | |
74
+ | `.claude/skills/einja-*` | `.claude/skills/einja-*/` | 個別列挙(L62-101) |
75
+ | `.claude/hooks/einja/` | `.claude/hooks/einja/` | `cleanParent: true`(L107) |
76
+ | `docs/einja/` | `docs/einja/` | `memory/`, `cli/` を除外(L114) |
77
+ | `scripts/` | `scripts/` | `_` プレフィックスのファイルはスキップ(L247-249) |
78
+
79
+ #### 単一ファイルマッピング(L125-156)
80
+
81
+ | 原本 | コピー先 | 必須 |
82
+ |------|---------|------|
83
+ | `.claude/settings.json` | `.claude/settings.json` | Yes |
84
+ | `.mcp.json` | `.mcp.json` | No |
85
+ | `docs/einja/cli/preset.yaml` | `preset.yaml` | Yes |
86
+ | `.envrc` | `.envrc` | Yes |
87
+ | `.vscode/settings.json` | `.vscode/settings.json` | No |
88
+
89
+ #### 特殊変換
90
+
91
+ | 原本 | コピー先 | 変換内容 |
92
+ |------|---------|---------|
93
+ | `CLAUDE.md` | `CLAUDE.md.template` | `@einja:excluded` 除去 + プレースホルダー変換(`generate-template.mjs`) |
94
+
95
+ ### 2.2 `FileCopier` クラスのマッピング(`file-copier.ts`)
96
+
97
+ **ファイル**: `packages/cli/src/lib/preset-update/file-copier.ts`
98
+
99
+ `FileCopier` は `einja sync` / `preset:update` で使用される。`copy-presets.mjs`(prebuild)とは別のコピーロジック。
100
+
101
+ ディレクトリマッピング(L44-85):
102
+
103
+ | source | destination | category |
104
+ |--------|------------|----------|
105
+ | `.claude/commands` | `.claude/commands/einja` | commands |
106
+ | `.claude/agents` | `.claude/agents/einja` | agents |
107
+ | `.claude/skills` | `.claude/skills` | skills |
108
+ | `.claude/hooks` | `.claude/hooks` | hooks |
109
+ | `docs/einja/steering` | `docs/einja/steering` | docs |
110
+ | `docs/einja/templates` | `docs/einja/templates` | docs |
111
+ | `docs/einja/instructions` | `docs/einja/instructions` | docs |
112
+ | `docs/einja/example` | `docs/einja/example` | docs |
113
+
114
+ 単一ファイルマッピング(L92-104):
115
+
116
+ | source | destination | category |
117
+ |--------|------------|----------|
118
+ | `.envrc` | `.envrc` | env |
119
+ | `.vscode/settings.json` | `.vscode/settings.json` | tools |
120
+
121
+ ---
122
+
123
+ ## 3. コピー対象フィルタ
124
+
125
+ ### 3.1 Skills のプレフィックスフィルタ
126
+
127
+ **ファイル**: `packages/cli/src/lib/preset-update/file-copier.ts` L194-195
128
+
129
+ ```typescript
130
+ // skillsカテゴリの場合、einja-プレフィックスでフィルタリング
131
+ const prefixFilter = mapping.category === "skills" ? "einja-" : undefined;
132
+ ```
133
+
134
+ `.claude/skills/` 配下のトップレベルディレクトリのうち、**`einja-` で始まるもののみ**が配布対象。
135
+
136
+ - **配布される**: `einja-project-overview/`, `einja-task-commit/`, `einja-skill-creator/` 等
137
+ - **配布されない**: `cli-package-specs/`(このSkill自体)、その他 `einja-` プレフィックスなしのSkill
138
+
139
+ `copy-presets.mjs` では個別列挙(L62-101)で同等の制御を実現している。
140
+
141
+ ### 3.2 `_` プレフィックスフィルタ
142
+
143
+ - `copy-presets.mjs` L247-249: `_` で始まるファイル名はスキップ
144
+ - `file-copier.ts` L291: `_` で始まるファイル名はスキップ
145
+
146
+ ### 3.3 隠しファイルフィルタ(`file-copier.ts` のみ)
147
+
148
+ - L303: `.` で始まるファイル名はスキップ(単一ファイルマッピングで明示されたものを除く)
149
+
150
+ ---
151
+
152
+ ## 4. マーカー仕様
153
+
154
+ **詳細仕様書**: `packages/cli/docs/MARKER_SPECIFICATION.md`
155
+ **実装**: `packages/cli/src/lib/sync/marker-processor.ts`
156
+
157
+ ### 4.1 `@einja:excluded`
158
+
159
+ テンプレート生成時に**セクション全体を除去**するマーカー。
160
+
161
+ ```markdown
162
+ <!-- @einja:excluded:start -->
163
+ このセクション内容はテンプレートには含まれない
164
+ <!-- @einja:excluded:end -->
165
+ ```
166
+
167
+ - `generate-template.mjs` L53-56: CLAUDE.md → CLAUDE.md.template 変換時に除去
168
+ - `template-update.ts` L56-67: create-einja-app テンプレート(README.md等)で除去
169
+ - `_template-update.ts` L173-185: 同上
170
+
171
+ ### 4.2 `@einja:managed`
172
+
173
+ `einja sync` 実行時に**常にテンプレート版で上書き**されるセクション。
174
+
175
+ ```markdown
176
+ <!-- @einja:managed:start -->
177
+ 共通ルール(sync時に最新版で上書き)
178
+ <!-- @einja:managed:end -->
179
+ ```
180
+
181
+ - ID属性はオプション: `<!-- @einja:managed:start id="section-a" -->`
182
+ - `marker-processor.ts` L16-17: パース用正規表現
183
+
184
+ ### 4.3 `@einja:project-private`
185
+
186
+ `einja sync` 実行時に**初回のみ追加、以降はユーザー編集を保持**するセクション。
187
+
188
+ ```markdown
189
+ <!-- @einja:project-private:start id="commit-rules-project" -->
190
+ プロジェクト固有の設定(ユーザーが自由に編集)
191
+ <!-- @einja:project-private:end -->
192
+ ```
193
+
194
+ - **ID属性は必須**(`marker-processor.ts` L174-181 でバリデーション)
195
+ - レガシー `@einja:seed` マーカーとの後方互換あり(L44-53, L303-307)
196
+
197
+ ### 4.4 マーカーバリデーション
198
+
199
+ `packages/cli/scripts/validate-markers.mjs` がビルド時(`copy-presets.mjs` L303-317 から呼び出し)に実行。
200
+
201
+ | チェック項目 | エラータイプ |
202
+ |------------|------------|
203
+ | start/end ペア一致 | `unpaired_start` / `unpaired_end` |
204
+ | ネスト禁止 | `nested` |
205
+ | project-private に ID 必須 | `project_private_without_id` |
206
+ | ID 重複禁止 | `duplicate_id` |
207
+
208
+ ---
209
+
210
+ ## 5. `post-setup.ts` 処理フロー
211
+
212
+ **ファイル**: `packages/create-einja-app/src/generators/post-setup.ts`
213
+
214
+ `create-einja-app` でプロジェクト生成後に実行されるセットアップフロー。
215
+
216
+ | Step | 処理 | 行番号 |
217
+ |------|------|--------|
218
+ | 0 | 初回セットアップ(`scripts/init.sh` 実行: Volta/Node.js/pnpm/direnv) | L57-64 |
219
+ | 1 | 依存関係インストール(`pnpm install`) + Prismaクライアント生成(`pnpm db:generate`) | L68-87 |
220
+ | 2 | 秘密鍵の自動ローテーション(`pnpm env:rotate-secrets --all --non-interactive`) | L90-99 |
221
+ | 3 | Git初期化(`git init` → `git add .` → `git commit`) | L102-113 |
222
+ | 4 | `@einja/dev-cli` 初期化(`npx @einja/dev-cli@latest init --force --no-backup`、`config.setupEinjaCli` が true の場合のみ) | L116-125 |
223
+ | 5 | 完了メッセージ表示 | L128 |
224
+
225
+ ---
226
+
227
+ ## 6. `setup-dev.ts` 処理フロー
228
+
229
+ **ファイル**: `scripts/setup-dev.ts`
230
+
231
+ 既存プロジェクトの開発環境セットアップスクリプト。
232
+
233
+ | Step | 処理 | 行番号 |
234
+ |------|------|--------|
235
+ | 1 | Volta インストール確認 | L158-191 |
236
+ | 2 | Volta シェル設定(`VOLTA_FEATURE_PNPM`) | L194-213 |
237
+ | 3 | Node.js / pnpm インストール(`volta install`) | L216-249 |
238
+ | 4 | direnv インストール確認(macOS: `brew install direnv`) | L324-355 |
239
+ | 5 | シェル設定(`direnv hook` を rc ファイルに追加) | L358-376 |
240
+ | 6 | dotenvx インストール | L379-419 |
241
+ | 7 | `.env` ファイル作成(`.env.local` から復号、worktree 対応) | L422-517 |
242
+ | 8 | `.env.personal` 作成 + `GITHUB_TOKEN` 対話設定 | L519-585 |
243
+ | 9 | direnv 有効化(`direnv allow`) | L588-594 |
244
+ | 10 | データベース起動(`docker-compose up -d postgres`) | L597-625 |
245
+ | 11 | データベース初期化(`pnpm db:generate` + `pnpm db:push`) | L610-613 |
246
+
247
+ worktree 環境では `.env.keys` をメインリポジトリから自動コピーする機能あり(L45-67, L73-90)。
@@ -3,7 +3,7 @@
3
3
  "lastSync": "2026-01-04T16:21:21.138Z",
4
4
  "templateVersion": "0.1.0",
5
5
  "files": {
6
- ".claude/commands/einja/update-docs-by-task-specs.md": {
6
+ ".claude/commands/einja/update-docs-by-issue-specs.md": {
7
7
  "hash": "6c09bb6748134849e8de535d6cdb382bfe0aeb0a3fb19730e1c7708ceaa283bc",
8
8
  "syncedAt": "2026-01-04T16:21:21.151Z"
9
9
  },
@@ -0,0 +1,10 @@
1
+ changelog:
2
+ exclude:
3
+ labels: ["dependencies", "skip-changelog"]
4
+ categories:
5
+ - title: "New Features"
6
+ labels: ["enhancement", "feature"]
7
+ - title: "Bug Fixes"
8
+ labels: ["bug", "fix"]
9
+ - title: "Other Changes"
10
+ labels: ["*"]
@@ -0,0 +1,60 @@
1
+ name: Changeset Status
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [main, staging]
6
+ types: [opened, synchronize, reopened]
7
+
8
+ jobs:
9
+ changeset-check:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+ with:
14
+ fetch-depth: 0
15
+
16
+ - name: Check for changesets
17
+ id: check
18
+ run: |
19
+ COUNT=$(ls .changeset/*.md 2>/dev/null | grep -cv README.md || echo 0)
20
+ echo "count=$COUNT" >> $GITHUB_OUTPUT
21
+ echo "has_changesets=$([[ $COUNT -gt 0 ]] && echo true || echo false)" >> $GITHUB_OUTPUT
22
+
23
+ - name: Comment on PR
24
+ uses: actions/github-script@v7
25
+ with:
26
+ script: |
27
+ const count = parseInt('${{ steps.check.outputs.count }}');
28
+ const hasChangesets = '${{ steps.check.outputs.has_changesets }}' === 'true';
29
+ const marker = '<!-- changeset-status -->';
30
+
31
+ let body;
32
+ if (hasChangesets) {
33
+ body = `${marker}\n### ✅ Changeset detected\n\nThis PR includes **${count}** changeset(s). A release will be created when merged.`;
34
+ } else {
35
+ body = `${marker}\n### ⚠️ No changeset found\n\nThis PR does not include a changeset. If this PR includes user-facing changes, please run:\n\n\`\`\`bash\npnpm changeset\n\`\`\`\n\nIf this change doesn't need a release (docs, CI, config), you can ignore this message.`;
36
+ }
37
+
38
+ // Find existing comment
39
+ const comments = await github.rest.issues.listComments({
40
+ owner: context.repo.owner,
41
+ repo: context.repo.repo,
42
+ issue_number: context.issue.number,
43
+ });
44
+ const existing = comments.data.find(c => c.body.includes(marker));
45
+
46
+ if (existing) {
47
+ await github.rest.issues.updateComment({
48
+ owner: context.repo.owner,
49
+ repo: context.repo.repo,
50
+ comment_id: existing.id,
51
+ body,
52
+ });
53
+ } else {
54
+ await github.rest.issues.createComment({
55
+ owner: context.repo.owner,
56
+ repo: context.repo.repo,
57
+ issue_number: context.issue.number,
58
+ body,
59
+ });
60
+ }