Replace bonsai-ui with logseq/lui - #10
Conversation
… registry, native bridge) Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Mechanical port of bonsai-ui ocaml/runtime worker stack: - journal_bounded_mailbox / journal_worker_eio_backend: verbatim copies - journal_worker_runtime: Worker.Private -> Journal_worker.Private, Worker_eio_backend -> Journal_worker_eio_backend, ID = Journal_worker_ids - journal_worker: same renames; subscribers are plain event -> unit callbacks; drain_to_effects ~schedule -> deliver (invokes subscribers directly on the app thread) - journal_worker_ids: add Int64_id/Int_id/String_id module types required by the existing .mli Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- journal_view: Bonsai_swiftui_ui-shaped shim over Lui_elements - journal_ids/journal_environment: Id and Environment replacements - journal_platform: LJP2 codec + env-push (24) + notice (25/26/27) envelopes - journal_bridge/journal_lui_bridge.c: lui_ocaml bridge + startup payload - journal_lui_native/journal_pump: extension registry + cross-thread pump - Rename Ui/ID/Environment/Graph_service references across app modules - Drop logseq_db_worker/bonsai in favor of logseq_db_worker/lui Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- pubspec: drop bonsai_flutter/bonsai_flutter_native for lui_flutter_backend (git dep pinned to the opam pin) + vendored journal_lui_native hook package that links the OCaml complete object (lui_ocaml_* + journal_ocaml_* exports from journal_lui_bridge.c) - main.dart: JournalRuntimeOwner owns JournalOcamlBridge + LUIFlutterBackend; patch callback applies LUI batches, LUIEvents forward to lui_ocaml_* entries, extension events to journal_ocaml_extension_event, wakeup schedules journal_ocaml_pump on the UI isolate, LJP2 platform channel bridged both directions, environment pushed as tag-24 envelopes, and notices resolve through a ScaffoldMessenger sink (tags 25/26/27) - extension registry: journal-chrome/-asset-import/-media/-asset-settings/ -list registered with fingerprints matching journal_lui_native.ml; renderers ported (grouped list with scroll requests, visible-range tracking, swipe + context-menu rows, disclosure expansion) - adapter: bonsai interfaces replaced with JournalPlatformServices/ JournalHostAdapter; LJP2 codec unchanged, tags 24-27 added - Runner configs renamed off bonsai artifacts; bonsai-flutter.sexp and bonsai-bound renderers/tests removed Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- test_bonsai_service.ml renamed to test_lui_service.ml and re-pointed to Logseq_db_worker_lui.Logseq_db_worker_lui_service, Journal_worker, Journal_worker_runtime, Journal_worker_ids - test_managed_sync_e2e.ml re-pointed to the same lui modules - dune: drop bonsai_swiftui.driver, bonsai_swiftui_test, logseq_db_worker.bonsai; add logseq_db_worker.lui Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- Re-point service imports to Logseq_db_worker_lui service in startup_test, application_view_test, journal_media*_test, journal_uploads_test - journal_adaptive_test: assert symbol identity via Journal_symbols.name and Journal_view.View.For_testing.key; decode Style.Color channels through ordered public rgb probes (shim has no to_argb32/view introspection) - journal_semantics_test: keep only test_timeline_media_targets (pure Journal_row.view); the remaining cases drove the removed bonsai_swiftui_test mounted-tree harness and cannot port - journal_routes_test, journal_timeline_state_test: Journal_ids/Journal_view renames; drop Hidden_target (no such lui outcome) - macos_mutation_input_diagnostics_pure_reducer_test: same renames (unwired) - source_boundary_test: lui service paths, lui/ocaml-signal opam pins, Journal_platform.show_notice_request; drop sexp manifest assertions - test/dune: drop all bonsai_swiftui* library entries and the bonsai-swiftui.sexp dep - Remove bonsai-swiftui.sexp and bonsai-flutter.sexp manifests - Delete test/macos_application_dispatch_test.ml: every case depended on the removed Bonsai test handle/mounted-tree harness - Finish test_lui_service.ml renames left unstaged Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Allow the new flutter/lib files landed by the lui_flutter_backend port, permit showModalBottomSheet/Image.file used by the new host, and stop requiring the removed flutter integration test Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ol test env names Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- swift/: JournalRuntime owns the LUIAppleBackend + OCaml runtime (5-arg lui_ocaml_start with the LDB1 startup payload), patch callback applies backend.apply, wakeup pumps on MainActor, platform requests marshal off the OCaml worker thread and return via journal_ocaml_platform_response. - JournalRuntimeHost is the shared SwiftUI host view (app scene + apple-tests harnesses): LUISwiftUIRoot + tag-24 environment pushes + tag-25/26/27 notice presentation through JournalApplicationPlatform. - JournalExtensions: one LUIAppleExtension per journal identifier (chrome, asset-import, media, asset-settings, list) with reproduced schema fingerprints; JournalList implements the journal-list payload/event contract (grouped sections, disclosure rows, visible-range, scroll completion, swipe/context actions, expanded + row events). - swift/Package.swift declares the JournalApp executable on LUIAppleBackendStatic + amplify-swift 2.61.0 with native link inputs from tool/build_journal_apple.sh; apple/Info.plist carries the sexp's bundle config; the script compiles journal_lui_bridge.c, links the complete OCaml object (or a link-validation stub), and assembles a signed .app. - apple-tests: OCaml probes rewritten as Lui_app signal+update fixtures self-registering Journal_bridge.hooks; Swift acceptance sources use JournalRuntimeHost/JournalApplicationPlatform observation hooks instead of BonsaiApplicationView/Bridge/Events/NativeViews; probe harnesses now stage swift/ overlays through tool/lui_probe_host.py. - Removed bonsai-swiftui.sexp and swift-packages/Package.resolved. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
The upstream app-test port removed macos_application_dispatch_test.ml and the bonsai_swiftui_test support library; the remaining mutation cases now load the lui package and use the Journal_view/Journal_ids shims. Also removes swift-packages/Package.resolved, superseded by swift/Package.swift. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- Replace Bonsai.Cont/component with a Lui_app.reducer_app: state record + action variant (Update | Platform_response | Environment_changed), update reducer, and a view built via Lui_elements.dyn. - Shim Bonsai.Effect as unit -> 'a thunks; send/set_state/set_state_and_effect route through Lui_app.send with a pending_actions queue because ocaml-signal updates are not reentrant. - Replicate Edge.on_change edges (feed, timeline presentation, drains, upload/media, notice, delete timer, sync-error timer) as post-update key diffs; Clock.until/every become generation-guarded timer threads that enqueue through Journal_pump. - Platform.request continuations become a pending_platform table keyed by LJP2 response tag; platform_event hook decodes tag-24 environment snapshots into Environment_changed. - native_hooks : Journal_bridge.hooks wires init/dispatch/extension_event/ pump/platform_event/platform_response/dispose/root_node; config arrives via init payload (unchanged C ABI). - Add Journal_view.mount accessor so the reducer view can return Lui_elements.t. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ui_app host Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".
|
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
…link flags Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…p bundle layout/entitlements Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
iOS Simulator smoke test: app boots + renders via lui, but stalls at "Opening journal" — blocks sign-in Tested Two build issues also found: (1) ANY Golden path (sign-in → E2EE → timeline → capture) is unreachable until the stall is fixed. Recording: https://app.devin.ai/api/presigned_proxy?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJvcmdfaWQiOiJvcmctZjZmZDVmNzI0MzlkNDlmZmJmY2QxYWQ2NTMwNjdhZTMiLCJ1c2VyX2lkIjpudWxsLCJidWNrZXRfbmFtZSI6ImRldmluYXR0YWNobWVudHMiLCJidWNrZXRfa2V5IjoiYXR0YWNobWVudHNfcHJpdmF0ZS9vcmctZjZmZDVmNzI0MzlkNDlmZmJmY2QxYWQ2NTMwNjdhZTMvN2U3ZjhjNTEtZDBhNS00NDAzLTk2ZDItNDM3MTdiNWVmNDExIiwiaWF0IjoxNzkwMTM3ODM5LCJleHAiOjE3OTA3NDI2MzksImZpbGVuYW1lIjoiam91cm5hbC1sdWktaW9zLXNpbS1zdGFsbC1lZGl0ZWQubXA0In0.ET2OWFhUxoB9QQKg5xRLpyffbeMBquChT5GLYYMyqPE |
…dhoc sign on iOS sim (iOS 27 rejects any entitlements blob) Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
The app parked on 'Opening journal' because mount-time exceptions raised inside the C bridge's patch emission were dropped silently. Fixes: - Wrap composed control labels in leaf properties: Button, Toggle, NavigationLink, Picker options, and Menu items are leaf host kinds that only accept ContextMenu children; their title/icon now travel as TextValue/InlineIconName props (label_content side-channel on the view record preserves the existing ~child/~label APIs and test ids). - Rewrite Menu to the lui dropdown model (menu_item + dropdown_menu children) with a title/icon API instead of composed label elements. - Mount toolbar items under a plain row (Toolbar kind accepts only fixed control children and no extensions) and guard placement/spacing hint props by node kind. - Register journal SF Symbol names as app:<slug> icons via LUIAppleBackend appIcons (swift/JournalIcons.swift). - Guard standard props on non-standard nodes: extension and placeholder nodes skip accessibility/frame/padding/semantics props via a shared node_is_standard check. - Declare journal extension child schemas on both OCaml and Swift sides so extensions can nest. - Surface startup exceptions on stderr instead of letting the bridge swallow them. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
The old bridge surfaced platform request failures to OCaml; the ported path returned nil from JournalApplicationPlatform.request and dropped it in deliverPlatformRequest, leaving the pending continuation parked indefinitely. On the iOS simulator the startup localAccount keychain read fails (errSecMissingEntitlement on unentitled sim builds) and the app sat on a blank screen forever; any keychain failure on a real device would hit the same silent hang. - journal_lui_bridge.c: new journal_ocaml_platform_failure entry that delivers the original request envelope back to OCaml. - journal_bridge: platform_failure hook (OCaml resolves the pending continuation with Error via Platform_response under the response tag). - application.ml: hoist response_tag to top level for the failure hook. - JournalRuntime.deliverPlatformRequest: nil response now reports the request as failed instead of being silently dropped. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ead-end signature Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Startup stall fixed + platform failure delivery restored (b957534, 5676639)The app previously parked forever on "Opening journal": mount-time lui schema violations raised inside the C bridge's Second defect: iOS Simulator verification (iOS 27.0 + 26.5, adhoc builds)
Two non-blocking observations: ~25–30k |
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…a compliance Worker->UI wakeup: replace the OCaml Condition waiter thread with a set_output_wakeup hook fired on the producing domain. The waiter deadlocked on iOS: while holding the shared output mutex it blocked re-acquiring its domain lock, which the UI thread holds inside CFRunLoop — download appeared stuck. Render loop: Lui_elements.dyn remounts the whole tree on every publish. Gate republish behind Signal.cutoff (==) and stop feeding mount-time echoes back into the model — Editor.apply_text_edit returns None for identical documents, the e2ee field and asset-settings refresh bail out when the new value is physically/equal to the old. Schema compliance (violations were swallowed by the C emit bridge and left blank screens): - Navigation_link list-item mounts its label as a child (schema requires text or children) and sets press-enabled so rows actually dispatch - toolbar role/variant hints limited to schema-representable values - back-button variant 'plain' -> 'ghost' - journal-media/journal-list declare standard children + extension children whitelists (OCaml/Swift/Flutter fingerprints in sync); JournalMedia now renders context.content - journal-chrome positional slots mount placeholder columns so the native child-index contract (feedback:3, journal:4) holds when a slot is empty iOS sim: embed entitlements via __TEXT,__entitlements at link time (the sim reads entitlements from the section, not the signature) so keychain works under adhoc signing. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ime gotchas Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Every caml_callback*_exn result that failed with Is_exception_result was silently dropped: emit_patch returned 0, lui_ocaml_root_node returned 0, and deliver_platform ignored the result value entirely. When OCaml threw (e.g. schema validation errors on unsupported property values or child kinds) the patch stream truncated silently and the host rendered a blank or half-blank screen with zero diagnostic output. Add report_ocaml_exception(), which formats the exception with caml_format_exception(Extract_exception(result)) and fprintf()s it to stderr tagged with the callback name, so the message reaches the app's stderr/simctl launch --console-pty log. Return contracts are unchanged: callers still get the same failure code; the exception is no longer swallowed.
Parity pass against the recorded bonsai build, confined to the shim and host Swift: - Section.create emits a heading + plain column card as direct list children so LUIListView groups them natively (panel/card kinds overlay children in a ZStack, which stacked the unlock texts). - Menu/toolbar/dock and capsule rows pin cross=center + measured widths so rows center instead of stretching half the bounded column. - content_unavailable centers deterministically (growing column + spacers + centered label/description/actions). - Navigation_link rows carry a trailing chevron icon to match NavigationLink's disclosure accessory. - Icon-only mounts get a uniform 40pt control width; icon-only button/menu-item labels stay on the a11y channel. - SectionDate uses an explicit label color: .primary inside a List section header resolves to adaptive gray on iOS 26. - Asset-import button shows icon-only; asset-settings root column fills the viewport and anchors top; new SF Symbol slugs registered. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- Drop the emulated '‹ Logseq Journal' back-link row: the system nav bar renders nothing for an empty title, so the shim's extra row had no old counterpart and pushed the nav row down. - Emit size="sm" on icon-only menu triggers (person icon, overflow …) so the glyph matches the old 16pt menu-item icon. - Replace .scrollPosition (two-way binding) with a ScrollViewReader + scrollTo for one-shot scroll requests. - Defer onAppear/onDisappear @State writes off the layout pass and debounce visible_range emits (80ms): a boundary row flickering during layout previously emitted a range oscillation that fed patches back and pinned the main thread at 100% CPU. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
mount_icon_only recorded one boolean and then pinned the item's top
mounted node to 40pt, which mis-measured two cases: a Toolbar.group
mounts a row of controls (the row itself got the icon width while its
leaves stayed unsized), and a text button ("Save", "Close") is not
collapsed at all yet still inherits a fixed-width capsule.
set_leaf_label now collects each leaf that actually fell back to its
icon (icon_only_collapsed_nodes), mount_icon_only applies width=40 to
just those leaves, and capsule drops its pinned
width = 12 + 56*children_count so the pill hugs its content like the
bonsai chrome bar did.
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…tem size) The previous pin at 38096c4 only covered PR #9; the icon-size wire property (logseq/lui#11) and the UIActivityIndicatorView spinner (logseq/lui#10) merged after it, and the icon trigger cells rely on menu-item size. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Latest lui maps a variantless button to .bordered (standard iOS chrome), which drew accent-colored button chrome inside the chrome capsules. Icon-collapsed bar controls and the back circle button now opt into variant=ghost + secondary foreground so they stay plain dark glyphs inside the pill.
Bottom-bar items that contain only controls now mount inside a lui toolbar node (the schema semantic for a control bar), wrapped in a box carrying the pill chrome. A row wrapper would auto-append a trailing spacer and stretch the capsule full width; a box hugs its content, so the pills stay compact. Groups mount their children flat into the enclosing toolbar since a wrapper row is not a legal toolbar child and a button-group would likewise stretch.
Fixes the timeline scroll regression: dyn branches previously dropped and recreated their whole subtree on every publish, which destroyed the journal-list UICollectionView and snapped scroll position to the top continuously. With reconcile, same-kind nodes keep their ids so the list survives patches.
Replaces the pre-merge pin 271fe33 with the squash-merged main commit. Same fix: dyn branches reconcile instead of drop+create, so the journal-list collection view survives publishes and timeline scrolling works.
Summary
Replaces the
bonsai-uistack (Jane StreetBonsai,bonsai_swiftui*,bonsai_flutter, and the BonsaiSwiftUI host) withlogseq/luiend to end: OCaml app layer, worker service, native bridge, Apple host, Flutter host, build configuration, and tests. Application logic and user-facing behavior are intended to remain unchanged; this is a rendering/runtime-architecture swap.OCaml app layer
app/application.ml{,i}now runs as aLui_appreducer app. Bonsai primitives are mapped structurally: edge callbacks, clock/effect scheduling, platform request/response tracking, and serialized dispatch.app/journal_view.ml{,i}provides the compatibility shim overLui_elements/Lui_uiused by the existing screen code.bonsai_swiftui_spec.Platform hosts
swift/hosts the app throughLUIAppleBackend; the root is wrapped inNavigationStackso toolbar nodes with explicitplacementhoist into native iOS/macOS chrome. The iOS detail and timeline bars now use system toolbar items and fused capsules matching the previous app.flutter/hosts the app throughlui_flutter_backendwith journal extension renderers, native asset linking, environment push, and notices.__TEXT,__entitlementsso keychain-backed auth works with ad-hoc signing.Compatibility fixes verified on iOS simulator
ocaml-sync-test: download, E2EE unlock, list rendering, detail navigation, menus, and capture surfaces were exercised.dune buildanddune runtestare green on the 5.5.0 switch.The journal pin currently tracks
logseq/lui@9181a9f2fada60af325a200be0dc94b6241fe85a, pending logseq/lui#24.Link to Devin session: https://app.devin.ai/sessions/5e3c7830582348419f3eedb3d505df6e
Open in Devin Desktop: https://app.devin.ai/desktop/session/5e3c7830582348419f3eedb3d505df6e?variant=devin
Requested by: @RCmerci