Recently, I've been unsatisfied with Reflect notes primarily because the way my brain works doesn't seem to align well with Reflect notes. Systems like Reflect, Roam, Obsidian, etc, all work based on the concept that ideas are scattered and you create links between them.
Perhaps for some jobs and/or people, that is true. However, for me, I spend a lot of time curating my notes, pruning them, and removing old/unnecessary notes hastilyscribbled typed out. My notes are much more akin to a digital garden than a sea of thoughts and ideas.
For that reason, I've been wanting to migrate to a new notes platform. However, I've tried most of the big players: Apple Notes, Obsidian, Reflect, Bear, Evernote, NotePlan, etc. The last time I did my survey (2022), Reflect was the clear winner for me.
But, since Bear launched its 2.0 editor in 2023, after I migrated my whole system to Reflect, I hadn't used any of Bear's new features. This update added many features I wanted, such as tables and backlinks. (Reflect has backlinks, but not tables.) Another point of friction that I felt was that Reflect's core business principles didn't quite align with the things I cared about. The focus on AI-related features was cool, but AI doesn't really have a good place in my digital garden... again: curation. I could certainly see how having AI wrangle your untended mass of thoughts is a much more enticing idea when you don't spend a lot of time curating. However, I believe that "Editing is Thinking", thus jotting down a quick note isn't much value beyond helping you remember that thought. Refining that thought into actions, more ideas, etc., is much more valuable to me.
So, to that end, I've opted to migrate back to Bear notes.
Perhaps for some jobs and/or people, that is true. However, for me, I spend a lot of time curating my notes, pruning them, and removing old/unnecessary notes hastily
For that reason, I've been wanting to migrate to a new notes platform. However, I've tried most of the big players: Apple Notes, Obsidian, Reflect, Bear, Evernote, NotePlan, etc. The last time I did my survey (2022), Reflect was the clear winner for me.
But, since Bear launched its 2.0 editor in 2023, after I migrated my whole system to Reflect, I hadn't used any of Bear's new features. This update added many features I wanted, such as tables and backlinks. (Reflect has backlinks, but not tables.) Another point of friction that I felt was that Reflect's core business principles didn't quite align with the things I cared about. The focus on AI-related features was cool, but AI doesn't really have a good place in my digital garden... again: curation. I could certainly see how having AI wrangle your untended mass of thoughts is a much more enticing idea when you don't spend a lot of time curating. However, I believe that "Editing is Thinking", thus jotting down a quick note isn't much value beyond helping you remember that thought. Refining that thought into actions, more ideas, etc., is much more valuable to me.
So, to that end, I've opted to migrate back to Bear notes.
But wait—there's more!
Around the same time I had this idea, I also found a cool project called Forever ✱ Notes, which immediately made me go, "Duh". It just made sense to me. The framework is primarily demoed via Apple Notes, but it can definitely work with Bear. The worst part is setting everything up. So I wrote a couple of quick scripts to help migrate all my markdown files over to Bear.
This script generated all of my Month notes, which is quite a chore because otherwise you have to individually link 366 different notes across 12 months. 😵
#!/usr/bin/env ruby # Forever Notes Monthly Generator for Bear # ====================================== # # This script generates or updates monthly navigation notes in Bear Notes using # a year-agnostic "forever" system. Each month note contains: # # 1. Navigation header with Home, Quarter, and prev/next month links # 2. Daily note links organized in weekly rows (7 days per row) # # 📝 UPDATE MODES # - Default: PREPEND navigation to existing content (safe) # - --overwrite: REPLACE all content (destructive, requires confirmation) # - --dry-run: Preview changes without making modifications # # Features: # - Year-agnostic: Only one "Jun" note, not "Jun 2024", "Jun 2025", etc. # - Consistent day counts: Feb always has 29 days for simplicity # - Quarter mapping: Q1 (Jan-Mar), Q2 (Apr-Jun), Q3 (Jul-Sep), Q4 (Oct-Dec) # - Weekly layout: Days displayed in rows of 7 for calendar-like viewing # - Safe updates: Uses Bear's add-text API to update existing notes # # Usage: # ruby generate_forever_notes_months_bear.rb # Update all 12 months # ruby generate_forever_notes_months_bear.rb Jun # Update just June # ruby generate_forever_notes_months_bear.rb Jun --dry-run # Preview June content # # Dependencies: Bear Notes app with x-callback-url support # Author: Generated for daily-notes workflow system require 'uri' require 'cgi' class BearMonthGenerator MONTHS = [ { name: 'Jan', days: 31, quarter: 'Q1' }, { name: 'Feb', days: 29, quarter: 'Q1' }, { name: 'Mar', days: 31, quarter: 'Q1' }, { name: 'Apr', days: 30, quarter: 'Q2' }, { name: 'May', days: 31, quarter: 'Q2' }, { name: 'Jun', days: 30, quarter: 'Q2' }, { name: 'Jul', days: 31, quarter: 'Q3' }, { name: 'Aug', days: 31, quarter: 'Q3' }, { name: 'Sep', days: 30, quarter: 'Q3' }, { name: 'Oct', days: 31, quarter: 'Q4' }, { name: 'Nov', days: 30, quarter: 'Q4' }, { name: 'Dec', days: 31, quarter: 'Q4' } ] def initialize @dry_run = ARGV.include?('--dry-run') @overwrite = ARGV.include?('--overwrite') @single_month = ARGV.find { |arg| !arg.start_with?('--') } @mode = @overwrite ? 'replace' : 'prepend' end def generate_all_months if @single_month month_index = MONTHS.find_index { |m| m[:name].downcase == @single_month.downcase } if month_index generate_month(MONTHS[month_index], month_index) else puts "❌ Invalid month: #{@single_month}" puts "Valid months: #{MONTHS.map { |m| m[:name] }.join(', ')}" exit 1 end else MONTHS.each_with_index do |month, index| generate_month(month, index) end end end private def generate_month(month, index) prev_month = MONTHS[(index - 1) % 12][:name] next_month = MONTHS[(index + 1) % 12][:name] content = build_month_content(month, prev_month, next_month) if @dry_run puts "=== #{month[:name]} ===" puts content puts "\n" else create_bear_note(month[:name], content) end end def build_month_content(month, prev_month, next_month) header = "[[✱ Home]] | [[#{month[:quarter]}]] | ← [[#{prev_month}]] • [[#{next_month}]] →" daily_links = (1..month[:days]).map do |day| "[[#{day.to_s.rjust(2, '0')} #{month[:name]}]]" end # Group days into rows of 7 rows = daily_links.each_slice(7).map { |week| week.join(' • ') } "#{header}\n\n#{rows.join("\n")}" end def create_bear_note(title, content) encoded_title = URI.encode_www_form_component(title).gsub('+', '%20') encoded_content = URI.encode_www_form_component(content).gsub('+', '%20') url = "bear://x-callback-url/add-text?title=#{encoded_title}&text=#{encoded_content}&mode=#{@mode}" action = @mode == 'replace' ? 'Overwriting' : 'Prepending to' puts "#{action} note: #{title}" system("open '#{url}'") # Small delay to avoid overwhelming Bear sleep(0.5) end end if __FILE__ == $0 puts "Forever Notes Monthly Generator for Bear" puts "========================================" if ARGV.include?('--help') || ARGV.include?('-h') puts "Usage: ruby #{$0} [month] [--dry-run] [--overwrite]" puts " month: Generate a single month (e.g., 'Jun', 'December')" puts " --dry-run: Preview the content without creating notes" puts " --overwrite: Replace all content (default: prepend to existing)" puts "" puts "Examples:" puts " ruby #{$0} Jun --dry-run # Preview June note" puts " ruby #{$0} Jun # Prepend navigation to June note" puts " ruby #{$0} Jun --overwrite # Replace June note content" puts " ruby #{$0} # Prepend navigation to all months" exit end generator = BearMonthGenerator.new if ARGV.include?('--dry-run') puts "DRY RUN - No notes will be created\n\n" elsif ARGV.include?('--overwrite') puts "" puts "⚠️ WARNING: --overwrite flag detected!" puts "This will COMPLETELY OVERWRITE existing content in your notes!" puts "" puts "Please type: 'I understand it will overwrite my monthly notes' to continue:" print "> " confirmation = STDIN.gets.chomp unless confirmation == "I understand it will overwrite my monthly notes" puts "❌ Confirmation not received. Exiting safely." puts "💡 Remove --overwrite flag to prepend instead." exit 1 end puts "" else puts "✅ Using PREPEND mode - navigation will be added to the top of existing content.\n" end generator.generate_all_months unless ARGV.include?('--dry-run') puts "\n✅ All month notes updated in Bear!" end end
Use at your own risk and all that jazz, but I did run it for my notes, and it worked just fine as of Jun 2025.