pdd-cli 0.0.90__py3-none-any.whl → 0.0.121__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.
- pdd/__init__.py +38 -6
- pdd/agentic_bug.py +323 -0
- pdd/agentic_bug_orchestrator.py +506 -0
- pdd/agentic_change.py +231 -0
- pdd/agentic_change_orchestrator.py +537 -0
- pdd/agentic_common.py +533 -770
- pdd/agentic_crash.py +2 -1
- pdd/agentic_e2e_fix.py +319 -0
- pdd/agentic_e2e_fix_orchestrator.py +582 -0
- pdd/agentic_fix.py +118 -3
- pdd/agentic_update.py +27 -9
- pdd/agentic_verify.py +3 -2
- pdd/architecture_sync.py +565 -0
- pdd/auth_service.py +210 -0
- pdd/auto_deps_main.py +63 -53
- pdd/auto_include.py +236 -3
- pdd/auto_update.py +125 -47
- pdd/bug_main.py +195 -23
- pdd/cmd_test_main.py +345 -197
- pdd/code_generator.py +4 -2
- pdd/code_generator_main.py +118 -32
- pdd/commands/__init__.py +6 -0
- pdd/commands/analysis.py +113 -48
- pdd/commands/auth.py +309 -0
- pdd/commands/connect.py +358 -0
- pdd/commands/fix.py +155 -114
- pdd/commands/generate.py +5 -0
- pdd/commands/maintenance.py +3 -2
- pdd/commands/misc.py +8 -0
- pdd/commands/modify.py +225 -163
- pdd/commands/sessions.py +284 -0
- pdd/commands/utility.py +12 -7
- pdd/construct_paths.py +334 -32
- pdd/context_generator_main.py +167 -170
- pdd/continue_generation.py +6 -3
- pdd/core/__init__.py +33 -0
- pdd/core/cli.py +44 -7
- pdd/core/cloud.py +237 -0
- pdd/core/dump.py +68 -20
- pdd/core/errors.py +4 -0
- pdd/core/remote_session.py +61 -0
- pdd/crash_main.py +219 -23
- pdd/data/llm_model.csv +4 -4
- pdd/docs/prompting_guide.md +864 -0
- pdd/docs/whitepaper_with_benchmarks/data_and_functions/benchmark_analysis.py +495 -0
- pdd/docs/whitepaper_with_benchmarks/data_and_functions/creation_compare.py +528 -0
- pdd/fix_code_loop.py +208 -34
- pdd/fix_code_module_errors.py +6 -2
- pdd/fix_error_loop.py +291 -38
- pdd/fix_main.py +208 -6
- pdd/fix_verification_errors_loop.py +235 -26
- pdd/fix_verification_main.py +269 -83
- pdd/frontend/dist/assets/index-B5DZHykP.css +1 -0
- pdd/frontend/dist/assets/index-CUWd8al1.js +450 -0
- pdd/frontend/dist/index.html +376 -0
- pdd/frontend/dist/logo.svg +33 -0
- pdd/generate_output_paths.py +46 -5
- pdd/generate_test.py +212 -151
- pdd/get_comment.py +19 -44
- pdd/get_extension.py +8 -9
- pdd/get_jwt_token.py +309 -20
- pdd/get_language.py +8 -7
- pdd/get_run_command.py +7 -5
- pdd/insert_includes.py +2 -1
- pdd/llm_invoke.py +531 -97
- pdd/load_prompt_template.py +15 -34
- pdd/operation_log.py +342 -0
- pdd/path_resolution.py +140 -0
- pdd/postprocess.py +122 -97
- pdd/preprocess.py +68 -12
- pdd/preprocess_main.py +33 -1
- pdd/prompts/agentic_bug_step10_pr_LLM.prompt +182 -0
- pdd/prompts/agentic_bug_step1_duplicate_LLM.prompt +73 -0
- pdd/prompts/agentic_bug_step2_docs_LLM.prompt +129 -0
- pdd/prompts/agentic_bug_step3_triage_LLM.prompt +95 -0
- pdd/prompts/agentic_bug_step4_reproduce_LLM.prompt +97 -0
- pdd/prompts/agentic_bug_step5_root_cause_LLM.prompt +123 -0
- pdd/prompts/agentic_bug_step6_test_plan_LLM.prompt +107 -0
- pdd/prompts/agentic_bug_step7_generate_LLM.prompt +172 -0
- pdd/prompts/agentic_bug_step8_verify_LLM.prompt +119 -0
- pdd/prompts/agentic_bug_step9_e2e_test_LLM.prompt +289 -0
- pdd/prompts/agentic_change_step10_identify_issues_LLM.prompt +1006 -0
- pdd/prompts/agentic_change_step11_fix_issues_LLM.prompt +984 -0
- pdd/prompts/agentic_change_step12_create_pr_LLM.prompt +140 -0
- pdd/prompts/agentic_change_step1_duplicate_LLM.prompt +73 -0
- pdd/prompts/agentic_change_step2_docs_LLM.prompt +101 -0
- pdd/prompts/agentic_change_step3_research_LLM.prompt +126 -0
- pdd/prompts/agentic_change_step4_clarify_LLM.prompt +164 -0
- pdd/prompts/agentic_change_step5_docs_change_LLM.prompt +981 -0
- pdd/prompts/agentic_change_step6_devunits_LLM.prompt +1005 -0
- pdd/prompts/agentic_change_step7_architecture_LLM.prompt +1044 -0
- pdd/prompts/agentic_change_step8_analyze_LLM.prompt +1027 -0
- pdd/prompts/agentic_change_step9_implement_LLM.prompt +1077 -0
- pdd/prompts/agentic_e2e_fix_step1_unit_tests_LLM.prompt +90 -0
- pdd/prompts/agentic_e2e_fix_step2_e2e_tests_LLM.prompt +91 -0
- pdd/prompts/agentic_e2e_fix_step3_root_cause_LLM.prompt +89 -0
- pdd/prompts/agentic_e2e_fix_step4_fix_e2e_tests_LLM.prompt +96 -0
- pdd/prompts/agentic_e2e_fix_step5_identify_devunits_LLM.prompt +91 -0
- pdd/prompts/agentic_e2e_fix_step6_create_unit_tests_LLM.prompt +106 -0
- pdd/prompts/agentic_e2e_fix_step7_verify_tests_LLM.prompt +116 -0
- pdd/prompts/agentic_e2e_fix_step8_run_pdd_fix_LLM.prompt +120 -0
- pdd/prompts/agentic_e2e_fix_step9_verify_all_LLM.prompt +146 -0
- pdd/prompts/agentic_fix_primary_LLM.prompt +2 -2
- pdd/prompts/agentic_update_LLM.prompt +192 -338
- pdd/prompts/auto_include_LLM.prompt +22 -0
- pdd/prompts/change_LLM.prompt +3093 -1
- pdd/prompts/detect_change_LLM.prompt +571 -14
- pdd/prompts/fix_code_module_errors_LLM.prompt +8 -0
- pdd/prompts/fix_errors_from_unit_tests_LLM.prompt +1 -0
- pdd/prompts/generate_test_LLM.prompt +19 -1
- pdd/prompts/generate_test_from_example_LLM.prompt +366 -0
- pdd/prompts/insert_includes_LLM.prompt +262 -252
- pdd/prompts/prompt_code_diff_LLM.prompt +123 -0
- pdd/prompts/prompt_diff_LLM.prompt +82 -0
- pdd/remote_session.py +876 -0
- pdd/server/__init__.py +52 -0
- pdd/server/app.py +335 -0
- pdd/server/click_executor.py +587 -0
- pdd/server/executor.py +338 -0
- pdd/server/jobs.py +661 -0
- pdd/server/models.py +241 -0
- pdd/server/routes/__init__.py +31 -0
- pdd/server/routes/architecture.py +451 -0
- pdd/server/routes/auth.py +364 -0
- pdd/server/routes/commands.py +929 -0
- pdd/server/routes/config.py +42 -0
- pdd/server/routes/files.py +603 -0
- pdd/server/routes/prompts.py +1347 -0
- pdd/server/routes/websocket.py +473 -0
- pdd/server/security.py +243 -0
- pdd/server/terminal_spawner.py +217 -0
- pdd/server/token_counter.py +222 -0
- pdd/summarize_directory.py +236 -237
- pdd/sync_animation.py +8 -4
- pdd/sync_determine_operation.py +329 -47
- pdd/sync_main.py +272 -28
- pdd/sync_orchestration.py +289 -211
- pdd/sync_order.py +304 -0
- pdd/template_expander.py +161 -0
- pdd/templates/architecture/architecture_json.prompt +41 -46
- pdd/trace.py +1 -1
- pdd/track_cost.py +0 -13
- pdd/unfinished_prompt.py +2 -1
- pdd/update_main.py +68 -26
- {pdd_cli-0.0.90.dist-info → pdd_cli-0.0.121.dist-info}/METADATA +15 -10
- pdd_cli-0.0.121.dist-info/RECORD +229 -0
- pdd_cli-0.0.90.dist-info/RECORD +0 -153
- {pdd_cli-0.0.90.dist-info → pdd_cli-0.0.121.dist-info}/WHEEL +0 -0
- {pdd_cli-0.0.90.dist-info → pdd_cli-0.0.121.dist-info}/entry_points.txt +0 -0
- {pdd_cli-0.0.90.dist-info → pdd_cli-0.0.121.dist-info}/licenses/LICENSE +0 -0
- {pdd_cli-0.0.90.dist-info → pdd_cli-0.0.121.dist-info}/top_level.txt +0 -0
pdd/commands/fix.py
CHANGED
|
@@ -1,82 +1,49 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
4
5
|
import click
|
|
5
|
-
from typing import
|
|
6
|
+
from typing import Optional, Tuple, Any
|
|
7
|
+
from rich.console import Console
|
|
6
8
|
|
|
9
|
+
# Relative imports for internal modules
|
|
7
10
|
from ..fix_main import fix_main
|
|
11
|
+
from ..agentic_e2e_fix import run_agentic_e2e_fix
|
|
8
12
|
from ..track_cost import track_cost
|
|
13
|
+
from ..operation_log import log_operation
|
|
9
14
|
from ..core.errors import handle_error
|
|
10
15
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
@click.
|
|
14
|
-
@click.argument("
|
|
15
|
-
@click.
|
|
16
|
-
@click.option(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
)
|
|
22
|
-
@click.option(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
)
|
|
28
|
-
@click.option(
|
|
29
|
-
|
|
30
|
-
type=click.Path(writable=True),
|
|
31
|
-
default=None,
|
|
32
|
-
help="Specify where to save the results log (file or directory).",
|
|
33
|
-
)
|
|
34
|
-
@click.option(
|
|
35
|
-
"--loop",
|
|
36
|
-
is_flag=True,
|
|
37
|
-
default=False,
|
|
38
|
-
help="Enable iterative fixing process."
|
|
39
|
-
)
|
|
40
|
-
@click.option(
|
|
41
|
-
"--verification-program",
|
|
42
|
-
type=click.Path(exists=True, dir_okay=False),
|
|
43
|
-
default=None,
|
|
44
|
-
help="Path to a Python program that verifies the fix.",
|
|
45
|
-
)
|
|
46
|
-
@click.option(
|
|
47
|
-
"--max-attempts",
|
|
48
|
-
type=int,
|
|
49
|
-
default=3,
|
|
50
|
-
show_default=True,
|
|
51
|
-
help="Maximum number of fix attempts.",
|
|
52
|
-
)
|
|
53
|
-
@click.option(
|
|
54
|
-
"--budget",
|
|
55
|
-
type=float,
|
|
56
|
-
default=5.0,
|
|
57
|
-
show_default=True,
|
|
58
|
-
help="Maximum cost allowed for the fixing process.",
|
|
59
|
-
)
|
|
60
|
-
@click.option(
|
|
61
|
-
"--auto-submit",
|
|
62
|
-
is_flag=True,
|
|
63
|
-
default=False,
|
|
64
|
-
help="Automatically submit the example if all unit tests pass.",
|
|
65
|
-
)
|
|
66
|
-
@click.option(
|
|
67
|
-
"--agentic-fallback/--no-agentic-fallback",
|
|
68
|
-
is_flag=True,
|
|
69
|
-
default=True,
|
|
70
|
-
help="Enable agentic fallback if the primary fix mechanism fails.",
|
|
71
|
-
)
|
|
16
|
+
console = Console()
|
|
17
|
+
|
|
18
|
+
@click.command(name="fix")
|
|
19
|
+
@click.argument("args", nargs=-1)
|
|
20
|
+
@click.option("--manual", is_flag=True, help="Use manual mode with explicit file arguments.")
|
|
21
|
+
@click.option("--timeout-adder", type=float, default=0.0, help="Additional seconds to add to each step's timeout (Agentic mode).")
|
|
22
|
+
@click.option("--max-cycles", type=int, default=5, help="Maximum number of outer loop cycles (Agentic mode).")
|
|
23
|
+
@click.option("--resume/--no-resume", default=True, help="Resume from saved state if available (Agentic mode).")
|
|
24
|
+
@click.option("--force", is_flag=True, help="Override branch mismatch safety check (Agentic mode).")
|
|
25
|
+
@click.option("--no-github-state", is_flag=True, help="Disable GitHub issue comment-based state persistence (Agentic mode).")
|
|
26
|
+
@click.option("--output-test", type=click.Path(), help="Specify where to save the fixed unit test file.")
|
|
27
|
+
@click.option("--output-code", type=click.Path(), help="Specify where to save the fixed code file.")
|
|
28
|
+
@click.option("--output-results", type=click.Path(), help="Specify where to save the results log.")
|
|
29
|
+
@click.option("--loop", is_flag=True, help="Enable iterative fixing process.")
|
|
30
|
+
@click.option("--verification-program", type=click.Path(), help="Path to verification program (required for --loop).")
|
|
31
|
+
@click.option("--max-attempts", type=int, default=3, help="Maximum number of fix attempts.")
|
|
32
|
+
@click.option("--budget", type=float, default=5.0, help="Maximum cost allowed for the fixing process.")
|
|
33
|
+
@click.option("--auto-submit", is_flag=True, help="Automatically submit example if tests pass.")
|
|
34
|
+
@click.option("--agentic-fallback/--no-agentic-fallback", default=True, help="Enable agentic fallback in loop mode.")
|
|
72
35
|
@click.pass_context
|
|
36
|
+
@log_operation(operation="fix", clears_run_report=True)
|
|
73
37
|
@track_cost
|
|
74
38
|
def fix(
|
|
75
39
|
ctx: click.Context,
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
40
|
+
args: Tuple[str, ...],
|
|
41
|
+
manual: bool,
|
|
42
|
+
timeout_adder: float,
|
|
43
|
+
max_cycles: int,
|
|
44
|
+
resume: bool,
|
|
45
|
+
force: bool,
|
|
46
|
+
no_github_state: bool,
|
|
80
47
|
output_test: Optional[str],
|
|
81
48
|
output_code: Optional[str],
|
|
82
49
|
output_results: Optional[str],
|
|
@@ -86,55 +53,129 @@ def fix(
|
|
|
86
53
|
budget: float,
|
|
87
54
|
auto_submit: bool,
|
|
88
55
|
agentic_fallback: bool,
|
|
89
|
-
) -> Optional[Tuple[
|
|
90
|
-
"""
|
|
56
|
+
) -> Optional[Tuple[Any, float, str]]:
|
|
57
|
+
"""
|
|
58
|
+
Fix errors in code and unit tests.
|
|
91
59
|
|
|
92
|
-
|
|
93
|
-
|
|
60
|
+
Supports two modes:
|
|
61
|
+
1. Agentic E2E Fix: pdd fix <GITHUB_ISSUE_URL>
|
|
62
|
+
2. Manual Mode: pdd fix --manual PROMPT_FILE CODE_FILE UNIT_TEST_FILE... ERROR_FILE
|
|
94
63
|
"""
|
|
95
64
|
try:
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
model_name = ""
|
|
65
|
+
if not args:
|
|
66
|
+
raise click.UsageError("Missing arguments. See 'pdd fix --help'.")
|
|
99
67
|
|
|
100
|
-
#
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
68
|
+
# Determine mode based on first argument
|
|
69
|
+
# If it looks like a URL and --manual is not set, use Agentic mode
|
|
70
|
+
is_url = args[0].startswith("http") or "github.com" in args[0]
|
|
71
|
+
|
|
72
|
+
# --- Agentic E2E Fix Mode ---
|
|
73
|
+
if is_url and not manual:
|
|
74
|
+
if len(args) > 1:
|
|
75
|
+
console.print("[yellow]Warning: Extra arguments ignored in Agentic E2E Fix mode.[/yellow]")
|
|
76
|
+
|
|
77
|
+
issue_url = args[0]
|
|
78
|
+
verbose = ctx.obj.get("verbose", False) if ctx.obj else False
|
|
79
|
+
quiet = ctx.obj.get("quiet", False) if ctx.obj else False
|
|
80
|
+
|
|
81
|
+
# Call the agentic fix workflow
|
|
82
|
+
success, message, cost, model, _ = run_agentic_e2e_fix(
|
|
83
|
+
issue_url=issue_url,
|
|
84
|
+
timeout_adder=timeout_adder,
|
|
85
|
+
max_cycles=max_cycles,
|
|
86
|
+
resume=resume,
|
|
87
|
+
force=force,
|
|
88
|
+
verbose=verbose,
|
|
89
|
+
quiet=quiet,
|
|
90
|
+
use_github_state=not no_github_state
|
|
117
91
|
)
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
"
|
|
121
|
-
|
|
122
|
-
"
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
92
|
+
|
|
93
|
+
if not success:
|
|
94
|
+
console.print(f"[bold red]Agentic fix failed:[/bold red] {message}")
|
|
95
|
+
else:
|
|
96
|
+
console.print(f"[bold green]Agentic fix completed:[/bold green] {message}")
|
|
97
|
+
|
|
98
|
+
return message, cost, model
|
|
99
|
+
|
|
100
|
+
# --- Manual Mode ---
|
|
101
|
+
else:
|
|
102
|
+
# Validate arguments for manual mode
|
|
103
|
+
# Expected structure:
|
|
104
|
+
# - Loop mode: PROMPT_FILE CODE_FILE UNIT_TEST_FILE [UNIT_TEST_FILE...]
|
|
105
|
+
# - Non-loop mode: PROMPT_FILE CODE_FILE UNIT_TEST_FILE [UNIT_TEST_FILE...] ERROR_FILE
|
|
106
|
+
min_args = 3 if loop else 4
|
|
107
|
+
if len(args) < min_args:
|
|
108
|
+
if loop:
|
|
109
|
+
raise click.UsageError(
|
|
110
|
+
"Loop mode requires at least 3 arguments: PROMPT_FILE CODE_FILE UNIT_TEST_FILE..."
|
|
111
|
+
)
|
|
112
|
+
else:
|
|
113
|
+
raise click.UsageError(
|
|
114
|
+
"Non-loop mode requires at least 4 arguments: PROMPT_FILE CODE_FILE UNIT_TEST_FILE... ERROR_FILE"
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
prompt_file = args[0]
|
|
118
|
+
code_file = args[1]
|
|
119
|
+
|
|
120
|
+
# In loop mode, error_file is optional (generated during loop)
|
|
121
|
+
# In non-loop mode, last argument is the error_file
|
|
122
|
+
if loop:
|
|
123
|
+
error_file = None
|
|
124
|
+
unit_test_files = args[2:] # All remaining args are test files
|
|
125
|
+
else:
|
|
126
|
+
error_file = args[-1]
|
|
127
|
+
unit_test_files = args[2:-1] # All args between code file and error file
|
|
128
|
+
|
|
129
|
+
total_cost = 0.0
|
|
130
|
+
last_model = "unknown"
|
|
131
|
+
all_success = True
|
|
132
|
+
results_summary = []
|
|
133
|
+
|
|
134
|
+
# Process each unit test file
|
|
135
|
+
for i, test_file in enumerate(unit_test_files):
|
|
136
|
+
if len(unit_test_files) > 1:
|
|
137
|
+
console.print(f"[bold blue]Processing test file {i+1}/{len(unit_test_files)}: {test_file}[/bold blue]")
|
|
138
|
+
|
|
139
|
+
# Call the core fix logic
|
|
140
|
+
# Note: If multiple test files are processed, output_test will overwrite
|
|
141
|
+
# the same location if specified, as per documentation warning.
|
|
142
|
+
success, _, _, _, cost, model = fix_main(
|
|
143
|
+
ctx=ctx,
|
|
144
|
+
prompt_file=prompt_file,
|
|
145
|
+
code_file=code_file,
|
|
146
|
+
unit_test_file=test_file,
|
|
147
|
+
error_file=error_file,
|
|
148
|
+
output_test=output_test,
|
|
149
|
+
output_code=output_code,
|
|
150
|
+
output_results=output_results,
|
|
151
|
+
loop=loop,
|
|
152
|
+
verification_program=verification_program,
|
|
153
|
+
max_attempts=max_attempts,
|
|
154
|
+
budget=budget,
|
|
155
|
+
auto_submit=auto_submit,
|
|
156
|
+
agentic_fallback=agentic_fallback,
|
|
157
|
+
strength=None, # Use context defaults inside fix_main
|
|
158
|
+
temperature=None # Use context defaults inside fix_main
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
total_cost += cost
|
|
162
|
+
last_model = model
|
|
163
|
+
if not success:
|
|
164
|
+
all_success = False
|
|
165
|
+
|
|
166
|
+
status = "Fixed" if success else "Failed"
|
|
167
|
+
results_summary.append(f"{test_file}: {status}")
|
|
168
|
+
|
|
169
|
+
# Construct return message
|
|
170
|
+
summary_str = "\n".join(results_summary)
|
|
171
|
+
if all_success:
|
|
172
|
+
return f"All files processed successfully.\n{summary_str}", total_cost, last_model
|
|
173
|
+
else:
|
|
174
|
+
return f"Some files failed to fix.\n{summary_str}", total_cost, last_model
|
|
127
175
|
|
|
128
|
-
|
|
129
|
-
overall_success = all(r["success"] for r in all_results)
|
|
130
|
-
result = {
|
|
131
|
-
"success": overall_success,
|
|
132
|
-
"results": all_results,
|
|
133
|
-
"total_attempts": sum(r["attempts"] for r in all_results),
|
|
134
|
-
}
|
|
135
|
-
return result, total_cost, model_name
|
|
136
|
-
except click.Abort:
|
|
176
|
+
except (click.Abort, click.UsageError, click.BadArgumentUsage, click.FileError, click.BadParameter):
|
|
137
177
|
raise
|
|
138
|
-
except Exception as
|
|
139
|
-
|
|
140
|
-
|
|
178
|
+
except Exception as e:
|
|
179
|
+
quiet = ctx.obj.get("quiet", False) if ctx.obj else False
|
|
180
|
+
handle_error(e, "fix", quiet)
|
|
181
|
+
sys.exit(1)
|
pdd/commands/generate.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Generate, test, and example commands.
|
|
3
3
|
"""
|
|
4
|
+
from __future__ import annotations
|
|
4
5
|
import click
|
|
5
6
|
from typing import Dict, Optional, Tuple, List
|
|
6
7
|
|
|
@@ -9,6 +10,7 @@ from ..context_generator_main import context_generator_main
|
|
|
9
10
|
from ..cmd_test_main import cmd_test_main
|
|
10
11
|
from ..track_cost import track_cost
|
|
11
12
|
from ..core.errors import handle_error, console
|
|
13
|
+
from ..operation_log import log_operation
|
|
12
14
|
|
|
13
15
|
class GenerateCommand(click.Command):
|
|
14
16
|
"""Ensure help shows PROMPT_FILE as required even when validated at runtime."""
|
|
@@ -69,6 +71,7 @@ class GenerateCommand(click.Command):
|
|
|
69
71
|
help="Do not automatically include test files found in the default tests directory.",
|
|
70
72
|
)
|
|
71
73
|
@click.pass_context
|
|
74
|
+
@log_operation("generate", clears_run_report=True, updates_fingerprint=True)
|
|
72
75
|
@track_cost
|
|
73
76
|
def generate(
|
|
74
77
|
ctx: click.Context,
|
|
@@ -159,6 +162,7 @@ def generate(
|
|
|
159
162
|
help="Specify where to save the generated example code (file or directory).",
|
|
160
163
|
)
|
|
161
164
|
@click.pass_context
|
|
165
|
+
@log_operation("example", updates_fingerprint=True)
|
|
162
166
|
@track_cost
|
|
163
167
|
def example(
|
|
164
168
|
ctx: click.Context,
|
|
@@ -222,6 +226,7 @@ def example(
|
|
|
222
226
|
help="Merge new tests with existing test file instead of creating a separate file.",
|
|
223
227
|
)
|
|
224
228
|
@click.pass_context
|
|
229
|
+
@log_operation("test", updates_run_report=True)
|
|
225
230
|
@track_cost
|
|
226
231
|
def test(
|
|
227
232
|
ctx: click.Context,
|
pdd/commands/maintenance.py
CHANGED
|
@@ -39,8 +39,9 @@ from ..core.utils import _run_setup_utility
|
|
|
39
39
|
)
|
|
40
40
|
@click.option(
|
|
41
41
|
"--target-coverage",
|
|
42
|
+
type=float,
|
|
42
43
|
default=None,
|
|
43
|
-
help="Desired code coverage percentage. Default:
|
|
44
|
+
help="Desired code coverage percentage. Default: 90.0 or .pddrc value.",
|
|
44
45
|
)
|
|
45
46
|
@click.option(
|
|
46
47
|
"--dry-run",
|
|
@@ -64,7 +65,7 @@ def sync(
|
|
|
64
65
|
budget: Optional[float],
|
|
65
66
|
skip_verify: bool,
|
|
66
67
|
skip_tests: bool,
|
|
67
|
-
target_coverage: float,
|
|
68
|
+
target_coverage: Optional[float],
|
|
68
69
|
dry_run: bool,
|
|
69
70
|
log: bool,
|
|
70
71
|
) -> Optional[Tuple[str, float, str]]:
|
pdd/commands/misc.py
CHANGED
|
@@ -39,6 +39,12 @@ from ..core.errors import handle_error
|
|
|
39
39
|
default=None,
|
|
40
40
|
help="List of keys to exclude from curly bracket doubling.",
|
|
41
41
|
)
|
|
42
|
+
@click.option(
|
|
43
|
+
"--pdd-tags",
|
|
44
|
+
is_flag=True,
|
|
45
|
+
default=False,
|
|
46
|
+
help="Inject PDD metadata tags (<pdd-reason>, <pdd-interface>, <pdd-dependency>) from architecture.json.",
|
|
47
|
+
)
|
|
42
48
|
@click.pass_context
|
|
43
49
|
# No @track_cost as preprocessing is local, but return dummy tuple for callback
|
|
44
50
|
def preprocess(
|
|
@@ -49,6 +55,7 @@ def preprocess(
|
|
|
49
55
|
recursive: bool,
|
|
50
56
|
double: bool,
|
|
51
57
|
exclude: Optional[Tuple[str, ...]],
|
|
58
|
+
pdd_tags: bool,
|
|
52
59
|
) -> Optional[Tuple[str, float, str]]:
|
|
53
60
|
"""Preprocess a prompt file to prepare it for LLM use."""
|
|
54
61
|
try:
|
|
@@ -62,6 +69,7 @@ def preprocess(
|
|
|
62
69
|
recursive=recursive,
|
|
63
70
|
double=double,
|
|
64
71
|
exclude=list(exclude) if exclude else [],
|
|
72
|
+
pdd_tags=pdd_tags,
|
|
65
73
|
)
|
|
66
74
|
|
|
67
75
|
# Handle the result from preprocess_main
|