@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.
Files changed (34) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +71 -0
  3. package/bin/cli.js +5 -0
  4. package/package.json +49 -0
  5. package/sources.json +25 -0
  6. package/src/cli.js +108 -0
  7. package/src/commands/doctor.js +340 -0
  8. package/src/commands/init.js +168 -0
  9. package/src/commands/list.js +146 -0
  10. package/src/commands/remove.js +182 -0
  11. package/src/commands/update.js +170 -0
  12. package/src/utils.js +154 -0
  13. package/templates/.claude/commands/idea2prd-manual.md +35 -0
  14. package/templates/.claude/skills/explore/SKILL.md +218 -0
  15. package/templates/.claude/skills/explore/references/questioning-techniques.md +151 -0
  16. package/templates/.claude/skills/explore/references/task-brief-templates.md +355 -0
  17. package/templates/.claude/skills/goap-research-ed25519/SKILL.md +418 -0
  18. package/templates/.claude/skills/goap-research-ed25519/references/ed25519-verification.md +658 -0
  19. package/templates/.claude/skills/goap-research-ed25519/references/research-actions.md +544 -0
  20. package/templates/.claude/skills/goap-research-ed25519/references/source-evaluation.md +560 -0
  21. package/templates/.claude/skills/goap-research-ed25519/scripts/ed25519_verifier.py +662 -0
  22. package/templates/.claude/skills/goap-research-ed25519/scripts/goap_planner.py +720 -0
  23. package/templates/.claude/skills/idea2prd-manual/SKILL.md +695 -0
  24. package/templates/.claude/skills/idea2prd-manual/references/adr-catalog.md +288 -0
  25. package/templates/.claude/skills/idea2prd-manual/references/c4-model.md +277 -0
  26. package/templates/.claude/skills/idea2prd-manual/references/completion-checklist-template.md +446 -0
  27. package/templates/.claude/skills/idea2prd-manual/references/ddd-patterns.md +261 -0
  28. package/templates/.claude/skills/idea2prd-manual/references/fitness-functions-catalog.md +414 -0
  29. package/templates/.claude/skills/idea2prd-manual/references/pseudocode-style.md +404 -0
  30. package/templates/.claude/skills/idea2prd-manual/scripts/ai_context_builder.py +491 -0
  31. package/templates/.claude/skills/idea2prd-manual/scripts/c4_generator.py +311 -0
  32. package/templates/.claude/skills/idea2prd-manual/scripts/fitness_validator.py +451 -0
  33. package/templates/.claude/skills/idea2prd-manual/scripts/pseudocode_generator.py +430 -0
  34. package/templates/.claude/skills/problem-solver-enhanced/SKILL.md +565 -0
@@ -0,0 +1,491 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ AI Context Package Builder for idea2prd skills.
4
+ Assembles .ai-context/ directory for Vibe Coding AI agents.
5
+ """
6
+
7
+ import os
8
+ import json
9
+ from dataclasses import dataclass, field
10
+ from typing import List, Dict, Optional
11
+ from datetime import datetime
12
+ from pathlib import Path
13
+
14
+
15
+ @dataclass
16
+ class BoundedContext:
17
+ """Represents a bounded context."""
18
+ name: str
19
+ type: str # Core, Supporting, Generic
20
+ responsibility: str
21
+ aggregates: List[str] = field(default_factory=list)
22
+ events: List[str] = field(default_factory=list)
23
+
24
+
25
+ @dataclass
26
+ class ADRSummary:
27
+ """Summary of an Architecture Decision Record."""
28
+ id: str
29
+ title: str
30
+ decision: str
31
+ rationale: str
32
+
33
+
34
+ @dataclass
35
+ class FitnessRule:
36
+ """A fitness rule for AI to follow."""
37
+ id: str
38
+ rule: str
39
+ threshold: str
40
+ consequence: str
41
+
42
+
43
+ @dataclass
44
+ class AIContextPackage:
45
+ """Complete AI context package data."""
46
+ product_name: str
47
+ description: str
48
+ bounded_contexts: List[BoundedContext] = field(default_factory=list)
49
+ adrs: List[ADRSummary] = field(default_factory=list)
50
+ glossary: Dict[str, str] = field(default_factory=dict)
51
+ coding_standards: Dict[str, str] = field(default_factory=dict)
52
+ fitness_rules: List[FitnessRule] = field(default_factory=list)
53
+ tech_stack: Dict[str, str] = field(default_factory=dict)
54
+
55
+
56
+ class AIContextBuilder:
57
+ """Builds .ai-context/ package for AI agents."""
58
+
59
+ def __init__(self, package: AIContextPackage):
60
+ self.package = package
61
+
62
+ def build_readme(self) -> str:
63
+ """Generate README.md for .ai-context/"""
64
+ return f"""# AI Context Package: {self.package.product_name}
65
+
66
+ This directory contains structured context for AI-assisted development (Vibe Coding).
67
+
68
+ ## Contents
69
+
70
+ | File | Purpose |
71
+ |------|---------|
72
+ | `architecture-summary.md` | System overview and key components |
73
+ | `key-decisions.md` | Top architecture decisions (from ADRs) |
74
+ | `domain-glossary.md` | Ubiquitous language definitions |
75
+ | `bounded-contexts.md` | Context responsibilities and boundaries |
76
+ | `coding-standards.md` | Code style and conventions |
77
+ | `fitness-rules.md` | Rules AI must follow |
78
+
79
+ ## Usage
80
+
81
+ When prompting AI for code generation, reference this context:
82
+
83
+ ```bash
84
+ # Claude Code
85
+ claude --context .ai-context/ "Implement [feature]"
86
+
87
+ # In conversation
88
+ "Using the context in .ai-context/, implement the UserAggregate"
89
+ ```
90
+
91
+ ## Important Rules
92
+
93
+ 1. **Follow ADRs** — All architecture decisions in `key-decisions.md` are binding
94
+ 2. **Use Domain Language** — Terms in `domain-glossary.md` have specific meanings
95
+ 3. **Respect Boundaries** — Don't cross bounded context boundaries directly
96
+ 4. **Validate with Fitness** — Code must pass rules in `fitness-rules.md`
97
+
98
+ ---
99
+ *Generated: {datetime.now().isoformat()}*
100
+ """
101
+
102
+ def build_architecture_summary(self) -> str:
103
+ """Generate architecture-summary.md"""
104
+ contexts_table = "\n".join([
105
+ f"| {ctx.name} | {ctx.type} | {ctx.responsibility} |"
106
+ for ctx in self.package.bounded_contexts
107
+ ])
108
+
109
+ tech_stack_lines = "\n".join([
110
+ f"- **{k}:** {v}" for k, v in self.package.tech_stack.items()
111
+ ])
112
+
113
+ return f"""# Architecture Summary
114
+
115
+ ## System Overview
116
+
117
+ **Product:** {self.package.product_name}
118
+ **Description:** {self.package.description}
119
+
120
+ ## Technology Stack
121
+
122
+ {tech_stack_lines}
123
+
124
+ ## Bounded Contexts
125
+
126
+ | Context | Type | Responsibility |
127
+ |---------|------|----------------|
128
+ {contexts_table}
129
+
130
+ ## Key Integration Points
131
+
132
+ ### Context Communication
133
+ - Contexts communicate via **Domain Events** (async)
134
+ - Direct API calls allowed for queries only
135
+ - No direct database access across contexts
136
+
137
+ ### External Integrations
138
+ - Authentication: OAuth 2.0 / JWT
139
+ - Email: External service via API
140
+ - Storage: Cloud storage service
141
+
142
+ ## Critical Constraints
143
+
144
+ 1. **Single Aggregate per Transaction** — Never modify multiple aggregates in one transaction
145
+ 2. **Event-Driven** — State changes emit domain events
146
+ 3. **API-First** — All functionality exposed via API
147
+
148
+ ---
149
+ *For detailed decisions, see `key-decisions.md`*
150
+ """
151
+
152
+ def build_key_decisions(self) -> str:
153
+ """Generate key-decisions.md from ADR summaries."""
154
+ decisions = "\n\n".join([
155
+ f"""### {adr.id}: {adr.title}
156
+
157
+ **Decision:** {adr.decision}
158
+
159
+ **Rationale:** {adr.rationale}
160
+ """
161
+ for adr in self.package.adrs
162
+ ])
163
+
164
+ return f"""# Key Architecture Decisions
165
+
166
+ This document summarizes the most important architecture decisions.
167
+ For full details, see individual ADRs in `docs/adr/`.
168
+
169
+ {decisions}
170
+
171
+ ---
172
+ *Total ADRs: {len(self.package.adrs)}*
173
+ """
174
+
175
+ def build_domain_glossary(self) -> str:
176
+ """Generate domain-glossary.md from ubiquitous language."""
177
+ terms = "\n".join([
178
+ f"| **{term}** | {definition} |"
179
+ for term, definition in sorted(self.package.glossary.items())
180
+ ])
181
+
182
+ return f"""# Domain Glossary (Ubiquitous Language)
183
+
184
+ Use these terms consistently in code, documentation, and communication.
185
+
186
+ | Term | Definition |
187
+ |------|------------|
188
+ {terms}
189
+
190
+ ## Usage Guidelines
191
+
192
+ 1. **In Code** — Use these exact terms for class/function/variable names
193
+ 2. **In APIs** — Use these terms in endpoint paths and payloads
194
+ 3. **In Documentation** — Don't use synonyms; use the defined terms
195
+ 4. **In Communication** — Align team vocabulary with these definitions
196
+
197
+ ---
198
+ *Terms: {len(self.package.glossary)}*
199
+ """
200
+
201
+ def build_bounded_contexts(self) -> str:
202
+ """Generate bounded-contexts.md"""
203
+ contexts = []
204
+
205
+ for ctx in self.package.bounded_contexts:
206
+ aggregates = ", ".join(ctx.aggregates) if ctx.aggregates else "TBD"
207
+ events = ", ".join(ctx.events) if ctx.events else "TBD"
208
+
209
+ contexts.append(f"""### {ctx.name}
210
+
211
+ **Type:** {ctx.type}
212
+ **Responsibility:** {ctx.responsibility}
213
+
214
+ **Aggregates:** {aggregates}
215
+ **Domain Events:** {events}
216
+
217
+ **Boundaries:**
218
+ - Owns its own database schema
219
+ - Exposes API for other contexts
220
+ - Publishes events for state changes
221
+ """)
222
+
223
+ return f"""# Bounded Contexts
224
+
225
+ ## Overview
226
+
227
+ This system is divided into {len(self.package.bounded_contexts)} bounded contexts.
228
+
229
+ ## Context Details
230
+
231
+ {"".join(contexts)}
232
+
233
+ ## Communication Rules
234
+
235
+ 1. **No Direct DB Access** — Contexts don't share database tables
236
+ 2. **API for Queries** — Use context's API to read data
237
+ 3. **Events for Commands** — Publish events for state changes
238
+ 4. **ACL for External** — Use Anti-Corruption Layer for external systems
239
+
240
+ ---
241
+ *Contexts: {len(self.package.bounded_contexts)}*
242
+ """
243
+
244
+ def build_coding_standards(self) -> str:
245
+ """Generate coding-standards.md"""
246
+ standards = "\n".join([
247
+ f"### {category}\n\n{rules}\n"
248
+ for category, rules in self.package.coding_standards.items()
249
+ ])
250
+
251
+ return f"""# Coding Standards
252
+
253
+ Follow these standards when generating code.
254
+
255
+ {standards}
256
+
257
+ ## File Structure
258
+
259
+ ```
260
+ src/
261
+ ├── [context]/
262
+ │ ├── domain/
263
+ │ │ ├── aggregates/
264
+ │ │ ├── entities/
265
+ │ │ ├── value-objects/
266
+ │ │ └── events/
267
+ │ ├── application/
268
+ │ │ ├── services/
269
+ │ │ └── commands/
270
+ │ ├── infrastructure/
271
+ │ │ ├── repositories/
272
+ │ │ └── external/
273
+ │ └── api/
274
+ │ ├── controllers/
275
+ │ └── dto/
276
+ ```
277
+
278
+ ## Naming Conventions
279
+
280
+ | Element | Convention | Example |
281
+ |---------|------------|---------|
282
+ | Aggregate | PascalCase | `UserAggregate` |
283
+ | Entity | PascalCase | `OrderItem` |
284
+ | Value Object | PascalCase | `EmailAddress` |
285
+ | Domain Event | PascalCase, past tense | `OrderPlaced` |
286
+ | Repository | PascalCase + Repository | `UserRepository` |
287
+ | Service | PascalCase + Service | `PricingService` |
288
+ """
289
+
290
+ def build_fitness_rules(self) -> str:
291
+ """Generate fitness-rules.md"""
292
+ rules = "\n".join([
293
+ f"""### {rule.id}: {rule.rule}
294
+
295
+ - **Threshold:** {rule.threshold}
296
+ - **Consequence:** {rule.consequence}
297
+ """
298
+ for rule in self.package.fitness_rules
299
+ ])
300
+
301
+ return f"""# Fitness Rules
302
+
303
+ AI-generated code MUST follow these rules. Violations will be caught by automated checks.
304
+
305
+ {rules}
306
+
307
+ ## Validation
308
+
309
+ All code is validated against these rules:
310
+ - On every commit (CI pipeline)
311
+ - On every PR (automated review)
312
+ - Before deployment (gate check)
313
+
314
+ ## Consequences of Violation
315
+
316
+ | Severity | Action |
317
+ |----------|--------|
318
+ | Critical | Block merge, immediate fix required |
319
+ | High | Block merge, fix within 24h |
320
+ | Medium | Warning, fix within sprint |
321
+ | Low | Note for improvement |
322
+
323
+ ---
324
+ *Rules: {len(self.package.fitness_rules)}*
325
+ """
326
+
327
+ def build_all(self, output_dir: str = ".ai-context") -> Dict[str, str]:
328
+ """Build all context files."""
329
+ files = {
330
+ "README.md": self.build_readme(),
331
+ "architecture-summary.md": self.build_architecture_summary(),
332
+ "key-decisions.md": self.build_key_decisions(),
333
+ "domain-glossary.md": self.build_domain_glossary(),
334
+ "bounded-contexts.md": self.build_bounded_contexts(),
335
+ "coding-standards.md": self.build_coding_standards(),
336
+ "fitness-rules.md": self.build_fitness_rules()
337
+ }
338
+
339
+ return files
340
+
341
+ def write_to_disk(self, output_dir: str = ".ai-context"):
342
+ """Write all files to disk."""
343
+ path = Path(output_dir)
344
+ path.mkdir(parents=True, exist_ok=True)
345
+
346
+ files = self.build_all(output_dir)
347
+
348
+ for filename, content in files.items():
349
+ filepath = path / filename
350
+ filepath.write_text(content)
351
+ print(f"Created: {filepath}")
352
+
353
+ print(f"\n✅ AI Context Package created in {output_dir}/")
354
+ print(f" Files: {len(files)}")
355
+
356
+
357
+ def create_sample_package() -> AIContextPackage:
358
+ """Create a sample AI context package for demonstration."""
359
+ return AIContextPackage(
360
+ product_name="Habit Tracker",
361
+ description="Application for tracking daily habits with statistics and reminders",
362
+ bounded_contexts=[
363
+ BoundedContext(
364
+ name="Identity",
365
+ type="Supporting",
366
+ responsibility="User authentication and profile management",
367
+ aggregates=["User"],
368
+ events=["UserRegistered", "UserProfileUpdated"]
369
+ ),
370
+ BoundedContext(
371
+ name="Habits",
372
+ type="Core",
373
+ responsibility="Habit definition and daily tracking",
374
+ aggregates=["Habit", "HabitLog"],
375
+ events=["HabitCreated", "HabitCompleted", "StreakBroken"]
376
+ ),
377
+ BoundedContext(
378
+ name="Analytics",
379
+ type="Supporting",
380
+ responsibility="Statistics and insights generation",
381
+ aggregates=["UserStats"],
382
+ events=["StatsUpdated", "InsightGenerated"]
383
+ )
384
+ ],
385
+ adrs=[
386
+ ADRSummary(
387
+ id="ADR-001",
388
+ title="Modular Monolith Architecture",
389
+ decision="Use modular monolith with clear bounded context boundaries",
390
+ rationale="Simpler deployment for MVP while maintaining clean architecture"
391
+ ),
392
+ ADRSummary(
393
+ id="ADR-002",
394
+ title="PostgreSQL Database",
395
+ decision="Use PostgreSQL as primary database",
396
+ rationale="ACID compliance, JSON support, and team expertise"
397
+ ),
398
+ ADRSummary(
399
+ id="ADR-003",
400
+ title="REST API",
401
+ decision="Use REST with JSON for API design",
402
+ rationale="Simple, widely supported, good tooling"
403
+ ),
404
+ ADRSummary(
405
+ id="ADR-004",
406
+ title="JWT Authentication",
407
+ decision="Use JWT tokens with OAuth 2.0 for authentication",
408
+ rationale="Stateless, mobile-friendly, standard approach"
409
+ )
410
+ ],
411
+ glossary={
412
+ "Habit": "A recurring activity that user wants to track",
413
+ "Streak": "Consecutive days of completing a habit",
414
+ "Check-in": "Recording completion of a habit for a specific day",
415
+ "Reminder": "Notification to prompt user to complete a habit",
416
+ "Insight": "AI-generated observation about user's habit patterns"
417
+ },
418
+ coding_standards={
419
+ "TypeScript": """- Use strict mode
420
+ - Prefer `interface` over `type` for object shapes
421
+ - Use `readonly` for immutable properties
422
+ - Explicit return types for public functions""",
423
+ "Testing": """- Unit tests for domain logic (Jest)
424
+ - Integration tests for repositories
425
+ - E2E tests for critical user journeys
426
+ - Minimum 80% coverage""",
427
+ "Error Handling": """- Use custom error classes per bounded context
428
+ - Return RFC 7807 Problem Details from API
429
+ - Log errors with correlation ID"""
430
+ },
431
+ fitness_rules=[
432
+ FitnessRule(
433
+ id="FF-001",
434
+ rule="No cross-context database access",
435
+ threshold="0 violations",
436
+ consequence="Block merge"
437
+ ),
438
+ FitnessRule(
439
+ id="FF-002",
440
+ rule="Aggregates must have ≤7 entities",
441
+ threshold="7 entities max",
442
+ consequence="Code review required"
443
+ ),
444
+ FitnessRule(
445
+ id="FF-003",
446
+ rule="All private endpoints require authentication",
447
+ threshold="100% coverage",
448
+ consequence="Block merge"
449
+ ),
450
+ FitnessRule(
451
+ id="FF-004",
452
+ rule="Test coverage minimum",
453
+ threshold="≥80%",
454
+ consequence="Block merge"
455
+ )
456
+ ],
457
+ tech_stack={
458
+ "Backend": "Node.js + Express + TypeScript",
459
+ "Database": "PostgreSQL",
460
+ "Cache": "Redis",
461
+ "Frontend": "React + TypeScript",
462
+ "API": "REST + JSON",
463
+ "Auth": "JWT + OAuth 2.0",
464
+ "Testing": "Jest + Playwright"
465
+ }
466
+ )
467
+
468
+
469
+ # =============================================================================
470
+ # Main / Example Usage
471
+ # =============================================================================
472
+
473
+ if __name__ == "__main__":
474
+ # Create sample package
475
+ package = create_sample_package()
476
+
477
+ # Build context
478
+ builder = AIContextBuilder(package)
479
+
480
+ # Print all files
481
+ files = builder.build_all()
482
+
483
+ for filename, content in files.items():
484
+ print("=" * 60)
485
+ print(f"FILE: {filename}")
486
+ print("=" * 60)
487
+ print(content)
488
+ print()
489
+
490
+ # Optionally write to disk
491
+ # builder.write_to_disk(".ai-context")