Your AI says it's done.malveon checks if it really is.
malveon reads your code and shows what your AI really built: hooked up, broken, missing or half done, with the line that proves it.
150 free runs. No card, no account.
curl -fsSL https://get.malveon.com/install.sh | shWindows: irm https://get.malveon.com/install.ps1 | iex. Also on npm, Homebrew, Scoop, and the VS Code and Cursor extension. After the 150 free runs, $19/month + tax. Your code stays on your computer.
~/landing-shop $ malveon --plan PLAN.mdmalveon checked 13 files, 5 plan items. Code read only; your app was not run. 3 file(s) not read (languages: malveon status).Found problems (2) 1. Plan item is broken PLAN.md:5 "`CancelButton` cancels an order with `DELETE /api/orders/[id]`" — `CancelButton` exists (src\components\CancelButton.tsx) — but it calls DELETE /api/order/:param (src\components\CancelButton.tsx:5), and no server route handles that; the server route for /api/orders… Next: Fix the connection the line describes, or change the line. 2. Plan item half built PLAN.md:6 "`OrderNotes` saves a note on an order with `POST /api/notes`" — POST /api/notes reaches its server route (src\app\api\notes\route.ts:4), but the route never changes any data: it only reads table `notes` (src\app\api\notes\route.ts:6) — and this line expects a cha… Next: Finish the missing connection. 3. New call goes nowhere (likely) src\components\CancelButton.tsx:5 DELETE /api/order/:param was added this session and no route answers it. Next: Add the route or fix the address.Also: 9 more (malveon --all) · 1 plan item not checked (malveon status)150-Run Free Trial: 147 of 150 runs left.
A real malveon report on a small test app, shortened. It says what it read, gives one verdict, and shows the top problems first: a Cancel button that calls an address the server doesn't have, and a note that never actually saves. The last line is your 150-Run Free Trial counter. malveon never stops your AI or your commit; it tells you.
Built after a week of reading Reddit threads from people whose AI said "fully functional" while half the features didn't actually work.
The AI says the Save button is done.You click it. Nothing gets saved.So you check every file yourself. That was the job you gave the AI.
And it isn't only the Save button.
- The second opinion that agrees
- So you ask another AI to check the first one. It reads the same files and gives you another opinion. You still don’t know.
- The thing that used to work
- While fixing one problem, your AI quietly breaks something else. You find out when a user clicks it.
- The extra nobody asked for
- You asked for one thing. The AI also added an Email receipt button and a new address on your server. You find out when you read the changes, if you do.
- The feature nobody uses
- A whole page, file or function gets written and never connected to anything. It sits in your project and confuses the next person who opens it.
- “All tests pass”
- Your AI says the tests pass. Maybe it ran them. Maybe it ran them before its last edit. You can’t tell from the sentence.
A straight answer for each one
Every item gets one of five answers, in malveon's own words.
- BROKENBroken
It’s there, but it won’t work. The button asks the server for something that doesn’t exist.
Your list said
CancelButtoncancels an order withDELETE /api/orders/[id]malveon foundit calls DELETE /api/order/:param (src\components\CancelButton.tsx:5), and no server route handles that
- NOT BUILTMissing
It’s on your list. It isn’t in the code at all.
Your list saidExport all orders as CSV from
GET /api/reports/ordersmalveon foundnothing in the code serves or calls /api/reports/orders
- HALF BUILTHalf done
Part of it is there. A button that leads nowhere, or a Save that never actually saves.
Your list said
OrderNotessaves a note on an order withPOST /api/notesmalveon foundthe route never changes any data: it only reads table
notes(src\app\api\notes\route.ts:6)- CONNECTEDHooked up
It’s built, and the button really reaches the part that does the work and saves it.
Your list said
RefundButtonsends a refund toPOST /api/refunds, which saves it torefundsmalveon foundinserts into table
refunds(src\app\api\refunds\route.ts:6)- SKIPPEDNot a coding task
Not checked. Either code can’t show it (a color change, a step you do by hand), or the line names no page, button or file to look up. It always says which, and it never blocks.
Your list saidButtons use the brand color and a 1.5px stroke icon
malveon founda design or styling change. To look at a page on screen, use malveon --layout
Every answer points to the exact spot in the code it's based on, so you can check it yourself.
Follow one feature from the button to where it's saved
A button sends a request, the server answers it, something gets saved. malveon follows that chain through the code, so it doesn't need to start your app.
CONNECTED(hooked up: the refund is saved)RefundButton sends a refund to POST /api/refunds, which saves it to refunds
The page
page /orders
Sends
POST /api/refunds
src/
components/ RefundButton.tsx:5 Server
route POST /api/refunds
src/
app/ api/ refunds/ route.ts:4 What gets saved
inserts into table
refundssrc/
app/ api/ refunds/ route.ts:6
HALF BUILT(half done: the note is never saved)OrderNotes saves a note on an order with POST /api/notes
The page
page /orders
Sends
POST /api/notes
src/
components/ OrderNotes.tsx:9 Server
route POST /api/notes
src/
app/ api/ notes/ route.ts:4 What gets saved
changes no data: only reads table
notessrc/
app/ api/ notes/ route.ts:6
Every submission failed. The page looked finished.
On a real app we test with, a form sent challengeId and the server expected challenge_id, so it turned away every submission. The AI said it was done.
What the form sendssrc/components/challenges/ChallengeDetailClient.tsx
133 const res = await fetch("/api/submissions", {134 method: "POST",135 headers: { "Content-Type": "application/json" },136 body: JSON.stringify({137 challengeId: id,138 githubRepo: submissionData.githubRepo,139 demoUrl: submissionData.demoUrl,140 techStack: selectedTechStack,141 wrongDecision: submissionData.wrongDecision,142 defendedDecision: submissionData.defendedDecision,143 }),144 });
What the server expects (and the error it returns otherwise)src/app/api/submissions/route.ts
47 try {48 const body = await request.json();4950 // Basic validation51 if (!body.challenge_id || !body.wrong_decision || !body.defended_decision) {52 return NextResponse.json({ error: "Missing required fields" }, { status: 400 });53 }
What malveon tells you:
Plan item is broken: the form at ChallengeDetailClient.tsx:133 sends challengeId, but the server at submissions/route.ts:38 reads challenge_id, wrong_decision and defended_decision. Next: Fix the connection the line describes, or change the line.
What your AI did that you didn't see
malveon compares your code with how it was when you started.
What it broke
New call goes nowhere (likely) src/components/CancelButton.tsx:5DELETE /api/order/:param was added this session and no route answers it.Next: Add the route or fix the address.
What nobody asked for
Added but not named in your words src/app/api/receipts/route.ts:4POST /api/receipts was added this session and no line of your request names it.Next: Keep it if you wanted it, or remove it.Added but not named in your words src/components/ReceiptButton.tsx:5POST /api/receipts was added this session and no line of your request names it.Next: Keep it if you wanted it, or remove it.
It broke something that worked. If a button that reached the server now points at an address that doesn't exist, malveon says so and shows the line. It also flags a few common leftovers: a debugging line left in, a test switched to “only”, or a secret key from a well-known service pasted into the code. If your AI changed what a function needs and other code still calls it the old way, malveon lists those callers too. That is a short list plus the before-and-after comparison, not a general bug finder.
It added something nobody asked for. malveon lists every new request, server address, page, database table, package, and button that changes your data, that neither your plan nor your own prompts asked for. Your AI's own summary doesn't count as asking. A button that only changes how the page looks, like a dark mode switch, is out of its reach. It lists these for you to review and doesn't block your work.
And what it left behind:
- A “done” the code doesn’t back up
- When your AI writes that an item is done or working, in a notes file, a commit message or its final message, malveon checks that against the code. If they disagree, it shows you the line. It reads English only.
- Unfinished work
- Notes to self (“TODO”, “FIXME”), functions that only say “not implemented”, sample data, leftover debugging lines, commented-out code and skipped tests, in lines your AI wrote this session. malveon lists them for you to look at.
- Tests removed to make them pass
- If your AI deleted tests or removed checks from them, malveon lists the files. A test deleted together with the code it tested is treated as a cleanup. It reads JavaScript, TypeScript, Python and Go tests.
- Two places answering one address
- If two parts of your server claim the same address for the same kind of request, only one of them can run. malveon lists both.
- Screens that look wrong
- malveon opens your pages in your own Chrome or Edge, in the background, at several window widths, and in dark mode if your styles have one. It lists text that overlaps, content that is cut off, sideways scrolling and text too faint to read. It only measures. It cannot tell an intended overlap from a mistake, and it starts your app only if you give it the start command and approve it once. Otherwise, point it at page files or an app you already have running.
- Work nothing reaches
- A new file or function that nothing in your app connects to is listed as possibly unused. It looks for whole features, not single unused variables, because your editor already underlines those.
It checks the code, not the AI's word
- No AI grading AI. malveon reads the code itself, so the same code always gets the same answer, and every answer points to the exact line.
- Your AI can run it too. It gets the same report you would see. When a decision is needed, like running commands on your computer, malveon asks you, not the AI.
- It checks what you asked for in chat. Most requests to an AI never make it into a written plan. Run malveon on once and it can check those too.
- It runs your project’s own build and tests only when you ask and approve, and if they fail it re-runs them on the code from when you started, to tell you whether this task broke them. It also sets your AI’s “all tests pass” beside what really ran.
- Vague requests like “make it better” leave nothing to look up. malveon asks your AI to say how you will know it is done, keeps those words, and lists them as yours to confirm.
- Each report opens with one verdict: Found problems, Worth a look, or Nothing found in the code I read. It also lists what malveon looked at and could not settle, so a quiet report never reads as more than it is.
- It tells you; it never stops you. malveon doesn’t block your AI or your saves. A background watcher re-checks when your files settle and keeps its latest look for malveon status. Pause it with one command.
Your AI agent asked malveon to run this project’s own commands on your machine:
npm run build (build, in the project root)
These run your project’s own code: its build scripts, test runner config and test files. Only approve a project you trust. Allow them until its commands change?
When your AI asks to run commands on your computer, this is what you see. Only you can answer it.
Save a file. See what broke.
Add the extension to VS Code or Cursor. It checks again after you save and puts problems next to your code.
Malveon: Results
- Plan items
- BROKEN (1)
CancelButtoncancels an order withDELETE /api/orders/[id]- NOT BUILT (1)
- HALF BUILT (1)
- CONNECTED (2)
- SKIPPED (2)not code tasks: headings, notes, design and manual steps
- Your prompts
- Other checks
- Frontend and backend agree on dataclean
- Backend route conflictsclean
- New bugs this session1
- Unplanned code7
- Files nobody asked about2
- Tests weakened or removedclean
- UI elements may overlapclean
- Unfinished codeclean
- Agent's claims vs reality1
Malveon / landing-shop
3 things block a commit
Fix these, then run the check again.
- Read from the code done
- Your build and tests: not run
- Your real app: not verified (malveon does not click through it)
- plan items: 1 BROKEN, 0 NOT BUILT, 1 HALF BUILT
- new bugs this session: 1 introduced (something that worked now broken, or a known bug pattern added)
- agent’s claims vs reality: 1 claim(s) contradicted by what was actually verified
- 1 BROKEN
- 1 NOT BUILT
- 1 HALF BUILT
- 2 CONNECTED
- 2 SKIPPED
Plan items
Every line of your plan, checked against the code. From PLAN.md. Change
CancelButton cancels an order with DELETE /api/orders/[id]
CancelButton exists (src\components\CancelButton.tsx) — but it calls DELETE /api/order/:param (src\components\CancelButton.tsx:5), and no server route handles that; the server route for /api/orders/:id exists (src\app\api\orders\[id]\route.ts:4), but no frontend call to it was found (if something outside the app calls it — a health check, webhook, cron job or public API — say so in the line)
src/app/api/orders/[id]/route.ts:4src/components/CancelButton.tsx:5
Set it up once, then keep working
Install
Paste one line into your terminal, or add the extension to VS Code or Cursor. Or try it first with npx malveon, no install.
Look at your project
Type malveon in your project folder. It needs no plan and lists what is wrong right now: buttons that do nothing, calls to addresses nothing serves, imports that cannot work.
Check your AI as it works
Run malveon on once. Then malveon re-checks while your AI works and keeps its latest look for malveon status. Give it your plan, or let it read your prompts, and it checks those too. Pause it any time with malveon off.
malveon never checks a live site, starts your app only with a command you give it and approve once, never runs your project's own commands until you've said yes, and never sends your code or file names anywhere.
Pick the line for your computer
Not sure which? On a Mac or Linux use the first line, on Windows the second. Copy it into your terminal and press Enter.
- macOS / Linux
- curl -fsSL https://get.malveon.com/install.sh | sh
- Windows
- irm https://get.malveon.com/install.ps1 | iex
- npm
- npm install -g malveon
- Homebrew
- brew tap ladsondavid/malveon https://github.com/LadsonDavid/Malveon && brew install malveon
- Scoop
- scoop bucket add malveon https://github.com/LadsonDavid/Malveon; scoop install malveon
- VS Code / Cursor
- Search “malveon” in Extensions
Every download is checked against the release's checksum list before it's installed, and a file that doesn't match is refused. That list is signed with malveon's release key. Updates always check the signature, and so does the Mac and Linux installer when your computer has OpenSSL 3.
Frequently asked questions
Don't take our word for it
Pick one. It opens with a question about malveon already typed, including what malveon can't do. The AI answers from what it finds online, so it can be wrong or out of date about us too. malveon's own answers never come from an AI. They come from your code.
The question it asks
I use AI coding agents (Claude Code, Cursor, Codex, Antigravity). Explain malveon (malveon.com): what it checks when my agent says a task is done, including anything the agent added that I didn’t ask for and anything it broke along the way, plus buttons that do nothing, deleted tests, unfinished work, and what the agent claims about its own work. How does it prove each verdict, and what does it do with a vague request like “make it better”? Also: whether it needs a plan to start, what it can’t check (does it ever run my app?), which parts are open source, what data it sends, and how to install it. Use malveon.com and github.com/LadsonDavid/Malveon as sources.
Find out what your AI really built.
150 free runs. No card, no account.
curl -fsSL https://get.malveon.com/install.sh | shWindows: irm https://get.malveon.com/install.ps1 | iex. Also on npm, Homebrew, Scoop, and the VS Code and Cursor extension. After the 150 free runs, $19/month + tax. Your code stays on your computer.