fix(mail): prevent message type failures (#960)
This commit is contained in:
@@ -11,9 +11,9 @@ import (
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/steveyegge/gastown/internal/beads"
|
||||
"github.com/steveyegge/gastown/internal/constants"
|
||||
"github.com/steveyegge/gastown/internal/claude"
|
||||
"github.com/steveyegge/gastown/internal/config"
|
||||
"github.com/steveyegge/gastown/internal/constants"
|
||||
"github.com/steveyegge/gastown/internal/deps"
|
||||
"github.com/steveyegge/gastown/internal/formula"
|
||||
"github.com/steveyegge/gastown/internal/shell"
|
||||
@@ -408,11 +408,8 @@ func initTownBeads(townPath string) error {
|
||||
|
||||
// Configure custom types for Gas Town (agent, role, rig, convoy, slot).
|
||||
// These were extracted from beads core in v0.46.0 and now require explicit config.
|
||||
configCmd := exec.Command("bd", "config", "set", "types.custom", constants.BeadsCustomTypes)
|
||||
configCmd.Dir = townPath
|
||||
if configOutput, configErr := configCmd.CombinedOutput(); configErr != nil {
|
||||
// Non-fatal: older beads versions don't need this, newer ones do
|
||||
fmt.Printf(" %s Could not set custom types: %s\n", style.Dim.Render("⚠"), strings.TrimSpace(string(configOutput)))
|
||||
if err := beads.EnsureCustomTypes(beadsDir); err != nil {
|
||||
return fmt.Errorf("ensuring custom types: %w", err)
|
||||
}
|
||||
|
||||
// Configure allowed_prefixes for convoy beads (hq-cv-* IDs).
|
||||
|
||||
@@ -212,6 +212,10 @@ func (m *Mailbox) identityVariants() []string {
|
||||
|
||||
// queryMessages runs a bd list query with the given filter flag and value.
|
||||
func (m *Mailbox) queryMessages(beadsDir, filterFlag, filterValue, status string) ([]*Message, error) {
|
||||
if err := beads.EnsureCustomTypes(beadsDir); err != nil {
|
||||
return nil, fmt.Errorf("ensuring custom types: %w", err)
|
||||
}
|
||||
|
||||
args := []string{"list",
|
||||
"--type", "message",
|
||||
filterFlag, filterValue,
|
||||
@@ -829,8 +833,8 @@ func (m *Mailbox) rewriteLegacy(messages []*Message) error {
|
||||
for _, msg := range messages {
|
||||
data, err := json.Marshal(msg)
|
||||
if err != nil {
|
||||
_ = file.Close() // best-effort cleanup
|
||||
_ = os.Remove(tmpPath) // best-effort cleanup
|
||||
_ = file.Close() // best-effort cleanup
|
||||
_ = os.Remove(tmpPath) // best-effort cleanup
|
||||
return err
|
||||
}
|
||||
_, _ = file.WriteString(string(data) + "\n") // non-fatal: partial write is acceptable
|
||||
|
||||
@@ -189,6 +189,13 @@ func (r *Router) resolveBeadsDir(_ string) string { // address unused: all mail
|
||||
return filepath.Join(r.townRoot, ".beads")
|
||||
}
|
||||
|
||||
func (r *Router) ensureCustomTypes(beadsDir string) error {
|
||||
if err := beads.EnsureCustomTypes(beadsDir); err != nil {
|
||||
return fmt.Errorf("ensuring custom types: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// isTownLevelAddress returns true if the address is for a town-level agent or the overseer.
|
||||
func isTownLevelAddress(address string) bool {
|
||||
addr := strings.TrimSuffix(address, "/")
|
||||
@@ -214,10 +221,10 @@ const (
|
||||
|
||||
// ParsedGroup represents a parsed @group address.
|
||||
type ParsedGroup struct {
|
||||
Type GroupType
|
||||
RoleType string // witness, crew, polecat, dog, etc.
|
||||
Rig string // rig name for rig-scoped groups
|
||||
Original string // original @group string
|
||||
Type GroupType
|
||||
RoleType string // witness, crew, polecat, dog, etc.
|
||||
Rig string // rig name for rig-scoped groups
|
||||
Original string // original @group string
|
||||
}
|
||||
|
||||
// parseGroupAddress parses a @group address into its components.
|
||||
@@ -697,6 +704,9 @@ func (r *Router) sendToSingle(msg *Message) error {
|
||||
}
|
||||
|
||||
beadsDir := r.resolveBeadsDir(msg.To)
|
||||
if err := r.ensureCustomTypes(beadsDir); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := runBdCommand(args, filepath.Dir(beadsDir), beadsDir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("sending message: %w", err)
|
||||
@@ -807,6 +817,9 @@ func (r *Router) sendToQueue(msg *Message) error {
|
||||
|
||||
// Queue messages go to town-level beads (shared location)
|
||||
beadsDir := r.resolveBeadsDir("")
|
||||
if err := r.ensureCustomTypes(beadsDir); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = runBdCommand(args, filepath.Dir(beadsDir), beadsDir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("sending to queue %s: %w", queueName, err)
|
||||
@@ -878,6 +891,9 @@ func (r *Router) sendToAnnounce(msg *Message) error {
|
||||
|
||||
// Announce messages go to town-level beads (shared location)
|
||||
beadsDir := r.resolveBeadsDir("")
|
||||
if err := r.ensureCustomTypes(beadsDir); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = runBdCommand(args, filepath.Dir(beadsDir), beadsDir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("sending to announce %s: %w", announceName, err)
|
||||
@@ -951,6 +967,9 @@ func (r *Router) sendToChannel(msg *Message) error {
|
||||
|
||||
// Channel messages go to town-level beads (shared location)
|
||||
beadsDir := r.resolveBeadsDir("")
|
||||
if err := r.ensureCustomTypes(beadsDir); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = runBdCommand(args, filepath.Dir(beadsDir), beadsDir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("sending to channel %s: %w", channelName, err)
|
||||
@@ -988,6 +1007,9 @@ func (r *Router) pruneAnnounce(announceName string, retainCount int) error {
|
||||
}
|
||||
|
||||
beadsDir := r.resolveBeadsDir("")
|
||||
if err := r.ensureCustomTypes(beadsDir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Query existing messages in this announce channel
|
||||
// Use bd list with labels filter to find messages with announce:<name> label
|
||||
|
||||
Reference in New Issue
Block a user