Show current work (in_progress issues) in crew/polecat status bar
- Added GetPaneWorkDir to tmux package to get pane current directory - Added getCurrentWork helper that queries beads for in_progress issues - Worker status line now shows first in_progress issue (ID: title) - Falls back to GT_ISSUE env var if set, or empty if no work in progress - Truncated to 40 chars to fit status bar Example: 👷 gt-44wh: Polecats must not create GitHu… | 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -3,9 +3,11 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/steveyegge/gastown/internal/beads"
|
||||||
"github.com/steveyegge/gastown/internal/mail"
|
"github.com/steveyegge/gastown/internal/mail"
|
||||||
"github.com/steveyegge/gastown/internal/tmux"
|
"github.com/steveyegge/gastown/internal/tmux"
|
||||||
)
|
)
|
||||||
@@ -68,11 +70,11 @@ func runStatusLine(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Crew/Polecat status line
|
// Crew/Polecat status line
|
||||||
return runWorkerStatusLine(rigName, polecat, crew, issue)
|
return runWorkerStatusLine(t, statusLineSession, rigName, polecat, crew, issue)
|
||||||
}
|
}
|
||||||
|
|
||||||
// runWorkerStatusLine outputs status for crew or polecat sessions.
|
// runWorkerStatusLine outputs status for crew or polecat sessions.
|
||||||
func runWorkerStatusLine(rigName, polecat, crew, issue string) error {
|
func runWorkerStatusLine(t *tmux.Tmux, session, rigName, polecat, crew, issue string) error {
|
||||||
// Determine agent type and identity
|
// Determine agent type and identity
|
||||||
var icon, identity string
|
var icon, identity string
|
||||||
if polecat != "" {
|
if polecat != "" {
|
||||||
@@ -86,15 +88,21 @@ func runWorkerStatusLine(rigName, polecat, crew, issue string) error {
|
|||||||
// Build status parts
|
// Build status parts
|
||||||
var parts []string
|
var parts []string
|
||||||
|
|
||||||
// Add icon prefix
|
// Try to get current work from beads if no issue env var
|
||||||
|
currentWork := issue
|
||||||
|
if currentWork == "" && session != "" {
|
||||||
|
currentWork = getCurrentWork(t, session, 40)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add icon and current work
|
||||||
if icon != "" {
|
if icon != "" {
|
||||||
if issue != "" {
|
if currentWork != "" {
|
||||||
parts = append(parts, fmt.Sprintf("%s %s", icon, issue))
|
parts = append(parts, fmt.Sprintf("%s %s", icon, currentWork))
|
||||||
} else {
|
} else {
|
||||||
parts = append(parts, icon)
|
parts = append(parts, icon)
|
||||||
}
|
}
|
||||||
} else if issue != "" {
|
} else if currentWork != "" {
|
||||||
parts = append(parts, issue)
|
parts = append(parts, currentWork)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mail preview
|
// Mail preview
|
||||||
@@ -353,3 +361,37 @@ func getMailPreview(identity string, maxLen int) (int, string) {
|
|||||||
|
|
||||||
return len(messages), subject
|
return len(messages), subject
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getCurrentWork returns a truncated title of the first in_progress issue.
|
||||||
|
// Uses the pane's working directory to find the beads.
|
||||||
|
func getCurrentWork(t *tmux.Tmux, session string, maxLen int) string {
|
||||||
|
// Get the pane's working directory
|
||||||
|
workDir, err := t.GetPaneWorkDir(session)
|
||||||
|
if err != nil || workDir == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if there's a .beads directory
|
||||||
|
beadsDir := filepath.Join(workDir, ".beads")
|
||||||
|
if _, err := os.Stat(beadsDir); os.IsNotExist(err) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query beads for in_progress issues
|
||||||
|
b := beads.New(workDir)
|
||||||
|
issues, err := b.List(beads.ListOptions{
|
||||||
|
Status: "in_progress",
|
||||||
|
Priority: -1,
|
||||||
|
})
|
||||||
|
if err != nil || len(issues) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return first issue's ID and title, truncated
|
||||||
|
issue := issues[0]
|
||||||
|
display := fmt.Sprintf("%s: %s", issue.ID, issue.Title)
|
||||||
|
if len(display) > maxLen {
|
||||||
|
display = display[:maxLen-1] + "…"
|
||||||
|
}
|
||||||
|
return display
|
||||||
|
}
|
||||||
|
|||||||
@@ -207,6 +207,15 @@ func (t *Tmux) GetPaneCommand(session string) (string, error) {
|
|||||||
return strings.TrimSpace(out), nil
|
return strings.TrimSpace(out), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetPaneWorkDir returns the current working directory of a pane.
|
||||||
|
func (t *Tmux) GetPaneWorkDir(session string) (string, error) {
|
||||||
|
out, err := t.run("list-panes", "-t", session, "-F", "#{pane_current_path}")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return strings.TrimSpace(out), nil
|
||||||
|
}
|
||||||
|
|
||||||
// CapturePane captures the visible content of a pane.
|
// CapturePane captures the visible content of a pane.
|
||||||
func (t *Tmux) CapturePane(session string, lines int) (string, error) {
|
func (t *Tmux) CapturePane(session string, lines int) (string, error) {
|
||||||
return t.run("capture-pane", "-p", "-t", session, "-S", fmt.Sprintf("-%d", lines))
|
return t.run("capture-pane", "-p", "-t", session, "-S", fmt.Sprintf("-%d", lines))
|
||||||
|
|||||||
Reference in New Issue
Block a user