feat(polecat): add repo path to worktrees for LLM ergonomics (GH#283)
Changes polecat worktree structure from: polecats/<name>/ to: polecats/<name>/<rigname>/ This gives Claude Code agents a recognizable directory name (e.g., tidepool/) in their cwd instead of just the polecat name, preventing confusion about which repo they are working in. Key changes: - Add clonePath() method to manager.go and session_manager.go for the actual git worktree path, keeping polecatDir() for existence checks - Update Add(), RepairWorktree(), Remove() to use new structure - Update daemon lifecycle and restart code for new paths - Update witness handlers to detect both structures - Update doctor checks (rig_check, branch_check, config_check, claude_settings_check) for backward compatibility - All code includes fallback to old structure for existing polecats Fixes #283 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
committed by
Steve Yegge
parent
c8c97fdf64
commit
9b2f4a7652
@@ -468,12 +468,20 @@ func (c *CloneDivergenceCheck) findAllClones(townRoot string) []string {
|
||||
}
|
||||
}
|
||||
|
||||
// Add polecats
|
||||
// Add polecats (handle both new and old structures)
|
||||
// New structure: polecats/<name>/<rigname>/
|
||||
// Old structure: polecats/<name>/
|
||||
rigName := entry.Name()
|
||||
polecatsPath := filepath.Join(rigPath, "polecats")
|
||||
if polecatEntries, err := os.ReadDir(polecatsPath); err == nil {
|
||||
for _, polecat := range polecatEntries {
|
||||
if polecat.IsDir() && !strings.HasPrefix(polecat.Name(), ".") {
|
||||
path := filepath.Join(polecatsPath, polecat.Name())
|
||||
// Try new structure first
|
||||
path := filepath.Join(polecatsPath, polecat.Name(), rigName)
|
||||
if !c.isGitRepo(path) {
|
||||
// Fall back to old structure
|
||||
path = filepath.Join(polecatsPath, polecat.Name())
|
||||
}
|
||||
if c.isGitRepo(path) {
|
||||
clones = append(clones, path)
|
||||
}
|
||||
|
||||
@@ -288,15 +288,23 @@ func (c *ClaudeSettingsCheck) findSettingsFiles(townRoot string) []staleSettings
|
||||
if !pcEntry.IsDir() || pcEntry.Name() == ".claude" {
|
||||
continue
|
||||
}
|
||||
pcWrongSettings := filepath.Join(polecatsDir, pcEntry.Name(), ".claude", "settings.json")
|
||||
if fileExists(pcWrongSettings) {
|
||||
files = append(files, staleSettingsInfo{
|
||||
path: pcWrongSettings,
|
||||
agentType: "polecat",
|
||||
rigName: rigName,
|
||||
sessionName: fmt.Sprintf("gt-%s-%s", rigName, pcEntry.Name()),
|
||||
wrongLocation: true,
|
||||
})
|
||||
// Check for wrong settings in both structures:
|
||||
// Old structure: polecats/<name>/.claude/settings.json
|
||||
// New structure: polecats/<name>/<rigname>/.claude/settings.json
|
||||
wrongPaths := []string{
|
||||
filepath.Join(polecatsDir, pcEntry.Name(), ".claude", "settings.json"),
|
||||
filepath.Join(polecatsDir, pcEntry.Name(), rigName, ".claude", "settings.json"),
|
||||
}
|
||||
for _, pcWrongSettings := range wrongPaths {
|
||||
if fileExists(pcWrongSettings) {
|
||||
files = append(files, staleSettingsInfo{
|
||||
path: pcWrongSettings,
|
||||
agentType: "polecat",
|
||||
rigName: rigName,
|
||||
sessionName: fmt.Sprintf("gt-%s-%s", rigName, pcEntry.Name()),
|
||||
wrongLocation: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -460,14 +460,24 @@ func (c *SessionHookCheck) findSettingsFiles(townRoot string) []string {
|
||||
}
|
||||
}
|
||||
|
||||
// Polecats
|
||||
// Polecats (handle both new and old structures)
|
||||
// New structure: polecats/<name>/<rigname>/.claude/settings.json
|
||||
// Old structure: polecats/<name>/.claude/settings.json
|
||||
rigName := filepath.Base(rig)
|
||||
polecatsPath := filepath.Join(rig, "polecats")
|
||||
if polecatEntries, err := os.ReadDir(polecatsPath); err == nil {
|
||||
for _, polecat := range polecatEntries {
|
||||
if polecat.IsDir() && !strings.HasPrefix(polecat.Name(), ".") {
|
||||
polecatSettings := filepath.Join(polecatsPath, polecat.Name(), ".claude", "settings.json")
|
||||
// Try new structure first
|
||||
polecatSettings := filepath.Join(polecatsPath, polecat.Name(), rigName, ".claude", "settings.json")
|
||||
if _, err := os.Stat(polecatSettings); err == nil {
|
||||
files = append(files, polecatSettings)
|
||||
} else {
|
||||
// Fall back to old structure
|
||||
polecatSettings = filepath.Join(polecatsPath, polecat.Name(), ".claude", "settings.json")
|
||||
if _, err := os.Stat(polecatSettings); err == nil {
|
||||
files = append(files, polecatSettings)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -698,14 +698,24 @@ func (c *PolecatClonesValidCheck) Run(ctx *CheckContext) *CheckResult {
|
||||
var warnings []string
|
||||
validCount := 0
|
||||
|
||||
// Get rig name for new structure path detection
|
||||
rigName := ctx.RigName
|
||||
|
||||
for _, entry := range entries {
|
||||
if !entry.IsDir() || strings.HasPrefix(entry.Name(), ".") {
|
||||
continue
|
||||
}
|
||||
|
||||
polecatPath := filepath.Join(polecatsDir, entry.Name())
|
||||
polecatName := entry.Name()
|
||||
|
||||
// Determine worktree path (handle both new and old structures)
|
||||
// New structure: polecats/<name>/<rigname>/
|
||||
// Old structure: polecats/<name>/
|
||||
polecatPath := filepath.Join(polecatsDir, polecatName, rigName)
|
||||
if _, err := os.Stat(polecatPath); os.IsNotExist(err) {
|
||||
polecatPath = filepath.Join(polecatsDir, polecatName)
|
||||
}
|
||||
|
||||
// Check if it's a git clone
|
||||
gitPath := filepath.Join(polecatPath, ".git")
|
||||
if _, err := os.Stat(gitPath); os.IsNotExist(err) {
|
||||
|
||||
Reference in New Issue
Block a user