Commit Graph
281 Commits
Author SHA1 Message Date
Brandon Thomas 80b3e3cb74 Merge pull request #47 from storytold/pr/release-0.2.1
Release: DesignCraft v0.2.1
v0.2.1
2026-10-06 08:00:51 -04:00
Brandon ThomasandClaude Opus 5.5 7f41aa51b0 Release: DesignCraft v0.2.1
Fixes the Windows installer: the Start Menu shortcut and Add/Remove Programs icon were blank, and the shortcut description was wrong. Release builds no longer open a console window behind the app.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-06 08:00:38 -04:00
Brandon Thomas d3001b4911 Merge pull request #46 from storytold/pr/windows-packaging
Windows packaging: Start Menu/Add-Remove icon, no console window, correct description
2026-10-06 07:54:02 -04:00
Brandon ThomasandClaude Opus 5.5 60de09f1bb Windows packaging: Start Menu/Add-Remove icon, no console window, correct description
The MSI Icon id had no .ico/.exe extension, which Windows Installer needs for
advertised shortcuts and ARPPRODUCTICON, so both showed a blank icon. Release
builds of the desktop app are now GUI-subsystem (no console window; the CLI stays
a console program), the shortcut/summary description names what DesignCraft does, and
packaging-lint rejects an Icon id without an extension. Found in printcraft#57.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-06 07:50:34 -04:00
Brandon ThomasandClaude Opus 5.5 02f187cc5d Text: story.replaceRange keeps the caret on a character boundary
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 17:32:57 -04:00
storybored379andOpenAI Codex e47f65a595 Text: keep selections on UTF-8 character boundaries
Use the document model boundary helper for explicit selections and retained selections after story replacement. Cover editing and caret movement through the command API.

Co-Authored-By: OpenAI Codex <[email protected]>
2026-10-05 17:32:57 -04:00
Brandon ThomasandClaude Opus 5.5 7d721c92eb Fonts: embed Shippori Mincho once, shared by documents and the UI
The UI theme included the 8.7 MB font a second time; it now uses
designcraft_fonts::JAPANESE_FALLBACK (release binary 72 MB -> 63 MB).
The ROADMAP note joins the Interface language entry.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 17:32:47 -04:00
midasdf 3ef82f850c i18n: bundle Japanese font fallback and translate vertical controls 2026-10-05 17:32:47 -04:00
Brandon Thomas 1adcf69521 Merge pull request #27 from storytold/pr/freebsd-ci-sync
FreeBSD CI: match the shared template
2026-10-05 10:04:33 -04:00
Brandon ThomasandClaude Opus 5.5 5276d7f67a FreeBSD CI: match the shared template (git + safe.directory, 4 vCPUs, pinned vmactions/freebsd-vm)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 09:45:12 -04:00
Brandon Thomas 1345488cff Merge pull request #25 from storytold/pr/freebsd
FreeBSD: CI job and X11 drag-and-drop on every non-Apple Unix
2026-10-05 08:30:23 -04:00
Brandon ThomasandClaude Opus 5.5 97487cf800 docs: point agents to the shared test corpora (#26)
Real-file test oracles live in storytold/photocraft-corpus, explained in
craftrules standards/test-corpora.md. Never commit large binary fixtures
here; fetch them pinned and sha256-verified.

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-05 08:24:08 -04:00
Brandon ThomasandClaude Opus 5.5 f327d1a078 FreeBSD CI: don't copy the build back out of the VM; longer timeout; alsa-lib
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 08:11:24 -04:00
Brandon ThomasandClaude Opus 5.5 811b0d8846 FreeBSD: CI job and X11 drag-and-drop on every non-Apple Unix
A FreeBSD workflow builds and tests the workspace in a FreeBSD 14 VM
(vmactions/freebsd-vm) on pushes to main, dependency changes and on
demand. The X11 backend choice for file drag-and-drop covered only
Linux; FreeBSD desktops use the same X11/Wayland stack, so it now applies
to all(unix, not(macos)).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 07:45:05 -04:00
Brandon Thomas c9a2040df3 Merge pull request #19 from storytold/pr/release-0.2.0
Release: DesignCraft v0.2.0
v0.2.0
2026-10-05 02:40:48 -04:00
Brandon ThomasandClaude Opus 5.5 6e7684a660 Release: DesignCraft v0.2.0
Bump the workspace version 0.1.1 -> 0.2.0 (cargo xtask version set 0.2.0).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 02:40:36 -04:00
Brandon Thomas afdae89d68 Merge pull request #14 from storytold/pr/never-crash-guard
Never crash: last-resort guard around every command
2026-10-04 14:20:03 -04:00
Brandon Thomas 87abffe7c0 Merge pull request #13 from storytold/pr/never-crash-apps
Never crash: apps (desktop, CLI, web)
2026-10-04 14:06:44 -04:00
Brandon Thomas 67535cf40a Merge pull request #12 from storytold/pr/never-crash-ui
Never crash: UI (ui-egui)
2026-10-04 14:06:22 -04:00
Brandon Thomas 9ec051e526 Merge pull request #11 from storytold/pr/never-crash-geom-color
Never crash: geom and color
2026-10-04 14:05:59 -04:00
Brandon Thomas e7f7ba13cc Merge pull request #18 from storytold/pr/never-crash-engine
Never crash: engine, MCP and tools
2026-10-04 14:05:42 -04:00
Brandon Thomas 1bf8ca50a1 Merge pull request #17 from storytold/pr/never-crash-render-pdf
Never crash: render and pdf
2026-10-04 14:05:25 -04:00
Brandon Thomas 9cf3a3309b Merge pull request #16 from storytold/pr/never-crash-doc-compose
Never crash: doc and compose
2026-10-04 14:05:09 -04:00
Brandon Thomas abb1667fef Merge pull request #15 from storytold/pr/never-crash-importers
Never crash: importers (text, IDML, fonts, format, EPUB, images)
2026-10-04 14:04:53 -04:00
Brandon Thomas 3e2cf149c6 Merge pull request #8 from storytold/pr/never-crash-steering
Never crash: steering rule, clippy.toml, forbid unsafe
2026-10-04 14:04:36 -04:00
Brandon ThomasandClaude Opus 5.5 f1662185de Never crash: last-resort guard around every command
Session::execute runs each command inside catch_unwind: a panic that escapes
(any edit, import or export, from the UI, CLI, MCP or control channel)
becomes EngineError::Internal, the document and selection are restored to
before the command, and crash recovery is saved when enabled. The first
Session installs a panic hook that logs the message and location.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 12:55:07 -04:00
Brandon ThomasandClaude Opus 5.5 59d7982780 Never crash: apps (desktop, CLI, web)
perf/bench return errors instead of expect() (bench runs on any document),
and the Windows resource build step fails the build without panic!. The
three app crates deny the panicking lints.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 12:43:34 -04:00
Brandon ThomasandClaude Opus 5.5 2c46e97a48 Never crash: UI
The canvas, Properties panel and QR dialog skip a frame instead of
expect()ing a document; the control channel caps ui.drag steps. ui-egui
denies the panicking lints.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 12:43:34 -04:00
Brandon ThomasandClaude Opus 5.5 d84107aaca Never crash: importers (text, IDML, fonts, format, EPUB, images)
An .xlsx cell reference far from the others no longer allocates the whole
range before the cell cap (billions of cells, out of memory), and long
column names can't overflow. IDML import doesn't trust zip part sizes for
up-front allocation and adds header/footer counts saturating. Tagged Text
and IDML export use let-else; the font fallback has a compiled-in last
resort. These crates deny the panicking lints.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 12:43:34 -04:00
Brandon ThomasandClaude Opus 5.5 f05bbfeea2 Never crash: engine, MCP and tools
Commands return errors instead of expect()/unreachable!() (book, library,
undo/redo, paste, find/replace, Pathfinder, tables, QR, select, swatches,
anchors, articles, transform again, XML import). The sample document builder
propagates errors. Commands that add a key to their parameters no longer
panic when a caller (control channel, MCP, script) passes an array or a
string, and corrupt crash-recovery metadata is ignored. engine, mcp and
tools now deny unwrap/expect/panic/unimplemented/todo/unreachable.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 12:43:33 -04:00
Brandon ThomasandClaude Opus 5.5 82d6def80b Never crash: render and pdf
Rasters stay below vello_cpu's u16 limits (a 65535-pixel-wide render
panicked inside it), page renders larger than 2^29 pixels decline instead of
allocating, PNG encoding never panics, and the PDF heading tag can't fail.
Both crates deny the panicking lints.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 12:43:33 -04:00
Brandon ThomasandClaude Opus 5.5 a539c76632 Never crash: doc and compose
expect() calls become let-else / fallbacks. A parent spread without pages
(possible in a .designcraft file) no longer underflows in parent_page_for,
and check() rejects a next_id so large that allocating ids would overflow.
Both crates deny the panicking lints.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 12:43:33 -04:00
Brandon ThomasandClaude Opus 5.5 89891fdfbe Never crash: geom and color return or fall back instead of panicking
Replace the unwrap/expect calls in path closing, bounds, Pathfinder output
and gradient sampling with let-else / if-let; the ASE reader uses checked
offsets (a 32-bit length could overflow on wasm32). Both crates now deny
unwrap/expect/panic/unimplemented/todo/unreachable.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 11:39:33 -04:00
Brandon ThomasandClaude Opus 5.5 38c09ad71b Never crash: steering rule, clippy.toml, forbid unsafe
AGENTS.md and CLAUDE.md get a "Never crash" section ahead of the
non-negotiables (craftrules standards/never-crash.md). Root clippy.toml lets
tests keep unwrap/expect/panic/indexing once crates deny them, and
unsafe_code goes from deny to forbid (no unsafe or allow(unsafe_code) in the
workspace).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 11:39:33 -04:00
Brandon ThomasandClaude Opus 5.5 192b72054d Linux: use the X11 backend under XWayland so files can be dropped (#2)
winit 0.30 has no file drag-and-drop on Wayland. DESIGNCRAFT_WAYLAND=1
keeps the native Wayland backend.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 11:38:26 -04:00
Brandon ThomasandClaude Opus 5.5 a2bbd96f30 UI: tool shortcuts work right after clicking the canvas (#1)
Only a focused text field blocks global shortcuts; the canvas (or a
button) holding egui focus after a click no longer swallows V/F/… until
Esc.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 11:38:17 -04:00
Brandon ThomasandClaude Opus 5.5 8490965e71 CI: fix new Rust 1.99 clippy lints (as_chunks, ?, redundant ref)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 11:37:09 -04:00
Brandon Thomas deab1dce10 Merge pull request #6 from storytold/pr/license-standard
Licensing: standard LICENSE files, NOTICE, ArtCraft brand terms
2026-10-04 10:09:14 -04:00
Brandon ThomasandClaude Opus 5.5 a848431dba Licensing: standard LICENSE files, NOTICE, ArtCraft brand terms
- LICENSE-MIT: copyright "ArtCraft Team and the DesignCraft contributors"
  (it wrongly named the PrintCraft contributors); LICENSE-APACHE: the
  standard text (adds the trailing newline).
- docs/brand/LICENSE-brand.txt: the ArtCraft brand terms.
- NOTICE: standard header and brand carve-out; third-party list kept.
- ASSETS.md: docs/brand/ rows point at LICENSE-brand.txt; brand files
  noted as the one non-open-source exception.
- README: standard "License and credits" section, nav anchor, badge alt.
- AGENTS.md / CLAUDE.md: asset rule notes the docs/brand/ exception.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 10:04:24 -04:00
storybored379andClaude Opus 5.5 8d0203a2d2 EPUB: styles whose names slug alike keep their own CSS classes
Paragraph and character styles become CSS classes through slug(), which
keeps only ASCII letters and digits. Different styles could therefore get
the same class: every all-non-ASCII name ("見出し", "本文", Cyrillic,
Greek…) becomes `basic`, and "Body Text" / "Body-Text" / "body text" all
become `body-text`. style.css then holds several rules for one class and
the last one wins, so e.g. a 30 pt centred Japanese heading style came
out at the body style's 10 pt, left-aligned, in the EPUB.

Map each style name to a class once per export (paragraph and character
styles separately), adding -2, -3… on a collision, and use that map for
both the stylesheet and the XHTML. A class set in Export Tagging still
takes precedence in the XHTML, as before.

Test: styles_whose_names_slug_alike_keep_their_own_classes.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 09:52:37 -04:00
storybored379andClaude Opus 5.5 eee64ae7c9 Layers: the active layer falls back to the top layer when it is removed
The active layer lives on DocState, outside the undo snapshots, and
nothing re-checked it when the document's layers changed. After New
Layer → Undo (or Delete Layer / Delete Unused Layers / Merge Layers on
the active layer) it kept pointing at a layer that no longer exists, and
every object created next (frames, lines, placed images, pasted items)
was put on that phantom layer: not drawn on the canvas, missing from PDF
export, ItemLayer referencing an undefined layer in IDML, and preflight
reported nothing.

After each command, if the active layer is gone, make the top layer
active (as on opening a document).

Test: active_layer_survives_undoing_new_layer.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-04 09:52:29 -04:00
storybored379andClaude Opus 5.5 01753f90f3 File: file.serialize returns the file's bytes (base64) — web Save wrote corrupt documents
file.serialize returned {json: String::from_utf8_lossy(to_bytes(doc))},
but since M6.1 the native format is a zip (deflated document.json + raw
assets), not JSON text. from_utf8_lossy turns every invalid UTF-8
sequence into U+FFFD, so the result is not the file: on the web, File ›
Save downloads exactly those bytes (download_document), and the
downloaded .designcraft can't be opened again ("invalid Zip archive").
Agents calling file.serialize got the same unusable string.

Return {base64, bytes} like the other byte-producing commands
(file.exportIdml, file.exportPdf, snippet.export) and decode it in
download_document.

Test: serialized_document_opens_again.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-04 09:51:34 -04:00
Brandon ThomasandClaude Opus 5.5 5294c8f677 T: ruby and kenten
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 02:47:55 -04:00
Brandon ThomasandClaude Opus 5.5 558e798dfc E: CMYK transparency blend space on screen
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 02:09:26 -04:00
Brandon ThomasandClaude Opus 5.5 e856b849bb M: video and sound in interactive PDF (screen annotations, renditions)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 01:44:50 -04:00
Brandon ThomasandClaude Opus 5.5 5b7969901c T: right-to-left carets and selections; Binding: Right to Left
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 01:34:47 -04:00
Brandon ThomasandClaude Opus 5.5 6334734b3a T: Insert Kashidas in the paragraph style Justification tab
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 01:18:41 -04:00
Brandon ThomasandClaude Opus 5.5 2827574a47 T: kashida justification for Arabic
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 01:15:38 -04:00
Brandon ThomasandClaude Opus 5.5 ee55acd858 T: Digits (World-Ready) — figures in Arabic-Indic, Persian and native scripts
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 01:06:38 -04:00
Brandon ThomasandClaude Opus 5.5 f888e6b061 X: DTDs — load, validate the structure, Tags panel
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 00:57:18 -04:00