summaryrefslogtreecommitdiff
path: root/internal/api
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-03-08 20:16:00 +0000
committerPeter Stone <thepeterstone@gmail.com>2026-03-08 20:16:00 +0000
commit1f36e2312d316969db65a601ac7d9793fbc3bc4c (patch)
tree1d91358beaf910df23a5bd18b9dabbc3f59d448a /internal/api
parent9955a2f10c034dac60bc17cde6b80b432e21d9d3 (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/api')
-rw-r--r--internal/api/elaborate.go12
-rw-r--r--internal/api/elaborate_test.go2
-rw-r--r--internal/api/validate.go6
3 files changed, 10 insertions, 10 deletions
diff --git a/internal/api/elaborate.go b/internal/api/elaborate.go
index 00f3297..e480e00 100644
--- a/internal/api/elaborate.go
+++ b/internal/api/elaborate.go
@@ -14,9 +14,9 @@ import (
const elaborateTimeout = 30 * time.Second
func buildElaboratePrompt(workDir string) string {
- workDirLine := ` "working_dir": string — leave empty unless you have a specific reason to set it,`
+ workDirLine := ` "project_dir": string — leave empty unless you have a specific reason to set it,`
if workDir != "" {
- workDirLine = fmt.Sprintf(` "working_dir": string — use %q for tasks that operate on this codebase, empty string otherwise,`, workDir)
+ workDirLine = fmt.Sprintf(` "project_dir": string — use %q for tasks that operate on this codebase, empty string otherwise,`, workDir)
}
return `You are a task configuration assistant for Claudomator, an AI task runner that executes tasks by running Claude as a subprocess.
@@ -53,7 +53,7 @@ type elaboratedTask struct {
type elaboratedClaude struct {
Model string `json:"model"`
Instructions string `json:"instructions"`
- WorkingDir string `json:"working_dir"`
+ ProjectDir string `json:"project_dir"`
MaxBudgetUSD float64 `json:"max_budget_usd"`
AllowedTools []string `json:"allowed_tools"`
}
@@ -87,7 +87,7 @@ func (s *Server) claudeBinaryPath() string {
func (s *Server) handleElaborateTask(w http.ResponseWriter, r *http.Request) {
var input struct {
Prompt string `json:"prompt"`
- WorkingDir string `json:"working_dir"`
+ ProjectDir string `json:"project_dir"`
}
if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
writeJSON(w, http.StatusBadRequest, map[string]string{"error": "invalid JSON: " + err.Error()})
@@ -99,8 +99,8 @@ func (s *Server) handleElaborateTask(w http.ResponseWriter, r *http.Request) {
}
workDir := s.workDir
- if input.WorkingDir != "" {
- workDir = input.WorkingDir
+ if input.ProjectDir != "" {
+ workDir = input.ProjectDir
}
ctx, cancel := context.WithTimeout(r.Context(), elaborateTimeout)
diff --git a/internal/api/elaborate_test.go b/internal/api/elaborate_test.go
index 52f7fdf..09f7fbe 100644
--- a/internal/api/elaborate_test.go
+++ b/internal/api/elaborate_test.go
@@ -56,7 +56,7 @@ func TestElaborateTask_Success(t *testing.T) {
Claude: elaboratedClaude{
Model: "sonnet",
Instructions: "Run go test -race ./... and report results.",
- WorkingDir: "",
+ ProjectDir: "",
MaxBudgetUSD: 0.5,
AllowedTools: []string{"Bash"},
},
diff --git a/internal/api/validate.go b/internal/api/validate.go
index d8ebde9..4b691a9 100644
--- a/internal/api/validate.go
+++ b/internal/api/validate.go
@@ -56,7 +56,7 @@ func (s *Server) handleValidateTask(w http.ResponseWriter, r *http.Request) {
Name string `json:"name"`
Claude struct {
Instructions string `json:"instructions"`
- WorkingDir string `json:"working_dir"`
+ ProjectDir string `json:"project_dir"`
AllowedTools []string `json:"allowed_tools"`
} `json:"claude"`
}
@@ -74,8 +74,8 @@ func (s *Server) handleValidateTask(w http.ResponseWriter, r *http.Request) {
}
userMsg := fmt.Sprintf("Task name: %s\n\nInstructions:\n%s", input.Name, input.Claude.Instructions)
- if input.Claude.WorkingDir != "" {
- userMsg += fmt.Sprintf("\n\nWorking directory: %s", input.Claude.WorkingDir)
+ if input.Claude.ProjectDir != "" {
+ userMsg += fmt.Sprintf("\n\nWorking directory: %s", input.Claude.ProjectDir)
}
if len(input.Claude.AllowedTools) > 0 {
userMsg += fmt.Sprintf("\n\nAllowed tools: %v", input.Claude.AllowedTools)