@@ -305,6 +305,106 @@ pub fn generateEvaluationPrompt(allocator: Allocator) ![]const u8 {
305305 ;
306306}
307307
308+ /// Generate prompt for AI to select which idea to work on
309+ /// Considers both simplicity/quick-wins and dependencies between ideas
310+ pub fn generateIdeaSelectionPrompt (ideas_formatted : []const u8 , allocator : Allocator ) ! []const u8 {
311+ var result = std .array_list .AlignedManaged (u8 , null ).init (allocator );
312+ errdefer result .deinit ();
313+
314+ try result .appendSlice (
315+ \\You are an AI assistant helping prioritize development tasks.
316+ \\
317+ \\Below are several ideas/tasks that need to be implemented. Your job is to:
318+ \\1. Analyze each idea for complexity and effort required
319+ \\2. Identify any DEPENDENCIES between ideas (if idea B requires idea A to be done first)
320+ \\3. Select the SIMPLEST idea that has NO blocking dependencies
321+ \\4. Prioritize: bug fixes > small features > documentation > refactoring > large features
322+ \\
323+ \\IMPORTANT: If ideas have dependencies, you MUST select one that can be implemented
324+ \\independently OR is a prerequisite for other ideas.
325+ \\
326+ \\IDEAS TO EVALUATE:
327+ \\
328+ \\
329+ );
330+
331+ try result .appendSlice (ideas_formatted );
332+
333+ try result .appendSlice (
334+ \\
335+ \\Respond with ONLY the idea number you selected and a brief reason, in this exact format:
336+ \\SELECTED_IDEA: <number>
337+ \\REASON: <one sentence explaining why this is the best quick-win>
338+ \\
339+ \\For example:
340+ \\SELECTED_IDEA: 2
341+ \\REASON: Small bug fix with no dependencies, can be completed quickly.
342+ \\
343+ \\Choose the quickest win that unblocks other work if dependencies exist.
344+ );
345+
346+ return result .toOwnedSlice ();
347+ }
348+
349+ /// Generate planning prompt for a specific idea
350+ /// The idea takes full precedence over any user hints
351+ pub fn generateIdeaPlanningPrompt (cycle : u32 , idea_content : []const u8 , idea_filename : []const u8 , allocator : Allocator ) ! []const u8 {
352+ var ts_buf : [24 ]u8 = undefined ;
353+ const ts = logger .timestampISO (& ts_buf );
354+
355+ var result = std .array_list .AlignedManaged (u8 , null ).init (allocator );
356+ errdefer result .deinit ();
357+
358+ try result .appendSlice (
359+ \\CRITICAL: You are operating in an AUTONOMOUS CONTINUOUS DEVELOPMENT loop.
360+ \\
361+ \\You have been assigned a SPECIFIC IDEA to implement. Focus ONLY on this idea.
362+ \\
363+ \\STRICT REQUIREMENTS:
364+ \\- You MUST create a plan with AT LEAST 3 actionable tasks for this specific idea
365+ \\- NEVER ask questions or wait for user input
366+ \\- Focus entirely on implementing the idea described below
367+ \\- Break down the idea into concrete, actionable steps
368+ \\
369+ \\IDEA TO IMPLEMENT (from
370+ );
371+ try result .appendSlice (idea_filename );
372+ try result .appendSlice ("):\n\n " );
373+ try result .appendSlice (idea_content );
374+ try result .appendSlice (
375+ \\
376+ \\
377+ \\Your task: Create a concrete development plan to implement this idea.
378+ \\Save a markdown checklist to .opencoder/current_plan.md with 3-10 actionable tasks.
379+ \\
380+ \\The plan MUST follow this exact format:
381+ \\# Plan: [descriptive title based on the idea]
382+ \\Created:
383+ );
384+ try result .appendSlice (ts );
385+ try result .appendSlice ("\n Cycle: " );
386+ try result .writer ().print ("{d}" , .{cycle });
387+ try result .appendSlice (
388+ \\
389+ \\
390+ \\## Context
391+ \\[Brief description of the idea and its purpose]
392+ \\
393+ \\## Tasks
394+ \\- [ ] Task 1: Specific, actionable description
395+ \\- [ ] Task 2: Specific, actionable description
396+ \\- [ ] Task 3: Specific, actionable description
397+ \\[Add more tasks as needed]
398+ \\
399+ \\## Notes
400+ \\[Any additional context or dependencies]
401+ \\
402+ \\After creating the plan file, respond with: PLAN_CREATED
403+ );
404+
405+ return result .toOwnedSlice ();
406+ }
407+
308408// ============================================================================
309409// Tests
310410// ============================================================================
@@ -422,3 +522,26 @@ test "generateEvaluationPrompt returns valid prompt" {
422522 try std .testing .expect (std .mem .indexOf (u8 , prompt , "COMPLETE" ) != null );
423523 try std .testing .expect (std .mem .indexOf (u8 , prompt , "NEEDS_WORK" ) != null );
424524}
525+
526+ test "generateIdeaSelectionPrompt includes ideas and format" {
527+ const allocator = std .testing .allocator ;
528+ const ideas = "## Idea 1: test.md\n Test content" ;
529+ const prompt = try generateIdeaSelectionPrompt (ideas , allocator );
530+ defer allocator .free (prompt );
531+
532+ try std .testing .expect (std .mem .indexOf (u8 , prompt , "SELECTED_IDEA:" ) != null );
533+ try std .testing .expect (std .mem .indexOf (u8 , prompt , "REASON:" ) != null );
534+ try std .testing .expect (std .mem .indexOf (u8 , prompt , "Test content" ) != null );
535+ try std .testing .expect (std .mem .indexOf (u8 , prompt , "dependencies" ) != null );
536+ }
537+
538+ test "generateIdeaPlanningPrompt includes idea content and filename" {
539+ const allocator = std .testing .allocator ;
540+ const prompt = try generateIdeaPlanningPrompt (5 , "Add dark mode support" , "dark-mode.md" , allocator );
541+ defer allocator .free (prompt );
542+
543+ try std .testing .expect (std .mem .indexOf (u8 , prompt , "Add dark mode support" ) != null );
544+ try std .testing .expect (std .mem .indexOf (u8 , prompt , "dark-mode.md" ) != null );
545+ try std .testing .expect (std .mem .indexOf (u8 , prompt , "PLAN_CREATED" ) != null );
546+ try std .testing .expect (std .mem .indexOf (u8 , prompt , "Cycle: 5" ) != null );
547+ }
0 commit comments