Skip to content

Commit e91ec3a

Browse files
committed
Bump version
1 parent de18ab7 commit e91ec3a

29 files changed

+1960
-183
lines changed

CHANGELOG.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,58 @@
1+
## v0.0.92 (2025-12-25)
2+
3+
### Feat
4+
5+
- add cloud configuration examples and enhance path handling
6+
- support subdirectory basenames in output path generation
7+
- implement environment variable checks for cloud execution in code generator
8+
- enhance error handling for cloud execution in code generator
9+
- add centralized cloud configuration module for PDD CLI
10+
- enhance cloud URL configuration and authentication handling
11+
- enhance backup organization and schema validation
12+
13+
### Fix
14+
15+
- resolve path resolution mismatch in sync_orchestration
16+
- mock isatty in test fixture for headless mode compatibility
17+
- extend --force to skip API key prompts in CI/headless environments
18+
- add headless mode detection for CI/non-TTY environments
19+
- add timeout and non-TTY mode for pdd sync in CI
20+
- rename code.py to buggy.py in agentic test fixtures
21+
- correct typo in prompt tag from <proompt_content> to <prompt_content>
22+
- package docs and add fallback path resolution for includes
23+
24+
### Refactor
25+
26+
- remove local _safe_basename function and update tests for subdirectory handling
27+
- centralize cloud configuration and authentication handling
28+
129
## v0.0.91 (2025-12-24)
230

31+
### Feat
32+
33+
- **Backup Directory Organization (Issue #174):** Moved all fix loop backup files from polluting source/test directories to `.pdd/backups/{module}/{timestamp}/` directory. Previously, backups like `module_1.py`, `module_2.py` would clutter the source directory; now they're stored as `.pdd/backups/module/20251224_143052/code_1.py` etc. Affects `fix_code_loop`, `fix_error_loop`, and `fix_verification_errors_loop`.
34+
35+
- **Schema Validation Fallback (Issue #168):** Added `SchemaValidationError` exception to `llm_invoke.py`. When Pydantic/JSON schema validation fails, the error now triggers model fallback to try the next candidate model instead of just logging and skipping to the next batch item. This fixes cases where a model consistently returns malformed structured output.
36+
37+
### Docs
38+
39+
- **PDD Doctrine - The Mold Paradigm:** Expanded `docs/prompt-driven-development-doctrine.md` with ~300 lines covering the manufacturing analogy (wood carving → injection molding), the three capitals (test, prompt, grounding), tests as specification vs verification, compound returns of mold refinement, skill evolution for developers, and the complete analogy mapping table.
40+
41+
### Data
42+
43+
- **LLM Model Catalog Update:** Updated `data/llm_model.csv`:
44+
- Updated GLM model from 4p6 to 4p7 with revised pricing ($0.60/$2.20)
45+
- Enabled structured output (`True`) for DeepSeek v3.2-maas on Vertex AI
46+
47+
### Deps
48+
49+
- Updated `litellm[caching]` to version 1.80
50+
51+
### Tests
52+
53+
- Added ~700 lines of tests across `test_llm_invoke.py` and new `test_llm_invoke_integration.py` covering schema validation fallback behavior and model fallback on validation errors.
54+
- Added backup location verification tests in `test_fix_code_loop.py`, `test_fix_error_loop.py`, and `test_fix_verification_errors_loop.py` ensuring backups are created in `.pdd/backups/` directory.
55+
356
## v0.0.90 (2025-12-23)
457

558
### Feat

README.md

Lines changed: 3 additions & 3 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.91-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.92-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.91
288+
Current version: 0.0.92
289289

290290
To check your installed version, run:
291291
```
@@ -466,7 +466,7 @@ Here is a brief overview of the main commands provided by PDD. Click the command
466466

467467
These options can be used with any command:
468468

469-
- `--force`: Overwrite existing files without asking for confirmation (commonly used with `sync`).
469+
- `--force`: Skip all interactive prompts (file overwrites, API key requests). Useful for CI/automation.
470470
- `--strength FLOAT`: Set the strength of the AI model (0.0 to 1.0, default is 0.5).
471471
- 0.0: Cheapest available model
472472
- 0.5: Default base model

context/core/cloud_example.py

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Example usage of the pdd.core.cloud module.
4+
5+
This module provides centralized cloud configuration and authentication handling
6+
for PDD CLI commands. It manages:
7+
- Cloud function URLs (base URLs and specific endpoints)
8+
- JWT token retrieval (via environment variables or device flow)
9+
- Cloud feature availability checks
10+
11+
File structure (relative to project root):
12+
pdd/
13+
core/
14+
cloud.py # The module being demonstrated
15+
context/
16+
core/
17+
cloud_example.py # This example file
18+
"""
19+
20+
import os
21+
import sys
22+
from pathlib import Path
23+
24+
# Ensure output directory exists
25+
script_dir = os.path.dirname(os.path.abspath(__file__))
26+
output_dir = os.path.join(script_dir, "output")
27+
os.makedirs(output_dir, exist_ok=True)
28+
29+
# Add project root to sys.path to allow importing pdd module
30+
# Assuming script is in context/core/, project root is ../../
31+
project_root = os.path.abspath(os.path.join(script_dir, "../../"))
32+
if project_root not in sys.path:
33+
sys.path.insert(0, project_root)
34+
35+
# Import the CloudConfig class and constants from the module
36+
from pdd.core.cloud import (
37+
CloudConfig,
38+
CLOUD_ENDPOINTS,
39+
PDD_CLOUD_URL_ENV,
40+
PDD_JWT_TOKEN_ENV,
41+
FIREBASE_API_KEY_ENV,
42+
GITHUB_CLIENT_ID_ENV,
43+
)
44+
45+
# Import rich console for output
46+
from rich.console import Console
47+
48+
console = Console()
49+
50+
51+
def example_cloud_urls():
52+
"""
53+
Demonstrate how to retrieve cloud URLs using CloudConfig.
54+
55+
This shows:
56+
1. Getting the default base URL
57+
2. Getting specific endpoint URLs
58+
3. Overriding the base URL via environment variables (e.g., for local testing)
59+
"""
60+
console.print("[bold cyan]=== Cloud URL Configuration ===[/bold cyan]")
61+
62+
# 1. Default Configuration
63+
base_url = CloudConfig.get_base_url()
64+
console.print(f"Default Base URL: [green]{base_url}[/green]")
65+
66+
# 2. Specific Endpoints
67+
# CloudConfig.get_endpoint_url handles path construction automatically
68+
console.print("\n[bold]Endpoint URLs:[/bold]")
69+
for name in CLOUD_ENDPOINTS:
70+
url = CloudConfig.get_endpoint_url(name)
71+
console.print(f" - {name}: [blue]{url}[/blue]")
72+
73+
# 3. Environment Override (Simulating a local emulator)
74+
console.print("\n[bold]Simulating Local Emulator Override:[/bold]")
75+
76+
# Save original env var if it exists
77+
original_url = os.environ.get(PDD_CLOUD_URL_ENV)
78+
79+
try:
80+
# Set a local emulator URL
81+
local_url = "http://127.0.0.1:5001/pdd-project/us-central1"
82+
os.environ[PDD_CLOUD_URL_ENV] = local_url
83+
84+
console.print(f" Set {PDD_CLOUD_URL_ENV} = {local_url}")
85+
86+
# Verify the override works
87+
new_base = CloudConfig.get_base_url()
88+
new_endpoint = CloudConfig.get_endpoint_url("generateCode")
89+
90+
console.print(f" Overridden Base URL: [green]{new_base}[/green]")
91+
console.print(f" Overridden Endpoint: [blue]{new_endpoint}[/blue]")
92+
93+
finally:
94+
# Restore environment
95+
if original_url:
96+
os.environ[PDD_CLOUD_URL_ENV] = original_url
97+
else:
98+
if PDD_CLOUD_URL_ENV in os.environ:
99+
del os.environ[PDD_CLOUD_URL_ENV]
100+
console.print()
101+
102+
103+
def example_cloud_availability():
104+
"""
105+
Demonstrate checking if cloud features are enabled.
106+
107+
Cloud features require specific API keys to be present in the environment.
108+
"""
109+
console.print("[bold cyan]=== Cloud Availability Check ===[/bold cyan]")
110+
111+
# Check current status
112+
is_enabled = CloudConfig.is_cloud_enabled()
113+
console.print(f"Cloud Enabled: [yellow]{is_enabled}[/yellow]")
114+
115+
if not is_enabled:
116+
console.print("[dim]Cloud features are disabled because API keys are missing.[/dim]")
117+
console.print(f"[dim]Required: {FIREBASE_API_KEY_ENV}, {GITHUB_CLIENT_ID_ENV}[/dim]")
118+
else:
119+
console.print("[green]Cloud features are ready to use.[/green]")
120+
console.print()
121+
122+
123+
def example_authentication_flow():
124+
"""
125+
Demonstrate the authentication flow logic.
126+
127+
Note: This example mocks the actual network calls to avoid interactive prompts
128+
or actual authentication requests during the demo run. It focuses on how
129+
the CloudConfig.get_jwt_token method prioritizes environment variables.
130+
"""
131+
console.print("[bold cyan]=== Authentication Flow ===[/bold cyan]")
132+
133+
# 1. Testing/CI Flow (Token Injection)
134+
# This is the preferred method for CI/CD pipelines or automated tests
135+
console.print("[bold]Scenario 1: Token Injection (CI/Testing)[/bold]")
136+
137+
fake_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.fake.token"
138+
os.environ[PDD_JWT_TOKEN_ENV] = fake_token
139+
140+
try:
141+
# When PDD_JWT_TOKEN is set, it returns immediately without network calls
142+
token = CloudConfig.get_jwt_token(verbose=True)
143+
console.print(f" Retrieved Token: [green]{token[:15]}...[/green]")
144+
145+
if token == fake_token:
146+
console.print(" [success]Successfully retrieved injected token[/success]")
147+
148+
finally:
149+
# Clean up
150+
if PDD_JWT_TOKEN_ENV in os.environ:
151+
del os.environ[PDD_JWT_TOKEN_ENV]
152+
153+
# 2. Interactive Flow (Explanation)
154+
console.print("\n[bold]Scenario 2: Interactive Device Flow[/bold]")
155+
console.print(" If PDD_JWT_TOKEN is not set, CloudConfig.get_jwt_token() will:")
156+
console.print(" 1. Check for Firebase/GitHub credentials")
157+
console.print(" 2. Initiate the Device Flow (async)")
158+
console.print(" 3. Prompt the user to authorize via browser")
159+
console.print(" 4. Return the JWT token or None on failure")
160+
161+
console.print("\n [dim]Skipping actual interactive auth for this non-interactive example.[/dim]")
162+
console.print()
163+
164+
165+
def main():
166+
"""
167+
Run all examples demonstrating the pdd.core.cloud module.
168+
"""
169+
console.print("\n[bold white on blue] PDD Cloud Config Module Examples [/bold white on blue]\n")
170+
171+
example_cloud_urls()
172+
example_cloud_availability()
173+
example_authentication_flow()
174+
175+
console.print("[bold green]Examples completed successfully![/bold green]")
176+
177+
178+
if __name__ == "__main__":
179+
main()

examples/hello/repo_root

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Subproject commit f1f4fc5cd1819241d329168f79496ecb809eeff6
1+
Subproject commit efe65d5056a7a737c50adbef5a3b01c29c32f44b

pdd/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""PDD - Prompt Driven Development"""
22

3-
__version__ = "0.0.91"
3+
__version__ = "0.0.92"
44

55
# Strength parameter used for LLM extraction across the codebase
66
# Used in postprocessing, XML tagging, code generation, and other extraction

0 commit comments

Comments
 (0)