Commit Graph
132 Commits
Author SHA1 Message Date
Khushboo Mehta 84d5eea7ff feat: update tutorials for ui modules ot use qml hot reloading correctly as per latest changes 2026-08-27 15:24:40 +02:00
Khushboo-dev-cpp f887991d28 Merge pull request #85 from logos-co/chore/updateIntentsMechanismAndGuide
feat: updated documentation and tests for the implemented intents mec…
2026-08-27 14:51:12 +02:00
Khushboo Mehta b527a82bcb feat: updated documentation and tests for the implemented intents mechnism 2026-08-27 14:11:43 +02:00
Khushboo-dev-cpp 24563c655a Merge pull request #78 from logos-co/feat/updateUiTutorialForQmlHotReloading
feat: update tutorials for ui modules ot use qml hot reloading correctly as per latest changes
2026-08-27 14:08:58 +02:00
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 24d8aea7d3 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-22 21:04:54 -03:00
Dario LipicarandClaude Opus 5 dc4635d3c4 ci: use logos-co/setup-nix-cache-action for Nix setup and caching (#83)
Replaces the per-repo installer + cachix pair with the shared action, which
installs Nix with the Logos Attic cache (cache.nix.logos.co) preconfigured and
publishes what the job builds — master to the public cache, every other ref to
ci.

Each converted job also gains

    environment: ${{ github.ref == 'refs/heads/master' && 'public-cache' || '' }}

because ATTIC_TOKEN_PUBLIC only exists inside that environment. Without it the
secret resolves empty on master and publishing is silently skipped — the job
still passes, so the omission would not surface as a failure.

The action installs Nix on every runner, macOS included. Sibling repos used
DeterminateSystems' installer there because cachix/install-nix-action collided
with the runner's pre-existing _nixbld users (eDSRecordAlreadyExists); that no
longer reproduces — logos-delivery-module converted the plain way and its
macos-latest leg passes — so the second installer is not carried over.

One property is deliberately not carried over: the old cachix step ran with
`continue-on-error: true` so a failed cache push could not fail a job whose
tests passed. The action exposes no equivalent, and adding one would also
swallow genuine setup failures now that the same step installs Nix rather than
only publishing at the end.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 23:50:27 -03: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 LipicarandClaude Opus 5 d3c325e5d2 docs: stop documenting removed generator flags (#81)
* docs: --module-dir was removed from logos-cpp-generator

The generator now refuses the flag (exit 2) instead of accepting it, so both
places the guide spelled it were about to become instructions that hard-error.
Replaced with the supported form: `--general-only` plus one
`--dep <name>=<name>.lidl` per dependency, which generates each wrapper from
that dependency's contract rather than by loading its built plugin.

Tutorial Sync Rule; the code change is in logos-cpp-sdk
(cpp-generator/legacy/main.cpp).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* docs(dev-boost): name an artifact the toolchain can still produce

The CMake block listed calc_wrap_qt_glue.h and calc_wrap_dispatch.cpp in
logos_module(SOURCES …). Those were emitted by --backend qt, which is deleted;
a module now emits <name>_cdylib_glue.{h,cpp} and Qt-plugin packaging is a
downstream step.

Nothing goes red — logos-tutorial has no dev-boost doctest — so this would have
stayed wrong silently. It was likely already stale (logos-dev-boost contains no
_qt_glue string at all), but the deletion turns "out of date" into "permanently
unbuildable", which the Tutorial Sync Rule exists to prevent.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 23:02:41 -03:00
Dario Lipicar c727e25c30 fix(doctests): track two upstream changes the specs still assert against (#80)
CI has been red on every run since the dependencies moved underneath it.  The
repo itself has not changed -- master's HEAD IS the commit that last went green,
on 2026-07-22 -- but logos-tutorial has no flake.lock: the specs scaffold
projects that resolve `github:logos-co/...` fresh at run time, so the same
commit passes or fails depending on the day.  Both failures below are the specs
asserting behaviour that upstream deliberately changed.

1. INTEGER WIDTH: `int` -> `qlonglong` in the generated Qt surface.

   `lm methods` now reports `qlonglong add(qlonglong a, qlonglong b)` where the
   spec expected `int add(int a, int b)`.  This is the LIDL type contract: one
   type per language, integers 64-bit throughout, no widening or narrowing.

   The tutorial's explanation was not merely stale -- it documented the OLD
   BUG as intended behaviour, telling the reader that their `int64_t` "shows up
   as `add(int,int)`".  That silent 64->32 narrowing is exactly what the type
   contract removed.  The bullet now says the width is preserved and why that
   matters, which is the part a tutorial is for.

   Only tutorial-wrapping-c-library asserts generator OUTPUT, so only it moves.
   The `int` in tutorial-cpp-ui-app is C++ the reader writes themselves (`.rep`
   SLOTs and their own `override` declarations), where the reader picks the
   type -- that spec passes, and is deliberately left alone.

2. BASECAMP NAVIGATION: the Settings section was renamed and its tab removed.

   `click("Modules")` failed with "No clickable element found with text
   'Modules'".  On basecamp master the section label is now "Module Inspector"
   (SettingsView.qml:53), and the "Core Modules" tab is gone -- it was split
   into its own view, which ModuleInspectorView.qml:18 says in as many words
   ("Formerly the 'Core Modules' tab of ModulesView").  So the tab-click step is
   deleted rather than renamed, and the objectName the Interface screen is
   opened through is `moduleInspectorView`, not `coreModulesView`.

   Verified against origin/master of logos-basecamp, which is what CI builds:
   `openInterface(name)` still exists (ModuleInspectorView.qml:46), and the
   surrounding anchors "Settings", "Sections", "Dashboard" are all still there.

NOT ADDRESSED HERE, because it is not a tutorial bug: the third failure,
`persistenceDir` not containing `calc-data`, is a real regression in
logos-logoscore-cli.  daemon_state.cpp:264 applies `--persistence-path` only
`if (cfg.dirs.data.empty())`, and dirs.data has a default -- so an explicitly
passed CLI flag loses to a default, silently.  The spec is right and should
stay red until that is fixed.
2026-08-10 19:45:46 -03:00
Dario LipicarandClaude Opus 5 fd14aa90f5 docs: cover the Windows target and lgpm --platform (#79)
The guide had no Windows content at all, and `lgpm` grew a `--platform` flag
(logos-package-manager 1ac7963) that nothing documented. Three additions, all
places the guide already made a claim that is now incomplete or wrong for
Windows:

* The variant-naming table gains `x86_64-windows`, with a note that the spelling
  is `windows-x86_64` and — unlike Linux, which accepts both `linux-x86_64` and
  `linux-amd64` — it has NO alias, so a package labelled `windows-amd64` simply
  will not install.
* 5.1 documents `--platform`, including why the default refusal exists. lgpm
  derives the variant from the machine it runs on and fail-closes otherwise;
  that refusal is the protection against installing a package built for one
  platform onto another, so the opt-out is explicit and never inferred, applies
  to install/list/info alike, and prints to stderr when active.
  With an explicit warning NOT to use it for a dev/portable mismatch: forcing
  that installs a package the runtime cannot load, trading a clear install-time
  error for a confusing load-time one.
* "Cross-platform builds" said to build on each target platform separately.
  That cannot be done for Windows — there is no Nix daemon for Windows, so it is
  cross-built from Linux (or from WSL2, which is Linux) and copied across.

Branched from master rather than the checked-out fix/ui-doctest-launch-timeout
so this carries none of that branch's work.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 19:11:36 -03:00
Dario LipicarandClaude Opus 4.8 bfc34c451c fix(doctests): raise launch_timeout for the nix run . UI tests (#77)
The tutorial doc-test went red on ubuntu with

  inspector not available on port 3768 after 120s

with `building '...-logos-standalone-app-1.0.0.drv'` as the last line of
the launch log: the app was still compiling when the clock ran out.

The runner pre-builds `nix run .` as `nix build .`, which is
packages.default — the UI plugin. But `nix run .` launches apps.default,
the standalone app, whose closure (logos-standalone-app plus the bundled
backend modules) is not covered by that warm build, so it compiles
during launch and is charged against the default 120s inspector wait.

Give the three `nix run` UI tests the same launch_timeout the
logos-wallet-module spec already uses for exactly this reason. Nothing
here is rendered into the generated Markdown.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 17:31:34 -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>
tutorial-v4
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 11fd79343c docs: concurrent dispatch (concurrency:"multi") section (#73)
Adds the metadata flag row + §1.6 explaining single vs multi, the per-language
thread-safety contract (Rust &self + Send + Sync / C++ self-synchronize), and the
"how it works" model: the module owns concurrency behind the ordinary callMethod
(pending sentinel + completion event) with NO provider/host ABI change, so an old
daemon/app loads + forwards a multi module unmodified. Protocol 0.2 (additive
minor). Notes the event-ordering caveat and the pre-0.2-caller caveat.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 16:59:20 -03:00
Khushboo-dev-cpp baa25f6e3d Merge pull request #74 from logos-co/feat/addDisplayNameInManifest
feat: add support for display_name in manifest files
2026-06-19 15:09:48 +02:00
Khushboo Mehta 1a24a39daf feat: add support for display_name in manifest files 2026-06-19 14:40:00 +02: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 LipicarandClaude Opus 4.8 fbf8b108b4 docs: document the nix build .#generate output (#71)
Add the new `.#generate` output (runs every code generator and emits a
ready-to-build module source tree) to the build-outputs section of the
developer guide.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 14:15:39 -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 Lipicar 1a4fa6fc20 doctest: make the bad-bind step outcome-agnostic (#69)
* doctest: make the bad-bind step outcome-agnostic

Asserting status:error relied on the inner call to a missing module
blocking long enough to time out the outer RPC. With faster failure
detection the plain-int typed wrapper returns the type's default and the
outer call reports ok — both surfaces are legitimate, and which one wins
is a platform/timing race (consistently the fast path on Linux since the
transport extraction, still the slow path on macOS). Assert on the
stable part and teach the real contract: bad binds fail at call time;
methods that need caller-visible errors should return result.

* doctest(qml-ui): gate the Modules click on a wait_for

Right after the calculator round-trip the shell is still settling; on a
busy CI runner the Modules entry can take longer than the click action's
retry budget to materialize (flipped red on both platforms in one run,
green the previous hour, identical pins). Same pattern the spec already
uses for the post-launch wait.

* doctest(qml-ui): open Settings before clicking Modules

The Modules entry lives in the Settings left rail; clicking it cold
relied on incidental tree state (passed or failed depending on whether
the entry happened to be materialized). Mirror the basecamp doctests'
proven sequence: click Settings, wait for the view, then click Modules.

* tutorial: demonstrate the CallError out-param on bound interface calls

Generated typed wrappers now take an optional trailing
logos::CallError* — sumVia checks it and returns -1 when the inner call
fails (err.code == "object_unavailable" for a missing module), so the
bad-bind lesson no longer depends on which way the failure-timing race
falls. The doctest assert stays tolerant of the slow-transport
outer-timeout surface.
2026-06-12 23:59:40 -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.7 c9f47391e5 feat: dependency interfaces — executable tutorial + guide (#64)
* feat: dependency interfaces tutorial (executable)

Add tests/tutorial-interface-dependencies.test.yaml — an executable
logos-doctest tutorial that builds calc_via_interface: a module declaring a
`calculator` interface and binding it to calc_module at runtime. Covers typed
sync/async/event calls, the no-validation rule, and the cross-repo interface
form. Registered in run.sh and CI (run + generate). Documents
interface_dependencies + bind_<interface> in the developer guide.

Depends on logos-cpp-sdk#74, logos-module-builder#108, logos-plugin-qt#8 —
the published flakes must carry these before the tutorial runs green in CI
(same release gating as the Composing Modules tutorial).

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

* address review: self-valid interface header + accurate CI step

- Interface calculator.h includes logos_module_context.h so the logos_events
  token is defined (valid C++ standalone); prose updated accordingly.
- CI step name/comment now reflect the third tutorial leaf
  (tutorial-interface-dependencies), not just the UI chain + Composing Modules.
(Copilot review, PR #64.)

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

* rerun

* rerun

* fix(tutorial): correct the no-validation negative test

Binding to a module that isn't loaded does NOT return a silent default — the
inner remote call fails and propagates, so `logoscore call ... sumVia
no_such_module` exits non-zero with RPC_FAILED. The step asserted "result":0
and let the non-zero exit fail the doctest step. Reframe it accurately: a bad
bind surfaces as an ordinary RPC failure (not a crash); absorb the exit with
`|| true`, capture stderr, and assert `"status":"error"`. Fix the prose and the
recap row to match.

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-05 22:19: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 3e77b0b333 Merge pull request #58 from logos-co/support_release_param
support specifying --release param on run.sh
2026-06-03 10:46:39 -04:00
Iuri Matias 187e748fa8 support specifying --release param on run.sh
support specifying --release param on run.sh

fix perms
2026-06-03 10:45:47 -04:00
Iuri Matias d0885d52b0 Merge pull request #57 from logos-co/extract_docspec
Use extracted logos-docspec
2026-06-01 10:42:09 -04: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 44e105f1b8 update test so it checks basecamp too 2026-05-29 17:23:02 -04:00
Iuri Matias 62c0f0ad3f update tutorials
update tutorials

fix test
2026-05-29 16:22:44 -04:00
Iuri Matias c6a22710d9 Merge pull request #56 from logos-co/screenshots
support screenshots
2026-05-29 16:04:41 -04:00
Iuri Matias 728e6ce8f3 include screenshots in reports 2026-05-29 15:55:18 -04:00
Iuri Matias a32ea8bce4 support screenshots 2026-05-29 15:43:10 -04:00
Iuri Matias d71b454c35 Merge pull request #54 from logos-co/runner_tui
Runner tui
2026-05-29 14:10:01 -04:00
Iuri Matias 3f91daa824 regenerate tutorials and outputs 2026-05-29 14:09:51 -04:00
Iuri Matias 3cae557ba1 fix issue with relying on old github tutorial example 2026-05-29 13:57:10 -04:00
Iuri Matias cc97dba1c6 fix issue with relying on old github tutorial example 2026-05-29 13:31:50 -04:00
Iuri Matias b5e30e6bb9 add --tui and --iterative option 2026-05-29 12:24:30 -04:00
Iuri Matias 6799f76650 Merge pull request #53 from logos-co/generate_outputs
support --output option ; generate both tutorials and example code fr…
2026-05-29 12:16:56 -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
Iuri Matias 49de0c013f Merge pull request #50 from logos-co/executable_tutorials
add executable tutorials support; convert tutorial-wrapping-c-library to an executable tutorial
2026-05-29 10:36:35 -04:00
Iuri Matias c6595b3664 generate links to report on check 2026-05-29 10:24:45 -04:00
Iuri Matias c79fc6aaf2 add support for a --report option that creates an html with the markdown and executed commands side by side 2026-05-29 10:11:00 -04:00
Iuri Matias 943cbc7997 test ci fix 2026-05-29 09:21:36 -04:00
Iuri Matias 6416b538dc regenerate tutorials 2026-05-29 09:01:48 -04:00