aidp 0.27.0 → 0.28.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 (90) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +89 -0
  3. data/lib/aidp/cli/models_command.rb +5 -6
  4. data/lib/aidp/cli.rb +10 -8
  5. data/lib/aidp/config.rb +54 -0
  6. data/lib/aidp/debug_mixin.rb +23 -1
  7. data/lib/aidp/execute/agent_signal_parser.rb +22 -0
  8. data/lib/aidp/execute/repl_macros.rb +2 -2
  9. data/lib/aidp/execute/steps.rb +94 -1
  10. data/lib/aidp/execute/work_loop_runner.rb +209 -17
  11. data/lib/aidp/execute/workflow_selector.rb +2 -25
  12. data/lib/aidp/firewall/provider_requirements_collector.rb +262 -0
  13. data/lib/aidp/harness/ai_decision_engine.rb +35 -2
  14. data/lib/aidp/harness/config_manager.rb +0 -5
  15. data/lib/aidp/harness/config_schema.rb +8 -0
  16. data/lib/aidp/harness/configuration.rb +27 -19
  17. data/lib/aidp/harness/enhanced_runner.rb +1 -4
  18. data/lib/aidp/harness/error_handler.rb +1 -72
  19. data/lib/aidp/harness/provider_factory.rb +11 -2
  20. data/lib/aidp/harness/state_manager.rb +0 -7
  21. data/lib/aidp/harness/thinking_depth_manager.rb +47 -68
  22. data/lib/aidp/harness/ui/enhanced_tui.rb +8 -18
  23. data/lib/aidp/harness/ui/enhanced_workflow_selector.rb +0 -18
  24. data/lib/aidp/harness/ui/progress_display.rb +6 -2
  25. data/lib/aidp/harness/user_interface.rb +0 -58
  26. data/lib/aidp/init/runner.rb +7 -2
  27. data/lib/aidp/planning/analyzers/feedback_analyzer.rb +365 -0
  28. data/lib/aidp/planning/builders/agile_plan_builder.rb +387 -0
  29. data/lib/aidp/planning/builders/project_plan_builder.rb +193 -0
  30. data/lib/aidp/planning/generators/gantt_generator.rb +190 -0
  31. data/lib/aidp/planning/generators/iteration_plan_generator.rb +392 -0
  32. data/lib/aidp/planning/generators/legacy_research_planner.rb +473 -0
  33. data/lib/aidp/planning/generators/marketing_report_generator.rb +348 -0
  34. data/lib/aidp/planning/generators/mvp_scope_generator.rb +310 -0
  35. data/lib/aidp/planning/generators/user_test_plan_generator.rb +373 -0
  36. data/lib/aidp/planning/generators/wbs_generator.rb +259 -0
  37. data/lib/aidp/planning/mappers/persona_mapper.rb +163 -0
  38. data/lib/aidp/planning/parsers/document_parser.rb +141 -0
  39. data/lib/aidp/planning/parsers/feedback_data_parser.rb +252 -0
  40. data/lib/aidp/provider_manager.rb +8 -32
  41. data/lib/aidp/providers/aider.rb +264 -0
  42. data/lib/aidp/providers/anthropic.rb +74 -2
  43. data/lib/aidp/providers/base.rb +25 -1
  44. data/lib/aidp/providers/codex.rb +26 -3
  45. data/lib/aidp/providers/cursor.rb +16 -0
  46. data/lib/aidp/providers/gemini.rb +13 -0
  47. data/lib/aidp/providers/github_copilot.rb +17 -0
  48. data/lib/aidp/providers/kilocode.rb +11 -0
  49. data/lib/aidp/providers/opencode.rb +11 -0
  50. data/lib/aidp/setup/wizard.rb +249 -39
  51. data/lib/aidp/version.rb +1 -1
  52. data/lib/aidp/watch/build_processor.rb +211 -30
  53. data/lib/aidp/watch/change_request_processor.rb +128 -14
  54. data/lib/aidp/watch/ci_fix_processor.rb +103 -37
  55. data/lib/aidp/watch/ci_log_extractor.rb +258 -0
  56. data/lib/aidp/watch/github_state_extractor.rb +177 -0
  57. data/lib/aidp/watch/implementation_verifier.rb +284 -0
  58. data/lib/aidp/watch/plan_generator.rb +7 -43
  59. data/lib/aidp/watch/plan_processor.rb +7 -6
  60. data/lib/aidp/watch/repository_client.rb +245 -17
  61. data/lib/aidp/watch/review_processor.rb +98 -17
  62. data/lib/aidp/watch/reviewers/base_reviewer.rb +1 -1
  63. data/lib/aidp/watch/runner.rb +181 -29
  64. data/lib/aidp/watch/state_store.rb +22 -1
  65. data/lib/aidp/workflows/definitions.rb +147 -0
  66. data/lib/aidp/workstream_cleanup.rb +245 -0
  67. data/lib/aidp/worktree.rb +19 -0
  68. data/templates/aidp.yml.example +57 -0
  69. data/templates/implementation/generate_tdd_specs.md +213 -0
  70. data/templates/implementation/iterative_implementation.md +122 -0
  71. data/templates/planning/agile/analyze_feedback.md +183 -0
  72. data/templates/planning/agile/generate_iteration_plan.md +179 -0
  73. data/templates/planning/agile/generate_legacy_research_plan.md +171 -0
  74. data/templates/planning/agile/generate_marketing_report.md +162 -0
  75. data/templates/planning/agile/generate_mvp_scope.md +127 -0
  76. data/templates/planning/agile/generate_user_test_plan.md +143 -0
  77. data/templates/planning/agile/ingest_feedback.md +174 -0
  78. data/templates/planning/assemble_project_plan.md +113 -0
  79. data/templates/planning/assign_personas.md +108 -0
  80. data/templates/planning/create_tasks.md +52 -6
  81. data/templates/planning/generate_gantt.md +86 -0
  82. data/templates/planning/generate_wbs.md +85 -0
  83. data/templates/planning/initialize_planning_mode.md +70 -0
  84. data/templates/skills/README.md +2 -2
  85. data/templates/skills/marketing_strategist/SKILL.md +279 -0
  86. data/templates/skills/product_manager/SKILL.md +177 -0
  87. data/templates/skills/ruby_aidp_planning/SKILL.md +497 -0
  88. data/templates/skills/ruby_rspec_tdd/SKILL.md +514 -0
  89. data/templates/skills/ux_researcher/SKILL.md +222 -0
  90. metadata +39 -1
@@ -0,0 +1,348 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../logger"
4
+
5
+ module Aidp
6
+ module Planning
7
+ module Generators
8
+ # Generates marketing report with key messages and differentiators
9
+ # Uses AI to craft compelling narratives from technical features
10
+ # Follows Zero Framework Cognition (ZFC) pattern
11
+ class MarketingReportGenerator
12
+ def initialize(ai_decision_engine:, config: nil)
13
+ @ai_decision_engine = ai_decision_engine
14
+ @config = config || Aidp::Config.agile_config
15
+ end
16
+
17
+ # Generate marketing report from MVP scope and feedback
18
+ # @param mvp_scope [Hash] MVP scope definition
19
+ # @param feedback_analysis [Hash] User feedback analysis (optional)
20
+ # @return [Hash] Marketing report structure
21
+ def generate(mvp_scope:, feedback_analysis: nil)
22
+ Aidp.log_debug("marketing_report_generator", "generate",
23
+ feature_count: mvp_scope[:mvp_features]&.size || 0,
24
+ has_feedback: !feedback_analysis.nil?)
25
+
26
+ # Use AI to generate marketing materials
27
+ marketing_report = generate_marketing_with_ai(mvp_scope, feedback_analysis)
28
+
29
+ {
30
+ overview: marketing_report[:overview],
31
+ value_proposition: marketing_report[:value_proposition],
32
+ key_messages: marketing_report[:key_messages],
33
+ differentiators: marketing_report[:differentiators],
34
+ target_audience: marketing_report[:target_audience],
35
+ positioning: marketing_report[:positioning],
36
+ success_metrics: marketing_report[:success_metrics],
37
+ launch_checklist: marketing_report[:launch_checklist],
38
+ messaging_framework: marketing_report[:messaging_framework],
39
+ metadata: {
40
+ generated_at: Time.now.iso8601,
41
+ key_message_count: marketing_report[:key_messages]&.size || 0,
42
+ differentiator_count: marketing_report[:differentiators]&.size || 0
43
+ }
44
+ }
45
+ end
46
+
47
+ # Format marketing report as markdown
48
+ # @param report [Hash] Marketing report structure
49
+ # @return [String] Markdown formatted marketing report
50
+ def format_as_markdown(report)
51
+ Aidp.log_debug("marketing_report_generator", "format_as_markdown")
52
+
53
+ output = ["# Marketing Report", ""]
54
+ output << "**Generated:** #{report[:metadata][:generated_at]}"
55
+ output << "**Key Messages:** #{report[:metadata][:key_message_count]}"
56
+ output << "**Differentiators:** #{report[:metadata][:differentiator_count]}"
57
+ output << ""
58
+
59
+ output << "## Overview"
60
+ output << ""
61
+ output << report[:overview]
62
+ output << ""
63
+
64
+ output << "## Value Proposition"
65
+ output << ""
66
+ output << "### Headline"
67
+ output << ""
68
+ output << report[:value_proposition][:headline]
69
+ output << ""
70
+ output << "### Subheadline"
71
+ output << ""
72
+ output << report[:value_proposition][:subheadline]
73
+ output << ""
74
+ output << "### Core Benefits"
75
+ output << ""
76
+ report[:value_proposition][:core_benefits].each do |benefit|
77
+ output << "- #{benefit}"
78
+ end
79
+ output << ""
80
+
81
+ output << "## Key Messages"
82
+ output << ""
83
+ report[:key_messages].each_with_index do |message, idx|
84
+ output << "### #{idx + 1}. #{message[:title]}"
85
+ output << ""
86
+ output << message[:description]
87
+ output << ""
88
+ output << "**Supporting Points:**"
89
+ message[:supporting_points].each do |point|
90
+ output << "- #{point}"
91
+ end
92
+ output << ""
93
+ end
94
+
95
+ output << "## Differentiators"
96
+ output << ""
97
+ output << "What sets us apart from competitors:"
98
+ output << ""
99
+ report[:differentiators].each_with_index do |diff, idx|
100
+ output << "### #{idx + 1}. #{diff[:title]}"
101
+ output << ""
102
+ output << diff[:description]
103
+ output << ""
104
+ output << "**Competitive Advantage:** #{diff[:advantage]}"
105
+ output << ""
106
+ end
107
+
108
+ output << "## Target Audience"
109
+ output << ""
110
+ report[:target_audience].each do |segment|
111
+ output << "### #{segment[:name]}"
112
+ output << ""
113
+ output << "**Description:** #{segment[:description]}"
114
+ output << ""
115
+ output << "**Pain Points:**"
116
+ segment[:pain_points].each do |pain|
117
+ output << "- #{pain}"
118
+ end
119
+ output << ""
120
+ output << "**Our Solution:**"
121
+ segment[:our_solution].each do |solution|
122
+ output << "- #{solution}"
123
+ end
124
+ output << ""
125
+ end
126
+
127
+ output << "## Positioning"
128
+ output << ""
129
+ output << "**Category:** #{report[:positioning][:category]}"
130
+ output << ""
131
+ output << "**Statement:** #{report[:positioning][:statement]}"
132
+ output << ""
133
+ output << "**Tagline:** #{report[:positioning][:tagline]}"
134
+ output << ""
135
+
136
+ output << "## Success Metrics"
137
+ output << ""
138
+ report[:success_metrics].each do |metric|
139
+ output << "- **#{metric[:name]}:** #{metric[:target]}"
140
+ output << " - Measurement: #{metric[:measurement]}"
141
+ output << ""
142
+ end
143
+
144
+ output << "## Messaging Framework"
145
+ output << ""
146
+ output << "| Audience | Message | Channel | Call to Action |"
147
+ output << "|----------|---------|---------|----------------|"
148
+ report[:messaging_framework].each do |msg|
149
+ output << "| #{msg[:audience]} | #{msg[:message]} | #{msg[:channel]} | #{msg[:cta]} |"
150
+ end
151
+ output << ""
152
+
153
+ output << "## Launch Checklist"
154
+ output << ""
155
+ report[:launch_checklist].each_with_index do |item, idx|
156
+ output << "- [ ] **#{item[:task]}**"
157
+ output << " - Owner: #{item[:owner]}"
158
+ output << " - Timeline: #{item[:timeline]}"
159
+ output << ""
160
+ end
161
+
162
+ output.join("\n")
163
+ end
164
+
165
+ private
166
+
167
+ def generate_marketing_with_ai(mvp_scope, feedback_analysis)
168
+ Aidp.log_debug("marketing_report_generator", "generate_marketing_with_ai")
169
+
170
+ prompt = build_marketing_prompt(mvp_scope, feedback_analysis)
171
+
172
+ schema = {
173
+ type: "object",
174
+ properties: {
175
+ overview: {type: "string"},
176
+ value_proposition: {
177
+ type: "object",
178
+ properties: {
179
+ headline: {type: "string"},
180
+ subheadline: {type: "string"},
181
+ core_benefits: {type: "array", items: {type: "string"}}
182
+ }
183
+ },
184
+ key_messages: {
185
+ type: "array",
186
+ items: {
187
+ type: "object",
188
+ properties: {
189
+ title: {type: "string"},
190
+ description: {type: "string"},
191
+ supporting_points: {type: "array", items: {type: "string"}}
192
+ }
193
+ }
194
+ },
195
+ differentiators: {
196
+ type: "array",
197
+ items: {
198
+ type: "object",
199
+ properties: {
200
+ title: {type: "string"},
201
+ description: {type: "string"},
202
+ advantage: {type: "string"}
203
+ }
204
+ }
205
+ },
206
+ target_audience: {
207
+ type: "array",
208
+ items: {
209
+ type: "object",
210
+ properties: {
211
+ name: {type: "string"},
212
+ description: {type: "string"},
213
+ pain_points: {type: "array", items: {type: "string"}},
214
+ our_solution: {type: "array", items: {type: "string"}}
215
+ }
216
+ }
217
+ },
218
+ positioning: {
219
+ type: "object",
220
+ properties: {
221
+ category: {type: "string"},
222
+ statement: {type: "string"},
223
+ tagline: {type: "string"}
224
+ }
225
+ },
226
+ success_metrics: {
227
+ type: "array",
228
+ items: {
229
+ type: "object",
230
+ properties: {
231
+ name: {type: "string"},
232
+ target: {type: "string"},
233
+ measurement: {type: "string"}
234
+ }
235
+ }
236
+ },
237
+ messaging_framework: {
238
+ type: "array",
239
+ items: {
240
+ type: "object",
241
+ properties: {
242
+ audience: {type: "string"},
243
+ message: {type: "string"},
244
+ channel: {type: "string"},
245
+ cta: {type: "string"}
246
+ }
247
+ }
248
+ },
249
+ launch_checklist: {
250
+ type: "array",
251
+ items: {
252
+ type: "object",
253
+ properties: {
254
+ task: {type: "string"},
255
+ owner: {type: "string"},
256
+ timeline: {type: "string"}
257
+ }
258
+ }
259
+ }
260
+ },
261
+ required: ["overview", "value_proposition", "key_messages", "differentiators"]
262
+ }
263
+
264
+ decision = @ai_decision_engine.decide(
265
+ context: "marketing_report_generation",
266
+ prompt: prompt,
267
+ data: {
268
+ mvp_scope: mvp_scope,
269
+ feedback_analysis: feedback_analysis
270
+ },
271
+ schema: schema
272
+ )
273
+
274
+ Aidp.log_debug("marketing_report_generator", "ai_report_generated",
275
+ messages: decision[:key_messages]&.size || 0)
276
+
277
+ decision
278
+ end
279
+
280
+ def build_marketing_prompt(mvp_scope, feedback_analysis)
281
+ feedback_insights = if feedback_analysis
282
+ <<~INSIGHTS
283
+ USER FEEDBACK INSIGHTS:
284
+ #{feedback_analysis[:findings]&.map { |f| "- #{f}" }&.join("\n") || "No insights"}
285
+ INSIGHTS
286
+ else
287
+ ""
288
+ end
289
+
290
+ <<~PROMPT
291
+ Generate a comprehensive marketing report for the following MVP.
292
+
293
+ MVP FEATURES:
294
+ #{mvp_scope[:mvp_features]&.map { |f| "- #{f[:name]}: #{f[:description]}" }&.join("\n") || "No features"}
295
+
296
+ SUCCESS CRITERIA:
297
+ #{mvp_scope[:success_criteria]&.map { |c| "- #{c}" }&.join("\n") || "No criteria"}
298
+
299
+ #{feedback_insights}
300
+
301
+ TASK:
302
+ Create marketing materials that translate technical features into compelling value propositions:
303
+
304
+ 1. OVERVIEW
305
+ - Brief summary of the marketing strategy
306
+
307
+ 2. VALUE PROPOSITION
308
+ - Compelling headline (10-15 words)
309
+ - Supporting subheadline (15-25 words)
310
+ - 3-5 core benefits
311
+
312
+ 3. KEY MESSAGES (3-5 messages)
313
+ - For each: title, description, 3-5 supporting points
314
+ - Focus on customer value, not technical features
315
+
316
+ 4. DIFFERENTIATORS (2-4 items)
317
+ - What makes this unique?
318
+ - Competitive advantages
319
+ - Why choose us over alternatives?
320
+
321
+ 5. TARGET AUDIENCE (2-3 segments)
322
+ - Name and description
323
+ - Pain points they experience
324
+ - How our solution addresses their needs
325
+
326
+ 6. POSITIONING
327
+ - Category (what market/space are we in?)
328
+ - Positioning statement (who, what, value, differentiation)
329
+ - Tagline (memorable 3-7 words)
330
+
331
+ 7. SUCCESS METRICS
332
+ - 4-6 measurable metrics for launch success
333
+ - Targets and how to measure
334
+
335
+ 8. MESSAGING FRAMEWORK
336
+ - For each audience: specific message, channel, call to action
337
+
338
+ 9. LAUNCH CHECKLIST
339
+ - 8-12 pre-launch tasks
340
+ - Owner and timeline for each
341
+
342
+ Make it compelling, customer-focused, and actionable. Avoid jargon.
343
+ PROMPT
344
+ end
345
+ end
346
+ end
347
+ end
348
+ end
@@ -0,0 +1,310 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../logger"
4
+
5
+ module Aidp
6
+ module Planning
7
+ module Generators
8
+ # Generates MVP scope definition using AI to analyze features
9
+ # Determines must-have vs nice-to-have features for MVP
10
+ # Uses Zero Framework Cognition (ZFC) - NO heuristics, pure AI decisions
11
+ class MVPScopeGenerator
12
+ def initialize(ai_decision_engine:, prompt: nil, config: nil)
13
+ @ai_decision_engine = ai_decision_engine
14
+ @prompt = prompt || TTY::Prompt.new
15
+ @config = config || Aidp::Config.agile_config
16
+ end
17
+
18
+ # Generate MVP scope from PRD and user priorities
19
+ # @param prd [Hash] Parsed PRD document
20
+ # @param user_priorities [Array<String>] User-specified priorities (optional)
21
+ # @return [Hash] MVP scope with must-have and nice-to-have features
22
+ def generate(prd:, user_priorities: nil)
23
+ Aidp.log_debug("mvp_scope_generator", "generate", has_prd: !prd.nil?)
24
+
25
+ # Collect user priorities if not provided
26
+ priorities = user_priorities || collect_user_priorities(prd)
27
+
28
+ Aidp.log_debug("mvp_scope_generator", "analyzing_features", priority_count: priorities.size)
29
+
30
+ # Use AI to analyze features and determine MVP viability
31
+ mvp_analysis = analyze_features_with_ai(prd, priorities)
32
+
33
+ {
34
+ mvp_features: mvp_analysis[:must_have],
35
+ deferred_features: mvp_analysis[:nice_to_have],
36
+ out_of_scope: mvp_analysis[:out_of_scope],
37
+ success_criteria: mvp_analysis[:success_criteria],
38
+ assumptions: mvp_analysis[:assumptions],
39
+ risks: mvp_analysis[:risks],
40
+ metadata: {
41
+ generated_at: Time.now.iso8601,
42
+ mvp_feature_count: mvp_analysis[:must_have].size,
43
+ deferred_feature_count: mvp_analysis[:nice_to_have].size,
44
+ out_of_scope_count: mvp_analysis[:out_of_scope].size,
45
+ user_priorities: priorities
46
+ }
47
+ }
48
+ end
49
+
50
+ # Format MVP scope as markdown
51
+ # @param mvp_scope [Hash] MVP scope structure
52
+ # @return [String] Markdown formatted MVP scope
53
+ def format_as_markdown(mvp_scope)
54
+ Aidp.log_debug("mvp_scope_generator", "format_as_markdown")
55
+
56
+ output = ["# MVP Scope Definition", ""]
57
+ output << "**Generated:** #{mvp_scope[:metadata][:generated_at]}"
58
+ output << "**MVP Features:** #{mvp_scope[:metadata][:mvp_feature_count]}"
59
+ output << "**Deferred Features:** #{mvp_scope[:metadata][:deferred_feature_count]}"
60
+ output << ""
61
+
62
+ output << "## Overview"
63
+ output << ""
64
+ output << "This document defines the Minimum Viable Product (MVP) scope, distinguishing between must-have features for initial release and nice-to-have features that can be deferred to later iterations."
65
+ output << ""
66
+
67
+ output << "## User Priorities"
68
+ output << ""
69
+ mvp_scope[:metadata][:user_priorities].each_with_index do |priority, idx|
70
+ output << "#{idx + 1}. #{priority}"
71
+ end
72
+ output << ""
73
+
74
+ output << "## MVP Features (Must-Have)"
75
+ output << ""
76
+ output << "These features are essential for the MVP and must be included in the first release:"
77
+ output << ""
78
+ mvp_scope[:mvp_features].each_with_index do |feature, idx|
79
+ output << "### #{idx + 1}. #{feature[:name]}"
80
+ output << ""
81
+ output << feature[:description] if feature[:description]
82
+ output << ""
83
+ output << "**Rationale:** #{feature[:rationale]}" if feature[:rationale]
84
+ output << ""
85
+ output << "**Acceptance Criteria:**"
86
+ (feature[:acceptance_criteria] || []).each do |criterion|
87
+ output << "- #{criterion}"
88
+ end
89
+ output << ""
90
+ end
91
+
92
+ output << "## Deferred Features (Nice-to-Have)"
93
+ output << ""
94
+ output << "These features can be implemented in future iterations:"
95
+ output << ""
96
+ mvp_scope[:deferred_features].each_with_index do |feature, idx|
97
+ output << "### #{idx + 1}. #{feature[:name]}"
98
+ output << ""
99
+ output << feature[:description] if feature[:description]
100
+ output << ""
101
+ output << "**Deferral Reason:** #{feature[:deferral_reason]}" if feature[:deferral_reason]
102
+ output << ""
103
+ end
104
+
105
+ output << "## Out of Scope"
106
+ output << ""
107
+ output << "These items are explicitly out of scope for the MVP:"
108
+ output << ""
109
+ mvp_scope[:out_of_scope].each do |item|
110
+ output << "- #{item}"
111
+ end
112
+ output << ""
113
+
114
+ output << "## Success Criteria"
115
+ output << ""
116
+ output << "The MVP will be considered successful if:"
117
+ output << ""
118
+ mvp_scope[:success_criteria].each do |criterion|
119
+ output << "- #{criterion}"
120
+ end
121
+ output << ""
122
+
123
+ output << "## Assumptions"
124
+ output << ""
125
+ mvp_scope[:assumptions].each do |assumption|
126
+ output << "- #{assumption}"
127
+ end
128
+ output << ""
129
+
130
+ output << "## Risks"
131
+ output << ""
132
+ mvp_scope[:risks].each_with_index do |risk, idx|
133
+ output << "#{idx + 1}. **#{risk[:title]}**"
134
+ output << " - **Impact:** #{risk[:impact]}"
135
+ output << " - **Mitigation:** #{risk[:mitigation]}"
136
+ output << ""
137
+ end
138
+
139
+ output.join("\n")
140
+ end
141
+
142
+ private
143
+
144
+ # Collect user priorities interactively
145
+ def collect_user_priorities(prd)
146
+ Aidp.log_debug("mvp_scope_generator", "collect_user_priorities")
147
+
148
+ @prompt.say("Let's define your MVP priorities.")
149
+ @prompt.say("")
150
+
151
+ priorities = []
152
+
153
+ # Ask about key priorities
154
+ priorities << @prompt.ask("What is the primary goal of this MVP?", required: true)
155
+ priorities << @prompt.ask("What is the main problem you're solving?", required: true)
156
+
157
+ # Ask about target users
158
+ target_users = @prompt.ask("Who are your target users?", required: true)
159
+ priorities << "Target users: #{target_users}"
160
+
161
+ # Ask about timeline
162
+ timeline = @prompt.ask("What is your target timeline for MVP launch? (e.g., 3 months)", required: true)
163
+ priorities << "Timeline: #{timeline}"
164
+
165
+ # Ask about constraints
166
+ if @prompt.yes?("Do you have any resource or technical constraints?")
167
+ constraints = @prompt.ask("What constraints should we consider?")
168
+ priorities << "Constraints: #{constraints}"
169
+ end
170
+
171
+ Aidp.log_debug("mvp_scope_generator", "priorities_collected", count: priorities.size)
172
+ priorities
173
+ end
174
+
175
+ # Use AI Decision Engine to analyze features and determine MVP scope
176
+ # This is ZFC - semantic analysis goes to AI, not code
177
+ def analyze_features_with_ai(prd, priorities)
178
+ Aidp.log_debug("mvp_scope_generator", "analyze_features_with_ai")
179
+
180
+ # Build prompt for AI analysis
181
+ prompt = build_mvp_analysis_prompt(prd, priorities)
182
+
183
+ # Define schema for structured output
184
+ schema = {
185
+ type: "object",
186
+ properties: {
187
+ must_have: {
188
+ type: "array",
189
+ items: {
190
+ type: "object",
191
+ properties: {
192
+ name: {type: "string"},
193
+ description: {type: "string"},
194
+ rationale: {type: "string"},
195
+ acceptance_criteria: {type: "array", items: {type: "string"}}
196
+ },
197
+ required: ["name", "description", "rationale"]
198
+ }
199
+ },
200
+ nice_to_have: {
201
+ type: "array",
202
+ items: {
203
+ type: "object",
204
+ properties: {
205
+ name: {type: "string"},
206
+ description: {type: "string"},
207
+ deferral_reason: {type: "string"}
208
+ },
209
+ required: ["name", "description", "deferral_reason"]
210
+ }
211
+ },
212
+ out_of_scope: {
213
+ type: "array",
214
+ items: {type: "string"}
215
+ },
216
+ success_criteria: {
217
+ type: "array",
218
+ items: {type: "string"}
219
+ },
220
+ assumptions: {
221
+ type: "array",
222
+ items: {type: "string"}
223
+ },
224
+ risks: {
225
+ type: "array",
226
+ items: {
227
+ type: "object",
228
+ properties: {
229
+ title: {type: "string"},
230
+ impact: {type: "string"},
231
+ mitigation: {type: "string"}
232
+ }
233
+ }
234
+ }
235
+ },
236
+ required: ["must_have", "nice_to_have", "success_criteria"]
237
+ }
238
+
239
+ # Call AI Decision Engine
240
+ decision = @ai_decision_engine.decide(
241
+ context: "mvp_scope_analysis",
242
+ prompt: prompt,
243
+ data: {
244
+ prd: prd,
245
+ priorities: priorities
246
+ },
247
+ schema: schema
248
+ )
249
+
250
+ Aidp.log_debug("mvp_scope_generator", "ai_analysis_complete",
251
+ must_have: decision[:must_have].size,
252
+ nice_to_have: decision[:nice_to_have].size)
253
+
254
+ decision
255
+ end
256
+
257
+ def build_mvp_analysis_prompt(prd, priorities)
258
+ <<~PROMPT
259
+ Analyze the following Product Requirements Document (PRD) and user priorities to determine the Minimum Viable Product (MVP) scope.
260
+
261
+ USER PRIORITIES:
262
+ #{priorities.map.with_index { |p, i| "#{i + 1}. #{p}" }.join("\n")}
263
+
264
+ PRD SUMMARY:
265
+ #{prd[:content] || prd.inspect}
266
+
267
+ TASK:
268
+ 1. Identify MUST-HAVE features that are absolutely essential for the MVP
269
+ - These should address the primary goal and solve the main problem
270
+ - Consider the target users and timeline
271
+ - Focus on core functionality that delivers value
272
+
273
+ 2. Identify NICE-TO-HAVE features that can be deferred to future iterations
274
+ - These are valuable but not critical for initial release
275
+ - Explain why each can be deferred
276
+
277
+ 3. Identify items that are OUT OF SCOPE for the MVP
278
+ - Features that don't align with MVP goals
279
+ - Advanced features that can wait
280
+
281
+ 4. Define SUCCESS CRITERIA for the MVP
282
+ - Measurable outcomes
283
+ - User satisfaction metrics
284
+ - Technical performance targets
285
+
286
+ 5. List ASSUMPTIONS
287
+ - What are we assuming about users, technology, or resources?
288
+
289
+ 6. Identify RISKS
290
+ - What could prevent MVP success?
291
+ - What's the impact and mitigation strategy?
292
+
293
+ For each must-have feature, provide:
294
+ - Clear name
295
+ - Description
296
+ - Rationale (why it's essential for MVP)
297
+ - Acceptance criteria (how we know it's done)
298
+
299
+ For each nice-to-have feature, provide:
300
+ - Clear name
301
+ - Description
302
+ - Deferral reason (why it can wait)
303
+
304
+ Be pragmatic and focus on delivering value quickly while managing scope.
305
+ PROMPT
306
+ end
307
+ end
308
+ end
309
+ end
310
+ end