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
@@ -6,6 +6,7 @@ require_relative "../message_display"
6
6
  require_relative "repository_client"
7
7
  require_relative "repository_safety_checker"
8
8
  require_relative "state_store"
9
+ require_relative "github_state_extractor"
9
10
  require_relative "plan_generator"
10
11
  require_relative "plan_processor"
11
12
  require_relative "build_processor"
@@ -40,10 +41,21 @@ module Aidp
40
41
  config: safety_config
41
42
  )
42
43
  @state_store = StateStore.new(project_dir: project_dir, repository: "#{owner}/#{repo}")
44
+ @state_extractor = GitHubStateExtractor.new(repository_client: @repository_client)
43
45
 
44
46
  # Extract label configuration from safety_config (it's actually the full watch config)
45
47
  label_config = safety_config[:labels] || safety_config["labels"] || {}
46
48
 
49
+ # Extract detection comment configuration (issue #280)
50
+ # Enabled by default, can be disabled in config
51
+ @post_detection_comments = if safety_config.key?(:post_detection_comments)
52
+ safety_config[:post_detection_comments]
53
+ elsif safety_config.key?("post_detection_comments")
54
+ safety_config["post_detection_comments"]
55
+ else
56
+ true # Enabled by default
57
+ end
58
+
47
59
  @plan_processor = PlanProcessor.new(
48
60
  repository_client: @repository_client,
49
61
  state_store: @state_store,
@@ -138,7 +150,12 @@ module Aidp
138
150
 
139
151
  def process_plan_triggers
140
152
  plan_label = @plan_processor.plan_label
141
- issues = @repository_client.list_issues(labels: [plan_label], state: "open")
153
+ begin
154
+ issues = @repository_client.list_issues(labels: [plan_label], state: "open")
155
+ rescue => e
156
+ Aidp.log_error("watch_runner", "plan_poll_failed", label: plan_label, error: e.message)
157
+ return # Skip this cycle, continue watch loop
158
+ end
142
159
  Aidp.log_debug("watch_runner", "plan_poll", label: plan_label, total: issues.size)
143
160
  issues.each do |issue|
144
161
  unless issue_has_label?(issue, plan_label)
@@ -146,7 +163,18 @@ module Aidp
146
163
  next
147
164
  end
148
165
 
149
- detailed = @repository_client.fetch_issue(issue[:number])
166
+ begin
167
+ detailed = @repository_client.fetch_issue(issue[:number])
168
+ rescue => e
169
+ Aidp.log_error("watch_runner", "fetch_issue_failed", issue: issue[:number], error: e.message)
170
+ next # Skip this issue, continue with others
171
+ end
172
+
173
+ # Check if already in progress by another instance
174
+ if @state_extractor.in_progress?(detailed)
175
+ Aidp.log_debug("watch_runner", "plan_skip_in_progress", issue: detailed[:number])
176
+ next
177
+ end
150
178
 
151
179
  # Check author authorization before processing
152
180
  unless @safety_checker.should_process_issue?(detailed, enforce: false)
@@ -154,6 +182,11 @@ module Aidp
154
182
  next
155
183
  end
156
184
 
185
+ # Check if detection comment already posted (deduplication)
186
+ unless @state_extractor.detection_comment_posted?(detailed, plan_label)
187
+ post_detection_comment(item_type: :issue, number: detailed[:number], label: plan_label)
188
+ end
189
+
157
190
  Aidp.log_debug("watch_runner", "plan_process", issue: detailed[:number])
158
191
  @plan_processor.process(detailed)
159
192
  rescue RepositorySafetyChecker::UnauthorizedAuthorError => e
@@ -163,38 +196,82 @@ module Aidp
163
196
 
164
197
  def process_build_triggers
165
198
  build_label = @build_processor.build_label
166
- issues = @repository_client.list_issues(labels: [build_label], state: "open")
199
+ begin
200
+ issues = @repository_client.list_issues(labels: [build_label], state: "open")
201
+ rescue => e
202
+ Aidp.log_error("watch_runner", "build_poll_failed", label: build_label, error: e.message)
203
+ return # Skip this cycle, continue watch loop
204
+ end
167
205
  Aidp.log_debug("watch_runner", "build_poll", label: build_label, total: issues.size)
168
206
  issues.each do |issue|
169
- unless issue_has_label?(issue, build_label)
170
- Aidp.log_debug("watch_runner", "build_skip_label_mismatch", issue: issue[:number], labels: issue[:labels])
171
- next
207
+ detailed = nil
208
+ in_progress_added = false
209
+
210
+ begin
211
+ unless issue_has_label?(issue, build_label)
212
+ Aidp.log_debug("watch_runner", "build_skip_label_mismatch", issue: issue[:number], labels: issue[:labels])
213
+ next
214
+ end
215
+
216
+ begin
217
+ detailed = @repository_client.fetch_issue(issue[:number])
218
+ rescue => e
219
+ Aidp.log_error("watch_runner", "fetch_issue_failed", issue: issue[:number], error: e.message)
220
+ next # Skip this issue, continue with others
221
+ end
222
+
223
+ # Check if already completed (via GitHub comments)
224
+ if @state_extractor.build_completed?(detailed)
225
+ Aidp.log_debug("watch_runner", "build_skip_completed", issue: detailed[:number])
226
+ next
227
+ end
228
+
229
+ # Check if already in progress by another instance
230
+ if @state_extractor.in_progress?(detailed)
231
+ Aidp.log_debug("watch_runner", "build_skip_in_progress", issue: detailed[:number])
232
+ next
233
+ end
234
+
235
+ # Check author authorization before processing
236
+ unless @safety_checker.should_process_issue?(detailed, enforce: false)
237
+ Aidp.log_debug("watch_runner", "build_skip_unauthorized_author", issue: detailed[:number], author: detailed[:author])
238
+ next
239
+ end
240
+
241
+ # Check if detection comment already posted (deduplication)
242
+ unless @state_extractor.detection_comment_posted?(detailed, build_label)
243
+ post_detection_comment(item_type: :issue, number: detailed[:number], label: build_label)
244
+ end
245
+
246
+ # Add in-progress label before processing
247
+ @repository_client.add_labels(detailed[:number], GitHubStateExtractor::IN_PROGRESS_LABEL)
248
+ in_progress_added = true
249
+
250
+ Aidp.log_debug("watch_runner", "build_process", issue: detailed[:number])
251
+ @build_processor.process(detailed)
252
+ rescue RepositorySafetyChecker::UnauthorizedAuthorError => e
253
+ Aidp.log_warn("watch_runner", "unauthorized issue author", issue: issue[:number], error: e.message)
254
+ ensure
255
+ # Remove in-progress label when done (only if we added it)
256
+ if in_progress_added && detailed
257
+ begin
258
+ @repository_client.remove_labels(detailed[:number], GitHubStateExtractor::IN_PROGRESS_LABEL)
259
+ rescue => e
260
+ Aidp.log_warn("watch_runner", "failed_to_remove_in_progress_label", issue: detailed[:number], error: e.message)
261
+ end
262
+ end
172
263
  end
173
-
174
- status = @state_store.build_status(issue[:number])
175
- if status["status"] == "completed"
176
- Aidp.log_debug("watch_runner", "build_skip_completed", issue: issue[:number])
177
- next
178
- end
179
-
180
- detailed = @repository_client.fetch_issue(issue[:number])
181
-
182
- # Check author authorization before processing
183
- unless @safety_checker.should_process_issue?(detailed, enforce: false)
184
- Aidp.log_debug("watch_runner", "build_skip_unauthorized_author", issue: detailed[:number], author: detailed[:author])
185
- next
186
- end
187
-
188
- Aidp.log_debug("watch_runner", "build_process", issue: detailed[:number])
189
- @build_processor.process(detailed)
190
- rescue RepositorySafetyChecker::UnauthorizedAuthorError => e
191
- Aidp.log_warn("watch_runner", "unauthorized issue author", issue: issue[:number], error: e.message)
192
264
  end
193
265
  end
194
266
 
195
267
  def process_review_triggers
196
268
  review_label = @review_processor.review_label
197
- prs = @repository_client.list_pull_requests(labels: [review_label], state: "open")
269
+ begin
270
+ prs = @repository_client.list_pull_requests(labels: [review_label], state: "open")
271
+ rescue => e
272
+ Aidp.log_error("watch_runner", "review_poll_failed", label: review_label, error: e.message)
273
+ return # Skip this cycle, continue watch loop
274
+ end
198
275
  Aidp.log_debug("watch_runner", "review_poll", label: review_label, total: prs.size)
199
276
  prs.each do |pr|
200
277
  unless pr_has_label?(pr, review_label)
@@ -202,7 +279,18 @@ module Aidp
202
279
  next
203
280
  end
204
281
 
205
- detailed = @repository_client.fetch_pull_request(pr[:number])
282
+ begin
283
+ detailed = @repository_client.fetch_pull_request(pr[:number])
284
+ rescue => e
285
+ Aidp.log_error("watch_runner", "fetch_pr_failed", pr: pr[:number], error: e.message)
286
+ next # Skip this PR, continue with others
287
+ end
288
+
289
+ # Check if already in progress by another instance
290
+ if @state_extractor.in_progress?(detailed)
291
+ Aidp.log_debug("watch_runner", "review_skip_in_progress", pr: detailed[:number])
292
+ next
293
+ end
206
294
 
207
295
  # Check author authorization before processing
208
296
  unless @safety_checker.should_process_issue?(detailed, enforce: false)
@@ -210,6 +298,11 @@ module Aidp
210
298
  next
211
299
  end
212
300
 
301
+ # Check if detection comment already posted (deduplication)
302
+ unless @state_extractor.detection_comment_posted?(detailed, review_label)
303
+ post_detection_comment(item_type: :pr, number: detailed[:number], label: review_label)
304
+ end
305
+
213
306
  Aidp.log_debug("watch_runner", "review_process", pr: detailed[:number])
214
307
  @review_processor.process(detailed)
215
308
  rescue RepositorySafetyChecker::UnauthorizedAuthorError => e
@@ -229,12 +322,23 @@ module Aidp
229
322
 
230
323
  detailed = @repository_client.fetch_pull_request(pr[:number])
231
324
 
325
+ # Check if already in progress by another instance
326
+ if @state_extractor.in_progress?(detailed)
327
+ Aidp.log_debug("watch_runner", "ci_fix_skip_in_progress", pr: detailed[:number])
328
+ next
329
+ end
330
+
232
331
  # Check author authorization before processing
233
332
  unless @safety_checker.should_process_issue?(detailed, enforce: false)
234
333
  Aidp.log_debug("watch_runner", "ci_fix_skip_unauthorized_author", pr: detailed[:number], author: detailed[:author])
235
334
  next
236
335
  end
237
336
 
337
+ # Check if detection comment already posted (deduplication)
338
+ unless @state_extractor.detection_comment_posted?(detailed, ci_fix_label)
339
+ post_detection_comment(item_type: :pr, number: detailed[:number], label: ci_fix_label)
340
+ end
341
+
238
342
  Aidp.log_debug("watch_runner", "ci_fix_process", pr: detailed[:number])
239
343
  @ci_fix_processor.process(detailed)
240
344
  rescue RepositorySafetyChecker::UnauthorizedAuthorError => e
@@ -254,12 +358,23 @@ module Aidp
254
358
 
255
359
  detailed = @repository_client.fetch_pull_request(pr[:number])
256
360
 
361
+ # Check if already in progress by another instance
362
+ if @state_extractor.in_progress?(detailed)
363
+ Aidp.log_debug("watch_runner", "change_request_skip_in_progress", pr: detailed[:number])
364
+ next
365
+ end
366
+
257
367
  # Check author authorization before processing
258
368
  unless @safety_checker.should_process_issue?(detailed, enforce: false)
259
369
  Aidp.log_debug("watch_runner", "change_request_skip_unauthorized_author", pr: detailed[:number], author: detailed[:author])
260
370
  next
261
371
  end
262
372
 
373
+ # Check if detection comment already posted (deduplication)
374
+ unless @state_extractor.detection_comment_posted?(detailed, change_request_label)
375
+ post_detection_comment(item_type: :pr, number: detailed[:number], label: change_request_label)
376
+ end
377
+
263
378
  Aidp.log_debug("watch_runner", "change_request_process", pr: detailed[:number])
264
379
  @change_request_processor.process(detailed)
265
380
  rescue RepositorySafetyChecker::UnauthorizedAuthorError => e
@@ -269,7 +384,7 @@ module Aidp
269
384
 
270
385
  def issue_has_label?(issue, label)
271
386
  Array(issue[:labels]).any? do |issue_label|
272
- name = issue_label.is_a?(Hash) ? issue_label["name"] : issue_label.to_s
387
+ name = (issue_label.is_a?(Hash) ? issue_label["name"] : issue_label.to_s)
273
388
  name.casecmp(label).zero?
274
389
  end
275
390
  end
@@ -371,9 +486,46 @@ module Aidp
371
486
  {}
372
487
  end
373
488
 
489
+ # Post detection comment to GitHub when aidp picks up a labeled item (issue #280)
490
+ # @param item_type [Symbol] Type of item (:issue or :pr)
491
+ # @param number [Integer] Issue or PR number
492
+ # @param label [String] Label that triggered detection
493
+ def post_detection_comment(item_type:, number:, label:)
494
+ return unless @post_detection_comments
495
+
496
+ # Check if we've already posted a detection comment for this item/label combination
497
+ detection_key = "#{item_type}_#{number}_#{label}"
498
+ return if @state_store.detection_comment_posted?(detection_key)
499
+
500
+ timestamp = Time.now.utc.iso8601
501
+ item_name = (item_type == :pr) ? "PR" : "issue"
502
+
503
+ comment_body = "aidp detected `#{label}` at #{timestamp} and is working on it"
504
+
505
+ begin
506
+ @repository_client.post_comment(number, comment_body)
507
+ @state_store.record_detection_comment(detection_key, timestamp: timestamp)
508
+
509
+ Aidp.log_info("watch_runner", "detection_comment_posted",
510
+ item_type: item_type,
511
+ number: number,
512
+ label: label,
513
+ timestamp: timestamp)
514
+
515
+ display_message("๐Ÿ’ฌ Posted detection comment for #{item_name} ##{number}", type: :info) if @verbose
516
+ rescue => e
517
+ # Don't fail processing if comment posting fails - just log it
518
+ Aidp.log_warn("watch_runner", "detection_comment_failed",
519
+ item_type: item_type,
520
+ number: number,
521
+ label: label,
522
+ error: e.message)
523
+ end
524
+ end
525
+
374
526
  def pr_has_label?(pr, label)
375
527
  Array(pr[:labels]).any? do |pr_label|
376
- name = pr_label.is_a?(Hash) ? pr_label["name"] : pr_label.to_s
528
+ name = (pr_label.is_a?(Hash) ? pr_label["name"] : pr_label.to_s)
377
529
  name.casecmp(label).zero?
378
530
  end
379
531
  end
@@ -124,7 +124,10 @@ module Aidp
124
124
  "changes_applied" => data[:changes_applied],
125
125
  "commits" => data[:commits],
126
126
  "reason" => data[:reason],
127
- "clarification_count" => data[:clarification_count]
127
+ "clarification_count" => data[:clarification_count],
128
+ "verification_reasons" => data[:verification_reasons],
129
+ "missing_items" => data[:missing_items],
130
+ "additional_work" => data[:additional_work]
128
131
  }.compact
129
132
 
130
133
  change_requests[pr_number.to_s] = payload
@@ -136,6 +139,19 @@ module Aidp
136
139
  save!
137
140
  end
138
141
 
142
+ # Detection comment tracking methods (issue #280)
143
+ def detection_comment_posted?(detection_key)
144
+ detection_comments.key?(detection_key.to_s)
145
+ end
146
+
147
+ def record_detection_comment(detection_key, timestamp:)
148
+ detection_comments[detection_key.to_s] = {
149
+ "timestamp" => timestamp,
150
+ "posted_at" => Time.now.utc.iso8601
151
+ }
152
+ save!
153
+ end
154
+
139
155
  private
140
156
 
141
157
  def ensure_directory
@@ -167,6 +183,7 @@ module Aidp
167
183
  base["reviews"] ||= {}
168
184
  base["ci_fixes"] ||= {}
169
185
  base["change_requests"] ||= {}
186
+ base["detection_comments"] ||= {}
170
187
  base
171
188
  end
172
189
  end
@@ -191,6 +208,10 @@ module Aidp
191
208
  state["change_requests"]
192
209
  end
193
210
 
211
+ def detection_comments
212
+ state["detection_comments"]
213
+ end
214
+
194
215
  def stringify_keys(hash)
195
216
  return {} unless hash
196
217
 
@@ -165,6 +165,26 @@ module Aidp
165
165
  ]
166
166
  },
167
167
 
168
+ tdd_feature_development: {
169
+ name: "TDD Feature Development",
170
+ description: "Test-driven development with tests written first",
171
+ icon: "๐Ÿงช",
172
+ details: [
173
+ "Product requirements",
174
+ "Architecture design",
175
+ "TDD test specifications (write tests FIRST)",
176
+ "RED: Tests fail initially",
177
+ "GREEN: Implement to pass tests",
178
+ "REFACTOR: Improve with confidence"
179
+ ],
180
+ steps: [
181
+ "00_PRD",
182
+ "02_ARCHITECTURE",
183
+ "17_TDD_SPECIFICATION",
184
+ "16_IMPLEMENTATION"
185
+ ]
186
+ },
187
+
168
188
  production_ready: {
169
189
  name: "Production-Ready",
170
190
  description: "Enterprise-grade with NFRs and compliance",
@@ -227,6 +247,133 @@ module Aidp
227
247
  ]
228
248
  },
229
249
 
250
+ waterfall_standard: {
251
+ name: "Waterfall Planning",
252
+ description: "Structured project planning with WBS and Gantt charts",
253
+ icon: "๐Ÿ“Š",
254
+ details: [
255
+ "Documentation ingestion or generation",
256
+ "Work breakdown structure (WBS)",
257
+ "Gantt chart with critical path",
258
+ "Task dependencies and milestones",
259
+ "Persona/agent assignment",
260
+ "Complete project plan"
261
+ ],
262
+ steps: [
263
+ "22_PLANNING_MODE_INIT",
264
+ "00_PRD",
265
+ "02_ARCHITECTURE",
266
+ "18_WBS",
267
+ "19_GANTT_CHART",
268
+ "20_PERSONA_ASSIGNMENT",
269
+ "21_PROJECT_PLAN_ASSEMBLY",
270
+ "16_IMPLEMENTATION"
271
+ ]
272
+ },
273
+
274
+ waterfall_minimal: {
275
+ name: "Waterfall Planning (Minimal)",
276
+ description: "Quick waterfall planning without full enterprise features",
277
+ icon: "๐Ÿ“‹",
278
+ details: [
279
+ "Essential documentation",
280
+ "Basic work breakdown",
281
+ "Simple Gantt chart",
282
+ "Task list with dependencies"
283
+ ],
284
+ steps: [
285
+ "22_PLANNING_MODE_INIT",
286
+ "00_PRD",
287
+ "18_WBS",
288
+ "16_IMPLEMENTATION"
289
+ ]
290
+ },
291
+
292
+ waterfall_tdd: {
293
+ name: "Waterfall Planning with TDD",
294
+ description: "Waterfall planning with test-driven development",
295
+ icon: "๐Ÿ“Š๐Ÿงช",
296
+ details: [
297
+ "Complete waterfall planning",
298
+ "Work breakdown structure",
299
+ "Gantt chart with critical path",
300
+ "TDD test specifications (write tests first)",
301
+ "Test-driven implementation",
302
+ "Persona assignments"
303
+ ],
304
+ steps: [
305
+ "22_PLANNING_MODE_INIT",
306
+ "00_PRD",
307
+ "02_ARCHITECTURE",
308
+ "18_WBS",
309
+ "19_GANTT_CHART",
310
+ "17_TDD_SPECIFICATION",
311
+ "20_PERSONA_ASSIGNMENT",
312
+ "21_PROJECT_PLAN_ASSEMBLY",
313
+ "16_IMPLEMENTATION"
314
+ ]
315
+ },
316
+
317
+ agile_mvp: {
318
+ name: "Agile MVP Planning",
319
+ description: "Plan MVP with user testing and marketing",
320
+ icon: "๐Ÿš€",
321
+ details: [
322
+ "MVP scope definition (must-have vs nice-to-have)",
323
+ "User testing plan with surveys and interviews",
324
+ "Marketing materials and messaging",
325
+ "Timeline with Gantt chart",
326
+ "Persona assignments"
327
+ ],
328
+ steps: [
329
+ "00_PRD",
330
+ "23_MVP_SCOPE",
331
+ "24_USER_TEST_PLAN",
332
+ "25_MARKETING_REPORT",
333
+ "19_GANTT_CHART",
334
+ "20_PERSONA_ASSIGNMENT",
335
+ "16_IMPLEMENTATION"
336
+ ]
337
+ },
338
+
339
+ agile_iteration: {
340
+ name: "Agile Iteration Planning",
341
+ description: "Plan next iteration based on user feedback",
342
+ icon: "๐Ÿ”„",
343
+ details: [
344
+ "Ingest user feedback data (CSV/JSON/markdown)",
345
+ "AI-powered feedback analysis",
346
+ "Next iteration plan with tasks",
347
+ "Timeline with Gantt chart",
348
+ "Persona assignments"
349
+ ],
350
+ steps: [
351
+ "26_INGEST_FEEDBACK",
352
+ "27_ANALYZE_FEEDBACK",
353
+ "28_ITERATION_PLAN",
354
+ "19_GANTT_CHART",
355
+ "20_PERSONA_ASSIGNMENT",
356
+ "16_IMPLEMENTATION"
357
+ ]
358
+ },
359
+
360
+ agile_legacy_research: {
361
+ name: "Legacy Product Research",
362
+ description: "Plan user research for existing codebase",
363
+ icon: "๐Ÿ”",
364
+ details: [
365
+ "Codebase analysis to identify features",
366
+ "User research plan generation",
367
+ "User testing plan with priorities",
368
+ "Improvement recommendations"
369
+ ],
370
+ steps: [
371
+ "29_LEGACY_RESEARCH_PLAN",
372
+ "24_USER_TEST_PLAN",
373
+ "16_IMPLEMENTATION"
374
+ ]
375
+ },
376
+
230
377
  custom: {
231
378
  name: "Custom Workflow",
232
379
  description: "Choose specific planning and implementation steps",