feat(agentic): expose session get/list commands

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-02 00:15:22 +00:00
parent 8828e89e62
commit 5ba7886deb
3 changed files with 151 additions and 0 deletions

View file

@ -8,6 +8,10 @@ import (
func (s *PrepSubsystem) registerSessionCommands() {
c := s.Core()
c.Command("session/get", core.Command{Description: "Read a stored session by session ID", Action: s.cmdSessionGet})
c.Command("agentic:session/get", core.Command{Description: "Read a stored session by session ID", Action: s.cmdSessionGet})
c.Command("session/list", core.Command{Description: "List stored sessions with optional filters", Action: s.cmdSessionList})
c.Command("agentic:session/list", core.Command{Description: "List stored sessions with optional filters", Action: s.cmdSessionList})
c.Command("session/start", core.Command{Description: "Start a stored session for a plan", Action: s.cmdSessionStart})
c.Command("agentic:session/start", core.Command{Description: "Start a stored session for a plan", Action: s.cmdSessionStart})
c.Command("session/continue", core.Command{Description: "Continue a stored session from saved context", Action: s.cmdSessionContinue})
@ -28,6 +32,97 @@ func (s *PrepSubsystem) registerSessionCommands() {
c.Command("agentic:session/replay", core.Command{Description: "Build replay context for a stored session", Action: s.cmdSessionReplay})
}
// core-agent session get ses-abc123
func (s *PrepSubsystem) cmdSessionGet(options core.Options) core.Result {
sessionID := optionStringValue(options, "session_id", "session-id", "id", "_arg")
if sessionID == "" {
core.Print(nil, "usage: core-agent session get <session-id>")
return core.Result{Value: core.E("agentic.cmdSessionGet", "session_id is required", nil), OK: false}
}
result := s.handleSessionGet(s.commandContext(), core.NewOptions(
core.Option{Key: "session_id", Value: sessionID},
))
if !result.OK {
err := commandResultError("agentic.cmdSessionGet", result)
core.Print(nil, "error: %v", err)
return core.Result{Value: err, OK: false}
}
output, ok := result.Value.(SessionOutput)
if !ok {
err := core.E("agentic.cmdSessionGet", "invalid session get output", nil)
core.Print(nil, "error: %v", err)
return core.Result{Value: err, OK: false}
}
core.Print(nil, "session: %s", output.Session.SessionID)
core.Print(nil, "status: %s", output.Session.Status)
core.Print(nil, "agent: %s", output.Session.AgentType)
if output.Session.PlanSlug != "" {
core.Print(nil, "plan: %s", output.Session.PlanSlug)
}
if output.Session.Summary != "" {
core.Print(nil, "summary: %s", output.Session.Summary)
}
if output.Session.CreatedAt != "" {
core.Print(nil, "started: %s", output.Session.CreatedAt)
}
if output.Session.UpdatedAt != "" {
core.Print(nil, "updated: %s", output.Session.UpdatedAt)
}
if output.Session.EndedAt != "" {
core.Print(nil, "ended: %s", output.Session.EndedAt)
}
if len(output.Session.ContextSummary) > 0 {
core.Print(nil, "context: %d item(s)", len(output.Session.ContextSummary))
}
if len(output.Session.WorkLog) > 0 {
core.Print(nil, "work log: %d item(s)", len(output.Session.WorkLog))
}
if len(output.Session.Artifacts) > 0 {
core.Print(nil, "artifacts: %d item(s)", len(output.Session.Artifacts))
}
if len(output.Session.Handoff) > 0 {
core.Print(nil, "handoff: %d item(s)", len(output.Session.Handoff))
}
return core.Result{Value: output, OK: true}
}
// core-agent session list --status=active --plan=ax-follow-up
func (s *PrepSubsystem) cmdSessionList(options core.Options) core.Result {
result := s.handleSessionList(s.commandContext(), core.NewOptions(
core.Option{Key: "plan_slug", Value: optionStringValue(options, "plan_slug", "plan")},
core.Option{Key: "agent_type", Value: optionStringValue(options, "agent_type", "agent")},
core.Option{Key: "status", Value: optionStringValue(options, "status")},
core.Option{Key: "limit", Value: optionIntValue(options, "limit")},
))
if !result.OK {
err := commandResultError("agentic.cmdSessionList", result)
core.Print(nil, "error: %v", err)
return core.Result{Value: err, OK: false}
}
output, ok := result.Value.(SessionListOutput)
if !ok {
err := core.E("agentic.cmdSessionList", "invalid session list output", nil)
core.Print(nil, "error: %v", err)
return core.Result{Value: err, OK: false}
}
if output.Count == 0 {
core.Print(nil, "no sessions")
return core.Result{Value: output, OK: true}
}
for _, session := range output.Sessions {
core.Print(nil, " %-10s %-10s %-24s %s", session.Status, session.AgentType, session.SessionID, sessionPlanSlug(session))
}
core.Print(nil, "%d session(s)", output.Count)
return core.Result{Value: output, OK: true}
}
// core-agent session start ax-follow-up --agent-type=codex
func (s *PrepSubsystem) cmdSessionStart(options core.Options) core.Result {
planSlug := optionStringValue(options, "plan_slug", "plan", "_arg")

View file

@ -19,6 +19,10 @@ func TestCommandsSession_RegisterSessionCommands_Good(t *testing.T) {
s.registerSessionCommands()
assert.Contains(t, c.Commands(), "session/get")
assert.Contains(t, c.Commands(), "agentic:session/get")
assert.Contains(t, c.Commands(), "session/list")
assert.Contains(t, c.Commands(), "agentic:session/list")
assert.Contains(t, c.Commands(), "session/handoff")
assert.Contains(t, c.Commands(), "agentic:session/handoff")
assert.Contains(t, c.Commands(), "session/start")
@ -39,6 +43,54 @@ func TestCommandsSession_RegisterSessionCommands_Good(t *testing.T) {
assert.Contains(t, c.Commands(), "agentic:session/replay")
}
func TestCommandsSession_CmdSessionGet_Good(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, "/v1/sessions/ses-get", r.URL.Path)
require.Equal(t, http.MethodGet, r.Method)
_, _ = w.Write([]byte(`{"data":{"session_id":"ses-get","plan_slug":"ax-follow-up","agent_type":"codex","status":"active","summary":"Working","created_at":"2026-03-31T12:00:00Z","updated_at":"2026-03-31T12:30:00Z","work_log":[{"type":"checkpoint","message":"started"}],"artifacts":[{"path":"pkg/agentic/session.go","action":"modified"}]}}`))
}))
defer server.Close()
subsystem := testPrepWithPlatformServer(t, server, "secret-token")
output := captureStdout(t, func() {
result := subsystem.cmdSessionGet(core.NewOptions(core.Option{Key: "_arg", Value: "ses-get"}))
require.True(t, result.OK)
})
assert.Contains(t, output, "session: ses-get")
assert.Contains(t, output, "plan: ax-follow-up")
assert.Contains(t, output, "work log: 1 item(s)")
assert.Contains(t, output, "artifacts: 1 item(s)")
}
func TestCommandsSession_CmdSessionList_Good(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, "/v1/sessions", r.URL.Path)
require.Equal(t, "ax-follow-up", r.URL.Query().Get("plan_slug"))
require.Equal(t, "codex", r.URL.Query().Get("agent_type"))
require.Equal(t, "active", r.URL.Query().Get("status"))
require.Equal(t, "5", r.URL.Query().Get("limit"))
_, _ = w.Write([]byte(`{"data":[{"session_id":"ses-1","plan_slug":"ax-follow-up","agent_type":"codex","status":"active"},{"session_id":"ses-2","agent_type":"claude","status":"paused"}],"count":2}`))
}))
defer server.Close()
subsystem := testPrepWithPlatformServer(t, server, "secret-token")
output := captureStdout(t, func() {
result := subsystem.cmdSessionList(core.NewOptions(
core.Option{Key: "plan_slug", Value: "ax-follow-up"},
core.Option{Key: "agent_type", Value: "codex"},
core.Option{Key: "status", Value: "active"},
core.Option{Key: "limit", Value: 5},
))
require.True(t, result.OK)
})
assert.Contains(t, output, "ses-1")
assert.Contains(t, output, "2 session(s)")
}
func TestCommandsSession_CmdSessionStart_Good(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, "/v1/sessions", r.URL.Path)

View file

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