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.

Check my project free

150 free runs. No card, no account.

curl -fsSL https://get.malveon.com/install.sh | sh

Windows: 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.

Terminal · landing-shop
~/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.
For every item on your list

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 saidCancelButton cancels an order with DELETE /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/orders

malveon 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 saidOrderNotes saves a note on an order with POST /api/notes

malveon 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 saidRefundButton sends a refund to POST /api/refunds, which saves it to refunds

malveon 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.

Start to finish

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

  1. The page

    page /orders

  2. Sends

    POST /api/refunds

    src/components/RefundButton.tsx:5

  3. Server

    route POST /api/refunds

    src/app/api/refunds/route.ts:4

  4. What gets saved

    inserts into table refunds

    src/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

  1. The page

    page /orders

  2. Sends

    POST /api/notes

    src/components/OrderNotes.tsx:9

  3. Server

    route POST /api/notes

    src/app/api/notes/route.ts:4

  4. What gets saved

    changes no data: only reads table notes

    src/app/api/notes/route.ts:6

A real one

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.

Along the way

What your AI did that you didn't see

malveon compares your code with how it was when you started.

What it broke

Broke something that worked
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

Not named in your words
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.
Why it's different

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.

When your AI asks to run commands on your computer, this is what you see. Only you can answer it.

In your editor

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 — landing-shop — Visual Studio Code
Malveon results

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

BROKEN1Would fail for a real user: the screen calls something the server doesn’t serve, or with the wrong method.

CancelButton cancels an order with DELETE /api/orders/[id]

PLAN.md:5

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

NOT BUILT1Your plan names it. The code doesn’t have it.
HALF BUILT1Part of it exists, but it isn’t connected yet.
CONNECTED2Built, and the screen reaches its server or database.
main malveon: blocked (3)
How it works

Set it up once, then keep working

01

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.

02

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.

03

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.

FAQ

Frequently asked questions

Ask your AI

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.

Check my project free

150 free runs. No card, no account.

curl -fsSL https://get.malveon.com/install.sh | sh

Windows: 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.