feat(v0.6): AgentSpec field on TaskMeta with backward-compat unmarshal

Replace TaskMeta.Agent (string) with TaskMeta.Agent (AgentSpec) carrying
type/command/args/env. Custom UnmarshalYAML preserves the legacy scalar
form: a built-in name (claude, opencode) maps to that type; any other
scalar maps to type=custom with the scalar as command. A missing agent
field leaves Type empty so the resolver fills in default_agent at launch.

ValidateAgentSpec enforces: known type (claude|opencode|custom),
type=custom requires command, command must be an executable name or
path with no whitespace or shell metacharacters.

Launch-path wiring (Task 3) and the --agent flag rework (Task 4) are
intentionally not part of this commit; cmd/* call sites are patched to
the minimum needed for the build to compile.
This commit is contained in:
2026-05-15 10:58:06 -04:00
parent 6c4c3e8df2
commit 8120c399df
31 changed files with 427 additions and 189 deletions
+10 -10
View File
@@ -22,16 +22,16 @@ func makeArchiveWs(t *testing.T, root, category, dirName string) string {
now := time.Now().UTC().Truncate(time.Second)
slug := dirName[11:]
meta := &workspace.TaskMeta{
ID: "test",
Slug: slug,
Title: slug,
CreatedAt: now,
UpdatedAt: now,
Status: "active",
Category: category,
Type: "task",
Mode: "local",
Agent: "claude",
ID: "test",
Slug: slug,
Title: slug,
CreatedAt: now,
UpdatedAt: now,
Status: "active",
Category: category,
Type: "task",
Mode: "local",
Agent: workspace.AgentSpec{Type: "claude"},
}
workspace.WriteMeta(filepath.Join(dir, "task.yaml"), meta)
return dir