fix: Use StatusHooked instead of StatusPinned for hook queries

The hook mechanism was broken because gt hook sets status=hooked
but gt mol status was querying for status=pinned.

Adds StatusHooked constant and updates queries accordingly.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Steve Yegge
2025-12-29 14:53:38 -08:00
parent 8b54292f7b
commit 251642b7ce
2 changed files with 25 additions and 20 deletions

View File

@@ -7,8 +7,13 @@ import (
) )
// StatusPinned is the status for pinned beads that never get closed. // StatusPinned is the status for pinned beads that never get closed.
// These are "domain table" beads like role definitions that persist permanently.
const StatusPinned = "pinned" const StatusPinned = "pinned"
// StatusHooked is the status for beads on an agent's hook (work assignment).
// This is distinct from pinned - hooked beads are active work, not permanent records.
const StatusHooked = "hooked"
// HandoffBeadTitle returns the well-known title for a role's handoff bead. // HandoffBeadTitle returns the well-known title for a role's handoff bead.
func HandoffBeadTitle(role string) string { func HandoffBeadTitle(role string) string {
return role + " Handoff" return role + " Handoff"

View File

@@ -367,37 +367,37 @@ func runMoleculeStatus(cmd *cobra.Command, args []string) error {
} }
} }
} else { } else {
// FALLBACK: Legacy pinned-query approach (for agents without agent beads) // FALLBACK: Query for hooked beads (work on agent's hook)
pinnedBeads, err := b.List(beads.ListOptions{ hookedBeads, err := b.List(beads.ListOptions{
Status: beads.StatusPinned, Status: beads.StatusHooked,
Assignee: target, Assignee: target,
Priority: -1, Priority: -1,
}) })
if err != nil { if err != nil {
return fmt.Errorf("listing pinned beads: %w", err) return fmt.Errorf("listing hooked beads: %w", err)
} }
// For town-level roles (mayor, deacon), scan all rigs if nothing found locally // For town-level roles (mayor, deacon), scan all rigs if nothing found locally
if len(pinnedBeads) == 0 && isTownLevelRole(target) { if len(hookedBeads) == 0 && isTownLevelRole(target) {
pinnedBeads = scanAllRigsForPinnedBeads(townRoot, target) hookedBeads = scanAllRigsForHookedBeads(townRoot, target)
} }
status.HasWork = len(pinnedBeads) > 0 status.HasWork = len(hookedBeads) > 0
if len(pinnedBeads) > 0 { if len(hookedBeads) > 0 {
// Take the first pinned bead // Take the first hooked bead
status.PinnedBead = pinnedBeads[0] status.PinnedBead = hookedBeads[0]
// Check for attached molecule // Check for attached molecule
attachment := beads.ParseAttachmentFields(pinnedBeads[0]) attachment := beads.ParseAttachmentFields(hookedBeads[0])
if attachment != nil { if attachment != nil {
status.AttachedMolecule = attachment.AttachedMolecule status.AttachedMolecule = attachment.AttachedMolecule
status.AttachedAt = attachment.AttachedAt status.AttachedAt = attachment.AttachedAt
status.AttachedArgs = attachment.AttachedArgs status.AttachedArgs = attachment.AttachedArgs
// Check if it's a wisp // Check if it's a wisp
status.IsWisp = strings.Contains(pinnedBeads[0].Description, "wisp: true") || status.IsWisp = strings.Contains(hookedBeads[0].Description, "wisp: true") ||
strings.Contains(pinnedBeads[0].Description, "is_wisp: true") strings.Contains(hookedBeads[0].Description, "is_wisp: true")
// Get progress if there's an attached molecule // Get progress if there's an attached molecule
if attachment.AttachedMolecule != "" { if attachment.AttachedMolecule != "" {
@@ -846,10 +846,10 @@ func isTownLevelRole(agentID string) bool {
return agentID == "mayor" || agentID == "deacon" return agentID == "mayor" || agentID == "deacon"
} }
// scanAllRigsForPinnedBeads scans all registered rigs for pinned beads // scanAllRigsForHookedBeads scans all registered rigs for hooked beads
// assigned to the target agent. Used for town-level roles that may have // assigned to the target agent. Used for town-level roles that may have
// work pinned in any rig. // work hooked in any rig.
func scanAllRigsForPinnedBeads(townRoot, target string) []*beads.Issue { func scanAllRigsForHookedBeads(townRoot, target string) []*beads.Issue {
// Load routes from town beads // Load routes from town beads
townBeadsDir := filepath.Join(townRoot, ".beads") townBeadsDir := filepath.Join(townRoot, ".beads")
routes, err := beads.LoadRoutes(townBeadsDir) routes, err := beads.LoadRoutes(townBeadsDir)
@@ -865,8 +865,8 @@ func scanAllRigsForPinnedBeads(townRoot, target string) []*beads.Issue {
} }
b := beads.New(rigBeadsDir) b := beads.New(rigBeadsDir)
pinnedBeads, err := b.List(beads.ListOptions{ hookedBeads, err := b.List(beads.ListOptions{
Status: beads.StatusPinned, Status: beads.StatusHooked,
Assignee: target, Assignee: target,
Priority: -1, Priority: -1,
}) })
@@ -874,8 +874,8 @@ func scanAllRigsForPinnedBeads(townRoot, target string) []*beads.Issue {
continue continue
} }
if len(pinnedBeads) > 0 { if len(hookedBeads) > 0 {
return pinnedBeads return hookedBeads
} }
} }