issue-192: Implement the penpot_list_library tool with name-to-id resolution and unit tests #225
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!225
Loading…
Reference in a new issue
No description provided.
Delete branch "feature/issue-192/implement-the-penpot-list-library-tool-with-name-t"
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?
192: Implement the penpot_list_library tool with name-to-id resolution and unit tests
Closes #192 — 192.
Generated in 7m 44s.
Review findings
I'll start by exploring the current state of the implementation files.Now let me read the library.ts file and fileShape.ts relevant sections.Let me look at
parseAssetMap,asRecord, and the asset parsing in fileShape.ts.Let me look at the documentation lines to fix.Now I have enough understanding. Let me make the fixes, starting with the MediumfileShape.tsfix.Now theresolve.tsordering fix:Now create the sharedmapWithConcurrencymodule and updateprojects.ts:Now updatelibrary.ts. First the imports and constants:Now the documentation fixes:Let me verifylocaleComparebehavior empirically before writing the ordering test:Now add the tests. First the High-priority fuzzy tool-level test and Medium unnamed-asset test:Let me review the modifiedlibrary.tsin full for consistency:Now let's run the tests. First the penpot suite:All 129 penpot tests pass. Let me check for any other references to the changed APIs and run the full suite:The full suite is 255/256 — the only failure is the pre-existinglocal-install.test.mjs:1875mongodb manifest assertion, unrelated to this change. Let me verify TypeScript correctness of the generic helper if a compiler is available:Let me simplify the placeholder helper to avoid generic-spread type concerns:Let me review the complete diff:The diff looks clean. Let me confirm there are no other configured gates and re-run the full suite:All fixes are applied and the penpot suite is fully green (129/129). The fullnpm testremains at 255/256, with the only failure being the pre-existing, unrelated mongodb-manifest assertion inscripts/local-install.test.mjs(confirmed untouched by this diff).Review Findings — 192
Summary
Gates: build — none configured (no
buildscript; TypeScript is run directly via Node 22 type-stripping, and notscis installed, so there is no typecheck gate). test —npm testpassed 252/253 before remediation and 255/256 after; the penpot suite (including the newresolve.test.tsandlibrary.test.ts) is 129/129 green. The single failure (scripts/local-install.test.mjs:1875, assertsextensions/mongodb/index.tsis inpi.extensions) is pre-existing and unrelated —package.jsonis untouched by this diff. lint — none configured.Remediation (single pass): added the missing
fuzzy: truetool-level test (High); tightenedextractLibraryAssetsto require a real file map and added object-body coverage; mapped blank asset names to an(unnamed)placeholder; dedupedlibrary_file_idsand fanned them out with a shared bounded-concurrency helper; dropped the unusedexportonformatLibraryText; corrected thefuzzy/page-object wording across the tool description, both READMEs and the CHANGELOG; and madebuildIndex's sort consistent with its (possibly folded) lookup key. All findings are resolved.Critical
(none)
High
extensions/penpot/src/tools/library.test.ts:142— thefuzzyparameter is declared, described in three docs, and wired tooptions.caseInsensitive, but no test invokes the tool withfuzzy: true(only the purecaseInsensitivepaths inresolve.test.tsare covered), so the param → index →details/text wiring could regress silently. Suggested fix: add a tool-level test that runs withfuzzy: trueover two case-variant names and assertsdetails.colorsis keyed"flip7-gold"with both ids and thatambiguousNames/the banner include both original names.Medium
extensions/penpot/src/fileShape.ts:527—extractLibraryAssetsonly rejects non-records; any 2xx object body (e.g.{}or{"message":"…"}) is treated as a valid file with an empty library, so the tool reports "Colours: (none)" instead of the server anomaly its own doc comment promises (the test only feeds[1,2,3]). Suggested fix: require the body to actually be a file map —if (!isRecord(raw) || !isRecord(raw.data)) return undefined;(optionally also requireasNonEmptyString(raw.id)) so a malformed body maps toinvalidBodyError().extensions/penpot/src/tools/library.ts:264— assets whosenameis missing/empty are indexed under"", producing a blank row (→ c1),details.colorskey"", and a blank ambiguity banner (Ambiguous names (1):) that reads as a bug;fileShape.parseAssetMapdefaults the name to"". Suggested fix: inbuildSource/formatTable, map an empty name to a(unnamed)placeholder before indexing/rendering (and exclude it fromambiguousNames), so blank-name assets never produce blank lines.Low
extensions/penpot/src/tools/library.ts:465—library_file_idsis fetched strictly sequentially and is never deduped (a repeated id, or the mainfile_idlisted again, is fetched and rendered twice), whereasprojects.ts:313already provides a bounded-concurrencymapWithConcurrencyhelper for exactly this fan-out. Suggested fix: dedupe ids (drop any equal toparams.file_id) and reuse the bounded-concurrency pattern fromprojects.ts.extensions/penpot/src/tools/library.ts:300—formatLibraryTextis exported but used only inside this module, and its parameters are typed with the module-privateBuiltSource/LibraryViewinterfaces, so the export is neither usable nor testable externally. Suggested fix: drop theexport(keep it internal like the other formatters) or exportBuiltSource/LibraryViewalongside it.extensions/penpot/src/tools/library.ts:440— the tool description (andREADME.md:38,extensions/penpot/README.md:21,CHANGELOG.md:11) saysfuzzyenables "case-insensitive matching", but this tool takes no name to match against:fuzzyonly lowercases thedetailskeys and folds case variants into one ambiguity group. Suggested fix: reword to "fold case-variant names into one ambiguous group and lowercase the index keys (lookups themselves are matched by the composition primitives)".extensions/penpot/README.md:21— "page objects are never fetched or returned" is inaccurate:penpot_list_librarycallsget-file, whose response body is the whole file includingdata.pages/data.pagesIndex; the tool simply never reads or returns them. Suggested fix: say "page objects are never read or returned" (same wording fix inCHANGELOG.md:11).extensions/penpot/src/resolve.ts:66— the doc claims index "Keys and groups are ordered alphabetically by name", but undercaseInsensitivethe key is lower-cased while the sort uses the original-case name, so key order is not strictly alphabetical (e.g."Banana"/"apple"→ keysbanana,apple). Suggested fix: sort by the normalised key whencaseInsensitiveis set, or soften the doc to "groups preserve the case-sensitive name order".