From f527972f4d8311a09e639ede6c4da4ca669cfd5e Mon Sep 17 00:00:00 2001 From: Peter Stone Date: Tue, 3 Mar 2026 21:15:06 +0000 Subject: Executor: dependency waiting and planning preamble - Pool.waitForDependencies polls depends_on task states before running - ClaudeRunner prepends planningPreamble to task instructions to prompt a plan-then-implement approach - Rate-limit test helper updated to match new ClaudeRunner signature Co-Authored-By: Claude Sonnet 4.6 --- internal/executor/claude_test.go | 79 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) (limited to 'internal/executor/claude_test.go') diff --git a/internal/executor/claude_test.go b/internal/executor/claude_test.go index 6745957..fa81b09 100644 --- a/internal/executor/claude_test.go +++ b/internal/executor/claude_test.go @@ -1,6 +1,7 @@ package executor import ( + "strings" "testing" "github.com/thepeterstone/claudomator/internal/task" @@ -12,6 +13,7 @@ func TestClaudeRunner_BuildArgs_BasicTask(t *testing.T) { Claude: task.ClaudeConfig{ Instructions: "fix the bug", Model: "sonnet", + SkipPlanning: true, }, } @@ -41,6 +43,7 @@ func TestClaudeRunner_BuildArgs_FullConfig(t *testing.T) { DisallowedTools: []string{"Write"}, ContextFiles: []string{"/src"}, AdditionalArgs: []string{"--verbose"}, + SkipPlanning: true, }, } @@ -72,7 +75,10 @@ func TestClaudeRunner_BuildArgs_FullConfig(t *testing.T) { func TestClaudeRunner_BuildArgs_AlwaysIncludesVerbose(t *testing.T) { r := &ClaudeRunner{} tk := &task.Task{ - Claude: task.ClaudeConfig{Instructions: "do something"}, + Claude: task.ClaudeConfig{ + Instructions: "do something", + SkipPlanning: true, + }, } args := r.buildArgs(tk) @@ -89,6 +95,77 @@ func TestClaudeRunner_BuildArgs_AlwaysIncludesVerbose(t *testing.T) { } } +func TestClaudeRunner_BuildArgs_PreamblePrepended(t *testing.T) { + r := &ClaudeRunner{} + tk := &task.Task{ + Claude: task.ClaudeConfig{ + Instructions: "fix the bug", + SkipPlanning: false, + }, + } + + args := r.buildArgs(tk) + + // The -p value should start with the preamble and end with the original instructions. + if len(args) < 2 || args[0] != "-p" { + t.Fatalf("expected -p as first arg, got: %v", args) + } + if !strings.HasPrefix(args[1], planningPreamble) { + t.Errorf("instructions should start with planning preamble") + } + if !strings.HasSuffix(args[1], "fix the bug") { + t.Errorf("instructions should end with original instructions") + } +} + +func TestClaudeRunner_BuildArgs_PreambleAddsBash(t *testing.T) { + r := &ClaudeRunner{} + tk := &task.Task{ + Claude: task.ClaudeConfig{ + Instructions: "do work", + AllowedTools: []string{"Read"}, + SkipPlanning: false, + }, + } + + args := r.buildArgs(tk) + + // Bash should be appended to allowed tools. + foundBash := false + for i, a := range args { + if a == "--allowedTools" && i+1 < len(args) && args[i+1] == "Bash" { + foundBash = true + } + } + if !foundBash { + t.Errorf("Bash should be added to --allowedTools when preamble is active: %v", args) + } +} + +func TestClaudeRunner_BuildArgs_PreambleBashNotDuplicated(t *testing.T) { + r := &ClaudeRunner{} + tk := &task.Task{ + Claude: task.ClaudeConfig{ + Instructions: "do work", + AllowedTools: []string{"Bash", "Read"}, + SkipPlanning: false, + }, + } + + args := r.buildArgs(tk) + + // Count Bash occurrences in --allowedTools values. + bashCount := 0 + for i, a := range args { + if a == "--allowedTools" && i+1 < len(args) && args[i+1] == "Bash" { + bashCount++ + } + } + if bashCount != 1 { + t.Errorf("Bash should appear exactly once in --allowedTools, got %d: %v", bashCount, args) + } +} + func TestClaudeRunner_BinaryPath_Default(t *testing.T) { r := &ClaudeRunner{} if r.binaryPath() != "claude" { -- cgit v1.2.3