package main import ( "database/sql" "fmt" "os" "path/filepath" "time" "git.wntrmute.dev/kyle/mcp/internal/config" "github.com/spf13/cobra" _ "modernc.org/sqlite" ) func snapshotCmd() *cobra.Command { return &cobra.Command{ Use: "snapshot", Short: "Create a database backup", RunE: func(cmd *cobra.Command, args []string) error { cfg, err := config.LoadAgentConfig(cfgPath) if err != nil { return fmt.Errorf("load config: %w", err) } backupDir := filepath.Join(filepath.Dir(cfg.Database.Path), "backups") if err := os.MkdirAll(backupDir, 0750); err != nil { return fmt.Errorf("create backup dir: %w", err) } ts := time.Now().Format("20060102-150405") backupPath := filepath.Join(backupDir, fmt.Sprintf("mcp-%s.db", ts)) db, err := sql.Open("sqlite", cfg.Database.Path) if err != nil { return fmt.Errorf("open database: %w", err) } defer func() { _ = db.Close() }() //nolint:gosec // backupPath is derived from config + timestamp, not user input; VACUUM INTO does not support placeholders if _, err := db.Exec("VACUUM INTO '" + backupPath + "'"); err != nil { return fmt.Errorf("vacuum into: %w", err) } fmt.Printf("snapshot: %s\n", backupPath) return nil }, } }