pdd-cli 0.0.58__py3-none-any.whl → 0.0.60__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 +1 -5
- pdd/pdd_completion.fish +24 -2
- pdd/pdd_completion.sh +18 -2
- pdd/pdd_completion.zsh +66 -0
- pdd_cli-0.0.58.data/data/utils/pdd-setup.py → pdd/setup_tool.py +182 -58
- {pdd_cli-0.0.58.dist-info → pdd_cli-0.0.60.dist-info}/METADATA +5 -3
- {pdd_cli-0.0.58.dist-info → pdd_cli-0.0.60.dist-info}/RECORD +12 -12
- {pdd_cli-0.0.58.dist-info → pdd_cli-0.0.60.dist-info}/WHEEL +0 -0
- {pdd_cli-0.0.58.dist-info → pdd_cli-0.0.60.dist-info}/entry_points.txt +0 -0
- {pdd_cli-0.0.58.dist-info → pdd_cli-0.0.60.dist-info}/licenses/LICENSE +0 -0
- {pdd_cli-0.0.58.dist-info → pdd_cli-0.0.60.dist-info}/top_level.txt +0 -0
pdd/__init__.py
CHANGED
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
|
-
|
|
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/pdd_completion.fish
CHANGED
|
@@ -10,6 +10,8 @@ complete -c pdd -n "__fish_use_subcommand" -l quiet -d "Decrease output verbosit
|
|
|
10
10
|
complete -c pdd -n "__fish_use_subcommand" -l output-cost -r -d "Enable cost tracking and output CSV file"
|
|
11
11
|
complete -c pdd -n "__fish_use_subcommand" -l review-examples -d "Review few-shot examples before execution"
|
|
12
12
|
complete -c pdd -n "__fish_use_subcommand" -l local -d "Run commands locally"
|
|
13
|
+
complete -c pdd -n "__fish_use_subcommand" -l context -r -d "Override .pddrc context"
|
|
14
|
+
complete -c pdd -n "__fish_use_subcommand" -l list-contexts -d ".pddrc contexts and exit"
|
|
13
15
|
complete -c pdd -n "__fish_use_subcommand" -l help -d "Show help message"
|
|
14
16
|
complete -c pdd -n "__fish_use_subcommand" -l version -d "Show version information"
|
|
15
17
|
|
|
@@ -29,12 +31,16 @@ complete -c pdd -n "__fish_use_subcommand" -a trace -d "Trace code line to promp
|
|
|
29
31
|
complete -c pdd -n "__fish_use_subcommand" -a bug -d "Generate unit test from bug report"
|
|
30
32
|
complete -c pdd -n "__fish_use_subcommand" -a auto-deps -d "Analyze and insert dependencies from directory or glob"
|
|
31
33
|
complete -c pdd -n "__fish_use_subcommand" -a verify -d "Verify functional correctness using LLM judgment"
|
|
34
|
+
complete -c pdd -n "__fish_use_subcommand" -a sync -d "Synchronize prompt, code, examples, tests"
|
|
35
|
+
complete -c pdd -n "__fish_use_subcommand" -a setup -d "Interactive setup and completion install"
|
|
36
|
+
complete -c pdd -n "__fish_use_subcommand" -a install_completion -d "Install shell completion"
|
|
37
|
+
complete -c pdd -n "__fish_use_subcommand" -a pytest-output -d "Run pytest and capture structured output"
|
|
32
38
|
|
|
33
39
|
# Command-specific completions
|
|
34
40
|
complete -c pdd -n "__fish_seen_subcommand_from generate" -l output -r -d "Output location for generated code"
|
|
35
41
|
complete -c pdd -n "__fish_seen_subcommand_from generate" -l original-prompt -r -d "Original prompt file for incremental generation"
|
|
36
42
|
complete -c pdd -n "__fish_seen_subcommand_from generate" -l incremental -d "Force incremental patching"
|
|
37
|
-
complete -c pdd -n "__fish_seen_subcommand_from generate" -s e -l env -xa "(env | cut -d= -f1 | sed 's
|
|
43
|
+
complete -c pdd -n "__fish_seen_subcommand_from generate" -s e -l env -xa "(env | cut -d= -f1 | sed 's/.*/&=/' | sort -u)" -d "Set template variable (KEY=VALUE) or read KEY from env"
|
|
38
44
|
complete -c pdd -n "__fish_seen_subcommand_from generate" -a "(__fish_complete_suffix .prompt)"
|
|
39
45
|
|
|
40
46
|
complete -c pdd -n "__fish_seen_subcommand_from example" -l output -r -d "Output location for example code"
|
|
@@ -126,10 +132,26 @@ complete -c pdd -n "__fish_seen_subcommand_from verify" -l budget -x -d "Max bud
|
|
|
126
132
|
complete -c pdd -n "__fish_seen_subcommand_from verify" -a "(__fish_complete_suffix .prompt)"
|
|
127
133
|
complete -c pdd -n "__fish_seen_subcommand_from verify" -a "(__fish_complete_suffix .py .js .java .cpp .rb .go)" # For CODE_FILE and PROGRAM_FILE
|
|
128
134
|
|
|
135
|
+
# sync command
|
|
136
|
+
complete -c pdd -n "__fish_seen_subcommand_from sync" -l max-attempts -x -d "Max attempts for loops"
|
|
137
|
+
complete -c pdd -n "__fish_seen_subcommand_from sync" -l budget -x -d "Total budget for sync"
|
|
138
|
+
complete -c pdd -n "__fish_seen_subcommand_from sync" -l skip-verify -d "Skip functional verification"
|
|
139
|
+
complete -c pdd -n "__fish_seen_subcommand_from sync" -l skip-tests -d "Skip unit test generation"
|
|
140
|
+
complete -c pdd -n "__fish_seen_subcommand_from sync" -l target-coverage -x -d "Desired coverage percentage"
|
|
141
|
+
complete -c pdd -n "__fish_seen_subcommand_from sync" -l log -d "Show analysis instead of running"
|
|
142
|
+
|
|
143
|
+
# setup and install_completion have no options
|
|
144
|
+
complete -c pdd -n "__fish_seen_subcommand_from setup" -d "Run interactive setup"
|
|
145
|
+
complete -c pdd -n "__fish_seen_subcommand_from install_completion" -d "Install shell completion"
|
|
146
|
+
|
|
147
|
+
# pytest-output command
|
|
148
|
+
complete -c pdd -n "__fish_seen_subcommand_from pytest-output" -l json-only -d "Print only JSON"
|
|
149
|
+
complete -c pdd -n "__fish_seen_subcommand_from pytest-output" -a "(__fish_complete_suffix .py)"
|
|
150
|
+
|
|
129
151
|
# File completion for all commands
|
|
130
152
|
complete -c pdd -n "__fish_seen_subcommand_from generate example test preprocess fix split change update detect conflicts crash trace bug auto-deps verify" -a "(__fish_complete_suffix .prompt)"
|
|
131
153
|
complete -c pdd -n "__fish_seen_subcommand_from generate example test preprocess fix split change update detect conflicts crash trace bug auto-deps verify" -a "(__fish_complete_suffix .py .js .java .cpp .rb .go)"
|
|
132
154
|
complete -c pdd -n "__fish_seen_subcommand_from generate example test preprocess fix split change update detect conflicts crash trace bug auto-deps verify" -a "(__fish_complete_suffix .log .txt .csv)"
|
|
133
155
|
|
|
134
156
|
# Help completion
|
|
135
|
-
complete -c pdd -n "__fish_seen_subcommand_from help" -a "generate example test preprocess fix split change update detect conflicts crash trace bug auto-deps verify" -d "Show help for specific command"
|
|
157
|
+
complete -c pdd -n "__fish_seen_subcommand_from help" -a "generate example test preprocess fix split change update detect conflicts crash trace bug auto-deps verify sync setup install_completion pytest-output" -d "Show help for specific command"
|
pdd/pdd_completion.sh
CHANGED
|
@@ -15,10 +15,10 @@ _pdd() {
|
|
|
15
15
|
cword=$COMP_CWORD
|
|
16
16
|
|
|
17
17
|
# Global options
|
|
18
|
-
local global_opts="--force --strength --time --temperature --verbose --quiet --output-cost --review-examples --local --help --version"
|
|
18
|
+
local global_opts="--force --strength --time --temperature --verbose --quiet --output-cost --review-examples --local --context --list-contexts --help --version"
|
|
19
19
|
|
|
20
20
|
# Commands
|
|
21
|
-
local commands="generate example test preprocess fix split change update detect conflicts crash trace bug auto-deps verify"
|
|
21
|
+
local commands="generate example test preprocess fix split change update detect conflicts crash trace bug auto-deps verify sync setup install_completion pytest-output"
|
|
22
22
|
|
|
23
23
|
# Command-specific options
|
|
24
24
|
local generate_opts="--output --original-prompt --incremental --env -e"
|
|
@@ -36,6 +36,8 @@ _pdd() {
|
|
|
36
36
|
local bug_opts="--output --language"
|
|
37
37
|
local auto_deps_opts="--output --csv --force-scan"
|
|
38
38
|
local verify_opts="--output-results --output-code --output-program --max-attempts --budget"
|
|
39
|
+
local sync_opts="--max-attempts --budget --skip-verify --skip-tests --target-coverage --log"
|
|
40
|
+
local pytest_output_opts="--json-only"
|
|
39
41
|
|
|
40
42
|
# Complete global options before command
|
|
41
43
|
if [[ $cword -eq 1 ]]; then
|
|
@@ -141,6 +143,20 @@ _pdd() {
|
|
|
141
143
|
_complete_files
|
|
142
144
|
COMPREPLY+=($(compgen -W "$verify_opts" -- "$cur"))
|
|
143
145
|
;;
|
|
146
|
+
sync)
|
|
147
|
+
# BASENAME (not a file), offer options
|
|
148
|
+
COMPREPLY+=($(compgen -W "$sync_opts" -- "$cur"))
|
|
149
|
+
;;
|
|
150
|
+
setup)
|
|
151
|
+
# no command-specific options
|
|
152
|
+
;;
|
|
153
|
+
install_completion)
|
|
154
|
+
# no command-specific options
|
|
155
|
+
;;
|
|
156
|
+
pytest-output)
|
|
157
|
+
_complete_files
|
|
158
|
+
COMPREPLY+=($(compgen -W "$pytest_output_opts" -- "$cur"))
|
|
159
|
+
;;
|
|
144
160
|
*)
|
|
145
161
|
COMPREPLY=($(compgen -W "$global_opts" -- "$cur"))
|
|
146
162
|
;;
|
pdd/pdd_completion.zsh
CHANGED
|
@@ -57,6 +57,8 @@ _pdd_global_opts=(
|
|
|
57
57
|
'--output-cost[Enable cost tracking and output a CSV file with usage details.]:filename:_files'
|
|
58
58
|
'--review-examples[Review and optionally exclude few-shot examples before command execution.]'
|
|
59
59
|
'--local[Run commands locally instead of in the cloud.]'
|
|
60
|
+
'--context[Override automatic .pddrc context]:context-name:_guard'
|
|
61
|
+
'--list-contexts[List available .pddrc contexts and exit]'
|
|
60
62
|
'--help[Show help message and exit.]'
|
|
61
63
|
'--version[Show version and exit.]'
|
|
62
64
|
)
|
|
@@ -396,6 +398,54 @@ _pdd_verify() {
|
|
|
396
398
|
'*:filename:_files'
|
|
397
399
|
}
|
|
398
400
|
|
|
401
|
+
# sync
|
|
402
|
+
# Usage: pdd [GLOBAL OPTIONS] sync [OPTIONS] BASENAME
|
|
403
|
+
# Options:
|
|
404
|
+
# --max-attempts [INT]
|
|
405
|
+
# --budget [FLOAT]
|
|
406
|
+
# --skip-verify
|
|
407
|
+
# --skip-tests
|
|
408
|
+
# --target-coverage [FLOAT]
|
|
409
|
+
# --log
|
|
410
|
+
# Arg:
|
|
411
|
+
# 1: BASENAME
|
|
412
|
+
_pdd_sync() {
|
|
413
|
+
_arguments -s \
|
|
414
|
+
$_pdd_global_opts \
|
|
415
|
+
'--max-attempts=[Maximum attempts for iterative loops (default 3)]:int' \
|
|
416
|
+
'--budget=[Maximum total cost for sync (default 10.0)]:float' \
|
|
417
|
+
'--skip-verify[Skip the functional verification step]' \
|
|
418
|
+
'--skip-tests[Skip unit test generation and fixing]' \
|
|
419
|
+
'--target-coverage=[Desired code coverage percentage]:float' \
|
|
420
|
+
'--log[Show analysis instead of executing operations]' \
|
|
421
|
+
'1:basename: ' \
|
|
422
|
+
'*: :'
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
# setup (no options)
|
|
426
|
+
_pdd_setup() {
|
|
427
|
+
_arguments -s $_pdd_global_opts
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
# install_completion (no options)
|
|
431
|
+
_pdd_install_completion() {
|
|
432
|
+
_arguments -s $_pdd_global_opts
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
# pytest-output
|
|
436
|
+
# Usage: pdd [GLOBAL OPTIONS] pytest-output [OPTIONS] TEST_FILE
|
|
437
|
+
# Options:
|
|
438
|
+
# --json-only
|
|
439
|
+
# Arg:
|
|
440
|
+
# 1: TEST_FILE
|
|
441
|
+
_pdd_pytest_output() {
|
|
442
|
+
_arguments -s \
|
|
443
|
+
$_pdd_global_opts \
|
|
444
|
+
'--json-only[Print only JSON to stdout]' \
|
|
445
|
+
'1:test-file:_files' \
|
|
446
|
+
'*:filename:_files'
|
|
447
|
+
}
|
|
448
|
+
|
|
399
449
|
##
|
|
400
450
|
# Main PDD completion dispatcher
|
|
401
451
|
##
|
|
@@ -421,6 +471,10 @@ _pdd() {
|
|
|
421
471
|
'bug:Generate a unit test based on incorrect vs desired outputs'
|
|
422
472
|
'auto-deps:Analyze a prompt and include deps from a directory or glob'
|
|
423
473
|
'verify:Verify functional correctness using LLM judgment and iteratively fix'
|
|
474
|
+
'sync:Synchronize prompt, code, examples, tests with analysis'
|
|
475
|
+
'setup:Interactive setup and completion install'
|
|
476
|
+
'install_completion:Install shell completion for current shell'
|
|
477
|
+
'pytest-output:Run pytest and capture structured output'
|
|
424
478
|
)
|
|
425
479
|
|
|
426
480
|
# If there's no subcommand yet (i.e., user typed only "pdd " or "pdd -<Tab>"), offer global opts or subcommands.
|
|
@@ -480,6 +534,18 @@ _pdd() {
|
|
|
480
534
|
verify)
|
|
481
535
|
_pdd_verify
|
|
482
536
|
;;
|
|
537
|
+
sync)
|
|
538
|
+
_pdd_sync
|
|
539
|
+
;;
|
|
540
|
+
setup)
|
|
541
|
+
_pdd_setup
|
|
542
|
+
;;
|
|
543
|
+
install_completion)
|
|
544
|
+
_pdd_install_completion
|
|
545
|
+
;;
|
|
546
|
+
pytest-output)
|
|
547
|
+
_pdd_pytest_output
|
|
548
|
+
;;
|
|
483
549
|
# If the subcommand is unknown or not typed yet, fall back to showing the list of subcommands.
|
|
484
550
|
*)
|
|
485
551
|
_describe -t subcommands 'pdd subcommand' _pdd_subcommands
|
|
@@ -9,6 +9,8 @@ import sys
|
|
|
9
9
|
import subprocess
|
|
10
10
|
import json
|
|
11
11
|
import requests
|
|
12
|
+
import csv
|
|
13
|
+
import importlib.resources
|
|
12
14
|
from pathlib import Path
|
|
13
15
|
from typing import Dict, Optional, Tuple, List
|
|
14
16
|
|
|
@@ -39,26 +41,27 @@ YELLOW = "\033[93m"
|
|
|
39
41
|
BOLD = "\033[1m"
|
|
40
42
|
|
|
41
43
|
# Template content inline
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
44
|
+
SUCCESS_PYTHON_TEMPLATE = """
|
|
45
|
+
Write a python script to print "You did it, <Username>!!!" to the console.
|
|
46
|
+
Do not write anything except that message.
|
|
47
|
+
Capitalize the username."""
|
|
48
|
+
|
|
49
|
+
def _read_packaged_llm_model_csv() -> Tuple[List[str], List[Dict[str, str]]]:
|
|
50
|
+
"""Load the packaged CSV (pdd/data/llm_model.csv) and return header + rows.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
(header_fields, rows) where header_fields is the list of column names
|
|
54
|
+
and rows is a list of dictionaries for each CSV row.
|
|
55
|
+
"""
|
|
56
|
+
try:
|
|
57
|
+
csv_text = importlib.resources.files('pdd').joinpath('data/llm_model.csv').read_text()
|
|
58
|
+
except Exception as e:
|
|
59
|
+
raise FileNotFoundError(f"Failed to load default LLM model CSV from package: {e}")
|
|
60
|
+
|
|
61
|
+
reader = csv.DictReader(csv_text.splitlines())
|
|
62
|
+
header = reader.fieldnames or []
|
|
63
|
+
rows = [row for row in reader]
|
|
64
|
+
return header, rows
|
|
62
65
|
|
|
63
66
|
def print_colored(text: str, color: str = WHITE, bold: bool = False) -> None:
|
|
64
67
|
"""Print colored text to console"""
|
|
@@ -95,16 +98,60 @@ def print_pdd_logo():
|
|
|
95
98
|
]
|
|
96
99
|
)
|
|
97
100
|
print(f"{CYAN}{logo}{RESET}")
|
|
98
|
-
|
|
101
|
+
print()
|
|
102
|
+
print_colored("Let's get set up quickly with a solid basic configuration!", WHITE, bold=True)
|
|
103
|
+
print()
|
|
104
|
+
print_colored("Supported: OpenAI, Google Gemini, and Anthropic Claude", WHITE)
|
|
99
105
|
print_colored("from their respective API endpoints (no third-parties, such as Azure)", WHITE)
|
|
100
106
|
print()
|
|
101
107
|
|
|
108
|
+
def get_csv_variable_names() -> Dict[str, str]:
|
|
109
|
+
"""Inspect packaged CSV to determine API key variable names per provider.
|
|
110
|
+
|
|
111
|
+
Focus on direct providers only: OpenAI GPT models (model startswith 'gpt-'),
|
|
112
|
+
Google Gemini (model startswith 'gemini/'), and Anthropic (model startswith 'anthropic/').
|
|
113
|
+
"""
|
|
114
|
+
header, rows = _read_packaged_llm_model_csv()
|
|
115
|
+
variable_names: Dict[str, str] = {}
|
|
116
|
+
|
|
117
|
+
for row in rows:
|
|
118
|
+
model = (row.get('model') or '').strip()
|
|
119
|
+
api_key = (row.get('api_key') or '').strip()
|
|
120
|
+
provider = (row.get('provider') or '').strip().upper()
|
|
121
|
+
|
|
122
|
+
if not api_key:
|
|
123
|
+
continue
|
|
124
|
+
|
|
125
|
+
if model.startswith('gpt-') and provider == 'OPENAI':
|
|
126
|
+
variable_names['OPENAI'] = api_key
|
|
127
|
+
elif model.startswith('gemini/') and provider == 'GOOGLE':
|
|
128
|
+
# Prefer direct Gemini key, not Vertex
|
|
129
|
+
variable_names['GOOGLE'] = api_key
|
|
130
|
+
elif model.startswith('anthropic/') and provider == 'ANTHROPIC':
|
|
131
|
+
variable_names['ANTHROPIC'] = api_key
|
|
132
|
+
|
|
133
|
+
# Fallbacks if not detected (keep prior behavior)
|
|
134
|
+
variable_names.setdefault('OPENAI', 'OPENAI_API_KEY')
|
|
135
|
+
# Prefer GEMINI_API_KEY name for Google if present
|
|
136
|
+
variable_names.setdefault('GOOGLE', 'GEMINI_API_KEY')
|
|
137
|
+
variable_names.setdefault('ANTHROPIC', 'ANTHROPIC_API_KEY')
|
|
138
|
+
return variable_names
|
|
139
|
+
|
|
102
140
|
def discover_api_keys() -> Dict[str, Optional[str]]:
|
|
103
141
|
"""Discover API keys from environment variables"""
|
|
142
|
+
# Get the variable names actually used in CSV template
|
|
143
|
+
csv_vars = get_csv_variable_names()
|
|
144
|
+
|
|
104
145
|
keys = {
|
|
105
146
|
'OPENAI_API_KEY': os.getenv('OPENAI_API_KEY'),
|
|
106
|
-
'
|
|
147
|
+
'ANTHROPIC_API_KEY': os.getenv('ANTHROPIC_API_KEY'),
|
|
107
148
|
}
|
|
149
|
+
|
|
150
|
+
# For Google, check both possible environment variables but use CSV template's variable name
|
|
151
|
+
google_var_name = csv_vars.get('GOOGLE', 'GEMINI_API_KEY') # Default to GEMINI_API_KEY
|
|
152
|
+
google_api_key = os.getenv('GEMINI_API_KEY') or os.getenv('GOOGLE_API_KEY')
|
|
153
|
+
keys[google_var_name] = google_api_key
|
|
154
|
+
|
|
108
155
|
return keys
|
|
109
156
|
|
|
110
157
|
def test_openai_key(api_key: str) -> bool:
|
|
@@ -140,6 +187,26 @@ def test_google_key(api_key: str) -> bool:
|
|
|
140
187
|
except Exception:
|
|
141
188
|
return False
|
|
142
189
|
|
|
190
|
+
def test_anthropic_key(api_key: str) -> bool:
|
|
191
|
+
"""Test Anthropic API key validity"""
|
|
192
|
+
if not api_key or not api_key.strip():
|
|
193
|
+
return False
|
|
194
|
+
|
|
195
|
+
try:
|
|
196
|
+
headers = {
|
|
197
|
+
'x-api-key': api_key.strip(),
|
|
198
|
+
'Content-Type': 'application/json'
|
|
199
|
+
}
|
|
200
|
+
response = requests.get(
|
|
201
|
+
'https://api.anthropic.com/v1/messages',
|
|
202
|
+
headers=headers,
|
|
203
|
+
timeout=10
|
|
204
|
+
)
|
|
205
|
+
# Anthropic returns 400 for invalid request structure but 401/403 for bad keys
|
|
206
|
+
return response.status_code != 401 and response.status_code != 403
|
|
207
|
+
except Exception:
|
|
208
|
+
return False
|
|
209
|
+
|
|
143
210
|
def test_api_keys(keys: Dict[str, Optional[str]]) -> Dict[str, bool]:
|
|
144
211
|
"""Test all discovered API keys"""
|
|
145
212
|
results = {}
|
|
@@ -153,8 +220,10 @@ def test_api_keys(keys: Dict[str, Optional[str]]) -> Dict[str, bool]:
|
|
|
153
220
|
print(f"Testing {key_name}...", end=" ", flush=True)
|
|
154
221
|
if key_name == 'OPENAI_API_KEY':
|
|
155
222
|
valid = test_openai_key(key_value)
|
|
156
|
-
elif key_name in ['GOOGLE_API_KEY']:
|
|
223
|
+
elif key_name in ['GEMINI_API_KEY', 'GOOGLE_API_KEY']:
|
|
157
224
|
valid = test_google_key(key_value)
|
|
225
|
+
elif key_name == 'ANTHROPIC_API_KEY':
|
|
226
|
+
valid = test_anthropic_key(key_value)
|
|
158
227
|
else:
|
|
159
228
|
valid = False
|
|
160
229
|
|
|
@@ -181,13 +250,16 @@ def get_user_keys(current_keys: Dict[str, Optional[str]]) -> Dict[str, Optional[
|
|
|
181
250
|
print_colored("Get API keys here:", WHITE)
|
|
182
251
|
print_colored(f" OpenAI {ARROW_RIGHT} https://platform.openai.com/api-keys", CYAN)
|
|
183
252
|
print_colored(f" Google Gemini {ARROW_RIGHT} https://aistudio.google.com/app/apikey", CYAN)
|
|
253
|
+
print_colored(f" Anthropic {ARROW_RIGHT} https://console.anthropic.com/settings/keys", CYAN)
|
|
184
254
|
print()
|
|
185
255
|
print_colored("A free instant starter key is available from Google Gemini (above)", CYAN)
|
|
186
256
|
print()
|
|
187
257
|
|
|
188
258
|
new_keys = current_keys.copy()
|
|
189
259
|
|
|
190
|
-
|
|
260
|
+
# Get the actual key names from discovered keys
|
|
261
|
+
key_names = list(current_keys.keys())
|
|
262
|
+
for key_name in key_names:
|
|
191
263
|
current_value = current_keys.get(key_name, "")
|
|
192
264
|
status = "found" if current_value else "not found"
|
|
193
265
|
|
|
@@ -230,7 +302,8 @@ def get_shell_init_file(shell: str) -> str:
|
|
|
230
302
|
'fish': home / '.config/fish/config.fish',
|
|
231
303
|
'csh': home / '.cshrc',
|
|
232
304
|
'tcsh': home / '.tcshrc',
|
|
233
|
-
'ksh': home / '.kshrc'
|
|
305
|
+
'ksh': home / '.kshrc',
|
|
306
|
+
'sh': home / '.profile'
|
|
234
307
|
}
|
|
235
308
|
|
|
236
309
|
return str(shell_files.get(shell, home / '.bashrc'))
|
|
@@ -249,13 +322,13 @@ def create_api_env_script(keys: Dict[str, str], shell: str) -> str:
|
|
|
249
322
|
for key, value in valid_keys.items():
|
|
250
323
|
lines.append(f'setenv {key} "{value}"')
|
|
251
324
|
return '\n'.join(lines) + '\n'
|
|
252
|
-
else: # bash, zsh, ksh and others
|
|
325
|
+
else: # bash, zsh, ksh, sh and others
|
|
253
326
|
lines = []
|
|
254
327
|
for key, value in valid_keys.items():
|
|
255
328
|
lines.append(f'export {key}="{value}"')
|
|
256
329
|
return '\n'.join(lines) + '\n'
|
|
257
330
|
|
|
258
|
-
def save_configuration(valid_keys: Dict[str, str]) -> Tuple[List[str], bool]:
|
|
331
|
+
def save_configuration(valid_keys: Dict[str, str]) -> Tuple[List[str], bool, Optional[str]]:
|
|
259
332
|
"""Save configuration to ~/.pdd/ directory"""
|
|
260
333
|
home = Path.home()
|
|
261
334
|
pdd_dir = home / '.pdd'
|
|
@@ -271,34 +344,60 @@ def save_configuration(valid_keys: Dict[str, str]) -> Tuple[List[str], bool]:
|
|
|
271
344
|
shell = detect_shell()
|
|
272
345
|
api_env_content = create_api_env_script(valid_keys, shell)
|
|
273
346
|
|
|
274
|
-
# Write api-env file
|
|
275
|
-
api_env_file = pdd_dir / 'api-env'
|
|
347
|
+
# Write shell-specific api-env file
|
|
348
|
+
api_env_file = pdd_dir / f'api-env.{shell}'
|
|
276
349
|
api_env_file.write_text(api_env_content)
|
|
277
350
|
api_env_file.chmod(0o755)
|
|
278
351
|
saved_files.append(str(api_env_file))
|
|
279
352
|
|
|
280
|
-
# Create llm_model.csv with
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
if '
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
353
|
+
# Create llm_model.csv with models from packaged CSV filtered by provider and available keys
|
|
354
|
+
header_fields, rows = _read_packaged_llm_model_csv()
|
|
355
|
+
|
|
356
|
+
# Keep only direct Google Gemini (model startswith 'gemini/'), OpenAI GPT (gpt-*) and Anthropic (anthropic/*)
|
|
357
|
+
def _is_supported_model(row: Dict[str, str]) -> bool:
|
|
358
|
+
model = (row.get('model') or '').strip()
|
|
359
|
+
if model.startswith('gpt-'):
|
|
360
|
+
return True
|
|
361
|
+
if model.startswith('gemini/'):
|
|
362
|
+
return True
|
|
363
|
+
if model.startswith('anthropic/'):
|
|
364
|
+
return True
|
|
365
|
+
return False
|
|
366
|
+
|
|
367
|
+
# Filter rows by supported models and by api_key presence in valid_keys
|
|
368
|
+
filtered_rows: List[Dict[str, str]] = []
|
|
369
|
+
for row in rows:
|
|
370
|
+
if not _is_supported_model(row):
|
|
371
|
+
continue
|
|
372
|
+
api_key_name = (row.get('api_key') or '').strip()
|
|
373
|
+
# Include only if we have a validated key for this row
|
|
374
|
+
if api_key_name and api_key_name in valid_keys:
|
|
375
|
+
filtered_rows.append(row)
|
|
376
|
+
|
|
377
|
+
# Write out the filtered CSV to ~/.pdd/llm_model.csv preserving column order
|
|
291
378
|
llm_model_file = pdd_dir / 'llm_model.csv'
|
|
292
|
-
llm_model_file.
|
|
379
|
+
with llm_model_file.open('w', newline='') as f:
|
|
380
|
+
writer = csv.DictWriter(f, fieldnames=header_fields)
|
|
381
|
+
writer.writeheader()
|
|
382
|
+
for row in filtered_rows:
|
|
383
|
+
writer.writerow({k: row.get(k, '') for k in header_fields})
|
|
293
384
|
saved_files.append(str(llm_model_file))
|
|
294
385
|
|
|
295
386
|
# Update shell init file
|
|
296
387
|
init_file_path = get_shell_init_file(shell)
|
|
297
388
|
init_file = Path(init_file_path)
|
|
389
|
+
init_file_updated = None
|
|
298
390
|
|
|
299
391
|
source_line = f'[ -f "{api_env_file}" ] && source "{api_env_file}"'
|
|
300
392
|
if shell == 'fish':
|
|
301
393
|
source_line = f'test -f "{api_env_file}"; and source "{api_env_file}"'
|
|
394
|
+
elif shell in ['csh', 'tcsh']:
|
|
395
|
+
source_line = f'if ( -f "{api_env_file}" ) source "{api_env_file}"'
|
|
396
|
+
elif shell == 'sh':
|
|
397
|
+
source_line = f'[ -f "{api_env_file}" ] && . "{api_env_file}"'
|
|
398
|
+
|
|
399
|
+
# Ensure parent directory exists (important for fish shell)
|
|
400
|
+
init_file.parent.mkdir(parents=True, exist_ok=True)
|
|
302
401
|
|
|
303
402
|
# Check if source line already exists
|
|
304
403
|
if init_file.exists():
|
|
@@ -306,15 +405,17 @@ def save_configuration(valid_keys: Dict[str, str]) -> Tuple[List[str], bool]:
|
|
|
306
405
|
if str(api_env_file) not in content:
|
|
307
406
|
with init_file.open('a') as f:
|
|
308
407
|
f.write(f'\n# PDD API environment\n{source_line}\n')
|
|
408
|
+
init_file_updated = str(init_file)
|
|
309
409
|
else:
|
|
310
410
|
init_file.write_text(f'# PDD API environment\n{source_line}\n')
|
|
411
|
+
init_file_updated = str(init_file)
|
|
311
412
|
|
|
312
|
-
return saved_files, created_pdd_dir
|
|
413
|
+
return saved_files, created_pdd_dir, init_file_updated
|
|
313
414
|
|
|
314
415
|
def create_sample_prompt():
|
|
315
416
|
"""Create the sample prompt file"""
|
|
316
|
-
prompt_file = Path('
|
|
317
|
-
prompt_file.write_text(
|
|
417
|
+
prompt_file = Path('success_python.prompt')
|
|
418
|
+
prompt_file.write_text(SUCCESS_PYTHON_TEMPLATE)
|
|
318
419
|
return str(prompt_file)
|
|
319
420
|
|
|
320
421
|
def show_menu(keys: Dict[str, Optional[str]], test_results: Dict[str, bool]) -> str:
|
|
@@ -325,7 +426,9 @@ def show_menu(keys: Dict[str, Optional[str]], test_results: Dict[str, bool]) ->
|
|
|
325
426
|
|
|
326
427
|
# Show current status
|
|
327
428
|
print_colored("Current API Key Status:", WHITE, bold=True)
|
|
328
|
-
|
|
429
|
+
# Get the actual key names from discovered keys
|
|
430
|
+
key_names = list(keys.keys())
|
|
431
|
+
for key_name in key_names:
|
|
329
432
|
key_value = keys.get(key_name)
|
|
330
433
|
if key_value:
|
|
331
434
|
status = f"{CHECK_MARK} Valid" if test_results.get(key_name) else f"{CROSS_MARK} Invalid"
|
|
@@ -356,7 +459,7 @@ def show_menu(keys: Dict[str, Optional[str]], test_results: Dict[str, bool]) ->
|
|
|
356
459
|
print_colored("\n\nSetup cancelled.", YELLOW)
|
|
357
460
|
sys.exit(0)
|
|
358
461
|
|
|
359
|
-
def create_exit_summary(saved_files: List[str], created_pdd_dir: bool, sample_prompt_file: str, shell: str) -> str:
|
|
462
|
+
def create_exit_summary(saved_files: List[str], created_pdd_dir: bool, sample_prompt_file: str, shell: str, valid_keys: Dict[str, str], init_file_updated: Optional[str] = None) -> str:
|
|
360
463
|
"""Create comprehensive exit summary"""
|
|
361
464
|
summary_lines = [
|
|
362
465
|
"\n\n\n\n\n",
|
|
@@ -364,22 +467,37 @@ def create_exit_summary(saved_files: List[str], created_pdd_dir: bool, sample_pr
|
|
|
364
467
|
"PDD Setup Complete!",
|
|
365
468
|
create_fat_divider(),
|
|
366
469
|
"",
|
|
367
|
-
"
|
|
470
|
+
"API Keys Configured:",
|
|
368
471
|
""
|
|
369
472
|
]
|
|
370
473
|
|
|
474
|
+
# Add configured API keys information
|
|
475
|
+
if valid_keys:
|
|
476
|
+
for key_name, key_value in valid_keys.items():
|
|
477
|
+
# Show just the first and last few characters for security
|
|
478
|
+
masked_key = f"{key_value[:8]}...{key_value[-4:]}" if len(key_value) > 12 else "***"
|
|
479
|
+
summary_lines.append(f" {key_name}: {masked_key}")
|
|
480
|
+
summary_lines.extend(["", "Files created and configured:", ""])
|
|
481
|
+
else:
|
|
482
|
+
summary_lines.extend([" None", "", "Files created and configured:", ""])
|
|
483
|
+
|
|
371
484
|
# File descriptions with alignment
|
|
372
485
|
file_descriptions = []
|
|
373
486
|
if created_pdd_dir:
|
|
374
487
|
file_descriptions.append(("~/.pdd/", "PDD configuration directory"))
|
|
375
488
|
|
|
376
489
|
for file_path in saved_files:
|
|
377
|
-
if 'api-env' in file_path:
|
|
378
|
-
file_descriptions.append((file_path, "API environment variables"))
|
|
490
|
+
if 'api-env.' in file_path:
|
|
491
|
+
file_descriptions.append((file_path, f"API environment variables ({shell} shell)"))
|
|
379
492
|
elif 'llm_model.csv' in file_path:
|
|
380
493
|
file_descriptions.append((file_path, "LLM model configuration"))
|
|
381
494
|
|
|
382
495
|
file_descriptions.append((sample_prompt_file, "Sample prompt for testing"))
|
|
496
|
+
|
|
497
|
+
# Add shell init file if it was updated
|
|
498
|
+
if init_file_updated:
|
|
499
|
+
file_descriptions.append((init_file_updated, f"Shell startup file (updated to source API environment)"))
|
|
500
|
+
|
|
383
501
|
file_descriptions.append(("PDD-SETUP-SUMMARY.txt", "This summary"))
|
|
384
502
|
|
|
385
503
|
# Find max file path length for alignment
|
|
@@ -397,10 +515,11 @@ def create_exit_summary(saved_files: List[str], created_pdd_dir: bool, sample_pr
|
|
|
397
515
|
f"1. Reload your shell environment:"
|
|
398
516
|
])
|
|
399
517
|
|
|
400
|
-
# Shell-specific source command
|
|
401
|
-
api_env_path = f"{Path.home()}/.pdd/api-env"
|
|
402
|
-
|
|
403
|
-
|
|
518
|
+
# Shell-specific source command for manual reloading
|
|
519
|
+
api_env_path = f"{Path.home()}/.pdd/api-env.{shell}"
|
|
520
|
+
# Use dot command for sh shell, source for others
|
|
521
|
+
if shell == 'sh':
|
|
522
|
+
source_cmd = f". {api_env_path}"
|
|
404
523
|
else:
|
|
405
524
|
source_cmd = f"source {api_env_path}"
|
|
406
525
|
|
|
@@ -408,7 +527,7 @@ def create_exit_summary(saved_files: List[str], created_pdd_dir: bool, sample_pr
|
|
|
408
527
|
f" {source_cmd}",
|
|
409
528
|
"",
|
|
410
529
|
f"2. Generate code from the sample prompt:",
|
|
411
|
-
f" pdd generate
|
|
530
|
+
f" pdd generate success_python.prompt",
|
|
412
531
|
"",
|
|
413
532
|
create_divider(),
|
|
414
533
|
"",
|
|
@@ -428,7 +547,8 @@ def create_exit_summary(saved_files: List[str], created_pdd_dir: bool, sample_pr
|
|
|
428
547
|
"",
|
|
429
548
|
f"{BULLET} As you get comfortable, learn configuration settings, including the .pddrc file, PDD_GENERATE_OUTPUT_PATH, and PDD_TEST_OUTPUT_PATH",
|
|
430
549
|
f"{BULLET} For larger projects, use Makefiles and/or 'pdd sync'",
|
|
431
|
-
f"{BULLET} For ongoing substantial projects, learn about llm_model.csv
|
|
550
|
+
f"{BULLET} For ongoing substantial projects, learn about llm_model.csv and the --strength,",
|
|
551
|
+
f" --temperature, and --time options to optimize model cost, latency, and output quality",
|
|
432
552
|
"",
|
|
433
553
|
f"{BULLET} Use 'pdd --help' to explore all available commands",
|
|
434
554
|
"",
|
|
@@ -478,12 +598,12 @@ def main():
|
|
|
478
598
|
print_colored(f"{create_divider()}", CYAN)
|
|
479
599
|
|
|
480
600
|
try:
|
|
481
|
-
saved_files, created_pdd_dir = save_configuration(valid_keys)
|
|
601
|
+
saved_files, created_pdd_dir, init_file_updated = save_configuration(valid_keys)
|
|
482
602
|
sample_prompt_file = create_sample_prompt()
|
|
483
603
|
shell = detect_shell()
|
|
484
604
|
|
|
485
605
|
# Create and display summary
|
|
486
|
-
summary = create_exit_summary(saved_files, created_pdd_dir, sample_prompt_file, shell)
|
|
606
|
+
summary = create_exit_summary(saved_files, created_pdd_dir, sample_prompt_file, shell, valid_keys, init_file_updated)
|
|
487
607
|
|
|
488
608
|
# Write summary to file
|
|
489
609
|
summary_file = Path('PDD-SETUP-SUMMARY.txt')
|
|
@@ -498,7 +618,11 @@ def main():
|
|
|
498
618
|
print_colored(line, YELLOW, bold=True)
|
|
499
619
|
elif line == create_divider():
|
|
500
620
|
print_colored(line, CYAN)
|
|
501
|
-
elif line.startswith("
|
|
621
|
+
elif line.startswith("API Keys Configured:") or line.startswith("Files created and configured:"):
|
|
622
|
+
print_colored(line, CYAN, bold=True)
|
|
623
|
+
elif line.startswith("QUICK START:"):
|
|
624
|
+
print_colored(line, YELLOW, bold=True)
|
|
625
|
+
elif line.startswith("LEARN MORE:") or line.startswith("TIPS:"):
|
|
502
626
|
print_colored(line, CYAN, bold=True)
|
|
503
627
|
elif "IMPORTANT:" in line or "Problems?" in line:
|
|
504
628
|
print_colored(line, YELLOW, bold=True)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pdd-cli
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.60
|
|
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.
|
|
56
|
+
.. image:: https://img.shields.io/badge/pdd--cli-v0.0.60-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.
|
|
133
|
+
You'll see the current PDD version (e.g., 0.0.60).
|
|
132
134
|
|
|
133
135
|
Getting Started with Examples
|
|
134
136
|
-----------------------------
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
pdd/__init__.py,sha256=
|
|
1
|
+
pdd/__init__.py,sha256=DkLNT664TDBz1q2bKJ1z7tY7zRdVTF6dTex1j5DokZU,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=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
|
|
@@ -45,9 +45,9 @@ pdd/llm_invoke.py,sha256=US8J9oZZdVgLIjcmOI-YyHu6z2un43ZN811IcQBmAIA,96728
|
|
|
45
45
|
pdd/load_prompt_template.py,sha256=stt42Og0PzXy0N_bsaivk5e2l5z_BnHiXIJZM14oVWw,2673
|
|
46
46
|
pdd/logo_animation.py,sha256=n6HJWzuFze2csAAW2-zbxfjvWFYRI4hIdwVBtHBOkj4,20782
|
|
47
47
|
pdd/mcp_config.json,sha256=D3ctWHlShvltbtH37zbYb6smVE0V80_lGjDKDIqsSBE,124
|
|
48
|
-
pdd/pdd_completion.fish,sha256=
|
|
49
|
-
pdd/pdd_completion.sh,sha256=
|
|
50
|
-
pdd/pdd_completion.zsh,sha256=
|
|
48
|
+
pdd/pdd_completion.fish,sha256=pfEyBWzFp3matC_SW2BTDNaBJybYKUEi3YpPE-D6AKU,13776
|
|
49
|
+
pdd/pdd_completion.sh,sha256=xgx-g6aeCCrlh6loeLyJN5jCsX15YXrWyT1U499p3C0,6490
|
|
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
53
|
pdd/preprocess.py,sha256=75-J1smdi1Uq7gRQRLtVdkIfwltkeIvIZE-TkxxxCz0,12326
|
|
@@ -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=h3MW7yr5tSlreq3u26aUfQqFTneQ-wNCoq0vwIYxqMY,24087
|
|
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,10 +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.
|
|
114
|
-
pdd_cli-0.0.
|
|
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.58.dist-info/RECORD,,
|
|
114
|
+
pdd_cli-0.0.60.dist-info/licenses/LICENSE,sha256=kvTJnnxPVTYlGKSY4ZN1kzdmJ0lxRdNWxgupaB27zsU,1066
|
|
115
|
+
pdd_cli-0.0.60.dist-info/METADATA,sha256=4vSMytmX5LPnADjAlOVkZPCSf--g5FWbATtu9zo7Qqs,12687
|
|
116
|
+
pdd_cli-0.0.60.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
117
|
+
pdd_cli-0.0.60.dist-info/entry_points.txt,sha256=Kr8HtNVb8uHZtQJNH4DnF8j7WNgWQbb7_Pw5hECSR-I,36
|
|
118
|
+
pdd_cli-0.0.60.dist-info/top_level.txt,sha256=xjnhIACeMcMeDfVNREgQZl4EbTni2T11QkL5r7E-sbE,4
|
|
119
|
+
pdd_cli-0.0.60.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|