@einja/dev-cli 0.1.6

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 (243) hide show
  1. package/README.md +179 -0
  2. package/dist/cli.d.ts +2 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +49 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/commands/init.d.ts +3 -0
  7. package/dist/commands/init.d.ts.map +1 -0
  8. package/dist/commands/init.js +243 -0
  9. package/dist/commands/init.js.map +1 -0
  10. package/dist/commands/list.d.ts +2 -0
  11. package/dist/commands/list.d.ts.map +1 -0
  12. package/dist/commands/list.js +23 -0
  13. package/dist/commands/list.js.map +1 -0
  14. package/dist/commands/sync.d.ts +7 -0
  15. package/dist/commands/sync.d.ts.map +1 -0
  16. package/dist/commands/sync.js +294 -0
  17. package/dist/commands/sync.js.map +1 -0
  18. package/dist/commands/sync.test.d.ts +2 -0
  19. package/dist/commands/sync.test.d.ts.map +1 -0
  20. package/dist/commands/sync.test.js +593 -0
  21. package/dist/commands/sync.test.js.map +1 -0
  22. package/dist/commands/task-loop.d.ts +11 -0
  23. package/dist/commands/task-loop.d.ts.map +1 -0
  24. package/dist/commands/task-loop.js +81 -0
  25. package/dist/commands/task-loop.js.map +1 -0
  26. package/dist/index.d.ts +4 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +3 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/lib/file-system.d.ts +39 -0
  31. package/dist/lib/file-system.d.ts.map +1 -0
  32. package/dist/lib/file-system.js +79 -0
  33. package/dist/lib/file-system.js.map +1 -0
  34. package/dist/lib/mcp-config.d.ts +43 -0
  35. package/dist/lib/mcp-config.d.ts.map +1 -0
  36. package/dist/lib/mcp-config.js +109 -0
  37. package/dist/lib/mcp-config.js.map +1 -0
  38. package/dist/lib/mcp-config.test.d.ts +2 -0
  39. package/dist/lib/mcp-config.test.d.ts.map +1 -0
  40. package/dist/lib/mcp-config.test.js +285 -0
  41. package/dist/lib/mcp-config.test.js.map +1 -0
  42. package/dist/lib/merger.d.ts +41 -0
  43. package/dist/lib/merger.d.ts.map +1 -0
  44. package/dist/lib/merger.js +164 -0
  45. package/dist/lib/merger.js.map +1 -0
  46. package/dist/lib/preset-update/cli-repo-detector.d.ts +35 -0
  47. package/dist/lib/preset-update/cli-repo-detector.d.ts.map +1 -0
  48. package/dist/lib/preset-update/cli-repo-detector.js +83 -0
  49. package/dist/lib/preset-update/cli-repo-detector.js.map +1 -0
  50. package/dist/lib/preset-update/cli-repo-detector.test.d.ts +2 -0
  51. package/dist/lib/preset-update/cli-repo-detector.test.d.ts.map +1 -0
  52. package/dist/lib/preset-update/cli-repo-detector.test.js +120 -0
  53. package/dist/lib/preset-update/cli-repo-detector.test.js.map +1 -0
  54. package/dist/lib/preset-update/file-copier.d.ts +59 -0
  55. package/dist/lib/preset-update/file-copier.d.ts.map +1 -0
  56. package/dist/lib/preset-update/file-copier.js +220 -0
  57. package/dist/lib/preset-update/file-copier.js.map +1 -0
  58. package/dist/lib/preset-update/file-copier.test.d.ts +2 -0
  59. package/dist/lib/preset-update/file-copier.test.d.ts.map +1 -0
  60. package/dist/lib/preset-update/file-copier.test.js +297 -0
  61. package/dist/lib/preset-update/file-copier.test.js.map +1 -0
  62. package/dist/lib/preset-update/preset-finder.d.ts +39 -0
  63. package/dist/lib/preset-update/preset-finder.d.ts.map +1 -0
  64. package/dist/lib/preset-update/preset-finder.js +92 -0
  65. package/dist/lib/preset-update/preset-finder.js.map +1 -0
  66. package/dist/lib/preset-update/preset-finder.test.d.ts +2 -0
  67. package/dist/lib/preset-update/preset-finder.test.d.ts.map +1 -0
  68. package/dist/lib/preset-update/preset-finder.test.js +128 -0
  69. package/dist/lib/preset-update/preset-finder.test.js.map +1 -0
  70. package/dist/lib/preset.d.ts +14 -0
  71. package/dist/lib/preset.d.ts.map +1 -0
  72. package/dist/lib/preset.js +52 -0
  73. package/dist/lib/preset.js.map +1 -0
  74. package/dist/lib/sync/backup-manager.d.ts +50 -0
  75. package/dist/lib/sync/backup-manager.d.ts.map +1 -0
  76. package/dist/lib/sync/backup-manager.js +117 -0
  77. package/dist/lib/sync/backup-manager.js.map +1 -0
  78. package/dist/lib/sync/backup-manager.test.d.ts +2 -0
  79. package/dist/lib/sync/backup-manager.test.d.ts.map +1 -0
  80. package/dist/lib/sync/backup-manager.test.js +155 -0
  81. package/dist/lib/sync/backup-manager.test.js.map +1 -0
  82. package/dist/lib/sync/batch-processor.d.ts +27 -0
  83. package/dist/lib/sync/batch-processor.d.ts.map +1 -0
  84. package/dist/lib/sync/batch-processor.js +46 -0
  85. package/dist/lib/sync/batch-processor.js.map +1 -0
  86. package/dist/lib/sync/batch-processor.test.d.ts +2 -0
  87. package/dist/lib/sync/batch-processor.test.d.ts.map +1 -0
  88. package/dist/lib/sync/batch-processor.test.js +110 -0
  89. package/dist/lib/sync/batch-processor.test.js.map +1 -0
  90. package/dist/lib/sync/category-validator.d.ts +36 -0
  91. package/dist/lib/sync/category-validator.d.ts.map +1 -0
  92. package/dist/lib/sync/category-validator.js +46 -0
  93. package/dist/lib/sync/category-validator.js.map +1 -0
  94. package/dist/lib/sync/category-validator.test.d.ts +2 -0
  95. package/dist/lib/sync/category-validator.test.d.ts.map +1 -0
  96. package/dist/lib/sync/category-validator.test.js +89 -0
  97. package/dist/lib/sync/category-validator.test.js.map +1 -0
  98. package/dist/lib/sync/conflict-reporter.d.ts +57 -0
  99. package/dist/lib/sync/conflict-reporter.d.ts.map +1 -0
  100. package/dist/lib/sync/conflict-reporter.js +81 -0
  101. package/dist/lib/sync/conflict-reporter.js.map +1 -0
  102. package/dist/lib/sync/conflict-reporter.test.d.ts +2 -0
  103. package/dist/lib/sync/conflict-reporter.test.d.ts.map +1 -0
  104. package/dist/lib/sync/conflict-reporter.test.js +132 -0
  105. package/dist/lib/sync/conflict-reporter.test.js.map +1 -0
  106. package/dist/lib/sync/diff-engine.d.ts +28 -0
  107. package/dist/lib/sync/diff-engine.d.ts.map +1 -0
  108. package/dist/lib/sync/diff-engine.js +118 -0
  109. package/dist/lib/sync/diff-engine.js.map +1 -0
  110. package/dist/lib/sync/diff-engine.test.d.ts +2 -0
  111. package/dist/lib/sync/diff-engine.test.d.ts.map +1 -0
  112. package/dist/lib/sync/diff-engine.test.js +133 -0
  113. package/dist/lib/sync/diff-engine.test.js.map +1 -0
  114. package/dist/lib/sync/file-filter.d.ts +40 -0
  115. package/dist/lib/sync/file-filter.d.ts.map +1 -0
  116. package/dist/lib/sync/file-filter.js +171 -0
  117. package/dist/lib/sync/file-filter.js.map +1 -0
  118. package/dist/lib/sync/file-filter.test.d.ts +2 -0
  119. package/dist/lib/sync/file-filter.test.d.ts.map +1 -0
  120. package/dist/lib/sync/file-filter.test.js +179 -0
  121. package/dist/lib/sync/file-filter.test.js.map +1 -0
  122. package/dist/lib/sync/hash-cache.d.ts +34 -0
  123. package/dist/lib/sync/hash-cache.d.ts.map +1 -0
  124. package/dist/lib/sync/hash-cache.js +51 -0
  125. package/dist/lib/sync/hash-cache.js.map +1 -0
  126. package/dist/lib/sync/hash-cache.test.d.ts +2 -0
  127. package/dist/lib/sync/hash-cache.test.d.ts.map +1 -0
  128. package/dist/lib/sync/hash-cache.test.js +110 -0
  129. package/dist/lib/sync/hash-cache.test.js.map +1 -0
  130. package/dist/lib/sync/integration.test.d.ts +2 -0
  131. package/dist/lib/sync/integration.test.d.ts.map +1 -0
  132. package/dist/lib/sync/integration.test.js +317 -0
  133. package/dist/lib/sync/integration.test.js.map +1 -0
  134. package/dist/lib/sync/marker-processor.d.ts +54 -0
  135. package/dist/lib/sync/marker-processor.d.ts.map +1 -0
  136. package/dist/lib/sync/marker-processor.js +208 -0
  137. package/dist/lib/sync/marker-processor.js.map +1 -0
  138. package/dist/lib/sync/marker-processor.test.d.ts +2 -0
  139. package/dist/lib/sync/marker-processor.test.d.ts.map +1 -0
  140. package/dist/lib/sync/marker-processor.test.js +245 -0
  141. package/dist/lib/sync/marker-processor.test.js.map +1 -0
  142. package/dist/lib/sync/metadata-manager.d.ts +46 -0
  143. package/dist/lib/sync/metadata-manager.d.ts.map +1 -0
  144. package/dist/lib/sync/metadata-manager.js +129 -0
  145. package/dist/lib/sync/metadata-manager.js.map +1 -0
  146. package/dist/lib/sync/metadata-manager.test.d.ts +2 -0
  147. package/dist/lib/sync/metadata-manager.test.d.ts.map +1 -0
  148. package/dist/lib/sync/metadata-manager.test.js +137 -0
  149. package/dist/lib/sync/metadata-manager.test.js.map +1 -0
  150. package/dist/lib/sync/performance.test.d.ts +2 -0
  151. package/dist/lib/sync/performance.test.d.ts.map +1 -0
  152. package/dist/lib/sync/performance.test.js +126 -0
  153. package/dist/lib/sync/performance.test.js.map +1 -0
  154. package/dist/types/index.d.ts +59 -0
  155. package/dist/types/index.d.ts.map +1 -0
  156. package/dist/types/index.js +2 -0
  157. package/dist/types/index.js.map +1 -0
  158. package/dist/types/preset-update.d.ts +106 -0
  159. package/dist/types/preset-update.d.ts.map +1 -0
  160. package/dist/types/preset-update.js +5 -0
  161. package/dist/types/preset-update.js.map +1 -0
  162. package/dist/types/sync.d.ts +169 -0
  163. package/dist/types/sync.d.ts.map +1 -0
  164. package/dist/types/sync.js +19 -0
  165. package/dist/types/sync.js.map +1 -0
  166. package/package.json +72 -0
  167. package/presets/minimal/.claude/agents/einja/docs/docs-updater.md +161 -0
  168. package/presets/minimal/.claude/agents/einja/frontend/design-engineer.md +685 -0
  169. package/presets/minimal/.claude/agents/einja/frontend/frontend-architect.md +747 -0
  170. package/presets/minimal/.claude/agents/einja/frontend/frontend-coder.md +441 -0
  171. package/presets/minimal/.claude/agents/einja/git/conflict-resolver.md +148 -0
  172. package/presets/minimal/.claude/agents/einja/specs/spec-design-generator.md +462 -0
  173. package/presets/minimal/.claude/agents/einja/specs/spec-qa-generator.md +466 -0
  174. package/presets/minimal/.claude/agents/einja/specs/spec-requirements-generator.md +416 -0
  175. package/presets/minimal/.claude/agents/einja/specs/spec-tasks-generator.md +608 -0
  176. package/presets/minimal/.claude/agents/einja/task/task-committer.md +82 -0
  177. package/presets/minimal/.claude/agents/einja/task/task-executer.md +352 -0
  178. package/presets/minimal/.claude/agents/einja/task/task-modification-analyzer.md +369 -0
  179. package/presets/minimal/.claude/agents/einja/task/task-qa.md +74 -0
  180. package/presets/minimal/.claude/agents/einja/task/task-reviewer.md +169 -0
  181. package/presets/minimal/.claude/commands/einja/frontend-implement.md +322 -0
  182. package/presets/minimal/.claude/commands/einja/spec-create.md +254 -0
  183. package/presets/minimal/.claude/commands/einja/start-dev.md +98 -0
  184. package/presets/minimal/.claude/commands/einja/sync-cursor-commands.md +203 -0
  185. package/presets/minimal/.claude/commands/einja/task-exec.md +390 -0
  186. package/presets/minimal/.claude/commands/einja/update-docs-by-task-specs.md +448 -0
  187. package/presets/minimal/.claude/hooks/einja/biome-format.sh +49 -0
  188. package/presets/minimal/.claude/hooks/einja/design-doc-check.sh +61 -0
  189. package/presets/minimal/.claude/hooks/einja/detect-secrets.sh +62 -0
  190. package/presets/minimal/.claude/hooks/einja/large-file-warning.sh +42 -0
  191. package/presets/minimal/.claude/hooks/einja/playwright-resize.sh +36 -0
  192. package/presets/minimal/.claude/hooks/einja/typecheck.sh +37 -0
  193. package/presets/minimal/.claude/hooks/einja/unset-volta-recursion.sh +32 -0
  194. package/presets/minimal/.claude/hooks/einja/validate-git-commit.sh +239 -0
  195. package/presets/minimal/.claude/hooks/einja/warn-index-ts.sh +34 -0
  196. package/presets/minimal/.claude/hooks/einja/warn-relative-import.sh +48 -0
  197. package/presets/minimal/.claude/settings.json +174 -0
  198. package/presets/minimal/.claude/skills/einja/api-development/SKILL.md +14 -0
  199. package/presets/minimal/.claude/skills/einja/backend-architecture/SKILL.md +14 -0
  200. package/presets/minimal/.claude/skills/einja/coding-standards/SKILL.md +120 -0
  201. package/presets/minimal/.claude/skills/einja/coding-standards/reference/naming-conventions.md +107 -0
  202. package/presets/minimal/.claude/skills/einja/coding-standards/reference/prohibited-patterns.md +169 -0
  203. package/presets/minimal/.claude/skills/einja/coding-standards/reference/typescript-rules.md +247 -0
  204. package/presets/minimal/.claude/skills/einja/component-design/SKILL.md +109 -0
  205. package/presets/minimal/.claude/skills/einja/component-design/reference/directory-structure.md +117 -0
  206. package/presets/minimal/.claude/skills/einja/component-design/reference/props-patterns.md +159 -0
  207. package/presets/minimal/.claude/skills/einja/component-design/reference/styling-guide.md +200 -0
  208. package/presets/minimal/.claude/skills/einja/conflict-resolver/SKILL.md +190 -0
  209. package/presets/minimal/.claude/skills/einja/frontend-development/SKILL.md +14 -0
  210. package/presets/minimal/.claude/skills/einja/general-context-loader/SKILL.md +254 -0
  211. package/presets/minimal/.claude/skills/einja/output-format/SKILL.md +137 -0
  212. package/presets/minimal/.claude/skills/einja/spec-context-loader/SKILL.md +177 -0
  213. package/presets/minimal/.claude/skills/einja/task-commit/SKILL.md +269 -0
  214. package/presets/minimal/.claude/skills/einja/task-qa/SKILL.md +306 -0
  215. package/presets/minimal/.claude/skills/einja/task-qa/reference/failure-patterns.md +69 -0
  216. package/presets/minimal/.claude/skills/einja/task-qa/reference/troubleshooting.md +65 -0
  217. package/presets/minimal/.claude/skills/einja/task-qa/reference/usage-patterns.md +52 -0
  218. package/presets/minimal/.claude/skills/einja/task-qa/templates/qa-test-template.md +128 -0
  219. package/presets/minimal/preset.yaml +111 -0
  220. package/presets/minimal/symlinks.json +45 -0
  221. package/scaffolds/.mcp.json +45 -0
  222. package/scaffolds/CLAUDE.md.template +318 -0
  223. package/scaffolds/steering/README.md +170 -0
  224. package/scaffolds/steering/acceptance-criteria-and-qa-guide.md +415 -0
  225. package/scaffolds/steering/architecture.md +481 -0
  226. package/scaffolds/steering/branch-strategy.md +362 -0
  227. package/scaffolds/steering/commit-rules.md +217 -0
  228. package/scaffolds/steering/db-schema-design.md +609 -0
  229. package/scaffolds/steering/development/api-development.md +783 -0
  230. package/scaffolds/steering/development/backend-architecture.md +731 -0
  231. package/scaffolds/steering/development/frontend-development.md +1537 -0
  232. package/scaffolds/steering/development/review-guidelines.md +365 -0
  233. package/scaffolds/steering/development/testing-strategy.md +819 -0
  234. package/scaffolds/steering/development-workflow.md +429 -0
  235. package/scaffolds/steering/infrastructure/deployment.md +277 -0
  236. package/scaffolds/steering/infrastructure/environment-variables.md +298 -0
  237. package/scaffolds/steering/product.md +540 -0
  238. package/scaffolds/steering/task-management.md +367 -0
  239. package/templates/README.md +159 -0
  240. package/templates/design-simple.md.template +172 -0
  241. package/templates/design.md.template +327 -0
  242. package/templates/qa-test.md.template +125 -0
  243. package/templates/requirements.md.template +254 -0
@@ -0,0 +1,36 @@
1
+ /**
2
+ * カテゴリバリデーションユーティリティ
3
+ * --onlyオプションで指定されたカテゴリの妥当性をチェック
4
+ */
5
+ /**
6
+ * 有効なカテゴリのリスト
7
+ */
8
+ export declare const VALID_CATEGORIES: readonly ["commands", "agents", "skills", "hooks", "docs"];
9
+ /**
10
+ * カテゴリの型定義
11
+ */
12
+ export type ValidCategory = (typeof VALID_CATEGORIES)[number];
13
+ /**
14
+ * カテゴリバリデーション結果
15
+ */
16
+ export interface CategoryValidationResult {
17
+ /** バリデーションが成功したか */
18
+ valid: boolean;
19
+ /** 有効なカテゴリのリスト */
20
+ validCategories: string[];
21
+ /** 無効なカテゴリのリスト */
22
+ invalidCategories: string[];
23
+ }
24
+ /**
25
+ * カテゴリ文字列をパースしてバリデーションする
26
+ * @param categoryString カンマ区切りのカテゴリ文字列(例: "commands,agents")
27
+ * @returns バリデーション結果
28
+ */
29
+ export declare function validateCategories(categoryString: string): CategoryValidationResult;
30
+ /**
31
+ * バリデーションエラーメッセージを生成する
32
+ * @param invalidCategories 無効なカテゴリのリスト
33
+ * @returns エラーメッセージ
34
+ */
35
+ export declare function createValidationErrorMessage(invalidCategories: string[]): string;
36
+ //# sourceMappingURL=category-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"category-validator.d.ts","sourceRoot":"","sources":["../../../src/lib/sync/category-validator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,eAAO,MAAM,gBAAgB,4DAA6D,CAAC;AAE3F;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACxC,oBAAoB;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,kBAAkB;IAClB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,kBAAkB;IAClB,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG,wBAAwB,CAuBnF;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,iBAAiB,EAAE,MAAM,EAAE,GAAG,MAAM,CAKhF"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * カテゴリバリデーションユーティリティ
3
+ * --onlyオプションで指定されたカテゴリの妥当性をチェック
4
+ */
5
+ /**
6
+ * 有効なカテゴリのリスト
7
+ */
8
+ export const VALID_CATEGORIES = ["commands", "agents", "skills", "hooks", "docs"];
9
+ /**
10
+ * カテゴリ文字列をパースしてバリデーションする
11
+ * @param categoryString カンマ区切りのカテゴリ文字列(例: "commands,agents")
12
+ * @returns バリデーション結果
13
+ */
14
+ export function validateCategories(categoryString) {
15
+ // カンマで分割してトリム
16
+ const categories = categoryString
17
+ .split(",")
18
+ .map((cat) => cat.trim())
19
+ .filter((cat) => cat !== "");
20
+ const validCategories = [];
21
+ const invalidCategories = [];
22
+ for (const category of categories) {
23
+ if (VALID_CATEGORIES.includes(category)) {
24
+ validCategories.push(category);
25
+ }
26
+ else {
27
+ invalidCategories.push(category);
28
+ }
29
+ }
30
+ return {
31
+ valid: invalidCategories.length === 0,
32
+ validCategories,
33
+ invalidCategories,
34
+ };
35
+ }
36
+ /**
37
+ * バリデーションエラーメッセージを生成する
38
+ * @param invalidCategories 無効なカテゴリのリスト
39
+ * @returns エラーメッセージ
40
+ */
41
+ export function createValidationErrorMessage(invalidCategories) {
42
+ const invalidList = invalidCategories.join(", ");
43
+ const validList = VALID_CATEGORIES.join(", ");
44
+ return `無効なカテゴリ: ${invalidList}\n\n有効なカテゴリは以下のいずれかです:\n - ${validList}`;
45
+ }
46
+ //# sourceMappingURL=category-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"category-validator.js","sourceRoot":"","sources":["../../../src/lib/sync/category-validator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAU,CAAC;AAmB3F;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,cAAsB;IACxD,cAAc;IACd,MAAM,UAAU,GAAG,cAAc;SAC/B,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;SACxB,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC;IAE9B,MAAM,eAAe,GAAa,EAAE,CAAC;IACrC,MAAM,iBAAiB,GAAa,EAAE,CAAC;IAEvC,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,gBAAgB,CAAC,QAAQ,CAAC,QAAyB,CAAC,EAAE,CAAC;YAC1D,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChC,CAAC;aAAM,CAAC;YACP,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAClC,CAAC;IACF,CAAC;IAED,OAAO;QACN,KAAK,EAAE,iBAAiB,CAAC,MAAM,KAAK,CAAC;QACrC,eAAe;QACf,iBAAiB;KACjB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,4BAA4B,CAAC,iBAA2B;IACvE,MAAM,WAAW,GAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjD,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAE9C,OAAO,YAAY,WAAW,+BAA+B,SAAS,EAAE,CAAC;AAC1E,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=category-validator.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"category-validator.test.d.ts","sourceRoot":"","sources":["../../../src/lib/sync/category-validator.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,89 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { VALID_CATEGORIES, createValidationErrorMessage, validateCategories, } from "./category-validator.js";
3
+ describe("category-validator", () => {
4
+ describe("validateCategories", () => {
5
+ it("単一の有効なカテゴリを受け入れる", () => {
6
+ const result = validateCategories("commands");
7
+ expect(result.valid).toBe(true);
8
+ expect(result.validCategories).toEqual(["commands"]);
9
+ expect(result.invalidCategories).toEqual([]);
10
+ });
11
+ it("複数の有効なカテゴリを受け入れる", () => {
12
+ const result = validateCategories("commands,agents,skills");
13
+ expect(result.valid).toBe(true);
14
+ expect(result.validCategories).toEqual(["commands", "agents", "skills"]);
15
+ expect(result.invalidCategories).toEqual([]);
16
+ });
17
+ it("全ての有効なカテゴリを受け入れる", () => {
18
+ const result = validateCategories("commands,agents,skills,docs");
19
+ expect(result.valid).toBe(true);
20
+ expect(result.validCategories).toEqual([
21
+ "commands",
22
+ "agents",
23
+ "skills",
24
+ "docs",
25
+ ]);
26
+ expect(result.invalidCategories).toEqual([]);
27
+ });
28
+ it("スペースを含む入力を正しくトリムする", () => {
29
+ const result = validateCategories(" commands , agents , skills ");
30
+ expect(result.valid).toBe(true);
31
+ expect(result.validCategories).toEqual(["commands", "agents", "skills"]);
32
+ expect(result.invalidCategories).toEqual([]);
33
+ });
34
+ it("単一の無効なカテゴリを拒否する", () => {
35
+ const result = validateCategories("invalid-category");
36
+ expect(result.valid).toBe(false);
37
+ expect(result.validCategories).toEqual([]);
38
+ expect(result.invalidCategories).toEqual(["invalid-category"]);
39
+ });
40
+ it("複数の無効なカテゴリを拒否する", () => {
41
+ const result = validateCategories("invalid1,invalid2");
42
+ expect(result.valid).toBe(false);
43
+ expect(result.validCategories).toEqual([]);
44
+ expect(result.invalidCategories).toEqual(["invalid1", "invalid2"]);
45
+ });
46
+ it("有効と無効が混在する場合、無効として判定する", () => {
47
+ const result = validateCategories("commands,invalid,agents");
48
+ expect(result.valid).toBe(false);
49
+ expect(result.validCategories).toEqual(["commands", "agents"]);
50
+ expect(result.invalidCategories).toEqual(["invalid"]);
51
+ });
52
+ it("空文字列を適切に処理する", () => {
53
+ const result = validateCategories("");
54
+ expect(result.valid).toBe(true);
55
+ expect(result.validCategories).toEqual([]);
56
+ expect(result.invalidCategories).toEqual([]);
57
+ });
58
+ it("連続したカンマを適切に処理する", () => {
59
+ const result = validateCategories("commands,,agents");
60
+ expect(result.valid).toBe(true);
61
+ expect(result.validCategories).toEqual(["commands", "agents"]);
62
+ expect(result.invalidCategories).toEqual([]);
63
+ });
64
+ });
65
+ describe("createValidationErrorMessage", () => {
66
+ it("単一の無効なカテゴリのエラーメッセージを生成する", () => {
67
+ const message = createValidationErrorMessage(["invalid-category"]);
68
+ expect(message).toContain("無効なカテゴリ: invalid-category");
69
+ expect(message).toContain("有効なカテゴリは以下のいずれかです:");
70
+ expect(message).toContain("commands, agents, skills, hooks, docs");
71
+ });
72
+ it("複数の無効なカテゴリのエラーメッセージを生成する", () => {
73
+ const message = createValidationErrorMessage([
74
+ "invalid1",
75
+ "invalid2",
76
+ "invalid3",
77
+ ]);
78
+ expect(message).toContain("無効なカテゴリ: invalid1, invalid2, invalid3");
79
+ expect(message).toContain("有効なカテゴリは以下のいずれかです:");
80
+ expect(message).toContain("commands, agents, skills, hooks, docs");
81
+ });
82
+ });
83
+ describe("VALID_CATEGORIES", () => {
84
+ it("全ての有効なカテゴリが定義されている", () => {
85
+ expect(VALID_CATEGORIES).toEqual(["commands", "agents", "skills", "hooks", "docs"]);
86
+ });
87
+ });
88
+ });
89
+ //# sourceMappingURL=category-validator.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"category-validator.test.js","sourceRoot":"","sources":["../../../src/lib/sync/category-validator.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ import type { Conflict } from "../../types/sync.js";
2
+ /**
3
+ * コンフリクト報告結果
4
+ */
5
+ export interface ConflictReport {
6
+ /** コンフリクトが存在するか */
7
+ hasConflicts: boolean;
8
+ /** コンフリクトが発生したファイルのパスと情報 */
9
+ files: Array<{
10
+ path: string;
11
+ conflicts: Conflict[];
12
+ }>;
13
+ /** 総コンフリクト数 */
14
+ totalConflicts: number;
15
+ }
16
+ /**
17
+ * コンフリクト報告クラス
18
+ * コンフリクトの検出、報告、ヘルプメッセージの生成を担当
19
+ */
20
+ export declare class ConflictReporter {
21
+ /**
22
+ * コンフリクト情報をレポートとしてまとめる
23
+ * @param fileConflicts - ファイルパスとコンフリクト情報のマップ
24
+ * @returns コンフリクトレポート
25
+ */
26
+ createReport(fileConflicts: Map<string, Conflict[]>): ConflictReport;
27
+ /**
28
+ * コンフリクトレポートを人間が読みやすい形式で出力する
29
+ * @param report - コンフリクトレポート
30
+ * @returns フォーマット済みのメッセージ
31
+ */
32
+ formatReport(report: ConflictReport): string;
33
+ /**
34
+ * コンフリクト解消方法のヘルプメッセージを生成する
35
+ * @returns ヘルプメッセージ
36
+ */
37
+ formatHelpMessage(): string;
38
+ /**
39
+ * ファイルに未解決のコンフリクトマーカーが存在するか検出する
40
+ * @param content - ファイル内容
41
+ * @returns 未解決のコンフリクトマーカーが存在するか
42
+ */
43
+ hasUnresolvedConflicts(content: string): boolean;
44
+ /**
45
+ * 未解決のコンフリクトが存在する場合のエラーメッセージを生成する
46
+ * @param filePath - ファイルパス
47
+ * @returns エラーメッセージ
48
+ */
49
+ formatUnresolvedConflictError(filePath: string): string;
50
+ /**
51
+ * コンフリクト発生時の終了メッセージを生成する
52
+ * @param report - コンフリクトレポート
53
+ * @returns 終了メッセージ
54
+ */
55
+ formatExitMessage(report: ConflictReport): string;
56
+ }
57
+ //# sourceMappingURL=conflict-reporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conflict-reporter.d.ts","sourceRoot":"","sources":["../../../src/lib/sync/conflict-reporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B,mBAAmB;IACnB,YAAY,EAAE,OAAO,CAAC;IACtB,4BAA4B;IAC5B,KAAK,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,QAAQ,EAAE,CAAC;KACtB,CAAC,CAAC;IACH,eAAe;IACf,cAAc,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,qBAAa,gBAAgB;IAC5B;;;;OAIG;IACH,YAAY,CACX,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,GACpC,cAAc;IAiBjB;;;;OAIG;IACH,YAAY,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM;IAkB5C;;;OAGG;IACH,iBAAiB,IAAI,MAAM;IAW3B;;;;OAIG;IACH,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAShD;;;;OAIG;IACH,6BAA6B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAIvD;;;;OAIG;IACH,iBAAiB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM;CAGjD"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * コンフリクト報告クラス
3
+ * コンフリクトの検出、報告、ヘルプメッセージの生成を担当
4
+ */
5
+ export class ConflictReporter {
6
+ /**
7
+ * コンフリクト情報をレポートとしてまとめる
8
+ * @param fileConflicts - ファイルパスとコンフリクト情報のマップ
9
+ * @returns コンフリクトレポート
10
+ */
11
+ createReport(fileConflicts) {
12
+ const files = Array.from(fileConflicts.entries())
13
+ .filter(([_, conflicts]) => conflicts.length > 0)
14
+ .map(([path, conflicts]) => ({ path, conflicts }));
15
+ const totalConflicts = files.reduce((sum, file) => sum + file.conflicts.length, 0);
16
+ return {
17
+ hasConflicts: files.length > 0,
18
+ files,
19
+ totalConflicts,
20
+ };
21
+ }
22
+ /**
23
+ * コンフリクトレポートを人間が読みやすい形式で出力する
24
+ * @param report - コンフリクトレポート
25
+ * @returns フォーマット済みのメッセージ
26
+ */
27
+ formatReport(report) {
28
+ if (!report.hasConflicts) {
29
+ return "コンフリクトは検出されませんでした。";
30
+ }
31
+ const lines = [];
32
+ lines.push(`⚠️ ${report.totalConflicts}件のコンフリクトが検出されました:\n`);
33
+ for (const file of report.files) {
34
+ lines.push(` 📄 ${file.path} (${file.conflicts.length}箇所)`);
35
+ for (const conflict of file.conflicts) {
36
+ lines.push(` - 行${conflict.line}`);
37
+ }
38
+ }
39
+ return lines.join("\n");
40
+ }
41
+ /**
42
+ * コンフリクト解消方法のヘルプメッセージを生成する
43
+ * @returns ヘルプメッセージ
44
+ */
45
+ formatHelpMessage() {
46
+ const lines = [];
47
+ lines.push("\n💡 コンフリクト解消方法:");
48
+ lines.push(" 1. 上記ファイルを開く");
49
+ lines.push(" 2. <<<<<<< LOCAL と >>>>>>> TEMPLATE の間を手動編集");
50
+ lines.push(" 3. コンフリクトマーカーを削除");
51
+ lines.push(" 4. 再度 sync を実行\n");
52
+ return lines.join("\n");
53
+ }
54
+ /**
55
+ * ファイルに未解決のコンフリクトマーカーが存在するか検出する
56
+ * @param content - ファイル内容
57
+ * @returns 未解決のコンフリクトマーカーが存在するか
58
+ */
59
+ hasUnresolvedConflicts(content) {
60
+ const lines = content.split("\n");
61
+ return lines.some((line) => line.startsWith("<<<<<<< LOCAL") ||
62
+ line.startsWith(">>>>>>> TEMPLATE"));
63
+ }
64
+ /**
65
+ * 未解決のコンフリクトが存在する場合のエラーメッセージを生成する
66
+ * @param filePath - ファイルパス
67
+ * @returns エラーメッセージ
68
+ */
69
+ formatUnresolvedConflictError(filePath) {
70
+ return `❌ 未解決のコンフリクトが存在します: ${filePath}\n\nコンフリクトマーカー(<<<<<<< LOCAL, =======, >>>>>>> TEMPLATE)を解消してから再度実行してください。`;
71
+ }
72
+ /**
73
+ * コンフリクト発生時の終了メッセージを生成する
74
+ * @param report - コンフリクトレポート
75
+ * @returns 終了メッセージ
76
+ */
77
+ formatExitMessage(report) {
78
+ return `${this.formatReport(report)}${this.formatHelpMessage()}\n⚠️ 同期処理は部分的に完了しましたが、コンフリクトの解消が必要です。`;
79
+ }
80
+ }
81
+ //# sourceMappingURL=conflict-reporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conflict-reporter.js","sourceRoot":"","sources":["../../../src/lib/sync/conflict-reporter.ts"],"names":[],"mappings":"AAiBA;;;GAGG;AACH,MAAM,OAAO,gBAAgB;IAC5B;;;;OAIG;IACH,YAAY,CACX,aAAsC;QAEtC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC;aAC/C,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;aAChD,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;QAEpD,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,CAClC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAC1C,CAAC,CACD,CAAC;QAEF,OAAO;YACN,YAAY,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC;YAC9B,KAAK;YACL,cAAc;SACd,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,YAAY,CAAC,MAAsB;QAClC,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;YAC1B,OAAO,oBAAoB,CAAC;QAC7B,CAAC;QAED,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,OAAO,MAAM,CAAC,cAAc,qBAAqB,CAAC,CAAC;QAE9D,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACjC,KAAK,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC;YAC7D,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACvC,KAAK,CAAC,IAAI,CAAC,WAAW,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;YACxC,CAAC;QACF,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC;IAED;;;OAGG;IACH,iBAAiB;QAChB,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC;QAC5D,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAEjC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC;IAED;;;;OAIG;IACH,sBAAsB,CAAC,OAAe;QACrC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClC,OAAO,KAAK,CAAC,IAAI,CAChB,CAAC,IAAI,EAAE,EAAE,CACR,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC;YAChC,IAAI,CAAC,UAAU,CAAC,kBAAkB,CAAC,CACpC,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,6BAA6B,CAAC,QAAgB;QAC7C,OAAO,uBAAuB,QAAQ,4EAA4E,CAAC;IACpH,CAAC;IAED;;;;OAIG;IACH,iBAAiB,CAAC,MAAsB;QACvC,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,iBAAiB,EAAE,wCAAwC,CAAC;IACxG,CAAC;CACD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=conflict-reporter.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conflict-reporter.test.d.ts","sourceRoot":"","sources":["../../../src/lib/sync/conflict-reporter.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,132 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { ConflictReporter } from "./conflict-reporter.js";
3
+ describe("ConflictReporter", () => {
4
+ const reporter = new ConflictReporter();
5
+ describe("createReport", () => {
6
+ it("コンフリクトがある場合、正しくレポートを作成する", () => {
7
+ const fileConflicts = new Map([
8
+ [
9
+ "file1.txt",
10
+ [
11
+ { line: 10, localContent: "local1", templateContent: "template1" },
12
+ { line: 20, localContent: "local2", templateContent: "template2" },
13
+ ],
14
+ ],
15
+ [
16
+ "file2.txt",
17
+ [{ line: 5, localContent: "local3", templateContent: "template3" }],
18
+ ],
19
+ ]);
20
+ const report = reporter.createReport(fileConflicts);
21
+ expect(report.hasConflicts).toBe(true);
22
+ expect(report.files).toHaveLength(2);
23
+ expect(report.totalConflicts).toBe(3);
24
+ expect(report.files[0].path).toBe("file1.txt");
25
+ expect(report.files[0].conflicts).toHaveLength(2);
26
+ expect(report.files[1].path).toBe("file2.txt");
27
+ expect(report.files[1].conflicts).toHaveLength(1);
28
+ });
29
+ it("コンフリクトがない場合、空のレポートを作成する", () => {
30
+ const fileConflicts = new Map([
31
+ ["file1.txt", []],
32
+ ["file2.txt", []],
33
+ ]);
34
+ const report = reporter.createReport(fileConflicts);
35
+ expect(report.hasConflicts).toBe(false);
36
+ expect(report.files).toHaveLength(0);
37
+ expect(report.totalConflicts).toBe(0);
38
+ });
39
+ });
40
+ describe("formatReport", () => {
41
+ it("コンフリクトがある場合、フォーマット済みのレポートを返す", () => {
42
+ const report = {
43
+ hasConflicts: true,
44
+ files: [
45
+ {
46
+ path: "file1.txt",
47
+ conflicts: [
48
+ { line: 10, localContent: "a", templateContent: "b" },
49
+ { line: 20, localContent: "c", templateContent: "d" },
50
+ ],
51
+ },
52
+ {
53
+ path: "file2.txt",
54
+ conflicts: [{ line: 5, localContent: "e", templateContent: "f" }],
55
+ },
56
+ ],
57
+ totalConflicts: 3,
58
+ };
59
+ const formatted = reporter.formatReport(report);
60
+ expect(formatted).toContain("3件のコンフリクトが検出されました");
61
+ expect(formatted).toContain("file1.txt (2箇所)");
62
+ expect(formatted).toContain("行10");
63
+ expect(formatted).toContain("行20");
64
+ expect(formatted).toContain("file2.txt (1箇所)");
65
+ expect(formatted).toContain("行5");
66
+ });
67
+ it("コンフリクトがない場合、メッセージを返す", () => {
68
+ const report = {
69
+ hasConflicts: false,
70
+ files: [],
71
+ totalConflicts: 0,
72
+ };
73
+ const formatted = reporter.formatReport(report);
74
+ expect(formatted).toBe("コンフリクトは検出されませんでした。");
75
+ });
76
+ });
77
+ describe("formatHelpMessage", () => {
78
+ it("コンフリクト解消方法のヘルプメッセージを返す", () => {
79
+ const helpMessage = reporter.formatHelpMessage();
80
+ expect(helpMessage).toContain("コンフリクト解消方法");
81
+ expect(helpMessage).toContain("上記ファイルを開く");
82
+ expect(helpMessage).toContain("<<<<<<< LOCAL と >>>>>>> TEMPLATE");
83
+ expect(helpMessage).toContain("再度 sync を実行");
84
+ });
85
+ });
86
+ describe("hasUnresolvedConflicts", () => {
87
+ it("未解決のコンフリクトマーカーが存在する場合、trueを返す", () => {
88
+ const content = `行1
89
+ <<<<<<< LOCAL (your changes)
90
+ ローカル版
91
+ =======
92
+ テンプレート版
93
+ >>>>>>> TEMPLATE (from @einja/cli)
94
+ 行2`;
95
+ expect(reporter.hasUnresolvedConflicts(content)).toBe(true);
96
+ });
97
+ it("コンフリクトマーカーが存在しない場合、falseを返す", () => {
98
+ const content = "行1\n行2\n行3";
99
+ expect(reporter.hasUnresolvedConflicts(content)).toBe(false);
100
+ });
101
+ });
102
+ describe("formatUnresolvedConflictError", () => {
103
+ it("未解決のコンフリクトエラーメッセージを返す", () => {
104
+ const error = reporter.formatUnresolvedConflictError("file.txt");
105
+ expect(error).toContain("未解決のコンフリクトが存在します");
106
+ expect(error).toContain("file.txt");
107
+ expect(error).toContain("<<<<<<< LOCAL");
108
+ expect(error).toContain(">>>>>>> TEMPLATE");
109
+ });
110
+ });
111
+ describe("formatExitMessage", () => {
112
+ it("コンフリクト発生時の終了メッセージを返す", () => {
113
+ const report = {
114
+ hasConflicts: true,
115
+ files: [
116
+ {
117
+ path: "file.txt",
118
+ conflicts: [
119
+ { line: 10, localContent: "a", templateContent: "b" },
120
+ ],
121
+ },
122
+ ],
123
+ totalConflicts: 1,
124
+ };
125
+ const message = reporter.formatExitMessage(report);
126
+ expect(message).toContain("1件のコンフリクトが検出されました");
127
+ expect(message).toContain("コンフリクト解消方法");
128
+ expect(message).toContain("同期処理は部分的に完了しました");
129
+ });
130
+ });
131
+ });
132
+ //# sourceMappingURL=conflict-reporter.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conflict-reporter.test.js","sourceRoot":"","sources":["../../../src/lib/sync/conflict-reporter.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { Conflict, MergeResult } from "../../types/sync.js";
2
+ /**
3
+ * 3方向マージエンジン
4
+ * node-diff3ライブラリを使用して、ベース版・ローカル版・テンプレート版の3方向マージを実行
5
+ */
6
+ export declare class DiffEngine {
7
+ /**
8
+ * 3方向マージを実行する
9
+ * @param base - ベース版の内容(前回同期時のテンプレート版)
10
+ * @param local - ローカル版の内容(現在のプロジェクトファイル)
11
+ * @param template - テンプレート版の内容(最新のテンプレートファイル)
12
+ * @returns マージ結果
13
+ */
14
+ merge3Way(base: string, local: string, template: string): MergeResult;
15
+ /**
16
+ * コンフリクトマーカーを検出する
17
+ * @param content - ファイル内容
18
+ * @returns 未解決のコンフリクトマーカーが存在するか
19
+ */
20
+ hasConflictMarkers(content: string): boolean;
21
+ /**
22
+ * コンフリクトマーカーをパースしてコンフリクト情報を抽出する
23
+ * @param content - ファイル内容
24
+ * @returns コンフリクト一覧
25
+ */
26
+ parseConflictMarkers(content: string): Conflict[];
27
+ }
28
+ //# sourceMappingURL=diff-engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff-engine.d.ts","sourceRoot":"","sources":["../../../src/lib/sync/diff-engine.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEjE;;;GAGG;AACH,qBAAa,UAAU;IACtB;;;;;;OAMG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW;IAmDrE;;;;OAIG;IACH,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAS5C;;;;OAIG;IACH,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,EAAE;CA2CjD"}
@@ -0,0 +1,118 @@
1
+ import { diff3Merge } from "node-diff3";
2
+ /**
3
+ * 3方向マージエンジン
4
+ * node-diff3ライブラリを使用して、ベース版・ローカル版・テンプレート版の3方向マージを実行
5
+ */
6
+ export class DiffEngine {
7
+ /**
8
+ * 3方向マージを実行する
9
+ * @param base - ベース版の内容(前回同期時のテンプレート版)
10
+ * @param local - ローカル版の内容(現在のプロジェクトファイル)
11
+ * @param template - テンプレート版の内容(最新のテンプレートファイル)
12
+ * @returns マージ結果
13
+ */
14
+ merge3Way(base, local, template) {
15
+ // 各バージョンを行単位に分割
16
+ const baseLines = base.split("\n");
17
+ const localLines = local.split("\n");
18
+ const templateLines = template.split("\n");
19
+ // node-diff3でマージを実行
20
+ const mergeResult = diff3Merge(localLines, baseLines, templateLines);
21
+ // マージ結果を処理
22
+ const conflicts = [];
23
+ const mergedLines = [];
24
+ let currentLine = 1;
25
+ for (const chunk of mergeResult) {
26
+ if ("ok" in chunk && chunk.ok) {
27
+ // コンフリクトなしのチャンク
28
+ mergedLines.push(...chunk.ok);
29
+ currentLine += chunk.ok.length;
30
+ }
31
+ else if ("conflict" in chunk && chunk.conflict) {
32
+ // コンフリクトが発生したチャンク
33
+ const localContent = chunk.conflict.a.join("\n");
34
+ const templateContent = chunk.conflict.b.join("\n");
35
+ // コンフリクト情報を記録
36
+ conflicts.push({
37
+ line: currentLine,
38
+ localContent,
39
+ templateContent,
40
+ });
41
+ // コンフリクトマーカーを挿入
42
+ mergedLines.push("<<<<<<< LOCAL (your changes)");
43
+ mergedLines.push(...chunk.conflict.a);
44
+ mergedLines.push("=======");
45
+ mergedLines.push(...chunk.conflict.b);
46
+ mergedLines.push(">>>>>>> TEMPLATE (from @einja/cli)");
47
+ // 行番号を更新(マーカー3行 + コンフリクト内容)
48
+ currentLine +=
49
+ 3 + chunk.conflict.a.length + chunk.conflict.b.length + 1;
50
+ }
51
+ }
52
+ return {
53
+ success: conflicts.length === 0,
54
+ content: mergedLines.join("\n"),
55
+ conflicts,
56
+ };
57
+ }
58
+ /**
59
+ * コンフリクトマーカーを検出する
60
+ * @param content - ファイル内容
61
+ * @returns 未解決のコンフリクトマーカーが存在するか
62
+ */
63
+ hasConflictMarkers(content) {
64
+ const lines = content.split("\n");
65
+ return lines.some((line) => line.startsWith("<<<<<<< LOCAL") ||
66
+ line.startsWith(">>>>>>> TEMPLATE"));
67
+ }
68
+ /**
69
+ * コンフリクトマーカーをパースしてコンフリクト情報を抽出する
70
+ * @param content - ファイル内容
71
+ * @returns コンフリクト一覧
72
+ */
73
+ parseConflictMarkers(content) {
74
+ const lines = content.split("\n");
75
+ const conflicts = [];
76
+ let inConflict = false;
77
+ let conflictStartLine = 0;
78
+ let localContent = [];
79
+ let templateContent = [];
80
+ let inLocalSection = false;
81
+ for (let i = 0; i < lines.length; i++) {
82
+ const line = lines[i];
83
+ if (line.startsWith("<<<<<<< LOCAL")) {
84
+ // コンフリクト開始
85
+ inConflict = true;
86
+ inLocalSection = true;
87
+ conflictStartLine = i + 1;
88
+ localContent = [];
89
+ templateContent = [];
90
+ }
91
+ else if (line === "=======" && inConflict) {
92
+ // LOCAL→TEMPLATE境界
93
+ inLocalSection = false;
94
+ }
95
+ else if (line.startsWith(">>>>>>> TEMPLATE") && inConflict) {
96
+ // コンフリクト終了
97
+ conflicts.push({
98
+ line: conflictStartLine,
99
+ localContent: localContent.join("\n"),
100
+ templateContent: templateContent.join("\n"),
101
+ });
102
+ inConflict = false;
103
+ inLocalSection = false;
104
+ }
105
+ else if (inConflict) {
106
+ // コンフリクト内容を収集
107
+ if (inLocalSection) {
108
+ localContent.push(line);
109
+ }
110
+ else {
111
+ templateContent.push(line);
112
+ }
113
+ }
114
+ }
115
+ return conflicts;
116
+ }
117
+ }
118
+ //# sourceMappingURL=diff-engine.js.map