acra-cli 0.1.1__py3-none-any.whl

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 (169) hide show
  1. acra/__init__.py +7 -0
  2. acra/__main__.py +4 -0
  3. acra/agents/__init__.py +0 -0
  4. acra/agents/__pycache__/__init__.cpython-312.pyc +0 -0
  5. acra/agents/__pycache__/llm.cpython-312.pyc +0 -0
  6. acra/agents/__pycache__/llm_utils.cpython-312.pyc +0 -0
  7. acra/agents/coder/__init__.py +0 -0
  8. acra/agents/coder/__pycache__/__init__.cpython-312.pyc +0 -0
  9. acra/agents/coder/__pycache__/coder_agent.cpython-312.pyc +0 -0
  10. acra/agents/coder/__pycache__/coder_chain.cpython-312.pyc +0 -0
  11. acra/agents/coder/coder_agent.py +235 -0
  12. acra/agents/coder/coder_chain.py +204 -0
  13. acra/agents/critic/__init__.py +0 -0
  14. acra/agents/critic/__pycache__/__init__.cpython-312.pyc +0 -0
  15. acra/agents/critic/__pycache__/critic_agent.cpython-312.pyc +0 -0
  16. acra/agents/critic/__pycache__/critic_chain.cpython-312.pyc +0 -0
  17. acra/agents/critic/critic_agent.py +199 -0
  18. acra/agents/critic/critic_chain.py +268 -0
  19. acra/agents/executor/__init__.py +0 -0
  20. acra/agents/executor/__pycache__/__init__.cpython-312.pyc +0 -0
  21. acra/agents/executor/__pycache__/docker_runner.cpython-312.pyc +0 -0
  22. acra/agents/executor/__pycache__/executor_agent.cpython-312.pyc +0 -0
  23. acra/agents/executor/__pycache__/sandbox_runner.cpython-312.pyc +0 -0
  24. acra/agents/executor/docker_runner.py +114 -0
  25. acra/agents/executor/executor_agent.py +142 -0
  26. acra/agents/executor/sandbox_runner.py +144 -0
  27. acra/agents/human/__init__.py +0 -0
  28. acra/agents/human/__pycache__/__init__.cpython-312.pyc +0 -0
  29. acra/agents/human/__pycache__/human_node.cpython-312.pyc +0 -0
  30. acra/agents/human/human_node.py +37 -0
  31. acra/agents/llm.py +263 -0
  32. acra/agents/llm_utils.py +161 -0
  33. acra/agents/memory/__init__.py +0 -0
  34. acra/agents/memory/__pycache__/__init__.cpython-312.pyc +0 -0
  35. acra/agents/memory/__pycache__/memory_agent.cpython-312.pyc +0 -0
  36. acra/agents/memory/__pycache__/memory_manager.cpython-312.pyc +0 -0
  37. acra/agents/memory/__pycache__/retrieval.cpython-312.pyc +0 -0
  38. acra/agents/memory/memory_agent.py +239 -0
  39. acra/agents/memory/memory_manager.py +273 -0
  40. acra/agents/memory/retrieval.py +355 -0
  41. acra/agents/planner/__init__.py +0 -0
  42. acra/agents/planner/__pycache__/__init__.cpython-312.pyc +0 -0
  43. acra/agents/planner/__pycache__/planner_agent.cpython-312.pyc +0 -0
  44. acra/agents/planner/__pycache__/planner_chain.cpython-312.pyc +0 -0
  45. acra/agents/planner/planner_agent.py +97 -0
  46. acra/agents/planner/planner_chain.py +160 -0
  47. acra/agents/researcher/__init__.py +1 -0
  48. acra/agents/researcher/__pycache__/__init__.cpython-312.pyc +0 -0
  49. acra/agents/researcher/__pycache__/researcher_agent.cpython-312.pyc +0 -0
  50. acra/agents/researcher/__pycache__/researcher_chain.cpython-312.pyc +0 -0
  51. acra/agents/researcher/researcher_agent.py +231 -0
  52. acra/agents/researcher/researcher_chain.py +193 -0
  53. acra/brain/__init__.py +6 -0
  54. acra/brain/model_registry.py +19 -0
  55. acra/brain/provider_manager.py +21 -0
  56. acra/cli.py +52 -0
  57. acra/commands/__init__.py +29 -0
  58. acra/commands/ask.py +49 -0
  59. acra/commands/brain.py +58 -0
  60. acra/commands/config.py +25 -0
  61. acra/commands/context.py +30 -0
  62. acra/commands/graph.py +18 -0
  63. acra/commands/keys.py +40 -0
  64. acra/commands/logs.py +13 -0
  65. acra/commands/memory.py +27 -0
  66. acra/commands/plugin.py +18 -0
  67. acra/commands/research.py +65 -0
  68. acra/commands/serve.py +13 -0
  69. acra/commands/session.py +20 -0
  70. acra/commands/utils.py +12 -0
  71. acra/config/__init__.py +36 -0
  72. acra/config/__pycache__/__init__.cpython-312.pyc +0 -0
  73. acra/config/__pycache__/defaults.cpython-312.pyc +0 -0
  74. acra/config/__pycache__/profile_manager.cpython-312.pyc +0 -0
  75. acra/config/defaults.py +88 -0
  76. acra/config/profile_manager.py +87 -0
  77. acra/execution/__init__.py +1 -0
  78. acra/execution/logs/__init__.py +1 -0
  79. acra/execution/logs/error_logs/__init__.py +1 -0
  80. acra/execution/logs/execution_logs/__init__.py +1 -0
  81. acra/execution/sandbox/__init__.py +1 -0
  82. acra/execution/sandbox/docker_executor.py +209 -0
  83. acra/execution/sandbox/isolated_runner.py +148 -0
  84. acra/execution/sandbox/sandbox_manager.py +178 -0
  85. acra/graph/__init__.py +0 -0
  86. acra/graph/checkpoint.py +85 -0
  87. acra/graph/conditional_edges.py +103 -0
  88. acra/graph/edges.py +85 -0
  89. acra/graph/graph_visualizer.py +175 -0
  90. acra/graph/nodes.py +68 -0
  91. acra/graph/router.py +69 -0
  92. acra/graph/state.py +93 -0
  93. acra/graph/workflow.py +117 -0
  94. acra/memory/__init__.py +1 -0
  95. acra/memory/checkpoints/__init__.py +1 -0
  96. acra/memory/checkpoints/data/__init__.py +1 -0
  97. acra/memory/checkpoints/postgres_checkpoint.py +247 -0
  98. acra/memory/checkpoints/sqlite_checkpoint.py +309 -0
  99. acra/memory/chroma_db/__init__.py +1 -0
  100. acra/memory/conversation_memory/__init__.py +1 -0
  101. acra/memory/conversation_memory/long_term.py +229 -0
  102. acra/memory/conversation_memory/short_term.py +158 -0
  103. acra/memory/storage/__init__.py +1 -0
  104. acra/memory/vector_store/__init__.py +0 -0
  105. acra/memory/vector_store/chroma_store.py +260 -0
  106. acra/memory/vector_store/embeddings.py +43 -0
  107. acra/observability/__init__.py +1 -0
  108. acra/observability/langsmith_tracing.py +91 -0
  109. acra/observability/metrics.py +189 -0
  110. acra/observability/monitoring.py +162 -0
  111. acra/observability/token_tracking.py +131 -0
  112. acra/prompts/__init__.py +1 -0
  113. acra/schemas/__init__.py +0 -0
  114. acra/schemas/__pycache__/__init__.cpython-312.pyc +0 -0
  115. acra/schemas/__pycache__/coder_schema.cpython-312.pyc +0 -0
  116. acra/schemas/__pycache__/critic_schema.cpython-312.pyc +0 -0
  117. acra/schemas/__pycache__/execution_schema.cpython-312.pyc +0 -0
  118. acra/schemas/__pycache__/planner_schema.cpython-312.pyc +0 -0
  119. acra/schemas/__pycache__/researcher_schema.cpython-312.pyc +0 -0
  120. acra/schemas/__pycache__/shared_schema.cpython-312.pyc +0 -0
  121. acra/schemas/coder_schema.py +257 -0
  122. acra/schemas/critic_schema.py +177 -0
  123. acra/schemas/execution_schema.py +74 -0
  124. acra/schemas/planner_schema.py +129 -0
  125. acra/schemas/researcher_schema.py +220 -0
  126. acra/schemas/shared_schema.py +329 -0
  127. acra/tools/__init__.py +1 -0
  128. acra/tools/code_tools/__init__.py +1 -0
  129. acra/tools/code_tools/file_reader.py +156 -0
  130. acra/tools/code_tools/file_writer.py +108 -0
  131. acra/tools/code_tools/python_repl.py +72 -0
  132. acra/tools/code_tools/terminal_runner.py +98 -0
  133. acra/tools/github_tools/__init__.py +1 -0
  134. acra/tools/github_tools/commit_generator.py +91 -0
  135. acra/tools/github_tools/github_search.py +113 -0
  136. acra/tools/github_tools/repo_analyzer.py +138 -0
  137. acra/tools/integration_test_helper.py +370 -0
  138. acra/tools/validation_tools/__init__.py +1 -0
  139. acra/tools/validation_tools/dependency_checker.py +101 -0
  140. acra/tools/validation_tools/environment_config_validator.py +353 -0
  141. acra/tools/validation_tools/http_validator.py +336 -0
  142. acra/tools/validation_tools/response_validator.py +407 -0
  143. acra/tools/validation_tools/security_checker.py +93 -0
  144. acra/tools/validation_tools/syntax_checker.py +75 -0
  145. acra/tools/validation_tools/web_framework_validator.py +382 -0
  146. acra/tools/web_tools/__init__.py +1 -0
  147. acra/tools/web_tools/arxiv_search.py +110 -0
  148. acra/tools/web_tools/serpapi_search.py +106 -0
  149. acra/tools/web_tools/tavily_search.py +96 -0
  150. acra/ui/__init__.py +8 -0
  151. acra/ui/__pycache__/__init__.cpython-312.pyc +0 -0
  152. acra/ui/__pycache__/banner.cpython-312.pyc +0 -0
  153. acra/ui/__pycache__/components.cpython-312.pyc +0 -0
  154. acra/ui/__pycache__/shell.cpython-312.pyc +0 -0
  155. acra/ui/__pycache__/theme.cpython-312.pyc +0 -0
  156. acra/ui/banner.py +40 -0
  157. acra/ui/components.py +32 -0
  158. acra/ui/shell.py +91 -0
  159. acra/ui/theme.py +28 -0
  160. acra/utils/__init__.py +21 -0
  161. acra/utils/context_manager.py +20 -0
  162. acra/utils/keyring_manager.py +83 -0
  163. acra/utils/output_formatter.py +18 -0
  164. acra/utils/session_manager.py +59 -0
  165. acra_cli-0.1.1.dist-info/METADATA +616 -0
  166. acra_cli-0.1.1.dist-info/RECORD +169 -0
  167. acra_cli-0.1.1.dist-info/WHEEL +5 -0
  168. acra_cli-0.1.1.dist-info/licenses/LICENSE +661 -0
  169. acra_cli-0.1.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,108 @@
1
+ import logging
2
+ from pathlib import Path
3
+ from typing import Dict
4
+
5
+ from acra.config import GENERATED_PROJECT_DIR, PROJECT_ROOT
6
+
7
+
8
+ # file writer tool
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+
13
+ def _resolve_allowed_path(filepath: str) -> Path:
14
+ target = Path(filepath).expanduser().resolve()
15
+ allowed_roots = [
16
+ Path(PROJECT_ROOT).resolve(),
17
+ Path(GENERATED_PROJECT_DIR).resolve(),
18
+ ]
19
+
20
+ if not any(target == root or target.is_relative_to(root) for root in allowed_roots):
21
+ raise ValueError(f"Refusing to write outside allowed roots: {filepath}")
22
+
23
+ return target
24
+
25
+
26
+ class FileWriterTool:
27
+ """
28
+ File writing utility.
29
+
30
+ Responsibilities:
31
+ - create files
32
+ - update files
33
+ - create directories
34
+ - support generated projects
35
+ """
36
+
37
+
38
+ # write file
39
+
40
+ @staticmethod
41
+ def write_file(
42
+ filepath: str,
43
+ content: str
44
+ ) -> Dict:
45
+ """
46
+ Write content to file.
47
+ """
48
+
49
+ try:
50
+ safe_path = _resolve_allowed_path(filepath)
51
+
52
+ safe_path.parent.mkdir(
53
+ parents=True,
54
+ exist_ok=True
55
+ )
56
+
57
+ with open(
58
+ safe_path,
59
+ "w",
60
+ encoding="utf-8"
61
+ ) as f:
62
+
63
+ f.write(content)
64
+
65
+ logger.info(f"File written: {filepath} ({len(content)} bytes)")
66
+
67
+ return {
68
+
69
+ "success": True,
70
+
71
+ "filepath": str(safe_path)
72
+ }
73
+
74
+ except Exception as e:
75
+ logger.error(f"Failed to write file {filepath}: {e}", exc_info=True)
76
+
77
+ return {
78
+
79
+ "success": False,
80
+
81
+ "filepath": filepath,
82
+
83
+ "error": str(e)
84
+ }
85
+
86
+
87
+ # write multiple files
88
+
89
+ @staticmethod
90
+ def write_files(
91
+ files: Dict[str, str]
92
+ ) -> Dict:
93
+ """
94
+ Write multiple files.
95
+ """
96
+
97
+ results = {}
98
+
99
+ for filepath, content in files.items():
100
+
101
+ results[filepath] = (
102
+ FileWriterTool.write_file(
103
+ filepath=filepath,
104
+ content=content
105
+ )
106
+ )
107
+
108
+ return results
@@ -0,0 +1,72 @@
1
+ import contextlib
2
+ import io
3
+ import traceback
4
+ from typing import Dict
5
+
6
+
7
+ # python repl tool
8
+
9
+ class PythonREPLTool:
10
+ """
11
+ Dynamic Python execution tool.
12
+
13
+ Responsibilities:
14
+ - execute Python snippets
15
+ - capture stdout/stderr
16
+ - support debugging workflows
17
+ - provide runtime experimentation
18
+ """
19
+
20
+ def __init__(self):
21
+ pass
22
+
23
+
24
+ # execute tool
25
+
26
+ def execute(
27
+ self,
28
+ code: str
29
+ ) -> Dict:
30
+ """
31
+ Execute Python code safely with fresh globals for each execution.
32
+ """
33
+
34
+ fresh_globals = {}
35
+ stdout_buffer = io.StringIO()
36
+
37
+ try:
38
+
39
+ with contextlib.redirect_stdout(
40
+ stdout_buffer
41
+ ):
42
+
43
+ exec(code, fresh_globals)
44
+
45
+ return {
46
+
47
+ "success": True,
48
+
49
+ "stdout": (
50
+ stdout_buffer.getvalue()
51
+ ),
52
+
53
+ "error": None
54
+ }
55
+
56
+ except Exception:
57
+
58
+ return {
59
+
60
+ "success": False,
61
+
62
+ "stdout": (
63
+ stdout_buffer.getvalue()
64
+ ),
65
+
66
+ "error": traceback.format_exc()
67
+ }
68
+
69
+
70
+ # global helper
71
+
72
+ python_repl = PythonREPLTool()
@@ -0,0 +1,98 @@
1
+ import subprocess
2
+ from typing import Dict, Optional
3
+
4
+
5
+ # terminal runner tool
6
+
7
+ class TerminalRunnerTool:
8
+ """
9
+ Terminal command execution tool.
10
+
11
+ Responsibilities:
12
+ - execute shell commands
13
+ - capture stdout/stderr
14
+ - support workflow automation
15
+ - assist execution/debugging
16
+ """
17
+
18
+
19
+ # run command
20
+
21
+ @staticmethod
22
+ def run_command(
23
+ command: str,
24
+ cwd: Optional[str] = None,
25
+ timeout: int = 60
26
+ ) -> Dict:
27
+ """
28
+ Execute terminal command.
29
+ """
30
+
31
+ try:
32
+
33
+ result = subprocess.run(
34
+
35
+ command,
36
+
37
+ shell=True,
38
+
39
+ capture_output=True,
40
+
41
+ text=True,
42
+
43
+ cwd=cwd,
44
+
45
+ timeout=timeout
46
+ )
47
+
48
+ success = (
49
+ result.returncode == 0
50
+ )
51
+
52
+ return {
53
+
54
+ "success": success,
55
+
56
+ "command": command,
57
+
58
+ "stdout": result.stdout,
59
+
60
+ "stderr": result.stderr,
61
+
62
+ "return_code": (
63
+ result.returncode
64
+ )
65
+ }
66
+
67
+ except subprocess.TimeoutExpired:
68
+
69
+ return {
70
+
71
+ "success": False,
72
+
73
+ "command": command,
74
+
75
+ "stdout": "",
76
+
77
+ "stderr": (
78
+ "Command timed out."
79
+ )
80
+ }
81
+
82
+ except Exception as e:
83
+
84
+ return {
85
+
86
+ "success": False,
87
+
88
+ "command": command,
89
+
90
+ "stdout": "",
91
+
92
+ "stderr": str(e)
93
+ }
94
+
95
+
96
+ # global helper
97
+
98
+ terminal_runner = TerminalRunnerTool()
@@ -0,0 +1 @@
1
+ # Package acra/tools/github_tools
@@ -0,0 +1,91 @@
1
+ from typing import Dict, List
2
+
3
+
4
+ # commit generator tool
5
+
6
+ class CommitMessageGenerator:
7
+ """
8
+ Git commit message generator.
9
+
10
+ Responsibilities:
11
+ - generate meaningful commit messages
12
+ - summarize code changes
13
+ - support workflow automation
14
+ """
15
+
16
+
17
+ # generate commit msg
18
+
19
+ @staticmethod
20
+ def generate_commit_message(
21
+ changed_files: List[str],
22
+ change_summary: str,
23
+ commit_type: str = "feat"
24
+ ) -> Dict:
25
+ """
26
+ Generate standardized commit message.
27
+ """
28
+
29
+ try:
30
+
31
+ short_summary = (
32
+ change_summary.strip()
33
+ .replace("\n", " ")
34
+ )
35
+
36
+ if len(short_summary) > 72:
37
+
38
+ short_summary = (
39
+ short_summary[:72] + "..."
40
+ )
41
+
42
+ commit_message = (
43
+ f"{commit_type}: "
44
+ f"{short_summary}"
45
+ )
46
+
47
+ detailed_description = {
48
+
49
+ "commit_message": commit_message,
50
+
51
+ "changed_files": changed_files,
52
+
53
+ "summary": change_summary
54
+ }
55
+
56
+ return {
57
+
58
+ "success": True,
59
+
60
+ "commit": detailed_description
61
+ }
62
+
63
+ except Exception as e:
64
+
65
+ return {
66
+
67
+ "success": False,
68
+
69
+ "error": str(e)
70
+ }
71
+
72
+
73
+ # global helper
74
+
75
+ def generate_commit_message(
76
+ changed_files: List[str],
77
+ change_summary: str,
78
+ commit_type: str = "feat"
79
+ ) -> Dict:
80
+ """
81
+ Simple commit generator helper.
82
+ """
83
+
84
+ return (
85
+ CommitMessageGenerator
86
+ .generate_commit_message(
87
+ changed_files=changed_files,
88
+ change_summary=change_summary,
89
+ commit_type=commit_type
90
+ )
91
+ )
@@ -0,0 +1,113 @@
1
+ import os
2
+ from typing import Dict, List
3
+
4
+ from github import Github
5
+
6
+
7
+ # github client
8
+
9
+ GITHUB_TOKEN = os.getenv(
10
+ "GITHUB_TOKEN"
11
+ )
12
+
13
+ github_client = Github(GITHUB_TOKEN)
14
+
15
+
16
+ # github search tool
17
+
18
+ class GitHubSearchTool:
19
+ """
20
+ GitHub repository search tool.
21
+
22
+ Responsibilities:
23
+ - search repositories
24
+ - retrieve implementation references
25
+ - support technical research
26
+ - discover open-source patterns
27
+ """
28
+
29
+ def __init__(
30
+ self,
31
+ max_results: int = 5
32
+ ):
33
+
34
+ self.max_results = max_results
35
+
36
+
37
+ # search repo
38
+
39
+ def search_repositories(
40
+ self,
41
+ query: str
42
+ ) -> Dict:
43
+ """
44
+ Search GitHub repositories.
45
+ """
46
+
47
+ try:
48
+
49
+ repositories = (
50
+ github_client.search_repositories(
51
+ query=query
52
+ )
53
+ )
54
+
55
+ results = []
56
+
57
+ for repo in repositories[
58
+ :self.max_results
59
+ ]:
60
+
61
+ results.append({
62
+
63
+ "name": repo.full_name,
64
+
65
+ "description": repo.description,
66
+
67
+ "stars": repo.stargazers_count,
68
+
69
+ "language": repo.language,
70
+
71
+ "url": repo.html_url,
72
+
73
+ "topics": repo.get_topics()
74
+ })
75
+
76
+ return {
77
+
78
+ "success": True,
79
+
80
+ "query": query,
81
+
82
+ "repositories": results
83
+ }
84
+
85
+ except Exception as e:
86
+
87
+ return {
88
+
89
+ "success": False,
90
+
91
+ "query": query,
92
+
93
+ "error": str(e),
94
+
95
+ "repositories": []
96
+ }
97
+
98
+
99
+ # global helper
100
+
101
+ def github_search(
102
+ query: str,
103
+ max_results: int = 5
104
+ ) -> Dict:
105
+ """
106
+ Simple GitHub repository search helper.
107
+ """
108
+
109
+ tool = GitHubSearchTool(
110
+ max_results=max_results
111
+ )
112
+
113
+ return tool.search_repositories(query)
@@ -0,0 +1,138 @@
1
+ import os
2
+ from typing import Dict, List
3
+
4
+ from github import Github
5
+
6
+
7
+ # github client
8
+
9
+ GITHUB_TOKEN = os.getenv(
10
+ "GITHUB_TOKEN"
11
+ )
12
+
13
+ github_client = Github(GITHUB_TOKEN)
14
+
15
+
16
+ # repo analyzer
17
+
18
+ class RepoAnalyzerTool:
19
+ """
20
+ GitHub repository analysis tool.
21
+
22
+ Responsibilities:
23
+ - inspect repository structure
24
+ - analyze technologies
25
+ - retrieve important files
26
+ - support implementation research
27
+ """
28
+
29
+
30
+ # analyze repo
31
+
32
+ def analyze_repository(
33
+ self,
34
+ repo_name: str
35
+ ) -> Dict:
36
+ """
37
+ Analyze GitHub repository.
38
+ """
39
+
40
+ try:
41
+
42
+ repo = github_client.get_repo(
43
+ repo_name
44
+ )
45
+
46
+ contents = repo.get_contents("")
47
+
48
+ file_structure = []
49
+
50
+ important_files = []
51
+
52
+ while contents:
53
+
54
+ file_content = contents.pop(0)
55
+
56
+ if file_content.type == "dir":
57
+
58
+ contents.extend(
59
+ repo.get_contents(
60
+ file_content.path
61
+ )
62
+ )
63
+
64
+ else:
65
+
66
+ file_structure.append(
67
+ file_content.path
68
+ )
69
+
70
+ if any(
71
+
72
+ keyword in file_content.path.lower()
73
+
74
+ for keyword in [
75
+
76
+ "readme",
77
+ "requirements",
78
+ "dockerfile",
79
+ "package.json",
80
+ "main.py",
81
+ "app.py"
82
+ ]
83
+ ):
84
+
85
+ important_files.append({
86
+
87
+ "path": file_content.path,
88
+
89
+ "download_url": (
90
+ file_content.download_url
91
+ )
92
+ })
93
+
94
+ return {
95
+
96
+ "success": True,
97
+
98
+ "repository": repo.full_name,
99
+
100
+ "description": repo.description,
101
+
102
+ "stars": repo.stargazers_count,
103
+
104
+ "language": repo.language,
105
+
106
+ "topics": repo.get_topics(),
107
+
108
+ "file_count": len(file_structure),
109
+
110
+ "important_files": important_files,
111
+
112
+ "file_structure": file_structure[:100]
113
+ }
114
+
115
+ except Exception as e:
116
+
117
+ return {
118
+
119
+ "success": False,
120
+
121
+ "repository": repo_name,
122
+
123
+ "error": str(e)
124
+ }
125
+
126
+
127
+ # global helper
128
+
129
+ def analyze_repository(
130
+ repo_name: str
131
+ ) -> Dict:
132
+ """
133
+ Simple repository analyzer helper.
134
+ """
135
+
136
+ tool = RepoAnalyzerTool()
137
+
138
+ return tool.analyze_repository(repo_name)