feat: add --ephemeral flag to bd mol bond (bd-kwjh.3)
When --ephemeral is set: - Spawned molecules go to .beads-ephemeral/ instead of .beads/ - Ephemeral directory is automatically gitignored - No auto-flush (ephemeral does not sync) - Proto+proto bonding ignores flag (templates stay in permanent storage) Updated help text to document wisp workflow (bond then squash/burn). Generated with Claude Code Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/steveyegge/beads/internal/beads"
|
||||||
"github.com/steveyegge/beads/internal/storage"
|
"github.com/steveyegge/beads/internal/storage"
|
||||||
"github.com/steveyegge/beads/internal/types"
|
"github.com/steveyegge/beads/internal/types"
|
||||||
"github.com/steveyegge/beads/internal/ui"
|
"github.com/steveyegge/beads/internal/ui"
|
||||||
@@ -31,11 +32,18 @@ Bond types:
|
|||||||
parallel - B runs alongside A
|
parallel - B runs alongside A
|
||||||
conditional - B runs only if A fails
|
conditional - B runs only if A fails
|
||||||
|
|
||||||
|
Ephemeral storage (wisps):
|
||||||
|
Use --ephemeral to create molecules in .beads-ephemeral/ instead of .beads/.
|
||||||
|
Ephemeral molecules (wisps) are local-only, gitignored, and not synced.
|
||||||
|
Use bd mol squash to convert a wisp to a digest in permanent storage.
|
||||||
|
Use bd mol burn to delete a wisp without creating a digest.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
bd mol bond mol-feature mol-deploy # Compound proto
|
bd mol bond mol-feature mol-deploy # Compound proto
|
||||||
bd mol bond mol-feature mol-deploy --type parallel # Run in parallel
|
bd mol bond mol-feature mol-deploy --type parallel # Run in parallel
|
||||||
bd mol bond mol-feature bd-abc123 # Attach proto to molecule
|
bd mol bond mol-feature bd-abc123 # Attach proto to molecule
|
||||||
bd mol bond bd-abc123 bd-def456 # Join two molecules`,
|
bd mol bond bd-abc123 bd-def456 # Join two molecules
|
||||||
|
bd mol bond mol-patrol --ephemeral # Create wisp for patrol cycle`,
|
||||||
Args: cobra.ExactArgs(2),
|
Args: cobra.ExactArgs(2),
|
||||||
Run: runMolBond,
|
Run: runMolBond,
|
||||||
}
|
}
|
||||||
@@ -70,6 +78,25 @@ func runMolBond(cmd *cobra.Command, args []string) {
|
|||||||
customTitle, _ := cmd.Flags().GetString("as")
|
customTitle, _ := cmd.Flags().GetString("as")
|
||||||
dryRun, _ := cmd.Flags().GetBool("dry-run")
|
dryRun, _ := cmd.Flags().GetBool("dry-run")
|
||||||
varFlags, _ := cmd.Flags().GetStringSlice("var")
|
varFlags, _ := cmd.Flags().GetStringSlice("var")
|
||||||
|
ephemeral, _ := cmd.Flags().GetBool("ephemeral")
|
||||||
|
|
||||||
|
// Determine which store to use for spawning
|
||||||
|
targetStore := store
|
||||||
|
if ephemeral {
|
||||||
|
// Open ephemeral storage for wisp creation
|
||||||
|
ephStore, err := beads.NewEphemeralStorage(ctx)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Error: failed to open ephemeral storage: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
defer ephStore.Close()
|
||||||
|
targetStore = ephStore
|
||||||
|
|
||||||
|
// Ensure ephemeral directory is gitignored
|
||||||
|
if err := beads.EnsureEphemeralGitignore(); err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Warning: could not update .gitignore: %v\n", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Validate bond type
|
// Validate bond type
|
||||||
if bondType != types.BondTypeSequential && bondType != types.BondTypeParallel && bondType != types.BondTypeConditional {
|
if bondType != types.BondTypeSequential && bondType != types.BondTypeParallel && bondType != types.BondTypeConditional {
|
||||||
@@ -121,11 +148,17 @@ func runMolBond(cmd *cobra.Command, args []string) {
|
|||||||
fmt.Printf(" A: %s (%s)\n", issueA.Title, operandType(aIsProto))
|
fmt.Printf(" A: %s (%s)\n", issueA.Title, operandType(aIsProto))
|
||||||
fmt.Printf(" B: %s (%s)\n", issueB.Title, operandType(bIsProto))
|
fmt.Printf(" B: %s (%s)\n", issueB.Title, operandType(bIsProto))
|
||||||
fmt.Printf(" Bond type: %s\n", bondType)
|
fmt.Printf(" Bond type: %s\n", bondType)
|
||||||
|
if ephemeral {
|
||||||
|
fmt.Printf(" Storage: ephemeral (.beads-ephemeral/)\n")
|
||||||
|
}
|
||||||
if aIsProto && bIsProto {
|
if aIsProto && bIsProto {
|
||||||
fmt.Printf(" Result: compound proto\n")
|
fmt.Printf(" Result: compound proto\n")
|
||||||
if customTitle != "" {
|
if customTitle != "" {
|
||||||
fmt.Printf(" Custom title: %s\n", customTitle)
|
fmt.Printf(" Custom title: %s\n", customTitle)
|
||||||
}
|
}
|
||||||
|
if ephemeral {
|
||||||
|
fmt.Printf(" Note: --ephemeral ignored for proto+proto (templates stay in permanent storage)\n")
|
||||||
|
}
|
||||||
} else if aIsProto || bIsProto {
|
} else if aIsProto || bIsProto {
|
||||||
fmt.Printf(" Result: spawn proto, attach to molecule\n")
|
fmt.Printf(" Result: spawn proto, attach to molecule\n")
|
||||||
} else {
|
} else {
|
||||||
@@ -135,16 +168,18 @@ func runMolBond(cmd *cobra.Command, args []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Dispatch based on operand types
|
// Dispatch based on operand types
|
||||||
|
// Note: proto+proto creates templates (permanent storage), others use targetStore
|
||||||
var result *BondResult
|
var result *BondResult
|
||||||
switch {
|
switch {
|
||||||
case aIsProto && bIsProto:
|
case aIsProto && bIsProto:
|
||||||
|
// Compound protos are templates - always use permanent storage
|
||||||
result, err = bondProtoProto(ctx, store, issueA, issueB, bondType, customTitle, actor)
|
result, err = bondProtoProto(ctx, store, issueA, issueB, bondType, customTitle, actor)
|
||||||
case aIsProto && !bIsProto:
|
case aIsProto && !bIsProto:
|
||||||
result, err = bondProtoMol(ctx, store, issueA, issueB, bondType, vars, actor)
|
result, err = bondProtoMol(ctx, targetStore, issueA, issueB, bondType, vars, actor)
|
||||||
case !aIsProto && bIsProto:
|
case !aIsProto && bIsProto:
|
||||||
result, err = bondMolProto(ctx, store, issueA, issueB, bondType, vars, actor)
|
result, err = bondMolProto(ctx, targetStore, issueA, issueB, bondType, vars, actor)
|
||||||
default:
|
default:
|
||||||
result, err = bondMolMol(ctx, store, issueA, issueB, bondType, actor)
|
result, err = bondMolMol(ctx, targetStore, issueA, issueB, bondType, actor)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -152,8 +187,10 @@ func runMolBond(cmd *cobra.Command, args []string) {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Schedule auto-flush
|
// Schedule auto-flush (only for non-ephemeral, ephemeral doesn't sync)
|
||||||
markDirtyAndScheduleFlush()
|
if !ephemeral {
|
||||||
|
markDirtyAndScheduleFlush()
|
||||||
|
}
|
||||||
|
|
||||||
if jsonOutput {
|
if jsonOutput {
|
||||||
outputJSON(result)
|
outputJSON(result)
|
||||||
@@ -165,6 +202,9 @@ func runMolBond(cmd *cobra.Command, args []string) {
|
|||||||
if result.Spawned > 0 {
|
if result.Spawned > 0 {
|
||||||
fmt.Printf(" Spawned: %d issues\n", result.Spawned)
|
fmt.Printf(" Spawned: %d issues\n", result.Spawned)
|
||||||
}
|
}
|
||||||
|
if ephemeral {
|
||||||
|
fmt.Printf(" Storage: ephemeral (wisp)\n")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// isProto checks if an issue is a proto (has the template label)
|
// isProto checks if an issue is a proto (has the template label)
|
||||||
@@ -378,6 +418,7 @@ func init() {
|
|||||||
molBondCmd.Flags().String("as", "", "Custom title for compound proto (proto+proto only)")
|
molBondCmd.Flags().String("as", "", "Custom title for compound proto (proto+proto only)")
|
||||||
molBondCmd.Flags().Bool("dry-run", false, "Preview what would be created")
|
molBondCmd.Flags().Bool("dry-run", false, "Preview what would be created")
|
||||||
molBondCmd.Flags().StringSlice("var", []string{}, "Variable substitution for spawned protos (key=value)")
|
molBondCmd.Flags().StringSlice("var", []string{}, "Variable substitution for spawned protos (key=value)")
|
||||||
|
molBondCmd.Flags().Bool("ephemeral", false, "Create molecule in ephemeral storage (wisp)")
|
||||||
|
|
||||||
molCmd.AddCommand(molBondCmd)
|
molCmd.AddCommand(molBondCmd)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user