Commit Graph
1968 Commits
Author SHA1 Message Date
Marco Arnulfo 1f2a8104bf M4: vector edit transform box around points of several layers
With points selected in more than one edited layer the transform box now
wraps them all, in the page's axes since the layers can be turned
differently. Its corners and edges scale them, outside a corner rotates
them and inside drags them; each layer's points are mapped in its own
coordinates and the whole drag is one undo step. A click inside clears
every layer's points.
2026-10-22 23:37:49 +02:00
NetterSilverandClaude Haiku 5.5 c857f8d0f3 Cap the issue list returned by Document::validate
Fixes #1058

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 23:30:11 +02:00
NetterSilverandClaude Opus 5.5 8aa456b198 Stop stale next_id from making pastes overwrite existing nodes
Fixes #1064

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 23:23:47 +02:00
NetterSilverandClaude Haiku 5.5 5a53425f51 Make is_ancestor fail closed on deep or looping parent chains
Fixes #1066

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 23:14:57 +02:00
NetterSilverandClaude Haiku 5.5 d5de4be1ab Enforce an absolute pre-hello deadline against ping slowloris
Fixes #1068

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 23:08:25 +02:00
saturngod 6cdc36f6c3 Fix stroke-only boolean operand outlines 2026-10-22 16:07:38 -05:00
zuujiscom 03354ec7d3 FreeBSD package.sh: accept only the two supported FreeBSD targets
Review follow-up. CARGO_BUILD_TARGET must be aarch64-unknown-freebsd or x86_64-unknown-freebsd,
the two the release builds; anything else, including made-up triples such as
aarch64-foo-unknown-freebsd, stops with exit 2.

Part of storytold/craft-common-actions#39.
2026-10-22 16:06:19 -05:00
NetterSilverandClaude Haiku 5.5 c80d1e7ae7 Shut kicked and removed connections when their close can't be queued
Fixes #1070

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 23:04:22 +02:00
NetterSilverandClaude Haiku 5.5 b8741162cd Refuse text.loadFont path for plugins
Fixes #1071

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 22:57:58 +02:00
NetterSilverandClaude Opus 5.5 d7d6bc8429 Enforce per-address storage caps per IPv6 /64, /56 and /48
Fixes #1073

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 22:49:58 +02:00
Gert Pellin d77e002170 M8: one Save goes through every file needing Save as; Enter answers Save (#1170)
Review: after a Save as, closing called request_close, which asked the
question again while another file still had changes. It now carries on
with save_then_close. Save is the default answer: Enter picks it when no
button has the keyboard.
2026-10-22 22:35:42 +02:00
zuujiscom 30149d765d FreeBSD package.sh: never run a FreeBSD target's binary on another OS
Review follow-up. With CARGO_BUILD_TARGET set on a host that is not FreeBSD (say an x86_64 Mac
building x86_64-unknown-freebsd), the architectures match but the binary still cannot run, so
the --version run is skipped there and the file(1) check is used instead.

Part of storytold/craft-common-actions#39.
2026-10-22 15:31:37 -05:00
NetterSilverandClaude Opus 5.5 4f39406fcd Keep the hello size limit until a connection is admitted
Fixes #1087

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 22:30:07 +02:00
Gert Pellin 83dac86bc5 M8: the unsaved-changes question on close offers Save (#1170)
Closing a window with unsaved changes asked "Close the window and lose
them?" with only Close without saving and Cancel. It now asks
Don't Save / Cancel / Save, as PhotoCraft and VectorCraft do. Save saves
each file of the window with unsaved changes and closes; a file without
a path (or saved as .fig) gets Save as first, and closing goes on once
that saved it. A failed save or a cancelled Save as keeps the window
open with its changes. The two changed strings are updated in every
catalog.
2026-10-22 22:23:11 +02:00
NetterSilverandClaude Opus 5.5 eafa1a1d06 Never overwrite a file's log when it can't be read
Fixes #1090

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 22:20:49 +02:00
NetterSilverandClaude Haiku 5.5 51a4509c87 Refuse library versions that leave no newer one to publish
Fixes #1092

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 22:16:23 +02:00
Gert Pellin d9cb5cd216 M7: the save-from-field test answers Save as and checks both files (#1157) 2026-10-22 22:05:36 +02:00
zuujiscom 477b25e63f FreeBSD package.sh: accept only executables in the cross-build check
Review follow-up. The file(1) check for binaries that cannot run here now needs an executable
(file says "executable" or "pie executable") or an ELF with an interpreter, which is how an older
file(1) still shows a PIE it calls a shared object. FreeBSD libraries, object files and core files
for the target architecture are refused.

Part of storytold/craft-common-actions#39.
2026-10-22 14:49:35 -05:00
NetterSilverandClaude Haiku 5.5 b5e5c2100e Make SVG unique_id linear for repeated layer names
Fixes #1106

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 21:48:28 +02:00
Gert Pellin 8f0982b5bd M7: Cmd/Ctrl+S saves while a panel field has the keyboard (#1157)
With the keyboard in a Design panel field (X, W, a colour…), the
shortcut handler returned before looking at any key, so Cmd/Ctrl+S and
Shift+Cmd/Ctrl+S did nothing: no save, no message, the tab kept its
unsaved dot. Those two now work from a field: the field lets go of the
keyboard, which commits what was typed as clicking away does, and the
save runs the next frame.
2026-10-22 21:46:32 +02:00
Gert Pellin c7d2a5f019 M9: the symbol test also looks for the Noto Sans Symbols2 spelling (#1156) 2026-10-22 21:46:12 +02:00
Gert Pellin bb2e56a7ea M0.9: --help wins over an earlier bad option (#1155)
Review: `mcp --bogus --help` stopped at --bogus with exit 2. The parser
now keeps the first bad option and reports it only when no --help or -h
follows.
2026-10-22 21:45:29 +02:00
Gert Pellin eb07717783 M0.9: trim mixed edge spaces and dots, document the name limits (#1154)
Review: " . .name. . " kept inner dots at the edges; trim spaces and dots
in one pass. docs/cli.md and safe_file_name's comment give the 100 and
200 character limits.
2026-10-22 21:43:52 +02:00
Brandon ThomasandClaude Opus 5.5 80f916326f Release 0.10.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v0.10.0
2026-10-22 15:39:04 -04:00
NetterSilverandClaude Haiku 5.5 c6dba8c8f3 Reject non-finite coordinates in control-channel ui.input
Fixes #1112

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 21:34:58 +02:00
zuujiscom e366f61e8f FreeBSD package.sh: accept only FreeBSD targets, check cross-built binaries
Review follow-up. CARGO_BUILD_TARGET must now be a *-unknown-freebsd triple, so a Linux or macOS
target can no longer be packaged under a FreeBSD name, and it is read before uname -m, so an
unsupported host does not block a valid cross build. When the binaries are for another
architecture and cannot run --version, file(1) must report each as a FreeBSD ELF executable
for the target architecture.

Part of storytold/craft-common-actions#39.
2026-10-22 14:32:12 -05:00
Gert Pellin 5a3dddc46f M9: fall back to the Noto symbol and math fonts on Linux (#1156)
Signs such as U+2316 and U+2912 are in no text face. The fallback list
had the macOS and Windows symbol fonts (Apple Symbols, Segoe UI Symbol)
but nothing a Linux install has, so they drew as empty boxes there even
with Noto Sans Symbols 2 or Noto Sans Math installed. Adds Noto Sans
Symbols, Noto Sans Symbols 2 (and the Symbols2 spelling some packages
use) and Noto Sans Math after them.
2026-10-22 21:29:58 +02:00
Gert Pellin 40315a123d M0.9: --help and -h after a figcraft-cli subcommand print the usage (#1155)
`figcraft-cli mcp --help` failed with "unknown option --help" and
exit code 2; only a leading --help worked. The argument parser now
returns CliError::Help for --help or -h among a subcommand's options
(not as an option's value), and main prints the usage on stdout with
exit code 0. docs/cli.md says so.
2026-10-22 21:25:24 +02:00
Gert Pellin ca30791fd7 M0.9: figcraft-cli export names files as the app's export does (#1154)
export into a folder replaced every character outside letters, digits,
'-', '_', space and '.' with '_', so a frame called
"Homepage - desktop (live + verbeteringen)" became
"Homepage - desktop _live _ verbeteringen_.png". The app's
file.exportLayers keeps those names and only replaces what file systems
refuse. The CLI now uses the engine's safe_file_name, and docs/cli.md
says which characters are replaced.

Also adds my own entry to contributors/people.toml.
2026-10-22 21:22:20 +02:00
zuujiscom 27ea0d4bdc FreeBSD package.sh: package the aarch64 cross build
The release workflow now cross-compiles FreeBSD aarch64 inside the x86_64 VM
(storytold/craft-common-actions#50) and sets CARGO_BUILD_TARGET=aarch64-unknown-freebsd.
package.sh now reads the binaries from target/<triple>/release when CARGO_BUILD_TARGET
is set, names the archive after the target instead of uname -m, and skips the --version
run when the binary is for another architecture than the machine. x86_64 packages are
unchanged.

Part of storytold/craft-common-actions#39.
2026-10-22 14:14:09 -05:00
NetterSilverandClaude Haiku 5.5 67ae35b155 Match widget data check depth to serde_json's recursion limit
Fixes #1118

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 21:11:15 +02:00
NetterSilverandClaude Opus 5.5 7e114c3420 Never drop Sync events when the live inbox is full
Fixes #1119

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 21:03:10 +02:00
NetterSilverandClaude Haiku 5.5 57e0872943 Bound the library/plugins close drain with a deadline
Fixes #1120

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 20:56:58 +02:00
NetterSilverandClaude Haiku 5.5 8c46b733e6 Restrict a pre-existing data directory to 0700
Fixes #1127

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 20:43:04 +02:00
NetterSilverandClaude Haiku 5.5 82779ec0f2 Guard file generation increments against u64 overflow
Fixes #1128

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 20:39:39 +02:00
NetterSilverandClaude Haiku 5.5 21d666465f Remove all leftover temp files at server startup
Fixes #1129

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 20:34:42 +02:00
NetterSilverandClaude Haiku 5.5 b8a5f76471 Keep context menu open after a same-frame trackpad tap
Fixes #1139

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 20:29:04 +02:00
NetterSilverandClaude Opus 5.5 83b9f74665 Write a final Greek sigma in lower-case text layout
Found while testing crates/text/src/layout.rs:1070 (shape_segment calls TextCase::apply_after one char at a time; crates/doc/src/text.rs:124 apply_after)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 19:04:10 +02:00
AganzeFelicite be6a547ff4 M7: the Type settings test checks it stays open at 264 px every frame (#1029) 2026-10-22 18:01:15 +02:00
Yarila 2cd88c0f46 Merge branch 'main' into fix/interface-size-menu-focus 2026-10-22 20:05:21 +05:00
lileeei 2437a65d1b M1: fill/stroke props accept "none" and null (#1036)
node.create, node.set and the other prop appliers map fill/stroke
"none" (either case) and null to an empty fills/strokes list, as
fills: [] already did (undocumented), so an outline-only shape is one
call - agents write "none" for no paint. KEYS and docs/mcp.md
document it; the error names the accepted forms. fill_none_tests
covers create, set, undo, text and the error.
2026-10-22 23:04:57 +08:00
MortenHusted ad9116ff5c M5: the prototyping parity status line and history name the layout fix 2026-10-22 17:01:21 +02:00
MortenHusted 3d5f3e7946 M5: prototype actions lay out what they change like the canvas does
Change to rebuilt the instance from the new variant, and set variable
and set variable mode re-applied bindings, but the player never laid the
result out: no text sizing, no auto layout. A hugging button with a
longer label than its main showed the other variant at the main's width,
its label clipped, and a text bound to a variable kept its old size.

These actions now run the engine's normalize on the player's document
afterwards, the pass that follows every edit on the canvas: text resizes
to what it shows, instances follow and auto layout reflows.
2026-10-22 16:41:30 +02:00
F3R9 0f85c2294e M9: avoid read-only snapshot rewrites and duplicate buffers
Validated formatting, workspace Clippy, workspace tests excluding the two pre-existing localized startup assertion failures tracked in #1017, layers, assets, WASM and plugins. The startup tests are unchanged in this independent fix.
2026-10-22 17:40:52 +03:00
NetterSilverandClaude Opus 5.5 6d748536b6 Drop XML-forbidden control characters from live-text SVG export
Found while testing crates/svg/src/lib.rs:153 (esc, used for tspan text at :598, :608 and :613)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 13:01:37 +00:00
MortenHusted f1c206509f M3: files from before the modes override keep the modes set inside their instances
A file or library saved before "modes" was an override group has a mode
chosen on a layer inside an instance without its marker, so the next
rebuild or library import still put the main's mode back.

Copies follow their main layer's modes when the main changes them, so a
layer inside an instance on other modes chose them itself.
mark_layer_modes marks those when a file opens and when a published
library is read from a file or a server. Layers on their main's modes
and top-level instances stay unmarked.
2026-10-22 13:41:56 +02:00
MortenHusted 6394e96005 M3: a variable mode set on a layer inside an instance is an override
A variable mode chosen on a layer inside an instance (the icon inside a
Close button, recoloured through an icon colour collection) wasn't an
override group. A full rebuild of the instance starts each layer over
from its main and carries only override groups, so the mode fell back
to the main's. Library import always rebuilds, as do main edits such as
a new auto layout direction, so a modal's recoloured close icon came
into other files in its default colour.

"modes" is now an override group: setting a mode inside an instance
records it, rebuilds carry it, rebasing a nested instance finds it, the
component panel lists it, and resetting it brings back the main's mode.
A top-level instance's own modes stay its own and record no override,
like its resizing.
2026-10-22 13:41:56 +02:00
Dylan M. Taylor 9ec80bf2c2 Say the library computes month and day; time-of-day is plain arithmetic
Narrows the range-extension wording: the date library computes the
calendar fields, and splitting seconds into hours, minutes and seconds
is ordinary arithmetic, which is what the code does.
2026-10-22 07:12:29 -04:00
Dylan M. Taylor a0e937918c Name the 400-year range extension as the one exception to the time rule
The rule said never to hand-roll calendar math, but the range fix
(shifting by whole 400-year Gregorian cycles so dates past chrono's year
range keep their old output) is cycle arithmetic, so the rule and the code
disagreed. The rule now names that exception: the library still computes
month, day and time, and only whole cycles are carried in the year.
2026-10-22 07:12:29 -04:00
Dylan M. Taylor e3169e5a61 collab/ui-egui: keep old UTC output past chrono's year range
`utc_date` (collab) and `date` (ui-egui) took `u64` seconds, which the old
hand-rolled civil-from-days code converted for the whole `u64` range. The
chrono rewrite used `from_timestamp(..).unwrap_or_default()`, so any instant
past chrono's own year limit (262143) silently became the epoch — changing
existing output. `u64::MAX` seconds, for example, used to read
`584554051223-11-09 07:00 UTC` / `Nov 9, 584554051223`, not 1970.

Fix: add a `utc_parts(days, sod, nanos)` helper per crate that moves the
instant into chrono's range by whole 400-year Gregorian cycles (146_097 days),
lets chrono do the month/day/time, and restores the real year afterwards.
chrono stays the only calendar logic; the cycle count just shifts the year, and
every `u64` day count fits in `i64` so the conversion is always exact (no epoch
fallback). Split seconds with `u64` arithmetic first to avoid the `i64` seconds
overflow near `u64::MAX`, matching the old code.

Tests now pin the old output instead of the epoch:
- collab utc_date(u64::MAX) == "584554051223-11-09 07:00 UTC"
  (and utc_date(253_402_300_800) == "10000-01-01 00:00 UTC", already pinned)
- ui-egui date(253_402_300_800) == "Jan 1, 10000"
  date(u64::MAX) == "Nov 9, 584554051223"
2026-10-22 07:12:29 -04:00