From bf2f200754491f22337cb75dc7f4880215d7b23c Mon Sep 17 00:00:00 2001 From: Steve Yegge Date: Fri, 26 Dec 2025 23:41:14 -0800 Subject: [PATCH] Move pour and ephemeral under bd mol subcommand (bd-2fs7) For consistency, all molecule operations are now under bd mol: - bd mol pour - create persistent mol - bd mol ephemeral - create ephemeral mol - bd mol ephemeral list - list ephemeral issues - bd mol ephemeral gc - garbage collect old ephemeral issues This aligns with existing mol subcommands: bond, squash, burn, etc. --- cmd/bd/ephemeral.go | 50 ++++++++++++++++++++++++++++++++++----------- cmd/bd/mol.go | 20 +++++++++--------- cmd/bd/pour.go | 8 ++++---- 3 files changed, 52 insertions(+), 26 deletions(-) diff --git a/cmd/bd/ephemeral.go b/cmd/bd/ephemeral.go index 9df287f8..db34370b 100644 --- a/cmd/bd/ephemeral.go +++ b/cmd/bd/ephemeral.go @@ -27,24 +27,34 @@ import ( // bd ephemeral gc - Garbage collect orphaned ephemeral issues var ephemeralCmd = &cobra.Command{ - Use: "ephemeral", - Short: "Manage ephemeral molecules", - Long: `Manage ephemeral issues - ephemeral molecules for operational workflows. + Use: "ephemeral [proto-id]", + Short: "Create or manage ephemeral molecules", + Long: `Create or manage ephemeral issues - ephemeral molecules for operational workflows. -Ephemeral issues are issues with Wisp=true in the main database. They're stored +When called with a proto-id argument, creates an ephemeral mol from that proto. +When called with a subcommand (list, gc), manages existing ephemeral issues. + +Ephemeral issues are issues with Ephemeral=true in the main database. They're stored locally but NOT exported to JSONL (and thus not synced via git). They're used for patrol cycles, operational loops, and other workflows that shouldn't accumulate in the shared issue database. -The wisp lifecycle: - 1. Create: bd ephemeral create or bd create --ephemeral +The ephemeral lifecycle: + 1. Create: bd mol ephemeral or bd create --ephemeral 2. Execute: Normal bd operations work on ephemeral issues - 3. Squash: bd mol squash (clears Wisp flag, promotes to persistent) - 4. Or burn: bd mol burn (deletes wisp without creating digest) + 3. Squash: bd mol squash (clears Ephemeral flag, promotes to persistent) + 4. Or burn: bd mol burn (deletes without creating digest) -Commands: +Examples: + bd mol ephemeral mol-patrol # Create ephemeral from proto + bd mol ephemeral list # List all ephemeral issues + bd mol ephemeral gc # Garbage collect old ephemeral issues + +Subcommands: list List all ephemeral issues in current context gc Garbage collect orphaned ephemeral issues`, + Args: cobra.MaximumNArgs(1), + Run: runEphemeral, } // EphemeralListItem represents a wisp in list output @@ -68,7 +78,19 @@ type EphemeralListResult struct { // OldThreshold is how old a wisp must be to be flagged as old (time-based, for ephemeral cleanup) const OldThreshold = 24 * time.Hour -// ephemeralCreateCmd instantiates a proto as an ephemeral wisp +// runEphemeral handles the ephemeral command when called directly with a proto-id +// It delegates to runEphemeralCreate for the actual work +func runEphemeral(cmd *cobra.Command, args []string) { + if len(args) == 0 { + // No proto-id provided, show help + cmd.Help() + return + } + // Delegate to the create logic + runEphemeralCreate(cmd, args) +} + +// ephemeralCreateCmd instantiates a proto as an ephemeral wisp (kept for backwards compat) var ephemeralCreateCmd = &cobra.Command{ Use: "create ", Short: "Instantiate a proto as an ephemeral wisp (solid -> vapor)", @@ -634,7 +656,11 @@ func runEphemeralGC(cmd *cobra.Command, args []string) { } func init() { - // Ephemeral create command flags + // Ephemeral command flags (for direct create: bd mol ephemeral ) + ephemeralCmd.Flags().StringSlice("var", []string{}, "Variable substitution (key=value)") + ephemeralCmd.Flags().Bool("dry-run", false, "Preview what would be created") + + // Ephemeral create command flags (kept for backwards compat: bd mol ephemeral create ) ephemeralCreateCmd.Flags().StringSlice("var", []string{}, "Variable substitution (key=value)") ephemeralCreateCmd.Flags().Bool("dry-run", false, "Preview what would be created") @@ -647,5 +673,5 @@ func init() { ephemeralCmd.AddCommand(ephemeralCreateCmd) ephemeralCmd.AddCommand(ephemeralListCmd) ephemeralCmd.AddCommand(ephemeralGCCmd) - rootCmd.AddCommand(ephemeralCmd) + molCmd.AddCommand(ephemeralCmd) } diff --git a/cmd/bd/mol.go b/cmd/bd/mol.go index ea65c62b..058fb289 100644 --- a/cmd/bd/mol.go +++ b/cmd/bd/mol.go @@ -20,8 +20,8 @@ import ( // Usage: // bd mol catalog # List available protos // bd mol show # Show proto/molecule structure -// bd pour --var key=value # Instantiate proto → persistent mol -// bd ephemeral create --var key=value # Instantiate proto → ephemeral wisp +// bd mol pour --var key=value # Instantiate proto → persistent mol +// bd mol ephemeral --var key=value # Instantiate proto → ephemeral mol // MoleculeLabel is the label used to identify molecules (templates) // Molecules use the same label as templates - they ARE templates with workflow semantics @@ -48,14 +48,14 @@ The molecule metaphor: - Distilling extracts a proto from an ad-hoc epic Commands: - catalog List available protos - show Show proto/molecule structure and variables - bond Polymorphic combine: proto+proto, proto+mol, mol+mol - distill Extract proto from ad-hoc epic - -See also: - bd pour # Instantiate as persistent mol (liquid phase) - bd ephemeral create # Instantiate as ephemeral wisp (vapor phase)`, + catalog List available protos + show Show proto/molecule structure and variables + pour Instantiate proto as persistent mol (liquid phase) + ephemeral Instantiate proto as ephemeral mol (vapor phase) + bond Polymorphic combine: proto+proto, proto+mol, mol+mol + squash Condense molecule to digest + burn Discard ephemeral mol + distill Extract proto from ad-hoc epic`, } // ============================================================================= diff --git a/cmd/bd/pour.go b/cmd/bd/pour.go index bcd05968..06b88305 100644 --- a/cmd/bd/pour.go +++ b/cmd/bd/pour.go @@ -32,9 +32,9 @@ Use pour for: - Anything you might need to reference later Examples: - bd pour mol-feature --var name=auth # Create persistent mol from proto - bd pour mol-release --var version=1.0 # Release workflow - bd pour mol-review --var pr=123 # Code review workflow`, + bd mol pour mol-feature --var name=auth # Create persistent mol from proto + bd mol pour mol-release --var version=1.0 # Release workflow + bd mol pour mol-review --var pr=123 # Code review workflow`, Args: cobra.ExactArgs(1), Run: runPour, } @@ -260,5 +260,5 @@ func init() { pourCmd.Flags().StringSlice("attach", []string{}, "Proto to attach after spawning (repeatable)") pourCmd.Flags().String("attach-type", types.BondTypeSequential, "Bond type for attachments: sequential, parallel, or conditional") - rootCmd.AddCommand(pourCmd) + molCmd.AddCommand(pourCmd) }