feat: Set BD_ACTOR env var when spawning agents (gt-rhfji)

When gt spawns agents (polecats, crew, patrol roles), it now sets the
BD_ACTOR env var so that bd commands (like `bd hook`) know the agent
identity without coupling to gt.

Updated spawn points:
- gt up (mayor, deacon, witness via ensureSession/ensureWitness)
- gt deacon start
- gt witness start
- gt start refinery
- gt mayor start
- Daemon deacon restart
- Daemon lifecycle restart
- Handoff respawn
- Refinery manager start

BD_ACTOR uses slash format (e.g., gastown/witness, gastown/crew/max)
while GT_ROLE may use dash format internally.

🤖 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-25 13:26:38 -08:00
parent 77a43886a3
commit 9afd6c5572
9 changed files with 67 additions and 19 deletions

View File

@@ -262,6 +262,9 @@ func (d *Daemon) restartSession(sessionName, identity string) error {
// Set environment
_ = d.tmux.SetEnvironment(sessionName, "GT_ROLE", identity)
// BD_ACTOR uses slashes instead of dashes for path-like identity
bdActor := identityToBDActor(identity)
_ = d.tmux.SetEnvironment(sessionName, "BD_ACTOR", bdActor)
// Apply theme
if identity == "mayor" {
@@ -427,3 +430,36 @@ func (d *Daemon) identityToStateFile(identity string) string {
return ""
}
}
// identityToBDActor converts a daemon identity (with dashes) to BD_ACTOR format (with slashes).
// Examples:
// - "mayor" → "mayor"
// - "gastown-witness" → "gastown/witness"
// - "gastown-refinery" → "gastown/refinery"
// - "gastown-crew-max" → "gastown/crew/max"
func identityToBDActor(identity string) string {
switch identity {
case "mayor", "deacon":
return identity
default:
// Pattern: <rig>-witness → <rig>/witness
if strings.HasSuffix(identity, "-witness") {
rigName := strings.TrimSuffix(identity, "-witness")
return rigName + "/witness"
}
// Pattern: <rig>-refinery → <rig>/refinery
if strings.HasSuffix(identity, "-refinery") {
rigName := strings.TrimSuffix(identity, "-refinery")
return rigName + "/refinery"
}
// Pattern: <rig>-crew-<name> → <rig>/crew/<name>
if strings.Contains(identity, "-crew-") {
parts := strings.SplitN(identity, "-crew-", 2)
if len(parts) == 2 {
return parts[0] + "/crew/" + parts[1]
}
}
// Unknown format - return as-is
return identity
}
}