janito 0.11.0__py3-none-any.whl → 0.13.0__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.
- janito/__init__.py +1 -1
- janito/__main__.py +6 -204
- janito/callbacks.py +34 -132
- janito/cli/__init__.py +6 -0
- janito/cli/agent.py +400 -0
- janito/cli/app.py +94 -0
- janito/cli/commands.py +329 -0
- janito/cli/output.py +29 -0
- janito/cli/utils.py +22 -0
- janito/config.py +358 -121
- janito/data/instructions_template.txt +28 -0
- janito/token_report.py +154 -145
- janito/tools/__init__.py +38 -21
- janito/tools/bash/bash.py +84 -0
- janito/tools/bash/unix_persistent_bash.py +184 -0
- janito/tools/bash/win_persistent_bash.py +308 -0
- janito/tools/decorators.py +2 -13
- janito/tools/delete_file.py +27 -9
- janito/tools/fetch_webpage/__init__.py +34 -0
- janito/tools/fetch_webpage/chunking.py +76 -0
- janito/tools/fetch_webpage/core.py +155 -0
- janito/tools/fetch_webpage/extractors.py +276 -0
- janito/tools/fetch_webpage/news.py +137 -0
- janito/tools/fetch_webpage/utils.py +108 -0
- janito/tools/find_files.py +106 -44
- janito/tools/move_file.py +72 -0
- janito/tools/prompt_user.py +37 -6
- janito/tools/replace_file.py +31 -4
- janito/tools/rich_console.py +176 -0
- janito/tools/search_text.py +35 -22
- janito/tools/str_replace_editor/editor.py +7 -4
- janito/tools/str_replace_editor/handlers/__init__.py +16 -0
- janito/tools/str_replace_editor/handlers/create.py +60 -0
- janito/tools/str_replace_editor/handlers/insert.py +100 -0
- janito/tools/str_replace_editor/handlers/str_replace.py +94 -0
- janito/tools/str_replace_editor/handlers/undo.py +64 -0
- janito/tools/str_replace_editor/handlers/view.py +159 -0
- janito/tools/str_replace_editor/utils.py +0 -1
- janito/tools/usage_tracker.py +136 -0
- janito-0.13.0.dist-info/METADATA +300 -0
- janito-0.13.0.dist-info/RECORD +47 -0
- janito/chat_history.py +0 -117
- janito/data/instructions.txt +0 -4
- janito/tools/bash.py +0 -22
- janito/tools/str_replace_editor/handlers.py +0 -335
- janito-0.11.0.dist-info/METADATA +0 -86
- janito-0.11.0.dist-info/RECORD +0 -26
- {janito-0.11.0.dist-info → janito-0.13.0.dist-info}/WHEEL +0 -0
- {janito-0.11.0.dist-info → janito-0.13.0.dist-info}/entry_points.txt +0 -0
- {janito-0.11.0.dist-info → janito-0.13.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,335 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Command handlers for the str_replace_editor package.
|
3
|
-
"""
|
4
|
-
import os
|
5
|
-
import pathlib
|
6
|
-
from typing import Dict, Any, Tuple
|
7
|
-
from janito.config import get_config
|
8
|
-
from .utils import normalize_path, _file_history
|
9
|
-
|
10
|
-
def handle_create(args: Dict[str, Any]) -> Tuple[str, bool]:
|
11
|
-
"""
|
12
|
-
Create a new file with the specified content.
|
13
|
-
|
14
|
-
Args:
|
15
|
-
args: Dictionary containing:
|
16
|
-
- path: Path to the file to create
|
17
|
-
- file_text: Content to write to the file
|
18
|
-
|
19
|
-
Returns:
|
20
|
-
A tuple containing (message, is_error)
|
21
|
-
"""
|
22
|
-
path = args.get("path")
|
23
|
-
file_text = args.get("file_text", "")
|
24
|
-
|
25
|
-
if not path:
|
26
|
-
return ("Missing required parameter: path", True)
|
27
|
-
|
28
|
-
path = normalize_path(path)
|
29
|
-
|
30
|
-
# Convert to Path object for better path handling
|
31
|
-
file_path = pathlib.Path(path)
|
32
|
-
|
33
|
-
# Check if the file already exists - according to spec, create cannot be used if file exists
|
34
|
-
if file_path.exists() and file_path.is_file():
|
35
|
-
return (f"File {path} already exists. The 'create' command cannot be used if the specified path already exists as a file.", True)
|
36
|
-
|
37
|
-
# Create parent directories if they don't exist
|
38
|
-
file_path.parent.mkdir(parents=True, exist_ok=True)
|
39
|
-
|
40
|
-
# Write the content to the file
|
41
|
-
try:
|
42
|
-
with open(file_path, 'w', encoding='utf-8') as f:
|
43
|
-
f.write(file_text)
|
44
|
-
# Show relative path if it's not an absolute path
|
45
|
-
display_path = path if os.path.isabs(path) else os.path.relpath(file_path, get_config().workspace_dir)
|
46
|
-
return (f"Successfully created file {display_path}", False)
|
47
|
-
except Exception as e:
|
48
|
-
return (f"Error creating file {path}: {str(e)}", True)
|
49
|
-
|
50
|
-
|
51
|
-
def handle_view(args: Dict[str, Any]) -> Tuple[str, bool]:
|
52
|
-
"""
|
53
|
-
View the contents of a file or list directory contents.
|
54
|
-
|
55
|
-
Args:
|
56
|
-
args: Dictionary containing:
|
57
|
-
- path: Path to the file or directory to view
|
58
|
-
- view_range (optional): Array of two integers specifying start and end line numbers
|
59
|
-
|
60
|
-
Returns:
|
61
|
-
A tuple containing (content_or_message, is_error)
|
62
|
-
"""
|
63
|
-
path = args.get("path")
|
64
|
-
view_range = args.get("view_range")
|
65
|
-
|
66
|
-
if not path:
|
67
|
-
return ("Missing required parameter: path", True)
|
68
|
-
|
69
|
-
path = normalize_path(path)
|
70
|
-
file_path = pathlib.Path(path)
|
71
|
-
|
72
|
-
if not file_path.exists():
|
73
|
-
return (f"File or directory {path} does not exist", True)
|
74
|
-
|
75
|
-
# If the path is a directory, list non-hidden files and directories up to 2 levels deep
|
76
|
-
if file_path.is_dir():
|
77
|
-
try:
|
78
|
-
result = []
|
79
|
-
# Process the first level
|
80
|
-
for item in sorted(file_path.iterdir()):
|
81
|
-
if item.name.startswith('.'):
|
82
|
-
continue # Skip hidden files/directories
|
83
|
-
|
84
|
-
if item.is_dir():
|
85
|
-
result.append(f"{item.name}/")
|
86
|
-
# Process the second level
|
87
|
-
try:
|
88
|
-
for subitem in sorted(item.iterdir()):
|
89
|
-
if subitem.name.startswith('.'):
|
90
|
-
continue # Skip hidden files/directories
|
91
|
-
|
92
|
-
if subitem.is_dir():
|
93
|
-
result.append(f"{item.name}/{subitem.name}/")
|
94
|
-
else:
|
95
|
-
result.append(f"{item.name}/{subitem.name}")
|
96
|
-
except PermissionError:
|
97
|
-
# Skip directories we can't access
|
98
|
-
pass
|
99
|
-
else:
|
100
|
-
result.append(item.name)
|
101
|
-
|
102
|
-
if not result:
|
103
|
-
return (f"Directory {path} is empty or contains only hidden files", False)
|
104
|
-
|
105
|
-
# Determine if we need to truncate the output
|
106
|
-
MAX_LINES = 100 # Arbitrary limit for demonstration
|
107
|
-
output = "\n".join(result)
|
108
|
-
if len(result) > MAX_LINES:
|
109
|
-
truncated_output = "\n".join(result[:MAX_LINES])
|
110
|
-
return (truncated_output + "\n<response clipped>", False)
|
111
|
-
|
112
|
-
return (output, False)
|
113
|
-
except Exception as e:
|
114
|
-
return (f"Error listing directory {path}: {str(e)}", True)
|
115
|
-
|
116
|
-
# If the path is a file, view its contents with cat -n style output
|
117
|
-
try:
|
118
|
-
with open(file_path, 'r', encoding='utf-8') as f:
|
119
|
-
content = f.readlines()
|
120
|
-
|
121
|
-
# If view_range is specified, return only the specified lines
|
122
|
-
if view_range:
|
123
|
-
start_line = max(1, view_range[0]) - 1 # Convert to 0-indexed
|
124
|
-
end_line = view_range[1] if view_range[1] != -1 else len(content)
|
125
|
-
end_line = min(end_line, len(content))
|
126
|
-
|
127
|
-
# Adjust content to only include the specified lines
|
128
|
-
content = content[start_line:end_line]
|
129
|
-
|
130
|
-
# Add line numbers to each line (cat -n style)
|
131
|
-
numbered_content = []
|
132
|
-
start_idx = 1 if view_range is None else view_range[0]
|
133
|
-
for i, line in enumerate(content):
|
134
|
-
line_number = start_idx + i
|
135
|
-
# Ensure line ends with newline
|
136
|
-
if not line.endswith('\n'):
|
137
|
-
line += '\n'
|
138
|
-
numbered_content.append(f"{line_number:6d}\t{line}")
|
139
|
-
|
140
|
-
# Show relative path if it's not an absolute path
|
141
|
-
display_path = path if os.path.isabs(path) else os.path.relpath(file_path, get_config().workspace_dir)
|
142
|
-
|
143
|
-
# Check if we need to truncate the output
|
144
|
-
MAX_LINES = 500 # Arbitrary limit for demonstration
|
145
|
-
if len(numbered_content) > MAX_LINES:
|
146
|
-
truncated_content = "".join(numbered_content[:MAX_LINES])
|
147
|
-
return (truncated_content + "\n<response clipped>", False)
|
148
|
-
|
149
|
-
return ("".join(numbered_content), False)
|
150
|
-
except Exception as e:
|
151
|
-
return (f"Error viewing file {path}: {str(e)}", True)
|
152
|
-
|
153
|
-
|
154
|
-
def handle_str_replace(args: Dict[str, Any]) -> Tuple[str, bool]:
|
155
|
-
"""
|
156
|
-
Replace a specific string in a file with a new string.
|
157
|
-
|
158
|
-
Args:
|
159
|
-
args: Dictionary containing:
|
160
|
-
- path: Path to the file to modify
|
161
|
-
- old_str: The text to replace (must match EXACTLY)
|
162
|
-
- new_str: The new text to insert
|
163
|
-
|
164
|
-
Returns:
|
165
|
-
A tuple containing (message, is_error)
|
166
|
-
"""
|
167
|
-
path = args.get("path")
|
168
|
-
old_str = args.get("old_str")
|
169
|
-
new_str = args.get("new_str", "") # new_str can be empty to effectively delete text
|
170
|
-
|
171
|
-
if not path:
|
172
|
-
return ("Missing required parameter: path", True)
|
173
|
-
if old_str is None:
|
174
|
-
return ("Missing required parameter: old_str", True)
|
175
|
-
|
176
|
-
path = normalize_path(path)
|
177
|
-
file_path = pathlib.Path(path)
|
178
|
-
|
179
|
-
if not file_path.exists():
|
180
|
-
return (f"File {path} does not exist", True)
|
181
|
-
|
182
|
-
try:
|
183
|
-
# Read the file content
|
184
|
-
with open(file_path, 'r', encoding='utf-8') as f:
|
185
|
-
content = f.read()
|
186
|
-
|
187
|
-
# Save the current content for undo
|
188
|
-
if path not in _file_history:
|
189
|
-
_file_history[path] = []
|
190
|
-
_file_history[path].append(content)
|
191
|
-
|
192
|
-
# Check if old_str exists in the content (must match EXACTLY)
|
193
|
-
if old_str not in content:
|
194
|
-
return ("Error: No exact match found for replacement. Please check your text and ensure whitespaces match exactly.", True)
|
195
|
-
|
196
|
-
# Count occurrences to check for multiple matches
|
197
|
-
match_count = content.count(old_str)
|
198
|
-
if match_count > 1:
|
199
|
-
return (f"Error: Found {match_count} matches for replacement text. The old_str parameter is not unique in the file. Please include more context to make it unique.", True)
|
200
|
-
|
201
|
-
# Replace the string
|
202
|
-
new_content = content.replace(old_str, new_str)
|
203
|
-
|
204
|
-
# Write the new content
|
205
|
-
with open(file_path, 'w', encoding='utf-8') as f:
|
206
|
-
f.write(new_content)
|
207
|
-
|
208
|
-
# Show relative path if it's not an absolute path in the original input
|
209
|
-
display_path = args.get("path") if os.path.isabs(args.get("path")) else os.path.relpath(file_path, get_config().workspace_dir)
|
210
|
-
return (f"Successfully replaced string in file {display_path}", False)
|
211
|
-
except Exception as e:
|
212
|
-
# Show relative path if it's not an absolute path in the original input
|
213
|
-
display_path = args.get("path") if os.path.isabs(args.get("path")) else os.path.relpath(file_path, get_config().workspace_dir)
|
214
|
-
return (f"Error replacing string in file {display_path}: {str(e)}", True)
|
215
|
-
|
216
|
-
|
217
|
-
def handle_insert(args: Dict[str, Any]) -> Tuple[str, bool]:
|
218
|
-
"""
|
219
|
-
Insert text at a specific location in a file.
|
220
|
-
|
221
|
-
Args:
|
222
|
-
args: Dictionary containing:
|
223
|
-
- path: Path to the file to modify
|
224
|
-
- insert_line: The line number after which to insert the text
|
225
|
-
- new_str: The text to insert
|
226
|
-
|
227
|
-
Returns:
|
228
|
-
A tuple containing (message, is_error)
|
229
|
-
"""
|
230
|
-
path = args.get("path")
|
231
|
-
insert_line = args.get("insert_line")
|
232
|
-
new_str = args.get("new_str")
|
233
|
-
|
234
|
-
if not path:
|
235
|
-
return ("Missing required parameter: path", True)
|
236
|
-
if insert_line is None:
|
237
|
-
return ("Missing required parameter: insert_line", True)
|
238
|
-
if new_str is None:
|
239
|
-
return ("Missing required parameter: new_str", True)
|
240
|
-
|
241
|
-
# Store the original path for display purposes
|
242
|
-
original_path = path
|
243
|
-
|
244
|
-
# Normalize the path (converts to absolute path)
|
245
|
-
path = normalize_path(path)
|
246
|
-
file_path = pathlib.Path(path)
|
247
|
-
|
248
|
-
if not file_path.exists():
|
249
|
-
return (f"File {path} does not exist", True)
|
250
|
-
|
251
|
-
try:
|
252
|
-
# Read the file content
|
253
|
-
with open(file_path, 'r', encoding='utf-8') as f:
|
254
|
-
lines = f.readlines()
|
255
|
-
content = "".join(lines)
|
256
|
-
|
257
|
-
# Save the current content for undo
|
258
|
-
if path not in _file_history:
|
259
|
-
_file_history[path] = []
|
260
|
-
_file_history[path].append(content)
|
261
|
-
|
262
|
-
# Check if insert_line is valid
|
263
|
-
if insert_line < 0 or insert_line > len(lines):
|
264
|
-
return (f"Invalid insert line {insert_line} for file {path}", True)
|
265
|
-
|
266
|
-
# Ensure new_str ends with a newline if it doesn't already
|
267
|
-
if new_str and not new_str.endswith('\n'):
|
268
|
-
new_str += '\n'
|
269
|
-
|
270
|
-
# Insert the new string
|
271
|
-
lines.insert(insert_line, new_str)
|
272
|
-
|
273
|
-
# Write the new content
|
274
|
-
with open(file_path, 'w', encoding='utf-8') as f:
|
275
|
-
f.writelines(lines)
|
276
|
-
|
277
|
-
# Show relative path if it's not an absolute path in the original input
|
278
|
-
display_path = original_path if os.path.isabs(original_path) else os.path.relpath(file_path, get_config().workspace_dir)
|
279
|
-
|
280
|
-
# If the response is too long, truncate it
|
281
|
-
response = f"Successfully inserted text at line {insert_line} in file {display_path}"
|
282
|
-
if len(response) > 1000: # Arbitrary limit for demonstration
|
283
|
-
return (response[:1000] + "\n<response clipped>", False)
|
284
|
-
|
285
|
-
return (response, False)
|
286
|
-
except Exception as e:
|
287
|
-
display_path = original_path if os.path.isabs(original_path) else os.path.relpath(file_path, get_config().workspace_dir)
|
288
|
-
return (f"Error inserting text in file {display_path}: {str(e)}", True)
|
289
|
-
|
290
|
-
|
291
|
-
def handle_undo_edit(args: Dict[str, Any]) -> Tuple[str, bool]:
|
292
|
-
"""
|
293
|
-
Undo the last edit made to a file using in-memory history.
|
294
|
-
|
295
|
-
Args:
|
296
|
-
args: Dictionary containing:
|
297
|
-
- path: Path to the file whose last edit should be undone
|
298
|
-
|
299
|
-
Returns:
|
300
|
-
A tuple containing (message, is_error)
|
301
|
-
"""
|
302
|
-
path = args.get("path")
|
303
|
-
|
304
|
-
if not path:
|
305
|
-
return ("Missing required parameter: path", True)
|
306
|
-
|
307
|
-
# Store the original path for display purposes
|
308
|
-
original_path = path
|
309
|
-
|
310
|
-
# Normalize the path (converts to absolute path)
|
311
|
-
path = normalize_path(path)
|
312
|
-
file_path = pathlib.Path(path)
|
313
|
-
|
314
|
-
# Check if file exists
|
315
|
-
if not file_path.exists():
|
316
|
-
return (f"File {path} does not exist", True)
|
317
|
-
|
318
|
-
# Check in-memory history
|
319
|
-
if path not in _file_history or not _file_history[path]:
|
320
|
-
return (f"No edit history for file {path}", True)
|
321
|
-
|
322
|
-
try:
|
323
|
-
# Get the last content
|
324
|
-
last_content = _file_history[path].pop()
|
325
|
-
|
326
|
-
# Write the last content back to the file
|
327
|
-
with open(path, 'w', encoding='utf-8') as f:
|
328
|
-
f.write(last_content)
|
329
|
-
|
330
|
-
# Show relative path if it's not an absolute path in the original input
|
331
|
-
display_path = original_path if os.path.isabs(original_path) else os.path.relpath(file_path, get_config().workspace_dir)
|
332
|
-
return (f"Successfully reverted the last edit made to the file {display_path}", False)
|
333
|
-
except Exception as e:
|
334
|
-
display_path = original_path if os.path.isabs(original_path) else os.path.relpath(file_path, get_config().workspace_dir)
|
335
|
-
return (f"Error undoing edit to file {display_path}: {str(e)}", True)
|
janito-0.11.0.dist-info/METADATA
DELETED
@@ -1,86 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.4
|
2
|
-
Name: janito
|
3
|
-
Version: 0.11.0
|
4
|
-
Summary: Janito CLI tool
|
5
|
-
Project-URL: Homepage, https://github.com/joaompinto/janito
|
6
|
-
Author-email: João Pinto <lamego.pinto@gmail.com>
|
7
|
-
License-File: LICENSE
|
8
|
-
Requires-Python: >=3.8
|
9
|
-
Requires-Dist: claudine>=0.1.0
|
10
|
-
Requires-Dist: rich>=13.0.0
|
11
|
-
Requires-Dist: typer>=0.9.0
|
12
|
-
Description-Content-Type: text/markdown
|
13
|
-
|
14
|
-
# 🤖 Janito
|
15
|
-
|
16
|
-
Janito is a powerful AI-assisted command-line interface (CLI) tool built with Python, leveraging Anthropic's Claude for intelligent code and file management.
|
17
|
-
|
18
|
-
## ✨ Features
|
19
|
-
|
20
|
-
- 🧠 Intelligent AI assistant powered by Claude
|
21
|
-
- 📁 File management capabilities
|
22
|
-
- 🔍 Smart code search and editing
|
23
|
-
- 💻 Interactive terminal interface with rich formatting
|
24
|
-
- 📊 Token usage tracking and cost reporting
|
25
|
-
|
26
|
-
## 🛠️ Installation
|
27
|
-
|
28
|
-
```bash
|
29
|
-
# Install directly from PyPI
|
30
|
-
pip install janito
|
31
|
-
```
|
32
|
-
|
33
|
-
For development or installation from source, please see [README_DEV.md](README_DEV.md).
|
34
|
-
|
35
|
-
## 🚀 Usage
|
36
|
-
|
37
|
-
After installation, you can use the `janito` command in your terminal:
|
38
|
-
|
39
|
-
```bash
|
40
|
-
# Get help
|
41
|
-
janito --help
|
42
|
-
|
43
|
-
|
44
|
-
# Ask the AI assistant a question
|
45
|
-
janito "Suggest improvements to this project"
|
46
|
-
|
47
|
-
janito "Add a --version to the cli to report he version"
|
48
|
-
|
49
|
-
```
|
50
|
-
|
51
|
-
## 🔧 Available Tools
|
52
|
-
|
53
|
-
Janito comes with several built-in tools:
|
54
|
-
- 📄 `str_replace_editor` - View, create, and edit files
|
55
|
-
- 🔎 `find_files` - Find files matching patterns
|
56
|
-
- 🗑️ `delete_file` - Delete files
|
57
|
-
- 🔍 `search_text` - Search for text patterns in files
|
58
|
-
|
59
|
-
## ⚙️ Requirements
|
60
|
-
|
61
|
-
- Python 3.8 or higher
|
62
|
-
- Dependencies:
|
63
|
-
- typer (>=0.9.0)
|
64
|
-
- rich (>=13.0.0)
|
65
|
-
- claudine (for Claude AI integration)
|
66
|
-
|
67
|
-
## 🔑 API Key
|
68
|
-
|
69
|
-
Janito requires an Anthropic API key to function. You can:
|
70
|
-
1. Set it as an environment variable: `export ANTHROPIC_API_KEY=your_api_key`
|
71
|
-
2. Or enter it when prompted
|
72
|
-
|
73
|
-
## 💻 Development
|
74
|
-
|
75
|
-
```bash
|
76
|
-
# Create a virtual environment
|
77
|
-
python -m venv .venv
|
78
|
-
source .venv/bin/activate # On Windows: .venv\Scripts\activate
|
79
|
-
|
80
|
-
# Install development dependencies
|
81
|
-
pip install -e ".[dev]"
|
82
|
-
```
|
83
|
-
|
84
|
-
## 📜 License
|
85
|
-
|
86
|
-
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
janito-0.11.0.dist-info/RECORD
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
janito/__init__.py,sha256=Ral9Ev43UBuUjoDGLTUMJ62fAiWUC6zMMkOKTkzAQmo,53
|
2
|
-
janito/__main__.py,sha256=IvUnkU8o5JEvwDkv-gXgPXdQWVubY7-0tiVOZrieu-s,8779
|
3
|
-
janito/callbacks.py,sha256=5SoXyyvksSK_xusch3Wb5dIBohChAD2g3B51CehUxYY,4916
|
4
|
-
janito/chat_history.py,sha256=LH1vBq472Duw3kis8FushjwZtI052IPsFZcKwaVjytM,3622
|
5
|
-
janito/config.py,sha256=ZKW4PtiSkayaXaT0jtLFUALl3CnXfgqFwxRwuZfb0es,4432
|
6
|
-
janito/test_file.py,sha256=c6GWGdTYG3z-Y5XBao9Tmhmq3G-v0L37OfwLgBo8zIU,126
|
7
|
-
janito/token_report.py,sha256=1ja93AGTMCXNV0WMUq2nmstKrrt9UEukjheOUVKEmzY,8842
|
8
|
-
janito/data/instructions.txt,sha256=ivNjw7s5qXYqV7K8ZLlPII_XSQSvtWq7WCHx3sr0b-I,232
|
9
|
-
janito/tools/__init__.py,sha256=XW9EaEishvAf4qtylJquti77Q8OL3dVyAIPO_LUUFFg,646
|
10
|
-
janito/tools/bash.py,sha256=FkVUYaPfo_yZ2zUiGKtE_7sPKJlWVBdtIdCB7m7-g4s,737
|
11
|
-
janito/tools/decorators.py,sha256=SMirsokAwesiS4ZoZhxXSenMR78Vh-C9PGLpyvW0Xwo,3095
|
12
|
-
janito/tools/delete_file.py,sha256=L5oilAuO3OtJ1qhmtRO-lVQMwDKteP-P3S55PI9g-AE,1442
|
13
|
-
janito/tools/find_files.py,sha256=VDoait4sMaJtQdECltTQzOAN_5FRpp8j5bFTznOnbcw,6280
|
14
|
-
janito/tools/prompt_user.py,sha256=TMa9BZk5t8AGwj_Zzxu9ciIXm1J0PhRMolGv6V5MPUA,738
|
15
|
-
janito/tools/replace_file.py,sha256=NFlmrvXagFwxfDk1Py-qZYLMXDkc_MiPAzaeQqvDBtk,1115
|
16
|
-
janito/tools/search_text.py,sha256=d3iYMGHS7ZeMJxek4A_7DwMrnsWkp_XOtp3bkyNor0M,9292
|
17
|
-
janito/tools/str_replace_editor/__init__.py,sha256=kYmscmQgft3Jzt3oCNz7k2FiRbJvku6OFDDC3Q_zoAA,144
|
18
|
-
janito/tools/str_replace_editor/editor.py,sha256=DqoK5Yn_3hClisUOkRfSIMvkPVofBuGIe8UpD93K9W0,2306
|
19
|
-
janito/tools/str_replace_editor/handlers.py,sha256=2HlBAnzg6S8YSfGtGZuQp857Rfn6nybew3TWf5TPnuI,13395
|
20
|
-
janito/tools/str_replace_editor/utils.py,sha256=h-unWcrVEcH0xgsW-iJuApUa0Lc4gsPyBlmtn2mw64I,979
|
21
|
-
janito/data/instructions.txt,sha256=ivNjw7s5qXYqV7K8ZLlPII_XSQSvtWq7WCHx3sr0b-I,232
|
22
|
-
janito-0.11.0.dist-info/METADATA,sha256=pTblnOR4OX2AqiuV6wyDPj7gDD2vRxDx4CvLLa281Nc,2146
|
23
|
-
janito-0.11.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
24
|
-
janito-0.11.0.dist-info/entry_points.txt,sha256=JMbF_1jg-xQddidpAYkzjOKdw70fy_ymJfcmerY2wIY,47
|
25
|
-
janito-0.11.0.dist-info/licenses/LICENSE,sha256=6-H8LXExbBIAuT4cyiE-Qy8Bad1K4pagQRVTWr6wkhk,1096
|
26
|
-
janito-0.11.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|