refactor: remove bd mol catalog in favor of bd formula list (bd-ctmg)

- Delete mol_catalog.go (duplicate functionality)
- Update mol.go help text to point to bd formula list
- Update CLI_REFERENCE.md and MOLECULES.md docs
- Update deprecated template.go references

🤖 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-27 14:34:08 -08:00
parent cd9f8102dd
commit 26785f9b46
5 changed files with 13 additions and 147 deletions

View File

@@ -18,7 +18,6 @@ import (
// - Compound: Result of bonding
//
// Usage:
// bd mol catalog # List available protos
// bd mol show <id> # Show proto/molecule structure
// bd mol pour <id> --var key=value # Instantiate proto → persistent mol
// bd mol wisp <id> --var key=value # Instantiate proto → ephemeral wisp
@@ -48,14 +47,15 @@ The molecule metaphor:
- Distilling extracts a proto from an ad-hoc epic
Commands:
catalog List available protos
show Show proto/molecule structure and variables
pour Instantiate proto as persistent mol (liquid phase)
wisp Instantiate proto as ephemeral wisp (vapor phase)
bond Polymorphic combine: proto+proto, proto+mol, mol+mol
squash Condense molecule to digest
burn Discard wisp
distill Extract proto from ad-hoc epic`,
distill Extract proto from ad-hoc epic
Use "bd formula list" to list available formulas.`,
}
// =============================================================================

View File

@@ -1,134 +0,0 @@
package main
import (
"fmt"
"sort"
"strings"
"github.com/spf13/cobra"
"github.com/steveyegge/beads/internal/ui"
)
// CatalogEntry represents a formula in the catalog.
type CatalogEntry struct {
Name string `json:"name"`
Type string `json:"type"`
Description string `json:"description"`
Source string `json:"source"`
Steps int `json:"steps"`
Vars []string `json:"vars,omitempty"`
}
var molCatalogCmd = &cobra.Command{
Use: "catalog",
Aliases: []string{"list", "ls"},
Short: "List available molecule formulas",
Long: `List formulas available for bd mol pour / bd mol wisp.
Formulas are ephemeral proto definitions stored as .formula.json files.
They are cooked inline when pouring, never stored as database beads.
Search paths (in priority order):
1. .beads/formulas/ (project-level)
2. ~/.beads/formulas/ (user-level)
3. ~/gt/.beads/formulas/ (Gas Town level)`,
Run: func(cmd *cobra.Command, args []string) {
typeFilter, _ := cmd.Flags().GetString("type")
// Get all search paths and scan for formulas
searchPaths := getFormulaSearchPaths()
seen := make(map[string]bool)
var entries []CatalogEntry
for _, dir := range searchPaths {
formulas, err := scanFormulaDir(dir)
if err != nil {
continue // Skip inaccessible directories
}
for _, f := range formulas {
if seen[f.Formula] {
continue // Skip shadowed formulas
}
seen[f.Formula] = true
// Apply type filter
if typeFilter != "" && string(f.Type) != typeFilter {
continue
}
// Extract variable names
var varNames []string
for name := range f.Vars {
varNames = append(varNames, name)
}
sort.Strings(varNames)
entries = append(entries, CatalogEntry{
Name: f.Formula,
Type: string(f.Type),
Description: truncateDescription(f.Description, 60),
Source: f.Source,
Steps: countSteps(f.Steps),
Vars: varNames,
})
}
}
// Sort by name
sort.Slice(entries, func(i, j int) bool {
return entries[i].Name < entries[j].Name
})
if jsonOutput {
outputJSON(entries)
return
}
if len(entries) == 0 {
fmt.Println("No formulas found.")
fmt.Println("\nTo create a formula, write a .formula.json file:")
fmt.Println(" .beads/formulas/my-workflow.formula.json")
fmt.Println("\nOr distill from existing work:")
fmt.Println(" bd mol distill <epic-id> my-workflow")
fmt.Println("\nTo instantiate from formula:")
fmt.Println(" bd mol pour <formula-name> --var key=value # persistent mol")
fmt.Println(" bd mol wisp <formula-name> --var key=value # ephemeral wisp")
return
}
fmt.Printf("%s\n\n", ui.RenderPass("Formulas (for bd mol pour / bd mol wisp):"))
// Group by type for display
byType := make(map[string][]CatalogEntry)
for _, e := range entries {
byType[e.Type] = append(byType[e.Type], e)
}
// Print workflow types first (most common for pour/wisp)
typeOrder := []string{"workflow", "expansion", "aspect"}
for _, t := range typeOrder {
typeEntries := byType[t]
if len(typeEntries) == 0 {
continue
}
typeIcon := getTypeIcon(t)
fmt.Printf("%s %s:\n", typeIcon, strings.Title(t))
for _, e := range typeEntries {
varInfo := ""
if len(e.Vars) > 0 {
varInfo = fmt.Sprintf(" (vars: %s)", strings.Join(e.Vars, ", "))
}
fmt.Printf(" %s: %s%s\n", ui.RenderAccent(e.Name), e.Description, varInfo)
}
fmt.Println()
}
},
}
func init() {
molCatalogCmd.Flags().String("type", "", "Filter by formula type (workflow, expansion, aspect)")
molCmd.AddCommand(molCatalogCmd)
}

View File

@@ -60,7 +60,7 @@ var templateCmd = &cobra.Command{
Use: "template",
GroupID: "setup",
Short: "Manage issue templates",
Deprecated: "use 'bd mol' instead (mol catalog, mol show, mol bond)",
Deprecated: "use 'bd mol' instead (formula list, mol show, mol bond)",
Long: `Manage Beads templates for creating issue hierarchies.
Templates are epics with the "template" label. They can have child issues
@@ -78,7 +78,7 @@ To use a template:
var templateListCmd = &cobra.Command{
Use: "list",
Short: "List available templates",
Deprecated: "use 'bd mol catalog' instead",
Deprecated: "use 'bd formula list' instead",
Run: func(cmd *cobra.Command, args []string) {
ctx := rootCtx
var beadsTemplates []*types.Issue