feat: add mail system and CLI commands
- internal/mail: Message types with priority support - internal/mail: Mailbox JSONL operations (list, get, append, delete) - internal/mail: Router for address resolution and delivery - gt mail send: Send messages to agents - gt mail inbox: List messages (--unread, --json) - gt mail read: Read and mark messages as read - Address formats: mayor/, rig/, rig/polecat, rig/refinery - High priority messages trigger tmux notification - Auto-detect sender from GT_RIG/GT_POLECAT env vars Closes gt-u1j.6, gt-u1j.12 Generated with Claude Code Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
67
internal/mail/types.go
Normal file
67
internal/mail/types.go
Normal file
@@ -0,0 +1,67 @@
|
||||
// Package mail provides JSONL-based messaging for agent communication.
|
||||
package mail
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Priority levels for messages.
|
||||
type Priority string
|
||||
|
||||
const (
|
||||
// PriorityNormal is the default priority.
|
||||
PriorityNormal Priority = "normal"
|
||||
|
||||
// PriorityHigh indicates an urgent message.
|
||||
PriorityHigh Priority = "high"
|
||||
)
|
||||
|
||||
// Message represents a mail message between agents.
|
||||
type Message struct {
|
||||
// ID is a unique message identifier.
|
||||
ID string `json:"id"`
|
||||
|
||||
// From is the sender address (e.g., "gastown/Toast" or "mayor/").
|
||||
From string `json:"from"`
|
||||
|
||||
// To is the recipient address.
|
||||
To string `json:"to"`
|
||||
|
||||
// Subject is a brief summary.
|
||||
Subject string `json:"subject"`
|
||||
|
||||
// Body is the full message content.
|
||||
Body string `json:"body"`
|
||||
|
||||
// Timestamp is when the message was sent.
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
|
||||
// Read indicates if the message has been read.
|
||||
Read bool `json:"read"`
|
||||
|
||||
// Priority is the message priority.
|
||||
Priority Priority `json:"priority"`
|
||||
}
|
||||
|
||||
// NewMessage creates a new message with a generated ID.
|
||||
func NewMessage(from, to, subject, body string) *Message {
|
||||
return &Message{
|
||||
ID: generateID(),
|
||||
From: from,
|
||||
To: to,
|
||||
Subject: subject,
|
||||
Body: body,
|
||||
Timestamp: time.Now(),
|
||||
Read: false,
|
||||
Priority: PriorityNormal,
|
||||
}
|
||||
}
|
||||
|
||||
// generateID creates a random message ID.
|
||||
func generateID() string {
|
||||
b := make([]byte, 8)
|
||||
rand.Read(b)
|
||||
return "msg-" + hex.EncodeToString(b)
|
||||
}
|
||||
Reference in New Issue
Block a user