Fix gt sling/hook: use Town beads for town-level roles (gt-4ol8f)

When slinging or hooking work to mayor/deacon, the pin now lands in Town
beads (~/.beads/) instead of rig beads. This ensures gt mol status finds
the pinned work when run from ~/gt.

The issue was that town-level roles operate from the town root, so their
hooks should be discoverable from there.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Steve Yegge
2025-12-27 17:46:43 -08:00
parent 711515506c
commit ed9816015d
2 changed files with 37 additions and 0 deletions

View File

@@ -8,6 +8,7 @@ import (
"github.com/spf13/cobra"
"github.com/steveyegge/gastown/internal/beads"
"github.com/steveyegge/gastown/internal/style"
"github.com/steveyegge/gastown/internal/workspace"
)
var hookCmd = &cobra.Command{
@@ -154,8 +155,17 @@ func runHook(cmd *cobra.Command, args []string) error {
}
// Pin the bead using bd update (discovery-based approach)
// For town-level roles (mayor, deacon), run from Town root so the pin
// lands in Town beads where these roles naturally operate.
pinCmd := exec.Command("bd", "update", beadID, "--status=pinned", "--assignee="+agentID)
pinCmd.Stderr = os.Stderr
if isTownLevelRole(agentID) {
townRoot, err := workspace.FindFromCwd()
if err != nil {
return fmt.Errorf("finding town root for town-level role: %w", err)
}
pinCmd.Dir = townRoot
}
if err := pinCmd.Run(); err != nil {
return fmt.Errorf("pinning bead: %w", err)
}

View File

@@ -11,6 +11,7 @@ import (
"github.com/steveyegge/gastown/internal/beads"
"github.com/steveyegge/gastown/internal/style"
"github.com/steveyegge/gastown/internal/tmux"
"github.com/steveyegge/gastown/internal/workspace"
)
var slingCmd = &cobra.Command{
@@ -231,8 +232,17 @@ func runSling(cmd *cobra.Command, args []string) error {
}
// Pin the bead using bd update (discovery-based approach)
// For town-level roles (mayor, deacon), run from Town root so the pin
// lands in Town beads where these roles naturally operate.
pinCmd := exec.Command("bd", "update", beadID, "--status=pinned", "--assignee="+targetAgent)
pinCmd.Stderr = os.Stderr
if isTownLevelRole(targetAgent) {
townRoot, err := workspace.FindFromCwd()
if err != nil {
return fmt.Errorf("finding town root for town-level role: %w", err)
}
pinCmd.Dir = townRoot
}
if err := pinCmd.Run(); err != nil {
return fmt.Errorf("pinning bead: %w", err)
}
@@ -593,8 +603,17 @@ func runSlingFormula(args []string) error {
fmt.Printf("%s Wisp created: %s\n", style.Bold.Render("✓"), wispResult.RootID)
// Step 3: Pin the wisp bead using bd update (discovery-based approach)
// For town-level roles (mayor, deacon), run from Town root so the pin
// lands in Town beads where these roles naturally operate.
pinCmd := exec.Command("bd", "update", wispResult.RootID, "--status=pinned", "--assignee="+targetAgent)
pinCmd.Stderr = os.Stderr
if isTownLevelRole(targetAgent) {
townRoot, err := workspace.FindFromCwd()
if err != nil {
return fmt.Errorf("finding town root for town-level role: %w", err)
}
pinCmd.Dir = townRoot
}
if err := pinCmd.Run(); err != nil {
return fmt.Errorf("pinning wisp bead: %w", err)
}
@@ -632,3 +651,11 @@ func runSlingFormula(args []string) error {
return nil
}
// isTownLevelRole returns true if the agent ID is a town-level role.
// Town-level roles (Mayor, Deacon) operate from the town root and their
// pinned beads should live in Town beads (~/.beads/), not rig beads.
// This ensures gt mol status finds pinned work when run from ~/gt.
func isTownLevelRole(agentID string) bool {
return agentID == "mayor" || agentID == "deacon"
}