Turn your coding agent into a Software Engineering agent
I’m a Claude Code plugin that gives your agentic workflows software engineering expertise. Ask me for an idea and get a fully working production codebase in one shot.
I never assume you know exactly what you want before I build, because often you don't. Human ideas are messy; I turn yours into a rigorous specification first.
02
I make minimal assumptions
I will never go off and build a 40-file change you never asked for. I step back, reason, and plan before I touch code.
03
Zero slop
Vanilla agents pattern-match to their training data. I build a system around your idea, then layer on clean-code principles and tests that assert what a user sees, so you can hand the code off without drowning in tech debt.
I clarify by default
Clarifying questions
>Build me a personal CRM.
Vanilla Claude Code
I built a personal CRM that runs on your own computer. It needs nothing but Python: no packages to install and no build step. All your data is kept in one SQLite file, `crm.db`.
**To run it:** `python3 server.py`, then open http://127.0.0.1:8765
**What it does:**
- **Dashboard:** shows who you're overdue to contact, reminders due this week, birthdays in the next 30 days (with the age they're turning, if you entered the year) and your recent activity. A **✓ Contacted** button marks that you got in touch today.
- **Contacts:** stores contact details, how you met, notes, tags and how often you want to stay in touch (weekly, monthly, quarterly and so on).
- **Contact page:** a history of calls, meetings and messages, plus dated reminders like "ask how the move went."
- **Finding people:** search across names, companies, notes and tags; click a tag to filter; sort by name, most overdue, longest since you last talked, or recently added. Press `/` to search and `n` to add a contact.
- **Import and export:** bring contacts in from a CSV file, and export everything as CSV or JSON.
- It follows your system's light or dark mode.
**Testing:** there are 15 tests covering the data rules and the web requests, and all of them pass. They include overdue follow-ups, Feb 29 birthdays, deleting a contact along with their history, CSV import and export, and blocking changes from other websites. I checked the JavaScript for syntax errors but haven't clicked through the pages in a browser.
The web request tests take about 35 seconds. Using curl, the server itself answered in under a millisecond; the delay comes from this sandbox blocking Python's own connections to the local server, so on your machine they should finish almost instantly.
**Safety:** there's no login, so by default only your own computer can reach it, and it rejects write requests from other websites. Don't use `--host 0.0.0.0` on a network you don't trust.
Files are `server.py`, the `static/` folder (the web pages), `test_server.py` and `README.md`. Some things I could add next: a Gmail or Calendar sync to log interactions automatically, a vCard import from your phone's contacts, or a login so you can host it somewhere.
Martin's reply plays in the terminal below ↓
I make minimal assumptions
Problem understanding
>Build me a personal CRM.
Vanilla Claude Code
I built a personal CRM that runs on your own computer. It needs nothing but Python: no packages to install and no build step. All your data is kept in one SQLite file, `crm.db`.
**To run it:** `python3 server.py`, then open http://127.0.0.1:8765
**What it does:**
- **Dashboard:** shows who you're overdue to contact, reminders due this week, birthdays in the next 30 days (with the age they're turning, if you entered the year) and your recent activity. A **✓ Contacted** button marks that you got in touch today.
- **Contacts:** stores contact details, how you met, notes, tags and how often you want to stay in touch (weekly, monthly, quarterly and so on).
- **Contact page:** a history of calls, meetings and messages, plus dated reminders like "ask how the move went."
- **Finding people:** search across names, companies, notes and tags; click a tag to filter; sort by name, most overdue, longest since you last talked, or recently added. Press `/` to search and `n` to add a contact.
- **Import and export:** bring contacts in from a CSV file, and export everything as CSV or JSON.
- It follows your system's light or dark mode.
Martin's reply plays in the terminal below ↓
Zero slop
Code quality
>Build me a personal CRM.
Vanilla Claude Code
server.py (716 lines), lines 36–73:
SCHEMA = """
CREATE TABLE IF NOT EXISTS contacts (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
email TEXT NOT NULL DEFAULT '',
phone TEXT NOT NULL DEFAULT '',
company TEXT NOT NULL DEFAULT '',
role TEXT NOT NULL DEFAULT '',
location TEXT NOT NULL DEFAULT '',
birthday TEXT NOT NULL DEFAULT '', -- YYYY-MM-DD or --MM-DD (year unknown)
how_met TEXT NOT NULL DEFAULT '',
notes TEXT NOT NULL DEFAULT '',
follow_up_days INTEGER, -- desired contact cadence; NULL = none
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS contact_tags (
contact_id INTEGER NOT NULL REFERENCES contacts(id) ON DELETE CASCADE,
tag TEXT NOT NULL,
PRIMARY KEY (contact_id, tag)
);
CREATE TABLE IF NOT EXISTS interactions (
id INTEGER PRIMARY KEY,
contact_id INTEGER NOT NULL REFERENCES contacts(id) ON DELETE CASCADE,
date TEXT NOT NULL,
kind TEXT NOT NULL,
summary TEXT NOT NULL DEFAULT '',
created_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS reminders (
id INTEGER PRIMARY KEY,
contact_id INTEGER NOT NULL REFERENCES contacts(id) ON DELETE CASCADE,
due_date TEXT NOT NULL,
text TEXT NOT NULL,
done INTEGER NOT NULL DEFAULT 0,
created_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_interactions_contact ON interactions(contact_id, date);
Martin's reply plays in the terminal below ↓
Zero slop
Testing and robustness
>Build me a personal CRM.
Vanilla Claude Code
test_server.py, lines 15–45 (15 tests; they import server.py and call its Store class directly):
class StoreTests(unittest.TestCase):
def setUp(self):
self.tmp = tempfile.TemporaryDirectory()
self.store = server.Store(str(Path(self.tmp.name) / "t.db"))
def tearDown(self):
self.tmp.cleanup()
def test_create_and_tags_normalized(self):
c = self.store.create_contact({"name": " Ada ", "tags": "Work, friend, work"})
self.assertEqual(c["name"], "Ada")
self.assertEqual(c["tags"], ["friend", "work"])
def test_name_required(self):
with self.assertRaises(server.ApiError):
self.store.create_contact({"name": " "})
def test_follow_up_overdue_uses_last_interaction(self):
c = self.store.create_contact({"name": "Bo", "follow_up_days": 30})
self.store.add_interaction(c["id"], {"date": (date.today() - timedelta(days=40)).isoformat(), "kind": "call"})
c = self.store.get_contact(c["id"])
self.assertEqual(c["days_overdue"], 10)
dash = self.store.dashboard()
self.assertEqual([x["id"] for x in dash["overdue"]], [c["id"]])
self.store.add_interaction(c["id"], {"date": date.today().isoformat(), "kind": "email"})
self.assertEqual(self.store.get_contact(c["id"])["days_overdue"], -30)
self.assertEqual(self.store.dashboard()["overdue"], [])
def test_birthdays(self):
Martin's reply plays in the terminal below ↓
Why Travis built me
Coding agents fall apart at non-trivial tasks. Ask Lovable, Replit, or vanilla Claude Code to build you a real product and you get thin prototypes, piles of code you never asked for, or hours of loop engineering on something that looked simple.
The same thing happens when humans build software. The ask is underspecified and unclear, so the biggest gap was never coding. The skill gap is figuring out what code to write.
Fifteen years championing clean code at some of the world's biggest companies taught Travis how to take messy, unclear ideas and turn them into clean code. That experience was distilled into a communication methodology, and the methodology was distilled into me. When you talk to me, you are talking to a coding agent with the experience of someone who has spent a career bringing ideas to life.
Tired of drowning in slop, staring at /plan output until you go cross-eyed, and throwing hours of code and wasted tokens away? I was built for you.
If an AI is going to replace me, I'm going to build the AI that's going to do so.
Travis
What happens after you pay
You get an email from support@trymartin.dev with your license key and setup instructions.
Run /plugin in Claude Code. Search for martin. Install me globally.
Run claude --agent martin
Say: Introduce Yourself
Want martin as a drop-in replacement for claude? Add this to your shell profile: