code-puppy 0.0.59__py3-none-any.whl → 0.0.61__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.
@@ -0,0 +1,393 @@
1
+ import os
2
+ from code_puppy.tools.common import should_ignore_path
3
+ from pathlib import Path
4
+ from rich.text import Text
5
+ from rich.tree import Tree as RichTree
6
+ from rich.console import Console
7
+ from tree_sitter_language_pack import get_parser
8
+
9
+ from functools import partial, wraps
10
+
11
+
12
+ def _f(fmt): # helper to keep the table tidy
13
+ return lambda name, _fmt=fmt: _fmt.format(name=name)
14
+
15
+
16
+ def mark_export(label_fn, default=False):
17
+ """Decorator to prefix 'export ' (or 'export default ') when requested."""
18
+
19
+ @wraps(label_fn)
20
+ def _wrap(name, *, exported=False):
21
+ prefix = "export default " if default else "export " if exported else ""
22
+ return prefix + label_fn(name)
23
+
24
+ return _wrap
25
+
26
+
27
+ LANGS = {
28
+ ".py": {
29
+ "lang": "python",
30
+ "name_field": "name",
31
+ "nodes": {
32
+ "function_definition": partial(_f("def {name}()"), style="green"),
33
+ "class_definition": partial(_f("class {name}"), style="magenta"),
34
+ },
35
+ },
36
+ ".rb": {
37
+ "lang": "ruby",
38
+ "name_field": "name",
39
+ "nodes": {
40
+ "method": partial(_f("def {name}"), style="green"),
41
+ "class": partial(_f("class {name}"), style="magenta"),
42
+ },
43
+ },
44
+ ".php": {
45
+ "lang": "php",
46
+ "name_field": "name",
47
+ "nodes": {
48
+ "function_definition": partial(_f("function {name}()"), style="green"),
49
+ "class_declaration": partial(_f("class {name}"), style="magenta"),
50
+ },
51
+ },
52
+ ".lua": {
53
+ "lang": "lua",
54
+ "name_field": "name",
55
+ "nodes": {
56
+ "function_declaration": partial(_f("function {name}()"), style="green")
57
+ },
58
+ },
59
+ ".pl": {
60
+ "lang": "perl",
61
+ "name_field": "name",
62
+ "nodes": {"sub_definition": partial(_f("sub {name}()"), style="green")},
63
+ },
64
+ ".r": {
65
+ "lang": "r",
66
+ "name_field": "name",
67
+ "nodes": {"function_definition": partial(_f("func {name}()"), style="green")},
68
+ },
69
+ ".js": {
70
+ "lang": "javascript",
71
+ "name_field": "name",
72
+ "nodes": {
73
+ "function_declaration": partial(_f("function {name}()"), style="green"),
74
+ "class_declaration": partial(_f("class {name}"), style="magenta"),
75
+ "export_statement": partial(_f("export {name}"), style="yellow"),
76
+ "export_default_statement": partial(
77
+ _f("export default {name}"), style="yellow"
78
+ ),
79
+ },
80
+ },
81
+ ".mjs": {
82
+ "lang": "javascript",
83
+ "name_field": "name",
84
+ "nodes": {
85
+ "function_declaration": partial(_f("function {name}()"), style="green"),
86
+ "class_declaration": partial(_f("class {name}"), style="magenta"),
87
+ "export_statement": partial(_f("export {name}"), style="yellow"),
88
+ "export_default_statement": partial(
89
+ _f("export default {name}"), style="yellow"
90
+ ),
91
+ },
92
+ },
93
+ ".cjs": {
94
+ "lang": "javascript",
95
+ "name_field": "name",
96
+ "nodes": {
97
+ "function_declaration": partial(_f("function {name}()"), style="green"),
98
+ "class_declaration": partial(_f("class {name}"), style="magenta"),
99
+ "export_statement": partial(_f("export {name}"), style="yellow"),
100
+ "export_default_statement": partial(
101
+ _f("export default {name}"), style="yellow"
102
+ ),
103
+ },
104
+ },
105
+ ".jsx": {
106
+ "lang": "jsx",
107
+ "name_field": None,
108
+ "nodes": {
109
+ "function_declaration": partial(_f("function {name}()"), style="green"),
110
+ "class_declaration": partial(_f("class {name}"), style="magenta"),
111
+ "export_statement": partial(_f("export {name}"), style="yellow"),
112
+ },
113
+ },
114
+ ".ts": {
115
+ "lang": "tsx",
116
+ "name_field": None,
117
+ "nodes": {
118
+ "function_declaration": partial(_f("function {name}()"), style="green"),
119
+ "class_declaration": partial(_f("class {name}"), style="magenta"),
120
+ "export_statement": partial(_f("export {name}"), style="yellow"),
121
+ },
122
+ },
123
+ ".tsx": {
124
+ "lang": "tsx",
125
+ "name_field": None,
126
+ "nodes": {
127
+ "function_declaration": partial(_f("function {name}()"), style="green"),
128
+ "class_declaration": partial(_f("class {name}"), style="magenta"),
129
+ "export_statement": partial(_f("export {name}"), style="yellow"),
130
+ "interface_declaration": partial(_f("interface {name}"), style="green"),
131
+ },
132
+ },
133
+ # ───────── systems / compiled ────────────────────────────────────
134
+ ".c": {
135
+ "lang": "c",
136
+ "name_field": "declarator", # struct ident is under declarator
137
+ "nodes": {
138
+ "function_definition": partial(_f("fn {name}()"), style="green"),
139
+ "struct_specifier": partial(_f("struct {name}"), style="magenta"),
140
+ },
141
+ },
142
+ ".h": {
143
+ "lang": "c",
144
+ "name_field": "declarator", # struct ident is under declarator
145
+ "nodes": {
146
+ "function_definition": partial(_f("fn {name}()"), style="green"),
147
+ "struct_specifier": partial(_f("struct {name}"), style="magenta"),
148
+ },
149
+ },
150
+ ".cpp": {
151
+ "lang": "cpp",
152
+ "name_field": "declarator",
153
+ "nodes": {
154
+ "function_definition": partial(_f("fn {name}()"), style="green"),
155
+ "class_specifier": partial(_f("class {name}"), style="magenta"),
156
+ "struct_specifier": partial(_f("struct {name}"), style="magenta"),
157
+ },
158
+ },
159
+ ".hpp": {
160
+ "lang": "cpp",
161
+ "name_field": "declarator",
162
+ "nodes": {
163
+ "function_definition": partial(_f("fn {name}()"), style="green"),
164
+ "class_specifier": partial(_f("class {name}"), style="magenta"),
165
+ "struct_specifier": partial(_f("struct {name}"), style="magenta"),
166
+ },
167
+ },
168
+ ".cc": {
169
+ "lang": "cpp",
170
+ "name_field": "declarator",
171
+ "nodes": {
172
+ "function_definition": partial(_f("fn {name}()"), style="green"),
173
+ "class_specifier": partial(_f("class {name}"), style="magenta"),
174
+ "struct_specifier": partial(_f("struct {name}"), style="magenta"),
175
+ },
176
+ },
177
+ ".hh": {
178
+ "lang": "cpp",
179
+ "name_field": "declarator",
180
+ "nodes": {
181
+ "function_definition": partial(_f("fn {name}()"), style="green"),
182
+ "class_specifier": partial(_f("class {name}"), style="magenta"),
183
+ "struct_specifier": partial(_f("struct {name}"), style="magenta"),
184
+ },
185
+ },
186
+ ".cs": {
187
+ "lang": "c_sharp",
188
+ "name_field": "name",
189
+ "nodes": {
190
+ "method_declaration": partial(_f("method {name}()"), style="green"),
191
+ "class_declaration": partial(_f("class {name}"), style="magenta"),
192
+ },
193
+ },
194
+ ".java": {
195
+ "lang": "java",
196
+ "name_field": "name",
197
+ "nodes": {
198
+ "method_declaration": partial(_f("method {name}()"), style="green"),
199
+ "class_declaration": partial(_f("class {name}"), style="magenta"),
200
+ },
201
+ },
202
+ ".kt": {
203
+ "lang": "kotlin",
204
+ "name_field": "name",
205
+ "nodes": {
206
+ "function_declaration": partial(_f("fun {name}()"), style="green"),
207
+ "class_declaration": partial(_f("class {name}"), style="magenta"),
208
+ },
209
+ },
210
+ ".swift": {
211
+ "lang": "swift",
212
+ "name_field": "name",
213
+ "nodes": {
214
+ "function_declaration": partial(_f("func {name}()"), style="green"),
215
+ "class_declaration": partial(_f("class {name}"), style="magenta"),
216
+ },
217
+ },
218
+ ".go": {
219
+ "lang": "go",
220
+ "name_field": "name",
221
+ "nodes": {
222
+ "function_declaration": partial(_f("func {name}()"), style="green"),
223
+ "type_spec": partial(_f("type {name}"), style="magenta"),
224
+ },
225
+ },
226
+ ".rs": {
227
+ "lang": "rust",
228
+ "name_field": "name",
229
+ "nodes": {
230
+ "function_item": partial(_f("fn {name}()"), style="green"),
231
+ "struct_item": partial(_f("struct {name}"), style="magenta"),
232
+ "trait_item": partial(_f("trait {name}"), style="magenta"),
233
+ },
234
+ },
235
+ ".zig": {
236
+ "lang": "zig",
237
+ "name_field": "name",
238
+ "nodes": {
239
+ "fn_proto": partial(_f("fn {name}()"), style="green"),
240
+ "struct_decl": partial(_f("struct {name}"), style="magenta"),
241
+ },
242
+ },
243
+ ".scala": {
244
+ "lang": "scala",
245
+ "name_field": "name",
246
+ "nodes": {
247
+ "function_definition": partial(_f("def {name}()"), style="green"),
248
+ "class_definition": partial(_f("class {name}"), style="magenta"),
249
+ "object_definition": partial(_f("object {name}"), style="magenta"),
250
+ },
251
+ },
252
+ ".hs": {
253
+ "lang": "haskell",
254
+ "name_field": "name",
255
+ "nodes": {
256
+ "function_declaration": partial(_f("fun {name}"), style="green"),
257
+ "type_declaration": partial(_f("type {name}"), style="magenta"),
258
+ },
259
+ },
260
+ ".jl": {
261
+ "lang": "julia",
262
+ "name_field": "name",
263
+ "nodes": {
264
+ "function_definition": partial(_f("function {name}()"), style="green"),
265
+ "abstract_type_definition": partial(_f("abstract {name}"), style="magenta"),
266
+ "struct_definition": partial(_f("struct {name}"), style="magenta"),
267
+ },
268
+ },
269
+ # ───────── scripting (shell / infra) ─────────────────────────────
270
+ ".sh": {
271
+ "lang": "bash",
272
+ "name_field": "name",
273
+ "nodes": {"function_definition": partial(_f("fn {name}()"), style="green")},
274
+ },
275
+ ".ps1": {
276
+ "lang": "powershell",
277
+ "name_field": "name",
278
+ "nodes": {
279
+ "function_definition": partial(_f("function {name}()"), style="green")
280
+ },
281
+ },
282
+ # ───────── web / data description (pure-function view) ───────────
283
+ ".html": {
284
+ "lang": "html",
285
+ "name_field": "name", # rarely useful, but included for completeness
286
+ "nodes": {"element": partial(_f("<{name}>"), style="yellow")},
287
+ },
288
+ ".css": {
289
+ "lang": "css",
290
+ "name_field": "name",
291
+ "nodes": {
292
+ "class_selector": partial(_f(".{name}"), style="yellow"),
293
+ "id_selector": partial(_f("#{name}"), style="yellow"),
294
+ },
295
+ },
296
+ }
297
+
298
+ # Cache parsers so we don’t re-create them file-after-file
299
+ _PARSER_CACHE = {}
300
+
301
+
302
+ def parser_for(lang_name):
303
+ if lang_name not in _PARSER_CACHE:
304
+ _PARSER_CACHE[lang_name] = get_parser(lang_name)
305
+ return _PARSER_CACHE[lang_name]
306
+
307
+
308
+ # ----------------------------------------------------------------------
309
+ # helper: breadth-first search for an identifier-ish node
310
+ # ----------------------------------------------------------------------
311
+ def _first_identifier(node):
312
+ from collections import deque
313
+
314
+ q = deque([node])
315
+ while q:
316
+ n = q.popleft()
317
+ if n.type in {"identifier", "property_identifier", "type_identifier"}:
318
+ return n
319
+ q.extend(n.children)
320
+ return None
321
+
322
+
323
+ def _span(node):
324
+ """Return "[start:end]" lines (1‑based, inclusive)."""
325
+ start_line = node.start_point[0] + 1
326
+ end_line = node.end_point[0] + 1
327
+ return Text(f" [{start_line}:{end_line}]", style="bold white")
328
+
329
+
330
+ def _walk(ts_node, rich_parent, info):
331
+ nodes_cfg = info["nodes"]
332
+ name_field = info["name_field"]
333
+
334
+ for child in ts_node.children:
335
+ t = child.type
336
+ if t in nodes_cfg:
337
+ style = nodes_cfg[t].keywords["style"]
338
+
339
+ if name_field:
340
+ ident = child.child_by_field_name(name_field)
341
+ else:
342
+ ident = _first_identifier(child)
343
+
344
+ label_text = ident.text.decode() if ident else "<anon>"
345
+ label = nodes_cfg[t].func(label_text)
346
+ branch = rich_parent.add(Text(label, style=style) + _span(child))
347
+ _walk(child, branch, info)
348
+ else:
349
+ _walk(child, rich_parent, info)
350
+
351
+
352
+ def map_code_file(filepath):
353
+ ext = Path(filepath).suffix
354
+ info = LANGS.get(ext)
355
+ if not info:
356
+ return None
357
+
358
+ code = Path(filepath).read_bytes()
359
+ parser = parser_for(info["lang"])
360
+ tree = parser.parse(code)
361
+
362
+ root_label = Path(filepath).name
363
+ base = RichTree(Text(root_label, style="bold cyan"))
364
+
365
+ if tree.root_node.has_error:
366
+ base.add(Text("⚠️ syntax error", style="bold red"))
367
+
368
+ _walk(tree.root_node, base, info)
369
+ return base
370
+
371
+
372
+ def make_code_map(directory: str, ignore_tests: bool = True) -> str:
373
+ base_tree = RichTree(Text(Path(directory).name, style="bold magenta"))
374
+
375
+ for root, dirs, files in os.walk(directory):
376
+ dirs[:] = [d for d in dirs if not d.startswith(".")]
377
+ for f in files:
378
+ if (
379
+ should_ignore_path(os.path.join(root, f))
380
+ or ignore_tests
381
+ and "test" in f
382
+ ):
383
+ continue
384
+ try:
385
+ file_tree = map_code_file(os.path.join(root, f))
386
+ if file_tree is not None:
387
+ base_tree.add(file_tree)
388
+ except Exception:
389
+ base_tree.add(Text(f"[error reading {f}]", style="bold red"))
390
+
391
+ buf = Console(record=True, width=120)
392
+ buf.print(base_tree)
393
+ return buf.export_text()
@@ -1,38 +1,23 @@
1
1
  {
2
2
  "gemini-2.5-flash-preview-05-20": {
3
3
  "type": "gemini",
4
- "name": "gemini-2.5-flash-preview-05-20",
5
- "max_requests_per_minute": 10,
6
- "max_retries": 3,
7
- "retry_base_delay": 10
4
+ "name": "gemini-2.5-flash-preview-05-20"
8
5
  },
9
6
  "gpt-4.1": {
10
7
  "type": "openai",
11
- "name": "gpt-4.1",
12
- "max_requests_per_minute": 100,
13
- "max_retries": 3,
14
- "retry_base_delay": 10
8
+ "name": "gpt-4.1"
15
9
  },
16
10
  "gpt-4.1-mini": {
17
11
  "type": "openai",
18
- "name": "gpt-4.1-mini",
19
- "max_requests_per_minute": 100,
20
- "max_retries": 3,
21
- "retry_base_delay": 10
12
+ "name": "gpt-4.1-mini"
22
13
  },
23
14
  "gpt-4.1-nano": {
24
15
  "type": "openai",
25
- "name": "gpt-4.1-nano",
26
- "max_requests_per_minute": 100,
27
- "max_retries": 3,
28
- "retry_base_delay": 10
16
+ "name": "gpt-4.1-nano"
29
17
  },
30
18
  "gpt-4.1-custom": {
31
19
  "type": "custom_openai",
32
20
  "name": "gpt-4.1-custom",
33
- "max_requests_per_minute": 100,
34
- "max_retries": 3,
35
- "retry_base_delay": 10,
36
21
  "custom_endpoint": {
37
22
  "url": "https://my.cute.endpoint:8080",
38
23
  "headers": {
@@ -44,9 +29,6 @@
44
29
  "ollama-llama3.3": {
45
30
  "type": "custom_openai",
46
31
  "name": "llama3.3",
47
- "max_requests_per_minute": 100,
48
- "max_retries": 3,
49
- "retry_base_delay": 5,
50
32
  "custom_endpoint": {
51
33
  "url": "http://localhost:11434/v1"
52
34
  }
@@ -54,9 +36,6 @@
54
36
  "meta-llama/Llama-3.3-70B-Instruct-Turbo": {
55
37
  "type": "custom_openai",
56
38
  "name": "meta-llama/Llama-3.3-70B-Instruct-Turbo",
57
- "max_requests_per_minute": 100,
58
- "max_retries": 3,
59
- "retry_base_delay": 5,
60
39
  "custom_endpoint": {
61
40
  "url": "https://api.together.xyz/v1",
62
41
  "api_key": "$TOGETHER_API_KEY"
@@ -65,9 +44,6 @@
65
44
  "grok-3-mini-fast": {
66
45
  "type": "custom_openai",
67
46
  "name": "grok-3-mini-fast",
68
- "max_requests_per_minute": 100,
69
- "max_retries": 3,
70
- "retry_base_delay": 5,
71
47
  "custom_endpoint": {
72
48
  "url": "https://api.x.ai/v1",
73
49
  "api_key": "$XAI_API_KEY"
@@ -76,9 +52,6 @@
76
52
  "azure-gpt-4.1": {
77
53
  "type": "azure_openai",
78
54
  "name": "gpt-4.1",
79
- "max_requests_per_minute": 100,
80
- "max_retries": 3,
81
- "retry_base_delay": 5,
82
55
  "api_version": "2024-12-01-preview",
83
56
  "api_key": "$AZURE_OPENAI_API_KEY",
84
57
  "azure_endpoint": "$AZURE_OPENAI_ENDPOINT"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-puppy
3
- Version: 0.0.59
3
+ Version: 0.0.61
4
4
  Summary: Code generation agent
5
5
  Author: Michael Pfaffenberger
6
6
  License: MIT
@@ -27,6 +27,8 @@ Requires-Dist: python-dotenv>=1.0.0
27
27
  Requires-Dist: rapidfuzz>=3.13.0
28
28
  Requires-Dist: rich>=13.4.2
29
29
  Requires-Dist: ruff>=0.11.11
30
+ Requires-Dist: tree-sitter-language-pack>=0.8.0
31
+ Requires-Dist: tree-sitter-typescript>=0.23.2
30
32
  Description-Content-Type: text/markdown
31
33
 
32
34
  # 🐶 Code Puppy 🐶
@@ -0,0 +1,28 @@
1
+ code_puppy/__init__.py,sha256=-ANvE6Xe5NlWDIRCIfL1x-rgtCZ6zM2Ye9NphFoULSY,82
2
+ code_puppy/agent.py,sha256=QRBid--LcJv8fbhS9u6Foavgt3jI1B-K_1Arv-kXQsc,3420
3
+ code_puppy/agent_prompts.py,sha256=DnPNubiFtD6Ot76cIsxedJEaEVYS5AaxR3JWJM5nXNg,6925
4
+ code_puppy/config.py,sha256=LTcZe5eHTT0zq-YJzSeNg8LCwhHb1HGN4tOkITtb7Eo,3941
5
+ code_puppy/main.py,sha256=qDbDB123MAv5r_kH91x1LxUROI9I28y2tvuYo2YxEbQ,10323
6
+ code_puppy/model_factory.py,sha256=jZH96zE5GMTK3RWjUpZB4HjbSO3fSaAzjRoQh8Y8lfg,7711
7
+ code_puppy/models.json,sha256=3tiU7_ra39CK8aOFRsVqG7veZDdzq8hAmI5BcfZEWck,1393
8
+ code_puppy/session_memory.py,sha256=4sgAAjbXdLSi8hETpd56tgtrG6hqMUuZWDlJOu6BQjA,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=gw8NpIxa6GOpczUJRyh7VNZwoXKKn-yvCqit7h2y6Gg,2931
12
+ code_puppy/command_line/meta_command_handler.py,sha256=aKSPu_aB98TAuaFwyI4HmrFd45dk6mrhnvR-WvnQuQA,5713
13
+ code_puppy/command_line/model_picker_completion.py,sha256=NkyZZG7IhcVWSJ3ADytwCA5f8DpNeVs759Qtqs4fQtY,3733
14
+ code_puppy/command_line/prompt_toolkit_completion.py,sha256=_gP0FIOgHDNHTTWLNL0XNzr6sO0ISe7Mec1uQNo9kcM,8337
15
+ code_puppy/command_line/utils.py,sha256=7eyxDHjPjPB9wGDJQQcXV_zOsGdYsFgI0SGCetVmTqE,1251
16
+ code_puppy/tools/__init__.py,sha256=J_HCbkivdr1rP5vfucxttXhGmTBx0S2LNoDMrbaE-Fc,558
17
+ code_puppy/tools/command_runner.py,sha256=cEphrDyr12CoqpKizzaxhMHhG1HiVcqXArTkwc6lvxU,6760
18
+ code_puppy/tools/common.py,sha256=4AmPc_jx45nhJBS1TMhqF-i9pJZzmyOmYBcrqFAhSIE,2275
19
+ code_puppy/tools/file_modifications.py,sha256=nEHvdHJ1ige82gguf7-dybD0_e5AYFVARsYFgaTGLfY,13056
20
+ code_puppy/tools/file_operations.py,sha256=xqj7MiK6sGTaC8NMrMRTybWlXG32S-DjybqJtnufRcI,11715
21
+ code_puppy/tools/ts_code_map.py,sha256=0fSZQdNuikG6W43LQXn2oxim75MsXy0DfSfHt-saSZo,13523
22
+ code_puppy/tools/web_search.py,sha256=sA2ierjuuYA517-uhb5s53SgeVsyOe1nExoZsrU1Fps,1284
23
+ code_puppy-0.0.61.data/data/code_puppy/models.json,sha256=3tiU7_ra39CK8aOFRsVqG7veZDdzq8hAmI5BcfZEWck,1393
24
+ code_puppy-0.0.61.dist-info/METADATA,sha256=aZT117pFif0vTOEZjXSr77kfQ-ek7il-DC6mTvQgkAs,4878
25
+ code_puppy-0.0.61.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
26
+ code_puppy-0.0.61.dist-info/entry_points.txt,sha256=d8YkBvIUxF-dHNJAj-x4fPEqizbY5d_TwvYpc01U5kw,58
27
+ code_puppy-0.0.61.dist-info/licenses/LICENSE,sha256=31u8x0SPgdOq3izJX41kgFazWsM43zPEF9eskzqbJMY,1075
28
+ code_puppy-0.0.61.dist-info/RECORD,,
@@ -1,92 +0,0 @@
1
- import ast
2
- import os
3
-
4
- import pathspec
5
- from rich.text import Text
6
- from rich.tree import Tree
7
-
8
-
9
- def summarize_node(node: ast.AST) -> str:
10
- if isinstance(node, ast.ClassDef):
11
- return f"class {node.name}"
12
- if isinstance(node, ast.FunctionDef):
13
- return f"def {node.name}()"
14
- return ""
15
-
16
-
17
- def get_docstring(node: ast.AST) -> str:
18
- doc = ast.get_docstring(node)
19
- if doc:
20
- lines = doc.strip().split("\n")
21
- return lines[0] if lines else doc.strip()
22
- return ""
23
-
24
-
25
- def map_python_file(file_path: str, show_doc: bool = True) -> Tree:
26
- tree = Tree(Text(file_path, style="bold cyan"))
27
- with open(file_path, "r", encoding="utf-8") as f:
28
- root = ast.parse(f.read(), filename=file_path)
29
- for node in root.body:
30
- summary = summarize_node(node)
31
- if summary:
32
- t = Tree(summary)
33
- if show_doc:
34
- doc = get_docstring(node)
35
- if doc:
36
- t.add(Text(f'"{doc}"', style="dim"))
37
- # Add inner functions
38
- if hasattr(node, "body"):
39
- for subnode in getattr(node, "body"):
40
- subsum = summarize_node(subnode)
41
- if subsum:
42
- sub_t = Tree(subsum)
43
- doc2 = get_docstring(subnode)
44
- if doc2:
45
- sub_t.add(Text(f'"{doc2}"', style="dim"))
46
- t.add(sub_t)
47
- tree.add(t)
48
- return tree
49
-
50
-
51
- def load_gitignore(directory: str):
52
- gitignore_file = os.path.join(directory, ".gitignore")
53
- if os.path.exists(gitignore_file):
54
- with open(gitignore_file, "r") as f:
55
- spec = pathspec.PathSpec.from_lines("gitwildmatch", f)
56
- return spec
57
- else:
58
- return pathspec.PathSpec.from_lines("gitwildmatch", [])
59
-
60
-
61
- def make_code_map(directory: str, show_doc: bool = True) -> Tree:
62
- """
63
- Recursively build a Tree displaying the code structure of all .py files in a directory,
64
- ignoring files listed in .gitignore if present.
65
- """
66
- base_tree = Tree(Text(directory, style="bold magenta"))
67
-
68
- spec = load_gitignore(directory)
69
- abs_directory = os.path.abspath(directory)
70
-
71
- for root, dirs, files in os.walk(directory):
72
- rel_root = os.path.relpath(root, abs_directory)
73
- # Remove ignored directories in-place for os.walk to not descend
74
- dirs[:] = [
75
- d
76
- for d in dirs
77
- if not spec.match_file(os.path.normpath(os.path.join(rel_root, d)))
78
- ]
79
- for fname in files:
80
- rel_file = os.path.normpath(os.path.join(rel_root, fname))
81
- if fname.endswith(".py") and not fname.startswith("__"):
82
- if not spec.match_file(rel_file):
83
- fpath = os.path.join(root, fname)
84
- try:
85
- file_tree = map_python_file(fpath, show_doc=show_doc)
86
- base_tree.add(file_tree)
87
- except Exception as e:
88
- err = Tree(
89
- Text(f"[error reading {fname}: {e}]", style="bold red")
90
- )
91
- base_tree.add(err)
92
- return base_tree
@@ -1,28 +0,0 @@
1
- code_puppy/__init__.py,sha256=-ANvE6Xe5NlWDIRCIfL1x-rgtCZ6zM2Ye9NphFoULSY,82
2
- code_puppy/agent.py,sha256=e3DBLW6dq30VuQdm5CVfLO81cU4ilyLJIz6rBj5U7pw,3239
3
- code_puppy/agent_prompts.py,sha256=bT8m7UCFU56yYdMtnB9xeiPtMwU3WA63d265PclCzb4,6774
4
- code_puppy/config.py,sha256=LTcZe5eHTT0zq-YJzSeNg8LCwhHb1HGN4tOkITtb7Eo,3941
5
- code_puppy/main.py,sha256=qDbDB123MAv5r_kH91x1LxUROI9I28y2tvuYo2YxEbQ,10323
6
- code_puppy/model_factory.py,sha256=tPS6lpfBRkTnHPPf_KpejMTtH02ZXiop2OSwaliyZ8g,11946
7
- code_puppy/models.json,sha256=7H-y97YK9BXhag5wJU19rtg24JtZWYx60RsBLBW3WiI,2162
8
- code_puppy/session_memory.py,sha256=4sgAAjbXdLSi8hETpd56tgtrG6hqMUuZWDlJOu6BQjA,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=gw8NpIxa6GOpczUJRyh7VNZwoXKKn-yvCqit7h2y6Gg,2931
12
- code_puppy/command_line/meta_command_handler.py,sha256=5jORzgSEmJBP8ixGIz8ET5Su9taPJZpQibe732LmOsg,5571
13
- code_puppy/command_line/model_picker_completion.py,sha256=NkyZZG7IhcVWSJ3ADytwCA5f8DpNeVs759Qtqs4fQtY,3733
14
- code_puppy/command_line/prompt_toolkit_completion.py,sha256=wxz8xCBge__EAxJRXYUCt9FoDpHog1QZ6RqpvoQP7O4,7904
15
- code_puppy/command_line/utils.py,sha256=7eyxDHjPjPB9wGDJQQcXV_zOsGdYsFgI0SGCetVmTqE,1251
16
- code_puppy/tools/__init__.py,sha256=J_HCbkivdr1rP5vfucxttXhGmTBx0S2LNoDMrbaE-Fc,558
17
- code_puppy/tools/code_map.py,sha256=5vzKBUddY0z9kMfHZmLiewUMJofDOONJIaXCWVhbE5E,3201
18
- code_puppy/tools/command_runner.py,sha256=6Ej2axH-b4ZGPLxOWg9kfW75qbftAecCFqWEtw3wEB8,6540
19
- code_puppy/tools/common.py,sha256=WAwij4KZ3JVFr9PssLsmIAPE9rlDKg8XSEtdKjNMQF4,1307
20
- code_puppy/tools/file_modifications.py,sha256=o7meMYjsQ70P1Lgc0XM0pFsh6Nn3XfJb7R5y-bwZp_M,13367
21
- code_puppy/tools/file_operations.py,sha256=-mo07EB6Rp_eDEFWqdJblj1Unz6flAsSY2ZNIxYzBiM,11595
22
- code_puppy/tools/web_search.py,sha256=sA2ierjuuYA517-uhb5s53SgeVsyOe1nExoZsrU1Fps,1284
23
- code_puppy-0.0.59.data/data/code_puppy/models.json,sha256=7H-y97YK9BXhag5wJU19rtg24JtZWYx60RsBLBW3WiI,2162
24
- code_puppy-0.0.59.dist-info/METADATA,sha256=s85j3wx1XwgNQJrliE5LzbUezX_T7NJcWWAKUA6ZJgg,4784
25
- code_puppy-0.0.59.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
26
- code_puppy-0.0.59.dist-info/entry_points.txt,sha256=d8YkBvIUxF-dHNJAj-x4fPEqizbY5d_TwvYpc01U5kw,58
27
- code_puppy-0.0.59.dist-info/licenses/LICENSE,sha256=31u8x0SPgdOq3izJX41kgFazWsM43zPEF9eskzqbJMY,1075
28
- code_puppy-0.0.59.dist-info/RECORD,,