name: tw-lvr-cli description: >- TW Property Price CLI (台灣實價登錄 CLI). Fetch the LATEST building-level real-estate transaction data from Taiwan's 內政部不動產實價登錄 (lvr.land.moi.gov.tw) as clean JSON. Use when the user wants recent transactions for an address, building, or 社區 (community) — especially rows newer than the quarterly open-data ZIP — building-level price comparisons, 查實價登錄, real price registry lookup, cross-check ZIP data, or 補錄交易. Writes results to disk with --out so large pulls never enter the model's context. For programmatic / agent use; a human eyeballing one building should use 591 or 樂居.
TW Property Price CLI (tw-lvr-cli) — latest Taiwan property transactions, as clean JSON
A deterministic, headless CLI. One command pulls building-level transactions the way the government site loads them, then cleans and optionally refines them into analysis-ready records. No server to run, no model in the loop.
Lead benefit for agents: keep the data out of your context window. The CLI
loads nothing into context until you invoke it via Bash, and --out <file>
writes results straight to disk so a large pull never streams through the model.
When to use
- "查實價登錄 for [building/address]", "latest transactions for [社區]"
- Comparing recent sales across a building or community
- Cross-checking / supplementing the quarterly open-data ZIP with newer rows
- Bulk / district-scale pulls where inlining every row would blow the context window
- Any task needing recent Taiwan property transactions in structured form
How to run
tw-lvr extract --where "台北市信義區松德路169巷" --from 202401 --to 202612 [--refine] [--ptype 1,2] [--query biz|sale] [--presale] [--top N] [--community <name>] [--out file.json|file.csv|dir/] [--format json|csv] [--pretty]
Also: tw-lvr glossary (output fields, origins, formulas), tw-lvr schema (alias),
tw-lvr upgrade (CLI + Skill update commands), tw-lvr skill install --agent codex|claude,
tw-lvr --version, tw-lvr --help.
- If
tw-lvris not on PATH: run it with no install vianpx -y tw-lvr-cli@latest extract ...(same flags), or install globally withnpm i -g tw-lvr-cli. Either way, install the browser once:npx playwright install chromium-headless-shell. (From a cloned repo:bun run build, thennode dist/cli.js extract ....) - To update a copied Skill, first update the package (
npm install -g tw-lvr-cli@latestorbun add -g tw-lvr-cli@latest), then runtw-lvr skill install --agent codexortw-lvr skill install --agent claude.tw-lvr upgrade --agent codexprints the one-line command. --refineadds Layer B: comparable/site-displayed unit price, exclusion flags, confidence.--query bizis the default buy/sell tab. Use--query saleor--presalefor 預售屋 examples.--top N(alias--limit N) returns only the N most recent transactions; output is always sorted newest-first.- Output is JSON by default (CSV if
--outends in.csvor--format csv); to stdout or--out.--prettymeans indented JSON for humans. - Prefer
--outfor anything beyond a handful of rows, then read back only the slice you need (--top N, orjq/grep/a follow-up Read on the file). This is the core context-saving move: a district-wide pull writes to disk in one command instead of injecting every row into your context. - The matched address is echoed to stderr ("resolved: …") — confirm it before trusting results.
- Time period (
--from/--to) are WESTERNYYYYMMmonths (e.g.202401). If the user gives no period, default to the current month and the previous 24 months. - Long spans / dense districts → chunk the month range. One
extractfetches the WHOLE district for the span (then filters), so a very large response fails with exit4[ERR_NETWORK] ... evicted from inspector cache. Verified ceiling: ~15k rows in one call is OK, ~17k fails — dense metros (e.g. 高雄鼓山, 台北信義) run ≈2k rows/yr, so ~7 years is the practical max there. Default each call to ≤60 months; on ERR_NETWORK, halve the window and retry. For longer history, split[--from,--to]into ≤60-month chunks, run each, concatenate, sort bytxnDateRocdescending, de-dupe bydetailKey, then apply--top/--communityon the merged set.
Reference materials
Load these only when needed:
references/tested-samples.md— runnable sample commands mirrored from the test/canary suite. Use it for demos, publish validation, smoke tests, or when a user wants examples to try.references/troubleshooting.md— investigation playbook forOK_EMPTY, district mismatches, citywide 新竹市/嘉義市 quirks, community-filter surprises, CSV/JSON checks, and browser/env failures.
If results look strange, load references/troubleshooting.md before explaining
the data. Re-run with --top 10 --out tmp/lvr-debug.json, inspect address and
building, and treat locality mismatches as a correctness investigation rather
than as valid market evidence.
Typed exit codes (self-correct on these)
0 ok / no matches · 2 bad input (fix the address) · 3 site changed (needs maintainer) ·
4 network (retry) · 5 rate limited (back off) · 6 environment/browser setup
(install the browser: npx playwright install chromium-headless-shell, or request Codex sandbox
escalation) · 7 partial (inspect per-record fields).
Interpreting the output
Each record (with --refine):
rawUnitPrice— 萬元/坪, TRUE raw = 總價 / 總面積 (parking still included).siteAdjUnitPrice/adjUnitPrice— 萬元/坪, the site's displayed unit price. InspectsiteUnitPriceFormula:(總價-車位總價)/(總面積-車位總面積)means parking-deducted;總價/總面積means parking-included/plain total-area.buildingUnit— the raw unit label for presale/building-unit rows, e.g.A2棟0號; use it withbuilding, date, price, and area to identify Leju-style rows.excluded+excludeReason— drop親友交易/純車位/非住宅from analysis.isPresale— 預售屋; keep but note.parkPriceIncluded+parkPriceSource— parking exists but no separate parking price is reported. In this case the numerator stays native; no invented official parking price is subtracted.confidence+parkingRefSource— provenance of the adjustment basis. Treat as a rollup signal, not an independent valuation model.txnDate("YYYY-MM"),totalPriceWan,totalAreaPing,floor,layout,note.
Without --refine you get faithful Clean Raw Records (no judgement) — refine yourself if you prefer.
Notes & limits
- Runtime: one transient headless browser (~2.5s/query, ~200MB). Requires the
chrome-headless-shellbrowser binary — install withnpx playwright install chromium-headless-shell, or setLVR_HEADLESS_SHELL. - No
agent-browserskill, logged-in Chrome profile, or interactive browser automation is required. - In Codex, a macOS
MachPortRendezvous/bootstrap_check_inpermission error means the sandbox blocked Chromium. Rerun the command outside the sandbox/escalated; do not treat it as a site-change signal. - Data source: 內政部 open data under the 政府資料開放授權條款 (OGDL / CC-BY). Attribute 內政部 when redistributing.
- The data is de-identified by law (no owner names); do not attempt to re-identify owners.