create-einja-app 0.3.1 → 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 (120) hide show
  1. package/README.md +34 -1
  2. package/dist/cli.js +92 -80
  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 +27 -0
  7. package/templates/default/.claude/settings.json +29 -1
  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/.env.personal.example +6 -2
  11. package/templates/default/.envrc +5 -0
  12. package/templates/default/.github/release.yml +10 -0
  13. package/templates/default/.github/workflows/changeset-status.yml +60 -0
  14. package/templates/default/.github/workflows/deploy-pr-preview.yml +23 -24
  15. package/templates/default/.github/workflows/deploy-stable-branches.yml +336 -100
  16. package/templates/default/.mcp.json +2 -12
  17. package/templates/default/.serena/project.yml +7 -0
  18. package/templates/default/CLAUDE.md +61 -10
  19. package/templates/default/README.md +22 -10
  20. package/templates/default/apps/admin/package.json +1 -1
  21. package/templates/default/apps/admin/tsconfig.json +2 -1
  22. package/templates/default/apps/web/package.json +1 -1
  23. package/templates/default/apps/web/tsconfig.json +2 -1
  24. package/templates/default/docs/plans/.gitkeep +0 -0
  25. package/templates/default/docs/plans/agile-munching-knuth.md +161 -0
  26. package/templates/default/docs/plans/agile-riding-nova.md +158 -0
  27. package/templates/default/docs/plans/agile-wibbling-dusk.md +91 -0
  28. package/templates/default/docs/plans/ancient-greeting-flamingo-agent-a87e67c.md +221 -0
  29. package/templates/default/docs/plans/ancient-greeting-flamingo-agent-ab73a1c.md +107 -0
  30. package/templates/default/docs/plans/ancient-greeting-flamingo.md +120 -0
  31. package/templates/default/docs/plans/ancient-watching-otter.md +152 -0
  32. package/templates/default/docs/plans/bright-sauteeing-bumblebee.md +30 -0
  33. package/templates/default/docs/plans/bright-stargazing-dawn.md +87 -0
  34. package/templates/default/docs/plans/calm-stirring-bonbon.md +196 -0
  35. package/templates/default/docs/plans/calm-watching-widget.md +111 -0
  36. package/templates/default/docs/plans/cheerful-wiggling-ullman.md +164 -0
  37. package/templates/default/docs/plans/compiled-humming-cherny.md +94 -0
  38. package/templates/default/docs/plans/composed-doodling-mountain.md +362 -0
  39. package/templates/default/docs/plans/dapper-launching-lynx.md +81 -0
  40. package/templates/default/docs/plans/dazzling-foraging-cascade.md +32 -0
  41. package/templates/default/docs/plans/effervescent-munching-kite-agent-ac08baf.md +672 -0
  42. package/templates/default/docs/plans/effervescent-munching-kite-agent-aecc373.md +442 -0
  43. package/templates/default/docs/plans/effervescent-munching-kite.md +263 -0
  44. package/templates/default/docs/plans/enchanted-wiggling-ember-agent-a5befd57d0ca4c7c7.md +177 -0
  45. package/templates/default/docs/plans/enchanted-wiggling-ember.md +170 -0
  46. package/templates/default/docs/plans/federated-questing-kahan.md +47 -0
  47. package/templates/default/docs/plans/fix-orphan-cleaner-review.md +25 -0
  48. package/templates/default/docs/plans/fix-sync-template-variables.md +162 -0
  49. package/templates/default/docs/plans/flickering-pondering-hearth.md +26 -0
  50. package/templates/default/docs/plans/fluttering-snuggling-sprout.md +172 -0
  51. package/templates/default/docs/plans/generic-sleeping-snowglobe-agent-a41d8da.md +179 -0
  52. package/templates/default/docs/plans/generic-sleeping-snowglobe.md +108 -0
  53. package/templates/default/docs/plans/generic-snuggling-pudding.md +57 -0
  54. package/templates/default/docs/plans/glimmering-giggling-sedgewick.md +126 -0
  55. package/templates/default/docs/plans/glittery-swimming-bachman.md +78 -0
  56. package/templates/default/docs/plans/happy-watching-toast.md +56 -0
  57. package/templates/default/docs/plans/harmonic-strolling-nebula.md +210 -0
  58. package/templates/default/docs/plans/idempotent-wiggling-cherny.md +122 -0
  59. package/templates/default/docs/plans/import-alias-refactor.md +75 -0
  60. package/templates/default/docs/plans/lazy-percolating-sloth-agent-abda679.md +346 -0
  61. package/templates/default/docs/plans/lazy-percolating-sloth.md +151 -0
  62. package/templates/default/docs/plans/linked-greeting-llama-agent-a7a6e5b.md +345 -0
  63. package/templates/default/docs/plans/linked-greeting-llama.md +467 -0
  64. package/templates/default/docs/plans/lovely-bubbling-rose.md +80 -0
  65. package/templates/default/docs/plans/optimized-watching-sprout.md +149 -0
  66. package/templates/default/docs/plans/peaceful-beaming-toast-agent-a292da6.md +288 -0
  67. package/templates/default/docs/plans/peaceful-beaming-toast-agent-a819699.md +366 -0
  68. package/templates/default/docs/plans/peaceful-beaming-toast-agent-ac11de2.md +474 -0
  69. package/templates/default/docs/plans/peaceful-beaming-toast.md +345 -0
  70. package/templates/default/docs/plans/purrfect-spinning-hickey-agent-ae6194c.md +300 -0
  71. package/templates/default/docs/plans/purrfect-spinning-hickey-agent-ae6900e.md +444 -0
  72. package/templates/default/docs/plans/purrfect-spinning-hickey.md +361 -0
  73. package/templates/default/docs/plans/recursive-fluttering-mitten.md +176 -0
  74. package/templates/default/docs/plans/recursive-kindling-lemon-agent-a42199e.md +186 -0
  75. package/templates/default/docs/plans/recursive-kindling-lemon.md +36 -0
  76. package/templates/default/docs/plans/seed-migration-tests.md +47 -0
  77. package/templates/default/docs/plans/sprightly-leaping-manatee.md +224 -0
  78. package/templates/default/docs/plans/stateful-wishing-lerdorf.md +161 -0
  79. package/templates/default/docs/plans/streamed-purring-wreath.md +40 -0
  80. package/templates/default/docs/plans/synthetic-percolating-pearl.md +101 -0
  81. package/templates/default/docs/plans/todo-create-einja-app-ux-fix.md +16 -0
  82. package/templates/default/docs/plans/todo-direnv-hang-fix.md +12 -0
  83. package/templates/default/docs/plans/todo-fix-sync-template-variables.md +21 -0
  84. package/templates/default/docs/plans/todo-github-actions-release-workflow.md +34 -0
  85. package/templates/default/docs/plans/todo-issue-spec-rename.md +24 -0
  86. package/templates/default/docs/plans/todo-phase4-marker-update.md +39 -0
  87. package/templates/default/docs/plans/todo-skill-creator-sync.md +23 -0
  88. package/templates/default/docs/plans/todo-skill-creator-upgrade.md +18 -0
  89. package/templates/default/docs/plans/typed-snuggling-parnas-agent-a6f6391.md +476 -0
  90. package/templates/default/docs/plans/typed-snuggling-parnas-agent-adb678b.md +144 -0
  91. package/templates/default/docs/plans/typed-snuggling-parnas.md +84 -0
  92. package/templates/default/docs/plans/velvety-chasing-spark.md +28 -0
  93. package/templates/default/docs/plans/warm-hopping-lighthouse-agent-a30aa4f.md +534 -0
  94. package/templates/default/docs/plans/warm-hopping-lighthouse-agent-a57a278.md +508 -0
  95. package/templates/default/docs/plans/warm-hopping-lighthouse-agent-a90b809.md +421 -0
  96. package/templates/default/docs/plans/warm-hopping-lighthouse.md +199 -0
  97. package/templates/default/docs/plans/wondrous-strolling-crystal-agent-a0615fc.md +215 -0
  98. package/templates/default/docs/plans/wondrous-strolling-crystal.md +182 -0
  99. package/templates/default/docs/plans/zesty-roaming-steele.md +74 -0
  100. package/templates/default/docs/verification-test.md +2 -0
  101. package/templates/default/gitignore +9 -1
  102. package/templates/default/package.json +6 -2
  103. package/templates/default/packages/admin-ui/package.json +1 -1
  104. package/templates/default/packages/server-core/tsconfig.json +6 -1
  105. package/templates/default/pnpm-lock.yaml +823 -57
  106. package/templates/default/scripts/ensure-serena.sh +75 -0
  107. package/templates/default/scripts/env-rotate-secrets.ts +66 -6
  108. package/templates/default/scripts/init-github.ts +363 -0
  109. package/templates/default/scripts/init.sh +11 -5
  110. package/templates/default/scripts/lib/worktree-config.ts +64 -0
  111. package/templates/default/scripts/setup-dev.ts +16 -1
  112. package/templates/default/scripts/stop-serena.sh +25 -0
  113. package/templates/default/scripts/worktree/dev.ts +2 -2
  114. package/templates/default/.claude/skills/create-einja-app-release/SKILL.md +0 -186
  115. package/templates/default/.claude/skills/dev-cli-release/SKILL.md +0 -173
  116. package/templates/default/.cursor/commands/spec-create.md +0 -227
  117. package/templates/default/.cursor/commands/task-exec.md +0 -287
  118. package/templates/default/.cursor/commands/update-docs-by-task-specs.md +0 -448
  119. /package/templates/default/scripts/{cli-template-update.ts → _cli-template-update.ts} +0 -0
  120. /package/templates/default/scripts/{template-update.ts → _template-update.ts} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-einja-app",
3
- "version": "0.3.1",
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
+ }
@@ -0,0 +1,27 @@
1
+ #!/bin/bash
2
+ # plan-mode-skill-loader.sh - Plan mode中にeinja-skill-firstのリマインダーを注入
3
+ #
4
+ # UserPromptSubmit hookとして設定
5
+ # permission_mode == "plan" の場合に、軽量リマインダーをadditionalContextとして注入
6
+ # 毎回注入しても2-3行なのでコスト無視可能。状態管理不要。
7
+
8
+ set -uo pipefail
9
+
10
+ input=$(cat)
11
+
12
+ # permission_modeを取得
13
+ permission_mode=$(echo "$input" | jq -r '.permission_mode // empty')
14
+
15
+ # Plan mode以外はスキップ
16
+ if [[ "$permission_mode" != "plan" ]]; then
17
+ exit 0
18
+ fi
19
+
20
+ # 軽量リマインダーを注入
21
+ # UserPromptSubmit の additionalContext は hookSpecificOutput 内に配置する必要がある
22
+ jq -n '{
23
+ "hookSpecificOutput": {
24
+ "hookEventName": "UserPromptSubmit",
25
+ "additionalContext": "【Plan mode自動リマインダー】計画作成前にeinja-skill-firstの評価を実施してください。.claude/skills/einja-skill-first/SKILL.mdを参照し、スキップ基準に該当しない場合はSkill作成の必要性を評価してください。スキップ基準(単発の小規模修正、既存キーワードトリガー一致、具体的かつ限定的な作業指示、1回限りの作業)に該当する場合は省略可。"
26
+ }
27
+ }'
@@ -1,4 +1,7 @@
1
1
  {
2
+ "env": {
3
+ "CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1"
4
+ },
2
5
  "includeCoAuthoredBy": false,
3
6
  "plansDirectory": "docs/plans",
4
7
  "permissions": {
@@ -75,6 +78,20 @@
75
78
  "mcp__playwright__browser_network_requests",
76
79
  "mcp__playwright__browser_close",
77
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",
78
95
  "mcp__serena",
79
96
  "mcp__serena__activate_project",
80
97
  "mcp__serena__check_onboarding_performed",
@@ -182,9 +199,20 @@
182
199
  }
183
200
  ]
184
201
  }
202
+ ],
203
+ "UserPromptSubmit": [
204
+ {
205
+ "hooks": [
206
+ {
207
+ "type": "command",
208
+ "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/einja/plan-mode-skill-loader.sh",
209
+ "timeout": 5000
210
+ }
211
+ ]
212
+ }
185
213
  ]
186
214
  },
187
215
  "enabledPlugins": {
188
216
  "code-simplifier@claude-plugins-official": true
189
217
  }
190
- }
218
+ }
@@ -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
  },
@@ -19,8 +19,12 @@
19
19
  # 必要なスコープ: repo, read:org
20
20
  GITHUB_TOKEN=
21
21
 
22
- # Claude Code 実験的機能フラグ
23
- ENABLE_TOOL_SEARCH=true
22
+ # Asana APIトークン(プロジェクト管理ツールAsanaのAPIアクセス用)
23
+ # 取得方法: https://app.asana.com/0/my-apps で個人アクセストークンを追加
24
+ ASANA_TOKEN=
25
+
26
+ # Serena MCPサーバーのポート番号(ポート衝突時のみ変更。通常は自動解決)
27
+ # SERENA_PORT=9851
24
28
 
25
29
  # その他の個人用トークン(必要に応じて)
26
30
  # OPENAI_API_KEY=
@@ -23,6 +23,11 @@ MAIN_WORKTREE=$(get_main_worktree)
23
23
  if [ -n "$MAIN_WORKTREE" ] && [ -f "$MAIN_WORKTREE/.env.personal" ]; then
24
24
  dotenv_if_exists "$MAIN_WORKTREE/.env.personal"
25
25
  fi
26
+
27
+ # Serena MCP サーバー自動起動
28
+ if [ -n "$MAIN_WORKTREE" ] && [ -f "$MAIN_WORKTREE/scripts/ensure-serena.sh" ]; then
29
+ source "$MAIN_WORKTREE/scripts/ensure-serena.sh" "$MAIN_WORKTREE"
30
+ fi
26
31
  # @einja:managed:end
27
32
 
28
33
  # @einja:seed:start id="project-env"
@@ -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
+ }
@@ -261,26 +261,6 @@ jobs:
261
261
  echo "name=$PROJECT_NAME" >> $GITHUB_OUTPUT
262
262
  fi
263
263
 
264
- # Vercel環境変数の自動同期(encrypted-only方式:dotenvxで管理しているもの = Vercelに同期すべきもの)
265
- - name: Sync environment variables to Vercel
266
- run: |
267
- # .env.previewから encrypted: を含むキー名を抽出
268
- # NEON_*とDATABASE_*を除外(Neon APIから動的取得・--envで注入するため)
269
- ENCRYPTED_KEYS=$(grep 'encrypted:' $GITHUB_WORKSPACE/.env.preview | sed 's/=.*//' | grep -vE '^(NEON_|DATABASE_)')
270
-
271
- npx dotenvx run -f $GITHUB_WORKSPACE/.env.preview -- bash -c "
272
- for key in $ENCRYPTED_KEYS; do
273
- value=\$(printenv \"\$key\" 2>/dev/null || true)
274
- if [ -n \"\$value\" ]; then
275
- echo \"Syncing \$key to Vercel (preview)...\"
276
- echo \"\$value\" | vercel env rm \"\$key\" preview --yes --token=\$VERCEL_TOKEN 2>/dev/null || true
277
- echo \"\$value\" | vercel env add \"\$key\" preview --token=\$VERCEL_TOKEN
278
- fi
279
- done
280
- "
281
- env:
282
- DOTENV_PRIVATE_KEY_PREVIEW: ${{ secrets.DOTENV_PRIVATE_KEY_PREVIEW }}
283
-
284
264
  # NOTE: dotenvxはデフォルトで既存の環境変数を上書きしない
285
265
  # env:で設定したDATABASE_URLがNeonブランチのURLとして優先される
286
266
  - name: Build Project (apps/${{ matrix.app }})
@@ -291,13 +271,32 @@ jobs:
291
271
  DOTENV_PRIVATE_KEY_PREVIEW: ${{ secrets.DOTENV_PRIVATE_KEY_PREVIEW }}
292
272
  DATABASE_URL: ${{ steps.db-urls.outputs.db_url_pooled }}
293
273
 
294
- # Vercel Deploy(ランタイムにもDATABASE_URLを渡す)
295
274
  - name: Deploy to Vercel
296
275
  id: deploy
297
276
  run: |
298
- DEPLOY_URL=$(vercel deploy --prebuilt --token=$VERCEL_TOKEN \
299
- --env DATABASE_URL="${{ steps.db-urls.outputs.db_url_pooled }}")
300
- echo "url=$DEPLOY_URL" >> $GITHUB_OUTPUT
277
+ npx dotenvx run -f $GITHUB_WORKSPACE/.env.preview -- bash -c '
278
+ declare -a ENV_FLAGS=()
279
+ while IFS= read -r key; do
280
+ case "$key" in
281
+ NEON_*|DOTENV_PUBLIC_KEY_*) continue ;;
282
+ esac
283
+ value="${!key}"
284
+ if [ -n "$value" ]; then
285
+ echo "::add-mask::${value}"
286
+ fi
287
+ ENV_FLAGS+=("--env" "${key}=${value}")
288
+ done < <(grep -E "^[A-Z_][A-Z0-9_]*=\"?encrypted:" "$GITHUB_WORKSPACE/.env.preview" | cut -d= -f1)
289
+
290
+ # DATABASE_URLはNeon APIから取得した値を注入(.env.previewには含まれない)
291
+ ENV_FLAGS+=("--env" "DATABASE_URL=${DATABASE_URL}")
292
+
293
+ echo "Deploying with ${#ENV_FLAGS[@]} runtime env vars..."
294
+ DEPLOY_URL=$(vercel deploy --prebuilt "${ENV_FLAGS[@]}" --token="$VERCEL_TOKEN")
295
+ echo "url=$DEPLOY_URL" >> "$GITHUB_OUTPUT"
296
+ '
297
+ env:
298
+ DOTENV_PRIVATE_KEY_PREVIEW: ${{ secrets.DOTENV_PRIVATE_KEY_PREVIEW }}
299
+ DATABASE_URL: ${{ steps.db-urls.outputs.db_url_pooled }}
301
300
 
302
301
  - name: Set Vercel alias
303
302
  if: steps.project-name.outputs.name != ''