@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.
- package/README.md +179 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +49 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +243 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list.d.ts +2 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +23 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/sync.d.ts +7 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +294 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/sync.test.d.ts +2 -0
- package/dist/commands/sync.test.d.ts.map +1 -0
- package/dist/commands/sync.test.js +593 -0
- package/dist/commands/sync.test.js.map +1 -0
- package/dist/commands/task-loop.d.ts +11 -0
- package/dist/commands/task-loop.d.ts.map +1 -0
- package/dist/commands/task-loop.js +81 -0
- package/dist/commands/task-loop.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/file-system.d.ts +39 -0
- package/dist/lib/file-system.d.ts.map +1 -0
- package/dist/lib/file-system.js +79 -0
- package/dist/lib/file-system.js.map +1 -0
- package/dist/lib/mcp-config.d.ts +43 -0
- package/dist/lib/mcp-config.d.ts.map +1 -0
- package/dist/lib/mcp-config.js +109 -0
- package/dist/lib/mcp-config.js.map +1 -0
- package/dist/lib/mcp-config.test.d.ts +2 -0
- package/dist/lib/mcp-config.test.d.ts.map +1 -0
- package/dist/lib/mcp-config.test.js +285 -0
- package/dist/lib/mcp-config.test.js.map +1 -0
- package/dist/lib/merger.d.ts +41 -0
- package/dist/lib/merger.d.ts.map +1 -0
- package/dist/lib/merger.js +164 -0
- package/dist/lib/merger.js.map +1 -0
- package/dist/lib/preset-update/cli-repo-detector.d.ts +35 -0
- package/dist/lib/preset-update/cli-repo-detector.d.ts.map +1 -0
- package/dist/lib/preset-update/cli-repo-detector.js +83 -0
- package/dist/lib/preset-update/cli-repo-detector.js.map +1 -0
- package/dist/lib/preset-update/cli-repo-detector.test.d.ts +2 -0
- package/dist/lib/preset-update/cli-repo-detector.test.d.ts.map +1 -0
- package/dist/lib/preset-update/cli-repo-detector.test.js +120 -0
- package/dist/lib/preset-update/cli-repo-detector.test.js.map +1 -0
- package/dist/lib/preset-update/file-copier.d.ts +59 -0
- package/dist/lib/preset-update/file-copier.d.ts.map +1 -0
- package/dist/lib/preset-update/file-copier.js +220 -0
- package/dist/lib/preset-update/file-copier.js.map +1 -0
- package/dist/lib/preset-update/file-copier.test.d.ts +2 -0
- package/dist/lib/preset-update/file-copier.test.d.ts.map +1 -0
- package/dist/lib/preset-update/file-copier.test.js +297 -0
- package/dist/lib/preset-update/file-copier.test.js.map +1 -0
- package/dist/lib/preset-update/preset-finder.d.ts +39 -0
- package/dist/lib/preset-update/preset-finder.d.ts.map +1 -0
- package/dist/lib/preset-update/preset-finder.js +92 -0
- package/dist/lib/preset-update/preset-finder.js.map +1 -0
- package/dist/lib/preset-update/preset-finder.test.d.ts +2 -0
- package/dist/lib/preset-update/preset-finder.test.d.ts.map +1 -0
- package/dist/lib/preset-update/preset-finder.test.js +128 -0
- package/dist/lib/preset-update/preset-finder.test.js.map +1 -0
- package/dist/lib/preset.d.ts +14 -0
- package/dist/lib/preset.d.ts.map +1 -0
- package/dist/lib/preset.js +52 -0
- package/dist/lib/preset.js.map +1 -0
- package/dist/lib/sync/backup-manager.d.ts +50 -0
- package/dist/lib/sync/backup-manager.d.ts.map +1 -0
- package/dist/lib/sync/backup-manager.js +117 -0
- package/dist/lib/sync/backup-manager.js.map +1 -0
- package/dist/lib/sync/backup-manager.test.d.ts +2 -0
- package/dist/lib/sync/backup-manager.test.d.ts.map +1 -0
- package/dist/lib/sync/backup-manager.test.js +155 -0
- package/dist/lib/sync/backup-manager.test.js.map +1 -0
- package/dist/lib/sync/batch-processor.d.ts +27 -0
- package/dist/lib/sync/batch-processor.d.ts.map +1 -0
- package/dist/lib/sync/batch-processor.js +46 -0
- package/dist/lib/sync/batch-processor.js.map +1 -0
- package/dist/lib/sync/batch-processor.test.d.ts +2 -0
- package/dist/lib/sync/batch-processor.test.d.ts.map +1 -0
- package/dist/lib/sync/batch-processor.test.js +110 -0
- package/dist/lib/sync/batch-processor.test.js.map +1 -0
- package/dist/lib/sync/category-validator.d.ts +36 -0
- package/dist/lib/sync/category-validator.d.ts.map +1 -0
- package/dist/lib/sync/category-validator.js +46 -0
- package/dist/lib/sync/category-validator.js.map +1 -0
- package/dist/lib/sync/category-validator.test.d.ts +2 -0
- package/dist/lib/sync/category-validator.test.d.ts.map +1 -0
- package/dist/lib/sync/category-validator.test.js +89 -0
- package/dist/lib/sync/category-validator.test.js.map +1 -0
- package/dist/lib/sync/conflict-reporter.d.ts +57 -0
- package/dist/lib/sync/conflict-reporter.d.ts.map +1 -0
- package/dist/lib/sync/conflict-reporter.js +81 -0
- package/dist/lib/sync/conflict-reporter.js.map +1 -0
- package/dist/lib/sync/conflict-reporter.test.d.ts +2 -0
- package/dist/lib/sync/conflict-reporter.test.d.ts.map +1 -0
- package/dist/lib/sync/conflict-reporter.test.js +132 -0
- package/dist/lib/sync/conflict-reporter.test.js.map +1 -0
- package/dist/lib/sync/diff-engine.d.ts +28 -0
- package/dist/lib/sync/diff-engine.d.ts.map +1 -0
- package/dist/lib/sync/diff-engine.js +118 -0
- package/dist/lib/sync/diff-engine.js.map +1 -0
- package/dist/lib/sync/diff-engine.test.d.ts +2 -0
- package/dist/lib/sync/diff-engine.test.d.ts.map +1 -0
- package/dist/lib/sync/diff-engine.test.js +133 -0
- package/dist/lib/sync/diff-engine.test.js.map +1 -0
- package/dist/lib/sync/file-filter.d.ts +40 -0
- package/dist/lib/sync/file-filter.d.ts.map +1 -0
- package/dist/lib/sync/file-filter.js +171 -0
- package/dist/lib/sync/file-filter.js.map +1 -0
- package/dist/lib/sync/file-filter.test.d.ts +2 -0
- package/dist/lib/sync/file-filter.test.d.ts.map +1 -0
- package/dist/lib/sync/file-filter.test.js +179 -0
- package/dist/lib/sync/file-filter.test.js.map +1 -0
- package/dist/lib/sync/hash-cache.d.ts +34 -0
- package/dist/lib/sync/hash-cache.d.ts.map +1 -0
- package/dist/lib/sync/hash-cache.js +51 -0
- package/dist/lib/sync/hash-cache.js.map +1 -0
- package/dist/lib/sync/hash-cache.test.d.ts +2 -0
- package/dist/lib/sync/hash-cache.test.d.ts.map +1 -0
- package/dist/lib/sync/hash-cache.test.js +110 -0
- package/dist/lib/sync/hash-cache.test.js.map +1 -0
- package/dist/lib/sync/integration.test.d.ts +2 -0
- package/dist/lib/sync/integration.test.d.ts.map +1 -0
- package/dist/lib/sync/integration.test.js +317 -0
- package/dist/lib/sync/integration.test.js.map +1 -0
- package/dist/lib/sync/marker-processor.d.ts +54 -0
- package/dist/lib/sync/marker-processor.d.ts.map +1 -0
- package/dist/lib/sync/marker-processor.js +208 -0
- package/dist/lib/sync/marker-processor.js.map +1 -0
- package/dist/lib/sync/marker-processor.test.d.ts +2 -0
- package/dist/lib/sync/marker-processor.test.d.ts.map +1 -0
- package/dist/lib/sync/marker-processor.test.js +245 -0
- package/dist/lib/sync/marker-processor.test.js.map +1 -0
- package/dist/lib/sync/metadata-manager.d.ts +46 -0
- package/dist/lib/sync/metadata-manager.d.ts.map +1 -0
- package/dist/lib/sync/metadata-manager.js +129 -0
- package/dist/lib/sync/metadata-manager.js.map +1 -0
- package/dist/lib/sync/metadata-manager.test.d.ts +2 -0
- package/dist/lib/sync/metadata-manager.test.d.ts.map +1 -0
- package/dist/lib/sync/metadata-manager.test.js +137 -0
- package/dist/lib/sync/metadata-manager.test.js.map +1 -0
- package/dist/lib/sync/performance.test.d.ts +2 -0
- package/dist/lib/sync/performance.test.d.ts.map +1 -0
- package/dist/lib/sync/performance.test.js +126 -0
- package/dist/lib/sync/performance.test.js.map +1 -0
- package/dist/types/index.d.ts +59 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/preset-update.d.ts +106 -0
- package/dist/types/preset-update.d.ts.map +1 -0
- package/dist/types/preset-update.js +5 -0
- package/dist/types/preset-update.js.map +1 -0
- package/dist/types/sync.d.ts +169 -0
- package/dist/types/sync.d.ts.map +1 -0
- package/dist/types/sync.js +19 -0
- package/dist/types/sync.js.map +1 -0
- package/package.json +72 -0
- package/presets/minimal/.claude/agents/einja/docs/docs-updater.md +161 -0
- package/presets/minimal/.claude/agents/einja/frontend/design-engineer.md +685 -0
- package/presets/minimal/.claude/agents/einja/frontend/frontend-architect.md +747 -0
- package/presets/minimal/.claude/agents/einja/frontend/frontend-coder.md +441 -0
- package/presets/minimal/.claude/agents/einja/git/conflict-resolver.md +148 -0
- package/presets/minimal/.claude/agents/einja/specs/spec-design-generator.md +462 -0
- package/presets/minimal/.claude/agents/einja/specs/spec-qa-generator.md +466 -0
- package/presets/minimal/.claude/agents/einja/specs/spec-requirements-generator.md +416 -0
- package/presets/minimal/.claude/agents/einja/specs/spec-tasks-generator.md +608 -0
- package/presets/minimal/.claude/agents/einja/task/task-committer.md +82 -0
- package/presets/minimal/.claude/agents/einja/task/task-executer.md +352 -0
- package/presets/minimal/.claude/agents/einja/task/task-modification-analyzer.md +369 -0
- package/presets/minimal/.claude/agents/einja/task/task-qa.md +74 -0
- package/presets/minimal/.claude/agents/einja/task/task-reviewer.md +169 -0
- package/presets/minimal/.claude/commands/einja/frontend-implement.md +322 -0
- package/presets/minimal/.claude/commands/einja/spec-create.md +254 -0
- package/presets/minimal/.claude/commands/einja/start-dev.md +98 -0
- package/presets/minimal/.claude/commands/einja/sync-cursor-commands.md +203 -0
- package/presets/minimal/.claude/commands/einja/task-exec.md +390 -0
- package/presets/minimal/.claude/commands/einja/update-docs-by-task-specs.md +448 -0
- package/presets/minimal/.claude/hooks/einja/biome-format.sh +49 -0
- package/presets/minimal/.claude/hooks/einja/design-doc-check.sh +61 -0
- package/presets/minimal/.claude/hooks/einja/detect-secrets.sh +62 -0
- package/presets/minimal/.claude/hooks/einja/large-file-warning.sh +42 -0
- package/presets/minimal/.claude/hooks/einja/playwright-resize.sh +36 -0
- package/presets/minimal/.claude/hooks/einja/typecheck.sh +37 -0
- package/presets/minimal/.claude/hooks/einja/unset-volta-recursion.sh +32 -0
- package/presets/minimal/.claude/hooks/einja/validate-git-commit.sh +239 -0
- package/presets/minimal/.claude/hooks/einja/warn-index-ts.sh +34 -0
- package/presets/minimal/.claude/hooks/einja/warn-relative-import.sh +48 -0
- package/presets/minimal/.claude/settings.json +174 -0
- package/presets/minimal/.claude/skills/einja/api-development/SKILL.md +14 -0
- package/presets/minimal/.claude/skills/einja/backend-architecture/SKILL.md +14 -0
- package/presets/minimal/.claude/skills/einja/coding-standards/SKILL.md +120 -0
- package/presets/minimal/.claude/skills/einja/coding-standards/reference/naming-conventions.md +107 -0
- package/presets/minimal/.claude/skills/einja/coding-standards/reference/prohibited-patterns.md +169 -0
- package/presets/minimal/.claude/skills/einja/coding-standards/reference/typescript-rules.md +247 -0
- package/presets/minimal/.claude/skills/einja/component-design/SKILL.md +109 -0
- package/presets/minimal/.claude/skills/einja/component-design/reference/directory-structure.md +117 -0
- package/presets/minimal/.claude/skills/einja/component-design/reference/props-patterns.md +159 -0
- package/presets/minimal/.claude/skills/einja/component-design/reference/styling-guide.md +200 -0
- package/presets/minimal/.claude/skills/einja/conflict-resolver/SKILL.md +190 -0
- package/presets/minimal/.claude/skills/einja/frontend-development/SKILL.md +14 -0
- package/presets/minimal/.claude/skills/einja/general-context-loader/SKILL.md +254 -0
- package/presets/minimal/.claude/skills/einja/output-format/SKILL.md +137 -0
- package/presets/minimal/.claude/skills/einja/spec-context-loader/SKILL.md +177 -0
- package/presets/minimal/.claude/skills/einja/task-commit/SKILL.md +269 -0
- package/presets/minimal/.claude/skills/einja/task-qa/SKILL.md +306 -0
- package/presets/minimal/.claude/skills/einja/task-qa/reference/failure-patterns.md +69 -0
- package/presets/minimal/.claude/skills/einja/task-qa/reference/troubleshooting.md +65 -0
- package/presets/minimal/.claude/skills/einja/task-qa/reference/usage-patterns.md +52 -0
- package/presets/minimal/.claude/skills/einja/task-qa/templates/qa-test-template.md +128 -0
- package/presets/minimal/preset.yaml +111 -0
- package/presets/minimal/symlinks.json +45 -0
- package/scaffolds/.mcp.json +45 -0
- package/scaffolds/CLAUDE.md.template +318 -0
- package/scaffolds/steering/README.md +170 -0
- package/scaffolds/steering/acceptance-criteria-and-qa-guide.md +415 -0
- package/scaffolds/steering/architecture.md +481 -0
- package/scaffolds/steering/branch-strategy.md +362 -0
- package/scaffolds/steering/commit-rules.md +217 -0
- package/scaffolds/steering/db-schema-design.md +609 -0
- package/scaffolds/steering/development/api-development.md +783 -0
- package/scaffolds/steering/development/backend-architecture.md +731 -0
- package/scaffolds/steering/development/frontend-development.md +1537 -0
- package/scaffolds/steering/development/review-guidelines.md +365 -0
- package/scaffolds/steering/development/testing-strategy.md +819 -0
- package/scaffolds/steering/development-workflow.md +429 -0
- package/scaffolds/steering/infrastructure/deployment.md +277 -0
- package/scaffolds/steering/infrastructure/environment-variables.md +298 -0
- package/scaffolds/steering/product.md +540 -0
- package/scaffolds/steering/task-management.md +367 -0
- package/templates/README.md +159 -0
- package/templates/design-simple.md.template +172 -0
- package/templates/design.md.template +327 -0
- package/templates/qa-test.md.template +125 -0
- 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 @@
|
|
|
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 @@
|
|
|
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
|