feat: Add built-in version tracking to bd (bd-loka)
Implement automatic bd version tracking and upgrade awareness: - Add LastBdVersion field to Config struct in metadata.json - Auto-update version on every bd command in PersistentPreRun - Add 'bd upgrade' command with status/review/ack subcommands - Show upgrade notifications on 'bd ready' and 'bd list' - Non-intrusive: only shows once per session, skipped for JSON output The system tracks version changes automatically and helps users stay aware of bd upgrades without manual intervention. Notifications are graceful - failures don't break commands. Example output on bd ready after upgrade: 🔄 bd upgraded from v0.22.0 to v0.24.2 since last use 💡 Run 'bd upgrade review' to see what changed 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -528,7 +528,11 @@
|
||||
{"id":"bd-la9d","content_hash":"298e5922cb0e6460d1cf14d2b7230c63403e72fcb511fb31d3fe2e2f241fd18a","title":"Blocking issue","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-20T19:43:48.758706-05:00","updated_at":"2025-11-20T19:43:48.758706-05:00","closed_at":"2025-11-07T21:55:09.43148-08:00","source_repo":"."}
|
||||
{"id":"bd-lln","content_hash":"650962c39553fb85e797c10044f4f1d89b6311855c7727c3f82c49dfea2ced97","title":"Add tests for performFlush error handling in FlushManager","description":"Test coverage gap identified by automated analysis (vc-217).\n\n**Original Issue:** [deleted:bd-da96-baseline-lint]\n\nIn cmd/bd/flush_manager.go:269, the performFlush method is flagged by unparam as always returning nil, indicating the error return value is never used.\n\nAdd tests to determine:\n- Whether performFlush can actually return errors in failure scenarios\n- If error return is needed, add tests for error cases (disk full, permission denied, etc.)\n- If error return is not needed, refactor to remove unused return value\n- Test full export vs incremental export error handling\n\nThis ensures proper error handling in the flush mechanism and removes dead code if the return value is unnecessary.\n\n_This issue was automatically created by AI test coverage analysis._","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-21T10:25:33.533653-05:00","updated_at":"2025-11-23T16:30:02.403576-08:00","closed_at":"2025-11-21T19:31:21.876949-05:00","source_repo":".","labels":["discovered:supervisor"],"dependencies":[{"issue_id":"bd-lln","depends_on_id":"bd-da96-baseline-lint","type":"discovered-from","created_at":"2025-11-21T10:25:33.534913-05:00","created_by":"ai-supervisor"}]}
|
||||
{"id":"bd-lm2q","content_hash":"e26fa6c461610f000935fb4ccd62239dd3ac22b5b1d2f0b440418f6e06551a4a","title":"Fix `bd sync` failure due to daemon auto-export timestamp skew","description":"`bd sync` fails with false-positive \"JSONL is newer than database\" after daemon auto-export.\nRoot Cause: Daemon exports local changes to JSONL, updating its timestamp. `bd sync` sees JSONL.mtime \u003e DB.mtime and assumes external changes, blocking export.\nProposed Fixes:\n1. `bd sync` auto-imports if timestamp matches but content differs (or just auto-imports).\n2. Content-based comparison instead of timestamp only.\n","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-20T18:56:16.876685-05:00","updated_at":"2025-11-20T22:02:51.641709-05:00","closed_at":"2025-11-20T20:54:39.512574-05:00","source_repo":"."}
|
||||
{"id":"bd-loka","content_hash":"d4df7667c0ec5387e9ff679b4dad73497dddfa4e5431ed4e0a1b7e0d09b386f8","title":"Add built-in version tracking to bd","description":"Enhance bd to automatically track its own version in metadata.json and detect upgrades.\n\n## Features to Implement\n1. Auto-update metadata.json with 'last_bd_version' field on every bd command\n2. Add 'bd upgrade status' - check if version changed since last run\n3. Add 'bd upgrade review' - show what's new since last-seen version (not just last 3)\n4. Add 'bd upgrade ack' - mark current version as acknowledged\n5. Smart detection output when version changes (show hint on bd ready, bd list, etc.)\n\n## Implementation Details\n- Store last_bd_version in metadata.json\n- Store last_version_check timestamp\n- Compare on every bd command (cached check, low overhead)\n- Only show notification once per session until ack'd\n\n## Example Output\n```\n$ bd ready\n🔄 bd upgraded from v0.23.0 to v0.24.2 since last use\n💡 Run 'bd upgrade review' to see what changed\n\nReady work: 5 issues\n...\n```\n\n## Acceptance Criteria\n- Version automatically tracked in metadata.json\n- Upgrade detection works across sessions\n- New bd upgrade subcommands functional\n- Non-intrusive notifications (show once, then quiet)\n","status":"open","priority":2,"issue_type":"feature","created_at":"2025-11-23T16:21:53.951611-08:00","updated_at":"2025-11-23T16:21:53.951611-08:00","source_repo":".","dependencies":[{"issue_id":"bd-loka","depends_on_id":"bd-nxgk","type":"parent-child","created_at":"2025-11-23T16:21:53.952998-08:00","created_by":"daemon"}]}
|
||||
{"id":"bd-loka","content_hash":"0898de8b6e263e7b84a67486cfae375ee0f5b8716bfa81934784d6f599bd9fc6","title":"Add built-in version tracking to bd","description":"Enhance bd to automatically track its own version in metadata.json and detect upgrades.\n\n## Features to Implement\n1. Auto-update metadata.json with 'last_bd_version' field on every bd command\n2. Add 'bd upgrade status' - check if version changed since last run\n3. Add 'bd upgrade review' - show what's new since last-seen version (not just last 3)\n4. Add 'bd upgrade ack' - mark current version as acknowledged\n5. Smart detection output when version changes (show hint on bd ready, bd list, etc.)\n\n## Implementation Details\n- Store last_bd_version in metadata.json\n- Store last_version_check timestamp\n- Compare on every bd command (cached check, low overhead)\n- Only show notification once per session until ack'd\n\n## Example Output\n```\n$ bd ready\n🔄 bd upgraded from v0.23.0 to v0.24.2 since last use\n💡 Run 'bd upgrade review' to see what changed\n\nReady work: 5 issues\n...\n```\n\n## Acceptance Criteria\n- Version automatically tracked in metadata.json\n- Upgrade detection works across sessions\n- New bd upgrade subcommands functional\n- Non-intrusive notifications (show once, then quiet)\n","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-11-23T16:21:53.951611-08:00","updated_at":"2025-11-23T17:06:34.003365-08:00","closed_at":"2025-11-23T17:06:34.003365-08:00","source_repo":".","dependencies":[{"issue_id":"bd-loka","depends_on_id":"bd-nxgk","type":"parent-child","created_at":"2025-11-23T16:21:53.952998-08:00","created_by":"daemon"}]}
|
||||
{"id":"bd-loka.1","content_hash":"ad9d4a6834bd8f787621c554822a2304ba0cf1dd7f13089085672058409d7432","title":"Add LastBdVersion field to Config struct","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-23T16:56:27.336668-08:00","updated_at":"2025-11-23T16:56:52.180512-08:00","closed_at":"2025-11-23T16:56:52.180512-08:00","source_repo":".","dependencies":[{"issue_id":"bd-loka.1","depends_on_id":"bd-loka","type":"parent-child","created_at":"2025-11-23T16:56:27.337232-08:00","created_by":"daemon"}]}
|
||||
{"id":"bd-loka.2","content_hash":"870d024d456a8a463619c6cb6e26c7ebd3d7dbd58a038fd89b15077d919dca31","title":"Add version tracking in PersistentPreRun","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-23T16:56:28.680947-08:00","updated_at":"2025-11-23T16:58:25.180851-08:00","closed_at":"2025-11-23T16:58:25.180851-08:00","source_repo":".","dependencies":[{"issue_id":"bd-loka.2","depends_on_id":"bd-loka","type":"parent-child","created_at":"2025-11-23T16:56:28.681524-08:00","created_by":"daemon"}]}
|
||||
{"id":"bd-loka.3","content_hash":"9816a590930f1fbf48077fb6362e987347443f728c830c44c87ca6950ef64f21","title":"Implement bd upgrade subcommand with status/review/ack","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-23T16:56:29.849527-08:00","updated_at":"2025-11-23T17:02:54.925905-08:00","closed_at":"2025-11-23T17:02:54.925905-08:00","source_repo":".","dependencies":[{"issue_id":"bd-loka.3","depends_on_id":"bd-loka","type":"parent-child","created_at":"2025-11-23T16:56:29.850054-08:00","created_by":"daemon"}]}
|
||||
{"id":"bd-loka.4","content_hash":"1981f4fe3828de02f941a2ad3601582b866a76148fa8bd90cba29e36695a3bc0","title":"Add upgrade notification system to bd ready/list","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-23T16:56:31.227711-08:00","updated_at":"2025-11-23T17:06:31.830726-08:00","closed_at":"2025-11-23T17:06:31.830726-08:00","source_repo":".","dependencies":[{"issue_id":"bd-loka.4","depends_on_id":"bd-loka","type":"parent-child","created_at":"2025-11-23T16:56:31.228284-08:00","created_by":"daemon"}]}
|
||||
{"id":"bd-lwnt","content_hash":"ddfa247870eb3734ffa7a4d0da6fcd4a359d2b48e02d70aad8560ec4bc13afdc","title":"Test P1 priority","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-05T12:58:38.074112-08:00","updated_at":"2025-11-05T12:58:44.711763-08:00","closed_at":"2025-11-05T12:58:44.711763-08:00","source_repo":"."}
|
||||
{"id":"bd-m0w","content_hash":"e8641e225f1d4cf13fbd97c4a83046e3597df180d3ee134125e4a35abc6941cd","title":"Add test coverage for internal/validation package","description":"","design":"Validation package has 1 test file. Critical for data integrity. Target: 80% coverage","acceptance_criteria":"- At least 4 test files\n- Package coverage \u003e= 80%\n- Tests cover all validation rules","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-20T21:21:24.129559-05:00","updated_at":"2025-11-20T21:21:24.129559-05:00","source_repo":".","dependencies":[{"issue_id":"bd-m0w","depends_on_id":"bd-ge7","type":"blocks","created_at":"2025-11-20T21:21:31.350477-05:00","created_by":"daemon"}]}
|
||||
{"id":"bd-m62x","content_hash":"45ec0b71d12d639a662267e71bc8febd4c90c6abce22de4795ea949fb6d204ae","title":"Benchmark Suite for Critical Operations","description":"Extend existing benchmark suite with comprehensive benchmarks for critical operations at 10K-20K scale.\n\nExisting benchmarks (keep these):\n- cycle_bench_test.go - Cycle detection up to 5K issues (linear, tree, dense graphs)\n- compact_bench_test.go - Compaction candidate queries (100 issues)\n- internal/rpc/bench_test.go - Daemon vs direct mode comparison\n\nNew benchmarks to add in sqlite_bench_test.go (~10-12 total):\n1. GetReadyWork - Simple, deep hierarchies, cross-linked (CRITICAL - not currently benchmarked)\n2. SearchIssues - No filters, complex filters (CRITICAL - not currently benchmarked)\n3. CreateIssue - Single issue creation\n4. UpdateIssue - Status/priority/assignee changes\n5. AddDependency - Extend to 10K/20K scale (currently only up to 5K)\n6. JSONL Export - Full export performance\n7. JSONL Import - Import performance\n\nScale levels:\n- Large: 10K issues (5K open, 5K closed)\n- XLarge: 20K issues (10K open, 10K closed)\n\nImplementation:\n- NEW FILE: internal/storage/sqlite/sqlite_bench_test.go\n- Keep existing cycle_bench_test.go and compact_bench_test.go unchanged\n- Build tag: //go:build bench\n- Standard testing.B benchmarks\n- b.ReportAllocs() for memory tracking\n- Test both SQLite and JSONL-imported databases\n\nAlways generates CPU and memory profiles for analysis.","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-11-13T22:22:43.770787-08:00","updated_at":"2025-11-13T23:15:33.781023-08:00","closed_at":"2025-11-13T23:15:33.781023-08:00","source_repo":".","dependencies":[{"issue_id":"bd-m62x","depends_on_id":"bd-q13h","type":"blocks","created_at":"2025-11-13T22:24:02.668091-08:00","created_by":"daemon"},{"issue_id":"bd-m62x","depends_on_id":"bd-zj8e","type":"blocks","created_at":"2025-11-13T22:24:06.30131-08:00","created_by":"daemon"}]}
|
||||
|
||||
@@ -301,6 +301,9 @@ var listCmd = &cobra.Command{
|
||||
return
|
||||
}
|
||||
|
||||
// Show upgrade notification if needed (bd-loka)
|
||||
maybeShowUpgradeNotification()
|
||||
|
||||
var issues []*types.Issue
|
||||
if err := json.Unmarshal(resp.Data, &issues); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error parsing response: %v\n", err)
|
||||
@@ -400,6 +403,9 @@ var listCmd = &cobra.Command{
|
||||
return
|
||||
}
|
||||
|
||||
// Show upgrade notification if needed (bd-loka)
|
||||
maybeShowUpgradeNotification()
|
||||
|
||||
// Load labels in bulk for display
|
||||
issueIDs := make([]string, len(issues))
|
||||
for i, issue := range issues {
|
||||
|
||||
@@ -83,6 +83,11 @@ var (
|
||||
|
||||
// Auto-import state
|
||||
autoImportEnabled = true // Can be disabled with --no-auto-import
|
||||
|
||||
// Version upgrade tracking (bd-loka)
|
||||
versionUpgradeDetected = false // Set to true if bd version changed since last run
|
||||
previousVersion = "" // The last bd version user had (empty = first run or unknown)
|
||||
upgradeAcknowledged = false // Set to true after showing upgrade notification once per session
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -293,6 +298,10 @@ var rootCmd = &cobra.Command{
|
||||
}
|
||||
}
|
||||
|
||||
// Track bd version changes (bd-loka)
|
||||
// Best-effort tracking - failures are silent
|
||||
trackBdVersion()
|
||||
|
||||
// Initialize daemon status
|
||||
socketPath := getSocketPath()
|
||||
daemonStatus = DaemonStatus{
|
||||
|
||||
@@ -75,6 +75,10 @@ var readyCmd = &cobra.Command{
|
||||
outputJSON(issues)
|
||||
return
|
||||
}
|
||||
|
||||
// Show upgrade notification if needed (bd-loka)
|
||||
maybeShowUpgradeNotification()
|
||||
|
||||
if len(issues) == 0 {
|
||||
yellow := color.New(color.FgYellow).SprintFunc()
|
||||
fmt.Printf("\n%s No ready work found (all issues have blocking dependencies)\n\n",
|
||||
@@ -131,6 +135,9 @@ var readyCmd = &cobra.Command{
|
||||
outputJSON(issues)
|
||||
return
|
||||
}
|
||||
// Show upgrade notification if needed (bd-loka)
|
||||
maybeShowUpgradeNotification()
|
||||
|
||||
if len(issues) == 0 {
|
||||
yellow := color.New(color.FgYellow).SprintFunc()
|
||||
fmt.Printf("\n%s No ready work found (all issues have blocking dependencies)\n\n",
|
||||
|
||||
215
cmd/bd/upgrade.go
Normal file
215
cmd/bd/upgrade.go
Normal file
@@ -0,0 +1,215 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/steveyegge/beads/internal/beads"
|
||||
"github.com/steveyegge/beads/internal/configfile"
|
||||
)
|
||||
|
||||
var upgradeCmd = &cobra.Command{
|
||||
Use: "upgrade",
|
||||
Short: "Check and manage bd version upgrades",
|
||||
Long: `Commands for checking bd version upgrades and reviewing changes.
|
||||
|
||||
The upgrade command helps you stay aware of bd version changes:
|
||||
- bd upgrade status: Check if bd version changed since last use
|
||||
- bd upgrade review: Show what's new since your last version
|
||||
- bd upgrade ack: Acknowledge the current version
|
||||
|
||||
Version tracking is automatic - bd updates metadata.json on every run.`,
|
||||
}
|
||||
|
||||
var upgradeStatusCmd = &cobra.Command{
|
||||
Use: "status",
|
||||
Short: "Check if bd version has changed",
|
||||
Long: `Check if bd has been upgraded since you last used it.
|
||||
|
||||
This command uses the version tracking that happens automatically
|
||||
at startup to detect if bd was upgraded.
|
||||
|
||||
Examples:
|
||||
bd upgrade status
|
||||
bd upgrade status --json`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
// Use in-memory state from trackBdVersion() which runs in PersistentPreRun
|
||||
if jsonOutput {
|
||||
result := map[string]interface{}{
|
||||
"upgraded": versionUpgradeDetected,
|
||||
"current_version": Version,
|
||||
}
|
||||
if versionUpgradeDetected {
|
||||
result["previous_version"] = previousVersion
|
||||
result["changes_available"] = len(getVersionsSince(previousVersion)) > 0
|
||||
}
|
||||
outputJSON(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Human-readable output
|
||||
if versionUpgradeDetected {
|
||||
fmt.Printf("✨ bd upgraded from v%s to v%s\n", previousVersion, Version)
|
||||
newVersions := getVersionsSince(previousVersion)
|
||||
if len(newVersions) > 0 {
|
||||
fmt.Printf(" %d version%s with changes available\n",
|
||||
len(newVersions),
|
||||
pluralize(len(newVersions)))
|
||||
fmt.Println()
|
||||
fmt.Println("Run 'bd upgrade review' to see what changed")
|
||||
}
|
||||
} else if previousVersion == "" {
|
||||
fmt.Printf("bd version: v%s (first run or version tracking just enabled)\n", Version)
|
||||
} else {
|
||||
fmt.Printf("bd version: v%s (no upgrade detected)\n", Version)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
var upgradeReviewCmd = &cobra.Command{
|
||||
Use: "review",
|
||||
Short: "Review changes since last bd version",
|
||||
Long: `Show what's new in bd since the last version you used.
|
||||
|
||||
Unlike 'bd info --whats-new' which shows the last 3 versions,
|
||||
this command shows ALL changes since your specific last version.
|
||||
|
||||
If you're upgrading from an old version, you'll see the complete
|
||||
changelog of everything that changed since then.
|
||||
|
||||
Examples:
|
||||
bd upgrade review
|
||||
bd upgrade review --json`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
// Use in-memory state from trackBdVersion() which runs in PersistentPreRun
|
||||
lastVersion := previousVersion
|
||||
|
||||
if lastVersion == "" {
|
||||
fmt.Println("No previous version recorded")
|
||||
fmt.Println("Run 'bd info --whats-new' to see recent changes")
|
||||
return
|
||||
}
|
||||
|
||||
if !versionUpgradeDetected {
|
||||
fmt.Printf("You're already on v%s (no upgrade detected)\n", Version)
|
||||
fmt.Println("Run 'bd info --whats-new' to see recent changes")
|
||||
return
|
||||
}
|
||||
|
||||
newVersions := getVersionsSince(lastVersion)
|
||||
|
||||
if jsonOutput {
|
||||
outputJSON(map[string]interface{}{
|
||||
"current_version": Version,
|
||||
"previous_version": lastVersion,
|
||||
"new_versions": newVersions,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Human-readable output
|
||||
fmt.Printf("\n🔄 Upgraded from v%s to v%s\n", lastVersion, Version)
|
||||
fmt.Println(strings.Repeat("=", 60))
|
||||
fmt.Println()
|
||||
|
||||
if len(newVersions) == 0 {
|
||||
fmt.Printf("v%s is newer than v%s but not in changelog\n", Version, lastVersion)
|
||||
fmt.Println("Run 'bd info --whats-new' to see recent documented changes")
|
||||
return
|
||||
}
|
||||
|
||||
for _, vc := range newVersions {
|
||||
versionMarker := ""
|
||||
if vc.Version == Version {
|
||||
versionMarker = " ← current"
|
||||
}
|
||||
|
||||
fmt.Printf("## v%s (%s)%s\n\n", vc.Version, vc.Date, versionMarker)
|
||||
|
||||
for _, change := range vc.Changes {
|
||||
fmt.Printf(" • %s\n", change)
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
fmt.Println("💡 Run 'bd upgrade ack' to mark this version as seen")
|
||||
fmt.Println()
|
||||
},
|
||||
}
|
||||
|
||||
var upgradeAckCmd = &cobra.Command{
|
||||
Use: "ack",
|
||||
Short: "Acknowledge the current bd version",
|
||||
Long: `Mark the current bd version as acknowledged.
|
||||
|
||||
This updates metadata.json to record that you've seen the current
|
||||
version. Mainly useful after reviewing upgrade changes to suppress
|
||||
future upgrade notifications.
|
||||
|
||||
Note: Version tracking happens automatically, so you don't need to
|
||||
run this command unless you want to explicitly mark acknowledgement.
|
||||
|
||||
Examples:
|
||||
bd upgrade ack
|
||||
bd upgrade ack --json`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
beadsDir := beads.FindBeadsDir()
|
||||
if beadsDir == "" {
|
||||
fmt.Println("Error: No .beads directory found")
|
||||
return
|
||||
}
|
||||
|
||||
cfg, err := configfile.Load(beadsDir)
|
||||
if err != nil {
|
||||
fmt.Printf("Error loading metadata.json: %v\n", err)
|
||||
return
|
||||
}
|
||||
if cfg == nil {
|
||||
cfg = configfile.DefaultConfig()
|
||||
}
|
||||
|
||||
previousVersion := cfg.LastBdVersion
|
||||
cfg.LastBdVersion = Version
|
||||
|
||||
if err := cfg.Save(beadsDir); err != nil {
|
||||
fmt.Printf("Error saving metadata.json: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Mark as acknowledged in current session
|
||||
upgradeAcknowledged = true
|
||||
versionUpgradeDetected = false
|
||||
|
||||
if jsonOutput {
|
||||
outputJSON(map[string]interface{}{
|
||||
"acknowledged": true,
|
||||
"current_version": Version,
|
||||
"previous_version": previousVersion,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if previousVersion == Version {
|
||||
fmt.Printf("✓ Already on v%s\n", Version)
|
||||
} else if previousVersion == "" {
|
||||
fmt.Printf("✓ Acknowledged bd v%s\n", Version)
|
||||
} else {
|
||||
fmt.Printf("✓ Acknowledged upgrade from v%s to v%s\n", previousVersion, Version)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
func pluralize(count int) string {
|
||||
if count == 1 {
|
||||
return ""
|
||||
}
|
||||
return "s"
|
||||
}
|
||||
|
||||
func init() {
|
||||
upgradeCmd.AddCommand(upgradeStatusCmd)
|
||||
upgradeCmd.AddCommand(upgradeReviewCmd)
|
||||
upgradeCmd.AddCommand(upgradeAckCmd)
|
||||
rootCmd.AddCommand(upgradeCmd)
|
||||
}
|
||||
103
cmd/bd/version_tracking.go
Normal file
103
cmd/bd/version_tracking.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/steveyegge/beads/internal/beads"
|
||||
"github.com/steveyegge/beads/internal/configfile"
|
||||
)
|
||||
|
||||
// trackBdVersion checks if bd version has changed since last run and updates metadata.json.
|
||||
// This function is best-effort - failures are silent to avoid disrupting commands.
|
||||
// Sets global variables versionUpgradeDetected and previousVersion if upgrade detected.
|
||||
//
|
||||
// bd-loka: Built-in version tracking for upgrade awareness
|
||||
func trackBdVersion() {
|
||||
// Find the beads directory
|
||||
beadsDir := beads.FindBeadsDir()
|
||||
if beadsDir == "" {
|
||||
// No .beads directory found - this is fine (e.g., bd init, bd version, etc.)
|
||||
return
|
||||
}
|
||||
|
||||
// Load current config
|
||||
cfg, err := configfile.Load(beadsDir)
|
||||
if err != nil {
|
||||
// Silent failure - config might not exist yet
|
||||
return
|
||||
}
|
||||
if cfg == nil {
|
||||
// No config file yet - create one with current version
|
||||
cfg = configfile.DefaultConfig()
|
||||
cfg.LastBdVersion = Version
|
||||
_ = cfg.Save(beadsDir) // Best effort
|
||||
return
|
||||
}
|
||||
|
||||
// Check if version changed
|
||||
if cfg.LastBdVersion != "" && cfg.LastBdVersion != Version {
|
||||
// Version upgrade detected!
|
||||
versionUpgradeDetected = true
|
||||
previousVersion = cfg.LastBdVersion
|
||||
}
|
||||
|
||||
// Update metadata.json with current version (best effort)
|
||||
// Only write if version actually changed to minimize I/O
|
||||
if cfg.LastBdVersion != Version {
|
||||
cfg.LastBdVersion = Version
|
||||
_ = cfg.Save(beadsDir) // Silent failure is fine
|
||||
}
|
||||
}
|
||||
|
||||
// getVersionsSince returns all version changes since the given version.
|
||||
// If sinceVersion is empty, returns all known versions.
|
||||
// Returns changes in chronological order (oldest first).
|
||||
func getVersionsSince(sinceVersion string) []VersionChange {
|
||||
if sinceVersion == "" {
|
||||
// Return all versions
|
||||
return versionChanges
|
||||
}
|
||||
|
||||
// Find the index of sinceVersion
|
||||
startIdx := -1
|
||||
for i, vc := range versionChanges {
|
||||
if vc.Version == sinceVersion {
|
||||
startIdx = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if startIdx == -1 {
|
||||
// sinceVersion not found in our changelog - return all versions
|
||||
// (user might be upgrading from a very old version)
|
||||
return versionChanges
|
||||
}
|
||||
|
||||
// Return versions after sinceVersion (don't include sinceVersion itself)
|
||||
if startIdx+1 < len(versionChanges) {
|
||||
return versionChanges[startIdx+1:]
|
||||
}
|
||||
|
||||
// No new versions
|
||||
return []VersionChange{}
|
||||
}
|
||||
|
||||
// maybeShowUpgradeNotification displays a one-time upgrade notification if version changed.
|
||||
// This is called by commands like 'bd ready' and 'bd list' to inform users of upgrades.
|
||||
// Returns true if notification was shown.
|
||||
func maybeShowUpgradeNotification() bool {
|
||||
// Only show if upgrade detected and not yet acknowledged
|
||||
if !versionUpgradeDetected || upgradeAcknowledged {
|
||||
return false
|
||||
}
|
||||
|
||||
// Mark as acknowledged so we only show once per session
|
||||
upgradeAcknowledged = true
|
||||
|
||||
// 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")
|
||||
fmt.Println()
|
||||
|
||||
return true
|
||||
}
|
||||
@@ -10,8 +10,9 @@ import (
|
||||
const ConfigFileName = "metadata.json"
|
||||
|
||||
type Config struct {
|
||||
Database string `json:"database"`
|
||||
JSONLExport string `json:"jsonl_export,omitempty"`
|
||||
Database string `json:"database"`
|
||||
JSONLExport string `json:"jsonl_export,omitempty"`
|
||||
LastBdVersion string `json:"last_bd_version,omitempty"`
|
||||
}
|
||||
|
||||
func DefaultConfig() *Config {
|
||||
|
||||
Reference in New Issue
Block a user