pdd-cli 0.0.57__py3-none-any.whl → 0.0.59__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 pdd-cli might be problematic. Click here for more details.

pdd/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  """PDD - Prompt Driven Development"""
2
2
 
3
- __version__ = "0.0.57"
3
+ __version__ = "0.0.59"
4
4
 
5
5
  # Strength parameter used for LLM extraction across the codebase
6
6
  # Used in postprocessing, XML tagging, code generation, and other extraction
pdd/cli.py CHANGED
@@ -155,11 +155,7 @@ def _should_show_onboarding_reminder(ctx: click.Context) -> bool:
155
155
 
156
156
  def _run_setup_utility() -> None:
157
157
  """Execute the interactive setup utility script."""
158
- setup_script = Path(__file__).resolve().parent.parent / "utils" / "pdd-setup.py"
159
- if not setup_script.exists():
160
- raise FileNotFoundError(f"Setup utility not found at {setup_script}")
161
-
162
- result = subprocess.run([sys.executable, str(setup_script)])
158
+ result = subprocess.run([sys.executable, "-m", "pdd.setup_tool"])
163
159
  if result.returncode not in (0, None):
164
160
  raise RuntimeError(f"Setup utility exited with status {result.returncode}")
165
161
 
pdd/setup_tool.py ADDED
@@ -0,0 +1,549 @@
1
+ """Interactive post-install setup utility for PDD."""
2
+
3
+ import os
4
+ import sys
5
+ from pathlib import Path
6
+ from typing import Dict, List, Optional, Tuple
7
+
8
+ import requests
9
+
10
+
11
+ # Global variables for non-ASCII characters and colors
12
+ HEAVY_HORIZONTAL = "━"
13
+ LIGHT_HORIZONTAL = "─"
14
+ HEAVY_VERTICAL = "┃"
15
+ LIGHT_VERTICAL = "│"
16
+ TOP_LEFT_CORNER = "┏"
17
+ TOP_RIGHT_CORNER = "┓"
18
+ BOTTOM_LEFT_CORNER = "┗"
19
+ BOTTOM_RIGHT_CORNER = "┛"
20
+ CROSS = "┼"
21
+ TEE_DOWN = "┬"
22
+ TEE_UP = "┴"
23
+ TEE_RIGHT = "├"
24
+ TEE_LEFT = "┤"
25
+ BULLET = "•"
26
+ ARROW_RIGHT = "→"
27
+ CHECK_MARK = "✓"
28
+ CROSS_MARK = "✗"
29
+
30
+ # Color codes
31
+ RESET = "\033[0m"
32
+ WHITE = "\033[97m"
33
+ CYAN = "\033[96m"
34
+ YELLOW = "\033[93m"
35
+ BOLD = "\033[1m"
36
+
37
+
38
+ # Template content inline
39
+ HELLO_PYTHON_TEMPLATE = """Create a Python program that prints "Hello <username>" in ASCII art.
40
+
41
+ Requirements:
42
+ - <username> is the username of the current session, using the "whoami" command
43
+ - in the code, generate the full english 26 character alphabet in ascii art as a map of character values to ascii art strings, then use those to render
44
+ - Use only the Python standard library (no external dependencies)
45
+ - Create large, bold ASCII art text, using ASCII drawing characters, symbols, or any other characters that are useful
46
+ - The drawn text should be at least 10 rows in height
47
+ - Make it visually appealing with simple characters like #, *, or =
48
+ - Keep the code clean and readable
49
+ - Add a brief comment explaining what the program does
50
+
51
+ The program should be self-contained and runnable with just `python3 filename.py`."""
52
+
53
+ LLM_MODEL_CSV_TEMPLATE = """provider,model,input,output,coding_arena_elo,base_url,api_key,max_reasoning_tokens,structured_output,reasoning_type
54
+ OpenAI,gpt-5-nano,0.05,0.4,1249,,OPENAI_API_KEY,0,True,none
55
+ Google,gemini/gemini-2.5-pro,1.25,10.0,1360,,GOOGLE_API_KEY,0,True,none
56
+ OpenAI,gpt-5-mini,0.25,2.0,1325,,OPENAI_API_KEY,0,True,effort
57
+ OpenAI,gpt-5,1.25,10.0,1482,,OPENAI_API_KEY,0,True,effort
58
+ OpenAI,gpt-4.1,2.0,8.0,1253,,OPENAI_API_KEY,0,True,none"""
59
+
60
+
61
+ def print_colored(text: str, color: str = WHITE, bold: bool = False) -> None:
62
+ """Print colored text to console."""
63
+
64
+ style = BOLD + color if bold else color
65
+ print(f"{style}{text}{RESET}")
66
+
67
+
68
+ def create_divider(char: str = LIGHT_HORIZONTAL, width: int = 80) -> str:
69
+ """Create a horizontal divider line."""
70
+
71
+ return char * width
72
+
73
+
74
+ def create_fat_divider(width: int = 80) -> str:
75
+ """Create a fat horizontal divider line."""
76
+
77
+ return HEAVY_HORIZONTAL * width
78
+
79
+
80
+ def print_pdd_logo() -> None:
81
+ """Print the PDD logo in ASCII art."""
82
+
83
+ logo = "\n".join(
84
+ [
85
+ " +xxxxxxxxxxxxxxx+",
86
+ "xxxxxxxxxxxxxxxxxxxxx+",
87
+ "xxx +xx+ PROMPT",
88
+ "xxx x+ xx+ DRIVEN",
89
+ "xxx x+ xxx DEVELOPMENT©",
90
+ "xxx x+ xx+",
91
+ "xxx x+ xx+ COMMAND LINE INTERFACE",
92
+ "xxx x+ xxx",
93
+ "xxx +xx+ ",
94
+ "xxx +xxxxxxxxxxx+",
95
+ "xxx +xx+",
96
+ "xxx +xx+",
97
+ "xxx+xx+ WWW.PROMPTDRIVEN.AI",
98
+ "xxxx+",
99
+ "xx+",
100
+ ]
101
+ )
102
+ print(f"{CYAN}{logo}{RESET}")
103
+ print_colored("Supported: OpenAI and Google Gemini (non-Vertex)", WHITE)
104
+ print_colored("from their respective API endpoints (no third-parties, such as Azure)", WHITE)
105
+ print()
106
+
107
+
108
+ def discover_api_keys() -> Dict[str, Optional[str]]:
109
+ """Discover API keys from environment variables."""
110
+
111
+ keys = {
112
+ "OPENAI_API_KEY": os.getenv("OPENAI_API_KEY"),
113
+ "GOOGLE_API_KEY": os.getenv("GOOGLE_API_KEY") or os.getenv("GEMINI_API_KEY"),
114
+ }
115
+ return keys
116
+
117
+
118
+ def test_openai_key(api_key: str) -> bool:
119
+ """Test OpenAI API key validity."""
120
+
121
+ if not api_key or not api_key.strip():
122
+ return False
123
+
124
+ try:
125
+ headers = {
126
+ "Authorization": f"Bearer {api_key.strip()}",
127
+ "Content-Type": "application/json",
128
+ }
129
+ response = requests.get(
130
+ "https://api.openai.com/v1/models",
131
+ headers=headers,
132
+ timeout=10,
133
+ )
134
+ return response.status_code == 200
135
+ except Exception:
136
+ return False
137
+
138
+
139
+ def test_google_key(api_key: str) -> bool:
140
+ """Test Google Gemini API key validity."""
141
+
142
+ if not api_key or not api_key.strip():
143
+ return False
144
+
145
+ try:
146
+ response = requests.get(
147
+ f"https://generativelanguage.googleapis.com/v1beta/models?key={api_key.strip()}",
148
+ timeout=10,
149
+ )
150
+ return response.status_code == 200
151
+ except Exception:
152
+ return False
153
+
154
+
155
+ def test_api_keys(keys: Dict[str, Optional[str]]) -> Dict[str, bool]:
156
+ """Test all discovered API keys."""
157
+
158
+ results: Dict[str, bool] = {}
159
+
160
+ print_colored(f"\n{LIGHT_HORIZONTAL * 40}", CYAN)
161
+ print_colored("Testing discovered API keys...", CYAN, bold=True)
162
+ print_colored(f"{LIGHT_HORIZONTAL * 40}", CYAN)
163
+
164
+ for key_name, key_value in keys.items():
165
+ if key_value:
166
+ print(f"Testing {key_name}...", end=" ", flush=True)
167
+ if key_name == "OPENAI_API_KEY":
168
+ valid = test_openai_key(key_value)
169
+ elif key_name in ["GOOGLE_API_KEY"]:
170
+ valid = test_google_key(key_value)
171
+ else:
172
+ valid = False
173
+
174
+ if valid:
175
+ print_colored(f"{CHECK_MARK} Valid", CYAN)
176
+ results[key_name] = True
177
+ else:
178
+ print_colored(f"{CROSS_MARK} Invalid", YELLOW)
179
+ results[key_name] = False
180
+ else:
181
+ print_colored(f"{key_name}: Not found", YELLOW)
182
+ results[key_name] = False
183
+
184
+ return results
185
+
186
+
187
+ def get_user_keys(current_keys: Dict[str, Optional[str]]) -> Dict[str, Optional[str]]:
188
+ """Interactive key entry/modification."""
189
+
190
+ print_colored(f"\n{create_fat_divider()}", YELLOW)
191
+ print_colored("API Key Configuration", YELLOW, bold=True)
192
+ print_colored(f"{create_fat_divider()}", YELLOW)
193
+
194
+ print_colored("You need only one API key to get started", WHITE)
195
+ print()
196
+ print_colored("Get API keys here:", WHITE)
197
+ print_colored(f" OpenAI {ARROW_RIGHT} https://platform.openai.com/api-keys", CYAN)
198
+ print_colored(f" Google Gemini {ARROW_RIGHT} https://aistudio.google.com/app/apikey", CYAN)
199
+ print()
200
+ print_colored("A free instant starter key is available from Google Gemini (above)", CYAN)
201
+ print()
202
+
203
+ new_keys = current_keys.copy()
204
+
205
+ for key_name in ["OPENAI_API_KEY", "GOOGLE_API_KEY"]:
206
+ current_value = current_keys.get(key_name, "")
207
+ status = "found" if current_value else "not found"
208
+
209
+ print_colored(f"{LIGHT_HORIZONTAL * 60}", CYAN)
210
+ print_colored(f"{key_name} (currently: {status})", WHITE, bold=True)
211
+
212
+ if current_value:
213
+ prompt = "Enter new key or press ENTER to keep existing: "
214
+ else:
215
+ prompt = "Enter API key (or press ENTER to skip): "
216
+
217
+ try:
218
+ user_input = input(f"{WHITE}{prompt}{RESET}").strip()
219
+ if user_input:
220
+ new_keys[key_name] = user_input
221
+ elif not current_value:
222
+ new_keys[key_name] = None
223
+ except KeyboardInterrupt:
224
+ print_colored("\n\nSetup cancelled.", YELLOW)
225
+ sys.exit(0)
226
+
227
+ return new_keys
228
+
229
+
230
+ def detect_shell() -> str:
231
+ """Detect user's default shell."""
232
+
233
+ try:
234
+ shell_path = os.getenv("SHELL", "/bin/bash")
235
+ shell_name = os.path.basename(shell_path)
236
+ return shell_name
237
+ except Exception:
238
+ return "bash"
239
+
240
+
241
+ def get_shell_init_file(shell: str) -> str:
242
+ """Get the appropriate shell initialization file."""
243
+
244
+ home = Path.home()
245
+
246
+ shell_files = {
247
+ "bash": home / ".bashrc",
248
+ "zsh": home / ".zshrc",
249
+ "fish": home / ".config/fish/config.fish",
250
+ "csh": home / ".cshrc",
251
+ "tcsh": home / ".tcshrc",
252
+ "ksh": home / ".kshrc",
253
+ }
254
+
255
+ return str(shell_files.get(shell, home / ".bashrc"))
256
+
257
+
258
+ def create_api_env_script(keys: Dict[str, str], shell: str) -> str:
259
+ """Create shell-appropriate environment script."""
260
+
261
+ valid_keys = {k: v for k, v in keys.items() if v}
262
+
263
+ if shell == "fish":
264
+ lines = []
265
+ for key, value in valid_keys.items():
266
+ lines.append(f"set -gx {key} \"{value}\"")
267
+ return "\n".join(lines) + "\n"
268
+ if shell in ["csh", "tcsh"]:
269
+ lines = []
270
+ for key, value in valid_keys.items():
271
+ lines.append(f"setenv {key} \"{value}\"")
272
+ return "\n".join(lines) + "\n"
273
+
274
+ lines = []
275
+ for key, value in valid_keys.items():
276
+ lines.append(f"export {key}=\"{value}\"")
277
+ return "\n".join(lines) + "\n"
278
+
279
+
280
+ def save_configuration(valid_keys: Dict[str, str]) -> Tuple[List[str], bool]:
281
+ """Save configuration to ~/.pdd/ directory."""
282
+
283
+ home = Path.home()
284
+ pdd_dir = home / ".pdd"
285
+ created_pdd_dir = False
286
+ saved_files: List[str] = []
287
+
288
+ if not pdd_dir.exists():
289
+ pdd_dir.mkdir(mode=0o755)
290
+ created_pdd_dir = True
291
+
292
+ shell = detect_shell()
293
+ api_env_content = create_api_env_script(valid_keys, shell)
294
+
295
+ api_env_file = pdd_dir / "api-env"
296
+ api_env_file.write_text(api_env_content)
297
+ api_env_file.chmod(0o755)
298
+ saved_files.append(str(api_env_file))
299
+
300
+ csv_lines = LLM_MODEL_CSV_TEMPLATE.strip().split("\n")
301
+ header = csv_lines[0]
302
+ valid_lines = [header]
303
+
304
+ for line in csv_lines[1:]:
305
+ if "OPENAI_API_KEY" in line and "OPENAI_API_KEY" in valid_keys:
306
+ valid_lines.append(line)
307
+ elif "GOOGLE_API_KEY" in line and "GOOGLE_API_KEY" in valid_keys:
308
+ valid_lines.append(line)
309
+
310
+ llm_model_file = pdd_dir / "llm_model.csv"
311
+ llm_model_file.write_text("\n".join(valid_lines) + "\n")
312
+ saved_files.append(str(llm_model_file))
313
+
314
+ init_file_path = get_shell_init_file(shell)
315
+ init_file = Path(init_file_path)
316
+
317
+ source_line = f'[ -f "{api_env_file}" ] && source "{api_env_file}"'
318
+ if shell == "fish":
319
+ source_line = f'test -f "{api_env_file}"; and source "{api_env_file}"'
320
+
321
+ if init_file.exists():
322
+ content = init_file.read_text()
323
+ if str(api_env_file) not in content:
324
+ with init_file.open("a", encoding="utf-8") as file_handle:
325
+ file_handle.write(f"\n# PDD API environment\n{source_line}\n")
326
+ else:
327
+ init_file.write_text(f"# PDD API environment\n{source_line}\n")
328
+
329
+ return saved_files, created_pdd_dir
330
+
331
+
332
+ def create_sample_prompt() -> str:
333
+ """Create the sample prompt file."""
334
+
335
+ prompt_file = Path("hello_you_python.prompt")
336
+ prompt_file.write_text(HELLO_PYTHON_TEMPLATE)
337
+ return str(prompt_file)
338
+
339
+
340
+ def show_menu(keys: Dict[str, Optional[str]], test_results: Dict[str, bool]) -> str:
341
+ """Show main menu and get user choice."""
342
+
343
+ print_colored(f"\n{create_divider()}", CYAN)
344
+ print_colored("Main Menu", CYAN, bold=True)
345
+ print_colored(f"{create_divider()}", CYAN)
346
+
347
+ print_colored("Current API Key Status:", WHITE, bold=True)
348
+ for key_name in ["OPENAI_API_KEY", "GOOGLE_API_KEY"]:
349
+ key_value = keys.get(key_name)
350
+ if key_value:
351
+ status = (
352
+ f"{CHECK_MARK} Valid"
353
+ if test_results.get(key_name)
354
+ else f"{CROSS_MARK} Invalid"
355
+ )
356
+ status_color = CYAN if test_results.get(key_name) else YELLOW
357
+ else:
358
+ status = "Not configured"
359
+ status_color = YELLOW
360
+
361
+ print(f" {key_name}: ", end="")
362
+ print_colored(status, status_color)
363
+
364
+ print()
365
+ print_colored("Options:", WHITE, bold=True)
366
+ print(" 1. Re-enter API keys")
367
+ print(" 2. Re-test current keys")
368
+ print(" 3. Save configuration and exit")
369
+ print(" 4. Exit without saving")
370
+ print()
371
+
372
+ while True:
373
+ try:
374
+ choice = input(f"{WHITE}Choose an option (1-4): {RESET}").strip()
375
+ if choice in ["1", "2", "3", "4"]:
376
+ return choice
377
+ print_colored("Please enter 1, 2, 3, or 4", YELLOW)
378
+ except KeyboardInterrupt:
379
+ print_colored("\n\nSetup cancelled.", YELLOW)
380
+ sys.exit(0)
381
+
382
+
383
+ def create_exit_summary(
384
+ saved_files: List[str],
385
+ created_pdd_dir: bool,
386
+ sample_prompt_file: str,
387
+ shell: str,
388
+ ) -> str:
389
+ """Create comprehensive exit summary."""
390
+
391
+ summary_lines = [
392
+ "\n\n\n\n\n",
393
+ create_fat_divider(),
394
+ "PDD Setup Complete!",
395
+ create_fat_divider(),
396
+ "",
397
+ "Files created and configured:",
398
+ "",
399
+ ]
400
+
401
+ file_descriptions: List[Tuple[str, str]] = []
402
+ if created_pdd_dir:
403
+ file_descriptions.append(("~/.pdd/", "PDD configuration directory"))
404
+
405
+ for file_path in saved_files:
406
+ if "api-env" in file_path:
407
+ file_descriptions.append((file_path, "API environment variables"))
408
+ elif "llm_model.csv" in file_path:
409
+ file_descriptions.append((file_path, "LLM model configuration"))
410
+
411
+ file_descriptions.append((sample_prompt_file, "Sample prompt for testing"))
412
+ file_descriptions.append(("PDD-SETUP-SUMMARY.txt", "This summary"))
413
+
414
+ max_path_len = max(len(path) for path, _ in file_descriptions)
415
+
416
+ for file_path, description in file_descriptions:
417
+ summary_lines.append(f"{file_path:<{max_path_len + 2}}{description}")
418
+
419
+ summary_lines.extend(
420
+ [
421
+ "",
422
+ create_divider(),
423
+ "",
424
+ "QUICK START:",
425
+ "",
426
+ "1. Reload your shell environment:",
427
+ ]
428
+ )
429
+
430
+ api_env_path = f"{Path.home()}/.pdd/api-env"
431
+ if shell == "fish":
432
+ source_cmd = f"source {api_env_path}"
433
+ else:
434
+ source_cmd = f"source {api_env_path}"
435
+
436
+ summary_lines.extend(
437
+ [
438
+ f" {source_cmd}",
439
+ "",
440
+ "2. Generate code from the sample prompt:",
441
+ " pdd generate hello_you_python.prompt",
442
+ "",
443
+ create_divider(),
444
+ "",
445
+ "LEARN MORE:",
446
+ "",
447
+ f"{BULLET} PDD documentation: pdd --help",
448
+ f"{BULLET} PDD website: https://promptdriven.ai/",
449
+ f"{BULLET} Discord community: https://discord.gg/Yp4RTh8bG7",
450
+ "",
451
+ "TIPS:",
452
+ "",
453
+ f"{BULLET} IMPORTANT: Reload your shell environment using the source command above",
454
+ "",
455
+ f"{BULLET} Start with simple prompts and gradually increase complexity",
456
+ f"{BULLET} Try out 'pdd test' with your prompt+code to create test(s) pdd can use to automatically verify and fix your output code",
457
+ f"{BULLET} Try out 'pdd example' with your prompt+code to create examples which help pdd do better",
458
+ "",
459
+ f"{BULLET} As you get comfortable, learn configuration settings, including the .pddrc file, PDD_GENERATE_OUTPUT_PATH, and PDD_TEST_OUTPUT_PATH",
460
+ f"{BULLET} For larger projects, use Makefiles and/or 'pdd sync'",
461
+ f"{BULLET} For ongoing substantial projects, learn about llm_model.csv to optimize model cost, latency, and output quality",
462
+ "",
463
+ f"{BULLET} Use 'pdd --help' to explore all available commands",
464
+ "",
465
+ "Problems? Shout out on our Discord for help! https://discord.gg/Yp4RTh8bG7",
466
+ ]
467
+ )
468
+
469
+ return "\n".join(summary_lines)
470
+
471
+
472
+ def main() -> None:
473
+ """Main setup workflow."""
474
+
475
+ print_pdd_logo()
476
+
477
+ print_colored(f"{create_divider()}", CYAN)
478
+ print_colored("Discovering local configuration...", CYAN, bold=True)
479
+ print_colored(f"{create_divider()}", CYAN)
480
+
481
+ keys = discover_api_keys()
482
+ test_results = test_api_keys(keys)
483
+
484
+ while True:
485
+ choice = show_menu(keys, test_results)
486
+
487
+ if choice == "1":
488
+ keys = get_user_keys(keys)
489
+ test_results = test_api_keys(keys)
490
+ elif choice == "2":
491
+ test_results = test_api_keys(keys)
492
+ elif choice == "3":
493
+ valid_keys = {k: v for k, v in keys.items() if v and test_results.get(k)}
494
+
495
+ if not valid_keys:
496
+ print_colored("\nNo valid API keys to save!", YELLOW)
497
+ continue
498
+
499
+ print_colored(f"\n{create_divider()}", CYAN)
500
+ print_colored("Saving configuration...", CYAN, bold=True)
501
+ print_colored(f"{create_divider()}", CYAN)
502
+
503
+ try:
504
+ saved_files, created_pdd_dir = save_configuration(valid_keys)
505
+ sample_prompt_file = create_sample_prompt()
506
+ shell = detect_shell()
507
+
508
+ summary = create_exit_summary(
509
+ saved_files,
510
+ created_pdd_dir,
511
+ sample_prompt_file,
512
+ shell,
513
+ )
514
+
515
+ summary_file = Path("PDD-SETUP-SUMMARY.txt")
516
+ summary_file.write_text(summary)
517
+
518
+ for line in summary.split("\n"):
519
+ if line == create_fat_divider():
520
+ print_colored(line, YELLOW, bold=True)
521
+ elif line == "PDD Setup Complete!":
522
+ print_colored(line, YELLOW, bold=True)
523
+ elif line == create_divider():
524
+ print_colored(line, CYAN)
525
+ elif any(
526
+ line.startswith(prefix)
527
+ for prefix in ["QUICK START:", "LEARN MORE:", "TIPS:"]
528
+ ):
529
+ print_colored(line, CYAN, bold=True)
530
+ elif "IMPORTANT:" in line or "Problems?" in line:
531
+ print_colored(line, YELLOW, bold=True)
532
+ else:
533
+ print(line)
534
+
535
+ break
536
+ except Exception as exc: # noqa: BLE001
537
+ print_colored(f"Error saving configuration: {exc}", YELLOW)
538
+ continue
539
+ elif choice == "4":
540
+ print_colored("\nExiting without saving configuration.", YELLOW)
541
+ break
542
+
543
+
544
+ if __name__ == "__main__":
545
+ try:
546
+ main()
547
+ except KeyboardInterrupt:
548
+ print_colored("\n\nSetup cancelled.", YELLOW)
549
+ sys.exit(0)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pdd-cli
3
- Version: 0.0.57
3
+ Version: 0.0.59
4
4
  Summary: PDD (Prompt-Driven Development) Command Line Interface
5
5
  Author: Greg Tanaka
6
6
  Author-email: glt@alumni.caltech.edu
@@ -44,6 +44,8 @@ Requires-Dist: openai>=1.99.5
44
44
  Provides-Extra: dev
45
45
  Requires-Dist: commitizen; extra == "dev"
46
46
  Requires-Dist: pytest-cov; extra == "dev"
47
+ Requires-Dist: pytest-testmon; extra == "dev"
48
+ Requires-Dist: pytest-xdist; extra == "dev"
47
49
  Requires-Dist: pytest-mock; extra == "dev"
48
50
  Requires-Dist: pytest-asyncio; extra == "dev"
49
51
  Requires-Dist: z3-solver; extra == "dev"
@@ -51,7 +53,7 @@ Requires-Dist: build; extra == "dev"
51
53
  Requires-Dist: twine; extra == "dev"
52
54
  Dynamic: license-file
53
55
 
54
- .. image:: https://img.shields.io/badge/pdd--cli-v0.0.57-blue
56
+ .. image:: https://img.shields.io/badge/pdd--cli-v0.0.59-blue
55
57
  :alt: PDD-CLI Version
56
58
 
57
59
  .. image:: https://img.shields.io/badge/Discord-join%20chat-7289DA.svg?logo=discord&logoColor=white&link=https://discord.gg/Yp4RTh8bG7
@@ -128,7 +130,7 @@ After installation, verify:
128
130
 
129
131
  pdd --version
130
132
 
131
- You'll see the current PDD version (e.g., 0.0.57).
133
+ You'll see the current PDD version (e.g., 0.0.59).
132
134
 
133
135
  Getting Started with Examples
134
136
  -----------------------------
@@ -1,4 +1,4 @@
1
- pdd/__init__.py,sha256=c7_rZfVUGfMl_L9YRmXqSUq_hMgTOjG1KknWvXAR0JQ,633
1
+ pdd/__init__.py,sha256=6ca93PkB5BfPH4LcpAo6xz5hCmdLn8B0P6cgmY8IqyY,633
2
2
  pdd/auto_deps_main.py,sha256=cpP3bbzVL3jomrGinpzTxzIDIC8tmDDYOwUAC1TKRaw,3970
3
3
  pdd/auto_include.py,sha256=OJcdcwTwJNqHPHKG9P4m9Ij-PiLex0EbuwJP0uiQi_Y,7484
4
4
  pdd/auto_update.py,sha256=w6jzTnMiYRNpwQHQxWNiIAwQ0d6xh1iOB3xgDsabWtc,5236
@@ -6,7 +6,7 @@ pdd/bug_main.py,sha256=EtaGTuucQ7VgqOhyg4o6GFG7_QtTsDPTrRdGJWT648M,4841
6
6
  pdd/bug_to_unit_test.py,sha256=BoQqNyKQpBQDW8-JwBH_RX4RHRSiU8Kk3EplFrkECt0,6665
7
7
  pdd/change.py,sha256=Hg_x0pa370-e6oDiczaTgFAy3Am9ReCPkqFrvqv4U38,6114
8
8
  pdd/change_main.py,sha256=04VHiO_D-jlfeRn6rrVH7ZTA5agXPoJGm1StGI8--XY,27804
9
- pdd/cli.py,sha256=kLmJZ-2ETIbbpclwM7cQuaVfAiUNTBxJ9RtB0CsF2h0,55355
9
+ pdd/cli.py,sha256=c5Gco_Ra1ZCZf1MtxrNZdySDhZqICHBQMSH5VBqVPEw,55162
10
10
  pdd/cmd_test_main.py,sha256=M-i5x26ORXurt_pu8x1sgLAyVIItbuRThiux4wBg3Ls,7768
11
11
  pdd/code_generator.py,sha256=AxMRZKGIlLh9xWdn2FA6b3zSoZ-5TIZNIAzqjFboAQs,4718
12
12
  pdd/code_generator_main.py,sha256=UtoskalEPpMAvCO-zd6xmr1lbQqSWQ7BvYgNJCybqok,35151
@@ -55,6 +55,7 @@ pdd/preprocess_main.py,sha256=WGhOB9qEu7MmFoyXNml_AmqGii73LJWngx4kTlZ526k,3262
55
55
  pdd/process_csv_change.py,sha256=ckNqVPRooWVyIvmqjdEgo2PDLnpoQ6Taa2dUaWGRlzU,27926
56
56
  pdd/pytest_output.py,sha256=IrRKYneW_F6zv9WaJwKFGnOBLFBFjk1CnhO_EVAjb9E,6612
57
57
  pdd/python_env_detector.py,sha256=y-QESoPNiKaD821uz8okX-9qA-oqvH9cQHY2_MwFHzU,5194
58
+ pdd/setup_tool.py,sha256=sksHVgSLSzlMVSX-WoAZwLRqQhKYPhuCBoq6XbOLhTI,18171
58
59
  pdd/split.py,sha256=9lWrh-JOjOpxRp4-s1VL7bqJMVWlsmY5LxONT7sYM8A,5288
59
60
  pdd/split_main.py,sha256=52rcZoeS_wpYRiqbqMUgr_hUY7GS62otwzDfuAGi6YA,4845
60
61
  pdd/summarize_directory.py,sha256=BR3-yGcmUdDT26vWLGokBo6mAZzaT7PzoY_qZriH3cc,10061
@@ -110,9 +111,9 @@ pdd/prompts/unfinished_prompt_LLM.prompt,sha256=vud_G9PlVv9Ig64uBC-hPEVFRk5lwpc8
110
111
  pdd/prompts/update_prompt_LLM.prompt,sha256=prIc8uLp2jqnLTHt6JvWDZGanPZipivhhYeXe0lVaYw,1328
111
112
  pdd/prompts/xml_convertor_LLM.prompt,sha256=YGRGXJeg6EhM9690f-SKqQrKqSJjLFD51UrPOlO0Frg,2786
112
113
  pdd/templates/architecture/architecture_json.prompt,sha256=uSNSsKTL-cuMMhi5a4GSpC94DKkOFAlXh7R0CUlo-hg,8126
113
- pdd_cli-0.0.57.dist-info/licenses/LICENSE,sha256=kvTJnnxPVTYlGKSY4ZN1kzdmJ0lxRdNWxgupaB27zsU,1066
114
- pdd_cli-0.0.57.dist-info/METADATA,sha256=5c-XFXqAOnpojCQwch2BmM4JsxO3YrgVhPGq-bduSOU,12597
115
- pdd_cli-0.0.57.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
116
- pdd_cli-0.0.57.dist-info/entry_points.txt,sha256=Kr8HtNVb8uHZtQJNH4DnF8j7WNgWQbb7_Pw5hECSR-I,36
117
- pdd_cli-0.0.57.dist-info/top_level.txt,sha256=xjnhIACeMcMeDfVNREgQZl4EbTni2T11QkL5r7E-sbE,4
118
- pdd_cli-0.0.57.dist-info/RECORD,,
114
+ pdd_cli-0.0.59.dist-info/licenses/LICENSE,sha256=kvTJnnxPVTYlGKSY4ZN1kzdmJ0lxRdNWxgupaB27zsU,1066
115
+ pdd_cli-0.0.59.dist-info/METADATA,sha256=wiXNwvDbviSCgnEaJwSbfWDv-BgkaZEjm3lpfHudbcM,12687
116
+ pdd_cli-0.0.59.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
117
+ pdd_cli-0.0.59.dist-info/entry_points.txt,sha256=Kr8HtNVb8uHZtQJNH4DnF8j7WNgWQbb7_Pw5hECSR-I,36
118
+ pdd_cli-0.0.59.dist-info/top_level.txt,sha256=xjnhIACeMcMeDfVNREgQZl4EbTni2T11QkL5r7E-sbE,4
119
+ pdd_cli-0.0.59.dist-info/RECORD,,