ace-git-copilot 0.2.2__tar.gz → 0.2.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. ace_git_copilot-0.2.4/.agents/AGENTS.md +17 -0
  2. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/PKG-INFO +10 -4
  3. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/README.md +9 -3
  4. ace_git_copilot-0.2.4/ace/ai/prompts/doctor.py +24 -0
  5. ace_git_copilot-0.2.4/ace/ai/prompts/rebase.py +36 -0
  6. ace_git_copilot-0.2.4/ace/ai/rebase_helper.py +157 -0
  7. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/cli.py +339 -0
  8. ace_git_copilot-0.2.4/ace/core/diagnostics.py +81 -0
  9. ace_git_copilot-0.2.4/ace/core/hooks.py +60 -0
  10. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/ui/dashboard.py +38 -1
  11. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/ui/display.py +68 -26
  12. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/ui/prompts.py +26 -6
  13. ace_git_copilot-0.2.4/ace/ui/themes.py +24 -0
  14. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/pyproject.toml +1 -1
  15. ace_git_copilot-0.2.4/tests/test_diagnostics.py +72 -0
  16. ace_git_copilot-0.2.4/tests/test_hooks.py +66 -0
  17. ace_git_copilot-0.2.4/tests/test_rebase_helper.py +48 -0
  18. ace_git_copilot-0.2.2/ace/ui/themes.py +0 -22
  19. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/.env.example +0 -0
  20. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/.github/workflows/tests.yml +0 -0
  21. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/.gitignore +0 -0
  22. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/__init__.py +0 -0
  23. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/__main__.py +0 -0
  24. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/ai/changelog_generator.py +0 -0
  25. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/ai/code_reviewer.py +0 -0
  26. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/ai/commit_generator.py +0 -0
  27. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/ai/conflict_resolver.py +0 -0
  28. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/ai/gitignore_generator.py +0 -0
  29. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/ai/history_analyzer.py +0 -0
  30. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/ai/intent_parser.py +0 -0
  31. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/ai/llm_factory.py +0 -0
  32. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/ai/pr_drafter.py +0 -0
  33. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/ai/prompts/changelog.py +0 -0
  34. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/ai/prompts/commit.py +0 -0
  35. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/ai/prompts/conflict.py +0 -0
  36. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/ai/prompts/explain.py +0 -0
  37. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/ai/prompts/ignore.py +0 -0
  38. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/ai/prompts/intent.py +0 -0
  39. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/ai/prompts/pr.py +0 -0
  40. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/ai/prompts/review.py +0 -0
  41. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/ai/prompts/search.py +0 -0
  42. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/ai/prompts/undo.py +0 -0
  43. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/core/config.py +0 -0
  44. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/core/context.py +0 -0
  45. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/core/git_ops.py +0 -0
  46. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/core/safety.py +0 -0
  47. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/ui/banner.py +0 -0
  48. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/utils/conflict_parser.py +0 -0
  49. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/utils/diff_parser.py +0 -0
  50. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/ace/utils/json_utils.py +0 -0
  51. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/tests/conftest.py +0 -0
  52. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/tests/test_changelog_generator.py +0 -0
  53. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/tests/test_code_reviewer.py +0 -0
  54. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/tests/test_conflict_resolver.py +0 -0
  55. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/tests/test_diff_trimmer.py +0 -0
  56. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/tests/test_git_ops.py +0 -0
  57. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/tests/test_help.py +0 -0
  58. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/tests/test_history_analyzer.py +0 -0
  59. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/tests/test_ignore.py +0 -0
  60. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/tests/test_intent_parser.py +0 -0
  61. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/tests/test_llm_factory.py +0 -0
  62. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/tests/test_pr_drafter.py +0 -0
  63. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/tests/test_safety.py +0 -0
  64. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/tests/test_search.py +0 -0
  65. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.4}/tests/test_undo.py +0 -0
@@ -0,0 +1,17 @@
1
+ # Custom Rules for Ace Workspace
2
+
3
+ Whenever a new version of Ace is created (e.g., version incremented in `pyproject.toml` or when releasing a new tag), we must build the package and publish the updated release to PyPI (pip) so that users can install the latest package.
4
+
5
+ ## Publishing Steps
6
+ 1. Increment the version number in [pyproject.toml](file:///d:/Ace/pyproject.toml).
7
+ 2. Clean previous build artifacts from `dist/`.
8
+ 3. Build the wheel and source distribution:
9
+ ```bash
10
+ python -m build
11
+ ```
12
+ *(or using `hatch build` / `poetry build` as appropriate)*
13
+ 4. Upload the built packages to PyPI using twine:
14
+ ```bash
15
+ twine upload dist/*
16
+ ```
17
+ 5. Ensure a corresponding git tag is pushed to GitHub.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ace-git-copilot
3
- Version: 0.2.2
3
+ Version: 0.2.4
4
4
  Summary: AI-powered Git copilot — talk to Git in plain English
5
5
  License: MIT
6
6
  Classifier: License :: OSI Approved :: MIT License
@@ -56,8 +56,11 @@ Ace is an intelligent command-line tool that brings AI assistance directly to yo
56
56
  * **Automated Code Review**: Rates code quality and points out bugs, security flaws, or styling issues inside staged or unstaged diffs.
57
57
  * **Merge Conflict Resolution**: Interactively walks you through conflict blocks and suggests correct merges.
58
58
  * **Rich Repo Stats and Changelogs**: Instantly computes repository statistics (commits, additions, deletions, file counts) and generates markdown release notes since the last tag.
59
- * **Semantic Commit Search**: Search commits by natural language queries (e.g. "fixed the authorization bug") instead of matching literal strings.
60
- * **Interactive TUI Dashboard**: Run `ace dash` to launch a terminal interface showing current status, branch info, commit charts, and interactive menus.
59
+ * **Semantic Commit Search & Checkout**: Search commits by natural language queries and interactively inspect diffs, checkout commits, or create branches.
60
+ * **Interactive TUI Dashboard**: Run `ace dash` to launch a terminal interface showing current status, branch info, workspace repository listings, and interactive menus.
61
+ * **Repository Health Diagnostics**: Run `ace doctor` to run repository health checks (detached heads, locks, large files) and generate step-by-step AI recovery advice.
62
+ * **Smart Git Hooks**: Run `ace hook install` to register pre-commit code review checks and prepare-commit-msg message drafting.
63
+ * **AI Auto-Squashing & Rebasing**: Run `ace squash` to automatically analyze branch commits and run automated interactive rebases.
61
64
  * **Safety Features**: Classifies actions into safe, moderate, or destructive levels, and requests confirmation before running destructive operations.
62
65
 
63
66
  ---
@@ -153,10 +156,13 @@ Ace has dedicated subcommands for specific tasks. Here is the complete command l
153
156
  | `ace review` | — | Run code review on staged, unstaged, or branch changes. |
154
157
  | `ace resolve` | — | Step-by-step interactive merge conflict resolver. |
155
158
  | `ace explain <query>`| — | Explain complex Git commands or repository errors. |
159
+ | `ace doctor` | — | Run repository diagnostics and generate step-by-step AI recovery recipes. |
160
+ | `ace hook <action>` | — | Install or uninstall pre-commit and prepare-commit-msg Git hooks. |
156
161
  | `ace stats` | — | Rich visualization of repo statistics, extension breakdowns, and history. |
157
162
  | `ace changelog` | — | Compile release changelogs since the last tag. |
158
163
  | `ace pr` | — | Draft a Markdown pull request title and description. |
159
- | `ace search <query>` | — | Semantically search commit history using natural language. |
164
+ | `ace search <query>` | — | Semantically search commit history with interactive checkout options. |
165
+ | `ace squash` | — | Automatically analyze commit history and run AI-guided interactive rebases. |
160
166
  | `ace ignore <rule>` | — | Generate and append standard templates to `.gitignore`. |
161
167
  | `ace undo` | — | Safely revert the last action after checking repository status. |
162
168
  | `ace dash` | — | Launch the interactive repository management console (TUI). |
@@ -28,8 +28,11 @@ Ace is an intelligent command-line tool that brings AI assistance directly to yo
28
28
  * **Automated Code Review**: Rates code quality and points out bugs, security flaws, or styling issues inside staged or unstaged diffs.
29
29
  * **Merge Conflict Resolution**: Interactively walks you through conflict blocks and suggests correct merges.
30
30
  * **Rich Repo Stats and Changelogs**: Instantly computes repository statistics (commits, additions, deletions, file counts) and generates markdown release notes since the last tag.
31
- * **Semantic Commit Search**: Search commits by natural language queries (e.g. "fixed the authorization bug") instead of matching literal strings.
32
- * **Interactive TUI Dashboard**: Run `ace dash` to launch a terminal interface showing current status, branch info, commit charts, and interactive menus.
31
+ * **Semantic Commit Search & Checkout**: Search commits by natural language queries and interactively inspect diffs, checkout commits, or create branches.
32
+ * **Interactive TUI Dashboard**: Run `ace dash` to launch a terminal interface showing current status, branch info, workspace repository listings, and interactive menus.
33
+ * **Repository Health Diagnostics**: Run `ace doctor` to run repository health checks (detached heads, locks, large files) and generate step-by-step AI recovery advice.
34
+ * **Smart Git Hooks**: Run `ace hook install` to register pre-commit code review checks and prepare-commit-msg message drafting.
35
+ * **AI Auto-Squashing & Rebasing**: Run `ace squash` to automatically analyze branch commits and run automated interactive rebases.
33
36
  * **Safety Features**: Classifies actions into safe, moderate, or destructive levels, and requests confirmation before running destructive operations.
34
37
 
35
38
  ---
@@ -125,10 +128,13 @@ Ace has dedicated subcommands for specific tasks. Here is the complete command l
125
128
  | `ace review` | — | Run code review on staged, unstaged, or branch changes. |
126
129
  | `ace resolve` | — | Step-by-step interactive merge conflict resolver. |
127
130
  | `ace explain <query>`| — | Explain complex Git commands or repository errors. |
131
+ | `ace doctor` | — | Run repository diagnostics and generate step-by-step AI recovery recipes. |
132
+ | `ace hook <action>` | — | Install or uninstall pre-commit and prepare-commit-msg Git hooks. |
128
133
  | `ace stats` | — | Rich visualization of repo statistics, extension breakdowns, and history. |
129
134
  | `ace changelog` | — | Compile release changelogs since the last tag. |
130
135
  | `ace pr` | — | Draft a Markdown pull request title and description. |
131
- | `ace search <query>` | — | Semantically search commit history using natural language. |
136
+ | `ace search <query>` | — | Semantically search commit history with interactive checkout options. |
137
+ | `ace squash` | — | Automatically analyze commit history and run AI-guided interactive rebases. |
132
138
  | `ace ignore <rule>` | — | Generate and append standard templates to `.gitignore`. |
133
139
  | `ace undo` | — | Safely revert the last action after checking repository status. |
134
140
  | `ace dash` | — | Launch the interactive repository management console (TUI). |
@@ -0,0 +1,24 @@
1
+ # Prompt templates for Git Diagnostics (ace doctor)
2
+
3
+ DOCTOR_SYSTEM_PROMPT = """
4
+ You are "Ace", an expert Git engineer and repository doctor.
5
+ Your job is to analyze the Git repository diagnostic findings and compile a clear explanation of what is wrong, along with a step-by-step recovery plan (with exact Git commands) to restore the repository to a clean, stable state.
6
+
7
+ Output format:
8
+ Your output must be formatted as markdown.
9
+ Include:
10
+ 1. 🩺 **Diagnostics Assessment**: A brief explanation of the problems found.
11
+ 2. 📋 **Recovery Plan**: A step-by-step guide with instructions and standard code blocks (e.g. `git restore` or `git stash`) to resolve the issues.
12
+ 3. 💡 **Prevention Tip**: A short advice block on how to prevent this state in the future.
13
+
14
+ Ensure all commands proposed are safe and exact. Avoid destructive operations without providing a clear stash/backup alternative first.
15
+ """
16
+
17
+ USER_PROMPT_TEMPLATE = """
18
+ Diagnostic Findings:
19
+ \"\"\"
20
+ {diagnostics_json}
21
+ \"\"\"
22
+
23
+ Analyze these findings and provide your diagnostics report and recovery guide.
24
+ """
@@ -0,0 +1,36 @@
1
+ # Prompt templates for Git Auto-Squash & Rebase Helper (ace squash)
2
+
3
+ REBASE_SYSTEM_PROMPT = """
4
+ You are "Ace", an expert Git engineer.
5
+ Your job is to analyze the local commits on a developer's branch and recommend how to group, squash, or reword them to build a clean, professional commit history.
6
+
7
+ You will be given:
8
+ 1. The list of recent local commits on the branch.
9
+
10
+ You MUST respond with a JSON object containing the following keys (no markdown blocks, no other text):
11
+ {
12
+ "recommendations": [
13
+ {
14
+ "hexsha": "commit_hash",
15
+ "summary": "commit_summary",
16
+ "action": "pick" | "squash" | "reword" | "drop",
17
+ "new_message": "New commit message if action is reword, or null"
18
+ }
19
+ ],
20
+ "explanation": "A brief explanation of the proposed squashing logic."
21
+ }
22
+
23
+ Guidelines:
24
+ 1. The oldest commit (chronologically first) MUST be 'pick'. You cannot squash the base/first commit of the branch.
25
+ 2. Group temporary commits (e.g., "typo fix", "formatting", "wip", "cleanup") into the main functional commits that preceded them by recommending "squash".
26
+ 3. Recommend "reword" to clean up poor messages to conform to clean Git conventions.
27
+ """
28
+
29
+ USER_PROMPT_TEMPLATE = """
30
+ Local Commits on branch:
31
+ \"\"\"
32
+ {commit_list_text}
33
+ \"\"\"
34
+
35
+ Analyze these commits and recommend rebase/squash actions.
36
+ """
@@ -0,0 +1,157 @@
1
+ import os
2
+ import tempfile
3
+ import json
4
+ import sys
5
+ from typing import Dict, Any, List
6
+ from langchain_core.messages import SystemMessage, HumanMessage
7
+ from ace.core.git_ops import GitOps
8
+ from ace.ai.llm_factory import get_llm
9
+ from ace.ai.prompts.rebase import REBASE_SYSTEM_PROMPT, USER_PROMPT_TEMPLATE
10
+ from ace.utils.json_utils import extract_json
11
+
12
+ class RebaseHelper:
13
+ def __init__(self, git_ops: GitOps):
14
+ self.git_ops = git_ops
15
+
16
+ def get_local_commits(self, base_branch: str) -> List[Dict[str, Any]]:
17
+ """Get list of local commits not merged into the base branch, in chronological order."""
18
+ try:
19
+ log_data = self.git_ops.execute(f"log {base_branch}..HEAD --reverse --format=%H|%an|%s")
20
+ except Exception:
21
+ return []
22
+
23
+ commits = []
24
+ for line in log_data.splitlines():
25
+ if "|" in line:
26
+ parts = line.split("|")
27
+ if len(parts) >= 3:
28
+ commits.append({
29
+ "hexsha": parts[0],
30
+ "author": parts[1],
31
+ "summary": parts[2].strip()
32
+ })
33
+ return commits
34
+
35
+ def analyze_commits(self, commits: List[Dict[str, Any]], offline: bool = False) -> Dict[str, Any]:
36
+ """Ask LLM to recommend squash/reword actions for the local commits."""
37
+ commit_lines = []
38
+ for c in commits:
39
+ commit_lines.append(f"- {c['hexsha'][:7]} - {c['summary']} (by {c['author']})")
40
+ commit_list_text = "\n".join(commit_lines)
41
+
42
+ usr_prompt = USER_PROMPT_TEMPLATE.format(commit_list_text=commit_list_text)
43
+
44
+ messages = [
45
+ SystemMessage(content=REBASE_SYSTEM_PROMPT),
46
+ HumanMessage(content=usr_prompt)
47
+ ]
48
+
49
+ llm = get_llm(offline_override=offline)
50
+ response = llm.invoke(messages)
51
+
52
+ return extract_json(response.content)
53
+
54
+ def run_auto_rebase(self, base_branch: str, recommendations: List[Dict[str, Any]]) -> str:
55
+ """Execute programmatic interactive rebase using Python sequence and message editors."""
56
+ action_map = {}
57
+ reword_messages = {}
58
+ for rec in recommendations:
59
+ sha = rec["hexsha"][:7].lower()
60
+ action_map[sha] = rec["action"].lower()
61
+ if rec["action"].lower() == "reword" and rec.get("new_message"):
62
+ reword_messages[rec["summary"].strip()] = rec["new_message"]
63
+
64
+ # Create mapping JSON
65
+ map_data = {
66
+ "actions": action_map,
67
+ "rewords": reword_messages
68
+ }
69
+
70
+ fd, map_path = tempfile.mkstemp(suffix=".json")
71
+ editor_path = None
72
+ reword_editor_path = None
73
+
74
+ try:
75
+ with os.fdopen(fd, 'w', encoding='utf-8') as f:
76
+ json.dump(map_data, f)
77
+
78
+ # Sequence editor: edits git-rebase-todo
79
+ seq_code = f"""import sys, json
80
+ with open({repr(map_path)}, 'r') as f:
81
+ data = json.load(f)
82
+ actions = data['actions']
83
+
84
+ todo_path = sys.argv[1]
85
+ with open(todo_path, 'r', encoding='utf-8') as f:
86
+ content = f.read()
87
+
88
+ lines = []
89
+ for line in content.splitlines():
90
+ if not line.strip() or line.startswith('#'):
91
+ lines.append(line)
92
+ continue
93
+ parts = line.split()
94
+ if len(parts) >= 2 and parts[0] == 'pick':
95
+ sha = parts[1][:7].lower()
96
+ if sha in actions:
97
+ action = actions[sha]
98
+ lines.append(action + ' ' + ' '.join(parts[1:]))
99
+ continue
100
+ lines.append(line)
101
+
102
+ with open(todo_path, 'w', encoding='utf-8') as f:
103
+ f.write('\\n'.join(lines) + '\\n')
104
+ """
105
+ editor_fd, editor_path = tempfile.mkstemp(suffix=".py")
106
+ with os.fdopen(editor_fd, 'w', encoding='utf-8') as f:
107
+ f.write(seq_code)
108
+
109
+ # Commit msg editor: edits COMMIT_EDITMSG for reword actions
110
+ reword_code = f"""import sys, json
111
+ with open({repr(map_path)}, 'r') as f:
112
+ data = json.load(f)
113
+ rewords = data['rewords']
114
+
115
+ msg_path = sys.argv[1]
116
+ with open(msg_path, 'r', encoding='utf-8') as f:
117
+ content = f.read()
118
+
119
+ lines = content.splitlines()
120
+ if lines:
121
+ subject = lines[0].strip()
122
+ if subject in rewords:
123
+ new_msg = rewords[subject]
124
+ comments = [l for l in lines[1:] if l.strip().startswith('#')]
125
+ with open(msg_path, 'w', encoding='utf-8') as f_out:
126
+ f_out.write(new_msg + '\\n\\n' + '\\n'.join(comments))
127
+ """
128
+ reword_fd, reword_editor_path = tempfile.mkstemp(suffix=".py")
129
+ with os.fdopen(reword_fd, 'w', encoding='utf-8') as f:
130
+ f.write(reword_code)
131
+
132
+ # Execute rebase with environment variables
133
+ env = os.environ.copy()
134
+ python_exe = sys.executable
135
+ env["GIT_SEQUENCE_EDITOR"] = f'"{python_exe}" "{editor_path}"'
136
+ env["GIT_EDITOR"] = f'"{python_exe}" "{reword_editor_path}"'
137
+
138
+ # Execute command directly using GitPython
139
+ # Run rebase -i base_branch
140
+ # GitPython execute method wraps repo.git
141
+ return self.git_ops.repo.git.rebase("-i", base_branch, env=env)
142
+ finally:
143
+ # Clean up temp files
144
+ try:
145
+ os.unlink(map_path)
146
+ except Exception:
147
+ pass
148
+ if editor_path:
149
+ try:
150
+ os.unlink(editor_path)
151
+ except Exception:
152
+ pass
153
+ if reword_editor_path:
154
+ try:
155
+ os.unlink(reword_editor_path)
156
+ except Exception:
157
+ pass