fix(beads): align agent bead prefixes and force multi-hyphen IDs (#482)
* fix(beads): align agent bead prefixes and force multi-hyphen IDs * fix(checkpoint): treat threshold as stale at boundary
This commit is contained in:
@@ -16,6 +16,7 @@ import (
|
||||
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/steveyegge/gastown/internal/beads"
|
||||
"github.com/steveyegge/gastown/internal/style"
|
||||
"github.com/steveyegge/gastown/internal/tui/convoy"
|
||||
"github.com/steveyegge/gastown/internal/workspace"
|
||||
@@ -319,6 +320,9 @@ func runConvoyCreate(cmd *cobra.Command, args []string) error {
|
||||
"--description=" + description,
|
||||
"--json",
|
||||
}
|
||||
if beads.NeedsForceForID(convoyID) {
|
||||
createArgs = append(createArgs, "--force")
|
||||
}
|
||||
|
||||
createCmd := exec.Command("bd", createArgs...)
|
||||
createCmd.Dir = townBeads
|
||||
|
||||
@@ -211,7 +211,14 @@ func TestQuerySessionEvents_FindsEventsFromAllLocations(t *testing.T) {
|
||||
if wsErr != nil {
|
||||
t.Fatalf("workspace.FindFromCwdOrError failed: %v", wsErr)
|
||||
}
|
||||
if foundTownRoot != townRoot {
|
||||
normalizePath := func(path string) string {
|
||||
resolved, err := filepath.EvalSymlinks(path)
|
||||
if err != nil {
|
||||
return filepath.Clean(path)
|
||||
}
|
||||
return resolved
|
||||
}
|
||||
if normalizePath(foundTownRoot) != normalizePath(townRoot) {
|
||||
t.Errorf("workspace.FindFromCwdOrError returned %s, expected %s", foundTownRoot, townRoot)
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/steveyegge/gastown/internal/beads"
|
||||
"github.com/steveyegge/gastown/internal/config"
|
||||
"github.com/steveyegge/gastown/internal/style"
|
||||
"github.com/steveyegge/gastown/internal/workspace"
|
||||
@@ -335,6 +336,9 @@ func executeConvoyFormula(f *formulaData, formulaName, targetRig string) error {
|
||||
"--title=" + convoyTitle,
|
||||
"--description=" + description,
|
||||
}
|
||||
if beads.NeedsForceForID(convoyID) {
|
||||
createArgs = append(createArgs, "--force")
|
||||
}
|
||||
|
||||
createCmd := exec.Command("bd", createArgs...)
|
||||
createCmd.Dir = townBeads
|
||||
@@ -365,6 +369,9 @@ func executeConvoyFormula(f *formulaData, formulaName, targetRig string) error {
|
||||
"--title=" + leg.Title,
|
||||
"--description=" + legDesc,
|
||||
}
|
||||
if beads.NeedsForceForID(legBeadID) {
|
||||
legArgs = append(legArgs, "--force")
|
||||
}
|
||||
|
||||
legCmd := exec.Command("bd", legArgs...)
|
||||
legCmd.Dir = townBeads
|
||||
@@ -405,6 +412,9 @@ func executeConvoyFormula(f *formulaData, formulaName, targetRig string) error {
|
||||
"--title=" + f.Synthesis.Title,
|
||||
"--description=" + synDesc,
|
||||
}
|
||||
if beads.NeedsForceForID(synthesisBeadID) {
|
||||
synArgs = append(synArgs, "--force")
|
||||
}
|
||||
|
||||
synCmd := exec.Command("bd", synArgs...)
|
||||
synCmd.Dir = townBeads
|
||||
|
||||
@@ -957,7 +957,7 @@ func runPolecatCheckRecovery(cmd *cobra.Command, args []string) error {
|
||||
// We need to read it directly from beads since manager doesn't expose it
|
||||
rigPath := r.Path
|
||||
bd := beads.New(rigPath)
|
||||
agentBeadID := beads.PolecatBeadID(rigName, polecatName)
|
||||
agentBeadID := polecatBeadIDForRig(r, rigName, polecatName)
|
||||
_, fields, err := bd.GetAgentBead(agentBeadID)
|
||||
|
||||
status := RecoveryStatus{
|
||||
@@ -1158,7 +1158,7 @@ func runPolecatNuke(cmd *cobra.Command, args []string) error {
|
||||
fmt.Printf(" - Kill session: gt-%s-%s\n", p.rigName, p.polecatName)
|
||||
fmt.Printf(" - Delete worktree: %s/polecats/%s\n", p.r.Path, p.polecatName)
|
||||
fmt.Printf(" - Delete branch (if exists)\n")
|
||||
fmt.Printf(" - Close agent bead: %s\n", beads.PolecatBeadID(p.rigName, p.polecatName))
|
||||
fmt.Printf(" - Close agent bead: %s\n", polecatBeadIDForRig(p.r, p.rigName, p.polecatName))
|
||||
|
||||
displayDryRunSafetyCheck(p)
|
||||
fmt.Println()
|
||||
@@ -1214,7 +1214,7 @@ func runPolecatNuke(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
// Step 5: Close agent bead (if exists)
|
||||
agentBeadID := beads.PolecatBeadID(p.rigName, p.polecatName)
|
||||
agentBeadID := polecatBeadIDForRig(p.r, p.rigName, p.polecatName)
|
||||
closeArgs := []string{"close", agentBeadID, "--reason=nuked"}
|
||||
if sessionID := runtime.SessionIDFromEnv(); sessionID != "" {
|
||||
closeArgs = append(closeArgs, "--session="+sessionID)
|
||||
|
||||
@@ -2,6 +2,7 @@ package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/steveyegge/gastown/internal/beads"
|
||||
@@ -104,7 +105,7 @@ func checkPolecatSafety(target polecatTarget) *SafetyCheckResult {
|
||||
|
||||
// Check 1: Unpushed commits via cleanup_status or git state
|
||||
bd := beads.New(target.r.Path)
|
||||
agentBeadID := beads.PolecatBeadID(target.rigName, target.polecatName)
|
||||
agentBeadID := polecatBeadIDForRig(target.r, target.rigName, target.polecatName)
|
||||
agentIssue, fields, err := bd.GetAgentBead(agentBeadID)
|
||||
|
||||
if err != nil || fields == nil {
|
||||
@@ -176,6 +177,15 @@ func checkPolecatSafety(target polecatTarget) *SafetyCheckResult {
|
||||
return result
|
||||
}
|
||||
|
||||
func rigPrefix(r *rig.Rig) string {
|
||||
townRoot := filepath.Dir(r.Path)
|
||||
return beads.GetPrefixForRig(townRoot, r.Name)
|
||||
}
|
||||
|
||||
func polecatBeadIDForRig(r *rig.Rig, rigName, polecatName string) string {
|
||||
return beads.PolecatBeadIDWithPrefix(rigPrefix(r), rigName, polecatName)
|
||||
}
|
||||
|
||||
// displaySafetyCheckBlocked prints blocked polecats and guidance.
|
||||
func displaySafetyCheckBlocked(blocked []*SafetyCheckResult) {
|
||||
fmt.Printf("%s Cannot nuke the following polecats:\n\n", style.Error.Render("Error:"))
|
||||
@@ -202,7 +212,7 @@ func displayDryRunSafetyCheck(target polecatTarget) {
|
||||
fmt.Printf("\n Safety checks:\n")
|
||||
polecatInfo, infoErr := target.mgr.Get(target.polecatName)
|
||||
bd := beads.New(target.r.Path)
|
||||
agentBeadID := beads.PolecatBeadID(target.rigName, target.polecatName)
|
||||
agentBeadID := polecatBeadIDForRig(target.r, target.rigName, target.polecatName)
|
||||
agentIssue, fields, err := bd.GetAgentBead(agentBeadID)
|
||||
|
||||
// Check 1: Git state
|
||||
|
||||
@@ -232,7 +232,7 @@ func runPolecatIdentityAdd(cmd *cobra.Command, args []string) error {
|
||||
|
||||
// Check if identity already exists
|
||||
bd := beads.New(r.Path)
|
||||
beadID := beads.PolecatBeadID(rigName, polecatName)
|
||||
beadID := polecatBeadIDForRig(r, rigName, polecatName)
|
||||
existingIssue, _, _ := bd.GetAgentBead(beadID)
|
||||
if existingIssue != nil && existingIssue.Status != "closed" {
|
||||
return fmt.Errorf("identity bead %s already exists", beadID)
|
||||
@@ -385,7 +385,7 @@ func runPolecatIdentityShow(cmd *cobra.Command, args []string) error {
|
||||
|
||||
// Get identity bead
|
||||
bd := beads.New(r.Path)
|
||||
beadID := beads.PolecatBeadID(rigName, polecatName)
|
||||
beadID := polecatBeadIDForRig(r, rigName, polecatName)
|
||||
issue, fields, err := bd.GetAgentBead(beadID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting identity bead: %w", err)
|
||||
@@ -414,10 +414,10 @@ func runPolecatIdentityShow(cmd *cobra.Command, args []string) error {
|
||||
if polecatIdentityShowJSON {
|
||||
output := struct {
|
||||
IdentityInfo
|
||||
Title string `json:"title"`
|
||||
CreatedAt string `json:"created_at,omitempty"`
|
||||
UpdatedAt string `json:"updated_at,omitempty"`
|
||||
CV *CVSummary `json:"cv,omitempty"`
|
||||
Title string `json:"title"`
|
||||
CreatedAt string `json:"created_at,omitempty"`
|
||||
UpdatedAt string `json:"updated_at,omitempty"`
|
||||
CV *CVSummary `json:"cv,omitempty"`
|
||||
}{
|
||||
IdentityInfo: IdentityInfo{
|
||||
Rig: rigName,
|
||||
@@ -563,8 +563,8 @@ func runPolecatIdentityRename(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
bd := beads.New(r.Path)
|
||||
oldBeadID := beads.PolecatBeadID(rigName, oldName)
|
||||
newBeadID := beads.PolecatBeadID(rigName, newName)
|
||||
oldBeadID := polecatBeadIDForRig(r, rigName, oldName)
|
||||
newBeadID := polecatBeadIDForRig(r, rigName, newName)
|
||||
|
||||
// Check old identity exists
|
||||
oldIssue, oldFields, err := bd.GetAgentBead(oldBeadID)
|
||||
@@ -631,7 +631,7 @@ func runPolecatIdentityRemove(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
bd := beads.New(r.Path)
|
||||
beadID := beads.PolecatBeadID(rigName, polecatName)
|
||||
beadID := polecatBeadIDForRig(r, rigName, polecatName)
|
||||
|
||||
// Check identity exists
|
||||
issue, fields, err := bd.GetAgentBead(beadID)
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/steveyegge/gastown/internal/beads"
|
||||
"github.com/steveyegge/gastown/internal/style"
|
||||
"github.com/steveyegge/gastown/internal/workspace"
|
||||
)
|
||||
@@ -80,6 +81,9 @@ func createAutoConvoy(beadID, beadTitle string) (string, error) {
|
||||
"--title=" + convoyTitle,
|
||||
"--description=" + description,
|
||||
}
|
||||
if beads.NeedsForceForID(convoyID) {
|
||||
createArgs = append(createArgs, "--force")
|
||||
}
|
||||
|
||||
createCmd := exec.Command("bd", append([]string{"--no-daemon"}, createArgs...)...)
|
||||
createCmd.Dir = townBeads
|
||||
|
||||
Reference in New Issue
Block a user