package status import ( "context" "fmt" "path/filepath" "iop/apps/node/internal/runtime" "iop/packages/config" ) // UsageStatus represents the parsed usage limits of an agent CLI. type UsageStatus struct { RawOutput string `json:"raw_output"` DailyLimit string `json:"daily_limit,omitempty"` DailyResetTime string `json:"daily_reset_time,omitempty"` WeeklyLimit string `json:"weekly_limit,omitempty"` WeeklyResetTime string `json:"weekly_reset_time,omitempty"` // Additional fields can be added as needed } // ToRuntime converts UsageStatus to the runtime domain type. func (s *UsageStatus) ToRuntime() *runtime.AgentUsageStatus { if s == nil { return nil } return &runtime.AgentUsageStatus{ RawOutput: s.RawOutput, DailyLimit: s.DailyLimit, DailyResetTime: s.DailyResetTime, WeeklyLimit: s.WeeklyLimit, WeeklyResetTime: s.WeeklyResetTime, } } // Checker defines the interface for checking CLI status/usage. type Checker interface { Check(ctx context.Context) (*UsageStatus, error) } // CheckUsage creates the appropriate checker and executes it. func CheckUsage(ctx context.Context, agent string, profile config.CLIProfileConf) (*UsageStatus, error) { checker, err := NewChecker(agent, profile) if err != nil { return nil, err } return checker.Check(ctx) } // NewChecker creates the appropriate checker for the given agent and profile. func NewChecker(agent string, profile config.CLIProfileConf) (Checker, error) { cmdBase := filepath.Base(profile.Command) switch { case agent == "codex" || cmdBase == "codex": return NewCodexChecker(profile.Command), nil case agent == "claude" || cmdBase == "claude": return NewClaudeChecker(), nil case agent == "gemini" || cmdBase == "gemini": return NewGeminiChecker(), nil default: return nil, fmt.Errorf("status check not supported for agent %q (command %q)", agent, profile.Command) } }