gt-975: Molecule execution support for polecats and crew
Added molecule workflow integration to Gas Town: 1. spawn.go: MoleculeContext in work assignment mail - Shows step N/M and molecule ID in subject - Includes molecule workflow instructions - Guides polecat through DAG execution 2. prime.go: outputMoleculeContext() - Detects if in-progress issue is a molecule step - Shows molecule progress and next steps - Displays molecule work loop instructions 3. molecule.go: 'gt molecule progress' command - Shows execution progress for molecule root - Displays done/in-progress/ready/blocked steps - Progress bar and completion percentage - JSON output for Witness automation This enables polecats to work through molecule DAGs: - Receive molecule-aware work assignments - See context in gt prime output - Follow DAG with 'bd ready --parent <root>' - Witness can monitor with 'gt molecule progress' 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -113,6 +113,24 @@ Lists each instantiation with its status and progress.`,
|
|||||||
RunE: runMoleculeInstances,
|
RunE: runMoleculeInstances,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var moleculeProgressCmd = &cobra.Command{
|
||||||
|
Use: "progress <root-issue-id>",
|
||||||
|
Short: "Show progress through a molecule's steps",
|
||||||
|
Long: `Show the execution progress of an instantiated molecule.
|
||||||
|
|
||||||
|
Given a root issue (the parent of molecule steps), displays:
|
||||||
|
- Total steps and completion status
|
||||||
|
- Which steps are done, in-progress, ready, or blocked
|
||||||
|
- Overall progress percentage
|
||||||
|
|
||||||
|
This is useful for the Witness to monitor molecule execution.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
gt molecule progress gt-abc`,
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
RunE: runMoleculeProgress,
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
// List flags
|
// List flags
|
||||||
moleculeListCmd.Flags().BoolVar(&moleculeJSON, "json", false, "Output as JSON")
|
moleculeListCmd.Flags().BoolVar(&moleculeJSON, "json", false, "Output as JSON")
|
||||||
@@ -133,6 +151,9 @@ func init() {
|
|||||||
// Instances flags
|
// Instances flags
|
||||||
moleculeInstancesCmd.Flags().BoolVar(&moleculeJSON, "json", false, "Output as JSON")
|
moleculeInstancesCmd.Flags().BoolVar(&moleculeJSON, "json", false, "Output as JSON")
|
||||||
|
|
||||||
|
// Progress flags
|
||||||
|
moleculeProgressCmd.Flags().BoolVar(&moleculeJSON, "json", false, "Output as JSON")
|
||||||
|
|
||||||
// Add subcommands
|
// Add subcommands
|
||||||
moleculeCmd.AddCommand(moleculeListCmd)
|
moleculeCmd.AddCommand(moleculeListCmd)
|
||||||
moleculeCmd.AddCommand(moleculeShowCmd)
|
moleculeCmd.AddCommand(moleculeShowCmd)
|
||||||
@@ -140,6 +161,7 @@ func init() {
|
|||||||
moleculeCmd.AddCommand(moleculeInstantiateCmd)
|
moleculeCmd.AddCommand(moleculeInstantiateCmd)
|
||||||
moleculeCmd.AddCommand(moleculeInstancesCmd)
|
moleculeCmd.AddCommand(moleculeInstancesCmd)
|
||||||
moleculeCmd.AddCommand(moleculeExportCmd)
|
moleculeCmd.AddCommand(moleculeExportCmd)
|
||||||
|
moleculeCmd.AddCommand(moleculeProgressCmd)
|
||||||
|
|
||||||
rootCmd.AddCommand(moleculeCmd)
|
rootCmd.AddCommand(moleculeCmd)
|
||||||
}
|
}
|
||||||
@@ -647,3 +669,152 @@ func findMoleculeInstances(b *beads.Beads, molID string) ([]*beads.Issue, error)
|
|||||||
|
|
||||||
return parents, nil
|
return parents, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MoleculeProgressInfo contains progress information for a molecule instance.
|
||||||
|
type MoleculeProgressInfo struct {
|
||||||
|
RootID string `json:"root_id"`
|
||||||
|
RootTitle string `json:"root_title"`
|
||||||
|
MoleculeID string `json:"molecule_id,omitempty"`
|
||||||
|
TotalSteps int `json:"total_steps"`
|
||||||
|
DoneSteps int `json:"done_steps"`
|
||||||
|
InProgress int `json:"in_progress_steps"`
|
||||||
|
ReadySteps []string `json:"ready_steps"`
|
||||||
|
BlockedSteps []string `json:"blocked_steps"`
|
||||||
|
Percent int `json:"percent_complete"`
|
||||||
|
Complete bool `json:"complete"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func runMoleculeProgress(cmd *cobra.Command, args []string) error {
|
||||||
|
rootID := args[0]
|
||||||
|
|
||||||
|
workDir, err := findLocalBeadsDir()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("not in a beads workspace: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
b := beads.New(workDir)
|
||||||
|
|
||||||
|
// Get the root issue
|
||||||
|
root, err := b.Show(rootID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("getting root issue: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find all children of the root issue
|
||||||
|
children, err := b.List(beads.ListOptions{
|
||||||
|
Parent: rootID,
|
||||||
|
Status: "all",
|
||||||
|
Priority: -1,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("listing children: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(children) == 0 {
|
||||||
|
return fmt.Errorf("no steps found for %s (not a molecule root?)", rootID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build progress info
|
||||||
|
progress := MoleculeProgressInfo{
|
||||||
|
RootID: rootID,
|
||||||
|
RootTitle: root.Title,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to find molecule ID from first child's description
|
||||||
|
for _, child := range children {
|
||||||
|
if molID := extractMoleculeID(child.Description); molID != "" {
|
||||||
|
progress.MoleculeID = molID
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build set of closed issue IDs for dependency checking
|
||||||
|
closedIDs := make(map[string]bool)
|
||||||
|
for _, child := range children {
|
||||||
|
if child.Status == "closed" {
|
||||||
|
closedIDs[child.ID] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Categorize steps
|
||||||
|
for _, child := range children {
|
||||||
|
progress.TotalSteps++
|
||||||
|
|
||||||
|
switch child.Status {
|
||||||
|
case "closed":
|
||||||
|
progress.DoneSteps++
|
||||||
|
case "in_progress":
|
||||||
|
progress.InProgress++
|
||||||
|
case "open":
|
||||||
|
// Check if all dependencies are closed
|
||||||
|
allDepsClosed := true
|
||||||
|
for _, depID := range child.DependsOn {
|
||||||
|
if !closedIDs[depID] {
|
||||||
|
allDepsClosed = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(child.DependsOn) == 0 || allDepsClosed {
|
||||||
|
progress.ReadySteps = append(progress.ReadySteps, child.ID)
|
||||||
|
} else {
|
||||||
|
progress.BlockedSteps = append(progress.BlockedSteps, child.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate completion percentage
|
||||||
|
if progress.TotalSteps > 0 {
|
||||||
|
progress.Percent = (progress.DoneSteps * 100) / progress.TotalSteps
|
||||||
|
}
|
||||||
|
progress.Complete = progress.DoneSteps == progress.TotalSteps
|
||||||
|
|
||||||
|
// JSON output
|
||||||
|
if moleculeJSON {
|
||||||
|
enc := json.NewEncoder(os.Stdout)
|
||||||
|
enc.SetIndent("", " ")
|
||||||
|
return enc.Encode(progress)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Human-readable output
|
||||||
|
fmt.Printf("\n%s %s\n\n", style.Bold.Render("🧬 Molecule Progress:"), root.Title)
|
||||||
|
fmt.Printf(" Root: %s\n", rootID)
|
||||||
|
if progress.MoleculeID != "" {
|
||||||
|
fmt.Printf(" Molecule: %s\n", progress.MoleculeID)
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Progress bar
|
||||||
|
barWidth := 20
|
||||||
|
filled := (progress.Percent * barWidth) / 100
|
||||||
|
bar := strings.Repeat("█", filled) + strings.Repeat("░", barWidth-filled)
|
||||||
|
fmt.Printf(" [%s] %d%% (%d/%d)\n\n", bar, progress.Percent, progress.DoneSteps, progress.TotalSteps)
|
||||||
|
|
||||||
|
// Step status
|
||||||
|
fmt.Printf(" Done: %d\n", progress.DoneSteps)
|
||||||
|
fmt.Printf(" In Progress: %d\n", progress.InProgress)
|
||||||
|
fmt.Printf(" Ready: %d", len(progress.ReadySteps))
|
||||||
|
if len(progress.ReadySteps) > 0 {
|
||||||
|
fmt.Printf(" (%s)", strings.Join(progress.ReadySteps, ", "))
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Printf(" Blocked: %d\n", len(progress.BlockedSteps))
|
||||||
|
|
||||||
|
if progress.Complete {
|
||||||
|
fmt.Printf("\n %s\n", style.Bold.Render("✓ Molecule complete!"))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// extractMoleculeID extracts the molecule ID from an issue's description.
|
||||||
|
func extractMoleculeID(description string) string {
|
||||||
|
lines := strings.Split(description, "\n")
|
||||||
|
for _, line := range lines {
|
||||||
|
line = strings.TrimSpace(line)
|
||||||
|
if strings.HasPrefix(line, "instantiated_from:") {
|
||||||
|
return strings.TrimSpace(strings.TrimPrefix(line, "instantiated_from:"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|||||||
@@ -82,6 +82,9 @@ func runPrime(cmd *cobra.Command, args []string) error {
|
|||||||
// Output handoff content if present
|
// Output handoff content if present
|
||||||
outputHandoffContent(ctx)
|
outputHandoffContent(ctx)
|
||||||
|
|
||||||
|
// Output molecule context if working on a molecule step
|
||||||
|
outputMoleculeContext(ctx)
|
||||||
|
|
||||||
// Run bd prime to output beads workflow context
|
// Run bd prime to output beads workflow context
|
||||||
runBdPrime(cwd)
|
runBdPrime(cwd)
|
||||||
|
|
||||||
@@ -464,3 +467,116 @@ func runMailCheckInject(workDir string) {
|
|||||||
fmt.Println(output)
|
fmt.Println(output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// outputMoleculeContext checks if the agent is working on a molecule step and shows progress.
|
||||||
|
func outputMoleculeContext(ctx RoleContext) {
|
||||||
|
// Only applies to polecats and crew workers
|
||||||
|
if ctx.Role != RolePolecat && ctx.Role != RoleCrew {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for in-progress issues
|
||||||
|
b := beads.New(ctx.WorkDir)
|
||||||
|
issues, err := b.List(beads.ListOptions{
|
||||||
|
Status: "in_progress",
|
||||||
|
Assignee: ctx.Polecat,
|
||||||
|
Priority: -1,
|
||||||
|
})
|
||||||
|
if err != nil || len(issues) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if any in-progress issue is a molecule step
|
||||||
|
for _, issue := range issues {
|
||||||
|
moleculeID := parseMoleculeMetadata(issue.Description)
|
||||||
|
if moleculeID == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the parent (root) issue ID
|
||||||
|
rootID := issue.Parent
|
||||||
|
if rootID == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a molecule step - show context
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Printf("%s\n\n", style.Bold.Render("## 🧬 Molecule Workflow"))
|
||||||
|
fmt.Printf("You are working on a molecule step.\n")
|
||||||
|
fmt.Printf(" Current step: %s\n", issue.ID)
|
||||||
|
fmt.Printf(" Molecule: %s\n", moleculeID)
|
||||||
|
fmt.Printf(" Root issue: %s\n\n", rootID)
|
||||||
|
|
||||||
|
// Show molecule progress by finding sibling steps
|
||||||
|
showMoleculeProgress(b, rootID)
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("**Molecule Work Loop:**")
|
||||||
|
fmt.Println("1. Complete current step, then `bd close " + issue.ID + "`")
|
||||||
|
fmt.Println("2. Check for next steps: `bd ready --parent " + rootID + "`")
|
||||||
|
fmt.Println("3. Work on next ready step(s)")
|
||||||
|
fmt.Println("4. When all steps done, run `gt done`")
|
||||||
|
break // Only show context for first molecule step found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseMoleculeMetadata extracts molecule info from a step's description.
|
||||||
|
// Looks for lines like:
|
||||||
|
//
|
||||||
|
// instantiated_from: mol-xyz
|
||||||
|
func parseMoleculeMetadata(description string) string {
|
||||||
|
lines := strings.Split(description, "\n")
|
||||||
|
for _, line := range lines {
|
||||||
|
line = strings.TrimSpace(line)
|
||||||
|
if strings.HasPrefix(line, "instantiated_from:") {
|
||||||
|
return strings.TrimSpace(strings.TrimPrefix(line, "instantiated_from:"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// showMoleculeProgress displays the progress through a molecule's steps.
|
||||||
|
func showMoleculeProgress(b *beads.Beads, rootID string) {
|
||||||
|
if rootID == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find all children of the root issue
|
||||||
|
children, err := b.List(beads.ListOptions{
|
||||||
|
Parent: rootID,
|
||||||
|
Status: "all",
|
||||||
|
Priority: -1,
|
||||||
|
})
|
||||||
|
if err != nil || len(children) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
total := len(children)
|
||||||
|
done := 0
|
||||||
|
inProgress := 0
|
||||||
|
var readySteps []string
|
||||||
|
|
||||||
|
for _, child := range children {
|
||||||
|
switch child.Status {
|
||||||
|
case "closed":
|
||||||
|
done++
|
||||||
|
case "in_progress":
|
||||||
|
inProgress++
|
||||||
|
case "open":
|
||||||
|
// Check if ready (no open dependencies)
|
||||||
|
if len(child.DependsOn) == 0 {
|
||||||
|
readySteps = append(readySteps, child.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Progress: %d/%d steps complete", done, total)
|
||||||
|
if inProgress > 0 {
|
||||||
|
fmt.Printf(" (%d in progress)", inProgress)
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
if len(readySteps) > 0 {
|
||||||
|
fmt.Printf("Ready steps: %s\n", strings.Join(readySteps, ", "))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -242,6 +242,9 @@ func runSpawn(cmd *cobra.Command, args []string) error {
|
|||||||
fmt.Printf("%s beads sync: %v\n", style.Dim.Render("Warning:"), err)
|
fmt.Printf("%s beads sync: %v\n", style.Dim.Render("Warning:"), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Track molecule context for work assignment mail
|
||||||
|
var moleculeCtx *MoleculeContext
|
||||||
|
|
||||||
// Handle molecule instantiation if specified
|
// Handle molecule instantiation if specified
|
||||||
if spawnMolecule != "" {
|
if spawnMolecule != "" {
|
||||||
b := beads.New(beadsPath)
|
b := beads.New(beadsPath)
|
||||||
@@ -281,9 +284,11 @@ func runSpawn(cmd *cobra.Command, args []string) error {
|
|||||||
|
|
||||||
// Find the first ready step (one with no dependencies)
|
// Find the first ready step (one with no dependencies)
|
||||||
var firstReadyStep *beads.Issue
|
var firstReadyStep *beads.Issue
|
||||||
for _, step := range steps {
|
var stepNumber int
|
||||||
|
for i, step := range steps {
|
||||||
if len(step.DependsOn) == 0 {
|
if len(step.DependsOn) == 0 {
|
||||||
firstReadyStep = step
|
firstReadyStep = step
|
||||||
|
stepNumber = i + 1
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -292,6 +297,14 @@ func runSpawn(cmd *cobra.Command, args []string) error {
|
|||||||
return fmt.Errorf("no ready step found in molecule (all steps have dependencies)")
|
return fmt.Errorf("no ready step found in molecule (all steps have dependencies)")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build molecule context for work assignment
|
||||||
|
moleculeCtx = &MoleculeContext{
|
||||||
|
MoleculeID: spawnMolecule,
|
||||||
|
RootIssueID: spawnIssue, // Original issue is the molecule root
|
||||||
|
TotalSteps: len(steps),
|
||||||
|
StepNumber: stepNumber,
|
||||||
|
}
|
||||||
|
|
||||||
// Switch to spawning on the first ready step
|
// Switch to spawning on the first ready step
|
||||||
fmt.Printf("\nSpawning on first ready step: %s\n", firstReadyStep.ID)
|
fmt.Printf("\nSpawning on first ready step: %s\n", firstReadyStep.ID)
|
||||||
spawnIssue = firstReadyStep.ID
|
spawnIssue = firstReadyStep.ID
|
||||||
@@ -340,7 +353,7 @@ func runSpawn(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Send work assignment mail to polecat inbox (before starting session)
|
// Send work assignment mail to polecat inbox (before starting session)
|
||||||
workMsg := buildWorkAssignmentMail(issue, spawnMessage, polecatAddress)
|
workMsg := buildWorkAssignmentMail(issue, spawnMessage, polecatAddress, moleculeCtx)
|
||||||
|
|
||||||
fmt.Printf("Sending work assignment to %s inbox...\n", polecatAddress)
|
fmt.Printf("Sending work assignment to %s inbox...\n", polecatAddress)
|
||||||
if err := router.Send(workMsg); err != nil {
|
if err := router.Send(workMsg); err != nil {
|
||||||
@@ -579,14 +592,27 @@ func buildSpawnContext(issue *BeadsIssue, message string) string {
|
|||||||
return sb.String()
|
return sb.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MoleculeContext contains information about a molecule workflow assignment.
|
||||||
|
type MoleculeContext struct {
|
||||||
|
MoleculeID string // The molecule template ID
|
||||||
|
RootIssueID string // The parent issue (molecule root)
|
||||||
|
TotalSteps int // Total number of steps in the molecule
|
||||||
|
StepNumber int // Which step this is (1-indexed)
|
||||||
|
}
|
||||||
|
|
||||||
// buildWorkAssignmentMail creates a work assignment mail message for a polecat.
|
// buildWorkAssignmentMail creates a work assignment mail message for a polecat.
|
||||||
// This replaces tmux-based context injection with persistent mailbox delivery.
|
// This replaces tmux-based context injection with persistent mailbox delivery.
|
||||||
func buildWorkAssignmentMail(issue *BeadsIssue, message, polecatAddress string) *mail.Message {
|
// If moleculeCtx is non-nil, includes molecule workflow instructions.
|
||||||
|
func buildWorkAssignmentMail(issue *BeadsIssue, message, polecatAddress string, moleculeCtx *MoleculeContext) *mail.Message {
|
||||||
var subject string
|
var subject string
|
||||||
var body strings.Builder
|
var body strings.Builder
|
||||||
|
|
||||||
if issue != nil {
|
if issue != nil {
|
||||||
subject = fmt.Sprintf("📋 Work Assignment: %s", issue.Title)
|
if moleculeCtx != nil {
|
||||||
|
subject = fmt.Sprintf("🧬 Molecule Step %d/%d: %s", moleculeCtx.StepNumber, moleculeCtx.TotalSteps, issue.Title)
|
||||||
|
} else {
|
||||||
|
subject = fmt.Sprintf("📋 Work Assignment: %s", issue.Title)
|
||||||
|
}
|
||||||
|
|
||||||
body.WriteString(fmt.Sprintf("Issue: %s\n", issue.ID))
|
body.WriteString(fmt.Sprintf("Issue: %s\n", issue.ID))
|
||||||
body.WriteString(fmt.Sprintf("Title: %s\n", issue.Title))
|
body.WriteString(fmt.Sprintf("Title: %s\n", issue.Title))
|
||||||
@@ -605,14 +631,32 @@ func buildWorkAssignmentMail(issue *BeadsIssue, message, polecatAddress string)
|
|||||||
body.WriteString(fmt.Sprintf("Task: %s\n", message))
|
body.WriteString(fmt.Sprintf("Task: %s\n", message))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add molecule context if present
|
||||||
|
if moleculeCtx != nil {
|
||||||
|
body.WriteString("\n## Molecule Workflow\n")
|
||||||
|
body.WriteString(fmt.Sprintf("You are working on step %d of %d in molecule %s.\n", moleculeCtx.StepNumber, moleculeCtx.TotalSteps, moleculeCtx.MoleculeID))
|
||||||
|
body.WriteString(fmt.Sprintf("Root issue: %s\n\n", moleculeCtx.RootIssueID))
|
||||||
|
body.WriteString("**IMPORTANT**: This is part of a molecule workflow. After completing this step:\n")
|
||||||
|
body.WriteString("1. Run `bd close " + issue.ID + "`\n")
|
||||||
|
body.WriteString("2. Run `bd ready --parent " + moleculeCtx.RootIssueID + "` to find next ready steps\n")
|
||||||
|
body.WriteString("3. If more steps are ready, continue working on them\n")
|
||||||
|
body.WriteString("4. When all steps are done, run `gt done` to signal completion\n\n")
|
||||||
|
}
|
||||||
|
|
||||||
body.WriteString("\n## Workflow\n")
|
body.WriteString("\n## Workflow\n")
|
||||||
body.WriteString("1. Run `gt prime` to load polecat context\n")
|
body.WriteString("1. Run `gt prime` to load polecat context\n")
|
||||||
body.WriteString("2. Run `bd sync --from-main` to get fresh beads\n")
|
body.WriteString("2. Run `bd sync --from-main` to get fresh beads\n")
|
||||||
body.WriteString("3. Work on your task, commit changes regularly\n")
|
body.WriteString("3. Work on your task, commit changes regularly\n")
|
||||||
body.WriteString("4. Run `bd close <issue-id>` when done\n")
|
body.WriteString("4. Run `bd close <issue-id>` when done\n")
|
||||||
body.WriteString("5. Run `bd sync` to push beads changes\n")
|
if moleculeCtx != nil {
|
||||||
body.WriteString("6. Push code: `git push origin HEAD`\n")
|
body.WriteString("5. Check `bd ready --parent " + moleculeCtx.RootIssueID + "` for more steps\n")
|
||||||
body.WriteString("7. Run `gt done` to signal completion\n")
|
body.WriteString("6. Repeat steps 3-5 for each ready step\n")
|
||||||
|
body.WriteString("7. When all steps done: run `bd sync`, push code, run `gt done`\n")
|
||||||
|
} else {
|
||||||
|
body.WriteString("5. Run `bd sync` to push beads changes\n")
|
||||||
|
body.WriteString("6. Push code: `git push origin HEAD`\n")
|
||||||
|
body.WriteString("7. Run `gt done` to signal completion\n")
|
||||||
|
}
|
||||||
body.WriteString("\n## Handoff Protocol\n")
|
body.WriteString("\n## Handoff Protocol\n")
|
||||||
body.WriteString("Before signaling done, ensure:\n")
|
body.WriteString("Before signaling done, ensure:\n")
|
||||||
body.WriteString("- Git status is clean (no uncommitted changes)\n")
|
body.WriteString("- Git status is clean (no uncommitted changes)\n")
|
||||||
|
|||||||
Reference in New Issue
Block a user