issue-252: penpot_add_text stages zero-area auto-width text, producing files that fail update-file with NaN points #265
No reviewers
Labels
No labels
bug
chore
documentation
enhancement
feature
ready
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
david/pi-extensions-and-skills!265
Loading…
Reference in a new issue
No description provided.
Delete branch "feature/issue-252/penpot-add-text-stages-zero-area-auto-width-text-p"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
252: penpot_add_text stages zero-area auto-width text, producing files that fail update-file with NaN points
Closes #252 — 252.
Generated in 1h 03m 49s.
Review findings
I'll start by reading the relevant files for the findings.Now let me look at the specific files mentioned in the findings.Let me look at more details — the instance change payloads, imports in svg.ts, and test assertions on "zero-area".Now let me check imports and the discard tool, and whether svg.ts can import from shapes.ts without a cycle.Now let me check how instance.ts sets
shapeRef/componentIdand what types the change obj carries:Now let me check the discard tool name,boundsToBox, and the commit test helpers:Now let me check instance.ts typing forshapeRef/componentIdand the add_svg test harness:Now let me look at the commit test helpers and theisAxisAlignedfunction:Let me look at the dry_run tests in commit.test.ts and the svg test harness helpers:Let me checkDEFAULT_TEXT_STYLEand remaining usages, then start making fixes.I have the full picture now. Let me check the svg tool test harness before making edits:I have full context now. Let me check the svg.ts module docs for text documentation, then make the edits.Now I have full context. Let me check the svg tool test helpers:I now have complete context. Let me apply the fixes, starting withshapes.ts(Low findings:assertPositiveBoxwording and shared constant):Now fix the commit.ts findings (Medium: dry_run ordering; Low: instance remedy):ThecomponentIdfield isn't onShapePayloadyet — instance clones carry it via a cast. Let me add the optional fields so the access is type-sound:Now the Medium + Low findings insvg.ts— guard the non-positive font-size viapushSkipand share the glyph-width constant:Now update the commit pre-flight test (dry_run behaviour) and add tests. First let me update the existing commit test to also pin the dry-run refusal:Now add tests for the SVG font-size guard in svg.test.ts and the tools/svg.test.ts:Let me fix the doc comment onassertPositiveBox(it still says "zero-area" is avoided, but the message keeps the phrase plus the≤ 0breakdown), then add the negative-dimension test:Now add the negative-dimension test in shapes.test.ts:Now run the test suite:All 880 tests pass (879 pass, 1 live-only skip, 0 fail). Let me update the CHANGELOG entry to stay consistent with the repo's convention, and verify no stale references remain:All gates green: 880 tests, 879 pass, 1 live-only skip, 0 fail. Let me do a final sanity check of the working-tree changes:All remediation work is complete and gates are green. Here is the annotated findings document:Review Findings — 252
Summary
Fixed all five code findings in one pass: the SVG import's
convertTextnow routes a non-positive parsedfont-sizethroughpushSkip(so a zero-area text descriptor is never emitted and the staging loop stays atomic),penpot_commit's text-geometry pre-flight now runs before thedry_runbranch (so a dry run refuses an uncommittable batch instead of reporting it committable), the zero-area refusal branches its remedy on the change carryingcomponentId/shapeRef(naming the library component forpenpot_instance_componentclones), the glyph-width factor is now one shared constant (APPROXIMATE_CHARACTER_WIDTH, exported fromshapes.tsand used by the SVG converter), andassertPositiveBoxreports failing dimensions with their≤ 0comparison so a negative width/height isn't misread as a plain zero-size box. New tests pin the SVG skip (converter- and tool-level, including staging atomicity), the dry-run refusal, the instance-clone remedy, and the negative-dimension message. Gates:npm test— 880 tests, 879 pass, 1 live-only skip, 0 fail; the repo has no build or lint script. The commit-message finding is left for the squash-merge step: amendingd4e7654would require a commit, which this stage must not perform.Critical
High
Medium
convertTextinsrc/svg.ts:1995computeswidth = text.length * fontSize * TEXT_WIDTH_FACTOR) can still produce a zero-area text descriptor (e.g.font-size="0"or a negative font-size, both of whichparseLengthaccepts), andbuildShapeForDescriptor→baseShapenow throws mid-staging-loop. BecausestageChangeis called per descriptor inside the loop with no try/catch, descriptors staged before the throw remain in the changeset and the tool exits with a raw internal error instead of its formatted skip report. Suggested fix: inconvertText(svg.ts:~1965), route a non-positive parsedfontSizethroughpushSkiplike the other invalid-input cases, or estimate a positive box viaestimateTextSizefor zero-area text descriptors so the import stays atomic.Low
assertCommittableTextGeometryruns after thedry_run === trueearly return, sopenpot_commitwithdry_run: truereports a batch containing a degenerate text shape as committable while the real commit will refuse it. Suggested fix: run the pre-flight before the dry-run branch (it performs no I/O, so dry-run semantics are unaffected) or surface the refusal indryRunText.penpot_instance_componentclones (instance.ts does not go throughbaseShape), where the correct remedy is discarding the instance or fixing the library. Suggested fix: branch the remedy on whether the change carriesshapeRef/componentId, or add a generic "or discard the staged change" that covers the instance case first.APPROXIMATE_CHARACTER_WIDTH = 0.58andTEXT_WIDTH_FACTOR = 0.6), which will drift. Suggested fix: have the SVG text path reuseestimateTextSize(also resolving the Medium finding) or export and share one constant.assertPositiveBoxreports negative dimensions as a "zero-area box (width -5, …)"; the message is slightly misleading for the negative case. Suggested fix: word it "non-positive box" or reportwidth ${input.width} ≤ 0.d4e7654— commit message is252: …but the AGENTS.md convention for issue-driven work isissue-252: …(branch namefeature/issue-252/…is correct). Suggested fix: useissue-252: <summary>for the squash-merge message when the PR is merged.(All severities assessed against the repo's own convention docs; no acceptance criteria were provided beyond the issue title, which the change addresses.)