feat: notify dispatcher when polecat work completes
When a crew or other agent dispatches work to a polecat using `gt sling`, the polecat now tracks who dispatched the work and sends them a completion notification when running `gt done`. Changes: - Add DispatchedBy field to AttachmentFields in beads/fields.go - Store dispatcher agent ID in bead when slinging (both direct and formula) - Check for dispatcher in done.go and send WORK_DONE notification to them This fixes the orchestration issue where crews were left waiting because polecats only notified the Witness on completion, not the dispatcher. Fixes: id-c17 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -322,6 +322,23 @@ func runDone(cmd *cobra.Command, args []string) error {
|
||||
fmt.Printf("%s Witness notified of %s\n", style.Bold.Render("✓"), exitType)
|
||||
}
|
||||
|
||||
// Notify dispatcher if work was dispatched by another agent
|
||||
if issueID != "" {
|
||||
if dispatcher := getDispatcherFromBead(cwd, issueID); dispatcher != "" && dispatcher != sender {
|
||||
dispatcherNotification := &mail.Message{
|
||||
To: dispatcher,
|
||||
From: sender,
|
||||
Subject: fmt.Sprintf("WORK_DONE: %s", issueID),
|
||||
Body: strings.Join(bodyLines, "\n"),
|
||||
}
|
||||
if err := townRouter.Send(dispatcherNotification); err != nil {
|
||||
style.PrintWarning("could not notify dispatcher %s: %v", dispatcher, err)
|
||||
} else {
|
||||
fmt.Printf("%s Dispatcher %s notified of %s\n", style.Bold.Render("✓"), dispatcher, exitType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Log done event (townlog and activity feed)
|
||||
LogDone(townRoot, sender, issueID)
|
||||
_ = events.LogFeed(events.TypeDone, sender, events.DonePayload(issueID, branch))
|
||||
@@ -406,6 +423,27 @@ func updateAgentStateOnDone(cwd, townRoot, exitType, issueID string) {
|
||||
}
|
||||
}
|
||||
|
||||
// getDispatcherFromBead retrieves the dispatcher agent ID from the bead's attachment fields.
|
||||
// Returns empty string if no dispatcher is recorded.
|
||||
func getDispatcherFromBead(cwd, issueID string) string {
|
||||
if issueID == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
bd := beads.New(cwd)
|
||||
issue, err := bd.Show(issueID)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
fields := beads.ParseAttachmentFields(issue)
|
||||
if fields == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return fields.DispatchedBy
|
||||
}
|
||||
|
||||
// computeCleanupStatus checks git state and returns the cleanup status.
|
||||
// Returns the most critical issue: has_unpushed > has_stash > has_uncommitted > clean
|
||||
func computeCleanupStatus(cwd string) string {
|
||||
|
||||
Reference in New Issue
Block a user