feat(agentic): add resume command alias

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-01 20:59:52 +00:00
parent cf8af42027
commit 3a9834ec03
3 changed files with 109 additions and 0 deletions

View file

@ -28,6 +28,8 @@ func (s *PrepSubsystem) registerCommands(ctx context.Context) {
c.Command("prep", core.Command{Description: "Prepare a workspace: clone repo, build prompt", Action: s.cmdPrep})
c.Command("prep-workspace", core.Command{Description: "Prepare a workspace: clone repo, build prompt", Action: s.cmdPrep})
c.Command("agentic:prep-workspace", core.Command{Description: "Prepare a workspace: clone repo, build prompt", Action: s.cmdPrep})
c.Command("resume", core.Command{Description: "Resume a blocked or completed workspace", Action: s.cmdResume})
c.Command("agentic:resume", core.Command{Description: "Resume a blocked or completed workspace", Action: s.cmdResume})
c.Command("generate", core.Command{Description: "Generate content from a prompt using the platform content pipeline", Action: s.cmdGenerate})
c.Command("agentic:generate", core.Command{Description: "Generate content from a prompt using the platform content pipeline", Action: s.cmdGenerate})
c.Command("complete", core.Command{Description: "Run the completion pipeline (QA → PR → Verify → Ingest → Poke)", Action: s.cmdComplete})
@ -243,6 +245,40 @@ func (s *PrepSubsystem) cmdPrep(options core.Options) core.Result {
return core.Result{OK: true}
}
func (s *PrepSubsystem) cmdResume(options core.Options) core.Result {
workspace := optionStringValue(options, "workspace", "_arg")
if workspace == "" {
core.Print(nil, "usage: core-agent resume <workspace> [--answer=\"...\"] [--agent=codex] [--dry-run]")
return core.Result{Value: core.E("agentic.cmdResume", "workspace is required", nil), OK: false}
}
_, output, err := s.resume(s.commandContext(), nil, ResumeInput{
Workspace: workspace,
Answer: optionStringValue(options, "answer"),
Agent: optionStringValue(options, "agent"),
DryRun: optionBoolValue(options, "dry_run", "dry-run"),
})
if err != nil {
core.Print(nil, "error: %v", err)
return core.Result{Value: err, OK: false}
}
core.Print(nil, "workspace: %s", output.Workspace)
core.Print(nil, "agent: %s", output.Agent)
if output.PID > 0 {
core.Print(nil, "pid: %d", output.PID)
}
if output.OutputFile != "" {
core.Print(nil, "output: %s", output.OutputFile)
}
if output.Prompt != "" {
core.Print(nil, "")
core.Print(nil, "--- prompt (%d chars) ---", len(output.Prompt))
core.Print(nil, "%s", output.Prompt)
}
return core.Result{Value: output, OK: true}
}
func (s *PrepSubsystem) cmdGenerate(options core.Options) core.Result {
prompt := optionStringValue(options, "prompt", "_arg")
briefID := optionStringValue(options, "brief_id", "brief-id")

View file

@ -0,0 +1,71 @@
// SPDX-License-Identifier: EUPL-1.2
package agentic
import (
"testing"
core "dappco.re/go/core"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestCommandsResume_CmdResume_Good_DryRun(t *testing.T) {
s, _ := testPrepWithCore(t, nil)
workspaceDir := core.JoinPath(WorkspaceRoot(), "core", "go-io", "task-42")
require.True(t, fs.EnsureDir(core.JoinPath(workspaceDir, "repo", ".git")).OK)
require.True(t, fs.Write(core.JoinPath(workspaceDir, "status.json"), core.JSONMarshalString(WorkspaceStatus{
Status: "blocked",
Agent: "codex",
Repo: "go-io",
Task: "Fix the failing tests",
})).OK)
result := s.cmdResume(core.NewOptions(
core.Option{Key: "workspace", Value: "core/go-io/task-42"},
core.Option{Key: "answer", Value: "Use the new Core API"},
core.Option{Key: "dry_run", Value: true},
))
require.True(t, result.OK)
output, ok := result.Value.(ResumeOutput)
require.True(t, ok)
assert.Equal(t, "core/go-io/task-42", output.Workspace)
assert.Equal(t, "codex", output.Agent)
assert.Contains(t, output.Prompt, "Fix the failing tests")
assert.Contains(t, output.Prompt, "Use the new Core API")
}
func TestCommandsResume_CmdResume_Bad_MissingWorkspace(t *testing.T) {
s, _ := testPrepWithCore(t, nil)
result := s.cmdResume(core.NewOptions())
assert.False(t, result.OK)
require.Error(t, result.Value.(error))
assert.Contains(t, result.Value.(error).Error(), "workspace is required")
}
func TestCommandsResume_CmdResume_Ugly_CorruptStatus(t *testing.T) {
s, _ := testPrepWithCore(t, nil)
workspaceDir := core.JoinPath(WorkspaceRoot(), "core", "go-io", "task-42")
require.True(t, fs.EnsureDir(core.JoinPath(workspaceDir, "repo", ".git")).OK)
require.True(t, fs.Write(core.JoinPath(workspaceDir, "status.json"), "{broken json").OK)
result := s.cmdResume(core.NewOptions(core.Option{Key: "_arg", Value: "core/go-io/task-42"}))
assert.False(t, result.OK)
require.Error(t, result.Value.(error))
assert.Contains(t, result.Value.(error).Error(), "no status.json in workspace")
}
func TestCommandsResume_RegisterCommands_Good(t *testing.T) {
s, c := testPrepWithCore(t, nil)
s.registerCommands(c.Context())
assert.Contains(t, c.Commands(), "resume")
assert.Contains(t, c.Commands(), "agentic:resume")
}

View file

@ -1282,6 +1282,8 @@ func TestCommands_RegisterCommands_Good_AllRegistered(t *testing.T) {
assert.Contains(t, cmds, "dispatch/shutdown-now")
assert.Contains(t, cmds, "prep")
assert.Contains(t, cmds, "agentic:prep-workspace")
assert.Contains(t, cmds, "resume")
assert.Contains(t, cmds, "agentic:resume")
assert.Contains(t, cmds, "complete")
assert.Contains(t, cmds, "scan")
assert.Contains(t, cmds, "agentic:scan")