package status import ( "context" "regexp" "strings" ) var ( // Regex patterns based on the Codex output format // "5h limit: [████████████████████] 98% left (resets 18:38)" // "Weekly limit: [████░░░░░░░░░░░░░░░░] 22% left (resets 10:20 on 8 May)" dailyLimitRegex = regexp.MustCompile(`5h limit:.*?\]\s*([^%\n]+%)[^\(]*\(resets\s+([^\)]+)\)`) weeklyLimitRegex = regexp.MustCompile(`Weekly limit:.*?\]\s*([^%\n]+%)[^\(]*\(resets\s+([^\)]+)\)`) ) // ParseStatusOutput cleans the raw string and attempts to parse limits. func ParseStatusOutput(ctx context.Context, raw string) (*UsageStatus, error) { cleanRaw := cleanANSI(raw) status := &UsageStatus{ RawOutput: cleanRaw, } // 1. Direct Parsing if match := dailyLimitRegex.FindStringSubmatch(cleanRaw); len(match) > 2 { status.DailyLimit = strings.TrimSpace(match[1]) status.DailyResetTime = strings.TrimSpace(match[2]) } if match := weeklyLimitRegex.FindStringSubmatch(cleanRaw); len(match) > 2 { status.WeeklyLimit = strings.TrimSpace(match[1]) status.WeeklyResetTime = strings.TrimSpace(match[2]) } // 2. LLM Fallback (Stub) // If direct parsing failed but we expect data, we could call an LLM here // via a centralized LLM adapter or internal utility, passing `cleanRaw` // to extract the schema as JSON. return status, nil } // cleanANSI removes ANSI escape codes from the string. func cleanANSI(str string) string { ansiRegex := regexp.MustCompile(`\x1b\[[0-9;]*m`) return ansiRegex.ReplaceAllString(str, "") }