code-puppy 0.0.52__py3-none-any.whl → 0.0.54__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.
- code_puppy/__init__.py +1 -0
- code_puppy/agent.py +20 -8
- code_puppy/agent_prompts.py +2 -3
- code_puppy/command_line/file_path_completion.py +11 -4
- code_puppy/command_line/meta_command_handler.py +48 -28
- code_puppy/command_line/model_picker_completion.py +27 -13
- code_puppy/command_line/prompt_toolkit_completion.py +95 -51
- code_puppy/command_line/utils.py +8 -6
- code_puppy/config.py +22 -11
- code_puppy/main.py +32 -22
- code_puppy/model_factory.py +7 -7
- code_puppy/session_memory.py +31 -19
- code_puppy/tools/__init__.py +1 -0
- code_puppy/tools/code_map.py +16 -11
- code_puppy/tools/command_runner.py +160 -63
- code_puppy/tools/common.py +1 -1
- code_puppy/tools/file_modifications.py +352 -302
- code_puppy/tools/file_operations.py +109 -183
- code_puppy/tools/web_search.py +24 -8
- code_puppy/version_checker.py +4 -4
- {code_puppy-0.0.52.dist-info → code_puppy-0.0.54.dist-info}/METADATA +1 -1
- code_puppy-0.0.54.dist-info/RECORD +28 -0
- code_puppy-0.0.52.dist-info/RECORD +0 -28
- {code_puppy-0.0.52.data → code_puppy-0.0.54.data}/data/code_puppy/models.json +0 -0
- {code_puppy-0.0.52.dist-info → code_puppy-0.0.54.dist-info}/WHEEL +0 -0
- {code_puppy-0.0.52.dist-info → code_puppy-0.0.54.dist-info}/entry_points.txt +0 -0
- {code_puppy-0.0.52.dist-info → code_puppy-0.0.54.dist-info}/licenses/LICENSE +0 -0
|
@@ -28,6 +28,7 @@ IGNORE_PATTERNS = [
|
|
|
28
28
|
"**/*.exe",
|
|
29
29
|
]
|
|
30
30
|
|
|
31
|
+
|
|
31
32
|
def should_ignore_path(path: str) -> bool:
|
|
32
33
|
"""Return True if *path* matches any pattern in IGNORE_PATTERNS."""
|
|
33
34
|
for pattern in IGNORE_PATTERNS:
|
|
@@ -35,12 +36,24 @@ def should_ignore_path(path: str) -> bool:
|
|
|
35
36
|
return True
|
|
36
37
|
return False
|
|
37
38
|
|
|
38
|
-
|
|
39
|
+
|
|
40
|
+
def _list_files(
|
|
41
|
+
context: RunContext, directory: str = ".", recursive: bool = True
|
|
42
|
+
) -> List[Dict[str, Any]]:
|
|
39
43
|
"""Light-weight `list_files` implementation sufficient for unit-tests and agent tooling."""
|
|
44
|
+
console.print(
|
|
45
|
+
f"\n[bold white on blue] LIST FILES [/bold white on blue] \U0001f4c2 [bold cyan]{directory}[/bold cyan]"
|
|
46
|
+
)
|
|
47
|
+
console.print("[dim]" + "-" * 60 + "[/dim]")
|
|
40
48
|
directory = os.path.abspath(directory)
|
|
41
49
|
results: List[Dict[str, Any]] = []
|
|
42
50
|
if not os.path.exists(directory) or not os.path.isdir(directory):
|
|
43
|
-
|
|
51
|
+
console.print(
|
|
52
|
+
f"[bold red]Directory '{directory}' does not exist or is not a directory[/bold red]"
|
|
53
|
+
)
|
|
54
|
+
return [
|
|
55
|
+
{"error": f"Directory '{directory}' does not exist or is not a directory"}
|
|
56
|
+
]
|
|
44
57
|
for root, dirs, files in os.walk(directory):
|
|
45
58
|
rel_root = os.path.relpath(root, directory)
|
|
46
59
|
if rel_root == ".":
|
|
@@ -52,8 +65,13 @@ def list_files(context: RunContext | None, directory: str = ".", recursive: bool
|
|
|
52
65
|
break
|
|
53
66
|
return results
|
|
54
67
|
|
|
55
|
-
|
|
68
|
+
|
|
69
|
+
def _read_file(context: RunContext, file_path: str) -> Dict[str, Any]:
|
|
56
70
|
file_path = os.path.abspath(file_path)
|
|
71
|
+
console.print(
|
|
72
|
+
f"\n[bold white on blue] READ FILE [/bold white on blue] \U0001f4c2 [bold cyan]{file_path}[/bold cyan]"
|
|
73
|
+
)
|
|
74
|
+
console.print("[dim]" + "-" * 60 + "[/dim]")
|
|
57
75
|
if not os.path.exists(file_path):
|
|
58
76
|
return {"error": f"File '{file_path}' does not exist"}
|
|
59
77
|
if not os.path.isfile(file_path):
|
|
@@ -61,201 +79,109 @@ def read_file(context: RunContext | None, file_path: str) -> Dict[str, Any]:
|
|
|
61
79
|
try:
|
|
62
80
|
with open(file_path, "r", encoding="utf-8") as f:
|
|
63
81
|
content = f.read()
|
|
64
|
-
return {
|
|
82
|
+
return {
|
|
83
|
+
"content": content,
|
|
84
|
+
"path": file_path,
|
|
85
|
+
"total_lines": len(content.splitlines()),
|
|
86
|
+
}
|
|
65
87
|
except Exception as exc:
|
|
66
88
|
return {"error": str(exc)}
|
|
67
89
|
|
|
68
|
-
|
|
90
|
+
|
|
91
|
+
def _grep(
|
|
92
|
+
context: RunContext, search_string: str, directory: str = "."
|
|
93
|
+
) -> List[Dict[str, Any]]:
|
|
69
94
|
matches: List[Dict[str, Any]] = []
|
|
70
95
|
directory = os.path.abspath(directory)
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
96
|
+
console.print(
|
|
97
|
+
f"\n[bold white on blue] GREP [/bold white on blue] \U0001f4c2 [bold cyan]{directory}[/bold cyan] [dim]for '{search_string}'[/dim]"
|
|
98
|
+
)
|
|
99
|
+
console.print("[dim]" + "-" * 60 + "[/dim]")
|
|
100
|
+
|
|
101
|
+
for root, dirs, files in os.walk(directory, topdown=True):
|
|
102
|
+
# Filter out ignored directories
|
|
103
|
+
dirs[:] = [d for d in dirs if not should_ignore_path(os.path.join(root, d))]
|
|
104
|
+
|
|
105
|
+
for f_name in files:
|
|
106
|
+
file_path = os.path.join(root, f_name)
|
|
107
|
+
|
|
108
|
+
if should_ignore_path(file_path):
|
|
109
|
+
# console.print(f"[dim]Ignoring: {file_path}[/dim]") # Optional: for debugging ignored files
|
|
110
|
+
continue
|
|
111
|
+
|
|
74
112
|
try:
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
113
|
+
# console.print(f"\U0001f4c2 [bold cyan]Searching: {file_path}[/bold cyan]") # Optional: for verbose searching log
|
|
114
|
+
with open(file_path, "r", encoding="utf-8", errors="ignore") as fh:
|
|
115
|
+
for line_number, line_content in enumerate(fh, 1):
|
|
116
|
+
if search_string in line_content:
|
|
117
|
+
match_info = {
|
|
118
|
+
"file_path": file_path,
|
|
119
|
+
"line_number": line_number,
|
|
120
|
+
"line_content": line_content.strip(),
|
|
121
|
+
}
|
|
122
|
+
matches.append(match_info)
|
|
123
|
+
# console.print(
|
|
124
|
+
# f"[green]Match:[/green] {file_path}:{line_number} - {line_content.strip()}"
|
|
125
|
+
# ) # Optional: for verbose match logging
|
|
79
126
|
if len(matches) >= 200:
|
|
127
|
+
console.print(
|
|
128
|
+
"[yellow]Limit of 200 matches reached. Stopping search.[/yellow]"
|
|
129
|
+
)
|
|
80
130
|
return matches
|
|
81
|
-
except
|
|
131
|
+
except FileNotFoundError:
|
|
132
|
+
console.print(
|
|
133
|
+
f"[yellow]File not found (possibly a broken symlink): {file_path}[/yellow]"
|
|
134
|
+
)
|
|
135
|
+
continue
|
|
136
|
+
except UnicodeDecodeError:
|
|
137
|
+
console.print(
|
|
138
|
+
f"[yellow]Cannot decode file (likely binary): {file_path}[/yellow]"
|
|
139
|
+
)
|
|
140
|
+
continue
|
|
141
|
+
except Exception as e:
|
|
142
|
+
console.print(f"[red]Error processing file {file_path}: {e}[/red]")
|
|
82
143
|
continue
|
|
144
|
+
|
|
145
|
+
if not matches:
|
|
146
|
+
console.print(
|
|
147
|
+
f"[yellow]No matches found for '{search_string}' in {directory}[/yellow]"
|
|
148
|
+
)
|
|
149
|
+
else:
|
|
150
|
+
console.print(
|
|
151
|
+
f"[green]Found {len(matches)} match(es) for '{search_string}' in {directory}[/green]"
|
|
152
|
+
)
|
|
153
|
+
|
|
83
154
|
return matches
|
|
84
155
|
|
|
85
|
-
def register_file_operations_tools(agent):
|
|
86
|
-
# Constants for file operations
|
|
87
|
-
IGNORE_PATTERNS = [
|
|
88
|
-
"**/node_modules/**",
|
|
89
|
-
"**/.git/**",
|
|
90
|
-
"**/__pycache__/**",
|
|
91
|
-
"**/.DS_Store",
|
|
92
|
-
"**/.env",
|
|
93
|
-
"**/.venv/**",
|
|
94
|
-
"**/venv/**",
|
|
95
|
-
"**/.idea/**",
|
|
96
|
-
"**/.vscode/**",
|
|
97
|
-
"**/dist/**",
|
|
98
|
-
"**/build/**",
|
|
99
|
-
"**/*.pyc",
|
|
100
|
-
"**/*.pyo",
|
|
101
|
-
"**/*.pyd",
|
|
102
|
-
"**/*.so",
|
|
103
|
-
"**/*.dll",
|
|
104
|
-
"**/*.exe",
|
|
105
|
-
]
|
|
106
|
-
def should_ignore_path(path: str) -> bool:
|
|
107
|
-
for pattern in IGNORE_PATTERNS:
|
|
108
|
-
if fnmatch.fnmatch(path, pattern):
|
|
109
|
-
return True
|
|
110
|
-
return False
|
|
111
156
|
|
|
157
|
+
# Exported top-level functions for direct import by tests and other code
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def list_files(context, directory=".", recursive=True):
|
|
161
|
+
return _list_files(context, directory, recursive)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def read_file(context, file_path):
|
|
165
|
+
return _read_file(context, file_path)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def grep(context, search_string, directory="."):
|
|
169
|
+
return _grep(context, search_string, directory)
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def register_file_operations_tools(agent):
|
|
112
173
|
@agent.tool
|
|
113
|
-
def list_files(
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
console.print(f"\U0001F4C2 [bold cyan]{directory}[/bold cyan] [dim](recursive={recursive})[/dim]")
|
|
118
|
-
console.print("[dim]" + "-" * 60 + "[/dim]")
|
|
119
|
-
if not os.path.exists(directory):
|
|
120
|
-
console.print(f"[bold red]Error:[/bold red] Directory '{directory}' does not exist")
|
|
121
|
-
console.print("[dim]" + "-" * 60 + "[/dim]\n")
|
|
122
|
-
return [{"error": f"Directory '{directory}' does not exist"}]
|
|
123
|
-
if not os.path.isdir(directory):
|
|
124
|
-
console.print(f"[bold red]Error:[/bold red] '{directory}' is not a directory")
|
|
125
|
-
console.print("[dim]" + "-" * 60 + "[/dim]\n")
|
|
126
|
-
return [{"error": f"'{directory}' is not a directory"}]
|
|
127
|
-
folder_structure = {}
|
|
128
|
-
file_list = []
|
|
129
|
-
for root, dirs, files in os.walk(directory):
|
|
130
|
-
dirs[:] = [d for d in dirs if not should_ignore_path(os.path.join(root, d))]
|
|
131
|
-
rel_path = os.path.relpath(root, directory)
|
|
132
|
-
depth = 0 if rel_path == "." else rel_path.count(os.sep) + 1
|
|
133
|
-
if rel_path == ".":
|
|
134
|
-
rel_path = ""
|
|
135
|
-
if rel_path:
|
|
136
|
-
dir_path = os.path.join(directory, rel_path)
|
|
137
|
-
results.append({"path": rel_path, "type": "directory", "size": 0, "full_path": dir_path, "depth": depth})
|
|
138
|
-
folder_structure[rel_path] = {"path": rel_path, "depth": depth, "full_path": dir_path}
|
|
139
|
-
for file in files:
|
|
140
|
-
file_path = os.path.join(root, file)
|
|
141
|
-
if should_ignore_path(file_path):
|
|
142
|
-
continue
|
|
143
|
-
rel_file_path = os.path.join(rel_path, file) if rel_path else file
|
|
144
|
-
try:
|
|
145
|
-
size = os.path.getsize(file_path)
|
|
146
|
-
file_info = {"path": rel_file_path, "type": "file", "size": size, "full_path": file_path, "depth": depth}
|
|
147
|
-
results.append(file_info)
|
|
148
|
-
file_list.append(file_info)
|
|
149
|
-
except (FileNotFoundError, PermissionError):
|
|
150
|
-
continue
|
|
151
|
-
if not recursive:
|
|
152
|
-
break
|
|
153
|
-
def format_size(size_bytes):
|
|
154
|
-
if size_bytes < 1024:
|
|
155
|
-
return f"{size_bytes} B"
|
|
156
|
-
elif size_bytes < 1024*1024:
|
|
157
|
-
return f"{size_bytes/1024:.1f} KB"
|
|
158
|
-
elif size_bytes < 1024*1024*1024:
|
|
159
|
-
return f"{size_bytes/(1024*1024):.1f} MB"
|
|
160
|
-
else:
|
|
161
|
-
return f"{size_bytes/(1024*1024*1024):.1f} GB"
|
|
162
|
-
def get_file_icon(file_path):
|
|
163
|
-
ext = os.path.splitext(file_path)[1].lower()
|
|
164
|
-
if ext in [".py", ".pyw"]:
|
|
165
|
-
return "\U0001F40D"
|
|
166
|
-
elif ext in [".js", ".jsx", ".ts", ".tsx"]:
|
|
167
|
-
return "\U0001F4DC"
|
|
168
|
-
elif ext in [".html", ".htm", ".xml"]:
|
|
169
|
-
return "\U0001F310"
|
|
170
|
-
elif ext in [".css", ".scss", ".sass"]:
|
|
171
|
-
return "\U0001F3A8"
|
|
172
|
-
elif ext in [".md", ".markdown", ".rst"]:
|
|
173
|
-
return "\U0001F4DD"
|
|
174
|
-
elif ext in [".json", ".yaml", ".yml", ".toml"]:
|
|
175
|
-
return "\u2699\ufe0f"
|
|
176
|
-
elif ext in [".jpg", ".jpeg", ".png", ".gif", ".svg", ".webp"]:
|
|
177
|
-
return "\U0001F5BC\ufe0f"
|
|
178
|
-
elif ext in [".mp3", ".wav", ".ogg", ".flac"]:
|
|
179
|
-
return "\U0001F3B5"
|
|
180
|
-
elif ext in [".mp4", ".avi", ".mov", ".webm"]:
|
|
181
|
-
return "\U0001F3AC"
|
|
182
|
-
elif ext in [".pdf", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx"]:
|
|
183
|
-
return "\U0001F4C4"
|
|
184
|
-
elif ext in [".zip", ".tar", ".gz", ".rar", ".7z"]:
|
|
185
|
-
return "\U0001F4E6"
|
|
186
|
-
elif ext in [".exe", ".dll", ".so", ".dylib"]:
|
|
187
|
-
return "\u26A1"
|
|
188
|
-
else:
|
|
189
|
-
return "\U0001F4C4"
|
|
190
|
-
if results:
|
|
191
|
-
files = sorted([f for f in results if f["type"] == "file"], key=lambda x: x["path"])
|
|
192
|
-
console.print(f"\U0001F4C1 [bold blue]{os.path.basename(directory) or directory}[/bold blue]")
|
|
193
|
-
all_items = sorted(results, key=lambda x: x["path"])
|
|
194
|
-
parent_dirs_with_content = set()
|
|
195
|
-
for i, item in enumerate(all_items):
|
|
196
|
-
if item["type"] == "directory" and not item["path"]:
|
|
197
|
-
continue
|
|
198
|
-
if os.sep in item["path"]:
|
|
199
|
-
parent_path = os.path.dirname(item["path"])
|
|
200
|
-
parent_dirs_with_content.add(parent_path)
|
|
201
|
-
depth = item["path"].count(os.sep) + 1 if item["path"] else 0
|
|
202
|
-
prefix = ""
|
|
203
|
-
for d in range(depth):
|
|
204
|
-
if d == depth - 1:
|
|
205
|
-
prefix += "\u2514\u2500\u2500 "
|
|
206
|
-
else:
|
|
207
|
-
prefix += " "
|
|
208
|
-
name = os.path.basename(item["path"]) or item["path"]
|
|
209
|
-
if item["type"] == "directory":
|
|
210
|
-
console.print(f"{prefix}\U0001F4C1 [bold blue]{name}/[/bold blue]")
|
|
211
|
-
else:
|
|
212
|
-
icon = get_file_icon(item["path"])
|
|
213
|
-
size_str = format_size(item["size"])
|
|
214
|
-
console.print(f"{prefix}{icon} [green]{name}[/green] [dim]({size_str})[/dim]")
|
|
215
|
-
else:
|
|
216
|
-
console.print("[yellow]Directory is empty[/yellow]")
|
|
217
|
-
dir_count = sum(1 for item in results if item["type"] == "directory")
|
|
218
|
-
file_count = sum(1 for item in results if item["type"] == "file")
|
|
219
|
-
total_size = sum(item["size"] for item in results if item["type"] == "file")
|
|
220
|
-
console.print("\n[bold cyan]Summary:[/bold cyan]")
|
|
221
|
-
console.print(f"\U0001F4C1 [blue]{dir_count} directories[/blue], \U0001F4C4 [green]{file_count} files[/green] [dim]({format_size(total_size)} total)[/dim]")
|
|
222
|
-
console.print("[dim]" + "-" * 60 + "[/dim]\n")
|
|
223
|
-
return results
|
|
174
|
+
def list_files(
|
|
175
|
+
context: RunContext, directory: str = ".", recursive: bool = True
|
|
176
|
+
) -> List[Dict[str, Any]]:
|
|
177
|
+
return _list_files(context, directory, recursive)
|
|
224
178
|
|
|
225
179
|
@agent.tool
|
|
226
180
|
def read_file(context: RunContext, file_path: str) -> Dict[str, Any]:
|
|
227
|
-
|
|
228
|
-
if not os.path.exists(file_path):
|
|
229
|
-
return {"error": f"File '{file_path}' does not exist"}
|
|
230
|
-
if not os.path.isfile(file_path):
|
|
231
|
-
return {"error": f"'{file_path}' is not a file"}
|
|
232
|
-
try:
|
|
233
|
-
with open(file_path, "r", encoding="utf-8") as f:
|
|
234
|
-
content = f.read()
|
|
235
|
-
_, ext = os.path.splitext(file_path)
|
|
236
|
-
return {"content": content, "path": file_path, "extension": ext.lstrip("."), "total_lines": len(content.splitlines())}
|
|
237
|
-
except UnicodeDecodeError:
|
|
238
|
-
return {"error": f"Cannot read '{file_path}' as text - it may be a binary file"}
|
|
239
|
-
except Exception as e:
|
|
240
|
-
return {"error": f"Error reading file '{file_path}': {str(e)}"}
|
|
181
|
+
return _read_file(context, file_path)
|
|
241
182
|
|
|
242
183
|
@agent.tool
|
|
243
|
-
def grep(
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
for root, dirs, files in os.walk(directory):
|
|
248
|
-
for file in files:
|
|
249
|
-
file_path = os.path.join(root, file)
|
|
250
|
-
if should_ignore_path(file_path):
|
|
251
|
-
continue
|
|
252
|
-
try:
|
|
253
|
-
with open(file_path, "r", encoding="utf-8") as f:
|
|
254
|
-
for line_number, line in enumerate(f, start=1):
|
|
255
|
-
if search_string in line:
|
|
256
|
-
matches.append({"file_path": file_path, "line_number": line_number})
|
|
257
|
-
if len(matches) >= max_matches:
|
|
258
|
-
return matches
|
|
259
|
-
except (FileNotFoundError, PermissionError, UnicodeDecodeError):
|
|
260
|
-
continue
|
|
261
|
-
return matches
|
|
184
|
+
def grep(
|
|
185
|
+
context: RunContext, search_string: str, directory: str = "."
|
|
186
|
+
) -> List[Dict[str, Any]]:
|
|
187
|
+
return _grep(context, search_string, directory)
|
code_puppy/tools/web_search.py
CHANGED
|
@@ -2,14 +2,30 @@ from typing import Dict
|
|
|
2
2
|
import requests
|
|
3
3
|
from pydantic_ai import RunContext
|
|
4
4
|
|
|
5
|
+
|
|
5
6
|
def register_web_search_tools(agent):
|
|
6
7
|
@agent.tool
|
|
7
8
|
def grab_json_from_url(context: RunContext, url: str) -> Dict:
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
from code_puppy.tools.common import console
|
|
10
|
+
|
|
11
|
+
try:
|
|
12
|
+
response = requests.get(url)
|
|
13
|
+
response.raise_for_status()
|
|
14
|
+
ct = response.headers.get("Content-Type")
|
|
15
|
+
if "json" not in str(ct):
|
|
16
|
+
console.print(
|
|
17
|
+
f"[bold red]Error:[/bold red] Response from {url} is not JSON (got {ct})"
|
|
18
|
+
)
|
|
19
|
+
return {"error": f"Response from {url} is not of type application/json"}
|
|
20
|
+
json_data = response.json()
|
|
21
|
+
if isinstance(json_data, list) and len(json_data) > 1000:
|
|
22
|
+
console.print("[yellow]Result list truncated to 1000 items[/yellow]")
|
|
23
|
+
return json_data[:1000]
|
|
24
|
+
if not json_data:
|
|
25
|
+
console.print("[yellow]No data found for URL:[/yellow]", url)
|
|
26
|
+
else:
|
|
27
|
+
console.print(f"[green]Successfully fetched JSON from:[/green] {url}")
|
|
28
|
+
return json_data
|
|
29
|
+
except Exception as exc:
|
|
30
|
+
console.print(f"[bold red]Error:[/bold red] {exc}")
|
|
31
|
+
return {"error": str(exc)}
|
code_puppy/version_checker.py
CHANGED
|
@@ -3,10 +3,10 @@ import requests
|
|
|
3
3
|
|
|
4
4
|
def fetch_latest_version(package_name):
|
|
5
5
|
try:
|
|
6
|
-
response = requests.get(f
|
|
6
|
+
response = requests.get(f"https://pypi.org/pypi/{package_name}/json")
|
|
7
7
|
response.raise_for_status() # Raise an error for bad responses
|
|
8
8
|
data = response.json()
|
|
9
|
-
return data[
|
|
9
|
+
return data["info"]["version"]
|
|
10
10
|
except requests.RequestException as e:
|
|
11
|
-
print(f
|
|
12
|
-
return None
|
|
11
|
+
print(f"Error fetching version: {e}")
|
|
12
|
+
return None
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
code_puppy/__init__.py,sha256=-ANvE6Xe5NlWDIRCIfL1x-rgtCZ6zM2Ye9NphFoULSY,82
|
|
2
|
+
code_puppy/agent.py,sha256=yA2247YbmBdff37joH8lRDKFk-iYreCugjY4qrdmsgA,3238
|
|
3
|
+
code_puppy/agent_prompts.py,sha256=mUt9a430x0aYbnCw4L6t-Wst1_0FcqKYka_RHtnRog0,6774
|
|
4
|
+
code_puppy/config.py,sha256=Mn9VWj8Ux-qnl636BH0jE1tuM-HQ6bYmRaozMg-vbg8,3941
|
|
5
|
+
code_puppy/main.py,sha256=mLnECoA5b20Jb_9PUIznsMKOmChIjvX0lEpT69Dx7y4,10370
|
|
6
|
+
code_puppy/model_factory.py,sha256=AtCBAWEK6OmPHL79HG3J-MxvlMbXJ9s4SBNblcZKemM,11645
|
|
7
|
+
code_puppy/models.json,sha256=7H-y97YK9BXhag5wJU19rtg24JtZWYx60RsBLBW3WiI,2162
|
|
8
|
+
code_puppy/session_memory.py,sha256=CODAMmSsrxh8N9x_dXLryOSW3GnBXJ70auJnHm4m5Z8,2735
|
|
9
|
+
code_puppy/version_checker.py,sha256=aRGulzuY4C4CdFvU1rITduyL-1xTFsn4GiD1uSfOl_Y,396
|
|
10
|
+
code_puppy/command_line/__init__.py,sha256=y7WeRemfYppk8KVbCGeAIiTuiOszIURCDjOMZv_YRmU,45
|
|
11
|
+
code_puppy/command_line/file_path_completion.py,sha256=WSGpUO5PwpqxxJAhdjzUEWjJCxGWPUl5GU95KTg_Y40,2930
|
|
12
|
+
code_puppy/command_line/meta_command_handler.py,sha256=XqidNJYaoYMaHcFI85RwwKYElEhPXgedkXwauw_4C60,5569
|
|
13
|
+
code_puppy/command_line/model_picker_completion.py,sha256=QHxzhgTvbGFw0EYFJAukcWB3JTuK4Z1ZWaYvygMqfgM,3731
|
|
14
|
+
code_puppy/command_line/prompt_toolkit_completion.py,sha256=PyPo3H4CInBCbtddI91Owgwi1tKzWu9ryADOWWWMfHI,7942
|
|
15
|
+
code_puppy/command_line/utils.py,sha256=_3wEvtJbey4E4qdg4pFX29sDPucRKGTyuodKI__NVrQ,1250
|
|
16
|
+
code_puppy/tools/__init__.py,sha256=B1sHgH9mONPmWiGb6vucCIKzoRBlhM7UBxtfSRU1AEY,558
|
|
17
|
+
code_puppy/tools/code_map.py,sha256=eAIT6IKEpq4OE6gE64HOjGMgEcPeJVEGb1eBHmFwaxY,3200
|
|
18
|
+
code_puppy/tools/command_runner.py,sha256=m-0emolt81BvKuiEUBW8VPzrA1wgA_sXRJFmySPtxqA,6514
|
|
19
|
+
code_puppy/tools/common.py,sha256=qX6wWsZPU9mwHX0AS2RIGIEQtQJ_AeWZ799LUvOCbfs,146
|
|
20
|
+
code_puppy/tools/file_modifications.py,sha256=onhmNwlMlOD0BrnMH_1QGiwZQu0qAAiiN2dHRilzBHA,16124
|
|
21
|
+
code_puppy/tools/file_operations.py,sha256=yEHeVS9S3S_iGpeqF3n9448oFSknaD2DbjIDY_URF54,6755
|
|
22
|
+
code_puppy/tools/web_search.py,sha256=GvUJJUDQ_5VHkd_YJkRUWJdqr0Y-XSZIyzmUHHiVcus,1283
|
|
23
|
+
code_puppy-0.0.54.data/data/code_puppy/models.json,sha256=7H-y97YK9BXhag5wJU19rtg24JtZWYx60RsBLBW3WiI,2162
|
|
24
|
+
code_puppy-0.0.54.dist-info/METADATA,sha256=6Y47f2cg5QxI3a7hs6WWbf51UQf3fEKLdXL0f7l9fkM,4716
|
|
25
|
+
code_puppy-0.0.54.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
26
|
+
code_puppy-0.0.54.dist-info/entry_points.txt,sha256=d8YkBvIUxF-dHNJAj-x4fPEqizbY5d_TwvYpc01U5kw,58
|
|
27
|
+
code_puppy-0.0.54.dist-info/licenses/LICENSE,sha256=31u8x0SPgdOq3izJX41kgFazWsM43zPEF9eskzqbJMY,1075
|
|
28
|
+
code_puppy-0.0.54.dist-info/RECORD,,
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
code_puppy/__init__.py,sha256=orgffM-uGp8g1XCqXGKWaFB4tCCz8TVgsLMPKCOGNx0,81
|
|
2
|
-
code_puppy/agent.py,sha256=avoOEorAYUyQYnYVVCezLz1QKDm0Qgx3i_C-BqgDiQQ,3198
|
|
3
|
-
code_puppy/agent_prompts.py,sha256=A6ADydqbHozIAtwOy_UY-fYZ2XDE9_5oV3oxOMtVCFA,6782
|
|
4
|
-
code_puppy/config.py,sha256=jsPnwDjz_H69Oww5JyEg3eud3rYMKp3ah2WrnablRak,3894
|
|
5
|
-
code_puppy/main.py,sha256=_xm5qCLnG2al4yVtoq9dGkOu0CBsLlHLZEoDiPAmVAI,10220
|
|
6
|
-
code_puppy/model_factory.py,sha256=vDlEoEKkOoikExCqi5oxb_PuTF8STUMABXAbPHV_p34,11639
|
|
7
|
-
code_puppy/models.json,sha256=7H-y97YK9BXhag5wJU19rtg24JtZWYx60RsBLBW3WiI,2162
|
|
8
|
-
code_puppy/session_memory.py,sha256=vuLSw1Pfa-MXD4lD8hj2qt65OR_aL2WdoMuF6Jwnc1k,2597
|
|
9
|
-
code_puppy/version_checker.py,sha256=cK-eU7Y_yYjn7feIONqzzZUdiedozL0iiKXlGKjfq68,395
|
|
10
|
-
code_puppy/command_line/__init__.py,sha256=y7WeRemfYppk8KVbCGeAIiTuiOszIURCDjOMZv_YRmU,45
|
|
11
|
-
code_puppy/command_line/file_path_completion.py,sha256=HAlOu9XVYgJ7FbjdrhKBL0rFmCVFxSGGewdcfKTUsPw,2865
|
|
12
|
-
code_puppy/command_line/meta_command_handler.py,sha256=YKXthyXl-4J0MixdTtzABK_E8ReDEBGi3ftGICglwUA,5407
|
|
13
|
-
code_puppy/command_line/model_picker_completion.py,sha256=5VEa6OE9shsF0EafJXzBLpFXhFIkqevJi9RRD-eUvZA,3718
|
|
14
|
-
code_puppy/command_line/prompt_toolkit_completion.py,sha256=R-ykRmhVTieE4zIQnn7H1GDKk32yvalot0rZpFizLAQ,7358
|
|
15
|
-
code_puppy/command_line/utils.py,sha256=L1PnV9tNupEW1zeziyb5aGAq8DYP8sMiuQbFYLO5Nus,1236
|
|
16
|
-
code_puppy/tools/__init__.py,sha256=48BVpMt0HAMtz8G_z9SQhX6LnRqR83_AVfMQMf7bY0g,557
|
|
17
|
-
code_puppy/tools/code_map.py,sha256=BghDHaebhGDfDGvA34gwO_5r92Py4O0Q3J4RV-WtnWs,3155
|
|
18
|
-
code_puppy/tools/command_runner.py,sha256=eg7pOIMkuHtNYVqVE1pPsNYSR2D6XXnkwFaBKd-Ejc8,4773
|
|
19
|
-
code_puppy/tools/common.py,sha256=dbmyZTrTBQh_0WWpaYN6jEync62W2mMrzNS8UFK0co4,146
|
|
20
|
-
code_puppy/tools/file_modifications.py,sha256=nT87uAoY14RTAapnFCgkLTmW9g9P9bymxts2MpSpoo0,19297
|
|
21
|
-
code_puppy/tools/file_operations.py,sha256=LJU_1b3WCXTAHa2B5VAbckrn1VVWb-HhcI3TF3BxYWs,11625
|
|
22
|
-
code_puppy/tools/web_search.py,sha256=HhcwX0MMvMDPFO8gr8gzgesD5wPXOypjkxyLZeNwL5g,589
|
|
23
|
-
code_puppy-0.0.52.data/data/code_puppy/models.json,sha256=7H-y97YK9BXhag5wJU19rtg24JtZWYx60RsBLBW3WiI,2162
|
|
24
|
-
code_puppy-0.0.52.dist-info/METADATA,sha256=06k73QklKcPlf-plfu2-wmaMzosKy7qrqaFSamlYkXo,4716
|
|
25
|
-
code_puppy-0.0.52.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
26
|
-
code_puppy-0.0.52.dist-info/entry_points.txt,sha256=d8YkBvIUxF-dHNJAj-x4fPEqizbY5d_TwvYpc01U5kw,58
|
|
27
|
-
code_puppy-0.0.52.dist-info/licenses/LICENSE,sha256=31u8x0SPgdOq3izJX41kgFazWsM43zPEF9eskzqbJMY,1075
|
|
28
|
-
code_puppy-0.0.52.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|