Files
osmedeus/pkg/cli/run_status.go
T
j3ssie 90ce5f4a16 refactor: consolidate process killing logic and ACP agent defaults
- Extract KillProcessAndChildren into core.types for reuse across CLI and server handlers
- Replace hardcoded 'claude-code' strings with core.DefaultACPAgent constant
- Precompute absolute allowed paths in ACP client to avoid repeated filepath.Abs calls
- Simplify runQuerySteps to delegate to runQueryTable, reducing code duplication
- Refactor agent_chat concurrency guard using sync.Mutex.TryLock for cleaner code
- Use request context for agent timeout instead of background context
2026-03-07 16:49:48 +08:00

161 lines
4.1 KiB
Go

package cli
import (
"context"
"encoding/json"
"fmt"
"github.com/j3ssie/osmedeus/v5/internal/core"
"github.com/j3ssie/osmedeus/v5/internal/database"
"github.com/j3ssie/osmedeus/v5/internal/executor"
"github.com/j3ssie/osmedeus/v5/internal/terminal"
"github.com/spf13/cobra"
)
// runStatusCmd - show status of a specific run
var runStatusCmd = &cobra.Command{
Use: "status <run-uuid>",
Short: "Show status of a workflow run",
Long: UsageRunStatus(),
Args: cobra.ExactArgs(1),
RunE: runRunStatus,
}
// runCancelCmd - cancel a running workflow
var runCancelCmd = &cobra.Command{
Use: "cancel <run-uuid>",
Short: "Cancel a running workflow",
Long: UsageRunCancel(),
Args: cobra.ExactArgs(1),
RunE: runRunCancel,
}
func init() {
runCmd.AddCommand(runStatusCmd)
runCmd.AddCommand(runCancelCmd)
}
func runRunStatus(cmd *cobra.Command, args []string) error {
if err := connectDB(); err != nil {
return err
}
defer func() { _ = database.Close() }()
runUUID := args[0]
ctx := context.Background()
run, err := database.GetRunByID(ctx, runUUID, false, false)
if err != nil {
return fmt.Errorf("run not found: %w", err)
}
if globalJSON {
jsonBytes, err := json.Marshal(run)
if err != nil {
return fmt.Errorf("failed to format run: %w", err)
}
fmt.Println(string(jsonBytes))
return nil
}
// Key-value display
printer := terminal.NewPrinter()
printer.Info("Run Details")
fmt.Println()
printField("run_uuid", run.RunUUID)
printField("workflow", run.WorkflowName)
printField("kind", run.WorkflowKind)
printField("target", run.Target)
printField("workspace", run.Workspace)
printField("status", terminal.ColorizeStatus(run.Status))
printField("progress", fmt.Sprintf("%d/%d steps", run.CompletedSteps, run.TotalSteps))
printField("trigger_type", run.TriggerType)
if run.StartedAt != nil {
printField("started_at", run.StartedAt.String())
}
if run.CompletedAt != nil {
printField("completed_at", run.CompletedAt.String())
}
if run.ErrorMessage != "" {
printField("error", run.ErrorMessage)
}
if run.CurrentPID > 0 {
printField("pid", fmt.Sprintf("%d", run.CurrentPID))
}
return nil
}
// printField prints a key-value pair with aligned formatting.
func printField(key, value string) {
fmt.Printf(" %-16s %s\n", key+":", value)
}
func runRunCancel(cmd *cobra.Command, args []string) error {
if err := connectDB(); err != nil {
return err
}
defer func() { _ = database.Close() }()
runUUID := args[0]
ctx := context.Background()
run, err := database.GetRunByID(ctx, runUUID, false, false)
if err != nil {
return fmt.Errorf("run not found: %w", err)
}
if run.Status != string(core.RunStatusPending) && run.Status != string(core.RunStatusRunning) {
return fmt.Errorf("cannot cancel run with status '%s'", run.Status)
}
var killedPIDs []int
var killMethod string
// Try to cancel via control plane first
controlPlane := executor.GetRunControlPlane()
controlPlanePIDs, controlPlaneErr := controlPlane.Cancel(run.RunUUID)
if controlPlaneErr == nil && len(controlPlanePIDs) > 0 {
killedPIDs = controlPlanePIDs
killMethod = "control_plane"
} else if run.CurrentPID > 0 {
if core.KillProcessAndChildren(run.CurrentPID) {
killedPIDs = []int{run.CurrentPID}
killMethod = "database_pid"
}
}
// Update database status
if err := database.UpdateRunStatus(ctx, run.RunUUID, string(core.RunStatusCancelled), "Cancelled via CLI"); err != nil {
return fmt.Errorf("failed to update run status: %w", err)
}
if globalJSON {
response := map[string]interface{}{
"message": "Run cancelled successfully",
"run_uuid": run.RunUUID,
"killed_pids": killedPIDs,
"kill_method": killMethod,
}
jsonBytes, err := json.Marshal(response)
if err != nil {
return fmt.Errorf("failed to format response: %w", err)
}
fmt.Println(string(jsonBytes))
return nil
}
printer := terminal.NewPrinter()
printer.Success("Run %s cancelled", run.RunUUID)
if len(killedPIDs) > 0 {
fmt.Printf(" Terminated %d process(es) via %s\n", len(killedPIDs), killMethod)
} else {
fmt.Println(" No active processes found to terminate")
}
return nil
}