pdd-cli 0.0.45__py3-none-any.whl → 0.0.90__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 (114) hide show
  1. pdd/__init__.py +4 -4
  2. pdd/agentic_common.py +863 -0
  3. pdd/agentic_crash.py +534 -0
  4. pdd/agentic_fix.py +1179 -0
  5. pdd/agentic_langtest.py +162 -0
  6. pdd/agentic_update.py +370 -0
  7. pdd/agentic_verify.py +183 -0
  8. pdd/auto_deps_main.py +15 -5
  9. pdd/auto_include.py +63 -5
  10. pdd/bug_main.py +3 -2
  11. pdd/bug_to_unit_test.py +2 -0
  12. pdd/change_main.py +11 -4
  13. pdd/cli.py +22 -1181
  14. pdd/cmd_test_main.py +73 -21
  15. pdd/code_generator.py +58 -18
  16. pdd/code_generator_main.py +672 -25
  17. pdd/commands/__init__.py +42 -0
  18. pdd/commands/analysis.py +248 -0
  19. pdd/commands/fix.py +140 -0
  20. pdd/commands/generate.py +257 -0
  21. pdd/commands/maintenance.py +174 -0
  22. pdd/commands/misc.py +79 -0
  23. pdd/commands/modify.py +230 -0
  24. pdd/commands/report.py +144 -0
  25. pdd/commands/templates.py +215 -0
  26. pdd/commands/utility.py +110 -0
  27. pdd/config_resolution.py +58 -0
  28. pdd/conflicts_main.py +8 -3
  29. pdd/construct_paths.py +258 -82
  30. pdd/context_generator.py +10 -2
  31. pdd/context_generator_main.py +113 -11
  32. pdd/continue_generation.py +47 -7
  33. pdd/core/__init__.py +0 -0
  34. pdd/core/cli.py +503 -0
  35. pdd/core/dump.py +554 -0
  36. pdd/core/errors.py +63 -0
  37. pdd/core/utils.py +90 -0
  38. pdd/crash_main.py +44 -11
  39. pdd/data/language_format.csv +71 -63
  40. pdd/data/llm_model.csv +20 -18
  41. pdd/detect_change_main.py +5 -4
  42. pdd/fix_code_loop.py +330 -76
  43. pdd/fix_error_loop.py +207 -61
  44. pdd/fix_errors_from_unit_tests.py +4 -3
  45. pdd/fix_main.py +75 -18
  46. pdd/fix_verification_errors.py +12 -100
  47. pdd/fix_verification_errors_loop.py +306 -272
  48. pdd/fix_verification_main.py +28 -9
  49. pdd/generate_output_paths.py +93 -10
  50. pdd/generate_test.py +16 -5
  51. pdd/get_jwt_token.py +9 -2
  52. pdd/get_run_command.py +73 -0
  53. pdd/get_test_command.py +68 -0
  54. pdd/git_update.py +70 -19
  55. pdd/incremental_code_generator.py +2 -2
  56. pdd/insert_includes.py +11 -3
  57. pdd/llm_invoke.py +1269 -103
  58. pdd/load_prompt_template.py +36 -10
  59. pdd/pdd_completion.fish +25 -2
  60. pdd/pdd_completion.sh +30 -4
  61. pdd/pdd_completion.zsh +79 -4
  62. pdd/postprocess.py +10 -3
  63. pdd/preprocess.py +228 -15
  64. pdd/preprocess_main.py +8 -5
  65. pdd/prompts/agentic_crash_explore_LLM.prompt +49 -0
  66. pdd/prompts/agentic_fix_explore_LLM.prompt +45 -0
  67. pdd/prompts/agentic_fix_harvest_only_LLM.prompt +48 -0
  68. pdd/prompts/agentic_fix_primary_LLM.prompt +85 -0
  69. pdd/prompts/agentic_update_LLM.prompt +1071 -0
  70. pdd/prompts/agentic_verify_explore_LLM.prompt +45 -0
  71. pdd/prompts/auto_include_LLM.prompt +100 -905
  72. pdd/prompts/detect_change_LLM.prompt +122 -20
  73. pdd/prompts/example_generator_LLM.prompt +22 -1
  74. pdd/prompts/extract_code_LLM.prompt +5 -1
  75. pdd/prompts/extract_program_code_fix_LLM.prompt +7 -1
  76. pdd/prompts/extract_prompt_update_LLM.prompt +7 -8
  77. pdd/prompts/extract_promptline_LLM.prompt +17 -11
  78. pdd/prompts/find_verification_errors_LLM.prompt +6 -0
  79. pdd/prompts/fix_code_module_errors_LLM.prompt +4 -2
  80. pdd/prompts/fix_errors_from_unit_tests_LLM.prompt +8 -0
  81. pdd/prompts/fix_verification_errors_LLM.prompt +22 -0
  82. pdd/prompts/generate_test_LLM.prompt +21 -6
  83. pdd/prompts/increase_tests_LLM.prompt +1 -5
  84. pdd/prompts/insert_includes_LLM.prompt +228 -108
  85. pdd/prompts/trace_LLM.prompt +25 -22
  86. pdd/prompts/unfinished_prompt_LLM.prompt +85 -1
  87. pdd/prompts/update_prompt_LLM.prompt +22 -1
  88. pdd/pytest_output.py +127 -12
  89. pdd/render_mermaid.py +236 -0
  90. pdd/setup_tool.py +648 -0
  91. pdd/simple_math.py +2 -0
  92. pdd/split_main.py +3 -2
  93. pdd/summarize_directory.py +49 -6
  94. pdd/sync_determine_operation.py +543 -98
  95. pdd/sync_main.py +81 -31
  96. pdd/sync_orchestration.py +1334 -751
  97. pdd/sync_tui.py +848 -0
  98. pdd/template_registry.py +264 -0
  99. pdd/templates/architecture/architecture_json.prompt +242 -0
  100. pdd/templates/generic/generate_prompt.prompt +174 -0
  101. pdd/trace.py +168 -12
  102. pdd/trace_main.py +4 -3
  103. pdd/track_cost.py +151 -61
  104. pdd/unfinished_prompt.py +49 -3
  105. pdd/update_main.py +549 -67
  106. pdd/update_model_costs.py +2 -2
  107. pdd/update_prompt.py +19 -4
  108. {pdd_cli-0.0.45.dist-info → pdd_cli-0.0.90.dist-info}/METADATA +19 -6
  109. pdd_cli-0.0.90.dist-info/RECORD +153 -0
  110. {pdd_cli-0.0.45.dist-info → pdd_cli-0.0.90.dist-info}/licenses/LICENSE +1 -1
  111. pdd_cli-0.0.45.dist-info/RECORD +0 -116
  112. {pdd_cli-0.0.45.dist-info → pdd_cli-0.0.90.dist-info}/WHEEL +0 -0
  113. {pdd_cli-0.0.45.dist-info → pdd_cli-0.0.90.dist-info}/entry_points.txt +0 -0
  114. {pdd_cli-0.0.45.dist-info → pdd_cli-0.0.90.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,264 @@
1
+ from __future__ import annotations
2
+
3
+ import re
4
+ import shutil
5
+ from collections.abc import Iterable as IterableABC
6
+ from dataclasses import dataclass, field
7
+ from pathlib import Path
8
+ from typing import Any, Dict, Iterable, List, Optional, Tuple
9
+
10
+ from importlib.resources import as_file
11
+
12
+ try:
13
+ from importlib.resources import files as pkg_files
14
+ except ImportError: # pragma: no cover
15
+ # Fallback for Python < 3.11 if needed.
16
+ from importlib_resources import files as pkg_files # type: ignore[attr-defined]
17
+
18
+
19
+ _FRONT_MATTER_PATTERN = re.compile(r"^---\s*\r?\n(.*?)\r?\n---\s*\r?\n?", re.DOTALL)
20
+ _SOURCE_PRIORITY = {"packaged": 0, "project": 1}
21
+
22
+
23
+ @dataclass
24
+ class TemplateMeta:
25
+ name: str
26
+ path: Path
27
+ description: str = ""
28
+ version: str = ""
29
+ tags: List[str] = field(default_factory=list)
30
+ language: str = ""
31
+ output: str = ""
32
+ variables: Dict[str, Any] = field(default_factory=dict)
33
+ usage: Dict[str, Any] = field(default_factory=dict)
34
+ discover: Dict[str, Any] = field(default_factory=dict)
35
+ output_schema: Dict[str, Any] = field(default_factory=dict)
36
+ notes: str = ""
37
+ source: str = "packaged"
38
+
39
+ @property
40
+ def alias(self) -> str:
41
+ return self.path.stem
42
+
43
+
44
+ def _safe_load_yaml(text: str) -> Optional[Dict[str, Any]]:
45
+ try:
46
+ import yaml # type: ignore
47
+ except ImportError as exc: # pragma: no cover - PyYAML is an install requirement
48
+ raise RuntimeError("PyYAML is required to parse template front matter") from exc
49
+
50
+ try:
51
+ data = yaml.safe_load(text) or {}
52
+ except Exception:
53
+ return None
54
+ if not isinstance(data, dict):
55
+ return None
56
+ return data
57
+
58
+
59
+ def _parse_front_matter(text: str) -> Tuple[Optional[Dict[str, Any]], str]:
60
+ match = _FRONT_MATTER_PATTERN.match(text)
61
+ if not match:
62
+ return None, text
63
+ meta_text = match.group(1)
64
+ rest = text[match.end():]
65
+ meta = _safe_load_yaml(meta_text)
66
+ return meta, rest
67
+
68
+
69
+ def _normalize_tags(tags: Any) -> List[str]:
70
+ if tags is None:
71
+ return []
72
+ if isinstance(tags, str):
73
+ return [tags.lower()]
74
+ if isinstance(tags, IterableABC):
75
+ normalized: List[str] = []
76
+ for tag in tags:
77
+ if tag is None:
78
+ continue
79
+ normalized.append(str(tag).lower())
80
+ return normalized
81
+ return []
82
+
83
+
84
+ def _ensure_mapping(value: Any) -> Dict[str, Any]:
85
+ if isinstance(value, dict):
86
+ return dict(value)
87
+ return {}
88
+
89
+
90
+ def _normalize_meta(raw: Dict[str, Any], path: Path, source: str) -> TemplateMeta:
91
+ name = str(raw.get("name") or path.stem)
92
+ description = str(raw.get("description") or "")
93
+ version = str(raw.get("version") or "")
94
+ language = str(raw.get("language") or "")
95
+ output = str(raw.get("output") or "")
96
+ tags = _normalize_tags(raw.get("tags"))
97
+ notes_raw = raw.get("notes")
98
+ notes = "" if notes_raw is None else str(notes_raw)
99
+
100
+ return TemplateMeta(
101
+ name=name,
102
+ path=path.resolve(),
103
+ description=description,
104
+ version=version,
105
+ tags=tags,
106
+ language=language,
107
+ output=output,
108
+ variables=_ensure_mapping(raw.get("variables")),
109
+ usage=_ensure_mapping(raw.get("usage")),
110
+ discover=_ensure_mapping(raw.get("discover")),
111
+ output_schema=_ensure_mapping(raw.get("output_schema")),
112
+ notes=notes,
113
+ source=source,
114
+ )
115
+
116
+
117
+ def _iter_project_templates() -> Iterable[Path]:
118
+ root = Path.cwd() / "prompts"
119
+ if not root.exists():
120
+ return ()
121
+ return (path for path in root.rglob("*.prompt") if path.is_file())
122
+
123
+
124
+ def _iter_packaged_templates() -> Iterable[Path]:
125
+ try:
126
+ pkg_root = pkg_files("pdd").joinpath("templates")
127
+ except ModuleNotFoundError: # pragma: no cover - package missing
128
+ return ()
129
+ if not pkg_root.is_dir():
130
+ return ()
131
+
132
+ resolved: List[Path] = []
133
+ for entry in pkg_root.rglob("*.prompt"): # type: ignore[attr-defined]
134
+ try:
135
+ with as_file(entry) as concrete:
136
+ path = Path(concrete)
137
+ if path.is_file():
138
+ resolved.append(path)
139
+ except FileNotFoundError:
140
+ continue
141
+ return resolved
142
+
143
+
144
+ def _load_meta_from_path(path: Path, source: str) -> Optional[TemplateMeta]:
145
+ try:
146
+ text = path.read_text(encoding="utf-8")
147
+ except OSError:
148
+ return None
149
+ front_matter, _ = _parse_front_matter(text)
150
+ if not front_matter:
151
+ return None
152
+ return _normalize_meta(front_matter, path, source)
153
+
154
+
155
+ def _index_templates() -> Tuple[Dict[str, TemplateMeta], Dict[str, TemplateMeta]]:
156
+ by_name: Dict[str, TemplateMeta] = {}
157
+ priority: Dict[str, int] = {}
158
+
159
+ def register(meta: TemplateMeta) -> None:
160
+ current_priority = priority.get(meta.name, -1)
161
+ new_priority = _SOURCE_PRIORITY.get(meta.source, 0)
162
+ if new_priority < current_priority:
163
+ return
164
+ by_name[meta.name] = meta
165
+ priority[meta.name] = new_priority
166
+
167
+ for path in _iter_packaged_templates():
168
+ meta = _load_meta_from_path(Path(path), "packaged")
169
+ if meta:
170
+ register(meta)
171
+
172
+ for path in _iter_project_templates():
173
+ meta = _load_meta_from_path(Path(path), "project")
174
+ if meta:
175
+ register(meta)
176
+
177
+ lookup = dict(by_name)
178
+ lookup_priority = priority.copy()
179
+
180
+ for meta in by_name.values():
181
+ alias = meta.alias
182
+ alias_priority = lookup_priority.get(alias, -1)
183
+ meta_priority = priority.get(meta.name, 0)
184
+ if alias_priority <= meta_priority:
185
+ lookup[alias] = meta
186
+ lookup_priority[alias] = meta_priority
187
+
188
+ return by_name, lookup
189
+
190
+
191
+ def _meta_to_payload(meta: TemplateMeta) -> Dict[str, Any]:
192
+ return {
193
+ "name": meta.name,
194
+ "path": str(meta.path),
195
+ "description": meta.description,
196
+ "version": meta.version,
197
+ "tags": list(meta.tags),
198
+ "language": meta.language,
199
+ "output": meta.output,
200
+ "variables": dict(meta.variables),
201
+ "usage": dict(meta.usage),
202
+ "discover": dict(meta.discover),
203
+ "output_schema": dict(meta.output_schema),
204
+ "notes": meta.notes,
205
+ }
206
+
207
+
208
+ def list_templates(filter_tag: Optional[str] = None) -> List[Dict[str, Any]]:
209
+ by_name, _ = _index_templates()
210
+ normalized_tag = filter_tag.lower() if filter_tag else None
211
+ items: List[Dict[str, Any]] = []
212
+ for meta in by_name.values():
213
+ if normalized_tag and normalized_tag not in meta.tags:
214
+ continue
215
+ items.append({
216
+ "name": meta.name,
217
+ "path": str(meta.path),
218
+ "description": meta.description,
219
+ "version": meta.version,
220
+ "tags": list(meta.tags),
221
+ })
222
+ items.sort(key=lambda item: item["name"].lower())
223
+ return items
224
+
225
+
226
+ def load_template(name: str) -> Dict[str, Any]:
227
+ _, lookup = _index_templates()
228
+ meta = lookup.get(name)
229
+ if not meta:
230
+ raise FileNotFoundError(f"Template '{name}' not found.")
231
+ return _meta_to_payload(meta)
232
+
233
+
234
+ def show_template(name: str) -> Dict[str, Any]:
235
+ meta = load_template(name)
236
+ summary = {
237
+ "name": meta["name"],
238
+ "path": meta["path"],
239
+ "description": meta.get("description", ""),
240
+ "version": meta.get("version", ""),
241
+ "tags": meta.get("tags", []),
242
+ "language": meta.get("language", ""),
243
+ "output": meta.get("output", ""),
244
+ }
245
+ return {
246
+ "summary": summary,
247
+ "variables": meta.get("variables", {}),
248
+ "usage": meta.get("usage", {}),
249
+ "discover": meta.get("discover", {}),
250
+ "output_schema": meta.get("output_schema", {}),
251
+ "notes": meta.get("notes", ""),
252
+ }
253
+
254
+
255
+ def copy_template(name: str, dest_dir: str) -> str:
256
+ meta = load_template(name)
257
+ src = Path(meta["path"])
258
+ if not src.exists():
259
+ raise FileNotFoundError(f"Template '{name}' file is missing at {src}")
260
+ dest_root = Path(dest_dir)
261
+ dest_root.mkdir(parents=True, exist_ok=True)
262
+ dest_path = dest_root / src.name
263
+ shutil.copy2(src, dest_path)
264
+ return str(dest_path.resolve())
@@ -0,0 +1,242 @@
1
+ ---
2
+ name: architecture/architecture_json
3
+ description: Unified architecture template for multiple tech stacks
4
+ version: 1.0.0
5
+ tags: [architecture, template, json]
6
+ language: json
7
+ output: architecture.json
8
+ post_process_python: ./pdd/render_mermaid.py
9
+ post_process_args:
10
+ - "{INPUT_FILE}"
11
+ - "{APP_NAME}"
12
+ - "{OUTPUT_HTML}"
13
+ variables:
14
+ APP_NAME:
15
+ required: false
16
+ type: string
17
+ description: Optional app name for context.
18
+ example: Shop
19
+ PRD_FILE:
20
+ required: true
21
+ type: path
22
+ description: Primary product requirements document (PRD) describing scope and goals.
23
+ example_paths: [PRD.md, docs/specs.md, docs/product/prd.md]
24
+ example_content: |
25
+ Title: Order Management MVP
26
+ Goals: Enable customers to create and track orders end-to-end.
27
+ Key Features:
28
+ - Create Order: id, user_id, items[], total, status
29
+ - View Order: details page with status timeline
30
+ - List Orders: filter by status, date, user
31
+ Non-Functional Requirements:
32
+ - P95 latency < 300ms for read endpoints
33
+ - Error rate < 0.1%
34
+ TECH_STACK_FILE:
35
+ required: false
36
+ type: path
37
+ description: Tech stack overview (languages, frameworks, infrastructure, and tools).
38
+ example_paths: [docs/tech_stack.md, docs/architecture/stack.md]
39
+ example_content: |
40
+ Backend: Python (FastAPI), Postgres (SQLAlchemy), PyTest
41
+ Frontend: Next.js (TypeScript), shadcn/ui, Tailwind CSS
42
+ API: REST
43
+ Auth: Firebase Auth (GitHub Device Flow), JWT for API
44
+ Infra: Vercel (frontend), Cloud Run (backend), Cloud SQL (Postgres)
45
+ Observability: OpenTelemetry traces, Cloud Logging
46
+ DOC_FILES:
47
+ required: false
48
+ type: list
49
+ description: Additional documentation files (comma/newline-separated).
50
+ example_paths: [docs/ux.md, docs/components.md]
51
+ example_content: |
52
+ Design overview, patterns and constraints
53
+ INCLUDE_FILES:
54
+ required: false
55
+ type: list
56
+ description: Specific source files to include (comma/newline-separated).
57
+ example_paths: [src/app.py, src/api.py, frontend/app/layout.tsx, frontend/app/page.tsx]
58
+ usage:
59
+ generate:
60
+ - name: Minimal (PRD only)
61
+ command: pdd generate --template architecture/architecture_json -e PRD_FILE=docs/specs.md --output architecture.json
62
+ - name: With tech stack overview
63
+ command: pdd generate --template architecture/architecture_json -e PRD_FILE=docs/specs.md -e TECH_STACK_FILE=docs/tech_stack.md --output architecture.json
64
+
65
+ discover:
66
+ enabled: false
67
+ max_per_pattern: 5
68
+ max_total: 10
69
+
70
+ output_schema:
71
+ type: array
72
+ items:
73
+ type: object
74
+ required: [reason, description, dependencies, priority, filename, filepath]
75
+ properties:
76
+ reason: { type: string }
77
+ description: { type: string }
78
+ dependencies: { type: array, items: { type: string } }
79
+ priority: { type: integer, minimum: 1 }
80
+ filename: { type: string }
81
+ filepath: { type: string }
82
+ tags: { type: array, items: { type: string } }
83
+ interface:
84
+ type: object
85
+ properties:
86
+ type: { type: string, enum: [component, page, module, api, graphql, cli, job, message, config] }
87
+ component: { type: object }
88
+ page:
89
+ type: object
90
+ properties:
91
+ route: { type: string }
92
+ params:
93
+ type: array
94
+ items:
95
+ type: object
96
+ required: [name, type]
97
+ properties:
98
+ name: { type: string }
99
+ type: { type: string }
100
+ description: { type: string }
101
+ dataSources:
102
+ type: array
103
+ items:
104
+ type: object
105
+ required: [kind, source]
106
+ properties:
107
+ kind: { type: string, enum: [api, query, stream, file, cache, message, job, other] }
108
+ source: { type: string }
109
+ method: { type: string }
110
+ description: { type: string }
111
+ auth: { type: string }
112
+ inputs: { type: array, items: { type: string } }
113
+ outputs: { type: array, items: { type: string } }
114
+ refreshInterval: { type: string }
115
+ notes: { type: string }
116
+ layout: { type: object }
117
+ module: { type: object }
118
+ api: { type: object }
119
+ graphql: { type: object }
120
+ cli: { type: object }
121
+ job: { type: object }
122
+ message: { type: object }
123
+ config: { type: object }
124
+ ---
125
+
126
+ Purpose: Produce an architecture JSON that enumerates prompt files to generate code files for the project.
127
+
128
+ <PRD_FILE><include>${PRD_FILE}</include></PRD_FILE>
129
+ <TECH_STACK_FILE><include>${TECH_STACK_FILE}</include></TECH_STACK_FILE>
130
+ <DOC_FILES><include-many>${DOC_FILES}</include-many></DOC_FILES>
131
+
132
+ <INCLUDE_FILES><include-many>${INCLUDE_FILES}</include-many></INCLUDE_FILES>
133
+
134
+ INSTRUCTIONS:
135
+ - Use only the facts from the included documents and files. Do not invent technologies or filenames.
136
+ - If TECH_STACK_FILE is absent, infer a reasonable tech stack from the PRD and included files; state key assumptions within each item's description.
137
+ - Output a single top-level JSON array of items. Each item must include:
138
+ - reason (briefly explain why this code module needs to exist), description, dependencies (filenames), priority (1 = highest), filename, filepath, optional tags.
139
+ - interface: include only the applicable sub-object (component, page, module, api, graphql, cli, job, message, or config). Omit all non-applicable sub-objects entirely.
140
+ - When interface.type is "page", each entry in `dataSources` must be an object with at least `kind` and `source` (e.g., URL or identifier). The `kind` field MUST be exactly one of: `"api"`, `"query"`, `"stream"`, `"file"`, `"cache"`, `"message"`, `"job"`, or `"other"`. Do not invent new values like `"api/mutation"`; instead, use `"api"` (for any HTTP/REST/GraphQL endpoint) or `"other"` and describe details such as queries vs. mutations in `description` or `notes`. Provide `method`, `description`, and any other useful metadata when known.
141
+ - Valid JSON only. No comments or trailing commas.
142
+
143
+ OUTPUT FORMAT (authoritative):
144
+ ```json
145
+ {
146
+ "type": "array",
147
+ "items": {
148
+ "type": "object",
149
+ "required": ["reason", "description", "dependencies", "priority", "filename", "filepath"],
150
+ "properties": {
151
+ "reason": {"type": "string"},
152
+ "description": {"type": "string"},
153
+ "dependencies": {"type": "array", "items": {"type": "string"}},
154
+ "priority": {"type": "integer", "minimum": 1},
155
+ "filename": {"type": "string"},
156
+ "filepath": {"type": "string"},
157
+ "tags": {"type": "array", "items": {"type": "string"}},
158
+ "interface": {
159
+ "type": "object",
160
+ "properties": {
161
+ "type": {"type": "string", "enum": ["component", "page", "module", "api", "graphql", "cli", "job", "message", "config"]},
162
+ "component": {"type": "object"},
163
+ "page": {
164
+ "type": "object",
165
+ "properties": {
166
+ "route": {"type": "string"},
167
+ "params": {
168
+ "type": "array",
169
+ "items": {
170
+ "type": "object",
171
+ "required": ["name", "type"],
172
+ "properties": {
173
+ "name": {"type": "string"},
174
+ "type": {"type": "string"},
175
+ "description": {"type": "string"}
176
+ }
177
+ }
178
+ }
179
+ }
180
+ },
181
+ "module": {"type": "object"},
182
+ "api": {"type": "object"},
183
+ "graphql": {"type": "object"},
184
+ "cli": {"type": "object"},
185
+ "job": {"type": "object"},
186
+ "message": {"type": "object"},
187
+ "config": {"type": "object"}
188
+ }
189
+ }
190
+ }
191
+ }
192
+ }
193
+ ```
194
+
195
+ INTERFACE TYPES (emit only applicable):
196
+ - page: route (string), params? (array of {name, type, description?}), dataSources? (array), layout? (object)
197
+ - component: props (array of {name, type, required?}), emits? (array), context? (array)
198
+ - module: functions (array of {name, signature, returns?, errors?, sideEffects?})
199
+ - api: endpoints (array of {method, path, auth?, requestSchema?, responseSchema?, errors?})
200
+ - graphql: sdl? (string) or operations {queries?[], mutations?[], subscriptions?[]}
201
+ - cli: commands (array of {name, args?[], flags?[], exitCodes?[]}), io? {stdin?, stdout?}
202
+ - job: trigger {schedule? | event?}, inputs? (array), outputs? (array), retryPolicy? (string)
203
+ - message: topics (array of {name, direction: "publish"|"subscribe", schema?, qos?})
204
+ - config: keys (array of {name, type, default?, required?, source: "env"|"file"|"secret"})
205
+
206
+ FILENAME CONVENTIONS:
207
+ - The "filename" field is the prompt filename to generate (not the code file). Use PDD convention: <base>_<LangOrFramework>.prompt where <LangOrFramework> matches the tech stack.
208
+ - Examples (adapt to your stack):
209
+ - Next.js (TypeScript React): page_TypeScriptReact.prompt -> generates page.tsx; layout_TypeScriptReact.prompt -> layout.tsx
210
+ - Python backend: api_Python.prompt -> api.py; orders_Python.prompt -> orders.py
211
+ - Choose descriptive <base> names (e.g., orders_page, orders_api) and keep names consistent across dependencies.
212
+
213
+ FILEPATH CONVENTIONS:
214
+ - The "filepath" field specifies the path of the output source file from the source tree root, using conventions appropriate for the language and framework.
215
+ - Examples (adapt to your stack):
216
+ - Next.js app router: app/orders/page.tsx, app/layout.tsx, app/api/orders/route.ts
217
+ - Next.js pages router: pages/orders.tsx, pages/api/orders.ts
218
+ - Python FastAPI: src/api.py, src/orders.py, src/models/order.py
219
+ - React components: src/components/OrderList.tsx, src/hooks/useOrders.ts
220
+ - Config files: .env.example, pyproject.toml, package.json
221
+ - Use forward slashes (/) for path separators regardless of OS.
222
+ - Include the appropriate file extension for the target language (.tsx, .py, .rs, .go, etc.).
223
+ - Follow standard directory structures for the framework (e.g., app/ for Next.js 13+, src/ for typical React/Python projects).
224
+
225
+ DEPENDENCY RULES:
226
+ - The "dependencies" array must list other items by their prompt filenames (the "filename" values), not code filenames.
227
+ - Do not reference files that are not part of this array unless they were explicitly provided via INCLUDE_FILES/DOC_FILES.
228
+ - Avoid cycles; if a cycle is necessary, justify it in the description and clarify initialization order.
229
+
230
+ PRIORITY AND ORDERING:
231
+ - Use unique integer priorities starting at 1 without gaps (1,2,3,...).
232
+ - Sort the top-level array by ascending priority.
233
+
234
+ TAGS (optional):
235
+ - Use short, lower-case tags for slicing (e.g., ["frontend","nextjs"], ["backend","api"], ["config"]).
236
+
237
+ CONTENT GUIDANCE:
238
+ - Descriptions must be architectural and actionable: responsibilities, interfaces, error handling, cross-cutting concerns.
239
+ - For API items, outline endpoints (method, path, auth) and high-level request/response shapes.
240
+ - For page/component items, include the route, key props, and data sources.
241
+
242
+ DO NOT INCLUDE the schema or these conventions in the output; return only the JSON array.
@@ -0,0 +1,174 @@
1
+ ---
2
+ name: generic/generate_prompt
3
+ description: Generate a module prompt (.prompt) for any stack (backend, frontend, CLI, jobs) using project docs and context
4
+ version: 1.0.0
5
+ tags: [template, prompt, generic]
6
+ language: prompt
7
+ output: prompts/${MODULE}_${LANG_OR_FRAMEWORK}.prompt
8
+ variables:
9
+ MODULE:
10
+ required: true
11
+ type: string
12
+ description: Module/component basename to generate a prompt for.
13
+ examples: [orders, auth, users]
14
+ LANG_OR_FRAMEWORK:
15
+ required: false
16
+ type: string
17
+ description: Target language or framework suffix used in prompt naming (matches your stack conventions).
18
+ examples: [Python, TypeScriptReact, Go, Java, Ruby]
19
+ default: Python
20
+ LAYER:
21
+ required: false
22
+ type: string
23
+ description: System layer or interface type for context.
24
+ examples: [backend, frontend, api, graphql, cli, job, message, config, module, component, page]
25
+ PRD_FILE:
26
+ required: false
27
+ type: path
28
+ description: Product requirements document providing overall context.
29
+ example_paths: [PRD.md, docs/product/prd.md]
30
+ API_DOC_FILE:
31
+ required: false
32
+ type: path
33
+ description: API documentation describing endpoints and conventions.
34
+ example_paths: [docs/api-documentation.md, docs/api.md]
35
+ DB_SCHEMA_FILE:
36
+ required: false
37
+ type: path
38
+ description: Database schema or ERD for backend data models.
39
+ example_paths: [context/database-schema.md, docs/db/schema.md]
40
+ BACKEND_FILES_CSV:
41
+ required: false
42
+ type: path
43
+ description: CSV listing backend Python files/modules (for context/reference).
44
+ example_paths: [prompts/backend/python_architecture.csv]
45
+ IO_DEPENDENCIES_CSV:
46
+ required: false
47
+ type: path
48
+ description: CSV of function inputs/outputs and dependencies for backend modules.
49
+ example_paths: [prompts/backend/io_dependencies.csv]
50
+ ARCHITECTURE_FILE:
51
+ required: true
52
+ type: path
53
+ description: Architecture JSON (from architecture/architecture_json) to drive module scope, dependencies, and interface.
54
+ example_paths: [architecture.json]
55
+ TECH_STACK_FILE:
56
+ required: false
57
+ type: path
58
+ description: Tech stack overview (languages, frameworks, infrastructure, tools) for shaping conventions.
59
+ example_paths: [docs/tech_stack.md, docs/architecture/stack.md]
60
+ CODE_GENERATOR_PROMPT:
61
+ required: false
62
+ type: path
63
+ description: Reference code generator prompt to mirror style and expectations.
64
+ example_paths: [prompts/code_generator_python.prompt, prompts/code_generator_main_python.prompt]
65
+ EXISTING_PROMPTS:
66
+ required: false
67
+ type: list
68
+ description: Existing prompt files to use as reference (comma/newline-separated).
69
+ example_paths: [prompts/orders_python.prompt, prompts/auth_python.prompt]
70
+ DEP_EXAMPLE_EXT:
71
+ required: false
72
+ type: string
73
+ description: File extension for dependency examples under context/ (for non-Python stacks).
74
+ examples: [py, ts, tsx, go, java]
75
+ default: py
76
+ usage:
77
+ generate:
78
+ - name: Minimal (architecture only)
79
+ command: pdd generate --template generic/generate_prompt -e MODULE=orders -e LANG_OR_FRAMEWORK=Python -e ARCHITECTURE_FILE=architecture.json --output 'prompts/${MODULE}_${LANG_OR_FRAMEWORK}.prompt'
80
+ - name: With project docs
81
+ command: pdd generate --template generic/generate_prompt -e MODULE=orders -e LANG_OR_FRAMEWORK=Python -e ARCHITECTURE_FILE=architecture.json -e PRD_FILE=docs/PRD.md -e API_DOC_FILE=docs/api-documentation.md -e DB_SCHEMA_FILE=context/database-schema.md --output 'prompts/${MODULE}_${LANG_OR_FRAMEWORK}.prompt'
82
+ - name: With CSVs and references (backend/Python)
83
+ command: pdd generate --template generic/generate_prompt -e MODULE=orders -e LANG_OR_FRAMEWORK=Python -e ARCHITECTURE_FILE=architecture.json -e PRD_FILE=docs/PRD.md -e API_DOC_FILE=docs/api-documentation.md -e DB_SCHEMA_FILE=context/database-schema.md -e BACKEND_FILES_CSV=prompts/backend/python_architecture.csv -e IO_DEPENDENCIES_CSV=prompts/backend/io_dependencies.csv -e CODE_GENERATOR_PROMPT=prompts/code_generator_python.prompt --output 'prompts/${MODULE}_${LANG_OR_FRAMEWORK}.prompt'
84
+ - name: Frontend (TypeScriptReact) variant
85
+ command: pdd generate --template generic/generate_prompt -e MODULE=profile_page -e LANG_OR_FRAMEWORK=TypeScriptReact -e LAYER=frontend -e ARCHITECTURE_FILE=architecture.json -e PRD_FILE=docs/PRD.md --output 'prompts/${MODULE}_${LANG_OR_FRAMEWORK}.prompt'
86
+ - name: From architecture.json
87
+ command: pdd generate --template generic/generate_prompt -e MODULE=orders_api -e LANG_OR_FRAMEWORK=Python -e LAYER=api -e ARCHITECTURE_FILE=architecture.json --output 'prompts/${MODULE}_${LANG_OR_FRAMEWORK}.prompt'
88
+
89
+ discover:
90
+ enabled: false
91
+ max_per_pattern: 5
92
+ max_total: 10
93
+ ---
94
+
95
+ % You are an expert prompt writer and software architect for PDD. Your goal is to write a high-quality prompt that will generate the code for the ${MODULE} module/component. The prompt you create will be used to produce a detailed implementation specification in a file named ${MODULE}_${LANG_OR_FRAMEWORK}.prompt, suitable for the specified stack and layer.
96
+
97
+ IMPORTANT: Your reply MUST begin with `<prompt>` on the very first line and end with `</prompt>` on the final line. Do not include any text, whitespace, or code fences outside this block.
98
+
99
+ % Project context (architecture required, others optional):
100
+ <prd><include>${PRD_FILE}</include></prd>
101
+ <api><include>${API_DOC_FILE}</include></api>
102
+ <database><include>${DB_SCHEMA_FILE}</include></database>
103
+ <backend_files_csv><include>${BACKEND_FILES_CSV}</include></backend_files_csv>
104
+ <io_dependencies_csv><include>${IO_DEPENDENCIES_CSV}</include></io_dependencies_csv>
105
+ <architecture><include>${ARCHITECTURE_FILE}</include></architecture>
106
+ <tech_stack><include>${TECH_STACK_FILE}</include></tech_stack>
107
+ <generate_code_cli_example><include>${CODE_GENERATOR_PROMPT}</include></generate_code_cli_example>
108
+
109
+ % Existing prompt references (optional):
110
+ <existing_backend_prompts><include-many>${EXISTING_PROMPTS}</include-many></existing_backend_prompts>
111
+
112
+ % Do the following:
113
+ - Explain concisely what you are going to do (create a prompt for the ${MODULE} module/component for the specified layer and stack).
114
+ - Analyze any difficulties this prompt might encounter for ${MODULE} (e.g., data modeling, API or UI contracts, transactions, idempotency, auth, state management, error handling) and briefly state mitigation strategies tailored to the given LAYER and LANG_OR_FRAMEWORK.
115
+ - Use the ARCHITECTURE_FILE to identify the item that corresponds to this prompt by matching `filename` to `${MODULE}_${LANG_OR_FRAMEWORK}.prompt` (or best match by basename and layer). Use that item’s `reason`, `description`, `dependencies`, `interface`, and `tags` to shape the sections below.
116
+ - Then create the prompt content for ${MODULE} inside XML tags named prompt, ensuring conventions fit the stack and layer.
117
+ - Ensure the final response consists solely of the `<prompt>...</prompt>` block; nothing else (including whitespace) may appear before `<prompt>` or after `</prompt>`.
118
+
119
+ % The prompt you generate must follow this structure:
120
+ 1) First paragraph: describe the role and responsibility of the ${MODULE} module/component within the system (consider the LAYER if provided).
121
+ 2) A "Requirements" section with numbered points covering functionality, contracts, error handling, validation, logging, performance, and security.
122
+ 3) A "Dependencies" section using XML include tags for each dependency (see format below).
123
+ 4) An "Instructions" section with precise implementation guidance (clarify inputs/outputs, function/class responsibilities, edge cases, and testing notes).
124
+ 5) A clear "Deliverable" section describing the expected code artifacts and entry points.
125
+
126
+ % Dependencies format and conventions:
127
+ - Represent each dependency using an XML tag with the dependency name, and put the file path inside an <include> tag, e.g.:
128
+ <orders_service>
129
+ <include>context/orders_service_example.${DEP_EXAMPLE_EXT}</include>
130
+ </orders_service>
131
+ - Prefer real example files available in the provided context (use <include-many> when listing multiple). If examples are not provided, assume dependency examples live under context/ using the pattern context/[dependency_name]_example.${DEP_EXAMPLE_EXT}.
132
+ - Include all necessary dependencies for the module/component (based on the provided context and references).
133
+ - The ARCHITECTURE_FILE lists `dependencies` referencing other prompt filenames. Convert each dependency prompt filename into a sensible dependency name (strip language suffix and `_prompt`), and map to context files with the `${DEP_EXAMPLE_EXT}` extension if present; otherwise, list the prompt filename explicitly in a "Prompt Dependencies" subsection.
134
+
135
+ % Architecture awareness (ARCHITECTURE_FILE is required):
136
+ - Align the "Requirements" and "Instructions" with the selected item’s `interface.type` (e.g., page, component, module, api, graphql, cli, job, message, config).
137
+ - For `api`, outline endpoints (method, path, auth) consistent with the architecture description; for `page`/`component`, describe route/props/data sources; for `job`, include trigger and retry policy; for `config`, list keys and sources.
138
+
139
+ % Style and quality requirements:
140
+ - The generated prompt must be detailed enough to yield production-ready code.
141
+ - Match the style and patterns of existing *_${LANG_OR_FRAMEWORK}.prompt files when present.
142
+ - Do not invent technologies or files; rely on the included context. If assumptions are necessary, state them explicitly and conservatively.
143
+
144
+ % Output contract:
145
+ - Start the output with `<prompt>` on its own line and end with `</prompt>` on its own line.
146
+ - Do not emit any characters (including whitespace, markdown fences, or commentary) outside the `<prompt>...</prompt>` block.
147
+ - Within the tags, include the sections described above as plain text.
148
+ - OUTPUT FORMAT (authoritative – copy/paste and replace the bracketed placeholders, keeping every literal token):
149
+ ```text
150
+ <prompt>
151
+ {ROLE_PARAGRAPH}
152
+ Requirements
153
+ 1. {REQ_ITEM_1}
154
+ 2. {REQ_ITEM_2}
155
+ Dependencies
156
+ <{DEPENDENCY_TAG_1}>
157
+ <include>{DEPENDENCY_INCLUDE_1}</include>
158
+ </{DEPENDENCY_TAG_1}>
159
+ {OPTIONAL_ADDITIONAL_DEPENDENCY_TAGS}
160
+ Prompt Dependencies:
161
+ {PROMPT_DEPENDENCIES_SECTION}
162
+ Instructions
163
+ - {INSTRUCTION_1}
164
+ - {INSTRUCTION_2}
165
+ Deliverable
166
+ - {DELIVERABLE_1}
167
+ - {DELIVERABLE_2}
168
+ Implementation assumptions (explicit)
169
+ - {ASSUMPTION_1}
170
+ - {ASSUMPTION_2}
171
+ Please produce production-ready prompt content that will generate the module consistent with the above.
172
+ </prompt>
173
+ ```
174
+ Replace each `{PLACEHOLDER}` with concrete content while preserving the surrounding structure and literal `<prompt>` / `<include>` tags.