fix(hook): enable cross-prefix bead hooking with database routing
The `gt hook` command was failing to persist hooks for beads from different prefixes (e.g., hooking an hq-* bead from a rig worker). The issue was that `runHook` used `b.Update()` which always writes to the local beads database, regardless of the bead's prefix. Changes: - Use `beads.ResolveHookDir()` to determine the correct database directory for the bead being hooked, based on its prefix - Execute `bd update` with the correct working directory for cross-prefix routing - Call `updateAgentHookBead()` to set the agent's hook_bead slot, enabling `gt hook status` to find cross-prefix hooked beads - Add integration test for cross-prefix hooking scenarios This matches the pattern already used by `gt sling` for cross-prefix dispatch. Fixes: gt-rphsv Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
+22
-3
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/steveyegge/gastown/internal/beads"
|
||||
"github.com/steveyegge/gastown/internal/events"
|
||||
"github.com/steveyegge/gastown/internal/style"
|
||||
"github.com/steveyegge/gastown/internal/workspace"
|
||||
)
|
||||
|
||||
var hookCmd = &cobra.Command{
|
||||
@@ -147,6 +148,12 @@ func runHook(_ *cobra.Command, args []string) error {
|
||||
return fmt.Errorf("detecting agent identity: %w", err)
|
||||
}
|
||||
|
||||
// Find town root (needed for cross-prefix bead resolution)
|
||||
townRoot, err := workspace.FindFromCwd()
|
||||
if err != nil {
|
||||
return fmt.Errorf("finding workspace: %w", err)
|
||||
}
|
||||
|
||||
// Find beads directory
|
||||
workDir, err := findLocalBeadsDir()
|
||||
if err != nil {
|
||||
@@ -225,9 +232,15 @@ func runHook(_ *cobra.Command, args []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Hook the bead using beads package (uses RPC when daemon available)
|
||||
status := beads.StatusHooked
|
||||
if err := b.Update(beadID, beads.UpdateOptions{Status: &status, Assignee: &agentID}); err != nil {
|
||||
// Hook the bead using bd update with cross-prefix routing.
|
||||
// The bead may be in a different beads database than the agent's local one
|
||||
// (e.g., hooking an hq-* bead from a rig worker). Use ResolveHookDir to
|
||||
// find the correct database directory based on the bead's prefix.
|
||||
// See: https://github.com/steveyegge/gastown/issues/gt-rphsv
|
||||
hookCmd := exec.Command("bd", "--no-daemon", "update", beadID, "--status=hooked", "--assignee="+agentID)
|
||||
hookCmd.Dir = beads.ResolveHookDir(townRoot, beadID, workDir)
|
||||
hookCmd.Stderr = os.Stderr
|
||||
if err := hookCmd.Run(); err != nil {
|
||||
return fmt.Errorf("hooking bead: %w", err)
|
||||
}
|
||||
|
||||
@@ -235,6 +248,12 @@ func runHook(_ *cobra.Command, args []string) error {
|
||||
fmt.Printf(" Use 'gt handoff' to restart with this work\n")
|
||||
fmt.Printf(" Use 'gt hook' to see hook status\n")
|
||||
|
||||
// Update agent bead's hook_bead slot for status queries.
|
||||
// This enables `gt hook status` to find cross-prefix hooked beads.
|
||||
// The agent bead has a hook_bead database field that tracks current work.
|
||||
townBeadsDir := filepath.Join(townRoot, ".beads")
|
||||
updateAgentHookBead(agentID, beadID, workDir, townBeadsDir)
|
||||
|
||||
// Log hook event to activity feed (non-fatal)
|
||||
if err := events.LogFeed(events.TypeHook, agentID, events.HookPayload(beadID)); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%s Warning: failed to log hook event: %v\n", style.Dim.Render("⚠"), err)
|
||||
|
||||
Reference in New Issue
Block a user