Metadata-Version: 2.4
Name: memprobe
Version: 0.1.1
Summary: Firmware memory budgets and size-regression checks for CI. Your binary stays local.
Author-email: memprobe <memprobe@gmail.com>
License: MIT
Project-URL: Homepage, https://memprobe.dev
Project-URL: Documentation, https://memprobe.dev/docs
Project-URL: Repository, https://github.com/memprobe-dev/memprobe_api
Project-URL: Issues, https://github.com/memprobe-dev/memprobe_api/issues
Keywords: firmware,embedded,elf,memory,ci,size,budget
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Embedded Systems
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: click>=8.0
Requires-Dist: pyelftools>=0.29
Requires-Dist: requests>=2.25
Requires-Dist: rich>=13.0
Requires-Dist: tomli>=1.1.0; python_version < "3.11"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Dynamic: license-file

# memprobe

Firmware memory budgets and size-regression checks for CI, from the command line.

`memprobe` reads the section and symbol table out of your ELF locally and
sends only that metadata to the [memprobe](https://memprobe.dev) API, which
returns the analysis. Your binary never leaves your machine: only the sizes
and symbol names it contains are sent, the same information `readelf` and
`nm` print.

```bash
pip install memprobe
```

## Quick start

1. Create an API key at <https://memprobe.dev> (Account → API keys).
2. Point the CLI at it:

   ```bash
   memprobe config set --key mp_live_xxxxxxxx
   ```

3. Check a build against budgets:

   ```bash
   memprobe init            # writes a memprobe.toml with flash/ram budgets
   memprobe check build/firmware.elf
   ```

   `check` exits non-zero when a budget is exceeded, so it gates a CI job.

## Commands

| Command | What it does |
|---|---|
| `memprobe analyze <elf>` | Size summary: flash/ram totals, biggest sections and symbols. |
| `memprobe check <elf>` | Fail (exit 1) if a budget in `memprobe.toml` is exceeded. The CI gate. |
| `memprobe diff <old> <new>` | Size change between two builds, with per-symbol deltas. `--format markdown` for PR comments. |
| `memprobe init` | Scaffold `memprobe.toml` with flash/ram budgets. |
| `memprobe account` | Show your plan and this month's usage. |
| `memprobe config set --key <key> [--server <url>]` | Store your API key (in `~/.memprobe/config.json`). |
| `memprobe config show` | Show the current key (masked) and server. |

`MEMPROBE_API_KEY` and `MEMPROBE_SERVER` environment variables override the
stored config, which is convenient in CI.

## CI

Because `memprobe check` exits non-zero when a budget is exceeded, it works as a
gate in any CI system. Run it as a build step with `MEMPROBE_API_KEY` set as a
secret:

```bash
pip install memprobe
memprobe check build/firmware.elf
```

On GitHub, [memprobe-action](https://github.com/memprobe-dev/memprobe-action)
wraps this and also posts a size report with symbol-level changes as a PR
comment:

```yaml
- uses: memprobe-dev/memprobe-action@v1
  with:
    file: build/firmware.elf
    api-key: ${{ secrets.MEMPROBE_API_KEY }}
```

## What runs where

| | Local (this tool) | memprobe API |
|---|---|---|
| Reads your ELF | yes | never sees the binary |
| Extracts sections/symbols | yes (via pyelftools) | no |
| Budget / diff / bloat analysis | no | yes |

This package contains no analysis logic and no proprietary code: it's a thin,
open-source client. The deeper analysis (call graph, dead-code, stack usage,
source attribution) lives in the web app at <https://memprobe.dev>.

## License

MIT
