altium-toolkit 1.1.22 → 1.1.23

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 (99) hide show
  1. package/README.md +34 -5
  2. package/docs/api.md +134 -23
  3. package/docs/model-format.md +174 -20
  4. package/docs/schemas/altium_toolkit/embedded_assets_a1.schema.json +56 -0
  5. package/docs/schemas/altium_toolkit/fixture_coverage_matrix_a1.schema.json +89 -0
  6. package/docs/schemas/altium_toolkit/geometry_bounds_a1.schema.json +86 -0
  7. package/docs/schemas/altium_toolkit/library_catalog_a1.schema.json +65 -0
  8. package/docs/schemas/altium_toolkit/library_diff_a1.schema.json +54 -0
  9. package/docs/schemas/altium_toolkit/library_inspection_a1.schema.json +94 -0
  10. package/docs/schemas/altium_toolkit/library_qa_a1.schema.json +4 -0
  11. package/docs/schemas/altium_toolkit/native_stream_inventory_a1.schema.json +66 -0
  12. package/docs/schemas/altium_toolkit/normalized_model_a1.schema.json +511 -1
  13. package/docs/schemas/altium_toolkit/parameter_record_inventory_a1.schema.json +84 -0
  14. package/docs/schemas/altium_toolkit/parser_diagnostics_a1.schema.json +63 -0
  15. package/docs/schemas/altium_toolkit/parser_value_verification_a1.schema.json +74 -0
  16. package/docs/schemas/altium_toolkit/pcb_class_report_a1.schema.json +79 -0
  17. package/docs/schemas/altium_toolkit/pcb_inspection_a1.schema.json +65 -0
  18. package/docs/schemas/altium_toolkit/pcb_net_membership_a1.schema.json +98 -0
  19. package/docs/schemas/altium_toolkit/project_bundle_a1.schema.json +3 -0
  20. package/docs/schemas/altium_toolkit/project_hierarchy_a1.schema.json +79 -0
  21. package/docs/schemas/altium_toolkit/unsupported_features_a1.schema.json +212 -0
  22. package/docs/testing.md +2 -0
  23. package/examples/README.md +21 -0
  24. package/examples/cli-utils.mjs +148 -0
  25. package/examples/corpus-smoke.mjs +523 -0
  26. package/examples/extract-bom.mjs +47 -0
  27. package/examples/generate-pnp.mjs +59 -0
  28. package/examples/inspect-board.mjs +70 -0
  29. package/examples/inspect-schematic.mjs +406 -0
  30. package/examples/library-catalog.mjs +115 -0
  31. package/examples/net-report.mjs +61 -0
  32. package/examples/validate-library.mjs +59 -0
  33. package/package.json +1 -1
  34. package/src/core/BinaryReader.mjs +213 -2
  35. package/src/core/altium/AltiumParser.mjs +352 -14
  36. package/src/core/altium/AltiumUnits.mjs +205 -0
  37. package/src/core/altium/AsciiRecordParser.mjs +9 -0
  38. package/src/core/altium/EmbeddedAssetReportBuilder.mjs +383 -0
  39. package/src/core/altium/FixtureCoverageMatrixBuilder.mjs +304 -0
  40. package/src/core/altium/GeometryBoundsReportBuilder.mjs +935 -0
  41. package/src/core/altium/LibraryCatalogArtifactBuilder.mjs +296 -0
  42. package/src/core/altium/LibraryDiffReportBuilder.mjs +260 -0
  43. package/src/core/altium/LibraryInspectionReportBuilder.mjs +156 -0
  44. package/src/core/altium/LibraryQaReportBuilder.mjs +374 -1
  45. package/src/core/altium/NativeStreamInventoryBuilder.mjs +177 -0
  46. package/src/core/altium/NormalizedModelSchema.mjs +3 -31
  47. package/src/core/altium/ParameterCollection.mjs +431 -0
  48. package/src/core/altium/ParameterRecordInventoryBuilder.mjs +274 -0
  49. package/src/core/altium/ParserCompatibilityFuzzer.mjs +106 -2
  50. package/src/core/altium/ParserDiagnosticNormalizer.mjs +213 -0
  51. package/src/core/altium/ParserErrors.mjs +90 -0
  52. package/src/core/altium/ParserFieldCoverageReportBuilder.mjs +656 -0
  53. package/src/core/altium/ParserUtils.mjs +24 -0
  54. package/src/core/altium/ParserValueVerificationReportBuilder.mjs +323 -0
  55. package/src/core/altium/PcbClassReportBuilder.mjs +366 -0
  56. package/src/core/altium/PcbInspectionReportBuilder.mjs +313 -0
  57. package/src/core/altium/PcbLayerGroups.mjs +308 -0
  58. package/src/core/altium/PcbLayerStackCustomDataParser.mjs +183 -0
  59. package/src/core/altium/PcbLayerStackInterchangeParser.mjs +473 -4
  60. package/src/core/altium/PcbLayerStackReadModelBuilder.mjs +83 -15
  61. package/src/core/altium/PcbLayerStackSourceMetadataParser.mjs +74 -4
  62. package/src/core/altium/PcbLibModelParser.mjs +20 -4
  63. package/src/core/altium/PcbLibStreamExtractor.mjs +49 -6
  64. package/src/core/altium/PcbModelParser.mjs +223 -4
  65. package/src/core/altium/PcbNetMembershipReportBuilder.mjs +270 -0
  66. package/src/core/altium/PcbStreamExtractor.mjs +130 -6
  67. package/src/core/altium/PcbTrackPrimitiveParser.mjs +66 -2
  68. package/src/core/altium/ProjectDesignBundleBuilder.mjs +15 -0
  69. package/src/core/altium/ProjectHierarchyReportBuilder.mjs +660 -0
  70. package/src/core/altium/ProjectNetlistExporter.mjs +2 -0
  71. package/src/core/altium/RawDataPreservationReportBuilder.mjs +348 -0
  72. package/src/core/altium/SchLibModelParser.mjs +840 -0
  73. package/src/core/altium/SchLibStreamExtractor.mjs +586 -0
  74. package/src/core/altium/SchematicBusEntryParser.mjs +3 -2
  75. package/src/core/altium/SchematicCodeSymbolParser.mjs +663 -0
  76. package/src/core/altium/SchematicConnectivityQaBuilder.mjs +177 -2
  77. package/src/core/altium/SchematicDisplayModeCatalogParser.mjs +10 -1
  78. package/src/core/altium/SchematicFieldCoverageReportBuilder.mjs +549 -0
  79. package/src/core/altium/SchematicHarnessParser.mjs +9 -3
  80. package/src/core/altium/SchematicHyperlinkParser.mjs +122 -0
  81. package/src/core/altium/SchematicNetlistBuilder.mjs +271 -8
  82. package/src/core/altium/SchematicOwnershipGraphParser.mjs +102 -3
  83. package/src/core/altium/SchematicPinParser.mjs +12 -45
  84. package/src/core/altium/SchematicPrimitiveParser.mjs +9 -14
  85. package/src/core/altium/SchematicQaReportBuilder.mjs +2 -0
  86. package/src/core/altium/SchematicRecordStreamParser.mjs +183 -0
  87. package/src/core/altium/SchematicRecordTypeRegistry.mjs +6 -1
  88. package/src/core/altium/SchematicSheetParser.mjs +8 -2
  89. package/src/core/altium/SchematicStreamExtractor.mjs +64 -25
  90. package/src/core/altium/SchematicTextOrientationResolver.mjs +76 -0
  91. package/src/core/altium/SchematicTextParser.mjs +28 -12
  92. package/src/core/altium/SchematicTextRunParser.mjs +81 -0
  93. package/src/core/altium/SchematicThumbnailParser.mjs +425 -0
  94. package/src/core/altium/UnsupportedFeatureReportBuilder.mjs +380 -0
  95. package/src/parser.mjs +35 -1
  96. package/src/renderers.mjs +1 -0
  97. package/src/ui/SchematicShapeRenderer.mjs +49 -6
  98. package/src/ui/SchematicSvgRenderer.mjs +37 -8
  99. package/src/ui/SchematicTypography.mjs +4 -3
package/README.md CHANGED
@@ -18,23 +18,34 @@ browser or Node-based tools.
18
18
 
19
19
  ## Features
20
20
 
21
- - Parse standalone native `.SchDoc`, `.PcbDoc`, `.PcbLib`, `.PrjPcb`, and
22
- `.IntLib` files from `ArrayBuffer`
23
- - Recover schematic records, PCB outlines, placements, PCB library footprints,
21
+ - Parse standalone native `.SchDoc`, `.PcbDoc`, `.SchLib`, `.PcbLib`,
22
+ `.PrjPcb`, and `.IntLib` files from `ArrayBuffer`
23
+ - Recover schematic records, PCB outlines, placements, schematic library
24
+ symbols, PCB library footprints,
24
25
  project document references, variants, parameters, primitives, embedded
25
26
  schematic images, component annotations from PrimitiveParameters/Text streams,
26
27
  PCB pad/via stack and hole-tolerance detail, via-protection sidecars, custom
27
28
  pad shape links, extended mask/paste sidecars, PCB union metadata, embedded
28
29
  PCB 3D payload metadata, PCB component provenance, differential-pair class
29
30
  joins, schematic directive semantics, barcode PCB text metadata, mechanical
30
- layer pairs, pick-and-place coordinate modes, PCB dimensions, project
31
+ layer pairs, pick-and-place coordinate modes, PCB dimensions, embedded-board
32
+ panel placements, placement rooms, project
31
33
  class-generation policy, project-level design bundles, annotation mappings,
32
34
  effective variant views, schematic/PCB ownership sidecars, deterministic
33
35
  wirelist/netlist exports, library render manifests, library lookup indexes,
36
+ library catalog artifacts, project hierarchy reports,
37
+ schematic-library section keys, pin side streams, compressed storage assets,
34
38
  schematic project-parameter text resolution, PCB QA statistics, structured
35
39
  diagnostics, and embedded PCB/PcbLib font payloads with basic text metrics
36
40
  - Preserve raw PCB primitive records through a read-only record registry so
37
- unsupported or partially decoded stream data remains inspectable
41
+ unsupported or partially decoded stream data remains inspectable; native OLE
42
+ stream inventories summarize known, unknown, consumed, and opaque streams
43
+ - Build deterministic parser field-coverage matrix, raw-data preservation,
44
+ parameter-record inventory, parser value-verification, normalized
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
38
49
  - Emit Circuit JSON arrays from parser roots, with non-serialized
39
50
  renderer-compatibility fields for existing consumers
40
51
  - Render semantically annotated schematic SVG, semantically annotated PCB SVG,
@@ -54,6 +65,14 @@ The package is published on npm as
54
65
  npm install altium-toolkit
55
66
  ```
56
67
 
68
+ GitHub Packages releases are published as `@sunbox/altium-toolkit`. Configure
69
+ the GitHub Packages registry for the `@sunbox` scope before installing:
70
+
71
+ ```bash
72
+ npm config set @sunbox:registry https://npm.pkg.github.com
73
+ npm install @sunbox/altium-toolkit
74
+ ```
75
+
57
76
  ## Usage
58
77
 
59
78
  ```js
@@ -90,11 +109,21 @@ import 'altium-toolkit/styles/altium-renderers.css'
90
109
  - [Normalized Model Schema](docs/schemas/altium_toolkit/normalized_model_a1.schema.json)
91
110
  - [Project Bundle Schema](docs/schemas/altium_toolkit/project_bundle_a1.schema.json)
92
111
  - [Netlist Schema](docs/schemas/altium_toolkit/netlist_a1.schema.json)
112
+ - [Parser Diagnostics Schema](docs/schemas/altium_toolkit/parser_diagnostics_a1.schema.json)
113
+ - [Parser Value Verification Schema](docs/schemas/altium_toolkit/parser_value_verification_a1.schema.json)
114
+ - [Geometry Bounds Schema](docs/schemas/altium_toolkit/geometry_bounds_a1.schema.json)
115
+ - [Fixture Coverage Matrix Schema](docs/schemas/altium_toolkit/fixture_coverage_matrix_a1.schema.json)
116
+ - [Unsupported Features Schema](docs/schemas/altium_toolkit/unsupported_features_a1.schema.json)
93
117
  - [Testing](docs/testing.md)
94
118
  - [Scope](spec/library-scope.md)
95
119
 
96
120
  ## Examples
97
121
 
122
+ - Read-only utility scripts:
123
+ `examples/inspect-board.mjs`, `examples/extract-bom.mjs`,
124
+ `examples/generate-pnp.mjs`, `examples/net-report.mjs`,
125
+ `examples/library-catalog.mjs`, `examples/validate-library.mjs`, and
126
+ `examples/corpus-smoke.mjs`
98
127
  - [Arduino Uno Altium example](examples/arduino-uno/) based on Mehdi
99
128
  KHALFALLAH's public
100
129
  [My-Arduino-UNO-Design](https://github.com/Mehdi-KHALFALLAH/My-Arduino-UNO-Design)
package/docs/api.md CHANGED
@@ -28,23 +28,26 @@ import { AltiumParser } from 'altium-toolkit/parser'
28
28
  const circuitJson = AltiumParser.parseArrayBuffer(fileName, arrayBuffer)
29
29
  ```
30
30
 
31
- `fileName` is used to infer schematic, PCB document, PCB footprint-library, PCB
32
- project, or integrated-library parsing from the extension. The parser accepts
33
- native `.SchDoc`, `.PcbDoc`, `.PcbLib`, `.PrjPcb`, and `.IntLib` bytes as an
34
- `ArrayBuffer` and returns a Circuit JSON element array. The returned array
35
- carries non-serialized renderer-compatibility fields such as `kind`, `fileType`,
36
- `schematic`, `pcb`, `pcbLibrary`, `project`, `integratedLibrary`, `summary`,
31
+ `fileName` is used to infer schematic, PCB document, schematic symbol-library,
32
+ PCB footprint-library, PCB project, or integrated-library parsing from the
33
+ extension. The parser accepts native `.SchDoc`, `.PcbDoc`, `.SchLib`,
34
+ `.PcbLib`, `.PrjPcb`, and `.IntLib` bytes as an `ArrayBuffer` and returns a
35
+ Circuit JSON element array. The returned array carries non-serialized
36
+ renderer-compatibility fields such as `kind`, `fileType`, `schematic`, `pcb`,
37
+ `schematicLibrary`, `pcbLibrary`, `project`, `integratedLibrary`, `summary`,
37
38
  `diagnostics`, and `bom` so existing renderers can consume parser output
38
39
  directly during the migration.
39
40
 
40
41
  PCB parsing reads the main primitive streams together with sidecar streams such
41
42
  as `PrimitiveParameters/Data`, `WideStrings6/Data`,
42
43
  `ExtendedPrimitiveInformation/Data`, `CustomShapes/Data`, `UnionNames/Data`,
43
- and `SmartUnions/Data`. Component parameters are joined by native primitive
44
+ `SmartUnions/Data`, `EmbeddedBoards6/Data`, and `Rooms6/Data`. Component parameters are joined by native primitive
44
45
  unique id, modern `Texts6` designator records may resolve their display string
45
46
  through the wide-string table, custom pad geometry is linked to anchor pads, and
46
47
  smart-union memberships are attached to referenced primitives before the
47
- normalized component list and BOM are built.
48
+ normalized component list and BOM are built. Embedded-board and room streams are
49
+ promoted to read-only `pcb.embeddedBoards` and `pcb.rooms` collections when
50
+ present.
48
51
 
49
52
  ```js
50
53
  import { CircuitJsonModelSchema } from 'altium-toolkit/parser'
@@ -58,21 +61,38 @@ Use `AltiumParser.parseArrayBufferToRendererModel(fileName, arrayBuffer)` when
58
61
  an integration still needs the legacy renderer model object. The
59
62
  `CircuitJsonModelAdapter` export also exposes `fromRendererModel()`,
60
63
  `toRendererModel()`, and `isCircuitJson()` for explicit conversions.
64
+ Use `AltiumParser.tryParseArrayBuffer()` or
65
+ `AltiumParser.tryParseArrayBufferToRendererModel()` when a batch integration
66
+ needs a non-throwing `{ ok, model, diagnostics }` envelope.
61
67
 
62
68
  Specialized parser helpers are exported for lower-level integrations, including
63
- `IntLibStreamExtractor`, `PcbBoardRegionSemanticsParser`,
64
- `PcbComponentPrimitiveIndexer`, `PcbCustomPadShapeParser`,
65
- `PcbDimensionParser`, `PcbEmbeddedFontExtractor`,
69
+ `AltiumUnits`, `IntLibStreamExtractor`, `FixtureCoverageMatrixBuilder`,
70
+ `GeometryBoundsReportBuilder`,
71
+ `ParameterCollection`, `ParameterRecordInventoryBuilder`,
72
+ `ParserDiagnosticNormalizer`,
73
+ `ParserFieldCoverageReportBuilder`, `ParserValueVerificationReportBuilder`,
74
+ `ParserCompatibilityFuzzer`, `NativeStreamInventoryBuilder`,
75
+ `RawDataPreservationReportBuilder`, `UnsupportedFeatureReportBuilder`,
76
+ `EmbeddedAssetReportBuilder`, `LibraryDiffReportBuilder`,
77
+ `LibraryInspectionReportBuilder`,
78
+ `PcbBoardRegionSemanticsParser`, `PcbComponentPrimitiveIndexer`,
79
+ `PcbCustomPadShapeParser`, `PcbDimensionParser`, `PcbEmbeddedFontExtractor`,
66
80
  `PcbExtendedPrimitiveInformationParser`, `PcbFontMetricsParser`,
67
- `LibraryRenderManifestBuilder`, `LibrarySearchIndex`,
68
- `PcbBomProfileBuilder`, `PcbLayerStackFidelityReportBuilder`,
69
- `PcbOwnershipGraphBuilder`, `PcbPadStackParser`, `PcbPickPlacePositionResolver`,
70
- `ProjectAnnotationParser`, `ProjectDesignBundleBuilder`,
81
+ `LibraryRenderManifestBuilder`, `LibraryCatalogArtifactBuilder`,
82
+ `LibrarySearchIndex`, `SchLibModelParser`, `SchLibStreamExtractor`,
83
+ `PcbBomProfileBuilder`, `PcbClassReportBuilder`,
84
+ `PcbInspectionReportBuilder`, `PcbLayerStackFidelityReportBuilder`,
85
+ `PcbLayerGroups`, `PcbNetMembershipReportBuilder`,
86
+ `PcbOwnershipGraphBuilder`, `PcbPadStackParser`,
87
+ `PcbPickPlacePositionResolver`, `ProjectAnnotationParser`,
88
+ `ProjectDesignBundleBuilder`, `ProjectHierarchyReportBuilder`,
71
89
  `ProjectNetlistExporter`, `ProjectVariantViewBuilder`,
72
90
  `PcbMechanicalLayerPairParser`, `PcbSpecialStringResolver`, `PcbUnionParser`,
73
91
  `PcbViaStackParser`, `PcbRuleParser`, `PcbRawRecordRegistry`,
74
- `PcbStatisticsBuilder`, `SchematicOwnershipGraphParser`, and
75
- `SchematicProjectParameterResolver`.
92
+ `PcbStatisticsBuilder`, `SchematicCodeSymbolParser`,
93
+ `SchematicOwnershipGraphParser`,
94
+ `SchematicProjectParameterResolver`, `SchematicRecordStreamParser`, and
95
+ `SchematicTextRunParser`.
76
96
  `PcbBoardRegionSemanticsParser` exposes the substack and bending-line
77
97
  normalization used by `.PcbDoc` models. `PcbComponentPrimitiveIndexer` exposes
78
98
  the native component-index grouping used to populate
@@ -83,6 +103,9 @@ parser-only Dimensions6 normalization used by `.PcbDoc` parsing.
83
103
  `SchematicOwnershipGraphParser` and `PcbOwnershipGraphBuilder` expose the
84
104
  read-only ownership sidecars that parser roots attach under
85
105
  `schematic.ownership` and `pcb.ownership`.
106
+ `SchematicCodeSymbolParser` exposes auxiliary schematic code-symbol, entry,
107
+ text, and marker records through the parser root's `schematic.codeSymbols`
108
+ sidecar.
86
109
  `PcbPickPlacePositionResolver` exposes the component-origin and pad-anchor
87
110
  coordinate modes used by the normalized `pnp` model.
88
111
  `ProjectDesignBundleBuilder` composes separately parsed project, schematic, and
@@ -93,7 +116,11 @@ and net views. `ProjectAnnotationParser` parses read-only annotation mapping
93
116
  files, and `ProjectNetlistExporter` emits deterministic wirelist and richer
94
117
  JSON netlist contracts from normalized bundles. The JSON contract includes
95
118
  schematic source sheets, graphical elements, aliases, terminal endpoints,
96
- hierarchy paths, and PCB net-table provenance when present.
119
+ hierarchy paths, and PCB net-table provenance when present. Alias arrays include
120
+ explicit schematic labels and additive unnamed-net candidates when available.
121
+ `ProjectHierarchyReportBuilder` emits a deterministic sheet hierarchy report
122
+ from parsed project and schematic models, including roots, child sheet links,
123
+ missing-sheet diagnostics, cycles, repeated references, and sheet-entry names.
97
124
  `PcbMechanicalLayerPairParser`
98
125
  exposes the mechanical-layer flip map used by `.PcbDoc` parsing. The font
99
126
  helpers expose the same
@@ -105,11 +132,70 @@ extractors.
105
132
  normalization. `PcbLayerStackFidelityReportBuilder` classifies layer-stack
106
133
  source evidence and unsupported native-regeneration limits for deterministic
107
134
  QA/reporting.
108
- `LibraryRenderManifestBuilder` and `LibrarySearchIndex` expose deterministic
109
- SchLib/PcbLib render/export manifests plus exact, keyword, and fuzzy lookup
110
- helpers. `PcbStatisticsBuilder` emits board QA summaries used by `.PcbDoc`
111
- models. `SchematicProjectParameterResolver` resolves dot-prefixed and
135
+ `PcbLayerGroups` classifies legacy PCB layer ids into stable groups such as
136
+ copper, overlay, paste, solder mask, mechanical, drill, and multi-layer for
137
+ filtering and reporting. It also exposes deterministic colors and draw
138
+ priorities for report and renderer-side layer ordering. `AltiumUnits` converts
139
+ common Altium lengths between mil, millimeter, inch, and raw fixed-point
140
+ coordinate units.
141
+ `ParserFieldCoverageReportBuilder` builds a deterministic report of observed,
142
+ mapped, missing, and unsupported native fields from explicit source records or
143
+ parser roots that carry source-record sidecars. Reports include a compact matrix
144
+ view with per-family coverage status and mapped-field ratios. Field matching is
145
+ case-insensitive, while report rows preserve observed source spelling.
146
+ `ParameterRecordInventoryBuilder` scans raw pipe/backtick parameter records into
147
+ delimiter-aware field rows, duplicate-key rollups, UTF-8 marker counts, and
148
+ typed scalar hints without changing parser semantics.
149
+ `ParameterCollection` exposes duplicate-preserving, case-insensitive typed
150
+ reads over parsed parameter fields for integrations that need local lookup
151
+ helpers without writer behavior.
152
+ `ParserValueVerificationReportBuilder` compares curated expected path/value
153
+ assertions against parser output, producing fixture-gate reports that classify
154
+ missing paths separately from mismatched values.
155
+ `ParserDiagnosticNormalizer` converts string, `Error`, and object diagnostics
156
+ into a shared envelope with stable `code`, `severity`, `message`, source stream,
157
+ record index, typed error kind, field, and context metadata. Typed parser error
158
+ classes include `AltiumParseError`, `AltiumCorruptFileError`, and
159
+ `AltiumUnsupportedFeatureError`.
160
+ `GeometryBoundsReportBuilder` emits `altium-toolkit.geometry-bounds.a1` reports
161
+ with deterministic axis-aligned bounds for common parsed schematic and PCB
162
+ primitive families. `FixtureCoverageMatrixBuilder` emits
163
+ `altium-toolkit.fixture-coverage-matrix.a1` reports from synthetic fixture
164
+ manifests, including required coverage/contract gaps and native-asset policy
165
+ status.
166
+ `RawDataPreservationReportBuilder` summarizes preserved raw primitive records
167
+ unknown records, and opaque schematic/library records without copying raw
168
+ payload bytes into the report. When parser roots carry native stream
169
+ inventories, it also reports known/unknown stream counts, unconsumed stream
170
+ counts, and stream byte totals separately from raw-record payload bytes.
171
+ `UnsupportedFeatureReportBuilder` emits
172
+ `altium-toolkit.unsupported-features.a1` summaries of unsupported record
173
+ families, unsupported or unparsed raw records, opaque preserved schematic rows,
174
+ and unsupported diagnostics across parser roots.
175
+ `NativeStreamInventoryBuilder` emits metadata-only OLE stream rows with byte
176
+ length, checksum, known/unknown classification, and consumed status.
177
+ `SchematicRecordStreamParser` exposes framed schematic stream parsing with
178
+ opaque-frame preservation for lower-level extractors.
179
+ `ParserCompatibilityFuzzer` runs deterministic malformed,
180
+ wrong-reader, and sparse-input cases against parser entrypoints for parser QA.
181
+ `EmbeddedAssetReportBuilder` emits unified embedded-asset inventories across
182
+ parser roots, and `LibraryDiffReportBuilder` compares parsed symbol and
183
+ footprint libraries by name, counts, and parameters.
184
+ `LibraryInspectionReportBuilder` composes library inventory and QA findings
185
+ into one stable artifact. `SchLibStreamExtractor` and `SchLibModelParser`
186
+ expose native schematic-symbol library recovery, including section keys,
187
+ file-header font metadata, pin side streams, compressed storage assets, and
188
+ implementation child rows where available.
189
+ `LibraryRenderManifestBuilder`, `LibraryCatalogArtifactBuilder`, and
190
+ `LibrarySearchIndex` expose deterministic SchLib/PcbLib render/export
191
+ manifests, static catalog artifacts, search metadata, plus exact, keyword, and
192
+ 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
112
196
  equals-prefixed schematic special strings for parser and SVG integrations.
197
+ `SchematicTextRunParser` parses schematic backslash suffix markers into display
198
+ text plus overline run metadata reused by pin and text rendering.
113
199
 
114
200
  ## Library Exporters
115
201
 
@@ -185,7 +271,8 @@ import {
185
271
  PcbSvgRenderer,
186
272
  PcbSideResolvedRenderModel,
187
273
  preparePcbSideResolvedRenderModel,
188
- BomTableRenderer
274
+ BomTableRenderer,
275
+ PcbLayerGroups
189
276
  } from 'altium-toolkit/renderers'
190
277
  ```
191
278
 
@@ -202,6 +289,9 @@ import {
202
289
  `side: 'back'` to project bottom components, documentation layers, copper
203
290
  primitives, vias, and pad stack geometry into the top-facing render surface.
204
291
  - `BomTableRenderer.render(rows)` returns grouped BOM table markup.
292
+ - `PcbLayerGroups` is also exported from the renderer entrypoint for
293
+ layer-filter and layer-visibility code that should not depend on parser
294
+ internals.
205
295
 
206
296
  Renderer output is deterministic string markup. The library does not attach DOM
207
297
  events or mutate a host document.
@@ -251,3 +341,24 @@ import {
251
341
 
252
342
  The library intentionally does not create Three.js objects, canvases, controls,
253
343
  or event listeners.
344
+
345
+ ## Read-only CLI Examples
346
+
347
+ The `examples/` directory includes small Node.js scripts for common
348
+ non-interactive workflows:
349
+
350
+ ```bash
351
+ node examples/inspect-board.mjs board.PcbDoc --json
352
+ node examples/inspect-schematic.mjs design.SchDoc --view all --json
353
+ node examples/extract-bom.mjs design.SchDoc
354
+ node examples/generate-pnp.mjs board.PcbDoc
355
+ node examples/net-report.mjs design.SchDoc --json
356
+ node examples/library-catalog.mjs footprints.PcbLib
357
+ node examples/validate-library.mjs footprints.PcbLib --json
358
+ node examples/corpus-smoke.mjs local-corpus --coverage --json
359
+ ```
360
+
361
+ Each script reads one input file and writes text, CSV, or JSON to stdout. The
362
+ corpus smoke script reads a caller-provided directory and can include aggregate
363
+ parser coverage and field-gap counters. The scripts are examples of library
364
+ usage, not installed package binaries.
@@ -64,13 +64,14 @@ the object form can call
64
64
 
65
65
  - `schema`: normalized model schema id, currently
66
66
  `urn:altium-toolkit:normalized-model:a1`
67
- - `kind`: `schematic`, `pcb`, `pcb-library`, `project`,
67
+ - `kind`: `schematic`, `pcb`, `schematic-library`, `pcb-library`, `project`,
68
68
  `integrated-library`, or `design-bundle`
69
- - `fileType`: `SchDoc`, `PcbDoc`, `PcbLib`, `PrjPcb`, `IntLib`, or
69
+ - `fileType`: `SchDoc`, `PcbDoc`, `SchLib`, `PcbLib`, `PrjPcb`, `IntLib`, or
70
70
  `ProjectDesignBundle`
71
71
  - `fileName`: original file name passed to the parser
72
72
  - `diagnostics`: parser warnings and recovery notes. Each diagnostic carries a
73
- machine-readable `code` plus `severity` and `message`.
73
+ machine-readable `code`, `severity`, and `message`; entries may also carry
74
+ source stream, storage, record-index, field, and context metadata.
74
75
  - `bom`: grouped component metadata where available
75
76
 
76
77
  ## Schema Contracts
@@ -83,6 +84,102 @@ The serialized parser return value follows the upstream
83
84
  [`tscircuit/circuit-json`](https://github.com/tscircuit/circuit-json) element
84
85
  array convention.
85
86
 
87
+ ## Parser Utility Reports
88
+
89
+ `ParserFieldCoverageReportBuilder.build()` emits
90
+ `altium-toolkit.parser-field-coverage.a1` reports. Rows are grouped by parser
91
+ domain and primitive family, with observed native fields split into mapped,
92
+ missing, and unsupported sets. The report also carries a compact matrix with
93
+ per-family coverage status and mapped-field ratios. Source field matching is
94
+ case-insensitive while observed field names preserve their original spelling.
95
+ It is intended for fixture coverage and parser QA; it does not mutate parser
96
+ output or require native source files in tests.
97
+
98
+ `ParameterRecordInventoryBuilder.build()` emits
99
+ `altium-toolkit.parameter-record-inventory.a1` reports. Rows expose raw keys,
100
+ normalized keys, values, delimiter type, backtick nesting level, duplicate
101
+ occurrence numbers, UTF-8 key markers, and simple boolean/integer/number hints.
102
+ Duplicate-key rollups include first and last values so consumers can audit
103
+ parser policies without changing parsed model output.
104
+ `ParameterCollection.parse()` provides the corresponding local read helper for
105
+ duplicate-preserving, case-insensitive string, integer, number, boolean, code,
106
+ and coordinate-style parameter access.
107
+
108
+ `ParserValueVerificationReportBuilder.build()` emits
109
+ `altium-toolkit.parser-value-verification.a1` reports for curated fixture
110
+ manifests. Each assertion targets one explicit model path and expected value,
111
+ then reports pass, missing-path, or mismatch status. This complements field
112
+ coverage by checking recovered values rather than only field presence.
113
+
114
+ `ParserDiagnosticNormalizer.buildReport()` emits
115
+ `altium-toolkit.parser-diagnostics.a1` reports from string, `Error`, or object
116
+ diagnostics. The normalized envelope uses stable codes, `info`/`warning`/`error`
117
+ severities, messages, and optional source-stream, storage, record-index, field,
118
+ typed error-kind, field, and context keys.
119
+
120
+ `GeometryBoundsReportBuilder.build()` emits
121
+ `altium-toolkit.geometry-bounds.a1` reports from parsed schematic and PCB
122
+ document models. Rows identify document, domain, primitive family, primitive
123
+ index, status, and rounded axis-aligned bounds; the summary carries the union
124
+ bounds and missing-bounds count for QA tooling.
125
+
126
+ `FixtureCoverageMatrixBuilder.build()` emits
127
+ `altium-toolkit.fixture-coverage-matrix.a1` reports from synthetic fixture
128
+ manifests. Coverage rows and contract rows list fixture keys, required flags,
129
+ and missing gaps, while the policy section records the manifest asset policy
130
+ and native-asset count.
131
+
132
+ `RawDataPreservationReportBuilder.build()` emits
133
+ `altium-toolkit.raw-data-preservation.a1` reports. It summarizes preserved raw
134
+ primitive records, unknown records, and opaque schematic/library records by
135
+ count, parse state, support state, and byte length without repeating the base64
136
+ payloads already carried by parser models. When parser roots include
137
+ `nativeStreams`, the report adds native-stream counts and byte totals without
138
+ folding those stream bytes into the raw-record payload total.
139
+
140
+ `UnsupportedFeatureReportBuilder.build()` emits
141
+ `altium-toolkit.unsupported-features.a1` reports. It collects unsupported
142
+ schematic record type summaries, unsupported or unparsed raw records, opaque
143
+ preserved records, and unsupported diagnostics so parser coverage gaps can be
144
+ reviewed separately from general raw-data preservation.
145
+
146
+ `NativeStreamInventoryBuilder.buildFromStreams()` emits
147
+ `altium-toolkit.native-stream-inventory.a1` reports for OLE stream maps. Parser
148
+ roots expose the same metadata under `schematic.nativeStreams`,
149
+ `pcb.nativeStreams`, `schematicLibrary.nativeStreams`, and
150
+ `pcbLibrary.nativeStreams` when the source file was parsed from a compound
151
+ document. Rows include stream path, storage, leaf name, byte length, checksum,
152
+ known/unknown classification, and consumed status.
153
+
154
+ `EmbeddedAssetReportBuilder.build()` emits
155
+ `altium-toolkit.embedded-assets.a1` reports that normalize schematic images,
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.
160
+ `LibraryInspectionReportBuilder.build()` emits
161
+ `altium-toolkit.library.inspection.a1` reports that combine library inventory
162
+ rows with duplicate, stale-link, missing-model, lint, and merge-plan QA
163
+ summaries.
164
+
165
+ `PcbNetMembershipReportBuilder.build()` emits
166
+ `altium-toolkit.pcb.net-membership.a1` reports that count observed copper
167
+ ownership by net across pads, tracks, arcs, vias, fills, regions, and polygons.
168
+ Declared-but-empty nets, observed-but-undeclared nets, unowned primitives, and
169
+ possible unrouted pad-only nets are split into deterministic lists.
170
+ `PcbClassReportBuilder.build()` emits
171
+ `altium-toolkit.pcb.class-report.a1` reports that summarize PCB classes by
172
+ kind, enabled state, member resolution, empty classes, and unresolved members.
173
+ `PcbInspectionReportBuilder.build()` emits `altium-toolkit.pcb.inspection.a1`
174
+ 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.
177
+
178
+ `PcbLayerGroups` provides stable layer-group names, deterministic display
179
+ colors, and draw priorities for legacy PCB layer ids. `AltiumUnits` provides
180
+ deterministic mil, millimeter, inch, and raw coordinate conversions for report
181
+ output.
182
+
86
183
  ## Schematic Fields
87
184
 
88
185
  Schematic documents include recovered `schematic` data with sheet metadata,
@@ -97,9 +194,18 @@ pie-chart primitives are exposed as first-class `schematic.beziers` and
97
194
  `schematic.pies` arrays for deterministic SVG rendering. Rounded rectangles are
98
195
  exposed through `schematic.roundedRectangles`, and IEEE drawing symbols are
99
196
  exposed through `schematic.ieeeSymbols` with a stable `symbolName`. The registry
100
- also names schematic families such as notes, compile masks, harness records,
101
- blankets, and hyperlinks so consumers can inspect supported parser coverage
102
- without stringly typed local maps.
197
+ also names schematic families such as notes, compile masks, harness records, and
198
+ blankets so consumers can inspect supported parser coverage without stringly
199
+ typed local maps. Hyperlink records are exposed as first-class
200
+ `schematic.hyperlinks` entries with URL, display text, location, font/color, and
201
+ owner/source metadata.
202
+
203
+ `schematic.qa.fieldCoverage` provides a parser-development coverage sidecar for
204
+ additive native fields that are not in the toolkit's current schematic field
205
+ catalog. It groups unrecognized field names by record type and stable record
206
+ keys without emitting top-level diagnostics. Known schematic fields are matched
207
+ case-insensitively, so uppercase native keys do not inflate the unrecognized
208
+ field counts.
103
209
 
104
210
  Record-28 text frames are preserved both as drawable note text and as a
105
211
  read-only `schematic.textFrames` contract with frame rectangle, alignment,
@@ -115,9 +221,14 @@ distinguish hidden directive metadata from visible sheet text.
115
221
 
116
222
  `schematic.ownership` is a read-only sidecar built from raw record
117
223
  `OwnerIndex` and `IndexInSheet` values. It exposes stable record keys,
118
- `childrenByParentKey`, `parentsByChildKey`, and `recordsByIndexInSheet` so
119
- consumers can inspect component, sheet-symbol, and directive children without
120
- reimplementing owner-index lookup rules.
224
+ `childrenByParentKey`, `parentsByChildKey`, `recordsByIndexInSheet`, and a
225
+ nested `hierarchy` projection so consumers can inspect component, sheet-symbol,
226
+ and directive children without reimplementing owner-index lookup rules.
227
+
228
+ `schematic.codeSymbols` is an optional read-only sidecar for auxiliary
229
+ code-symbol style records. It preserves block geometry, entry pins, title/source
230
+ text rows, routine and memory metadata, and marker points without affecting
231
+ schematic SVG rendering or netlist merging.
121
232
 
122
233
  Schematic project parameters and special strings can be resolved without
123
234
  mutating source parser models through `SchematicProjectParameterResolver`.
@@ -133,10 +244,17 @@ family, and matching top-level warning diagnostic.
133
244
 
134
245
  The normalized schematic net model is single-sheet. `schematic.nets` is built
135
246
  from the wires, labels, ports, pins, junctions, bus entries, and sheet entries
136
- present in the parsed `.SchDoc`. Project-level hierarchy, repeated channels,
137
- variants, and cross-sheet compilation metadata are preserved through the
138
- `.PrjPcb` parser, but this schema does not currently emit a compiled
247
+ present in the parsed `.SchDoc`. Nets with explicit labels keep those labels as
248
+ their canonical `name`; unnamed nets keep their stable `UnknownNetN` name and
249
+ may add `autoName`, `autoNameSource`, and `aliasCandidates` from connected
250
+ component pins for display/search use. Project-level hierarchy, repeated
251
+ channels, variants, and cross-sheet compilation metadata are preserved through
252
+ the `.PrjPcb` parser, but this schema does not currently emit a compiled
139
253
  multi-sheet design netlist.
254
+ `schematic.connectivityQa` reports read-only connectivity findings, including
255
+ implicit generated net names, dangling labels, orphan ports, unconnected pins,
256
+ ambiguous junctions, and un-junctioned tee contacts where one wire endpoint
257
+ touches another wire interior without an authored junction.
140
258
 
141
259
  Embedded schematic images preserve the raw record geometry and expose
142
260
  browser-facing payload metadata. When an embedded stream contains a native
@@ -144,6 +262,14 @@ PNG/JPEG/GIF/SVG/WebP payload alongside a preview, `mimeType` and `dataBase64`
144
262
  refer to the native payload while `sourceMimeType` records the preview format.
145
263
  Alpha-bearing 32-bit BMP previews are converted to PNG and marked with
146
264
  `hasAlpha` so SVG renderers can display transparency deterministically.
265
+ When a schematic OLE container exposes preview metadata, `schematic.thumbnails`
266
+ contains PNG thumbnail sidecars with `kind`, dimensions, `sourceStream`,
267
+ `pixelFormat`, `mimeType`, and `dataBase64` fields.
268
+
269
+ When a native framed schematic stream contains non-property frames,
270
+ `schematic.opaqueRecords` preserves compact metadata for those unmodelled
271
+ payloads. Each row carries source stream context, frame type, record index, byte
272
+ length, and base64 payload data for downstream read-only diagnostics.
147
273
 
148
274
  ## PCB Fields
149
275
 
@@ -218,6 +344,11 @@ dielectric thickness, dielectric constant, and dissipation factor, plus
218
344
  aggregate material and role counts. The `planning` section summarizes keepout
219
345
  regions, room-related rules and names, board-region flex/rigid counts, locked
220
346
  3D regions, bending-line counts, and board-region layer-stack usage.
347
+ Native panel and placement streams are exposed as `pcb.embeddedBoards` and
348
+ `pcb.rooms` when present. Embedded-board rows preserve source document path,
349
+ placement layer, rotation, mirroring, array counts and spacing, unique id, and
350
+ selected policy flags. Room rows preserve name, unique id, members, and simple
351
+ bounds when available.
221
352
 
222
353
  Decoded pad primitives preserve raw `padFlags` plus named tenting and testpoint
223
354
  flags. Pad shape codes are kept as raw `shapeTop` / `shapeMid` / `shapeBottom`
@@ -301,6 +432,19 @@ callers that do not need the full geometry.
301
432
 
302
433
  ## PCB Library Fields
303
434
 
435
+ Schematic symbol libraries include recovered `schematicLibrary` data with a
436
+ library header, file-header metadata, section keys, stream names, ordered
437
+ `symbols`, lookup `indexes`, embedded file inventory, opaque native frames,
438
+ render manifest, and library QA report. Each symbol exposes source storage,
439
+ pins, parts, parameters, implementation rows, primitive summaries, and
440
+ referenced embedded assets where available. Pin rows preserve side-stream
441
+ metadata such as fractional location/length, descriptions, package length,
442
+ symbol line width, text placement, and pin-function hints when those streams are
443
+ present.
444
+ `schematicLibrary.indexes.symbolsByName` provides read-only symbol lookup and
445
+ search metadata, while `schematicLibrary.renderManifest` lists deterministic
446
+ symbol render outputs and embedded asset descriptors.
447
+
304
448
  PCB footprint libraries include recovered `pcbLibrary` data with library header
305
449
  properties, optional SectionKeys mappings, ComponentParamsTOC entries, and an
306
450
  ordered `footprints` list. Each footprint exposes its source storage name,
@@ -329,8 +473,13 @@ preserved versus stripped parameter names and stripped implementation keys.
329
473
  `LibraryRenderManifestBuilder.buildSchematicTemplateExtractionManifest()`
330
474
  summarizes template identity, owned records, fonts, title-block fields, and
331
475
  missing template parameters without generating template files.
332
- `LibrarySearchIndex` provides exact, keyword, and fuzzy symbol/footprint lookup
333
- helpers over parsed library read models.
476
+ `LibraryCatalogArtifactBuilder.build()` emits
477
+ `altium-toolkit.library.catalog.a1` artifacts for parsed schematic and PCB
478
+ libraries. The artifact includes deterministic entries, QA issue badges,
479
+ search-index rows, preview SVG keys from render manifests, and a static HTML
480
+ catalog string with no server or runtime interaction. `LibrarySearchIndex`
481
+ provides exact, keyword, and fuzzy symbol/footprint lookup helpers over parsed
482
+ library read models.
334
483
 
335
484
  ## Project Fields
336
485
 
@@ -354,9 +503,13 @@ should combine project metadata with separately parsed schematic documents.
354
503
  `ProjectDesignBundleBuilder.build({ projectModel, documentModels,
355
504
  annotationModels })` composes already parsed project, schematic, PCB, and
356
505
  annotation models into a `design-bundle` payload. The bundle exposes `project`,
357
- `variants`, `sheets`, `components`, `schematic_hierarchy`, `pnp`, `nets`,
358
- `annotations`, and `indexes` so multi-document consumers can use one normalized
359
- JSON object above single-document parser output. Passing `variantName` adds
506
+ `variants`, `sheets`, `components`, `schematic_hierarchy`,
507
+ `schematicHierarchyReport`, `pnp`, `nets`, `annotations`, and `indexes` so
508
+ multi-document consumers can use one normalized JSON object above
509
+ single-document parser output. `ProjectHierarchyReportBuilder.build()` emits
510
+ the richer hierarchy report directly from parsed project and schematic models,
511
+ including child sheet links, missing sheets, cycles, repeated references,
512
+ roots, and sheet-entry names. Passing `variantName` adds
360
513
  `effectiveVariant`, which applies DNP rows, alternate fitted rows, parameter
361
514
  overrides, and annotation designator mappings to BOM, PnP, component, and net
362
515
  views without mutating the source parser models. `ProjectNetlistExporter` emits
@@ -365,7 +518,8 @@ effective variant view. The wirelist remains a compact line-oriented
365
518
  `component.pin` view. The JSON netlist also carries aliases, auto-named flags,
366
519
  schematic source sheets, graphical source elements, terminal endpoints,
367
520
  hierarchy paths, and PCB net-table provenance when the bundle includes those
368
- details.
521
+ details. Alias lists include explicit schematic labels and additive unnamed-net
522
+ alias candidates when present.
369
523
 
370
524
  ## SVG And 3D Contracts
371
525
 
@@ -410,5 +564,5 @@ Parser fixes may add detail, but existing field names and shapes should stay
410
564
  compatible unless a new schema id explicitly documents a model migration.
411
565
  Focused machine-readable schemas are available under
412
566
  `docs/schemas/altium_toolkit/` for the normalized root plus focused project,
413
- netlist, SVG, PCB review, layer-stack, Draftsman, library, and CI/reporting
414
- contracts.
567
+ netlist, SVG, PCB review, layer-stack, Draftsman, library, parser QA,
568
+ inspection, unsupported-feature, and CI/reporting contracts.
@@ -0,0 +1,56 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "altium-toolkit.embedded-assets.a1",
4
+ "title": "Altium Toolkit Embedded Assets A1",
5
+ "type": "object",
6
+ "additionalProperties": true,
7
+ "required": ["schema", "summary", "assets"],
8
+ "properties": {
9
+ "schema": {
10
+ "const": "altium-toolkit.embedded-assets.a1"
11
+ },
12
+ "summary": {
13
+ "type": "object",
14
+ "additionalProperties": true
15
+ },
16
+ "assets": {
17
+ "type": "array",
18
+ "items": {
19
+ "type": "object",
20
+ "additionalProperties": true,
21
+ "required": [
22
+ "modelFileName",
23
+ "modelKind",
24
+ "kind",
25
+ "name",
26
+ "format",
27
+ "sourceStream",
28
+ "byteLength"
29
+ ],
30
+ "properties": {
31
+ "modelFileName": {
32
+ "type": "string"
33
+ },
34
+ "modelKind": {
35
+ "type": "string"
36
+ },
37
+ "kind": {
38
+ "type": "string"
39
+ },
40
+ "name": {
41
+ "type": "string"
42
+ },
43
+ "format": {
44
+ "type": "string"
45
+ },
46
+ "sourceStream": {
47
+ "type": "string"
48
+ },
49
+ "byteLength": {
50
+ "type": "number"
51
+ }
52
+ }
53
+ }
54
+ }
55
+ }
56
+ }