- Added constants.SupportedShells for consistent shell list
- Updated 7 usages across start.go, crew_lifecycle.go, crew_helpers.go, tmux.go
- All tests pass
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Enhanced the package-level documentation to explain why all write
operations in the keepalive package silently ignore errors.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add PrintWarning helper in internal/style/style.go
- Update 35 warning message outputs across 16 files to use consistent format
- All warnings now display as "⚠ Warning: <message>" in yellow/bold
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Extended the unified cycle system to include rig infrastructure sessions:
- Witness ↔ Refinery (per rig) now cycle with C-b n/p
Also moved SetCycleBindings into ConfigureGasTownSession so ALL Gas Town
sessions automatically get the unified cycle bindings. Removed redundant
individual calls from crew, mayor, and deacon startup code.
Cycle groups are now:
- Town: Mayor ↔ Deacon
- Crew (per rig): All crew members in same rig
- Infra (per rig): Witness ↔ Refinery
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fail fast with clear error when run outside ~/gt instead of
hanging while bd tries to start.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Reduced runStart from 126 lines to 48 lines by extracting:
- startCoreAgents: Mayor and Deacon session startup (28 lines)
- startRigAgents: Witness/Refinery startup for --all flag (37 lines)
- startConfiguredCrew: Auto-start configured crew members (29 lines)
No behavior change - all existing tests pass.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Return *Model from NewModel() so SetEventChannel works
- Use sync.Once for safe channel close on quit
- Use pointer receivers consistently throughout
- Capture channels in closure to prevent race
- Fix indent panic in renderAgent when indent < 2
- Remove unused filterActive and err fields
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Notifications now come immediately after push, before cleanup
- Added STOP HERE warning after push
- Made verification gate more emphatic
- Cleanup happens only after notifications confirmed
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Updated mol-refinery-patrol.formula.toml:
- Added MR bead ID tracking to inbox-check MERGE_READY parsing
- Restructured merge-push into 3 clear steps with REQUIRED callouts
- Added Step 2: MERGED notification (DO NOT SKIP)
- Added Step 3: Close MR bead (DO NOT SKIP)
- Added verification checklist before proceeding
- Added generate-summary verification to catch missed notifications
This ensures refinery agents complete the full lifecycle and trigger
witness cleanup (gt polecat nuke) after merge.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add bubbletea and bubbles dependencies
- Create internal/tui/feed package with:
- model.go: Main bubbletea model with agent tree and event stream
- view.go: Rendering logic with lipgloss styling
- keys.go: Vim-style key bindings (j/k, tab, /, q)
- styles.go: Color palette and component styles
- events.go: Event source from bd activity
- Update gt feed to use TUI by default (--plain for text mode)
- TUI features: agent tree by role, event stream, keyboard nav
Closes gt-be0as, gt-lexye, gt-1uhmj
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The sessionToAgentID function was missing handling for polecat sessions,
causing gt sling to fail to update the agent bead's hook_bead field.
Before: gt-gastown-nux -> gt-gastown-nux (unchanged, no match)
After: gt-gastown-nux -> gastown/polecats/nux (correct format)
This enables updateAgentHookBead to properly convert to the agent bead ID
(gt-polecat-gastown-nux) and update the hook_bead field, which is
required for agents to know they have work on their hook.
Found via E2E test (gt-j0gx2) - nux wasn't picking up slung work because
hook_bead was null despite the task being pinned.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Claude needs ~2 seconds to initialize before it can process nudges.
Without this delay, the initial "Work slung" message would arrive
before Claude was ready, causing the SessionStart hook not to fire.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The loadTasksFromBeads() function was reading 'dependents' from bd show
output, but the actual JSON field is 'dependencies'. This caused swarms
to have empty task lists, requiring manual dispatch.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move duplicated processExists function to shared util package:
- Create internal/util/process.go with ProcessExists function
- Add internal/util/process_test.go with basic tests
- Update witness/manager.go to use util.ProcessExists
- Update refinery/manager.go to use util.ProcessExists
- Remove local processExists functions from both files
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Updated MERGED handling to use gt polecat nuke for full cleanup
(session + worktree + branch + agent bead)
- Added note that session management is polecat-controlled
- Witness only uses recycle for stuck recovery, not routine step transitions
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Create helper functions in internal/session/names.go for consistent
session name construction across Gas Town agents:
- MayorSessionName()
- DeaconSessionName()
- WitnessSessionName(rig)
- RefinerySessionName(rig)
- CrewSessionName(rig, name)
- PolecatSessionName(rig, name)
Includes comprehensive unit tests in names_test.go.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The previous implementation set separate bindings for crew vs town
sessions, but tmux key bindings are global. This meant whichever
session type was started last would overwrite the other's bindings.
New approach:
- Add unified `gt cycle next/prev` command that auto-detects session type
- Town sessions (gt-mayor, gt-deacon) cycle within town group
- Crew sessions (gt-*-crew-*) cycle within their rig's crew
- Other sessions (polecats, witness, refinery) do nothing on cycle
The old SetCrewCycleBindings and SetTownCycleBindings are now aliases
for the unified SetCycleBindings function.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create gt town next/prev commands for cycling between town-level sessions
- Add SetTownCycleBindings() to tmux package
- Wire up bindings when starting mayor and deacon sessions
Now mayor and deacon have the same C-b n/p cycling behavior as crew workers.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Prevents data loss from concurrent/interrupted state file writes by using
atomic write pattern (write to .tmp, then rename).
Changes:
- Add internal/util package with AtomicWriteJSON/AtomicWriteFile helpers
- Update witness/manager.go saveState to use atomic writes
- Update refinery/manager.go saveState to use atomic writes
- Update crew/manager.go saveState to use atomic writes
- Update daemon/types.go SaveState to use atomic writes
- Update polecat/namepool.go Save to use atomic writes
- Add comprehensive tests for atomic write utilities
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds tests to prevent regression of polecat identity bugs:
1. TestInstallCLAUDETemplate: Verifies template is loaded from
mayor/rig/templates/ (not rig root) with correct variable substitution.
2. TestInstallCLAUDETemplateNotAtRigRoot: Verifies templates at the
old buggy location (rig root) are NOT used.
3. TestPolecatCommandFormat: Documents and verifies that polecat sessions
export GT_ROLE=polecat, GT_RIG, GT_POLECAT, BD_ACTOR inline before
starting Claude (because tmux SetEnvironment only affects new panes).
These tests ensure polecats correctly identify as polecats, not mayor.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Two bugs caused polecats to think they were mayor:
1. Template lookup path (gt-si6am):
- Was looking at rig.Path/templates/ which doesn't exist
- Now correctly looks at mayor/rig/templates/
- Polecats get the polecat CLAUDE.md instead of inheriting mayor's
2. Env var export (gt-y41ep):
- tmux SetEnvironment only affects new panes, not current shell
- Now exports GT_ROLE, GT_RIG, GT_POLECAT, BD_ACTOR inline before Claude
- Matches how crew sessions work
Combined effect (gt-9ar8x): Polecats now correctly identify as polecats
and work from their own directory instead of mayor/rig.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implements the nuclear cleanup option for post-merge polecat removal:
- Kills Claude session (force mode)
- Deletes git worktree (bypassing all safety checks)
- Deletes polecat branch
- Closes agent bead
Supports --all for bulk nuke and --dry-run for preview.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements session-preserving polecat recycle:
- Kills Claude session (tmux kill-session)
- Preserves sandbox (worktree and branch intact)
- Updates agent bead state to 'stopped'
- Leaves polecat ready for respawn on next molecule step
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fixed two integration test bugs:
gt-hj0ei: Polecat wrote files outside worktree
- Added CRITICAL directory discipline section at top
- Emphasizes staying in polecats/<name>/ directory
gt-ibuga: Polecat didnt commit before gt done
- Replaced vague completion protocol with explicit checklist
- Uses gt done command instead of manual mail
Created witness-CLAUDE.md template that emphasizes the critical
MERGE_READY step in the pre-kill verification checklist.
The witness must send MERGE_READY to refinery BEFORE killing a polecat
session, so the refinery knows which branch to merge.
Uses {{RIG}} placeholder for rig-specific deployment.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Previously gt done wrote MRs to .beads/mq/*.json files, but gt mq list
queried beads for issue_type=merge-request. These were two different
storage systems, so MRs created by gt done never showed in gt mq list.
Now gt done creates a proper MR bead with:
- issue_type: merge-request
- Description containing branch, target, source_issue, rig, worker
Also updated mq_submit.go for consistency.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add installCLAUDETemplate() to Manager that:
- Reads templates/polecat-CLAUDE.md from rig root
- Substitutes {{rig}} and {{name}} with actual values
- Writes to polecats/<name>/CLAUDE.md
Called from both Add() and Recreate() after worktree creation.
Non-fatal if template is missing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>