ace-git-copilot 0.6.2__tar.gz → 0.6.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 (145) hide show
  1. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/PKG-INFO +1 -1
  2. ace_git_copilot-0.6.4/ace/__init__.py +1 -0
  3. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/cli.py +9 -2
  4. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/utils/string_utils.py +2 -6
  5. ace_git_copilot-0.6.4/ace/utils/update_checker.py +74 -0
  6. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/pyproject.toml +1 -1
  7. ace_git_copilot-0.6.4/tests/test_update_checker.py +22 -0
  8. ace_git_copilot-0.6.2/ace/__init__.py +0 -1
  9. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/AGENTS.md +0 -0
  10. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/BRIEFING.md +0 -0
  11. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/ORIGINAL_REQUEST.md +0 -0
  12. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/e2e_testing_track/BRIEFING.md +0 -0
  13. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/e2e_testing_track/ORIGINAL_REQUEST.md +0 -0
  14. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/e2e_testing_track/SCOPE.md +0 -0
  15. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/e2e_testing_track/progress.md +0 -0
  16. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/explorer_init/BRIEFING.md +0 -0
  17. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/explorer_init/ORIGINAL_REQUEST.md +0 -0
  18. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/explorer_init/emojis_list.txt +0 -0
  19. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/explorer_init/find_unused_modules.py +0 -0
  20. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/explorer_init/handoff.md +0 -0
  21. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/explorer_init/measure_lazy_startup.py +0 -0
  22. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/explorer_init/measure_startup.py +0 -0
  23. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/explorer_init/profile_imports.py +0 -0
  24. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/explorer_init/progress.md +0 -0
  25. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/explorer_init/run_importtime.py +0 -0
  26. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/explorer_init/search_banner.py +0 -0
  27. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/explorer_init/search_emojis.py +0 -0
  28. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/explorer_init/search_git_usages.py +0 -0
  29. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/explorer_init/search_usages.py +0 -0
  30. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/explorer_init/test_import_profiler.py +0 -0
  31. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/explorer_init/test_mocked_sys.py +0 -0
  32. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/handoff.md +0 -0
  33. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/implementation_track/BRIEFING.md +0 -0
  34. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/implementation_track/ORIGINAL_REQUEST.md +0 -0
  35. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/implementation_track/explorer_initial_report.md +0 -0
  36. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/implementation_track/progress.md +0 -0
  37. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/orchestrator/.gitkeep +0 -0
  38. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/orchestrator/BRIEFING.md +0 -0
  39. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/orchestrator/ORIGINAL_REQUEST.md +0 -0
  40. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/orchestrator/PROJECT.md +0 -0
  41. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/orchestrator/progress.md +0 -0
  42. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/teamwork_preview_explorer_e2e_explore/BRIEFING.md +0 -0
  43. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/teamwork_preview_explorer_e2e_explore/ORIGINAL_REQUEST.md +0 -0
  44. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/teamwork_preview_explorer_e2e_explore/handoff.md +0 -0
  45. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/teamwork_preview_explorer_e2e_explore/progress.md +0 -0
  46. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/worker_e2e_testing/BRIEFING.md +0 -0
  47. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/worker_e2e_testing/ORIGINAL_REQUEST.md +0 -0
  48. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/worker_e2e_testing/progress.md +0 -0
  49. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/worker_m1_startup/BRIEFING.md +0 -0
  50. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/worker_m1_startup/ORIGINAL_REQUEST.md +0 -0
  51. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.agents/worker_m1_startup/progress.md +0 -0
  52. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.env.example +0 -0
  53. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.github/workflows/tests.yml +0 -0
  54. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/.gitignore +0 -0
  55. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/CODE_OF_CONDUCT.md +0 -0
  56. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/CONTRIBUTING.md +0 -0
  57. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/LICENSE +0 -0
  58. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/PROJECT.md +0 -0
  59. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/README.md +0 -0
  60. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/SECURITY.md +0 -0
  61. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/SUPPORT.md +0 -0
  62. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/TEST_INFRA.md +0 -0
  63. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/TEST_READY.md +0 -0
  64. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/__main__.py +0 -0
  65. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/ai/changelog_generator.py +0 -0
  66. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/ai/code_reviewer.py +0 -0
  67. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/ai/commit_generator.py +0 -0
  68. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/ai/conflict_resolver.py +0 -0
  69. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/ai/gitignore_generator.py +0 -0
  70. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/ai/history_analyzer.py +0 -0
  71. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/ai/intent_parser.py +0 -0
  72. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/ai/llm_factory.py +0 -0
  73. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/ai/pr_drafter.py +0 -0
  74. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/ai/prompts/blame.py +0 -0
  75. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/ai/prompts/changelog.py +0 -0
  76. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/ai/prompts/commit.py +0 -0
  77. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/ai/prompts/conflict.py +0 -0
  78. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/ai/prompts/doctor.py +0 -0
  79. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/ai/prompts/explain.py +0 -0
  80. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/ai/prompts/ignore.py +0 -0
  81. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/ai/prompts/intent.py +0 -0
  82. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/ai/prompts/pr.py +0 -0
  83. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/ai/prompts/rebase.py +0 -0
  84. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/ai/prompts/review.py +0 -0
  85. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/ai/prompts/search.py +0 -0
  86. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/ai/prompts/standup.py +0 -0
  87. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/ai/prompts/undo.py +0 -0
  88. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/ai/push_resolver.py +0 -0
  89. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/ai/rebase_helper.py +0 -0
  90. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/core/config.py +0 -0
  91. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/core/context.py +0 -0
  92. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/core/diagnostics.py +0 -0
  93. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/core/git_ops.py +0 -0
  94. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/core/hooks.py +0 -0
  95. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/core/safety.py +0 -0
  96. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/ui/banner.py +0 -0
  97. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/ui/dashboard.py +0 -0
  98. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/ui/display.py +0 -0
  99. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/ui/prompts.py +0 -0
  100. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/ui/themes.py +0 -0
  101. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/utils/conflict_parser.py +0 -0
  102. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/utils/diff_parser.py +0 -0
  103. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/utils/i18n.py +0 -0
  104. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/ace/utils/json_utils.py +0 -0
  105. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/media/cli_in_action.svg +0 -0
  106. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/media/dashboard.svg +0 -0
  107. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/media/stats.svg +0 -0
  108. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/conftest.py +0 -0
  109. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/e2e/conftest.py +0 -0
  110. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/e2e/test_tier1_features.py +0 -0
  111. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/e2e/test_tier2_boundaries.py +0 -0
  112. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/e2e/test_tier3_combinations.py +0 -0
  113. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/e2e/test_tier4_workloads.py +0 -0
  114. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_alias.py +0 -0
  115. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_blame.py +0 -0
  116. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_changelog_generator.py +0 -0
  117. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_code_reviewer.py +0 -0
  118. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_config_atomic_write.py +0 -0
  119. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_conflict_resolver.py +0 -0
  120. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_conflict_resolver_backup.py +0 -0
  121. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_context_gitdir_detection.py +0 -0
  122. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_diagnostics.py +0 -0
  123. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_diff_trimmer.py +0 -0
  124. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_fallback.py +0 -0
  125. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_git_ops.py +0 -0
  126. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_git_ops_execute.py +0 -0
  127. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_help.py +0 -0
  128. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_history_analyzer.py +0 -0
  129. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_hooks.py +0 -0
  130. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_i18n.py +0 -0
  131. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_ignore.py +0 -0
  132. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_intent_parser.py +0 -0
  133. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_interceptor.py +0 -0
  134. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_llm_factory.py +0 -0
  135. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_llm_factory_ollama.py +0 -0
  136. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_merge_state.py +0 -0
  137. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_pr_drafter.py +0 -0
  138. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_push_resolver.py +0 -0
  139. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_rebase_helper.py +0 -0
  140. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_safety.py +0 -0
  141. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_search.py +0 -0
  142. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_standup.py +0 -0
  143. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_string_utils.py +0 -0
  144. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_undo.py +0 -0
  145. {ace_git_copilot-0.6.2 → ace_git_copilot-0.6.4}/tests/test_workspace.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ace-git-copilot
3
- Version: 0.6.2
3
+ Version: 0.6.4
4
4
  Summary: AI-powered Git copilot — talk to Git in plain English
5
5
  Project-URL: Homepage, https://github.com/jachinsamuel/Ace
6
6
  Project-URL: Documentation, https://github.com/jachinsamuel/Ace#readme
@@ -0,0 +1 @@
1
+ __version__ = "0.6.4"
@@ -78,6 +78,12 @@ def main(
78
78
  None, "--version", callback=version_callback, is_eager=True, help="Show the version and exit."
79
79
  ),
80
80
  ):
81
+ try:
82
+ from ace.utils.update_checker import check_for_updates
83
+ check_for_updates()
84
+ except Exception:
85
+ pass
86
+
81
87
  from ace.core.git_ops import GitOps, NotAGitRepositoryError
82
88
  from ace.ai.intent_parser import IntentParser
83
89
  from ace.ai.llm_factory import get_llm, LLMConfigurationError
@@ -162,6 +168,7 @@ def main(
162
168
  risk_level = parsed.get("risk_level", "safe")
163
169
 
164
170
  if not commands:
171
+ print_warning("No Git commands planned.")
165
172
  show_warning_panel(f"No actionable Git commands generated for: '{query}'\n{explanation}", "Empty Plan")
166
173
  return
167
174
 
@@ -170,7 +177,7 @@ def main(
170
177
  show_plan(commands, [explanation] + [""] * (len(commands) - 1))
171
178
 
172
179
  if dry_run:
173
- print_info("Dry run specified. Skipping execution.")
180
+ print_info("Dry-run mode: execution skipped.")
174
181
  return
175
182
 
176
183
  # Evaluate safety for the full plan
@@ -197,7 +204,7 @@ def main(
197
204
  execute_plan = confirm("Execute plan?", default=True)
198
205
 
199
206
  if not execute_plan:
200
- print_warning("Execution cancelled by user.")
207
+ print_info("Execution aborted.")
201
208
  return
202
209
 
203
210
  # Execute commands and capture output
@@ -31,10 +31,6 @@ def strip_emojis(text: str) -> str:
31
31
  )
32
32
 
33
33
  cleaned = emoji_pattern.sub("", text)
34
- # Replace multiple spaces/newlines with a single space (while preserving newlines if multi-line)
35
- # To be safe for markdown summaries, we can just strip emojis and keep other formatting intact.
36
- # Let's do a simple strip of double spaces that result from removing the emoji.
37
- cleaned = re.sub(r' +', ' ', cleaned)
38
- # Strip trailing whitespace on lines while preserving leading indentation
39
- lines = [line.rstrip() for line in cleaned.splitlines()]
34
+ # Clean up double spaces per line and strip leading/trailing whitespace on lines
35
+ lines = [re.sub(r' +', ' ', line).strip() for line in cleaned.splitlines()]
40
36
  return "\n".join(lines).strip()
@@ -0,0 +1,74 @@
1
+ """Update checker utility for Ace CLI."""
2
+
3
+ import json
4
+ import os
5
+ import time
6
+ import urllib.request
7
+ from pathlib import Path
8
+ from ace import __version__ as CURRENT_VERSION
9
+
10
+ CACHE_FILE = Path.home() / ".ace" / "version_cache.json"
11
+ CHECK_INTERVAL_SECONDS = 86400 # Check PyPI once per 24 hours
12
+
13
+
14
+ def check_for_updates() -> None:
15
+ """
16
+ Check PyPI for newer version of ace-git-copilot.
17
+ Display a non-intrusive notification if a newer version exists.
18
+ """
19
+ # Skip during CI runs
20
+ if os.getenv("CI") or os.getenv("GITHUB_ACTIONS"):
21
+ return
22
+
23
+ latest_version = None
24
+ now = time.time()
25
+
26
+ # Read cache
27
+ if CACHE_FILE.exists():
28
+ try:
29
+ data = json.loads(CACHE_FILE.read_text(encoding="utf-8"))
30
+ last_check = data.get("last_check", 0)
31
+ cached_latest = data.get("latest_version")
32
+ if now - last_check < CHECK_INTERVAL_SECONDS and cached_latest:
33
+ latest_version = cached_latest
34
+ except Exception:
35
+ pass
36
+
37
+ # Fetch from PyPI if cache expired or missing
38
+ if not latest_version:
39
+ try:
40
+ url = "https://pypi.org/pypi/ace-git-copilot/json"
41
+ req = urllib.request.Request(url, headers={"User-Agent": "ace-cli"})
42
+ with urllib.request.urlopen(req, timeout=0.8) as resp:
43
+ pypi_data = json.loads(resp.read().decode("utf-8"))
44
+ latest_version = pypi_data.get("info", {}).get("version")
45
+
46
+ # Write cache
47
+ if latest_version:
48
+ CACHE_FILE.parent.mkdir(parents=True, exist_ok=True)
49
+ CACHE_FILE.write_text(
50
+ json.dumps({"last_check": now, "latest_version": latest_version}),
51
+ encoding="utf-8",
52
+ )
53
+ except Exception:
54
+ return
55
+
56
+ if not latest_version:
57
+ return
58
+
59
+ def parse_ver(v_str: str):
60
+ try:
61
+ return tuple(int(x) for x in v_str.split("."))
62
+ except Exception:
63
+ return (0, 0, 0)
64
+
65
+ if parse_ver(latest_version) > parse_ver(CURRENT_VERSION):
66
+ try:
67
+ from ace.ui.display import console
68
+
69
+ console.print(
70
+ f"[dim yellow]💡 A new version of Ace is available: [bold]v{CURRENT_VERSION}[/bold] → [bold #00E676]v{latest_version}[/bold #00E676]. "
71
+ f"Run [bold cyan]pip install --upgrade ace-git-copilot[/bold cyan] to update.[/dim yellow]\n"
72
+ )
73
+ except Exception:
74
+ pass
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ace-git-copilot"
3
- version = "0.6.2"
3
+ version = "0.6.4"
4
4
  description = "AI-powered Git copilot — talk to Git in plain English"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -0,0 +1,22 @@
1
+ from ace.utils.update_checker import check_for_updates, CACHE_FILE, CHECK_INTERVAL_SECONDS
2
+ import time
3
+ import json
4
+
5
+
6
+ def test_update_checker_no_crash(monkeypatch, tmp_path):
7
+ # Ensure CI check doesn't skip
8
+ monkeypatch.delenv("CI", raising=False)
9
+ monkeypatch.delenv("GITHUB_ACTIONS", raising=False)
10
+
11
+ fake_cache = tmp_path / "version_cache.json"
12
+ monkeypatch.setattr("ace.utils.update_checker.CACHE_FILE", fake_cache)
13
+
14
+ # Write old cache
15
+ fake_cache.write_text(
16
+ json.dumps({"last_check": time.time(), "latest_version": "0.6.3"}),
17
+ encoding="utf-8",
18
+ )
19
+
20
+ # Run check_for_updates
21
+ check_for_updates()
22
+ assert fake_cache.exists()
@@ -1 +0,0 @@
1
- __version__ = "0.6.2"
File without changes