ace-git-copilot 0.4.0__tar.gz → 0.4.2__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.4.0 → ace_git_copilot-0.4.2}/PKG-INFO +1 -1
- ace_git_copilot-0.4.2/ace/__init__.py +1 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/ai/history_analyzer.py +2 -1
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/cli.py +75 -23
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/pyproject.toml +1 -1
- ace_git_copilot-0.4.2/tests/test_interceptor.py +42 -0
- ace_git_copilot-0.4.0/ace/__init__.py +0 -1
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/AGENTS.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/BRIEFING.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/ORIGINAL_REQUEST.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/e2e_testing_track/BRIEFING.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/e2e_testing_track/ORIGINAL_REQUEST.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/e2e_testing_track/SCOPE.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/e2e_testing_track/progress.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/explorer_init/BRIEFING.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/explorer_init/ORIGINAL_REQUEST.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/explorer_init/emojis_list.txt +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/explorer_init/find_unused_modules.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/explorer_init/handoff.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/explorer_init/measure_lazy_startup.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/explorer_init/measure_startup.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/explorer_init/profile_imports.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/explorer_init/progress.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/explorer_init/run_importtime.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/explorer_init/search_banner.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/explorer_init/search_emojis.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/explorer_init/search_git_usages.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/explorer_init/search_usages.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/explorer_init/test_import_profiler.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/explorer_init/test_mocked_sys.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/handoff.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/implementation_track/BRIEFING.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/implementation_track/ORIGINAL_REQUEST.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/implementation_track/explorer_initial_report.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/implementation_track/progress.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/orchestrator/.gitkeep +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/orchestrator/BRIEFING.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/orchestrator/ORIGINAL_REQUEST.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/orchestrator/PROJECT.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/orchestrator/progress.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/teamwork_preview_explorer_e2e_explore/BRIEFING.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/teamwork_preview_explorer_e2e_explore/ORIGINAL_REQUEST.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/teamwork_preview_explorer_e2e_explore/handoff.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/teamwork_preview_explorer_e2e_explore/progress.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/worker_e2e_testing/BRIEFING.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/worker_e2e_testing/ORIGINAL_REQUEST.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/worker_e2e_testing/progress.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/worker_m1_startup/BRIEFING.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/worker_m1_startup/ORIGINAL_REQUEST.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/worker_m1_startup/progress.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.env.example +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.github/workflows/tests.yml +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.gitignore +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/CODE_OF_CONDUCT.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/CONTRIBUTING.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/LICENSE +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/PROJECT.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/README.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/SECURITY.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/SUPPORT.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/TEST_INFRA.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/TEST_READY.md +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/__main__.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/ai/changelog_generator.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/ai/code_reviewer.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/ai/commit_generator.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/ai/conflict_resolver.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/ai/gitignore_generator.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/ai/intent_parser.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/ai/llm_factory.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/ai/pr_drafter.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/ai/prompts/blame.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/ai/prompts/changelog.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/ai/prompts/commit.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/ai/prompts/conflict.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/ai/prompts/doctor.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/ai/prompts/explain.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/ai/prompts/ignore.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/ai/prompts/intent.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/ai/prompts/pr.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/ai/prompts/rebase.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/ai/prompts/review.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/ai/prompts/search.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/ai/prompts/standup.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/ai/prompts/undo.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/ai/rebase_helper.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/core/config.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/core/context.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/core/diagnostics.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/core/git_ops.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/core/hooks.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/core/safety.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/ui/banner.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/ui/dashboard.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/ui/display.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/ui/prompts.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/ui/themes.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/utils/conflict_parser.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/utils/diff_parser.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/utils/json_utils.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/ace/utils/string_utils.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/conftest.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/e2e/conftest.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/e2e/test_tier1_features.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/e2e/test_tier2_boundaries.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/e2e/test_tier3_combinations.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/e2e/test_tier4_workloads.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/test_blame.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/test_changelog_generator.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/test_code_reviewer.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/test_config_atomic_write.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/test_conflict_resolver.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/test_conflict_resolver_backup.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/test_context_gitdir_detection.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/test_diagnostics.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/test_diff_trimmer.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/test_git_ops.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/test_git_ops_execute.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/test_help.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/test_history_analyzer.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/test_hooks.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/test_ignore.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/test_intent_parser.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/test_llm_factory.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/test_llm_factory_ollama.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/test_merge_state.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/test_pr_drafter.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/test_rebase_helper.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/test_safety.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/test_search.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/test_standup.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/test_string_utils.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/tests/test_undo.py +0 -0
- {ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/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.4.
|
|
3
|
+
Version: 0.4.2
|
|
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.4.2"
|
|
@@ -196,7 +196,8 @@ class HistoryAnalyzer:
|
|
|
196
196
|
|
|
197
197
|
commit_lines = []
|
|
198
198
|
for c in commits:
|
|
199
|
-
|
|
199
|
+
repo_prefix = f"[{c['repo_name']}] " if "repo_name" in c else ""
|
|
200
|
+
commit_lines.append(f"- {repo_prefix}{c['hexsha'][:7]} - {c['summary']} (by {c['author']})")
|
|
200
201
|
commit_list_text = "\n".join(commit_lines)
|
|
201
202
|
|
|
202
203
|
from ace.ai.prompts.standup import STANDUP_SYSTEM_PROMPT, USER_PROMPT_TEMPLATE
|
|
@@ -84,16 +84,38 @@ def main(
|
|
|
84
84
|
from ace.core.safety import SafetyChecker
|
|
85
85
|
from ace.ui.prompts import confirm
|
|
86
86
|
|
|
87
|
-
if
|
|
87
|
+
# Intercept subcommand if the user typed an English sentence (e.g. 'ace add and commit')
|
|
88
|
+
intercepted_query = None
|
|
89
|
+
if ctx.invoked_subcommand in ("add", "stage", "commit", "review", "explain", "resolve", "search"):
|
|
90
|
+
import sys
|
|
91
|
+
sub_cmd = ctx.invoked_subcommand
|
|
92
|
+
sub_idx = -1
|
|
93
|
+
for idx, arg in enumerate(sys.argv):
|
|
94
|
+
if arg == sub_cmd and idx > 0 and not sys.argv[idx - 1].startswith("-"):
|
|
95
|
+
sub_idx = idx
|
|
96
|
+
break
|
|
97
|
+
if sub_idx != -1:
|
|
98
|
+
sub_args = sys.argv[sub_idx + 1:]
|
|
99
|
+
nl_indicators = {"and", "with", "to", "the", "a", "new", "my", "all", "but", "yesterday", "last", "from", "for", "changed", "everything"}
|
|
100
|
+
if any(arg.lower() in nl_indicators for arg in sub_args):
|
|
101
|
+
query_parts = []
|
|
102
|
+
for arg in sys.argv[1:]:
|
|
103
|
+
if arg.startswith("-"):
|
|
104
|
+
continue
|
|
105
|
+
query_parts.append(arg)
|
|
106
|
+
intercepted_query = " ".join(query_parts)
|
|
107
|
+
|
|
108
|
+
if intercepted_query:
|
|
109
|
+
query = intercepted_query
|
|
110
|
+
elif ctx.invoked_subcommand is not None:
|
|
88
111
|
# A subcommand was invoked, let it execute
|
|
89
112
|
return
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
query = " ".join(ctx.args)
|
|
113
|
+
else:
|
|
114
|
+
if not ctx.args:
|
|
115
|
+
# No query and no subcommand, Typer will show help
|
|
116
|
+
console.print(ctx.get_help())
|
|
117
|
+
raise typer.Exit()
|
|
118
|
+
query = " ".join(ctx.args)
|
|
97
119
|
|
|
98
120
|
# Initialize GitOps
|
|
99
121
|
try:
|
|
@@ -1898,36 +1920,66 @@ def standup_cmd(
|
|
|
1898
1920
|
from ace.ai.history_analyzer import HistoryAnalyzer
|
|
1899
1921
|
from rich.markdown import Markdown
|
|
1900
1922
|
from rich.panel import Panel
|
|
1923
|
+
import pathlib
|
|
1901
1924
|
|
|
1925
|
+
current_dir = pathlib.Path(".")
|
|
1926
|
+
repos_found = []
|
|
1927
|
+
|
|
1928
|
+
# 1. Try active repository in current folder
|
|
1902
1929
|
try:
|
|
1903
1930
|
git_ops = GitOps()
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
# 1. Resolve author filter
|
|
1909
|
-
author_name = None
|
|
1910
|
-
if not all_authors:
|
|
1931
|
+
repos_found.append((current_dir.resolve().name, git_ops))
|
|
1932
|
+
except NotAGitRepositoryError:
|
|
1933
|
+
# Fallback: scan immediate subdirectories for sibling repositories
|
|
1911
1934
|
try:
|
|
1912
|
-
|
|
1935
|
+
for child in sorted(current_dir.iterdir()):
|
|
1936
|
+
if child.is_dir() and ((child / ".git").exists() or (child / "gitdir").exists() or child.name.endswith(".git")):
|
|
1937
|
+
try:
|
|
1938
|
+
repos_found.append((child.name, GitOps(str(child))))
|
|
1939
|
+
except Exception:
|
|
1940
|
+
pass
|
|
1913
1941
|
except Exception:
|
|
1914
1942
|
pass
|
|
1915
1943
|
|
|
1916
|
-
|
|
1944
|
+
if not repos_found:
|
|
1945
|
+
show_error_panel("Not a git repository (or any of the parent directories).", "Git Error")
|
|
1946
|
+
raise typer.Exit(code=1)
|
|
1947
|
+
|
|
1948
|
+
# 2. Gather commits from all resolved repositories
|
|
1949
|
+
all_commits = []
|
|
1917
1950
|
since_arg = f"{days} days ago"
|
|
1918
|
-
commits = git_ops.get_log(since=since_arg, author=author_name)
|
|
1919
1951
|
|
|
1920
|
-
|
|
1952
|
+
# We need a primary git_ops instance to initialize HistoryAnalyzer
|
|
1953
|
+
primary_git_ops = repos_found[0][1]
|
|
1954
|
+
|
|
1955
|
+
for repo_name, git_ops in repos_found:
|
|
1956
|
+
author_name = None
|
|
1957
|
+
if not all_authors:
|
|
1958
|
+
try:
|
|
1959
|
+
author_name = git_ops.repo.git.config("user.name")
|
|
1960
|
+
except Exception:
|
|
1961
|
+
pass
|
|
1962
|
+
|
|
1963
|
+
try:
|
|
1964
|
+
repo_commits = git_ops.get_log(since=since_arg, author=author_name)
|
|
1965
|
+
for c in repo_commits:
|
|
1966
|
+
c["repo_name"] = repo_name
|
|
1967
|
+
all_commits.append(c)
|
|
1968
|
+
except Exception:
|
|
1969
|
+
pass
|
|
1970
|
+
|
|
1971
|
+
if not all_commits:
|
|
1921
1972
|
author_msg = "your" if not all_authors else "any"
|
|
1922
|
-
|
|
1973
|
+
scope_msg = "this repository" if len(repos_found) == 1 else f"{len(repos_found)} repositories in this directory"
|
|
1974
|
+
print_warning(f"No recent commits found from {author_msg} author in {scope_msg} in the last {days} day(s).")
|
|
1923
1975
|
raise typer.Exit(code=0)
|
|
1924
1976
|
|
|
1925
|
-
analyzer = HistoryAnalyzer(
|
|
1977
|
+
analyzer = HistoryAnalyzer(primary_git_ops)
|
|
1926
1978
|
|
|
1927
1979
|
try:
|
|
1928
1980
|
get_llm(offline_override=offline)
|
|
1929
|
-
with spinner(f"Analyzing {len(
|
|
1930
|
-
standup_report = analyzer.generate_standup(
|
|
1981
|
+
with spinner(f"Analyzing {len(all_commits)} commits across {len(repos_found)} repo(s) and generating standup..."):
|
|
1982
|
+
standup_report = analyzer.generate_standup(all_commits, offline=offline)
|
|
1931
1983
|
except Exception as e:
|
|
1932
1984
|
show_error_panel(f"Failed to generate standup: {e}", "AI Error")
|
|
1933
1985
|
raise typer.Exit(code=1)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from unittest.mock import MagicMock, patch
|
|
2
|
+
import sys
|
|
3
|
+
from typer.testing import CliRunner
|
|
4
|
+
from ace.cli import app
|
|
5
|
+
|
|
6
|
+
runner = CliRunner()
|
|
7
|
+
|
|
8
|
+
@patch("ace.core.git_ops.GitOps")
|
|
9
|
+
@patch("ace.ai.llm_factory.get_llm")
|
|
10
|
+
@patch("ace.ai.intent_parser.IntentParser")
|
|
11
|
+
def test_subcommand_interceptor_nl(mock_parser_class, mock_get_llm, mock_git_ops_class):
|
|
12
|
+
# Setup mocks
|
|
13
|
+
mock_git_ops = MagicMock()
|
|
14
|
+
mock_git_ops_class.return_value = mock_git_ops
|
|
15
|
+
|
|
16
|
+
mock_parser = MagicMock()
|
|
17
|
+
mock_parser.parse_intent.return_value = {"commands": [], "explanation": "NL query matched"}
|
|
18
|
+
mock_parser_class.return_value = mock_parser
|
|
19
|
+
|
|
20
|
+
# We mock sys.argv to simulate running: ace add and commit
|
|
21
|
+
with patch.object(sys, "argv", ["ace", "add", "and", "commit"]):
|
|
22
|
+
# Run command without subcommand routing triggering
|
|
23
|
+
result = runner.invoke(app, ["add", "and", "commit"])
|
|
24
|
+
|
|
25
|
+
assert result.exit_code == 0
|
|
26
|
+
# The IntentParser should have been called with the combined string
|
|
27
|
+
mock_parser.parse_intent.assert_called_once_with("add and commit", offline=False)
|
|
28
|
+
|
|
29
|
+
@patch("ace.core.git_ops.GitOps")
|
|
30
|
+
def test_subcommand_interceptor_normal_subcmd(mock_git_ops_class):
|
|
31
|
+
# Setup mock to fail staging of a non-existent file
|
|
32
|
+
mock_git_ops = MagicMock()
|
|
33
|
+
mock_git_ops.execute.side_effect = Exception("failed to stage")
|
|
34
|
+
mock_git_ops_class.return_value = mock_git_ops
|
|
35
|
+
|
|
36
|
+
# Simulate: ace add file1.txt (no NL indicators)
|
|
37
|
+
with patch.object(sys, "argv", ["ace", "add", "file1.txt"]):
|
|
38
|
+
result = runner.invoke(app, ["add", "file1.txt"])
|
|
39
|
+
|
|
40
|
+
# Normal execution path: it routes to the add subcommand, tries to run git add, and fails
|
|
41
|
+
assert result.exit_code == 1
|
|
42
|
+
mock_git_ops.execute.assert_called_once_with("add file1.txt")
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.4.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/e2e_testing_track/ORIGINAL_REQUEST.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/explorer_init/find_unused_modules.py
RENAMED
|
File without changes
|
|
File without changes
|
{ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/explorer_init/measure_lazy_startup.py
RENAMED
|
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
|
{ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/explorer_init/test_import_profiler.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/implementation_track/ORIGINAL_REQUEST.md
RENAMED
|
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
|
{ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/worker_e2e_testing/ORIGINAL_REQUEST.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ace_git_copilot-0.4.0 → ace_git_copilot-0.4.2}/.agents/worker_m1_startup/ORIGINAL_REQUEST.md
RENAMED
|
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
|
|
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
|