Preserve paragraph breaks after a ParaStyle tag starts the story so leading empty paragraphs and their styles survive Tagged Text import.
Validated individually and after #638 with all six cargo xtask ci gates (1,278 tests passed, four existing tests ignored, 15 WASM compilation checks), six independent paragraph/header/Unicode probes, and an actual export-to-placement command smoke test.
Refs #641
Move and mirror segment midpoints when reversing gradient stops so reversed gradients preserve color and opacity interpolation.
Validated locally on macOS with all six cargo xtask ci gates (1,277 tests passed, four existing tests ignored, 15 WASM compilation checks), plus independent regressions, undo/redo, native and IDML round trips, and PNG/PDF rendering.
Refs #638
Route AppKit termination through the existing unsaved-document close transaction using the immutable winit patch. Restore pending prompts from hidden or minimized windows and preserve answers across repeated requests.
Validation: all six local gates, native cancellation/retry/save smoke, and hosted platform checks.
Fixes#544.
PR #623.
Force actual failed recovery publication at the reserved destination so privileged runners exercise the intended retention path. Keep the normal writer, publication order and existing assertions; enable these fixtures across platforms.
Validation: all six local gates and the FreeBSD root VM workspace build/tests.
PR #627.
Checkpoint the latest document state during App::on_exit after honoring current quit approvals. Keep incomplete or stale plans, clear recovery for clean documents and report unavailable or failed storage.
Follow-up to #545; cancelable macOS Dock Quit remains open in #544.
PR #617.
Keep recovered snapshots available through a second crash before autosave. Track checkpoint ownership across folders and restarted IDs; Save, Close and Revert clean only checkpoints owned by that document.
Follow-up to #506 and the retention concern in #380.
PR #616.
Prepare and stage every chapter before a book update writes files. Preserve imported IDML sources, reject open native chapters and report completed paths after a later write failure.
Follow-up to #485.
PR #615.
Route desktop writes and CLI raster exports through the engine atomic writer. Add actual-caller regressions for reader visibility, private modes, symlinks and valid long filenames.
Follow-up to #485.
PR #614.
Preserve document paths, revisions and collection contents when persistence fails. Rebase Save a Copy paths without changing the open document.
Follow-up to #485.
PR #613.
Prompt for unsaved documents on window close and application/menu quit. Defer discarding documents until all approvals are current, retaining every tab when a later decision cancels quitting.
Refs #544. Cancelable macOS Dock Quit remains separate.
Co-authored-by: aiongg <aiongtaigi@gmail.com>
Co-authored-by: skylar taylor-barrick <hi@skylar.cc>
Keep each app's recovery data in an owned run folder. Validate current folder and lock ownership and disable recovery when isolation fails instead of using the shared root.
Fixes#496.
Co-authored-by: noah1400 <48360809+noah1400@users.noreply.github.com>
Co-authored-by: skylar taylor-barrick <hi@skylar.cc>
Replace native engine saves and engine/MCP exports atomically, preserving private permissions during staging and cleaning up failed writes. Add regressions for long filenames and caught writer unwinding.
Fixes#436.
Co-authored-by: aiongg <aiongtaigi@gmail.com>
Co-authored-by: skylar taylor-barrick <hi@skylar.cc>
The previous release build failed in craft-common-actions, not in this
repo: riscv64 packaging got --formats deb,rpm,tar (fixed in
craft-common-actions#3), Linux jobs lacked the ALSA headers
(craft-common-actions#5), and Windows signing needed the AZURE_* secrets
listed in the caller.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Since the release workflow moved to storytold/craft-common-actions, it has
passed only the Apple and WINDOWS_CERTIFICATE secrets. The signing job reads
values from the release environment, but only for names the caller lists, so
the AZURE_* names that Trusted Signing uses came through empty and Windows
builds would ship unsigned. Same fix as storytold/craft-launcher#174.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Return ordered item IDs from Move, Duplicate and Step and Repeat while preserving the existing moved and created counts, selection and undo behavior. Scripts can use the IDs to operate on copies.
Validation: eight independent probes covering both swatch validation and returned IDs, plus all six cargo xtask ci gates on main after #520 (1,188 native tests passed, 3 ignored; all 15 applicable crates passed WASM compilation checks). Both ROADMAP entries and command regression modules are retained.
Task: #521
Reject unknown object fill, stroke and gap swatch names before editing the document, and suggest an existing name where possible.
Validation: three independent atomicity and compatibility probes, plus all six cargo xtask ci gates against current main (1,187 native tests passed, 3 ignored; all 15 applicable crates passed WASM compilation checks). ROADMAP progress entries are retained.
Task: #520
Reject unknown character fill swatches before modifying text or undo history. Registered swatch names remain valid, including names that resemble hex colours.
Validation: invalid-name atomicity and save/reopen regressions, plus all six cargo xtask ci gates on main after #514 and #523 (1,186 native tests passed, 3 ignored; 15 crates passed WASM compilation checks).
Task: #403
Parent-page text now uses the absolute page index as its cache key, so repeated page numbers and renumbering do not reuse another page's composition.
Validation: targeted canvas and PDF regressions, plus all six cargo xtask ci gates on main after #514 (1,179 native tests passed, 3 ignored; 15 crates passed WASM compilation checks).
Task: #523
Do not resend a request after a transport failure. Report the uncertain outcome and reconnect on the next explicit request.
Validation: all six cargo xtask ci gates passed on the merge candidate; 1,177 native tests passed and all 15 WASM packages checked. Lost-reply, invalid UTF-8 and timeout probes reproduced duplicate edits before the fix and one edit afterward.
Task: #514
Match IDML part names leniently, report missing parts, and show import warnings when opening a file. Cover the malformed URI crash with a regression test.
Validation: all six cargo xtask ci gates passed on the current main merge candidate; 1,176 native tests passed and all 15 WASM packages checked.
Hosted FreeBSD tests and Windows ARM64 packaging and install/run checks passed.
Task: #356
Co-authored-by: skylartaylor <26588250+skylartaylor@users.noreply.github.com>
Honor the capitalized-word hyphenation setting for uppercase words and retain the current roadmap entries.
Validation: all six cargo xtask ci gates passed on the current main merge candidate; 1,170 native tests passed and all 15 WASM packages checked.
Task: #538
Co-authored-by: skylartaylor <26588250+skylartaylor@users.noreply.github.com>
Share duplicate file data while keeping distinct link paths independent, and leave unused assets out of saved documents.
Validation: all six cargo xtask ci gates passed on the merge candidate; 1,170 native tests passed and all 15 WASM packages checked. Independent regression checks cover updates, relinking, embedding, undo and save/reopen.
Task: #420
* Place: an image placed into a frame fills it once and leaves Auto-Fit off
* Place: the fitting test names its fitting, since a placed image no longer auto-fits
A CMYK component of 1 or less was read as a fraction even when the other
components were percentages, so {"c": 0.7, "m": 0, "y": 12.2, "k": 0}
(a pale cream) became C 70 % Y 12.2 % and exported as
`0.7019608 0 0.12156863 0 k`. The same applied to RGB arrays.
Now a colour is read as percentages (0..100, or 0..255 for RGB) when any
component is above 1, and as fractions only when every component is
within 0..1.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Every font field's menu (Control bar, Contextual Task Bar, Properties > Character,
Character and Glyphs panels, Paragraph/Character Style Options, Find/Replace Font)
keeps its search focused and open on a click and filters as you type. In a dialog,
Return picked the highlighted family and also pressed OK, and Escape closed the
menu and cancelled the dialog: the menu now consumes the keys it uses. The
drawn font fields report themselves as combo boxes to screen readers.
Text set in Portuguese ("Portuguese: Brazilian", "Portuguese", pt_BR) got
no hyphenation, so justified Portuguese columns could only stretch their
word spaces (up to 335 % of the normal space in a 56 mm column of 10 pt
Times).
Turn on hypher's "portuguese" feature, beside Spanish: hyph-pt.tex 1.4
(2024-07-13) from hyph-utf8, BSD-3-Clause, credited in NOTICE.
Lang::for_language already maps the Portuguese names and locale codes.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
file.place sized a placed PDF page (and SVG) from its size rounded to
whole points, while the export draws the page into that size: a page of
91.774 x 613.276 pt became 92 x 613 and was drawn 0.25 % wider and
0.3 % shorter, so pieces laid edge to edge left gaps of up to 1.9 pt.
A 100.4 x 50.4 pt page placed 100.4 pt wide came out 50.2 pt tall:
`Rect { x0: 0.0, y0: 0.0, x1: 100.4, y1: 50.2 }`.
The graphic's natural size is now the exact page (crop box) or SVG size;
the rounded pixel size stays for display and preflight. place.load (the
place cursor) gets the same exact size.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* ci: refactor workflows to use reusable artcraft-common-actions
* ci: point reusable workflows to storytold/craft-common-actions
* ci: pin storytold/craft-common-actions to commit 27a978f and pass secrets explicitly
* ci: use @main (unpinned) for craft-common-actions with explanation comment
- release.yml: new linux-riscv64 job (cross-compiled on ubuntu-24.04 against
ports.ubuntu.com riscv64 libs, tar.gz only, CLI smoke-tested under QEMU),
ported from GridCraft; the draft release job needs it, so SHA256SUMS covers it.
- packaging/linux/package.sh: CROSS_ARCH/CROSS_TARGET/CROSS_COMPILE/EMULATOR
support, as in GridCraft.
- cargo xtask version set 0.6.0; README, hardware parity and ROADMAP log note
the new platform.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Progress docs per craftrules standards/progress-docs.md: target-app parity, gaps, roadmap with alpha gate, readiness by audience (full / mainstream / essentials) with Opus 5.5 hours, and feature, format, hardware, UI and localization parity docs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Consecutive paragraphs with the same Split Columns settings form a split
block: their text fills the sub-columns of the column one after the
other from the block's top, inset by the outside gutter and separated by
the inside gutter, then moves on to the next column. When text follows
the block, its last part is balanced across the sub-columns and the text
continues below the deepest one at the full column width; a block that
ends the story fills its sub-columns in turn. Keep options don't apply
between a block's lines.
IDML: SplitColumnInsideGutter and SplitColumnOutsideGutter import and
export (paragraph attributes split_inside_gutter, split_outside_gutter).
Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* PDF export: Export Adobe PDF options dialog with remembered settings
File > Export PDF... now opens an options dialog (General / Compression /
Marks and Bleeds / Advanced) that exposes only the parameters the engine's
file.exportPdf already supports: PDF standard, image compression, flattener
preset, spreads, document bleed, crop/bleed/page-info marks with weight and
offset, tagged PDF, page range, and the title. Choosing a preset fills the
dependent fields; editing any field switches the preset to Custom.
The last-used settings persist in ui.json (UiState.pdfExport) and are reused
across exports and sessions. Programmatic callers that pass explicit params
(path, options) still export directly without the dialog; cancelling the save
picker writes nothing.
Adds English and ar/pt-br strings, unit tests for the settings serde, the
dialog defaults and preset mapping, the open/confirm flow (stub writer), and
the menu dispatch, plus a ROADMAP note.
* PDF export: rename dialog title to "Export PDF"
---------
Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>