kopipasta 0.35.0__py3-none-any.whl → 0.36.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.
Potentially problematic release.
This version of kopipasta might be problematic. Click here for more details.
- kopipasta/cache.py +6 -3
- kopipasta/file.py +91 -56
- kopipasta/import_parser.py +141 -69
- kopipasta/main.py +611 -302
- kopipasta/prompt.py +50 -39
- kopipasta/tree_selector.py +243 -149
- {kopipasta-0.35.0.dist-info → kopipasta-0.36.0.dist-info}/METADATA +1 -1
- kopipasta-0.36.0.dist-info/RECORD +13 -0
- kopipasta-0.35.0.dist-info/RECORD +0 -13
- {kopipasta-0.35.0.dist-info → kopipasta-0.36.0.dist-info}/LICENSE +0 -0
- {kopipasta-0.35.0.dist-info → kopipasta-0.36.0.dist-info}/WHEEL +0 -0
- {kopipasta-0.35.0.dist-info → kopipasta-0.36.0.dist-info}/entry_points.txt +0 -0
- {kopipasta-0.35.0.dist-info → kopipasta-0.36.0.dist-info}/top_level.txt +0 -0
kopipasta/prompt.py
CHANGED
|
@@ -8,55 +8,59 @@ from typing import Dict, List, Tuple
|
|
|
8
8
|
def get_file_snippet(file_path, max_lines=50, max_bytes=4096):
|
|
9
9
|
snippet = ""
|
|
10
10
|
byte_count = 0
|
|
11
|
-
with open(file_path,
|
|
11
|
+
with open(file_path, "r") as file:
|
|
12
12
|
for i, line in enumerate(file):
|
|
13
13
|
if i >= max_lines or byte_count >= max_bytes:
|
|
14
14
|
break
|
|
15
15
|
snippet += line
|
|
16
|
-
byte_count += len(line.encode(
|
|
16
|
+
byte_count += len(line.encode("utf-8"))
|
|
17
17
|
return snippet
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
def get_language_for_file(file_path):
|
|
21
21
|
extension = os.path.splitext(file_path)[1].lower()
|
|
22
22
|
language_map = {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
23
|
+
".py": "python",
|
|
24
|
+
".js": "javascript",
|
|
25
|
+
".jsx": "jsx",
|
|
26
|
+
".ts": "typescript",
|
|
27
|
+
".tsx": "tsx",
|
|
28
|
+
".html": "html",
|
|
29
|
+
".htm": "html",
|
|
30
|
+
".css": "css",
|
|
31
|
+
".json": "json",
|
|
32
|
+
".md": "markdown",
|
|
33
|
+
".sql": "sql",
|
|
34
|
+
".sh": "bash",
|
|
35
|
+
".yml": "yaml",
|
|
36
|
+
".yaml": "yaml",
|
|
37
|
+
".go": "go",
|
|
38
|
+
".toml": "toml",
|
|
39
|
+
".c": "c",
|
|
40
|
+
".cpp": "cpp",
|
|
41
|
+
".cc": "cpp",
|
|
42
|
+
".h": "cpp",
|
|
43
|
+
".hpp": "cpp",
|
|
44
44
|
}
|
|
45
|
-
return language_map.get(extension,
|
|
45
|
+
return language_map.get(extension, "")
|
|
46
46
|
|
|
47
47
|
|
|
48
48
|
def get_project_structure(ignore_patterns):
|
|
49
49
|
tree = []
|
|
50
|
-
for root, dirs, files in os.walk(
|
|
51
|
-
dirs[:] = [
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
for root, dirs, files in os.walk("."):
|
|
51
|
+
dirs[:] = [
|
|
52
|
+
d for d in dirs if not is_ignored(os.path.join(root, d), ignore_patterns)
|
|
53
|
+
]
|
|
54
|
+
files = [
|
|
55
|
+
f for f in files if not is_ignored(os.path.join(root, f), ignore_patterns)
|
|
56
|
+
]
|
|
57
|
+
level = root.replace(".", "").count(os.sep)
|
|
58
|
+
indent = " " * 4 * level + "|-- "
|
|
55
59
|
tree.append(f"{indent}{os.path.basename(root)}/")
|
|
56
|
-
subindent =
|
|
60
|
+
subindent = " " * 4 * (level + 1) + "|-- "
|
|
57
61
|
for f in files:
|
|
58
62
|
tree.append(f"{subindent}{f}")
|
|
59
|
-
return
|
|
63
|
+
return "\n".join(tree)
|
|
60
64
|
|
|
61
65
|
|
|
62
66
|
def handle_env_variables(content, env_vars):
|
|
@@ -73,21 +77,28 @@ def handle_env_variables(content, env_vars):
|
|
|
73
77
|
|
|
74
78
|
for key, value in detected_vars:
|
|
75
79
|
while True:
|
|
76
|
-
choice = input(
|
|
77
|
-
|
|
80
|
+
choice = input(
|
|
81
|
+
f"How would you like to handle {key}? (m)ask / (s)kip / (k)eep: "
|
|
82
|
+
).lower()
|
|
83
|
+
if choice in ["m", "s", "k"]:
|
|
78
84
|
break
|
|
79
85
|
print("Invalid choice. Please enter 'm', 's', or 'k'.")
|
|
80
86
|
|
|
81
|
-
if choice ==
|
|
82
|
-
content = content.replace(value,
|
|
83
|
-
elif choice ==
|
|
87
|
+
if choice == "m":
|
|
88
|
+
content = content.replace(value, "*" * len(value))
|
|
89
|
+
elif choice == "s":
|
|
84
90
|
content = content.replace(value, "[REDACTED]")
|
|
85
91
|
# If 'k', we don't modify the content
|
|
86
92
|
|
|
87
93
|
return content
|
|
88
94
|
|
|
89
95
|
|
|
90
|
-
def generate_prompt_template(
|
|
96
|
+
def generate_prompt_template(
|
|
97
|
+
files_to_include: List[FileTuple],
|
|
98
|
+
ignore_patterns: List[str],
|
|
99
|
+
web_contents: Dict[str, Tuple[FileTuple, str]],
|
|
100
|
+
env_vars: Dict[str, str],
|
|
101
|
+
) -> Tuple[str, int]:
|
|
91
102
|
prompt = "# Project Overview\n\n"
|
|
92
103
|
prompt += "## Project Structure\n\n"
|
|
93
104
|
prompt += "```\n"
|
|
@@ -116,7 +127,7 @@ def generate_prompt_template(files_to_include: List[FileTuple], ignore_patterns:
|
|
|
116
127
|
for url, (file_tuple, content) in web_contents.items():
|
|
117
128
|
_, is_snippet, _, content_type = file_tuple
|
|
118
129
|
content = handle_env_variables(content, env_vars)
|
|
119
|
-
language = content_type if content_type in [
|
|
130
|
+
language = content_type if content_type in ["json", "csv"] else ""
|
|
120
131
|
prompt += f"### {url}{' (snippet)' if is_snippet else ''}\n\n```{language}\n{content}\n```\n\n"
|
|
121
132
|
|
|
122
133
|
prompt += "## Task Instructions\n\n"
|
|
@@ -160,4 +171,4 @@ def generate_prompt_template(files_to_include: List[FileTuple], ignore_patterns:
|
|
|
160
171
|
"**You MUST NOT**: Assume project file contents, continue past [AWAITING USER RESPONSE], be agreeable when you see problems\n"
|
|
161
172
|
)
|
|
162
173
|
prompt += analysis_text
|
|
163
|
-
return prompt, cursor_position
|
|
174
|
+
return prompt, cursor_position
|