pdd-cli 0.0.61__py3-none-any.whl → 0.0.62__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 +1 -1
- pdd/cli.py +129 -9
- pdd/data/language_format.csv +3 -0
- pdd/data/llm_model.csv +2 -2
- pdd/preprocess.py +121 -5
- pdd/templates/architecture/architecture_json.prompt +16 -1
- pdd/templates/generic/generate_prompt.prompt +47 -15
- {pdd_cli-0.0.61.dist-info → pdd_cli-0.0.62.dist-info}/METADATA +3 -3
- {pdd_cli-0.0.61.dist-info → pdd_cli-0.0.62.dist-info}/RECORD +13 -13
- {pdd_cli-0.0.61.dist-info → pdd_cli-0.0.62.dist-info}/WHEEL +0 -0
- {pdd_cli-0.0.61.dist-info → pdd_cli-0.0.62.dist-info}/entry_points.txt +0 -0
- {pdd_cli-0.0.61.dist-info → pdd_cli-0.0.62.dist-info}/licenses/LICENSE +0 -0
- {pdd_cli-0.0.61.dist-info → pdd_cli-0.0.62.dist-info}/top_level.txt +0 -0
pdd/__init__.py
CHANGED
pdd/cli.py
CHANGED
|
@@ -14,9 +14,11 @@ from typing import Any, Dict, List, Optional, Tuple
|
|
|
14
14
|
from pathlib import Path # Import Path
|
|
15
15
|
|
|
16
16
|
import click
|
|
17
|
+
from rich import box
|
|
17
18
|
from rich.console import Console
|
|
18
|
-
from rich.theme import Theme
|
|
19
19
|
from rich.markup import MarkupError, escape
|
|
20
|
+
from rich.table import Table
|
|
21
|
+
from rich.theme import Theme
|
|
20
22
|
|
|
21
23
|
# --- Relative Imports for Internal Modules ---
|
|
22
24
|
from . import DEFAULT_STRENGTH, __version__, DEFAULT_TIME
|
|
@@ -449,20 +451,138 @@ def templates_show(name: str):
|
|
|
449
451
|
try:
|
|
450
452
|
data = template_registry.show_template(name)
|
|
451
453
|
summary = data.get("summary", {})
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
454
|
+
|
|
455
|
+
def _render_key_value_table(title: Optional[str], items: List[Tuple[str, Any]], *, highlight_path: bool = False):
|
|
456
|
+
"""Render a 2-column Rich table for key/value pairs."""
|
|
457
|
+
|
|
458
|
+
table = Table(show_header=False, box=box.SIMPLE, expand=True)
|
|
459
|
+
table.add_column("Field", style="info", no_wrap=True)
|
|
460
|
+
table.add_column("Value", overflow="fold")
|
|
461
|
+
|
|
462
|
+
added_rows = False
|
|
463
|
+
for label, value in items:
|
|
464
|
+
if value in (None, "", [], {}):
|
|
465
|
+
continue
|
|
466
|
+
if isinstance(value, (list, tuple)):
|
|
467
|
+
value_str = ", ".join(str(v) for v in value)
|
|
468
|
+
else:
|
|
469
|
+
value_str = str(value)
|
|
470
|
+
|
|
471
|
+
if highlight_path and label.lower() == "path":
|
|
472
|
+
value_markup = f"[path]{escape(value_str)}[/path]"
|
|
473
|
+
else:
|
|
474
|
+
value_markup = escape(value_str)
|
|
475
|
+
|
|
476
|
+
table.add_row(label, value_markup)
|
|
477
|
+
added_rows = True
|
|
478
|
+
|
|
479
|
+
if added_rows:
|
|
480
|
+
if title:
|
|
481
|
+
console.print(f"[info]{title}[/info]")
|
|
482
|
+
console.print(table)
|
|
483
|
+
|
|
484
|
+
summary_items = [
|
|
485
|
+
("Name", summary.get("name")),
|
|
486
|
+
("Description", summary.get("description")),
|
|
487
|
+
("Version", summary.get("version")),
|
|
488
|
+
("Tags", summary.get("tags", [])),
|
|
489
|
+
("Language", summary.get("language")),
|
|
490
|
+
("Output", summary.get("output")),
|
|
491
|
+
("Path", summary.get("path")),
|
|
492
|
+
]
|
|
493
|
+
_render_key_value_table("Template Summary:", summary_items, highlight_path=True)
|
|
494
|
+
|
|
456
495
|
if data.get("variables"):
|
|
457
496
|
console.print("\n[info]Variables:[/info]")
|
|
458
|
-
|
|
459
|
-
|
|
497
|
+
variables_table = Table(box=box.SIMPLE_HEAD, show_lines=False, expand=True)
|
|
498
|
+
variables_table.add_column("Name", style="bold", no_wrap=True)
|
|
499
|
+
variables_table.add_column("Required", style="info", no_wrap=True)
|
|
500
|
+
variables_table.add_column("Type", no_wrap=True)
|
|
501
|
+
variables_table.add_column("Description", overflow="fold")
|
|
502
|
+
variables_table.add_column("Default/Examples", overflow="fold")
|
|
503
|
+
|
|
504
|
+
for var_name, var_meta in data["variables"].items():
|
|
505
|
+
required = var_meta.get("required")
|
|
506
|
+
if required is True:
|
|
507
|
+
required_str = "Yes"
|
|
508
|
+
elif required is False:
|
|
509
|
+
required_str = "No"
|
|
510
|
+
else:
|
|
511
|
+
required_str = "-"
|
|
512
|
+
|
|
513
|
+
var_type = escape(str(var_meta.get("type", "-")))
|
|
514
|
+
description = escape(str(var_meta.get("description", "")))
|
|
515
|
+
|
|
516
|
+
default_parts: List[str] = []
|
|
517
|
+
default_value = var_meta.get("default")
|
|
518
|
+
if default_value not in (None, ""):
|
|
519
|
+
default_parts.append(f"default: {default_value}")
|
|
520
|
+
|
|
521
|
+
examples_value = var_meta.get("examples")
|
|
522
|
+
if examples_value:
|
|
523
|
+
if isinstance(examples_value, (list, tuple)):
|
|
524
|
+
examples_str = ", ".join(str(example) for example in examples_value)
|
|
525
|
+
else:
|
|
526
|
+
examples_str = str(examples_value)
|
|
527
|
+
default_parts.append(f"examples: {examples_str}")
|
|
528
|
+
|
|
529
|
+
example_paths_value = var_meta.get("example_paths")
|
|
530
|
+
if example_paths_value:
|
|
531
|
+
if isinstance(example_paths_value, (list, tuple)):
|
|
532
|
+
example_paths_str = ", ".join(str(example) for example in example_paths_value)
|
|
533
|
+
else:
|
|
534
|
+
example_paths_str = str(example_paths_value)
|
|
535
|
+
default_parts.append(f"paths: {example_paths_str}")
|
|
536
|
+
|
|
537
|
+
default_examples = "\n".join(default_parts) if default_parts else "-"
|
|
538
|
+
|
|
539
|
+
variables_table.add_row(
|
|
540
|
+
escape(str(var_name)),
|
|
541
|
+
required_str,
|
|
542
|
+
var_type,
|
|
543
|
+
description,
|
|
544
|
+
escape(default_examples),
|
|
545
|
+
)
|
|
546
|
+
|
|
547
|
+
console.print(variables_table)
|
|
548
|
+
|
|
460
549
|
if data.get("usage"):
|
|
461
550
|
console.print("\n[info]Usage:[/info]")
|
|
462
|
-
|
|
551
|
+
usage = data["usage"]
|
|
552
|
+
if isinstance(usage, dict):
|
|
553
|
+
for group_name, entries in usage.items():
|
|
554
|
+
console.print(f"[bold]{escape(str(group_name))}[/bold]")
|
|
555
|
+
usage_table = Table(box=box.SIMPLE, show_lines=False, expand=True)
|
|
556
|
+
usage_table.add_column("Name", style="bold", no_wrap=True)
|
|
557
|
+
usage_table.add_column("Command", overflow="fold")
|
|
558
|
+
|
|
559
|
+
if isinstance(entries, (list, tuple)):
|
|
560
|
+
iterable_entries = entries
|
|
561
|
+
else:
|
|
562
|
+
iterable_entries = [entries]
|
|
563
|
+
|
|
564
|
+
for entry in iterable_entries:
|
|
565
|
+
if isinstance(entry, dict):
|
|
566
|
+
name_value = escape(str(entry.get("name", "")))
|
|
567
|
+
command_value = escape(str(entry.get("command", "")))
|
|
568
|
+
else:
|
|
569
|
+
name_value = "-"
|
|
570
|
+
command_value = escape(str(entry))
|
|
571
|
+
usage_table.add_row(name_value, f"[command]{command_value}[/command]")
|
|
572
|
+
|
|
573
|
+
if usage_table.row_count:
|
|
574
|
+
console.print(usage_table)
|
|
575
|
+
else:
|
|
576
|
+
console.print(usage)
|
|
577
|
+
|
|
463
578
|
if data.get("discover"):
|
|
464
579
|
console.print("\n[info]Discover:[/info]")
|
|
465
|
-
|
|
580
|
+
discover = data["discover"]
|
|
581
|
+
if isinstance(discover, dict):
|
|
582
|
+
discover_items = [(str(key), value) for key, value in discover.items()]
|
|
583
|
+
_render_key_value_table(None, discover_items)
|
|
584
|
+
else:
|
|
585
|
+
console.print(discover)
|
|
466
586
|
if data.get("output_schema"):
|
|
467
587
|
console.print("\n[info]Output Schema:[/info]")
|
|
468
588
|
try:
|
pdd/data/language_format.csv
CHANGED
pdd/data/llm_model.csv
CHANGED
|
@@ -2,7 +2,7 @@ provider,model,input,output,coding_arena_elo,base_url,api_key,max_reasoning_toke
|
|
|
2
2
|
OpenAI,gpt-5-nano,0.05,0.4,1249,,OPENAI_API_KEY,0,True,none
|
|
3
3
|
Google,vertex_ai/gemini-2.5-flash,0.15,0.6,1290,,VERTEX_CREDENTIALS,0,True,effort
|
|
4
4
|
Google,gemini/gemini-2.5-pro,1.25,10.0,1360,,GEMINI_API_KEY,0,True,none
|
|
5
|
-
Google,vertex_ai/claude-sonnet-4,3.0,15.0,1359,,VERTEX_CREDENTIALS,64000,True,budget
|
|
5
|
+
Google,vertex_ai/claude-sonnet-4-5,3.0,15.0,1359,,VERTEX_CREDENTIALS,64000,True,budget
|
|
6
6
|
Google,vertex_ai/gemini-2.5-pro,1.25,10.0,1405,,VERTEX_CREDENTIALS,0,True,none
|
|
7
7
|
OpenAI,gpt-5-mini,0.25,2.0,1325,,OPENAI_API_KEY,0,True,effort
|
|
8
8
|
OpenAI,gpt-5,1.25,10.0,1482,,OPENAI_API_KEY,0,True,effort
|
|
@@ -15,6 +15,6 @@ OpenAI,openai/mlx-community/Qwen3-30B-A3B-4bit,0,0,1040,http://localhost:8080,,0
|
|
|
15
15
|
OpenAI,lm_studio/openai-gpt-oss-120b-mlx-6,0.0001,0,1082,http://localhost:1234/v1,,0,True,none
|
|
16
16
|
Fireworks,fireworks_ai/accounts/fireworks/models/glm-4p5,3.0,8.0,1364,,FIREWORKS_API_KEY,0,False,none
|
|
17
17
|
OpenAI,groq/moonshotai/kimi-k2-instruct,1.0,3.0,1330,,GROQ_API_KEY,0,True,none
|
|
18
|
-
Anthropic,anthropic/claude-sonnet-4-
|
|
18
|
+
Anthropic,anthropic/claude-sonnet-4-5-20250929,3.0,15.0,1356,,ANTHROPIC_API_KEY,64000,True,budget
|
|
19
19
|
Anthropic,anthropic/claude-opus-4-1-20250805,3.0,15.0,1474,,ANTHROPIC_API_KEY,32000,True,budget
|
|
20
20
|
Anthropic,anthropic/claude-3-5-haiku-20241022,3.0,15.0,1133,,ANTHROPIC_API_KEY,8192,True,budget
|
pdd/preprocess.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import re
|
|
3
3
|
import subprocess
|
|
4
|
-
from typing import List, Optional
|
|
4
|
+
from typing import List, Optional, Tuple
|
|
5
5
|
import traceback
|
|
6
6
|
from rich.console import Console
|
|
7
7
|
from rich.panel import Panel
|
|
@@ -11,22 +11,107 @@ from rich.traceback import install
|
|
|
11
11
|
install()
|
|
12
12
|
console = Console()
|
|
13
13
|
|
|
14
|
+
# Debug/Instrumentation controls
|
|
15
|
+
_DEBUG_PREPROCESS = str(os.getenv("PDD_PREPROCESS_DEBUG", "")).lower() in ("1", "true", "yes", "on")
|
|
16
|
+
_DEBUG_OUTPUT_FILE = os.getenv("PDD_PREPROCESS_DEBUG_FILE") # Optional path to write a debug report
|
|
17
|
+
_DEBUG_EVENTS: List[str] = []
|
|
18
|
+
|
|
19
|
+
def _dbg(msg: str) -> None:
|
|
20
|
+
if _DEBUG_PREPROCESS:
|
|
21
|
+
console.print(f"[dim][PPD][preprocess][/dim] {escape(msg)}")
|
|
22
|
+
_DEBUG_EVENTS.append(msg)
|
|
23
|
+
|
|
24
|
+
def _write_debug_report() -> None:
|
|
25
|
+
if _DEBUG_PREPROCESS and _DEBUG_OUTPUT_FILE:
|
|
26
|
+
try:
|
|
27
|
+
with open(_DEBUG_OUTPUT_FILE, "w", encoding="utf-8") as fh:
|
|
28
|
+
fh.write("Preprocess Debug Report\n\n")
|
|
29
|
+
for line in _DEBUG_EVENTS:
|
|
30
|
+
fh.write(line + "\n")
|
|
31
|
+
except Exception:
|
|
32
|
+
# Avoid interfering with normal flow if writing fails
|
|
33
|
+
pass
|
|
34
|
+
|
|
35
|
+
def _extract_fence_spans(text: str) -> List[Tuple[int, int]]:
|
|
36
|
+
"""Return list of (start, end) spans for fenced code blocks ```...```.
|
|
37
|
+
|
|
38
|
+
The spans are [start, end) indices in the original text.
|
|
39
|
+
"""
|
|
40
|
+
spans: List[Tuple[int, int]] = []
|
|
41
|
+
try:
|
|
42
|
+
for m in re.finditer(r"```[\w\s]*\n[\s\S]*?```", text):
|
|
43
|
+
spans.append((m.start(), m.end()))
|
|
44
|
+
except Exception:
|
|
45
|
+
pass
|
|
46
|
+
return spans
|
|
47
|
+
|
|
48
|
+
def _is_inside_any_span(idx: int, spans: List[Tuple[int, int]]) -> bool:
|
|
49
|
+
for s, e in spans:
|
|
50
|
+
if s <= idx < e:
|
|
51
|
+
return True
|
|
52
|
+
return False
|
|
53
|
+
|
|
54
|
+
def _scan_risky_placeholders(text: str) -> Tuple[List[Tuple[int, str]], List[Tuple[int, str]]]:
|
|
55
|
+
"""Scan for risky placeholders outside code fences.
|
|
56
|
+
|
|
57
|
+
Returns two lists of (line_no, snippet):
|
|
58
|
+
- single_brace: matches like {name} not doubled and not part of {{...}}
|
|
59
|
+
- template_brace: `${...}` occurrences (which include single { ... })
|
|
60
|
+
"""
|
|
61
|
+
single_brace: List[Tuple[int, str]] = []
|
|
62
|
+
template_brace: List[Tuple[int, str]] = []
|
|
63
|
+
try:
|
|
64
|
+
fence_spans = _extract_fence_spans(text)
|
|
65
|
+
# Single-brace variable placeholders (avoid matching {{ or }})
|
|
66
|
+
for m in re.finditer(r"(?<!\{)\{([A-Za-z_][A-Za-z0-9_]*)\}(?!\})", text):
|
|
67
|
+
if not _is_inside_any_span(m.start(), fence_spans):
|
|
68
|
+
line_no = text.count("\n", 0, m.start()) + 1
|
|
69
|
+
single_brace.append((line_no, m.group(0)))
|
|
70
|
+
# JavaScript template placeholders like ${...}
|
|
71
|
+
for m in re.finditer(r"\$\{[^\}]+\}", text):
|
|
72
|
+
if not _is_inside_any_span(m.start(), fence_spans):
|
|
73
|
+
line_no = text.count("\n", 0, m.start()) + 1
|
|
74
|
+
template_brace.append((line_no, m.group(0)))
|
|
75
|
+
except Exception:
|
|
76
|
+
pass
|
|
77
|
+
return single_brace, template_brace
|
|
78
|
+
|
|
14
79
|
def preprocess(prompt: str, recursive: bool = False, double_curly_brackets: bool = True, exclude_keys: Optional[List[str]] = None) -> str:
|
|
15
80
|
try:
|
|
16
81
|
if not prompt:
|
|
17
82
|
console.print("[bold red]Error:[/bold red] Empty prompt provided")
|
|
18
83
|
return ""
|
|
84
|
+
_DEBUG_EVENTS.clear()
|
|
85
|
+
_dbg(f"Start preprocess(recursive={recursive}, double_curly={double_curly_brackets}, exclude_keys={exclude_keys})")
|
|
86
|
+
_dbg(f"Initial length: {len(prompt)} characters")
|
|
19
87
|
console.print(Panel("Starting prompt preprocessing", style="bold blue"))
|
|
20
88
|
prompt = process_backtick_includes(prompt, recursive)
|
|
89
|
+
_dbg("After backtick includes processed")
|
|
21
90
|
prompt = process_xml_tags(prompt, recursive)
|
|
91
|
+
_dbg("After XML-like tags processed")
|
|
22
92
|
if double_curly_brackets:
|
|
23
93
|
prompt = double_curly(prompt, exclude_keys)
|
|
94
|
+
_dbg("After double_curly execution")
|
|
95
|
+
# Scan for risky placeholders remaining outside code fences
|
|
96
|
+
singles, templates = _scan_risky_placeholders(prompt)
|
|
97
|
+
if singles:
|
|
98
|
+
_dbg(f"WARNING: Found {len(singles)} single-brace placeholders outside code fences (examples):")
|
|
99
|
+
for ln, frag in singles[:5]:
|
|
100
|
+
_dbg(f" line {ln}: {frag}")
|
|
101
|
+
if templates:
|
|
102
|
+
_dbg(f"INFO: Found {len(templates)} template literals ${'{...'} outside code fences (examples):")
|
|
103
|
+
for ln, frag in templates[:5]:
|
|
104
|
+
_dbg(f" line {ln}: {frag}")
|
|
24
105
|
# Don't trim whitespace that might be significant for the tests
|
|
25
106
|
console.print(Panel("Preprocessing complete", style="bold green"))
|
|
107
|
+
_dbg(f"Final length: {len(prompt)} characters")
|
|
108
|
+
_write_debug_report()
|
|
26
109
|
return prompt
|
|
27
110
|
except Exception as e:
|
|
28
111
|
console.print(f"[bold red]Error during preprocessing:[/bold red] {str(e)}")
|
|
29
112
|
console.print(Panel(traceback.format_exc(), title="Error Details", style="red"))
|
|
113
|
+
_dbg(f"Exception: {str(e)}")
|
|
114
|
+
_write_debug_report()
|
|
30
115
|
return prompt
|
|
31
116
|
|
|
32
117
|
def get_file_path(file_name: str) -> str:
|
|
@@ -45,14 +130,17 @@ def process_backtick_includes(text: str, recursive: bool) -> str:
|
|
|
45
130
|
content = file.read()
|
|
46
131
|
if recursive:
|
|
47
132
|
content = preprocess(content, recursive=True, double_curly_brackets=False)
|
|
133
|
+
_dbg(f"Included via backticks: {file_path} (len={len(content)})")
|
|
48
134
|
return f"```{content}```"
|
|
49
135
|
except FileNotFoundError:
|
|
50
136
|
console.print(f"[bold red]Warning:[/bold red] File not found: {file_path}")
|
|
137
|
+
_dbg(f"Missing backtick include: {file_path}")
|
|
51
138
|
# First pass (recursive=True): leave the tag so a later env expansion can resolve it
|
|
52
139
|
# Second pass (recursive=False): replace with a visible placeholder
|
|
53
140
|
return match.group(0) if recursive else f"```[File not found: {file_path}]```"
|
|
54
141
|
except Exception as e:
|
|
55
142
|
console.print(f"[bold red]Error processing include:[/bold red] {str(e)}")
|
|
143
|
+
_dbg(f"Error processing backtick include {file_path}: {e}")
|
|
56
144
|
return f"```[Error processing include: {file_path}]```"
|
|
57
145
|
prev_text = ""
|
|
58
146
|
current_text = text
|
|
@@ -80,14 +168,17 @@ def process_include_tags(text: str, recursive: bool) -> str:
|
|
|
80
168
|
content = file.read()
|
|
81
169
|
if recursive:
|
|
82
170
|
content = preprocess(content, recursive=True, double_curly_brackets=False)
|
|
171
|
+
_dbg(f"Included via XML tag: {file_path} (len={len(content)})")
|
|
83
172
|
return content
|
|
84
173
|
except FileNotFoundError:
|
|
85
174
|
console.print(f"[bold red]Warning:[/bold red] File not found: {file_path}")
|
|
175
|
+
_dbg(f"Missing XML include: {file_path}")
|
|
86
176
|
# First pass (recursive=True): leave the tag so a later env expansion can resolve it
|
|
87
177
|
# Second pass (recursive=False): replace with a visible placeholder
|
|
88
178
|
return match.group(0) if recursive else f"[File not found: {file_path}]"
|
|
89
179
|
except Exception as e:
|
|
90
180
|
console.print(f"[bold red]Error processing include:[/bold red] {str(e)}")
|
|
181
|
+
_dbg(f"Error processing XML include {file_path}: {e}")
|
|
91
182
|
return f"[Error processing include: {file_path}]"
|
|
92
183
|
prev_text = ""
|
|
93
184
|
current_text = text
|
|
@@ -113,15 +204,18 @@ def process_shell_tags(text: str, recursive: bool) -> str:
|
|
|
113
204
|
# Defer execution until after env var expansion
|
|
114
205
|
return match.group(0)
|
|
115
206
|
console.print(f"Executing shell command: [cyan]{escape(command)}[/cyan]")
|
|
207
|
+
_dbg(f"Shell tag command: {command}")
|
|
116
208
|
try:
|
|
117
209
|
result = subprocess.run(command, shell=True, check=True, capture_output=True, text=True)
|
|
118
210
|
return result.stdout
|
|
119
211
|
except subprocess.CalledProcessError as e:
|
|
120
212
|
error_msg = f"Command '{command}' returned non-zero exit status {e.returncode}."
|
|
121
213
|
console.print(f"[bold red]Error:[/bold red] {error_msg}")
|
|
214
|
+
_dbg(f"Shell command error: {error_msg}")
|
|
122
215
|
return f"Error: {error_msg}"
|
|
123
216
|
except Exception as e:
|
|
124
217
|
console.print(f"[bold red]Error executing shell command:[/bold red] {str(e)}")
|
|
218
|
+
_dbg(f"Shell execution exception: {e}")
|
|
125
219
|
return f"[Shell execution error: {str(e)}]"
|
|
126
220
|
return re.sub(pattern, replace_shell, text, flags=re.DOTALL)
|
|
127
221
|
|
|
@@ -133,24 +227,30 @@ def process_web_tags(text: str, recursive: bool) -> str:
|
|
|
133
227
|
# Defer network operations until after env var expansion
|
|
134
228
|
return match.group(0)
|
|
135
229
|
console.print(f"Scraping web content from: [cyan]{url}[/cyan]")
|
|
230
|
+
_dbg(f"Web tag URL: {url}")
|
|
136
231
|
try:
|
|
137
232
|
try:
|
|
138
233
|
from firecrawl import FirecrawlApp
|
|
139
234
|
except ImportError:
|
|
235
|
+
_dbg("firecrawl import failed; package not installed")
|
|
140
236
|
return f"[Error: firecrawl-py package not installed. Cannot scrape {url}]"
|
|
141
237
|
api_key = os.environ.get('FIRECRAWL_API_KEY')
|
|
142
238
|
if not api_key:
|
|
143
239
|
console.print("[bold yellow]Warning:[/bold yellow] FIRECRAWL_API_KEY not found in environment")
|
|
240
|
+
_dbg("FIRECRAWL_API_KEY not set")
|
|
144
241
|
return f"[Error: FIRECRAWL_API_KEY not set. Cannot scrape {url}]"
|
|
145
242
|
app = FirecrawlApp(api_key=api_key)
|
|
146
243
|
response = app.scrape_url(url, formats=['markdown'])
|
|
147
244
|
if hasattr(response, 'markdown'):
|
|
245
|
+
_dbg(f"Web scrape returned markdown (len={len(response.markdown)})")
|
|
148
246
|
return response.markdown
|
|
149
247
|
else:
|
|
150
248
|
console.print(f"[bold yellow]Warning:[/bold yellow] No markdown content returned for {url}")
|
|
249
|
+
_dbg("Web scrape returned no markdown content")
|
|
151
250
|
return f"[No content available for {url}]"
|
|
152
251
|
except Exception as e:
|
|
153
252
|
console.print(f"[bold red]Error scraping web content:[/bold red] {str(e)}")
|
|
253
|
+
_dbg(f"Web scraping exception: {e}")
|
|
154
254
|
return f"[Web scraping error: {str(e)}]"
|
|
155
255
|
return re.sub(pattern, replace_web, text, flags=re.DOTALL)
|
|
156
256
|
|
|
@@ -173,11 +273,14 @@ def process_include_many_tags(text: str, recursive: bool) -> str:
|
|
|
173
273
|
console.print(f"Including (many): [cyan]{full_path}[/cyan]")
|
|
174
274
|
with open(full_path, 'r', encoding='utf-8') as fh:
|
|
175
275
|
contents.append(fh.read())
|
|
276
|
+
_dbg(f"Included (many): {p}")
|
|
176
277
|
except FileNotFoundError:
|
|
177
278
|
console.print(f"[bold red]Warning:[/bold red] File not found: {p}")
|
|
279
|
+
_dbg(f"Missing include-many: {p}")
|
|
178
280
|
contents.append(f"[File not found: {p}]")
|
|
179
281
|
except Exception as e:
|
|
180
282
|
console.print(f"[bold red]Error processing include-many:[/bold red] {str(e)}")
|
|
283
|
+
_dbg(f"Error processing include-many {p}: {e}")
|
|
181
284
|
contents.append(f"[Error processing include: {p}]")
|
|
182
285
|
return "\n".join(contents)
|
|
183
286
|
return re.sub(pattern, replace_many, text, flags=re.DOTALL)
|
|
@@ -187,6 +290,7 @@ def double_curly(text: str, exclude_keys: Optional[List[str]] = None) -> str:
|
|
|
187
290
|
exclude_keys = []
|
|
188
291
|
|
|
189
292
|
console.print("Doubling curly brackets...")
|
|
293
|
+
_dbg("double_curly invoked")
|
|
190
294
|
|
|
191
295
|
# Special case handling for specific test patterns
|
|
192
296
|
if "Mix of {excluded{inner}} nesting" in text and "excluded" in exclude_keys:
|
|
@@ -210,8 +314,8 @@ def double_curly(text: str, exclude_keys: Optional[List[str]] = None) -> str:
|
|
|
210
314
|
"2": {{"id": "2", "name": "Resource Two"}}
|
|
211
315
|
}}"""
|
|
212
316
|
|
|
213
|
-
# Protect ${IDENT} placeholders so
|
|
214
|
-
#
|
|
317
|
+
# Protect ${IDENT} placeholders so we can safely double braces, then restore
|
|
318
|
+
# them as ${{IDENT}} to avoid PromptTemplate interpreting {IDENT}.
|
|
215
319
|
protected_vars: List[str] = []
|
|
216
320
|
def _protect_var(m):
|
|
217
321
|
protected_vars.append(m.group(0))
|
|
@@ -235,10 +339,22 @@ def double_curly(text: str, exclude_keys: Optional[List[str]] = None) -> str:
|
|
|
235
339
|
# Restore already doubled brackets
|
|
236
340
|
text = re.sub(r'__ALREADY_DOUBLED__(.*?)__END_ALREADY__', r'{{\1}}', text)
|
|
237
341
|
|
|
238
|
-
# Restore protected ${IDENT} placeholders
|
|
342
|
+
# Restore protected ${IDENT} placeholders as ${{IDENT}} so single braces
|
|
343
|
+
# don't leak into PromptTemplate formatting. This is safe for JS template
|
|
344
|
+
# literals and prevents missing-key errors in later formatting steps.
|
|
239
345
|
def _restore_var(m):
|
|
240
346
|
idx = int(m.group(1))
|
|
241
|
-
|
|
347
|
+
if 0 <= idx < len(protected_vars):
|
|
348
|
+
original = protected_vars[idx] # e.g., ${FOO}
|
|
349
|
+
try:
|
|
350
|
+
inner = re.match(r"\$\{([A-Za-z_][A-Za-z0-9_]*)\}", original)
|
|
351
|
+
if inner:
|
|
352
|
+
# Build as concatenation to avoid f-string brace escaping confusion
|
|
353
|
+
return "${{" + inner.group(1) + "}}" # -> ${{FOO}}
|
|
354
|
+
except Exception:
|
|
355
|
+
pass
|
|
356
|
+
return original
|
|
357
|
+
return m.group(0)
|
|
242
358
|
text = re.sub(r"__PDD_VAR_(\d+)__", _restore_var, text)
|
|
243
359
|
|
|
244
360
|
# Special handling for code blocks
|
|
@@ -84,7 +84,21 @@ output_schema:
|
|
|
84
84
|
properties:
|
|
85
85
|
route: { type: string }
|
|
86
86
|
params: { type: array, items: { type: object } }
|
|
87
|
-
dataSources:
|
|
87
|
+
dataSources:
|
|
88
|
+
type: array
|
|
89
|
+
items:
|
|
90
|
+
type: object
|
|
91
|
+
required: [kind, source]
|
|
92
|
+
properties:
|
|
93
|
+
kind: { enum: [api, query, stream, file, cache, message, job, other] }
|
|
94
|
+
source: { type: string }
|
|
95
|
+
method: { type: string }
|
|
96
|
+
description: { type: string }
|
|
97
|
+
auth: { type: string }
|
|
98
|
+
inputs: { type: array, items: { type: string } }
|
|
99
|
+
outputs: { type: array, items: { type: string } }
|
|
100
|
+
refreshInterval: { type: string }
|
|
101
|
+
notes: { type: string }
|
|
88
102
|
layout: { type: object }
|
|
89
103
|
module: { type: object }
|
|
90
104
|
api: { type: object }
|
|
@@ -109,6 +123,7 @@ INSTRUCTIONS:
|
|
|
109
123
|
- Output a single top-level JSON array of items. Each item must include:
|
|
110
124
|
- reason, description, dependencies (filenames), priority (1 = highest), filename, optional tags.
|
|
111
125
|
- interface: include only the applicable sub-object (component, page, module, api, graphql, cli, job, message, or config). Omit all non-applicable sub-objects entirely.
|
|
126
|
+
- When interface.type is "page", each entry in `dataSources` must be an object with at least `kind` (e.g., api/query) and `source` (e.g., URL or identifier). Provide `method`, `description`, and any other useful metadata when known.
|
|
112
127
|
- Valid JSON only. No comments or trailing commas.
|
|
113
128
|
|
|
114
129
|
OUTPUT FORMAT (authoritative):
|
|
@@ -22,11 +22,11 @@ variables:
|
|
|
22
22
|
type: string
|
|
23
23
|
description: System layer or interface type for context.
|
|
24
24
|
examples: [backend, frontend, api, graphql, cli, job, message, config, module, component, page]
|
|
25
|
-
|
|
25
|
+
PRD_FILE:
|
|
26
26
|
required: false
|
|
27
27
|
type: path
|
|
28
|
-
description:
|
|
29
|
-
example_paths: [
|
|
28
|
+
description: Product requirements document providing overall context.
|
|
29
|
+
example_paths: [PRD.md, docs/product/prd.md]
|
|
30
30
|
API_DOC_FILE:
|
|
31
31
|
required: false
|
|
32
32
|
type: path
|
|
@@ -48,7 +48,7 @@ variables:
|
|
|
48
48
|
description: CSV of function inputs/outputs and dependencies for backend modules.
|
|
49
49
|
example_paths: [prompts/backend/io_dependencies.csv]
|
|
50
50
|
ARCHITECTURE_FILE:
|
|
51
|
-
required:
|
|
51
|
+
required: true
|
|
52
52
|
type: path
|
|
53
53
|
description: Architecture JSON (from architecture/architecture_json) to drive module scope, dependencies, and interface.
|
|
54
54
|
example_paths: [architecture.json]
|
|
@@ -75,14 +75,14 @@ variables:
|
|
|
75
75
|
default: py
|
|
76
76
|
usage:
|
|
77
77
|
generate:
|
|
78
|
-
- name: Minimal (
|
|
79
|
-
command: pdd generate -e MODULE=orders -e LANG_OR_FRAMEWORK=Python --output 'prompts/${MODULE}_${LANG_OR_FRAMEWORK}.prompt' pdd/templates/generic/generate_prompt.prompt
|
|
78
|
+
- name: Minimal (architecture only)
|
|
79
|
+
command: pdd generate -e MODULE=orders -e LANG_OR_FRAMEWORK=Python -e ARCHITECTURE_FILE=architecture.json --output 'prompts/${MODULE}_${LANG_OR_FRAMEWORK}.prompt' pdd/templates/generic/generate_prompt.prompt
|
|
80
80
|
- name: With project docs
|
|
81
|
-
command: pdd generate -e MODULE=orders -e LANG_OR_FRAMEWORK=Python -e
|
|
81
|
+
command: pdd generate -e MODULE=orders -e LANG_OR_FRAMEWORK=Python -e ARCHITECTURE_FILE=architecture.json -e PRD_FILE=docs/PRD.md -e API_DOC_FILE=docs/api-documentation.md -e DB_SCHEMA_FILE=context/database-schema.md --output 'prompts/${MODULE}_${LANG_OR_FRAMEWORK}.prompt' pdd/templates/generic/generate_prompt.prompt
|
|
82
82
|
- name: With CSVs and references (backend/Python)
|
|
83
|
-
command: pdd generate -e MODULE=orders -e LANG_OR_FRAMEWORK=Python -e
|
|
83
|
+
command: pdd generate -e MODULE=orders -e LANG_OR_FRAMEWORK=Python -e ARCHITECTURE_FILE=architecture.json -e PRD_FILE=docs/PRD.md -e API_DOC_FILE=docs/api-documentation.md -e DB_SCHEMA_FILE=context/database-schema.md -e BACKEND_FILES_CSV=prompts/backend/python_architecture.csv -e IO_DEPENDENCIES_CSV=prompts/backend/io_dependencies.csv -e CODE_GENERATOR_PROMPT=prompts/code_generator_python.prompt --output 'prompts/${MODULE}_${LANG_OR_FRAMEWORK}.prompt' pdd/templates/generic/generate_prompt.prompt
|
|
84
84
|
- name: Frontend (TypeScriptReact) variant
|
|
85
|
-
command: pdd generate -e MODULE=profile_page -e LANG_OR_FRAMEWORK=TypeScriptReact -e LAYER=frontend -e
|
|
85
|
+
command: pdd generate -e MODULE=profile_page -e LANG_OR_FRAMEWORK=TypeScriptReact -e LAYER=frontend -e ARCHITECTURE_FILE=architecture.json -e PRD_FILE=docs/PRD.md --output 'prompts/${MODULE}_${LANG_OR_FRAMEWORK}.prompt' pdd/templates/generic/generate_prompt.prompt
|
|
86
86
|
- name: From architecture.json
|
|
87
87
|
command: pdd generate -e MODULE=orders_api -e LANG_OR_FRAMEWORK=Python -e LAYER=api -e ARCHITECTURE_FILE=architecture.json --output 'prompts/${MODULE}_${LANG_OR_FRAMEWORK}.prompt' pdd/templates/generic/generate_prompt.prompt
|
|
88
88
|
|
|
@@ -94,8 +94,10 @@ discover:
|
|
|
94
94
|
|
|
95
95
|
% You are an expert prompt writer and software architect for PDD. Your goal is to write a high-quality prompt that will generate the code for the ${MODULE} module/component. The prompt you create will be used to produce a detailed implementation specification in a file named ${MODULE}_${LANG_OR_FRAMEWORK}.prompt, suitable for the specified stack and layer.
|
|
96
96
|
|
|
97
|
-
|
|
98
|
-
|
|
97
|
+
IMPORTANT: Your reply MUST begin with `<prompt>` on the very first line and end with `</prompt>` on the final line. Do not include any text, whitespace, or code fences outside this block.
|
|
98
|
+
|
|
99
|
+
% Project context (architecture required, others optional):
|
|
100
|
+
<prd><include>${PRD_FILE}</include></prd>
|
|
99
101
|
<api><include>${API_DOC_FILE}</include></api>
|
|
100
102
|
<database><include>${DB_SCHEMA_FILE}</include></database>
|
|
101
103
|
<backend_files_csv><include>${BACKEND_FILES_CSV}</include></backend_files_csv>
|
|
@@ -110,8 +112,9 @@ discover:
|
|
|
110
112
|
% Do the following:
|
|
111
113
|
- Explain concisely what you are going to do (create a prompt for the ${MODULE} module/component for the specified layer and stack).
|
|
112
114
|
- Analyze any difficulties this prompt might encounter for ${MODULE} (e.g., data modeling, API or UI contracts, transactions, idempotency, auth, state management, error handling) and briefly state mitigation strategies tailored to the given LAYER and LANG_OR_FRAMEWORK.
|
|
113
|
-
-
|
|
115
|
+
- Use the ARCHITECTURE_FILE to identify the item that corresponds to this prompt by matching `filename` to `${MODULE}_${LANG_OR_FRAMEWORK}.prompt` (or best match by basename and layer). Use that item’s `reason`, `description`, `dependencies`, `interface`, and `tags` to shape the sections below.
|
|
114
116
|
- Then create the prompt content for ${MODULE} inside XML tags named prompt, ensuring conventions fit the stack and layer.
|
|
117
|
+
- Ensure the final response consists solely of the `<prompt>...</prompt>` block; nothing else (including whitespace) may appear before `<prompt>` or after `</prompt>`.
|
|
115
118
|
|
|
116
119
|
% The prompt you generate must follow this structure:
|
|
117
120
|
1) First paragraph: describe the role and responsibility of the ${MODULE} module/component within the system (consider the LAYER if provided).
|
|
@@ -127,9 +130,9 @@ discover:
|
|
|
127
130
|
</orders_service>
|
|
128
131
|
- Prefer real example files available in the provided context (use <include-many> when listing multiple). If examples are not provided, assume dependency examples live under context/ using the pattern context/[dependency_name]_example.${DEP_EXAMPLE_EXT}.
|
|
129
132
|
- Include all necessary dependencies for the module/component (based on the provided context and references).
|
|
130
|
-
-
|
|
133
|
+
- The ARCHITECTURE_FILE lists `dependencies` referencing other prompt filenames. Convert each dependency prompt filename into a sensible dependency name (strip language suffix and `_prompt`), and map to context files with the `${DEP_EXAMPLE_EXT}` extension if present; otherwise, list the prompt filename explicitly in a "Prompt Dependencies" subsection.
|
|
131
134
|
|
|
132
|
-
% Architecture awareness (
|
|
135
|
+
% Architecture awareness (ARCHITECTURE_FILE is required):
|
|
133
136
|
- Align the "Requirements" and "Instructions" with the selected item’s `interface.type` (e.g., page, component, module, api, graphql, cli, job, message, config).
|
|
134
137
|
- For `api`, outline endpoints (method, path, auth) consistent with the architecture description; for `page`/`component`, describe route/props/data sources; for `job`, include trigger and retry policy; for `config`, list keys and sources.
|
|
135
138
|
|
|
@@ -139,4 +142,33 @@ discover:
|
|
|
139
142
|
- Do not invent technologies or files; rely on the included context. If assumptions are necessary, state them explicitly and conservatively.
|
|
140
143
|
|
|
141
144
|
% Output contract:
|
|
142
|
-
-
|
|
145
|
+
- Start the output with `<prompt>` on its own line and end with `</prompt>` on its own line.
|
|
146
|
+
- Do not emit any characters (including whitespace, markdown fences, or commentary) outside the `<prompt>...</prompt>` block.
|
|
147
|
+
- Within the tags, include the sections described above as plain text.
|
|
148
|
+
- OUTPUT FORMAT (authoritative – copy/paste and replace the bracketed placeholders, keeping every literal token):
|
|
149
|
+
```text
|
|
150
|
+
<prompt>
|
|
151
|
+
{ROLE_PARAGRAPH}
|
|
152
|
+
Requirements
|
|
153
|
+
1. {REQ_ITEM_1}
|
|
154
|
+
2. {REQ_ITEM_2}
|
|
155
|
+
Dependencies
|
|
156
|
+
<{DEPENDENCY_TAG_1}>
|
|
157
|
+
<include>{DEPENDENCY_INCLUDE_1}</include>
|
|
158
|
+
</{DEPENDENCY_TAG_1}>
|
|
159
|
+
{OPTIONAL_ADDITIONAL_DEPENDENCY_TAGS}
|
|
160
|
+
Prompt Dependencies:
|
|
161
|
+
{PROMPT_DEPENDENCIES_SECTION}
|
|
162
|
+
Instructions
|
|
163
|
+
- {INSTRUCTION_1}
|
|
164
|
+
- {INSTRUCTION_2}
|
|
165
|
+
Deliverable
|
|
166
|
+
- {DELIVERABLE_1}
|
|
167
|
+
- {DELIVERABLE_2}
|
|
168
|
+
Implementation assumptions (explicit)
|
|
169
|
+
- {ASSUMPTION_1}
|
|
170
|
+
- {ASSUMPTION_2}
|
|
171
|
+
Please produce production-ready prompt content that will generate the module consistent with the above.
|
|
172
|
+
</prompt>
|
|
173
|
+
```
|
|
174
|
+
Replace each `{PLACEHOLDER}` with concrete content while preserving the surrounding structure and literal `<prompt>` / `<include>` tags.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pdd-cli
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.62
|
|
4
4
|
Summary: PDD (Prompt-Driven Development) Command Line Interface
|
|
5
5
|
Author: Greg Tanaka
|
|
6
6
|
Author-email: glt@alumni.caltech.edu
|
|
@@ -53,7 +53,7 @@ Requires-Dist: build; extra == "dev"
|
|
|
53
53
|
Requires-Dist: twine; extra == "dev"
|
|
54
54
|
Dynamic: license-file
|
|
55
55
|
|
|
56
|
-
.. image:: https://img.shields.io/badge/pdd--cli-v0.0.
|
|
56
|
+
.. image:: https://img.shields.io/badge/pdd--cli-v0.0.62-blue
|
|
57
57
|
:alt: PDD-CLI Version
|
|
58
58
|
|
|
59
59
|
.. image:: https://img.shields.io/badge/Discord-join%20chat-7289DA.svg?logo=discord&logoColor=white&link=https://discord.gg/Yp4RTh8bG7
|
|
@@ -130,7 +130,7 @@ After installation, verify:
|
|
|
130
130
|
|
|
131
131
|
pdd --version
|
|
132
132
|
|
|
133
|
-
You'll see the current PDD version (e.g., 0.0.
|
|
133
|
+
You'll see the current PDD version (e.g., 0.0.62).
|
|
134
134
|
|
|
135
135
|
Getting Started with Examples
|
|
136
136
|
-----------------------------
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
pdd/__init__.py,sha256=
|
|
1
|
+
pdd/__init__.py,sha256=41MUueYvzpXybf55GOfmYTViLeVAZihThf7Y-8g_YI4,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=
|
|
9
|
+
pdd/cli.py,sha256=qjDBwwwE-sTWFqKTJOIiYh2nuimlTTgXtMDE0RUuVaU,60805
|
|
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
|
|
@@ -50,7 +50,7 @@ pdd/pdd_completion.sh,sha256=xgx-g6aeCCrlh6loeLyJN5jCsX15YXrWyT1U499p3C0,6490
|
|
|
50
50
|
pdd/pdd_completion.zsh,sha256=V9-V8jqw3osjlXNOvjYMJf0E771-_EQe-Cboo1xzPvY,17090
|
|
51
51
|
pdd/postprocess.py,sha256=mNw3iSDxE-eTYo3QwJCj_EmdEnnB5ysUN62YPapC_IM,4433
|
|
52
52
|
pdd/postprocess_0.py,sha256=OW17GyCFLYErCyWh2tL4syuho3q2yFf2wyekQ4BLdPM,2168
|
|
53
|
-
pdd/preprocess.py,sha256=
|
|
53
|
+
pdd/preprocess.py,sha256=STmC_e4ST253jrhYtya1GfGBDIECu2n3P68S0qyGIxs,17779
|
|
54
54
|
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
|
|
@@ -72,8 +72,8 @@ pdd/update_main.py,sha256=SWCd7Us3YatrDR7B66dQCpRCIgQoMHysPzxa4dedVmk,4385
|
|
|
72
72
|
pdd/update_model_costs.py,sha256=RfeOlAHtc1FCx47A7CjrH2t5WXQclQ_9uYtNjtQh75I,22998
|
|
73
73
|
pdd/update_prompt.py,sha256=zc-HiI1cwGBkJHVmNDyoSZa13lZH90VdB9l8ajdj6Kk,4543
|
|
74
74
|
pdd/xml_tagger.py,sha256=5Bc3HRm7iz_XjBdzQIcMb8KocUQ8PELI2NN5Gw4amd4,4825
|
|
75
|
-
pdd/data/language_format.csv,sha256=
|
|
76
|
-
pdd/data/llm_model.csv,sha256=
|
|
75
|
+
pdd/data/language_format.csv,sha256=i4AfibdhmMnx_xAnv5jHA8TGSftjOJnLcKE53kS7kLY,1010
|
|
76
|
+
pdd/data/llm_model.csv,sha256=u7naNW110fejsV443qlzs0_TmCAzxa8EJogjmmJSAZs,1702
|
|
77
77
|
pdd/prompts/auto_include_LLM.prompt,sha256=sNF2rdJu9wJ8c0lwjCfZ9ZReX8zGXRUNehRs1ZiyDoc,12108
|
|
78
78
|
pdd/prompts/bug_to_unit_test_LLM.prompt,sha256=KdMkvRVnjVSf0NTYIaDXIMT93xPttXEwkMpjWx5leLs,1588
|
|
79
79
|
pdd/prompts/change_LLM.prompt,sha256=5rgWIL16p3VRURd2_lNtcbu_MVRqPhI8gFIBt1gkzDQ,2164
|
|
@@ -110,11 +110,11 @@ pdd/prompts/trim_results_start_LLM.prompt,sha256=OKz8fAf1cYWKWgslFOHEkUpfaUDARh3
|
|
|
110
110
|
pdd/prompts/unfinished_prompt_LLM.prompt,sha256=vud_G9PlVv9Ig64uBC-hPEVFRk5lwpc8pW6tOIxJM4I,5082
|
|
111
111
|
pdd/prompts/update_prompt_LLM.prompt,sha256=prIc8uLp2jqnLTHt6JvWDZGanPZipivhhYeXe0lVaYw,1328
|
|
112
112
|
pdd/prompts/xml_convertor_LLM.prompt,sha256=YGRGXJeg6EhM9690f-SKqQrKqSJjLFD51UrPOlO0Frg,2786
|
|
113
|
-
pdd/templates/architecture/architecture_json.prompt,sha256=
|
|
114
|
-
pdd/templates/generic/generate_prompt.prompt,sha256=
|
|
115
|
-
pdd_cli-0.0.
|
|
116
|
-
pdd_cli-0.0.
|
|
117
|
-
pdd_cli-0.0.
|
|
118
|
-
pdd_cli-0.0.
|
|
119
|
-
pdd_cli-0.0.
|
|
120
|
-
pdd_cli-0.0.
|
|
113
|
+
pdd/templates/architecture/architecture_json.prompt,sha256=omwivayKRP87_PJXqmUPEOwWItZ10b42tnn1aLoslGE,8986
|
|
114
|
+
pdd/templates/generic/generate_prompt.prompt,sha256=4PhcNczpYpwSiaGt0r2f-vhSO3JFqeU1fTEy6YpPudQ,10758
|
|
115
|
+
pdd_cli-0.0.62.dist-info/licenses/LICENSE,sha256=kvTJnnxPVTYlGKSY4ZN1kzdmJ0lxRdNWxgupaB27zsU,1066
|
|
116
|
+
pdd_cli-0.0.62.dist-info/METADATA,sha256=Ha871-qxdSiVohQUS1P-kfhePM1SBYMzYWmtGojHaMw,12687
|
|
117
|
+
pdd_cli-0.0.62.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
118
|
+
pdd_cli-0.0.62.dist-info/entry_points.txt,sha256=Kr8HtNVb8uHZtQJNH4DnF8j7WNgWQbb7_Pw5hECSR-I,36
|
|
119
|
+
pdd_cli-0.0.62.dist-info/top_level.txt,sha256=xjnhIACeMcMeDfVNREgQZl4EbTni2T11QkL5r7E-sbE,4
|
|
120
|
+
pdd_cli-0.0.62.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|