feat(agentic): expose commit command

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-02 02:45:26 +00:00
parent bde7bb068d
commit 2e9529c018
5 changed files with 165 additions and 0 deletions

View file

@ -72,6 +72,7 @@ func (s *PrepSubsystem) registerCommands(ctx context.Context) {
c.Command("agentic:prompt/version", core.Command{Description: "Read the current prompt snapshot for a workspace", Action: s.cmdPromptVersion})
c.Command("extract", core.Command{Description: "Extract a workspace template to a directory", Action: s.cmdExtract})
s.registerPlanCommands()
s.registerCommitCommands()
s.registerSessionCommands()
s.registerTaskCommands()
s.registerStateCommands()

View file

@ -0,0 +1,48 @@
// SPDX-License-Identifier: EUPL-1.2
package agentic
import core "dappco.re/go/core"
func (s *PrepSubsystem) registerCommitCommands() {
c := s.Core()
c.Command("commit", core.Command{Description: "Write the final dispatch record to the workspace journal", Action: s.cmdCommit})
c.Command("agentic:commit", core.Command{Description: "Write the final dispatch record to the workspace journal", Action: s.cmdCommit})
}
// core-agent commit core/go-io/task-42
func (s *PrepSubsystem) cmdCommit(options core.Options) core.Result {
workspace := optionStringValue(options, "workspace", "_arg")
if workspace == "" {
core.Print(nil, "usage: core-agent commit <workspace>")
return core.Result{Value: core.E("agentic.cmdCommit", "workspace is required", nil), OK: false}
}
result := s.handleCommit(s.commandContext(), core.NewOptions(
core.Option{Key: "workspace", Value: workspace},
))
if !result.OK {
err := commandResultError("agentic.cmdCommit", result)
core.Print(nil, "error: %v", err)
return core.Result{Value: err, OK: false}
}
output, ok := result.Value.(CommitOutput)
if !ok {
err := core.E("agentic.cmdCommit", "invalid commit output", nil)
core.Print(nil, "error: %v", err)
return core.Result{Value: err, OK: false}
}
core.Print(nil, "workspace: %s", output.Workspace)
core.Print(nil, "journal: %s", output.JournalPath)
if output.MarkerPath != "" {
core.Print(nil, "marker: %s", output.MarkerPath)
}
if output.Skipped {
core.Print(nil, "skipped: true")
} else {
core.Print(nil, "committed: %s", output.CommittedAt)
}
return core.Result{Value: output, OK: true}
}

View file

@ -0,0 +1,112 @@
// 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 TestCommandsCommit_RegisterCommitCommands_Good(t *testing.T) {
c := core.New(core.WithOption("name", "test"))
s := &PrepSubsystem{ServiceRuntime: core.NewServiceRuntime(c, AgentOptions{})}
s.registerCommitCommands()
assert.Contains(t, c.Commands(), "commit")
assert.Contains(t, c.Commands(), "agentic:commit")
}
func TestCommandsCommit_CmdCommit_Good(t *testing.T) {
root := t.TempDir()
t.Setenv("CORE_WORKSPACE", root)
workspaceName := "core/go-io/task-42"
workspaceDir := core.JoinPath(WorkspaceRoot(), workspaceName)
require.True(t, fs.EnsureDir(workspaceDir).OK)
require.True(t, writeStatus(workspaceDir, &WorkspaceStatus{
Status: "completed",
Agent: "codex",
Repo: "go-io",
Org: "core",
Task: "Fix tests",
Branch: "agent/fix-tests",
Runs: 2,
}) == nil)
s := &PrepSubsystem{}
output := captureStdout(t, func() {
result := s.cmdCommit(core.NewOptions(core.Option{Key: "_arg", Value: workspaceName}))
require.True(t, result.OK)
commitOutput, ok := result.Value.(CommitOutput)
require.True(t, ok)
assert.Equal(t, workspaceName, commitOutput.Workspace)
assert.False(t, commitOutput.Skipped)
assert.NotEmpty(t, commitOutput.JournalPath)
assert.NotEmpty(t, commitOutput.MarkerPath)
assert.NotEmpty(t, commitOutput.CommittedAt)
})
assert.Contains(t, output, "workspace: core/go-io/task-42")
assert.Contains(t, output, "journal:")
assert.Contains(t, output, "committed:")
}
func TestCommandsCommit_CmdCommit_Bad_MissingWorkspace(t *testing.T) {
s := &PrepSubsystem{}
result := s.cmdCommit(core.NewOptions())
assert.False(t, result.OK)
require.Error(t, result.Value.(error))
assert.Contains(t, result.Value.(error).Error(), "workspace is required")
}
func TestCommandsCommit_CmdCommit_Ugly_MissingStatus(t *testing.T) {
root := t.TempDir()
t.Setenv("CORE_WORKSPACE", root)
workspaceName := "core/go-io/task-99"
workspaceDir := core.JoinPath(WorkspaceRoot(), workspaceName)
require.True(t, fs.EnsureDir(workspaceDir).OK)
s := &PrepSubsystem{}
result := s.cmdCommit(core.NewOptions(core.Option{Key: "_arg", Value: workspaceName}))
assert.False(t, result.OK)
require.Error(t, result.Value.(error))
assert.Contains(t, result.Value.(error).Error(), "status not found")
}
func TestCommandsCommit_CmdCommit_Ugly_Idempotent(t *testing.T) {
root := t.TempDir()
t.Setenv("CORE_WORKSPACE", root)
workspaceName := "core/go-io/task-100"
workspaceDir := core.JoinPath(WorkspaceRoot(), workspaceName)
require.True(t, fs.EnsureDir(workspaceDir).OK)
require.True(t, writeStatus(workspaceDir, &WorkspaceStatus{
Status: "merged",
Agent: "codex",
Repo: "go-io",
Org: "core",
Task: "Merge cleanly",
Branch: "agent/merge-cleanly",
Runs: 1,
}) == nil)
s := &PrepSubsystem{}
first := s.cmdCommit(core.NewOptions(core.Option{Key: "_arg", Value: workspaceName}))
require.True(t, first.OK)
second := s.cmdCommit(core.NewOptions(core.Option{Key: "_arg", Value: workspaceName}))
require.True(t, second.OK)
commitOutput, ok := second.Value.(CommitOutput)
require.True(t, ok)
assert.True(t, commitOutput.Skipped)
assert.NotEmpty(t, commitOutput.MarkerPath)
}

View file

@ -1499,6 +1499,8 @@ func TestCommands_RegisterCommands_Good_AllRegistered(t *testing.T) {
assert.Contains(t, cmds, "agentic:plan/delete")
assert.Contains(t, cmds, "plan/delete")
assert.Contains(t, cmds, "agentic:plan-cleanup")
assert.Contains(t, cmds, "commit")
assert.Contains(t, cmds, "agentic:commit")
assert.Contains(t, cmds, "session/start")
assert.Contains(t, cmds, "session/get")
assert.Contains(t, cmds, "agentic:session/get")

View file

@ -709,6 +709,8 @@ func TestPrep_OnStartup_Good_RegistersGenerateCommand(t *testing.T) {
assert.Contains(t, c.Commands(), "epic")
assert.Contains(t, c.Commands(), "agentic:epic")
assert.Contains(t, c.Commands(), "plan-cleanup")
assert.Contains(t, c.Commands(), "commit")
assert.Contains(t, c.Commands(), "agentic:commit")
assert.Contains(t, c.Commands(), "plan/from-issue")
assert.Contains(t, c.Commands(), "session/end")
assert.Contains(t, c.Commands(), "agentic:session/end")