As an electrical engineer, I always enjoyed dabbling in programming, but comfortably outsourced it once an implementation needed real solutions. Then AI popped up and started making software accessible. Claude Code, Cursor, Codex, Gemini CLI, all these tools lived in my projects. I could collaborate with them, and I was having a blast innovating and creating features! I really enjoyed solving the problems and learning about software as I did side project after side project. I scaffolded my own llama.cpp dashboard to manage and deploy my local models. Built a Hebbian Graph to approximate a memory layer. I codified calculations I used at work every day in a CLI tool. Each project as stimulating as the last. Then I tried to ship my first project. It was a simple LLM wrapper for a company to use as an internal chatbot. Shipping a real project took far more work than a personal one, and it required real engineering and effort. I shipped a product I was proud of, but it exposed 2 issues that I had to coin terms for that took me from overjoyed to despaired.
Siloed Solutions: Projects had carefully crafted and hard earned solutions resting in them. There was almost no clean way to extract the logic out for reuse in a later project without breaking some important business rules in the journey and Iād pay a reimplementation tax. In my LLM wrapper I spent over 30 hours fine tuning certain solutions and when I went to use it again in a new project, it was going to take similar leg work.
Redundant Tokens: I could only redo the same backend infrastructure in projects before I started pulling my hair out. I was constantly using tokens on the same websocket implementations.
I felt like a mouse on a wheel. Like I would be spinning forever and explaining to Claude for the 50th time how I wanted my designs to operate and look.
So... I chose to solve my problem.
I knew about prompting, skills, MCPs, and things like progressive disclosure were helpful to some people. However, every time I asked myself whether I'd trust those to be my quality layer for shipping an enterprise solution, the answer was an immediate NO. I needed to know my business logic was exactly the same as my last project so that all my debugging wins would be reflected. My engineering practice taught me to perceive unknowns as wrongs, and vibe coding was producing a lot of unknowns that I couldn't justify as waiting for testing.
I decided to start thinking about how I could copy code around in a controlled manner. I settled on a widget based design. This meant every previously siloed solution could be packaged into a widget, and a single command could install it into my project instead of asking the LLM to rewrite it.
Cartograph
Out of all the frustration came the inception of Cartograph. An agent first CLI tool that I use daily to help manage my AI written code. The engine itself is written in Python, but its applications are language agnostic. It already supports multiple languages of differing domains from SystemVerilog to JavaScript. Currently it requires a decent amount of manual drive since the models don't know about the tool. There is a built setup command that will print the command list and instructions for an agent to utilize the tool.
Cartograph Github (MIT License)
What is a widget in Cartograph?
A widget is a reusable code module with tests, examples, metadata, and declared dependencies. Each widget is self-contained and language-specific. This is an example of a python widget that is scaffolded with a cartograph create "retry backoff" --language python --domain backend
cg/backend_retry_backoff_python/
widget.json # metadata, version, dependencies
src/ # source code
tests/ # test files must pass
examples/
example_usage.py # must run successfully
What makes it tick?
Validation. Widget.json will show some general rules for how the widget needs to be constructed. Once the agent is done creating the widget, it will run cartograph validate backend_retry_backoff_python and it will run through a validation engine that both ensures the code runs cleanly if possible and doesn't contain contamination like API keys or print statements. If a language has hard opinions on certain items it will also scan for those. A widget is not allowed to be checked in to your storage unless it passes validation and receives a validation stamp. When ready use the cartograph checkin <id>.
Search. Once a widget is checked in, to use it again anywhere else its a command away. cartograph search "backoff" will retrieve the widget.json info using a hybrid TF-IDF and n-gram search. Then just a simple cartograph install <id> and it will automatically go to the /cg directory for use in your project.
What if I want to improve my widget?
Every widget.json carries a version with it. When you make changes to your widget and check it back in, Cartograph handles the bumping of the version for the agent and your improvements get checked in with a forced commit message for what changed.
What if I want validation beyond the base rules?
Cartograph provides a solid baseline focused on making sure widgets are runnable and free of obvious issues. If you need stricter checks, you can add custom rules that run after the built-in validation. These rules are written in the widgets native language when applicable and can emit warnings or blocks.
Where I am now
I've been using Cartograph daily for weeks. My registry has grown to 200+ widgets across Python, JavaScript, Nim, SystemVerilog, and OpenSCAD. Every project I start now begins with a search instead of a blank file. I love telling my AI agents to remember that the logic it writes should be encompassed in a widget. The mouse on the wheel is gone. Cartograph is free and open source, and it will stay that way.
I have setup a basic free cloud layer as well that I publish all my widgets to. You will have access to these widgets for free on install! Please note it is still early so expect some hiccups. If you would like to publish your own widgets to the cloud you can sign in with a Google Account using the CLI.
If it solves the same problem for you that it solved for me, I hope you try it. Please let me know if you hit any edge cases! I would love to keep sharpening the tool so it's usable for everyone.

Top comments (0)