Repository navigation
0.4.0
Changed
- Breaking — the processing error channel is now typed.
ProcessingOutcome::errorMessage(a free
string) is replaced bystd::optional<Models::ProcessingError> error, and
ProjectItem::applyProcessingResults()now returnsstd::vector<Models::ProcessingError>
(previouslyvoid). Consumers readoutcome.error->messageinstead ofoutcome.errorMessage, and
should surface the vector returned byapplyProcessingResults().outcome.failed/
outcome.cancelledare unchanged (failed == error.has_value()). Core::InputResultgainserrorCode/errorCategory— the per-input skip reason
(SkippedError) now carries a stable machine tag alongside the existingdetailstring, so a
consumer can group/localise skips without parsing English. The file and message are still
inputPath/detail(no duplication).
Added
Models::ProcessingError— one typed error vocabulary (code+category+message+fileslice) shared wherever a failure is consumed as a result:ProcessingOutcome::error, the
applyProcessingResults()return, and theInputResulttag.ProcessingErrorCategory
(Load/ProfileMatch/Slice/Encode/Io) andProcessingErrorCodecover the pipeline's
fatal sites and the post-render hash failure. Deliberately no liveonErrorcallback: for a fatal
error the run returns immediately (readoutcome.error), and per-input skips already flow through
onInput;onLog(Error, …)remains the human transcript.
FileStatus::Error— a new, sticky input status for a page that was rendered but whose content
hash could not be computed afterwards.WorkspaceEditor::duplicateProject(source, newName)— seeds a new project from an existing one,
copying its input files and profile links (canvasProfileIds+outputProfileId) only. The
output directory, the output slice list and all render state are deliberately dropped, so the copy
starts withPendinginputs and renders into its own folder. Mints a fresh workspace-unique project
uid (the source keeps its own) and fresh project-local input uids — no identifier collides. Enables
the GUI's "New from this…" action for the multi-publisher workflow.- Complete third-party notices for the bundled DLL graph. The Windows packages now ship
credits/THIRD-PARTY-NOTICES.txt,credits/licenses/(18 canonical/upstream licence texts) and a
credits/sbom.spdx.jsoncovering all 32 components (the 3 direct deps + the ~29 libvips runtime /
compiler-runtime DLLs — glib, libpng, libjpeg/mozjpeg, freetype, harfbuzz, cairo, pango, webp, …),
instead of only libvips + nlohmann/json. Generated at configure time (cmake/gen_credits.cmake) from
the web-build's authoritativeversions.json+ a curatedcmake/third_party.json; aThird-party coverageCI workflow fails if a bundled DLL is unmapped. The committedsbom/snapshot (GitHub
dependency graph) was refreshed to the full graph. (Legal note:third_party.jsonSPDX ids are
curated best-effort and pending a final review; libimagequant is disclosed as GPL-3.0-or-later.) - Safety net for unforeseen faults.
ProcessingPipeline::run()now wraps its whole body so any
exception that escapes the inline handling (a bug, out-of-memory, a non-std::exceptionthrow) becomes
a typedUnexpected/Internalfailure onoutcome.errorinstead of unwinding out ofrun()and
terminating the caller's worker thread; the CLI gained an equivalent top-level guard that prints a
reportable diagnostic. NewProcessingErrorCode::Unexpected+ProcessingErrorCategory::Internal.
(This handles C++ exceptions only — a hardware fault such as a segfault or null dereference is an OS
signal / SEH, not a C++ exception, and is out of scope; catching those needs a dedicated crash handler.)
The CLI also installsstd::set_terminateto print the in-flight exception on theterminatepaths
(uncaught exception /noexceptviolation / pure-virtual call) instead of aborting silently.
Fixed
- An unreadable-after-render input no longer loops forever, silently. When
computeFileSha256()
returned""(indistinguishable for "absent" and "locked / denied / offline"),
applyProcessingResults()left a successfully-rendered input atPending;sanitize()re-confirmed
Pending, so every subsequent render redid all the work and overwrote the output indefinitely with
nothing reported. Such an input is now set toFileStatus::Error(sticky, non-forcing) and returned
as a typedInputHashFailedfailure; it recovers toProcessedonce the file can be read again.
CLI
project duplicate --workspace F --name SRC --new-name COPY [--output DIR]— seeds a new project
fromSRC(input files + profile links only; no outputs / output dir / render state), the CLI face of
WorkspaceEditor::duplicateProject(). Refuses a missing source or an already-taken name; without
--outputit notes that the copy needs an output directory before rendering.processgained structured, TTY-aware output — a per-input tally (with the typed skip reason),
a strip-assembly marker, an in-place progress bar (plain lines when piped), timing, and dedicated
error sections that renderProcessingErrorfields (category / slice / file) plus the post-render
"unverified input(s)" list.--jsonis unchanged apart from a newunverifiedInputsarray. Symbols
only, no colour, so redirected output stays clean.
What's Changed
- chore(deps): bump advanced-security/spdx-dependency-submission-action from 0.1.1 to 0.2.0 by @dependabot[bot] in #1
- chore(deps): bump actions/checkout from 4 to 7 by @dependabot[bot] in #2
- chore(deps): update pytest requirement from >=7.0 to >=9.1.1 in /tests/cli-tests by @dependabot[bot] in #3
- chore(deps): bump softprops/action-gh-release from 2 to 3 by @dependabot[bot] in #8
- chore(deps): bump actions/attest-build-provenance from 1 to 4 by @dependabot[bot] in #7
- chore(deps): bump actions/upload-artifact from 4 to 7 by @dependabot[bot] in #6
- chore(deps): bump actions/checkout from 4 to 7 by @dependabot[bot] in #5
- chore(deps): bump actions/download-artifact from 4 to 8 by @dependabot[bot] in #4
New Contributors
- @dependabot[bot] made their first contribution in #1
Full Changelog: 0.3.1...0.4.0