summaryrefslogtreecommitdiff
path: root/internal/executor/claude.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/executor/claude.go')
-rw-r--r--internal/executor/claude.go17
1 files changed, 13 insertions, 4 deletions
diff --git a/internal/executor/claude.go b/internal/executor/claude.go
index 4839a90..0e29f7f 100644
--- a/internal/executor/claude.go
+++ b/internal/executor/claude.go
@@ -32,6 +32,7 @@ type ClaudeRunner struct {
type BlockedError struct {
QuestionJSON string // raw JSON from the question file
SessionID string // claude session to resume once the user answers
+ SandboxDir string // preserved sandbox path; resume must run here so Claude finds its session files
}
func (e *BlockedError) Error() string { return fmt.Sprintf("task blocked: %s", e.QuestionJSON) }
@@ -98,10 +99,16 @@ func (r *ClaudeRunner) Run(ctx context.Context, t *task.Task, e *storage.Executi
}
// For new (non-resume) executions with a project_dir, clone into a sandbox.
- // Resume executions run directly in project_dir to pick up the previous session.
+ // Resume executions run in the preserved sandbox (e.SandboxDir) so Claude
+ // finds its session files under the same project slug. If no sandbox was
+ // preserved (e.g. task had no project_dir), fall back to project_dir.
var sandboxDir string
effectiveWorkingDir := projectDir
- if projectDir != "" && e.ResumeSessionID == "" {
+ if e.ResumeSessionID != "" {
+ if e.SandboxDir != "" {
+ effectiveWorkingDir = e.SandboxDir
+ }
+ } else if projectDir != "" {
var err error
sandboxDir, err = setupSandbox(projectDir)
if err != nil {
@@ -137,8 +144,10 @@ func (r *ClaudeRunner) Run(ctx context.Context, t *task.Task, e *storage.Executi
data, readErr := os.ReadFile(questionFile)
if readErr == nil {
os.Remove(questionFile) // consumed
- // Preserve sandbox on BLOCKED — agent may have partial work.
- return &BlockedError{QuestionJSON: strings.TrimSpace(string(data)), SessionID: e.SessionID}
+ // Preserve sandbox on BLOCKED — agent may have partial work and its
+ // Claude session files are stored under the sandbox's project slug.
+ // The resume execution must run in the same directory.
+ return &BlockedError{QuestionJSON: strings.TrimSpace(string(data)), SessionID: e.SessionID, SandboxDir: sandboxDir}
}
// Merge sandbox back to project_dir and clean up.