code-lm 0.2.3__tar.gz → 0.2.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.
- {code_lm-0.2.3/src/code_lm.egg-info → code_lm-0.2.4}/PKG-INFO +1 -1
- {code_lm-0.2.3 → code_lm-0.2.4}/pyproject.toml +1 -1
- {code_lm-0.2.3 → code_lm-0.2.4}/setup.py +1 -1
- {code_lm-0.2.3 → code_lm-0.2.4/src/code_lm.egg-info}/PKG-INFO +1 -1
- code_lm-0.2.4/src/gemini_cli/tools/directory_tools.py +119 -0
- code_lm-0.2.3/src/gemini_cli/tools/directory_tools.py +0 -31
- {code_lm-0.2.3 → code_lm-0.2.4}/MANIFEST.in +0 -0
- {code_lm-0.2.3 → code_lm-0.2.4}/README.md +0 -0
- {code_lm-0.2.3 → code_lm-0.2.4}/setup.cfg +0 -0
- {code_lm-0.2.3 → code_lm-0.2.4}/src/code_lm.egg-info/SOURCES.txt +0 -0
- {code_lm-0.2.3 → code_lm-0.2.4}/src/code_lm.egg-info/dependency_links.txt +0 -0
- {code_lm-0.2.3 → code_lm-0.2.4}/src/code_lm.egg-info/entry_points.txt +0 -0
- {code_lm-0.2.3 → code_lm-0.2.4}/src/code_lm.egg-info/requires.txt +0 -0
- {code_lm-0.2.3 → code_lm-0.2.4}/src/code_lm.egg-info/top_level.txt +0 -0
- {code_lm-0.2.3 → code_lm-0.2.4}/src/gemini_cli/__init__.py +0 -0
- {code_lm-0.2.3 → code_lm-0.2.4}/src/gemini_cli/config.py +0 -0
- {code_lm-0.2.3 → code_lm-0.2.4}/src/gemini_cli/main.py +0 -0
- {code_lm-0.2.3 → code_lm-0.2.4}/src/gemini_cli/models/__init__.py +0 -0
- {code_lm-0.2.3 → code_lm-0.2.4}/src/gemini_cli/models/gemini.py +0 -0
- {code_lm-0.2.3 → code_lm-0.2.4}/src/gemini_cli/models/openrouter.py +0 -0
- {code_lm-0.2.3 → code_lm-0.2.4}/src/gemini_cli/tools/__init__.py +0 -0
- {code_lm-0.2.3 → code_lm-0.2.4}/src/gemini_cli/tools/base.py +0 -0
- {code_lm-0.2.3 → code_lm-0.2.4}/src/gemini_cli/tools/file_tools.py +0 -0
- {code_lm-0.2.3 → code_lm-0.2.4}/src/gemini_cli/tools/quality_tools.py +0 -0
- {code_lm-0.2.3 → code_lm-0.2.4}/src/gemini_cli/tools/summarizer_tool.py +0 -0
- {code_lm-0.2.3 → code_lm-0.2.4}/src/gemini_cli/tools/system_tools.py +0 -0
- {code_lm-0.2.3 → code_lm-0.2.4}/src/gemini_cli/tools/task_complete_tool.py +0 -0
- {code_lm-0.2.3 → code_lm-0.2.4}/src/gemini_cli/tools/test_runner.py +0 -0
- {code_lm-0.2.3 → code_lm-0.2.4}/src/gemini_cli/tools/tree_tool.py +0 -0
- {code_lm-0.2.3 → code_lm-0.2.4}/src/gemini_cli/utils.py +0 -0
|
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
|
|
2
2
|
|
|
3
3
|
setup(
|
|
4
4
|
name="code-lm",
|
|
5
|
-
version="0.2.
|
|
5
|
+
version="0.2.4",
|
|
6
6
|
description="A CLI for interacting with various LLM models using OpenRouter and other APIs.",
|
|
7
7
|
long_description=open("README.md").read(),
|
|
8
8
|
long_description_content_type="text/markdown",
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tools for directory operations.
|
|
3
|
+
"""
|
|
4
|
+
import os
|
|
5
|
+
import platform
|
|
6
|
+
import logging
|
|
7
|
+
import subprocess
|
|
8
|
+
from .base import BaseTool
|
|
9
|
+
|
|
10
|
+
log = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
class CreateDirectoryTool(BaseTool):
|
|
13
|
+
"""Tool to create a new directory."""
|
|
14
|
+
name = "create_directory"
|
|
15
|
+
description = "Creates a new directory, including any necessary parent directories."
|
|
16
|
+
|
|
17
|
+
def execute(self, dir_path: str) -> str:
|
|
18
|
+
"""
|
|
19
|
+
Creates a directory.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
dir_path: The path of the directory to create.
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
A success or error message.
|
|
26
|
+
"""
|
|
27
|
+
try:
|
|
28
|
+
# Basic path safety
|
|
29
|
+
if ".." in dir_path.split(os.path.sep):
|
|
30
|
+
log.warning(f"Attempted to access parent directory in create_directory path: {dir_path}")
|
|
31
|
+
return f"Error: Invalid path '{dir_path}'. Cannot access parent directories."
|
|
32
|
+
|
|
33
|
+
target_path = os.path.abspath(os.path.expanduser(dir_path))
|
|
34
|
+
log.info(f"Attempting to create directory: {target_path}")
|
|
35
|
+
|
|
36
|
+
if os.path.exists(target_path):
|
|
37
|
+
if os.path.isdir(target_path):
|
|
38
|
+
log.warning(f"Directory already exists: {target_path}")
|
|
39
|
+
return f"Directory already exists: {dir_path}"
|
|
40
|
+
else:
|
|
41
|
+
log.error(f"Path exists but is not a directory: {target_path}")
|
|
42
|
+
return f"Error: Path exists but is not a directory: {dir_path}"
|
|
43
|
+
|
|
44
|
+
os.makedirs(target_path, exist_ok=True) # exist_ok=True handles race conditions slightly better
|
|
45
|
+
log.info(f"Successfully created directory: {target_path}")
|
|
46
|
+
return f"Successfully created directory: {dir_path}"
|
|
47
|
+
|
|
48
|
+
except OSError as e:
|
|
49
|
+
log.error(f"Error creating directory '{dir_path}': {e}", exc_info=True)
|
|
50
|
+
return f"Error creating directory: {str(e)}"
|
|
51
|
+
except Exception as e:
|
|
52
|
+
log.error(f"Unexpected error creating directory '{dir_path}': {e}", exc_info=True)
|
|
53
|
+
return f"Error creating directory: {str(e)}"
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class LsTool(BaseTool):
|
|
57
|
+
"""Tool to list directory contents using a platform-specific command."""
|
|
58
|
+
name = "ls"
|
|
59
|
+
description = "Lists the contents of a specified directory (long format, including hidden files)."
|
|
60
|
+
args_schema: dict = {
|
|
61
|
+
"path": {
|
|
62
|
+
"type": "string",
|
|
63
|
+
"description": "Optional path to a specific directory relative to the workspace root. If omitted, uses the current directory.",
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
required_args: list[str] = []
|
|
67
|
+
|
|
68
|
+
def execute(self, path: str | None = None) -> str:
|
|
69
|
+
"""Executes the platform-specific directory listing command."""
|
|
70
|
+
target_path = "." # Default to current directory
|
|
71
|
+
if path:
|
|
72
|
+
# Basic path safety - prevent navigating outside workspace root if needed
|
|
73
|
+
target_path = os.path.normpath(path) # Normalize path
|
|
74
|
+
if target_path.startswith(".."):
|
|
75
|
+
log.warning(f"Attempted to access parent directory in ls path: {path}")
|
|
76
|
+
return f"Error: Invalid path '{path}'. Cannot access parent directories."
|
|
77
|
+
|
|
78
|
+
if platform.system() == "Windows":
|
|
79
|
+
command = ['cmd', '/c', 'dir', '/A', target_path] # Use dir on Windows
|
|
80
|
+
else:
|
|
81
|
+
command = ['ls', '-lA', target_path] # Use ls on Unix-based systems
|
|
82
|
+
|
|
83
|
+
log.info(f"Executing directory listing command: {' '.join(command)}")
|
|
84
|
+
|
|
85
|
+
try:
|
|
86
|
+
process = subprocess.run(
|
|
87
|
+
command,
|
|
88
|
+
capture_output=True,
|
|
89
|
+
text=True,
|
|
90
|
+
check=False, # Don't raise exception on non-zero exit code
|
|
91
|
+
timeout=15 # Add a timeout
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
if process.returncode == 0:
|
|
95
|
+
log.info(f"Directory listing command successful for path '{target_path}'.")
|
|
96
|
+
output = process.stdout.strip()
|
|
97
|
+
if len(output.splitlines()) > 100:
|
|
98
|
+
log.warning(f"Directory listing output for '{target_path}' exceeded 100 lines. Truncating.")
|
|
99
|
+
output = "\n".join(output.splitlines()[:100]) + "\n... (output truncated)"
|
|
100
|
+
return output
|
|
101
|
+
else:
|
|
102
|
+
stderr_lower = process.stderr.lower()
|
|
103
|
+
if "no such file or directory" in stderr_lower or "not found" in stderr_lower:
|
|
104
|
+
log.error(f"Directory listing command failed: Directory not found '{target_path}'. Stderr: {process.stderr.strip()}")
|
|
105
|
+
return f"Error: Directory not found: '{target_path}'"
|
|
106
|
+
else:
|
|
107
|
+
log.error(f"Directory listing command failed with return code {process.returncode}. Path: '{target_path}'. Stderr: {process.stderr.strip()}")
|
|
108
|
+
error_detail = process.stderr.strip() if process.stderr else "(No stderr)"
|
|
109
|
+
return f"Error executing directory listing command (Code: {process.returncode}): {error_detail}"
|
|
110
|
+
|
|
111
|
+
except FileNotFoundError:
|
|
112
|
+
log.error("Directory listing command not found. Ensure it is installed and in the system's PATH.")
|
|
113
|
+
return "Error: Directory listing command not found. Please ensure it is installed and in the system's PATH."
|
|
114
|
+
except subprocess.TimeoutExpired:
|
|
115
|
+
log.error(f"Directory listing command timed out for path '{target_path}' after 15 seconds.")
|
|
116
|
+
return f"Error: Directory listing command timed out for path '{target_path}'."
|
|
117
|
+
except Exception as e:
|
|
118
|
+
log.exception(f"An unexpected error occurred while executing directory listing command for path '{target_path}': {e}")
|
|
119
|
+
return f"An unexpected error occurred while executing directory listing command: {str(e)}"
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Directory tools for interacting with the file system.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
import os
|
|
6
|
-
import platform
|
|
7
|
-
import subprocess
|
|
8
|
-
import logging
|
|
9
|
-
|
|
10
|
-
log = logging.getLogger(__name__)
|
|
11
|
-
|
|
12
|
-
class LsTool:
|
|
13
|
-
"""Tool for listing directory contents."""
|
|
14
|
-
|
|
15
|
-
def execute(self, path: str = ".") -> str:
|
|
16
|
-
"""List the contents of a directory."""
|
|
17
|
-
try:
|
|
18
|
-
# Check the operating system and use the appropriate command
|
|
19
|
-
if platform.system() == "Windows":
|
|
20
|
-
# Use dir command on Windows
|
|
21
|
-
result = subprocess.run(["cmd", "/c", "dir", path], capture_output=True, text=True, check=True)
|
|
22
|
-
else:
|
|
23
|
-
# Use ls command on Unix-based systems
|
|
24
|
-
result = subprocess.run(["ls", path], capture_output=True, text=True, check=True)
|
|
25
|
-
return result.stdout
|
|
26
|
-
except FileNotFoundError:
|
|
27
|
-
log.error("'ls' or 'dir' command not found. Ensure it is installed or in PATH.")
|
|
28
|
-
raise
|
|
29
|
-
except subprocess.CalledProcessError as e:
|
|
30
|
-
log.error(f"Error executing directory listing: {e}")
|
|
31
|
-
raise
|
|
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
|