ReadTeardownsPricingDocsMCPOpen the chatRecipesWhat we never takeOpt out a siteChangelogStatusvorluno.dev
INSTALLnpm i -g @mvoom/cli
LICENCEMIT
SOURCEthis page is the package README
OTHERS/docs/sdk · /docs/mcp
DOCS / 03 · CLI

@mvoom/cli

The semantic decompiler for web motion, from your terminal.

README

The semantic decompiler for web motion, from your terminal. See what moves on a page, measure one piece, and keep every component you own up to date — without leaving the shell.

npm i -g @mvoom/cli   # or: npx @mvoom/cli --help
The hosted service is not live yet. Until api.mvoom.com opens, point MVOOM_API at a service you run yourself (npm run api in the mvoom repository). The package is published now so the install path is real from day one.

mvoom auth                         # paste your key once
mvoom capture https://example.com  # what moves there — free
mvoom capture https://example.com --piece .hero --save src/motion/hero
mvoom sync                         # every fix, for everything you own, in place

What it is for

Four things, and only four.

CommandWhat it doesWhat it costs
authsaves your API key, after checking it worksnothing
capture <url>lists what moves on that page — each piece, how much, a price rangenothing
capture <url> --piece <sel>measures one piece in a real browser, prints the briefone read — it asks first
syncpulls the latest build of every component in mvoom.jsonnothing under support
budgetwhat your agent may spend on its own — you can only tighten itnothing
connectpairs this folder with your account: buy at mvoom.cc, it lands herenothing
This tool never buys anything. A purchase needs your signature, and that lives in the MCP connector and at mvoom.cc — where you can see the price, the brief and the balance before you say yes. A CLI that buys with a flag is a script that buys for you.

auth — the key never touches the command line

$ mvoom auth
Paste your API key (it is not echoed back):
✓ Signed in as solo. Key saved to ~/.mvoom/credentials.

The key is read from a prompt, not from an argument: an argument ends up in your shell history, which is a plain file that sometimes syncs between machines. --key exists for a CI, where there is no history and the value comes from a secret — and that is the only place to use it.

It is checked against the service before it is saved. Saving a bad key would leave you with an auth that said "done" and a capture that said 401 ten minutes later, in another command, with no visible relation to the first.

MVOOM_API_KEY in the environment wins over the file. mvoom auth --forget removes it.

On Windows, file permissions are not restricted. chmod 600 does nothing there, so the tool says so instead of pretending. The file lives in your profile — not in a project — because a file inside a repository ends up in the repository.

capture — looking is free, measuring is not

$ mvoom capture https://example.com
Looking at https://example.com…
7 things move on that page. 2 worth naming:

  01  hero                                 4 moving · $14.86–33.86
      .hero
  02  product cards                        3 moving · $12.1–27.4
      .cards article

Measure one with mvoom capture https://example.com --piece "<selector>". That spends one read.

Pieces marked as noise — a cookie banner, a chat bubble — are left out of the list. The total tells you how much actually moved.

$ mvoom capture https://example.com --piece .hero
Measuring spends one read (79 left today). Continue? [y/N] y

Measuring opens the page in a real browser and runs the engine's passes. It spends one of your reads, so it asks first — unless you pass --yes, or there is no terminal, or you asked for --json. In a script, whoever launched it already decided.

What comes back is the brief: duration, easing, trigger, stagger, what could not be measured, and a paragraph to paste into your AI. It is free. The clean component is what costs, and it is bought elsewhere.

--save <path> notes the measured piece in mvoom.json so sync knows where it goes once it is bought. The path is yours: the service never decides where your files live.

sync — every fix, in place

$ mvoom sync
  =  src/motion/hero          up to date v1.0.0
  ↑  src/motion/cards         updated    v1.1.0
  ·  src/motion/footer        measured, not bought

For every component in mvoom.json, sync asks the service to recompile it and writes the files where the manifest says. Under support, a recompile with the same engine build is not a recompile: nothing is generated, nothing is charged, and sync says "up to date". That is what lets you run it on every start.

--dry says what would change and writes nothing.

sync never writes outside the project. A manifest arrives by git clone, which means anyone can write one. A path with ../ in it, or a file name from the service that tries to escape, is refused with the reason — not resolved "as best it can".

MVOOM.JSON

{
  "version": 1,
  "componentes": [
    { "purchaseId": "pur_…", "ruta": "src/motion/hero", "version": "1.0.0", "etiqueta": "hero" }
  ]
}

Plain JSON, committed with the project, and it never contains credentials. sync looks for it walking up from the current directory, the way git finds .git.

budget — you can only tighten it

$ mvoom budget --per-action 500 --monthly 5000
✓ Saved. The service is enforcing these — and it only ever tightens.

  per autonomous purchase  500 cr  $5.00  (plan allows up to 2,000)
  per month, total         5,000 cr  $50.00  (plan allows up to 10,000)

These are the ceilings your agent may spend without asking you. The plan sets the hard ceiling; here you can only go down. Asking for more than the plan allows is trimmed to the ceiling and the tool prints what actually applies — printing what you asked for would make you believe in a limit that is not in force.

connect — buy there, it lands here

$ mvoom connect --dir src/motion
Purchases from your account will be written into src/motion. Allow it? [y/N] y
● Connected.
  device  MacBook-Pro
  since   9/12/2026, 1:48 PM
  folder  /Users/you/project/src/motion
Buy at mvoom.cc and it lands here. Ctrl-C disconnects.
  ↓  src/motion/HeroReveal  v1.0.0 · 5 files

The same words — "Connected." — appear on the connect screen of your account, with the device, the time and the folder. Three rules, all of them enforced:

  1. The terminal opens the channel. It asks the service every few seconds whether anything new

was bought; nothing on your machine listens, and our servers never connect to it.

  1. The folder is decided here. It is sent to the service so you can see it in your account —

no path ever travels the other way, not even a relative one.

  1. One terminal, one folder, confirmed the first time (remembered in

~/.mvoom/connected-folders). Closing the terminal disconnects; so does the button on the web — the next question gets a 410 and the CLI stops.

What lands is noted in mvoom.json, so sync knows about it from then on.

--json — for scripts and agents

mvoom capture https://example.com --json | jq '.pieces[].selector'

--json is a mode, not a format. It changes where each thing goes: the result is one object on stdout, and everything else — progress, warnings, errors — goes to stderr, also as JSON. That is what lets you pipe the result and still see the progress, and what lets an agent read an error the same way it reads a success.

{"ok":false,"code":"BAD_KEY","message":"that key is not valid — it may have been rotated"}

Exit code is 0 on success and 1 on any failure. There is no third state.

What this package does not do

Not includedWhy
BuyingNeeds your signature. Lives in the MCP connector and at mvoom.cc
Measuring locallyThe engine runs on the service, in a real browser. This asks and waits
Logging the keyNever — not in an error, not in verbose mode, not truncated more than the first characters of auth --status
A config file in the projectOnly mvoom.json, and it holds paths and versions, never credentials
Listeningconnect polls; it opens no port and accepts no connection

Zero dependencies

Node brings fetch, parseArgs and readline. Bringing an HTTP client and an argument parser for five commands would impose a dependency tree on whoever installs this — and what is here is exactly what you read in four short files.

Support

VersioningSemantic, with a hand-written changelog
Securitysecurity@vorluno.dev — first response within 48 hours
LicenceMIT. The engine that produces the measurements is not — see ADR-MV016

<sub>Built and maintained by Vorluno Software, S.A. Every number this prints was measured in a real browser, never inferred from a screenshot.</sub>

THE OTHER TWO