@dzhechkov/skills-idea2prd 0.1.0
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.
- package/LICENSE +21 -0
- package/README.md +71 -0
- package/bin/cli.js +5 -0
- package/package.json +49 -0
- package/sources.json +25 -0
- package/src/cli.js +108 -0
- package/src/commands/doctor.js +340 -0
- package/src/commands/init.js +168 -0
- package/src/commands/list.js +146 -0
- package/src/commands/remove.js +182 -0
- package/src/commands/update.js +170 -0
- package/src/utils.js +154 -0
- package/templates/.claude/commands/idea2prd-manual.md +35 -0
- package/templates/.claude/skills/explore/SKILL.md +218 -0
- package/templates/.claude/skills/explore/references/questioning-techniques.md +151 -0
- package/templates/.claude/skills/explore/references/task-brief-templates.md +355 -0
- package/templates/.claude/skills/goap-research-ed25519/SKILL.md +418 -0
- package/templates/.claude/skills/goap-research-ed25519/references/ed25519-verification.md +658 -0
- package/templates/.claude/skills/goap-research-ed25519/references/research-actions.md +544 -0
- package/templates/.claude/skills/goap-research-ed25519/references/source-evaluation.md +560 -0
- package/templates/.claude/skills/goap-research-ed25519/scripts/ed25519_verifier.py +662 -0
- package/templates/.claude/skills/goap-research-ed25519/scripts/goap_planner.py +720 -0
- package/templates/.claude/skills/idea2prd-manual/SKILL.md +695 -0
- package/templates/.claude/skills/idea2prd-manual/references/adr-catalog.md +288 -0
- package/templates/.claude/skills/idea2prd-manual/references/c4-model.md +277 -0
- package/templates/.claude/skills/idea2prd-manual/references/completion-checklist-template.md +446 -0
- package/templates/.claude/skills/idea2prd-manual/references/ddd-patterns.md +261 -0
- package/templates/.claude/skills/idea2prd-manual/references/fitness-functions-catalog.md +414 -0
- package/templates/.claude/skills/idea2prd-manual/references/pseudocode-style.md +404 -0
- package/templates/.claude/skills/idea2prd-manual/scripts/ai_context_builder.py +491 -0
- package/templates/.claude/skills/idea2prd-manual/scripts/c4_generator.py +311 -0
- package/templates/.claude/skills/idea2prd-manual/scripts/fitness_validator.py +451 -0
- package/templates/.claude/skills/idea2prd-manual/scripts/pseudocode_generator.py +430 -0
- package/templates/.claude/skills/problem-solver-enhanced/SKILL.md +565 -0
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
C4 Model Diagram Generator for idea2prd skills.
|
|
4
|
+
Generates Mermaid C4 diagrams from structured input.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass, field
|
|
8
|
+
from typing import List, Optional
|
|
9
|
+
from enum import Enum
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ContainerType(Enum):
|
|
13
|
+
WEB_APP = "Container"
|
|
14
|
+
API = "Container"
|
|
15
|
+
DATABASE = "ContainerDb"
|
|
16
|
+
QUEUE = "ContainerQueue"
|
|
17
|
+
MOBILE = "Container"
|
|
18
|
+
WORKER = "Container"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass
|
|
22
|
+
class Person:
|
|
23
|
+
alias: str
|
|
24
|
+
name: str
|
|
25
|
+
description: str = ""
|
|
26
|
+
external: bool = False
|
|
27
|
+
|
|
28
|
+
def to_mermaid(self) -> str:
|
|
29
|
+
func = "Person_Ext" if self.external else "Person"
|
|
30
|
+
return f'{func}({self.alias}, "{self.name}", "{self.description}")'
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@dataclass
|
|
34
|
+
class System:
|
|
35
|
+
alias: str
|
|
36
|
+
name: str
|
|
37
|
+
description: str = ""
|
|
38
|
+
external: bool = False
|
|
39
|
+
|
|
40
|
+
def to_mermaid(self) -> str:
|
|
41
|
+
func = "System_Ext" if self.external else "System"
|
|
42
|
+
return f'{func}({self.alias}, "{self.name}", "{self.description}")'
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@dataclass
|
|
46
|
+
class Container:
|
|
47
|
+
alias: str
|
|
48
|
+
name: str
|
|
49
|
+
technology: str
|
|
50
|
+
description: str
|
|
51
|
+
container_type: ContainerType = ContainerType.API
|
|
52
|
+
|
|
53
|
+
def to_mermaid(self) -> str:
|
|
54
|
+
return f'{self.container_type.value}({self.alias}, "{self.name}", "{self.technology}", "{self.description}")'
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@dataclass
|
|
58
|
+
class Component:
|
|
59
|
+
alias: str
|
|
60
|
+
name: str
|
|
61
|
+
technology: str
|
|
62
|
+
description: str
|
|
63
|
+
|
|
64
|
+
def to_mermaid(self) -> str:
|
|
65
|
+
return f'Component({self.alias}, "{self.name}", "{self.technology}", "{self.description}")'
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@dataclass
|
|
69
|
+
class Relationship:
|
|
70
|
+
from_alias: str
|
|
71
|
+
to_alias: str
|
|
72
|
+
label: str
|
|
73
|
+
technology: str = ""
|
|
74
|
+
|
|
75
|
+
def to_mermaid(self) -> str:
|
|
76
|
+
if self.technology:
|
|
77
|
+
return f'Rel({self.from_alias}, {self.to_alias}, "{self.label}", "{self.technology}")'
|
|
78
|
+
return f'Rel({self.from_alias}, {self.to_alias}, "{self.label}")'
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@dataclass
|
|
82
|
+
class C4Diagram:
|
|
83
|
+
title: str
|
|
84
|
+
elements: List = field(default_factory=list)
|
|
85
|
+
relationships: List[Relationship] = field(default_factory=list)
|
|
86
|
+
boundaries: dict = field(default_factory=dict)
|
|
87
|
+
|
|
88
|
+
def add_person(self, alias: str, name: str, description: str = "", external: bool = False):
|
|
89
|
+
self.elements.append(Person(alias, name, description, external))
|
|
90
|
+
return self
|
|
91
|
+
|
|
92
|
+
def add_system(self, alias: str, name: str, description: str = "", external: bool = False):
|
|
93
|
+
self.elements.append(System(alias, name, description, external))
|
|
94
|
+
return self
|
|
95
|
+
|
|
96
|
+
def add_container(self, alias: str, name: str, technology: str, description: str,
|
|
97
|
+
container_type: ContainerType = ContainerType.API, boundary: str = None):
|
|
98
|
+
container = Container(alias, name, technology, description, container_type)
|
|
99
|
+
if boundary:
|
|
100
|
+
if boundary not in self.boundaries:
|
|
101
|
+
self.boundaries[boundary] = []
|
|
102
|
+
self.boundaries[boundary].append(container)
|
|
103
|
+
else:
|
|
104
|
+
self.elements.append(container)
|
|
105
|
+
return self
|
|
106
|
+
|
|
107
|
+
def add_component(self, alias: str, name: str, technology: str, description: str, boundary: str = None):
|
|
108
|
+
component = Component(alias, name, technology, description)
|
|
109
|
+
if boundary:
|
|
110
|
+
if boundary not in self.boundaries:
|
|
111
|
+
self.boundaries[boundary] = []
|
|
112
|
+
self.boundaries[boundary].append(component)
|
|
113
|
+
else:
|
|
114
|
+
self.elements.append(component)
|
|
115
|
+
return self
|
|
116
|
+
|
|
117
|
+
def add_relationship(self, from_alias: str, to_alias: str, label: str, technology: str = ""):
|
|
118
|
+
self.relationships.append(Relationship(from_alias, to_alias, label, technology))
|
|
119
|
+
return self
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class C4Generator:
|
|
123
|
+
"""Generates C4 diagrams in Mermaid format."""
|
|
124
|
+
|
|
125
|
+
@staticmethod
|
|
126
|
+
def generate_context_diagram(diagram: C4Diagram) -> str:
|
|
127
|
+
"""Generate Level 1: System Context diagram."""
|
|
128
|
+
lines = [
|
|
129
|
+
"```mermaid",
|
|
130
|
+
"C4Context",
|
|
131
|
+
f' title {diagram.title}',
|
|
132
|
+
""
|
|
133
|
+
]
|
|
134
|
+
|
|
135
|
+
# Add elements
|
|
136
|
+
for elem in diagram.elements:
|
|
137
|
+
lines.append(f" {elem.to_mermaid()}")
|
|
138
|
+
|
|
139
|
+
lines.append("")
|
|
140
|
+
|
|
141
|
+
# Add relationships
|
|
142
|
+
for rel in diagram.relationships:
|
|
143
|
+
lines.append(f" {rel.to_mermaid()}")
|
|
144
|
+
|
|
145
|
+
lines.append("```")
|
|
146
|
+
return "\n".join(lines)
|
|
147
|
+
|
|
148
|
+
@staticmethod
|
|
149
|
+
def generate_container_diagram(diagram: C4Diagram, system_name: str) -> str:
|
|
150
|
+
"""Generate Level 2: Container diagram."""
|
|
151
|
+
lines = [
|
|
152
|
+
"```mermaid",
|
|
153
|
+
"C4Container",
|
|
154
|
+
f' title {diagram.title}',
|
|
155
|
+
""
|
|
156
|
+
]
|
|
157
|
+
|
|
158
|
+
# Add non-boundary elements (persons, external systems)
|
|
159
|
+
for elem in diagram.elements:
|
|
160
|
+
if isinstance(elem, (Person, System)):
|
|
161
|
+
lines.append(f" {elem.to_mermaid()}")
|
|
162
|
+
|
|
163
|
+
lines.append("")
|
|
164
|
+
|
|
165
|
+
# Add system boundary with containers
|
|
166
|
+
if diagram.boundaries:
|
|
167
|
+
for boundary_name, containers in diagram.boundaries.items():
|
|
168
|
+
lines.append(f' Container_Boundary({boundary_name.lower().replace(" ", "_")}, "{boundary_name}") {{')
|
|
169
|
+
for container in containers:
|
|
170
|
+
lines.append(f" {container.to_mermaid()}")
|
|
171
|
+
lines.append(" }")
|
|
172
|
+
lines.append("")
|
|
173
|
+
|
|
174
|
+
# Add relationships
|
|
175
|
+
for rel in diagram.relationships:
|
|
176
|
+
lines.append(f" {rel.to_mermaid()}")
|
|
177
|
+
|
|
178
|
+
lines.append("```")
|
|
179
|
+
return "\n".join(lines)
|
|
180
|
+
|
|
181
|
+
@staticmethod
|
|
182
|
+
def generate_component_diagram(diagram: C4Diagram, container_name: str) -> str:
|
|
183
|
+
"""Generate Level 3: Component diagram."""
|
|
184
|
+
lines = [
|
|
185
|
+
"```mermaid",
|
|
186
|
+
"C4Component",
|
|
187
|
+
f' title {diagram.title}',
|
|
188
|
+
""
|
|
189
|
+
]
|
|
190
|
+
|
|
191
|
+
# Add container boundary with components
|
|
192
|
+
if diagram.boundaries:
|
|
193
|
+
for boundary_name, components in diagram.boundaries.items():
|
|
194
|
+
lines.append(f' Container_Boundary({boundary_name.lower().replace(" ", "_")}, "{boundary_name}") {{')
|
|
195
|
+
for component in components:
|
|
196
|
+
lines.append(f" {component.to_mermaid()}")
|
|
197
|
+
lines.append(" }")
|
|
198
|
+
lines.append("")
|
|
199
|
+
|
|
200
|
+
# Add external elements
|
|
201
|
+
for elem in diagram.elements:
|
|
202
|
+
lines.append(f" {elem.to_mermaid()}")
|
|
203
|
+
|
|
204
|
+
lines.append("")
|
|
205
|
+
|
|
206
|
+
# Add relationships
|
|
207
|
+
for rel in diagram.relationships:
|
|
208
|
+
lines.append(f" {rel.to_mermaid()}")
|
|
209
|
+
|
|
210
|
+
lines.append("```")
|
|
211
|
+
return "\n".join(lines)
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def generate_standard_saas_c4(product_name: str, bounded_contexts: List[str]) -> dict:
|
|
215
|
+
"""
|
|
216
|
+
Generate standard C4 diagrams for a typical SaaS application.
|
|
217
|
+
|
|
218
|
+
Args:
|
|
219
|
+
product_name: Name of the product
|
|
220
|
+
bounded_contexts: List of bounded context names
|
|
221
|
+
|
|
222
|
+
Returns:
|
|
223
|
+
Dictionary with context, container, and component diagrams
|
|
224
|
+
"""
|
|
225
|
+
diagrams = {}
|
|
226
|
+
|
|
227
|
+
# Level 1: System Context
|
|
228
|
+
context = C4Diagram(title=f"System Context: {product_name}")
|
|
229
|
+
context.add_person("user", "User", "Primary user of the system")
|
|
230
|
+
context.add_person("admin", "Administrator", "System administrator", external=False)
|
|
231
|
+
context.add_system("system", product_name, "The main system")
|
|
232
|
+
context.add_system("email", "Email Service", "Sends notifications", external=True)
|
|
233
|
+
context.add_system("auth", "Identity Provider", "SSO/OAuth", external=True)
|
|
234
|
+
context.add_relationship("user", "system", "Uses", "HTTPS")
|
|
235
|
+
context.add_relationship("admin", "system", "Manages", "HTTPS")
|
|
236
|
+
context.add_relationship("system", "email", "Sends via", "SMTP/API")
|
|
237
|
+
context.add_relationship("system", "auth", "Authenticates via", "OAuth 2.0")
|
|
238
|
+
|
|
239
|
+
diagrams["context"] = C4Generator.generate_context_diagram(context)
|
|
240
|
+
|
|
241
|
+
# Level 2: Container
|
|
242
|
+
container = C4Diagram(title=f"Container Diagram: {product_name}")
|
|
243
|
+
container.add_person("user", "User", "")
|
|
244
|
+
container.add_container("spa", "Web Application", "React, TypeScript", "User interface",
|
|
245
|
+
ContainerType.WEB_APP, product_name)
|
|
246
|
+
container.add_container("api", "API Server", "Node.js, Express", "Business logic and REST API",
|
|
247
|
+
ContainerType.API, product_name)
|
|
248
|
+
container.add_container("worker", "Background Worker", "Node.js", "Async job processing",
|
|
249
|
+
ContainerType.WORKER, product_name)
|
|
250
|
+
container.add_container("db", "Database", "PostgreSQL", "Application data",
|
|
251
|
+
ContainerType.DATABASE, product_name)
|
|
252
|
+
container.add_container("cache", "Cache", "Redis", "Session & cache",
|
|
253
|
+
ContainerType.DATABASE, product_name)
|
|
254
|
+
container.add_system("email", "Email Service", "", external=True)
|
|
255
|
+
|
|
256
|
+
container.add_relationship("user", "spa", "Uses", "HTTPS")
|
|
257
|
+
container.add_relationship("spa", "api", "Calls", "REST/JSON")
|
|
258
|
+
container.add_relationship("api", "db", "Reads/Writes", "SQL")
|
|
259
|
+
container.add_relationship("api", "cache", "Caches", "Redis")
|
|
260
|
+
container.add_relationship("worker", "db", "Reads/Writes", "SQL")
|
|
261
|
+
container.add_relationship("worker", "email", "Sends via", "API")
|
|
262
|
+
|
|
263
|
+
diagrams["container"] = C4Generator.generate_container_diagram(container, product_name)
|
|
264
|
+
|
|
265
|
+
# Level 3: Component diagrams for each bounded context
|
|
266
|
+
for bc in bounded_contexts:
|
|
267
|
+
component = C4Diagram(title=f"Component Diagram: {bc} Context")
|
|
268
|
+
component.add_component("ctrl", f"{bc} Controller", "Express Router", "HTTP endpoints",
|
|
269
|
+
boundary="API Server")
|
|
270
|
+
component.add_component("app", f"{bc} App Service", "TypeScript", "Use case orchestration",
|
|
271
|
+
boundary="API Server")
|
|
272
|
+
component.add_component("domain", f"{bc} Domain", "TypeScript", "Business logic",
|
|
273
|
+
boundary="API Server")
|
|
274
|
+
component.add_component("repo", f"{bc} Repository", "TypeScript", "Data access",
|
|
275
|
+
boundary="API Server")
|
|
276
|
+
component.add_container("db", "Database", "PostgreSQL", "", ContainerType.DATABASE)
|
|
277
|
+
|
|
278
|
+
component.add_relationship("ctrl", "app", "Calls")
|
|
279
|
+
component.add_relationship("app", "domain", "Uses")
|
|
280
|
+
component.add_relationship("app", "repo", "Uses")
|
|
281
|
+
component.add_relationship("repo", "db", "SQL")
|
|
282
|
+
|
|
283
|
+
diagrams[f"component_{bc.lower().replace(' ', '_')}"] = C4Generator.generate_component_diagram(
|
|
284
|
+
component, "API Server"
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
return diagrams
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
# Example usage
|
|
291
|
+
if __name__ == "__main__":
|
|
292
|
+
# Generate diagrams for a sample product
|
|
293
|
+
diagrams = generate_standard_saas_c4(
|
|
294
|
+
product_name="Habit Tracker",
|
|
295
|
+
bounded_contexts=["User Management", "Habits", "Analytics"]
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
print("=" * 60)
|
|
299
|
+
print("CONTEXT DIAGRAM")
|
|
300
|
+
print("=" * 60)
|
|
301
|
+
print(diagrams["context"])
|
|
302
|
+
|
|
303
|
+
print("\n" + "=" * 60)
|
|
304
|
+
print("CONTAINER DIAGRAM")
|
|
305
|
+
print("=" * 60)
|
|
306
|
+
print(diagrams["container"])
|
|
307
|
+
|
|
308
|
+
print("\n" + "=" * 60)
|
|
309
|
+
print("COMPONENT DIAGRAM: Habits")
|
|
310
|
+
print("=" * 60)
|
|
311
|
+
print(diagrams["component_habits"])
|