diff options
| author | Peter Stone <thepeterstone@gmail.com> | 2026-03-08 20:16:00 +0000 |
|---|---|---|
| committer | Peter Stone <thepeterstone@gmail.com> | 2026-03-08 20:16:00 +0000 |
| commit | 1f36e2312d316969db65a601ac7d9793fbc3bc4c (patch) | |
| tree | 1d91358beaf910df23a5bd18b9dabbc3f59d448a /internal/task | |
| parent | 9955a2f10c034dac60bc17cde6b80b432e21d9d3 (diff) | |
feat: rename working_dir→project_dir; git sandbox execution
- ClaudeConfig.WorkingDir → ProjectDir (json: project_dir)
- UnmarshalJSON fallback reads legacy working_dir from DB records
- New executions with project_dir clone into a temp sandbox via git clone --local
- Non-git project_dirs get git init + initial commit before clone
- After success: verify clean working tree, merge --ff-only back to project_dir, remove sandbox
- On failure/BLOCKED: sandbox preserved, path included in error message
- Resume executions run directly in project_dir (no re-clone)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'internal/task')
| -rw-r--r-- | internal/task/task.go | 26 | ||||
| -rw-r--r-- | internal/task/validator_test.go | 2 |
2 files changed, 25 insertions, 3 deletions
diff --git a/internal/task/task.go b/internal/task/task.go index f6635cc..498c364 100644 --- a/internal/task/task.go +++ b/internal/task/task.go @@ -1,6 +1,9 @@ package task -import "time" +import ( + "encoding/json" + "time" +) type State string @@ -29,7 +32,7 @@ type ClaudeConfig struct { Model string `yaml:"model" json:"model"` ContextFiles []string `yaml:"context_files" json:"context_files"` Instructions string `yaml:"instructions" json:"instructions"` - WorkingDir string `yaml:"working_dir" json:"working_dir"` + ProjectDir string `yaml:"project_dir" json:"project_dir"` MaxBudgetUSD float64 `yaml:"max_budget_usd" json:"max_budget_usd"` PermissionMode string `yaml:"permission_mode" json:"permission_mode"` AllowedTools []string `yaml:"allowed_tools" json:"allowed_tools"` @@ -39,6 +42,25 @@ type ClaudeConfig struct { SkipPlanning bool `yaml:"skip_planning" json:"skip_planning"` } +// UnmarshalJSON reads project_dir with fallback to legacy working_dir. +func (c *ClaudeConfig) UnmarshalJSON(data []byte) error { + type Alias ClaudeConfig + aux := &struct { + ProjectDir string `json:"project_dir"` + WorkingDir string `json:"working_dir"` // legacy + *Alias + }{Alias: (*Alias)(c)} + if err := json.Unmarshal(data, aux); err != nil { + return err + } + if aux.ProjectDir != "" { + c.ProjectDir = aux.ProjectDir + } else { + c.ProjectDir = aux.WorkingDir + } + return nil +} + type RetryConfig struct { MaxAttempts int `yaml:"max_attempts" json:"max_attempts"` Backoff string `yaml:"backoff" json:"backoff"` // "linear", "exponential" diff --git a/internal/task/validator_test.go b/internal/task/validator_test.go index 967eed3..02bde45 100644 --- a/internal/task/validator_test.go +++ b/internal/task/validator_test.go @@ -11,7 +11,7 @@ func validTask() *Task { Name: "Valid Task", Claude: ClaudeConfig{ Instructions: "do something", - WorkingDir: "/tmp", + ProjectDir: "/tmp", }, Priority: PriorityNormal, Retry: RetryConfig{MaxAttempts: 1, Backoff: "exponential"}, |
