From 9f3474c69e3cd9c26602246ce910288909cfb35e Mon Sep 17 00:00:00 2001 From: Gabriel Crisan Date: Thu, 11 Dec 2025 12:04:27 +0200 Subject: [PATCH 01/20] Add solution templates --- .../solution_templates/solution_1.md | 128 ++++++++++++++++++ .../solution_templates/solution_2.md | 63 +++++++++ 2 files changed, 191 insertions(+) create mode 100644 llm-git-conflict-resolve/solution_templates/solution_1.md create mode 100644 llm-git-conflict-resolve/solution_templates/solution_2.md diff --git a/llm-git-conflict-resolve/solution_templates/solution_1.md b/llm-git-conflict-resolve/solution_templates/solution_1.md new file mode 100644 index 00000000..a03cbf17 --- /dev/null +++ b/llm-git-conflict-resolve/solution_templates/solution_1.md @@ -0,0 +1,128 @@ +# Git Merge Conflict Prompt for AI Agents + +Acest proiect defineste un skill pentru Claude Code Agent, conceput pentru a detecta si rezolva conflicte Git merge. Skill-ul ofera instructiuni clare, proceduri bine definite si unelte auxiliare pentru a ajuta agentul sa interpreteze fisiere aflate in conflict si sa genereze o versiune finala corecta, fara marcaje de conflict. + +## Obiectiv + +Skill-ul are ca scop furnizarea unui set complet de instructiuni prin care un AI agent poate: + +- Detecta conflictele din fisiere. +- Identifica structura markerelor Git (`<<<<<<<`, `=======`, `>>>>>>>`). +- Extrage sectiunile aflate in conflict. +- Analiza diferentele dintre variantele HEAD si branch. +- Aplica diverse strategii de merge (automata, preferinta pentru HEAD, preferinta pentru branch, semantica). +- Apela cod Python auxiliar pentru analize mai avansate. +- Genera o rezolvare finala coerenta. +- Rescrie fisierul final fara conflicte. + +Agentul nu utilizeaza comenzi Git propriu-zise. Toate operatiunile se bazeaza exclusiv pe procesarea textului, conform instructiunilor din acest skill. + +--- + +# Continutul skill-ului + +Structura skill-ului este formata din trei componente principale: fisierul de logica (`skill.md`), scriptul auxiliar (`merge_utils.py`) si documentatia de utilizare (`usage.md`). + +## 1. `skill.md` – Instructiunile principale + +Acest fisier defineste comportamentul agentului si regulile pe care trebuie sa le urmeze in timpul rezolvarii conflictelor. + +### Ce contine + +- Descrierea scopului skill-ului. +- Explicarea pasilor operationali obligatorii. +- Definirea clara a modului de detectare si extragere a conflictelor. +- Regulile de analiza si de aplicare a strategiilor de merge. +- Instructiuni despre cum sa utilizeze codul auxiliar Python. +- Exemple de input si output pentru a ghida agentul. + +### Pasii operationali + +1. Identificarea marcajelor de conflict: + ``` + <<<<<<< HEAD + ... + ======= + ... + >>>>>>> branch + ``` +2. Extractia celor doua sectiuni in structura: + ```json + { + "HEAD": "...", + "branch": "..." + } + ``` +3. Analiza diferentelor dintre sectiuni. +4. Aplicarea unei strategii de merge, conform instructiunilor si contextului. +5. Generarea unei rezolvari finale. +6. Daca este necesar, apelarea scriptului Python (`merge_utils.py`) pentru: + - detectarea conflictelor, + - comparari avansate, + - analiza semantica. +7. Interpretarea outputului JSON primit de la script. +8. Reconstruirea fisierului final fara marcaje de conflict. + +### Strategii de merge documentate + +- Strategie automata: daca una dintre versiuni este continuta in cealalta. +- Preferinta HEAD: agentul pastreaza versiunea din HEAD. +- Preferinta branch: agentul pastreaza versiunea din branch. +- Merge semantic: + - reconstructie JSON, + - combinarea functiilor in cod atunci cand modificarile nu sunt conflictuale. +- Merge asistat: agentul solicita utilizatorului o alegere explicita. + +### Exemple + +Skill-ul trebuie sa includa exemple de conflicte si rezolvarile lor, astfel incat agentul sa inteleaga formatul asteptat. + +--- + +## 2. `merge_utils.py` – Cod Python auxiliar + +Acest script este destinat operatiunilor care sunt mai eficiente sau mai sigure atunci cand sunt executate ca program local. Agentul il poate apela in mod explicit in timpul procesului. + +### Functionalitati posibile + +- `detect_conflicts(file_text)` identifica toate sectiunile conflictuale dintr-un fisier si intoarce o structura JSON. +- `three_way_merge(base, ours, theirs)` implementeaza logica unui merge in trei sensuri. +- `ast_merge_python(ours, theirs)` realizeaza un merge semantic asupra functiilor Python. +- `json_merge(ours, theirs)` combina structuri JSON intr-un mod sigur. +- `line_similarity(a, b)` ofera un scor de similaritate intre linii pentru decizii automatizate. + +### Format de output recomandat + +```json +{ + "conflicts": [ + { + "start_line": 42, + "end_line": 68, + "HEAD": "...", + "branch": "...", + "type": "text" + } + ] +} +``` + +--- + +## 3. `usage.md` – Documentatie de utilizare + +Fisierul `usage.md` explica modul corect de utilizare al skill-ului, atat pentru agent, cat si pentru utilizator. + +### Continut + +- Instructiuni despre cum trebuie apelat scriptul Python. +- Formatele acceptate pentru input. +- Modul de interpretare al outputului. +- Exemple complete de rulare. +- Conventii stabilite intre agent si script (argumente CLI, structuri JSON, etc.). + +--- + +# Concluzie + +Skill-ul ofera o metodologie completa pentru rezolvarea conflictelor Git fara a utiliza Git in mod direct. Documentatia din `skill.md` deserveste drept ghid operational pentru agent, `merge_utils.py` furnizeaza suport tehnic avansat, iar `usage.md` clarifica modul de interactiune cu skill-ul. Acest set de fisiere permite agentului sa detecteze, interpreteze si combine eficient sectiunile aflate in conflict, oferind o versiune finala curata si coerenta. diff --git a/llm-git-conflict-resolve/solution_templates/solution_2.md b/llm-git-conflict-resolve/solution_templates/solution_2.md new file mode 100644 index 00000000..854d058a --- /dev/null +++ b/llm-git-conflict-resolve/solution_templates/solution_2.md @@ -0,0 +1,63 @@ +# Git Merge Conflict Resolution Skill for AI Agents + +This repository contains a modular skill designed to enable AI agents (specifically within the Claude Code environment) to autonomously and accurately resolve git merge conflicts. + +While Large Language Models are proficient at writing code, they often struggle with the syntax of standard git merge markers (`<<<<<<<`, `=======`, `>>>>>>>`) due to a lack of context regarding the conflicting branches. This project bridges that gap by providing the agent with executable tools to retrieve the full history of the conflict (Base, Local, Remote) and a strict set of operational guidelines. + +## Architecture Overview + +The solution relies on a "Tool-Use" pattern where the agent acts not just as a text processor but as an orchestrator. It uses local Python scripts to interact with the Git CLI, processes the data, and applies resolution logic based on a predefined educational context. + +## Repository Structure & File Descriptions + +To implement this skill effectively, the project requires the following file structure. Each file serves a specific role in the agent's decision-making loop. + +### 1. `instructions.md` (The Educational Layer) +This file acts as the system prompt or "knowledge base" for the agent. It dictates the behavior and decision-making process. It does not contain code to be executed, but rather the logic the agent must follow. + +* **Purpose:** Teaches the agent the "Algorithm of Resolution." +* **Key Contents:** + * **Step-by-Step Workflow:** Instructions to identify conflicts, fetch raw data, analyze intent, and apply fixes. + * **Conflict Strategies:** Rules for handling specific scenarios (e.g., "If *Local* changes variable names and *Remote* changes logic, keep both"). + * **Import Handling:** Specific instructions to perform a union of imports rather than overwriting them. + * **Fallbacks:** Directives on what to do when code intent is ambiguous (e.g., defaulting to HEAD and adding a TODO comment). + +### 2. `git_tools.py` (The Execution Layer) +This Python script serves as the bridge between the AI agent and the local Git repository. The agent calls functions within this file to gather factual data about the state of the codebase. + +* **Purpose:** Provides deterministic, structured data to the LLM. +* **Key Functions:** + * `list_conflicted_files()`: Parses `git status --porcelain` to identify files requiring attention. + * `get_three_way_diff(filepath)`: Uses `git show` to extract the three versions of the truth: + * **:1 (Base):** The common ancestor. + * **:2 (Ours):** The local changes (HEAD). + * **:3 (Theirs):** The incoming changes. + * `validate_syntax(filepath)`: A utility to run language-specific linters (e.g., `ast` for Python) to ensure the resolved code is syntactically valid before staging. + +### 3. `resolution_template.md` (Optional) +A template file used by the agent to structure its reasoning before editing the code. + +* **Purpose:** Forces the agent to output a "Chain of Thought" before writing code. +* **Structure:** + * Conflict Summary. + * Detected Intent (Local vs. Remote). + * Proposed Resolution Strategy. + +## Operational Workflow + +When the agent is tasked with fixing a merge conflict, the expected execution flow is: + +1. **Context Loading:** The agent reads `instructions.md` to understand its role and constraints. +2. **Discovery:** The agent executes `python git_tools.py --list` to find the target files. +3. **Data Extraction:** For every conflict, the agent executes `python git_tools.py --extract `. It receives a structured object containing the Base, Ours, and Theirs content. +4. **Logic Synthesis:** The agent compares the three versions. Instead of guessing based on conflict markers, it reconstructs the valid code path based on the logic defined in the instructions. +5. **Application:** The agent rewrites the file content locally. +6. **Verification:** The agent executes `python git_tools.py --verify ` to catch syntax errors. + +## Integration + +To add this skill to your agent configuration: + +1. Place `git_tools.py` in the root or a dedicated `scripts/` directory. +2. Add the content of `instructions.md` to the agent's context or system prompt. +3. Ensure the agent has permission to execute shell commands (specifically `python` and `git`). \ No newline at end of file From bfeb02f71898577dce335e7fa76990b3b61897ca Mon Sep 17 00:00:00 2001 From: Gabriel Crisan Date: Thu, 11 Dec 2025 12:13:46 +0200 Subject: [PATCH 02/20] Translate solution file form romanian to english --- .../solution_templates/solution_1.md | 144 +++++++++--------- 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/llm-git-conflict-resolve/solution_templates/solution_1.md b/llm-git-conflict-resolve/solution_templates/solution_1.md index a03cbf17..eb67d716 100644 --- a/llm-git-conflict-resolve/solution_templates/solution_1.md +++ b/llm-git-conflict-resolve/solution_templates/solution_1.md @@ -1,44 +1,44 @@ # Git Merge Conflict Prompt for AI Agents -Acest proiect defineste un skill pentru Claude Code Agent, conceput pentru a detecta si rezolva conflicte Git merge. Skill-ul ofera instructiuni clare, proceduri bine definite si unelte auxiliare pentru a ajuta agentul sa interpreteze fisiere aflate in conflict si sa genereze o versiune finala corecta, fara marcaje de conflict. +This project defines a skill for the Claude Code Agent, designed to detect and resolve Git merge conflicts. The skill provides clear instructions, well‑defined procedures, and auxiliary tools to help the agent interpret files containing conflicts and generate a correct final version without conflict markers. -## Obiectiv +## Objective -Skill-ul are ca scop furnizarea unui set complet de instructiuni prin care un AI agent poate: +The goal of the skill is to provide a complete set of instructions enabling an AI agent to: -- Detecta conflictele din fisiere. -- Identifica structura markerelor Git (`<<<<<<<`, `=======`, `>>>>>>>`). -- Extrage sectiunile aflate in conflict. -- Analiza diferentele dintre variantele HEAD si branch. -- Aplica diverse strategii de merge (automata, preferinta pentru HEAD, preferinta pentru branch, semantica). -- Apela cod Python auxiliar pentru analize mai avansate. -- Genera o rezolvare finala coerenta. -- Rescrie fisierul final fara conflicte. +- Detect conflicts in files. +- Identify the structure of Git markers (`<<<<<<<`, `=======`, `>>>>>>>`). +- Extract the conflicting sections. +- Analyze differences between HEAD and branch versions. +- Apply various merge strategies (automatic, HEAD‑first, branch‑first, semantic). +- Call auxiliary Python code for more advanced analysis. +- Generate a coherent final resolution. +- Rewrite the final file without conflict markers. -Agentul nu utilizeaza comenzi Git propriu-zise. Toate operatiunile se bazeaza exclusiv pe procesarea textului, conform instructiunilor din acest skill. +The agent **does not use real Git commands**. All operations are based exclusively on text processing according to the instructions in this skill. --- -# Continutul skill-ului +# Skill Contents -Structura skill-ului este formata din trei componente principale: fisierul de logica (`skill.md`), scriptul auxiliar (`merge_utils.py`) si documentatia de utilizare (`usage.md`). +The skill consists of three main components: the logic file (`skill.md`), the auxiliary script (`merge_utils.py`), and the usage documentation (`usage.md`). -## 1. `skill.md` – Instructiunile principale +## 1. `skill.md` – Main Instructions -Acest fisier defineste comportamentul agentului si regulile pe care trebuie sa le urmeze in timpul rezolvarii conflictelor. +This file defines the agent’s behavior and the rules it must follow when resolving conflicts. -### Ce contine +### What it contains -- Descrierea scopului skill-ului. -- Explicarea pasilor operationali obligatorii. -- Definirea clara a modului de detectare si extragere a conflictelor. -- Regulile de analiza si de aplicare a strategiilor de merge. -- Instructiuni despre cum sa utilizeze codul auxiliar Python. -- Exemple de input si output pentru a ghida agentul. +- Description of the skill’s purpose. +- Explanation of mandatory operational steps. +- Clear definition of how to detect and extract conflicts. +- Rules for analyzing and applying merge strategies. +- Instructions on how to use the auxiliary Python code. +- Sample inputs and outputs to guide the agent. -### Pasii operationali +### Operational steps -1. Identificarea marcajelor de conflict: +1. Identify conflict markers: ``` <<<<<<< HEAD ... @@ -46,52 +46,52 @@ Acest fisier defineste comportamentul agentului si regulile pe care trebuie sa l ... >>>>>>> branch ``` -2. Extractia celor doua sectiuni in structura: +2. Extract the two sections into this structure: ```json - { - "HEAD": "...", - "branch": "..." - } + { + "HEAD": "...", + "branch": "..." + } ``` -3. Analiza diferentelor dintre sectiuni. -4. Aplicarea unei strategii de merge, conform instructiunilor si contextului. -5. Generarea unei rezolvari finale. -6. Daca este necesar, apelarea scriptului Python (`merge_utils.py`) pentru: - - detectarea conflictelor, - - comparari avansate, - - analiza semantica. -7. Interpretarea outputului JSON primit de la script. -8. Reconstruirea fisierului final fara marcaje de conflict. - -### Strategii de merge documentate - -- Strategie automata: daca una dintre versiuni este continuta in cealalta. -- Preferinta HEAD: agentul pastreaza versiunea din HEAD. -- Preferinta branch: agentul pastreaza versiunea din branch. -- Merge semantic: - - reconstructie JSON, - - combinarea functiilor in cod atunci cand modificarile nu sunt conflictuale. -- Merge asistat: agentul solicita utilizatorului o alegere explicita. - -### Exemple - -Skill-ul trebuie sa includa exemple de conflicte si rezolvarile lor, astfel incat agentul sa inteleaga formatul asteptat. +3. Analyze the differences between the two sections. +4. Apply a merge strategy based on instructions and context. +5. Generate a final resolved version. +6. If necessary, call the Python script (`merge_utils.py`) for: + - conflict detection, + - advanced comparisons, + - semantic analysis. +7. Interpret the JSON output returned by the script. +8. Reconstruct the final file without conflict markers. + +### Documented merge strategies + +- **Automatic strategy**: if one version is contained in the other. +- **HEAD‑first strategy**: keep the HEAD version. +- **Branch‑first strategy**: keep the branch version. +- **Semantic merge**: + - reconstruct JSON, + - combine functions in code when changes are not conflicting. +- **Assisted merge**: the agent asks the user for explicit selection. + +### Examples + +The skill includes examples of conflicts and their correct resolutions so that the agent understands the expected format. --- -## 2. `merge_utils.py` – Cod Python auxiliar +## 2. `merge_utils.py` – Auxiliary Python Code -Acest script este destinat operatiunilor care sunt mai eficiente sau mai sigure atunci cand sunt executate ca program local. Agentul il poate apela in mod explicit in timpul procesului. +This script is used for operations that are more efficient or safer when executed as local Python code. The agent may explicitly call it during the merge process. -### Functionalitati posibile +### Possible functionalities -- `detect_conflicts(file_text)` identifica toate sectiunile conflictuale dintr-un fisier si intoarce o structura JSON. -- `three_way_merge(base, ours, theirs)` implementeaza logica unui merge in trei sensuri. -- `ast_merge_python(ours, theirs)` realizeaza un merge semantic asupra functiilor Python. -- `json_merge(ours, theirs)` combina structuri JSON intr-un mod sigur. -- `line_similarity(a, b)` ofera un scor de similaritate intre linii pentru decizii automatizate. +- `detect_conflicts(file_text)` identifies all conflicting sections in a file and returns a JSON structure. +- `three_way_merge(base, ours, theirs)` implements a three‑way merge. +- `ast_merge_python(ours, theirs)` performs a semantic merge of Python functions. +- `json_merge(ours, theirs)` safely combines JSON structures. +- `line_similarity(a, b)` returns a similarity score between lines for automated decisions. -### Format de output recomandat +### Recommended output format ```json { @@ -109,20 +109,20 @@ Acest script este destinat operatiunilor care sunt mai eficiente sau mai sigure --- -## 3. `usage.md` – Documentatie de utilizare +## 3. `usage.md` – Usage Documentation -Fisierul `usage.md` explica modul corect de utilizare al skill-ului, atat pentru agent, cat si pentru utilizator. +The `usage.md` file explains the correct way to use the skill, for both the agent and the user. -### Continut +### Contents -- Instructiuni despre cum trebuie apelat scriptul Python. -- Formatele acceptate pentru input. -- Modul de interpretare al outputului. -- Exemple complete de rulare. -- Conventii stabilite intre agent si script (argumente CLI, structuri JSON, etc.). +- Instructions on how to call the Python script. +- Accepted input formats. +- How to interpret output. +- Complete examples of usage. +- Conventions between agent and script (CLI arguments, JSON structures, etc.). --- -# Concluzie +# Conclusion -Skill-ul ofera o metodologie completa pentru rezolvarea conflictelor Git fara a utiliza Git in mod direct. Documentatia din `skill.md` deserveste drept ghid operational pentru agent, `merge_utils.py` furnizeaza suport tehnic avansat, iar `usage.md` clarifica modul de interactiune cu skill-ul. Acest set de fisiere permite agentului sa detecteze, interpreteze si combine eficient sectiunile aflate in conflict, oferind o versiune finala curata si coerenta. +The skill provides a complete methodology for resolving Git merge conflicts without using Git directly. The documentation in `skill.md` serves as the operational guide for the agent, `merge_utils.py` provides advanced technical support, and `usage.md` clarifies how to interact with the skill. This set of files enables the agent to efficiently detect, interpret, and combine conflicting sections, producing a clean and coherent final version. From 3e2622ba13006f9c6038ee687739710048852072 Mon Sep 17 00:00:00 2001 From: Gabriel Crisan Date: Thu, 11 Dec 2025 12:22:54 +0200 Subject: [PATCH 03/20] Add solution_3.md --- .../solution_templates/solution_3.md | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 llm-git-conflict-resolve/solution_templates/solution_3.md diff --git a/llm-git-conflict-resolve/solution_templates/solution_3.md b/llm-git-conflict-resolve/solution_templates/solution_3.md new file mode 100644 index 00000000..787e2cfb --- /dev/null +++ b/llm-git-conflict-resolve/solution_templates/solution_3.md @@ -0,0 +1,131 @@ +# Git Merge Conflict Resolution Skill for AI Agents + +This repository contains a modular skill designed to enable AI agents (specifically within the Claude Code environment) to autonomously and accurately resolve git merge conflicts. + +While Large Language Models are proficient at writing code, they often struggle with the syntax of standard git merge markers (`<<<<<<<`, `=======`, `>>>>>>>`) due to a lack of context regarding the conflicting branches. This project bridges that gap by providing the agent with executable tools to retrieve the full history of the conflict (Base, Local, Remote) and a strict set of operational guidelines. + +## Architecture Overview + +The solution relies on a "Tool-Use" pattern where the agent acts not just as a text processor but as an orchestrator. It uses local Python scripts to interact with the Git CLI, processes the data, and applies resolution logic based on a predefined educational context. + +## Repository Structure & File Descriptions + +To implement this skill effectively, the project requires the following file structure. Each file serves a specific role in the agent's decision-making loop. + +### 1. `instructions.md` (The Educational Layer) + +This file acts as the system prompt or "knowledge base" for the agent. It dictates the behavior and decision-making process. It does not contain code to be executed, but rather the logic the agent must follow. + +**Purpose:** Teaches the agent the "Algorithm of Resolution." + +**Key Contents:** + +* **Step-by-Step Workflow:** Instructions to identify conflicts, fetch raw data, analyze intent, and apply fixes. +* **Conflict Strategies:** Rules for handling specific scenarios: + * **Independent Changes:** When both branches modified different parts, merge both changes + * **Conflicting Logic:** When same lines have incompatible changes, prefer the version from the more authoritative branch (typically main/master) + * **Rename Conflicts:** When variables/functions are renamed, follow the naming standard from main branch + * **Import Conflicts:** Perform a union of all imports from both branches, sorted alphabetically + * **Ambiguous Cases:** When intent is unclear, keep current version and add TODO comment with explanation +* **Special Cases:** Instructions for handling deleted files, binary files, and multiple conflicts in one file +* **Validation Requirements:** Mandate to always validate syntax before staging + +### 2. `git_tools.py` (The Execution Layer) + +This Python script serves as the bridge between the AI agent and the local Git repository. The agent calls functions within this file to gather factual data about the state of the codebase. + +**Purpose:** Provides deterministic, structured data to the LLM. + +**Key Functions:** + +* `list_conflicted_files()`: Parses `git status --porcelain` to identify files with merge conflicts (status "UU") +* `get_three_way_diff(filepath)`: Uses `git show` to extract the three versions: + * **:1 (Base):** The common ancestor + * **:2 (Ours):** The local changes (HEAD) + * **:3 (Theirs):** The incoming changes + * Returns structured JSON with all three versions plus branch names +* `validate_syntax(filepath)`: Runs language-specific validation: + * Python: Uses `ast.parse()` to check syntax + * JavaScript/TypeScript: Attempts to use eslint if available + * Java: Attempts to use javac if available + * Returns JSON with validation status and error messages + +**CLI Interface:** Accepts commands `--list`, `--extract `, `--verify ` and outputs JSON for easy parsing by the agent. + +### 3. `resolution_template.md` (Optional) + +A template file used by the agent to structure its reasoning before editing the code. + +**Purpose:** Forces the agent to output a "Chain of Thought" before writing code. + +**Structure:** +* Conflict Summary (file, branches, location) +* Version Analysis (what Base, Ours, and Theirs contain) +* Detected Intent (what each branch was trying to accomplish) +* Conflict Type Classification +* Proposed Resolution Strategy +* Proposed Resolution Code +* Reasoning +* Validation Checklist + +### 4. `examples/conflict_scenarios.md` (Optional but Recommended) + +Real-world examples of common conflict patterns and their resolutions. + +**Purpose:** Provides concrete examples the agent can reference when encountering similar conflicts. + +**Contents:** +* Example: Independent feature additions (logging vs. validation) with resolution showing both merged +* Example: Variable rename conflicts with resolution following main branch convention +* Example: Import statement differences with resolution performing union +* Example: Conflicting algorithm changes with resolution preferring main branch +* Example: Deleted vs. modified file with context-dependent decision + +Each example shows Base, Ours, Theirs, and the Resolution with explanation. + +## Operational Workflow + +When the agent is tasked with fixing a merge conflict, the expected execution flow is: + +1. **Context Loading:** The agent reads `instructions.md` to understand its role and constraints. +2. **Discovery:** The agent executes `python git_tools.py --list` to find the target files. +3. **Data Extraction:** For every conflict, the agent executes `python git_tools.py --extract `. It receives a structured JSON object containing the Base, Ours, and Theirs content plus branch information. +4. **Intent Analysis:** The agent compares the three versions to understand what changed and why in each branch. +5. **Strategy Selection:** Based on the analysis, the agent selects the appropriate resolution strategy from `instructions.md`. +6. **Logic Synthesis:** The agent reconstructs the valid code path based on the chosen strategy, preserving intent from both branches when possible. +7. **Application:** The agent rewrites the file content locally with the resolved code. +8. **Verification:** The agent executes `python git_tools.py --verify ` to catch syntax errors. +9. **Staging:** If validation passes, the agent runs `git add `. +10. **Completion:** After all conflicts are resolved, the agent can commit the merge. + +## Key Design Principles + +**Separation of Concerns:** Documentation defines the "what" and "why" while code handles the "how". The agent orchestrates both. + +**Structured Data Over Text Parsing:** All tool outputs are JSON with predictable schemas. The agent receives facts (three versions) not opinions (conflict markers). + +**Explicit Decision Framework:** Every type of conflict has a defined strategy in instructions.md with documented fallback behavior. + +**Safety Through Validation:** Syntax validation is mandatory before staging to prevent broken commits. + +**Transparency and Traceability:** Optional resolution template encourages documenting reasoning, and TODO comments preserve context when full resolution is not possible. + +## Integration + +To add this skill to your agent configuration: + +1. Place `git_tools.py` in the root or a dedicated `scripts/` directory. +2. Add the content of `instructions.md` to the agent's context or system prompt. +3. Optionally add `resolution_template.md` and `examples/conflict_scenarios.md` to the context. +4. Ensure the agent has permission to execute shell commands (specifically `python` and `git`). + +## Expected Outcomes + +With this skill properly configured, the agent should be able to: + +* Detect all merge conflicts in a repository +* Successfully resolve the majority of simple conflicts (independent changes, imports, renames) +* Identify complex conflicts that require human review and add appropriate TODO comments +* Never stage syntactically invalid code +* Preserve the intent of changes from both branches when merging +* Defer to humans for semantic conflicts requiring deep domain knowledge \ No newline at end of file From ed59dfdb4c0923a584a3ee2974e1e48d854935fc Mon Sep 17 00:00:00 2001 From: Gabriel Crisan Date: Thu, 11 Dec 2025 12:47:10 +0200 Subject: [PATCH 04/20] Add a comparative analysis of the proposed solutions --- .../solutions_comparison.md | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 llm-git-conflict-resolve/solution_templates/solutions_comparison.md diff --git a/llm-git-conflict-resolve/solution_templates/solutions_comparison.md b/llm-git-conflict-resolve/solution_templates/solutions_comparison.md new file mode 100644 index 00000000..88235e06 --- /dev/null +++ b/llm-git-conflict-resolve/solution_templates/solutions_comparison.md @@ -0,0 +1,34 @@ +# Comparative Analysis: Git Merge Agent Skill Architectures + +This document provides a technical comparison of three architectural approaches for implementing an AI-driven Git Merge Conflict Resolution skill. + +| Criterion | Solution 1: "The Text Processor" | Solution 2: "The Modular Architect" | Solution 3: "The Strategic Expert" | +| :--- | :--- | :--- | :--- | +| **Core Philosophy** | **Human Simulation**. The agent reads the "broken" file with markers and attempts to repair it textually. | **Systems Engineering**. Focuses on the *data pipeline*, tool orchestration, and a clean file structure. | **Strategic Reasoning**. Focuses on *decision rules* (how to handle imports, renames) and specific conflict scenarios. | +| **Source of Truth** | **Conflict Markers** (`<<<<<<<`). The agent sees a single text file containing conflict syntax. | **Git History** (`git show`). The agent sees 3 distinct, clean file versions. | **Git History** (`git show`). The agent sees 3 distinct, clean file versions. | +| **Merge Method** | **2-Way Merge** (HEAD vs. Branch). **Incomplete** data model. | **3-Way Merge** (Base + Ours + Theirs). Industry standard. | **3-Way Merge** (Base + Ours + Theirs). Industry standard. | +| **Decision Context** | **Limited**. It lacks the "Base" (ancestor), so it cannot distinguish between a *deletion* and a *modification*. | **Maximum**. It knows exactly what the code looked like before the conflict. | **Maximum**. Identical to Solution 2, but adds context via examples. | +| **Tech Dependencies** | **Minimal**. Python only. Can run in environments where `git` CLI execution is blocked. | **Standard**. Requires access to CLI, Python, and an installed Git instance. | **Standard**. Requires access to CLI, Python, and an installed Git instance. | +| **Hallucination Risk** | **High**. The agent might fail to remove markers correctly or misinterpret where the conflict block ends. | **Low**. Data is provided as structured JSON. The agent does not guess syntax. | **Low**. Relies on deterministic Python outputs and explicit logic. | +| **Documentation Focus** | **Parsing**. Teaches the agent how to visually identify conflict text. | **Architecture**. Teaches the agent how the components interact. | **Business Logic**. Teaches the agent *how to think* about specific code problems. | +| **Setup Complexity** | **Low**. Simple instructions, but high operational risk. | **Medium**. Clean structure, easy to replicate as a boilerplate. | **High**. Requires detailed prompts (`instructions.md`) and example scenarios. | +| **Recommended For** | **Restricted Environments**. Sandboxes where the agent cannot execute system commands (`exec`). | **Open Source / Boilerplate**. A clean starting point for a new tool. | **Enterprise / Production**. When code accuracy and complex resolution logic are critical. | + +--- + +## Final Recommendation: The Hybrid Enterprise Approach + +Based on the technical analysis above, the optimal strategy is **not to choose a single solution**, but to implement a **Hybrid Architecture** that combines the structural robustness of Solution 2 with the decision-making intelligence of Solution 3. + +### Why a Hybrid Approach? + +1. **Structure from Solution 2 ("The Skeleton"):** We adopt the modular file structure (`git_tools.py`, `README.md`) and the strict JSON data pipeline. This ensures the agent interacts with deterministic data, eliminating the "hallucination risk" associated with parsing raw text markers found in Solution 1. +2. **Intelligence from Solution 3 ("The Brain"):** While Solution 2 provides the tools, Solution 3 provides the logic. We populate the system prompt (`instructions.md`) with the advanced decision matrices (e.g., handling imports, refactors vs. logic changes) from Solution 3. Without these rules, the tools are useless; without the tools, the rules are risky to apply. +3. **Data Integrity (3-Way Merge):** By rejecting Solution 1 entirely, we ensure the agent always has access to the "Base" (ancestor) version via Git CLI tools. This is mathematically necessary to distinguish between a *deletion* (intentional removal) and a *modification*, preventing accidental code loss. + +### Proposed Implementation Blueprint + +To build the most robust skill, follow this composition: + +1. **Architecture:** Adopt the clean file organization and Python tool scripts from **Solution 2**. +2. **Logic:** Fill the `instructions.md` (System Prompt) with the detailed conflict strategies and scenarios from **Solution 3**. \ No newline at end of file From fd7a23c374d6d1c14554fee7323a495d43b09c81 Mon Sep 17 00:00:00 2001 From: Gabriel Crisan Date: Thu, 11 Dec 2025 15:48:14 +0200 Subject: [PATCH 05/20] Refactor solution_3.md --- .../solution_templates/solution_3.md | 178 ++++++++---------- 1 file changed, 83 insertions(+), 95 deletions(-) diff --git a/llm-git-conflict-resolve/solution_templates/solution_3.md b/llm-git-conflict-resolve/solution_templates/solution_3.md index 787e2cfb..6b01a1e9 100644 --- a/llm-git-conflict-resolve/solution_templates/solution_3.md +++ b/llm-git-conflict-resolve/solution_templates/solution_3.md @@ -1,131 +1,119 @@ -# Git Merge Conflict Resolution Skill for AI Agents +# Git Merge Conflict Resolution Skill - Solution Design -This repository contains a modular skill designed to enable AI agents (specifically within the Claude Code environment) to autonomously and accurately resolve git merge conflicts. +## Core Philosophy -While Large Language Models are proficient at writing code, they often struggle with the syntax of standard git merge markers (`<<<<<<<`, `=======`, `>>>>>>>`) due to a lack of context regarding the conflicting branches. This project bridges that gap by providing the agent with executable tools to retrieve the full history of the conflict (Base, Local, Remote) and a strict set of operational guidelines. +This skill treats merge conflict resolution as a **semantic understanding problem** rather than text manipulation. The agent reconstructs the complete 3-way evolution (Base → Ours, Base → Theirs) to understand *why* conflicts occurred, enabling intelligent reconciliation based on developer intent rather than pattern-matching on conflict markers. -## Architecture Overview +## Approach -The solution relies on a "Tool-Use" pattern where the agent acts not just as a text processor but as an orchestrator. It uses local Python scripts to interact with the Git CLI, processes the data, and applies resolution logic based on a predefined educational context. +**Context Over Heuristics**: Extract full 3-way diffs, analyze commit messages, examine dependencies, and make decisions based on semantic code understanding. -## Repository Structure & File Descriptions +**Progressive Resolution**: Address conflicts by difficulty—trivial (whitespace) → structural (imports) → logical (algorithms)—auto-resolving simple cases while escalating complex ones. -To implement this skill effectively, the project requires the following file structure. Each file serves a specific role in the agent's decision-making loop. +**Safety Through Validation**: Multi-layer verification (syntax, semantics, integration) with automatic backups before any modifications. -### 1. `instructions.md` (The Educational Layer) +## Skill Structure -This file acts as the system prompt or "knowledge base" for the agent. It dictates the behavior and decision-making process. It does not contain code to be executed, but rather the logic the agent must follow. +``` +git-merge-conflict-skill/ +├── instructions/ +│ ├── 01-workflow.md # Detection, prioritization, backup creation +│ ├── 02-context-extraction.md # How to retrieve 3-way diffs and commit history +│ ├── 03-resolution-strategies.md # Decision trees for each conflict type +│ ├── 04-validation.md # Post-resolution verification protocol +│ └── 05-escalation.md # When and how to request human help +│ +└── tools/ + ├── conflict_extractor.py # Extract 3-way diffs and parse conflict markers + ├── semantic_analyzer.py # Analyze dependencies and infer intent + ├── conflict_categorizer.py # Classify conflict types automatically + ├── resolution_validator.py # Verify syntax and semantic correctness + └── git_context.py # Fetch commit history and branch metadata +``` -**Purpose:** Teaches the agent the "Algorithm of Resolution." +### Instructions Layer (Markdown) -**Key Contents:** +**Purpose**: Educate the agent on resolution logic—the "what to do" without executable code. -* **Step-by-Step Workflow:** Instructions to identify conflicts, fetch raw data, analyze intent, and apply fixes. -* **Conflict Strategies:** Rules for handling specific scenarios: - * **Independent Changes:** When both branches modified different parts, merge both changes - * **Conflicting Logic:** When same lines have incompatible changes, prefer the version from the more authoritative branch (typically main/master) - * **Rename Conflicts:** When variables/functions are renamed, follow the naming standard from main branch - * **Import Conflicts:** Perform a union of all imports from both branches, sorted alphabetically - * **Ambiguous Cases:** When intent is unclear, keep current version and add TODO comment with explanation -* **Special Cases:** Instructions for handling deleted files, binary files, and multiple conflicts in one file -* **Validation Requirements:** Mandate to always validate syntax before staging +**01-workflow.md**: Teaches initial conflict detection, how to scan for conflicts, create backups, and prioritize resolution order (simple first). -### 2. `git_tools.py` (The Execution Layer) +**02-context-extraction.md**: Guides the agent through retrieving Base/Ours/Theirs versions, fetching commit messages from both branches, and understanding author intent through git blame. -This Python script serves as the bridge between the AI agent and the local Git repository. The agent calls functions within this file to gather factual data about the state of the codebase. +**03-resolution-strategies.md**: Core decision logic organized by conflict type: +- **Imports**: Union merge, deduplicate, sort alphabetically +- **Whitespace**: Auto-resolve with project formatter +- **Renames**: Detect pattern, apply rename everywhere, keep other side's logic +- **Function signatures**: Check compatibility, merge if safe, escalate if breaking +- **Logic divergence**: Compare intents (bugfix vs feature), attempt combination or escalate with analysis +- **Refactoring**: Accept new structure, apply other side's changes to relocated code -**Purpose:** Provides deterministic, structured data to the LLM. +**04-validation.md**: Multi-stage verification—syntax check (must pass), semantic check (undefined vars, type errors), integration check (works with surrounding code), plus test recommendations. -**Key Functions:** +**05-escalation.md**: Clear criteria for requesting human help—ambiguous intent, data loss risk, test conflicts, complex dependencies. Defines escalation report format with detailed analysis and resolution options. -* `list_conflicted_files()`: Parses `git status --porcelain` to identify files with merge conflicts (status "UU") -* `get_three_way_diff(filepath)`: Uses `git show` to extract the three versions: - * **:1 (Base):** The common ancestor - * **:2 (Ours):** The local changes (HEAD) - * **:3 (Theirs):** The incoming changes - * Returns structured JSON with all three versions plus branch names -* `validate_syntax(filepath)`: Runs language-specific validation: - * Python: Uses `ast.parse()` to check syntax - * JavaScript/TypeScript: Attempts to use eslint if available - * Java: Attempts to use javac if available - * Returns JSON with validation status and error messages +### Tools Layer (Python) -**CLI Interface:** Accepts commands `--list`, `--extract `, `--verify ` and outputs JSON for easy parsing by the agent. +**Purpose**: Provide deterministic, structured data to the agent—the "how to fetch" without decision logic. -### 3. `resolution_template.md` (Optional) +**conflict_extractor.py**: +- Scans repository using `git status --porcelain` +- Extracts 3-way diff via git stages (`:1` base, `:2` ours, `:3` theirs) +- Parses conflict markers, returns structured blocks with surrounding context -A template file used by the agent to structure its reasoning before editing the code. +**semantic_analyzer.py**: +- Maps code dependencies (what variables/functions are used) +- Detects rename patterns by comparing identifiers across versions +- Infers intent by analyzing commit messages and code changes +- Validates that resolved code satisfies its dependencies -**Purpose:** Forces the agent to output a "Chain of Thought" before writing code. +**conflict_categorizer.py**: +- Automatically classifies conflicts (IMPORT, LOGIC, REFACTOR, etc.) +- Estimates difficulty (EASY, MEDIUM, HARD, ESCALATE) +- Provides initial assessment to guide strategy selection -**Structure:** -* Conflict Summary (file, branches, location) -* Version Analysis (what Base, Ours, and Theirs contain) -* Detected Intent (what each branch was trying to accomplish) -* Conflict Type Classification -* Proposed Resolution Strategy -* Proposed Resolution Code -* Reasoning -* Validation Checklist +**resolution_validator.py**: +- Language-specific syntax checking (AST parsing for Python, etc.) +- Semantic validation (undefined references, type mismatches) +- Runs project linters +- Suggests relevant tests based on changed code -### 4. `examples/conflict_scenarios.md` (Optional but Recommended) +**git_context.py**: +- Fetches commit messages that modified conflicted regions +- Finds merge base (common ancestor commit) +- Retrieves author info for escalation context +- Creates backup branches before resolution -Real-world examples of common conflict patterns and their resolutions. +## Resolution Workflow -**Purpose:** Provides concrete examples the agent can reference when encountering similar conflicts. +``` +DETECT → EXTRACT → CATEGORIZE → STRATEGIZE → RESOLVE → VALIDATE → COMMIT/ESCALATE +``` -**Contents:** -* Example: Independent feature additions (logging vs. validation) with resolution showing both merged -* Example: Variable rename conflicts with resolution following main branch convention -* Example: Import statement differences with resolution performing union -* Example: Conflicting algorithm changes with resolution preferring main branch -* Example: Deleted vs. modified file with context-dependent decision +**For each conflict:** -Each example shows Base, Ours, Theirs, and the Resolution with explanation. +1. **Extract Context**: Get 3-way diff, commit history, dependencies +2. **Categorize**: Classify type and difficulty using categorizer tool +3. **Select Strategy**: Match to decision tree in instructions +4. **Apply Resolution**: Generate resolved code based on strategy +5. **Validate**: Syntax → Semantics → Integration (must pass all) +6. **Finalize**: Stage if valid, escalate with detailed report if not -## Operational Workflow +## Key Innovations -When the agent is tasked with fixing a merge conflict, the expected execution flow is: +**Intent-Driven Resolution**: Analyzes commit messages + code semantics to understand the *goal* of each change, enabling intelligent merging of complementary features. -1. **Context Loading:** The agent reads `instructions.md` to understand its role and constraints. -2. **Discovery:** The agent executes `python git_tools.py --list` to find the target files. -3. **Data Extraction:** For every conflict, the agent executes `python git_tools.py --extract `. It receives a structured JSON object containing the Base, Ours, and Theirs content plus branch information. -4. **Intent Analysis:** The agent compares the three versions to understand what changed and why in each branch. -5. **Strategy Selection:** Based on the analysis, the agent selects the appropriate resolution strategy from `instructions.md`. -6. **Logic Synthesis:** The agent reconstructs the valid code path based on the chosen strategy, preserving intent from both branches when possible. -7. **Application:** The agent rewrites the file content locally with the resolved code. -8. **Verification:** The agent executes `python git_tools.py --verify ` to catch syntax errors. -9. **Staging:** If validation passes, the agent runs `git add `. -10. **Completion:** After all conflicts are resolved, the agent can commit the merge. +**Complete Context**: 3-way diff reveals full story (original → how each side changed → why), eliminating guesswork from conflict markers alone. -## Key Design Principles +**Explicit Boundaries**: Clear escalation criteria prevent incorrect auto-resolutions while maximizing safe automation. -**Separation of Concerns:** Documentation defines the "what" and "why" while code handles the "how". The agent orchestrates both. +**Semantic Validation**: Beyond syntax, verifies resolved code makes semantic sense—no undefined variables, consistent types, satisfied dependencies. -**Structured Data Over Text Parsing:** All tool outputs are JSON with predictable schemas. The agent receives facts (three versions) not opinions (conflict markers). +**Progressive Complexity**: Sorts conflicts simple → complex, builds confidence on easy cases, bails early if complexity exceeds capabilities. -**Explicit Decision Framework:** Every type of conflict has a defined strategy in instructions.md with documented fallback behavior. +## Success Criteria -**Safety Through Validation:** Syntax validation is mandatory before staging to prevent broken commits. +**Target auto-resolution rates**: 95% for trivial conflicts (imports, whitespace), 60% for structural (renames, refactors), 30% for logic conflicts. -**Transparency and Traceability:** Optional resolution template encourages documenting reasoning, and TODO comments preserve context when full resolution is not possible. +**Quality**: Zero syntax errors through validation. <1% semantic errors through multi-layer checking. Clear escalation reports when human input needed. -## Integration - -To add this skill to your agent configuration: - -1. Place `git_tools.py` in the root or a dedicated `scripts/` directory. -2. Add the content of `instructions.md` to the agent's context or system prompt. -3. Optionally add `resolution_template.md` and `examples/conflict_scenarios.md` to the context. -4. Ensure the agent has permission to execute shell commands (specifically `python` and `git`). - -## Expected Outcomes - -With this skill properly configured, the agent should be able to: - -* Detect all merge conflicts in a repository -* Successfully resolve the majority of simple conflicts (independent changes, imports, renames) -* Identify complex conflicts that require human review and add appropriate TODO comments -* Never stage syntactically invalid code -* Preserve the intent of changes from both branches when merging -* Defer to humans for semantic conflicts requiring deep domain knowledge \ No newline at end of file +**Safety-first**: Always backup before changes. Never commit invalid code. Escalate with detailed analysis when uncertain. \ No newline at end of file From c5c44f1c0609bca1cb38a31fc1defd72d527c9d0 Mon Sep 17 00:00:00 2001 From: Gabriel Crisan Date: Thu, 11 Dec 2025 16:15:59 +0200 Subject: [PATCH 06/20] Fix solutions analysis --- .../solutions_comparison.md | 44 ++++++++----------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/llm-git-conflict-resolve/solution_templates/solutions_comparison.md b/llm-git-conflict-resolve/solution_templates/solutions_comparison.md index 88235e06..6556d0b0 100644 --- a/llm-git-conflict-resolve/solution_templates/solutions_comparison.md +++ b/llm-git-conflict-resolve/solution_templates/solutions_comparison.md @@ -1,34 +1,28 @@ -# Comparative Analysis: Git Merge Agent Skill Architectures +# Comparative Analysis: AI Git Merge Skill Architectures -This document provides a technical comparison of three architectural approaches for implementing an AI-driven Git Merge Conflict Resolution skill. +This document evaluates the 3 strategies for building an Claude skill to resolve Git merge conflicts, ranging from text-based processing to deep semantic analysis. -| Criterion | Solution 1: "The Text Processor" | Solution 2: "The Modular Architect" | Solution 3: "The Strategic Expert" | -| :--- | :--- | :--- | :--- | -| **Core Philosophy** | **Human Simulation**. The agent reads the "broken" file with markers and attempts to repair it textually. | **Systems Engineering**. Focuses on the *data pipeline*, tool orchestration, and a clean file structure. | **Strategic Reasoning**. Focuses on *decision rules* (how to handle imports, renames) and specific conflict scenarios. | -| **Source of Truth** | **Conflict Markers** (`<<<<<<<`). The agent sees a single text file containing conflict syntax. | **Git History** (`git show`). The agent sees 3 distinct, clean file versions. | **Git History** (`git show`). The agent sees 3 distinct, clean file versions. | -| **Merge Method** | **2-Way Merge** (HEAD vs. Branch). **Incomplete** data model. | **3-Way Merge** (Base + Ours + Theirs). Industry standard. | **3-Way Merge** (Base + Ours + Theirs). Industry standard. | -| **Decision Context** | **Limited**. It lacks the "Base" (ancestor), so it cannot distinguish between a *deletion* and a *modification*. | **Maximum**. It knows exactly what the code looked like before the conflict. | **Maximum**. Identical to Solution 2, but adds context via examples. | -| **Tech Dependencies** | **Minimal**. Python only. Can run in environments where `git` CLI execution is blocked. | **Standard**. Requires access to CLI, Python, and an installed Git instance. | **Standard**. Requires access to CLI, Python, and an installed Git instance. | -| **Hallucination Risk** | **High**. The agent might fail to remove markers correctly or misinterpret where the conflict block ends. | **Low**. Data is provided as structured JSON. The agent does not guess syntax. | **Low**. Relies on deterministic Python outputs and explicit logic. | -| **Documentation Focus** | **Parsing**. Teaches the agent how to visually identify conflict text. | **Architecture**. Teaches the agent how the components interact. | **Business Logic**. Teaches the agent *how to think* about specific code problems. | -| **Setup Complexity** | **Low**. Simple instructions, but high operational risk. | **Medium**. Clean structure, easy to replicate as a boilerplate. | **High**. Requires detailed prompts (`instructions.md`) and example scenarios. | -| **Recommended For** | **Restricted Environments**. Sandboxes where the agent cannot execute system commands (`exec`). | **Open Source / Boilerplate**. A clean starting point for a new tool. | **Enterprise / Production**. When code accuracy and complex resolution logic are critical. | - ---- -## Final Recommendation: The Hybrid Enterprise Approach -Based on the technical analysis above, the optimal strategy is **not to choose a single solution**, but to implement a **Hybrid Architecture** that combines the structural robustness of Solution 2 with the decision-making intelligence of Solution 3. +| Criterion | Solution 1: "The Text Processor" | Solution 2: "The Modular Architect" | Solution 3: "The Semantic Expert" | +| :--- | :--- | :--- | :--- | +| **Core Philosophy** | **Text Manipulation**. Operates exclusively on text processing without executing real Git commands. | **Tool Orchestration**. Acts as a bridge between the LLM and Git CLI to fetch deterministic data. | **Semantic Understanding**. Focuses on *intent*, context, and progressive resolution (simple → complex). | +| **Source of Truth** | **Conflict Markers**. Parses `<<<<<<<` and `>>>>>>>` from file text. | **Git History (3-Way)**. Uses `git show` to extract Base, Ours, and Theirs versions. | **Rich Context**. Combines 3-Way Diff + Commit Messages + Dependency Graphs + Git Blame. | +| **Architecture** | **Simple Scripting**. `skill.md` (rules) + `merge_utils.py` (helper functions). | **Modular Tooling**. `instructions.md` (logic) + `git_tools.py` (execution) + `template`. | **Granular Micro-Services**. Split instructions (Workflow, Context, Strategy) & specialized tools (Extractor, Analyzer, Validator). | +| **Resolution Logic** | **Pattern Matching**. Applies strategies (Head/Branch first) based on text structure. | **Standard 3-Way**. Reconstructs code based on the "Base" version and divergent changes. | **Intent-Driven**. Analyzes *why* code changed (e.g., Refactor vs. Feature) using commit history and semantics. | +| **Validation** | **Basic**. Optional Python script helper. | **Syntax Only**. Runs linters (e.g., AST, eslint) before staging. | **Multi-Layer**. Syntax + Semantic (undefined vars) + Integration checks + Escalation reports. | +| **Complexity** | **Low**. Easy to implement, high risk of error due to lack of context. | **Medium**. Balanced approach, industry standard for automation. | **High**. Complex setup requiring dependency analysis and conflict categorization logic. | -### Why a Hybrid Approach? +--- -1. **Structure from Solution 2 ("The Skeleton"):** We adopt the modular file structure (`git_tools.py`, `README.md`) and the strict JSON data pipeline. This ensures the agent interacts with deterministic data, eliminating the "hallucination risk" associated with parsing raw text markers found in Solution 1. -2. **Intelligence from Solution 3 ("The Brain"):** While Solution 2 provides the tools, Solution 3 provides the logic. We populate the system prompt (`instructions.md`) with the advanced decision matrices (e.g., handling imports, refactors vs. logic changes) from Solution 3. Without these rules, the tools are useless; without the tools, the rules are risky to apply. -3. **Data Integrity (3-Way Merge):** By rejecting Solution 1 entirely, we ensure the agent always has access to the "Base" (ancestor) version via Git CLI tools. This is mathematically necessary to distinguish between a *deletion* (intentional removal) and a *modification*, preventing accidental code loss. +## Final Recommendation: The "Semantic Architect" Hybrid -### Proposed Implementation Blueprint +While **Solution 2** offers the cleanest structural foundation, **Solution 3** offers the necessary intelligence to handle real-world software engineering. **Solution 1** is not recommended for production as it lacks "Real Git" access, making it prone to errors. -To build the most robust skill, follow this composition: +The optimal approach is to **upgrade the architecture of Solution 2 with the intelligence of Solution 3**: -1. **Architecture:** Adopt the clean file organization and Python tool scripts from **Solution 2**. -2. **Logic:** Fill the `instructions.md` (System Prompt) with the detailed conflict strategies and scenarios from **Solution 3**. \ No newline at end of file +1. **Adopt the Infrastructure of Solution 2:** Keep the setup simple with a single robust Python interface (`git_tools.py`) rather than five separate micro-scripts, to maintain agent speed and reduce token usage. +2. **Inject the Logic of Solution 3:** + * **Context:** Enhance `git_tools.py` to fetch **Commit Messages** (from Solution 3), not just code diffs. The agent needs to know *why* a change happened. + * **Categorization:** Adopt the **"Progressive Resolution"** workflow from Solution 3. Teach the agent to identify and solve "Trivial" conflicts (whitespace/imports) first, before attempting "Logical" conflicts. + * **Safety:** Implement the **Backup & Escalation** protocol from Solution 3. If the agent cannot determine intent, it must stop and generate a report rather than guessing. \ No newline at end of file From f6b87d694e35077eb4be5560b681eb3953d76df8 Mon Sep 17 00:00:00 2001 From: Gabriel Crisan Date: Thu, 11 Dec 2025 19:00:32 +0200 Subject: [PATCH 07/20] Fix solution_2.md --- .../solution_templates/solution_2.md | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/llm-git-conflict-resolve/solution_templates/solution_2.md b/llm-git-conflict-resolve/solution_templates/solution_2.md index 854d058a..cf801a6d 100644 --- a/llm-git-conflict-resolve/solution_templates/solution_2.md +++ b/llm-git-conflict-resolve/solution_templates/solution_2.md @@ -52,12 +52,4 @@ When the agent is tasked with fixing a merge conflict, the expected execution fl 3. **Data Extraction:** For every conflict, the agent executes `python git_tools.py --extract `. It receives a structured object containing the Base, Ours, and Theirs content. 4. **Logic Synthesis:** The agent compares the three versions. Instead of guessing based on conflict markers, it reconstructs the valid code path based on the logic defined in the instructions. 5. **Application:** The agent rewrites the file content locally. -6. **Verification:** The agent executes `python git_tools.py --verify ` to catch syntax errors. - -## Integration - -To add this skill to your agent configuration: - -1. Place `git_tools.py` in the root or a dedicated `scripts/` directory. -2. Add the content of `instructions.md` to the agent's context or system prompt. -3. Ensure the agent has permission to execute shell commands (specifically `python` and `git`). \ No newline at end of file +6. **Verification:** The agent executes `python git_tools.py --verify ` to catch syntax errors. \ No newline at end of file From f471808c64245f2cd2369bf6e290b7beba63fc6d Mon Sep 17 00:00:00 2001 From: Gabriel Crisan Date: Fri, 12 Dec 2025 02:35:32 +0200 Subject: [PATCH 08/20] Add first implementation of the skill (incomplete) --- .gitignore | 4 +- llm-git-conflict-resolve/skill/git_tools.py | 507 +++++++++++++++ .../skill/instructions.md | 588 ++++++++++++++++++ 3 files changed, 1098 insertions(+), 1 deletion(-) create mode 100644 llm-git-conflict-resolve/skill/git_tools.py create mode 100644 llm-git-conflict-resolve/skill/instructions.md diff --git a/.gitignore b/.gitignore index d01bd1a9..60a37584 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,6 @@ Cargo.lock # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ \ No newline at end of file +#.idea/ + +.DS_Store \ No newline at end of file diff --git a/llm-git-conflict-resolve/skill/git_tools.py b/llm-git-conflict-resolve/skill/git_tools.py new file mode 100644 index 00000000..f12f1fc4 --- /dev/null +++ b/llm-git-conflict-resolve/skill/git_tools.py @@ -0,0 +1,507 @@ +#!/usr/bin/env python3 +""" +Git Merge Conflict Tools - Interface for Claude Code Agent +Provides deterministic, structured data about Git conflicts without resolution logic. +""" + +import subprocess +import json +import sys +import re +import argparse +import ast +from pathlib import Path +from typing import Dict, List, Optional, Tuple +from dataclasses import dataclass, asdict +from enum import Enum + + +class ConflictType(Enum): + """Classification of conflict types""" + IMPORT = "IMPORT" + WHITESPACE = "WHITESPACE" + RENAME = "RENAME" + REFACTOR = "REFACTOR" + LOGIC = "LOGIC" + FUNCTION_SIGNATURE = "FUNCTION_SIGNATURE" + UNKNOWN = "UNKNOWN" + + +class Difficulty(Enum): + """Estimated difficulty of resolution""" + EASY = "EASY" + MEDIUM = "MEDIUM" + HARD = "HARD" + ESCALATE = "ESCALATE" + + # FIX: Această metodă permite funcției max() să compare dificultățile + def __lt__(self, other): + if self.__class__ is other.__class__: + order = ["EASY", "MEDIUM", "HARD", "ESCALATE"] + try: + return order.index(self.value) < order.index(other.value) + except ValueError: + return False + return NotImplemented + + +@dataclass +class ConflictBlock: + """Represents a single conflict block in a file""" + start_line: int + end_line: int + ours: str + theirs: str + base: Optional[str] = None + markers: Dict[str, int] = None + + +@dataclass +class FileConflict: + """Complete conflict information for a file""" + filepath: str + conflict_type: ConflictType + difficulty: Difficulty + blocks: List[ConflictBlock] + auto_resolvable: bool + + +def run_git_command(args: List[str], check: bool = True) -> subprocess.CompletedProcess: + """Execute git command and return result""" + try: + result = subprocess.run( + ['git'] + args, + capture_output=True, + text=True, + check=check + ) + return result + except subprocess.CalledProcessError as e: + # Don't crash immediately on git errors, allow handling + if check: + print(f"Git command failed: {e.stderr}", file=sys.stderr) + raise + return e + + +def list_conflicts() -> List[str]: + """ + List all files with merge conflicts. + """ + result = run_git_command(['status', '--porcelain']) + conflicts = [] + + if result.stdout: + for line in result.stdout.splitlines(): + # UU = both modified, AA = both added + if line.startswith('UU ') or line.startswith('AA '): + filepath = line[3:].strip() + conflicts.append(filepath) + + return conflicts + + +def extract_three_way(filepath: str) -> Dict: + """ + Extract Base, Ours, and Theirs versions from Git stages. + """ + # Git stages: :1 = base, :2 = ours (HEAD), :3 = theirs (incoming) + stages = {} + + for stage_num, stage_name in [('1', 'base'), ('2', 'ours'), ('3', 'theirs')]: + try: + result = run_git_command(['show', f':{stage_num}:{filepath}'], check=False) + stages[stage_name] = result.stdout if result.returncode == 0 else None + except Exception: + stages[stage_name] = None + + # Parse conflict markers from working tree + try: + with open(filepath, 'r', encoding='utf-8') as f: + content = f.read() + markers = parse_conflict_markers(content) + except Exception as e: + markers = [] + print(f"Warning: Could not parse markers: {e}", file=sys.stderr) + + return { + 'filepath': filepath, + 'base': stages['base'], + 'ours': stages['ours'], + 'theirs': stages['theirs'], + 'markers': markers + } + + +def parse_conflict_markers(content: str) -> List[Dict]: + """ + Parse conflict markers from file content. + """ + lines = content.splitlines(keepends=True) + conflicts = [] + i = 0 + + while i < len(lines): + # Look for conflict start marker + if lines[i].startswith('<<<<<<<'): + start = i + ours_lines = [] + theirs_lines = [] + separator_idx = None + end_idx = None + + # Find separator + i += 1 + while i < len(lines): + if lines[i].startswith('======='): + separator_idx = i + break + ours_lines.append(lines[i]) + i += 1 + + # Find end marker + if separator_idx: + i += 1 + while i < len(lines): + if lines[i].startswith('>>>>>>>'): + end_idx = i + break + theirs_lines.append(lines[i]) + i += 1 + + if separator_idx and end_idx: + conflicts.append({ + 'start_line': start + 1, + 'end_line': end_idx + 1, + 'ours': ''.join(ours_lines), + 'theirs': ''.join(theirs_lines), + 'ours_label': lines[start].strip(), + 'theirs_label': lines[end_idx].strip() + }) + + i += 1 + + return conflicts + + +def get_context(filepath: str, lines_context: int = 5) -> Dict: + """ + Get commit history and context for conflicted file. + """ + # Get merge base + try: + merge_base = run_git_command(['merge-base', 'HEAD', 'MERGE_HEAD']).stdout.strip() + except Exception: + merge_base = None + + # Get commits from both branches + ours_commits = [] + theirs_commits = [] + + if merge_base: + try: + # Commits in our branch + result = run_git_command([ + 'log', '--oneline', '--no-merges', + f'{merge_base}..HEAD', '--', filepath + ], check=False) + if result.stdout: + ours_commits = [line.strip() for line in result.stdout.splitlines()] + + # Commits in their branch + result = run_git_command([ + 'log', '--oneline', '--no-merges', + f'{merge_base}..MERGE_HEAD', '--', filepath + ], check=False) + if result.stdout: + theirs_commits = [line.strip() for line in result.stdout.splitlines()] + except Exception as e: + print(f"Warning: Could not fetch commit history: {e}", file=sys.stderr) + + # Analyze dependencies (basic implementation) + dependencies = analyze_dependencies(filepath) + + return { + 'filepath': filepath, + 'merge_base': merge_base, + 'ours_commits': ours_commits, + 'theirs_commits': theirs_commits, + 'dependencies': dependencies + } + + +def analyze_dependencies(filepath: str) -> Dict[str, List[str]]: + """ + Analyze code dependencies (imports, functions, variables). + """ + try: + # Try to read local file, might have markers + with open(filepath, 'r', encoding='utf-8') as f: + content = f.read() + except Exception: + return {'imports': [], 'functions': [], 'variables': []} + + imports = [] + functions = [] + + # Basic pattern matching + import_patterns = [ + r'^\s*import\s+[\w., ]+', + r'^\s*from\s+[\w.]+\s+import\s+', + r'^\s*#include\s*[<"][\w./]+[>"]', + ] + + for pattern in import_patterns: + imports.extend(re.findall(pattern, content, re.MULTILINE)) + + # Function definitions (simplified) + func_pattern = r'\b(?:def|function|func)\s+(\w+)\s*\(' + functions = re.findall(func_pattern, content) + + return { + 'imports': imports[:20], + 'functions': functions[:20], + 'variables': [] + } + + +def categorize_conflict(filepath: str) -> Dict: + """ + Automatically categorize conflict type and difficulty. + """ + data = extract_three_way(filepath) + markers = data.get('markers', []) + + if not markers: + return { + 'type': ConflictType.UNKNOWN.value, + 'difficulty': Difficulty.MEDIUM.value, + 'auto_resolvable': False, + 'reason': 'No conflict markers found' + } + + # Analyze all conflict blocks + conflict_types = [] + max_difficulty = Difficulty.EASY + + for marker in markers: + ours = marker['ours'].strip() + theirs = marker['theirs'].strip() + + # 1. IMPORT + if any(keyword in ours + theirs for keyword in ['import ', 'from ', '#include', 'require(']): + conflict_types.append(ConflictType.IMPORT) + continue + + # 2. WHITESPACE + if ours.replace(' ', '').replace('\t', '').replace('\n', '') == \ + theirs.replace(' ', '').replace('\t', '').replace('\n', ''): + conflict_types.append(ConflictType.WHITESPACE) + continue + + # 3. FUNCTION SIGNATURE + if any(keyword in ours + theirs for keyword in ['def ', 'function ', 'func ', 'class ']): + conflict_types.append(ConflictType.FUNCTION_SIGNATURE) + max_difficulty = max(max_difficulty, Difficulty.MEDIUM) + continue + + # 4. RENAME DETECTOR (Logic Nou) + ours_words = set(re.findall(r'\w+', ours)) + theirs_words = set(re.findall(r'\w+', theirs)) + diff = ours_words.symmetric_difference(theirs_words) + + # Verificăm dacă schimbarea implică cifre (ex: value=2 vs value=3) + is_numeric_change = any(d.isdigit() for d in diff) + + # Euristică: E rename doar dacă NU sunt cifre implicate + if not is_numeric_change and len(diff) < 3 and len(ours_words) > 0: + conflict_types.append(ConflictType.RENAME) + max_difficulty = max(max_difficulty, Difficulty.MEDIUM) + continue + + # 5. Default: LOGIC + conflict_types.append(ConflictType.LOGIC) + max_difficulty = Difficulty.HARD + + # Determine primary type + if not conflict_types: + primary_type = ConflictType.UNKNOWN + else: + priority = [ConflictType.LOGIC, ConflictType.FUNCTION_SIGNATURE, + ConflictType.REFACTOR, ConflictType.RENAME, + ConflictType.IMPORT, ConflictType.WHITESPACE] + primary_type = conflict_types[0] + for t in priority: + if t in conflict_types: + primary_type = t + break + + auto_resolvable = all( + t in [ConflictType.IMPORT, ConflictType.WHITESPACE] + for t in conflict_types + ) + + # Escalate logic + if primary_type == ConflictType.LOGIC: + max_difficulty = Difficulty.HARD + if len(markers) > 3: + max_difficulty = Difficulty.ESCALATE + + return { + 'type': primary_type.value, + 'difficulty': max_difficulty.value, + 'auto_resolvable': auto_resolvable, + 'all_types': [t.value for t in conflict_types], + 'num_conflicts': len(markers) + } + + +def validate_file(filepath: str, language: Optional[str] = None) -> Dict: + """ + Validate syntax and semantics of resolved file. + """ + if language is None: + ext = Path(filepath).suffix.lower() + lang_map = { + '.py': 'python', + '.js': 'javascript', '.ts': 'typescript', + '.go': 'go', '.rs': 'rust', + '.java': 'java', '.cpp': 'cpp', '.c': 'c' + } + language = lang_map.get(ext, 'unknown') + + results = { + 'filepath': filepath, + 'language': language, + 'syntax_valid': None, + 'semantic_errors': [], + 'warnings': [] + } + + # Python syntax validation + if language == 'python': + try: + with open(filepath, 'r', encoding='utf-8') as f: + code = f.read() + ast.parse(code) + results['syntax_valid'] = True + except SyntaxError as e: + results['syntax_valid'] = False + results['semantic_errors'].append(f"Line {e.lineno}: {e.msg}") + except Exception as e: + results['warnings'].append(f"Validation error: {str(e)}") + + # Other languages - placeholders + else: + results['warnings'].append(f'No syntax validator available for {language}') + results['syntax_valid'] = True # Assume valid if we can't check + + # Check for remaining conflict markers + try: + with open(filepath, 'r', encoding='utf-8') as f: + content = f.read() + + if any(marker in content for marker in ['<<<<<<<', '=======', '>>>>>>>']): + results['semantic_errors'].append('Conflict markers still present') + results['syntax_valid'] = False + except Exception as e: + results['warnings'].append(f'Could not check for markers: {e}') + + return results + + +def create_backup(branch_name: Optional[str] = None) -> str: + """ + Create backup branch before resolution. + """ + if branch_name is None: + from datetime import datetime + timestamp = datetime.now().strftime('%Y%m%d-%H%M%S') + branch_name = f'backup-merge-{timestamp}' + + try: + run_git_command(['branch', branch_name]) + return branch_name + except Exception as e: + # Branch might exist, try to checkout logic or simple fail + raise RuntimeError(f"Failed to create backup branch: {e}") + + +def main(): + """CLI interface for git_tools""" + parser = argparse.ArgumentParser( + description='Git merge conflict analysis tools for Claude Code' + ) + + subparsers = parser.add_subparsers(dest='command', help='Command to execute') + + # List conflicts + subparsers.add_parser('list', help='List all files with conflicts') + + # Extract three-way diff + extract_parser = subparsers.add_parser('extract', help='Extract 3-way diff') + extract_parser.add_argument('filepath', help='File to extract') + extract_parser.add_argument('--with-context', action='store_true', + help='Include commit history context') + + # Get context + context_parser = subparsers.add_parser('context', help='Get commit context') + context_parser.add_argument('filepath', help='File to analyze') + + # Categorize conflict + categorize_parser = subparsers.add_parser('categorize', help='Categorize conflict') + categorize_parser.add_argument('filepath', help='File to categorize') + + # Validate file + validate_parser = subparsers.add_parser('validate', help='Validate resolved file') + validate_parser.add_argument('filepath', help='File to validate') + validate_parser.add_argument('--language', help='Programming language') + + # Create backup + backup_parser = subparsers.add_parser('backup', help='Create backup branch') + backup_parser.add_argument('--name', help='Custom branch name') + + args = parser.parse_args() + + try: + if args.command == 'list': + conflicts = list_conflicts() + print(json.dumps(conflicts, indent=2)) + + elif args.command == 'extract': + data = extract_three_way(args.filepath) + if args.with_context: + context = get_context(args.filepath) + data['context'] = context + category = categorize_conflict(args.filepath) + data['category'] = category + print(json.dumps(data, indent=2)) + + elif args.command == 'context': + context = get_context(args.filepath) + print(json.dumps(context, indent=2)) + + elif args.command == 'categorize': + category = categorize_conflict(args.filepath) + print(json.dumps(category, indent=2)) + + elif args.command == 'validate': + results = validate_file(args.filepath, args.language) + print(json.dumps(results, indent=2)) + + elif args.command == 'backup': + branch_name = create_backup(args.name) + print(json.dumps({'backup_branch': branch_name}, indent=2)) + + else: + parser.print_help() + sys.exit(1) + + except Exception as e: + # Return structured error for the AI to handle + print(json.dumps({'error': str(e)}), file=sys.stderr) + sys.exit(1) + + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/llm-git-conflict-resolve/skill/instructions.md b/llm-git-conflict-resolve/skill/instructions.md new file mode 100644 index 00000000..fff2244e --- /dev/null +++ b/llm-git-conflict-resolve/skill/instructions.md @@ -0,0 +1,588 @@ +# Git Merge Conflict Resolution Skill + +## Purpose + +You are a Git merge conflict resolution expert. This skill enables you to detect, analyze, and intelligently resolve merge conflicts by understanding the **intent** behind code changes, not just pattern-matching on conflict markers. + +**Core Philosophy**: Treat merge conflicts as a semantic understanding problem. Reconstruct the complete 3-way evolution (Base → Ours, Base → Theirs) to understand *why* conflicts occurred, enabling intelligent reconciliation based on developer intent. + +--- + +## Operational Workflow + +Follow this systematic process for every conflict resolution task: + +``` +DETECT → BACKUP → CATEGORIZE → EXTRACT CONTEXT → +STRATEGIZE → RESOLVE → VALIDATE → COMMIT/ESCALATE +``` + +### Step 1: Detection + +Scan for conflicts when the user mentions merge issues or when you detect merge state. + +```bash +python git_tools.py list +``` + +**Output**: JSON array of conflicted files +```json +["src/auth.py", "src/utils.js", "README.md"] +``` + +### Step 2: Mandatory Backup + +**ALWAYS create a backup branch before ANY resolution attempts.** + +```bash +python git_tools.py backup +``` + +**Output**: +```json +{"backup_branch": "backup-merge-20241211-143022"} +``` + +Inform the user: "Created backup branch: `backup-merge-20241211-143022`" + +### Step 3: Categorization & Prioritization + +Process conflicts in order: **EASY → MEDIUM → HARD** + +For each file, categorize the conflict: + +```bash +python git_tools.py categorize src/auth.py +``` + +**Output**: +```json +{ + "type": "IMPORT", + "difficulty": "EASY", + "auto_resolvable": true, + "all_types": ["IMPORT"], + "num_conflicts": 1 +} +``` + +**Priority Rules**: +1. Auto-resolve all EASY conflicts first (builds confidence) +2. Attempt MEDIUM conflicts with semantic analysis +3. HARD conflicts require detailed analysis, often escalate +4. ESCALATE difficulty = immediately create escalation report + +--- + +## Context Extraction + +**NEVER resolve conflicts based solely on conflict markers.** Always fetch complete context. + +### Extract Full 3-Way Diff + Context + +```bash +python git_tools.py extract src/auth.py --with-context +``` + +**Output**: +```json +{ + "filepath": "src/auth.py", + "base": "# Original common ancestor code", + "ours": "# Our HEAD version", + "theirs": "# Their incoming version", + "markers": [ + { + "start_line": 42, + "end_line": 68, + "ours": "def validate_email(email):\n ...", + "theirs": "def validate_user_email(email):\n ..." + } + ], + "context": { + "merge_base": "abc123def", + "ours_commits": [ + "a1b2c3d Add email validation", + "e4f5g6h Fix validation regex" + ], + "theirs_commits": [ + "h7i8j9k Rename function for clarity", + "l0m1n2o Update docstring" + ], + "dependencies": { + "imports": ["import re", "from typing import bool"], + "functions": ["validate_email", "check_domain"] + } + }, + "category": { + "type": "RENAME", + "difficulty": "MEDIUM", + "auto_resolvable": false + } +} +``` + +### Understanding the Context + +From this data, you must infer: + +1. **What changed?** (diff between versions) +2. **Why did it change?** (commit messages) +3. **Are changes complementary or contradictory?** + +**Example Analysis**: +- Ours: Added validation logic +- Theirs: Renamed function for clarity +- **Intent**: Both are improvements, not contradictory +- **Resolution**: Apply rename + keep validation logic + +--- + +## Resolution Strategies by Conflict Type + +### 1. IMPORT Conflicts (Difficulty: EASY) + +**Strategy**: Union merge + deduplicate + sort + +**Example**: +```python +# Ours +import requests +import json + +# Theirs +import requests +import yaml +import json +``` + +**Resolution**: +```python +import json +import requests +import yaml +``` + +**Implementation**: +1. Extract all import statements from both sides +2. Combine into a set (automatic deduplication) +3. Sort alphabetically +4. Apply language-specific formatting (e.g., group stdlib vs third-party) + +**Auto-resolve**: YES + +--- + +### 2. WHITESPACE Conflicts (Difficulty: EASY) + +**Strategy**: Apply project formatter + +**Detection**: Content is identical after removing whitespace + +**Resolution**: +1. Choose either version (they're semantically identical) +2. Run formatter: `black` (Python), `prettier` (JS/TS), `gofmt` (Go) +3. Apply formatted version + +**Auto-resolve**: YES + +--- + +### 3. RENAME Conflicts (Difficulty: MEDIUM) + +**Strategy**: Detect pattern, apply consistently + +**Example**: +```python +# Ours: kept old name, added feature +def calculate_total(items): + return sum(item.price for item in items) * 1.1 # Added tax + +# Theirs: renamed function +def compute_total(items): + return sum(item.price for item in items) +``` + +**Analysis**: +- Theirs: renamed `calculate_total` → `compute_total` +- Ours: added tax calculation (10%) + +**Resolution**: +```python +def compute_total(items): + return sum(item.price for item in items) * 1.1 # Added tax +``` + +**Implementation**: +1. Detect rename pattern (compare Base with both sides) +2. Identify which side has the rename +3. Apply functional changes from other side to renamed version +4. Search entire file for old name references, update all + +**Auto-resolve**: If rename is clear and no semantic conflicts + +--- + +### 4. REFACTOR Conflicts (Difficulty: MEDIUM-HARD) + +**Strategy**: Apply changes to new structure + +**Example**: +```python +# Base +def process_data(data): + validated = validate(data) + transformed = transform(validated) + return save(transformed) + +# Ours: refactored into class +class DataProcessor: + def process(self, data): + validated = self.validate(data) + transformed = self.transform(validated) + return self.save(transformed) + +# Theirs: added error handling +def process_data(data): + validated = validate(data) + if not validated: + raise ValueError("Invalid data") + transformed = transform(validated) + return save(transformed) +``` + +**Resolution**: +```python +class DataProcessor: + def process(self, data): + validated = self.validate(data) + if not validated: + raise ValueError("Invalid data") + transformed = self.transform(validated) + return self.save(transformed) +``` + +**Implementation**: +1. Identify structural change (function → class) +2. Identify logical change (error handling) +3. Accept new structure +4. Apply logical changes to new structure +5. Update all call sites to use new structure + +**Auto-resolve**: If logical changes don't depend on old structure + +--- + +### 5. FUNCTION SIGNATURE Conflicts (Difficulty: MEDIUM) + +**Strategy**: Check compatibility, merge if safe + +**Example**: +```python +# Ours: added parameter +def fetch_user(user_id, include_deleted=False): + ... + +# Theirs: added different parameter +def fetch_user(user_id, cache=True): + ... +``` + +**Analysis**: Both parameters have defaults → backward compatible + +**Resolution**: +```python +def fetch_user(user_id, include_deleted=False, cache=True): + ... +``` + +**When to escalate**: +- Parameters conflict in position +- Removing required parameters (breaking change) +- Type incompatibilities + +**Auto-resolve**: If both changes add optional parameters + +--- + +### 6. LOGIC Conflicts (Difficulty: HARD) + +**Strategy**: Analyze intent, combine if complementary, escalate if contradictory + +**Example 1 - Complementary** (Auto-resolve): +```python +# Ours: bug fix +if user.age >= 18: + grant_access() + +# Theirs: feature addition +if user.is_verified: + grant_access() +``` + +**Resolution** (combine conditions): +```python +if user.age >= 18 and user.is_verified: + grant_access() +``` + +**Example 2 - Contradictory** (ESCALATE): +```python +# Ours: sorting algorithm A +results.sort(key=lambda x: x.score) + +# Theirs: sorting algorithm B +results.sort(key=lambda x: x.timestamp) +``` + +**Analysis**: Different sorting criteria → ambiguous intent → **ESCALATE** + +**Implementation**: +1. Check commit messages for intent keywords: + - "fix", "bug" → bug fix + - "feat", "add" → new feature + - "refactor" → restructuring +2. If bug fix + feature → usually safe to combine +3. If feature + feature → check if complementary +4. If contradictory logic → **ESCALATE** + +**Auto-resolve**: ONLY if clearly complementary (e.g., bug fix + feature) + +--- + +## Validation Protocol + +**After EVERY resolution, validate before committing:** + +```bash +python git_tools.py validate src/auth.py +``` + +**Output**: +```json +{ + "syntax_valid": true, + "semantic_errors": [], + "warnings": [] +} +``` + +### Validation Layers + +#### Layer 1: Syntax (MANDATORY) +- **Python**: AST parsing +- **JavaScript/TypeScript**: ESLint +- **Go**: `go fmt` +- **Other**: Basic checks + +**Failure action**: STOP. Report syntax error, do not commit. + +#### Layer 2: Semantic (RECOMMENDED) +- No undefined variables +- Consistent types +- Satisfied imports/dependencies +- No remaining conflict markers + +**Failure action**: Review and fix if possible, otherwise escalate. + +#### Layer 3: Integration (OPTIONAL) +- Works with surrounding code +- Doesn't break existing tests +- Maintains API contracts + +**Failure action**: Suggest running tests, warn user. + +--- + +## Escalation Criteria + +**When to NOT auto-resolve:** + +1. **Ambiguous Intent** + - Two features that contradict each other + - Cannot determine which approach is correct + - Commit messages don't clarify intent + +2. **Data Loss Risk** + - One side deletes data, other modifies it + - Structural changes that might lose information + +3. **Test Conflicts** + - Different test expectations + - Conflicting assertions + +4. **Complex Dependencies** + - Changes cascade to multiple files + - Requires deep architectural understanding + +5. **Validation Failure** + - Syntax errors after resolution + - Semantic errors that can't be fixed automatically + +--- + +## Escalation Report Format + +When escalating, provide this structured report: + +```markdown +## Conflict Escalation: [filepath] + +**Classification**: [TYPE] | [DIFFICULTY] + +**Summary**: +Brief description of the conflict + +**Context Analysis**: +- **Ours (HEAD)**: [commit messages and intent] +- **Theirs (incoming)**: [commit messages and intent] +- **Merge Base**: [common ancestor state] + +**Why Auto-Resolution Failed**: +[Specific reason: ambiguous intent, data loss risk, etc.] + +**Resolution Options**: + +1. **Option A** (Recommended: [why]) + - Approach: [description] + - Trade-offs: [pros/cons] + - Implementation: [high-level steps] + +2. **Option B** + - Approach: [description] + - Trade-offs: [pros/cons] + - Implementation: [high-level steps] + +3. **Option C** (if applicable) + - [...] + +**Requested Action**: +Please review the options and specify which resolution to apply, or provide guidance on how to combine the changes. + +**Files Affected**: +- [list of files that would be modified] + +**Backup Branch**: `backup-merge-20241211-143022` +``` + +--- + +## Complete Example Workflow + +### Scenario: User says "help me resolve merge conflicts" + +```bash +# 1. Detect conflicts +$ python git_tools.py list +["src/auth.py", "src/config.js", "README.md"] + +# 2. Create backup +$ python git_tools.py backup +{"backup_branch": "backup-merge-20241211-150000"} +``` + +**Tell user**: "Found 3 conflicts. Created backup: `backup-merge-20241211-150000`" + +```bash +# 3. Process first file (easiest first) +$ python git_tools.py categorize README.md +{ + "type": "WHITESPACE", + "difficulty": "EASY", + "auto_resolvable": true +} +``` + +**Action**: Auto-resolve by choosing either version and formatting + +```bash +# 4. Process second file +$ python git_tools.py extract src/config.js --with-context +{ + "category": {"type": "IMPORT", "difficulty": "EASY"}, + "markers": [...], + "context": {"ours_commits": ["Add dotenv"], "theirs_commits": ["Add axios"]} +} +``` + +**Action**: Union merge imports + +```bash +# 5. Process third file +$ python git_tools.py extract src/auth.py --with-context +{ + "category": {"type": "LOGIC", "difficulty": "HARD"}, + "context": { + "ours_commits": ["Implement JWT validation"], + "theirs_commits": ["Implement OAuth2"] + } +} +``` + +**Analysis**: Two different authentication approaches → **ESCALATE** + +**Action**: Create detailed escalation report with options: +1. Keep JWT (existing approach) +2. Switch to OAuth2 (modern standard) +3. Support both (most flexible) + +--- + +## Best Practices + +### DO +- Always create backup before starting +- Process conflicts from easy → hard +- Fetch complete context (don't rely on markers alone) +- Validate after every resolution +- Explain your reasoning to the user +- Escalate when uncertain + +### DON'T +- Never skip backup creation +- Never resolve based on markers alone +- Never commit without validation +- Never guess when intent is ambiguous +- Never modify more files than necessary +- Never use `git merge --ours` or `--theirs` blindly + +--- + +## Special Cases + +### Binary Files +```bash +# Cannot merge binaries, user must choose +git checkout --ours binary_file.png +# OR +git checkout --theirs binary_file.png +``` + +### Generated Files +- Lockfiles (`package-lock.json`, `Cargo.lock`): regenerate +- Built artifacts: rebuild +- Auto-generated code: re-run generator + +### Deleted Files +- If Ours deleted, Theirs modified → escalate +- If Theirs deleted, Ours modified → escalate +- If both deleted → auto-resolve (accept deletion) + +--- + +## Success Metrics + +**Target auto-resolution rates**: +- Trivial (IMPORT, WHITESPACE): **95%** +- Structural (RENAME, REFACTOR): **60%** +- Logic conflicts: **30%** + +**Quality standards**: +- Zero syntax errors through validation +- <1% semantic errors through multi-layer checking +- Clear escalation reports when human input needed + +**Safety-first principle**: +- Always backup before changes +- Never commit invalid code +- Escalate with detailed analysis when uncertain \ No newline at end of file From 167e21db139e4b2245db45ed8827a0dc007fc3b1 Mon Sep 17 00:00:00 2001 From: Gabriel Crisan Date: Fri, 12 Dec 2025 21:38:45 +0200 Subject: [PATCH 09/20] Refactor skill files in order to integrate slash commands --- llm-git-conflict-resolve/skill/git_tools.py | 582 +++------------- .../skill/instructions.md | 644 ++---------------- 2 files changed, 181 insertions(+), 1045 deletions(-) diff --git a/llm-git-conflict-resolve/skill/git_tools.py b/llm-git-conflict-resolve/skill/git_tools.py index f12f1fc4..21ebec80 100644 --- a/llm-git-conflict-resolve/skill/git_tools.py +++ b/llm-git-conflict-resolve/skill/git_tools.py @@ -1,507 +1,151 @@ -#!/usr/bin/env python3 -""" -Git Merge Conflict Tools - Interface for Claude Code Agent -Provides deterministic, structured data about Git conflicts without resolution logic. -""" - -import subprocess -import json import sys -import re import argparse +import subprocess +import json +import os import ast -from pathlib import Path -from typing import Dict, List, Optional, Tuple -from dataclasses import dataclass, asdict -from enum import Enum - - -class ConflictType(Enum): - """Classification of conflict types""" - IMPORT = "IMPORT" - WHITESPACE = "WHITESPACE" - RENAME = "RENAME" - REFACTOR = "REFACTOR" - LOGIC = "LOGIC" - FUNCTION_SIGNATURE = "FUNCTION_SIGNATURE" - UNKNOWN = "UNKNOWN" - - -class Difficulty(Enum): - """Estimated difficulty of resolution""" - EASY = "EASY" - MEDIUM = "MEDIUM" - HARD = "HARD" - ESCALATE = "ESCALATE" - - # FIX: Această metodă permite funcției max() să compare dificultățile - def __lt__(self, other): - if self.__class__ is other.__class__: - order = ["EASY", "MEDIUM", "HARD", "ESCALATE"] - try: - return order.index(self.value) < order.index(other.value) - except ValueError: - return False - return NotImplemented - - -@dataclass -class ConflictBlock: - """Represents a single conflict block in a file""" - start_line: int - end_line: int - ours: str - theirs: str - base: Optional[str] = None - markers: Dict[str, int] = None - - -@dataclass -class FileConflict: - """Complete conflict information for a file""" - filepath: str - conflict_type: ConflictType - difficulty: Difficulty - blocks: List[ConflictBlock] - auto_resolvable: bool - -def run_git_command(args: List[str], check: bool = True) -> subprocess.CompletedProcess: - """Execute git command and return result""" +def run_git_command(command): + """Executes a git command and returns the output as a string.""" try: - result = subprocess.run( - ['git'] + args, - capture_output=True, - text=True, - check=check + result = subprocess.check_output( + command, + stderr=subprocess.STDOUT, + shell=True ) - return result + return result.decode('utf-8').strip() except subprocess.CalledProcessError as e: - # Don't crash immediately on git errors, allow handling - if check: - print(f"Git command failed: {e.stderr}", file=sys.stderr) - raise - return e - - -def list_conflicts() -> List[str]: - """ - List all files with merge conflicts. - """ - result = run_git_command(['status', '--porcelain']) - conflicts = [] - - if result.stdout: - for line in result.stdout.splitlines(): - # UU = both modified, AA = both added - if line.startswith('UU ') or line.startswith('AA '): - filepath = line[3:].strip() - conflicts.append(filepath) - - return conflicts - - -def extract_three_way(filepath: str) -> Dict: - """ - Extract Base, Ours, and Theirs versions from Git stages. - """ - # Git stages: :1 = base, :2 = ours (HEAD), :3 = theirs (incoming) - stages = {} - - for stage_num, stage_name in [('1', 'base'), ('2', 'ours'), ('3', 'theirs')]: - try: - result = run_git_command(['show', f':{stage_num}:{filepath}'], check=False) - stages[stage_name] = result.stdout if result.returncode == 0 else None - except Exception: - stages[stage_name] = None - - # Parse conflict markers from working tree - try: - with open(filepath, 'r', encoding='utf-8') as f: - content = f.read() - markers = parse_conflict_markers(content) - except Exception as e: - markers = [] - print(f"Warning: Could not parse markers: {e}", file=sys.stderr) - - return { - 'filepath': filepath, - 'base': stages['base'], - 'ours': stages['ours'], - 'theirs': stages['theirs'], - 'markers': markers - } - - -def parse_conflict_markers(content: str) -> List[Dict]: - """ - Parse conflict markers from file content. - """ - lines = content.splitlines(keepends=True) - conflicts = [] - i = 0 - - while i < len(lines): - # Look for conflict start marker - if lines[i].startswith('<<<<<<<'): - start = i - ours_lines = [] - theirs_lines = [] - separator_idx = None - end_idx = None - - # Find separator - i += 1 - while i < len(lines): - if lines[i].startswith('======='): - separator_idx = i - break - ours_lines.append(lines[i]) - i += 1 - - # Find end marker - if separator_idx: - i += 1 - while i < len(lines): - if lines[i].startswith('>>>>>>>'): - end_idx = i - break - theirs_lines.append(lines[i]) - i += 1 - - if separator_idx and end_idx: - conflicts.append({ - 'start_line': start + 1, - 'end_line': end_idx + 1, - 'ours': ''.join(ours_lines), - 'theirs': ''.join(theirs_lines), - 'ours_label': lines[start].strip(), - 'theirs_label': lines[end_idx].strip() - }) + # Return None to signal that, for example, the file does not exist in that version + return None + +def list_conflicted_files(): + """Identifies files marked as conflicted.""" + # --porcelain provides a stable format for parsing + output = run_git_command("git status --porcelain") + if not output: + return [] + + conflicted_files = [] + for line in output.split('\n'): + # Conflicts are usually marked with 'UU', 'AA', 'UD', etc. + # The first 2 characters indicate the status + status = line[:2] + filepath = line[3:].strip() - i += 1 + # Simplified filter: if both sides modified (U) or added (A) + if 'U' in status or 'A' in status: + conflicted_files.append({ + "filepath": filepath, + "status": status + }) - return conflicts + return conflicted_files - -def get_context(filepath: str, lines_context: int = 5) -> Dict: +def get_file_content_at_stage(filepath, stage): """ - Get commit history and context for conflicted file. + Extracts file content at a specific git stage. + Stage 1 = Base (Ancestor) + Stage 2 = Ours (Local/HEAD) + Stage 3 = Theirs (Remote/MERGE_HEAD) """ - # Get merge base - try: - merge_base = run_git_command(['merge-base', 'HEAD', 'MERGE_HEAD']).stdout.strip() - except Exception: - merge_base = None - - # Get commits from both branches - ours_commits = [] - theirs_commits = [] - - if merge_base: - try: - # Commits in our branch - result = run_git_command([ - 'log', '--oneline', '--no-merges', - f'{merge_base}..HEAD', '--', filepath - ], check=False) - if result.stdout: - ours_commits = [line.strip() for line in result.stdout.splitlines()] - - # Commits in their branch - result = run_git_command([ - 'log', '--oneline', '--no-merges', - f'{merge_base}..MERGE_HEAD', '--', filepath - ], check=False) - if result.stdout: - theirs_commits = [line.strip() for line in result.stdout.splitlines()] - except Exception as e: - print(f"Warning: Could not fetch commit history: {e}", file=sys.stderr) - - # Analyze dependencies (basic implementation) - dependencies = analyze_dependencies(filepath) - - return { - 'filepath': filepath, - 'merge_base': merge_base, - 'ours_commits': ours_commits, - 'theirs_commits': theirs_commits, - 'dependencies': dependencies - } + # git show :: + content = run_git_command(f"git show :{stage}:{filepath}") + return content if content is not None else "" - -def analyze_dependencies(filepath: str) -> Dict[str, List[str]]: +def get_commit_context(filepath): """ - Analyze code dependencies (imports, functions, variables). + Extracts commit messages to understand semantic intent (Solution 3). """ - try: - # Try to read local file, might have markers - with open(filepath, 'r', encoding='utf-8') as f: - content = f.read() - except Exception: - return {'imports': [], 'functions': [], 'variables': []} - - imports = [] - functions = [] + # HEAD is the current branch (Local) + local_msg = run_git_command(f"git log -1 --pretty=%B HEAD -- {filepath}") - # Basic pattern matching - import_patterns = [ - r'^\s*import\s+[\w., ]+', - r'^\s*from\s+[\w.]+\s+import\s+', - r'^\s*#include\s*[<"][\w./]+[>"]', - ] - - for pattern in import_patterns: - imports.extend(re.findall(pattern, content, re.MULTILINE)) - - # Function definitions (simplified) - func_pattern = r'\b(?:def|function|func)\s+(\w+)\s*\(' - functions = re.findall(func_pattern, content) + # MERGE_HEAD is the incoming branch (Remote). + # It might be null if we are not in a standard merge, but we handle the case. + remote_msg = run_git_command(f"git log -1 --pretty=%B MERGE_HEAD -- {filepath}") return { - 'imports': imports[:20], - 'functions': functions[:20], - 'variables': [] + "local_intent": local_msg.strip() if local_msg else "Unknown (Manual changes or no commit msg)", + "remote_intent": remote_msg.strip() if remote_msg else "Unknown (No MERGE_HEAD found)" } - -def categorize_conflict(filepath: str) -> Dict: +def verify_syntax(filepath): """ - Automatically categorize conflict type and difficulty. + Verifies file syntax. Currently supports Python via AST. + Can be extended for JS/TS by running 'node -c' etc. """ - data = extract_three_way(filepath) - markers = data.get('markers', []) - - if not markers: - return { - 'type': ConflictType.UNKNOWN.value, - 'difficulty': Difficulty.MEDIUM.value, - 'auto_resolvable': False, - 'reason': 'No conflict markers found' - } - - # Analyze all conflict blocks - conflict_types = [] - max_difficulty = Difficulty.EASY - - for marker in markers: - ours = marker['ours'].strip() - theirs = marker['theirs'].strip() - - # 1. IMPORT - if any(keyword in ours + theirs for keyword in ['import ', 'from ', '#include', 'require(']): - conflict_types.append(ConflictType.IMPORT) - continue - - # 2. WHITESPACE - if ours.replace(' ', '').replace('\t', '').replace('\n', '') == \ - theirs.replace(' ', '').replace('\t', '').replace('\n', ''): - conflict_types.append(ConflictType.WHITESPACE) - continue - - # 3. FUNCTION SIGNATURE - if any(keyword in ours + theirs for keyword in ['def ', 'function ', 'func ', 'class ']): - conflict_types.append(ConflictType.FUNCTION_SIGNATURE) - max_difficulty = max(max_difficulty, Difficulty.MEDIUM) - continue + if not os.path.exists(filepath): + return {"status": "error", "message": "File not found"} - # 4. RENAME DETECTOR (Logic Nou) - ours_words = set(re.findall(r'\w+', ours)) - theirs_words = set(re.findall(r'\w+', theirs)) - diff = ours_words.symmetric_difference(theirs_words) - - # Verificăm dacă schimbarea implică cifre (ex: value=2 vs value=3) - is_numeric_change = any(d.isdigit() for d in diff) - - # Euristică: E rename doar dacă NU sunt cifre implicate - if not is_numeric_change and len(diff) < 3 and len(ours_words) > 0: - conflict_types.append(ConflictType.RENAME) - max_difficulty = max(max_difficulty, Difficulty.MEDIUM) - continue - - # 5. Default: LOGIC - conflict_types.append(ConflictType.LOGIC) - max_difficulty = Difficulty.HARD - - # Determine primary type - if not conflict_types: - primary_type = ConflictType.UNKNOWN - else: - priority = [ConflictType.LOGIC, ConflictType.FUNCTION_SIGNATURE, - ConflictType.REFACTOR, ConflictType.RENAME, - ConflictType.IMPORT, ConflictType.WHITESPACE] - primary_type = conflict_types[0] - for t in priority: - if t in conflict_types: - primary_type = t - break - - auto_resolvable = all( - t in [ConflictType.IMPORT, ConflictType.WHITESPACE] - for t in conflict_types - ) - - # Escalate logic - if primary_type == ConflictType.LOGIC: - max_difficulty = Difficulty.HARD - if len(markers) > 3: - max_difficulty = Difficulty.ESCALATE - - return { - 'type': primary_type.value, - 'difficulty': max_difficulty.value, - 'auto_resolvable': auto_resolvable, - 'all_types': [t.value for t in conflict_types], - 'num_conflicts': len(markers) - } + # File extension + _, ext = os.path.splitext(filepath) - -def validate_file(filepath: str, language: Optional[str] = None) -> Dict: - """ - Validate syntax and semantics of resolved file. - """ - if language is None: - ext = Path(filepath).suffix.lower() - lang_map = { - '.py': 'python', - '.js': 'javascript', '.ts': 'typescript', - '.go': 'go', '.rs': 'rust', - '.java': 'java', '.cpp': 'cpp', '.c': 'c' - } - language = lang_map.get(ext, 'unknown') - - results = { - 'filepath': filepath, - 'language': language, - 'syntax_valid': None, - 'semantic_errors': [], - 'warnings': [] - } - - # Python syntax validation - if language == 'python': + if ext == '.py': try: with open(filepath, 'r', encoding='utf-8') as f: - code = f.read() - ast.parse(code) - results['syntax_valid'] = True + source = f.read() + ast.parse(source) + return {"status": "valid", "message": "Python syntax check passed."} except SyntaxError as e: - results['syntax_valid'] = False - results['semantic_errors'].append(f"Line {e.lineno}: {e.msg}") - except Exception as e: - results['warnings'].append(f"Validation error: {str(e)}") + return { + "status": "error", + "message": f"Syntax Error on line {e.lineno}: {e.msg}", + "details": str(e) + } - # Other languages - placeholders - else: - results['warnings'].append(f'No syntax validator available for {language}') - results['syntax_valid'] = True # Assume valid if we can't check - - # Check for remaining conflict markers - try: - with open(filepath, 'r', encoding='utf-8') as f: - content = f.read() - - if any(marker in content for marker in ['<<<<<<<', '=======', '>>>>>>>']): - results['semantic_errors'].append('Conflict markers still present') - results['syntax_valid'] = False - except Exception as e: - results['warnings'].append(f'Could not check for markers: {e}') - - return results + # For other files, currently return valid (or implement specific linters) + return {"status": "valid", "message": f"No linter configured for {ext}, assuming valid."} + +def main(): + parser = argparse.ArgumentParser(description="Git Merge Conflict Tool for AI Agents") + subparsers = parser.add_subparsers(dest="command", help="Available commands") + # --- Command: list --- + subparsers.add_parser("list", help="List conflicted files") -def create_backup(branch_name: Optional[str] = None) -> str: - """ - Create backup branch before resolution. - """ - if branch_name is None: - from datetime import datetime - timestamp = datetime.now().strftime('%Y%m%d-%H%M%S') - branch_name = f'backup-merge-{timestamp}' - - try: - run_git_command(['branch', branch_name]) - return branch_name - except Exception as e: - # Branch might exist, try to checkout logic or simple fail - raise RuntimeError(f"Failed to create backup branch: {e}") + # --- Command: extract --- + extract_parser = subparsers.add_parser("extract", help="Extract content and context") + extract_parser.add_argument("filepath", type=str, help="Path to the conflicted file") + # --- Command: verify --- + verify_parser = subparsers.add_parser("verify", help="Verify syntax") + verify_parser.add_argument("filepath", type=str, help="Path to the file to verify") -def main(): - """CLI interface for git_tools""" - parser = argparse.ArgumentParser( - description='Git merge conflict analysis tools for Claude Code' - ) - - subparsers = parser.add_subparsers(dest='command', help='Command to execute') - - # List conflicts - subparsers.add_parser('list', help='List all files with conflicts') - - # Extract three-way diff - extract_parser = subparsers.add_parser('extract', help='Extract 3-way diff') - extract_parser.add_argument('filepath', help='File to extract') - extract_parser.add_argument('--with-context', action='store_true', - help='Include commit history context') - - # Get context - context_parser = subparsers.add_parser('context', help='Get commit context') - context_parser.add_argument('filepath', help='File to analyze') - - # Categorize conflict - categorize_parser = subparsers.add_parser('categorize', help='Categorize conflict') - categorize_parser.add_argument('filepath', help='File to categorize') - - # Validate file - validate_parser = subparsers.add_parser('validate', help='Validate resolved file') - validate_parser.add_argument('filepath', help='File to validate') - validate_parser.add_argument('--language', help='Programming language') - - # Create backup - backup_parser = subparsers.add_parser('backup', help='Create backup branch') - backup_parser.add_argument('--name', help='Custom branch name') - args = parser.parse_args() - - try: - if args.command == 'list': - conflicts = list_conflicts() - print(json.dumps(conflicts, indent=2)) - - elif args.command == 'extract': - data = extract_three_way(args.filepath) - if args.with_context: - context = get_context(args.filepath) - data['context'] = context - category = categorize_conflict(args.filepath) - data['category'] = category - print(json.dumps(data, indent=2)) - - elif args.command == 'context': - context = get_context(args.filepath) - print(json.dumps(context, indent=2)) - - elif args.command == 'categorize': - category = categorize_conflict(args.filepath) - print(json.dumps(category, indent=2)) - - elif args.command == 'validate': - results = validate_file(args.filepath, args.language) - print(json.dumps(results, indent=2)) + + # Command routing + if args.command == "list": + result = list_conflicted_files() + print(json.dumps(result, indent=2)) + + elif args.command == "extract": + filepath = args.filepath - elif args.command == 'backup': - branch_name = create_backup(args.name) - print(json.dumps({'backup_branch': branch_name}, indent=2)) + # 1. Extract Diff (Code) + diff_data = { + "base": get_file_content_at_stage(filepath, 1), + "local": get_file_content_at_stage(filepath, 2), + "remote": get_file_content_at_stage(filepath, 3) + } - else: - parser.print_help() - sys.exit(1) - - except Exception as e: - # Return structured error for the AI to handle - print(json.dumps({'error': str(e)}), file=sys.stderr) - sys.exit(1) + # 2. Extract Context (Intent) + context_data = get_commit_context(filepath) + + # 3. Build the complete payload + full_payload = { + "file": filepath, + "diff": diff_data, + "context": context_data, + "note": "Use 'context' to determine intent, then merge 'diff' accordingly." + } + print(json.dumps(full_payload, indent=2)) + + elif args.command == "verify": + result = verify_syntax(args.filepath) + print(json.dumps(result, indent=2)) + else: + # If no command is provided + parser.print_help() -if __name__ == '__main__': +if __name__ == "__main__": main() \ No newline at end of file diff --git a/llm-git-conflict-resolve/skill/instructions.md b/llm-git-conflict-resolve/skill/instructions.md index fff2244e..240361e7 100644 --- a/llm-git-conflict-resolve/skill/instructions.md +++ b/llm-git-conflict-resolve/skill/instructions.md @@ -1,588 +1,80 @@ -# Git Merge Conflict Resolution Skill - -## Purpose - -You are a Git merge conflict resolution expert. This skill enables you to detect, analyze, and intelligently resolve merge conflicts by understanding the **intent** behind code changes, not just pattern-matching on conflict markers. - -**Core Philosophy**: Treat merge conflicts as a semantic understanding problem. Reconstruct the complete 3-way evolution (Base → Ours, Base → Theirs) to understand *why* conflicts occurred, enabling intelligent reconciliation based on developer intent. - ---- - -## Operational Workflow - -Follow this systematic process for every conflict resolution task: - -``` -DETECT → BACKUP → CATEGORIZE → EXTRACT CONTEXT → -STRATEGIZE → RESOLVE → VALIDATE → COMMIT/ESCALATE -``` - -### Step 1: Detection - -Scan for conflicts when the user mentions merge issues or when you detect merge state. - -```bash -python git_tools.py list -``` - -**Output**: JSON array of conflicted files -```json -["src/auth.py", "src/utils.js", "README.md"] -``` - -### Step 2: Mandatory Backup - -**ALWAYS create a backup branch before ANY resolution attempts.** - -```bash -python git_tools.py backup -``` - -**Output**: -```json -{"backup_branch": "backup-merge-20241211-143022"} -``` - -Inform the user: "Created backup branch: `backup-merge-20241211-143022`" - -### Step 3: Categorization & Prioritization - -Process conflicts in order: **EASY → MEDIUM → HARD** - -For each file, categorize the conflict: - -```bash -python git_tools.py categorize src/auth.py -``` - -**Output**: -```json -{ - "type": "IMPORT", - "difficulty": "EASY", - "auto_resolvable": true, - "all_types": ["IMPORT"], - "num_conflicts": 1 -} -``` - -**Priority Rules**: -1. Auto-resolve all EASY conflicts first (builds confidence) -2. Attempt MEDIUM conflicts with semantic analysis -3. HARD conflicts require detailed analysis, often escalate -4. ESCALATE difficulty = immediately create escalation report - ---- - -## Context Extraction - -**NEVER resolve conflicts based solely on conflict markers.** Always fetch complete context. - -### Extract Full 3-Way Diff + Context - -```bash -python git_tools.py extract src/auth.py --with-context -``` - -**Output**: -```json -{ - "filepath": "src/auth.py", - "base": "# Original common ancestor code", - "ours": "# Our HEAD version", - "theirs": "# Their incoming version", - "markers": [ - { - "start_line": 42, - "end_line": 68, - "ours": "def validate_email(email):\n ...", - "theirs": "def validate_user_email(email):\n ..." - } - ], - "context": { - "merge_base": "abc123def", - "ours_commits": [ - "a1b2c3d Add email validation", - "e4f5g6h Fix validation regex" - ], - "theirs_commits": [ - "h7i8j9k Rename function for clarity", - "l0m1n2o Update docstring" - ], - "dependencies": { - "imports": ["import re", "from typing import bool"], - "functions": ["validate_email", "check_domain"] - } - }, - "category": { - "type": "RENAME", - "difficulty": "MEDIUM", - "auto_resolvable": false - } -} -``` - -### Understanding the Context - -From this data, you must infer: - -1. **What changed?** (diff between versions) -2. **Why did it change?** (commit messages) -3. **Are changes complementary or contradictory?** - -**Example Analysis**: -- Ours: Added validation logic -- Theirs: Renamed function for clarity -- **Intent**: Both are improvements, not contradictory -- **Resolution**: Apply rename + keep validation logic - ---- - -## Resolution Strategies by Conflict Type - -### 1. IMPORT Conflicts (Difficulty: EASY) - -**Strategy**: Union merge + deduplicate + sort - -**Example**: -```python -# Ours -import requests -import json - -# Theirs -import requests -import yaml -import json -``` - -**Resolution**: -```python -import json -import requests -import yaml -``` - -**Implementation**: -1. Extract all import statements from both sides -2. Combine into a set (automatic deduplication) -3. Sort alphabetically -4. Apply language-specific formatting (e.g., group stdlib vs third-party) - -**Auto-resolve**: YES - ---- - -### 2. WHITESPACE Conflicts (Difficulty: EASY) - -**Strategy**: Apply project formatter - -**Detection**: Content is identical after removing whitespace - -**Resolution**: -1. Choose either version (they're semantically identical) -2. Run formatter: `black` (Python), `prettier` (JS/TS), `gofmt` (Go) -3. Apply formatted version - -**Auto-resolve**: YES - ---- - -### 3. RENAME Conflicts (Difficulty: MEDIUM) - -**Strategy**: Detect pattern, apply consistently - -**Example**: -```python -# Ours: kept old name, added feature -def calculate_total(items): - return sum(item.price for item in items) * 1.1 # Added tax - -# Theirs: renamed function -def compute_total(items): - return sum(item.price for item in items) -``` - -**Analysis**: -- Theirs: renamed `calculate_total` → `compute_total` -- Ours: added tax calculation (10%) - -**Resolution**: -```python -def compute_total(items): - return sum(item.price for item in items) * 1.1 # Added tax -``` - -**Implementation**: -1. Detect rename pattern (compare Base with both sides) -2. Identify which side has the rename -3. Apply functional changes from other side to renamed version -4. Search entire file for old name references, update all - -**Auto-resolve**: If rename is clear and no semantic conflicts - ---- - -### 4. REFACTOR Conflicts (Difficulty: MEDIUM-HARD) - -**Strategy**: Apply changes to new structure - -**Example**: -```python -# Base -def process_data(data): - validated = validate(data) - transformed = transform(validated) - return save(transformed) - -# Ours: refactored into class -class DataProcessor: - def process(self, data): - validated = self.validate(data) - transformed = self.transform(validated) - return self.save(transformed) - -# Theirs: added error handling -def process_data(data): - validated = validate(data) - if not validated: - raise ValueError("Invalid data") - transformed = transform(validated) - return save(transformed) -``` - -**Resolution**: -```python -class DataProcessor: - def process(self, data): - validated = self.validate(data) - if not validated: - raise ValueError("Invalid data") - transformed = self.transform(validated) - return self.save(transformed) -``` - -**Implementation**: -1. Identify structural change (function → class) -2. Identify logical change (error handling) -3. Accept new structure -4. Apply logical changes to new structure -5. Update all call sites to use new structure - -**Auto-resolve**: If logical changes don't depend on old structure - ---- - -### 5. FUNCTION SIGNATURE Conflicts (Difficulty: MEDIUM) - -**Strategy**: Check compatibility, merge if safe - -**Example**: -```python -# Ours: added parameter -def fetch_user(user_id, include_deleted=False): - ... - -# Theirs: added different parameter -def fetch_user(user_id, cache=True): - ... -``` - -**Analysis**: Both parameters have defaults → backward compatible - -**Resolution**: -```python -def fetch_user(user_id, include_deleted=False, cache=True): - ... -``` - -**When to escalate**: -- Parameters conflict in position -- Removing required parameters (breaking change) -- Type incompatibilities - -**Auto-resolve**: If both changes add optional parameters - ---- - -### 6. LOGIC Conflicts (Difficulty: HARD) - -**Strategy**: Analyze intent, combine if complementary, escalate if contradictory - -**Example 1 - Complementary** (Auto-resolve): -```python -# Ours: bug fix -if user.age >= 18: - grant_access() - -# Theirs: feature addition -if user.is_verified: - grant_access() -``` - -**Resolution** (combine conditions): -```python -if user.age >= 18 and user.is_verified: - grant_access() -``` - -**Example 2 - Contradictory** (ESCALATE): -```python -# Ours: sorting algorithm A -results.sort(key=lambda x: x.score) - -# Theirs: sorting algorithm B -results.sort(key=lambda x: x.timestamp) -``` - -**Analysis**: Different sorting criteria → ambiguous intent → **ESCALATE** - -**Implementation**: -1. Check commit messages for intent keywords: - - "fix", "bug" → bug fix - - "feat", "add" → new feature - - "refactor" → restructuring -2. If bug fix + feature → usually safe to combine -3. If feature + feature → check if complementary -4. If contradictory logic → **ESCALATE** - -**Auto-resolve**: ONLY if clearly complementary (e.g., bug fix + feature) - ---- - -## Validation Protocol - -**After EVERY resolution, validate before committing:** - -```bash -python git_tools.py validate src/auth.py -``` - -**Output**: -```json -{ - "syntax_valid": true, - "semantic_errors": [], - "warnings": [] -} -``` - -### Validation Layers - -#### Layer 1: Syntax (MANDATORY) -- **Python**: AST parsing -- **JavaScript/TypeScript**: ESLint -- **Go**: `go fmt` -- **Other**: Basic checks - -**Failure action**: STOP. Report syntax error, do not commit. - -#### Layer 2: Semantic (RECOMMENDED) -- No undefined variables -- Consistent types -- Satisfied imports/dependencies -- No remaining conflict markers - -**Failure action**: Review and fix if possible, otherwise escalate. - -#### Layer 3: Integration (OPTIONAL) -- Works with surrounding code -- Doesn't break existing tests -- Maintains API contracts - -**Failure action**: Suggest running tests, warn user. +# Git Merge Conflict Resolution Skill - System Instructions + +You are an expert Git Merge Conflict Orchestrator designed to run within the Claude Code environment. Your goal is to resolve complex git merge conflicts autonomously by analyzing not just the textual diffs, but the semantic intent behind changes. + +You must operate using a strict "Tool-Use" pattern. Do not guess conflict resolutions based solely on standard git markers (<<<<<<<, =======, >>>>>>>). Instead, use the provided Python CLI tools to retrieve factual data (Base, Local, Remote versions and Commit Context). + +## I. SLASH COMMAND INTERFACE + +You must listen for the following slash commands from the user and execute the corresponding workflow immediately. + +### /scan +**Purpose:** Identifies files currently in conflict. +**Action:** +1. Execute: `python git_tools.py list` +2. Parse the JSON output. +3. Present a bulleted list of conflicted files to the user. +4. Ask: "Which file would you like to resolve?" + +### /resolve +**Purpose:** Initiates the full resolution cycle for a specific file. +**Action:** +1. **Extraction:** Execute `python git_tools.py extract `. +2. **Analysis:** Read the JSON output. You will receive: + - `diff`: The content of Base, Ours (Local), and Theirs (Remote). + - `context`: The commit messages explaining *why* changes were made. +3. **Reasoning:** Formulate a plan (Chain of Thought) based on the Resolution Logic defined in Section II. +4. **Execution:** Rewrite the file locally with the resolved content. +5. **Verification:** Automatically trigger `/verify `. + +### /verify +**Purpose:** Validates the syntax of the resolved file. +**Action:** +1. Execute: `python git_tools.py verify `. +2. If `status` is "valid": + - Inform the user: "Syntax valid. Ready to stage." + - Ask if you should run `git add `. +3. If `status` is "error": + - Analyze the error message. + - Attempt one auto-correction if the error is trivial. + - If the error persists, display the error to the user and ask for guidance. + +### /help +**Purpose:** Lists available commands. +**Action:** Display the definitions of `/scan`, `/resolve`, and `/verify`. --- -## Escalation Criteria - -**When to NOT auto-resolve:** +## II. RESOLUTION LOGIC & STRATEGY -1. **Ambiguous Intent** - - Two features that contradict each other - - Cannot determine which approach is correct - - Commit messages don't clarify intent +When resolving a conflict via `/resolve`, you must follow this decision matrix. -2. **Data Loss Risk** - - One side deletes data, other modifies it - - Structural changes that might lose information +### 1. Intent Analysis (The Semantic Layer) +Before touching the code, look at the `context` object from the tool output. +- **Refactor vs. Feature:** If Local is a "Refactor" (renaming variables) and Remote is a "Feature" (adding logic using old names), you must apply the Remote logic but update it to use the new Local variable names. +- **Fix vs. Formatting:** If one side is a "Hotfix" and the other is "Style/Formatting", prioritize the logic of the Hotfix but try to respect the new formatting rules. -3. **Test Conflicts** - - Different test expectations - - Conflicting assertions +### 2. Import & Dependency Handling +- **Never Overwrite:** When imports conflict, perform a **Union**. Keep all unique imports from both Local and Remote unless one was explicitly deleted in the other (compare against Base). +- **Sorting:** Organize imports alphabetically or according to language standards after merging. -4. **Complex Dependencies** - - Changes cascade to multiple files - - Requires deep architectural understanding +### 3. Structural Conflicts +- **Deletions:** If Local modified a function but Remote deleted the file or the function: + - Check the Remote intent. If the deletion was intentional (e.g., "Deprecate module"), accept the deletion but warn the user. + - If unclear, keep the Local code and wrap it in comments with `TODO: Review potential deletion from Remote`. -5. **Validation Failure** - - Syntax errors after resolution - - Semantic errors that can't be fixed automatically +### 4. Code Synthesis +- **Do not output Git Markers:** The final file must be valid code, free of `<<<<<<<` markers. +- **Ambiguity Fallback:** If you cannot determine the correct path with >90% confidence, insert a comment in the code: + `// TODO: AI_RESOLUTION_UNCERTAIN - [Explanation of conflict]` + And inform the user explicitly. --- -## Escalation Report Format - -When escalating, provide this structured report: - -```markdown -## Conflict Escalation: [filepath] - -**Classification**: [TYPE] | [DIFFICULTY] - -**Summary**: -Brief description of the conflict - -**Context Analysis**: -- **Ours (HEAD)**: [commit messages and intent] -- **Theirs (incoming)**: [commit messages and intent] -- **Merge Base**: [common ancestor state] - -**Why Auto-Resolution Failed**: -[Specific reason: ambiguous intent, data loss risk, etc.] - -**Resolution Options**: - -1. **Option A** (Recommended: [why]) - - Approach: [description] - - Trade-offs: [pros/cons] - - Implementation: [high-level steps] - -2. **Option B** - - Approach: [description] - - Trade-offs: [pros/cons] - - Implementation: [high-level steps] - -3. **Option C** (if applicable) - - [...] - -**Requested Action**: -Please review the options and specify which resolution to apply, or provide guidance on how to combine the changes. - -**Files Affected**: -- [list of files that would be modified] - -**Backup Branch**: `backup-merge-20241211-143022` -``` - ---- - -## Complete Example Workflow - -### Scenario: User says "help me resolve merge conflicts" - -```bash -# 1. Detect conflicts -$ python git_tools.py list -["src/auth.py", "src/config.js", "README.md"] - -# 2. Create backup -$ python git_tools.py backup -{"backup_branch": "backup-merge-20241211-150000"} -``` - -**Tell user**: "Found 3 conflicts. Created backup: `backup-merge-20241211-150000`" - -```bash -# 3. Process first file (easiest first) -$ python git_tools.py categorize README.md -{ - "type": "WHITESPACE", - "difficulty": "EASY", - "auto_resolvable": true -} -``` - -**Action**: Auto-resolve by choosing either version and formatting - -```bash -# 4. Process second file -$ python git_tools.py extract src/config.js --with-context -{ - "category": {"type": "IMPORT", "difficulty": "EASY"}, - "markers": [...], - "context": {"ours_commits": ["Add dotenv"], "theirs_commits": ["Add axios"]} -} -``` - -**Action**: Union merge imports - -```bash -# 5. Process third file -$ python git_tools.py extract src/auth.py --with-context -{ - "category": {"type": "LOGIC", "difficulty": "HARD"}, - "context": { - "ours_commits": ["Implement JWT validation"], - "theirs_commits": ["Implement OAuth2"] - } -} -``` - -**Analysis**: Two different authentication approaches → **ESCALATE** - -**Action**: Create detailed escalation report with options: -1. Keep JWT (existing approach) -2. Switch to OAuth2 (modern standard) -3. Support both (most flexible) - ---- - -## Best Practices - -### DO -- Always create backup before starting -- Process conflicts from easy → hard -- Fetch complete context (don't rely on markers alone) -- Validate after every resolution -- Explain your reasoning to the user -- Escalate when uncertain - -### DON'T -- Never skip backup creation -- Never resolve based on markers alone -- Never commit without validation -- Never guess when intent is ambiguous -- Never modify more files than necessary -- Never use `git merge --ours` or `--theirs` blindly - ---- - -## Special Cases - -### Binary Files -```bash -# Cannot merge binaries, user must choose -git checkout --ours binary_file.png -# OR -git checkout --theirs binary_file.png -``` - -### Generated Files -- Lockfiles (`package-lock.json`, `Cargo.lock`): regenerate -- Built artifacts: rebuild -- Auto-generated code: re-run generator - -### Deleted Files -- If Ours deleted, Theirs modified → escalate -- If Theirs deleted, Ours modified → escalate -- If both deleted → auto-resolve (accept deletion) - ---- - -## Success Metrics - -**Target auto-resolution rates**: -- Trivial (IMPORT, WHITESPACE): **95%** -- Structural (RENAME, REFACTOR): **60%** -- Logic conflicts: **30%** - -**Quality standards**: -- Zero syntax errors through validation -- <1% semantic errors through multi-layer checking -- Clear escalation reports when human input needed +## III. OPERATIONAL GUIDELINES -**Safety-first principle**: -- Always backup before changes -- Never commit invalid code -- Escalate with detailed analysis when uncertain \ No newline at end of file +1. **State Management:** You are stateless. Always rely on `git_tools.py` for the current truth. +2. **Safety First:** Never run `git add` unless `/verify` returns a success status or the user explicitly overrides. +3. **Communication:** Be concise. + - Bad: "I have looked at the file and I can see that..." + - Good: "Conflict detected in `utils.py`. Local renames `process_data`, Remote optimizes loop. Merging logic..." \ No newline at end of file From 3b23a6a76d43333f6492e5d3eac21f2fb9c4a59f Mon Sep 17 00:00:00 2001 From: Gabriel Crisan Date: Fri, 12 Dec 2025 21:40:48 +0200 Subject: [PATCH 10/20] Add script for testing through a simulation --- .../setup_conflict_demo.sh | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100755 llm-git-conflict-resolve/setup_conflict_demo.sh diff --git a/llm-git-conflict-resolve/setup_conflict_demo.sh b/llm-git-conflict-resolve/setup_conflict_demo.sh new file mode 100755 index 00000000..85faf93e --- /dev/null +++ b/llm-git-conflict-resolve/setup_conflict_demo.sh @@ -0,0 +1,130 @@ +#!/bin/bash + +# Setup script for Git merge conflict resolution demo +# Run this from llm-git-conflict-resolve/ directory + +echo "Setting up Git merge conflict playground..." +echo "" + +# 1. Create and enter playground directory +mkdir -p playground +cd playground + +# 2. Initialize git repo +echo "Initializing Git repository..." +git init +git config user.email "test@example.com" +git config user.name "Test User" + +# 3. Copy git_tools.py & instructions.md from skill directory +echo "Copying git_tools.py..." +cp ../skill/git_tools.py . +echo "Copying instructions.md..." +cp ../skill/instructions.md . + +# 4. Create initial file with base implementation +echo "Creating base file..." +cat > utils.py << 'EOF' +import os +import sys + +def process_data(data): + """Process the input data.""" + result = [] + for item in data: + result.append(item * 2) + return result + +def calculate_sum(numbers): + """Calculate sum of numbers.""" + total = 0 + for num in numbers: + total += num + return total +EOF + +git add utils.py +git commit -m "Initial commit: Base implementation" + +# 5. Create feature branch (Remote) - adds new functionality +echo "Creating feature branch..." +git checkout -b feature +cat > utils.py << 'EOF' +import os +import sys +import json + +def process_data(data): + """Process the input data with enhanced logging.""" + result = [] + for item in data: + print(f"Processing: {item}") + result.append(item * 2) + return result + +def calculate_sum(numbers): + """Calculate sum of numbers.""" + total = 0 + for num in numbers: + total += num + return total + +def export_to_json(data, filename): + """Export data to JSON file.""" + with open(filename, 'w') as f: + json.dump(data, f, indent=2) +EOF + +git commit -a -m "Feature: Add JSON export and logging to process_data" + +# 6. Go back to master - refactor function names +echo "Switching to master and refactoring..." +git checkout master +cat > utils.py << 'EOF' +import os +import sys + +def transform_data(data): + """Transform the input data (renamed from process_data).""" + result = [] + for item in data: + result.append(item * 2) + return result + +def sum_numbers(numbers): + """Calculate sum of numbers (renamed from calculate_sum).""" + total = 0 + for num in numbers: + total += num + return total +EOF + +git commit -a -m "Refactor: Rename functions for clarity (process_data -> transform_data, calculate_sum -> sum_numbers)" + +# 7. Create the conflict! +echo "Creating merge conflict..." +git merge feature --no-edit 2>/dev/null || true + +echo "" +echo "==================================" +echo "Conflict playground created!" +echo "==================================" +echo "" +echo "Location: playground/" +echo "" +echo "Conflict Summary:" +echo " - Local (master): Refactored function names" +echo " - Remote (feature): Added JSON export + logging" +echo "" +echo "Test the tool with:" +echo " cd playground" +echo " python3 git_tools.py list" +echo " python3 git_tools.py extract utils.py" +echo " python3 git_tools.py verify utils.py" +echo "" +echo "Expected resolution:" +echo " - Keep new function names from Local (transform_data, sum_numbers)" +echo " - Add JSON export function from Remote" +echo " - Add logging to transform_data (but use new name)" +echo " - Keep json import from Remote" +echo "" From 677f34cbaf1cc1fd539804f413d3173f6d8d8180 Mon Sep 17 00:00:00 2001 From: Gabriel Crisan Date: Fri, 12 Dec 2025 23:15:48 +0200 Subject: [PATCH 11/20] Update instructions.md to have a more active agent --- .../skill/instructions.md | 119 +++++++++--------- 1 file changed, 57 insertions(+), 62 deletions(-) diff --git a/llm-git-conflict-resolve/skill/instructions.md b/llm-git-conflict-resolve/skill/instructions.md index 240361e7..e288e290 100644 --- a/llm-git-conflict-resolve/skill/instructions.md +++ b/llm-git-conflict-resolve/skill/instructions.md @@ -1,80 +1,75 @@ # Git Merge Conflict Resolution Skill - System Instructions -You are an expert Git Merge Conflict Orchestrator designed to run within the Claude Code environment. Your goal is to resolve complex git merge conflicts autonomously by analyzing not just the textual diffs, but the semantic intent behind changes. +You are an expert Git Merge Conflict Orchestrator. Your goal is to resolve complex git merge conflicts autonomously by analyzing not just the textual diffs, but the semantic intent behind changes. -You must operate using a strict "Tool-Use" pattern. Do not guess conflict resolutions based solely on standard git markers (<<<<<<<, =======, >>>>>>>). Instead, use the provided Python CLI tools to retrieve factual data (Base, Local, Remote versions and Commit Context). +## I. INTERACTION & GUIDANCE PROTOCOL (CRITICAL) -## I. SLASH COMMAND INTERFACE +**1. The "Welcome" Rule:** +At the very beginning of the conversation (or if the user says "help" or "start"), you MUST display the available commands and immediately suggest the first step. + - Example: "I am ready to resolve conflicts. Type `scan` to identify conflicted files." -You must listen for the following slash commands from the user and execute the corresponding workflow immediately. +**2. The "Next Step" Rule:** +You must NEVER leave the user guessing. Every single response must end with a **direct instruction** on what to type next. + - **Do not use slashes (/)** in your suggested commands. + - If you found conflicts -> Tell user to type: `resolve ` + - If you proposed code -> Tell user to type: `apply` + - If you verified syntax -> Tell user to type: `scan` to check for more or `git add` to stage. -### /scan -**Purpose:** Identifies files currently in conflict. -**Action:** -1. Execute: `python git_tools.py list` -2. Parse the JSON output. -3. Present a bulleted list of conflicted files to the user. -4. Ask: "Which file would you like to resolve?" +--- -### /resolve -**Purpose:** Initiates the full resolution cycle for a specific file. -**Action:** -1. **Extraction:** Execute `python git_tools.py extract `. -2. **Analysis:** Read the JSON output. You will receive: - - `diff`: The content of Base, Ours (Local), and Theirs (Remote). - - `context`: The commit messages explaining *why* changes were made. -3. **Reasoning:** Formulate a plan (Chain of Thought) based on the Resolution Logic defined in Section II. -4. **Execution:** Rewrite the file locally with the resolved content. -5. **Verification:** Automatically trigger `/verify `. - -### /verify -**Purpose:** Validates the syntax of the resolved file. -**Action:** -1. Execute: `python git_tools.py verify `. -2. If `status` is "valid": - - Inform the user: "Syntax valid. Ready to stage." - - Ask if you should run `git add `. -3. If `status` is "error": - - Analyze the error message. - - Attempt one auto-correction if the error is trivial. - - If the error persists, display the error to the user and ask for guidance. - -### /help -**Purpose:** Lists available commands. -**Action:** Display the definitions of `/scan`, `/resolve`, and `/verify`. +## II. TOOL USAGE +1. **`python3 git_tools.py `**: Your primary interface for git analysis. +2. **`run_shell_command`** (Native Tool): Use this to execute the python scripts and to write files to disk. --- -## II. RESOLUTION LOGIC & STRATEGY +## III. COMMAND WORKFLOWS -When resolving a conflict via `/resolve`, you must follow this decision matrix. +You must listen for the following keywords. Execute the action, then **Guide the User**. -### 1. Intent Analysis (The Semantic Layer) -Before touching the code, look at the `context` object from the tool output. -- **Refactor vs. Feature:** If Local is a "Refactor" (renaming variables) and Remote is a "Feature" (adding logic using old names), you must apply the Remote logic but update it to use the new Local variable names. -- **Fix vs. Formatting:** If one side is a "Hotfix" and the other is "Style/Formatting", prioritize the logic of the Hotfix but try to respect the new formatting rules. +### COMMAND: scan +**Triggers:** "scan", "find conflicts", "list", "status" +**Action:** +1. Execute: `python3 git_tools.py list` +2. Parse the JSON output. +3. Present a bulleted list of conflicted files. +4. **GUIDANCE:** End your response with: + > "To start resolving, please type: `resolve `" -### 2. Import & Dependency Handling -- **Never Overwrite:** When imports conflict, perform a **Union**. Keep all unique imports from both Local and Remote unless one was explicitly deleted in the other (compare against Base). -- **Sorting:** Organize imports alphabetically or according to language standards after merging. +### COMMAND: resolve +**Triggers:** "resolve ", "fix ", "extract " +**Action:** +1. Execute `python3 git_tools.py extract `. +2. Analyze the Diff + Context using the Resolution Logic (Section IV). +3. Output the fully merged code block. +4. **GUIDANCE:** End your response with: + > "Review the code above. If it looks correct, type `apply` to save it." + +### COMMAND: apply +**Triggers:** "apply", "yes", "save", "confirm" +**Action:** +1. Use `run_shell_command` to overwrite the file with the resolved content. + - **Important:** Write the full content cleanly to the target file. +2. Immediately execute `python3 git_tools.py verify `. +3. Report the status ("Syntax Valid" or "Error"). +4. **GUIDANCE:** + - If valid: "Syntax verified. You can now run `git add ` in your terminal, or type `scan` to check for other conflicts." + - If error: "There is a syntax error. Shall I try to fix it?" + +### COMMAND: help +**Triggers:** "help", "info", "commands" +**Action:** List the commands (`scan`, `resolve`, `apply`) and explain the workflow. -### 3. Structural Conflicts -- **Deletions:** If Local modified a function but Remote deleted the file or the function: - - Check the Remote intent. If the deletion was intentional (e.g., "Deprecate module"), accept the deletion but warn the user. - - If unclear, keep the Local code and wrap it in comments with `TODO: Review potential deletion from Remote`. +--- -### 4. Code Synthesis -- **Do not output Git Markers:** The final file must be valid code, free of `<<<<<<<` markers. -- **Ambiguity Fallback:** If you cannot determine the correct path with >90% confidence, insert a comment in the code: - `// TODO: AI_RESOLUTION_UNCERTAIN - [Explanation of conflict]` - And inform the user explicitly. +## IV. RESOLUTION LOGIC & STRATEGY ---- +### 1. Intent Analysis +- **Refactor vs. Feature:** If Local is "Refactor" (renaming) and Remote is "Feature" (logic), apply Remote logic using Local names. +- **Business Logic:** If Local changes a value and Remote adds a condition, **combine both** (e.g. `if new_check and price < new_limit`). -## III. OPERATIONAL GUIDELINES +### 2. Imports +- **Union:** Keep all unique imports. Sort alphabetically. -1. **State Management:** You are stateless. Always rely on `git_tools.py` for the current truth. -2. **Safety First:** Never run `git add` unless `/verify` returns a success status or the user explicitly overrides. -3. **Communication:** Be concise. - - Bad: "I have looked at the file and I can see that..." - - Good: "Conflict detected in `utils.py`. Local renames `process_data`, Remote optimizes loop. Merging logic..." \ No newline at end of file +### 3. Output +- **No Git Markers:** Final code must not contain `<<<<<<<`. \ No newline at end of file From bc3102afbe72cd064fe658a54fa31beb9c6bd259 Mon Sep 17 00:00:00 2001 From: Gabriel Crisan Date: Fri, 12 Dec 2025 23:22:58 +0200 Subject: [PATCH 12/20] Add scripts for conflict simulations that test the agent --- .../generate_conflict_logic_merge.sh | 93 +++++++++++++ .../generate_conflict_rename_vs_modify.sh | 106 ++++++++++++++ .../setup_conflict_demo.sh | 130 ------------------ 3 files changed, 199 insertions(+), 130 deletions(-) create mode 100755 llm-git-conflict-resolve/generate_conflict_logic_merge.sh create mode 100755 llm-git-conflict-resolve/generate_conflict_rename_vs_modify.sh delete mode 100755 llm-git-conflict-resolve/setup_conflict_demo.sh diff --git a/llm-git-conflict-resolve/generate_conflict_logic_merge.sh b/llm-git-conflict-resolve/generate_conflict_logic_merge.sh new file mode 100755 index 00000000..61c3f1c2 --- /dev/null +++ b/llm-git-conflict-resolve/generate_conflict_logic_merge.sh @@ -0,0 +1,93 @@ +#!/bin/bash + +# Setup script for Git merge conflict demo (Scenario: Logic Merge) +# Conflict: Price Update (Local) vs Stock Check (Remote) + +# 1. Create directory +mkdir -p playground-2 +cd playground-2 + +# 2. Initialize git quietly +git init -q +git config user.email "dev@example.com" +git config user.name "Dev User" + +# 3. Copy tools and setup GEMINI.md +if [ -d "../skill" ]; then + cp ../skill/git_tools.py . + cp ../skill/instructions.md GEMINI.md +else + echo "Error: '../skill' directory not found." + exit 1 +fi + +# 4. Base Commit +cat > products.py << 'EOF' +import sys + +def filter_products(products): + """ + Filters a list of products based on basic criteria. + Current rule: Only cheap products under $100. + """ + valid_products = [] + for p in products: + if p['price'] < 100: + valid_products.append(p) + return valid_products +EOF + +git add products.py +git commit -q -m "Initial commit" + +# 5. Remote Branch (Feature): Add Stock Check & Logging +git checkout -q -b feature-stock +cat > products.py << 'EOF' +import sys +import logging + +def filter_products(products): + """ + Filters products: cheap AND in stock. + """ + valid_products = [] + for p in products: + # Feature: Added stock check logic + if p['price'] < 100 and p['in_stock'] is True: + valid_products.append(p) + else: + logging.info(f"Skipping product: {p['id']}") + return valid_products +EOF + +git commit -a -q -m "Feature: Add stock check validation" + +# 6. Local Branch (Master): Update Price Policy (Inflation) +git checkout -q master +cat > products.py << 'EOF' +import sys +import math + +def filter_products(products): + """ + Filters a list of products based on basic criteria. + Updated rule: Adjusted for inflation, limit is now $150. + """ + valid_products = [] + for p in products: + # Master: Updated price limit to 150 + if p['price'] < 150: + valid_products.append(p) + return valid_products +EOF + +git commit -a -q -m "Policy Update: Increase price limit to $150" + +# 7. Create Conflict +git merge feature-stock --no-edit > /dev/null 2>&1 || true + +echo "==================================" +echo "Playground 2 Ready (Logic Conflict)" +echo "Folder: playground-2/" +echo "To start: cd playground-2 && gemini" +echo "==================================" \ No newline at end of file diff --git a/llm-git-conflict-resolve/generate_conflict_rename_vs_modify.sh b/llm-git-conflict-resolve/generate_conflict_rename_vs_modify.sh new file mode 100755 index 00000000..8cb3cb5c --- /dev/null +++ b/llm-git-conflict-resolve/generate_conflict_rename_vs_modify.sh @@ -0,0 +1,106 @@ +#!/bin/bash + +# Setup script for Git merge conflict demo (Scenario: Rename vs Modify) + +# 1. Create directory +mkdir -p playground +cd playground + +# 2. Initialize git quietly +git init -q +git config user.email "test@example.com" +git config user.name "Test User" + +# 3. Copy tools and setup GEMINI.md +if [ -d "../skill" ]; then + cp ../skill/git_tools.py . + cp ../skill/instructions.md GEMINI.md +else + echo "Error: '../skill' directory not found." + exit 1 +fi + +# 4. Base Commit +cat > utils.py << 'EOF' +import os +import sys + +def process_data(data): + """Process the input data.""" + result = [] + for item in data: + result.append(item * 2) + return result + +def calculate_sum(numbers): + """Calculate sum of numbers.""" + total = 0 + for num in numbers: + total += num + return total +EOF + +git add utils.py +git commit -q -m "Initial commit" + +# 5. Remote Branch (Feature): Add logging & new function +git checkout -q -b feature +cat > utils.py << 'EOF' +import os +import sys +import json + +def process_data(data): + """Process the input data with enhanced logging.""" + result = [] + for item in data: + print(f"Processing: {item}") + result.append(item * 2) + return result + +def calculate_sum(numbers): + """Calculate sum of numbers.""" + total = 0 + for num in numbers: + total += num + return total + +def export_to_json(data, filename): + """Export data to JSON file.""" + with open(filename, 'w') as f: + json.dump(data, f, indent=2) +EOF + +git commit -a -q -m "Feature: Add JSON export and logging" + +# 6. Local Branch (Master): Rename functions +git checkout -q master +cat > utils.py << 'EOF' +import os +import sys + +def transform_data(data): + """Transform the input data (renamed from process_data).""" + result = [] + for item in data: + result.append(item * 2) + return result + +def sum_numbers(numbers): + """Calculate sum of numbers (renamed from calculate_sum).""" + total = 0 + for num in numbers: + total += num + return total +EOF + +git commit -a -q -m "Refactor: Rename functions" + +# 7. Create Conflict +git merge feature --no-edit > /dev/null 2>&1 || true + +echo "==================================" +echo "Playground 1 Ready (Rename vs Modify)" +echo "Folder: playground/" +echo "To start: cd playground && gemini" +echo "==================================" \ No newline at end of file diff --git a/llm-git-conflict-resolve/setup_conflict_demo.sh b/llm-git-conflict-resolve/setup_conflict_demo.sh deleted file mode 100755 index 85faf93e..00000000 --- a/llm-git-conflict-resolve/setup_conflict_demo.sh +++ /dev/null @@ -1,130 +0,0 @@ -#!/bin/bash - -# Setup script for Git merge conflict resolution demo -# Run this from llm-git-conflict-resolve/ directory - -echo "Setting up Git merge conflict playground..." -echo "" - -# 1. Create and enter playground directory -mkdir -p playground -cd playground - -# 2. Initialize git repo -echo "Initializing Git repository..." -git init -git config user.email "test@example.com" -git config user.name "Test User" - -# 3. Copy git_tools.py & instructions.md from skill directory -echo "Copying git_tools.py..." -cp ../skill/git_tools.py . -echo "Copying instructions.md..." -cp ../skill/instructions.md . - -# 4. Create initial file with base implementation -echo "Creating base file..." -cat > utils.py << 'EOF' -import os -import sys - -def process_data(data): - """Process the input data.""" - result = [] - for item in data: - result.append(item * 2) - return result - -def calculate_sum(numbers): - """Calculate sum of numbers.""" - total = 0 - for num in numbers: - total += num - return total -EOF - -git add utils.py -git commit -m "Initial commit: Base implementation" - -# 5. Create feature branch (Remote) - adds new functionality -echo "Creating feature branch..." -git checkout -b feature -cat > utils.py << 'EOF' -import os -import sys -import json - -def process_data(data): - """Process the input data with enhanced logging.""" - result = [] - for item in data: - print(f"Processing: {item}") - result.append(item * 2) - return result - -def calculate_sum(numbers): - """Calculate sum of numbers.""" - total = 0 - for num in numbers: - total += num - return total - -def export_to_json(data, filename): - """Export data to JSON file.""" - with open(filename, 'w') as f: - json.dump(data, f, indent=2) -EOF - -git commit -a -m "Feature: Add JSON export and logging to process_data" - -# 6. Go back to master - refactor function names -echo "Switching to master and refactoring..." -git checkout master -cat > utils.py << 'EOF' -import os -import sys - -def transform_data(data): - """Transform the input data (renamed from process_data).""" - result = [] - for item in data: - result.append(item * 2) - return result - -def sum_numbers(numbers): - """Calculate sum of numbers (renamed from calculate_sum).""" - total = 0 - for num in numbers: - total += num - return total -EOF - -git commit -a -m "Refactor: Rename functions for clarity (process_data -> transform_data, calculate_sum -> sum_numbers)" - -# 7. Create the conflict! -echo "Creating merge conflict..." -git merge feature --no-edit 2>/dev/null || true - -echo "" -echo "==================================" -echo "Conflict playground created!" -echo "==================================" -echo "" -echo "Location: playground/" -echo "" -echo "Conflict Summary:" -echo " - Local (master): Refactored function names" -echo " - Remote (feature): Added JSON export + logging" -echo "" -echo "Test the tool with:" -echo " cd playground" -echo " python3 git_tools.py list" -echo " python3 git_tools.py extract utils.py" -echo " python3 git_tools.py verify utils.py" -echo "" -echo "Expected resolution:" -echo " - Keep new function names from Local (transform_data, sum_numbers)" -echo " - Add JSON export function from Remote" -echo " - Add logging to transform_data (but use new name)" -echo " - Keep json import from Remote" -echo "" From 9b52b295788058aea69b90de087c5a75848fa4b6 Mon Sep 17 00:00:00 2001 From: Gabriel Crisan Date: Fri, 12 Dec 2025 23:40:24 +0200 Subject: [PATCH 13/20] Update instructions.md to improve usability --- .../skill/instructions.md | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/llm-git-conflict-resolve/skill/instructions.md b/llm-git-conflict-resolve/skill/instructions.md index e288e290..f77d4c7c 100644 --- a/llm-git-conflict-resolve/skill/instructions.md +++ b/llm-git-conflict-resolve/skill/instructions.md @@ -5,15 +5,17 @@ You are an expert Git Merge Conflict Orchestrator. Your goal is to resolve compl ## I. INTERACTION & GUIDANCE PROTOCOL (CRITICAL) **1. The "Welcome" Rule:** -At the very beginning of the conversation (or if the user says "help" or "start"), you MUST display the available commands and immediately suggest the first step. - - Example: "I am ready to resolve conflicts. Type `scan` to identify conflicted files." +At the very beginning of the conversation (or if the user says "hello", "hi", "start"), you MUST: + 1. Greet the user. + 2. **Explicitly state:** "You can type `help` to list all available commands." + 3. Suggest the immediate next step: "Type `scan` to identify conflicted files." **2. The "Next Step" Rule:** You must NEVER leave the user guessing. Every single response must end with a **direct instruction** on what to type next. - **Do not use slashes (/)** in your suggested commands. - If you found conflicts -> Tell user to type: `resolve ` - If you proposed code -> Tell user to type: `apply` - - If you verified syntax -> Tell user to type: `scan` to check for more or `git add` to stage. + - If you verified syntax -> Tell user to run `git add ` manually. --- @@ -48,17 +50,21 @@ You must listen for the following keywords. Execute the action, then **Guide the ### COMMAND: apply **Triggers:** "apply", "yes", "save", "confirm" **Action:** -1. Use `run_shell_command` to overwrite the file with the resolved content. - - **Important:** Write the full content cleanly to the target file. -2. Immediately execute `python3 git_tools.py verify `. -3. Report the status ("Syntax Valid" or "Error"). +1. **Write:** Use `run_shell_command` to overwrite the file with the resolved content. +2. **Verify:** Execute `python3 git_tools.py verify `. +3. **Report:** Report the status ("Syntax Valid" or "Error"). 4. **GUIDANCE:** - - If valid: "Syntax verified. You can now run `git add ` in your terminal, or type `scan` to check for other conflicts." - - If error: "There is a syntax error. Shall I try to fix it?" + - If valid: "Syntax verified. You must now run `git add ` in your terminal to mark the conflict as resolved. Then type `scan` to check for other conflicts." + - If error: "Syntax error detected. Shall I try to fix it?" ### COMMAND: help **Triggers:** "help", "info", "commands" -**Action:** List the commands (`scan`, `resolve`, `apply`) and explain the workflow. +**Action:** +1. List the available commands: + - `scan`: Find conflicted files. + - `resolve `: Analyze and fix a specific file. + - `apply`: Save the fixed code to disk. +2. Explain the workflow: "Scan -> Resolve -> Apply -> Manually Git Add". --- From a9c713f804660a502483e72d36e72bc0377a51ab Mon Sep 17 00:00:00 2001 From: Gabriel Crisan Date: Sat, 13 Dec 2025 00:03:13 +0200 Subject: [PATCH 14/20] Update instructions.md to improve reasoning capabilities of the agent --- .../skill/instructions.md | 66 ++++++++++--------- 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/llm-git-conflict-resolve/skill/instructions.md b/llm-git-conflict-resolve/skill/instructions.md index f77d4c7c..905e4f0a 100644 --- a/llm-git-conflict-resolve/skill/instructions.md +++ b/llm-git-conflict-resolve/skill/instructions.md @@ -2,20 +2,20 @@ You are an expert Git Merge Conflict Orchestrator. Your goal is to resolve complex git merge conflicts autonomously by analyzing not just the textual diffs, but the semantic intent behind changes. -## I. INTERACTION & GUIDANCE PROTOCOL (CRITICAL) +## I. INTERACTION & GUIDANCE PROTOCOL **1. The "Welcome" Rule:** -At the very beginning of the conversation (or if the user says "hello", "hi", "start"), you MUST: +At the very beginning of the conversation (or if the user says "hello", "hi", "start" or anything similar), you should: 1. Greet the user. - 2. **Explicitly state:** "You can type `help` to list all available commands." - 3. Suggest the immediate next step: "Type `scan` to identify conflicted files." + 2. Mention that `help` lists available commands. + 3. Suggest typing `scan` to begin. **2. The "Next Step" Rule:** -You must NEVER leave the user guessing. Every single response must end with a **direct instruction** on what to type next. +Always guide the user on what to do next. Do not leave the conversation dead-ended. - **Do not use slashes (/)** in your suggested commands. - - If you found conflicts -> Tell user to type: `resolve ` - - If you proposed code -> Tell user to type: `apply` - - If you verified syntax -> Tell user to run `git add ` manually. + - After scanning -> Suggest resolving specific files. + - After resolving -> Suggest applying the changes. + - After applying -> Remind the user to manually `git add` the file. --- @@ -27,7 +27,7 @@ You must NEVER leave the user guessing. Every single response must end with a ** ## III. COMMAND WORKFLOWS -You must listen for the following keywords. Execute the action, then **Guide the User**. +You must listen for the following keywords. Execute the action, then **guide the user**. ### COMMAND: scan **Triggers:** "scan", "find conflicts", "list", "status" @@ -35,17 +35,16 @@ You must listen for the following keywords. Execute the action, then **Guide the 1. Execute: `python3 git_tools.py list` 2. Parse the JSON output. 3. Present a bulleted list of conflicted files. -4. **GUIDANCE:** End your response with: - > "To start resolving, please type: `resolve `" +4. **Guidance Example:** "To start resolving, you can type `resolve `." -### COMMAND: resolve -**Triggers:** "resolve ", "fix ", "extract " +### COMMAND: resolve +**Triggers:** "resolve", "solve", "fix", "extract" (with or without filename) **Action:** -1. Execute `python3 git_tools.py extract `. -2. Analyze the Diff + Context using the Resolution Logic (Section IV). -3. Output the fully merged code block. -4. **GUIDANCE:** End your response with: - > "Review the code above. If it looks correct, type `apply` to save it." +1. **Validation:** If the user did NOT specify a filename (e.g., just said "solve"), ask: "Which file would you like to resolve?" and STOP. +2. **Extraction:** If a filename is present, execute `python3 git_tools.py extract `. +3. Analyze the Diff + Context using the Resolution Logic (Section IV). +4. Output the fully merged code block. +5. **Guidance Example:** "Review the code above. If it looks correct, type `apply` to save it." ### COMMAND: apply **Triggers:** "apply", "yes", "save", "confirm" @@ -53,29 +52,32 @@ You must listen for the following keywords. Execute the action, then **Guide the 1. **Write:** Use `run_shell_command` to overwrite the file with the resolved content. 2. **Verify:** Execute `python3 git_tools.py verify `. 3. **Report:** Report the status ("Syntax Valid" or "Error"). -4. **GUIDANCE:** - - If valid: "Syntax verified. You must now run `git add ` in your terminal to mark the conflict as resolved. Then type `scan` to check for other conflicts." +4. **Guidance Example:** + - If valid: "Syntax verified. Please run `git add ` manually to mark it resolved, then type `scan` to check for others." - If error: "Syntax error detected. Shall I try to fix it?" ### COMMAND: help **Triggers:** "help", "info", "commands" **Action:** -1. List the available commands: - - `scan`: Find conflicted files. - - `resolve `: Analyze and fix a specific file. - - `apply`: Save the fixed code to disk. -2. Explain the workflow: "Scan -> Resolve -> Apply -> Manually Git Add". +1. List the available commands (`scan`, `resolve`, `apply`). +2. Explain the workflow briefly. --- ## IV. RESOLUTION LOGIC & STRATEGY -### 1. Intent Analysis -- **Refactor vs. Feature:** If Local is "Refactor" (renaming) and Remote is "Feature" (logic), apply Remote logic using Local names. -- **Business Logic:** If Local changes a value and Remote adds a condition, **combine both** (e.g. `if new_check and price < new_limit`). +You must use your understanding of programming logic to merge the files. Do not rely on git markers blindly. -### 2. Imports -- **Union:** Keep all unique imports. Sort alphabetically. +### 1. Semantic Intent Analysis +- Read the commit messages in the `context` object to understand *why* changes were made on each branch. +- **Structural vs. Functional:** Distinguish between changes that alter code structure (renaming, moving functions) and changes that alter behavior (new logic, new values). +- **Adaptation:** If one branch changes the structure (e.g., renames a variable) and the other modifies the logic of that same variable, you must apply the new logic to the new name. -### 3. Output -- **No Git Markers:** Final code must not contain `<<<<<<<`. \ No newline at end of file +### 2. Logic Synthesis +- **Preserve Intent:** Your goal is to produce code that satisfies the requirements of **both** branches simultaneously. +- **Additive Changes:** If both branches add new constraints or conditions to the same block of code, attempt to combine them (Logical Union) unless they are explicitly mutually exclusive. +- **Conflict Precedence:** If two branches change the exact same value to different things (e.g., a timeout setting), look for clues in the commit message (e.g., "Updated policy") to decide which value supersedes the other. + +### 3. Code Integrity +- **Imports:** Ensure the final file includes all necessary imports from both versions. +- **Syntax:** The final output must be valid code with no `<<<<<<<` markers remaining. \ No newline at end of file From deed0320462e6bd5bb03c7c6a134451be064133f Mon Sep 17 00:00:00 2001 From: Gabriel Crisan Date: Sat, 13 Dec 2025 00:11:25 +0200 Subject: [PATCH 15/20] Adjust generated folders naming --- .../generate_conflict_logic_merge.sh | 10 +++++----- .../generate_conflict_rename_vs_modify.sh | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/llm-git-conflict-resolve/generate_conflict_logic_merge.sh b/llm-git-conflict-resolve/generate_conflict_logic_merge.sh index 61c3f1c2..4d940e03 100755 --- a/llm-git-conflict-resolve/generate_conflict_logic_merge.sh +++ b/llm-git-conflict-resolve/generate_conflict_logic_merge.sh @@ -4,8 +4,8 @@ # Conflict: Price Update (Local) vs Stock Check (Remote) # 1. Create directory -mkdir -p playground-2 -cd playground-2 +mkdir -p conflict-logic-merge +cd conflict-logic-merge # 2. Initialize git quietly git init -q @@ -87,7 +87,7 @@ git commit -a -q -m "Policy Update: Increase price limit to $150" git merge feature-stock --no-edit > /dev/null 2>&1 || true echo "==================================" -echo "Playground 2 Ready (Logic Conflict)" -echo "Folder: playground-2/" -echo "To start: cd playground-2 && gemini" +echo "Conflicted Repo Ready (Logic Conflict)" +echo "Folder: conflict-logic-merge/" +echo "To start: cd conflict-logic-merge && gemini" echo "==================================" \ No newline at end of file diff --git a/llm-git-conflict-resolve/generate_conflict_rename_vs_modify.sh b/llm-git-conflict-resolve/generate_conflict_rename_vs_modify.sh index 8cb3cb5c..f7dedc85 100755 --- a/llm-git-conflict-resolve/generate_conflict_rename_vs_modify.sh +++ b/llm-git-conflict-resolve/generate_conflict_rename_vs_modify.sh @@ -3,8 +3,8 @@ # Setup script for Git merge conflict demo (Scenario: Rename vs Modify) # 1. Create directory -mkdir -p playground -cd playground +mkdir -p conflict-rename-vs-modify +cd conflict-rename-vs-modify # 2. Initialize git quietly git init -q @@ -100,7 +100,7 @@ git commit -a -q -m "Refactor: Rename functions" git merge feature --no-edit > /dev/null 2>&1 || true echo "==================================" -echo "Playground 1 Ready (Rename vs Modify)" -echo "Folder: playground/" -echo "To start: cd playground && gemini" +echo "Conflicted Repo Ready (Rename vs Modify)" +echo "Folder: conflict-rename-vs-modify/" +echo "To start: cd conflict-rename-vs-modify && gemini" echo "==================================" \ No newline at end of file From 8e57b31a5d76583d9f5ebde4a8142e5eb2c3afb9 Mon Sep 17 00:00:00 2001 From: Gabriel Crisan Date: Sat, 13 Dec 2025 00:24:32 +0200 Subject: [PATCH 16/20] Add final changes --- llm-git-conflict-resolve/generate_conflict_logic_merge.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/llm-git-conflict-resolve/generate_conflict_logic_merge.sh b/llm-git-conflict-resolve/generate_conflict_logic_merge.sh index 4d940e03..c5b08b11 100755 --- a/llm-git-conflict-resolve/generate_conflict_logic_merge.sh +++ b/llm-git-conflict-resolve/generate_conflict_logic_merge.sh @@ -52,7 +52,6 @@ def filter_products(products): """ valid_products = [] for p in products: - # Feature: Added stock check logic if p['price'] < 100 and p['in_stock'] is True: valid_products.append(p) else: @@ -75,7 +74,6 @@ def filter_products(products): """ valid_products = [] for p in products: - # Master: Updated price limit to 150 if p['price'] < 150: valid_products.append(p) return valid_products From 2a44f656a9ca490aac884ad1662dfbce03ebffaf Mon Sep 17 00:00:00 2001 From: Gabriel Crisan Date: Sat, 13 Dec 2025 00:52:29 +0200 Subject: [PATCH 17/20] Add Makefile for easy cleaning --- llm-git-conflict-resolve/Makefile | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 llm-git-conflict-resolve/Makefile diff --git a/llm-git-conflict-resolve/Makefile b/llm-git-conflict-resolve/Makefile new file mode 100644 index 00000000..fcae1cae --- /dev/null +++ b/llm-git-conflict-resolve/Makefile @@ -0,0 +1,28 @@ +SCRIPT_RENAME = generate_conflict_rename_vs_modify.sh +DIR_RENAME = conflict-rename-vs-modify + +SCRIPT_LOGIC = generate_conflict_logic_merge.sh +DIR_LOGIC = conflict-logic-merge + +.PHONY: all help rename logic clean + +all: help + +help: + @echo "Available targets:" + @echo " make rename - Generate Rename vs Modify conflicted repo" + @echo " make logic - Generate Logic Merge conflicted repo" + @echo " make clean - Remove generated directories" + +rename: + @rm -rf $(DIR_RENAME) + @chmod +x $(SCRIPT_RENAME) + @./$(SCRIPT_RENAME) + +logic: + @rm -rf $(DIR_LOGIC) + @chmod +x $(SCRIPT_LOGIC) + @./$(SCRIPT_LOGIC) + +clean: + @rm -rf $(DIR_RENAME) $(DIR_LOGIC) \ No newline at end of file From 10c827a91605877fe67b0810b69901f6acd6aecc Mon Sep 17 00:00:00 2001 From: Gabriel Crisan Date: Sat, 13 Dec 2025 01:12:21 +0200 Subject: [PATCH 18/20] Add README documenting git merge conflict resolution skill --- llm-git-conflict-resolve/skill/README.md | 196 +++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 llm-git-conflict-resolve/skill/README.md diff --git a/llm-git-conflict-resolve/skill/README.md b/llm-git-conflict-resolve/skill/README.md new file mode 100644 index 00000000..d37c58ab --- /dev/null +++ b/llm-git-conflict-resolve/skill/README.md @@ -0,0 +1,196 @@ +# Git Merge Conflict Resolution Skill + +An intelligent AI-powered tool that resolves complex git merge conflicts by understanding the semantic intent behind code changes, not just the textual differences. + +## What This Skill Does + +This skill acts as an **expert Git Merge Conflict Orchestrator** that: + +- **Automatically detects** merge conflicts in your repository +- **Analyzes semantic intent** by examining commit messages and code changes +- **Intelligently merges** conflicting changes by understanding what each branch was trying to accomplish +- **Verifies syntax** of resolved files to ensure code validity +- **Guides you step-by-step** through the entire conflict resolution process + +Unlike traditional merge tools that only show you textual differences, this skill understands programming logic and can synthesize changes from both branches to produce code that satisfies both sets of requirements. + +## How It Works + +### The Intelligence Behind Resolution + +1. **Three-Way Diff Analysis**: Extracts the base (common ancestor), local (your changes), and remote (incoming changes) versions of each conflicted file + +2. **Semantic Intent Detection**: Reads commit messages to understand *why* changes were made on each branch, not just *what* changed + +3. **Logic Synthesis**: Intelligently combines changes by: + - Distinguishing structural changes (renaming, refactoring) from functional changes (new logic, behavior) + - Adapting one branch's logic to another branch's structural changes + - Combining additive changes when both branches add new constraints + - Choosing between conflicting values based on commit context + +4. **Code Integrity Validation**: Ensures the final output is syntactically valid and includes all necessary imports + +## How to Use This Skill + +### Prerequisites + +- You must be in a git repository with active merge conflicts +- Python 3 must be available on your system +- The `git_tools.py` script must be present in your working directory + +### Basic Workflow + +**1. Start the conversation** +``` +Hello +``` +The AI will greet you and suggest typing `scan` to begin. + +**2. Scan for conflicts** +``` +scan +``` +This lists all files with merge conflicts. + +**3. Resolve a specific file** +``` +resolve filename.py +``` +The AI will analyze the conflict and present a fully merged version of the file. + +**4. Apply the resolution** +``` +apply +``` +This writes the resolved content to disk and verifies syntax. + +**5. Mark as resolved in git** +```bash +git add filename.py +``` +You must manually run this command to tell git the conflict is resolved. + +**6. Continue with remaining conflicts** +``` +scan +``` +Repeat the process for other conflicted files. + +### Available Commands + +| Command | Aliases | Description | +|---------|---------|-------------| +| `scan` | find conflicts, list, status | Lists all files with merge conflicts | +| `resolve ` | solve, fix, extract | Analyzes and resolves conflicts in the specified file | +| `apply` | yes, save, confirm | Saves the resolved content and verifies syntax | +| `help` | info, commands | Shows available commands and workflow | + +### Example Session + +``` +User: hi +AI: Hello! Welcome to the Git Merge Conflict Resolver. Type 'help' to see available + commands, or type 'scan' to begin analyzing conflicts. + +User: scan +AI: Found 2 conflicted files: + • src/app.py (UU) + • config/settings.py (UU) + + To start resolving, type: resolve src/app.py + +User: resolve src/app.py +AI: [Analyzes the file and presents merged code] + + Review the code above. If it looks correct, type 'apply' to save it. + +User: apply +AI: ✓ File written successfully + ✓ Syntax verified: Python syntax check passed + + Please run `git add src/app.py` manually to mark it resolved, then type 'scan' to check for remaining conflicts. +``` + +## Resolution Strategies + +The AI uses several intelligent strategies to resolve conflicts: + +### 1. Structural vs. Functional Changes +- **Structural**: Renaming variables, moving functions, reformatting +- **Functional**: New logic, different values, behavior changes + +If one branch renames a variable and another modifies its logic, the AI applies the logic to the new name. + +### 2. Additive Merging +When both branches add new functionality (new imports, new conditions, new checks), the AI combines them unless they're mutually exclusive. + +### 3. Conflict Precedence +For direct conflicts (same value changed to different things), the AI examines commit messages to determine which change reflects the more recent policy or intent. + +### 4. Import Consolidation +Ensures all necessary imports from both versions are included in the final file. + +## Limitations + +### Current Constraints + +1. **Language Support**: Syntax verification currently only works for **Python files**. Other languages are assumed valid. + +2. **Manual Git Operations**: You must still manually run `git add ` after applying changes. + +3. **Complex Business Logic**: The AI makes its best judgment based on code structure and commit messages, but cannot understand complex business requirements or domain-specific rules. + +4. **Binary Files**: Cannot resolve conflicts in binary files (images, compiled code, etc.). + +5. **Requires Context**: Works best when commit messages are descriptive. Poor commit messages ("fixed stuff", "updates") reduce resolution accuracy. + +### When Human Review is Essential + +- **Security-sensitive code**: Always review changes to authentication, authorization, or cryptographic code +- **Database migrations**: Schema changes require careful human oversight +- **API contracts**: Changes to public APIs need manual verification +- **Configuration values**: Production settings should be manually confirmed + +## Best Practices + +### For Optimal Results + +1. **Write descriptive commit messages**: Clear messages help the AI understand intent + - Poor example: "updates" + - Good example: "Refactored authentication to use JWT tokens" + +2. **Review before applying**: Always review the proposed resolution before typing `apply` + +3. **Test after resolution**: Run your test suite after resolving conflicts + +4. **Resolve one file at a time**: Don't rush through multiple files without verification + +5. **Keep git_tools.py accessible**: Ensure the script is in your working directory + +### Troubleshooting + +**"File not found" error**: Make sure you're in the git repository root + +**"No conflicts found"**: Run `git status` to verify you're in a merge state + +**Syntax errors after resolution**: The AI will detect these and offer to fix them, or you can manually edit the file + +**Unexpected resolution**: Provide feedback and manually adjust the code. The AI learns from descriptive commit messages. + +## Getting Help + +- Type `help` at any time to see available commands +- The AI will always guide you on the next step +- If stuck, start over with `scan` to see the current state + +## Contributing + +This skill improves with better commit message analysis and expanded language support. Future enhancements may include: +- JavaScript/TypeScript syntax verification +- Automatic git add after successful resolution +- Interactive conflict resolution for ambiguous cases +- Machine learning from user feedback on resolutions + +--- + +**Remember**: This tool is designed to assist, not replace human judgment. Always review critical changes, especially in production code. \ No newline at end of file From 97db58239bbb22891b2dad70c1fbb76e8ab47763 Mon Sep 17 00:00:00 2001 From: bullet Date: Sat, 13 Dec 2025 13:15:59 +0200 Subject: [PATCH 19/20] added: implementation for multiple Language suported for the skill advanced multi-language syntax validation covering: Python (.py) - Full AST validation JavaScript/TypeScript (.js, .jsx, .ts, .tsx) - Node.js and tsc validation JSON (.json) - Native parser validation Go (.go) - Go compiler validation Rust (.rs) - Rustc validation Generic (all others) - Basic readability checks Signed-off-by: bullet --- multyLanguageImplementation/get_tools.py | 139 ++++++ .../syntax_validators.py | 467 ++++++++++++++++++ 2 files changed, 606 insertions(+) create mode 100644 multyLanguageImplementation/get_tools.py create mode 100644 multyLanguageImplementation/syntax_validators.py diff --git a/multyLanguageImplementation/get_tools.py b/multyLanguageImplementation/get_tools.py new file mode 100644 index 00000000..4bffb28f --- /dev/null +++ b/multyLanguageImplementation/get_tools.py @@ -0,0 +1,139 @@ +import sys +import argparse +import subprocess +import json +import os + +# Import the new multi-language syntax validator +from syntax_validators import verify_syntax as validate_syntax_multi_lang + +def run_git_command(command): + """Executes a git command and returns the output as a string.""" + try: + result = subprocess.check_output( + command, + stderr=subprocess.STDOUT, + shell=True + ) + return result.decode('utf-8').strip() + except subprocess.CalledProcessError as e: + # Return None to signal that, for example, the file does not exist in that version + return None + +def list_conflicted_files(): + """Identifies files marked as conflicted.""" + # --porcelain provides a stable format for parsing + output = run_git_command("git status --porcelain") + if not output: + return [] + + conflicted_files = [] + for line in output.split('\n'): + # Conflicts are usually marked with 'UU', 'AA', 'UD', etc. + # The first 2 characters indicate the status + status = line[:2] + filepath = line[3:].strip() + + # Simplified filter: if both sides modified (U) or added (A) + if 'U' in status or 'A' in status: + conflicted_files.append({ + "filepath": filepath, + "status": status + }) + + return conflicted_files + +def get_file_content_at_stage(filepath, stage): + """ + Extracts file content at a specific git stage. + Stage 1 = Base (Ancestor) + Stage 2 = Ours (Local/HEAD) + Stage 3 = Theirs (Remote/MERGE_HEAD) + """ + # git show :: + content = run_git_command(f"git show :{stage}:{filepath}") + return content if content is not None else "" + +def get_commit_context(filepath): + """ + Extracts commit messages to understand semantic intent (Solution 3). + """ + # HEAD is the current branch (Local) + local_msg = run_git_command(f"git log -1 --pretty=%B HEAD -- {filepath}") + + # MERGE_HEAD is the incoming branch (Remote). + # It might be null if we are not in a standard merge, but we handle the case. + remote_msg = run_git_command(f"git log -1 --pretty=%B MERGE_HEAD -- {filepath}") + + return { + "local_intent": local_msg.strip() if local_msg else "Unknown (Manual changes or no commit msg)", + "remote_intent": remote_msg.strip() if remote_msg else "Unknown (No MERGE_HEAD found)" + } + +def verify_syntax(filepath): + """ + Verifies file syntax using the multi-language validator. + Now supports: Python, JavaScript, TypeScript, JSON, Go, Rust, and more. + + Falls back to basic file readability check for unsupported types. + """ + if not os.path.exists(filepath): + return {"status": "error", "message": "File not found"} + + # Delegate to the multi-language validator + return validate_syntax_multi_lang(filepath) + +def main(): + parser = argparse.ArgumentParser(description="Git Merge Conflict Tool for AI Agents") + subparsers = parser.add_subparsers(dest="command", help="Available commands") + + # --- Command: list --- + subparsers.add_parser("list", help="List conflicted files") + + # --- Command: extract --- + extract_parser = subparsers.add_parser("extract", help="Extract content and context") + extract_parser.add_argument("filepath", type=str, help="Path to the conflicted file") + + # --- Command: verify --- + verify_parser = subparsers.add_parser("verify", help="Verify syntax") + verify_parser.add_argument("filepath", type=str, help="Path to the file to verify") + + args = parser.parse_args() + + # Command routing + if args.command == "list": + result = list_conflicted_files() + print(json.dumps(result, indent=2)) + + elif args.command == "extract": + filepath = args.filepath + + # 1. Extract Diff (Code) + diff_data = { + "base": get_file_content_at_stage(filepath, 1), + "local": get_file_content_at_stage(filepath, 2), + "remote": get_file_content_at_stage(filepath, 3) + } + + # 2. Extract Context (Intent) + context_data = get_commit_context(filepath) + + # 3. Build the complete payload + full_payload = { + "file": filepath, + "diff": diff_data, + "context": context_data, + "note": "Use 'context' to determine intent, then merge 'diff' accordingly." + } + print(json.dumps(full_payload, indent=2)) + + elif args.command == "verify": + result = verify_syntax(args.filepath) + print(json.dumps(result, indent=2)) + + else: + # If no command is provided + parser.print_help() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/multyLanguageImplementation/syntax_validators.py b/multyLanguageImplementation/syntax_validators.py new file mode 100644 index 00000000..078fe181 --- /dev/null +++ b/multyLanguageImplementation/syntax_validators.py @@ -0,0 +1,467 @@ +""" +Multi-language syntax validation module for git merge conflict resolution. +This module provides syntax checking for various programming languages without +requiring external dependencies beyond standard library where possible. +""" + +import os +import ast +import json +import subprocess +import tempfile +from typing import Dict, Optional + + +class SyntaxValidator: + """Base class for language-specific syntax validators.""" + + def __init__(self): + self.supported_extensions = [] + + def validate(self, filepath: str) -> Dict[str, str]: + """ + Validates syntax of a file. + + Returns: + Dict with keys: 'status' ('valid' or 'error'), 'message', 'details' (optional) + """ + raise NotImplementedError("Subclasses must implement validate()") + + +class PythonValidator(SyntaxValidator): + """Validates Python syntax using AST.""" + + def __init__(self): + super().__init__() + self.supported_extensions = ['.py'] + + def validate(self, filepath: str) -> Dict[str, str]: + try: + with open(filepath, 'r', encoding='utf-8') as f: + source = f.read() + ast.parse(source) + return { + "status": "valid", + "message": "Python syntax check passed.", + "language": "python" + } + except SyntaxError as e: + return { + "status": "error", + "message": f"Syntax Error on line {e.lineno}: {e.msg}", + "details": str(e), + "language": "python" + } + except Exception as e: + return { + "status": "error", + "message": f"Unexpected error: {str(e)}", + "language": "python" + } + + +class JavaScriptValidator(SyntaxValidator): + """Validates JavaScript/TypeScript syntax using Node.js.""" + + def __init__(self): + super().__init__() + self.supported_extensions = ['.js', '.jsx', '.mjs'] + self.has_node = self._check_node_available() + + def _check_node_available(self) -> bool: + """Check if Node.js is installed.""" + try: + subprocess.run(['node', '--version'], + capture_output=True, + check=True, + timeout=2) + return True + except (subprocess.CalledProcessError, FileNotFoundError, subprocess.TimeoutExpired): + return False + + def validate(self, filepath: str) -> Dict[str, str]: + if not self.has_node: + return { + "status": "skipped", + "message": "Node.js not found. Install Node.js for JavaScript validation.", + "language": "javascript" + } + + try: + # Use node --check for syntax validation + result = subprocess.run( + ['node', '--check', filepath], + capture_output=True, + text=True, + timeout=5 + ) + + if result.returncode == 0: + return { + "status": "valid", + "message": "JavaScript syntax check passed.", + "language": "javascript" + } + else: + return { + "status": "error", + "message": "JavaScript syntax error detected.", + "details": result.stderr, + "language": "javascript" + } + except subprocess.TimeoutExpired: + return { + "status": "error", + "message": "Syntax check timed out.", + "language": "javascript" + } + except Exception as e: + return { + "status": "error", + "message": f"Validation failed: {str(e)}", + "language": "javascript" + } + + +class TypeScriptValidator(SyntaxValidator): + """Validates TypeScript syntax using tsc.""" + + def __init__(self): + super().__init__() + self.supported_extensions = ['.ts', '.tsx'] + self.has_tsc = self._check_tsc_available() + + def _check_tsc_available(self) -> bool: + """Check if TypeScript compiler is installed.""" + try: + subprocess.run(['tsc', '--version'], + capture_output=True, + check=True, + timeout=2) + return True + except (subprocess.CalledProcessError, FileNotFoundError, subprocess.TimeoutExpired): + return False + + def validate(self, filepath: str) -> Dict[str, str]: + if not self.has_tsc: + return { + "status": "skipped", + "message": "TypeScript compiler (tsc) not found. Install with: npm install -g typescript", + "language": "typescript" + } + + try: + # Use tsc --noEmit for syntax check without generating output + result = subprocess.run( + ['tsc', '--noEmit', '--skipLibCheck', filepath], + capture_output=True, + text=True, + timeout=10 + ) + + if result.returncode == 0: + return { + "status": "valid", + "message": "TypeScript syntax check passed.", + "language": "typescript" + } + else: + return { + "status": "error", + "message": "TypeScript syntax error detected.", + "details": result.stderr, + "language": "typescript" + } + except subprocess.TimeoutExpired: + return { + "status": "error", + "message": "Syntax check timed out.", + "language": "typescript" + } + except Exception as e: + return { + "status": "error", + "message": f"Validation failed: {str(e)}", + "language": "typescript" + } + + +class JSONValidator(SyntaxValidator): + """Validates JSON syntax.""" + + def __init__(self): + super().__init__() + self.supported_extensions = ['.json'] + + def validate(self, filepath: str) -> Dict[str, str]: + try: + with open(filepath, 'r', encoding='utf-8') as f: + json.load(f) + return { + "status": "valid", + "message": "JSON syntax check passed.", + "language": "json" + } + except json.JSONDecodeError as e: + return { + "status": "error", + "message": f"JSON Error on line {e.lineno}, column {e.colno}: {e.msg}", + "details": str(e), + "language": "json" + } + except Exception as e: + return { + "status": "error", + "message": f"Unexpected error: {str(e)}", + "language": "json" + } + + +class GoValidator(SyntaxValidator): + """Validates Go syntax using go fmt.""" + + def __init__(self): + super().__init__() + self.supported_extensions = ['.go'] + self.has_go = self._check_go_available() + + def _check_go_available(self) -> bool: + """Check if Go is installed.""" + try: + subprocess.run(['go', 'version'], + capture_output=True, + check=True, + timeout=2) + return True + except (subprocess.CalledProcessError, FileNotFoundError, subprocess.TimeoutExpired): + return False + + def validate(self, filepath: str) -> Dict[str, str]: + if not self.has_go: + return { + "status": "skipped", + "message": "Go compiler not found. Install Go for validation.", + "language": "go" + } + + try: + # Use go fmt to check syntax + result = subprocess.run( + ['go', 'fmt', filepath], + capture_output=True, + text=True, + timeout=5 + ) + + # go fmt returns non-zero on syntax errors + if "syntax error" in result.stderr.lower(): + return { + "status": "error", + "message": "Go syntax error detected.", + "details": result.stderr, + "language": "go" + } + + return { + "status": "valid", + "message": "Go syntax check passed.", + "language": "go" + } + except subprocess.TimeoutExpired: + return { + "status": "error", + "message": "Syntax check timed out.", + "language": "go" + } + except Exception as e: + return { + "status": "error", + "message": f"Validation failed: {str(e)}", + "language": "go" + } + + +class RustValidator(SyntaxValidator): + """Validates Rust syntax using rustc.""" + + def __init__(self): + super().__init__() + self.supported_extensions = ['.rs'] + self.has_rustc = self._check_rustc_available() + + def _check_rustc_available(self) -> bool: + """Check if Rust compiler is installed.""" + try: + subprocess.run(['rustc', '--version'], + capture_output=True, + check=True, + timeout=2) + return True + except (subprocess.CalledProcessError, FileNotFoundError, subprocess.TimeoutExpired): + return False + + def validate(self, filepath: str) -> Dict[str, str]: + if not self.has_rustc: + return { + "status": "skipped", + "message": "Rust compiler (rustc) not found. Install Rust for validation.", + "language": "rust" + } + + try: + # Use rustc with --crate-type lib and output to temp dir + with tempfile.TemporaryDirectory() as tmpdir: + result = subprocess.run( + ['rustc', '--crate-type', 'lib', '--out-dir', tmpdir, filepath], + capture_output=True, + text=True, + timeout=10 + ) + + if result.returncode == 0: + return { + "status": "valid", + "message": "Rust syntax check passed.", + "language": "rust" + } + else: + return { + "status": "error", + "message": "Rust syntax error detected.", + "details": result.stderr, + "language": "rust" + } + except subprocess.TimeoutExpired: + return { + "status": "error", + "message": "Syntax check timed out.", + "language": "rust" + } + except Exception as e: + return { + "status": "error", + "message": f"Validation failed: {str(e)}", + "language": "rust" + } + + +class GenericValidator(SyntaxValidator): + """Fallback validator for unsupported file types.""" + + def __init__(self): + super().__init__() + self.supported_extensions = [] # Matches any extension + + def validate(self, filepath: str) -> Dict[str, str]: + _, ext = os.path.splitext(filepath) + + # Check if file exists and is readable + if not os.path.exists(filepath): + return { + "status": "error", + "message": "File not found", + "language": "unknown" + } + + try: + with open(filepath, 'r', encoding='utf-8') as f: + f.read() + return { + "status": "valid", + "message": f"No linter configured for {ext}. Basic readability check passed.", + "language": "unknown" + } + except UnicodeDecodeError: + return { + "status": "warning", + "message": f"File appears to be binary ({ext}). Skipping syntax check.", + "language": "binary" + } + except Exception as e: + return { + "status": "error", + "message": f"File read error: {str(e)}", + "language": "unknown" + } + + +class ValidatorRegistry: + """Registry that maps file extensions to appropriate validators.""" + + def __init__(self): + self.validators = [ + PythonValidator(), + JavaScriptValidator(), + TypeScriptValidator(), + JSONValidator(), + GoValidator(), + RustValidator(), + ] + self.generic_validator = GenericValidator() + + # Build extension map + self.extension_map = {} + for validator in self.validators: + for ext in validator.supported_extensions: + self.extension_map[ext] = validator + + def get_validator(self, filepath: str) -> SyntaxValidator: + """Returns the appropriate validator for a given file.""" + _, ext = os.path.splitext(filepath) + return self.extension_map.get(ext, self.generic_validator) + + def validate_file(self, filepath: str) -> Dict[str, str]: + """Validates a file using the appropriate validator.""" + validator = self.get_validator(filepath) + return validator.validate(filepath) + + def list_supported_languages(self) -> list: + """Returns list of supported languages with their extensions.""" + languages = [] + for validator in self.validators: + if validator.supported_extensions: + lang = validator.validate("") # Get language name + languages.append({ + "language": lang.get("language", "unknown"), + "extensions": validator.supported_extensions + }) + return languages + + +# Singleton instance +_registry = ValidatorRegistry() + + +def verify_syntax(filepath: str) -> Dict[str, str]: + """ + Main entry point for syntax verification. + This function should be called from get_tools.py + + Args: + filepath: Path to the file to verify + + Returns: + Dictionary with validation results + """ + return _registry.validate_file(filepath) + + +def list_supported_languages() -> list: + """Returns list of all supported languages.""" + return _registry.list_supported_languages() + + +if __name__ == "__main__": + # CLI for testing + import sys + + if len(sys.argv) < 2: + print("Usage: python syntax_validators.py ") + print("\nSupported languages:") + for lang_info in list_supported_languages(): + print(f" {lang_info['language']}: {', '.join(lang_info['extensions'])}") + sys.exit(1) + + filepath = sys.argv[1] + result = verify_syntax(filepath) + print(json.dumps(result, indent=2)) \ No newline at end of file From e893b35063127f21d8915822050f6035e52b9a4b Mon Sep 17 00:00:00 2001 From: bullet Date: Sat, 13 Dec 2025 13:47:31 +0200 Subject: [PATCH 20/20] added: documentation for multiple language suport Signed-off-by: bullet --- .../CONFLICT_TYPES.md | 478 ++++++++++++++++++ .../LANGUAGE_SUPPORT.md | 296 +++++++++++ 2 files changed, 774 insertions(+) create mode 100644 documentationMultipleLanguageSuport/CONFLICT_TYPES.md create mode 100644 documentationMultipleLanguageSuport/LANGUAGE_SUPPORT.md diff --git a/documentationMultipleLanguageSuport/CONFLICT_TYPES.md b/documentationMultipleLanguageSuport/CONFLICT_TYPES.md new file mode 100644 index 00000000..4257d4d4 --- /dev/null +++ b/documentationMultipleLanguageSuport/CONFLICT_TYPES.md @@ -0,0 +1,478 @@ +# Git Merge Conflict Types - Multi-Language Reference + +This document categorizes common types of merge conflicts across different programming languages and provides resolution strategies for AI agents. + +--- + +## Conflict Classification System + +Each conflict is assigned a **difficulty score (1-5)** that determines whether the agent should: +- **1-2 (Trivial):** Auto-resolve without user input +- **3 (Moderate):** Auto-resolve with confidence indicators +- **4 (Complex):** Present options to user +- **5 (Critical):** Always require user decision + +--- + +## Language-Agnostic Conflicts + +These patterns appear across all languages: + +### 1. Whitespace Conflicts (Difficulty: 1) + +**Description:** Differences only in spaces, tabs, or newlines. + +**Example:** +```python +<<<<<<< HEAD +def hello(): + print("world") +======= +def hello(): + print("world") # Tab instead of spaces +>>>>>>> branch +``` + +**Resolution Strategy:** +- Normalize to project style (detect from `.editorconfig` or majority usage) +- If Python: always use spaces (PEP 8) +- If Go: always use tabs + +**Auto-Resolve:** Yes + +--- + +### 2. Comment Conflicts (Difficulty: 1) + +**Description:** Only comments differ between versions. + +**Example:** +```javascript +<<<<<<< HEAD +// TODO: Refactor this function +======= +// FIXME: This needs optimization +>>>>>>> branch +function process() { ... } +``` + +**Resolution Strategy:** +- Merge both comments if they convey different information +- If duplicate meaning, keep the more actionable one + +**Auto-Resolve:** Yes + +--- + +### 3. Import/Dependency Conflicts (Difficulty: 2) + +**Description:** Different imports or dependencies added on each branch. + +**Python Example:** +```python +<<<<<<< HEAD +import os +import sys +======= +import os +import json +>>>>>>> branch +``` + +**JavaScript Example:** +```javascript +<<<<<<< HEAD +import { useState } from 'react'; +import axios from 'axios'; +======= +import { useState } from 'react'; +import fetch from 'node-fetch'; +>>>>>>> branch +``` + +**Resolution Strategy:** +- **Union merge:** Include all unique imports +- Sort imports alphabetically (language convention) +- Remove duplicates +- Verify all imports are actually used in the resolved code + +**Auto-Resolve:** Yes (with verification) + +--- + +### 4. Variable/Function Renaming (Difficulty: 3) + +**Description:** One branch renames an identifier, the other modifies its usage. + +**Example:** +```python +<<<<<<< HEAD +def calculate_total(items): + return sum(items) +======= +def compute_sum(items): + return sum(items) +>>>>>>> branch + +# Elsewhere in the file: +result = calculate_total([1, 2, 3]) # Which name to use? +``` + +**Resolution Strategy:** +1. Detect rename pattern (same logic, different name) +2. Choose the new name from the branch that renamed +3. **Update all references** throughout the file +4. Verify no undefined references remain + +**Auto-Resolve:** ⚠️ Conditional (if confident about rename scope) + +--- + +### 5. Configuration Value Changes (Difficulty: 3) + +**Description:** Both branches change the same config value. + +**JSON Example:** +```json +{ +<<<<<<< HEAD + "timeout": 5000 +======= + "timeout": 10000 +>>>>>>> branch +} +``` + +**YAML Example:** +```yaml +<<<<<<< HEAD +max_connections: 100 +======= +max_connections: 200 +>>>>>>> branch +``` + +**Resolution Strategy:** +- Check commit messages for rationale +- If one is a "hotfix" or "critical", prefer that value +- Otherwise, ask user which value to keep +- Suggest creating an environment variable instead + +**Auto-Resolve:** ❌ No (user decision needed) + +--- + +## Language-Specific Conflicts + +### Python + +#### Type Hints Conflict (Difficulty: 2) +```python +<<<<<<< HEAD +def process(data: dict) -> list: +======= +def process(data: Dict[str, Any]) -> List[str]: +>>>>>>> branch +``` + +**Resolution:** Prefer the more specific type hint (branch version). + +#### Docstring Conflict (Difficulty: 2) +```python +<<<<<<< HEAD +"""Process data and return results.""" +======= +""" +Process data with validation. + +Args: + data: Input dictionary + +Returns: + List of processed items +""" +>>>>>>> branch +``` + +**Resolution:** Keep the more detailed docstring. + +--- + +### JavaScript/TypeScript + +#### TypeScript Interface Conflict (Difficulty: 3) +```typescript +<<<<<<< HEAD +interface User { + name: string; + email: string; +} +======= +interface User { + name: string; + email: string; + age?: number; +} +>>>>>>> branch +``` + +**Resolution:** Union merge (keep all properties). Mark new fields as optional. + +#### React Component Props Conflict (Difficulty: 4) +```tsx +<<<<<<< HEAD +function Button({ onClick }: { onClick: () => void }) { +======= +function Button({ onClick, disabled }: { onClick: () => void; disabled?: boolean }) { +>>>>>>> branch +``` + +**Resolution:** Union merge props, ensure new props have defaults. + +--- + +### Go + +#### Error Handling Pattern Conflict (Difficulty: 3) +```go +<<<<<<< HEAD +if err != nil { + return err +} +======= +if err != nil { + return fmt.Errorf("failed to connect: %w", err) +} +>>>>>>> branch +``` + +**Resolution:** Prefer wrapped errors (better debugging). + +--- + +### Rust + +#### Ownership/Borrow Conflict (Difficulty: 5) +```rust +<<<<<<< HEAD +fn process(data: Vec) -> usize { + data.len() +} +======= +fn process(data: &Vec) -> usize { + data.len() +} +>>>>>>> branch +``` + +**Resolution:** This requires semantic analysis. Prefer `&Vec` (borrowing) unless ownership transfer is needed. **Must verify borrow checker passes.** + +--- + +## Logic Conflicts (All Languages) + +### 6. Conditional Logic Merge (Difficulty: 4) + +**Description:** Both branches add different conditions to the same block. + +**Python Example:** +```python +<<<<<<< HEAD +if user.is_authenticated and user.has_permission: + allow_access() +======= +if user.is_authenticated and not user.is_banned: + allow_access() +>>>>>>> branch +``` + +**Resolution Strategy:** +- **Additive approach:** Combine conditions with `and` +- Result: `if user.is_authenticated and user.has_permission and not user.is_banned:` +- Verify logical consistency (no contradictions) + +**Auto-Resolve:** ⚠️ Conditional (if intents align) + +--- + +### 7. Algorithm Change Conflict (Difficulty: 5) + +**Description:** Both branches implement different algorithms for the same function. + +**Example:** +```python +<<<<<<< HEAD +def sort_items(items): + return sorted(items) # Quick sort +======= +def sort_items(items): + # Bubble sort for stability + for i in range(len(items)): + for j in range(len(items)-i-1): + if items[j] > items[j+1]: + items[j], items[j+1] = items[j+1], items[j] + return items +>>>>>>> branch +``` + +**Resolution Strategy:** +- **Cannot auto-merge** - fundamentally different approaches +- Present both implementations to user +- Suggest keeping both as separate functions (e.g., `sort_items_fast` vs `sort_items_stable`) + +**Auto-Resolve:** ❌ Never + +--- + +## Detection Patterns (For Agent Implementation) + +The agent should detect conflict types using these heuristics: + +### Whitespace Detection +```python +def is_whitespace_conflict(local, remote): + return local.strip() == remote.strip() +``` + +### Import Detection +```python +def is_import_conflict(local, remote, language): + patterns = { + 'python': r'^import |^from .* import', + 'javascript': r'^import .* from|^const .* = require', + 'go': r'^import \(', + } + local_is_import = re.match(patterns[language], local) + remote_is_import = re.match(patterns[language], remote) + return local_is_import and remote_is_import +``` + +### Rename Detection +```python +def is_rename_conflict(local, remote): + # Check if structure is identical except for one identifier + local_tokens = tokenize(local) + remote_tokens = tokenize(remote) + + if len(local_tokens) != len(remote_tokens): + return False + + differences = sum(1 for l, r in zip(local_tokens, remote_tokens) if l != r) + return differences == 1 # Only one token differs +``` + +--- + +## Resolution Priority Rules + +When multiple conflicts exist in a file, resolve in this order: + +1. **Whitespace conflicts** (trivial) +2. **Comment conflicts** (trivial) +3. **Import conflicts** (can affect later resolutions) +4. **Rename conflicts** (affects variable references) +5. **Logic conflicts** (most complex) + +--- + +## Agent Decision Tree + +``` +Is conflict whitespace-only? +├─ YES → Auto-normalize and resolve +└─ NO + │ + Are both sides adding new imports? + ├─ YES → Union merge imports + └─ NO + │ + Is it a rename + modification? + ├─ YES → Apply rename everywhere + └─ NO + │ + Are commit messages clear? + ├─ YES → Follow semantic intent + └─ NO → Present options to user +``` + +--- + +## Language-Specific Import Sorting + +### Python (PEP 8 Order) +1. Standard library imports +2. Related third-party imports +3. Local application imports + +```python +import os +import sys + +import numpy as np +import pandas as pd + +from .models import User +``` + +### JavaScript/TypeScript +1. External packages +2. Internal packages +3. Relative imports + +```javascript +import React from 'react'; +import axios from 'axios'; + +import { API_URL } from '@/config'; + +import './styles.css'; +``` + +### Go +- Group standard library, then external packages +- Use `goimports` tool for automatic sorting + +--- + +## Testing Conflict Resolution + +Create test scenarios for each conflict type: + +```bash +# Setup test repo +git init test-conflicts +cd test-conflicts + +# Create conflicting branches +git checkout -b feature-a +echo "version A" > file.txt +git commit -am "Change A" + +git checkout main +echo "version B" > file.txt +git commit -am "Change B" + +# Attempt merge +git merge feature-a # Creates conflict + +# Test agent resolution +python get_tools.py extract file.txt +# Agent analyzes and resolves... +``` + +--- + +## Future Enhancements + +1. **Machine Learning Model:** Train on resolved conflicts to predict resolution strategy +2. **AST-Level Merging:** Parse code into AST, merge at semantic level +3. **Test-Driven Resolution:** Run tests for each resolution candidate +4. **Cross-Reference Detection:** Identify when changes in one file affect imports in another + +--- + +## References + +- [Google Sheet - Conflict Types](https://docs.google.com/spreadsheets/d/1cT7eUNmxuOgy26hpWKud_L2dnhitMGqS2d6XJF2SJ4A/) +- Git Documentation: [How Conflicts Are Presented](https://git-scm.com/docs/git-merge#_how_conflicts_are_presented) +- [Semantic Merge Paper (2011)](https://www.semanticmerge.com/) \ No newline at end of file diff --git a/documentationMultipleLanguageSuport/LANGUAGE_SUPPORT.md b/documentationMultipleLanguageSuport/LANGUAGE_SUPPORT.md new file mode 100644 index 00000000..9e25dcca --- /dev/null +++ b/documentationMultipleLanguageSuport/LANGUAGE_SUPPORT.md @@ -0,0 +1,296 @@ +# Multi-Language Syntax Validation Support + +This document describes the syntax validation capabilities of the Git Merge Conflict Resolution skill across different programming languages. + +## Currently Supported Languages + +### Python (.py) + +- **Validator:** Built-in AST parser +- **Requirements:** None (Python standard library) +- **Validation Method:** `ast.parse()` +- **Coverage:** Full syntax validation including indentation errors + +### JavaScript (.js, .jsx, .mjs) + +- **Validator:** Node.js +- **Requirements:** `node` must be installed +- **Validation Method:** `node --check` +- **Coverage:** ECMAScript syntax validation +- **Install:** [Download Node.js](https://nodejs.org/) + +### TypeScript (.ts, .tsx) + +- **Validator:** TypeScript Compiler +- **Requirements:** `tsc` must be installed globally +- **Validation Method:** `tsc --noEmit --skipLibCheck` +- **Coverage:** Full TypeScript type checking +- **Install:** `npm install -g typescript` + +### JSON (.json) + +- **Validator:** Built-in JSON parser +- **Requirements:** None (Python standard library) +- **Validation Method:** `json.load()` +- **Coverage:** JSON syntax and structure validation + +### Go (.go) + +- **Validator:** Go compiler +- **Requirements:** `go` must be installed +- **Validation Method:** `go fmt` +- **Coverage:** Go syntax validation +- **Install:** [Download Go](https://golang.org/dl/) + +### Rust (.rs) + +- **Validator:** Rust compiler +- **Requirements:** `rustc` must be installed +- **Validation Method:** `rustc --crate-type lib` +- **Coverage:** Full Rust syntax and borrow checker +- **Install:** [Install Rust](https://rustup.rs/) + +### Generic Fallback (All Other Files) + +- **Validator:** Basic file readability check +- **Requirements:** None +- **Coverage:** Checks if file exists and is readable as UTF-8 text +- **Limitation:** Does NOT validate actual syntax + +--- + +## Validation Status Messages + +The validator returns a JSON object with the following fields: + +```json +{ + "status": "valid" | "error" | "warning" | "skipped", + "message": "Human-readable status message", + "details": "Detailed error information (if applicable)", + "language": "python" | "javascript" | "typescript" | ... +} +``` + +### Status Types + +| Status | Meaning | +| --------- | ---------------------------------------------------- | +| `valid` | File syntax is correct | +| `error` | Syntax error detected | +| `warning` | File validated but with caveats (e.g., binary files) | +| `skipped` | Required tool not installed, validation skipped | + +--- + +## Usage Examples + +### From Command Line + +```bash +# Verify a Python file +python get_tools.py verify src/main.py + +# Verify a TypeScript file +python get_tools.py verify components/App.tsx + +# Verify a JSON configuration +python get_tools.py verify package.json +``` + +### From Agent Context + +The agent can call the verify command after resolving conflicts: + +``` +Agent: I've resolved the conflict in `server.js`. Let me verify the syntax... +System: python get_tools.py verify server.js +Output: {"status": "valid", "message": "JavaScript syntax check passed.", "language": "javascript"} +Agent: ✓ Syntax verified. You can now run `git add server.js`. +``` + +--- + +## Adding Support for New Languages + +To add a new language validator: + +### 1. Create a Validator Class + +In `syntax_validators.py`, add a new class: + +```python +class YourLanguageValidator(SyntaxValidator): + """Validates YourLanguage syntax.""" + + def __init__(self): + super().__init__() + self.supported_extensions = ['.ext'] # File extensions + self.has_tool = self._check_tool_available() + + def _check_tool_available(self) -> bool: + """Check if validation tool is installed.""" + try: + subprocess.run(['your-tool', '--version'], + capture_output=True, + check=True, + timeout=2) + return True + except: + return False + + def validate(self, filepath: str) -> Dict[str, str]: + if not self.has_tool: + return { + "status": "skipped", + "message": "Tool not found. Install instructions...", + "language": "yourlanguage" + } + + # Your validation logic here + # ... + + return { + "status": "valid", + "message": "Validation passed.", + "language": "yourlanguage" + } +``` + +### 2. Register the Validator + +In `ValidatorRegistry.__init__()`, add your validator: + +```python +self.validators = [ + PythonValidator(), + JavaScriptValidator(), + # ... existing validators ... + YourLanguageValidator(), # Add here +] +``` + +### 3. Test + +```bash +python syntax_validators.py path/to/file.ext +``` + +--- + +## Language Priority Suggestions + +Based on GitHub usage statistics, recommended next languages to support: + +1. **Java** (.java) - Use `javac` or `jdk.compiler` API +2. **C/C++** (.c, .cpp, .h) - Use `gcc -fsyntax-only` +3. **C#** (.cs) - Use `dotnet build` or Roslyn +4. **PHP** (.php) - Use `php -l` +5. **Ruby** (.rb) - Use `ruby -c` +6. **Swift** (.swift) - Use `swiftc -parse` +7. **Kotlin** (.kt) - Use `kotlinc` + +--- + +## Graceful Degradation + +The system is designed to **never block** the agent's workflow: + +- If a validator is not installed → `status: "skipped"` with helpful install message +- If file type is unsupported → Generic validator checks basic readability +- If validation times out → Returns error but doesn't crash + +This ensures the agent can always proceed with merge resolution, even in environments with limited tooling. + +--- + +## Performance Considerations + +### Fast Validators (< 100ms) + +- Python (AST) +- JSON (Native) +- Generic (File read) + +### Medium Validators (< 1s) + +- JavaScript (Node.js) +- Go (go fmt) + +### Slower Validators (1-5s) + +- TypeScript (tsc with type checking) +- Rust (rustc compilation) + +**Optimization:** All validators have a 5-10 second timeout to prevent hanging. + +--- + +## Testing the Validator + +### Create Test Files + +```bash +# In your test repo +mkdir -p test_files + +# Python test +echo "print('hello')" > test_files/valid.py +echo "print('unclosed" > test_files/invalid.py + +# JavaScript test +echo "console.log('hello');" > test_files/valid.js +echo "console.log('unclosed" > test_files/invalid.js + +# JSON test +echo '{"valid": true}' > test_files/valid.json +echo '{"invalid": }' > test_files/invalid.json +``` + +### Run Validation + +```bash +python get_tools.py verify test_files/valid.py +python get_tools.py verify test_files/invalid.py +python get_tools.py verify test_files/valid.js +python get_tools.py verify test_files/invalid.json +``` + +--- + +## FAQ + +### Q: What if I don't have Node.js installed? + +**A:** JavaScript files will return `status: "skipped"` with a message explaining what's missing. The agent can still resolve the conflict, but won't validate syntax. + +### Q: Can I disable validation for certain file types? + +**A:** Yes. Modify the `ValidatorRegistry` to skip specific extensions, or the agent can be instructed to skip the verify step. + +### Q: Does validation modify my files? + +**A:** No. All validators are read-only except `go fmt`, which we run in a way that doesn't modify the original file. + +### Q: What about binary files (images, PDFs)? + +**A:** The generic validator detects binary files and returns `status: "warning"` without attempting text parsing. + +--- + +## Integration with instructions.md + +The agent's main instructions should reference this capability: + +```markdown +### COMMAND: apply + +**Action:** + +1. Write the resolved content to disk +2. **Verify syntax** using `python get_tools.py verify ` +3. Report validation status to user +4. If syntax is invalid, ask user if they want Claude to fix it +``` + +This ensures every resolved conflict is validated before the user stages it.