Commit Graph
1565 Commits
Author SHA1 Message Date
aiongg c5a1cbfb5f update: CheckResultDialog shows the result of a manual update check 2026-10-31 04:39:40 +00:00
aiongg a2be97cf8e docs: tidy AGENTS.md and clean-room doc 2026-10-31 04:17:35 +00:00
marshiyar 61bde471fd update: a package manager's copy and another app's bundle do not self-update on macOS and Windows
self_update::detect fell back to Install::Standalone for any executable it
could not place, so on macOS a Homebrew, MacPorts or Nix copy, or a program
inside another app's bundle, was replaced in place, and on Windows so was a
scoop, winget, Chocolatey or Store copy. The package manager's record then
stays on the old version, and the bundle belongs to another app.

macOS now treats executables under /opt/homebrew, /usr/local/Cellar,
/usr/local/Homebrew, /usr/local/opt, /opt/local and /nix as owned by a package
manager, and any executable inside an .app bundle that is not this app's own
as not ours; none of them self-update. Windows does the same for scoop, winget,
Chocolatey and WindowsApps folders. The rules are plain path functions, so
they are tested on every platform.

Tested: three new tests failed before the change (the macOS and Windows folder
rules, and detect on an executable in another app's bundle) and pass after it.
cargo test -p craft-update (209 tests), clippy -D warnings and fmt pass on
macOS; the Windows branch was not compiled here.

Fixes #390 for macOS and Windows; the Linux side is #388.
2026-10-30 20:02:37 -07:00
Dylan M. Taylor 4323a0f90e Merge pull request #406 from solarmaster961/fix/flatpak-system-bundle-self-update
fix(linux): self-update a system-wide Flatpak bundle in place
2026-10-30 22:56:43 -04:00
Dylan M. Taylorandcoderabbitai[bot] 003f133f6d Update crates/update/src/install.rs
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-10-30 22:48:52 -04:00
VoiceLessQ 7ec82661cb fix(update): cap a GitHub rate-limit wait at one hour
An absurd x-ratelimit-reset or retry-after stopped the API until restart.
GitHub's quota refills within the hour.
2026-10-30 22:44:18 -04:00
VoiceLessQ f0b5b22dce fix(update): read GitHub API answers up to a 16 MiB cap
get_api shared the 4 MiB limit for small answers. A launcher version list of
100 releases can pass that: SolidCraft's was 6.5 MB (craft-launcher#1021).
Other small requests keep 4 MiB.
2026-10-30 22:43:46 -04:00
Dylan M. Taylor 2b8bd856ce Merge pull request #458 from storytold/fixup/crw-365-follow-up
fixup(crw): trim derivation artifacts (follow-up to #365)
2026-10-30 22:42:50 -04:00
Dylan M. Taylor a0fdc73717 fixup(crw): trim shipped derivation artifacts 2026-10-30 22:41:55 -04:00
Dylan M. Taylor b645a09174 Merge pull request #365 from rwoldberg/clean-room-crw-format-decode
Clean room crw format decode
2026-10-30 22:40:13 -04:00
Dylan M. Taylor 0ad3952f5e docs(crw): declare table generator Python version 2026-10-30 22:40:07 -04:00
Zinadin ZidanandClaude Opus 5.5 7070670d5f Merge main into fix/391-safe-release-link
Brings in main's launcher version pins (craft-update: apps respect the
launcher's per-app version choice, and the follow-ups through 9817c81).

One conflict, in updater.rs's tests: main made the newer() helper
pub(super) for updater_pin_tests.rs, and this branch added its two #391
tests (download_opens_only_a_safe_release_page,
every_releases_page_is_a_safe_web_link) just above it. Kept both tests
and main's pub(super). Everything else merged cleanly: Download still
goes through download_action (safe_web_link, then the app's releases
page), "What's new" still checks safe_web_link, and main's pin checks
in offer, check_now, finish_check and start_install are untouched. Main
adds no new way for the prompt to open a URL.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 07:09:40 +06:00
Dylan M. Taylor 8846e5d34a Merge pull request #449 from Jeremy8776/feat/update-version-pins
craft-update: apps respect the launcher's per-app version choice
2026-10-30 20:55:18 -04:00
JeremyandClaude Opus 5.5 9817c81fd2 craft-update: the version-choice file sits in a host folder Flatpaks can read
A Flatpak launcher wrote versions.json inside its own sandbox, and no Flatpak
app could read the launcher's folder, so pins never reached Flatpak apps, nor
host apps started from their menu entry. The file now sits in its own folder,
ArtCraft/versions under the host's per-user data folder, found from inside a
Flatpak too (HOST_XDG_DATA_HOME, else ~/.local/share). A Flatpak app reads it
with one read-only grant for that folder alone (pins::FLATPAK_GRANT).

folders::host_data_local_dir replaces install's private copy of the same rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 21:55:00 +00:00
Martin Ball 9dce709a53 Merge storytold/wordcraft#4191 2026-10-30 21:16:12 +00:00
Martin Ball 12c0bd61e3 Merge storytold/wordcraft#4575 2026-10-30 21:16:12 +00:00
Zinadin ZidanandClaude Opus 5.5 35b908febb update: only ureq's Trace logs print the GitHub token (#391)
ureq 3.5's Debug request log lists an allow-list of safe headers and
leaves Authorization out; the unredacted wire is its Trace output
(ureq-proto's log_data). `Http::with_github_token` now says so: apps
should redact Bearer tokens or keep `ureq` and `ureq_proto` at Debug or
quieter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 23:56:36 +06:00
Zinadin ZidanandClaude Opus 5.5 7ae5bbf07d update: Download falls back to the app's releases page (#391)
Download closes the prompt, so a release link that fails
`release::safe_web_link` left the user with nothing opened. It now opens
`App::releases_url()` instead, which passes the check for every app in the
suite; a release link with `&` or another shell metacharacter is still
refused.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 23:56:36 +06:00
Zinadin ZidanandClaude Opus 5.5 3f21cfa0ae update: the prompt opens only a safe release link; document token logging (#391)
`Release`'s fields are public, so an app that builds one from its own
feed or cache could hand any URL to the prompt's "What's new" link and to
Action::OpenUrl after Download. Both now go through
`release::safe_web_link`, as the launcher does before every open_url.
`Http::with_github_token` says that ureq's debug logs print the Bearer
token, so apps should redact it or keep ureq below Debug.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:22:32 +06:00
MarekSpodBiedry a2c28ae762 hayro-interpret: pad a missing low byte in 16-bit image data instead of panicking (#328) 2026-10-30 16:38:22 +01:00
JeremyandClaude Opus 5.5 0ada678488 craft-update: every check answer uses the launcher's choice as it stands when the check ends
finish_check now re-reads the choice before looking at the answer, so an app
the launcher pinned mid-check reports UpToDate and an up-to-date managed()
whether the network found a release, nothing, or an error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 12:52:57 +00:00
JeremyandClaude Opus 5.5 a710ab7897 craft-update: a pin made while a check runs still holds its answer
finish_check used the choice cached when the check started, so a launcher
pin made during the network request still opened the stable prompt. It now
re-reads the choice when the check finishes, as offer does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 12:42:23 +00:00
JeremyandClaude Opus 5.5 0db8c1ba47 craft-update: a pin closes a stale prompt; tracks() skips stable; isolate the pretend test
Review fixes for #449:
- A prompt opened while the app followed stable stayed open after the
  launcher pinned it, and its Update button still installed the stable
  release. Reading a managed choice now closes a prompt that is not
  installing, and an install re-reads the choice before it starts. A
  running or finished install keeps its prompt, which tick reports through.
- Pins::tracks listed an explicit Stable entry despite its docs.
- The pretend-version child test read the developer's real pins file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 12:36:42 +00:00
JeremyandClaude Opus 5.5 7d303b4b50 craft-update: apps respect the launcher's per-app version choice
The launcher lets someone keep an app on an older release or on nightlies,
but the app's own update check never knew, so a pinned app prompted to
update on every start and "Update and restart" undid the downgrade.

`pins` is one small file the launcher writes (versions.json in its per-user
data folder, or the absolute path in CRAFT_VERSIONS_FILE) and apps read:
app id to Stable, Nightly or Pinned(tag), the launcher's own serde shape.
A missing or damaged file means everyone follows stable; an entry a newer
launcher wrote is left to the launcher and kept on save.

`Updater` reads it before each check and before an offer. An app kept off
stable gets no prompt and no network call; a requested check reports
UpToDate, and `Updater::managed()` says why, so the public Status enum is
unchanged and no app breaks on a rev bump.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 12:22:38 +00:00
Dylan M. Taylor 04aa1703b3 update: honor pretend versions in app release checks (#436) 2026-10-30 02:12:36 -04:00
Dylan M. Taylor 1065653e75 craft-update: the startup prompt shows the app's icon, accent colour and developer (#434)
The update prompt drew the app name's first letter in a blue square and used that blue for
its buttons and highlights. App gains accent and developer, and the prompt now draws:

- App::icon_png (decoded once per context, PNG only, at most 1024 px a side and never past
  the renderer's texture limit), keeping the letter badge for an app without a usable icon;
- App::accent filling its buttons, the badge and an UPDATE chip, with white or black text,
  whichever contrasts more, so every Craft app's accent reaches WCAG AA (4.5:1) for these
  small labels; the What's new link is body text with an accent underline (accent-coloured
  text missed 4.5:1 for several apps). No accent keeps the default blue;
- "by <developer>" beside the app name: App::developer, ArtCraft (app::DEVELOPER) for every
  app in the storytold organisation unless the app passes its own;
- its own button states: backgrounds for unfilled buttons (LATER, DISMISS) when hovered and
  pressed, as the host app's style can hover in a colour its dark text doesn't read on, and a
  2 px focus ring in the body text colour on every button (egui shows focus in that state)
  and on the What's new link.

Apps opt in by passing their own App, e.g.
App { icon_png: Some(include_bytes!("…128x128…png")), accent: Some([0x3f, 0x5f, 0xe0]), ..suite::WORDCRAFT }.
2026-10-30 01:25:19 -04:00
Dylan M. Taylor 733a038aa5 craft-print: log why the printer list is empty when lpstat can't run; document Flatpak needs (#429)
* craft-print: log why the printer list is empty when lpstat can't run; document Flatpak needs

Flatpak apps saw "No printers found" with working CUPS printers: the Freedesktop
runtime has libcups but not lpstat/lp, and the sandbox had neither the CUPS socket
nor Avahi (driverless printers come from lpstat -e). Log the spawn failure and say
in the README what a Flatpak must bundle and grant.

* craft-print: log a failed lpstat -p -d; README separates what each Flatpak piece is for

Review (CodeRabbit): a non-zero lpstat exit was dropped silently, and the README
said any missing piece empties the printer list when only lpstat and the socket do.

* craft-print README: driver options need the PPD, remote servers need network, socket paths are remapped

Review (CodeRabbit): printer_options reads /etc/cups/ppd before lpoptions, so it is
the PPD, not lpoptions, that a Flatpak lacks; a client.conf server is reached only
with --share=network.

* craft-print README: scope the CUPS_SERVER override to one app; describe the stricter socket wrapper

Review (CodeRabbit): flatpak override without an app id applies to every app.
2026-10-29 18:48:26 -04:00
VoiceLessQ 0d6fbfc403 Merge origin/main
main split Czech's suggest_in into one helper per round for the
cognitive_complexity limit (storytold/wordcraft#4501). On this branch that code is the
shared affix_suggest::suggest_in (36 of 30), so cs/suggest.rs stays the
thin wrapper and the shared function gets the same split. The candidates
are offered in the same order; a dump of 13,081 calls over every
language's test dictionary matches the old engine except one: the typo
round counts the lower-cased letters, so "İ" (two letters lower case)
now gets "I" in Polish, where the old count stopped one letter short.
2026-10-29 14:55:30 -02:00
Don Omondi 67cbb60759 pdf reader: a five-point open polyline is not a rectangle
`path_as_rect` in the vendored hayro-interpret took any five-element path whose
points reached all four corners of its bounding box for that box. An open
polyline of one MoveTo and four LineTo passes that test when its ends sit on
the corners, so it was drawn as a closed rectangle and a clip of that shape was
dropped. VectorCraft #2920: an open zigzag in an .ai file opened as its
bounding box.

Port PdfCraft #3327 (hayro-interpret patch 35): a path is a rectangle only when
its four points are distinct, each step runs along one axis, and the last point
returns exactly to the first, closed with ClosePath or a fourth line.

Tests: `rectangles` in crates/pdf/tests/interpretation.rs (4 of its 5 tests
fail without the change) and `context::path_as_rect_tests` in the vendored
crate. SOURCE.json and the reader ledger record the change.
2026-10-29 19:10:31 +03:00
aiongg 1b5582a72e Merge pull request #423 from Jeremy8776/feat/self-update-migrate-to-machine
craft-update: an app installed for one account moves to an install for everyone on its update
2026-10-29 11:44:02 -04:00
aiongg 488c1da8fe Merge pull request #425 from Jeremy8776/fix/update-local-build-downgrade
craft-update: a build from source is never offered the release it already contains
2026-10-29 11:35:24 -04:00
Jeremy 8efdc23ce8 Merge upstream/main to resolve MSI migration conflicts 2026-10-29 15:32:14 +00:00
JeremyandClaude Opus 5.5 df399edff8 craft-update: a Windows MSI copy updates itself in its own context, wherever it is installed (#419)
* craft-update: a Windows MSI copy updates itself in its own context, wherever it is installed

Self-update only recognised an MSI copy by the launcher's per-user folder (the HKCU InstallDir
key, or %LOCALAPPDATA%\Programs\<App>). Every app installed for everyone, in
Program Files\ArtCraft\<App> or the older Program Files\<App>, was treated as a loose folder and
updated by unpacking the portable zip over Program Files without permission.

- msi_context moves here from the launcher (craft-launcher crates/native/src/msi_context.rs at
  b827fed, unchanged apart from visibility, MsiScope and scope_arguments). Windows Installer's
  own registration decides a copy's context, for the launcher and the apps alike, so the
  launcher can drop its copy and both routes follow one rule.
- New msi_copy module: a copy is an MSI copy when an App Paths entry names its exe (a registry
  read, cheap enough for status checks). Its update asks Windows Installer for the context; the
  App Paths hive is only the fallback when that lookup cannot run.
- The update stops, before the app exits, when the copy is registered in both hives, the lookup
  is unclear, or Windows lists the app more than once.
- After the update the helper starts the exe the registrations name now, since the package may
  have moved an exact old default folder.
- A failed self-update now names the Windows Installer log, as the launcher's installs do.
- The launcher's own per-user package is recognised and updated exactly as before.

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

* craft-update: a copy only takes the Windows Installer context of its own hive

Review follow-up (CodeRabbit on #419). The product code for the context lookup came from the
app's only uninstall record, which was not proven to own the running exe. A package writes App
Paths under HKMU, always the hive of its own context, so a registration whose Windows Installer
context differs from the hive that named this exe belongs to another copy. The update now stops
then, instead of taking the other copy's context.

Also documents the remaining helpers the diff touches.

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

* craft-update: an app in the old per-user folder is judged by its registration first

Review follow-up (CodeRabbit on #419). The folder rule for the launcher's per-user package also
matched an app installed in %LOCALAPPDATA%\Programs\<App>, and it ran before the App Paths
check, so such a copy skipped the product-count, conflict and context checks. Now an app is
judged by its registration first; the folder rule only covers an app copy no registration names.

The launcher in its own folder still keeps its old path whatever is registered: on a real PC it
has an App Paths entry and a stale second uninstall record, and registration-first would have
stopped its self-update.

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

* craft-update: when the Windows Installer lookup cannot run, the uninstall records decide

Review follow-up (CodeRabbit on #419). The fallback trusted the App Paths hive, so a stale entry
or a product registered in both scopes could run the update in the wrong context. The fallback
now follows the launcher's rule: the context every uninstall record of the product agrees on
(msi_context::single_scope over HKLM in both views and HKCU). Missing or mixed records stop the
update, and an agreed context that differs from the App Paths hive still stops it as another
copy's registration.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 11:26:20 -04:00
JeremyandClaude Opus 5.5 25c2e9ffc5 craft-update: resolve the whole default folders, not just LOCALAPPDATA
Review follow-up (CodeRabbit on #423). If LOCALAPPDATA\Programs or Programs\ArtCraft is itself a
junction, the exe's folder resolves through it but a default path built from a resolved
LOCALAPPDATA does not, so a default install was planned as a chosen folder. The Windows layer now
resolves each complete default folder (new default_folders) and hands them to the planner, which
only compares.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 13:50:36 +00:00
JeremyandClaude Opus 5.5 eff2500447 craft-update: migration review fixes (profile links, recovery message, Linux test)
Review follow-up (CodeRabbit and CI on #423):
- The profile roots and LOCALAPPDATA are canonicalised like the exe's folder, so a profile behind
  a junction or a subst drive still matches its default folder and still counts as the profile.
- When a failed move leaves no program to start, the helper starts nothing, so the recorded
  "run its installer" message is not replaced by a restart error.
- The default-folder test builds its expected path the way the plan does, so it also passes
  where Path::join uses '/' (Linux CI).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 13:33:30 +00:00
JeremyandClaude Opus 5.5 7fd60c5870 craft-update: a build from source is never offered the release it already contains
Reported by FredApps: PhotoCraft built from main as 0.17.0-integration.20261029.f5b3f123 offered
"Update and Restart" to 0.17.0, a downgrade. Semver puts a pre-release before its release, and
the update check and the self-update guard compared with plain semver.

New version::offers_update: a pre-release label the suite publishes (alpha, beta, rc, nightly)
sorts as before; any other label marks a build from source, which is only offered a strictly
higher X.Y.Z. check_for_update (through a new testable offered_release) and the self-update
guard both use it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 13:29:47 +00:00
JeremyandClaude Opus 5.5 2e2e8f8daa craft-update: an app installed for one account moves to an install for everyone on its update
Temporary (craft-libs#422, step 4): new msi_migrate module, to be removed two releases after the
app packages become per-machine only.

The released packages refuse a per-machine install while a per-user copy exists, so the move
removes first and installs second: remove the per-user product (no permission prompt; if that
fails nothing has changed), install the new version for everyone, and if that fails or
permission is refused, install the new version for the account again in its old folder.
Settings and documents live outside the program folder and are never touched.

Which copies move: a per-user default folder goes to Program Files\ArtCraft\<App>; a chosen
folder outside the profile moves in place; a chosen folder inside the profile keeps updating
for the account. The launcher's own package never moves.

Tested with real Windows Installer runs of a renamed dual-scope package carrying the apps' own
install-policy.wxi: the move with the permission prompt accepted (twice), and with it refused
(the app came back for the account at the new version, the failed log kept). Also unit tests for
every plan and the order of steps, and a mutation check (9 of 9 killed).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 13:14:18 +00:00
JeremyandClaude Opus 5.5 cd7cc8eb39 craft-update: when the Windows Installer lookup cannot run, the uninstall records decide
Review follow-up (CodeRabbit on #419). The fallback trusted the App Paths hive, so a stale entry
or a product registered in both scopes could run the update in the wrong context. The fallback
now follows the launcher's rule: the context every uninstall record of the product agrees on
(msi_context::single_scope over HKLM in both views and HKCU). Missing or mixed records stop the
update, and an agreed context that differs from the App Paths hive still stops it as another
copy's registration.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 12:51:39 +00:00
JeremyandClaude Opus 5.5 1e01964871 craft-update: an app in the old per-user folder is judged by its registration first
Review follow-up (CodeRabbit on #419). The folder rule for the launcher's per-user package also
matched an app installed in %LOCALAPPDATA%\Programs\<App>, and it ran before the App Paths
check, so such a copy skipped the product-count, conflict and context checks. Now an app is
judged by its registration first; the folder rule only covers an app copy no registration names.

The launcher in its own folder still keeps its old path whatever is registered: on a real PC it
has an App Paths entry and a stale second uninstall record, and registration-first would have
stopped its self-update.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 12:36:08 +00:00
JeremyandClaude Opus 5.5 7898779169 craft-update: a copy only takes the Windows Installer context of its own hive
Review follow-up (CodeRabbit on #419). The product code for the context lookup came from the
app's only uninstall record, which was not proven to own the running exe. A package writes App
Paths under HKMU, always the hive of its own context, so a registration whose Windows Installer
context differs from the hive that named this exe belongs to another copy. The update now stops
then, instead of taking the other copy's context.

Also documents the remaining helpers the diff touches.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 12:21:27 +00:00
JeremyandClaude Opus 5.5 9ce610bf16 craft-update: a Windows MSI copy updates itself in its own context, wherever it is installed
Self-update only recognised an MSI copy by the launcher's per-user folder (the HKCU InstallDir
key, or %LOCALAPPDATA%\Programs\<App>). Every app installed for everyone, in
Program Files\ArtCraft\<App> or the older Program Files\<App>, was treated as a loose folder and
updated by unpacking the portable zip over Program Files without permission.

- msi_context moves here from the launcher (craft-launcher crates/native/src/msi_context.rs at
  b827fed, unchanged apart from visibility, MsiScope and scope_arguments). Windows Installer's
  own registration decides a copy's context, for the launcher and the apps alike, so the
  launcher can drop its copy and both routes follow one rule.
- New msi_copy module: a copy is an MSI copy when an App Paths entry names its exe (a registry
  read, cheap enough for status checks). Its update asks Windows Installer for the context; the
  App Paths hive is only the fallback when that lookup cannot run.
- The update stops, before the app exits, when the copy is registered in both hives, the lookup
  is unclear, or Windows lists the app more than once.
- After the update the helper starts the exe the registrations name now, since the package may
  have moved an exact old default folder.
- A failed self-update now names the Windows Installer log, as the launcher's installs do.
- The launcher's own per-user package is recognised and updated exactly as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 12:08:01 +00:00
Dylan M. Taylor 8829439d68 crw: address the remaining CodeRabbit record findings
- 02 §4: the decoder refuses the G5 with Error::Unsupported; the embedded-JPEG fallback is the
  caller's, not the decoder's.
- 04: the Auto-slot claim holds outside the white-balance preset captures.
- The record README no longer says it holds everything in the order it happened: the derivation
  trail stays at the pinned LightCraft revision.
- docs/clean-room.md allows that split for a derivation done in another repository, so the
  standard and the CRW record agree.
2026-10-28 22:19:44 -04:00
Dylan M. Taylor b600e6a5cd crw: split decode_entropy under the cognitive-complexity limit
main's workspace lints now deny cognitive_complexity above 30, and decode_entropy scored 41.
The emit macro becomes a Chains struct, unstuffing its own function, and the three stream-end
checks one. Same algorithm: the pinned CC0 digests still match byte for byte.

Also correct two record lines: the G5 is the one file that does not match, and the frozen
code tables are not the only logs that ship.
2026-10-28 22:15:50 -04:00
Dylan M. Taylor fea36c4309 Merge branch 'main' into clean-room-crw-format-decode 2026-10-28 22:10:33 -04:00
aiongg 1a11a48978 craft-dialogs: native file and message dialogs that never block the event loop (#412)
* Add craft-dialogs: native file and message dialogs that never block the event loop

Requests queue and show at the end of the frame on the main thread; answers come
back with the app's continuation on a later frame. One dialog at a time, a drop
guard and a panic guard so a dialog never stays open, and an override for tests.

On macOS, Open and Folder show as a free-standing NSOpenPanel
(beginWithCompletionHandler, which rfd can't show), Save and message boxes as
sheets through rfd's async dialogs, never falling back to runModal. Filter
extensions match in any letter case on Linux.

* craft-dialogs: Dialogs::raise brings the open macOS panel to the front

* CI: dialogs workflow (Linux clippy and tests for craft-dialogs)

* craft-dialogs: per-instance macOS panel, parent window check, override panic guard, CI lints macOS code

* craft-dialogs: raise only a visible panel; Open and Folder need a running app
2026-10-28 16:49:37 -04:00
solarmaster961andCursor bd9a4d7b16 fix(linux): self-update a system-wide Flatpak bundle in place
A system install was offered only as a download. Reinstalling that bundle
through Flatpak's install-bundle action is denied without a password dialog
when polkit cannot fill in $(path). Use pkexec on the host instead, and keep
per-user bundles on flatpak install --user.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-28 09:11:52 +01:00
aiongg b4afa6d22a Merge pull request #307 from rbulboaca/fix/windows-print-vendor-ticket-prefix
print: give the job ticket the driver's own prefix for its vendor nam…
2026-10-28 00:47:44 -04:00
aiongg 5f00550cf7 print: respell a QName value written after whitespace
A pretty-printed ticket puts whitespace before the value, so the prefix
starts after it; without this the ticket fell back to Windows' spelling.
2026-10-28 04:28:55 +00:00
enriquemelzer-bitandenriquemelzer-bit e11f9d9aeb fix(menu): preserve Cargo 1.95 manifest compatibility (#366)
Co-authored-by: enriquemelzer-bit <319226743+enriquemelzer-bit@users.noreply.github.com>
2026-10-27 21:53:44 -04:00
Dylan M. Taylor 34f31b9a4c Refactor proof for strict Clippy checks 2026-10-28 01:06:48 +00:00