fix(rig): improve UX for rig creation (#7)

- Add progress feedback during slow clone operations (30+ seconds)
- Fix README Quick Start to match actual workflow (--git flag, crew add)
- Update install output to use 'gt mayor attach' consistently
- Clarify "Next steps" wording in rig add output

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
jack
2026-01-03 13:54:02 -08:00
committed by Steve Yegge
parent ae6eddbbe7
commit d3e47221ac
4 changed files with 27 additions and 9 deletions

View File

@@ -25,17 +25,27 @@ Multi-agent orchestrator for Claude Code. Track work with convoys; sling to agen
# Install
go install github.com/steveyegge/gastown/cmd/gt@latest
# Create workspace
gt install ~/gt
# Create workspace (--git auto-initializes git repository)
gt install ~/gt --git
cd ~/gt
# Add a project
gt rig add myproject https://github.com/you/repo.git
# Enter the Mayor's office (recommended)
gt mayor attach
# Create your personal workspace
gt crew add <yourname> --rig myproject
# Start working
cd myproject/crew/<yourname>
```
Once inside the Mayor session, you're talking to Claude with full town context. Just tell it what you want:
For advanced multi-agent coordination, use the Mayor session:
```bash
gt mayor attach # Enter the Mayor's office
```
Inside the Mayor session, you're talking to Claude with full town context:
> "Help me fix the authentication bug in myproject"
@@ -78,7 +88,7 @@ The primary Gas Town experience. Agents run in tmux sessions with the Mayor as y
```bash
gt start # Start Gas Town (daemon + Mayor session)
cd ~/gt && gt prime # Enter Mayor session
gt mayor attach # Enter Mayor session
# Inside Mayor session, just ask:
# "Create a convoy for issues 123 and 456 in myproject"

View File

@@ -242,7 +242,7 @@ func runInstall(cmd *cobra.Command, args []string) error {
}
fmt.Printf(" %d. Add a rig: %s\n", step, style.Dim.Render("gt rig add <name> <git-url>"))
step++
fmt.Printf(" %d. Start the Mayor: %s\n", step, style.Dim.Render("cd "+absPath+" && gt prime"))
fmt.Printf(" %d. Enter the Mayor's office: %s\n", step, style.Dim.Render("gt mayor attach"))
return nil
}

View File

@@ -399,8 +399,8 @@ func runRigAdd(cmd *cobra.Command, args []string) error {
fmt.Printf(" └── polecats/\n")
fmt.Printf("\nNext steps:\n")
fmt.Printf(" gt crew add <name> --rig %s # Create your workspace\n", name)
fmt.Printf(" cd %s/crew/<name> # Work in your clone\n", filepath.Join(townRoot, name))
fmt.Printf(" gt crew add <name> --rig %s # Create your personal workspace\n", name)
fmt.Printf(" cd %s/crew/<name> # Start working\n", filepath.Join(townRoot, name))
return nil
}

View File

@@ -266,6 +266,7 @@ func (m *Manager) AddRig(opts AddRigOptions) (*Rig, error) {
// Create shared bare repo as source of truth for refinery and polecats.
// This allows refinery to see polecat branches without pushing to remote.
// Mayor remains a separate clone (doesn't need branch visibility).
fmt.Printf(" Cloning repository (this may take a moment)...\n")
bareRepoPath := filepath.Join(rigPath, ".repo.git")
if localRepo != "" {
if err := m.git.CloneBareWithReference(opts.GitURL, bareRepoPath, localRepo); err != nil {
@@ -280,6 +281,7 @@ func (m *Manager) AddRig(opts AddRigOptions) (*Rig, error) {
return nil, fmt.Errorf("creating bare repo: %w", err)
}
}
fmt.Printf(" ✓ Created shared bare repo\n")
bareGit := git.NewGitWithDir(bareRepoPath, "")
// Detect default branch (main, master, etc.)
@@ -293,6 +295,7 @@ func (m *Manager) AddRig(opts AddRigOptions) (*Rig, error) {
// Create mayor as regular clone (separate from bare repo).
// Mayor doesn't need to see polecat branches - that's refinery's job.
// This also allows mayor to stay on the default branch without conflicting with refinery.
fmt.Printf(" Creating mayor clone...\n")
mayorRigPath := filepath.Join(rigPath, "mayor", "rig")
if err := os.MkdirAll(filepath.Dir(mayorRigPath), 0755); err != nil {
return nil, fmt.Errorf("creating mayor dir: %w", err)
@@ -310,6 +313,7 @@ func (m *Manager) AddRig(opts AddRigOptions) (*Rig, error) {
return nil, fmt.Errorf("cloning for mayor: %w", err)
}
}
fmt.Printf(" ✓ Created mayor clone\n")
// Check if source repo has .beads/ with its own prefix - if so, use that prefix.
// This ensures we use the project's existing beads database instead of creating a new one.
@@ -347,6 +351,7 @@ func (m *Manager) AddRig(opts AddRigOptions) (*Rig, error) {
// Create refinery as worktree from bare repo on default branch.
// Refinery needs to see polecat branches (shared .repo.git) and merges them.
// Being on the default branch allows direct merge workflow.
fmt.Printf(" Creating refinery worktree...\n")
refineryRigPath := filepath.Join(rigPath, "refinery", "rig")
if err := os.MkdirAll(filepath.Dir(refineryRigPath), 0755); err != nil {
return nil, fmt.Errorf("creating refinery dir: %w", err)
@@ -354,6 +359,7 @@ func (m *Manager) AddRig(opts AddRigOptions) (*Rig, error) {
if err := bareGit.WorktreeAddExisting(refineryRigPath, defaultBranch); err != nil {
return nil, fmt.Errorf("creating refinery worktree: %w", err)
}
fmt.Printf(" ✓ Created refinery worktree\n")
// Create refinery CLAUDE.md (overrides any from cloned repo)
if err := m.createRoleCLAUDEmd(refineryRigPath, "refinery", opts.Name, ""); err != nil {
return nil, fmt.Errorf("creating refinery CLAUDE.md: %w", err)
@@ -414,9 +420,11 @@ Use crew for your own workspace. Polecats are for batch work dispatch.
}
// Initialize beads at rig level
fmt.Printf(" Initializing beads database...\n")
if err := m.initBeads(rigPath, opts.BeadsPrefix); err != nil {
return nil, fmt.Errorf("initializing beads: %w", err)
}
fmt.Printf(" ✓ Initialized beads (prefix: %s)\n", opts.BeadsPrefix)
// Create agent beads for this rig (witness, refinery) and
// global agents (deacon, mayor) if this is the first rig.