npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@emdzej/inpax-cli

v0.8.0

Published

inpax CLI — decompile, run, compile, edit, patch, and bundle INPA scripts. One binary subsumes the toolchain (used to be split across inpax-compiler, ipo-editor, bimmerz-bundler).

Readme

@emdzej/inpax-cli

The full inpax toolchain in a single binary. Decompile, run, compile, edit, patch, and bundle — all behind one inpax command on your PATH.

Same VM that powers the browser SPA. Same parser used to patch constants. Same compiler used to turn .IPS source into .IPO bytecode.

Heads-up: as of inpax 0.6.8 the older @emdzej/inpax-compiler, @emdzej/inpax-ipo-editor, and @emdzej/bimmerz-bundler binaries are folded into this CLI. Replace npm i -g @emdzej/inpax-compiler etc. with npm i -g @emdzej/inpax-cli; the old packages are deprecated on npm.

Install

npm i -g @emdzej/inpax-cli
inpax --help

Commands

| Command | Purpose | |---|---| | inpax decompile <file> | Print BEST/2 bytecode as readable assembly. | | inpax run <file> | Execute an .ipo in a terminal TUI or headless mode. | | inpax compile <files…> | IPS source → IPO bytecode. | | inpax compile new <file> | Scaffold a starter .ips with inpainit/inpaexit stubs. | | inpax edit <file> | Open an Ink TUI to edit constants in a compiled .ipo. | | inpax patch init <file> | Emit a starter YAML patch listing the IPO's current constants. | | inpax patch apply <file> <patch…> | Apply one or more YAML patches to an .ipo. | | inpax bundle <input-dir> | Walk an INPA / EDIABAS / NCS install, apply .bimmerzignore, write a zip. | | inpax bundle init | Scaffold a starter .bimmerzignore. |

Run any subcommand with --help for the full flag list.

inpax decompile

Decompile an IPO into readable assembly with named opcodes, resolved constants, and synthesised jump labels.

inpax decompile RADIO.IPO                       # whole file to stdout
inpax decompile RADIO.IPO -o radio.asm          # to a file
inpax decompile RADIO.IPO -f inpainit           # one function only
inpax decompile RADIO.IPO --no-color --no-raw   # plain, no per-instruction hex

| Flag | Description | |---|---| | -o, --output <file> | Write to a file instead of stdout | | -f, --function <name> | Decompile one specific function | | --no-color | Disable ANSI colour | | --no-raw | Hide the raw 4-byte hex per instruction | | --no-comments | Hide inline comments (constant resolution, etc.) | | --no-labels | Don't synthesise Lnn: labels for jump targets |

inpax run

Execute an IPO in a terminal TUI that reproduces real INPA's cell-grid screen — F-key menu, user-box dialogs, analog gauges, digital LED indicators, the lot. Or run headless for logs-only use.

inpax run MS43.IPO                              # TUI mode (default)
inpax run MS43.IPO --headless                   # log-only

# Talk to a real ECU
inpax run MS43.IPO --sgbd ~/Downloads/inpa/EDIABAS/Ecu

# Pin a complete ediabasx config (overrides --sgbd)
inpax run MS43.IPO --ediabas-config ./inpax.config.json

# Develop without a real car
inpax run MS43.IPO --mock

# Debug + VM instruction trace
inpax run MS43.IPO --debug --trace

| Flag | Default | Description | |---|---|---| | -f, --function <name> | inpainit | Entry function to invoke | | -d, --debug | off | Enable debug-level logging | | --trace | off | Trace every VM instruction (very verbose) | | --headless | off | Use the CLI provider — no TTY required | | --sgbd <path> | — | Directory containing .PRG / .GRP files for the live ECU | | --ediabas-config <path> | — | Path to an ediabas.config.json — overrides --sgbd | | --mock | off | Use the in-process mock provider (no real car needed) | | --tick <ms> | 16 | Scheduler tick interval |

TUI keymap

| Key | Action | |---|---| | 19, 0 | F1–F10 | | Shift+10 | F11–F20 | | / / PgUp / PgDn / Home / End | Scroll between LINE blocks (paginated screens) | | C | Copy current screen to clipboard | | P | Pause / resume the scheduler | | Q | Quit |

inpax compile

Compile INPA IPS source into IPO bytecode. Output drops next to each input by default; pass -o for a single file or a target directory in batch mode.

inpax compile RADIO.IPS                         # → RADIO.IPO
inpax compile *.ips -o build/                   # batch → build/<name>.ipo
inpax compile foo.ips -I ./headers -e cp1250    # custom include path + encoding

inpax compile new my-script.ips --title "Demo"  # scaffold starter .ips

| Flag | Description | |---|---| | -o, --output <path> | Output file (single input) or output directory (batch) | | -I, --include <dir> | Add directory to the #include search path. Repeatable. | | -e, --encoding <name> | Source-file encoding (default cp1252; e.g. cp1250, utf-8) | | --continue | Keep going after one file fails | | -v, --verbose | Extra info to stderr |

inpax edit

Open an Ink TUI for editing constants in a compiled .ipo. Optional codepage override for non-Latin-1 installs (cp1250 for Polish, cp1252 for German).

inpax edit MS43.IPO
inpax edit MS43.IPO --codepage cp1250            # Polish install
inpax edit MS43.IPO --readonly                   # browse only
inpax edit MS43.IPO --no-backup                  # don't write .bak on save

| Flag | Description | |---|---| | --codepage <name> | Codepage for string decode/encode (default cp1252) | | --no-backup | Don't write <file>.bak on save | | --allow-ffi | Edit strings that look like FFI descriptors | | --readonly | View only — no edits or save |

inpax patch

Non-interactive workflow for distributing translations / overrides without shipping modified IPOs. init snapshots the current constants into a YAML file; humans edit the YAML; apply writes the edits back to the IPO with checksum verification.

# Snapshot the IPO's string constants into a starter patch
inpax patch init MS43.IPO --types string --output ms43.patch.yaml

# Apply one or more patches; dry-run first to see what changes
inpax patch apply MS43.IPO ms43.patch.yaml --dry-run
inpax patch apply MS43.IPO ms43.patch.yaml -o MS43.translated.ipo

The patch format is small enough to hand-edit; see the ipo-community-patches repo for examples.

inpax bundle

Curate a BMW software install (INPA / EDIABAS / NCS) into a small zip the web tools can mount into OPFS. .bimmerzignore patterns work like .gitignore and are matched case-insensitively.

# One-shot
inpax bundle ~/inpa -o inpa-bundle.zip

# Custom ignore + dry-run preview
inpax bundle ~/inpa -i my-ignore --dry-run --verbose

# Scaffold the default ignore file to edit
inpax bundle init
inpax bundle ~/inpa -i .bimmerzignore -o inpa-bundle.zip

| Flag | Description | |---|---| | -o, --output <file> | Output zip path (default ./bimmerz-bundle.zip) | | -i, --ignore <file> | Gitignore-style file (default <input>/.bimmerzignore if present) | | --no-default-ignore | Skip the built-in install-junk patterns | | --dry-run | Walk + match but don't write the zip | | --verbose | Log every kept and skipped file |

Logging

Powered by @emdzej/bimmerz-logger. The library never reads process.env; the CLI translates env vars into the central logger config at boot.

| Variable | Values | Effect | |---|---|---| | INPAX_LOG_LEVEL | trace\|debug\|info\|warn\|error\|fatal\|silent | Default level | | INPAX_LOG_CATEGORIES | cat=lvl,cat=lvl,… | Per-category overrides (hierarchical) | | INPAX_LOG_DESTINATION | path | Write to file instead of stdout | | INPAX_LOG_FORMAT | pretty\|json | Output format |

Examples:

# Everything to debug
INPAX_LOG_LEVEL=debug inpax run MS43.IPO --trace

# Just the VM dispatcher + state machine
INPAX_LOG_CATEGORIES="INPAX.vm=trace,INPAX.state-machine-executor=debug" \
  inpax run MS43.IPO

# JSON output to file
INPAX_LOG_FORMAT=json INPAX_LOG_DESTINATION=/tmp/inpax.log \
  inpax run MS43.IPO

Categories: hierarchical dot-paths — a rule for INPAX covers every subcategory unless overridden. Current set: INPAX, INPAX.vm, INPAX.dispatcher, INPAX.internal-functions, INPAX.main-scheduler, INPAX.screen-executor, INPAX.state-machine-executor, INPAX.signature-handler, INPAX.ui-provider, INPAX.interpreter-cli.

The web app's Settings dialog has the same surface plus the EDIABASX.* categories from @emdzej/ediabasx-ediabas — see @emdzej/bimmerz-logger's README for the full API.

Development

pnpm --filter @emdzej/inpax-cli build   # tsc
pnpm --filter @emdzej/inpax-cli dev     # tsc --watch

Inside the workspace, pnpm cli <subcommand> runs the local build: pnpm cli decompile script.ipo is identical to running the installed binary.

Workspace aliases also exist for the most-used subcommands:

pnpm compile script.ips      # = pnpm cli compile script.ips
pnpm editor script.ipo       # = pnpm cli edit script.ipo

Related

License

PolyForm Noncommercial 1.0.0 — free for personal, research, and hobby use. Commercial use needs a separate licence.