From c678d2e3d4b44e19887b096b45f9875ef64c6434 Mon Sep 17 00:00:00 2001 From: citadel Date: Mon, 5 Jan 2026 00:16:40 -0800 Subject: [PATCH] fix: Close hooked beads before clearing agent hook (gt-vwjz6) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, when gt done was called, it cleared the agent's hook_bead slot but didn't update the status of the hooked bead itself. This left handoff beads with status=hooked forever. Now the hooked bead is closed (status changed from hooked to closed) before clearing the agent's hook slot. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- internal/cmd/done.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/internal/cmd/done.go b/internal/cmd/done.go index 8832555a..cc85a168 100644 --- a/internal/cmd/done.go +++ b/internal/cmd/done.go @@ -419,6 +419,20 @@ func updateAgentStateOnDone(cwd, townRoot, exitType, _ string) { // issueID unus beadsPath = filepath.Join(townRoot, ctx.Rig) } bd := beads.New(beadsPath) + + // BUG FIX (gt-vwjz6): Close hooked beads before clearing the hook. + // Previously, the agent's hook_bead slot was cleared but the hooked bead itself + // stayed status=hooked forever. Now we close the hooked bead before clearing. + if agentBead, err := bd.Show(agentBeadID); err == nil && agentBead.HookBead != "" { + hookedBeadID := agentBead.HookBead + // Only close if the hooked bead exists and is still in "hooked" status + if hookedBead, err := bd.Show(hookedBeadID); err == nil && hookedBead.Status == beads.StatusHooked { + if err := bd.Close(hookedBeadID); err != nil { + fmt.Fprintf(os.Stderr, "Warning: couldn't close hooked bead %s: %v\n", hookedBeadID, err) + } + } + } + emptyHook := "" if err := bd.UpdateAgentState(agentBeadID, newState, &emptyHook); err != nil { // Log warning instead of silent ignore - helps debug cross-beads issues