Commit Graph
3779 Commits
Author SHA1 Message Date
skylar taylor-barrick 65ff3a00c0 Merge pull request #4172 from songzhihui/fix/windows-cjk-viewer
M2: continue CJK viewer fallback for Windows GBK PDFs
2026-10-30 18:45:08 -06:00
Dylan M. Taylor ec33924e80 fix(flatpak): allow reading launcher version pins (#5490)
* fix(flatpak): allow reading launcher version pins

* fix(flatpak): allow reading launcher version pins
2026-10-30 20:12:04 -04:00
songzhihui a57095c872 M2: assert exact GBK glyph rasters for installed Chinese families 2026-10-31 01:39:00 +08:00
songzhihui 9447cdc810 M2: merge main and resolve CJK viewer integration conflicts 2026-10-31 01:14:02 +08:00
skylar taylor-barrick fa5f9f8c3b Merge pull request #5426 from FredApps/chore/parity-integration-20261030
Integrate 27 reviewed PDF editing, forms and optimizer PRs
2026-10-30 09:24:25 -06:00
FredApps 6772772440 test: accept preserved CCITT filter arrays in lossless regression 2026-10-30 15:52:18 +01:00
FredApps 7fe33d1cbd test: verify conservative review fixes across rendering and automation 2026-10-30 15:32:44 +01:00
FredApps 4791cacd2c test: qualify conservative tone retention and format review regressions 2026-10-30 14:55:44 +01:00
FredApps d7f3e67141 fix: bound backdrop edits and withhold unsafe integration behavior 2026-10-30 14:45:50 +01:00
FredApps 673178b70c fix(edit): require intact streams when identifying page backdrops 2026-10-30 13:21:04 +01:00
FredApps 25f3d12960 style: format checked soft-wrap budget assignment 2026-10-30 12:54:56 +01:00
FredApps ee71348bc8 fix: bound soft-wrap metadata and preserve unknown backdrop content 2026-10-30 12:47:37 +01:00
FredApps 6d7f739e3c test: enforce page press routing and record integration regression evidence 2026-10-30 12:38:09 +01:00
FredApps bdf56209ce style: format combined paragraph regression 2026-10-30 11:08:55 +01:00
FredApps 7d3d4830e5 Integrate remaining six PdfCraft parity PRs with conflict resolutions
Includes #4325 #1952 #4180 #2529 #4320 #4805, preserving their original histories.
Keep paragraph alignment and hard/soft wrap metadata together; retain CCITT/downsampling/RGB ownership guards with bounded JBIG2 export and exact-copy symbol encoding.
Combined interaction regressions added. Validation pending.
2026-10-30 11:02:07 +01:00
FredApps a07f94f2f7 test: supply Fill & Sign colour in combined window-title fixture 2026-10-30 10:46:11 +01:00
FredApps b21af3b969 Integrate 21 clean-merging PdfCraft parity PRs
Preserve each original PR head and its authorship as a merge parent.
Includes #4304 #4335 #4384 #4404 #4179 #5300 #4719 #4541 #2815 #4620 #3789 #3779 #2960 #5208 #4596 #3636 #4494 #4013 #5134 #2133 #2635.
Conflicting candidates skipped. Combined CI pending; see docs/integration-20261030.md.
2026-10-30 10:35:42 +01:00
FredApps 4b319bb383 Keep typed font sizes accessible and within the current panel layout
Use a named compact preset arrow beside the field, retain the row alignment/width assertions for the editable control, and open the current colour flyout in the saved-text regression. No accessibility or layout checks are disabled.
2026-10-30 09:29:42 +01:00
FredApps e19f964690 Handle the current fallible FDF export API in the round-trip regression 2026-10-30 09:10:25 +01:00
FredApps 7227eb68ab Name the Pages sidebar keyboard group and record its accessible snapshot 2026-10-30 09:10:05 +01:00
FredApps ee82cf1a72 Remove extra blank lines after relocating font-size controls 2026-10-30 08:58:13 +01:00
FredApps b07a012cd7 Reconcile button export values with current form authoring modules
Preserve caption editing and current form/Prepare module boundaries. Carry export-only appearance preservation, validation and data round-trip tests to their current paths, and retain current attribution metadata. Hosted CI must validate this refreshed head.
2026-10-30 08:56:21 +01:00
FredApps ea66a642fe Reconcile Pages sidebar selection with current keyboard and panel modules
Preserve main's continuous text selection, page tools and module split. Carry only this branch's sidebar-focus feature and regression onto main, without resurrecting old common files from criss-cross merge bases. Hosted CI remains required.
2026-10-30 08:52:06 +01:00
FredApps 6b38a5ab47 Reconcile typed font sizes and Fill & Sign colours with current UI
Use the unified Format Text panel and current page-input context instead of restoring old monolithic UI code. Preserve main's pointer routing, editor accessibility and preferences; retain colour, save and input regressions. Hosted CI must validate this refreshed head.
2026-10-30 08:47:42 +01:00
Dylan M. Taylor 1d1cbc4ec9 UPD.1: honor app pretend versions in update checks (#5397) 2026-10-30 02:35:18 -04:00
Dylan M. Taylor 3517d05b47 Update prompt shows the app icon and accent color instead of a letter (#5388)
UPDATE_APP (native builds; craft-update is a native-only dependency) carries our 128 px icon and accent (#b70228, its red, from the icon (#5245)). The updater, the self-update
helper and craft-update's startup prompt all get them through crate::UPDATE_APP; the
prompt draws the icon, the accent and "by ArtCraft" (craft-update's default developer).

craft-update is pinned to storytold/craft-libs main at 1065653e7 (#434).
Clippy fixes for Rust 1.99 in untouched code (same logic):
- crates/edit/src/images.rs
- crates/forms/src/appearance.rs
2026-10-30 01:27:58 -04:00
Dylan M. Taylor f76dbb9e8c deps: bump tar, zip, roxmltree, rustls-webpki and symphonia to their latest versions (#5381)
- `zip`: 9.1.0 → 9.1.3

Requirement `roxmltree` 0.20 → 0.21: `ParsingOptions` gained `entity_resolver` (initializers take `..Default::default()`, i.e. none, as before) and is no longer `Copy` (two functions build it with a closure, the pattern merge.rs already used).
2026-10-29 22:21:27 -04:00
Dylan M. Taylor 834a4daf9c CI: workflows only call craft-common-actions at @main (#5378)
AGENTS.md (and CLAUDE.md where present) gets a CI workflows section: workflows only call
craft-common-actions at @main, with no other jobs; feature and fix PRs don't touch CI and
link or open a craft-common-actions issue (a PR only for a small fix that is safe for
every app and does not increase CI time); legacy jobs
aren't added to and move only as their own task, staying until a shared workflow runs them.

windows-arm64.yml moves from its SHA pin to @main. The pinned revision is on
craft-common-actions main and the workflow (and the actions it calls) is identical
there, so nothing changes in behaviour.
2026-10-29 22:10:15 -04:00
Grzegorz MartensandClaude Opus 5.5 2d0a7b2241 M11: black-and-white RGB used beyond the page content read stays RGB
Packing makes an RGB image grey for every use at once, but /DefaultGray and
/DefaultRGB were checked only where the walk reads: page content and forms.
An annotation's appearance, a pattern, a Type3 glyph or a soft mask's group
drawing the same image can have other default colour spaces, so its colours
could change there.

The walk now records, by object number, every reference in the resources it
reads (each /XObject entry, drawn or not, an /XObject dictionary under its
resources, resources under a page, page-tree node or form), reading the
resources of every page and of every node above one, each page and node a
root. An image the walk reached stays covered unless an object reachable
from the trailer refers to it, or to an object on its way from a page, other
than through those references, or it is held by one that isn't covered; an
eight-bit DeviceRGB image that isn't covered stays RGB. So resources, an
/XObject dictionary or a form a page shares with an appearance keep it RGB,
as does a reference with another generation, while LibreOffice's layout (one
resources object for a page, its /Pages node, and a form inside it that
names it again) still packs. The scan runs only when packing is on and there
is such an image.

The images drawn or listed where the defaults are in force are kept by
object number too, so one named with another generation there stays RGB.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 23:57:08 +01:00
Dylan M. Taylor 726ecf2625 packaging: Flatpak finds and prints to CUPS printers (#5346)
* packaging: Flatpak finds and prints to CUPS printers

The Print dialog listed no printers in the Flatpak: the runtime has libcups but not
lpstat/lp, the sandbox couldn't reach the CUPS socket, and driverless network printers
(lpstat -e) need Avahi. Bundle lpstat/lp/lpoptions from CUPS 2.4.20 (Apache-2.0,
statically linked, licence installed) and grant --socket=cups and
--system-talk-name=org.freedesktop.Avahi in both manifests.

* packaging: Flatpak reads the user's CUPS settings (~/.cups, read-only)

Review (CodeRabbit): without it the sandbox's lp/lpstat ignore the user's default
printer and saved options (lpoptions) and a print server named in their client.conf.

* packaging: Flatpak CUPS tools reach the host socket when client.conf names a custom path

Review: Flatpak mounts the host's CUPS socket at /var/run/cups/cups.sock whatever
path ~/.cups/client.conf or CUPS_SERVER names, so lp/lpstat/lpoptions now run through
a wrapper that points a socket path missing in the sandbox there. Server names
(remote servers) and sockets that exist are left alone. Tested in the sandbox:
CUPS_SERVER=/run/custom/cups.sock lists the host's printers through the wrapper and
none without it; a host name is passed through unchanged.

* packaging: redirect a custom CUPS socket only when it is the one Flatpak mounted

Review (CodeRabbit): Flatpak picks the socket it mounts at /var/run/cups/cups.sock
with stricter rules than CUPS (flatpak-run-cups.c: a socket CUPS_SERVER, else the
first line spelled exactly "ServerName /path" in ~/.cups/client.conf, else the
default), while CUPS reads the keyword in any case and takes the last ServerName. The
wrapper now redirects only when CUPS' socket is the one Flatpak chose, so a job can't
reach a different server; otherwise CUPS fails on the missing path.

* packaging: never redirect a CUPS_SERVER the sandbox was given

Review (CodeRabbit): Flatpak picks the socket it mounts from the host's CUPS_SERVER,
so one set by flatpak run --env or an override may not be what it mounted. The
wrapper now leaves any CUPS_SERVER alone and redirects only a client.conf socket that
matches Flatpak's choice; otherwise CUPS fails on the missing path instead of
reaching a different server.

* packaging: point CUPS at the mounted socket only when it is the one Flatpak chose, else fail

Review (CodeRabbit): with a custom socket listed first and the default last in
~/.cups/client.conf, Flatpak mounts the custom one at /var/run/cups/cups.sock while
CUPS picks the last line, finds that path, and talks to the custom server. The
wrapper now compares CUPS' socket with Flatpak's choice even when the path exists:
equal, CUPS is pointed at the mount; different, the tool fails with an error instead
of reaching another server.
2026-10-29 18:48:45 -04:00
Grzegorz MartensandClaude Opus 5.5 c7f39a4d9a M11: the parity table no longer lists JBIG2 symbol coding as missing
docs/target-app-parity.md's optimize row lists lossy JBIG2, refinement
coding and a symbol dictionary shared between images as missing, with a
status line and a revision row.

From reviews with the pdfcraft-review skill.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P6yUtvWGPsJpMLyh6pxSXG
2026-10-29 22:37:25 +01:00
Grzegorz MartensandClaude Opus 5.5 f3a547d717 M11: a test that Export ▸ Images reads symbol-coded JBIG2
The optimizer now writes JBIG2 images as a symbol dictionary and text
regions, and Export ▸ Images has to read them back. A page of three
repeated letters, symbol coded (smaller than the generic coding),
exports as its picture. The test is added to create.export-all-images'
parity evidence. Asked for in pre-push review.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P6yUtvWGPsJpMLyh6pxSXG
2026-10-29 22:37:25 +01:00
Grzegorz MartensandClaude Opus 5.5 fe05b73d08 M11: JBIG2 symbol coding: tests for region numbering; the symbol cap applies to each plan
Review of the previous commit:
- Nothing checked the segment numbers the region split assigns: a
  mutant numbering every region 2 decoded. The many-marks test now
  reads each segment's number, and has a bar too tall to be a symbol,
  so the generic region is numbered after the last text region.
- The decoder's 32,767-symbol limit was checked against all distinct
  marks, before either plan, so an image with more distinct marks lost
  the second plan, which codes only the repeated ones. The limit now
  applies to each plan (MAX_CODED_SYMBOLS); finding marks keeps its
  memory bound of 65,536 (MAX_SYMBOLS), as before the previous commit.
  A test has 32,768 distinct marks above a page of repeated text, which
  encode_jbig2 still symbol codes through the second plan.
- The dense-page optimizer test now checks that it takes several text
  regions, and a compile-time assert keeps segment numbers within a
  byte's reach.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P6yUtvWGPsJpMLyh6pxSXG
2026-10-29 22:37:07 +01:00
Grzegorz MartensandClaude Opus 5.5 deb70c92ca M11: JBIG2 symbol coding: at most 10,000 copies a text region and 32,767 symbols
A review found that a dense page came out as a stream PdfCraft's own
renderer refuses, so the page drew blank after optimizing: hayro-jbig2
decodes a text region of at most 10,000 symbol instances, and refuses
32,768 symbols or more. The stream was valid (Poppler decoded it), but
every mark went into one text region and up to 65,536 symbols were kept.
A 300 dpi letter page of the optimizer test's own text crossed it.

A page with more than 10,000 marks is now placed by several text
regions, each over a band of rows and all referring to the one symbol
dictionary, which each region but the last keeps retained (7.2.4). Past
32,767 distinct symbols the image is coded generically.

New tests: 25,000 copies placed by three regions, which decode; the
symbol caps decoded, not just reached; and in the optimizer, a whole
letter page of rendered text that looks the same as JBIG2 symbols (it
drew blank before). The READMEs say "still looked at" for the caps, and
that the scans figure is the six pages' total (20% on one page).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P6yUtvWGPsJpMLyh6pxSXG
2026-10-29 22:37:07 +01:00
Grzegorz MartensandClaude Opus 5.5 8eeafe3309 M11: JBIG2 symbol coding: tests for tall marks, the other corner and the symbol caps
A second review found two rules tested one way only: a mark 257 tall
(not just wide) is left to the generic region, which also bounds the
bitmap allocated for each mark, and runs joined at the lower-left corner
are one mark. The test now has a 1 x 257 column and an anti-diagonal.
The caps on distinct symbols (65,536) and their pixels (2^24) are tested
at and past them, as the run and row caps are.

The scans figure now names its noise: with 2% or more of the letters'
edge pixels flipped, symbols save at most 8% over the generic region.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P6yUtvWGPsJpMLyh6pxSXG
2026-10-29 22:37:07 +01:00
Grzegorz MartensandClaude Opus 5.5 0d40594cf9 M11: JBIG2 symbol coding: tests for padding, the 32-bit range and the mark rules
Review found behaviour the tests let break unnoticed (each was a
surviving mutant, and each new test fails on it):
- black padding bits: a run reaching past the row would stop symbol
  coding on many scans;
- Annex A's 32-bit range and PREV at exactly 256, where a decision would
  go uncoded: coordinates past 4,435 on a 12,000-pixel-wide and a
  10,050-row page, and the contexts of 4436's coding;
- marks joined at a corner are one mark; 256 pixels a side is a symbol,
  257 is left to the generic region;
- the run and row caps, at and past them.

The roadmap's status line for this change now comes first, and the
"about a third smaller than Group 4 on scans" figure is replaced by what
was measured: 27-33% on the same pages with scan-like noise added.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P6yUtvWGPsJpMLyh6pxSXG
2026-10-29 22:37:07 +01:00
Grzegorz MartensandClaude Opus 5.5 9edd08ce07 M11: JBIG2 symbol coding for black-and-white images
pdfcraft_filters::encode_jbig2 stores each distinct mark of a 1-bit
image (8-connected black pixels, at most 256 a side) once, as a symbol
in a symbol dictionary, and places its exact copies with an immediate
lossless text region that refers to it. Larger marks, and in a second
plan marks that occur once, go to a generic region over their box. It
keeps whichever of that and the generic coding (encode_jbig2_generic,
unchanged) is smaller. Only exact copies share a symbol, so the stream
decodes to the same bits.

Written from the JBIG committee's ISO/IEC 14492 Final Committee Draft:
6.4 and 6.5 (text region and symbol dictionary decoding), 7.2, 7.4.2
and 7.4.3 (segment headers and syntax) and Annex A (the integer coders,
checked against its worked example and Table A.1).

On six pages of rendered 300 dpi text the output is 28% of the generic
coding's size and 17% of Group 4's, at about 100 ms a page; hayro-jbig2
and Poppler (pdfimages) both decode it to the original bits. Scans,
whose copies of a letter are seldom identical, gain little: that needs
refinement coding. A dictionary shared between pages (/JBIG2Globals)
is a further step.

The optimizer's Monochrome Images > JBIG2 (lossless) and doc_optimize
mono jbig2 use it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P6yUtvWGPsJpMLyh6pxSXG
2026-10-29 22:37:07 +01:00
Grzegorz MartensandClaude Opus 5.5 e18d1bfed3 M11: Export ▸ Images decodes JBIG2 globals within 32 MiB of their own
An image's /JBIG2Globals were decoded with the 1 GiB any stream may decode
to, before the JBIG2 page's size is known, so the page's pixel limit didn't
bound them: a few kilobytes of Flate could make export allocate up to 1 GiB.
They now decode within MAX_GLOBALS (32 MiB); globals past it skip the image,
with the limit in the reason. The test covers one byte over and exactly the
limit, and the image's /DecodeParms direct, by reference and in an array.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 22:37:03 +01:00
Grzegorz MartensandClaude Opus 5.5 ebad7f849d M6: form_set_props' refusals are argument errors, so the tool's own notation guard is tested
The test only checked each refusal's message. Without the tool's notation guard, set_props
refuses the same notation with the same message as a failed edit, so the test passed with the
guard removed. It now asserts InvalidArgs for every row, and fails on "a EVCALC b" without the
guard.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 20:48:48 +01:00
Grzegorz MartensandClaude Opus 5.5 2055f48f5f M6: calculation checks: English copies of the new rows in the catalogues that had none
ckb and nb get all eleven rows, th and lo the six strings, and sq the five plurals beside its
strings, each under "# Untranslated". Their rows next to these were missing too, so following
them had added nothing.

hi, id, ko, lo and th list one plural form (plural_none), so they get no English copy of the
plurals: one English wording would be used for every count ("1 formulas read ..."). Without an
entry, the English fallback picks the right form, as it already does for the page's other plurals
in those catalogues.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P6yUtvWGPsJpMLyh6pxSXG
2026-10-29 20:48:48 +01:00
Grzegorz MartensandClaude Opus 5.5 f64c71f65f M6: a test that set_props refuses an unstorable notation before writing anything
The tooltip given with it, which set_props writes before the calculation,
isn't set either; with the check moved to the calculation the test fails
(from the review).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P6yUtvWGPsJpMLyh6pxSXG
2026-10-29 20:48:48 +01:00
Grzegorz MartensandClaude Opus 5.5 46382092f1 M6: Field Properties refuses a notation it couldn't store, and stays open with what was typed
set_props refuses such a notation before writing anything, so the
Calculate tab can't store one either (the tool already refused it). A
refused edit used to close Field Properties and lose everything typed
into it; the dialog now stays open with its changes, as the dialog for
several fields does, and the notice says why (from the review).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P6yUtvWGPsJpMLyh6pxSXG
2026-10-29 20:48:48 +01:00
Grzegorz MartensandClaude Opus 5.5 d7c8e6ad1b M6: calculation checks: a notation's last name keeps the escaped space that ends it
parse_calculate trimmed the notation with str::trim, which also took an
escaped space ending its last name: "Qty * Total\ " read back as
"Qty * Total\", a field the form doesn't have, while the script's
JavaScript still read "Total ". It now trims to its first and last
token, as the field-reading scan does. notation_storable compares the
names and operators read back with those given, so a notation ending in
a lone \ (which escapes the space after it) is refused; a proptest reads
back notations of any names (from the review).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P6yUtvWGPsJpMLyh6pxSXG
2026-10-29 20:48:38 +01:00
Grzegorz MartensandClaude Opus 5.5 fd3634cc38 M6: form_set_props refuses a notation it couldn't store as written
A notation is kept in the script's /** BVCALC … EVCALC **/ comment and read
back from there. One holding EVCALC was stored cut short ("a EVCALC b"
read back as "a", and its JavaScript translation didn't parse), one
holding */ ended the comment, and an empty one became "event.value = ;".
form_set_props now refuses each (af::notation_storable: it has to read back
as itself). The test also pins a notation beside op alone and beside
fields alone (from the review).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P6yUtvWGPsJpMLyh6pxSXG
2026-10-29 20:48:38 +01:00
Grzegorz MartensandClaude Opus 5.5 fefb99a786 M6: calculation checks: the page's steps are chosen by a function the tests reach
steps() takes the widgets by object, so each of two fields sharing a name
gets its own step; a test checks it, unfocused and with a focus (from the
review: no test failed with the step looked up by name).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P6yUtvWGPsJpMLyh6pxSXG
2026-10-29 20:48:38 +01:00
Grzegorz MartensandClaude Opus 5.5 50a4a19a1a M6: calculation checks: Finnish and Persian text
Both translate the neighbouring Calculation order rows; Finnish had
English copies of the new ones, and Persian came in with main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P6yUtvWGPsJpMLyh6pxSXG
2026-10-29 20:48:38 +01:00
Grzegorz MartensandClaude Opus 5.5 c97bf57029 M6: form_set_props refuses unknown, mistyped and conflicting keys in calculate and validate
A notation beside op and fields set the notation and dropped the rest, a
field name that wasn't a string was left out, a misspelt key was ignored,
and validate {"min": 0, "max": "100"} wrote a min-only range. Each is
now refused and nothing changes. A null bound, as form_fields shows the
one a range doesn't have, is no bound, so its output is taken back.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P6yUtvWGPsJpMLyh6pxSXG
2026-10-29 20:48:38 +01:00
Grzegorz MartensandClaude Opus 5.5 50faef001a M6: calculation checks: CalculatedField::issues says it covers the formula too
MissingField and BuiltNames are about the formula, not its place in the
order.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P6yUtvWGPsJpMLyh6pxSXG
2026-10-29 20:48:38 +01:00
Grzegorz MartensandClaude Opus 5.5 1808720d75 M6: calculation checks: an AFSimple string list with an argument after it is read and renamed, as an array is
AFSimple_Calculate("SUM", "a, b", x) gave only a built-name site, so a
rename no longer rewrote a and b (main did) while parse_calculate still
read the sum of a and b: after a rename the sum read missing fields. The
string list now keeps its names when an argument follows, and what
follows is a name built at run time, as for an array (from the review).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P6yUtvWGPsJpMLyh6pxSXG
2026-10-29 20:48:38 +01:00
Grzegorz MartensandClaude Opus 5.5 49d5c40356 M6: calculation checks: a row or widget in focus is its own field, not the first of its name
The page's focus was a name, so with two fields called total (a
malformed form) hovering the second one's row showed the first one's
missing fields in the pill, and outlined and numbered both on the page.
A row and a widget under the pointer now carry their field object: the
pill says that field's reads and issues, and the page outlines it, its
step and the formulas that read it by object. The Prepare selection is
still only a name, so it stands for every field of that name and the
pill says all of their issues (from FredApps's review).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P6yUtvWGPsJpMLyh6pxSXG
2026-10-29 20:48:38 +01:00