altium-toolkit 1.1.24 → 1.1.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +5 -3
  2. package/docs/api.md +43 -17
  3. package/docs/model-format.md +51 -11
  4. package/docs/schemas/altium_toolkit/library_compatibility_a1.schema.json +116 -0
  5. package/docs/schemas/altium_toolkit/library_qa_a1.schema.json +3 -0
  6. package/docs/schemas/altium_toolkit/unsupported_features_a1.schema.json +58 -1
  7. package/package.json +1 -1
  8. package/spec/library-compatibility.md +65 -0
  9. package/src/core/altium/AltiumParser.mjs +8 -1
  10. package/src/core/altium/LibraryCompatibilityGeometry.mjs +618 -0
  11. package/src/core/altium/LibraryCompatibilityModelHintBuilder.mjs +296 -0
  12. package/src/core/altium/LibraryCompatibilityReportBuilder.mjs +930 -0
  13. package/src/core/altium/LibraryQaReportBuilder.mjs +29 -1
  14. package/src/core/altium/PcbDimensionParser.mjs +1 -0
  15. package/src/core/altium/PcbDimensionReportBuilder.mjs +190 -0
  16. package/src/core/altium/PcbEmbeddedModelExtractor.mjs +140 -10
  17. package/src/core/altium/PcbFabricationReadinessReportBuilder.mjs +607 -0
  18. package/src/core/altium/PcbInspectionReportBuilder.mjs +56 -3
  19. package/src/core/altium/PcbLayerStackReadModelBuilder.mjs +138 -3
  20. package/src/core/altium/PcbLibModelParser.mjs +24 -2
  21. package/src/core/altium/PcbLibStorageNameResolver.mjs +171 -0
  22. package/src/core/altium/PcbLibStreamExtractor.mjs +15 -93
  23. package/src/core/altium/PcbPrimitiveFieldOffsetReportBuilder.mjs +352 -0
  24. package/src/core/altium/PcbRuleImpactReportBuilder.mjs +313 -0
  25. package/src/core/altium/PcbShapeBasedBodyGeometryParser.mjs +514 -0
  26. package/src/core/altium/SchematicConnectivityQaBuilder.mjs +442 -2
  27. package/src/core/altium/SchematicImageDiagnosticsBuilder.mjs +214 -0
  28. package/src/core/altium/UnsupportedFeatureReportBuilder.mjs +523 -3
  29. package/src/parser.mjs +8 -0
  30. package/src/styles/altium-renderers.css +36 -0
  31. package/src/ui/PcbDimensionPrimitiveRenderer.mjs +422 -0
  32. package/src/ui/PcbScene3dBoardOutlineRefiner.mjs +6 -0
  33. package/src/ui/PcbScene3dBuilder.mjs +10 -2
  34. package/src/ui/PcbScene3dStaticBodyPlacementBuilder.mjs +225 -0
  35. package/src/ui/PcbSvgRenderer.mjs +78 -2
package/README.md CHANGED
@@ -43,9 +43,9 @@ browser or Node-based tools.
43
43
  - Build deterministic parser field-coverage matrix, raw-data preservation,
44
44
  parameter-record inventory, parser value-verification, normalized
45
45
  diagnostics, geometry-bounds, fixture-coverage, embedded-asset,
46
- library-diff, library-QA lint, project-hierarchy, and static
47
- library-catalog reports, classify PCB layer ids, and convert common Altium
48
- length units for downstream QA tooling
46
+ library-diff, library-compatibility, library-QA lint, project-hierarchy, and
47
+ static library-catalog reports, classify PCB layer ids, and convert common
48
+ Altium length units for downstream QA tooling
49
49
  - Emit Circuit JSON arrays from parser roots, with non-serialized
50
50
  renderer-compatibility fields for existing consumers
51
51
  - Render semantically annotated schematic SVG, semantically annotated PCB SVG,
@@ -114,8 +114,10 @@ import 'altium-toolkit/styles/altium-renderers.css'
114
114
  - [Geometry Bounds Schema](docs/schemas/altium_toolkit/geometry_bounds_a1.schema.json)
115
115
  - [Fixture Coverage Matrix Schema](docs/schemas/altium_toolkit/fixture_coverage_matrix_a1.schema.json)
116
116
  - [Unsupported Features Schema](docs/schemas/altium_toolkit/unsupported_features_a1.schema.json)
117
+ - [Library Compatibility Schema](docs/schemas/altium_toolkit/library_compatibility_a1.schema.json)
117
118
  - [Testing](docs/testing.md)
118
119
  - [Scope](spec/library-scope.md)
120
+ - [Library Compatibility Reports](spec/library-compatibility.md)
119
121
 
120
122
  ## Examples
121
123
 
package/docs/api.md CHANGED
@@ -73,11 +73,13 @@ Specialized parser helpers are exported for lower-level integrations, including
73
73
  `ParserFieldCoverageReportBuilder`, `ParserValueVerificationReportBuilder`,
74
74
  `ParserCompatibilityFuzzer`, `NativeStreamInventoryBuilder`,
75
75
  `RawDataPreservationReportBuilder`, `UnsupportedFeatureReportBuilder`,
76
- `EmbeddedAssetReportBuilder`, `LibraryDiffReportBuilder`,
77
- `LibraryInspectionReportBuilder`,
76
+ `EmbeddedAssetReportBuilder`, `LibraryCompatibilityReportBuilder`,
77
+ `LibraryDiffReportBuilder`, `LibraryInspectionReportBuilder`,
78
78
  `PcbBoardRegionSemanticsParser`, `PcbComponentPrimitiveIndexer`,
79
- `PcbCustomPadShapeParser`, `PcbDimensionParser`, `PcbEmbeddedFontExtractor`,
80
- `PcbExtendedPrimitiveInformationParser`, `PcbFontMetricsParser`,
79
+ `PcbCustomPadShapeParser`, `PcbDimensionParser`,
80
+ `PcbDimensionReportBuilder`, `PcbEmbeddedFontExtractor`,
81
+ `PcbExtendedPrimitiveInformationParser`,
82
+ `PcbFabricationReadinessReportBuilder`, `PcbFontMetricsParser`,
81
83
  `LibraryRenderManifestBuilder`, `LibraryCatalogArtifactBuilder`,
82
84
  `LibrarySearchIndex`, `SchLibModelParser`, `SchLibStreamExtractor`,
83
85
  `PcbBomProfileBuilder`, `PcbClassReportBuilder`,
@@ -88,8 +90,10 @@ Specialized parser helpers are exported for lower-level integrations, including
88
90
  `ProjectDesignBundleBuilder`, `ProjectHierarchyReportBuilder`,
89
91
  `ProjectNetlistExporter`, `ProjectVariantViewBuilder`,
90
92
  `PcbMechanicalLayerPairParser`, `PcbSpecialStringResolver`, `PcbUnionParser`,
91
- `PcbViaStackParser`, `PcbRuleParser`, `PcbRawRecordRegistry`,
93
+ `PcbViaStackParser`, `PcbRuleImpactReportBuilder`, `PcbRuleParser`,
94
+ `PcbRawRecordRegistry`, `PcbReviewPolygonRealizationBuilder`,
92
95
  `PcbStatisticsBuilder`, `SchematicCodeSymbolParser`,
96
+ `SchematicConnectivityQaBuilder`, `SchematicImageDiagnosticsBuilder`,
93
97
  `SchematicOwnershipGraphParser`,
94
98
  `SchematicProjectParameterResolver`, `SchematicRecordStreamParser`, and
95
99
  `SchematicTextRunParser`.
@@ -100,6 +104,15 @@ the native component-index grouping used to populate
100
104
  rule helpers expose the same mask/cache, stack, and typed-constraint
101
105
  normalization used by `.PcbDoc` parsing. `PcbDimensionParser` exposes the
102
106
  parser-only Dimensions6 normalization used by `.PcbDoc` parsing.
107
+ `PcbDimensionReportBuilder` classifies recovered PCB dimensions as renderable
108
+ or unresolved from their reference geometry, and
109
+ `PcbRuleImpactReportBuilder` summarizes enabled/disabled design rules by
110
+ affected primitive family, scope predicate, manufacturing category, and
111
+ length-valued constraints. `PcbFabricationReadinessReportBuilder` summarizes
112
+ pad/via fabrication review items such as local pad stacks, offsets, slots,
113
+ mask overrides, thermal relief, via spans, and via protection metadata.
114
+ `PcbReviewPolygonRealizationBuilder` exposes the polygon-pour realization rows
115
+ used by `pcb.reviewMetadata`.
103
116
  `SchematicOwnershipGraphParser` and `PcbOwnershipGraphBuilder` expose the
104
117
  read-only ownership sidecars that parser roots attach under
105
118
  `schematic.ownership` and `pcb.ownership`.
@@ -179,8 +192,13 @@ opaque-frame preservation for lower-level extractors.
179
192
  `ParserCompatibilityFuzzer` runs deterministic malformed,
180
193
  wrong-reader, and sparse-input cases against parser entrypoints for parser QA.
181
194
  `EmbeddedAssetReportBuilder` emits unified embedded-asset inventories across
182
- parser roots, and `LibraryDiffReportBuilder` compares parsed symbol and
183
- footprint libraries by name, counts, and parameters.
195
+ parser roots. `LibraryCompatibilityReportBuilder` emits source-neutral
196
+ schematic-library pin compatibility rows, symbol bounds, field-placement risk
197
+ rows, footprint bounds, pad diagnostics, custom pad outline diagnostics, and
198
+ package-key suggestions with pin-one rotation hints for footprints without
199
+ embedded or body-level model references. `LibraryDiffReportBuilder` compares
200
+ parsed symbol and footprint
201
+ libraries by name, counts, and parameters.
184
202
  `LibraryInspectionReportBuilder` composes library inventory and QA findings
185
203
  into one stable artifact. `SchLibStreamExtractor` and `SchLibModelParser`
186
204
  expose native schematic-symbol library recovery, including section keys,
@@ -190,10 +208,16 @@ implementation child rows where available.
190
208
  `LibrarySearchIndex` expose deterministic SchLib/PcbLib render/export
191
209
  manifests, static catalog artifacts, search metadata, plus exact, keyword, and
192
210
  fuzzy lookup helpers. `PcbStatisticsBuilder`, `PcbNetMembershipReportBuilder`,
193
- `PcbClassReportBuilder`, and `PcbInspectionReportBuilder` emit board QA,
194
- net-ownership, class-membership, and combined inspection artifacts for
195
- `.PcbDoc` models. `SchematicProjectParameterResolver` resolves dot-prefixed and
196
- equals-prefixed schematic special strings for parser and SVG integrations.
211
+ `PcbClassReportBuilder`, `PcbDimensionReportBuilder`,
212
+ `PcbRuleImpactReportBuilder`, `PcbFabricationReadinessReportBuilder`, and
213
+ `PcbInspectionReportBuilder` emit board QA, net-ownership, class-membership,
214
+ dimension QA, rule-impact, fabrication-readiness, and combined inspection
215
+ artifacts for `.PcbDoc` models. `SchematicImageDiagnosticsBuilder` and
216
+ `SchematicConnectivityQaBuilder` expose the same image payload and connectivity
217
+ QA sidecars attached to parsed schematic models.
218
+ `SchematicProjectParameterResolver`
219
+ resolves dot-prefixed and equals-prefixed schematic special strings for parser
220
+ and SVG integrations.
197
221
  `SchematicTextRunParser` parses schematic backslash suffix markers into display
198
222
  text plus overline run metadata reused by pin and text rendering.
199
223
 
@@ -303,13 +327,14 @@ available. The embedded `schematic-semantic-metadata` JSON sidecar uses schema
303
327
  components, and pins for downstream highlighting.
304
328
 
305
329
  PCB SVG output includes stable semantic `data-*` attributes on recovered board,
306
- copper, pad, via, component, and text elements. The embedded
330
+ copper, pad, via, component, text, and dimension elements. The embedded
307
331
  `pcb-semantic-metadata` JSON sidecar uses schema
308
332
  `altium-toolkit.pcb.svg.semantics.a1` and links SVG element keys to primitive
309
- kind, layer, net/class, component, pad number, hole ownership, and board-outline
310
- identity where that metadata is available. The same sidecar also records view
311
- context, including board centroid, included layer ids, layer roles, cutouts, and
312
- pad/via drill render state (`open`, `covered`, `filled`, or `capped`).
333
+ kind, layer, net/class, component, pad number, dimension kind/text, hole
334
+ ownership, and board-outline identity where that metadata is available. The
335
+ same sidecar also records view context, including board centroid, included layer
336
+ ids, layer roles, cutouts, and pad/via drill render state (`open`, `covered`,
337
+ `filled`, or `capped`).
313
338
  `PcbSvgRenderer.renderLayerSvgs()` uses the same semantic sidecar shape with
314
339
  `view.kind: 'layer'` and a layer-specific `layerSet`.
315
340
 
@@ -331,7 +356,8 @@ import {
331
356
  `drillCutouts` plus fill holes for drilled pads and vias. External model
332
357
  placements include `projection` diagnostics indicating whether bounds came
333
358
  from authored overrides, resolved model bounds, nearby pad spans, procedural
334
- component fallback, or only the model anchor.
359
+ component fallback, or only the model anchor. Shape-based 3D bodies with
360
+ complete native geometry are exposed as `staticBodyPlacements`.
335
361
  - `PcbScene3dModelRegistry` resolves embedded or session model candidates for
336
362
  component placements.
337
363
  - `PcbScene3dScenePreparator.prepare(documentModel, options)` prepares the same
@@ -154,9 +154,17 @@ known/unknown classification, and consumed status.
154
154
  `EmbeddedAssetReportBuilder.build()` emits
155
155
  `altium-toolkit.embedded-assets.a1` reports that normalize schematic images,
156
156
  embedded file inventories, PCB font/model payloads, and integrated-library
157
- source entries into one stable asset table. `LibraryDiffReportBuilder.build()`
158
- emits `altium-toolkit.library.diff.a1` reports comparing parsed symbol and
159
- footprint libraries by item name, counts, and parameter values.
157
+ source entries into one stable asset table.
158
+ `LibraryCompatibilityReportBuilder.build()` emits
159
+ `altium-toolkit.library.compatibility.a1` reports for schematic-library pin
160
+ roles and edge markers, hidden-pin hints, symbol bounds, field-placement risk
161
+ rows, footprint bounds, pad diagnostics, custom pad outline diagnostics, and
162
+ package-key suggestions with pin-one rotation hints for missing model
163
+ references. The report is read-only and is also composed into library QA when
164
+ it emits issues.
165
+ `LibraryDiffReportBuilder.build()` emits `altium-toolkit.library.diff.a1`
166
+ reports comparing parsed symbol and footprint libraries by item name, counts,
167
+ and parameter values.
160
168
  `LibraryInspectionReportBuilder.build()` emits
161
169
  `altium-toolkit.library.inspection.a1` reports that combine library inventory
162
170
  rows with duplicate, stale-link, missing-model, lint, and merge-plan QA
@@ -170,10 +178,23 @@ possible unrouted pad-only nets are split into deterministic lists.
170
178
  `PcbClassReportBuilder.build()` emits
171
179
  `altium-toolkit.pcb.class-report.a1` reports that summarize PCB classes by
172
180
  kind, enabled state, member resolution, empty classes, and unresolved members.
181
+ `PcbDimensionReportBuilder.build()` emits
182
+ `altium-toolkit.pcb.dimensions.a1` reports that classify recovered PCB
183
+ dimensions as renderable or unresolved from reference geometry and summarize
184
+ dimension kinds. `PcbRuleImpactReportBuilder.build()` emits
185
+ `altium-toolkit.pcb.rule-impact.a1` reports that group design rules by enabled
186
+ state, affected primitive families, scope predicates, manufacturing category,
187
+ and length-valued constraints.
188
+ `PcbFabricationReadinessReportBuilder.build()` emits
189
+ `altium-toolkit.pcb.fabrication-readiness.a1` reports that summarize pad/via
190
+ fabrication review items such as non-simple pad stack modes, local pad
191
+ offsets, slotted and non-plated holes, mask overrides, thermal relief, via
192
+ spans, via protection, and microvia-like geometry.
173
193
  `PcbInspectionReportBuilder.build()` emits `altium-toolkit.pcb.inspection.a1`
174
194
  reports that compose board statistics, primitive counts, design-rule counts,
175
- diagnostics, net membership, class membership, and route-analysis summaries
176
- into one inspection artifact.
195
+ diagnostics, net membership, class membership, dimension QA, rule-impact,
196
+ review metadata, fabrication-readiness, and route-analysis summaries into one
197
+ inspection artifact.
177
198
 
178
199
  `PcbLayerGroups` provides stable layer-group names, deterministic display
179
200
  colors, and draw priorities for legacy PCB layer ids. `AltiumUnits` provides
@@ -254,7 +275,12 @@ multi-sheet design netlist.
254
275
  `schematic.connectivityQa` reports read-only connectivity findings, including
255
276
  implicit generated net names, dangling labels, orphan ports, unconnected pins,
256
277
  ambiguous junctions, and un-junctioned tee contacts where one wire endpoint
257
- touches another wire interior without an authored junction.
278
+ touches another wire interior without an authored junction. Harness-specific
279
+ findings flag sheet entries whose local harness type cannot be resolved,
280
+ harness entries without linked signal-harness geometry, and connector type-label
281
+ mismatches. Pin interpretation findings flag hidden name/number labels,
282
+ endpoint symbol markers, and power-like pin names whose recovered electrical
283
+ type is not a power pin.
258
284
 
259
285
  Embedded schematic images preserve the raw record geometry and expose
260
286
  browser-facing payload metadata. When an embedded stream contains a native
@@ -262,6 +288,10 @@ PNG/JPEG/GIF/SVG/WebP payload alongside a preview, `mimeType` and `dataBase64`
262
288
  refer to the native payload while `sourceMimeType` records the preview format.
263
289
  Alpha-bearing 32-bit BMP previews are converted to PNG and marked with
264
290
  `hasAlpha` so SVG renderers can display transparency deterministically.
291
+ `schematic.imageDiagnostics` reports embedded payload counts, external image
292
+ references, missing embedded payloads, unsupported MIME states, converted
293
+ preview/native payloads, and alpha-bearing images without attempting any file
294
+ system lookups.
265
295
  When a schematic OLE container exposes preview metadata, `schematic.thumbnails`
266
296
  contains PNG thumbnail sidecars with `kind`, dimensions, `sourceStream`,
267
297
  `pixelFormat`, `mimeType`, and `dataBase64` fields.
@@ -378,9 +408,11 @@ consumers.
378
408
 
379
409
  PCB dimensions from `Dimensions6/Data` are exposed through `pcb.dimensions`.
380
410
  Dimension entries preserve native kind codes and raw fields while adding a
381
- normalized `kind` (`linear`, `angular`, `radial`, `datum`, `baseline`, or
382
- `ordinate`), reference points, optional text location, prefix/suffix, precision,
383
- measured value, angle value, and unit.
411
+ normalized `kind` (`linear`, `angular`, `radial`, `diameter`, `datum`,
412
+ `baseline`, or `ordinate`), reference points, optional text location,
413
+ prefix/suffix, precision, measured value, angle value, and unit. PCB SVG output
414
+ renders dimensions with sufficient reference geometry as static mechanical
415
+ dimension primitives and includes them in the semantic sidecar.
384
416
 
385
417
  `pcb.extendedPrimitiveInformation` exposes
386
418
  `ExtendedPrimitiveInformation/Data` entries keyed by primitive index and, when
@@ -454,7 +486,12 @@ preserves raw mixed-format primitive records with the same registry metadata
454
486
  shape used by PcbDoc raw records. Library-level `embeddedFonts` uses the same
455
487
  payload and metric shape as PCB documents. Library-level `embeddedModels` and
456
488
  `componentBodies` preserve embedded 3D payloads and body references when
457
- present.
489
+ present. When declared footprint names cannot be resolved to storage names,
490
+ `pcbLibrary.storageDiagnostics.missingFootprints` lists the declared name,
491
+ attempted storage candidates, and reason. Shape-based component bodies may
492
+ include `staticGeometry` for
493
+ extruded-polygon, cone, cylinder, and sphere bodies, with dimensions and
494
+ vertices expressed in mils when native evidence is available.
458
495
  `pcbLibrary.indexes.footprintsByName` provides read-only footprint lookup and
459
496
  search metadata, including source storage, primitive counts, pad/text counts,
460
497
  and keyword tokens from footprint and component parameters. Footprint entries
@@ -540,7 +577,10 @@ External model placements in the 3D scene description include a `projection`
540
577
  diagnostic object. The `source` explains whether bounds came from an authored
541
578
  projection override, resolved model bounds, nearby pad-span fallback,
542
579
  procedural component fallback, or model-anchor fallback. The diagnostic does
543
- not alter placement coordinates.
580
+ not alter placement coordinates. Shape-based component bodies with complete
581
+ static geometry are exposed separately as `staticBodyPlacements`, using the
582
+ same board-centered coordinate convention as component and external-model
583
+ placements.
544
584
 
545
585
  ## Integrated Library Fields
546
586
 
@@ -0,0 +1,116 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "altium-toolkit.library.compatibility.a1",
4
+ "title": "Altium Toolkit Library Compatibility A1",
5
+ "type": "object",
6
+ "additionalProperties": true,
7
+ "required": [
8
+ "schema",
9
+ "summary",
10
+ "symbolPins",
11
+ "hiddenPins",
12
+ "symbolBounds",
13
+ "fieldPlacementRisks",
14
+ "footprintBounds",
15
+ "padDiagnostics",
16
+ "modelSuggestions",
17
+ "issues"
18
+ ],
19
+ "properties": {
20
+ "schema": {
21
+ "const": "altium-toolkit.library.compatibility.a1"
22
+ },
23
+ "summary": {
24
+ "type": "object",
25
+ "additionalProperties": true,
26
+ "properties": {
27
+ "schematicLibraryCount": {
28
+ "type": "number"
29
+ },
30
+ "pcbLibraryCount": {
31
+ "type": "number"
32
+ },
33
+ "symbolPinCount": {
34
+ "type": "number"
35
+ },
36
+ "hiddenPinCount": {
37
+ "type": "number"
38
+ },
39
+ "symbolBoundsCount": {
40
+ "type": "number"
41
+ },
42
+ "fieldPlacementRiskCount": {
43
+ "type": "number"
44
+ },
45
+ "footprintBoundsCount": {
46
+ "type": "number"
47
+ },
48
+ "padDiagnosticCount": {
49
+ "type": "number"
50
+ },
51
+ "modelSuggestionCount": {
52
+ "type": "number"
53
+ },
54
+ "issueCount": {
55
+ "type": "number"
56
+ }
57
+ }
58
+ },
59
+ "symbolPins": {
60
+ "type": "array",
61
+ "items": {
62
+ "type": "object",
63
+ "additionalProperties": true
64
+ }
65
+ },
66
+ "hiddenPins": {
67
+ "type": "array",
68
+ "items": {
69
+ "type": "object",
70
+ "additionalProperties": true
71
+ }
72
+ },
73
+ "symbolBounds": {
74
+ "type": "array",
75
+ "items": {
76
+ "type": "object",
77
+ "additionalProperties": true
78
+ }
79
+ },
80
+ "fieldPlacementRisks": {
81
+ "type": "array",
82
+ "items": {
83
+ "type": "object",
84
+ "additionalProperties": true
85
+ }
86
+ },
87
+ "footprintBounds": {
88
+ "type": "array",
89
+ "items": {
90
+ "type": "object",
91
+ "additionalProperties": true
92
+ }
93
+ },
94
+ "padDiagnostics": {
95
+ "type": "array",
96
+ "items": {
97
+ "type": "object",
98
+ "additionalProperties": true
99
+ }
100
+ },
101
+ "modelSuggestions": {
102
+ "type": "array",
103
+ "items": {
104
+ "type": "object",
105
+ "additionalProperties": true
106
+ }
107
+ },
108
+ "issues": {
109
+ "type": "array",
110
+ "items": {
111
+ "type": "object",
112
+ "additionalProperties": true
113
+ }
114
+ }
115
+ }
116
+ }
@@ -63,6 +63,9 @@
63
63
  "type": "object",
64
64
  "additionalProperties": true
65
65
  },
66
+ "compatibility": {
67
+ "$ref": "library_compatibility_a1.schema.json"
68
+ },
66
69
  "issues": {
67
70
  "type": "array",
68
71
  "items": {
@@ -10,7 +10,8 @@
10
10
  "recordTypes",
11
11
  "rawRecords",
12
12
  "opaqueRecords",
13
- "diagnostics"
13
+ "diagnostics",
14
+ "edgeCases"
14
15
  ],
15
16
  "properties": {
16
17
  "schema": {
@@ -25,6 +26,7 @@
25
26
  "rawRecordCount",
26
27
  "opaqueRecordCount",
27
28
  "diagnosticCount",
29
+ "edgeCaseCount",
28
30
  "itemCount",
29
31
  "status"
30
32
  ],
@@ -44,6 +46,9 @@
44
46
  "diagnosticCount": {
45
47
  "type": "number"
46
48
  },
49
+ "edgeCaseCount": {
50
+ "type": "number"
51
+ },
47
52
  "itemCount": {
48
53
  "type": "number"
49
54
  },
@@ -75,6 +80,12 @@
75
80
  "items": {
76
81
  "$ref": "#/$defs/diagnostic"
77
82
  }
83
+ },
84
+ "edgeCases": {
85
+ "type": "array",
86
+ "items": {
87
+ "$ref": "#/$defs/edgeCase"
88
+ }
78
89
  }
79
90
  },
80
91
  "$defs": {
@@ -207,6 +218,52 @@
207
218
  "type": "string"
208
219
  }
209
220
  }
221
+ },
222
+ "edgeCase": {
223
+ "type": "object",
224
+ "additionalProperties": true,
225
+ "required": ["code"],
226
+ "properties": {
227
+ "fileName": {
228
+ "type": "string"
229
+ },
230
+ "domain": {
231
+ "type": "string"
232
+ },
233
+ "code": {
234
+ "type": "string"
235
+ },
236
+ "feature": {
237
+ "type": "string"
238
+ },
239
+ "supportState": {
240
+ "type": "string"
241
+ },
242
+ "severity": {
243
+ "enum": ["info", "warning", "error"]
244
+ },
245
+ "message": {
246
+ "type": "string"
247
+ },
248
+ "source": {
249
+ "type": "string"
250
+ },
251
+ "sourceStream": {
252
+ "type": "string"
253
+ },
254
+ "sourceStorage": {
255
+ "type": "string"
256
+ },
257
+ "recordIndex": {
258
+ "type": "number"
259
+ },
260
+ "recordType": {
261
+ "type": "number"
262
+ },
263
+ "errorKind": {
264
+ "type": "string"
265
+ }
266
+ }
210
267
  }
211
268
  }
212
269
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "altium-toolkit",
3
- "version": "1.1.24",
3
+ "version": "1.1.26",
4
4
  "description": "Altium document parsing and non-interactive rendering utilities",
5
5
  "keywords": [
6
6
  "altium",
@@ -0,0 +1,65 @@
1
+ <!--
2
+ SPDX-FileCopyrightText: 2026 André Fiedler
3
+
4
+ SPDX-License-Identifier: CC-BY-SA-4.0
5
+ -->
6
+
7
+ # Library Compatibility Reports
8
+
9
+ Library compatibility reports provide deterministic, source-neutral QA over
10
+ parsed schematic symbol libraries and PCB footprint libraries. The report is
11
+ read-only: it never rewrites symbols, footprints, model references, or rendered
12
+ output.
13
+
14
+ ## Scope
15
+
16
+ The report focuses on compatibility signals that are useful across importer,
17
+ renderer, catalog, and review workflows:
18
+
19
+ - schematic pin electrical roles, decorative edge markers, hidden state, and
20
+ hidden-pin placement hints
21
+ - schematic symbol bounds, pin/body bounds, deterministic field anchor hints,
22
+ and visible field-placement risk rows
23
+ - PCB footprint bounds and padded courtyard-like bounds derived from recovered
24
+ pad and primitive geometry
25
+ - PCB pad diagnostics for top/bottom size mismatches, explicit zero-size pads,
26
+ unknown pad shapes, unresolved pad layers, and custom pad outline geometry
27
+ - package-name keys and pin-one rotation hints that can help downstream tools
28
+ suggest model matches when a footprint has no embedded or body-level model
29
+ reference
30
+
31
+ The report does not perform format conversion, file writing, model download,
32
+ interactive model binding, or application UI work.
33
+
34
+ ## Contract
35
+
36
+ `LibraryCompatibilityReportBuilder.build()` emits
37
+ `altium-toolkit.library.compatibility.a1` with these top-level arrays:
38
+
39
+ - `symbolPins`: normalized schematic-library pin compatibility rows
40
+ - `hiddenPins`: hidden pins with placement hints and source location metadata
41
+ - `symbolBounds`: per-symbol bounds, body bounds, pin bounds, source counts,
42
+ and deterministic field anchor hints
43
+ - `fieldPlacementRisks`: warning rows for visible designator/comment/value
44
+ fields placed inside symbol bounds
45
+ - `footprintBounds`: footprint-level bounds, courtyard bounds, and primitive
46
+ source counts
47
+ - `padDiagnostics`: warning rows for pad geometry and mapping problems
48
+ - `modelSuggestions`: package-key and rotation-hint rows for model matching by
49
+ host tools
50
+ - `issues`: flattened warning/info rows suitable for library QA summaries
51
+
52
+ PcbLib extraction also exposes `diagnostics.missingFootprints` rows when a
53
+ declared footprint name cannot be resolved to a compound-document storage. Each
54
+ row lists the declared name, attempted storage candidates, and reason. Parsed
55
+ PcbLib models surface the same rows at
56
+ `pcbLibrary.storageDiagnostics.missingFootprints`.
57
+
58
+ `LibraryQaReportBuilder.build()` composes compatibility issues into its
59
+ top-level `issues` array when the compatibility report finds non-empty issue
60
+ rows. Clean inputs keep the existing QA summary shape.
61
+
62
+ ## Testing Policy
63
+
64
+ Tests for this report use synthetic library objects only. They must not rely on
65
+ native library files or real project, customer, vendor, or product identifiers.
@@ -32,6 +32,7 @@ import { SchematicSheetParser } from './SchematicSheetParser.mjs'
32
32
  import { SchematicJunctionParser } from './SchematicJunctionParser.mjs'
33
33
  import { SchematicBusEntryParser } from './SchematicBusEntryParser.mjs'
34
34
  import { SchematicImageParser } from './SchematicImageParser.mjs'
35
+ import { SchematicImageDiagnosticsBuilder } from './SchematicImageDiagnosticsBuilder.mjs'
35
36
  import { SchematicNetlistBuilder } from './SchematicNetlistBuilder.mjs'
36
37
  import { SchematicRecordTypeRegistry } from './SchematicRecordTypeRegistry.mjs'
37
38
  import { SchematicComponentTextResolver } from './SchematicComponentTextResolver.mjs'
@@ -617,6 +618,9 @@ export class AltiumParser {
617
618
  recordIndexAwareRecords,
618
619
  arrayBuffer
619
620
  )
621
+ const imageDiagnosticsReport = SchematicImageDiagnosticsBuilder.build({
622
+ images
623
+ })
620
624
  const { thumbnails, diagnostics: thumbnailDiagnostics } =
621
625
  SchematicThumbnailParser.parse(arrayBuffer)
622
626
  const template = SchematicTemplateParser.parse(
@@ -832,7 +836,9 @@ export class AltiumParser {
832
836
  texts: anchoredTexts,
833
837
  pins,
834
838
  ports,
835
- junctions
839
+ junctions,
840
+ sheetEntries,
841
+ harnesses
836
842
  })
837
843
  const embeddedFiles = schematicExtraction?.embeddedFiles || null
838
844
  const nativeStreams = schematicExtraction?.nativeStreams || null
@@ -905,6 +911,7 @@ export class AltiumParser {
905
911
  junctions,
906
912
  busEntries,
907
913
  images,
914
+ imageDiagnostics: imageDiagnosticsReport,
908
915
  ...(thumbnails.length ? { thumbnails } : {}),
909
916
  nets,
910
917
  ownership,