* test(doctests): `lm` publishes the LIDL contract vocabulary, not Qt names
A universal module's `getMethods()` comes from the cdylib backend's
`lidlInterfaceJson()` (logos-plugin-qt's glue forwards
`logos_module_get_methods` verbatim), and that now answers in the LIDL
contract spelling. `lm methods`, `lm events` and `logoscore module-info`
print those strings straight through, so every listing in Part 1 changed:
qlonglong add(qlonglong a, qlonglong b) -> int add(int a, int b)
QString libVersion() -> tstr libVersion()
void versionReady(QString version) -> void versionReady(tstr version)
Six `expect_contains` in tutorial-wrapping-c-library.test.yaml were pinned
to the Qt spellings and now fail.
HOW THIS WAS ALMOST MISSED, because the trap will recur. The hand-pinned
`outputs/tutorial-wrapping-c-library.md` already showed `int add(int a, int b)`
and `add(int,int)` — a stale snapshot from an earlier era that happened to
read as "already LIDL, nothing to do". CI runs the ASSERTIONS in
`tests/*.test.yaml`; it never diffs the outputs tree. Clearing a file by
reading `outputs/` proves nothing.
Every replacement string is derived mechanically rather than by hand: the
tutorial's own `src/calc_module_impl.h` + `metadata.json` were run through
`logos-cpp-generator --from-header --backend cdylib`, the emitted
`lidlInterfaceJson()` was parsed back into JSON, and that JSON was rendered
through logos-module's own printer (`cmd/main.cpp`) and logoscore's
(`src/client/output.cpp`). The displayed blocks in BOTH trees now compare
byte-identical to that render.
Two accuracy fixes fall out of doing that, both pre-existing drift in the
blocks being rewritten:
* the derived identity methods `name()` / `version()` DO appear in every
listing (nothing filters `derived` on the read side) and were missing
from the shown output;
* the `module-info` block said `libVersion() -> QString` and
`versionReady(version: QString)`.
The C++-type table gains a column. "On the wire (Qt)" conflated two
different questions; it is now "LIDL contract type" — what the module
publishes, what Step 5 prints, what a Rust or Nim binding sees — and "A Qt
consumer sees", which is only the C++/Qt caller's spelling.
Also here, same cause:
* tutorial-composing-modules and tutorial-interface-dependencies had the
same "shows up as QString ... the wire types the generated glue exposes"
prose. Their assertions are name-only, so they did not fail — but they
described the listing wrongly. `LogosMap` publishes as `{tstr: any}`,
verified by generating calc_aggregator's glue.
* logos-developer-guide.md's `lm methods --json` example was a
handwritten-Qt listing (`initLogos(LogosAPI*)`) presented as the general
case. It now shows both publishers and says which is which: a universal
module publishes its contract, a handwritten Qt plugin publishes what its
QMetaObject says.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* docs(guide): the plugin path needs the module's contract, not just its plugin
`logos-cpp-generator <plugin> [--module-only]` is documented here as a way to
generate a module's consumer wrapper, and the examples pass only the plugin.
That is now a trap for any module built with `interface: "universal"` or
`"cdylib"`: its published `getMethods()` answers in the LIDL contract
vocabulary — the same change d963871 pinned in the `lm` listings — while the
wrapper emitter reads Qt type names and falls back to QVariant / LogosMap for
anything else. The wrapper would compile and have lost every type.
The generator now takes the METHODS from the `.lidl` contract named by
`--events-from` (the flag keeps its name; the file always was the whole
contract), and REFUSES a LIDL-spelled listing when no contract was given rather
than emitting the untyped wrapper. Nix builds already pass the flag —
buildHeaders.nix finds `<module>/share/logos/<name>.lidl` — so only hand-run
invocations, which is what this section documents, had to change.
Both examples gain the flag, a second example shows the handcrafted-Qt case
that legitimately omits it, and the synopsis in the CLI reference lists it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Update artifacts for tutorial-v4. Regenerate outputs/ against the 0.2.0
release tags: every {release} reference (logos-basecamp, logos-logoscore-cli,
logos-module-builder, logos-package-manager, logos-module) now resolves to
0.2.0 in both the generated .md tutorials and the example module flake.nix
files.
- Add the missing {release} placeholder to the advanced flake.nix examples in
tutorial-wrapping-c-library and tutorial-interface-dependencies so they pin
consistently.
- run.sh: clean now also removes the .logoscore persistence dirs; --release
examples updated from tutorial-vN to 0.2.0 (repos carry semver tags;
logos-tutorial carries the tutorial-vN tag).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* docs: replace logoscore inline (-c) mode with daemon/client workflow
logos-logoscore-cli's inline mode (`logoscore -m <dir> -l <mod> -c
"mod.method(args)" --quit-on-finish`) has been removed. Update the developer
guide and the wrapping-a-C-library tutorial to use the daemon + client
workflow instead:
logoscore -D -m ./modules -l my_module & # start a daemon, pre-load module
logoscore call my_module doSomething hello # call (positional args; @file ok)
logoscore stop # stop when done
- §5.1 "Inline Mode (Legacy)" → "One-shot execution" (daemon + `call`), with a
note that inline mode was removed and a daemon-startup flags table.
- CLI quick-reference: drop the inline one-liner; show daemon pre-load instead.
- Troubleshooting "quick check": load-module + call + stop.
- tutorial-wrapping-c-library spec + its rendered output: "inline (legacy)
mode" → "the full daemon/client workflow".
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs: address review — fix §6.1 anchor, daemon readiness waits, document --config-dir
- Fix the "Running with logoscore" link anchor: #51 → #61 (the section is 6.1;
the old anchor 404s). In both the wrapping-c-library spec and its output.
- Daemon examples background `-D` then call immediately, which can race daemon
startup. Wait for readiness (`until logoscore status; do sleep 0.2; done`) in
the §6.1 one-shot example and the troubleshooting quick-check; background the
previously-foreground openmetrics `-D` snippet too.
- Document `--config-dir` (and `--persistence-path`) in the daemon startup flags
table, since the openmetrics example uses `--config-dir`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs: daemon starts clean — drop -l, load modules via load-module
Follow-up to dropping inline mode: logoscore's daemon now starts clean (the
-l/--load-modules autoload flag is removed). Update the §6.1 one-shot example
and CLI quick-reference to start a clean daemon and load modules with
`load-module`; drop the -l row from the daemon startup flags table.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Document + verify event introspection in the tutorials
Mirror the per-method documentation coverage for events. The
wrapping-c-library calc_module already emits a versionReady event; give
it a /// doc comment and assert the whole event pipeline end-to-end.
- wrapping-c-library: document the versionReady event; add a 'List
events' step asserting 'lm events' shows the signature + both
description lines; assert logoscore module-info's Events section.
- qml-ui-app: rename the basecamp ui_test driver call openMethods ->
openInterface and assert the event's description renders on the
Interface screen (basecamp-interface-docs.png).
- Regenerate both tutorial markdowns.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* rerun
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* demonstrate and validate method doc comments (wrapping-c-library)
Add /// doc comments to the calc module's methods and assert they surface
via `lm methods` (human + --json) and `logoscore module-info`. Corrects the
stale lm output (provider-path introspection lists only impl methods, not
eventResponse/initLogos). Regenerated the tutorial markdown.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* showcase multi-line doc comments in the calc module
factorial uses two /// lines and libVersion uses a /** ... */ block; both
join into a single-line description. Assertions and rendered output updated
to match the joined text.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* preserve multi-line doc comments in the calc module tutorial
factorial/libVersion/libVersionNotify now keep their line breaks in lm and
logoscore module-info output; assertions and rendered markdown updated.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* use consistent introspection terminology in the tutorial
Refer to "the module's method introspection" throughout instead of mixing the
internal getMethods()/getPluginMethods names. Addresses review feedback on #60.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* verify method docs on basecamp's Methods screen (Part 2 doctest)
Extends the Part 2 basecamp ui_test to open calc_module's Methods screen
(via CoreModulesView.openMethods) and assert each method's description
renders — including factorial's multi-line doc comment. Closes the GUI
surface of the per-method documentation feature in the automated doctest.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* rerun
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
support --output option ; generate both tutorials and example code from test specs
delete old code files
add to readme instructions about run.sh
update run.sh to avoid logs and hardcoded paths