ace-git-copilot 0.2.1__tar.gz → 0.2.3__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.
- ace_git_copilot-0.2.3/.agents/AGENTS.md +17 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/PKG-INFO +7 -1
- ace_git_copilot-0.2.3/ace/__init__.py +1 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/cli.py +0 -1
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/ui/display.py +68 -26
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/ui/prompts.py +7 -6
- ace_git_copilot-0.2.3/ace/ui/themes.py +24 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/pyproject.toml +9 -1
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/tests/test_llm_factory.py +0 -1
- ace_git_copilot-0.2.1/ace/__init__.py +0 -1
- ace_git_copilot-0.2.1/ace/ui/themes.py +0 -22
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/.env.example +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/.github/workflows/tests.yml +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/.gitignore +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/README.md +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/__main__.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/ai/changelog_generator.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/ai/code_reviewer.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/ai/commit_generator.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/ai/conflict_resolver.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/ai/gitignore_generator.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/ai/history_analyzer.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/ai/intent_parser.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/ai/llm_factory.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/ai/pr_drafter.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/ai/prompts/changelog.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/ai/prompts/commit.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/ai/prompts/conflict.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/ai/prompts/explain.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/ai/prompts/ignore.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/ai/prompts/intent.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/ai/prompts/pr.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/ai/prompts/review.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/ai/prompts/search.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/ai/prompts/undo.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/core/config.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/core/context.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/core/git_ops.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/core/safety.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/ui/banner.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/ui/dashboard.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/utils/conflict_parser.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/utils/diff_parser.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/ace/utils/json_utils.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/tests/conftest.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/tests/test_changelog_generator.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/tests/test_code_reviewer.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/tests/test_conflict_resolver.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/tests/test_diff_trimmer.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/tests/test_git_ops.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/tests/test_help.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/tests/test_history_analyzer.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/tests/test_ignore.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/tests/test_intent_parser.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/tests/test_pr_drafter.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/tests/test_safety.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/tests/test_search.py +0 -0
- {ace_git_copilot-0.2.1 → ace_git_copilot-0.2.3}/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,7 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ace-git-copilot
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: AI-powered Git copilot — talk to Git in plain English
|
|
5
|
+
License: MIT
|
|
6
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
7
|
+
Classifier: Operating System :: OS Independent
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
5
11
|
Requires-Python: >=3.11
|
|
6
12
|
Requires-Dist: click>=8.0
|
|
7
13
|
Requires-Dist: gitpython>=3.1
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.2.2"
|
|
@@ -5,6 +5,8 @@ from rich.console import Console
|
|
|
5
5
|
from rich.panel import Panel
|
|
6
6
|
from rich.syntax import Syntax
|
|
7
7
|
from rich.text import Text
|
|
8
|
+
from rich.table import Table
|
|
9
|
+
from rich import box
|
|
8
10
|
from ace.ui.themes import get_rich_theme
|
|
9
11
|
|
|
10
12
|
# Initialize global Rich console with the application theme
|
|
@@ -12,19 +14,19 @@ console = Console(theme=get_rich_theme())
|
|
|
12
14
|
|
|
13
15
|
def print_info(message: str) -> None:
|
|
14
16
|
"""Print an informational message."""
|
|
15
|
-
console.print(f"[info]
|
|
17
|
+
console.print(f" [info]⚡ {message}[/info]")
|
|
16
18
|
|
|
17
19
|
def print_success(message: str) -> None:
|
|
18
20
|
"""Print a success message."""
|
|
19
|
-
console.print(f"[success]
|
|
21
|
+
console.print(f" [success]✔ {message}[/success]")
|
|
20
22
|
|
|
21
23
|
def print_warning(message: str) -> None:
|
|
22
24
|
"""Print a warning message."""
|
|
23
|
-
console.print(f"[warning]⚠️ {message}[/warning]")
|
|
25
|
+
console.print(f" [warning]⚠️ {message}[/warning]")
|
|
24
26
|
|
|
25
27
|
def print_error(message: str) -> None:
|
|
26
28
|
"""Print an error message."""
|
|
27
|
-
console.print(f"[error]
|
|
29
|
+
console.print(f" [error]✖ {message}[/error]", file=sys.stderr)
|
|
28
30
|
|
|
29
31
|
def show_warning_panel(message: str, title: str = "WARNING") -> None:
|
|
30
32
|
"""Show a yellow warning panel with a title."""
|
|
@@ -53,42 +55,82 @@ def spinner(message: str = "Thinking..."):
|
|
|
53
55
|
yield status
|
|
54
56
|
|
|
55
57
|
def show_plan(commands: List[str], explanations: List[str]) -> None:
|
|
56
|
-
"""Display the execution plan
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
content,
|
|
67
|
-
title="🧠 Ace AI Git Plan",
|
|
68
|
-
border_style="panel.border",
|
|
69
|
-
expand=False
|
|
58
|
+
"""Display the execution plan table with commands and descriptions."""
|
|
59
|
+
table = Table(
|
|
60
|
+
show_header=True,
|
|
61
|
+
header_style="bold #FF6D00",
|
|
62
|
+
box=box.ROUNDED,
|
|
63
|
+
border_style="#FF6D00",
|
|
64
|
+
title="[bold white]🧠 Proposed Execution Plan[/bold white]",
|
|
65
|
+
title_justify="left",
|
|
66
|
+
expand=False,
|
|
67
|
+
padding=(0, 2)
|
|
70
68
|
)
|
|
71
|
-
|
|
69
|
+
table.add_column("Step", justify="center", style="bold #00D5FF", width=6)
|
|
70
|
+
table.add_column("Command", style="bold white", width=30)
|
|
71
|
+
table.add_column("Explanation", style="#E0E0E0")
|
|
72
|
+
|
|
73
|
+
for i, (cmd, exp) in enumerate(zip(commands, explanations), 1):
|
|
74
|
+
cmd_styled = Text(cmd, style="bold white")
|
|
75
|
+
if cmd.startswith("git "):
|
|
76
|
+
cmd_styled = Text("git ", style="bold #Highlight") + Text(cmd[4:], style="bold white")
|
|
77
|
+
elif cmd.startswith("ace "):
|
|
78
|
+
cmd_styled = Text("ace ", style="bold #ai") + Text(cmd[4:], style="bold white")
|
|
79
|
+
|
|
80
|
+
table.add_row(f"{i:02d}", cmd_styled, exp)
|
|
81
|
+
|
|
82
|
+
console.print()
|
|
83
|
+
console.print(table)
|
|
84
|
+
console.print()
|
|
72
85
|
|
|
73
86
|
def show_commit_message(message: str) -> None:
|
|
74
|
-
"""Display a suggested commit message in a clear panel."""
|
|
75
|
-
# Split into subject and body
|
|
87
|
+
"""Display a suggested commit message in a clear panel with length warning indicators."""
|
|
76
88
|
lines = message.splitlines()
|
|
77
89
|
subject = lines[0] if lines else ""
|
|
78
90
|
body = "\n".join(lines[1:]) if len(lines) > 1 else ""
|
|
79
91
|
|
|
80
92
|
text = Text()
|
|
81
|
-
|
|
93
|
+
# Style conventional commit components if present
|
|
94
|
+
import re
|
|
95
|
+
conv_match = re.match(r"^(\w+)(?:\(([^)]+)\))?(!?):(.*)$", subject)
|
|
96
|
+
if conv_match:
|
|
97
|
+
c_type, c_scope, c_breaking, c_desc = conv_match.groups()
|
|
98
|
+
text.append(c_type, style="bold #00D5FF")
|
|
99
|
+
if c_scope:
|
|
100
|
+
text.append(f"({c_scope})", style="bold #Highlight")
|
|
101
|
+
if c_breaking:
|
|
102
|
+
text.append("!", style="bold #error")
|
|
103
|
+
text.append(f":{c_desc}", style="bold #success")
|
|
104
|
+
else:
|
|
105
|
+
text.append(subject, style="bold #success")
|
|
106
|
+
|
|
82
107
|
if body:
|
|
83
|
-
text.append("\n" + body, style="
|
|
108
|
+
text.append("\n" + body, style="#E0E0E0")
|
|
109
|
+
|
|
110
|
+
# Character count styling for the subtitle
|
|
111
|
+
sub_len = len(subject)
|
|
112
|
+
if sub_len <= 50:
|
|
113
|
+
sub_color = "#00E676" # optimal
|
|
114
|
+
elif sub_len <= 72:
|
|
115
|
+
sub_color = "#FFD600" # acceptable warning
|
|
116
|
+
else:
|
|
117
|
+
sub_color = "#FF1744" # too long
|
|
118
|
+
|
|
119
|
+
subtitle = f"[dim]Length:[/dim] [bold {sub_color}]{sub_len}[/bold {sub_color}][dim]/72 chars[/dim]"
|
|
84
120
|
|
|
85
121
|
panel = Panel(
|
|
86
122
|
text,
|
|
87
|
-
title="📝 Suggested Commit Message",
|
|
88
|
-
|
|
89
|
-
|
|
123
|
+
title="[bold white]📝 Suggested Commit Message[/bold white]",
|
|
124
|
+
subtitle=subtitle,
|
|
125
|
+
subtitle_align="right",
|
|
126
|
+
border_style="#FF6D00",
|
|
127
|
+
box=box.ROUNDED,
|
|
128
|
+
expand=False,
|
|
129
|
+
padding=(1, 2)
|
|
90
130
|
)
|
|
131
|
+
console.print()
|
|
91
132
|
console.print(panel)
|
|
133
|
+
console.print()
|
|
92
134
|
|
|
93
135
|
def show_diff(diff_text: str) -> None:
|
|
94
136
|
"""Render a syntax-highlighted git diff."""
|
|
@@ -10,7 +10,7 @@ def confirm(question: str, default: bool = True) -> bool:
|
|
|
10
10
|
Returns True if confirmed, False otherwise.
|
|
11
11
|
"""
|
|
12
12
|
suffix = " [Y/n]" if default else " [y/N]"
|
|
13
|
-
prompt = f"[bold white]{question}[/bold white]{suffix}"
|
|
13
|
+
prompt = f" ❔ [bold white]{question}[/bold white] [bold #00D5FF]{suffix}[/bold #00D5FF] "
|
|
14
14
|
|
|
15
15
|
# Render with rich, but prompt using click
|
|
16
16
|
console.print(prompt, end="")
|
|
@@ -37,13 +37,14 @@ def prompt_action(options: Dict[str, Tuple[str, str]], default_key: str = "\r")
|
|
|
37
37
|
Returns the selected key character.
|
|
38
38
|
"""
|
|
39
39
|
text = Text()
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
text.append(" ⌨️ ")
|
|
41
|
+
for idx, (key, (label, _)) in enumerate(options.items()):
|
|
42
|
+
if idx > 0:
|
|
43
|
+
text.append(" • ", style="dim")
|
|
43
44
|
|
|
44
45
|
display_key = "Enter" if key == "\r" else key
|
|
45
|
-
text.append(f"[{display_key}]", style="bold
|
|
46
|
-
text.append(f" {label}", style="
|
|
46
|
+
text.append(f"[{display_key}]", style="bold #00D5FF")
|
|
47
|
+
text.append(f" {label}", style="#E0E0E0")
|
|
47
48
|
|
|
48
49
|
console.print(text)
|
|
49
50
|
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Styling theme definitions for Rich terminal output
|
|
2
|
+
|
|
3
|
+
from rich.theme import Theme
|
|
4
|
+
|
|
5
|
+
# Premium dark-mode color palette (Neon-Sunset style)
|
|
6
|
+
THEME_STYLES = {
|
|
7
|
+
"info": "bold #00D5FF", # Vibrant cyan
|
|
8
|
+
"warning": "bold #FFD600", # Neon yellow
|
|
9
|
+
"error": "bold #FF1744", # Electric red
|
|
10
|
+
"success": "bold #00E676", # Spring green
|
|
11
|
+
"ai": "bold #FF6D00", # Safety orange / Ace signature highlight
|
|
12
|
+
"git.add": "#00E676",
|
|
13
|
+
"git.delete": "#FF1744",
|
|
14
|
+
"git.modify": "#FFD600",
|
|
15
|
+
"command": "bold #FFFFFF on #1A237E", # Deep blue background for git commands
|
|
16
|
+
"path": "underline #00D5FF",
|
|
17
|
+
"panel.border": "#FF6D00",
|
|
18
|
+
"highlight": "bold #B388FF", # Light violet highlight
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
def get_rich_theme() -> Theme:
|
|
22
|
+
"""Get the Rich theme object containing all styling rules."""
|
|
23
|
+
return Theme(THEME_STYLES)
|
|
24
|
+
|
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "ace-git-copilot"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.3"
|
|
4
4
|
description = "AI-powered Git copilot — talk to Git in plain English"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
7
|
+
license = { text = "MIT" }
|
|
8
|
+
classifiers = [
|
|
9
|
+
"Programming Language :: Python :: 3",
|
|
10
|
+
"Programming Language :: Python :: 3.11",
|
|
11
|
+
"Programming Language :: Python :: 3.12",
|
|
12
|
+
"License :: OSI Approved :: MIT License",
|
|
13
|
+
"Operating System :: OS Independent",
|
|
14
|
+
]
|
|
7
15
|
dependencies = [
|
|
8
16
|
"typer[all]>=0.12",
|
|
9
17
|
"click>=8.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.2.1"
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# Styling theme definitions for Rich terminal output
|
|
2
|
-
|
|
3
|
-
from rich.theme import Theme
|
|
4
|
-
|
|
5
|
-
# Styles used across the app
|
|
6
|
-
THEME_STYLES = {
|
|
7
|
-
"info": "cyan",
|
|
8
|
-
"warning": "yellow",
|
|
9
|
-
"error": "bold red",
|
|
10
|
-
"success": "green",
|
|
11
|
-
"ai": "bold orange3",
|
|
12
|
-
"git.add": "green",
|
|
13
|
-
"git.delete": "red",
|
|
14
|
-
"git.modify": "yellow",
|
|
15
|
-
"command": "bold white on blue",
|
|
16
|
-
"path": "underline cyan",
|
|
17
|
-
"panel.border": "orange3",
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
def get_rich_theme() -> Theme:
|
|
21
|
-
"""Get the Rich theme object containing all styling rules."""
|
|
22
|
-
return Theme(THEME_STYLES)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|