When run from inside a crew directory like gastown/crew/joe, the command
now auto-detects the crew workspace name instead of requiring it as an
argument. This matches the existing behavior of 'gt crew at'.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
All agent bead creation now uses shared role beads:
- gt-mayor-role, gt-deacon-role
- gt-witness-role, gt-refinery-role
- gt-crew-role, gt-polecat-role
Previous code created per-instance role bead references like
gt-witness-gastown-role which is wrong. Role beads are shared
class definitions, not per-instance.
Files fixed:
- internal/rig/manager.go
- internal/doctor/agent_beads_check.go
- internal/cmd/prime.go
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
crew_add.go: Use gt-crew-role instead of per-instance role bead
polecat/manager.go: Add RoleBead field pointing to gt-polecat-role
Per agent-as-bead design, role beads are shared class definitions.
Each agent bead references its role via the role_bead field/slot.
Fixes gt-ne9he
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace .runtime/swarms.json with beads-backed swarm tracking:
- gt swarm create: calls bd create --type=epic --mol-type=swarm
- gt swarm status: calls bd swarm status
- gt swarm list: calls bd list --mol-type=swarm --type=epic
- gt swarm start: uses bd swarm status to find ready tasks
- gt swarm land: checks completion via bd, closes epic
- gt swarm cancel: closes epic with cancelled reason
Removed:
- SwarmStore type and LoadSwarmStore/Save functions
- Old spawnSwarmWorkers (replaced with spawnSwarmWorkersFromBeads)
- Unused helper functions (stateStyle, taskStateIcon, matchesStatus)
This implements "discovery over tracking" principle from swarm-architecture.md:
swarm state is now derived from beads epic/issue statuses rather than
maintaining separate state in .runtime/swarms.json.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Show unread mail count and first message subject for each agent
- Display format: "mail: 📬 N unread → Subject..."
- Only shows mail line when agent has unread messages
- Fix agent bead ID generation for global agents (mayor/, deacon/)
Example output:
🏭 Refinery
gt-refinery-gastown running
hook: refinery Handoff
mail: 📬 8 unread → MERGE_READY morsov
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Show full agent bead ID for each agent (e.g., gt-crew-gastown-joe)
- Display hook/pinned work with bead ID and title
- Use role icons and section separators for clarity
- Fall back to hooks array when agent bead lacks hook_bead field
Example output:
🎩 Mayor
gt-mayor running
hook: (none)
─── gastown/ ───────────────────────
🏭 Refinery
gt-refinery-gastown running
hook: refinery Handoff
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use tree characters (├── └── │) for hierarchical display
- Group agents by role type (Witness, Refinery, Crew, Polecats)
- Add role icons (🎩 Mayor, 🔔 Deacon, 👁 Witness, 🏭 Refinery, 👷 Crew, 😺 Polecats)
- Show pinned work inline with truncation
- Fix unused import in polecat/manager.go
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Inverse of 'gt rig shutdown'. Starts rig patrol agents:
- Checks tmux sessions to avoid duplicates
- Starts witness if not running
- Starts refinery if not running
- Reports what was started vs skipped
Also adds ProcessExists util function needed by witness/refinery managers.
- polecat.go: Remove unreachable first loop in splitLines (was using filepath.SplitList incorrectly)
- townlog/logger.go: Remove unused Event.JSON() method and json import
- lock/lock.go: Remove unused ErrStaleLock error variable
- refinery/manager.go: Remove unused getTestCommand() method
Note: witness.StatePaused is actually used by cmd/witness.go, not dead code.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 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>
- 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>
Instead of Go code checking git state to decide if polecat removal is safe,
the polecat now self-reports its cleanup_status via its agent bead.
Changes:
- Add CleanupStatus field to AgentFields struct
- Update FormatAgentDescription and ParseAgentFields for cleanup_status
- Add UpdateAgentCleanupStatus function to beads package
- Update gt done to compute and report git cleanup status
- Update RemoveWithOptions to read cleanup_status from agent bead first,
falling back to git check for backward compatibility
Valid cleanup_status values:
- clean: no uncommitted work
- has_uncommitted: has uncommitted changes
- has_stash: has stashed changes
- has_unpushed: has unpushed commits
- unknown: git check failed
This follows ZFC (Zero Figuring in Code) principles - the polecat is the
authority on its own state, not Go code inferring it from external signals.
🤖 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>
- 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>
Create AgentIdentity type to parse and construct session names, replacing
duplicated logic in sling.go and handoff.go.
- Add internal/session/identity.go with AgentIdentity type
- ParseSessionName handles: mayor, deacon, witness, refinery, crew, polecat
- SessionName() reconstructs valid tmux session name
- Address() returns mail-style address (e.g., "gastown/crew/max")
- GTRole() returns GT_ROLE env var format
- Update sling.go:sessionToAgentID to use ParseSessionName
- Update handoff.go:sessionToGTRole to use ParseSessionName
- Add comprehensive unit tests with round-trip verification
🤖 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 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>
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 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>
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>
- doctor/agent_beads_check.go: Check and create agent beads for all crew workers
- New listCrewWorkers() helper finds crew directories in each rig
- Run() checks for missing crew agent beads
- Fix() creates missing crew agent beads with proper fields
- cmd/crew_add.go: Create agent bead when adding a crew worker
- Creates gt-crew-<rig>-<name> agent bead after workspace creation
- Non-fatal if bead creation fails (warns but continues)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Strip (gt-xxx), (bd-xxx) suffixes from code comments. The descriptions
remain meaningful without the ephemeral issue IDs.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 2: Adds dedicated tmux window support:
- gt feed --window creates 'feed' window in current session
- If window exists, switches to it (idempotent)
- Always uses --follow mode in window (persistent stream)
- Error handling for non-tmux environments
Users can now C-b n/p to cycle to/from the activity feed.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changes:
1. prime.go: Create agent beads on first prime for all roles including crew
2. done.go: Update agent state to done/stuck/idle when work completes
3. sling.go: Populate hook_bead when work is assigned to agents
4. mol-witness-patrol.formula.toml: Document dead and spawning states
Closes: gt-hymm0, gt-0lop3, gt-59k2x, gt-c4j4j
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Wraps bd activity with Gas Town integration:
- Default follow mode for streaming
- --rig flag to target specific rig beads
- Passthrough of bd activity flags (--since, --mol, --type, --limit)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add HookBead and State fields to AgentRuntime struct
- discoverGlobalAgents and discoverRigAgents now look up agent beads
- Display hook_bead ID and work title in status output
- Show agent_state when not idle
- Fall back to legacy Hooks array for rig agents without agent beads
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changes:
1. Fix reportAgentState in prime.go to use beads API directly instead of
non-existent `bd agent state` command. Agents now properly self-report
their state to their agent beads on startup.
2. Update witness patrol survey-workers step to use agent beads:
- List polecats via `bd list --type=agent --json`
- Filter by role_type: polecat in description
- Check agent_state field (running/idle/stuck/done)
- Trust agent-reported state (ZFC principle)
No more PID/tmux inference for polecat state - agents self-report.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
gt rig add now creates .claude/settings.json with patrol hooks for:
- witness/ directory (SessionStart, PreCompact, UserPromptSubmit hooks)
- refinery/ directory (same hooks)
gt deacon start also creates hooks if not present (idempotent).
These hooks run `gt prime && gt mail check --inject` on session start,
enabling autonomous patrol execution when daemon sends heartbeats.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Bootstrap now creates agent beads for ZFC compliance:
- Always: <prefix>-witness-<rig>, <prefix>-refinery-<rig>
- First rig only: <prefix>-deacon, <prefix>-mayor
Agent beads are created in the rig's beads database (not town beads)
because the daemon looks up beads by prefix routing.
Changes:
- internal/rig/manager.go: Added initAgentBeads() function
- internal/cmd/install.go: Added comment explaining why beads aren't
created here (no rig exists yet at install time)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add AgentFields and ParseAgentFieldsFromDescription to internal/beads/fields.go
- Update daemon/lifecycle.go to use shared parsing
- Update cmd/molecule_status.go to use shared parsing
- Remove duplicate parsing code and unused isAgentRunningByBead function
This consolidates agent bead field parsing in one place, following the pattern
established for AttachmentFields and MRFields.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This change migrates gt mol status from querying by pinned status + assignee
to reading the hook_bead field from agent beads.
Changes:
- Add AgentBeadFields struct to parse agent bead description fields
- Add buildAgentBeadID function to convert identity to agent bead ID
- Update runMoleculeStatus to:
1. First try to find the agent bead by ID
2. Read hook_bead from agent bead description
3. If hook_bead is set, fetch and display that bead
4. Fall back to legacy pinned-query approach if no agent bead or hook
The implementation is backwards compatible - agents without agent beads
(like polecats before gt-rxa7v is completed) still work via the fallback.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds a new fixable doctor check that verifies beads routing configuration:
- Checks if routes.jsonl exists
- Verifies all rigs have routing entries (by path, not just prefix)
- Validates that routes point to valid locations with .beads directories
- Can auto-fix by adding missing routes with --fix
The check is smart about prefix mismatches: if a rig already has a route
by path (e.g., gastown/mayor/rig), it won't report it as missing even if
the prefix in rigs.json differs from what's in routes.jsonl.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When mayor/deacon checks their hook from ~/gt, gt mol status now scans all
registered rigs for pinned beads. This ensures the propulsion principle works
regardless of which directory the agent starts in.
The scan uses routes.jsonl to find all rig beads directories.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>