Codex 5.5 batch lane processed 26 open Mantis tickets. 13 stale-fixed, 4 implemented, 9 deferred. Tickets implemented: - #142 — agentic_sprint_start + agentic_sprint_complete MCP tools wired to /v1/sprints/{id}/{start,complete} platform endpoints with tests - #225 — cmd/core-agent/commands.go: removed raw flag parsing; startupArgs() uses Core arg filtering + local log-level strip - #226 — cmd/core-agent/main.go: syscall.Exit(1) → core.Exit(1) - #227 — pkg/agentic/dispatch.go: runtime.GOOS → Core environment-backed OS detection Tickets stale-fixed: #161, #162, #163, #166, #167, #168, #171, #172, #223, #224, #230, #231, #232, #233 Tickets deferred: #160, #164, #165, #173, #222, #228, #229, #234 Co-authored-by: Codex <noreply@openai.com> Closes tasks.lthn.sh/view.php?id=142 Closes tasks.lthn.sh/view.php?id=225 Closes tasks.lthn.sh/view.php?id=226 Closes tasks.lthn.sh/view.php?id=227
This commit is contained in:
parent
56a97e9178
commit
bf10d16f49
6 changed files with 80 additions and 33 deletions
|
|
@ -3,7 +3,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"os"
|
||||
|
||||
"dappco.re/go/agent/pkg/agentic"
|
||||
"dappco.re/go/core"
|
||||
|
|
@ -16,33 +16,7 @@ type applicationCommandSet struct {
|
|||
// args := startupArgs()
|
||||
// _ = c.Cli().Run("version")
|
||||
func startupArgs() []string {
|
||||
previous := flag.CommandLine
|
||||
commandLine := flag.NewFlagSet("core-agent", flag.ContinueOnError)
|
||||
commandLine.SetOutput(core.NewBuffer())
|
||||
commandLine.BoolFunc("quiet", "", func(string) error {
|
||||
core.SetLevel(core.LevelError)
|
||||
return nil
|
||||
})
|
||||
commandLine.BoolFunc("q", "", func(string) error {
|
||||
core.SetLevel(core.LevelError)
|
||||
return nil
|
||||
})
|
||||
commandLine.BoolFunc("debug", "", func(string) error {
|
||||
core.SetLevel(core.LevelDebug)
|
||||
return nil
|
||||
})
|
||||
commandLine.BoolFunc("d", "", func(string) error {
|
||||
core.SetLevel(core.LevelDebug)
|
||||
return nil
|
||||
})
|
||||
|
||||
flag.CommandLine = commandLine
|
||||
defer func() {
|
||||
flag.CommandLine = previous
|
||||
}()
|
||||
|
||||
flag.Parse()
|
||||
return applyLogLevel(commandLine.Args())
|
||||
return applyLogLevel(core.FilterArgs(os.Args[1:]))
|
||||
}
|
||||
|
||||
// args := applyLogLevel([]string{"version", "-q"})
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ package main
|
|||
|
||||
import (
|
||||
"context"
|
||||
"syscall"
|
||||
|
||||
agentpkg "dappco.re/go/agent"
|
||||
"dappco.re/go/core"
|
||||
|
|
@ -20,7 +19,7 @@ import (
|
|||
func main() {
|
||||
if err := runCoreAgent(); err != nil {
|
||||
core.Error("core-agent failed", "err", err)
|
||||
syscall.Exit(1)
|
||||
core.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,13 +4,12 @@ package agentic
|
|||
|
||||
import (
|
||||
"context"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"dappco.re/go/agent/pkg/messages"
|
||||
core "dappco.re/go/core"
|
||||
"dappco.re/go/process"
|
||||
coremcp "dappco.re/go/mcp/pkg/mcp"
|
||||
"dappco.re/go/process"
|
||||
"github.com/modelcontextprotocol/go-sdk/mcp"
|
||||
)
|
||||
|
||||
|
|
@ -235,7 +234,7 @@ func containerRuntimeBinary(runtime string) string {
|
|||
// goosIsDarwin reports whether the running process is on macOS. Captured at
|
||||
// package init so tests can compare against a fixed value without taking a
|
||||
// dependency on the `runtime` package themselves.
|
||||
var goosIsDarwin = runtime.GOOS == "darwin"
|
||||
var goosIsDarwin = core.Lower(core.Trim(envOr("GOOS", core.Env("OS")))) == "darwin"
|
||||
|
||||
// runtimeAvailable reports whether the runtime's binary is available on PATH
|
||||
// or via known absolute paths. Apple Container additionally requires macOS as
|
||||
|
|
|
|||
|
|
@ -732,6 +732,8 @@ func TestPrep_RegisterTools_Good_RegistersCompletionTool(t *testing.T) {
|
|||
assert.Contains(t, toolNames, "agentic_task_create")
|
||||
assert.Contains(t, toolNames, "agentic_state_set")
|
||||
assert.Contains(t, toolNames, "agentic_sprint_create")
|
||||
assert.Contains(t, toolNames, "agentic_sprint_start")
|
||||
assert.Contains(t, toolNames, "agentic_sprint_complete")
|
||||
assert.Contains(t, toolNames, "session_complete")
|
||||
assert.Contains(t, toolNames, "agentic_message_send")
|
||||
assert.Contains(t, toolNames, "agent_send")
|
||||
|
|
|
|||
|
|
@ -65,6 +65,12 @@ type SprintArchiveInput struct {
|
|||
Slug string `json:"slug,omitempty"`
|
||||
}
|
||||
|
||||
// input := agentic.SprintTransitionInput{Slug: "ax-follow-up"}
|
||||
type SprintTransitionInput struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Slug string `json:"slug,omitempty"`
|
||||
}
|
||||
|
||||
// out := agentic.SprintOutput{Success: true, Sprint: agentic.Sprint{Slug: "ax-follow-up"}}
|
||||
type SprintOutput struct {
|
||||
Success bool `json:"success"`
|
||||
|
|
@ -191,6 +197,16 @@ func (s *PrepSubsystem) registerSprintTools(svc *coremcp.Service) {
|
|||
Description: "Update fields on a tracked platform sprint by slug.",
|
||||
}, s.sprintUpdate)
|
||||
|
||||
coremcp.AddToolRecorded(svc, svc.Server(), "agentic", &mcp.Tool{
|
||||
Name: "agentic_sprint_start",
|
||||
Description: "Start a tracked platform sprint by slug or ID.",
|
||||
}, s.sprintStart)
|
||||
|
||||
coremcp.AddToolRecorded(svc, svc.Server(), "agentic", &mcp.Tool{
|
||||
Name: "agentic_sprint_complete",
|
||||
Description: "Complete a tracked platform sprint by slug or ID.",
|
||||
}, s.sprintComplete)
|
||||
|
||||
coremcp.AddToolRecorded(svc, svc.Server(), "agentic", &mcp.Tool{
|
||||
Name: "sprint_archive",
|
||||
Description: "Archive a tracked platform sprint by slug.",
|
||||
|
|
@ -308,6 +324,14 @@ func (s *PrepSubsystem) sprintUpdate(ctx context.Context, _ *mcp.CallToolRequest
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (s *PrepSubsystem) sprintStart(ctx context.Context, _ *mcp.CallToolRequest, input SprintTransitionInput) (*mcp.CallToolResult, SprintOutput, error) {
|
||||
return s.sprintTransition(ctx, "sprint.start", "start", input)
|
||||
}
|
||||
|
||||
func (s *PrepSubsystem) sprintComplete(ctx context.Context, _ *mcp.CallToolRequest, input SprintTransitionInput) (*mcp.CallToolResult, SprintOutput, error) {
|
||||
return s.sprintTransition(ctx, "sprint.complete", "complete", input)
|
||||
}
|
||||
|
||||
func (s *PrepSubsystem) sprintArchive(ctx context.Context, _ *mcp.CallToolRequest, input SprintArchiveInput) (*mcp.CallToolResult, SprintArchiveOutput, error) {
|
||||
identifier := sprintIdentifier(input.Slug, input.ID)
|
||||
if identifier == "" {
|
||||
|
|
@ -334,6 +358,23 @@ func (s *PrepSubsystem) sprintArchive(ctx context.Context, _ *mcp.CallToolReques
|
|||
return nil, output, nil
|
||||
}
|
||||
|
||||
func (s *PrepSubsystem) sprintTransition(ctx context.Context, action, transition string, input SprintTransitionInput) (*mcp.CallToolResult, SprintOutput, error) {
|
||||
identifier := sprintIdentifier(input.Slug, input.ID)
|
||||
if identifier == "" {
|
||||
return nil, SprintOutput{}, core.E("sprintTransition", "id or slug is required", nil)
|
||||
}
|
||||
|
||||
result := s.platformPayload(ctx, action, "POST", core.Concat("/v1/sprints/", identifier, "/", transition), nil)
|
||||
if !result.OK {
|
||||
return nil, SprintOutput{}, resultErrorValue(action, result)
|
||||
}
|
||||
|
||||
return nil, SprintOutput{
|
||||
Success: true,
|
||||
Sprint: parseSprint(payloadResourceMap(result.Value.(map[string]any), "sprint")),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func sprintIdentifier(values ...string) string {
|
||||
for _, value := range values {
|
||||
if trimmed := core.Trim(value); trimmed != "" {
|
||||
|
|
|
|||
|
|
@ -93,3 +93,35 @@ func TestSprint_HandleSprintList_Ugly_NestedEnvelope(t *testing.T) {
|
|||
assert.Equal(t, 2, output.Sprints[0].WorkspaceID)
|
||||
assert.Equal(t, "Finish RFC parity", output.Sprints[0].Goal)
|
||||
}
|
||||
|
||||
func TestSprint_SprintStart_Good(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
require.Equal(t, "/v1/sprints/ax-follow-up/start", r.URL.Path)
|
||||
require.Equal(t, http.MethodPost, r.Method)
|
||||
_, _ = w.Write([]byte(`{"data":{"sprint":{"slug":"ax-follow-up","title":"AX Follow-up","status":"active"}}}`))
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
subsystem := testPrepWithPlatformServer(t, server, "secret-token")
|
||||
_, output, err := subsystem.sprintStart(context.Background(), nil, SprintTransitionInput{Slug: "ax-follow-up"})
|
||||
require.NoError(t, err)
|
||||
assert.True(t, output.Success)
|
||||
assert.Equal(t, "ax-follow-up", output.Sprint.Slug)
|
||||
assert.Equal(t, "active", output.Sprint.Status)
|
||||
}
|
||||
|
||||
func TestSprint_SprintComplete_Good(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
require.Equal(t, "/v1/sprints/7/complete", r.URL.Path)
|
||||
require.Equal(t, http.MethodPost, r.Method)
|
||||
_, _ = w.Write([]byte(`{"data":{"sprint":{"id":7,"slug":"ax-follow-up","title":"AX Follow-up","status":"completed"}}}`))
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
subsystem := testPrepWithPlatformServer(t, server, "secret-token")
|
||||
_, output, err := subsystem.sprintComplete(context.Background(), nil, SprintTransitionInput{ID: "7"})
|
||||
require.NoError(t, err)
|
||||
assert.True(t, output.Success)
|
||||
assert.Equal(t, 7, output.Sprint.ID)
|
||||
assert.Equal(t, "completed", output.Sprint.Status)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue