From 2568226dfcfe101d03c59392e54559080597c20d Mon Sep 17 00:00:00 2001 From: Peter Stone Date: Sat, 7 Mar 2026 07:12:04 +0000 Subject: feat: add create CLI command with --parent-id; deploy to /usr/local/bin claudomator create -i [flags] --parent-id attach as subtask of given task ID --working-dir working directory --model claude model --budget max USD --timeout task timeout --priority high/normal/low --start queue immediately after creating deploy script now also copies binary to /usr/local/bin/claudomator. Co-Authored-By: Claude Sonnet 4.6 --- internal/cli/create.go | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++ internal/cli/root.go | 1 + 2 files changed, 86 insertions(+) create mode 100644 internal/cli/create.go (limited to 'internal/cli') diff --git a/internal/cli/create.go b/internal/cli/create.go new file mode 100644 index 0000000..fdad932 --- /dev/null +++ b/internal/cli/create.go @@ -0,0 +1,85 @@ +package cli + +import ( + "bytes" + "encoding/json" + "fmt" + "net/http" + + "github.com/spf13/cobra" +) + +func newCreateCmd() *cobra.Command { + var ( + serverURL string + instructions string + workingDir string + model string + parentID string + budget float64 + timeout string + priority string + autoStart bool + ) + + cmd := &cobra.Command{ + Use: "create ", + Short: "Create a task via the running server", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + return createTask(serverURL, args[0], instructions, workingDir, model, parentID, budget, timeout, priority, autoStart) + }, + } + + cmd.Flags().StringVar(&serverURL, "server", "http://localhost:8484", "claudomator server URL") + cmd.Flags().StringVarP(&instructions, "instructions", "i", "", "task instructions (required)") + cmd.Flags().StringVarP(&workingDir, "working-dir", "d", "", "working directory for the task") + cmd.Flags().StringVarP(&model, "model", "m", "", "claude model to use") + cmd.Flags().StringVar(&parentID, "parent-id", "", "parent task ID (makes this a subtask)") + cmd.Flags().Float64Var(&budget, "budget", 1.0, "max budget in USD") + cmd.Flags().StringVar(&timeout, "timeout", "15m", "task timeout") + cmd.Flags().StringVar(&priority, "priority", "normal", "priority: high, normal, low") + cmd.Flags().BoolVar(&autoStart, "start", false, "queue for execution immediately after creating") + _ = cmd.MarkFlagRequired("instructions") + + return cmd +} + +func createTask(serverURL, name, instructions, workingDir, model, parentID string, budget float64, timeout, priority string, autoStart bool) error { + body := map[string]interface{}{ + "name": name, + "timeout": timeout, + "priority": priority, + "claude": map[string]interface{}{ + "instructions": instructions, + "working_dir": workingDir, + "model": model, + "max_budget_usd": budget, + }, + } + if parentID != "" { + body["parent_task_id"] = parentID + } + + data, _ := json.Marshal(body) + resp, err := http.Post(serverURL+"/api/tasks", "application/json", bytes.NewReader(data)) //nolint:noctx + if err != nil { + return fmt.Errorf("POST /api/tasks: %w", err) + } + defer resp.Body.Close() + + var result map[string]interface{} + _ = json.NewDecoder(resp.Body).Decode(&result) + + if resp.StatusCode >= 300 { + return fmt.Errorf("server returned %d: %v", resp.StatusCode, result["error"]) + } + + id, _ := result["id"].(string) + fmt.Printf("Created task %s\n", id) + + if autoStart { + return startTask(serverURL, id) + } + return nil +} diff --git a/internal/cli/root.go b/internal/cli/root.go index 75ec393..1a528fb 100644 --- a/internal/cli/root.go +++ b/internal/cli/root.go @@ -42,6 +42,7 @@ func NewRootCmd() *cobra.Command { newInitCmd(), newLogsCmd(), newStartCmd(), + newCreateCmd(), ) return cmd -- cgit v1.2.3