feat(witness): add --env flag for environment variable overrides

Extends the --agent flag with a more general --env flag that allows
setting arbitrary environment variables when starting a witness.

Precedence (highest to lowest):
1. CLI --env overrides
2. Role bead env_vars
3. config.AgentEnv() defaults

Examples:
  gt witness start greenplace --env ANTHROPIC_MODEL=claude-3-haiku
  gt witness restart greenplace --env DEBUG=1 --env VERBOSE=true

Co-authored-by: joshuavial <git@codewithjv.com>
This commit is contained in:
gastown/crew/gus
2026-01-09 22:00:43 -08:00
committed by Steve Yegge
parent f9473c7b9e
commit 86751e1ea5
6 changed files with 36 additions and 24 deletions

View File

@@ -5,6 +5,7 @@ import (
"fmt"
"os"
"path/filepath"
"strings"
"time"
"github.com/steveyegge/gastown/internal/agent"
@@ -101,7 +102,8 @@ func (m *Manager) witnessDir() string {
// If foreground is true, only updates state (no tmux session - deprecated).
// Otherwise, spawns a Claude agent in a tmux session.
// agentOverride optionally specifies a different agent alias to use.
func (m *Manager) Start(foreground bool, agentOverride string) error {
// envOverrides are KEY=VALUE pairs that override all other env var sources.
func (m *Manager) Start(foreground bool, agentOverride string, envOverrides []string) error {
w, err := m.loadState()
if err != nil {
return err
@@ -159,19 +161,6 @@ func (m *Manager) Start(foreground bool, agentOverride string) error {
return fmt.Errorf("creating tmux session: %w", err)
}
// Set environment variables (non-fatal: session works without these)
// Use centralized AgentEnv for consistency across all role startup paths
townRoot := filepath.Dir(m.rig.Path)
envVars := config.AgentEnv(config.AgentEnvConfig{
Role: "witness",
Rig: m.rig.Name,
TownRoot: townRoot,
BeadsDir: beads.ResolveBeadsDir(m.rig.Path),
})
for k, v := range envVars {
_ = t.SetEnvironment(sessionID, k, v)
}
// Apply Gas Town theming (non-fatal: theming failure doesn't affect operation)
theme := tmux.AssignTheme(m.rig.Name)
_ = t.ConfigureGasTownSession(sessionID, theme, m.rig.Name, "witness", "witness")
@@ -183,10 +172,28 @@ func (m *Manager) Start(foreground bool, agentOverride string) error {
}
townRoot := m.townRoot()
// Set environment variables (non-fatal: session works without these)
// Use centralized AgentEnv for consistency across all role startup paths
envVars := config.AgentEnv(config.AgentEnvConfig{
Role: "witness",
Rig: m.rig.Name,
TownRoot: townRoot,
BeadsDir: beads.ResolveBeadsDir(m.rig.Path),
})
for k, v := range envVars {
_ = t.SetEnvironment(sessionID, k, v)
}
// Apply role config env vars if present (non-fatal).
for key, value := range roleConfigEnvVars(roleConfig, townRoot, m.rig.Name) {
_ = t.SetEnvironment(sessionID, key, value)
}
// Apply CLI env overrides (highest priority, non-fatal).
for _, override := range envOverrides {
if key, value, ok := strings.Cut(override, "="); ok {
_ = t.SetEnvironment(sessionID, key, value)
}
}
// Update state to running
now := time.Now()