Commit Graph

28 Commits

Author SHA1 Message Date
gastown/crew/max
4ef93e1d8a fix(rig): respect parked/docked status in gt up and gt rig start
Previously, `gt up` and `gt rig start` would start witnesses and
refineries for parked/docked rigs, bypassing the operational status
protection. Only the daemon respected the wisp config status.

Now both commands check wisp config status before starting agents:
- `gt up` shows "skipped (rig parked)" for parked/docked rigs
- `gt rig start` warns and skips parked/docked rigs

This prevents accidentally bringing parked/docked rigs back online
when running routine commands.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 00:50:46 -08:00
Keith Wyatt
7d8d96f7f9 perf(up): parallelize all agent startup with concurrency limit (#476)
* perf(up): parallelize agent startup with worker pool and channel-based collection

- Run daemon, deacon, mayor, and rig prefetch all in parallel (4-way concurrent init)
- Use fixed worker pool instead of goroutine-per-task for bounded concurrency
- Replace mutex-protected maps with channel-based result collection (zero lock contention)
- Pre-allocate maps with known capacity to reduce allocations
- Use string concatenation instead of fmt.Sprintf for display names
- Reduce `gt up` startup time from ~50s to ~10s for towns with multiple rigs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(lint): fix errcheck and misspell issues in orphans.go

- Check error return from fmt.Scanln calls
- Fix "Cancelled" -> "Canceled" spelling

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 13:46:50 -08:00
Will Saults
bda248fb9a feat(refinery,boot): add --agent flag for model selection (#469)
* feat(refinery,boot): add --agent flag for model selection (hq-7d5m)

Add --agent flag to gt refinery start/attach/restart and gt boot spawn
commands for consistent model selection across all agent launch points.

Implementation follows the existing pattern from gt deacon start:
- Add StringVar flag for agent alias
- Pass override to Manager/Boot via SetAgentOverride()
- Use BuildAgentStartupCommandWithAgentOverride when override is set

Files affected:
- cmd/gt/refinery.go: add flags to start/attach/restart commands
- internal/refinery/manager.go: add SetAgentOverride and use in Start()
- cmd/gt/boot.go: add flag to spawn command
- internal/boot/boot.go: add SetAgentOverride and use in spawnTmux()

Closes #438

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(refinery,boot): use parameter-passing pattern for --agent flag

Address PR review feedback:

1. ADD TESTS: Add tests for --agent flag existence following witness_test.go pattern
   - internal/cmd/refinery_test.go: tests for start/attach/restart
   - internal/cmd/boot_test.go: test for spawn

2. ALIGN PATTERN: Change from setter pattern to parameter-passing pattern
   - Manager.Start(foreground, agentOverride) instead of SetAgentOverride + Start
   - Boot.Spawn(agentOverride) instead of SetAgentOverride + Spawn
   - Matches witness.go style: Start(foreground bool, agentOverride string, ...)

Updated all callers to pass empty string for default agent:
- internal/daemon/daemon.go
- internal/cmd/rig.go
- internal/cmd/start.go
- internal/cmd/up.go

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: furiosa <will@saults.io>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 13:14:47 -08:00
gastown/crew/gus
86751e1ea5 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>
2026-01-09 22:00:43 -08:00
joshuavial
0d3f6c9654 feat: allow witness restart agent override 2026-01-09 21:56:53 -08:00
joshuavial
85dd150d75 Skip dot dirs when scanning polecats 2026-01-08 22:10:40 +13:00
julianknutsen
c91ab85457 fix: restore agent override support lost in manager refactors
The manager refactors (ea8bef2, 72544cc0) conflicted with the agent
override feature, causing regressions:

Deacon (ea8bef2):
- Lost agentOverride parameter
- Re-added respawn loop (removed in 5f2e16f)
- Lost GUPP (startup + propulsion nudges)

Crew (72544cc0):
- Lost agentOverride wiring to StartOptions
- --agent flag had no effect on crew refresh/restart

This fix restores agent override support and GUPP while keeping
improvements from the manager refactors (zombie detection, etc).

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 21:08:51 -08:00
julianknutsen
ea8bef2029 refactor: unify agent startup with Manager pattern
- Create mayor.Manager for mayor lifecycle (Start/Stop/IsRunning/Status)
- Create deacon.Manager for deacon lifecycle with respawn loop
- Move session.Manager to polecat.SessionManager (clearer naming)
- Add zombie session detection for mayor/deacon (kills tmux if Claude dead)
- Remove duplicate session startup code from up.go, start.go, mayor.go
- Rename sessMgr -> polecatMgr for consistency
- Make witness/refinery SessionName() public for status display

All agent types now follow the same Manager pattern:
  mgr := agent.NewManager(...)
  mgr.Start(...)
  mgr.Stop()
  mgr.IsRunning()
  mgr.Status()

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 22:32:35 -08:00
julianknutsen
72544cc06d Unify agent startup with Manager pattern
Refactors all agent startup paths (witness, refinery, crew, polecat) to use
a consistent Manager interface with Start(), Stop(), IsRunning(), and
SessionName() methods.

Includes:
- Witness manager with GUPP propulsion nudge for startup
- Refinery manager for engineer sessions
- Crew manager for worker agents
- Session/polecat manager updates
- claude_settings_check doctor check for settings validation
- Settings management consolidated from rig/manager.go
- Settings location moved outside source repos to prevent conflicts

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 21:44:04 -08:00
mayor
31a32c084b Unify agent startup with GUPP propulsion nudge
Witness and Refinery startup was duplicated across cmd/witness.go, cmd/up.go,
cmd/rig.go, and daemon.go. Worse, not all code paths sent the propulsion nudge
(GUPP - Gas Town Universal Propulsion Principle). Now unified in Manager.Start()
which handles everything including nudges.

Changes:
- witness/manager.go: Full rewrite with session creation, env vars, theming,
  WaitForClaudeReady, startup nudge, and propulsion nudge (GUPP)
- refinery/manager.go: Add propulsion nudge sequence after Claude startup
- cmd/witness.go: Simplify to just call mgr.Start(), remove ensureWitnessSession
- cmd/rig.go: Use witness.Manager.Start() instead of inline session creation
- cmd/start.go: Use witness.Manager.Start()
- cmd/up.go: Use witness.Manager.Start(), remove ensureWitness(),
  add EnsureSettingsForRole in ensureSession()
- daemon.go: Use witness.Manager.Start() and refinery.Manager.Start() for
  unified startup with proper nudges

This ensures all agent startup paths (gt witness start, gt rig boot, gt up,
daemon restarts) consistently apply GUPP propulsion nudges.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 01:51:25 -08:00
max
1b69576573 fix: Address golangci-lint errors (errcheck, gosec) (#76)
Apply PR #76 from dannomayernotabot:

- Add golangci exclusions for internal package false positives
- Tighten file permissions (0644 -> 0600) for sensitive files
- Add ReadHeaderTimeout to HTTP server (slowloris prevention)
- Explicit error ignoring with _ = for intentional cases
- Add //nolint comments with justifications
- Spelling: cancelled -> canceled (US locale)

Co-Authored-By: dannomayernotabot <noreply@github.com>

🤖 Generated with Claude Code
2026-01-03 16:11:55 -08:00
markov-kernel
e7145cfd77 fix: Make Mayor/Deacon session names include town name
Session names `gt-mayor` and `gt-deacon` were hardcoded, causing tmux
session name collisions when running multiple towns simultaneously.

Changed to `gt-{town}-mayor` and `gt-{town}-deacon` format (e.g.,
`gt-ai-mayor`) to allow concurrent multi-town operation.

Key changes:
- session.MayorSessionName() and DeaconSessionName() now take townName param
- Added workspace.GetTownName() helper to load town name from config
- Updated all callers in cmd/, daemon/, doctor/, mail/, rig/, templates/
- Updated tests with new session name format
- Bead IDs remain unchanged (already scoped by .beads/ directory)

Fixes #60

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 21:37:05 +01:00
kustrun
94857fc913 fix(session): Auto-accept Claude bypass permissions warning dialog
When Claude starts with --dangerously-skip-permissions, it shows a warning
dialog requiring Down+Enter to accept. This blocked automated polecat and
agent startup.

Added AcceptBypassPermissionsWarning() to tmux package that:
- Checks if the warning dialog is present by capturing pane content
- Only sends Down+Enter if "Bypass Permissions mode" text is found
- Avoids interfering with sessions that don't show the warning

Updated all Claude startup locations:
- session/manager.go (polecat sessions)
- cmd/up.go (mayor, witness, crew, polecat cold starts)
- daemon/daemon.go (crashed polecat restarts)
- daemon/lifecycle.go (role session starts)
2026-01-02 22:44:58 +01:00
gastown/crew/gus
b7c26d52e1 Migrate startup paths from SessionBeacon to StartupNudge (gt-7pp3l)
All 12 startup paths now use session.StartupNudge instead of the
older SessionBeacon pattern. The key difference is that StartupNudge
includes sender information, enabling better predecessor discovery
via gt seance.

Files updated:
- crew_lifecycle.go: 3 locations (refresh, restart)
- start.go: 2 locations (crew start)
- deacon.go: 1 location (deacon start)
- witness.go: 1 location (witness start)
- up.go: 4 locations (mayor, witness, crew, polecat)
- mayor.go: 1 location (mayor start)
- session/manager.go: 1 location (polecat spawn)

Format change:
Old: [GAS TOWN] address • molID • timestamp
New: [GAS TOWN] recipient <- sender • timestamp • topic[:mol-id]

This completes the Agent Startup Consolidation epic (gt-85whr).

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 11:52:46 -08:00
gastown/crew/gus
626a24e013 Refactor startup paths to use RuntimeConfig (gt-j0546)
Replaced all hardcoded 'claude --dangerously-skip-permissions' invocations
with configurable helpers from internal/config:

- GetRuntimeCommand(rigPath) - simple command string
- GetRuntimeCommandWithPrompt(rigPath, prompt) - with initial prompt
- BuildAgentStartupCommand(role, bdActor, rigPath, prompt) - generic agent
- BuildPolecatStartupCommand(rigName, polecatName, rigPath, prompt) - polecat
- BuildCrewStartupCommand(rigName, crewName, rigPath, prompt) - crew
- BuildStartupCommand(envVars, rigPath, prompt) - custom env vars

Files updated:
- internal/cmd/start.go (4 locations)
- internal/cmd/crew_lifecycle.go (2 locations)
- internal/cmd/crew_at.go (2 locations)
- internal/cmd/deacon.go
- internal/cmd/witness.go
- internal/cmd/up.go (2 locations)
- internal/cmd/handoff.go (2 locations)
- internal/daemon/daemon.go (3 locations)
- internal/daemon/lifecycle.go
- internal/session/manager.go
- internal/refinery/manager.go
- internal/boot/boot.go

This enables future support for alternative LLM runtimes (aider, etc.)
via rig/town settings configuration.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 23:48:34 -08:00
gastown/polecats/dementus
59ffb3cc58 Add runtime configuration for LLM commands (gt-dc2fs)
Add RuntimeConfig type to RigSettings allowing per-rig LLM runtime
configuration. This moves hardcoded "claude --dangerously-skip-permissions"
invocations to configurable settings.

Changes:
- Add RuntimeConfig type with Command, Args, InitialPrompt fields
- Add BuildCommand() and BuildCommandWithPrompt() methods
- Add helper functions: LoadRuntimeConfig, BuildAgentStartupCommand,
  BuildPolecatStartupCommand, BuildCrewStartupCommand
- Update startup paths in up.go and mayor.go to use new config
- Add comprehensive tests for RuntimeConfig functionality

Remaining hardcoded invocations can be updated incrementally.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 23:09:03 -08:00
Steve Yegge
66042da18b Add session beacon for predecessor discovery via /resume
Inject an identity beacon as the first message when Gas Town starts Claude
sessions. This beacon becomes the session title in Claude Code '/resume
picker, enabling workers to find their predecessor sessions for debugging.

Beacon format: [GAS TOWN] <address> • <mol-id or "ready"> • <timestamp>

Examples:
- [GAS TOWN] gastown/crew/max • gt-abc12 • 2025-12-30T14:32
- [GAS TOWN] gastown/polecats/Toast • ready • 2025-12-30T09:15
- [GAS TOWN] deacon • patrol • 2025-12-30T08:00

Workers can now press / in /resume picker and search for their address
(e.g., "gastown/crew/max") to see all predecessor sessions.

Note: Respawn-loop agents (deacon/refinery via up.go) skip beacon injection
since Claude restarts multiple times - would need post-restart injection.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 18:01:47 -08:00
Steve Yegge
3099d99424 Set GIT_AUTHOR_NAME per agent session (gt-6r18e.1)
Export GIT_AUTHOR_NAME alongside BD_ACTOR in all agent session startup
locations. This enables git log --author queries for agent work while
keeping GIT_AUTHOR_EMAIL as the workspace owner.

Files updated:
- internal/session/manager.go (polecat sessions)
- internal/daemon/daemon.go (deacon, witness, polecat via daemon)
- internal/daemon/lifecycle.go (polecat lifecycle)
- internal/cmd/*.go (crew, mayor, deacon, witness, refinery, up, handoff)
- internal/session/manager_test.go (updated test expectations)
- docs/federation.md (marked feature as implemented)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 16:14:33 -08:00
Steve Yegge
907eba7194 Instrument gt commands to emit events to activity feed (gt-7aw1m)
Add events.LogFeed calls to the following gt commands:
- nudge.go: Log TypeNudge events when nudging agents
- unsling.go: Log TypeUnhook events when removing work from hooks
- up.go: Log TypeBoot events when starting Gas Town services
- down.go: Log TypeHalt events when stopping Gas Town services
- stop.go: Log TypeKill events when stopping polecat sessions
- polecat_spawn.go: Log TypeSpawn events when spawning polecats

Also add helper functions to events package:
- UnhookPayload: Creates payload for unhook events
- KillPayload: Creates payload for kill events
- HaltPayload: Creates payload for halt events

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 10:43:34 -08:00
Steve Yegge
212d818305 fix: Capture stderr instead of suppressing in command execution
Several files were setting cmd.Stderr = nil, which hides potentially
critical error messages:

- prime.go: bd prime, gt mail check, and bd show commands now log
  stderr on failure for debugging
- orphans.go: git fsck now includes stderr in error messages
- patrol_helpers.go: bd list/show/catalog commands now log stderr

Daemon launch cases (up.go, daemon.go, daemon_check.go) correctly
use nil for I/O detachment but now have clarifying comments.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 00:52:02 -08:00
Steve Yegge
1a1ab4842b Eradicate hook files, use pinned beads only (gt-rgd9x)
- Remove hook functions from internal/wisp/io.go (WriteSlungWork, ReadHook, BurnHook, etc.)
- Remove hook types from internal/wisp/types.go (SlungWork, Wisp, etc.)
- Update up.go to query pinned beads instead of reading hook files
- Remove SlungWork field from molecule_status.go
- Remove hook-*.json pattern from .beads/.gitignore
- Delete live hook file /Users/stevey/gt/deacon/.beads/hook-deacon.json

Work is now tracked exclusively via pinned beads (status=pinned, assignee=agent).

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 16:46:39 -08:00
Steve Yegge
efb2afbcca Add gt up --restore for crew and polecat restoration
Features:
- Add CrewConfig to RigSettings (settings/config.json)
- Add --restore flag to gt up
- Crew startup from natural language preferences (e.g., 'max', 'joe and max', 'all')
- Polecat restoration from hook files (work attached)

Example rig settings:
  {"crew": {"startup": "max"}}

Usage:
  gt up --restore

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 23:18:46 -08:00
Steve Yegge
34b5a3bb8d Document intentional error suppressions with comments (gt-zn9m)
All 156 instances of _ = error suppression in non-test code now have
explanatory comments documenting why the error is intentionally ignored.

Categories of intentional suppressions:
- non-fatal: session works without these - tmux environment setup
- non-fatal: theming failure does not affect operation - visual styling
- best-effort cleanup - defer cleanup on failure paths
- best-effort notification - mail/notifications that should not block
- best-effort interrupt - graceful shutdown attempts
- crypto/rand.Read only fails on broken system - random ID generation
- output errors non-actionable - fmt.Fprint to io.Writer

This addresses the silent failure and debugging concerns raised in the
issue by making the intentionality explicit in the code.

Generated with Claude Code https://claude.com/claude-code

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 23:14:29 -08:00
Steve Yegge
9afd6c5572 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>
2025-12-25 13:26:38 -08:00
Steve Yegge
f86a73c2f0 feat: Add gcloud-style command grouping to gt help output
Organize 43 commands into 7 logical groups using cobra's built-in
AddGroup/GroupID feature:

- Work Management: spawn, sling, hook, handoff, done, mol, mq, etc.
- Agent Management: mayor, witness, refinery, deacon, polecat, etc.
- Communication: mail, nudge, broadcast, peek
- Services: daemon, start, stop, up, down, shutdown
- Workspace: rig, crew, init, install, git-init, namepool
- Configuration: account, theme, hooks, issue, completion
- Diagnostics: status, doctor, prime, version, help

Also renamed molecule to mol as the primary command name
(molecule is now an alias).

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 02:32:01 -08:00
Steve Yegge
0a135b2cd3 Add refineries to gt up boot sequence 2025-12-22 20:19:33 -08:00
Steve Yegge
5d7291962a Rename ephemeral -> wisp terminology throughout Gas Town
- .beads-ephemeral/ -> .beads-wisp/
- Rename doctor checks: EphemeralCheck -> WispCheck
- Update all docs to use 'transient' for polecats, 'wisp' for molecules
- Preserve 'ephemeral' only as descriptive adjective for wisps
- Steam engine metaphor: wisps are steam vapors that dissipate

Part of Christmas launch wisp terminology unification.
2025-12-22 00:55:31 -08:00
Steve Yegge
da12531d3d feat: add gt up/down commands and daemon doctor check
New commands:
- `gt up` - Idempotent boot command that brings up all services:
  Daemon, Deacon, Mayor, and Witnesses for all rigs
- `gt down` - Graceful shutdown of all services

Doctor improvements:
- New daemon check verifies daemon is running
- Fixable with `gt doctor --fix` to auto-start daemon

The system can run degraded (any services down) but `gt up` ensures
a fully operational Gas Town with one idempotent command.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-20 02:26:09 -08:00