feat: add crew directory structure and manager

Add crew/ directory support to rig structure for user-managed
persistent workspaces. Crew workers are separate from polecats
(AI-managed) and can have optional custom BEADS_DIR configuration.

- Add internal/crew package with Worker type and Manager
- Update rig types to include Crew slice and CrewCount in summary
- Update rig manager to scan for crew workers
- Add crew/ to AgentDirs for rig initialization

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Steve Yegge
2025-12-16 20:31:18 -08:00
parent 0c9c3f5563
commit 05f692cc2f
5 changed files with 567 additions and 6 deletions

View File

@@ -94,6 +94,16 @@ func (m *Manager) loadRig(name string, entry config.RigEntry) (*Rig, error) {
}
}
// Scan for crew workers
crewDir := filepath.Join(rigPath, "crew")
if entries, err := os.ReadDir(crewDir); err == nil {
for _, e := range entries {
if e.IsDir() {
rig.Crew = append(rig.Crew, e.Name())
}
}
}
// Check for witness
witnessPath := filepath.Join(rigPath, "witness", "rig")
if _, err := os.Stat(witnessPath); err == nil {

View File

@@ -22,6 +22,10 @@ type Rig struct {
// Polecats is the list of polecat names in this rig.
Polecats []string `json:"polecats,omitempty"`
// Crew is the list of crew worker names in this rig.
// Crew workers are user-managed persistent workspaces.
Crew []string `json:"crew,omitempty"`
// HasWitness indicates if the rig has a witness agent.
HasWitness bool `json:"has_witness"`
@@ -35,6 +39,7 @@ type Rig struct {
// AgentDirs are the standard agent directories in a rig.
var AgentDirs = []string{
"polecats",
"crew",
"refinery/rig",
"witness/rig",
"mayor/rig",
@@ -42,18 +47,20 @@ var AgentDirs = []string{
// RigSummary provides a concise overview of a rig.
type RigSummary struct {
Name string `json:"name"`
Name string `json:"name"`
PolecatCount int `json:"polecat_count"`
HasWitness bool `json:"has_witness"`
HasRefinery bool `json:"has_refinery"`
CrewCount int `json:"crew_count"`
HasWitness bool `json:"has_witness"`
HasRefinery bool `json:"has_refinery"`
}
// Summary returns a RigSummary for this rig.
func (r *Rig) Summary() RigSummary {
return RigSummary{
Name: r.Name,
Name: r.Name,
PolecatCount: len(r.Polecats),
HasWitness: r.HasWitness,
HasRefinery: r.HasRefinery,
CrewCount: len(r.Crew),
HasWitness: r.HasWitness,
HasRefinery: r.HasRefinery,
}
}