Instrument gt commands to appear in activity feed (gt-7aw1m)

Phase 1 of activity feed improvements: gt commands now log events to
~/gt/.events.jsonl. This is the raw audit log that the feed daemon
(phase 2) will curate into the user-facing feed.

Instrumented commands:
- gt sling: logs sling events with bead and target
- gt hook: logs hook events with bead
- gt handoff: logs handoff events with subject
- gt done: logs done events with bead and branch
- gt mail send: logs mail events with to and subject

Event format follows the specification:
```json
{"ts":"2025-12-30T07:36:28Z","source":"gt","type":"mail",
 "actor":"gastown/crew/joe","payload":{...},"visibility":"feed"}
```

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Steve Yegge
2025-12-29 23:37:50 -08:00
parent fcea70efa1
commit 2844edb541
6 changed files with 209 additions and 2 deletions

View File

@@ -7,6 +7,7 @@ import (
"github.com/spf13/cobra"
"github.com/steveyegge/gastown/internal/beads"
"github.com/steveyegge/gastown/internal/events"
"github.com/steveyegge/gastown/internal/git"
"github.com/steveyegge/gastown/internal/mail"
"github.com/steveyegge/gastown/internal/style"
@@ -213,8 +214,9 @@ func runDone(cmd *cobra.Command, args []string) error {
fmt.Printf("%s Witness notified of %s\n", style.Bold.Render("✓"), exitType)
}
// Log done event
// Log done event (townlog and activity feed)
LogDone(townRoot, sender, issueID)
_ = events.LogFeed(events.TypeDone, sender, events.DonePayload(issueID, branch))
// Update agent bead state (ZFC: self-report completion)
updateAgentStateOnDone(cwd, townRoot, exitType, issueID)

View File

@@ -8,6 +8,7 @@ import (
"strings"
"github.com/spf13/cobra"
"github.com/steveyegge/gastown/internal/events"
"github.com/steveyegge/gastown/internal/session"
"github.com/steveyegge/gastown/internal/style"
"github.com/steveyegge/gastown/internal/tmux"
@@ -127,13 +128,15 @@ func runHandoff(cmd *cobra.Command, args []string) error {
// Handing off ourselves - print feedback then respawn
fmt.Printf("%s Handing off %s...\n", style.Bold.Render("🤝"), currentSession)
// Log handoff event
// Log handoff event (both townlog and events feed)
if townRoot, err := workspace.FindFromCwd(); err == nil && townRoot != "" {
agent := sessionToGTRole(currentSession)
if agent == "" {
agent = currentSession
}
LogHandoff(townRoot, agent, handoffSubject)
// Also log to activity feed
_ = events.LogFeed(events.TypeHandoff, agent, events.HandoffPayload(handoffSubject, true))
}
// Dry run mode - show what would happen (BEFORE any side effects)

View File

@@ -7,6 +7,7 @@ import (
"github.com/spf13/cobra"
"github.com/steveyegge/gastown/internal/beads"
"github.com/steveyegge/gastown/internal/events"
"github.com/steveyegge/gastown/internal/style"
)
@@ -164,6 +165,9 @@ func runHook(cmd *cobra.Command, args []string) error {
fmt.Printf(" Use 'gt handoff' to restart with this work\n")
fmt.Printf(" Use 'gt mol status' to see hook status\n")
// Log hook event to activity feed
_ = events.LogFeed(events.TypeHook, agentID, events.HookPayload(beadID))
return nil
}

View File

@@ -10,6 +10,7 @@ import (
"strings"
"github.com/spf13/cobra"
"github.com/steveyegge/gastown/internal/events"
"github.com/steveyegge/gastown/internal/mail"
"github.com/steveyegge/gastown/internal/style"
"github.com/steveyegge/gastown/internal/workspace"
@@ -384,6 +385,9 @@ func runMailSend(cmd *cobra.Command, args []string) error {
return fmt.Errorf("sending message: %w", err)
}
// Log mail event to activity feed
_ = events.LogFeed(events.TypeMail, from, events.MailPayload(to, mailSubject))
fmt.Printf("%s Message sent to %s\n", style.Bold.Render("✓"), to)
fmt.Printf(" Subject: %s\n", mailSubject)
if len(msg.CC) > 0 {

View File

@@ -9,6 +9,7 @@ import (
"github.com/spf13/cobra"
"github.com/steveyegge/gastown/internal/beads"
"github.com/steveyegge/gastown/internal/events"
"github.com/steveyegge/gastown/internal/session"
"github.com/steveyegge/gastown/internal/style"
"github.com/steveyegge/gastown/internal/tmux"
@@ -330,6 +331,10 @@ func runSling(cmd *cobra.Command, args []string) error {
fmt.Printf("%s Work attached to hook (status=hooked)\n", style.Bold.Render("✓"))
// Log sling event to activity feed
actor := detectActor()
_ = events.LogFeed(events.TypeSling, actor, events.SlingPayload(beadID, targetAgent))
// Update agent bead's hook_bead field (ZFC: agents track their current work)
updateAgentHookBead(targetAgent, beadID)
@@ -688,6 +693,12 @@ func runSlingFormula(args []string) error {
}
fmt.Printf("%s Attached to hook (status=hooked)\n", style.Bold.Render("✓"))
// Log sling event to activity feed (formula slinging)
actor := detectActor()
payload := events.SlingPayload(wispResult.RootID, targetAgent)
payload["formula"] = formulaName
_ = events.LogFeed(events.TypeSling, actor, payload)
// Update agent bead's hook_bead field (ZFC: agents track their current work)
updateAgentHookBead(targetAgent, wispResult.RootID)
@@ -768,6 +779,15 @@ func wakeRigAgents(rigName string) {
_ = t.NudgeSession(refinerySession, "Polecat dispatched - check for merge requests")
}
// detectActor returns the current agent's actor string for event logging.
func detectActor() string {
roleInfo, err := GetRole()
if err != nil {
return "unknown"
}
return roleInfo.ActorString()
}
// agentIDToBeadID converts an agent ID to its corresponding agent bead ID.
// Uses canonical naming: prefix-rig-role-name
func agentIDToBeadID(agentID string) string {