diff --git a/internal/common/task_utils.go b/internal/common/task_utils.go index b89a8d5..1542912 100644 --- a/internal/common/task_utils.go +++ b/internal/common/task_utils.go @@ -58,6 +58,13 @@ func AugmentArgsForTask(task *types.Task, args []string, opts TaskAugmentOptions args = append(args, "--no-computer-use") } } + + // Pass harness setting if explicitly configured. + if task.AgentConfigSnapshot.Harness != nil && task.AgentConfigSnapshot.Harness.Type != nil { + if harness := strings.TrimSpace(*task.AgentConfigSnapshot.Harness.Type); harness != "" { + args = append(args, "--harness", harness) + } + } } if task.AgentConfigSnapshot != nil && task.AgentConfigSnapshot.EnvironmentID != nil { diff --git a/internal/common/task_utils_test.go b/internal/common/task_utils_test.go index 3348a66..1e47bef 100644 --- a/internal/common/task_utils_test.go +++ b/internal/common/task_utils_test.go @@ -55,6 +55,26 @@ func TestAugmentArgsForTask_IdleOnCompletePrecedence(t *testing.T) { opts: TaskAugmentOptions{IdleOnComplete: "20m"}, expected: []string{"agent", "run", "--idle-on-complete", "20m"}, }, + { + name: "adds --harness when harness type is set", + task: &types.Task{ + AgentConfigSnapshot: &types.AmbientAgentConfig{ + Harness: &types.Harness{Type: strPtr("claude")}, + }, + }, + opts: TaskAugmentOptions{}, + expected: []string{"agent", "run", "--harness", "claude", "--idle-on-complete"}, + }, + { + name: "skips --harness when harness type is nil", + task: &types.Task{ + AgentConfigSnapshot: &types.AmbientAgentConfig{ + Harness: &types.Harness{}, + }, + }, + opts: TaskAugmentOptions{}, + expected: []string{"agent", "run", "--idle-on-complete"}, + }, { name: "still appends other config-derived args before idle timeout", task: &types.Task{ diff --git a/internal/types/messages.go b/internal/types/messages.go index e11aa9d..3763e05 100644 --- a/internal/types/messages.go +++ b/internal/types/messages.go @@ -65,7 +65,20 @@ type TaskDefinition struct { Prompt string `json:"prompt"` } -// AmbientAgentConfig represents the agent configuration +// Harness defines a third-party harness to run a cloud agent with. +type Harness struct { + // Type is the name of the harness, e.g. "claude". + Type *string `json:"type,omitempty"` +} + +// HarnessAuthSecrets holds authentication secrets for third-party harnesses. +// Only the secret for the harness specified gets injected into the environment. +type HarnessAuthSecrets struct { + // ClaudeAuthSecretName is the name of a managed secret for Claude Code harness authentication. + ClaudeAuthSecretName *string `json:"claude_auth_secret_name,omitempty"` +} + +// AmbientAgentConfig represents the agent configuration. type AmbientAgentConfig struct { EnvironmentID *string `json:"environment_id,omitempty"` BasePrompt *string `json:"base_prompt,omitempty"` @@ -75,6 +88,8 @@ type AmbientAgentConfig struct { MCPServers map[string]json.RawMessage `json:"mcp_servers,omitempty"` ComputerUseEnabled *bool `json:"computer_use_enabled,omitempty"` IdleTimeoutMinutes *int `json:"idle_timeout_minutes,omitempty"` + Harness *Harness `json:"harness,omitempty"` + HarnessAuthSecrets *HarnessAuthSecrets `json:"harness_auth_secrets,omitempty"` } // Task represents an ambient agent job.