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.
- checksums.yaml +4 -4
- data/README.md +89 -0
- data/lib/aidp/cli/models_command.rb +5 -6
- data/lib/aidp/cli.rb +10 -8
- data/lib/aidp/config.rb +54 -0
- data/lib/aidp/debug_mixin.rb +23 -1
- data/lib/aidp/execute/agent_signal_parser.rb +22 -0
- data/lib/aidp/execute/repl_macros.rb +2 -2
- data/lib/aidp/execute/steps.rb +94 -1
- data/lib/aidp/execute/work_loop_runner.rb +209 -17
- data/lib/aidp/execute/workflow_selector.rb +2 -25
- data/lib/aidp/firewall/provider_requirements_collector.rb +262 -0
- data/lib/aidp/harness/ai_decision_engine.rb +35 -2
- data/lib/aidp/harness/config_manager.rb +0 -5
- data/lib/aidp/harness/config_schema.rb +8 -0
- data/lib/aidp/harness/configuration.rb +27 -19
- data/lib/aidp/harness/enhanced_runner.rb +1 -4
- data/lib/aidp/harness/error_handler.rb +1 -72
- data/lib/aidp/harness/provider_factory.rb +11 -2
- data/lib/aidp/harness/state_manager.rb +0 -7
- data/lib/aidp/harness/thinking_depth_manager.rb +47 -68
- data/lib/aidp/harness/ui/enhanced_tui.rb +8 -18
- data/lib/aidp/harness/ui/enhanced_workflow_selector.rb +0 -18
- data/lib/aidp/harness/ui/progress_display.rb +6 -2
- data/lib/aidp/harness/user_interface.rb +0 -58
- data/lib/aidp/init/runner.rb +7 -2
- data/lib/aidp/planning/analyzers/feedback_analyzer.rb +365 -0
- data/lib/aidp/planning/builders/agile_plan_builder.rb +387 -0
- data/lib/aidp/planning/builders/project_plan_builder.rb +193 -0
- data/lib/aidp/planning/generators/gantt_generator.rb +190 -0
- data/lib/aidp/planning/generators/iteration_plan_generator.rb +392 -0
- data/lib/aidp/planning/generators/legacy_research_planner.rb +473 -0
- data/lib/aidp/planning/generators/marketing_report_generator.rb +348 -0
- data/lib/aidp/planning/generators/mvp_scope_generator.rb +310 -0
- data/lib/aidp/planning/generators/user_test_plan_generator.rb +373 -0
- data/lib/aidp/planning/generators/wbs_generator.rb +259 -0
- data/lib/aidp/planning/mappers/persona_mapper.rb +163 -0
- data/lib/aidp/planning/parsers/document_parser.rb +141 -0
- data/lib/aidp/planning/parsers/feedback_data_parser.rb +252 -0
- data/lib/aidp/provider_manager.rb +8 -32
- data/lib/aidp/providers/aider.rb +264 -0
- data/lib/aidp/providers/anthropic.rb +74 -2
- data/lib/aidp/providers/base.rb +25 -1
- data/lib/aidp/providers/codex.rb +26 -3
- data/lib/aidp/providers/cursor.rb +16 -0
- data/lib/aidp/providers/gemini.rb +13 -0
- data/lib/aidp/providers/github_copilot.rb +17 -0
- data/lib/aidp/providers/kilocode.rb +11 -0
- data/lib/aidp/providers/opencode.rb +11 -0
- data/lib/aidp/setup/wizard.rb +249 -39
- data/lib/aidp/version.rb +1 -1
- data/lib/aidp/watch/build_processor.rb +211 -30
- data/lib/aidp/watch/change_request_processor.rb +128 -14
- data/lib/aidp/watch/ci_fix_processor.rb +103 -37
- data/lib/aidp/watch/ci_log_extractor.rb +258 -0
- data/lib/aidp/watch/github_state_extractor.rb +177 -0
- data/lib/aidp/watch/implementation_verifier.rb +284 -0
- data/lib/aidp/watch/plan_generator.rb +7 -43
- data/lib/aidp/watch/plan_processor.rb +7 -6
- data/lib/aidp/watch/repository_client.rb +245 -17
- data/lib/aidp/watch/review_processor.rb +98 -17
- data/lib/aidp/watch/reviewers/base_reviewer.rb +1 -1
- data/lib/aidp/watch/runner.rb +181 -29
- data/lib/aidp/watch/state_store.rb +22 -1
- data/lib/aidp/workflows/definitions.rb +147 -0
- data/lib/aidp/workstream_cleanup.rb +245 -0
- data/lib/aidp/worktree.rb +19 -0
- data/templates/aidp.yml.example +57 -0
- data/templates/implementation/generate_tdd_specs.md +213 -0
- data/templates/implementation/iterative_implementation.md +122 -0
- data/templates/planning/agile/analyze_feedback.md +183 -0
- data/templates/planning/agile/generate_iteration_plan.md +179 -0
- data/templates/planning/agile/generate_legacy_research_plan.md +171 -0
- data/templates/planning/agile/generate_marketing_report.md +162 -0
- data/templates/planning/agile/generate_mvp_scope.md +127 -0
- data/templates/planning/agile/generate_user_test_plan.md +143 -0
- data/templates/planning/agile/ingest_feedback.md +174 -0
- data/templates/planning/assemble_project_plan.md +113 -0
- data/templates/planning/assign_personas.md +108 -0
- data/templates/planning/create_tasks.md +52 -6
- data/templates/planning/generate_gantt.md +86 -0
- data/templates/planning/generate_wbs.md +85 -0
- data/templates/planning/initialize_planning_mode.md +70 -0
- data/templates/skills/README.md +2 -2
- data/templates/skills/marketing_strategist/SKILL.md +279 -0
- data/templates/skills/product_manager/SKILL.md +177 -0
- data/templates/skills/ruby_aidp_planning/SKILL.md +497 -0
- data/templates/skills/ruby_rspec_tdd/SKILL.md +514 -0
- data/templates/skills/ux_researcher/SKILL.md +222 -0
- metadata +39 -1
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../../logger"
|
|
4
|
+
require "find"
|
|
5
|
+
|
|
6
|
+
module Aidp
|
|
7
|
+
module Planning
|
|
8
|
+
module Generators
|
|
9
|
+
# Generates user research plan for existing/legacy codebases
|
|
10
|
+
# Analyzes code structure to identify features and suggest research priorities
|
|
11
|
+
# Uses Zero Framework Cognition (ZFC) for research question generation
|
|
12
|
+
class LegacyResearchPlanner
|
|
13
|
+
def initialize(ai_decision_engine:, prompt: nil, config: nil)
|
|
14
|
+
@ai_decision_engine = ai_decision_engine
|
|
15
|
+
@prompt = prompt || TTY::Prompt.new
|
|
16
|
+
@config = config || Aidp::Config.agile_config
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Generate legacy research plan from codebase analysis
|
|
20
|
+
# @param codebase_path [String] Path to codebase directory
|
|
21
|
+
# @param language [String] Primary language/framework (optional)
|
|
22
|
+
# @param known_users [String] Known user segments (optional)
|
|
23
|
+
# @return [Hash] Research plan structure
|
|
24
|
+
def generate(codebase_path:, language: nil, known_users: nil)
|
|
25
|
+
Aidp.log_debug("legacy_research_planner", "generate",
|
|
26
|
+
codebase_path: codebase_path,
|
|
27
|
+
language: language)
|
|
28
|
+
|
|
29
|
+
# Analyze codebase structure
|
|
30
|
+
codebase_analysis = analyze_codebase(codebase_path, language)
|
|
31
|
+
|
|
32
|
+
Aidp.log_debug("legacy_research_planner", "codebase_analyzed",
|
|
33
|
+
features: codebase_analysis[:features].size,
|
|
34
|
+
files: codebase_analysis[:file_count])
|
|
35
|
+
|
|
36
|
+
# Use AI to generate research plan
|
|
37
|
+
research_plan = generate_research_plan_with_ai(codebase_analysis, known_users)
|
|
38
|
+
|
|
39
|
+
{
|
|
40
|
+
overview: research_plan[:overview],
|
|
41
|
+
current_features: research_plan[:current_features],
|
|
42
|
+
research_questions: research_plan[:research_questions],
|
|
43
|
+
research_methods: research_plan[:research_methods],
|
|
44
|
+
testing_priorities: research_plan[:testing_priorities],
|
|
45
|
+
user_segments: research_plan[:user_segments],
|
|
46
|
+
improvement_opportunities: research_plan[:improvement_opportunities],
|
|
47
|
+
timeline: research_plan[:timeline],
|
|
48
|
+
codebase_summary: codebase_analysis[:summary],
|
|
49
|
+
metadata: {
|
|
50
|
+
generated_at: Time.now.iso8601,
|
|
51
|
+
codebase_path: codebase_path,
|
|
52
|
+
language: language,
|
|
53
|
+
feature_count: research_plan[:current_features]&.size || 0,
|
|
54
|
+
file_count: codebase_analysis[:file_count],
|
|
55
|
+
research_question_count: research_plan[:research_questions]&.size || 0
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Format research plan as markdown
|
|
61
|
+
# @param plan [Hash] Research plan structure
|
|
62
|
+
# @return [String] Markdown formatted research plan
|
|
63
|
+
def format_as_markdown(plan)
|
|
64
|
+
Aidp.log_debug("legacy_research_planner", "format_as_markdown")
|
|
65
|
+
|
|
66
|
+
output = ["# Legacy User Research Plan", ""]
|
|
67
|
+
output << "**Generated:** #{plan[:metadata][:generated_at]}"
|
|
68
|
+
output << "**Codebase:** #{plan[:metadata][:codebase_path]}"
|
|
69
|
+
output << "**Features Identified:** #{plan[:metadata][:feature_count]}"
|
|
70
|
+
output << "**Files Analyzed:** #{plan[:metadata][:file_count]}"
|
|
71
|
+
output << ""
|
|
72
|
+
|
|
73
|
+
output << "## Overview"
|
|
74
|
+
output << ""
|
|
75
|
+
output << plan[:overview]
|
|
76
|
+
output << ""
|
|
77
|
+
|
|
78
|
+
output << "## Codebase Summary"
|
|
79
|
+
output << ""
|
|
80
|
+
output << plan[:codebase_summary]
|
|
81
|
+
output << ""
|
|
82
|
+
|
|
83
|
+
output << "## Current Features"
|
|
84
|
+
output << ""
|
|
85
|
+
output << "Features identified in the codebase:"
|
|
86
|
+
output << ""
|
|
87
|
+
plan[:current_features].each_with_index do |feature, idx|
|
|
88
|
+
output << "### #{idx + 1}. #{feature[:name]}"
|
|
89
|
+
output << ""
|
|
90
|
+
output << "**Description:** #{feature[:description]}"
|
|
91
|
+
output << ""
|
|
92
|
+
output << "**Entry Points:** #{feature[:entry_points]&.join(", ") || "Unknown"}"
|
|
93
|
+
output << ""
|
|
94
|
+
output << "**Status:** #{feature[:status]}"
|
|
95
|
+
output << ""
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
output << "## Research Questions"
|
|
99
|
+
output << ""
|
|
100
|
+
output << "Key questions to answer about user experience:"
|
|
101
|
+
output << ""
|
|
102
|
+
plan[:research_questions].each_with_index do |question, idx|
|
|
103
|
+
output << "#{idx + 1}. #{question[:question]}"
|
|
104
|
+
output << " - **Category:** #{question[:category]}"
|
|
105
|
+
output << " - **Priority:** #{question[:priority]}"
|
|
106
|
+
output << ""
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
output << "## Recommended Research Methods"
|
|
110
|
+
output << ""
|
|
111
|
+
plan[:research_methods].each do |method|
|
|
112
|
+
output << "### #{method[:name]}"
|
|
113
|
+
output << ""
|
|
114
|
+
output << method[:description]
|
|
115
|
+
output << ""
|
|
116
|
+
output << "**When to Use:** #{method[:when_to_use]}"
|
|
117
|
+
output << ""
|
|
118
|
+
output << "**Expected Insights:** #{method[:expected_insights]}"
|
|
119
|
+
output << ""
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
output << "## Testing Priorities"
|
|
123
|
+
output << ""
|
|
124
|
+
output << "Features/flows to focus on first:"
|
|
125
|
+
output << ""
|
|
126
|
+
plan[:testing_priorities].each_with_index do |priority, idx|
|
|
127
|
+
output << "#{idx + 1}. **#{priority[:feature]}** (Priority: #{priority[:priority]})"
|
|
128
|
+
output << " - Rationale: #{priority[:rationale]}"
|
|
129
|
+
output << " - Focus Areas: #{priority[:focus_areas]&.join(", ")}"
|
|
130
|
+
output << ""
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
output << "## User Segments"
|
|
134
|
+
output << ""
|
|
135
|
+
plan[:user_segments].each do |segment|
|
|
136
|
+
output << "### #{segment[:name]}"
|
|
137
|
+
output << ""
|
|
138
|
+
output << segment[:description]
|
|
139
|
+
output << ""
|
|
140
|
+
output << "**Research Focus:** #{segment[:research_focus]}"
|
|
141
|
+
output << ""
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
output << "## Improvement Opportunities"
|
|
145
|
+
output << ""
|
|
146
|
+
output << "Based on codebase analysis:"
|
|
147
|
+
output << ""
|
|
148
|
+
plan[:improvement_opportunities].each_with_index do |opportunity, idx|
|
|
149
|
+
output << "#{idx + 1}. **#{opportunity[:title]}**"
|
|
150
|
+
output << " - Description: #{opportunity[:description]}"
|
|
151
|
+
output << " - Impact: #{opportunity[:impact]}"
|
|
152
|
+
output << " - Effort: #{opportunity[:effort]}"
|
|
153
|
+
output << ""
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
output << "## Research Timeline"
|
|
157
|
+
output << ""
|
|
158
|
+
plan[:timeline].each do |phase|
|
|
159
|
+
output << "- **#{phase[:phase]}:** #{phase[:duration]}"
|
|
160
|
+
end
|
|
161
|
+
output << ""
|
|
162
|
+
|
|
163
|
+
output.join("\n")
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
private
|
|
167
|
+
|
|
168
|
+
# Analyze codebase structure to extract features and patterns
|
|
169
|
+
def analyze_codebase(codebase_path, language)
|
|
170
|
+
Aidp.log_debug("legacy_research_planner", "analyze_codebase", path: codebase_path)
|
|
171
|
+
|
|
172
|
+
unless Dir.exist?(codebase_path)
|
|
173
|
+
raise ArgumentError, "Codebase path does not exist: #{codebase_path}"
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# Collect basic codebase information
|
|
177
|
+
files = []
|
|
178
|
+
directories = []
|
|
179
|
+
readme_content = nil
|
|
180
|
+
|
|
181
|
+
Find.find(codebase_path) do |path|
|
|
182
|
+
# Skip common ignore patterns
|
|
183
|
+
if File.basename(path).start_with?(".") ||
|
|
184
|
+
path.include?("node_modules") ||
|
|
185
|
+
path.include?("vendor") ||
|
|
186
|
+
path.include?(".git")
|
|
187
|
+
Find.prune
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
if File.directory?(path)
|
|
191
|
+
directories << path
|
|
192
|
+
elsif File.file?(path)
|
|
193
|
+
files << path
|
|
194
|
+
# Try to read README for context
|
|
195
|
+
if File.basename(path).match?(/^README/i)
|
|
196
|
+
readme_content = begin
|
|
197
|
+
File.read(path)
|
|
198
|
+
rescue
|
|
199
|
+
nil
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
# Extract feature hints from directory structure and file names
|
|
206
|
+
features = extract_features_from_structure(files, directories, codebase_path)
|
|
207
|
+
|
|
208
|
+
{
|
|
209
|
+
features: features,
|
|
210
|
+
file_count: files.size,
|
|
211
|
+
directory_count: directories.size,
|
|
212
|
+
readme_content: readme_content,
|
|
213
|
+
language: language || detect_language(files),
|
|
214
|
+
summary: "Analyzed #{files.size} files in #{directories.size} directories. " \
|
|
215
|
+
"Identified #{features.size} potential features based on code structure."
|
|
216
|
+
}
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
# Extract potential features from codebase structure
|
|
220
|
+
def extract_features_from_structure(files, directories, base_path)
|
|
221
|
+
features = []
|
|
222
|
+
|
|
223
|
+
# Look for common patterns in directory names
|
|
224
|
+
directories.each do |dir|
|
|
225
|
+
dir_name = File.basename(dir)
|
|
226
|
+
relative_path = dir.sub("#{base_path}/", "")
|
|
227
|
+
|
|
228
|
+
# Skip common infrastructure directories
|
|
229
|
+
next if %w[lib spec test config bin vendor node_modules].include?(dir_name)
|
|
230
|
+
|
|
231
|
+
# Directories that might represent features
|
|
232
|
+
if relative_path.match?(/features?|components?|modules?|pages?|views?|controllers?|services?/i)
|
|
233
|
+
features << {
|
|
234
|
+
name: dir_name.gsub(/[-_]/, " ").capitalize,
|
|
235
|
+
type: :directory_based,
|
|
236
|
+
path: relative_path,
|
|
237
|
+
description: "Feature identified from directory: #{relative_path}"
|
|
238
|
+
}
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
# Look for controller/route files that indicate features
|
|
243
|
+
files.each do |file|
|
|
244
|
+
file_name = File.basename(file, ".*")
|
|
245
|
+
relative_path = file.sub("#{base_path}/", "")
|
|
246
|
+
|
|
247
|
+
if file.match?(/controller|router|routes|handler/i)
|
|
248
|
+
features << {
|
|
249
|
+
name: file_name.gsub(/[-_](controller|router|routes|handler)/, "").gsub(/[-_]/, " ").capitalize,
|
|
250
|
+
type: :route_based,
|
|
251
|
+
path: relative_path,
|
|
252
|
+
description: "Feature identified from routing/controller file: #{File.basename(file)}"
|
|
253
|
+
}
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
# Deduplicate by name
|
|
258
|
+
features.uniq { |f| f[:name].downcase }.take(20) # Limit to 20 features
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
# Detect primary language from file extensions
|
|
262
|
+
def detect_language(files)
|
|
263
|
+
extensions = files.map { |f| File.extname(f) }.compact
|
|
264
|
+
ext_counts = extensions.each_with_object(Hash.new(0)) { |ext, counts| counts[ext] += 1 }
|
|
265
|
+
|
|
266
|
+
language_map = {
|
|
267
|
+
".rb" => "Ruby",
|
|
268
|
+
".js" => "JavaScript",
|
|
269
|
+
".ts" => "TypeScript",
|
|
270
|
+
".py" => "Python",
|
|
271
|
+
".go" => "Go",
|
|
272
|
+
".java" => "Java",
|
|
273
|
+
".cs" => "C#",
|
|
274
|
+
".php" => "PHP",
|
|
275
|
+
".swift" => "Swift",
|
|
276
|
+
".kt" => "Kotlin"
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
most_common_ext = ext_counts.max_by { |_, count| count }&.first
|
|
280
|
+
language_map[most_common_ext] || "Unknown"
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
def generate_research_plan_with_ai(codebase_analysis, known_users)
|
|
284
|
+
Aidp.log_debug("legacy_research_planner", "generate_research_plan_with_ai")
|
|
285
|
+
|
|
286
|
+
prompt = build_research_plan_prompt(codebase_analysis, known_users)
|
|
287
|
+
|
|
288
|
+
schema = {
|
|
289
|
+
type: "object",
|
|
290
|
+
properties: {
|
|
291
|
+
overview: {type: "string"},
|
|
292
|
+
current_features: {
|
|
293
|
+
type: "array",
|
|
294
|
+
items: {
|
|
295
|
+
type: "object",
|
|
296
|
+
properties: {
|
|
297
|
+
name: {type: "string"},
|
|
298
|
+
description: {type: "string"},
|
|
299
|
+
entry_points: {type: "array", items: {type: "string"}},
|
|
300
|
+
status: {type: "string"}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
},
|
|
304
|
+
research_questions: {
|
|
305
|
+
type: "array",
|
|
306
|
+
items: {
|
|
307
|
+
type: "object",
|
|
308
|
+
properties: {
|
|
309
|
+
question: {type: "string"},
|
|
310
|
+
category: {type: "string"},
|
|
311
|
+
priority: {type: "string"}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
},
|
|
315
|
+
research_methods: {
|
|
316
|
+
type: "array",
|
|
317
|
+
items: {
|
|
318
|
+
type: "object",
|
|
319
|
+
properties: {
|
|
320
|
+
name: {type: "string"},
|
|
321
|
+
description: {type: "string"},
|
|
322
|
+
when_to_use: {type: "string"},
|
|
323
|
+
expected_insights: {type: "string"}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
},
|
|
327
|
+
testing_priorities: {
|
|
328
|
+
type: "array",
|
|
329
|
+
items: {
|
|
330
|
+
type: "object",
|
|
331
|
+
properties: {
|
|
332
|
+
feature: {type: "string"},
|
|
333
|
+
priority: {type: "string"},
|
|
334
|
+
rationale: {type: "string"},
|
|
335
|
+
focus_areas: {type: "array", items: {type: "string"}}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
},
|
|
339
|
+
user_segments: {
|
|
340
|
+
type: "array",
|
|
341
|
+
items: {
|
|
342
|
+
type: "object",
|
|
343
|
+
properties: {
|
|
344
|
+
name: {type: "string"},
|
|
345
|
+
description: {type: "string"},
|
|
346
|
+
research_focus: {type: "string"}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
},
|
|
350
|
+
improvement_opportunities: {
|
|
351
|
+
type: "array",
|
|
352
|
+
items: {
|
|
353
|
+
type: "object",
|
|
354
|
+
properties: {
|
|
355
|
+
title: {type: "string"},
|
|
356
|
+
description: {type: "string"},
|
|
357
|
+
impact: {type: "string"},
|
|
358
|
+
effort: {type: "string"}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
},
|
|
362
|
+
timeline: {
|
|
363
|
+
type: "array",
|
|
364
|
+
items: {
|
|
365
|
+
type: "object",
|
|
366
|
+
properties: {
|
|
367
|
+
phase: {type: "string"},
|
|
368
|
+
duration: {type: "string"}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
},
|
|
373
|
+
required: ["overview", "current_features", "research_questions", "testing_priorities"]
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
decision = @ai_decision_engine.decide(
|
|
377
|
+
context: "legacy_research_plan_generation",
|
|
378
|
+
prompt: prompt,
|
|
379
|
+
data: {
|
|
380
|
+
codebase_analysis: codebase_analysis,
|
|
381
|
+
known_users: known_users
|
|
382
|
+
},
|
|
383
|
+
schema: schema
|
|
384
|
+
)
|
|
385
|
+
|
|
386
|
+
Aidp.log_debug("legacy_research_planner", "ai_plan_generated",
|
|
387
|
+
features: decision[:current_features]&.size || 0,
|
|
388
|
+
questions: decision[:research_questions]&.size || 0)
|
|
389
|
+
|
|
390
|
+
decision
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
def build_research_plan_prompt(codebase_analysis, known_users)
|
|
394
|
+
features_text = codebase_analysis[:features].map { |f|
|
|
395
|
+
"- #{f[:name]} (#{f[:type]}, #{f[:path]})"
|
|
396
|
+
}.join("\n")
|
|
397
|
+
|
|
398
|
+
readme_context = if codebase_analysis[:readme_content]
|
|
399
|
+
<<~README
|
|
400
|
+
README CONTENT (for context):
|
|
401
|
+
#{codebase_analysis[:readme_content][0..2000]}
|
|
402
|
+
README
|
|
403
|
+
else
|
|
404
|
+
""
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
<<~PROMPT
|
|
408
|
+
Generate a comprehensive user research plan for an existing/legacy codebase.
|
|
409
|
+
|
|
410
|
+
CODEBASE ANALYSIS:
|
|
411
|
+
Language: #{codebase_analysis[:language]}
|
|
412
|
+
Files: #{codebase_analysis[:file_count]}
|
|
413
|
+
Directories: #{codebase_analysis[:directory_count]}
|
|
414
|
+
|
|
415
|
+
POTENTIAL FEATURES IDENTIFIED:
|
|
416
|
+
#{features_text}
|
|
417
|
+
|
|
418
|
+
#{readme_context}
|
|
419
|
+
|
|
420
|
+
KNOWN USER SEGMENTS:
|
|
421
|
+
#{known_users || "Not specified - suggest based on codebase"}
|
|
422
|
+
|
|
423
|
+
TASK:
|
|
424
|
+
Create a user research plan to understand how users experience this existing product:
|
|
425
|
+
|
|
426
|
+
1. OVERVIEW
|
|
427
|
+
- Why user research is needed for this product
|
|
428
|
+
- What we hope to learn
|
|
429
|
+
|
|
430
|
+
2. CURRENT FEATURES
|
|
431
|
+
- For each feature identified, provide:
|
|
432
|
+
- Clear name and description
|
|
433
|
+
- Likely entry points (how users access it)
|
|
434
|
+
- Status (active, deprecated, experimental)
|
|
435
|
+
|
|
436
|
+
3. RESEARCH QUESTIONS (8-12 questions)
|
|
437
|
+
- Questions about user experience with current features
|
|
438
|
+
- Category (usability, value, workflow, pain_points, missing_features)
|
|
439
|
+
- Priority (high/medium/low)
|
|
440
|
+
|
|
441
|
+
4. RECOMMENDED RESEARCH METHODS (3-4 methods)
|
|
442
|
+
- Method name (e.g., User Interviews, Surveys, Analytics Analysis)
|
|
443
|
+
- Description of the method
|
|
444
|
+
- When to use it
|
|
445
|
+
- Expected insights
|
|
446
|
+
|
|
447
|
+
5. TESTING PRIORITIES
|
|
448
|
+
- Which features/flows to focus on first
|
|
449
|
+
- Priority level (critical/high/medium)
|
|
450
|
+
- Rationale for prioritization
|
|
451
|
+
- Focus areas for each
|
|
452
|
+
|
|
453
|
+
6. USER SEGMENTS (2-3 segments)
|
|
454
|
+
- Different types of users to study
|
|
455
|
+
- Description of each segment
|
|
456
|
+
- Research focus for that segment
|
|
457
|
+
|
|
458
|
+
7. IMPROVEMENT OPPORTUNITIES
|
|
459
|
+
- Based on code structure, what might need improvement
|
|
460
|
+
- Impact (high/medium/low)
|
|
461
|
+
- Effort estimate (low/medium/high)
|
|
462
|
+
|
|
463
|
+
8. TIMELINE
|
|
464
|
+
- Research phases with duration estimates
|
|
465
|
+
- Codebase analysis, recruitment, data collection, analysis, reporting
|
|
466
|
+
|
|
467
|
+
Focus on understanding existing user experience and identifying improvement opportunities.
|
|
468
|
+
PROMPT
|
|
469
|
+
end
|
|
470
|
+
end
|
|
471
|
+
end
|
|
472
|
+
end
|
|
473
|
+
end
|