{
  "schema": "leumas.docs.page/1",
  "id": "pkg:@leumas/lmx",
  "slug": "engines/lmx",
  "kind": "capabilities",
  "bucket": "package",
  "title": "@leumas/lmx",
  "name": "@leumas/lmx",
  "eyebrow": null,
  "chip": null,
  "summary": "LMX — the Leumas multi-interpreter scripting engine. General languages (lmx/lmy/lmz/lmm/lmc/lmn), the ecosystem languages that speak Leumas (lmq query, lmai prompt orchestration, lmg grids), and...",
  "keywords": [
    "lmx",
    "lmx language",
    "lmq",
    "lmai",
    "lma",
    "lmi",
    "lmg",
    "scripting",
    "interpreters",
    "leumas lmx"
  ],
  "audience": "both",
  "funnel": {
    "product": null,
    "cta": null
  },
  "body": "# @leumas/lmx\n\n**Sixteen little languages with one runtime.** A script's *extension* picks the interpreter — nothing\nto configure and no project file. `hello.lmx` is the full language; rename it `hello.lmm` and the same\nruntime reads it as a matrix machine.\n\nPublic face: **[lmx.leumas.tech](https://lmx.leumas.tech)** — a browser sandbox that runs the local\nmodes with no account, and the `lmx` CLI as a single downloadable file.\n\n## The sixteen\n\n| Ext | Name | What it is |\n|---|---|---|\n| `.lmx` | Full Language | General-purpose language: variables, math, if/for/while, functions, imports. |\n| `.lmy` | Sequential | One statement per line — quick, calculator-style scripting. |\n| `.lmz` | Event-driven | Register on/emit handlers; reactive event-bus scripting. |\n| `.lmm` | Math / Matrices | Vector accumulator + trigonometry + matrix algebra. |\n| `.lmc` | Constraint Solver | Declare variables + equations; solve for the unknowns from what you know. |\n| `.lmn` | Notifications | Declarative toast / alert / sound / desktop-message directives. |\n| `.lmq` | Query | Read stored collections — FROM / WHERE / SELECT / ORDER BY / aggregates. |\n| `.lmai` | Prompt Orchestration | Declare prompts and shapes, ASK a model, branch on the answer. |\n| `.lmg` | Grids | Author and run a programming grid as text — cells, `$refs`, dependency order. |\n| `.lma` | Any-tool | Call anything this install has — adapters, actions, MCP tools, capabilities. |\n| `.lmi` | Install | Ask the RUNNING deployment what it is and what it can actually do. |\n| `.lms` | Shell Automation | Runs OS shell commands (RUN / CAPTURE / IF_SUCCESS). |\n| `.lmk` | GUI Automation | Controls mouse/keyboard via robotjs (native desktop only). |\n| `.lmd` | Command Dispatch | Discovers namespaced commands and spawns them (experimental). |\n| `.lmnet` | Network | ping / fetch / post over the network (SSRF-sensitive). |\n| `.lmt` | Timers | after/every time blocks that dispatch other scripts (experimental). |\n\nThat table is **generated from `src/host/interpreters.catalog.js`**, which is also what the API's\n`/api/lmx/interpreters` route, the Studio picker and `INTERPRETERS.md` read. There is one list.\n\n## Three tiers, and the difference is not politeness\n\n**Local** (`lmx lmy lmz lmm lmc lmn lmg`) — no host access at all. These run anywhere: the browser\nsandbox, the CLI, the API.\n\n**Install-backed** (`lmq lmai lma lmi`) — their *vocabulary is a running Leumas*. `lma` has no verb\ntable: its verbs are every adapter tool, every stored functioncall, every automation action, every\nMCP tool and every capability the install currently holds, so registering an adapter makes existing\nscripts able to call it with nothing rebuilt. These need an identity, because they read somebody's\ndata, spend somebody's model credits and call somebody's tools. They are refused by name in the\npublic sandbox and by the CLI unless it is pointed at an install with `--studio`.\n\n**Privileged** (`lms lmk lmd lmnet lmt`) — these touch the host. Admin role **and** an explicit env\nflag (`LMX_ENABLE_SHELL` / `LMX_ENABLE_GUI` / `LMX_ENABLE_NET`), both off by default. That is a\nsecurity control, not a paywall — LMX is free.\n\n## Running a script\n\nThree entry points, and the difference between the first two is the whole design:\n\n```js\nimport { runScript } from '@leumas/lmx';        // a WORKER: isolated, hard deadline, terminate()\nimport { runLocal }  from '@leumas/lmx/local';  // IN-PROCESS: no deadline, no bridges, streams to stdout\nimport { INTERPRETERS } from '@leumas/lmx/catalog';  // the catalogue alone — no express, browser-safe\n```\n\n`runScript` is right for a **server** running somebody else's script: the timeout is the only real\nbound on a `while (true)`, and it never rejects — a syntax error is `{ok: false, error}`, which is\nwhat lets a caller tell a failed script from a request that never arrived.\n\n`runLocal` is right for a **command**: a person running their own script on their own machine wants\nstdin, a TTY, an exit code and no five-second cap. It is also the only shape a single-file build can\ncarry.\n\n> [warning] **Import the leaves, not the barrel, unless you serve HTTP.** `.` re-exports `createLmxRouter`,\n> which imports **express** — free inside the API, and a whole web framework inside a CLI binary.\n> `@leumas/lmx/local` and `@leumas/lmx/catalog` carry neither.\n\n## HTTP\n\n| Route | Auth | What |\n|---|---|---|\n| `GET /api/lmx/interpreters` | member | the catalogue, with each mode's `enabled` flag |\n| `GET /api/lmx/demos` · `/demos/:id` | member | the bundled example scripts |\n| `POST /api/lmx/run` | member | `{mode, source, inputs?}` — every safe mode, bridges wired to the caller |\n| `GET /api/lmx/public/interpreters` | **none** | only what the sandbox will run |\n| `POST /api/lmx/public/run` | **none** | the anonymous sandbox — see below |\n\nThe **public** pair is a separate router (`createPublicLmxRouter`), not the authenticated one with a\nsofter guard: `createLmxRouter` turns every route into an open one when handed a non-function\n`requireAuth`, and making that conditional would arm exactly that trap. Its bounds are inside the\nrouter, not around it — a narrowed mode list, no bridges and no `adapter()`, a hard 3s deadline, a\nsource cap and a concurrency cap. It is mounted only where the role declares `publicSandbox`, so a\ncustomer's appliance never carries it.\n\n**The bridges are FACTORIES**, `(user) => bridge`, built per request. One bridge built at mount time\nand shared would hand every user the first user's permissions, key and wallet.\n\n## The CLI\n\n```sh\nlmx hello.lmx                  # the extension picks the interpreter\nlmx -e 'print(6 * 7)' -m lmx   # a string\nlmx modes                      # every interpreter and where it runs\nlmx --studio https://api.leumas.tech --token <t> report.lmq\n```\n\nShipped as **one file** per machine (`pnpm lmx:binary`), built by the same Node SEA lane as\nLeumasNode. Exit codes are a contract: `0` ran, `1` the script or the request failed, `2` you called\nit wrong.\n\n## Traps\n\n- **An `lmai` reply is not proof a model ran.** `providerRegistry.resolve()` never fails — `auto`\n  falls back to an echo stub. A *shaped* ask on the stub echoes the prompt, which contains the\n  `SHAPE` example, so a flawless-looking classification can be your own example handed back.\n  `stub: true` and `tokens: 0` are the only tells, and the runner prints a warning by itself.\n- **`lmi` must never answer \"yes\" by default.** No entitlement engine wired means `unknown`, never\n  `true`. And entitled ≠ fulfillable: `CAN` and `PROVIDERS FOR` are different questions.\n- **`{{ $C1 }}`, not `{{C1}}`**, in a template cell — the bare form renders the literal text.\n- **The in-script `adapter()` builtin is unmetered.** `lma`'s `USE` charges against the same\n  `tool:<ref>` target the HTTP route does; the older builtin does not, and changing it would alter\n  existing scripts' behaviour.\n\n## Verify\n\n`pnpm smoke:lmx` (every safe mode, every bridge, every gate, docs drift) ·\n`pnpm smoke:lmx-public` (the anonymous lane: what it refuses) ·\n`pnpm smoke:lmx-cli --binary` (the shipped binary, which is the only thing that sees the SEA defects) ·\n`node --test shared/engines/lmx/src/test/*.test.js`.\n\nAgent skill: `leumas-lmx`. Per-language references: `docs/{lma,lmi,lmq,lmai,lmg}.md`.\n",
  "source": {
    "path": "shared/engines/lmx/README.md",
    "blobSha": "",
    "commit": "",
    "committedAt": "",
    "provenance": "no-git",
    "bytes": 7484,
    "hash": "7c50d1058381b9eb023edac365f32f7f8d33f612"
  },
  "urls": {
    "html": "/p/engines/lmx",
    "json": "/docs/engines/lmx.json",
    "md": "/docs/engines/lmx.md"
  },
  "links": {
    "composes": [
      "pkg:@leumas/grids"
    ],
    "usedBy": [
      "pkg:@leumas/dynamic"
    ],
    "product": [],
    "howTo": [
      "how-to:dynamic-layer"
    ],
    "skills": [
      "skill:leumas-lmx"
    ]
  },
  "exports": null
}
