Alejozen cli start

  • #projects
  • #research

Context

Once I started to use org-roam to register my notes, and focus on my personal projects, I resolved that it would be amaxing to register my learnings in a personal blog. My plan is to use the blog as a way to share with other people my thoughts, and learn more about tools like astro (which I use to back my blog site). I want a way to be able to automate the transformation of the notes into blog posts.

Insights

I’ve been using org-roam for some time. I’m not particularly good at recording everything I do, but I’ve developed a system that integrates smoothly into my worlflow. I use doom emacs for programming in clojure, java and scala (mostly clojure to be honest). Sometime ago I was watching a youtube video about org-roam and thought it was really nice to give it a go. The org-roam system is based on notes, which can be linked with one another, forming a sort of graph. I’m not an expert in the inner workings of the org-roam system, but hope to learn more with this project.

Shortly after, I decided to post my notes in a blog. One reason was that I wanted to learn more about how to use AI tools for programming, and a blog seems a good vibe code project. I’m not the best designer, but would like to start getting more involved into frontent. Another reason is that I’ve really enjoyed learning from other peoples blog how to code, discover about programming languages, and just start sharing some thoughts. The main problem is that I don’t want to write twice, because I’m lazy. So I like to port my org-roam notes directly as blog posts automatically. Purists may say that the roam note taking system is not suposed to have large nodes, and that each node should correspond to a concept, etc. I’ll keep using org-roam beacause it is a convenient way to keep track of my work and notes, that requires little cognitive effort to handle. If my notes are long blog posts, I don’t care for now.

To solve this problem, and also to learn more about clis, I decided to create one to automate the process. So the flow I envision is more or less like this. The cli would allow me to:

  • Port a single org-roam note as a blog post
  • Commit a blog post to my blog repo
  • Push a commit and create an standard PR

With this, I’m more than happy for now. I’m vibe coding the website so that it looks nice. The blog posts should be ported as astro markdown, since that is the framework I’m using, and should be all located in the content/blog dir of the repo.

The basic cli skeleton

Okay. So I decided to use babashka to create the cli, mostly because I love clojure, and have used babashka in my work. I’ve found that TDD is a very productive approach when developing complex logic that have a clear validation process. So I set up the cli with testing tasks. I will focus testing coverage on pure logic functions, and omit E2E testing for now. I’ve discovered in the past some amazing tools to create beautiful clis in clojure so I’ll list them here for brevity:

  • hlship/cli-tools: an amazing open source package to handle clis. Adds documentation, nested commands, and even input schema validation.
  • clj-commons/pretty: because I want pretty print in my terminal. A cli without color is a cli without soul. And I cannot allow that.
  • nubank/matcher-combinators: For testing. It allows me to focus my tests in what matters.
  • cognitect-labs/test-runner: I’m a lazy person and didn’t want to build my own babashka test runner.

With that in mind, here is an starter bb.edn

clojure
{:paths   ["src"]
 :deps    {io.github.hlship/cli-tools           {:mvn/version "1.0.3"}
           org.clj-commons/pretty               {:mvn/version "3.8.0"}
           mvxcvi/puget                         {:mvn/version "1.3.4"}
           nubank/matcher-combinators           {:mvn/version "3.11.0"}
           io.github.cognitect-labs/test-runner {:git/tag "v0.5.1"
                                                 :git/sha "dfb30dd"}}
 :tasks   {test:unit        {:doc      "Run unit tests"
                             :extra-paths ["test"]
                             :requires ([cognitect.test-runner.api :as tr])
                             :task     (tr/test {:dir ["test/unit"]})}}}

And here is the basic file structure of the project

text
├── bb.edn
├── resources
│   └── secrets
│       └── org-roam.edn
├── src
│   └── notes
│       ├── commands
│       ├── helpers
│       │   └── org_roam_db.clj
│       └── logic
│           └── core.clj
└── test
    └── unit
        └── notes
            └── logic
                └── core_test.clj

The file structure was generated manually by myself with a little help from gemini. I dare say that for some basic stuff I resort to AI. For more long term goals and fun logic functions, I use my actual brain though. I’ll discuss the meat of the project in the future. For now, this has been a long note. Too long for an org-roam systems some may say.

Related Resources