Skip to content

Commit 53871f9

Browse files
committed
Bump version
1 parent 8dc6193 commit 53871f9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+4497
-219
lines changed

.pddrc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,12 @@ contexts:
104104
pdd_cli:
105105
paths: ["pdd/**", "*.py", "prompts/**", "tests/**"]
106106
defaults:
107-
generate_output_path: "pdd/"
108-
test_output_path: "tests/"
109-
example_output_path: "context/"
107+
generate_output_path: "pdd"
108+
test_output_path: "tests"
109+
example_output_path: "context"
110110
default_language: "python"
111111
target_coverage: 80.0
112112
strength: 1
113113
temperature: 0.0
114114
budget: 10.0
115-
max_attempts: 3
115+
max_attempts: 3

CHANGELOG.md

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,44 @@
1+
## v0.0.101 (2026-01-03)
2+
3+
### Feat
4+
5+
- Enhance agentic bug investigation prompts and regression testing
6+
- Enhance agentic bug investigation workflow and testing
7+
- Implement agentic bug investigation workflow with orchestrator
8+
- Add agentic bug workflow with 8-step GitHub issue investigation (#153)
9+
- add ONBOARDING.md to sync patterns
10+
- Introduce sync configuration for bidirectional repository synchronization
11+
- Enhance cloud execution support for `pdd crash` and `pdd verify` commands
12+
13+
### Fix
14+
15+
- Improve error handling in analysis commands
16+
- Refactor output handling in analysis_example.py
17+
- Enhance analysis command examples and output handling
18+
- Update analysis prompts to include function namespaces
19+
- escape tag examples in preprocess_python.prompt (from pdd_cap PR #11)
20+
- remove root ONBOARDING.md from sync (use docs/*.md instead)
21+
- update Firecrawl API for 4.0+ compatibility
22+
- use git config for CAP_REPO_TOKEN auth
23+
124
## v0.0.100 (2026-01-02)
225

326
### Feat
427

5-
- Add cloud execution support for pdd crash and pdd verify commands
28+
- **Cloud Execution for `pdd crash` and `pdd verify` Commands (PR #218):** Added cloud-first execution with automatic local fallback for both commands. Uses JWT authentication via `CloudConfig.get_jwt_token()` and posts to the `crashCode` and `verifyCode` endpoints. Supports hybrid mode for loop iterations—local program execution with cloud LLM calls. Set `PDD_CLOUD_ONLY=1` or `PDD_NO_LOCAL_FALLBACK=1` to disable fallback. Non-recoverable errors (401/402/403/400) raise `UsageError`; recoverable errors (5xx, timeouts) fall back to local.
29+
30+
### Docs
31+
32+
- Updated `crash_main_python.prompt` and `fix_verification_main_python.prompt` with cloud execution strategy documentation.
33+
34+
### Tests
35+
36+
- Added 374+ lines of tests in `test_crash_main.py` covering cloud success paths, fallback scenarios, and hybrid loop mode.
37+
- Added 221+ lines of tests in `test_fix_main.py` for cloud execution coverage.
638

739
### Fix
840

9-
- Address valid Copilot suggestions - fix patch target and remove outdated comment
41+
- Fixed patch target in test mocking and removed outdated comment.
1042

1143
## v0.0.99 (2026-01-01)
1244

Makefile

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,11 @@ PUBLIC_PDD_REMOTE ?= https://github.com/promptdriven/pdd.git
6464
# CAP public repo (optional second destination)
6565
PUBLIC_PDD_CAP_REPO_DIR ?= staging/public/pdd_cap
6666
PUBLIC_PDD_CAP_REMOTE ?= https://github.com/promptdriven/pdd_cap.git
67-
# Top-level files to publish if present
68-
PUBLIC_ROOT_FILES ?= LICENSE CHANGELOG.md CONTRIBUTING.md requirements.txt pyproject.toml .env.example README.md .gitignore SETUP_WITH_GEMINI.md Makefile pdd-local.sh .pddrc
67+
# Top-level files to publish if present (read from .sync-config.yml)
68+
PUBLIC_ROOT_FILES ?= $(shell python scripts/get_sync_patterns.py root_files 2>/dev/null || echo "LICENSE README.md requirements.txt pyproject.toml")
6969
# Include core unit tests by default
7070
PUBLIC_COPY_TESTS ?= 1
71-
PUBLIC_TEST_INCLUDE ?= tests/test_*.py tests/__init__.py tests/conftest.py
71+
PUBLIC_TEST_INCLUDE ?= $(shell python scripts/get_sync_patterns.py test_patterns 2>/dev/null || echo "tests/test_*.py tests/__init__.py tests/conftest.py")
7272
PUBLIC_TEST_EXCLUDE ?= tests/regression* tests/sync_regression* tests/**/regression* tests/**/sync_regression* tests/**/*.ipynb tests/csv/**
7373
PUBLIC_COPY_CONTEXT ?= 1
7474
PUBLIC_CONTEXT_INCLUDE ?= context/**/*_example.py
@@ -846,6 +846,9 @@ publish-public-cap:
846846
@echo "Copying VS Code extension to CAP public repo"
847847
@mkdir -p $(PUBLIC_PDD_CAP_REPO_DIR)/utils
848848
@cp -r ./utils/vscode_prompt $(PUBLIC_PDD_CAP_REPO_DIR)/utils/
849+
@echo "Copying python preamble to CAP public repo"
850+
@mkdir -p $(PUBLIC_PDD_CAP_REPO_DIR)/context
851+
@cp context/python_preamble.prompt $(PUBLIC_PDD_CAP_REPO_DIR)/context/
849852
@echo "Copying selected top-level files to CAP public repo (if present): $(PUBLIC_ROOT_FILES)"
850853
@set -e; for f in $(PUBLIC_ROOT_FILES); do \
851854
if [ -f "$$f" ]; then \

README.md

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# PDD (Prompt-Driven Development) Command Line Interface
22

3-
![PDD-CLI Version](https://img.shields.io/badge/pdd--cli-v0.0.100-blue) [![Discord](https://img.shields.io/badge/Discord-join%20chat-7289DA.svg?logo=discord&logoColor=white)](https://discord.gg/Yp4RTh8bG7)
3+
![PDD-CLI Version](https://img.shields.io/badge/pdd--cli-v0.0.101-blue) [![Discord](https://img.shields.io/badge/Discord-join%20chat-7289DA.svg?logo=discord&logoColor=white)](https://discord.gg/Yp4RTh8bG7)
44

55
## Introduction
66

@@ -285,7 +285,7 @@ export PDD_TEST_OUTPUT_PATH=/path/to/tests/
285285

286286
## Version
287287

288-
Current version: 0.0.100
288+
Current version: 0.0.101
289289

290290
To check your installed version, run:
291291
```
@@ -458,7 +458,7 @@ Here is a brief overview of the main commands provided by PDD. Click the command
458458
- **[`conflicts`](#11-conflicts)**: Finds and suggests resolutions for conflicts between two prompt files.
459459
- **[`crash`](#12-crash)**: Fixes errors in a code module and its calling program that caused a crash. Includes an agentic fallback mode for complex errors.
460460
- **[`trace`](#13-trace)**: Finds the corresponding line number in a prompt file for a given code line.
461-
- **[`bug`](#14-bug)**: Generates a unit test based on observed vs. desired program outputs.
461+
- **[`bug`](#14-bug)**: Generates a unit test from a GitHub issue via an agentic workflow that analyzes, reproduces, and creates failing tests.
462462
- **[`auto-deps`](#15-auto-deps)**: Analyzes and inserts needed dependencies into a prompt file.
463463
- **[`verify`](#16-verify)**: Verifies functional correctness by running a program and judging its output against the prompt's intent using an LLM.
464464

@@ -1395,7 +1395,7 @@ Options:
13951395
13961396
#### XML-like Tags
13971397
1398-
PDD supports the following XML-like tags in prompt files:
1398+
PDD supports the following XML-like tags in prompt files. Note: XML-like tags (`<include>`, `<include-many>`, `<shell>`, `<web>`) are left untouched inside fenced code blocks (``` or ~~~) or inline single backticks so documentation examples remain literal.
13991399
14001400
1. **`include`**: Includes the content of the specified file in the prompt. The tag is replaced directly with the file content.
14011401
```xml
@@ -1802,26 +1802,46 @@ This will print out the line number in the prompt file for the associated the co
18021802
18031803
### 14. bug
18041804
1805-
Generate a unit test based on observed and desired outputs, given the original prompt and code.
1805+
Generate a unit test from a GitHub issue. The issue serves as the source of truth for both the error output and expected behavior. An agentic workflow analyzes the issue, reproduces the bug, and creates a failing test.
18061806
18071807
```
1808-
pdd [GLOBAL OPTIONS] bug [OPTIONS] PROMPT_FILE CODE_FILE PROGRAM_FILE CURRENT_OUTPUT_FILE DESIRED_OUTPUT_FILE
1808+
pdd [GLOBAL OPTIONS] bug <github-issue-url>
1809+
pdd [GLOBAL OPTIONS] bug --manual PROMPT_FILE CODE_FILE PROGRAM_FILE CURRENT_OUTPUT DESIRED_OUTPUT
18091810
```
18101811
1812+
**How it works (step-by-step with GitHub comments):**
1813+
1814+
1. **Duplicate check** - Search for existing issues describing the same problem. If found, merge content and close the duplicate. Posts comment with findings.
1815+
1816+
2. **Documentation check** - Review repo documentation to determine if this is a bug or user error. Posts comment with findings.
1817+
1818+
3. **Reproduce** - Attempt to reproduce the issue locally. Posts comment confirming reproduction (or failure to reproduce).
1819+
1820+
4. **Root cause analysis** - Run experiments to identify the root cause. Posts comment explaining the root cause.
1821+
1822+
5. **Test plan** - Design a plan for creating tests to detect the problem. Posts comment with the test plan.
1823+
1824+
6. **Generate test** - Create the failing unit test. Posts comment with the generated test code.
1825+
1826+
7. **Verify detection** - Confirm the test successfully detects the bug. Posts comment confirming verification.
1827+
1828+
8. **Create draft PR** - Create a draft pull request with the failing test and link it to the issue. Posts comment with PR link.
1829+
18111830
Arguments:
1812-
- `PROMPT_FILE`: Filename of the prompt file that generated the code.
1813-
- `CODE_FILE`: Filename of the code file being tested.
1814-
- `PROGRAM_FILE`: Filename of the program used to run the code under test.
1815-
- `CURRENT_OUTPUT_FILE`: File containing the current (incorrect) output of the program.
1816-
- `DESIRED_OUTPUT_FILE`: File containing the desired (correct) output of the program.
1831+
- `ISSUE_URL`: GitHub issue URL (e.g., https://github.com/owner/repo/issues/123)
18171832
18181833
Options:
1819-
- `--output LOCATION`: Specify where to save the generated unit test. The default file name is `test_<basename>_bug.<language_extension>`. If an output file with the specified name already exists, a new file with a numbered suffix (e.g., `test_calculator_bug_1.py`) will be created instead of overwriting.
1820-
- `--language`: Specify the programming language for the unit test (default is "Python").
1834+
- `--manual`: Use legacy mode with explicit file arguments (PROMPT_FILE, CODE_FILE, PROGRAM_FILE, CURRENT_OUTPUT, DESIRED_OUTPUT)
1835+
- `--output LOCATION`: Specify where to save the generated unit test. Default: `test_<module>_bug.py`
1836+
- `--language LANG`: Specify the programming language for the unit test (default is "Python").
18211837
18221838
Example:
1823-
```
1824-
pdd [GLOBAL OPTIONS] bug --output tests/test_factorial_calculator_bug.py factorial_calculator_python.prompt src/factorial_calculator.py main_program.py current_output.txt desired_output.txt
1839+
```bash
1840+
# Agentic mode (recommended)
1841+
pdd bug https://github.com/myorg/myrepo/issues/42
1842+
1843+
# Manual mode (legacy)
1844+
pdd bug --manual prompt.prompt code.py main.py current.txt desired.txt
18251845
```
18261846
18271847
### 15. auto-deps
@@ -2014,6 +2034,10 @@ PDD automatically detects the appropriate context based on:
20142034
- `budget`: Default budget for iterative commands
20152035
- `max_attempts`: Default maximum attempts for fixing operations
20162036
2037+
**Path Behavior**:
2038+
- Paths ending with `/` are treated as explicit directories and do **not** preserve subdirectory basenames (e.g., `commands/analysis` -> `pdd/analysis.py`).
2039+
- Paths without trailing `/` preserve subdirectory basenames when the path is an existing directory (e.g., `commands/analysis` -> `pdd/commands/analysis.py`).
2040+
20172041
**Usage Examples**:
20182042
```bash
20192043
# Auto-detect context from current directory

context/agentic_bug_example.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
"""Example showing how to use run_agentic_bug for GitHub issue-based bug investigation."""
2+
3+
import sys
4+
from pathlib import Path
5+
from unittest.mock import patch, MagicMock
6+
7+
# Add the project root to sys.path
8+
project_root = Path(__file__).resolve().parent.parent
9+
sys.path.append(str(project_root))
10+
11+
from pdd.agentic_bug import run_agentic_bug
12+
13+
14+
def main():
15+
"""Demonstrate the agentic bug workflow with a mocked GitHub issue."""
16+
17+
# Example GitHub issue URL
18+
issue_url = "https://github.com/example/repo/issues/42"
19+
20+
print(f"Running agentic bug investigation for: {issue_url}")
21+
print("-" * 60)
22+
23+
# Mock the agentic task execution to avoid real API calls
24+
with patch("pdd.agentic_bug.run_agentic_bug_orchestrator") as mock_orchestrator:
25+
# Simulate successful 8-step workflow
26+
mock_orchestrator.return_value = (
27+
True, # success
28+
"Investigation complete. Created test_calculator_bug.py", # message
29+
2.50, # total_cost across all 8 steps
30+
"anthropic", # model/provider used
31+
["tests/test_calculator_bug.py"] # changed_files
32+
)
33+
34+
# --- EXECUTE THE MODULE ---
35+
success, message, cost, model, changed_files = run_agentic_bug(
36+
issue_url=issue_url,
37+
verbose=True,
38+
quiet=False
39+
)
40+
41+
# Output the results
42+
print("\n--- Result Summary ---")
43+
print(f"Success : {success}")
44+
print(f"Model Used : {model}")
45+
print(f"Cost : ${cost:.2f}")
46+
print(f"Changed Files : {changed_files}")
47+
print("-" * 30)
48+
print(f"Message : {message}")
49+
50+
51+
if __name__ == "__main__":
52+
main()
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
"""
2+
Example usage of the agentic_bug_orchestrator module.
3+
4+
This script demonstrates how to invoke the `run_agentic_bug_orchestrator` function.
5+
Since the orchestrator relies on internal modules like `run_agentic_task` and `load_prompt_template`,
6+
this example mocks those dependencies to simulate a successful bug investigation workflow
7+
without making actual LLM calls or requiring a real GitHub issue.
8+
9+
Scenario:
10+
We simulate an issue where a user reports a "ZeroDivisionError" in a calculator app.
11+
The orchestrator will step through the 9-step process, finding the bug, generating a test,
12+
and creating a fix.
13+
"""
14+
15+
import sys
16+
from pathlib import Path
17+
from unittest.mock import patch, MagicMock
18+
19+
# Ensure the project root is in sys.path so we can import the module
20+
# Adjust this path based on your actual project structure relative to this script
21+
project_root = Path(__file__).resolve().parent.parent
22+
sys.path.append(str(project_root))
23+
24+
try:
25+
# Import the module to be tested
26+
# Note: We assume the file is at pdd/agentic_bug_orchestrator.py
27+
from pdd.agentic_bug_orchestrator import run_agentic_bug_orchestrator
28+
except ImportError:
29+
print("Error: Could not import 'pdd.agentic_bug_orchestrator'.")
30+
print("Ensure your PYTHONPATH is set correctly or the file structure matches.")
31+
sys.exit(1)
32+
33+
34+
def mock_load_prompt_template(template_name: str) -> str:
35+
"""
36+
Mock implementation of load_prompt_template.
37+
Returns a dummy prompt string based on the requested template name.
38+
"""
39+
return f"MOCK PROMPT FOR: {template_name}\nContext: {{issue_content}}"
40+
41+
42+
def mock_run_agentic_task(instruction: str, cwd: Path, verbose: bool, quiet: bool, label: str):
43+
"""
44+
Mock implementation of run_agentic_task.
45+
Simulates the output of an LLM agent for each step of the workflow.
46+
"""
47+
step_num = label.replace("step", "")
48+
49+
# Default return values
50+
success = True
51+
cost = 0.15 # Simulated cost per step
52+
provider = "gpt-4-mock"
53+
files = []
54+
output = ""
55+
56+
if step_num == "1":
57+
output = "No duplicate issues found. Proceeding."
58+
elif step_num == "2":
59+
output = "Checked documentation. This behavior is not documented, likely a bug."
60+
elif step_num == "3":
61+
output = "Sufficient information provided in the issue description."
62+
elif step_num == "4":
63+
output = "Successfully reproduced the ZeroDivisionError with input (10, 0)."
64+
elif step_num == "5":
65+
output = "Root cause identified: 'divide' function lacks check for denominator == 0."
66+
elif step_num == "6":
67+
output = "Plan: Create a test case 'test_divide_zero' asserting ValueError is raised."
68+
elif step_num == "7":
69+
output = "Generated file 'tests/test_calculator_bug.py'."
70+
files = ["tests/test_calculator_bug.py"]
71+
elif step_num == "8":
72+
output = "Verification successful: The new test fails as expected against current code."
73+
elif step_num == "9":
74+
output = "Created draft PR #101 linking to issue #42."
75+
else:
76+
output = "Unknown step executed."
77+
78+
return success, output, cost, provider, files
79+
80+
81+
def main():
82+
"""Main function to run the agentic bug orchestrator simulation."""
83+
# Define dummy issue data
84+
issue_data = {
85+
"issue_url": "https://github.com/example/calculator/issues/42",
86+
"issue_content": "When I divide by zero, the app crashes instead of raising a clean error.",
87+
"repo_owner": "example",
88+
"repo_name": "calculator",
89+
"issue_number": 42,
90+
"issue_author": "bug_hunter_99",
91+
"issue_title": "Crash on division by zero",
92+
"cwd": Path("./temp_workspace"),
93+
"verbose": True,
94+
"quiet": False
95+
}
96+
97+
print("Starting Agentic Bug Orchestrator Simulation...")
98+
print("-" * 60)
99+
100+
# Patch the internal dependencies
101+
# We patch where they are imported IN the orchestrator module, not where they are defined
102+
with patch("pdd.agentic_bug_orchestrator.load_prompt_template", side_effect=mock_load_prompt_template), \
103+
patch("pdd.agentic_bug_orchestrator.run_agentic_task", side_effect=mock_run_agentic_task):
104+
105+
# Run the orchestrator
106+
success, final_msg, total_cost, model, changed_files = run_agentic_bug_orchestrator(
107+
**issue_data
108+
)
109+
110+
print("-" * 60)
111+
print("Simulation Complete.")
112+
print(f"Success: {success}")
113+
print(f"Final Message: {final_msg}")
114+
print(f"Total Cost: ${total_cost:.2f}")
115+
print(f"Model Used: {model}")
116+
print(f"Changed Files: {changed_files}")
117+
118+
119+
if __name__ == "__main__":
120+
main()

0 commit comments

Comments
 (0)