225 Commits
Author SHA1 Message Date
Brandon ThomasandClaude Opus 5.5 d07cbbe94c Merge PR #859 (with main's 255-click limit kept inside its event budget)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-14 12:58:52 -04:00
Brandon Thomas 0df9238c73 Merge PR #850 2026-10-14 12:56:09 -04:00
Brandon Thomas b8d975b094 Merge PR #866 2026-10-14 12:39:59 -04:00
Brandon Thomas 23aeddb354 Merge PR #864 2026-10-14 12:39:58 -04:00
Brandon Thomas c1a1970168 Merge PR #862 2026-10-14 12:39:58 -04:00
Brandon Thomas a6e7e2a0c7 Merge PR #838 2026-10-14 12:39:58 -04:00
moppeeerandClaude Opus 5.5 23e1680e7d feat(ui): Swatches panel header like InDesign's; swatches go to the fill or stroke in front
LYH Studio episode 6 colours the "1969" headline (8:28) and the loop's
stroke (9:15) from the Swatches panel, whose header holds InDesign's
Fill/Stroke proxy, Formatting Affects Container/Text and the Tint field.

- Header: a Fill/Stroke proxy showing the colours of what colour edits
  apply to (panels::color_target; a click brings the other to the front,
  as X does), the container/text buttons (app.formattingAffectsText) and
  the tint of the colour in front.
- The Tint field sends only the tint, so each selected object (or run of
  text) keeps its own swatch: object.fill takes a tint without a swatch,
  and a stroke tint alone doesn't give a stroke-less object a stroke.
- Clicking a swatch applies it to the fill or stroke in front
  (panels::apply_swatch, to the text when colours affect text); that row
  is highlighted.
- Bottom row: New Color Group, New Swatch, Delete Swatch (the swatch last
  clicked). Rows and the proxy are named for accessibility (and tests).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-14 10:27:38 +02:00
moppeeer 2a9e29f6ff Merge branch 'codex/page-tool-control-panel' into codex/liquid-object-pins
# Conflicts:
#	crates/engine/src/tests.rs
2026-10-14 09:39:24 +02:00
aiongg 7d601b5903 Integration: #864 drops the Controlled by Parent rule from the menus and the Objects Move with Page checkbox (neither has an effect yet)
(cherry picked from commit 47b51d637756a468555feeac60965d3c94ab05d1)
2026-10-14 09:38:25 +02:00
moppeeer 3f1eb00bb3 Merge branch 'codex/page-tool' into codex/page-tool-control-panel
# Conflicts:
#	crates/engine/src/tests.rs
2026-10-14 09:38:16 +02:00
moppeeer 65dbf3c3a2 Merge remote-tracking branch 'origin/main' into codex/page-tool
# Conflicts:
#	crates/engine/src/tests.rs
2026-10-14 09:37:32 +02:00
moppeeer ed6bcae877 Merge remote-tracking branch 'origin/main' into codex/gradient-cmyk-blend 2026-10-14 09:12:51 +02:00
LabDennis ff5d866ff3 chore(sync): merge upstream main into PR #854 2026-10-14 06:51:45 +02:00
0f4f382b0e feat(text): improve editing, snapping, and threading
Add multi-click text selection, pending caret formatting and clipboard support, text-aware colour controls, guide/grid snapping, and frame threading with loaded-port interactions.

Include the layout, drop-cap and IDML updates carried from #83, with safeguards for generated and linked stories, external text references, local IDs, locked frames and atomic colour edits.

Fixes #23.

Co-authored-by: Sean Hammond <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 21:41:46 -06:00
moppeeerandClaude Opus 5.5 8f71219533 feat(tools): Page tool pins and locks objects on object-based pages, on the canvas
Chris Cicchino's "Adobe InDesign – Page Tool and Liquid Layout" (6:32–
9:58) clicks an object with the Page tool on an object-based page and
gets InDesign's on-canvas liquid controls: a pin outside each edge
("Object is pinned relative to the page edge. Click to release.") and a
padlock on the width and height lines ("The object's width is locked.
Click to let the object change width as the page changes width."). The
pins and resize settings existed (liquid.object, the Liquid Layout
panel) but the canvas showed none of it.

- tools: on an object-based page a Page tool click selects the object
  with its page (layout.selectPage takes `ids`); its pins (14 px outside
  each edge's middle) and width/height locks (beside the centre) toggle
  liquid.object on click, show InDesign's tooltips on hover and a hand
  cursor.
- canvas: LiquidPins (orange dashed width/height lines with padlocks,
  open when the object follows the page; hollow pins, or a line to the
  page edge when pinned) and Tip overlays; tooltip translations.

Builds on the Page tool PR (#862).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-14 01:21:51 +02:00
moppeeerandClaude Opus 5.5 8864307d7c docs: the Page tool's Control panel in the parity notes
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-14 00:52:06 +02:00
moppeeerandClaude Opus 5.5 cc13e80c9d feat(tools): Page tool selects pages; handles preview the liquid rule, Alt-drag resizes
Chris Cicchino's "Adobe InDesign – Page Tool and Liquid Layout" (0:42–
2:06) selects a page with the Page tool, gets its bounding box with
handles, drags a handle (the page springs back: a liquid-rule preview),
holds Option to really resize it, Shift for proportions, and reads the
size in a tooltip by the cursor. DesignCraft's Page tool only opened a
generic Page Size dialog on click.

- tools: the Page tool selects the page under a click (none on the
  pasteboard); the selected page shows its outline, eight handles and
  its liquid page rule ("Scale", "Object-Based"…) above it. Dragging a
  handle previews layout.pageSize (the liquid rule re-flows the
  objects) and springs back on release; Alt resizes, Shift keeps the
  proportions; a W/H readout follows the pointer; resize cursors on the
  handles. Double-click a page for the Page Size dialog.
- doc: Selection.page (the Page tool's page); engine: layout.selectPage
  (no undo step).
- layout.pageSize `anchor` (0-8): the page grows away from the
  reference point and its objects and guides keep their place relative
  to it (a handle drag anchors the opposite edge); liquid rules work
  from that.
- canvas: PageHandles and Tag overlays; translations for the tags and
  the Resize Page undo label.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-14 00:29:55 +02:00
Andreas Haraminac 5024ed8870 #732: bound control-channel click and drag event queues 2026-10-13 21:55:44 +00:00
LabDennis 0fd627aa44 perf(assets): index duplicate candidates by content (#727) 2026-10-13 23:12:09 +02:00
aiongg 129adfa429 Layout: Table of Contents dialog with entry styles, page number position and IDML TOC styles (#755) 2026-10-13 20:41:56 +00:00
moppeeerandClaude Opus 5.5 dc712baeca fix(color): gradients between process colours blend as inks, as InDesign shows them
LYH Studio episode 6 builds every gradient from C=0 M=100 Y=0 K=0 to
C=100 M=0 Y=0 K=0. InDesign blends a gradient's process stops as inks:
halfway is C 50 M 50, a light lilac. DesignCraft converted both ends to
RGB and blended there, so the middle came out a darker violet (117, 88,
189 instead of 135, 119, 181), and every Episode 6 gradient looked
different. A midpoint between CMYK stops also became an RGB colour, so
the PDF shading turned RGB with a conversion warning.

- color: `Color::lerp` blends CMYK with CMYK (or grey), and grey with
  grey, in ink space; anything with RGB still blends in RGB.
- `Gradient::display_stops`: the expanded stops plus samples through
  each span that isn't RGB at both ends, for renderers that interpolate
  in RGB; the screen renderer uses it.
- pdf: a midpoint's expanded stop now keeps the stops' space; the
  colour-space test expects no conversion for CMYK or grey midpoints.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 20:38:38 +02:00
Brandon Thomas 89e9abbc8d Merge branch 'pr/662' into batch1
# Conflicts:
#	crates/engine/src/cmd/object.rs
2026-10-13 02:23:56 -04:00
Brandon Thomas ea8dc959d1 Merge branch 'pr/573' into batch1 2026-10-13 02:23:12 -04:00
Brandon Thomas 6e551af3e7 Merge branch 'pr/663' into batch1 2026-10-13 02:23:11 -04:00
Brandon Thomas 878169130e Merge branch 'pr/600' into batch1 2026-10-13 02:21:53 -04:00
Marco Arnulfo 9e15d5a17e fix(cli): accept a UTF-8 BOM in scripts and document the syntax in script --help (fixes #654) 2026-10-13 00:41:46 +02:00
Marco Arnulfo 3d59dd5d97 fix(cmd): reject unknown spread values instead of falling back to page 1 (part of #651) 2026-10-13 00:38:54 +02:00
skylar taylor-barrick 64f0ca8fa6 fix(macos): make Dock Quit cancelable
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.
2026-10-12 14:52:12 -06:00
skylar taylor-barrick c3859c828b fix(recovery): preserve documents on orderly app exit
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.
2026-10-12 12:18:32 -06:00
skylar taylor-barrick 8e151a2fd4 fix(recovery): retain recovered checkpoints until save or close
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.
2026-10-12 12:15:46 -06:00
skylar taylor-barrick 9509b2bcea fix(book): stage chapter updates before saving
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.
2026-10-12 12:12:01 -06:00
skylar taylor-barrick e198eb5d1d fix(export): replace desktop and CLI outputs atomically
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.
2026-10-12 12:04:39 -06:00
skylar taylor-barrick b9048a5b08 fix(save): preserve live state when persistence fails
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.
2026-10-12 11:53:46 -06:00
moppeeerandClaude Opus 5.5 7ee66df165 feat(ui): Step and Repeat dialog with Create as a grid and Preview
Edit > Step and Repeat opened the generic command form (Count 1..1000, Dx, Dy, Rows, Columns, Ids). It now has InDesign's dialog: Repeat (Count, or Rows and Columns when Create as a grid is on), Offset (Vertical, Horizontal, in the document's ruler units or any unit typed) and Preview, which shows the copies on the page while the dialog is open. Cancel, Esc and ui.dialog.cancel take the preview away; OK makes the copies once, as one undo step. A value that isn't a number keeps the dialog open and says so.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 18:29:02 +02:00
d020b4e85d fix(ui): preserve documents when quitting is cancelled
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 <[email protected]>
Co-authored-by: skylar taylor-barrick <[email protected]>
2026-10-12 09:31:24 -06:00
Noah Scholzandskylar taylor-barrick 328b4d5a52 fix(recovery): isolate recovery data between app instances
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 <[email protected]>
Co-authored-by: skylar taylor-barrick <[email protected]>
2026-10-12 09:26:34 -06:00
5cdcac4ace fix(save): replace files atomically
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 <[email protected]>
Co-authored-by: skylar taylor-barrick <[email protected]>
2026-10-12 09:19:36 -06:00
aiongg b21111f232 Toolbox: Shift+X, D, X and / shortcuts for the Fill/Stroke proxy
The proxy's tooltips named keys that did nothing. color.defaultFillStroke
(D), color.swapFillStroke (Shift+X), color.toggleFillStroke (X) and
color.applyNone (/) are UI commands; the proxy's buttons run the same
commands. Swap keeps the fill and stroke tints.

Which of fill and stroke is in front lives in UiState, shared by the
Tools panel proxy, the Color panel and the commands. The single-key
shortcuts stay out of text being typed, like the tool shortcuts.
2026-10-12 14:21:36 +00:00
KnottyDyes 80c2904681 fix(mcp): prevent request replay after lost replies
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
2026-10-11 21:10:01 -06:00
skylar taylor-barrick 65ef027f9f Merge pull request #452 from storytold/codex/craft-print
M6: Adopt craft-print and support Windows PDF printing
2026-10-11 18:12:43 -06:00
japbcoelhoandClaude Opus 5.5 2b46ca664c Hyphenation: Portuguese text is hyphenated with hyph-utf8's Portuguese patterns (#512)
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 <[email protected]>
2026-10-11 17:39:53 -06:00
skylar taylor-barrick 3ec5cef6a2 M6: Adopt merged craft-print with scaling and queue duplex defaults 2026-10-11 22:14:24 +02:00
skylar taylor-barrick 9f7da3f6ab M6: Adopt craft-print for CUPS and Windows PDF printing 2026-10-11 07:29:54 +02:00
skylar taylor-barrick a77bf8bff5 UI.9: reconcile upstream before shared UI landing 2026-10-10 18:00:07 -06:00
Brandon ThomasandClaude Opus 5.5 a9124a0517 Release prep: version 0.6.0; Linux riscv64 tar.gz in releases (#398)
- 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 <[email protected]>
2026-10-10 19:33:30 -04:00
skylar taylor-barrick c62866443c UI.9: integrate shared panel docking and preserve workspace behavior 2026-10-10 14:42:40 -06:00
Brandon ThomasandClaude Opus 5.5 a127c6d5c3 Progress docs: target-app parity, gaps, alpha gate, readiness by audience (#355)
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 <[email protected]>
2026-10-10 14:09:17 -04:00
d0d4812ada Set a text selection as warichu inside the parent line (#280)
* Set warichu as smaller lines inside the parent line.

Type › Warichu stacks the selected run after the line is broken, closes up the rest of the line, and round-trips the IDML warichu properties. The line break itself still sees the full-size run.

* Keep clicks, the caret, and Up/Down on each warichu row.

The glyphs were already stacked inside the parent line, but hit testing, the caret, and vertical movement still used that parent line. Break minimums, row widths, spacing, and tab leaders now follow the small lines, and underlines sit on the small baseline.

---------

Co-authored-by: Brandon Thomas <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-10 03:47:14 -04:00
617e487dff Styles: Character Style Options dialog (#144)
* Styles: editing a character style renames it everywhere it is used, changes its Based On and unsets attributes; [None] can't be edited

* UI: Character Style Options edits a character style's name, Based On and character formats, opened by double-clicking the style, Edit in its menu, or New Character Style…

---------

Co-authored-by: Brandon Thomas <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-10 02:14:30 -04:00
SawizzleandClaude Opus 5.5 a42fa20677 docs: register the MCP server from an installed release (#269)
* docs: register the MCP server from an installed release

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs: drop the third-party link; the Windows path is the default install folder

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-10 01:51:07 -04:00