Skip to content

feat(viewers): display generated CDR messages in Rerun and browser - #4733

Open
TomCC7 wants to merge 10 commits into
cc/feat/cdr-unit-recordingfrom
cc/feat/cdr-unit-viewers
Open

TomCC7 wants to merge 10 commits into
cc/feat/cdr-unit-recordingfrom
cc/feat/cdr-unit-viewers

Conversation

@TomCC7

@TomCC7 TomCC7 commented Oct 20, 2026 •

Copy link
Copy Markdown
Member

What this adds

  • Render generated CDR messages through the existing Rerun bridge while retaining legacy rendering.
  • Decode browser SDK channels from complete cdrgen schemas in their manifest, using Foxglove's ROS2 libraries.
  • Use Rerun's native importer for offline CDR MCAP files.

How to test

From this PR's checkout:

DIMOS_ALLOW_MISSING_COCKPIT=1 uv sync --locked --extra visualization --extra web
uv run --extra visualization --extra web python -I examples/message-viewer/demo_cdr_rerun.py cdr-viewer.rrd
uv run --extra visualization rerun cdr-viewer.rrd
uv run --extra visualization rerun cdr-viewer.mcap

Use a new output name. The demo runs the real bridge and creates a live RRD plus a source-scene MCAP. Check TF, geometry, images, depth, calibration, clouds and legacy rendering. Native MCAP import visualizes supported standard types; Path and custom EntityMarkers remain reflected fields.

Scene checklist and native MCAP export.

For the browser, run these in separate terminals:

uv run --extra web python -I examples/message-viewer/demo_cdr_browser.py
cd web/sdk
deno task fixture --host 127.0.0.1

Open http://127.0.0.1:5174/demo_cdr.html?live=1. Expect connected, all eight channels, increasing counts and zero decode errors. Browser checklist.

Validation includes 38 focused tests and the installed Rerun example with native MCAP conversion. This layer leaves dimos mem rerun, navigation and dimos.msgs unchanged.

Published CDR dependency update

Consume published dimos-cdrgen==0.1.2 throughout this stack, including packaging examples, the Python lock and the Nix generator wheel. PyPI release and successful publisher run. Downloaded wheel/sdist hashes match that run's artifacts exactly.

The external CDR library fix is available as fork release v0.2.4-dimos.1, pinned to its tested commit. Shared SDK API 0.2.0 is isolated in #4774; explicit legacy SDK 0.1.0 pins remain compatible and are respected by autofix. No DimOS PR has been merged.

Final combined-stack verification after installing the published generator: SDK 158, adapters 2, mapper 102, MLS 135, local planner 93, follower 63, V4L2 6 tests; all 12 real native/DimSim exchanges pass. The seven Nix source-staging layouts pass locked Cargo dependency resolution using archive 8101c8db4a50043f1dbd0127fd00220ec9b5a37a. Full Nix builds and hardware/model-dependent tests remain unverified. These are combined-tip results, not independent full test runs of every intermediate PR.

Final native CI passed on the exact stack tip, including SDK/consumer builds, Rust tests and all 12 native/DimSim exchanges: https://github.com/dimensionalOS/dimos/actions/runs/39851662834

@github-actions github-actions Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

go2 replay realtime (arm64)

Details
Benchmark suite Current: aebb801 Previous: c240b54 Ratio
peak memory 1576.324 MB 1827.461 MB 0.86
peak threads 361 threads 364 threads 0.99
network (transport) 2727.33 MB 2726.743 MB 1.00
disk write 1.828 MB 1.809 MB 1.01
instructions 116.977 G 136.831 G 0.85

This comment was automatically generated by workflow using github-action-benchmark.

@codecov

codecov Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

❌ 2 Tests Failed:

Tests completed Failed Passed Skipped
6551 2 6549 57
View the top 2 failed test(s) by shortest run time
dimos.codebase_checks.test_no_init_files::test_no_init_files
Stack Traces | 0.044s run time
def test_no_init_files():
        dimos_dir = DIMOS_PROJECT_ROOT / "dimos"
        init_files = sorted(dimos_dir.rglob("__init__.py"))
        # The root dimos/__init__.py is allowed for the porcelain lazy import.
        init_files = [f for f in init_files if f != dimos_dir / "__init__.py"]
        if init_files:
            listing = "\n".join(f"  - {f.relative_to(dimos_dir)}" for f in init_files)
>           raise AssertionError(
                f"Found __init__.py files in dimos/:\n{listing}\n\n"
                "__init__.py files are not allowed because they lead to unnecessary "
                "extraneous imports. Everything should be imported straight from the "
                "source module."
            )
E           AssertionError: Found __init__.py files in dimos/:
E             - message_utils/__init__.py
E           
E           __init__.py files are not allowed because they lead to unnecessary extraneous imports. Everything should be imported straight from the source module.

dimos_dir  = PosixPath('.../dimos/dimos/dimos')
init_files = [PosixPath('.../dimos/dimos/dimos/message_utils/__init__.py')]
listing    = '  - message_utils/__init__.py'

dimos/codebase_checks/test_no_init_files.py:25: AssertionError
dimos.core.test_build_native_modules::test_module_locks_pin_the_shared_code_as_it_is_now
Stack Traces | 4.25s run time
@pytest.mark.skipif(not _IN_GIT_CHECKOUT, reason="needs a git checkout to read refs")
    def test_module_locks_pin_the_shared_code_as_it_is_now() -> None:
        """Every module's pin on native/cpp or native/rust must hold this commit's tree.
    
        `nix flake lock` and `cargo build --locked` do not notice that the shared code
        moved -- they only check that the lock is complete -- so a change there can land
        while every module still builds against the revision before it. The revision is
        free to be older than HEAD; what must match is the content it pins.
        """
        stale = {
            _rel(lock): names
            for lock in _RELOCK.flake_locks()
            if (names := _RELOCK.stale_flake_inputs(lock))
        }
        stale |= {
            _rel(manifest): why
            for manifest in _RELOCK.cargo_manifests()
            if (why := _RELOCK.stale_cargo_pins(manifest))
        }
>       assert not stale, (
            "these modules pin shared code that is not the code in this commit, so they build "
            f"against the older version: {stale} -- push, run bin/relock-shared-flakes, commit"
        )
E       AssertionError: these modules pin shared code that is not the code in this commit, so they build against the older version: {'.../memory/rust/Cargo.toml': ['dimos-module @ 6663bcb6e5', 'dimos-module-macros @ 6663bcb6e5'], '.../realsense/rust/Cargo.toml': ['dimos-module @ 6663bcb6e5', 'dimos-module-macros @ 6663bcb6e5'], '.../v4l2/rust/Cargo.toml': ['dimos-module @ 6663bcb6e5', 'dimos-module-macros @ 6663bcb6e5'], '.../livox/rust/Cargo.toml': ['dimos-module @ 6663bcb6e5', 'dimos-module-macros @ 6663bcb6e5'], '.../pointlio/rust/Cargo.toml': ['dimos-module @ 6663bcb6e5', 'dimos-module-macros @ 6663bcb6e5'], '.../lidar/virtual_mid360/Cargo.toml': ['dimos-module @ 6663bcb6e5', 'dimos-module-macros @ 6663bcb6e5'], '.../dim_slam/rust/Cargo.toml': ['dimos-module @ 6663bcb6e5', 'dimos-module-macros @ 6663bcb6e5'], '.../ray_tracing/rust/Cargo.toml': ['dimos-module @ 6663bcb6e5', 'dimos-module-macros @ 6663bcb6e5'], '.../mls_planner/rust/Cargo.toml': ['dimos-module @ 6663bcb6e5', 'dimos-module-macros @ 6663bcb6e5'], '.../local_planner/rust/Cargo.toml': ['dimos-module @ 6663bcb6e5', 'dimos-module-macros @ 6663bcb6e5'], '.../fancy/rust/Cargo.toml': ['dimos-module @ 6663bcb6e5', 'dimos-module-macros @ 6663bcb6e5'], '.../depth2depth_cloud/rust/Cargo.toml': ['dimos-module @ 6663bcb6e5', 'dimos-module-macros @ 6663bcb6e5'], '.../dds/rust/Cargo.toml': ['dimos-module @ 6663bcb6e5', 'dimos-module-macros @ 6663bcb6e5'], '.../native-modules/rust/Cargo.toml': ['dimos-module @ 6663bcb6e5', 'dimos-module-macros @ 6663bcb6e5']} -- push, run bin/relock-shared-flakes, commit
E       assert not {'.../memory/rust/Cargo.toml': ['dimos-module @ 6663bcb6e5', 'dimos-module-macros @ 6663bcb6e5'], '.../realsense/rust/Cargo.toml': ['dimos-module @ 6663bcb6e5', 'dimos-module-macros @ 6663bcb6e5'], '.../v4l2/rust/Cargo.toml': ['dimos-module @ 6663bcb6e5', 'dimos-module-macros @ 6663bcb6e5'], '.../livox/rust/Cargo.toml': ['dimos-module @ 6663bcb6e5', 'dimos-module-macros @ 6663bcb6e5'], ...}

names      = []
stale      = {'.../memory/rust/Cargo.toml': ['dimos-module @ 6663bcb6e5', 'dimos-module-macros @ 6663bcb6e5'], 'dimo....../livox/rust/Cargo.toml': ['dimos-module @ 6663bcb6e5', 'dimos-module-macros @ 6663bcb6e5'], ...}
why        = ['dimos-module @ 6663bcb6e5', 'dimos-module-macros @ 6663bcb6e5']

dimos/core/test_build_native_modules.py:476: AssertionError

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@TomCC7
TomCC7 added this pull request to stack #4743 October 20, 2026 22:26
@TomCC7
TomCC7 force-pushed the cc/feat/cdr-unit-viewers branch from bd424bb to 309e817 Compare October 21, 2026 04:39
@TomCC7 TomCC7 changed the title feat(viewers): consolidate manifest CDR and Rerun consumers feat(viewers): display generated CDR messages in Rerun and browser Oct 21, 2026
@TomCC7

TomCC7 commented Oct 21, 2026 •

Copy link
Copy Markdown
Member Author

Review report

Updated: 2026-10-21. Direct base: #4732.

  • Base: 12c81e08e10fa0d5fc1a7595ce8056d771a1f430
  • Head: 22e03e1b5c1747bbaf57e388d421766886e5ca35

Behavior changes

  • Live Rerun: generated CDR values now pass through viewer-owned adapters and explicit typed subscriptions. The existing legacy rendering path remains. Generated message definitions and dimos.msgs are not changed by this PR. Image/cloud buffer helpers live in dimos.message_utils; Rerun keeps its local JSON display helper.
  • Browser: an explicitly declared *.cdr.v1 channel carries complete ROS2 definitions from the installed cdrgen registry in params.cdr. Python sends CDR payloads; the SDK builds a Foxglove MessageReader from that manifest. No browser-generated message package is needed. Array-bearing messages require explicit subscriptions.
  • Offline MCAP: use Rerun's native importer. It does not call these Python adapters. Supported standard ROS2 types receive native visualizations; Path and custom EntityMarkers remain reflected fields. The example MCAP is a synthetic source scene, not output from the Rust recorder.

Review map

Read the adapters, channel/schema flow, and SDK decoder first. Examples and tests follow that path. All 32 changed files are listed below, relative to the direct base.

File map, grouped in review order

Rerun adapters

File Change Purpose
dimos/visualization/rerun/cdr.py Added Maps generated geometry, TF, cameras, clouds and entities to Rerun archetypes; keeps conversion out of message definitions.
dimos/message_utils/init.py Added Declares the utility package without re-exporting or eagerly importing helpers.
dimos/message_utils/pointcloud.py Added Reads structured cloud buffers, padding and byte order; extracts positions and packed RGB independently of Rerun.
dimos/message_utils/image.py Added Reads generated image buffers, row padding and byte order; decodes compressed images independently of Rerun.
dimos/visualization/rerun/bridge.py Modified Dispatches generated values, maintains frame/calibration attachment, scopes source time, and owns explicit CDR subscriptions.

Python browser channel path

File Change Purpose
dimos/web/cdr_codec.py Added Exports complete installed ROS2 definitions and encodes values with cdrgen; checks registered type identity.
dimos/web/codecs.py Modified Resolves explicit *.cdr.v1 encoders while retaining registered encoder precedence.
dimos/web/cockpit.py Modified Adds generated schema metadata to authored channel manifests; reserves params.cdr.

TypeScript decoding and subscriptions

File Change Purpose
web/sdk/src/decoders/cdr.ts Added Uses Foxglove ROS2 schema parsing and CDR reading; rejects invalid headers and trailing data; bounds previews.
web/sdk/src/decoders/index.ts Modified Resolves and caches CDR decoders per manifest record; checks encoding against its declared type.
web/sdk/src/index.ts Modified Exports the CDR decoder and schema/sequence helpers.
web/cockpit/src/subscriptions.ts Modified Requires an explicit panel subscription for variable-length CDR arrays, matching the large-payload policy.
pyproject.toml Modified Excludes the test-only CDR generator from package discovery and adds generated message sources to mypy's search path.
web/sdk/package.json Modified Adds pinned Foxglove schema-parser and ROS2-serialization dependencies.
web/deno.lock Modified Records browser dependency resolution.

Runnable examples and documentation

File Change Purpose
examples/message-viewer/demo_cdr_rerun.py Added Sends a synthetic scene through local Zenoh and the real bridge, saves RRD, and writes source-scene MCAP.
examples/message-viewer/demo_cdr_browser.py Added Owns its eight-message sample scene and starts producers, the authored bridge and a local relay without importing test modules.
web/sdk/fixture/demo_cdr.ts Added Provides live subscriptions and fixed-vector inspection, decoded values and schema display.
web/sdk/fixture/demo_cdr.html Added Hosts the browser demo.
docs/usage/visualization.md Modified Documents installation, RRD/MCAP commands, scene checks and native-import limitations; marks WIP.
docs/web/bridge.md Modified Documents schema flow, explicit CDR channel authoring, browser demo and WIP boundaries.

Tests and reproducible vectors

File Change Purpose
dimos/visualization/rerun/test_cdr.py Added Tests rendering, frames, source-time cleanup, calibration order and subscription disposal.
dimos/visualization/rerun/test_cdr_entities.py Added Checks generated entity rendering.
dimos/visualization/rerun/test_cdr_image_values.py Added Checks encoded PNG and compressed depth values/units.
dimos/visualization/rerun/test_cdr_e2e.py Added Runs the reviewer scene, inspects live RRD, and converts/inspects MCAP with the Rerun CLI.
dimos/web/test_cdr_codec.py Added Tests schema ownership, invalid declarations, import isolation and Python-generated browser vectors.
dimos/web/relay_bridge/test_relay_bridge_authoring.py Modified Adds subscription-gated CDR encoding coverage to existing authoring tests.
dimos/web/relay_bridge/module_test_support.py Modified Keeps the fake-relay harness off native RPC sockets.
dimos/web/relay_bridge/tests/cdr_fixtures.py Added Builds browser vectors from actual generated messages, including both byte orders.
web/sdk/tests/fixtures/cdr_frames.json Added Stores generated schemas, payloads and expected values used by Python and browser tests.
web/sdk/src/decoders/cdr.test.ts Added Tests decoder identity, endian handling, malformed payloads and bounded previews.
web/cockpit/src/subscriptions.test.ts Modified Tests CDR scalar and variable-array subscription policy.

Validation

Current Python lint validation: 22e03e1b5c1747bbaf57e388d421766886e5ca35. Added build/message-source/python to mypy_path so mypy can resolve the generated types exposed by editable installation. No import errors were suppressed and no CI workflow changed.

The previous web checks are from 71e269045919e15e62716c82e92ca9549ddc13d5. Python functional tests and installed-wheel evidence are from e020c9f29570b9138d012c871ca73e842a1c13b4. These earlier results are labeled below rather than presented as fresh checks of this configuration-only revision.

Check Current result
Python rendering, web codec, relay authoring and document branding 59 passed at e020c9f29. Includes schema-vector consistency after relocation and the previously failing brand-spelling check.
Installed-wheel reviewer example and native MCAP import 1 passed at e020c9f29. Existing end-to-end test runs the real local Zenoh/Rerun example, inspects the live RRD, converts MCAP and checks imported components.
Full SDK Vitest suite 411 passed at 71e269045. Includes the CDR decoder checks.
Full cockpit Vitest suite 196 passed at 71e269045. Includes CDR subscription policy.
Relay/shared Deno suite 199 passed at 71e269045, with 36 steps.
Web CI static checks and builds Passed at 71e269045. Deno fmt, lint, frozen install, relay/shared check, SDK and cockpit type-check, and both production bundle builds.
Fresh wheel contents and imports Passed at e020c9f29. Includes both public helper modules; excludes the test generator, test vectors and removed modules. Installed helper imports do not load Rerun.
Full Python lint checks Passed. mypy 1.19.0 checks all 1235 source files without incremental cache; deptry 0.25.1 reports no dependency issues. The local dependency environment was aligned with the lockfile for missing lint packages.
Generated field-type probe Passed. A valid integer width is accepted; assigning a string to Image.width still fails with an assignment type error.
Existing pre-commit hooks, all files Passed. Matches the lint job’s existing skip list; includes Ruff, license, lock consistency, documentation links and Deno formatting.

The earlier report's thread-cleanup error and interrupted web subset did not reproduce with the complete local test environment. Python emitted a subprocess ResourceWarning; the tests and their thread-leak checks completed successfully. No production lifecycle code was changed.

Reproduce the focused checks

From this PR's repository root, run the existing Python lint commands in its lint environment:

uv sync --only-group lint --frozen
uv run --no-sync deptry dimos --config pyproject.toml --github-output
uv run --no-sync mypy --no-incremental
SKIP=cargo-fmt,native-module-lint pre-commit run --all-files

The earlier web checks used:

cd web
deno fmt --check
deno lint
deno install --frozen
deno task check
deno task test
cd sdk
deno task check
deno task test
deno task build
cd ../cockpit
deno task check
deno task test
deno task build

The installed-wheel check used dimos/visualization/rerun/test_cdr_e2e.py with a freshly installed wheel in the test interpreter's environment. Deno version: 2.6.10. To regenerate the cross-language vectors from the checkout:

uv run python -m dimos.web.relay_bridge.tests.cdr_fixtures

The failed CI job log was inspected once to diagnose the lint error; CI was not polled after pushing the fix. Graphical browser inspection, browser end-to-end tests, Docker build and hardware calls were not performed in this revision. The live browser's full interactive flow was not rerun in this revision; its installed Python example's --help and isolated helper imports were checked.

Review focus

  • dimos.message_utils.image and .pointcloud own general buffer operations. Extracted function bodies are unchanged. Rerun retains archetype construction and its private _json_value display helper.
  • The test-only generator is under dimos/web/relay_bridge/tests; its committed vectors are under web/sdk/tests/fixtures. The Python live browser example constructs its own scene without importing test modules. Offline browser inspection explicitly reads the test vectors.
  • Manifest type checks bind an encoding name to a declared type. They are not schema-hash negotiation or proof that a peer uses the same definition.
  • A generic browser decoder supplies values and previews, not domain-specific panels. Native MCAP import and the live bridge support different visualizations.

Remaining work

WIP remains for automatic generated-type discovery, browser-to-robot CDR publishing, business-graph migration and domain-specific browser panels. This revision updates #4733 only; later stack branches have not been restacked onto its new head.

Reviewer demos and expected scenes:
Live Rerun and native MCAP,
live browser.

Comment thread dimos/message_utils/image.py
return entries


def _json_value(value: Any) -> Any:

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need more repo-wide serialization method for common types. check what codebase has and propose what should we do to establish

from dimos.web.relay_bridge.locate import find_web_dir


def build_messages() -> list[tuple[str, Any]]:

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is this for?

Comment thread web/sdk/tests/fixtures/cdr_frames.json
@greptile-apps

greptile-apps Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 4/5

[Medium impact] The PR changes generated-message viewing across the browser and Rerun workflows.

Fix source-timeline transform recording before merging; the external-schema compatibility issue is non-blocking.

Findings

  1. P1 Transforms miss source playback ▶
  2. P2 External schemas lose package context ▶

Summary

Adds generated CDR messages to Rerun and the browser SDK while keeping legacy rendering.

  • Browser channels decode generated CDR messages from their schemas.
  • Rerun displays generated messages while keeping legacy rendering available.

Both reported failures were reproduced. Neither is resolved by the supplied higher dependent PR revisions.

Reviews (1) · Last reviewed commit: "fix(viewers): use globalThis for browser..." · Reviewed by Greptile

Comment on lines +678 to +681
stamp = getattr(getattr(msg, "header", None), "stamp", None)
if stamp is not None:
nanos = int(stamp.sec) * 1_000_000_000 + int(stamp.nanosec)
rr.set_time("source", timestamp=np.datetime64(nanos, "ns"))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Transforms miss source playback

Generated TFMessage timestamps belong to individual transforms, but this callback sets source only from a top-level header. The resulting transforms are recorded on log_time and log_tick, not source, while stamped images and poses are recorded on source. During source playback, Rerun cannot retrieve the transform edges needed to place that sensor data correctly.

A real bridge recording confirmed that all three transform updates were unavailable at their source timestamps, including latest-at queries, while the corresponding images and poses remained available. Set source from each transform’s timestamp when logging it, then restore or clear the timeline state. This playback failure should be fixed before merging.

Knowledge Base Used: Rerun visualization bridge

Artifacts

Executed generated-message bridge reproduction

  • The executed script sends generated TF, pose, and image updates through the production bridge and records current behavior plus an external timing control, without modifying production.

Executed source-timeline query and higher-snapshot checks

  • The executed inspection script samples actual TF availability with latest-at filling, checks static and log-time controls, and compares scoped higher-PR functions, confirming the failure and absence of a supplied fix.

Executed inspection command wrapper

  • The executed wrapper records the exact inspection command, working directory, exit code, and captured output, making the successful verification reproducible.

Observed TF queries and higher-PR comparison output

  • The captured successful run shows null source-timeline TF values before, correct values with the timing control, working static/log-time controls, and identical relevant functions in all seven higher heads.

Real Rerun recording from current PR4733 bridge

  • Actual generated messages were logged through the current bridge into this recording, whose TF values are unavailable on the source timeline.

Real Rerun recording with external TF timing control

  • The same generated message sequence was recorded with source externally assigned around each TF update, making all three TF translations available at their source timestamps.

View artifacts

TREX Ran code and verified through TREX

Comment on lines +24 to +25
const definitions = parse(schema.definition, { ros2: true });
const reader = new MessageReader(definitions);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 External schemas lose package context

cdrDecoder ignores schema.type when parsing the complete definition. Generated schemas leave the root unnamed, so the parser cannot use its package to resolve short field names. A valid external message containing a local Point and a nested geometry_msgs/Point throws Cannot unambiguously determine fully-qualified type name for 'Point'; the decoder factory then returns null, and the registry marks the channel unsupported.

This is a non-blocking compatibility gap for external packages with overlapping short type names. Supply the root identity from schema.type before type resolution and add a regression test covering two packages with a Point type.

Artifacts

Decoder and registry reject a valid complete schema

  • Executed the unchanged SDK with the generated schema and binary controls, capturing the exact ambiguity error, null factory result, and undefined registry result.

Decoder and registry succeed with root identity supplied

  • Executed the same fixture with an isolated in-memory root-identity change, showing successful decoding without editing production files.

Full reproduction source and generated binary fixture

  • Captured the complete authored scripts, fixture, registry source, and generator output so the executed reproduction can be inspected and repeated.

Higher-stack source comparisons and exact source citations

  • Compared all supplied heads and printed numbered resolution helpers, showing identical decoder, registry, and exporter blobs across the stack.

View artifacts

TREX Ran code and verified through TREX

@TomCC7
TomCC7 removed this pull request from stack #4743 October 22, 2026 18:51
@TomCC7
TomCC7 added this pull request to stack #4776 October 22, 2026 18:52

This branch was successfully deployed

1 active (outdated) deployment
cachix — aebb8010 Deployed Oct 22, 2026 by TomCC7 via cachix-build-macos #14015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants