upstream/main c3859c82 (#614e198eb5d, #6159509b2bc, #6168e151a2f, #617c3859c82).
Conflict: ROADMAP.md: header keeps next's change list plus orderly native exit recovery; progress log both
Conflict: apps/designcraft-cli/src/main.rs: next's case-insensitive .jpg/.jpeg check with main's write_atomic
Conflict: apps/designcraft/src/main.rs: on_exit keeps next's startup.presented() (not an Option) and adds preserve_documents_on_exit; next's discard_marked_text and main's preserve_documents_on_exit both; Services write uses write_atomic and keeps next's clipboard_text; tests both
Conflict: crates/engine/src/cmd/book.rs: main's ChapterBatch paginate with next's chapter-number resolution and {pages, chapters} result and doc
Conflict: crates/engine/src/cmd/file.rs: revert takes main's discard_document ordering without the revision + 1 (next's DocState::new hands out a fresh revision)
Conflict: crates/engine/src/recovery.rs: main's save_tracked, write_entry and open (st.bump_revision() for next's global revisions); next's reopen-twice test assertions kept
Conflict: docs/gaps.md, docs/target-app-parity.md: headers combined; next's Language, Books and Numbering lines plus main's book update safety line
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.
`run --pdf-options '[1]' --export a.pdf` panicked when the PDF's path
was added to the options (exit status 101). The value is now checked
where it is read.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
--export knew .pdf, .epub, .idml and .designcraft and saved a PNG of
the page under every other name: out.html, out.txt, OUT.PDF, and
out.designcraft from `script`. The exit status was 0.
.html and .htm now run file.exportHtml, .rtf and .txt run
file.exportText (the story being edited or of the selected frame), and
extensions match in any case. A name with another extension is an
error before anything runs; one with no extension is still a PNG.
`run` and `script` share one list, and `script` saves a copy for
.designcraft.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Asking for help is not an error, but `designcraft-cli --help` shared the
catch-all arm with unknown commands, so it wrote the usage block to
stderr and exited 1 — unusable in a pipeline and wrong by convention
(`--version` already exits 0).
Split the arm: `--help`, `-h` and `help` now print the same usage block
to stdout and succeed, while an unknown command keeps it on stderr and
still fails. The usage text and links line are hoisted into a shared
`USAGE` const and `usage_footer()` so the two paths can't drift.
Fixes#243🤖 Generated with Codebuff
Co-authored-by: Codebuff <noreply@codebuff.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* CLI: run rejects an export option with no export after it (#67)
--page, --scale and --pdf-options apply to the exports that follow them; one
given after the last --export or --all-pages did nothing and said nothing.
The usage text and docs/agents.md say so.
* MCP: document that text offsets and story lengths are UTF-8 bytes (#68)
* MCP: docs name the UI-only commands precisely; app.links works headless (#62)
* README: PDF and EPUB export ship (#60)
`designcraft-cli commands | head -1` panicked and exited with status 101:
thread 'main' panicked at library/std/src/io/stdio.rs:1168:9:
failed printing to stdout: Broken pipe (os error 32)
println! panics when stdout is closed. Output now goes through outln!, which
ends the program with status 0 on a broken pipe (the reader has what it
wanted) and reports any other write error on stderr with status 1.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>