Commit Graph
18 Commits
Author SHA1 Message Date
Dario LipicarandClaude Opus 5 efaa390484 docs: the widened Qt consumer surface (#84)
* 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>
2026-08-27 13:32:32 +02:00
Dario LipicarandClaude Opus 5 b8f8741801 fix(doctests): ship a 256x256 placeholder icon, per the LGX icon contract (#82)
nix-bundle-lgx 6fb5d5b ("feat: add requirement for icons with manifest
0.4.0") validates the packaged icon straight out of the PNG IHDR: exactly
256x256, required for `type == "ui_qml"`. The tutorials embed a base64
placeholder that is 64x64, so `nix build '.#lgx'` now fails for calc_ui:

    ERROR: icon does not match the Logos icon standard.
      expected: PNG, exactly 256x256
      actual:   PNG, 64x64

That one rejection is the whole of the red run (208 passed, 3 failed):
`result-lgx/` is never created, so `Install the UI plugin` fails on a
literal `result-lgx/*.lgx`, and basecamp then launches without the plugin
("No clickable element found with text 'calc_ui'").

Regenerate the placeholder at 256x256, keeping the same solid #2ECC71. It
is now a 1-bit palette PNG rather than RGBA, which makes the embedded blob
shorter than the one it replaces (280 -> 144 base64 chars, 209 -> 106
bytes) despite the 16x pixel count.

The C++ UI tutorial carried the same 64x64 blob and was passing only
because its chain never reaches an `.#lgx` step — fixed here too, before
it surfaces.

Verified by extracting bundle.sh's validator verbatim and running the
tutorials' own `- run:` command through it: the old icon is rejected with
the exact CI error text, the new one passes.

outputs/*.md are hand-maintained (they carry deliberate /0.2.0 flake pins
that the generator does not emit), so the mirrored edits there are by hand
rather than regenerated.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 23:30:29 -03:00
Dario Gabriel LipicarandClaude Opus 4.8 dbce6ad7ca tutorial-v4 release
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>
2026-06-28 00:39:59 -03:00
Dario LipicarandClaude Opus 4.8 7d811ec731 tutorial(cpp-ui): exercise the full .rep surface beyond slots (#75)
Part 3's .rep previously declared only slots. Broaden it to cover the whole
Qt Remote Objects contract a universal UI backend can author, so the tutorial
teaches the breadth of .rep, not just call-and-return:

  - SLOT(void announceVersion())             — a void / fire-and-forget slot
  - PROP(QString versionEvent READONLY)      — fed by a typed calc_module event
                                               subscription armed in onContextReady()
  - PROP(int computeCount READONLY)          — a slot-driven counter (int PROP)
  - PROP(int memory READWRITE)               — a register the QML view writes back
  - SIGNAL(computed(QString op, int result)) — a backend -> view push

The backend gains onContextReady() (event subscription) and a record() helper
(bumps computeCount, emits computed); the QML view gains a Connections block,
Computations / Last-op labels, and a Memory register with Store/Clear buttons
that assign backend.memory. Step 9's UI test drives each surface — the slot
return value, the int PROP (Computations: 1), the signal payload (add = 8),
and the READWRITE round-trip (Memory: 0 -> 8) — and the closing .rep pattern
table now marks every row exercised except Model.

Regenerated outputs/ (md + calc_ui_cpp sources + screenshots). Verified end to
end via the doctest chain (Part 1->2->3): 69/69 steps, UI test 14/14.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 23:53:43 -03:00
Dario LipicarandClaude Opus 4.8 a00e9ef944 tutorial(cpp-ui): Qt-typed dependency calls via LogosUiPluginContext (#72)
* tutorial(cpp-ui): Qt-typed dependency calls via LogosUiPluginContext

Sync Part 3 (calc_ui_cpp) to the new UI authoring model: the backend derives
LogosUiPluginContext (not the std-typed LogosModuleContext), and its
modules().calc_module wrappers are now Qt-typed (api-style qt). libVersion()
returns modules().calc_module.libVersion() directly — the QString::fromStdString
conversion is gone since the wrapper now returns QString, matching the .rep slot.

Depends on logos-co/logos-qt-sdk#3, logos-co/logos-plugin-qt#14, and
logos-co/logos-module-builder#124. Part of a 4-repo change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* tutorial(cpp-ui): don't pin logos-module-builder in calc-ui-cpp flake

The generated example flake hard-pinned logos-module-builder to a specific
commit; every other tutorial output (and the generated .md) tracks the branch
via `github:logos-co/logos-module-builder` — only release builds pin (the
spec's `{release}` placeholder). Drop the stray rev to match.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* tutorial(cpp-ui): fix the doctest spec backend for Qt-typed modules()

The doctest CI executes the spec's `file:` blocks, not the committed outputs/
tree — and the spec's backend still used the std-typed model: it derived
LogosModuleContext and wrapped `modules().calc_module.libVersion()` in
QString::fromStdString(...). That compiled only while module-builder was pinned
to a stale pre-flip commit (ui_qml api-style=std → libVersion() returned
std::string). Now that the flake tracks module-builder master (api-style=qt,
libVersion() returns QString), QString::fromStdString(QString) fails to compile.

Bring the spec in line with the generated outputs (already fixed): derive
LogosUiPluginContext, include logos_ui_plugin_context.h, and return
modules().calc_module.libVersion() directly. Prose/diagram updated to match.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 12:14:21 -03:00
Dario Lipicar 961b752ee6 tutorial(cpp-ui): rewrite Part 3 to the universal authoring model (#70)
* tutorial(cpp-ui): rewrite Part 3 to the universal authoring model

calc_ui_cpp now uses interface: universal — you write only the .rep and a
CalcUiCppBackend deriving CalcUiCppSimpleSource + LogosModuleContext, calling
modules().calc_module.* (typed SDK). The *Plugin/*Interface classes,
initLogos, and setBackend wiring are generated; the hand-written interface +
plugin steps are gone. CMake uses REP_FILE + the backend sources + INCLUDE_DIRS.

Regenerated outputs/tutorial-cpp-ui-app.md and outputs/logos-calc-ui-cpp/.
Verified end to end: the full Part 1->2->3 chain runs 69/69 against the
universal templates (logos-module-builder feat/universal-templates), including
the live UI drive (Add -> 8) and the integration-test build.

Depends on the logos-module-builder universal-templates change so that the
#ui-qml-backend scaffold is the universal form.

* tutorial(cpp-ui): derive module NAME from metadata.json in CMake

Match the templates: read the name via file(READ metadata.json) +
string(JSON ... name) and pass NAME ${MODULE_NAME} to logos_module(), so the
module name has a single source of truth. Same string(JSON) pattern the
converted templates use (build-verified there).
2026-06-13 09:18:00 -03:00
Dario LipicarandClaude Opus 4.8 30e6478c00 fix(qml-ui): navigate Settings → Modules → Core Modules in basecamp (#68)
basecamp moved its modules view: the old top-level "Modules" sidebar entry
was renamed to "Package Manager", and the UI Modules / Core Modules tabs now
live under Settings → Modules. The Part 2 UI doc-test still clicked a
top-level "Modules", which no longer exists, so the step failed with:

    click("Modules"): No element found with text 'Modules'

Click "Settings" first (and wait for the Settings view to render), then the
now-nested "Modules" sub-tab — mirroring logos-basecamp's own
basecamp-modules doc-test. Prose and the generated outputs/ markdown updated
to "Settings → Modules → Core Modules".

Caught by the logos-workspace nightly doc-test run against the bumped
logos-basecamp commit.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 23:22:16 -03:00
Dario LipicarandClaude Opus 4.8 ae7c65ad95 docs: replace logoscore inline (-c) mode with daemon/client workflow (#66)
* 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>
2026-06-09 22:37:36 -03:00
Dario LipicarandClaude Opus 4.7 c2cd6f09eb docs: LIDL-based dependency consumption + dependency_overrides (#65)
* docs: document LIDL-based dependency consumption + dependency_overrides

Tutorial-sync for "concrete dependencies via LIDL":
- Developer guide §9.2: explain that each module publishes a cheap LIDL
  interface contract (packages.<sys>.lidl) and that consuming a dependency
  generates modules().<dep> from that LIDL WITHOUT building the dependency's
  plugin — only the standalone-app run (#run) bundles/builds deps. Notes the
  cross-language pipeline (Rust -> LIDL -> C++) and the transitional fallback
  for deps that don't yet expose a `lidl` output.
- Document the new `dependency_overrides` metadata field (§9.2 + field table).
- Composing Modules tutorial: correct the prose that said the builder "fetches
  calc_module's headers" — it now reads calc_module's published LIDL contract
  and does not build calc_module's plugin at the aggregator build step.

Depends on logos-cpp-sdk#77, logos-plugin-qt#9, logos-module-builder#110 (the
described behavior ships with those).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* address review: regenerate composing tutorial md; reconcile §8.2/§9.2

- Regenerate outputs/tutorial-composing-modules.md so the committed markdown
  matches the updated YAML prose (it had stale "fetch headers" / "exported
  interface" wording). Verified identical to `doctest generate`.
- Developer guide §9.2: add a note tying the LIDL-contract dependency wrapper
  generation to §8.2 — it's the same logos-cpp-generator driven by the dep's
  LIDL/.h contract (like interface_dependencies) rather than inspecting a
  compiled plugin (the manual/standalone path), so the two sections no longer
  read as conflicting mechanisms.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 12:22:30 -03:00
Dario LipicarandClaude Opus 4.8 c84322d50c Add "Composing Modules" tutorial: calc_aggregator core module (#63)
* Add "Composing Modules" tutorial: calc_aggregator core module

New executable tutorial (tests/tutorial-composing-modules.test.yaml) that
builds calc_aggregator, a core (universal) module depending on calc_module,
showcasing every LogosModuleContext capability end-to-end via logoscore:

- modulePath / instanceId / instancePersistencePath getters
- durable per-instance persistence (a run counter that survives a restart),
  wired up in onContextReady()
- typed sync dependency calls (computeReport composes five calc_module calls
  into one map)
- typed async dependency call (fibonacciAsync with a callback)
- typed event subscription (onVersionReady on calc_module's versionReady)

Driven entirely from the logoscore daemon (no UI), mirroring Part 1's flow.

Also:
- README: list the tutorial and the calc_aggregator example module
- run.sh: build the module into outputs/ via --workdir (reusing the chain's
  calc_module, no rebuild) and clean its calc-data/ persistence dir
- ci.yml: run the new spec and verify its markdown generation
- outputs/: rendered tutorial + cleaned module source

The typed event subscriber requires logos-cpp-sdk PR #72 (LIDL parser: accept
reserved words as identifiers in name positions) so calc_module's versionReady
event sidecar round-trips; the doctest's event step stays red against published
deps until that lands and the module builder bumps its SDK pin.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* rerun

* Address review: warn about SDK dependency, make CI non-blocking

- prerequisites + event step: explicit toolchain note that the typed event
  subscriber needs logos-cpp-sdk#72 (calc_module's `version` event param
  collides with a reserved word), with a workaround (pin a fixed
  logos-module-builder, or skip the event step — everything else works on
  the released toolchain).
- ci.yml: split the Composing Modules spec out of the blocking UI-chain run
  into its own `continue-on-error: true` step so it doesn't block merges
  until #72 lands; a comment says to fold it back in once the dep ships.
- regenerate outputs/tutorial-composing-modules.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Re-enable Composing Modules as a blocking CI tutorial

logos-cpp-sdk#72 (LIDL parser: reserved words usable as identifiers) is merged
and logos-module-builder has bumped its SDK pin, so calc_module's versionReady
event sidecar now round-trips and the typed onVersionReady subscriber builds on
the published toolchain.

- ci.yml: fold the spec back into the blocking UI-chain run (and the published
  two-column report); drop the temporary continue-on-error step.
- spec: remove the now-obsolete toolchain prerequisite note and the event-step
  heads-up.
- regenerate outputs/tutorial-composing-modules.md.

Verified end-to-end against the published toolchain: 77/77 doctest steps pass,
including the build and the full event round-trip.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 09:46:55 -03:00
Dario LipicarandClaude Opus 4.8 9a75e048bf Document + verify event introspection in the tutorials (#62)
* 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>
2026-06-04 17:41:23 -03:00
Dario LipicarandClaude Opus 4.8 d85b19c222 Demonstrate & validate method doc comments (wrapping-c-library) (#60)
* 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>
2026-06-04 12:39:51 -03:00
Iuri Matias d2502ab05d use logos-docspec
use logos-docspec

fix perms
2026-05-30 10:23:00 -04:00
Iuri Matias f9a762a628 regenerate outputs 2026-05-29 17:28:54 -04:00
Iuri Matias 62c0f0ad3f update tutorials
update tutorials

fix test
2026-05-29 16:22:44 -04:00
Iuri Matias a32ea8bce4 support screenshots 2026-05-29 15:43:10 -04:00
Iuri Matias 3f91daa824 regenerate tutorials and outputs 2026-05-29 14:09:51 -04:00
Iuri Matias d17fce1360 support --output option ; generate both tutorials and example code from test specs
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
2026-05-29 11:50:37 -04:00