refactor: move mol run semantics from bd into gt spawn (gt-r7jj2)

Replace bd mol run call with separate bd commands:
1. bd pour - creates issues from proto template
2. bd update --status=in_progress - claims work
3. bd pin - pins root for session recovery

This moves orchestration logic into gt (where it belongs) and keeps
bd as pure data operations. Coordinated with bd-00u3 which deprecates
bd mol run.

🤖 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-25 01:05:06 -08:00
parent ac3371f9ae
commit e8db866ddb

View File

@@ -259,54 +259,68 @@ func runSpawn(cmd *cobra.Command, args []string) error {
// Handle molecule instantiation if specified // Handle molecule instantiation if specified
if spawnMolecule != "" { if spawnMolecule != "" {
// Use bd mol run to create the molecule - this handles everything: // Molecule instantiation uses three separate bd commands:
// - Creates child issues from proto template // 1. bd pour - creates issues from proto template
// - Assigns root to polecat // 2. bd update - sets status to in_progress (claims work)
// - Sets root status to in_progress // 3. bd pin - pins root for session recovery
// - Pins root for session recovery // This keeps bd as pure data operations and gt as orchestration.
fmt.Printf("Running molecule %s on %s...\n", spawnMolecule, spawnIssue) fmt.Printf("Running molecule %s on %s...\n", spawnMolecule, spawnIssue)
cmd := exec.Command("bd", "--no-daemon", "mol", "run", spawnMolecule, // Step 1: Pour the molecule (create issues from template)
pourCmd := exec.Command("bd", "--no-daemon", "pour", spawnMolecule,
"--var", "issue="+spawnIssue, "--json") "--var", "issue="+spawnIssue, "--json")
cmd.Dir = beadsPath pourCmd.Dir = beadsPath
var stdout, stderr bytes.Buffer var pourStdout, pourStderr bytes.Buffer
cmd.Stdout = &stdout pourCmd.Stdout = &pourStdout
cmd.Stderr = &stderr pourCmd.Stderr = &pourStderr
if err := cmd.Run(); err != nil { if err := pourCmd.Run(); err != nil {
errMsg := strings.TrimSpace(stderr.String()) errMsg := strings.TrimSpace(pourStderr.String())
if errMsg != "" { if errMsg != "" {
return fmt.Errorf("running molecule: %s", errMsg) return fmt.Errorf("pouring molecule: %s", errMsg)
} }
return fmt.Errorf("running molecule: %w", err) return fmt.Errorf("pouring molecule: %w", err)
} }
// Parse mol run output // Parse pour output to get root ID
var molResult struct { var pourResult struct {
RootID string `json:"root_id"` NewEpicID string `json:"new_epic_id"`
IDMapping map[string]string `json:"id_mapping"` IDMapping map[string]string `json:"id_mapping"`
Created int `json:"created"` Created int `json:"created"`
Assignee string `json:"assignee"`
Pinned bool `json:"pinned"`
} }
if err := json.Unmarshal(stdout.Bytes(), &molResult); err != nil { if err := json.Unmarshal(pourStdout.Bytes(), &pourResult); err != nil {
return fmt.Errorf("parsing molecule result: %w", err) return fmt.Errorf("parsing pour result: %w", err)
} }
fmt.Printf("%s Molecule created: %s (%d steps)\n", rootID := pourResult.NewEpicID
style.Bold.Render("✓"), molResult.RootID, molResult.Created-1) // -1 for root fmt.Printf("%s Molecule poured: %s (%d steps)\n",
style.Bold.Render("✓"), rootID, pourResult.Created-1) // -1 for root
// Step 2: Set status to in_progress (claim work)
updateCmd := exec.Command("bd", "--no-daemon", "update", rootID, "--status=in_progress")
updateCmd.Dir = beadsPath
if err := updateCmd.Run(); err != nil {
return fmt.Errorf("setting molecule status: %w", err)
}
// Step 3: Pin the root for session recovery
pinCmd := exec.Command("bd", "--no-daemon", "pin", rootID)
pinCmd.Dir = beadsPath
if err := pinCmd.Run(); err != nil {
return fmt.Errorf("pinning molecule: %w", err)
}
// Build molecule context for work assignment // Build molecule context for work assignment
moleculeCtx = &MoleculeContext{ moleculeCtx = &MoleculeContext{
MoleculeID: spawnMolecule, MoleculeID: spawnMolecule,
RootIssueID: molResult.RootID, RootIssueID: rootID,
TotalSteps: molResult.Created - 1, // -1 for root TotalSteps: pourResult.Created - 1, // -1 for root
StepNumber: 1, // Starting on first step StepNumber: 1, // Starting on first step
} }
// Update spawnIssue to be the molecule root (for assignment tracking) // Update spawnIssue to be the molecule root (for assignment tracking)
spawnIssue = molResult.RootID spawnIssue = rootID
} }
// Get or create issue // Get or create issue