@einja/dev-cli 0.1.40 → 0.1.44

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 (207) hide show
  1. package/README.md +89 -1
  2. package/dist/cli.js +1 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/init.d.ts.map +1 -1
  5. package/dist/commands/init.js +71 -1
  6. package/dist/commands/init.js.map +1 -1
  7. package/dist/commands/list.js.map +1 -1
  8. package/dist/commands/sync.d.ts.map +1 -1
  9. package/dist/commands/sync.js +187 -13
  10. package/dist/commands/sync.js.map +1 -1
  11. package/dist/commands/task-loop/lib/github-client.test.js.map +1 -1
  12. package/dist/commands/task-loop/lib/vibe-kanban-rest-client.js +2 -2
  13. package/dist/commands/task-loop/lib/vibe-kanban-rest-client.js.map +1 -1
  14. package/dist/lib/dependency-checker.d.ts.map +1 -1
  15. package/dist/lib/merger.d.ts +12 -0
  16. package/dist/lib/merger.d.ts.map +1 -1
  17. package/dist/lib/merger.js +28 -0
  18. package/dist/lib/merger.js.map +1 -1
  19. package/dist/lib/preset-update/cli-repo-detector.d.ts.map +1 -1
  20. package/dist/lib/preset-update/file-copier.d.ts.map +1 -1
  21. package/dist/lib/preset-update/file-copier.js +3 -3
  22. package/dist/lib/preset-update/file-copier.js.map +1 -1
  23. package/dist/lib/preset-update/preset-finder.d.ts.map +1 -1
  24. package/dist/lib/preset.d.ts.map +1 -1
  25. package/dist/lib/sync/category-validator.d.ts +1 -1
  26. package/dist/lib/sync/category-validator.d.ts.map +1 -1
  27. package/dist/lib/sync/category-validator.js +2 -1
  28. package/dist/lib/sync/category-validator.js.map +1 -1
  29. package/dist/lib/sync/category-validator.test.js +3 -1
  30. package/dist/lib/sync/category-validator.test.js.map +1 -1
  31. package/dist/lib/sync/conflict-reporter.d.ts.map +1 -1
  32. package/dist/lib/sync/diff-engine.d.ts.map +1 -1
  33. package/dist/lib/sync/file-filter.d.ts.map +1 -1
  34. package/dist/lib/sync/file-filter.js +1 -0
  35. package/dist/lib/sync/file-filter.js.map +1 -1
  36. package/dist/lib/sync/integration.test.js +255 -69
  37. package/dist/lib/sync/integration.test.js.map +1 -1
  38. package/dist/lib/sync/json-processor.d.ts +4 -4
  39. package/dist/lib/sync/json-processor.d.ts.map +1 -1
  40. package/dist/lib/sync/json-processor.js +11 -11
  41. package/dist/lib/sync/json-processor.js.map +1 -1
  42. package/dist/lib/sync/marker-processor.d.ts +60 -8
  43. package/dist/lib/sync/marker-processor.d.ts.map +1 -1
  44. package/dist/lib/sync/marker-processor.js +117 -26
  45. package/dist/lib/sync/marker-processor.js.map +1 -1
  46. package/dist/lib/sync/marker-processor.test.js +261 -40
  47. package/dist/lib/sync/marker-processor.test.js.map +1 -1
  48. package/dist/lib/sync/metadata-manager.d.ts +4 -0
  49. package/dist/lib/sync/metadata-manager.d.ts.map +1 -1
  50. package/dist/lib/sync/metadata-manager.js +15 -0
  51. package/dist/lib/sync/metadata-manager.js.map +1 -1
  52. package/dist/lib/sync/metadata-manager.test.js +69 -0
  53. package/dist/lib/sync/metadata-manager.test.js.map +1 -1
  54. package/dist/lib/sync/orphan-cleaner.d.ts +29 -0
  55. package/dist/lib/sync/orphan-cleaner.d.ts.map +1 -0
  56. package/dist/lib/sync/orphan-cleaner.js +80 -0
  57. package/dist/lib/sync/orphan-cleaner.js.map +1 -0
  58. package/dist/lib/sync/orphan-cleaner.test.d.ts +2 -0
  59. package/dist/lib/sync/orphan-cleaner.test.d.ts.map +1 -0
  60. package/dist/lib/sync/orphan-cleaner.test.js +169 -0
  61. package/dist/lib/sync/orphan-cleaner.test.js.map +1 -0
  62. package/dist/lib/sync/project-private-synchronizer.d.ts +52 -0
  63. package/dist/lib/sync/project-private-synchronizer.d.ts.map +1 -0
  64. package/dist/lib/sync/project-private-synchronizer.js +110 -0
  65. package/dist/lib/sync/project-private-synchronizer.js.map +1 -0
  66. package/dist/lib/sync/project-private-synchronizer.test.d.ts +2 -0
  67. package/dist/lib/sync/project-private-synchronizer.test.d.ts.map +1 -0
  68. package/dist/lib/sync/project-private-synchronizer.test.js +348 -0
  69. package/dist/lib/sync/project-private-synchronizer.test.js.map +1 -0
  70. package/dist/types/index.d.ts +1 -0
  71. package/dist/types/index.d.ts.map +1 -1
  72. package/dist/types/sync.d.ts +36 -6
  73. package/dist/types/sync.d.ts.map +1 -1
  74. package/dist/types/sync.js +2 -2
  75. package/dist/types/sync.js.map +1 -1
  76. package/package.json +5 -4
  77. package/presets/default/.claude/agents/einja/Explore.md +140 -0
  78. package/presets/default/.claude/agents/einja/backend-architect.md +21 -1
  79. package/presets/default/.claude/agents/einja/codex-agent.md +5 -1
  80. package/presets/default/.claude/agents/einja/design-engineer.md +5 -1
  81. package/presets/default/.claude/agents/einja/docs/docs-updater.md +7 -93
  82. package/presets/default/.claude/agents/einja/frontend-architect.md +21 -1
  83. package/presets/default/.claude/agents/einja/frontend-coder.md +5 -1
  84. package/presets/default/.claude/agents/einja/{specs/spec-design-generator.md → issue-specs/design-generator.md} +16 -8
  85. package/presets/default/.claude/agents/einja/{specs/spec-qa-generator.md → issue-specs/qa-generator.md} +10 -4
  86. package/presets/default/.claude/agents/einja/{specs/spec-requirements-generator.md → issue-specs/requirements-generator.md} +9 -6
  87. package/presets/default/.claude/agents/einja/{specs/spec-tasks-generator.md → issue-specs/tasks-generator.md} +19 -16
  88. package/presets/default/.claude/agents/einja/{specs/spec-tasks-validator.md → issue-specs/tasks-validator.md} +13 -9
  89. package/presets/default/.claude/agents/einja/issue-specs/ui-design-generator.md +114 -0
  90. package/presets/default/.claude/agents/einja/task/task-executer.md +64 -116
  91. package/presets/default/.claude/agents/einja/task/task-modification-analyzer.md +6 -2
  92. package/presets/default/.claude/agents/einja/task/task-qa.md +7 -3
  93. package/presets/default/.claude/agents/einja/task/task-reviewer.md +17 -1
  94. package/presets/default/.claude/commands/einja/einja-sync.md +124 -45
  95. package/presets/default/.claude/commands/einja/frontend-implement.md +3 -1
  96. package/presets/default/.claude/commands/einja/issue-exec.md +413 -0
  97. package/presets/default/.claude/commands/einja/start-dev.md +4 -0
  98. package/presets/default/.claude/commands/einja/sync-cursor-commands.md +10 -6
  99. package/presets/default/.claude/commands/einja/{update-docs-by-task-specs.md → update-docs-by-issue-specs.md} +61 -57
  100. package/presets/default/.claude/hooks/einja/plan-mode-skill-loader.sh +27 -0
  101. package/presets/default/.claude/settings.json +29 -5
  102. package/presets/default/.claude/skills/{einja-general-context-loader → _einja-general-context-loader}/SKILL.md +6 -2
  103. package/presets/default/.claude/skills/{einja-output-format → _einja-output-format}/SKILL.md +5 -1
  104. package/presets/default/.claude/skills/_einja-project-overview/SKILL.md +29 -0
  105. package/presets/default/.claude/skills/{einja-spec-context-loader → _einja-spec-context-loader}/SKILL.md +9 -5
  106. package/presets/default/.claude/skills/einja-coding-standards/references/testing-strategy.md +899 -0
  107. package/presets/default/.claude/skills/einja-conflict-resolver/SKILL.md +5 -1
  108. package/presets/default/.claude/skills/einja-create-pr/SKILL.md +138 -0
  109. package/presets/default/.claude/skills/einja-infra-maintenance/SKILL.md +779 -0
  110. package/presets/default/.claude/{commands/einja/spec-create.md → skills/einja-issue-spec-create/SKILL.md} +60 -23
  111. package/presets/default/.claude/skills/einja-issue-spec-generator/SKILL.md +105 -0
  112. package/presets/default/.claude/skills/einja-issue-spec-generator/references/format-rules.md +35 -0
  113. package/presets/default/.claude/skills/einja-issue-spec-validator/SKILL.md +130 -0
  114. package/presets/default/.claude/skills/einja-issue-spec-validator/references/validation-rules.md +52 -0
  115. package/presets/default/.claude/skills/einja-npm-release/SKILL.md +242 -0
  116. package/presets/default/.claude/skills/einja-skill-creator/SKILL.md +311 -263
  117. package/presets/default/.claude/skills/einja-skill-creator/agents/analyzer.md +274 -0
  118. package/presets/default/.claude/skills/einja-skill-creator/agents/comparator.md +202 -0
  119. package/presets/default/.claude/skills/einja-skill-creator/agents/grader.md +195 -0
  120. package/presets/default/.claude/skills/einja-skill-creator/assets/eval_review.html +146 -0
  121. package/presets/default/.claude/skills/einja-skill-creator/eval-viewer/generate_review.py +471 -0
  122. package/presets/default/.claude/skills/einja-skill-creator/eval-viewer/viewer.html +1325 -0
  123. package/presets/default/.claude/skills/einja-skill-creator/references/schemas.md +430 -0
  124. package/presets/default/.claude/skills/einja-skill-creator/scripts/aggregate_benchmark.py +401 -0
  125. package/presets/default/.claude/skills/einja-skill-creator/scripts/compare_runs.py +154 -0
  126. package/presets/default/.claude/skills/einja-skill-creator/scripts/generate_report.py +272 -0
  127. package/presets/default/.claude/skills/einja-skill-creator/scripts/improve_description.py +247 -0
  128. package/presets/default/.claude/skills/einja-skill-creator/scripts/init_skill.py +13 -19
  129. package/presets/default/.claude/skills/einja-skill-creator/scripts/package_skill.py +36 -7
  130. package/presets/default/.claude/skills/einja-skill-creator/scripts/run_eval.py +310 -0
  131. package/presets/default/.claude/skills/einja-skill-creator/scripts/run_loop.py +375 -0
  132. package/presets/default/.claude/skills/einja-skill-creator/scripts/utils.py +48 -0
  133. package/presets/default/.claude/skills/einja-skill-first/SKILL.md +265 -0
  134. package/presets/default/.claude/skills/einja-subagent-question-protocol/SKILL.md +98 -0
  135. package/presets/default/.claude/skills/einja-task-commit/SKILL.md +11 -7
  136. package/presets/default/.claude/{commands/einja/task-exec.md → skills/einja-task-exec/SKILL.md} +106 -89
  137. package/presets/default/.claude/skills/einja-task-qa/SKILL.md +8 -4
  138. package/presets/default/.claude/skills/einja-task-qa/references/troubleshooting.md +1 -1
  139. package/presets/default/.claude/skills/einja-task-qa/references/usage-patterns.md +2 -2
  140. package/presets/default/.claude/skills/einja-team-exec/SKILL.md +165 -0
  141. package/presets/default/.envrc +5 -0
  142. package/presets/default/.mcp.json +2 -12
  143. package/presets/default/CLAUDE.md.template +45 -8
  144. package/presets/default/docs/einja/example/specs/issues/issue999-example-task/tasks.md +1 -1
  145. package/presets/default/docs/einja/instructions/deployment-setup.md +4 -9
  146. package/presets/default/docs/einja/instructions/environment-setup.md +3 -8
  147. package/presets/default/docs/einja/instructions/issue-exec-workflow.md +276 -0
  148. package/presets/default/docs/einja/instructions/local-server-environment-and-worktree.md +71 -9
  149. package/presets/default/docs/einja/instructions/neon-cli-reference.md +3 -8
  150. package/presets/default/docs/einja/instructions/setup-flow.md +279 -0
  151. package/presets/default/docs/einja/instructions/task-execute.md +63 -68
  152. package/presets/default/docs/einja/instructions/vercel-cli-reference.md +17 -10
  153. package/presets/default/docs/einja/steering/README.md +11 -11
  154. package/presets/default/docs/einja/steering/acceptance-criteria-and-qa-guide.md +4 -9
  155. package/presets/default/docs/einja/steering/architecture.md +3 -8
  156. package/presets/default/docs/einja/steering/branch-strategy.md +63 -70
  157. package/presets/default/docs/einja/steering/commit-rules.md +3 -8
  158. package/presets/default/docs/einja/steering/db-schema-design.md +3 -8
  159. package/presets/default/docs/einja/steering/development/api-development.md +3 -8
  160. package/presets/default/docs/einja/steering/development/backend-architecture.md +3 -8
  161. package/presets/default/docs/einja/steering/development/coding-standards.md +723 -0
  162. package/presets/default/docs/einja/steering/development/component-design.md +502 -0
  163. package/presets/default/docs/einja/steering/development/database-guidelines.md +2 -2
  164. package/presets/default/docs/einja/steering/development/frontend-development.md +3 -8
  165. package/presets/default/docs/einja/steering/development/playwright-guidelines.md +59 -0
  166. package/presets/default/docs/einja/steering/development/review-guidelines.md +3 -8
  167. package/presets/default/docs/einja/steering/development/testing-strategy.md +3 -8
  168. package/presets/default/docs/einja/steering/development-workflow.md +155 -140
  169. package/presets/default/docs/einja/steering/infrastructure/deployment.md +156 -55
  170. package/presets/default/docs/einja/steering/infrastructure/environment-variables.md +4 -8
  171. package/presets/default/docs/einja/steering/product.md +3 -8
  172. package/presets/default/docs/einja/steering/task-management.md +22 -110
  173. package/presets/default/scripts/ensure-serena.sh +75 -0
  174. package/presets/default/scripts/env-rotate-secrets.ts +396 -0
  175. package/presets/default/scripts/env-show.ts +130 -0
  176. package/presets/default/scripts/env.ts +479 -0
  177. package/presets/default/scripts/init-github.ts +363 -0
  178. package/presets/default/scripts/init.sh +98 -0
  179. package/presets/default/scripts/lib/env-common.ts +108 -0
  180. package/presets/default/scripts/lib/worktree-config.ts +64 -0
  181. package/presets/default/scripts/setup-dev.ts +655 -0
  182. package/presets/default/scripts/stop-serena.sh +25 -0
  183. package/presets/default/scripts/worktree/dev.ts +872 -0
  184. package/dist/lib/sync/seed-synchronizer.d.ts +0 -27
  185. package/dist/lib/sync/seed-synchronizer.d.ts.map +0 -1
  186. package/dist/lib/sync/seed-synchronizer.js +0 -72
  187. package/dist/lib/sync/seed-synchronizer.js.map +0 -1
  188. package/dist/lib/sync/seed-synchronizer.test.d.ts +0 -2
  189. package/dist/lib/sync/seed-synchronizer.test.d.ts.map +0 -1
  190. package/dist/lib/sync/seed-synchronizer.test.js +0 -147
  191. package/dist/lib/sync/seed-synchronizer.test.js.map +0 -1
  192. package/presets/default/.claude/agents/einja/git/conflict-resolver.md +0 -148
  193. package/presets/default/.claude/hooks/einja/validate-git-commit.sh +0 -239
  194. package/presets/default/.claude/skills/einja-api-development/SKILL.md +0 -14
  195. package/presets/default/.claude/skills/einja-backend-architecture/SKILL.md +0 -18
  196. package/presets/default/.claude/skills/einja-coding-standards/SKILL.md +0 -132
  197. package/presets/default/.claude/skills/einja-coding-standards/references/import-conventions.md +0 -69
  198. package/presets/default/.claude/skills/einja-coding-standards/references/naming-conventions.md +0 -107
  199. package/presets/default/.claude/skills/einja-coding-standards/references/prohibited-patterns.md +0 -169
  200. package/presets/default/.claude/skills/einja-coding-standards/references/typescript-rules.md +0 -247
  201. package/presets/default/.claude/skills/einja-component-design/SKILL.md +0 -109
  202. package/presets/default/.claude/skills/einja-component-design/references/directory-structure.md +0 -117
  203. package/presets/default/.claude/skills/einja-component-design/references/props-patterns.md +0 -159
  204. package/presets/default/.claude/skills/einja-component-design/references/styling-guide.md +0 -122
  205. package/presets/default/.claude/skills/einja-frontend-development/SKILL.md +0 -14
  206. package/presets/default/.claude/skills/einja-project-overview/SKILL.md +0 -35
  207. package/presets/default/docs/einja/instructions/task-vibe-kanban-loop.md +0 -565
@@ -1,27 +0,0 @@
1
- /**
2
- * @einja:seedマーカーの同期を行うクラス
3
- *
4
- * seedマーカーはプロジェクト固有のテンプレートを提供します。
5
- * - ファイルにseed(ID)がない場合: テンプレートから追加
6
- * - ファイルにseed(ID)がある場合: 保持(上書きしない)
7
- */
8
- export declare class SeedSynchronizer {
9
- private readonly processor;
10
- /**
11
- * seedセクションを同期する
12
- *
13
- * @param localContent - ローカルファイルの内容
14
- * @param templateContent - テンプレートファイルの内容
15
- * @returns 同期後の内容
16
- */
17
- syncSeeds(localContent: string, templateContent: string): string;
18
- /**
19
- * ファイル全体がseed扱い(マーカーなし)の場合の同期処理
20
- *
21
- * @param localExists - ローカルにファイルが存在するか
22
- * @param templateContent - テンプレートファイルの内容
23
- * @returns 同期後の内容(ローカルが存在する場合はnull)
24
- */
25
- syncUnmarkedFile(localExists: boolean, templateContent: string): string | null;
26
- }
27
- //# sourceMappingURL=seed-synchronizer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"seed-synchronizer.d.ts","sourceRoot":"","sources":["../../../src/lib/sync/seed-synchronizer.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IAEnD;;;;;;OAMG;IACH,SAAS,CAAC,YAAY,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,MAAM;IA4ChE;;;;;;OAMG;IACH,gBAAgB,CAAC,WAAW,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;CAU/E"}
@@ -1,72 +0,0 @@
1
- import { MarkerProcessor } from "./marker-processor.js";
2
- /**
3
- * @einja:seedマーカーの同期を行うクラス
4
- *
5
- * seedマーカーはプロジェクト固有のテンプレートを提供します。
6
- * - ファイルにseed(ID)がない場合: テンプレートから追加
7
- * - ファイルにseed(ID)がある場合: 保持(上書きしない)
8
- */
9
- export class SeedSynchronizer {
10
- constructor() {
11
- this.processor = new MarkerProcessor();
12
- }
13
- /**
14
- * seedセクションを同期する
15
- *
16
- * @param localContent - ローカルファイルの内容
17
- * @param templateContent - テンプレートファイルの内容
18
- * @returns 同期後の内容
19
- */
20
- syncSeeds(localContent, templateContent) {
21
- // Given: ローカルとテンプレートのセクションをパース
22
- const localSections = this.processor.parseMarkers(localContent);
23
- const templateSections = this.processor.parseMarkers(templateContent);
24
- // Given: ローカルに存在するseedのIDを収集
25
- const localSeedIds = new Set();
26
- for (const section of localSections) {
27
- if (section.type === "seed" && section.id) {
28
- localSeedIds.add(section.id);
29
- }
30
- }
31
- // When: テンプレートのseedセクションを取得
32
- const templateSeeds = templateSections.filter((section) => section.type === "seed");
33
- // When: ローカルに存在しないseedセクションを抽出
34
- const seedsToAdd = templateSeeds.filter((seed) => seed.id && !localSeedIds.has(seed.id));
35
- // Then: ローカルに追加するseedがない場合は、ローカルをそのまま返す
36
- if (seedsToAdd.length === 0) {
37
- return localContent;
38
- }
39
- // Then: ローカルの末尾にseedセクションを追加
40
- const lines = localContent.split("\n");
41
- const result = [...lines];
42
- // 末尾に空行がない場合は追加
43
- if (result.length > 0 && result[result.length - 1].trim() !== "") {
44
- result.push("");
45
- }
46
- for (const seed of seedsToAdd) {
47
- // セクション間に空行を追加
48
- if (result[result.length - 1] !== "") {
49
- result.push("");
50
- }
51
- result.push(seed.content);
52
- }
53
- return result.join("\n");
54
- }
55
- /**
56
- * ファイル全体がseed扱い(マーカーなし)の場合の同期処理
57
- *
58
- * @param localExists - ローカルにファイルが存在するか
59
- * @param templateContent - テンプレートファイルの内容
60
- * @returns 同期後の内容(ローカルが存在する場合はnull)
61
- */
62
- syncUnmarkedFile(localExists, templateContent) {
63
- // Given: ローカルにファイルが存在しない場合
64
- if (!localExists) {
65
- // When: テンプレートをそのまま追加
66
- return templateContent;
67
- }
68
- // Then: ローカルが存在する場合は何もしない(利用者管理)
69
- return null;
70
- }
71
- }
72
- //# sourceMappingURL=seed-synchronizer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"seed-synchronizer.js","sourceRoot":"","sources":["../../../src/lib/sync/seed-synchronizer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD;;;;;;GAMG;AACH,MAAM,OAAO,gBAAgB;IAA7B;QACmB,cAAS,GAAG,IAAI,eAAe,EAAE,CAAC;IAsErD,CAAC;IApEC;;;;;;OAMG;IACH,SAAS,CAAC,YAAoB,EAAE,eAAuB;QACrD,+BAA+B;QAC/B,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QAChE,MAAM,gBAAgB,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;QAEtE,6BAA6B;QAC7B,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;QACvC,KAAK,MAAM,OAAO,IAAI,aAAa,EAAE,CAAC;YACpC,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,EAAE,EAAE,CAAC;gBAC1C,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;QAED,4BAA4B;QAC5B,MAAM,aAAa,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;QAEpF,+BAA+B;QAC/B,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAEzF,wCAAwC;QACxC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO,YAAY,CAAC;QACtB,CAAC;QAED,6BAA6B;QAC7B,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACvC,MAAM,MAAM,GAAa,CAAC,GAAG,KAAK,CAAC,CAAC;QAEpC,gBAAgB;QAChB,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACjE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAClB,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;YAC9B,eAAe;YACf,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;gBACrC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAClB,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5B,CAAC;QAED,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IAED;;;;;;OAMG;IACH,gBAAgB,CAAC,WAAoB,EAAE,eAAuB;QAC5D,2BAA2B;QAC3B,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,sBAAsB;YACtB,OAAO,eAAe,CAAC;QACzB,CAAC;QAED,iCAAiC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=seed-synchronizer.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"seed-synchronizer.test.d.ts","sourceRoot":"","sources":["../../../src/lib/sync/seed-synchronizer.test.ts"],"names":[],"mappings":""}
@@ -1,147 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import { SeedSynchronizer } from "./seed-synchronizer.js";
3
- describe("SeedSynchronizer", () => {
4
- const synchronizer = new SeedSynchronizer();
5
- describe("syncSeeds", () => {
6
- it("ローカルに存在しないseedセクションがテンプレートに存在する場合、ローカルに追加されること", () => {
7
- // Given: ローカルにseedがない
8
- const localContent = `ローカル行1
9
- ローカル行2`;
10
- // Given: テンプレートにseedがある
11
- const templateContent = `テンプレート行1
12
- <!-- @einja:seed:start id="seed-1" -->
13
- シードセクション1
14
- <!-- @einja:seed:end -->
15
- テンプレート行2`;
16
- // When: seedを同期
17
- const result = synchronizer.syncSeeds(localContent, templateContent);
18
- // Then: ローカルの末尾にseedが追加される
19
- expect(result).toContain("ローカル行1");
20
- expect(result).toContain("ローカル行2");
21
- expect(result).toContain('<!-- @einja:seed:start id="seed-1" -->');
22
- expect(result).toContain("シードセクション1");
23
- expect(result).toContain("<!-- @einja:seed:end -->");
24
- });
25
- it("ローカルに既に存在するseedセクションは上書きされないこと", () => {
26
- // Given: ローカルにseedがある
27
- const localContent = `ローカル行1
28
- <!-- @einja:seed:start id="seed-1" -->
29
- ローカルシードセクション1
30
- <!-- @einja:seed:end -->
31
- ローカル行2`;
32
- // Given: テンプレートに同じIDのseedがある
33
- const templateContent = `テンプレート行1
34
- <!-- @einja:seed:start id="seed-1" -->
35
- テンプレートシードセクション1
36
- <!-- @einja:seed:end -->
37
- テンプレート行2`;
38
- // When: seedを同期
39
- const result = synchronizer.syncSeeds(localContent, templateContent);
40
- // Then: ローカルがそのまま保持される
41
- expect(result).toBe(localContent);
42
- expect(result).toContain("ローカルシードセクション1");
43
- expect(result).not.toContain("テンプレートシードセクション1");
44
- });
45
- it("ローカルに一部のseedが存在し、テンプレートに新しいseedがある場合、新しいseedのみ追加されること", () => {
46
- // Given: ローカルにseed-1がある
47
- const localContent = `ローカル行1
48
- <!-- @einja:seed:start id="seed-1" -->
49
- ローカルシードセクション1
50
- <!-- @einja:seed:end -->
51
- ローカル行2`;
52
- // Given: テンプレートにseed-1とseed-2がある
53
- const templateContent = `テンプレート行1
54
- <!-- @einja:seed:start id="seed-1" -->
55
- テンプレートシードセクション1
56
- <!-- @einja:seed:end -->
57
- テンプレート行2
58
- <!-- @einja:seed:start id="seed-2" -->
59
- テンプレートシードセクション2
60
- <!-- @einja:seed:end -->
61
- テンプレート行3`;
62
- // When: seedを同期
63
- const result = synchronizer.syncSeeds(localContent, templateContent);
64
- // Then: seed-1はそのまま、seed-2が追加される
65
- expect(result).toContain("ローカルシードセクション1");
66
- expect(result).not.toContain("テンプレートシードセクション1");
67
- expect(result).toContain('<!-- @einja:seed:start id="seed-2" -->');
68
- expect(result).toContain("テンプレートシードセクション2");
69
- expect(result).toContain("<!-- @einja:seed:end -->");
70
- });
71
- it("複数の新しいseedセクションが追加される場合、全て追加されること", () => {
72
- // Given: ローカルにseedがない
73
- const localContent = "ローカル行1";
74
- // Given: テンプレートに複数のseedがある
75
- const templateContent = `テンプレート行1
76
- <!-- @einja:seed:start id="seed-1" -->
77
- シードセクション1
78
- <!-- @einja:seed:end -->
79
- テンプレート行2
80
- <!-- @einja:seed:start id="seed-2" -->
81
- シードセクション2
82
- <!-- @einja:seed:end -->
83
- テンプレート行3`;
84
- // When: seedを同期
85
- const result = synchronizer.syncSeeds(localContent, templateContent);
86
- // Then: 全てのseedが追加される
87
- expect(result).toContain('<!-- @einja:seed:start id="seed-1" -->');
88
- expect(result).toContain("シードセクション1");
89
- expect(result).toContain('<!-- @einja:seed:start id="seed-2" -->');
90
- expect(result).toContain("シードセクション2");
91
- });
92
- it("managedセクションとseedセクションが混在する場合、seedのみが同期対象となること", () => {
93
- // Given: ローカルにmanagedとseedがある
94
- const localContent = `ローカル行1
95
- <!-- @einja:managed:start -->
96
- ローカル管理セクション
97
- <!-- @einja:managed:end -->
98
- <!-- @einja:seed:start id="seed-1" -->
99
- ローカルシードセクション
100
- <!-- @einja:seed:end -->
101
- ローカル行2`;
102
- // Given: テンプレートにmanagedとseed-1、seed-2がある
103
- const templateContent = `テンプレート行1
104
- <!-- @einja:managed:start -->
105
- テンプレート管理セクション
106
- <!-- @einja:managed:end -->
107
- <!-- @einja:seed:start id="seed-1" -->
108
- テンプレートシードセクション1
109
- <!-- @einja:seed:end -->
110
- <!-- @einja:seed:start id="seed-2" -->
111
- テンプレートシードセクション2
112
- <!-- @einja:seed:end -->
113
- テンプレート行2`;
114
- // When: seedを同期
115
- const result = synchronizer.syncSeeds(localContent, templateContent);
116
- // Then: seed-2のみ追加、seed-1とmanagedは元のまま
117
- expect(result).toContain("ローカル管理セクション");
118
- expect(result).toContain("ローカルシードセクション");
119
- expect(result).not.toContain("テンプレートシードセクション1");
120
- expect(result).toContain('<!-- @einja:seed:start id="seed-2" -->');
121
- expect(result).toContain("テンプレートシードセクション2");
122
- });
123
- });
124
- describe("syncUnmarkedFile", () => {
125
- it("ローカルにファイルが存在しない場合、テンプレート内容を返すこと", () => {
126
- // Given: ローカルにファイルが存在しない
127
- const localExists = false;
128
- const templateContent = `テンプレート行1
129
- テンプレート行2`;
130
- // When: マーカーなしファイルを同期
131
- const result = synchronizer.syncUnmarkedFile(localExists, templateContent);
132
- // Then: テンプレート内容が返る
133
- expect(result).toBe(templateContent);
134
- });
135
- it("ローカルにファイルが存在する場合、nullを返すこと(何もしない)", () => {
136
- // Given: ローカルにファイルが存在する
137
- const localExists = true;
138
- const templateContent = `テンプレート行1
139
- テンプレート行2`;
140
- // When: マーカーなしファイルを同期
141
- const result = synchronizer.syncUnmarkedFile(localExists, templateContent);
142
- // Then: nullが返る(何もしない)
143
- expect(result).toBeNull();
144
- });
145
- });
146
- });
147
- //# sourceMappingURL=seed-synchronizer.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"seed-synchronizer.test.js","sourceRoot":"","sources":["../../../src/lib/sync/seed-synchronizer.test.ts"],"names":[],"mappings":"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"}
@@ -1,148 +0,0 @@
1
- ---
2
- name: conflict-resolver
3
- description: gitコンフリクトを安全に解消する専用エージェント
4
- model: sonnet
5
- color: orange
6
- skills:
7
- - conflict-resolver
8
- ---
9
-
10
- # conflict-resolver エージェント
11
-
12
- gitコンフリクト(rebase/merge/stash/cherry-pick等)を1ファイルずつユーザーに確認しながら安全に解消します。
13
-
14
- ## 役割
15
-
16
- - コンフリクト状態の検出と診断
17
- - 各コンフリクトファイルについてマージ案を提示
18
- - ユーザー確認後に解消を実行
19
- - 操作の継続(rebase --continue等)または中断を管理
20
-
21
- ## 処理フロー
22
-
23
- conflict-resolver Skill を実行し、以下の手順でコンフリクトを解消します:
24
-
25
- ### ステップ1: コンフリクト状態の確認
26
-
27
- 1. コンフリクトファイルの一覧を表示
28
- 2. 操作タイプを判定(rebase/merge/cherry-pick/stash)
29
- 3. 10件以上の場合は継続確認
30
-
31
- ### ステップ2: 各ファイルについてユーザーに確認(1ファイルずつ)
32
-
33
- **⚠️ 重要**: 複数ファイルをまとめて質問せず、必ず1ファイルごとにAskUserQuestionを実行すること。
34
-
35
- 各コンフリクトファイルに対して:
36
-
37
- 1. 双方の差分を表示(`git diff --ours` / `git diff --theirs`)
38
- 2. ファイル内容を読み、両方の変更箇所を理解
39
- 3. **AskUserQuestionツールで**マージ案を提示し、ユーザーの選択を待つ
40
-
41
- ```yaml
42
- AskUserQuestion:
43
- question: "{ファイル名}のコンフリクト解消方法を選択してください"
44
- header: "コンフリクト解消"
45
- options:
46
- - label: "HEAD側を優先"
47
- description: "現在のブランチの変更を採用。メリット: 現在の実装を維持。デメリット: マージ元の変更が失われる"
48
- - label: "マージ元を優先"
49
- description: "マージ元の変更を採用。メリット: 新しい変更を取り込める。デメリット: 現在の実装が上書きされる"
50
- - label: "マージ案A(両方の変更を統合)"
51
- description: "{具体的なマージ内容}。メリット: 両方の変更を活かせる。デメリット: 統合リスク"
52
- - label: "このファイルをスキップ"
53
- description: "後で手動解消。メリット: 判断保留。デメリット: 後で対応が必要"
54
- - label: "操作全体を中断"
55
- description: "rebase/merge/cherry-pickを中断。メリット: 安全に戻せる。デメリット: 解消作業が無効"
56
- ```
57
-
58
- 4. ユーザーの選択後、次のファイルへ進む(全ファイル完了までループ)
59
-
60
- ### ステップ3: 確認後に解消を実行
61
-
62
- 1. ユーザーが選択した案に従ってファイルを編集
63
- 2. `git add <file>` でステージング
64
- 3. 編集結果をユーザーに表示して最終確認
65
-
66
- ### ステップ4: 全ファイル解消後
67
-
68
- 1. 残りコンフリクトの検証(`git diff --check`)
69
- 2. 操作タイプに応じて継続:
70
- - rebase: `git rebase --continue`
71
- - merge: `git commit`
72
- - cherry-pick: `git cherry-pick --continue`
73
- - stash: `git stash drop`
74
- 3. 追加のコンフリクトがあればステップ2に戻る
75
-
76
- ### ステップ5: 中断・やり直しオプション
77
-
78
- ユーザーが中断を希望した場合、操作タイプに応じて中断:
79
- - rebase: `git rebase --abort`
80
- - merge: `git merge --abort`
81
- - cherry-pick: `git cherry-pick --abort`
82
- - stash: `git checkout -- .` でリセット
83
-
84
- ## 禁止事項
85
-
86
- 以下の操作は**絶対に行わない**:
87
-
88
- - ユーザー確認なしでのコンフリクト自動解消
89
- - `--ours`や`--theirs`オプションの無断使用
90
- - コンフリクトマーカー(`<<<<<<<`、`=======`、`>>>>>>>`)を残したままのコミット
91
-
92
- ## 出力形式
93
-
94
- ### 成功時
95
-
96
- ```markdown
97
- ## コンフリクト解消完了
98
-
99
- ### 解消サマリー
100
- - **コンフリクトファイル数**: {count}個
101
- - **操作タイプ**: [rebase / merge / cherry-pick / stash]
102
-
103
- ### 解消ファイル一覧
104
- | # | ファイル | 解消方法 |
105
- |---|---------|---------|
106
- | 1 | src/auth/login.ts | 両方の変更を取り込み |
107
- | 2 | src/config.ts | HEAD側を優先 |
108
-
109
- ### ステータス: SUCCESS
110
- ```
111
-
112
- ### 中断時
113
-
114
- ```markdown
115
- ## コンフリクト解消
116
-
117
- ### ステータス: ABORTED
118
-
119
- **理由**: [ユーザーが中断を選択 / 手動解消を希望]
120
-
121
- 操作は中断されました。
122
- ```
123
-
124
- ### 失敗時
125
-
126
- ```markdown
127
- ## コンフリクト解消
128
-
129
- ### ステータス: FAILURE
130
-
131
- **エラー**: [エラー内容]
132
-
133
- [推奨される対処方法]
134
- ```
135
-
136
- ## 利用シーン
137
-
138
- | シーン | 呼び出し元 |
139
- |--------|-----------|
140
- | PR作成時のコンフリクト | task-committer |
141
- | rebase時のコンフリクト | 直接呼び出し |
142
- | merge時のコンフリクト | 直接呼び出し |
143
- | stash適用時のコンフリクト | 直接呼び出し |
144
-
145
- ## 連携エージェント
146
-
147
- - **呼び出し元**: `task-committer` - push時にコンフリクトが発生した場合
148
- - **単体呼び出し**: ユーザーがrebase/merge/stash時に直接呼び出し可能
@@ -1,239 +0,0 @@
1
- #!/bin/bash
2
- # validate-git-commit.sh - git commitコマンドのメッセージ形式を検証
3
- #
4
- # 目的:
5
- # - git commit実行前にコミットメッセージの形式を検証
6
- # - 不適切なメッセージ(---、Markdown形式等)をブロック
7
- # - コミットルール(docs/einja/steering/commit-rules.md)に準拠を強制
8
- #
9
- # 使用方法:
10
- # - PreToolUse hookとして設定
11
- # - exit code 0: 許可
12
- # - exit code 2: ブロック(stderrがClaudeに送信される)
13
-
14
- set -uo pipefail
15
-
16
- # 標準入力からJSON入力を読み取る
17
- input=$(cat)
18
-
19
- # ツール名を取得
20
- tool_name=$(echo "$input" | jq -r '.tool_name // empty')
21
-
22
- # Bashツール以外は無視
23
- if [[ "$tool_name" != "Bash" ]]; then
24
- exit 0
25
- fi
26
-
27
- # コマンドを取得
28
- command=$(echo "$input" | jq -r '.tool_input.command // empty')
29
-
30
- # git commitコマンドでない場合はスキップ(volta unset対応で部分マッチ)
31
- if [[ ! "$command" =~ git[[:space:]]+commit ]]; then
32
- exit 0
33
- fi
34
-
35
- # --amend のみの場合はスキップ(メッセージ変更なし)
36
- # -m / --message がない場合のみスキップ
37
- if [[ "$command" =~ --amend ]]; then
38
- if [[ ! "$command" =~ -m ]] && [[ ! "$command" =~ --message ]]; then
39
- exit 0
40
- fi
41
- fi
42
-
43
- # -m / --message オプションがない場合はスキップ(インタラクティブエディタ使用)
44
- if [[ ! "$command" =~ -m ]] && [[ ! "$command" =~ --message ]]; then
45
- exit 0
46
- fi
47
-
48
- # コミットメッセージを抽出
49
- commit_message=""
50
-
51
- # パターン1: -m "message" / -m 'message' (スペースあり)
52
- if [[ "$command" =~ -m[[:space:]]+\"([^\"]+)\" ]]; then
53
- commit_message="${BASH_REMATCH[1]}"
54
- elif [[ "$command" =~ -m[[:space:]]+\'([^\']+)\' ]]; then
55
- commit_message="${BASH_REMATCH[1]}"
56
- # パターン2: -m"message" / -m'message' (スペースなし)
57
- elif [[ "$command" =~ -m\"([^\"]+)\" ]]; then
58
- commit_message="${BASH_REMATCH[1]}"
59
- elif [[ "$command" =~ -m\'([^\']+)\' ]]; then
60
- commit_message="${BASH_REMATCH[1]}"
61
- # パターン3: --message="message" / --message='message'
62
- elif [[ "$command" =~ --message=\"([^\"]+)\" ]]; then
63
- commit_message="${BASH_REMATCH[1]}"
64
- elif [[ "$command" =~ --message=\'([^\']+)\' ]]; then
65
- commit_message="${BASH_REMATCH[1]}"
66
- # パターン4: --message "message" / --message 'message' (スペースあり)
67
- elif [[ "$command" =~ --message[[:space:]]+\"([^\"]+)\" ]]; then
68
- commit_message="${BASH_REMATCH[1]}"
69
- elif [[ "$command" =~ --message[[:space:]]+\'([^\']+)\' ]]; then
70
- commit_message="${BASH_REMATCH[1]}"
71
- # パターン5: -m="message" / -m='message'
72
- elif [[ "$command" =~ -m=\"([^\"]+)\" ]]; then
73
- commit_message="${BASH_REMATCH[1]}"
74
- elif [[ "$command" =~ -m=\'([^\']+)\' ]]; then
75
- commit_message="${BASH_REMATCH[1]}"
76
- # パターン6: HEREDOC形式 -m "$(cat <<'EOF'...EOF)"
77
- elif [[ "$command" =~ -m[[:space:]]*\"\$\(cat ]]; then
78
- # HEREDOCからメッセージの最初の行を抽出
79
- commit_message=$(echo "$command" | sed -n "/<<.*EOF/,/^EOF/p" | sed '1d;$d' | head -1)
80
- fi
81
-
82
- # メッセージが取得できない場合は許可(予期しないパターン)
83
- if [[ -z "$commit_message" ]]; then
84
- exit 0
85
- fi
86
-
87
- # 変数参照の場合はスキップ(実行時まで値が確定しない)
88
- if [[ "$commit_message" =~ ^\$ ]]; then
89
- exit 0
90
- fi
91
-
92
- # 最初の行(概要行)を取得
93
- first_line=$(echo "$commit_message" | head -1)
94
-
95
- # === 検証ルール ===
96
-
97
- # 有効なプレフィックス一覧
98
- VALID_PREFIXES="^(feat|fix|docs|style|refactor|test|chore):"
99
-
100
- # ルール1: プレフィックスの存在確認
101
- if ! echo "$first_line" | grep -qE "$VALID_PREFIXES"; then
102
- cat >&2 <<ERRMSG
103
-
104
- ❌ コミットメッセージ形式エラー
105
-
106
- 検出されたメッセージ:
107
- "$first_line"
108
-
109
- 問題:
110
- 有効なプレフィックスがありません。
111
-
112
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
113
- ⚡ 対処方法: /task-commit Skillを使用してください
114
-
115
- このSkillはコミットルールに従って:
116
- - 適切なプレフィックス(feat/fix/docs等)を付与
117
- - 変更内容に応じたコミット分割を提案
118
- - 日本語で明確なメッセージを生成
119
-
120
- 実行: Skill("task-commit") を呼び出す
121
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
122
-
123
- 参照: docs/einja/steering/commit-rules.md
124
-
125
- ERRMSG
126
- exit 2
127
- fi
128
-
129
- # プレフィックス後の説明部分を抽出(禁止パターン検出に使用)
130
- description=$(echo "$first_line" | sed -E 's/^(feat|fix|docs|style|refactor|test|chore):[[:space:]]*//')
131
-
132
- # ルール2: プレフィックス後のメッセージが空でないか(3文字以上)
133
- if [[ -z "$description" ]] || [[ ${#description} -lt 3 ]]; then
134
- cat >&2 <<ERRMSG
135
-
136
- ❌ コミットメッセージ形式エラー
137
-
138
- 検出されたメッセージ:
139
- "$first_line"
140
-
141
- 問題:
142
- プレフィックス後の説明が不足しています。
143
- 具体的な変更内容を記述してください(3文字以上)。
144
-
145
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
146
- ⚡ 対処方法: /task-commit Skillを使用してください
147
-
148
- このSkillはコミットルールに従って:
149
- - 適切なプレフィックス(feat/fix/docs等)を付与
150
- - 変更内容に応じたコミット分割を提案
151
- - 日本語で明確なメッセージを生成
152
-
153
- 実行: Skill("task-commit") を呼び出す
154
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
155
-
156
- 参照: docs/einja/steering/commit-rules.md
157
-
158
- ERRMSG
159
- exit 2
160
- fi
161
-
162
- # ルール3: 明らかに不適切なメッセージのパターン検出(説明部分に対して適用)
163
- INVALID_PATTERNS=(
164
- "^---$"
165
- "^\*\*.*\*\*$"
166
- "^完了しました"
167
- "^実装完了"
168
- "^修正完了"
169
- "^update$"
170
- "^fix$"
171
- "^changes$"
172
- "^wip$"
173
- )
174
-
175
- for pattern in "${INVALID_PATTERNS[@]}"; do
176
- if echo "$description" | grep -qiE "$pattern"; then
177
- cat >&2 <<ERRMSG
178
-
179
- ❌ コミットメッセージ形式エラー
180
-
181
- 検出されたメッセージ:
182
- "$first_line"
183
-
184
- 問題:
185
- コミットメッセージの説明部分が不適切な形式です。
186
- 具体的な変更内容を記述してください。
187
-
188
- 禁止されたパターン: $pattern
189
-
190
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
191
- ⚡ 対処方法: /task-commit Skillを使用してください
192
-
193
- このSkillはコミットルールに従って:
194
- - 適切なプレフィックス(feat/fix/docs等)を付与
195
- - 変更内容に応じたコミット分割を提案
196
- - 日本語で明確なメッセージを生成
197
-
198
- 実行: Skill("task-commit") を呼び出す
199
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
200
-
201
- 参照: docs/einja/steering/commit-rules.md
202
-
203
- ERRMSG
204
- exit 2
205
- fi
206
- done
207
-
208
- # ルール4: メッセージがMarkdown見出し形式でないか
209
- if echo "$first_line" | grep -qE "^#{1,6}[[:space:]]"; then
210
- cat >&2 <<ERRMSG
211
-
212
- ❌ コミットメッセージ形式エラー
213
-
214
- 検出されたメッセージ:
215
- "$first_line"
216
-
217
- 問題:
218
- Markdownの見出し形式(#)は使用できません。
219
- プレフィックス形式で記述してください。
220
-
221
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
222
- ⚡ 対処方法: /task-commit Skillを使用してください
223
-
224
- このSkillはコミットルールに従って:
225
- - 適切なプレフィックス(feat/fix/docs等)を付与
226
- - 変更内容に応じたコミット分割を提案
227
- - 日本語で明確なメッセージを生成
228
-
229
- 実行: Skill("task-commit") を呼び出す
230
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
231
-
232
- 参照: docs/einja/steering/commit-rules.md
233
-
234
- ERRMSG
235
- exit 2
236
- fi
237
-
238
- # 全ての検証をパス
239
- exit 0
@@ -1,14 +0,0 @@
1
- ---
2
- name: api-development
3
- description: "Hono + Zodを使用したAPI実装のガイドライン"
4
- ---
5
-
6
- # API開発ガイド Skill
7
-
8
- ## 概要
9
-
10
- このSkillは、API実装時に参照すべきガイドラインを提供します。
11
-
12
- ## 詳細ドキュメント
13
-
14
- @docs/einja/steering/development/api-development.md