ace-git-copilot 0.2.2__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.
Files changed (57) hide show
  1. ace_git_copilot-0.2.3/.agents/AGENTS.md +17 -0
  2. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/PKG-INFO +1 -1
  3. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/ui/display.py +68 -26
  4. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/ui/prompts.py +7 -6
  5. ace_git_copilot-0.2.3/ace/ui/themes.py +24 -0
  6. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/pyproject.toml +1 -1
  7. ace_git_copilot-0.2.2/ace/ui/themes.py +0 -22
  8. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/.env.example +0 -0
  9. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/.github/workflows/tests.yml +0 -0
  10. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/.gitignore +0 -0
  11. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/README.md +0 -0
  12. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/__init__.py +0 -0
  13. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/__main__.py +0 -0
  14. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/ai/changelog_generator.py +0 -0
  15. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/ai/code_reviewer.py +0 -0
  16. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/ai/commit_generator.py +0 -0
  17. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/ai/conflict_resolver.py +0 -0
  18. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/ai/gitignore_generator.py +0 -0
  19. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/ai/history_analyzer.py +0 -0
  20. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/ai/intent_parser.py +0 -0
  21. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/ai/llm_factory.py +0 -0
  22. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/ai/pr_drafter.py +0 -0
  23. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/ai/prompts/changelog.py +0 -0
  24. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/ai/prompts/commit.py +0 -0
  25. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/ai/prompts/conflict.py +0 -0
  26. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/ai/prompts/explain.py +0 -0
  27. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/ai/prompts/ignore.py +0 -0
  28. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/ai/prompts/intent.py +0 -0
  29. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/ai/prompts/pr.py +0 -0
  30. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/ai/prompts/review.py +0 -0
  31. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/ai/prompts/search.py +0 -0
  32. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/ai/prompts/undo.py +0 -0
  33. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/cli.py +0 -0
  34. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/core/config.py +0 -0
  35. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/core/context.py +0 -0
  36. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/core/git_ops.py +0 -0
  37. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/core/safety.py +0 -0
  38. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/ui/banner.py +0 -0
  39. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/ui/dashboard.py +0 -0
  40. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/utils/conflict_parser.py +0 -0
  41. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/utils/diff_parser.py +0 -0
  42. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/ace/utils/json_utils.py +0 -0
  43. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/tests/conftest.py +0 -0
  44. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/tests/test_changelog_generator.py +0 -0
  45. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/tests/test_code_reviewer.py +0 -0
  46. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/tests/test_conflict_resolver.py +0 -0
  47. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/tests/test_diff_trimmer.py +0 -0
  48. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/tests/test_git_ops.py +0 -0
  49. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/tests/test_help.py +0 -0
  50. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/tests/test_history_analyzer.py +0 -0
  51. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/tests/test_ignore.py +0 -0
  52. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/tests/test_intent_parser.py +0 -0
  53. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/tests/test_llm_factory.py +0 -0
  54. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/tests/test_pr_drafter.py +0 -0
  55. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/tests/test_safety.py +0 -0
  56. {ace_git_copilot-0.2.2 → ace_git_copilot-0.2.3}/tests/test_search.py +0 -0
  57. {ace_git_copilot-0.2.2 → 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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ace-git-copilot
3
- Version: 0.2.2
3
+ Version: 0.2.3
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
@@ -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] {message}[/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] {message}[/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] {message}[/error]", file=sys.stderr)
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 panel with commands and their description."""
57
- content = Text()
58
- content.append("Proposed Plan:\n", style="bold white")
59
-
60
- for i, (cmd, exp) in enumerate(zip(commands, explanations), 1):
61
- content.append(f"\n {i}. ", style="ai")
62
- content.append(f"{cmd}\n", style="bold white")
63
- content.append(f" -> {exp}\n", style="dim italic")
64
-
65
- panel = Panel(
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
- console.print(panel)
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
- text.append(subject, style="bold green")
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="white")
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
- border_style="panel.border",
89
- expand=False
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
- for key, (label, _) in options.items():
41
- if text.cell_len > 0:
42
- text.append(" ")
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 cyan")
46
- text.append(f" {label}", style="white")
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,6 +1,6 @@
1
1
  [project]
2
2
  name = "ace-git-copilot"
3
- version = "0.2.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"
@@ -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)