ordel (free CLI)
Local QA automation for individual devs — a persistent, deterministic "QA brain" your own coding agent (Claude Code / Cursor / Copilot) drives over MCP. No account, no DB, no Ordel LLM. Your agent is the brain; Ordel is the memory + determinism.
Status: early build. The engine loop (map → record → generate → run) works locally today; a single-command
npx ordeldistribution is planned but not started.
What works today (local, anonymous)
ordel init # create .ordel/ + an ORDEL.md bridge file. No account.
ordel doctor # preflight: Node / npx / @playwright/test / Chromium (+ how to fix)
ordel status # local coverage: pages, elements, run history
ordel graph # print the local app graph
ordel adopt # existing Playwright/Cypress suite -> flake report + heal patches
ordel record <name> <url> # click through a flow yourself -> page objects + a spec using them
ordel run # run the Playwright suite; one evidence-backed verdict per test
ordel report # copy-pasteable Markdown report (Slack/Teams/Jira); --json too
ordel catalog export catalog.json # the element catalog as a portable file (CATALOG.md)
ordel catalog import catalog.json # merge one in; local elements win, conflicts listed
ordel mcp-install # print the MCP config to add to Claude Code / Cursor / Copilot
ordel mcp-install --skill # also install the agent skill (Claude Code, Codex)
Recording a flow yourself
ordel record signup http://localhost:3000/ opens a visible browser at that URL. Click
and type through the flow as a user would, then close the window to finish (Ctrl+C
works too, and keeps what was recorded).
To assert something, Alt+click it (Option+click on a Mac). That records
toHaveText(<its text>), or toBeVisible() when it has no text. The final URL is
asserted automatically. A recording with no assertion runs unjudged, because it
proves nothing.
Ordel writes back:
- every page you landed on, into the catalog;
- a page object per page (
pages/<Class>.ts, or its managed block updated); tests/signup.spec.ts, which drives those page objects (homePage.submit.click()).
A hand-written page object is never overwritten: steps on its page use a direct locator
instead, and the command says so. Passwords are never stored. The spec reads them from
ORDEL_PASSWORD, and query strings (where a GET form puts its fields) are dropped from
every recorded URL.
Adopting an existing suite
ordel adopt points Ordel at the suite you already have (Playwright, or Cypress *.cy.*
specs) and reports on it without changing it:
- Ingest: every functional spec becomes a flow in
.ordel/flows/. Cypress chains are translated to the same flow format; a chain it cannot represent faithfully is counted, never guessed. - Flake report: it runs a Playwright suite until
.ordel/runs/holds--runs(default 3) judged runs, then classifies each test asflaky(passed only on retry, or flipped twice),regressed(passed, then kept failing),failing,recovered,stable, or too few runs to say. - Heal report: each failing test whose test-id locator no longer resolves is healed
against a live capture of the page it was catalogued on. The page must have been
captured while the test was green: run
ordel explore <url>first to build that baseline. A confident heal becomes a unified diff under.ordel/patches/<heal-id>.patch. An element that is simply gone is reported as a real failure, not healed to something else.
Nothing in your code changes until you review a patch:
ordel adopt --apply heal-0001 # write the fix, mark the heal accepted, refresh the catalog
ordel adopt --reject heal-0001 # write nothing, record the rejection
--apply refuses a patch whose file changed since it was made. Agents get the same
report through the adopt_suite MCP tool. They cannot apply or reject a heal: that is
the human review step.
Honest verdicts
ordel run (and the run_test MCP tool) never reports a green it cannot back. Each
executed test gets one verdict: pass, fail, flaky, skipped or unjudged,
with its evidence: the assertions it actually ran and any heal it depends on.
A test that Playwright calls green is unjudged, not passed, when:
- it ran no assertion at all (a vacuous pass),
- no assertion evidence was captured for it,
- its spec depends on a heal no human has reviewed yet.
A run that executed no test is no_tests, never a pass. ordel run --json prints the
full ordel.run/v1 document, which is also recorded under .ordel/runs/.
| Exit code | Meaning |
|---|---|
| 0 | at least one test ran, and every one passed with evidence |
| 1 | a test failed, no test ran, or the run itself errored |
| 3 | nothing failed, but at least one test is unjudged |
Then your coding agent, via MCP, drives the loop (needs Node + @playwright/test in the
project — run ordel doctor to check):
get_app_context/heal_selector— what Ordel knows + deterministic self-heal of a broken selector (fingerprint match, no LLM; ambiguous cases returnneeds_agentwith ranked candidates for your agent's own LLM to resolve — Ordel never spends inference). Every resolved heal is recorded in.ordel/heals.jsonpending human review.explore/record_flow— drive the real browser to map the app + record a flow.generate_scenarios/generate_invariant/generate_perf_check/generate_pom— turn artifacts into runnable specs (happy/negative/boundary, data-integrity, latency, POM).run_test— run a spec vianpx playwright testand read the evidence-backed verdicts.- QA-mind planning:
coverage_report/risk_rank/plan_tests/regression_set.
In progress (honest — no fake success)
- Single
npx ordeldistribution — the plan is a compiled Python engine binary wrapped in one npm package; not started (today's install path ispip/uv, see Dev below). eject(one-command raw-Playwright export) — scaffold; but there's no lock-in today either: generated tests are already plaintests/*.spec.ts+pages/*.tson disk.- Team sync + hosted dashboard = the paid upgrade (this CLI stays free & local).
The pieces
ordel-engine(sibling package) — the pure deterministic core: fingerprint matching + self-heal, stdlib-only, zero backend.ordel_cli.store— the.ordel/file store (the local shell).ordel_cli.heal_service— heal + per-page circuit-breaker.ordel_cli.mcp_server— the local stdio MCP server your agent connects to.
Dev
pip install -e packages/ordel-engine -e packages/ordel-cli
pip install pytest
pytest packages/ordel-cli/tests packages/ordel-engine/tests -q
Known limitations (by design)
- Single-writer. The
.ordel/store is for one dev on one machine. Writes are atomic (temp-file +os.replace, so a crash can't corrupt a file), and a corruptedgraph.jsonis reported cleanly (never silently overwritten). But two processes writing the same page concurrently is last-writer-wins — there is no file lock. That is deliberate: a single-user local CLI doesn't warrant lock files / their failure modes. Team-scale concurrency is the hosted product's job (ordel push). - Browser tools need a local Node +
@playwright/test(explore/record_flow/run_test). They don't ship a browser; runordel doctor— if Node/Playwright/Chromium are missing it tells you the exact command to fix. Without them these tools report the missing dependency, never fake success.
Privacy
Local-first: no Ordel LLM, no telemetry, no account, no data sent to Ordel. The only
network requests are to your own target app and standard package/browser downloads you
initiate. Full policy: https://ordel.io/privacy (also ships as PRIVACY.md next to the
installed package, and at the repo root here).
Metadata
Release files for ordel-cli 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ordel_cli-0.3.0.tar.gz | 85.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ordel_cli-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 187.0 kB
Release files / ordel_cli-0.3.0.tar.gz
| Download URL | ordel_cli-0.3.0.tar.gz |
|---|---|
| Size | 85.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
50f5697f219a668ba2b2bcf07f4b8c2559ef44e9b7faabf9809637eeedf624a8
|
|
BLAKE2b-256 checksum How to use checksums |
2ea4b83ae11ca6e972835df27cc1632891e4d603251a00e34cf47c67a7ab31da
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Release files / ordel_cli-0.3.0-py3-none-any.whl
| Download URL | ordel_cli-0.3.0-py3-none-any.whl |
|---|---|
| Size | 101.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e6bc8993011f64faa50adf0c5c41673cb4909f4efaf26a91bdbcc30b30a78a3b
|
|
BLAKE2b-256 checksum How to use checksums |
2a1462dde064176fe56bcc26b7fbf45333ae3295e5d0bf6d203cbbdaa2fa2bc2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|