package main import ( "bufio" "encoding/json" "fmt" "os" "os/exec" "path/filepath" "regexp" "strings" "golang.org/x/sys/unix" ) const statuslineWidthOffset = 7 // Input JSON structure from Claude Code type StatusInput struct { Model struct { DisplayName string `json:"display_name"` } `json:"model"` Workspace struct { CurrentDir string `json:"current_dir"` } `json:"workspace"` ContextWindow struct { ContextWindowSize int `json:"context_window_size"` CurrentUsage *struct { InputTokens int `json:"input_tokens"` CacheCreationTokens int `json:"cache_creation_input_tokens"` CacheReadInputTokens int `json:"cache_read_input_tokens"` } `json:"current_usage"` } `json:"context_window"` } // ANSI color codes const ( reset = "\033[0m" bold = "\033[1m" red = "\033[31m" green = "\033[32m" yellow = "\033[33m" magenta = "\033[35m" cyan = "\033[36m" boldGreen = "\033[1;32m" ) func main() { // Read JSON from stdin reader := bufio.NewReader(os.Stdin) var input strings.Builder for { line, err := reader.ReadString('\n') input.WriteString(line) if err != nil { break } } var data StatusInput if err := json.Unmarshal([]byte(input.String()), &data); err != nil { fmt.Fprintf(os.Stderr, "Error parsing JSON: %v\n", err) os.Exit(1) } // Calculate context info contextInfo := formatContextInfo(data.ContextWindow.ContextWindowSize, data.ContextWindow.CurrentUsage) // Get directory name dirName := filepath.Base(data.Workspace.CurrentDir) // Check gitea status giteaStatus := getGiteaStatus() // Get git info gitInfo := getGitInfo(data.Workspace.CurrentDir) // Build left part left := fmt.Sprintf("%s %s%s%s %sāžœ%s %s%s%s%s", giteaStatus, magenta, data.Model.DisplayName, reset, boldGreen, reset, cyan, dirName, reset, gitInfo) // Build right part right := fmt.Sprintf("%s%s%s", yellow, contextInfo, reset) // Calculate visible lengths (strip ANSI) leftVisible := stripANSI(left) rightVisible := stripANSI(right) // Get terminal width termWidth := getTerminalWidth() - statuslineWidthOffset // Calculate padding padding := termWidth - len(leftVisible) - len(rightVisible) if padding < 1 { padding = 1 } // Output with padding fmt.Printf("%s%s%s", left, strings.Repeat(" ", padding), right) } func formatContextInfo(contextSize int, usage *struct { InputTokens int `json:"input_tokens"` CacheCreationTokens int `json:"cache_creation_input_tokens"` CacheReadInputTokens int `json:"cache_read_input_tokens"` }) string { totalK := contextSize / 1000 if usage == nil { return fmt.Sprintf("0/%dk", totalK) } currentTokens := usage.InputTokens + usage.CacheCreationTokens + usage.CacheReadInputTokens currentK := currentTokens / 1000 return fmt.Sprintf("%dk/%dk", currentK, totalK) } func getGiteaStatus() string { // Check if gitea process is running using pgrep cmd := exec.Command("pgrep", "-x", "gitea") if err := cmd.Run(); err == nil { return green + "ā—" + reset } return red + "ā—" + reset } func getGitInfo(cwd string) string { // Change to the directory oldDir, _ := os.Getwd() if err := os.Chdir(cwd); err != nil { return "" } defer os.Chdir(oldDir) // Check if we're in a git repo cmd := exec.Command("git", "rev-parse", "--git-dir") cmd.Stderr = nil if err := cmd.Run(); err != nil { return "" } // Get branch name branch := "" cmd = exec.Command("git", "symbolic-ref", "--short", "HEAD") cmd.Stderr = nil if out, err := cmd.Output(); err == nil { branch = strings.TrimSpace(string(out)) } else { // Fallback to short SHA cmd = exec.Command("git", "rev-parse", "--short", "HEAD") cmd.Stderr = nil if out, err := cmd.Output(); err == nil { branch = strings.TrimSpace(string(out)) } } if branch == "" { return "" } // Check if working tree is dirty isDirty := false // Check unstaged changes cmd = exec.Command("git", "diff", "--no-ext-diff", "--quiet", "--exit-code", "--no-optional-locks") cmd.Stderr = nil if err := cmd.Run(); err != nil { isDirty = true } // Check staged changes if !isDirty { cmd = exec.Command("git", "diff-index", "--cached", "--quiet", "HEAD", "--no-optional-locks") cmd.Stderr = nil if err := cmd.Run(); err != nil { isDirty = true } } if isDirty { return fmt.Sprintf(" git:(%s) āœ—", branch) } return fmt.Sprintf(" git:(%s)", branch) } func getTerminalWidth() int { ws, err := unix.IoctlGetWinsize(int(os.Stdout.Fd()), unix.TIOCGWINSZ) if err != nil { return 80 } return int(ws.Col) } var ansiRegex = regexp.MustCompile(`\x1b\[[0-9;]*m`) func stripANSI(s string) string { return ansiRegex.ReplaceAllString(s, "") }