Which jm command do I want?¶
A quick lookup, not a tutorial: find the command, then open its command page for the details.
Starting a project¶
No just-makeit.toml yet? jm new <project> scaffolds a complete, building,
tested project. Add --object <name> or --module <mod> to create your first
component in the same step.
Creating a component¶
| To create… | run… |
|---|---|
A stateful class in its own .so |
jm object <name> |
Several classes sharing one .so |
jm module <mod>, then jm object <name> --module <mod> |
| A stateless C function (no class) | jm function <fn> --module <mod> |
New object? Its step() shape and state come next under
Shaping an object.
Extending a component¶
| To add… | run… |
|---|---|
| A named execute method | jm method <obj> <name> |
| A read-only Python property | jm property <obj> <name> |
| A read-write property | jm property <obj> <name> --writable |
| A state field | jm add --state <var>:T [--object <obj>] |
| A warning after construction | jm warning <obj> --condition <field> --message "…" |
A specific create()-failure exception |
jm error <obj> --category ValueError --message "…" |
| A second Python class over the same C core | jm view <obj> <ClassName> --module <mod> --create-fn <fn> |
A SIMD / JM_HOT performance pass |
jm perf |
Shipping and operating¶
| To… | run… |
|---|---|
| Package a runnable app (C / console / PEP 723) | jm app --target c\|console\|pep723 |
| Build, test, or benchmark | jm build · jm test · jm bench |
| Push hand-edited TOML into files | jm apply (see below) |
| Compose an external fragment | jm apply <fragment.toml> |
| Rebuild a component from the manifest | jm regenerate <name> (see below) |
| Delete generated code and its wiring | jm remove <kind> <name> |
| Reconstruct the CLI history from TOML | jm script |
| Upgrade an old project's schema | jm upgrade |
Shaping an object¶
jm object defaults to a 1:1 processor over float _Complex. For any other
shape, pass a --preset — or the flags it stands for:
Your step() |
Preset | …the flags it stands for |
|---|---|---|
| input → output (1:1) | processor (default) |
--arg-type "float _Complex" |
| array → one sample | — | --arg-type "T[]" (steps() not generated) |
| nothing in, samples out | generator |
--arg-type void (complex return by default) |
| samples in, nothing out | consumer |
--return-type void |
no step(), custom verbs |
reader |
--no-step (+ --init-param filepath:"const char *" to open a file) |
| array → array | blockwise |
override --arg-type / --return-type |
And what state it carries:
| State | How |
|---|---|
| Scalar defaults only | [[state]] entries (the default path) |
| No internal state | --no-state + [[init_params]] |
| Public ctor ≠ internal state | [[state]] + [[init_params]] + create_impl |
| A field overridable per call | state.controllable = true (TOML only) |
Shaping a method's output¶
For jm method, the output shape is a TOML setting on the method:
| Output | Setting |
|---|---|
| Fixed N out for N in (resampler) | out_type="float", out_divisor=2 |
| Variable count out (event emitter) | variable_output=true (provide <comp>_<name>_max_out(state, n)) |
| A list of records (events) | result_fields=[{name, type}, …] |
| Several parallel buffers | multi_output=["float _Complex", …] |
| Excluded from benchmarks | bench=false |
Wiring an external library¶
Declare how it's found on [project]:
| It's… | Declaration |
|---|---|
| A vendored C subdir | c_deps = ["liba", "libb"] |
Findable by find_package |
find_packages = ["Doppler"] |
| A pkg-config module | pkg_modules = ["doppler"] |
Then link or include it on the component (or module) that uses it:
extra_link_libs = ["${DOPPLER_LIBRARY}"],
extra_include_dirs = ["${DOPPLER_INCLUDE_DIR}"].
apply vs regenerate¶
You edited just-makeit.toml by hand. Which command carries the change into
the generated files?
jm apply |
jm regenerate <name> |
|
|---|---|---|
| Use when | Glue changed — _ext.c, .pyi, CMakeLists.txt, or a new method/property that just needs to reach the public API |
Structural change — a new state field or a changed signature |
| What it does | Regenerates glue and injects missing declarations into _core.h. The state struct and inline step() are sacred; _core.c is never touched |
Deletes every file the component owns and re-runs apply. Leaves the TOML alone |
| Your hand-written code | Untouched | Lifted out and spliced back by function name; --discard skips that for a clean reset |
apply is the safe, additive refresh. regenerate is the deliberate
rebuild — reach for it when a signature change or new state field has to
re-stub the sacred _core.c. jm add is regenerate specialised for state
(always a clean reset); git stash first regardless.
When the CLI can't reach it¶
Every common TOML knob has a CLI flag — Configuration → Complete CLI ↔ TOML mapping is the authoritative status of each key. A small tail stays TOML-only by design:
opaquestate fields,no_ctorper field,controllableper field (see Arguments)init_paramsmodifiers (default_raw,real_type,real_create_fn,create_fn),init_post_parse,string_enum:init-param typesmax_results/max_results_paramon methods and functionsno_generatemodules,extra_cfiles, per-componentextra_link_libs
See Configuration for the full schema.