pdd-cli 0.0.45__py3-none-any.whl → 0.0.118__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.
Files changed (195) hide show
  1. pdd/__init__.py +40 -8
  2. pdd/agentic_bug.py +323 -0
  3. pdd/agentic_bug_orchestrator.py +497 -0
  4. pdd/agentic_change.py +231 -0
  5. pdd/agentic_change_orchestrator.py +526 -0
  6. pdd/agentic_common.py +598 -0
  7. pdd/agentic_crash.py +534 -0
  8. pdd/agentic_e2e_fix.py +319 -0
  9. pdd/agentic_e2e_fix_orchestrator.py +426 -0
  10. pdd/agentic_fix.py +1294 -0
  11. pdd/agentic_langtest.py +162 -0
  12. pdd/agentic_update.py +387 -0
  13. pdd/agentic_verify.py +183 -0
  14. pdd/architecture_sync.py +565 -0
  15. pdd/auth_service.py +210 -0
  16. pdd/auto_deps_main.py +71 -51
  17. pdd/auto_include.py +245 -5
  18. pdd/auto_update.py +125 -47
  19. pdd/bug_main.py +196 -23
  20. pdd/bug_to_unit_test.py +2 -0
  21. pdd/change_main.py +11 -4
  22. pdd/cli.py +22 -1181
  23. pdd/cmd_test_main.py +350 -150
  24. pdd/code_generator.py +60 -18
  25. pdd/code_generator_main.py +790 -57
  26. pdd/commands/__init__.py +48 -0
  27. pdd/commands/analysis.py +306 -0
  28. pdd/commands/auth.py +309 -0
  29. pdd/commands/connect.py +290 -0
  30. pdd/commands/fix.py +163 -0
  31. pdd/commands/generate.py +257 -0
  32. pdd/commands/maintenance.py +175 -0
  33. pdd/commands/misc.py +87 -0
  34. pdd/commands/modify.py +256 -0
  35. pdd/commands/report.py +144 -0
  36. pdd/commands/sessions.py +284 -0
  37. pdd/commands/templates.py +215 -0
  38. pdd/commands/utility.py +110 -0
  39. pdd/config_resolution.py +58 -0
  40. pdd/conflicts_main.py +8 -3
  41. pdd/construct_paths.py +589 -111
  42. pdd/context_generator.py +10 -2
  43. pdd/context_generator_main.py +175 -76
  44. pdd/continue_generation.py +53 -10
  45. pdd/core/__init__.py +33 -0
  46. pdd/core/cli.py +527 -0
  47. pdd/core/cloud.py +237 -0
  48. pdd/core/dump.py +554 -0
  49. pdd/core/errors.py +67 -0
  50. pdd/core/remote_session.py +61 -0
  51. pdd/core/utils.py +90 -0
  52. pdd/crash_main.py +262 -33
  53. pdd/data/language_format.csv +71 -63
  54. pdd/data/llm_model.csv +20 -18
  55. pdd/detect_change_main.py +5 -4
  56. pdd/docs/prompting_guide.md +864 -0
  57. pdd/docs/whitepaper_with_benchmarks/data_and_functions/benchmark_analysis.py +495 -0
  58. pdd/docs/whitepaper_with_benchmarks/data_and_functions/creation_compare.py +528 -0
  59. pdd/fix_code_loop.py +523 -95
  60. pdd/fix_code_module_errors.py +6 -2
  61. pdd/fix_error_loop.py +491 -92
  62. pdd/fix_errors_from_unit_tests.py +4 -3
  63. pdd/fix_main.py +278 -21
  64. pdd/fix_verification_errors.py +12 -100
  65. pdd/fix_verification_errors_loop.py +529 -286
  66. pdd/fix_verification_main.py +294 -89
  67. pdd/frontend/dist/assets/index-B5DZHykP.css +1 -0
  68. pdd/frontend/dist/assets/index-DQ3wkeQ2.js +449 -0
  69. pdd/frontend/dist/index.html +376 -0
  70. pdd/frontend/dist/logo.svg +33 -0
  71. pdd/generate_output_paths.py +139 -15
  72. pdd/generate_test.py +218 -146
  73. pdd/get_comment.py +19 -44
  74. pdd/get_extension.py +8 -9
  75. pdd/get_jwt_token.py +318 -22
  76. pdd/get_language.py +8 -7
  77. pdd/get_run_command.py +75 -0
  78. pdd/get_test_command.py +68 -0
  79. pdd/git_update.py +70 -19
  80. pdd/incremental_code_generator.py +2 -2
  81. pdd/insert_includes.py +13 -4
  82. pdd/llm_invoke.py +1711 -181
  83. pdd/load_prompt_template.py +19 -12
  84. pdd/path_resolution.py +140 -0
  85. pdd/pdd_completion.fish +25 -2
  86. pdd/pdd_completion.sh +30 -4
  87. pdd/pdd_completion.zsh +79 -4
  88. pdd/postprocess.py +14 -4
  89. pdd/preprocess.py +293 -24
  90. pdd/preprocess_main.py +41 -6
  91. pdd/prompts/agentic_bug_step10_pr_LLM.prompt +182 -0
  92. pdd/prompts/agentic_bug_step1_duplicate_LLM.prompt +73 -0
  93. pdd/prompts/agentic_bug_step2_docs_LLM.prompt +129 -0
  94. pdd/prompts/agentic_bug_step3_triage_LLM.prompt +95 -0
  95. pdd/prompts/agentic_bug_step4_reproduce_LLM.prompt +97 -0
  96. pdd/prompts/agentic_bug_step5_root_cause_LLM.prompt +123 -0
  97. pdd/prompts/agentic_bug_step6_test_plan_LLM.prompt +107 -0
  98. pdd/prompts/agentic_bug_step7_generate_LLM.prompt +172 -0
  99. pdd/prompts/agentic_bug_step8_verify_LLM.prompt +119 -0
  100. pdd/prompts/agentic_bug_step9_e2e_test_LLM.prompt +289 -0
  101. pdd/prompts/agentic_change_step10_identify_issues_LLM.prompt +1006 -0
  102. pdd/prompts/agentic_change_step11_fix_issues_LLM.prompt +984 -0
  103. pdd/prompts/agentic_change_step12_create_pr_LLM.prompt +131 -0
  104. pdd/prompts/agentic_change_step1_duplicate_LLM.prompt +73 -0
  105. pdd/prompts/agentic_change_step2_docs_LLM.prompt +101 -0
  106. pdd/prompts/agentic_change_step3_research_LLM.prompt +126 -0
  107. pdd/prompts/agentic_change_step4_clarify_LLM.prompt +164 -0
  108. pdd/prompts/agentic_change_step5_docs_change_LLM.prompt +981 -0
  109. pdd/prompts/agentic_change_step6_devunits_LLM.prompt +1005 -0
  110. pdd/prompts/agentic_change_step7_architecture_LLM.prompt +1044 -0
  111. pdd/prompts/agentic_change_step8_analyze_LLM.prompt +1027 -0
  112. pdd/prompts/agentic_change_step9_implement_LLM.prompt +1077 -0
  113. pdd/prompts/agentic_crash_explore_LLM.prompt +49 -0
  114. pdd/prompts/agentic_e2e_fix_step1_unit_tests_LLM.prompt +90 -0
  115. pdd/prompts/agentic_e2e_fix_step2_e2e_tests_LLM.prompt +91 -0
  116. pdd/prompts/agentic_e2e_fix_step3_root_cause_LLM.prompt +89 -0
  117. pdd/prompts/agentic_e2e_fix_step4_fix_e2e_tests_LLM.prompt +96 -0
  118. pdd/prompts/agentic_e2e_fix_step5_identify_devunits_LLM.prompt +91 -0
  119. pdd/prompts/agentic_e2e_fix_step6_create_unit_tests_LLM.prompt +106 -0
  120. pdd/prompts/agentic_e2e_fix_step7_verify_tests_LLM.prompt +116 -0
  121. pdd/prompts/agentic_e2e_fix_step8_run_pdd_fix_LLM.prompt +120 -0
  122. pdd/prompts/agentic_e2e_fix_step9_verify_all_LLM.prompt +146 -0
  123. pdd/prompts/agentic_fix_explore_LLM.prompt +45 -0
  124. pdd/prompts/agentic_fix_harvest_only_LLM.prompt +48 -0
  125. pdd/prompts/agentic_fix_primary_LLM.prompt +85 -0
  126. pdd/prompts/agentic_update_LLM.prompt +925 -0
  127. pdd/prompts/agentic_verify_explore_LLM.prompt +45 -0
  128. pdd/prompts/auto_include_LLM.prompt +122 -905
  129. pdd/prompts/change_LLM.prompt +3093 -1
  130. pdd/prompts/detect_change_LLM.prompt +686 -27
  131. pdd/prompts/example_generator_LLM.prompt +22 -1
  132. pdd/prompts/extract_code_LLM.prompt +5 -1
  133. pdd/prompts/extract_program_code_fix_LLM.prompt +7 -1
  134. pdd/prompts/extract_prompt_update_LLM.prompt +7 -8
  135. pdd/prompts/extract_promptline_LLM.prompt +17 -11
  136. pdd/prompts/find_verification_errors_LLM.prompt +6 -0
  137. pdd/prompts/fix_code_module_errors_LLM.prompt +12 -2
  138. pdd/prompts/fix_errors_from_unit_tests_LLM.prompt +9 -0
  139. pdd/prompts/fix_verification_errors_LLM.prompt +22 -0
  140. pdd/prompts/generate_test_LLM.prompt +41 -7
  141. pdd/prompts/generate_test_from_example_LLM.prompt +115 -0
  142. pdd/prompts/increase_tests_LLM.prompt +1 -5
  143. pdd/prompts/insert_includes_LLM.prompt +316 -186
  144. pdd/prompts/prompt_code_diff_LLM.prompt +119 -0
  145. pdd/prompts/prompt_diff_LLM.prompt +82 -0
  146. pdd/prompts/trace_LLM.prompt +25 -22
  147. pdd/prompts/unfinished_prompt_LLM.prompt +85 -1
  148. pdd/prompts/update_prompt_LLM.prompt +22 -1
  149. pdd/pytest_output.py +127 -12
  150. pdd/remote_session.py +876 -0
  151. pdd/render_mermaid.py +236 -0
  152. pdd/server/__init__.py +52 -0
  153. pdd/server/app.py +335 -0
  154. pdd/server/click_executor.py +587 -0
  155. pdd/server/executor.py +338 -0
  156. pdd/server/jobs.py +661 -0
  157. pdd/server/models.py +241 -0
  158. pdd/server/routes/__init__.py +31 -0
  159. pdd/server/routes/architecture.py +451 -0
  160. pdd/server/routes/auth.py +364 -0
  161. pdd/server/routes/commands.py +929 -0
  162. pdd/server/routes/config.py +42 -0
  163. pdd/server/routes/files.py +603 -0
  164. pdd/server/routes/prompts.py +1322 -0
  165. pdd/server/routes/websocket.py +473 -0
  166. pdd/server/security.py +243 -0
  167. pdd/server/terminal_spawner.py +209 -0
  168. pdd/server/token_counter.py +222 -0
  169. pdd/setup_tool.py +648 -0
  170. pdd/simple_math.py +2 -0
  171. pdd/split_main.py +3 -2
  172. pdd/summarize_directory.py +237 -195
  173. pdd/sync_animation.py +8 -4
  174. pdd/sync_determine_operation.py +839 -112
  175. pdd/sync_main.py +351 -57
  176. pdd/sync_orchestration.py +1400 -756
  177. pdd/sync_tui.py +848 -0
  178. pdd/template_expander.py +161 -0
  179. pdd/template_registry.py +264 -0
  180. pdd/templates/architecture/architecture_json.prompt +237 -0
  181. pdd/templates/generic/generate_prompt.prompt +174 -0
  182. pdd/trace.py +168 -12
  183. pdd/trace_main.py +4 -3
  184. pdd/track_cost.py +140 -63
  185. pdd/unfinished_prompt.py +51 -4
  186. pdd/update_main.py +567 -67
  187. pdd/update_model_costs.py +2 -2
  188. pdd/update_prompt.py +19 -4
  189. {pdd_cli-0.0.45.dist-info → pdd_cli-0.0.118.dist-info}/METADATA +29 -11
  190. pdd_cli-0.0.118.dist-info/RECORD +227 -0
  191. {pdd_cli-0.0.45.dist-info → pdd_cli-0.0.118.dist-info}/licenses/LICENSE +1 -1
  192. pdd_cli-0.0.45.dist-info/RECORD +0 -116
  193. {pdd_cli-0.0.45.dist-info → pdd_cli-0.0.118.dist-info}/WHEEL +0 -0
  194. {pdd_cli-0.0.45.dist-info → pdd_cli-0.0.118.dist-info}/entry_points.txt +0 -0
  195. {pdd_cli-0.0.45.dist-info → pdd_cli-0.0.118.dist-info}/top_level.txt +0 -0
pdd/core/cloud.py ADDED
@@ -0,0 +1,237 @@
1
+ """
2
+ Centralized cloud configuration for PDD CLI commands.
3
+
4
+ Provides consistent cloud URL configuration and JWT token handling
5
+ across all cloud-enabled commands (generate, fix, test, sync, etc.).
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import asyncio
11
+ import os
12
+ from typing import Optional
13
+
14
+ from rich.console import Console
15
+
16
+ from ..get_jwt_token import (
17
+ AuthError,
18
+ NetworkError,
19
+ RateLimitError,
20
+ TokenError,
21
+ UserCancelledError,
22
+ get_jwt_token as device_flow_get_token,
23
+ )
24
+
25
+ console = Console()
26
+
27
+ # Environment variable names
28
+ FIREBASE_API_KEY_ENV = "NEXT_PUBLIC_FIREBASE_API_KEY"
29
+ GITHUB_CLIENT_ID_ENV = "GITHUB_CLIENT_ID"
30
+ PDD_CLOUD_URL_ENV = "PDD_CLOUD_URL"
31
+ PDD_JWT_TOKEN_ENV = "PDD_JWT_TOKEN"
32
+
33
+ # Default cloud endpoints
34
+ DEFAULT_BASE_URL = "https://us-central1-prompt-driven-development.cloudfunctions.net"
35
+
36
+ # Endpoint paths (can be extended as more endpoints are added)
37
+ CLOUD_ENDPOINTS = {
38
+ "generateCode": "/generateCode",
39
+ "generateExample": "/generateExample",
40
+ "generateTest": "/generateTest",
41
+ "generateBugTest": "/generateBugTest",
42
+ "fixCode": "/fixCode",
43
+ "crashCode": "/crashCode",
44
+ "verifyCode": "/verifyCode",
45
+ "syncState": "/syncState",
46
+ "trackUsage": "/trackUsage",
47
+ "getCreditBalance": "/getCreditBalance",
48
+ "llmInvoke": "/llmInvoke",
49
+ # Remote session endpoints
50
+ "registerSession": "/registerSession",
51
+ "listSessions": "/listSessions",
52
+ "heartbeatSession": "/heartbeatSession",
53
+ "deregisterSession": "/deregisterSession",
54
+ # Command relay endpoints (Firestore message bus)
55
+ "getCommands": "/getCommands",
56
+ "getCommandStatus": "/getCommandStatus",
57
+ "updateCommand": "/updateCommand",
58
+ "cancelCommand": "/cancelCommand",
59
+ }
60
+
61
+
62
+ class CloudConfig:
63
+ """Centralized cloud configuration for all PDD commands."""
64
+
65
+ @staticmethod
66
+ def _ensure_default_env() -> None:
67
+ """Default PDD_ENV for CLI usage when unset."""
68
+ if os.environ.get("PDD_ENV"):
69
+ return
70
+
71
+ # Local/emulator signals should keep PDD_ENV local.
72
+ if (os.environ.get("FUNCTIONS_EMULATOR") or
73
+ os.environ.get("FIREBASE_AUTH_EMULATOR_HOST") or
74
+ os.environ.get("FIREBASE_EMULATOR_HUB")):
75
+ os.environ["PDD_ENV"] = "local"
76
+ return
77
+
78
+ cloud_url = (os.environ.get(PDD_CLOUD_URL_ENV) or "").lower()
79
+ if cloud_url:
80
+ if any(host in cloud_url for host in ("localhost", "127.0.0.1", "0.0.0.0")):
81
+ os.environ["PDD_ENV"] = "local"
82
+ return
83
+ if "prompt-driven-development-stg" in cloud_url or "staging" in cloud_url:
84
+ os.environ["PDD_ENV"] = "staging"
85
+ return
86
+
87
+ # Default to production for typical CLI usage.
88
+ os.environ["PDD_ENV"] = "prod"
89
+
90
+ @staticmethod
91
+ def get_base_url() -> str:
92
+ """Get cloud base URL, allowing override via PDD_CLOUD_URL.
93
+
94
+ For testing against different environments:
95
+ - Local emulator: http://127.0.0.1:5555/prompt-driven-development/us-central1
96
+ - Staging: https://us-central1-prompt-driven-development-stg.cloudfunctions.net
97
+ - Production: (default) https://us-central1-prompt-driven-development.cloudfunctions.net
98
+ """
99
+ custom_url = os.environ.get(PDD_CLOUD_URL_ENV)
100
+ if custom_url:
101
+ # If full URL provided (with endpoint), extract base
102
+ # If base URL provided, use as-is
103
+ return custom_url.rstrip("/")
104
+ return DEFAULT_BASE_URL
105
+
106
+ @staticmethod
107
+ def get_endpoint_url(endpoint_name: str) -> str:
108
+ """Get full URL for a specific cloud endpoint.
109
+
110
+ Args:
111
+ endpoint_name: Name of endpoint (e.g., 'generateCode', 'syncState')
112
+
113
+ Returns:
114
+ Full URL for the endpoint
115
+ """
116
+ base = CloudConfig.get_base_url()
117
+
118
+ # Check if PDD_CLOUD_URL already includes the endpoint
119
+ custom_url = os.environ.get(PDD_CLOUD_URL_ENV, "")
120
+ if endpoint_name in custom_url:
121
+ return custom_url
122
+
123
+ path = CLOUD_ENDPOINTS.get(endpoint_name, f"/{endpoint_name}")
124
+ return f"{base}{path}"
125
+
126
+ @staticmethod
127
+ def get_jwt_token(
128
+ verbose: bool = False,
129
+ app_name: str = "PDD Code Generator"
130
+ ) -> Optional[str]:
131
+ """Get JWT token for cloud authentication.
132
+
133
+ Checks PDD_JWT_TOKEN environment variable first (for testing/CI),
134
+ then falls back to interactive device flow authentication.
135
+
136
+ Args:
137
+ verbose: Whether to print status messages
138
+ app_name: Application name for device flow
139
+
140
+ Returns:
141
+ JWT token string, or None if authentication failed
142
+
143
+ Note:
144
+ Callers should handle None return by falling back to local execution.
145
+ """
146
+ # Default env to prod for typical CLI usage (unless emulator/custom URL says otherwise).
147
+ CloudConfig._ensure_default_env()
148
+
149
+ # Check for pre-injected token (testing/CI)
150
+ injected_token = os.environ.get(PDD_JWT_TOKEN_ENV)
151
+ if injected_token:
152
+ if verbose:
153
+ console.print(f"[info]Using injected JWT token from {PDD_JWT_TOKEN_ENV}[/info]")
154
+ return injected_token
155
+
156
+ # Standard device flow authentication
157
+ try:
158
+ firebase_api_key = os.environ.get(FIREBASE_API_KEY_ENV)
159
+ github_client_id = os.environ.get(GITHUB_CLIENT_ID_ENV)
160
+
161
+ if not firebase_api_key:
162
+ raise AuthError(f"{FIREBASE_API_KEY_ENV} not set.")
163
+ if not github_client_id:
164
+ raise AuthError(f"{GITHUB_CLIENT_ID_ENV} not set.")
165
+
166
+ return asyncio.run(device_flow_get_token(
167
+ firebase_api_key=firebase_api_key,
168
+ github_client_id=github_client_id,
169
+ app_name=app_name
170
+ ))
171
+ except (AuthError, NetworkError, TokenError, UserCancelledError, RateLimitError) as e:
172
+ # Always display auth errors (both these expected ones and the unexpected ones handled below) - critical for debugging auth issues
173
+ console.print(f"[yellow]Cloud authentication error: {e}[/yellow]")
174
+ return None
175
+ except Exception as e:
176
+ # Always display unexpected errors too
177
+ console.print(f"[yellow]Unexpected auth error: {e}[/yellow]")
178
+ return None
179
+
180
+ @staticmethod
181
+ def is_running_in_cloud() -> bool:
182
+ """Check if we're running inside a cloud environment.
183
+
184
+ Detects Google Cloud Functions/Cloud Run via K_SERVICE env var,
185
+ or local emulator via FUNCTIONS_EMULATOR. This prevents infinite
186
+ loops when cloud endpoints call the CLI internally.
187
+ """
188
+ return bool(
189
+ os.environ.get("K_SERVICE") or
190
+ os.environ.get("FUNCTIONS_EMULATOR")
191
+ )
192
+
193
+ @staticmethod
194
+ def is_cloud_enabled() -> bool:
195
+ """Check if cloud features are available.
196
+
197
+ Cloud is enabled if:
198
+ 1. PDD_FORCE_LOCAL is NOT set (respects --local flag), AND
199
+ 2. NOT already running inside a cloud environment (prevents infinite loops), AND
200
+ 3. Either:
201
+ a. PDD_JWT_TOKEN is set (injected token for testing/CI), OR
202
+ b. Both FIREBASE_API_KEY and GITHUB_CLIENT_ID are set (for device flow auth)
203
+ """
204
+ # Respect --local flag (sets PDD_FORCE_LOCAL=1)
205
+ if os.environ.get("PDD_FORCE_LOCAL"):
206
+ return False
207
+
208
+ # CRITICAL: Never enable cloud mode when already running in cloud
209
+ # This prevents infinite loops when cloud endpoints call CLI internally
210
+ if CloudConfig.is_running_in_cloud():
211
+ return False
212
+
213
+ # Check for injected token first (testing/CI scenario)
214
+ if os.environ.get(PDD_JWT_TOKEN_ENV):
215
+ return True
216
+ # Check for device flow auth credentials
217
+ return bool(
218
+ os.environ.get(FIREBASE_API_KEY_ENV) and
219
+ os.environ.get(GITHUB_CLIENT_ID_ENV)
220
+ )
221
+
222
+
223
+ # Re-export exception classes for convenience
224
+ __all__ = [
225
+ 'CloudConfig',
226
+ 'AuthError',
227
+ 'NetworkError',
228
+ 'TokenError',
229
+ 'UserCancelledError',
230
+ 'RateLimitError',
231
+ 'FIREBASE_API_KEY_ENV',
232
+ 'GITHUB_CLIENT_ID_ENV',
233
+ 'PDD_CLOUD_URL_ENV',
234
+ 'PDD_JWT_TOKEN_ENV',
235
+ 'DEFAULT_BASE_URL',
236
+ 'CLOUD_ENDPOINTS',
237
+ ]