Skip to content

m-dev-tools/m-cli-extras

Repository files navigation

m-cli-extras

Out-of-tree subcommands for the m-cli toolchain.

m-cli's core stays focused on the canonical 5 commands (fmt/lint/test/coverage/doc). m-cli-extras is the bucket for niche, opinionated, or third-party-flavored utilities that shouldn't bloat core but are still worth having a place for.

Plugins register against m-cli via the m_cli.plugins Python entry-point group. After installing this package, each plugin shows up as a regular m <name> subcommand:

$ pip install m-cli-extras   # or: uv add m-cli-extras
$ m plugins
m-cli plugin API v1

Registered plugins (1):
  m corpus-stats   (m-cli-extras 0.1.0)

Shipped subcommands

Command What it does
m corpus-stats Walk a directory of .m files, report file / line / label / parse-error counts.

More to come — see the m-cli-extras roadmap below for the candidate list.

m corpus-stats — quick reference

$ m corpus-stats /path/to/corpus
corpus                          /path/to/corpus
files                           1234
total_lines                     287654
total_labels                    9821
files_with_parse_errors         12

$ m corpus-stats /path/to/corpus --json
{
  "corpus": "/path/to/corpus",
  "files": 1234,
  "total_lines": 287654,
  "total_labels": 9821,
  "files_with_parse_errors": 12
}

Use cases:

  • Sizing rule profiles before lint runs (find out how big a regression gate would be).
  • Sanity-checking a corpus acquisition step (did we really get all 39,330 VistA routines?).
  • Quick "how big is this codebase" answers without spinning up a full lint pass.

Installation

Standard pip / uv install once the package is on PyPI. Until then, install from a clone alongside m-cli:

git clone https://github.com/m-dev-tools/m-cli ~/projects/m-cli
git clone https://github.com/m-dev-tools/m-cli-extras ~/projects/m-cli-extras
cd ~/projects/m-cli-extras
uv sync --extra dev

pyproject.toml declares m-cli as a sibling path-dep ({ path = "../m-cli", editable = true }). Once m-cli ships its own wheel via the same release-asset pattern tree-sitter-m uses, this will switch to a URL pin.

Adding a new plugin

The plugin contract is documented at m-cli/docs/plugin-development.md.

To add a new subcommand to this package:

  1. Create src/m_cli_extras/<name>/cli.py with a register(subparsers) function (see corpus_stats/cli.py as the worked example).

  2. Add the entry-point to pyproject.toml:

    [project.entry-points."m_cli.plugins"]
    <name> = "m_cli_extras.<name>.cli:register"
  3. Write tests in tests/test_<name>.py.

  4. Update this README's "Shipped subcommands" table.

The integration boundary is the entry-point — that's where m-cli calls into the plugin. Test the register() function with a fresh argparse.ArgumentParser per test; you don't need to install the plugin to test it.

Roadmap

Candidates from the m-dev-tools sprint plan (Tier 6b):

  • m bench — perf benchmarking m-cli operations against a corpus
  • m diff — semantic AST diff between two .m files
  • m migrate <preset> — bulk-apply Phase A formatter translation
  • m audit — license/header audit for a project's .m files

These will land incrementally as the need surfaces. Open an issue if you want to prioritize one.

License

AGPL-3.0 — parity with m-cli and the rest of the m-dev-tools toolchain.

About

Out-of-tree subcommands for m-cli — niche utilities (m corpus-stats, etc.) registered via the m_cli.plugins entry-point group

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors