docs/parity-checklist.md: the PR's edit to the LRC-LIB-CATALOG-SWITCH row applied to main's row.
docs/whats-new.md: the PR's 2026-10-29 section added above main's sections.
unused_port() lets its port go before the CLI connects, and the denoise-serve test
does the same before starting its server: with several test threads the server could
start on a port a refused-connection test had picked, which then reached it instead
of being refused. The three tests now hold one lock for their whole run.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The `--connect` failure-hint tests connected to 127.0.0.1:18437 and assumed
nothing listened there, but agents give their apps' control servers ports in
18000-19999. With an app on 18437 the tests sent it `ui.inspect` and failed.
They now bind 127.0.0.1:0, drop the listener and use that port, and check the
`--control <port>` hint against it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
UPDATE_APP (native builds; craft-update is a native-only dependency) carries our 128 px icon and accent (#f2a516, its colour in ArtCraft Launcher). The updater, the self-update
helper and craft-update's startup prompt all get them through crate::UPDATE_APP; the
prompt draws the icon, the accent and "by ArtCraft" (craft-update's default developer).
craft-update is pinned to storytold/craft-libs main at 1065653e7 (#434).
Clippy fixes for Rust 1.99 in untouched code (same logic):
- crates/engine/src/cmd/export.rs
- crates/ui-egui/src/dialogs/rules_editor/rules_move.rs
- crates/ui-egui/src/panels/detail.rs
The reasons Try Again and the launch check give for a missing remembered library are now in the
interface language (all 17 catalogs). A folder that can't be looked into (no permission, a share
that timed out) is no longer called gone: lightcraft_engine::library::library_state tells a missing
catalog from a failed lookup, and the window shows the system's reason.
When the library last opened was missing at launch (its drive or network share not connected yet, or moved), LightCraft created an empty library at that path, seeded it with the demo photos and opened it. The launch plan now marks the library remembered in Settings, and when it holds no library the session opens nothing and the can't-open window offers Try Again, Choose Another Library, Continue Without Saving and Quit. The default location, --library and LIGHTCRAFT_LIBRARY are still created when missing, as before.
Each argument's check had its own 2 s, so several paths on a dead mount could hold the window back
2 s each. `launch_imports_in` now takes one `launch_deadline()` for the whole batch and checks each
argument with `launch_path_until`; once it has passed, an argument is imported without the check.
Test: a past deadline imports a library folder at once, without probing it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reuse cached folder listings through Arc and allow tests to inject Local places.
Show browsed folders below hidden ancestors as session roots. Apply the same
hidden-entry checks to folder walks, browsing, import scanning, and Local.
xtask parity reads the UI command tables from menus.rs and every file under menus/, and the desktop app's dialog-filter test checks every source file under src/, so both keep finding their items after files move into subdirectories.
A request sent just as the app expires an idle control connection crosses
the app's id-less idle-close notice: the client's pre-send check saw an
open connection, wrote the request, and read the notice as its reply, so
`--connect` and the MCP server failed a command the app never read.
The app reads nothing after its idle timeout, so such a request never ran.
The app now marks the notice `"closed": "idle"`, and `Remote::call` sends
a request whose reply is that notice once more on a new connection (it
also matches the notice's exact text, for apps from before the marker).
At most one resend per call, whatever the reason; a reply with an id or
any other error is returned as before.
`idle_close_reconnects_without_replaying_a_command` now forces both
orders (notice before the next request, and a request crossing it)
instead of racing the notice; with main's client it fails every run.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>