10973 Commits
Author SHA1 Message Date
FredApps 0faabbfe85 Merge main into release for VectorCraft v0.24.0 v0.24.0 2026-11-11 19:05:13 +01:00
FredApps a72412eb8f Release: VectorCraft v0.24.0 (#6599) 2026-11-11 19:04:49 +01:00
Dylan M. Taylor 9e28b56354 Merge pull request #6633 from storytold/chore/craft-update-6e03f65
Updates: take craft-update from craft-libs main at 6e03f65bf
2026-11-11 12:53:15 -05:00
Dylan M. Taylor 3ef3afc51d Updates: take craft-update from craft-libs main at 6e03f65bf 2026-11-11 12:53:09 -05:00
BFlat ad70adf96e Merge pull request #6624 from Messhias/feat/g5-symbol-lib-skill-icons
G5: built-in Skill Icons symbol library
2026-11-12 00:50:41 +07:00
BFlat adeacac9aa Merge pull request #6623 from dotCooCoo/fix/swatch-name-negative-zero
Swatches: default names read a -0 component as 0
2026-11-12 00:44:12 +07:00
Dylan M. Taylor a07e05a207 ci: run Harden-Runner on every job (#6629)
Adds step-security/harden-runner (audit, pinned to v2.22.4 like
craft-common-actions) as the first step of each job that did not have it,
so every workflow in the org's public repos reports its egress to
StepSecurity. Audit, not block: block-mode allow lists come from each
job's observed traffic.
2026-11-11 12:42:58 -05:00
BFlat 25433ede65 Merge pull request #6619 from jmverges/fix/6610-aligned-lines-trailing-tracking
Type: aligned lines leave the tracking after their last character out
2026-11-12 00:39:30 +07:00
BFlat 61acb79de3 Merge pull request #6620 from storytold/fix/sec-links-shared-reads
Links: groups of one file share one decoded image per operation
2026-11-12 00:21:59 +07:00
BFlat 428a4d875d Merge pull request #6614 from dotCooCoo/fix/simplify-keeps-small-closed-subpaths
Simplify: a closed subpath whose refit is one curve stays in the path
2026-11-12 00:17:42 +07:00
BFlat 5af4deeaf5 Merge pull request #6616 from dotCooCoo/chore/craft-update-6e03f65
Updates: take craft-update from craft-libs main at 6e03f65bf
2026-11-12 00:13:22 +07:00
Fabio William Conceição f07c2f7e9c G5: built-in Skill Icons symbol library
Five symbol libraries; MCP docs list Skill Icons with the other generated symbol libraries.
2026-11-11 17:08:39 +00:00
BFlat 3deafc24eb Merge pull request #6612 from dotCooCoo/feat/js-e4x-xml
JavaScript: run E4X XML literals and the XML, XMLList, Namespace and QName objects behind an option
2026-11-12 00:01:49 +07:00
BFlat 45246e9c9d Merge pull request #6551 from Messhias/fix/mcp-gaps-command-list
MCP: list UI_COMMANDS in command_list and close catalogue gaps (#6460)
2026-11-11 23:51:59 +07:00
dotCooCoo 4da8e7e8c7 Swatches: default names read a -0 component as 0
`color_name` clamps each component before rounding, but `clamp` keeps a
-0.0, so a color with a -0.0 component was named "R=-0 G=128 B=-0" (and
"K=-0", "Gray K=-0" in CMYK and Gray). Adding 0.0 after rounding turns
it into 0, as the Lab branch already does.
2026-11-11 08:50:42 -08:00
BFlat 29207e507d Merge pull request #6611 from dotCooCoo/fix/plugins-folder-cleared-forgets-folder
Plug-ins: setting the plug-ins folder again after clearing it installs its plug-ins
2026-11-11 23:46:01 +07:00
Dylan M. Taylor ec9169591a Links: groups of one file share one decoded image per operation 2026-11-11 16:42:19 +00:00
jmverges 352b488b12 Merge remote-tracking branch 'upstream/main' into fix/aligned-lines-trailing-tracking
# Conflicts:
#	docs/file-format-parity.md
2026-11-11 16:38:59 +00:00
dotCooCoo 96d17d593c Updates: take craft-update from craft-libs main at 6e03f65bf 2026-11-11 08:33:30 -08:00
BFlat b6b23703b0 Merge pull request #6608 from dotCooCoo/fix/inspect-pending-read-root
MCP: ui.inspect leaves out paths outside the read roots
2026-11-11 23:25:21 +07:00
BFlat caaf261e9f Merge pull request #6605 from dotCooCoo/fix/gradient-stop-symbol-part
Gradients: picking a part of a symbol instance leaves no gradient stop selected
2026-11-11 23:25:06 +07:00
dotCooCoo 9ce1558c5e Simplify: a closed subpath whose refit is one curve stays in the path
A closed subpath that refits to a single curve has one anchor, which is
not a subpath, so Simplify dropped it: a small circle inside a compound
path was lost and the result ended hundreds of points from the original,
and a small closed path on its own came out empty. Such a subpath is now
refitted in two parts, cut at the point farthest from its start, or in
three when two parts would still enclose no area (two lines that retrace
each other with Convert to Straight Lines). A closed subpath of a single
segment stays as it is.
2026-11-11 08:21:15 -08:00
BFlat de70970017 Merge pull request #6607 from dotCooCoo/fix/pasted-svg-filter-capital-fallback
Effects: a pasted SVG filter takes a free capital letter or punctuation character when no lowercase name is free
2026-11-11 23:20:31 +07:00
BFlat 2ba90707b0 Merge pull request #6602 from dotCooCoo/fix/3d-group-member-blend-mode
3D effects: Extrude & Bevel, Inflate and Rotate on a group keep each member's blending mode
2026-11-11 23:20:20 +07:00
BFlat d4e541b0bf Merge pull request #6571 from jmverges/fix/6570-envelope-edit-contents-moved
.ai import: an envelope in Edit Contents opens on its drawn art when its mesh lies away by a move
2026-11-11 23:15:39 +07:00
dotCooCoo de95640d93 JavaScript: XML namespace declarations and QName strings count against the heap limit
addNamespace and setNamespace now add a declaration's bytes to the heap total when the element
gains a new prefix, and QName.prototype.toString adds the bytes of the string it returns. Before,
both only checked for room, so a loop of distinct prefixes could grow an element past the heap
limit until a collection recounted it.
2026-11-11 08:09:22 -08:00
Fabio William Conceição 6e540361af xtask: collapse if in ui-commands reexport parse 2026-11-11 16:08:34 +00:00
jmvergesandClaude Opus 5.5 9f80b4daae Type: aligned lines leave the tracking after their last character out (#6610)
A centred or right-aligned line of tracked type was measured with the
tracking after its last character, so it sat half that tracking
(centred) or the whole tracking (right-aligned) left of where the page
of users' .ai files draws it. That page aligns a line as wide as its
characters without that tracking.

Shaping now records the tracking each glyph's advance holds
(SGlyph::tracking), and a line that isn't justified leaves its last
character's out of the width it is aligned by. The last character is
the last one the line draws before a paragraph's end, a forced line
break or the spaces a wrap leaves; spaces or a tab typed before a
paragraph's end or a forced line break keep the letter's tracking, as
the page does. Forced line breaks and wraps aren't in the files: they
follow the rule so that turning a wrap into a paragraph or a forced line
break keeps the line in place. Hyphenated lines, lines whose last
character hangs, vertical and right-to-left lines and type on a path
keep it. The tracking stays in the glyph's advance, so the caret,
selections, line breaking and Fit Headline are unchanged.
LineInfo::trailing gives the amount. Right-aligned area type sets the
text after its last tab the same way.

What aligns by line widths follows. Convert To Area Type makes its
frame end where the lines are aligned, with room for the tracking, so
tracked type converted either way stays in place. Affinity import lines
up differently aligned paragraphs of artistic text by the aligned
widths. SVG import moves a centred or right-aligned letter-spaced line
back by its share of the last letter spacing, so it stays where a reader
draws it and SVG export, which anchors lines at the end of their
advances, reads back unchanged.

Centred and right-aligned tracked type lays out differently than before
in every document.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 16:07:40 +00:00
dotCooCoo 8eb3788eba Plug-ins: setting the plug-ins folder again after clearing it installs its plug-ins
Clearing Preferences > Plug-ins & Scratch Disks > Additional Plug-ins Folder
left the folder recorded as the one last loaded. Setting the same folder
again then matched that record, and nothing in it was installed, so a
plug-in removed in the meantime stayed removed. Clearing the preference now
forgets the folder when it is the one last loaded.
2026-11-11 08:07:27 -08:00
dotCooCoo bc6c20d0c9 JavaScript: a limit during an XML path assignment or list copy keeps the tree whole
- A list copy holds each new copy as a root while the list is charged
  for it, so a collection at that point no longer frees the copy. Before,
  `x.setChildren(<c/> + <d/>)` near the heap limit could leave one child
  twice or end with an internal error.
- An assignment to a path such as `x.a.b = v` or `x.a.b[0] = v` removes
  the elements it added for the path when a later step stops at a limit
  or throws.
- Comparing XML values counts the attribute tables and the work stack
  against the heap limit.
2026-11-11 08:00:42 -08:00
Fabio William Conceição 3f26409d4a MCP: keep UI_COMMANDS mirror in sync via xtask
Add `cargo xtask ui-commands` (and `--check` in ci) so the headless
catalogue cannot drift from desktop UI_COMMANDS, and fix params-doc
escaping that printed literal backslashes.
2026-11-11 15:56:33 +00:00
dotCooCoo c4d323eb28 Merge main into feat/js-e4x-xml
# Conflicts:
#	crates/js/src/interp.rs
2026-11-11 07:48:21 -08:00
Fabio William Conceição 13098fa9f4 MCP: list UI_COMMANDS in command_list and close catalogue gaps (#6460)
Headless command_list exposes the desktop UI catalogue with ui: true, docs
clarify effect vs command ids, and prompts cover spelling, variables and path tools.
2026-11-11 15:48:05 +00:00
dotCooCoo 774f7568da MCP: ui.inspect hides every loaded library path outside the read roots
Under --automation-read-root, ui.inspect and ui.docking hid a library's
path only when its panel was in ui.library_panels. A library used as the
Color Guide's limit, or named by a closed panel's place in
ui.docking_hidden, a workspace layout or the docking layout, still showed
its full loaded/<path> id.

The ids to hide now come from every place the UI state refers to a
library: the library panels, the Color Guide's limit, and the panel ids in
the docking layout, closed panels, icon and collapsed lists and workspace
layouts. Typed text such as a command palette query is not read as an id.

Two hidden libraries with the same file name no longer share one id, which
dropped one of them from an object keyed by panel id. They show as
loaded/<file name>, loaded/<file name> (2) and so on, in the order of
their full ids, and a library has the same id in ui.inspect and
ui.docking.

Docs: docs/mcp.md.
2026-11-11 07:40:36 -08:00
dotCooCoo b44cbdb048 Gradients: picking a part of a symbol instance leaves no gradient stop selected
A stop selected on a whole dynamic symbol instance's gradient stayed
selected after Direct Selection picked an object of that instance's art,
because the instance stayed the first selected object. The Gradient panel
kept the stop highlighted and the Gradient tool took Delete and the arrow
keys for it, while every gradient edit is refused for a picked object.

The stop's owner now records whether a part is picked, so the stop is not
selected while one is, and is selected again when the whole instance is.
2026-11-11 07:39:47 -08:00
dotCooCoo 478d86cb5f 3D effects: test that only the blended member's faces are drawn in its mode
The blending-mode test for a member of a 3D group now checks that every face of the multiplied member, and no face of the other member, is drawn inside the Multiply group, telling the members apart by height. Before, it only checked that some faces were multiplied and some were not, so it also passed when the mode went to the wrong member.
2026-11-11 07:38:55 -08:00
dotCooCoo ac8e39fa2e Effects: a pasted SVG filter also takes a free punctuation character when no letter or digit is free
A filter's id can be any character, so when every letter and digit is in
use a pasted filter at the size limit with a one-letter name now tries the
other printable ASCII characters (`!` to `~`) before the paste is refused.
2026-11-11 07:26:02 -08:00
dotCooCoo f60da17d39 Effects: a pasted SVG filter also takes a free capital letter when no lowercase name is free
Filter names are case-sensitive, but a pasted filter at the size limit with a
one-letter name only tried the letters a to z and the digits 0 to 9 as a new
name. A paste was refused while every capital letter was still free. It now
also tries A to Z.
2026-11-11 07:26:02 -08:00
jmverges 4556f7718e Merge remote-tracking branch 'upstream/main' into fix/envelope-edit-contents
# Conflicts:
#	docs/file-format-parity.md
2026-11-11 15:19:51 +00:00
dotCooCoo 6ae93b1222 3D effects: Extrude & Bevel, Inflate and Rotate on a group keep each member's blending mode
On a group, these effects drew every member's solids in Normal mode: only
an opacity mask on a member or on a group inside the 3D group was applied
to the solids it holds. A member's blending mode, and that of a group
inside the 3D group, now apply the same way, to the solids of the members
it holds together. Group Revolve already did this.
2026-11-11 07:12:15 -08:00
BFlat 9fc43f2a35 Merge pull request #6598 from dotCooCoo/fix/pasted-svg-filter-brush-names
Effects: a pasted SVG filter avoids brush effect names and is refused with no free name
2026-11-11 22:10:15 +07:00
BFlat fe537ab13b Merge pull request #6585 from Hassan1305/fix-6437-outline-select-behind
Outline view: a click on a path's outline selects it through an image or a gradient mesh in front (#6437)
2026-11-11 22:04:00 +07:00
BFlat 855e11e8dd Merge pull request #6563 from dotCooCoo/feat/script-dollar-object
Scripts: $ has the Dollar object's other members, with localize and toSource
2026-11-11 21:59:38 +07:00
dotCooCoo 5d7e2fa8e1 MCP: ui.inspect leaves out paths outside the read roots
Under --automation-read-root, ui.inspect returned the paths of documents
still opening, the recent files, library panels' files and the folder
preferences even when they lay outside the read roots. The reply now
leaves them out, checked with file_access::check_read as ui.menu.list
checks recent files and listed scripts:

- opening and ui.recent_files keep only the readable paths, in order.
- A library panel keeps its row without its path; a library loaded from
  outside the roots shows as loaded/<file name> in its id and panel id,
  in ui.inspect and ui.docking.
- The folder preferences in ui.engine_prefs and in an open Preferences
  dialog are left out; an empty folder and the scratch disk choices
  Startup and None stay.

The app's own state is not changed. Without roots the replies are as
before.

Docs: docs/mcp.md, docs/control-protocol.md, docs/target-app-parity.md.
2026-11-11 06:13:33 -08:00
dotCooCoo e0e361a834 Effects: a pasted SVG filter avoids brush effect names and is refused with no free name
Follows #6592. Paste now also skips the names that effects in the
document's brush art use when it picks a free name for a pasted SVG
filter. When no free name keeps the filter within the 64 KB limit (a
one-letter name at the limit with every free letter and digit taken),
the paste is refused instead of keeping the name of the document's
filter. Clipboard::import_into and import_text_styles return a Result,
and their callers pass the error on before the document changes.
2026-11-11 06:08:58 -08:00
HassanKhan fd43a1901d Merge remote-tracking branch 'upstream/main' into fix-6437-outline-select-behind
# Conflicts:
#	docs/ui-parity.md
2026-11-11 19:01:30 +05:00
dotCooCoo 48e342f03b Merge main into feat/script-dollar-object 2026-11-11 05:55:39 -08:00
BFlat 015805322a Merge pull request #6594 from dotCooCoo/fix/menu-list-recent-test-disabled-rows
Tests: a recent file outside the read root is not listed even as a disabled row
2026-11-11 20:51:37 +07:00
BFlat bebe0a402a Merge pull request #6568 from Hassan1305/fix-6506-middle-click-close-tab
Document tabs: a middle-click closes the tab, as the × does (#6506)
2026-11-11 20:51:28 +07:00
BFlat 8c05cbbe72 Merge pull request #4338 from SofiaAFigueredo/fix/4312-move-edges-snap-to-ruler-guides
Fix #4312: a Shift move lands the selection's edges and centre on ruler guides
2026-11-11 20:45:06 +07:00