
Jules AI - The (Currently) Free Coding Assistant That Can't Follow Directions But Gets Shit Done
Jules is currently free, so I figured it was worth a try. Of course, I had to find out what I could break.
I wanted to make sure I added everything I could to the Python script I could before moving onto the plugin and added:
You can find the code for that here.
It took me about an hour to update the Python script. I figured I was on a roll. I had working code, and all Claude had to do was convert it to JavaScript and make it an Obsidian plugin. Famous last words. There is always something and many times it is something stupid.
I had updated the Python script in a Claude chat inside of a Claude project, but had yet added any Project Resources. Now that I was going to work on the plugin, I uploaded these there:
And I sent this message:
I have attached a Python script to import apple books annotations. I have also attached the Obsidian plugin sample for reference. I have also attached an article on how an older version of the Python script integrates with Obsidian. Help me create an Obsidian plugin that does the same thing, step by step.
Claude recognized I had sequential thinking MCP and used it right away and came up with a plan.
But I forgot to tell Claude where the project was located, so after that, it spit out all the files in the chat. I quickly corrected that issue by telling it to create all the files in my project itself.
The initial conversion went surprisingly smoothly:
Well, it was functional. But let’s just say I was not even halfway done yet. Also, and I am so tired of this, Claude corrected my name everywhere from “Stephan” to “Stephen”.
Just like Google always does.
No, Google, my name is “Stephan.” But back on track. Here are the issues I ran into after I had a “working” Obsidian plugin.
A big hurdle was database access. Claude initially tried better-sqlite3
but ran into Electron compatibility issues. We switched to sql.js
, a pure JavaScript SQLite implementation, but then faced WebAssembly loading problems.
The solution: Configure sql.js
with proper WASM file handling in the Obsidian environment.
Even after fixing the SQLite library, we had issues with SQL query formatting when passed to the command line. Claude described the approach as “bulletproof” right before it broke, which became a running theme.
One book showed chapters as “Ahr5106 us trade bbp text 2” instead of readable names. This required Claude to revisit the CFI parsing logic and ensure consistency with the Python version. This is still a challenge and I am going to do research before I try to fix this.
It was now two hours since I started revising the original Python script. The Python script used ebooklib
to extract book covers and enhanced metadata. Finding a JavaScript equivalent proved challenging. And I was a little gun shy by now, so I asked:
Is there anything in JavaScript that will do the same thing the python script did with
ebooklib
, like get the cover image and other metadata? If you know of something, do not commit code until I say it is working. It works now and I don’t want to commit broken code.
Claude suggested three options, and I chose epub2
for its popularity and feature set. However, it took several rounds of debugging across multiple chat sessions to get ePub parsing working correctly.
Testing on my actual Apple Books account (with 4,711 book) shook some new bugs loose:
The plugin tried to query columns that didn’t exist on my primary account, causing SQLite errors. The Python script handled this gracefully, but the plugin needed updates.
With thousands of books, we hit “maxBuffer length exceeded” errors. Claude implemented chunked processing to handle large datasets.
The plugin kept breaking up annotations that should have been together and duplicating others. This took six rounds of debugging, with Claude repeatedly missing the fact that the Python version worked perfectly.
I finally resorted to extended thinking:
Think as hard as you can about the fact that the Python script is working, and the plugin is not and the only thing happening is SQLite queries and handling the results, so this should be fucking simple.
Total development time: About 6 hours across multiple sessions, with Claude handling the bulk of the coding.
I am happy with the results. There is still some more work to do:
But for now I can use it and when I fix it, just have it overwrite all the old files. Then, once I am happy with it, store a hash of the file in properties or something like that and have overwriting work more intelligently.
I do plan on releasing this as a community plugin. I just want to use it a while to see if there are any more bugs I want to fix or features I want to add.
But for now the simplest way to install and test this plugin is with BRAT (Beta Reviewer’s Auto-update Tool):
https://github.com/eristoddle/obsidian-apple-books-import
latest
version from the dropdown.I took a break from a more complex project for a day to see if I could finish a smaller one. And even though there is still more work to do here, I think it was a success and an excellent test. I will continue to explore new ways of making the “vibe coding” process go smoother. In the couple of days that it took me to write this, I found even more tools to help.
Because I have no end of software ideas I have been collecting, but never got to, because I never had the time. So I will continue to work on my main vibe-coding project while taking a break to test new ways of doing this on smaller projects. My next post should be about the next set of things I learned developing an Electron app with Claude Code. I already have notes on it, but wanted to try this first.