diff --git a/internal/agent/agent.go b/internal/agent/agent.go index 119aa0c..4177e71 100644 --- a/internal/agent/agent.go +++ b/internal/agent/agent.go @@ -14,6 +14,10 @@ type Agent interface { Name() string } +// GlobalWorkDir is the target codebase directory for agent subprocesses. +// Set this before running agents to ensure they operate on the correct codebase. +var GlobalWorkDir string + // shellQuote quotes a string for safe use in shell commands func shellQuote(s string) string { // Use single quotes and escape any single quotes in the string diff --git a/internal/agent/claude.go b/internal/agent/claude.go index bdf5a36..454f94d 100644 --- a/internal/agent/claude.go +++ b/internal/agent/claude.go @@ -102,6 +102,9 @@ func (a *ClaudeAgent) Run(ctx context.Context, prompt string) (<-chan string, <- claudeArgs += " -p " + shellQuote(prompt) cmd := exec.CommandContext(ctx, "bash", "-lc", claudeArgs) + if GlobalWorkDir != "" { + cmd.Dir = GlobalWorkDir + } stdout, err := cmd.StdoutPipe() if err != nil { diff --git a/internal/agent/codex.go b/internal/agent/codex.go index 14f40f4..d879cbb 100644 --- a/internal/agent/codex.go +++ b/internal/agent/codex.go @@ -63,6 +63,9 @@ func (a *CodexAgent) Run(ctx context.Context, prompt string) (<-chan string, <-c codexArgs += " -" cmd := exec.CommandContext(ctx, "bash", "-lc", codexArgs) + if GlobalWorkDir != "" { + cmd.Dir = GlobalWorkDir + } cmd.Stdin = strings.NewReader(prompt) stdout, err := cmd.StdoutPipe() diff --git a/internal/agent/gemini.go b/internal/agent/gemini.go index 7ed780f..78659e3 100644 --- a/internal/agent/gemini.go +++ b/internal/agent/gemini.go @@ -56,6 +56,9 @@ func (a *GeminiAgent) Run(ctx context.Context, prompt string) (<-chan string, <- } cmd := exec.CommandContext(ctx, "bash", "-lc", geminiArgs) + if GlobalWorkDir != "" { + cmd.Dir = GlobalWorkDir + } cmd.Stdin = strings.NewReader(prompt) stdout, err := cmd.StdoutPipe() diff --git a/internal/cli/assess.go b/internal/cli/assess.go index c45c094..4f184fb 100644 --- a/internal/cli/assess.go +++ b/internal/cli/assess.go @@ -52,6 +52,11 @@ func runAssess(cmd *cobra.Command, args []string) error { return fmt.Errorf("failed to load plan: %w", err) } + // Set working directory for agent subprocesses from plan + if p.CodebaseRoot != "" { + agent.GlobalWorkDir = p.CodebaseRoot + } + display.PrintHeader("ASSESS") display.PrintStatus("Plan: %s", p.Name) diff --git a/internal/cli/complete.go b/internal/cli/complete.go index 489f2c3..af62933 100644 --- a/internal/cli/complete.go +++ b/internal/cli/complete.go @@ -53,6 +53,11 @@ func runComplete(cmd *cobra.Command, args []string) error { return fmt.Errorf("failed to load plan: %w", err) } + // Set working directory for agent subprocesses from plan + if p.CodebaseRoot != "" { + agent.GlobalWorkDir = p.CodebaseRoot + } + display.PrintHeader("SYNTHESIZE") display.PrintStatus("Plan: %s", p.Name) display.PrintStatus("Subsystem: %s", completeSubsystem) diff --git a/internal/cli/convene.go b/internal/cli/convene.go index 04b0771..393270d 100644 --- a/internal/cli/convene.go +++ b/internal/cli/convene.go @@ -95,6 +95,11 @@ func runConvene(cmd *cobra.Command, args []string) error { return fmt.Errorf("failed to load plan: %w", err) } + // Set working directory for agent subprocesses from plan + if p.CodebaseRoot != "" { + agent.GlobalWorkDir = p.CodebaseRoot + } + display.PrintHeader("CONVENE") display.PrintStatus("Plan: %s", p.Name) display.PrintStatus("Subsystem: %s", conveneSubsystem) diff --git a/internal/cli/plan.go b/internal/cli/plan.go index 94be1c7..2e4206b 100644 --- a/internal/cli/plan.go +++ b/internal/cli/plan.go @@ -52,6 +52,9 @@ func runPlan(cmd *cobra.Command, args []string) error { return fmt.Errorf("path must be a directory: %s", absPath) } + // Set working directory for all agent subprocesses + agent.GlobalWorkDir = absPath + // Initialize state directory st, err := state.New(absPath) if err != nil { diff --git a/internal/cli/run.go b/internal/cli/run.go index 3e91bf9..b948950 100644 --- a/internal/cli/run.go +++ b/internal/cli/run.go @@ -83,6 +83,9 @@ func runFull(cmd *cobra.Command, args []string) error { return fmt.Errorf("path must be a directory: %s", absPath) } + // Set working directory for all agent subprocesses + agent.GlobalWorkDir = absPath + // Initialize state st, err := state.New(absPath) if err != nil {