Implement BD_GUIDE.md generation for version-stamped documentation (bd-woro)
This implements the ability to separate bd-specific instructions from project-specific instructions by generating a canonical BD_GUIDE.md file. ## Changes 1. Added `--output` flag to `bd onboard` command - Generates version-stamped BD_GUIDE.md at specified path - Includes both agentsContent and copilotInstructionsContent - Auto-generated header warns against manual editing 2. Version tracking integration - checkAndSuggestBDGuideUpdate() detects outdated BD_GUIDE.md - Suggests regeneration when bd version changes - Integrated with maybeShowUpgradeNotification() 3. Comprehensive test coverage - Tests for BD_GUIDE.md generation - Tests for version stamp validation - Tests for content inclusion 4. Documentation updates - Updated AGENTS.md with BD_GUIDE.md workflow - Added regeneration instructions to upgrade workflow ## Benefits - Clear separation of concerns (bd vs project instructions) - Deterministic updates (no LLM involved) - Git-trackable diffs show exactly what changed - Progressive disclosure (agents read when needed) ## Usage \`\`\`bash # Generate BD_GUIDE.md bd onboard --output .beads/BD_GUIDE.md # After upgrading bd bd onboard --output .beads/BD_GUIDE.md # Regenerate \`\`\` Closes bd-woro
This commit is contained in:
@@ -114,9 +114,67 @@ func maybeShowUpgradeNotification() {
|
||||
// Display notification
|
||||
fmt.Printf("🔄 bd upgraded from v%s to v%s since last use\n", previousVersion, Version)
|
||||
fmt.Println("💡 Run 'bd upgrade review' to see what changed")
|
||||
|
||||
// Check if BD_GUIDE.md exists and needs updating
|
||||
checkAndSuggestBDGuideUpdate()
|
||||
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
// checkAndSuggestBDGuideUpdate checks if .beads/BD_GUIDE.md exists and suggests regeneration if outdated.
|
||||
// bd-woro: Auto-update BD_GUIDE.md on version changes
|
||||
func checkAndSuggestBDGuideUpdate() {
|
||||
beadsDir := beads.FindBeadsDir()
|
||||
if beadsDir == "" {
|
||||
return
|
||||
}
|
||||
|
||||
guidePath := beadsDir + "/BD_GUIDE.md"
|
||||
|
||||
// Check if BD_GUIDE.md exists
|
||||
if _, err := os.Stat(guidePath); os.IsNotExist(err) {
|
||||
// File doesn't exist - no suggestion needed
|
||||
return
|
||||
}
|
||||
|
||||
// Read first few lines to check version stamp
|
||||
content, err := os.ReadFile(guidePath)
|
||||
if err != nil {
|
||||
return // Silent failure
|
||||
}
|
||||
|
||||
// Look for version in the first 200 bytes (should be in the header)
|
||||
header := string(content)
|
||||
if len(header) > 200 {
|
||||
header = header[:200]
|
||||
}
|
||||
|
||||
// Check if the file has the old version stamp
|
||||
oldVersionStamp := fmt.Sprintf("bd v%s", previousVersion)
|
||||
currentVersionStamp := fmt.Sprintf("bd v%s", Version)
|
||||
|
||||
if containsSubstring(header, oldVersionStamp) && !containsSubstring(header, currentVersionStamp) {
|
||||
// BD_GUIDE.md is outdated
|
||||
fmt.Printf("📄 BD_GUIDE.md is outdated (v%s → v%s)\n", previousVersion, Version)
|
||||
fmt.Printf("💡 Run 'bd onboard --output .beads/BD_GUIDE.md' to regenerate\n")
|
||||
}
|
||||
}
|
||||
|
||||
// containsSubstring checks if haystack contains needle (case-sensitive)
|
||||
func containsSubstring(haystack, needle string) bool {
|
||||
return len(haystack) >= len(needle) && findSubstring(haystack, needle) >= 0
|
||||
}
|
||||
|
||||
// findSubstring returns the index of needle in haystack, or -1 if not found
|
||||
func findSubstring(haystack, needle string) int {
|
||||
for i := 0; i <= len(haystack)-len(needle); i++ {
|
||||
if haystack[i:i+len(needle)] == needle {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// autoMigrateOnVersionBump automatically migrates the database when CLI version changes.
|
||||
// This function is best-effort - failures are silent to avoid disrupting commands.
|
||||
// Called from PersistentPreRun after daemon check but before opening DB for main operation.
|
||||
|
||||
Reference in New Issue
Block a user