* Linux: StartupWMClass is the window's app id
The desktop entry said StartupWMClass=pdfcraft, but the window carries the
app id ai.storyteller.pdfcraft (APP_ID) on Wayland and under X11 alike, so
nothing that matches a window to its launcher by that key ever matched it:
on X11 the launch's startup notification can't end when the window maps.
VectorCraft, GridCraft and WordCraft already use the app id.
A test reads the entry and compares it with APP_ID.
* Contributors: add atoslins (Atos Lins)
---------
Co-authored-by: Brandon Thomas <[email protected]>
- Cargo.toml: [workspace.package] and the internal path-dependency requirements move to 0.6.0
(they pinned 0.5.0, which `cargo update -w` can't match); Cargo.lock refreshed.
- release.yml: new `linux-riscv64` job, ported from GridCraft. Cross-compiles on ubuntu-24.04
against ports.ubuntu.com riscv64 libs (the linux job's -dev packages, :riscv64), builds the
tar.gz and the CLI-only tar.gz, smoke-tests pdfcraft-cli under QEMU, and is in the draft
release job's needs, so SHA256SUMS covers it.
- packaging/linux/package.sh: CROSS_ARCH / CROSS_TARGET / CROSS_COMPILE / EMULATOR support.
- README and docs/releasing.md list the riscv64 tarballs (glibc 2.39+).
- contributors.json refreshed.
Co-authored-by: Claude Opus 5.5 <[email protected]>
* M14: give Windows PDF files a dedicated document icon
Embed the document icon as resource 2 through the existing Windows resource
build and select it in both PDF association registrations. Keep the asset
reproducible and carry its required licence notices in Windows packages.
Formatting, strict Clippy, 1,842 existing workspace tests, all 30 WASM crate
checks, assets, layering and parity pass. The Windows x64 release package
checks pass, and the contributor confirmed the icon in Explorer.
Co-authored-by: Codex <[email protected]>
* Refresh catalog hashes after merging main
---------
Co-authored-by: Codex <[email protected]>
Co-authored-by: Brandon Thomas <[email protected]>
* Issue #390: build the DMG with hdiutil create so the app passes codesign --strict
makehybrid -hfs wrote a com.apple.FinderInfo (Finder location -1,-1) on every
file in the image, and codesign --verify --deep --strict rejects that as
"Finder information, or similar detritus", on the app in the DMG and on a copy
installed from it. hdiutil create -srcfolder writes the files as they are; it
attaches a device while copying, so it gets up to five tries. A gate mounts
the finished image read-only and verifies the app inside with --strict.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01REz7wTfQgnopyvN9eQJJVu
* Issue #390: retry hdiutil attach and detach in the DMG gate too
As suggested in review: the gate mounts the signed image under set -e, so a
"Resource busy" there would stop a release after the DMG was built. The same
five tries with growing pauses now cover create, attach and detach.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01REz7wTfQgnopyvN9eQJJVu
---------
Co-authored-by: Tristan von Kries <[email protected]>
Co-authored-by: Claude Fable 5.1 <[email protected]>
Add packaging/windows/security-audit.ps1, a read-only maintainer helper that records a
release file's SHA-256, Authenticode status and, with an external YARA binary and rule,
every matched string identifier and offset. Document the procedure in docs/releasing.md
("Scanner detections").
No application, dependency, installer or network behaviour changes: the diff touches only
the helper and the release documentation.
Co-authored-by: Claude Haiku 5.5 <[email protected]>
* Print: list driverless CUPS destinations, not only permanent queues
The Print dialog's printer list came from `lpstat -p -d`, which lists only
permanent queues. A driverless IPP printer discovered on the network — the
standard setup on modern Linux desktops — has no permanent queue: only
`lpstat -e` (CUPS >= 1.7) names it, and CUPS builds a temporary queue when
`lp` sends it a job. Until now such printers were invisible and the dialog
showed only Save as PDF.
Enumerate `lpstat -e` alongside `lpstat -p -d` and merge the answers: queues
first, deduplicated, default still from `-d`; a spooler without `-e` keeps
today's behaviour and loses only the driverless names. The .deb/.rpm now
recommend cups-client so a machine without a print stack is not silently
printerless.
Fixes#652
Co-authored-by: ZCode (GLM-5.3) <[email protected]>
* Print: fix the off-unix build and a driverless default's marker
`lpstat_e_command` is called only from `printers`' unix block, so off unix
it was dead code and CI's Windows clippy gate (`-D warnings`) failed to
build the crate. Gate it like its caller.
The default destination can itself be driverless — `lpoptions -d` names a
destination no queue exists for — and the merge appended it from
`lpstat -e` with `default: false`, so the dialog preselected the first
queue instead of the user's default. The `-d` default now marks the
appended entry too; the test covers it, and CRLF in `-e` output.
Co-authored-by: ZCode (GLM-5.3) <[email protected]>
---------
Co-authored-by: ZCode (GLM-5.3) <[email protected]>
Co-authored-by: Brandon Thomas <[email protected]>
Release builds said "Text recognition isn't installed: its models are
missing" because no packaging script or release job fetched the OCR
models: only `cargo xtask models` does, into the source tree.
- packaging/env.sh gains stage_models DEST, which runs
`cargo xtask models DEST` (every ATTRIBUTION.toml kind = "model" file,
SHA-256 verified, with its licence text). No model file is named, so
the models PRs #433/#572 add ship without packaging changes.
- `cargo xtask models` also writes ATTRIBUTION.txt crediting each model
(CC-BY-SA-4.0 requires attribution when redistributed).
- macOS: PdfCraft.app/Contents/Resources/models, before signing.
- Windows: models\ beside pdfcraft.exe in the MSI (WiX v5 <Files>
harvest) and the portable zip; test-msi.ps1 checks the folder.
- Linux deb/rpm/tar.gz/AppImage, Flatpak bundle and FreeBSD tarball:
share/pdfcraft/models beside bin/. Models::search_dirs now also looks
in <exe dir>/../share/pdfcraft/models (Models::dirs_beside_exe); a
test builds every package layout on disk and finds the models in each.
release.yml and freebsd.yml check the packages contain them.
- The missing-models messages no longer tell end users to run cargo,
and the 11 catalogs that keyed an old PRINTCRAFT_MODELS wording (or
the previous one) now key the current English text; ATTRIBUTION
hashes updated. A test checks the translations match.
The web (wasm) build, which the issue reports, still has no models; this
is the desktop half only.
Co-authored-by: Claude Opus 5.5 <[email protected]>
On Linux, pdfcraft-cli shipped only inside the desktop packages (about
55 MB), while macOS already publishes pdfcraft-cli-<v>-macos-universal.zip.
Servers, CI and agent sandboxes only need the headless CLI.
packaging/linux/package.sh gains a `cli` format, on by default, that writes
pdfcraft-cli-<v>-linux-<arch>.tar.gz: the stripped pdfcraft-cli from the
shared staging tree plus the licences/README via copy_docs. copy_docs now
also copies NOTICE (every package benefits). The release job already
uploads and checksums every file in dist/release; its package check now
lists the archive and runs the extracted binary. README and
docs/releasing.md list the new artifact and state the glibc 2.35 baseline.
Co-authored-by: Claude Opus 5.5 <[email protected]>
The DMG opened as a plain Finder window. It now shows the app icon's figure on
the PdfCraft colour, with PdfCraft.app and the Applications link side by side.
Same approach as PhotoCraft's and VectorCraft's.
- packaging/macos/dmg/: background.svg (source; text outlined, no paper grain,
the figure an <image> of assets/app-icon), background.tiff (1x + 2x HiDPI,
16-colour palette, Deflate, sRGB; ~95 KB) and dmg-layout.DS_Store (Finder
view settings: window, icon size 128, positions, background).
- generate.py writes the TIFF and the layout on any OS, byte-for-byte
reproducible, with nothing from the machine that ran it.
- package.sh copies them into the staging folder; the image is still built with
hdiutil makehybrid. Nothing extra runs in the signing job.
- The volume name drops the version: the layout finds the background through
an alias that includes the volume name. The DMG file name keeps the version.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Linux: accept file:// URI args so desktop launchers recognise pdfcraft as PDF default
GNOME Files (and other freedesktop-spec launchers) only register an app as the
default handler for a mimetype if its .desktop Exec accepts URIs (%u/%U), not
just paths (%F). pdfcraft's entry used %F, so even after `xdg-mime default
ai.storyteller.pdfcraft.desktop application/pdf`, double-clicking a PDF in
Files silently fell back to another installed viewer.
Switch Exec to %u and decode file:// args back to plain paths in main.rs
before they reach the rest of the app, which only ever opens paths. Other
schemes and plain CLI paths pass through unchanged.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
* path_from_arg: file://localhost, foreign hosts left alone, Windows drive paths, no indexing; Exec %U (several files)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
---------
Co-authored-by: Dmitriy Bunakalya <[email protected]>
Co-authored-by: Claude Sonnet 5 <[email protected]>
Co-authored-by: Brandon Thomas <[email protected]>
* Issue #157: the Windows portable zip keeps settings, logs and recovery beside pdfcraft.exe
The portable zip had no portable.txt, and the app had no portable mode: it always wrote %APPDATA%\PdfCraft and %LOCALAPPDATA%\PdfCraft. Now portable.txt (or PdfCraft.portable) beside the executable puts the settings, log files, crash recovery and new digital IDs in PdfCraftData next to it, as PhotoCraft does, and the zip ships portable.txt. An unwritable PdfCraftData falls back to the per-user folders and says so.
* Issue #157: update ATTRIBUTION.toml SHA-256 for the translation catalogs this PR changes
---------
Co-authored-by: Brandon Thomas <[email protected]>
* #305: harden Windows MSI deployment and progress UI
Co-authored-by: Codex <[email protected]>
* Keep the MSI manufacturer as Learning Machines LLC
The company name matches the Linux packages; changing it is the owner's call.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* #305: keep compiled-MSI checks compatible with PowerShell COM
Validated the compiled x64 MSI and negative scope, publisher and progress mutations.
Co-authored-by: Codex <[email protected]>
* ROADMAP: the publisher name is unchanged
Co-Authored-By: Claude Opus 5.5 <[email protected]>
---------
Co-authored-by: Codex <[email protected]>
Co-authored-by: Brandon Thomas <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
* Release: Flatpak bundles (x86_64, aarch64), AppImage zsync updates, README Downloads
- AppImages embed gh-releases-zsync update information and ship a .zsync beside them;
the Linux job installs zsync and checks both.
- New flatpak job (x86_64 on ubuntu-24.04, aarch64 on ubuntu-24.04-arm) repackages the
Linux tarball with packaging/linux/flatpak-bundle.sh and the new bundle manifest, then
smoke-tests it in the sandbox. finish-args shared with the Flathub manifest (packaging-lint
checks they match): Wayland/X11, dri, CUPS for printing, Documents and Downloads.
- Only the signing jobs and the draft-release job keep `environment: release`, so a branch
dispatch is a dry run of everything else and can never draft a release.
- README: a Downloads section listing every build; docs/releasing.md updated.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Flatpak: no CUPS socket (the runtime has no lp); document printing as unavailable there
Co-Authored-By: Claude Opus 5.5 <[email protected]>
---------
Co-authored-by: Brandon Thomas <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
* #143: Windows MSI desktop shortcut checkbox and install-complete dialog
Add native installer dialogs (installer-ui.wxs): a welcome screen with a
"Create a desktop shortcut" checkbox (ticked by default), repair/remove,
progress, and "Setup completed successfully" / failed / cancelled screens
with Finish. Unattended /qn and /qb installs never wait on a dialog and can
skip the desktop shortcut with INSTALLDESKTOPSHORTCUT=0.
Start Menu and desktop shortcuts are now plain links to pdfcraft.exe in
their own components (HKLM key paths, removed on uninstall) instead of
advertised MSI shortcuts.
test-msi.ps1 checks the compiled MSI's shortcut, checkbox and dialog tables
during packaging; the ARM64 install smoke test checks both shortcut
targets, their removal on uninstall, and the INSTALLDESKTOPSHORTCUT=0
opt-out.
Co-authored-by: ChatGPT <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01JqiBTPWGWbhQDYNFcxFte6
* #143: run test-msi out of process before signing; add files-in-use dialog
test-msi.ps1 held the MSI open through a Windows Installer COM handle in
package.ps1's own process, so signtool could fail on signed release builds.
Run it in a child process and release the COM objects.
The hand-authored UI had no MsiRMFilesInUse dialog, so an upgrade or repair
while PdfCraft is running could not offer to close it. Add one (OK closes the
programs with MSIRMSHUTDOWN=2, Cancel stops setup) and check for it in
test-msi.ps1.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01JqiBTPWGWbhQDYNFcxFte6
---------
Co-authored-by: ChatGPT <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: Brandon Thomas <[email protected]>
CFBundleDocumentTypes listed PDF by extension and MIME type only.
LaunchServices keeps those as plain tags (.pdf, application/pdf)
instead of resolving them to com.adobe.pdf, so Finder greys the app
out under Open With > Recommended Applications and a forced open
fails with 'cannot open files in the PDF document format'.
Add LSItemContentTypes com.adobe.pdf (keeping extension and MIME for
backward compatibility). Role stays Editor, rank stays Alternate, so
the app is offered without hijacking the default. Verified with
lsregister -dump: bindings change from '.pdf, application/pdf' to
'com.adobe.pdf' with claimed UTIs com.adobe.pdf; plutil -lint and
xmllint --noout pass.
Follow-up to #73.
Co-authored-by: Brandon Thomas <[email protected]>
The app, crates, binaries, bundle id, packaging, icons, screenshots and docs are now
PdfCraft / pdfcraft (repo storytold/pdfcraft). On first launch the desktop app moves the
PrintCraft settings and crash-recovery folders to the new name, and both apps read settings
saved under the old storage key, so upgrades keep recent files, preferences and unsaved work.
The signing test fixtures keep their PrintCraft subject names (they are binary).
Co-authored-by: Claude Opus 5.5 <[email protected]>
The MSI registered no file association. The only PrintCraft entry a
user could pick in "Choose an app on your PC" was the advertised Start
Menu shortcut, which Windows can't run as a file handler ("This app
can't run on your PC").
The MSI now uses Windows' Default Programs registration: a
PrintCraft.Document ProgID (open command, icon), .pdf OpenWithProgids,
Applications\printcraft.exe (friendly name, supported types), and
Capabilities\FileAssociations listed under RegisteredApplications.
PrintCraft appears under "Open with" and in Settings > Default apps.
It never takes over an existing default: .pdf's own default value is
left alone, and the user chooses.
Checked locally with WiX 5.0.2: the MSI builds, passes ICE validation
(only the existing ICE61 note on same-version upgrades), and its
Registry table holds exactly these values.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
release.yml's comments say "See docs/releasing.md", but the workflow came
over from PhotoCraft without its document. It now describes PrintCraft's
pipeline as it is: cutting a release and test runs, every artifact
(including Windows on ARM64), the craft-fonts pin, each platform's
packaging, signing and notarization, the release-environment secrets,
and the packaging checks.
Written from release.yml and the packaging scripts. It says plainly that
the binaries don't embed the commit yet, and packaging/env.sh no longer
points to a build_info.rs that doesn't exist.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The Linux package description, AppStream metadata (categories,
keywords, a screenshot that doesn't exist), the MSI's comment and the
web embedding example still described PhotoCraft. They now describe a
PDF workbench, AppStream lists application/pdf, and the screenshot is
one of ours.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Finder hands files to an app as an Apple event, not on the command
line. winit doesn't handle it, so AppKit answered "PrintCraft cannot
open files in the PDF document format". The bundle also declared no PDF
document type: its Info.plist still carried the sibling image editor's
types.
- Info.plist declares PDF (by extension and MIME type) as a document
type, role Editor, rank Alternate: offered under Open With and
settable as the default, without taking over on install.
- apps/printcraft registers open-documents and quit Apple event
handlers through fmv-macos-events (=0.1.0, the audited safe wrapper
PhotoCraft uses, since the Objective-C interop needs unsafe), before
the launch event arrives.
- printcraft-ui-egui gains OsEvent and PrintCraftApp::os_events, polled
every frame: Open opens each file as File > Open does; Quit closes the
window like its close button, so unsaved changes are asked about.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Shippori Mincho (and its OFL file) leaves assets/fonts/: the Japanese fonts now
live in storytold/craft-fonts. printcraft-fonts gets craft-fonts' build.rs recipe:
with CRAFT_FONTS_DIR=<checkout> it embeds the manifest's fonts as CRAFT_FONTS
(wasm32: only BIZ UDPGothic Regular); without it CRAFT_FONTS is empty and the
app builds, tests and runs as before, minus the Japanese face.
- SHIPPORI_MINCHO is now Option<&[u8]> from CRAFT_FONTS; japanese_glyph
(was shippori_glyph) uses document_japanese_font() (Shippori Mincho, then
BIZ UDMincho, then any Jpan face) and returns GlyphError::NoFont without one.
- Editing PDF text into Japanese without craft-fonts is a clear EditError that
leaves the page untouched.
- UI: every Jpan craft font (BIZ UDPGothic first) is the last fallback of
every egui family, sharing the same static bytes.
- Tests: Japanese glyph/edit tests skip without craft-fonts; new UI tests for
no-tofu Japanese with craft-fonts and working fonts without it.
- CI: the Linux test job checks out craft-fonts at a pinned SHA and runs the
tests with CRAFT_FONTS_DIR. Releases build every platform with it
(CRAFT_FONTS_REQUIRED=1) and ship each font's OFL as OFL-<family>.txt.
- ATTRIBUTION.toml gains [[build_input]] (checked by xtask assets); NOTICE,
AGENTS.md, CLAUDE.md, README and docs say fonts live in craft-fonts.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The cross-compiled ARM64 binary can't run on the x64 packaging runner; the
windows-arm64 workflow installs and runs it on ARM64 instead. (x86 builds
still run there: x64 Windows runs them.)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
- package.ps1 takes -Arch arm64 (aarch64-pc-windows-msvc, WiX -arch arm64)
and now checks each binary's PE Machine as well as its Subsystem, so an x64
build can never ship labelled arm64.
- release.yml builds, signs and packages a Windows ARM64 MSI and portable zip
next to x64 and x86, cross-compiled on the x64 runner so signing and WiX
run exactly as they do for x64.
- New windows-arm64.yml (PRs touching Cargo/packaging, main, weekly):
packages the ARM64 MSI the same way (unsigned), installs it on a Windows 11
ARM64 runner, checks both installed binaries are ARM64, opens/reads/edits/
renders/saves a PDF with the installed CLI, uninstalls; and runs the whole
test suite natively on ARM64. The MSI is kept as an artifact for 7 days.
- README: Windows builds for x64, x86 and ARM64.
Requested by @maxffarrell.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
- printcraft.exe release builds use the GUI subsystem, so launching it no
longer opens a console window next to it (debug builds keep the console).
- The MSI's Icon id gains its .ico extension: Windows Installer requires it
for advertised shortcuts and ARPPRODUCTICON, so the Start Menu shortcut and
Add/Remove Programs showed a blank icon.
- Guards: package.ps1 checks the PE subsystem of both binaries (app = GUI,
CLI = console) before packaging; packaging-lint fails on an Icon id without
.ico/.exe.
- The shortcut's description said "image editor"; it's a PDF workbench.
Reported, with the exact fixes, by @MikailuReeves.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The release workflow gains a FreeBSD x86_64 job: packaging/freebsd/package.sh
builds in the same pinned FreeBSD VM and writes a /usr/local-style tar.gz
(app, CLI, desktop entry, MIME type, AppStream metadata, icons, licences).
README and CLAUDE.md list FreeBSD now that its CI job builds PrintCraft and
passes all 688 tests on FreeBSD 14.3.
Co-Authored-By: Claude Opus 5.5 <[email protected]>