I Run 3 SaaS Apps With 4 Slash Commands (Not 30 Subagents)

Every week another solopreneur shows me their .claude/ folder with 30 subagents, an orchestrator, three MCP servers, and a YAML config that needs a diagram to explain. Then they ask me why it broke in week two. I run three production apps — real invoicing, real onboarding, real daily ops for paying clients — with four markdown files in one folder. Let me open it.
Why the flat-file setup beats subagent chains for solo operators
A slash command in Claude Code is just a markdown file sitting in .claude/commands/. When you type /invoice, Claude reads that file as a prompt and executes against your current working directory. No orchestration layer. No subagent handoff. No hidden state machine deciding which worker agent gets the task.
That sounds boring until you're debugging at 11pm. With a subagent chain, when step four gets skipped, you have to figure out which agent decided to skip it, why the orchestrator accepted that decision, and whether the MCP server returned partial data. With a flat markdown file, you open it, you read the numbered list, you find the step, you fix the line. Thirty seconds.
The brutal trade-off table nobody publishes:
| Approach | Setup time | Debug time when it breaks | Cost / month | Files to maintain |
|---|---|---|---|---|
| 30-subagent "AI OS" | 8-20 hours | 1-4 hours per incident | $80-200 in tokens + infra | 30+ |
| 4 slash commands | 90 minutes | 5 minutes | $12-30 in tokens | 4 |
I tried the orchestrator-plus-workers pattern on a real client project earlier this year. Within ten days I ripped the whole thing out. What replaced it is the folder I'm about to show you.
What makes flat files survive six months in production
- You can
git diffa behavior change and see exactly what shifted - A year from now, you can re-read the file and understand it without re-watching a course
- Edits are plain English — the client can read them
- No version drift between agent A and agent B's prompts
The /invoice command: 8 minutes per invoice → 40 seconds
The invoicing business I built this for used to spend about eight minutes per invoice. Pull the client record, copy line items, generate the PDF, write the email in Serbian or English depending on the client, attach it, send it, log it. Forty invoices a week is over five hours of pure clerical work.
The whole command is a 40-line markdown file. Here's the skeleton (sanitized):
# /invoice
You are generating an invoice. Follow these steps in order. Do not skip.
1. Read the client ID from my next message.
2. Query `./data/clients.db` for that client's billing profile,
VAT status, and preferred language.
3. Read pending line items from `./data/pending/{client_id}.json`.
4. Calculate subtotal, VAT (20% for SR, reverse-charge for EU B2B,
0% for non-EU), and total. Round to 2 decimals.
5. Render PDF using `./templates/invoice_{lang}.html` via the existing
`render_invoice.py` script. Save to `./out/INV-{number}.pdf`.
6. Draft an email in the client's language using the tone from
`./templates/email_invoice_{lang}.md`. Show me the draft.
7. STOP. Wait for my "send" confirmation.
8. On confirmation: send via the existing `send_mail.py` and append
a row to `./data/ledger.csv`.
That's it. There's no magic. It's a numbered list, references to four files that already exist on disk, and one explicit STOP so I review the draft before anything leaves the machine. Forty seconds end-to-end. Same compliance, same template, same VAT logic — just no human typing.
The detail people miss: step 7. Without that stop, you eventually send a malformed draft to your biggest customer. With it, you spend ten seconds reading and one second approving.
The /onboard command: 2 hours → 15 minutes, with human checkpoints
New client intake used to be a two-hour ritual. Folder structure, CRM record, welcome packet PDF, billing profile, kickoff email with the right attachments, calendar invite for the first check-in. Six places to forget something.
/onboard is around 55 lines. The structurally important part is what I call checkpoint markers — places where the file literally says, in English:
## Step 4: Contract terms
Ask me for:
- Project scope (1-2 sentences)
- Monthly retainer amount
- Start date
- Notice period in days
STOP HERE AND ASK THE USER TO CONFIRM BEFORE PROCEEDING.
Do not invent values. Do not assume defaults.
Claude respects those markers every single time. I've run this command maybe 80 times across clients and not once has it autonomously past a STOP HERE. The reason is simple: the model is reading a numbered prompt, not executing a state machine. When the prompt says stop, the prompt stops.
Fifteen minutes total, most of which is me typing the contract details. The rest is deterministic file writes and a draft email I review before sending.
The /triage command: where business context lives in plain English
Every morning at 08:00 a cron job runs /triage. It walks the Gmail inbox, classifies messages, archives noise, and pushes a summary to a Telegram channel. Urgent gets flagged. Newsletter gets archived. Anything that needs a human in the next two hours surfaces immediately.
The file is 22 lines. The shortest of the four. And it's the most valuable, because the definition of "urgent" is the entire product:
# /triage
Read unread Gmail messages from the last 12 hours via `gmail_read.py`.
URGENT (flag immediately):
- Sender domain in `./config/vip_domains.txt`
- Subject contains "invoice", "overdue", "kvar", "hitno"
- Reply to a thread where I sent the last message > 48h ago
- Any message from accounting@[redacted].rs between Jan-Apr
(tax season — always urgent)
ARCHIVE (no notification):
- Sender matches `./config/newsletter_senders.txt`
- Subject starts with "[GitHub]", "[Notion]", "Your receipt"
For everything else: one-line summary in Telegram.
Format: `[URGENT|NORMAL] sender — subject — 1-line gist`
Push via `telegram_push.py` to channel `daily_triage`.
That "accounting firm in March is urgent, July is not" line is what no generic SaaS triage tool gets right. It can't. The business context lives in the markdown file, in plain English, and I edit it whenever the business changes. Last month a client added a new payment processor — I added one line to vip_domains.txt and the triage adapted. No retraining, no config dashboard, no support ticket.
The /ship command: deterministic deploys, no 3am rollbacks
Fourth command is for the dev side. Pre-deploy checklist, run the test suite, check migrations, push, tag, write the deploy log.
# /ship
Run in order. If any step fails, STOP and report which one.
1. `git status` — must be clean
2. `pytest -x` — must pass
3. Scan `./migrations/` for files newer than last deploy tag.
If any found: print them and require confirmation.
4. `git push origin main`
5. Compute next semver tag from `./CHANGELOG.md` top entry.
Create tag, push tag.
6. Append entry to `./deploy.log` with timestamp, tag, commit hash.
7. Post a one-line summary to Telegram `deploys` channel.
Used to be a fifteen-minute ritual where I'd forget one step every fourth deploy and break something. Now it runs deterministically and the file itself is the documentation. New engineer joins, reads the file, understands the deploy in a minute.
Where this approach breaks (and what nobody else tells you)
The moment you chain these commands autonomously, you lose. I tried having /triage automatically trigger /invoice for any client who replied "yes" to a quote. It worked for three days. Then a client's email thread had two "yes" replies in different sub-threads, and I invoiced them twice. My biggest customer at the time. Refund, apology, awkward call.
The fix was not a smarter agent. The fix was: slash commands are tools, you are the orchestrator. Every state-changing action — sending an invoice, creating a CRM record, pushing a deploy — has a human in the loop. Reads can be automated. Writes get a checkpoint.
The rules I won't break anymore
- One command does one job; no chaining inside a
.mdfile - Every external write has a
STOPbefore it on the first run - Anything that touches money or client communication waits for explicit confirmation
- If a command grows past ~70 lines, split it — don't add a subagent
The 30-subagent setups fail because they violate all four. They chain by design, they trust the orchestrator to handle writes, they grow without bound, and when one link misbehaves you cannot see which one.
The folder, in full
.claude/
└── commands/
├── invoice.md (40 lines)
├── onboard.md (55 lines)
├── triage.md (22 lines)
└── ship.md (28 lines)
145 lines of markdown running three production apps. Versioned in git. Diffable. Readable by the client. No MCP gymnastics, no orchestrator, no hidden state.
Copy that structure tonight. Start with one command — the one that eats the most of your week. Write it as a numbered list. Add a STOP before every write. Run it for a week and edit the file when reality disagrees with the prompt. That's the whole loop.
Why bizflowai.io helps with this
This is exactly the pattern we ship for clients at bizflowai.io — invoicing automation, inbox triage, onboarding flows, deploy hygiene — all built as small, auditable slash commands inside the client's own repo, not as a black-box SaaS they rent forever. The deliverable is the markdown they can read, edit, and own. When the business changes, they change one line. No vendor lock-in, no orchestrator to debug at midnight.
Frequently asked questions
What is a Claude Code slash command?
A slash command in Claude Code is a markdown file stored in the .claude/commands folder. When you type slash followed by the file name, Claude reads that file as a prompt and executes it against your current working directory. There's no orchestration layer, no subagent handoff, and no hidden state, making it easy to read, edit, and version-control.
Why do slash commands work better than subagents for solopreneurs?
Slash commands are flat markdown files you can open, read, and understand in thirty seconds, even a year later. Subagent chains with orchestrators and MCP servers create debugging nightmares because you can't tell which agent skipped a step. For solo operators running real production apps, the flat-file approach wins because it has no hidden state and no autonomous chain surprises.
How do I add human checkpoints to a Claude Code command?
Write the instruction directly into the markdown file in plain English. For example, include a line like 'stop here and ask the user to confirm before proceeding.' Claude respects these checkpoint markers every time, pausing for inputs only a human can provide such as contract terms, and confirming before write operations. This prevents autonomous chains from making unwanted changes.
How much time can slash commands save on invoicing?
A small invoicing business reduced invoice processing from about eight minutes to forty seconds end to end using a forty-line markdown slash command. The command pulls client data from a local database, calculates totals with VAT, renders a PDF from a template, drafts the email in the client's language, and logs the transaction. The human reviews and approves in ten seconds.
When should I use a markdown slash command versus a generic automation tool?
Use a markdown slash command when business context matters, such as knowing that emails from a specific accounting firm are urgent in March but not in July. Generic triage tools fail because they lack this context. A markdown file lets you define rules in plain English and edit them whenever the business changes, keeping the logic transparent and maintainable.
Want more like this?
I publish practical AI automation, GenAI engineering, and faceless content workflows on YouTube every week.
Subscribe to bizflowai.io on YouTube — never miss a new tutorial.
Planning an AI automation project or need a second opinion on your architecture?
Connect with me on LinkedIn — Lazar Milicevic, GenAI Engineer & bizflowai.io Founder.
Visit bizflowai.io for our services, case studies, and AI consulting.
Frequently asked questions
What is a Claude Code slash command?
A slash command in Claude Code is a markdown file stored in the .claude/commands folder. When you type slash followed by the file name, Claude reads that file as a prompt and executes it against your current working directory. There's no orchestration layer, no subagent handoff, and no hidden state, making it easy to read, edit, and version-control.
Why do slash commands work better than subagents for solopreneurs?
Slash commands are flat markdown files you can open, read, and understand in thirty seconds, even a year later. Subagent chains with orchestrators and MCP servers create debugging nightmares because you can't tell which agent skipped a step. For solo operators running real production apps, the flat-file approach wins because it has no hidden state and no autonomous chain surprises.
How do I add human checkpoints to a Claude Code command?
Write the instruction directly into the markdown file in plain English. For example, include a line like 'stop here and ask the user to confirm before proceeding.' Claude respects these checkpoint markers every time, pausing for inputs only a human can provide such as contract terms, and confirming before write operations. This prevents autonomous chains from making unwanted changes.
How much time can slash commands save on invoicing?
A small invoicing business reduced invoice processing from about eight minutes to forty seconds end to end using a forty-line markdown slash command. The command pulls client data from a local database, calculates totals with VAT, renders a PDF from a template, drafts the email in the client's language, and logs the transaction. The human reviews and approves in ten seconds.
When should I use a markdown slash command versus a generic automation tool?
Use a markdown slash command when business context matters, such as knowing that emails from a specific accounting firm are urgent in March but not in July. Generic triage tools fail because they lack this context. A markdown file lets you define rules in plain English and edit them whenever the business changes, keeping the logic transparent and maintainable.