Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ __pycache__/
!/dist/commands.json
!/dist/lint-rules.json
!/dist/fmt-rules.json
!/dist/m-test-engine.json
/build/
*.egg-info/
.mypy_cache/
Expand Down
18 changes: 17 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,23 @@ dist/fmt-rules.json: $(FMT_SOURCES)
@mkdir -p dist
$(M) fmt --list-rules --json > $@

manifest: dist/commands.json dist/lint-rules.json dist/fmt-rules.json
# Vendored from m-dev-tools/m-test-engine. The source of truth is
# $(M_TEST_ENGINE)/dist/m-test-engine.json — copied here at release
# time so a fresh `pip install m-cli` carries the engine contract
# without needing network access. The drift gate (`git diff --exit-code
# dist/` below) catches missed re-vendoring after an upstream bump.
#
# If M_TEST_ENGINE is not a local checkout, the rule is a no-op — the
# vendored copy already in git is treated as authoritative.
M_TE_MANIFEST := $(wildcard $(M_TEST_ENGINE)/dist/m-test-engine.json)
ifneq ($(M_TE_MANIFEST),)
dist/m-test-engine.json: $(M_TE_MANIFEST)
@mkdir -p dist
cp $< $@
@echo "vendored dist/m-test-engine.json from $(M_TEST_ENGINE)"
endif

manifest: dist/commands.json dist/lint-rules.json dist/fmt-rules.json dist/m-test-engine.json

check-manifest: manifest
git diff --exit-code dist/
Expand Down
5 changes: 5 additions & 0 deletions dist/commands.json
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,11 @@
],
"examples": []
},
"engine": {
"purpose": "Manage the m-test-engine container (install/start/stop/...)",
"options": [],
"examples": []
},
"errors": {
"purpose": "List every U-STD* error code and the labels that raise it",
"options": [
Expand Down
33 changes: 33 additions & 0 deletions dist/m-test-engine.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"$schema": "https://raw.githubusercontent.com/m-dev-tools/m-test-engine/main/dist/m-test-engine.schema.json",
"protocol": 1,
"image": "ghcr.io/m-dev-tools/m-test-engine",
"default_tag": "r2.02",
"container": "m-test-engine",
"bind_mount": {
"host": "/m-work",
"container": "/m-work",
"mode": "rw"
},
"compose_file": "docker/compose.yml",
"repo_url": "https://github.com/m-dev-tools/m-test-engine",
"min_docker": "20.10",
"ydb_version": "r2.02",
"run_args": {
"hostname": "m-test-engine",
"working_dir": "/m-work",
"restart": "unless-stopped",
"volumes": [
{
"name": "m-test-engine-globals",
"target": "/data"
}
],
"command": [
"tail",
"-f",
"/dev/null"
]
},
"verified_on": "2026-05-11"
}
41 changes: 41 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
created: 2026-05-11
last_modified: 2026-05-11
revisions: 0
doc_type: [REFERENCE]
---

# m-cli — Documentation Index

> First-pass index generated 2026-05-11. Labels follow the shared vocabulary below; the same vocabulary is used across all m-dev-tools repos.

## Vocabulary

Each doc is labeled `[TYPE · type? · connection · connection?]`.

**Types** — `HISTORY` · `ARCHITECTURE` · `DESIGN` · `ADR` · `SPEC` · `REFERENCE` · `GUIDE` · `TUTORIAL` · `ROADMAP` · `PLAN` · `RESEARCH` · `SURVEY` · `GAP-ANALYSIS` · `STATUS` · `EXPLAINER` · `NOTES` · `WORKED-EXAMPLE` · `SETUP` · `INTEGRATION` · `PROPOSAL` · `BUILD-LOG` · `CHANGELOG` · `POSTMORTEM`

**Repo connections** — `history` · `function` · `design` · `architecture` · `planning` · `implementation`

## Top-level

- **`evolution.md`** — `[HISTORY · BUILD-LOG · history · implementation]` Chronological narrative of how m-cli was built tier by tier, milestone by milestone, with performance journey and deferred items.
- **`guide.md`** — `[GUIDE · REFERENCE · function · architecture]` Comprehensive user-facing reference covering every subcommand, configuration, profiles, and the four-tier framework m-cli implements.
- **`m-linting-user-guide.md`** — `[GUIDE · function]` How-to guide for `m lint`: profiles, severity, thresholds, output formats, inline disables, and CLI flags.
- **`plugin-development.md`** — `[GUIDE · SPEC · function · architecture]` Contract and walkthrough for registering out-of-tree subcommands via the `m_cli.plugins` entry-point group.
- **`pre-commit.md`** — `[GUIDE · INTEGRATION · function]` Downstream pre-commit integration recipe for `m-fmt-check`, `m-fmt`, and `m-lint` hooks via `language: system`.
- **`vista-meta-bootstrap.md`** — `[HISTORY · EXPLAINER · history · design]` Records how the vista-meta YottaDB container bootstrapped m-cli development and why m-cli is now engine-independent.
- **`worked-example-accsum.md`** — `[WORKED-EXAMPLE · TUTORIAL · function]` End-to-end TDD walkthrough building an `accsum` access-log summariser to demonstrate every `m` subcommand in context.

## `plans/` — design proposals, surveys, status reports, and implementation plans tracking m-cli's roadmap

- **`plans/iris-ydb-portability.md`** — `[PLAN · RESEARCH · planning · architecture]` Function-by-function IRIS vs YottaDB CLI comparison with an engine-adapter refactor plan for cross-engine dispatch.
- **`plans/language-cli-survey.md`** — `[SURVEY · GAP-ANALYSIS · planning · design]` Survey of Rust/Go/Python/JS/Java CLI toolchains scored on productivity and quality, closing with a rank-ordered m-cli gap analysis.
- **`plans/linter-profiles-guide.md`** — `[DESIGN · PROPOSAL · design · planning]` Proposes splitting the `sac` profile into four mechanism-grounded profiles (KIDS-build / vista / safety / sac-style) by gatekeeper.
- **`plans/m-cli-history-and-evolution.md`** — `[HISTORY · EXPLAINER · history · architecture]` Chronicles the six-week sprint birthing m-tools, vista-meta, m-standard, tree-sitter-m, m-cli, and m-stdlib as cooperating siblings.
- **`plans/m-corpus-catalog.md`** — `[REFERENCE · RESEARCH · planning]` Catalog of non-VistA open-source M corpora vetted as candidates for the M-MOD-NN regression gate.
- **`plans/m-env-implementation-plan.md`** — `[PLAN · planning · implementation]` Self-contained implementation guide for an `m-env` POC proving containerized YottaDB/IRIS environments before folding into m-cli.
- **`plans/m-environment-tool.md`** — `[PROPOSAL · DESIGN · design · planning]` Design proposal for `m init` / `m env` / `m doctor` commands managing Dev Container-based M execution environments.
- **`plans/m-linter-status-2026-04-30.md`** — `[STATUS · POSTMORTEM · implementation]` Comprehensive audit of every shipped lint rule against a 4,215-routine non-VA corpus with prioritized fixes and landed deltas.
- **`plans/m-linting-implementation-plan.md`** — `[PLAN · BUILD-LOG · planning · implementation]` Phase-by-phase tracker for the M-MOD-NN modernization track, vista split, thresholds, engine-aware rules, and data-flow research.
- **`plans/m-linting-survey.md`** — `[SURVEY · GAP-ANALYSIS · design · planning]` Audits the 42 XINDEX/SAC rules for modern relevance and proposes a rank-ordered greenfield rule set drawn from first principles.
7 changes: 7 additions & 0 deletions docs/evolution.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
---
created: 2026-05-10
last_modified: 2026-05-10
revisions: 1
doc_type: [HISTORY, BUILD-LOG]
---

# m-cli — evolution

How m-cli was built, in chronological order. This is **archaeology** — read the
Expand Down
7 changes: 7 additions & 0 deletions docs/guide.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
---
created: 2026-04-27
last_modified: 2026-05-10
revisions: 12
doc_type: [GUIDE, REFERENCE]
---

# m-cli — Comprehensive Guide

**Document type:** Reference + roadmap
Expand Down
7 changes: 7 additions & 0 deletions docs/m-linting-user-guide.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
---
created: 2026-04-30
last_modified: 2026-05-10
revisions: 2
doc_type: [GUIDE]
---

# m lint — User Guide

The `m lint` command checks `.m` source for engine-neutral logic, style,
Expand Down
7 changes: 7 additions & 0 deletions docs/plans/iris-ydb-portability.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
---
created: 2026-04-30
last_modified: 2026-05-10
revisions: 2
doc_type: [PLAN, RESEARCH]
---

# IRIS ↔ YottaDB CLI Comparison — Portability Plan for `m-cli`

> **Purpose.** A function-by-function comparison of the command-line surface
Expand Down
11 changes: 11 additions & 0 deletions docs/plans/language-cli-survey.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
---
created: 2026-04-30
last_modified: 2026-05-10
revisions: 4
doc_type: [SURVEY, GAP-ANALYSIS]
---

# Language CLI Survey — Tooling Landscape and `m-cli` Gap Analysis

> **Purpose.** A comprehensive survey of the CLI toolchains shipped by five of the
Expand All @@ -6,6 +13,10 @@
> software development life cycle (SDLC). Closes with a rank-ordered gap analysis
> for `m-cli` — the canonical CLI for the M (MUMPS) language.
>
> **Implementation:** the actionable punch list for Phase 3b/3c (with
> dependencies, priorities, and exit criteria) lives in
> [`phase-3-plan.md`](phase-3-plan.md). Phase 3a is shipped.
>
> **Scope.** Five languages: **Rust, Go, Python, JavaScript/TypeScript, Java.**
> Chosen for top consistent rankings (TIOBE / Stack Overflow / GitHub Octoverse
> 2024–2026) and for spanning the design space — single-binary unified CLIs
Expand Down
7 changes: 7 additions & 0 deletions docs/plans/linter-profiles-guide.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
---
created: 2026-05-06
last_modified: 2026-05-10
revisions: 2
doc_type: [DESIGN, PROPOSAL]
---

# Linter Profiles Guide

**Status:** design / review artifact. **Drafted 2026-05-06**, rewritten same day after the realization that the right organizing axis for SAC rules is *which gatekeeper enforces them*, not *which era they came from*. This doc proposes splitting today's `sac` profile into four mechanism-grounded profiles and reorganizing tags accordingly.
Expand Down
4 changes: 4 additions & 0 deletions docs/plans/m-cli-history-and-evolution.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ title: m-cli — history and evolution
status: live (2026-05-06)
audience: anyone trying to understand how m-cli came to exist, what its precursors were, and where it sits among the M-language tooling sibling projects
companion: ../README.md (current capability surface)
created: 2026-05-06
last_modified: 2026-05-10
revisions: 3
doc_type: [HISTORY, EXPLAINER]
---

# m-cli — history and evolution
Expand Down
4 changes: 4 additions & 0 deletions docs/plans/m-corpus-catalog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ purpose: Candidate corpora for m-cli's modern-rule-set regression gate
inventory_date: 2026-04-29
inventoried_by: research pass for m-cli M-MOD-NN rule design
scope: Public, post-2010-active, NOT VistA-derived, substantial enough to surface real lint findings
created: 2026-04-30
last_modified: 2026-05-10
revisions: 2
doc_type: [REFERENCE, RESEARCH]
---

# Catalog: open-source M / MUMPS / ObjectScript corpora (non-VistA)
Expand Down
7 changes: 7 additions & 0 deletions docs/plans/m-env-implementation-plan.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
---
created: 2026-05-07
last_modified: 2026-05-10
revisions: 4
doc_type: [PLAN]
---

# `m-env` Implementation Plan

**Document type:** self-contained implementation guide
Expand Down
7 changes: 7 additions & 0 deletions docs/plans/m-environment-tool.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
---
created: 2026-05-07
last_modified: 2026-05-10
revisions: 4
doc_type: [PROPOSAL, DESIGN]
---

# `m environment` / `m doctor` / `m init` — Engine Environment Strategy

**Document type:** design proposal
Expand Down
7 changes: 7 additions & 0 deletions docs/plans/m-linter-status-2026-04-30.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
---
created: 2026-04-30
last_modified: 2026-05-10
revisions: 4
doc_type: [STATUS, POSTMORTEM]
---

# `m lint` — Status & Audit Report

**Date:** 2026-04-30 *(filename was requested as `m-linter-status-2024-04-40.md`; date corrected — 2024 was a typo and `04-40` is not a valid date)*
Expand Down
7 changes: 7 additions & 0 deletions docs/plans/m-linting-implementation-plan.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
---
created: 2026-04-30
last_modified: 2026-05-10
revisions: 4
doc_type: [PLAN, BUILD-LOG]
---

# M Linting Implementation Plan

**Status:** working plan, derived from [`docs/m-linting-survey.md`](m-linting-survey.md) §7 (greenfield rule list) and §8 (roadmap), informed by [`docs/m-corpus-catalog.md`](m-corpus-catalog.md) for the regression gate.
Expand Down
7 changes: 7 additions & 0 deletions docs/plans/m-linting-survey.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
---
created: 2026-04-30
last_modified: 2026-05-10
revisions: 2
doc_type: [SURVEY, GAP-ANALYSIS]
---

# M Linting Survey & Greenfield Recommendations

**Status:** the four open questions in the original draft (§9) are now
Expand Down
29 changes: 29 additions & 0 deletions docs/plugin-development.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
---
created: 2026-05-09
last_modified: 2026-05-09
revisions: 1
doc_type: [GUIDE, SPEC]
---

# Plugin development

m-cli's built-in subcommands (`m fmt`, `m lint`, `m test`, `m doc`, …)
Expand Down Expand Up @@ -124,6 +131,28 @@ def my_command(args):
if no transport is available — let the exception propagate; the user
gets a useful message.

## Engine drivers (out-of-tree)

A second, narrower entry-point group exists for engine lifecycle
drivers: **`m_cli_engines`**. Out-of-tree drivers implement the
[`m_cli.engine_driver.EngineDriver`][] Protocol and register the class
(not a function) under their name:

```toml
[project.entry-points."m_cli_engines"]
iris = "m_cli_iris_engine.driver:IrisDriver"
podman = "m_cli_podman_engine.driver:PodmanDriver"
```

The built-in `docker` driver is **not** registered through this group —
m-cli always falls back to `DockerDriver` when no override is
requested. The group is the seam for adding non-Docker engines without
forking core. `m_cli.engine_driver.discover_drivers()` walks the group
for `m engine`'s capability output and future driver-selection UX.

Same `PLUGIN_API_VERSION = 1` envelope: the group name + the
`EngineDriver` Protocol shape are part of the v1 contract.

## Versioning

`m_cli.plugins.PLUGIN_API_VERSION` is currently `1`. We bump it on a
Expand Down
7 changes: 7 additions & 0 deletions docs/pre-commit.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
---
created: 2026-04-27
last_modified: 2026-05-07
revisions: 2
doc_type: [GUIDE, INTEGRATION]
---

# Pre-commit integration

`m-cli` ships a [pre-commit](https://pre-commit.com) hook scaffold so
Expand Down
7 changes: 7 additions & 0 deletions docs/vista-meta-bootstrap.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
---
created: 2026-05-10
last_modified: 2026-05-10
revisions: 1
doc_type: [HISTORY, EXPLAINER]
---

# vista-meta bootstrap — and why m-cli is independent of it now

This document records how the `vista-meta` YottaDB container was used during
Expand Down
7 changes: 7 additions & 0 deletions docs/worked-example-accsum.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
---
created: 2026-05-09
last_modified: 2026-05-09
revisions: 2
doc_type: [WORKED-EXAMPLE, TUTORIAL]
---

# Worked example — building `accsum` with `m`, TDD, and m-stdlib

**Document type:** end-to-end walkthrough
Expand Down
4 changes: 4 additions & 0 deletions src/m_cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from m_cli.doc.manifest import manifest_command
from m_cli.doc.search import search_command
from m_cli.doctor import doctor_command
from m_cli.engine_cli import add_engine_arguments
from m_cli.fmt import fmt_command
from m_cli.lint import lint_command
from m_cli.lsp import lsp_command
Expand Down Expand Up @@ -508,6 +509,9 @@ def build_parser() -> argparse.ArgumentParser:
)
lsp_parser.set_defaults(func=lsp_command)

# `m engine` — lifecycle for m-test-engine container
add_engine_arguments(subparsers)

# `m doctor`
doctor_parser = subparsers.add_parser(
"doctor",
Expand Down
Loading
Loading