pdd-cli 0.0.90__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.
- pdd/__init__.py +38 -6
- pdd/agentic_bug.py +323 -0
- pdd/agentic_bug_orchestrator.py +497 -0
- pdd/agentic_change.py +231 -0
- pdd/agentic_change_orchestrator.py +526 -0
- pdd/agentic_common.py +521 -786
- pdd/agentic_e2e_fix.py +319 -0
- pdd/agentic_e2e_fix_orchestrator.py +426 -0
- pdd/agentic_fix.py +118 -3
- pdd/agentic_update.py +25 -8
- pdd/architecture_sync.py +565 -0
- pdd/auth_service.py +210 -0
- pdd/auto_deps_main.py +63 -53
- pdd/auto_include.py +185 -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 +87 -29
- pdd/commands/auth.py +309 -0
- pdd/commands/connect.py +290 -0
- pdd/commands/fix.py +136 -113
- pdd/commands/maintenance.py +3 -2
- pdd/commands/misc.py +8 -0
- pdd/commands/modify.py +190 -164
- pdd/commands/sessions.py +284 -0
- 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 +27 -3
- pdd/core/cloud.py +237 -0
- 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 +204 -4
- 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-DQ3wkeQ2.js +449 -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 +459 -95
- pdd/load_prompt_template.py +15 -34
- pdd/path_resolution.py +140 -0
- pdd/postprocess.py +4 -1
- 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 +131 -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 +20 -1
- pdd/prompts/generate_test_from_example_LLM.prompt +115 -0
- pdd/prompts/insert_includes_LLM.prompt +262 -252
- pdd/prompts/prompt_code_diff_LLM.prompt +119 -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 +1322 -0
- pdd/server/routes/websocket.py +473 -0
- pdd/server/security.py +243 -0
- pdd/server/terminal_spawner.py +209 -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 +136 -75
- 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 +23 -5
- {pdd_cli-0.0.90.dist-info → pdd_cli-0.0.118.dist-info}/METADATA +15 -10
- pdd_cli-0.0.118.dist-info/RECORD +227 -0
- pdd_cli-0.0.90.dist-info/RECORD +0 -153
- {pdd_cli-0.0.90.dist-info → pdd_cli-0.0.118.dist-info}/WHEEL +0 -0
- {pdd_cli-0.0.90.dist-info → pdd_cli-0.0.118.dist-info}/entry_points.txt +0 -0
- {pdd_cli-0.0.90.dist-info → pdd_cli-0.0.118.dist-info}/licenses/LICENSE +0 -0
- {pdd_cli-0.0.90.dist-info → pdd_cli-0.0.118.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="/logo.svg" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>Prompt Driven Development</title>
|
|
8
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
9
|
+
<script>
|
|
10
|
+
tailwind.config = {
|
|
11
|
+
theme: {
|
|
12
|
+
screens: {
|
|
13
|
+
'xs': '475px',
|
|
14
|
+
'sm': '640px',
|
|
15
|
+
'md': '768px',
|
|
16
|
+
'lg': '1024px',
|
|
17
|
+
'xl': '1280px',
|
|
18
|
+
'2xl': '1536px',
|
|
19
|
+
},
|
|
20
|
+
extend: {
|
|
21
|
+
colors: {
|
|
22
|
+
surface: {
|
|
23
|
+
50: '#f8fafc',
|
|
24
|
+
100: '#f1f5f9',
|
|
25
|
+
200: '#e2e8f0',
|
|
26
|
+
300: '#cbd5e1',
|
|
27
|
+
400: '#94a3b8',
|
|
28
|
+
500: '#64748b',
|
|
29
|
+
600: '#475569',
|
|
30
|
+
700: '#334155',
|
|
31
|
+
800: '#1e293b',
|
|
32
|
+
900: '#0f172a',
|
|
33
|
+
950: '#020617',
|
|
34
|
+
},
|
|
35
|
+
accent: {
|
|
36
|
+
50: '#eff6ff',
|
|
37
|
+
100: '#dbeafe',
|
|
38
|
+
200: '#bfdbfe',
|
|
39
|
+
300: '#93c5fd',
|
|
40
|
+
400: '#60a5fa',
|
|
41
|
+
500: '#3b82f6',
|
|
42
|
+
600: '#2563eb',
|
|
43
|
+
700: '#1d4ed8',
|
|
44
|
+
800: '#1e40af',
|
|
45
|
+
900: '#1e3a8a',
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
fontFamily: {
|
|
49
|
+
sans: ['Inter', 'system-ui', '-apple-system', 'sans-serif'],
|
|
50
|
+
mono: ['JetBrains Mono', 'Fira Code', 'ui-monospace', 'monospace'],
|
|
51
|
+
},
|
|
52
|
+
boxShadow: {
|
|
53
|
+
'glow': '0 0 20px rgba(59, 130, 246, 0.3)',
|
|
54
|
+
'glow-lg': '0 0 40px rgba(59, 130, 246, 0.4)',
|
|
55
|
+
'inner-glow': 'inset 0 1px 0 rgba(255, 255, 255, 0.05)',
|
|
56
|
+
},
|
|
57
|
+
backdropBlur: {
|
|
58
|
+
xs: '2px',
|
|
59
|
+
},
|
|
60
|
+
animation: {
|
|
61
|
+
'fade-in': 'fadeIn 0.3s ease-out',
|
|
62
|
+
'slide-up': 'slideUp 0.3s ease-out',
|
|
63
|
+
'slide-down': 'slideDown 0.2s ease-out',
|
|
64
|
+
'scale-in': 'scaleIn 0.2s ease-out',
|
|
65
|
+
'pulse-slow': 'pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite',
|
|
66
|
+
'slide-in-right': 'slideInRight 0.25s ease-out',
|
|
67
|
+
},
|
|
68
|
+
textColor: {
|
|
69
|
+
text: {
|
|
70
|
+
primary: '#f1f5f9',
|
|
71
|
+
secondary: '#94a3b8',
|
|
72
|
+
muted: '#64748b',
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
}
|
|
78
|
+
</script>
|
|
79
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
80
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
81
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
|
82
|
+
<style>
|
|
83
|
+
* {
|
|
84
|
+
-webkit-font-smoothing: antialiased;
|
|
85
|
+
-moz-osx-font-smoothing: grayscale;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
body {
|
|
89
|
+
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/* Custom scrollbar - Webkit (Chrome, Safari, Edge) */
|
|
93
|
+
::-webkit-scrollbar {
|
|
94
|
+
width: 10px;
|
|
95
|
+
height: 10px;
|
|
96
|
+
}
|
|
97
|
+
::-webkit-scrollbar-track {
|
|
98
|
+
background: #1e293b;
|
|
99
|
+
border-radius: 5px;
|
|
100
|
+
}
|
|
101
|
+
::-webkit-scrollbar-thumb {
|
|
102
|
+
background: #475569;
|
|
103
|
+
border-radius: 5px;
|
|
104
|
+
border: 2px solid #1e293b;
|
|
105
|
+
}
|
|
106
|
+
::-webkit-scrollbar-thumb:hover {
|
|
107
|
+
background: #64748b;
|
|
108
|
+
}
|
|
109
|
+
::-webkit-scrollbar-corner {
|
|
110
|
+
background: #1e293b;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/* Firefox scrollbar */
|
|
114
|
+
* {
|
|
115
|
+
scrollbar-width: thin;
|
|
116
|
+
scrollbar-color: #475569 #1e293b;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/* Animations */
|
|
120
|
+
@keyframes fadeIn {
|
|
121
|
+
from { opacity: 0; transform: translateY(-10px); }
|
|
122
|
+
to { opacity: 1; transform: translateY(0); }
|
|
123
|
+
}
|
|
124
|
+
@keyframes slideUp {
|
|
125
|
+
from { opacity: 0; transform: translateY(20px); }
|
|
126
|
+
to { opacity: 1; transform: translateY(0); }
|
|
127
|
+
}
|
|
128
|
+
@keyframes slideDown {
|
|
129
|
+
from { opacity: 0; transform: translateY(-10px); }
|
|
130
|
+
to { opacity: 1; transform: translateY(0); }
|
|
131
|
+
}
|
|
132
|
+
@keyframes scaleIn {
|
|
133
|
+
from { opacity: 0; transform: scale(0.95); }
|
|
134
|
+
to { opacity: 1; transform: scale(1); }
|
|
135
|
+
}
|
|
136
|
+
@keyframes slideInRight {
|
|
137
|
+
from { opacity: 0; transform: translateX(20px); }
|
|
138
|
+
to { opacity: 1; transform: translateX(0); }
|
|
139
|
+
}
|
|
140
|
+
@keyframes indeterminate {
|
|
141
|
+
0% { transform: translateX(-100%); }
|
|
142
|
+
100% { transform: translateX(300%); }
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.animate-fade-in { animation: fadeIn 0.3s ease-out; }
|
|
146
|
+
.animate-indeterminate { animation: indeterminate 1.5s ease-in-out infinite; }
|
|
147
|
+
.animate-slide-up { animation: slideUp 0.3s ease-out; }
|
|
148
|
+
.animate-slide-down { animation: slideDown 0.2s ease-out; }
|
|
149
|
+
.animate-scale-in { animation: scaleIn 0.2s ease-out; }
|
|
150
|
+
.animate-slide-in-right { animation: slideInRight 0.25s ease-out; }
|
|
151
|
+
|
|
152
|
+
/* Glass morphism utility */
|
|
153
|
+
.glass {
|
|
154
|
+
background: rgba(30, 41, 59, 0.7);
|
|
155
|
+
backdrop-filter: blur(12px);
|
|
156
|
+
-webkit-backdrop-filter: blur(12px);
|
|
157
|
+
}
|
|
158
|
+
.glass-light {
|
|
159
|
+
background: rgba(51, 65, 85, 0.5);
|
|
160
|
+
backdrop-filter: blur(8px);
|
|
161
|
+
-webkit-backdrop-filter: blur(8px);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/* Gradient text utility */
|
|
165
|
+
.text-gradient {
|
|
166
|
+
background: linear-gradient(135deg, #60a5fa, #a78bfa);
|
|
167
|
+
-webkit-background-clip: text;
|
|
168
|
+
-webkit-text-fill-color: transparent;
|
|
169
|
+
background-clip: text;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/* Focus ring */
|
|
173
|
+
.focus-ring:focus {
|
|
174
|
+
outline: none;
|
|
175
|
+
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.5);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/* Card hover effect */
|
|
179
|
+
.card-hover {
|
|
180
|
+
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
|
181
|
+
}
|
|
182
|
+
.card-hover:hover {
|
|
183
|
+
transform: translateY(-2px);
|
|
184
|
+
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/* Markdown rendering styles */
|
|
188
|
+
.markdown-body {
|
|
189
|
+
color: #e2e8f0;
|
|
190
|
+
line-height: 1.7;
|
|
191
|
+
font-size: 15px;
|
|
192
|
+
}
|
|
193
|
+
.markdown-body h1, .markdown-body h2, .markdown-body h3,
|
|
194
|
+
.markdown-body h4, .markdown-body h5, .markdown-body h6 {
|
|
195
|
+
color: #f1f5f9;
|
|
196
|
+
font-weight: 600;
|
|
197
|
+
margin-top: 1.5em;
|
|
198
|
+
margin-bottom: 0.75em;
|
|
199
|
+
line-height: 1.3;
|
|
200
|
+
}
|
|
201
|
+
.markdown-body h1 { font-size: 2em; border-bottom: 1px solid #334155; padding-bottom: 0.3em; }
|
|
202
|
+
.markdown-body h2 { font-size: 1.5em; border-bottom: 1px solid #334155; padding-bottom: 0.3em; }
|
|
203
|
+
.markdown-body h3 { font-size: 1.25em; }
|
|
204
|
+
.markdown-body h4 { font-size: 1.1em; }
|
|
205
|
+
.markdown-body p { margin-bottom: 1em; }
|
|
206
|
+
.markdown-body ul, .markdown-body ol {
|
|
207
|
+
padding-left: 1.5em;
|
|
208
|
+
margin-bottom: 1em;
|
|
209
|
+
}
|
|
210
|
+
.markdown-body li { margin-bottom: 0.35em; }
|
|
211
|
+
.markdown-body ul { list-style-type: disc; }
|
|
212
|
+
.markdown-body ol { list-style-type: decimal; }
|
|
213
|
+
.markdown-body li > ul, .markdown-body li > ol { margin-top: 0.35em; margin-bottom: 0; }
|
|
214
|
+
.markdown-body code {
|
|
215
|
+
background: #1e293b;
|
|
216
|
+
padding: 0.2em 0.4em;
|
|
217
|
+
border-radius: 6px;
|
|
218
|
+
font-family: 'JetBrains Mono', 'Fira Code', ui-monospace, monospace;
|
|
219
|
+
font-size: 0.9em;
|
|
220
|
+
color: #93c5fd;
|
|
221
|
+
}
|
|
222
|
+
.markdown-body pre {
|
|
223
|
+
background: #0f172a;
|
|
224
|
+
border: 1px solid #334155;
|
|
225
|
+
border-radius: 8px;
|
|
226
|
+
padding: 1em;
|
|
227
|
+
overflow-x: auto;
|
|
228
|
+
margin-bottom: 1em;
|
|
229
|
+
}
|
|
230
|
+
.markdown-body pre code {
|
|
231
|
+
background: transparent;
|
|
232
|
+
padding: 0;
|
|
233
|
+
border-radius: 0;
|
|
234
|
+
color: #e2e8f0;
|
|
235
|
+
font-size: 0.875em;
|
|
236
|
+
}
|
|
237
|
+
.markdown-body blockquote {
|
|
238
|
+
border-left: 4px solid #3b82f6;
|
|
239
|
+
padding-left: 1em;
|
|
240
|
+
margin-left: 0;
|
|
241
|
+
margin-bottom: 1em;
|
|
242
|
+
color: #94a3b8;
|
|
243
|
+
font-style: italic;
|
|
244
|
+
}
|
|
245
|
+
.markdown-body a {
|
|
246
|
+
color: #60a5fa;
|
|
247
|
+
text-decoration: none;
|
|
248
|
+
}
|
|
249
|
+
.markdown-body a:hover { text-decoration: underline; }
|
|
250
|
+
.markdown-body hr {
|
|
251
|
+
border: none;
|
|
252
|
+
border-top: 1px solid #334155;
|
|
253
|
+
margin: 2em 0;
|
|
254
|
+
}
|
|
255
|
+
.markdown-body table {
|
|
256
|
+
width: 100%;
|
|
257
|
+
border-collapse: collapse;
|
|
258
|
+
margin-bottom: 1em;
|
|
259
|
+
}
|
|
260
|
+
.markdown-body th, .markdown-body td {
|
|
261
|
+
border: 1px solid #334155;
|
|
262
|
+
padding: 0.5em 0.75em;
|
|
263
|
+
text-align: left;
|
|
264
|
+
}
|
|
265
|
+
.markdown-body th {
|
|
266
|
+
background: #1e293b;
|
|
267
|
+
font-weight: 600;
|
|
268
|
+
}
|
|
269
|
+
.markdown-body img {
|
|
270
|
+
max-width: 100%;
|
|
271
|
+
border-radius: 8px;
|
|
272
|
+
}
|
|
273
|
+
.markdown-body strong { color: #f1f5f9; font-weight: 600; }
|
|
274
|
+
.markdown-body em { color: #cbd5e1; }
|
|
275
|
+
|
|
276
|
+
/* ReactFlow edge selection styles */
|
|
277
|
+
.react-flow__edge.selected .react-flow__edge-path {
|
|
278
|
+
stroke: #f97316 !important;
|
|
279
|
+
stroke-width: 3px !important;
|
|
280
|
+
}
|
|
281
|
+
.react-flow__edge:hover .react-flow__edge-path {
|
|
282
|
+
stroke: #60a5fa !important;
|
|
283
|
+
stroke-width: 2.5px !important;
|
|
284
|
+
}
|
|
285
|
+
.react-flow__edge.selected:hover .react-flow__edge-path {
|
|
286
|
+
stroke: #fb923c !important;
|
|
287
|
+
stroke-width: 3px !important;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/* CodeMirror Autocomplete styles */
|
|
291
|
+
.cm-tooltip {
|
|
292
|
+
z-index: 1000 !important;
|
|
293
|
+
}
|
|
294
|
+
.cm-tooltip.cm-tooltip-autocomplete {
|
|
295
|
+
background: #1e293b !important;
|
|
296
|
+
border: 1px solid #334155 !important;
|
|
297
|
+
border-radius: 8px !important;
|
|
298
|
+
box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.4) !important;
|
|
299
|
+
overflow: hidden !important;
|
|
300
|
+
}
|
|
301
|
+
.cm-tooltip.cm-tooltip-autocomplete > ul {
|
|
302
|
+
font-family: inherit !important;
|
|
303
|
+
max-height: 280px !important;
|
|
304
|
+
padding: 4px 0 !important;
|
|
305
|
+
}
|
|
306
|
+
.cm-tooltip.cm-tooltip-autocomplete > ul > li {
|
|
307
|
+
padding: 8px 12px !important;
|
|
308
|
+
display: flex !important;
|
|
309
|
+
align-items: center !important;
|
|
310
|
+
gap: 8px !important;
|
|
311
|
+
cursor: pointer !important;
|
|
312
|
+
}
|
|
313
|
+
.cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected] {
|
|
314
|
+
background: #3b82f6 !important;
|
|
315
|
+
color: white !important;
|
|
316
|
+
}
|
|
317
|
+
.cm-completionLabel {
|
|
318
|
+
color: #60a5fa !important;
|
|
319
|
+
font-weight: 500 !important;
|
|
320
|
+
}
|
|
321
|
+
.cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected] .cm-completionLabel {
|
|
322
|
+
color: white !important;
|
|
323
|
+
}
|
|
324
|
+
.cm-completionDetail {
|
|
325
|
+
color: #94a3b8 !important;
|
|
326
|
+
font-size: 11px !important;
|
|
327
|
+
margin-left: auto !important;
|
|
328
|
+
font-style: normal !important;
|
|
329
|
+
}
|
|
330
|
+
.cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected] .cm-completionDetail {
|
|
331
|
+
color: rgba(255, 255, 255, 0.8) !important;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/* Mobile responsive utilities */
|
|
335
|
+
/* Hide scrollbars utility */
|
|
336
|
+
.scrollbar-hide {
|
|
337
|
+
-ms-overflow-style: none;
|
|
338
|
+
scrollbar-width: none;
|
|
339
|
+
}
|
|
340
|
+
.scrollbar-hide::-webkit-scrollbar {
|
|
341
|
+
display: none;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/* Safe area insets for notched devices */
|
|
345
|
+
.safe-top {
|
|
346
|
+
padding-top: env(safe-area-inset-top);
|
|
347
|
+
}
|
|
348
|
+
.safe-bottom {
|
|
349
|
+
padding-bottom: env(safe-area-inset-bottom);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/* Prevent iOS zoom on input focus */
|
|
353
|
+
@media screen and (max-width: 640px) {
|
|
354
|
+
input, textarea, select {
|
|
355
|
+
font-size: 16px !important;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
</style>
|
|
359
|
+
|
|
360
|
+
<script type="importmap">
|
|
361
|
+
{
|
|
362
|
+
"imports": {
|
|
363
|
+
"react-dom/": "https://aistudiocdn.com/react-dom@^19.2.0/",
|
|
364
|
+
"react/": "https://aistudiocdn.com/react@^19.2.0/",
|
|
365
|
+
"react": "https://aistudiocdn.com/react@^19.2.0",
|
|
366
|
+
"@google/genai": "https://aistudiocdn.com/@google/genai@^0.15.0"
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
</script>
|
|
370
|
+
<script type="module" crossorigin src="/assets/index-DQ3wkeQ2.js"></script>
|
|
371
|
+
<link rel="stylesheet" crossorigin href="/assets/index-B5DZHykP.css">
|
|
372
|
+
</head>
|
|
373
|
+
<body class="bg-surface-950 text-gray-200">
|
|
374
|
+
<div id="root"></div>
|
|
375
|
+
</body>
|
|
376
|
+
</html>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<defs>
|
|
4
|
+
<filter id="glow" x="-60%" y="-60%" width="220%" height="220%">
|
|
5
|
+
<feGaussianBlur in="SourceGraphic" stdDeviation="40" result="blur"/>
|
|
6
|
+
<feMerge>
|
|
7
|
+
<feMergeNode in="blur"/>
|
|
8
|
+
<feMergeNode in="SourceGraphic"/>
|
|
9
|
+
</feMerge>
|
|
10
|
+
</filter>
|
|
11
|
+
</defs>
|
|
12
|
+
|
|
13
|
+
<g stroke="#00e3ff"
|
|
14
|
+
stroke-width="60"
|
|
15
|
+
stroke-linecap="round"
|
|
16
|
+
stroke-linejoin="round"
|
|
17
|
+
fill="none"
|
|
18
|
+
filter="url(#glow)">
|
|
19
|
+
|
|
20
|
+
<!-- speech-bubble "P" outline -->
|
|
21
|
+
<path d="
|
|
22
|
+
M 260 180
|
|
23
|
+
H 600
|
|
24
|
+
A 230 230 0 0 1 600 660
|
|
25
|
+
H 480
|
|
26
|
+
L 260 880
|
|
27
|
+
V 180
|
|
28
|
+
Z"/>
|
|
29
|
+
|
|
30
|
+
<!-- chevron shifted +15 px -->
|
|
31
|
+
<polyline points="505 340 585 420 505 500"/>
|
|
32
|
+
</g>
|
|
33
|
+
</svg>
|
pdd/generate_output_paths.py
CHANGED
|
@@ -156,17 +156,38 @@ CONTEXT_CONFIG_MAP: Dict[str, Dict[str, str]] = {
|
|
|
156
156
|
# --- Helper Function ---
|
|
157
157
|
|
|
158
158
|
def _get_default_filename(command: str, output_key: str, basename: str, language: str, file_extension: str) -> str:
|
|
159
|
-
"""Generates the default filename based on the command and output key.
|
|
159
|
+
"""Generates the default filename based on the command and output key.
|
|
160
|
+
|
|
161
|
+
Supports subdirectory basenames like 'core/cloud'. When the basename contains
|
|
162
|
+
a forward slash, the directory structure is preserved in the output:
|
|
163
|
+
- Directory part (e.g., 'core/') is prepended to the final filename
|
|
164
|
+
- Pattern is applied only to the name part (e.g., 'cloud')
|
|
165
|
+
|
|
166
|
+
Example: basename='core/cloud', pattern='test_{basename}{ext}'
|
|
167
|
+
Result: 'core/test_cloud.py' (NOT 'test_core/cloud.py')
|
|
168
|
+
"""
|
|
160
169
|
try:
|
|
170
|
+
# Split basename into directory and name components for subdirectory support
|
|
171
|
+
if '/' in basename:
|
|
172
|
+
dir_part, name_part = basename.rsplit('/', 1)
|
|
173
|
+
dir_prefix = dir_part + '/'
|
|
174
|
+
else:
|
|
175
|
+
dir_prefix = ''
|
|
176
|
+
name_part = basename
|
|
177
|
+
|
|
161
178
|
pattern = DEFAULT_FILENAMES[command][output_key]
|
|
179
|
+
|
|
162
180
|
# Use specific extension if in pattern, otherwise use language extension
|
|
163
181
|
if '{ext}' in pattern:
|
|
164
|
-
|
|
182
|
+
# Ensure file_extension starts with '.' if not empty
|
|
165
183
|
effective_extension = file_extension if file_extension.startswith('.') or not file_extension else '.' + file_extension
|
|
166
|
-
|
|
184
|
+
filename = pattern.format(basename=name_part, language=language, ext=effective_extension)
|
|
167
185
|
else:
|
|
168
186
|
# Pattern already contains the full extension (e.g., .prompt, .log, .csv)
|
|
169
|
-
|
|
187
|
+
filename = pattern.format(basename=name_part, language=language)
|
|
188
|
+
|
|
189
|
+
# Prepend directory part to preserve subdirectory structure
|
|
190
|
+
return dir_prefix + filename
|
|
170
191
|
except KeyError:
|
|
171
192
|
logger.error(f"Default filename pattern not found for command '{command}', output key '{output_key}'.")
|
|
172
193
|
# Fallback or raise error - returning a basic fallback for now
|
|
@@ -311,6 +332,11 @@ def generate_output_paths(
|
|
|
311
332
|
elif context_path:
|
|
312
333
|
source = "context"
|
|
313
334
|
|
|
335
|
+
# Check if the ORIGINAL context path ends with / (explicit complete directory)
|
|
336
|
+
# When user configures "context/" or "backend/functions/utils/", they mean
|
|
337
|
+
# "put files directly here" - don't add dir_prefix from basename
|
|
338
|
+
original_context_path_ends_with_slash = context_path.endswith('/')
|
|
339
|
+
|
|
314
340
|
# Resolve relative `.pddrc` paths based on path_resolution_mode.
|
|
315
341
|
# "cwd" mode: resolve relative to current working directory (for sync)
|
|
316
342
|
# "config_base" mode: resolve relative to config_base_dir (for fix, etc.)
|
|
@@ -335,7 +361,22 @@ def generate_output_paths(
|
|
|
335
361
|
|
|
336
362
|
if is_dir:
|
|
337
363
|
logger.debug(f"Context path '{context_path}' identified as a directory.")
|
|
338
|
-
|
|
364
|
+
# When the config path explicitly ends with /, it's a complete directory
|
|
365
|
+
# Don't add dir_prefix - generate filename with just the name part
|
|
366
|
+
if original_context_path_ends_with_slash:
|
|
367
|
+
# Extract just the name part without dir_prefix
|
|
368
|
+
if '/' in basename:
|
|
369
|
+
_, name_part = basename.rsplit('/', 1)
|
|
370
|
+
else:
|
|
371
|
+
name_part = basename
|
|
372
|
+
# Generate filename without dir_prefix
|
|
373
|
+
filename_without_prefix = _get_default_filename(
|
|
374
|
+
command, output_key, name_part, language, file_extension
|
|
375
|
+
)
|
|
376
|
+
final_path = os.path.join(context_path, filename_without_prefix)
|
|
377
|
+
logger.debug(f"Using explicit directory without dir_prefix: {final_path}")
|
|
378
|
+
else:
|
|
379
|
+
final_path = os.path.join(context_path, default_filename)
|
|
339
380
|
else:
|
|
340
381
|
logger.debug(f"Context path '{context_path}' identified as a specific file path.")
|
|
341
382
|
final_path = context_path
|