@intelligentelectron/pcb-lens 0.0.6 → 0.0.8
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.
- package/CHANGELOG.md +21 -7
- package/dist/tools/lib/types.d.ts +14 -7
- package/dist/tools/lib/types.d.ts.map +1 -1
- package/dist/tools/query-net.d.ts +2 -2
- package/dist/tools/query-net.d.ts.map +1 -1
- package/dist/tools/query-net.js +153 -50
- package/dist/tools/query-net.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,27 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.0.8] - 2026-02-27
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- `query_net` now groups pin connectivity by component refdes (`pins: { [refdes]: string[] }`) to reduce payload size
|
|
13
|
+
- `query_net` now omits empty routing/via arrays and zero-value summary fields (`totalSegments`, `totalVias`)
|
|
14
|
+
- `query_net` now rejects patterns that match all nets and directs callers to `get_design_overview` for discovery
|
|
15
|
+
|
|
16
|
+
## [0.0.7] - 2026-02-27
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- `query_net` now extracts pins from `<LogicalNet>` sections instead of only `<LayerFeature>/<Set>`, which returned empty pin arrays
|
|
21
|
+
- `query_net` now extracts layer usage from `<PhyNetPoint>` sections, fixing empty `layersUsed` for nets without routing segments
|
|
22
|
+
- `query_net` now returns all nets matching the regex pattern instead of only the first match
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- `query_net` return type changed from single `QueryNetResult` to `QueryNetsResult` wrapper with `pattern`, `units`, and `matches` array (consistent with `query_components`)
|
|
27
|
+
- Non-matching patterns now return `{ matches: [] }` instead of an error
|
|
28
|
+
|
|
8
29
|
## [0.0.6] - 2026-02-27
|
|
9
30
|
|
|
10
31
|
### Added
|
|
@@ -69,10 +90,3 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
69
90
|
- Test fixture download script for IPC-2581 consortium samples
|
|
70
91
|
- Release automation with CI workflows and binary compilation
|
|
71
92
|
- Integration tests against IPC-2581 consortium fixtures
|
|
72
|
-
|
|
73
|
-
[0.0.6]: https://github.com/IntelligentElectron/pcb-lens/releases/tag/v0.0.6
|
|
74
|
-
[0.0.5]: https://github.com/IntelligentElectron/pcb-lens/releases/tag/v0.0.5
|
|
75
|
-
[0.0.4]: https://github.com/IntelligentElectron/pcb-lens/releases/tag/v0.0.4
|
|
76
|
-
[0.0.3]: https://github.com/IntelligentElectron/pcb-lens/releases/tag/v0.0.3
|
|
77
|
-
[0.0.2]: https://github.com/IntelligentElectron/pcb-lens/releases/tag/v0.0.2
|
|
78
|
-
[0.0.1]: https://github.com/IntelligentElectron/pcb-lens/releases/tag/v0.0.1
|
|
@@ -113,18 +113,25 @@ export interface RenderNetResult {
|
|
|
113
113
|
};
|
|
114
114
|
}
|
|
115
115
|
/**
|
|
116
|
-
*
|
|
116
|
+
* Per-net result from query_net tool.
|
|
117
117
|
*/
|
|
118
118
|
export interface QueryNetResult {
|
|
119
119
|
netName: string;
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
totalVias: number;
|
|
120
|
+
pins: Record<string, string[]>;
|
|
121
|
+
routing?: NetRouteInfo[];
|
|
122
|
+
vias?: NetViaInfo[];
|
|
123
|
+
totalSegments?: number;
|
|
124
|
+
totalVias?: number;
|
|
126
125
|
layersUsed: string[];
|
|
127
126
|
}
|
|
127
|
+
/**
|
|
128
|
+
* Result from query_net tool (multi-match wrapper).
|
|
129
|
+
*/
|
|
130
|
+
export interface QueryNetsResult {
|
|
131
|
+
pattern: string;
|
|
132
|
+
units: string;
|
|
133
|
+
matches: QueryNetResult[];
|
|
134
|
+
}
|
|
128
135
|
/**
|
|
129
136
|
* Detected Cadence SPB installation.
|
|
130
137
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/tools/lib/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,eAAO,MAAM,aAAa,GAAI,QAAQ,OAAO,KAAG,MAAM,IAAI,WACY,CAAC;AAEvE;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,MAAM;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE;QACL,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,MAAM,EAAE,CAAC;KACtB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/tools/lib/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
-
import type { ErrorResult,
|
|
3
|
-
export declare const queryNet: (filePath: string, pattern: string) => Promise<
|
|
2
|
+
import type { ErrorResult, QueryNetsResult } from "./lib/types.js";
|
|
3
|
+
export declare const queryNet: (filePath: string, pattern: string) => Promise<QueryNetsResult | ErrorResult>;
|
|
4
4
|
export declare const register: (server: McpServer) => void;
|
|
5
5
|
//# sourceMappingURL=query-net.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-net.d.ts","sourceRoot":"","sources":["../../src/tools/query-net.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"query-net.d.ts","sourceRoot":"","sources":["../../src/tools/query-net.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EACV,WAAW,EAKX,eAAe,EAChB,MAAM,gBAAgB,CAAC;AAqDxB,eAAO,MAAM,QAAQ,GACnB,UAAU,MAAM,EAChB,SAAS,MAAM,KACd,OAAO,CAAC,eAAe,GAAG,WAAW,CAwOvC,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,QAAQ,SAAS,KAAG,IAkB5C,CAAC"}
|
package/dist/tools/query-net.js
CHANGED
|
@@ -2,6 +2,35 @@ import { z } from "zod";
|
|
|
2
2
|
import { attr, numAttr, streamAllLines } from "./lib/xml-utils.js";
|
|
3
3
|
import { buildLineDescDict, extractMicronFactor, formatResult, validateFile, validatePattern, } from "./shared.js";
|
|
4
4
|
import { withTelemetry } from "../telemetry.js";
|
|
5
|
+
const makeAccumulator = () => ({
|
|
6
|
+
pins: [],
|
|
7
|
+
pinsSeen: new Set(),
|
|
8
|
+
phyNetLayers: new Set(),
|
|
9
|
+
routeMap: new Map(),
|
|
10
|
+
viaMap: new Map(),
|
|
11
|
+
});
|
|
12
|
+
const addPin = (acc, refdes, pin) => {
|
|
13
|
+
const key = `${refdes}.${pin}`;
|
|
14
|
+
if (!acc.pinsSeen.has(key)) {
|
|
15
|
+
acc.pinsSeen.add(key);
|
|
16
|
+
acc.pins.push({ refdes, pin });
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
const groupPinsByRefdes = (pins) => {
|
|
20
|
+
const grouped = new Map();
|
|
21
|
+
for (const { refdes, pin } of pins) {
|
|
22
|
+
if (!grouped.has(refdes)) {
|
|
23
|
+
grouped.set(refdes, []);
|
|
24
|
+
}
|
|
25
|
+
grouped.get(refdes).push(pin);
|
|
26
|
+
}
|
|
27
|
+
const result = {};
|
|
28
|
+
const sortedRefdes = [...grouped.keys()].sort((a, b) => a.localeCompare(b));
|
|
29
|
+
for (const refdes of sortedRefdes) {
|
|
30
|
+
result[refdes] = grouped.get(refdes).sort((a, b) => a.localeCompare(b));
|
|
31
|
+
}
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
5
34
|
export const queryNet = async (filePath, pattern) => {
|
|
6
35
|
const err = await validateFile(filePath);
|
|
7
36
|
if (err)
|
|
@@ -11,32 +40,90 @@ export const queryNet = async (filePath, pattern) => {
|
|
|
11
40
|
return validation;
|
|
12
41
|
const { regex } = validation;
|
|
13
42
|
const factor = await extractMicronFactor(filePath);
|
|
14
|
-
// Pass 1:
|
|
15
|
-
|
|
43
|
+
// Pass 1: Discover matching nets from LogicalNet + PhyNet sections,
|
|
44
|
+
// extract pins from LogicalNet, extract layers from PhyNetPoint.
|
|
45
|
+
const accumulators = new Map();
|
|
46
|
+
const phyNetNames = new Set();
|
|
47
|
+
const matchedPhyNetNames = new Set();
|
|
48
|
+
let insideMatchedLogicalNet = false;
|
|
49
|
+
let insideMatchedPhyNet = false;
|
|
50
|
+
let currentLogicalNetName = "";
|
|
51
|
+
let currentPhyNetName = "";
|
|
16
52
|
await streamAllLines(filePath, (line) => {
|
|
53
|
+
// Stop once we reach LayerFeature (Pass 3 handles that)
|
|
54
|
+
if (line.includes("<LayerFeature"))
|
|
55
|
+
return false;
|
|
56
|
+
// LogicalNet pin extraction
|
|
57
|
+
if (line.includes("<LogicalNet ")) {
|
|
58
|
+
const name = attr(line, "name");
|
|
59
|
+
if (name && regex.test(name)) {
|
|
60
|
+
insideMatchedLogicalNet = true;
|
|
61
|
+
currentLogicalNetName = name;
|
|
62
|
+
if (!accumulators.has(name))
|
|
63
|
+
accumulators.set(name, makeAccumulator());
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
insideMatchedLogicalNet = false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (insideMatchedLogicalNet) {
|
|
70
|
+
if (line.includes("<PinRef ")) {
|
|
71
|
+
const compRef = attr(line, "componentRef");
|
|
72
|
+
const pin = attr(line, "pin");
|
|
73
|
+
if (compRef && pin) {
|
|
74
|
+
addPin(accumulators.get(currentLogicalNetName), compRef, pin);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (line.includes("</LogicalNet>")) {
|
|
78
|
+
insideMatchedLogicalNet = false;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// PhyNet layer extraction
|
|
17
82
|
if (line.includes("<PhyNet ")) {
|
|
18
83
|
const name = attr(line, "name");
|
|
84
|
+
if (name) {
|
|
85
|
+
phyNetNames.add(name);
|
|
86
|
+
}
|
|
19
87
|
if (name && regex.test(name)) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
88
|
+
insideMatchedPhyNet = true;
|
|
89
|
+
currentPhyNetName = name;
|
|
90
|
+
matchedPhyNetNames.add(name);
|
|
91
|
+
if (!accumulators.has(name))
|
|
92
|
+
accumulators.set(name, makeAccumulator());
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
insideMatchedPhyNet = false;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (insideMatchedPhyNet) {
|
|
99
|
+
if (line.includes("<PhyNetPoint ")) {
|
|
100
|
+
const layerRef = attr(line, "layerRef");
|
|
101
|
+
if (layerRef) {
|
|
102
|
+
accumulators.get(currentPhyNetName).phyNetLayers.add(layerRef);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (line.includes("</PhyNet>")) {
|
|
106
|
+
insideMatchedPhyNet = false;
|
|
23
107
|
}
|
|
24
108
|
}
|
|
25
109
|
});
|
|
26
|
-
|
|
27
|
-
|
|
110
|
+
// If no nets matched, return empty matches (not an error)
|
|
111
|
+
if (accumulators.size === 0) {
|
|
112
|
+
return { pattern, units: "MICRON", matches: [] };
|
|
28
113
|
}
|
|
29
|
-
|
|
114
|
+
if (phyNetNames.size > 0 && matchedPhyNetNames.size === phyNetNames.size) {
|
|
115
|
+
return {
|
|
116
|
+
error: `Pattern '${pattern}' matches all ${phyNetNames.size} physical nets. Use a more specific pattern, or use get_design_overview for net counts and discovery.`,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
// Pass 2: Build LineDesc dictionary
|
|
30
120
|
const lineDescDict = await buildLineDescDict(filePath);
|
|
31
|
-
// Pass 3:
|
|
32
|
-
|
|
33
|
-
const pins = [];
|
|
34
|
-
const pinsSeen = new Set();
|
|
35
|
-
const routeMap = new Map();
|
|
36
|
-
const viaMap = new Map();
|
|
121
|
+
// Pass 3: LayerFeature routing/vias for all matched nets
|
|
122
|
+
const matchedNames = new Set(accumulators.keys());
|
|
37
123
|
const skipLayers = new Set(["REF-route", "REF-both"]);
|
|
38
124
|
let currentLayerName = "";
|
|
39
125
|
let insideMatchedSet = false;
|
|
126
|
+
let currentSetNetName = "";
|
|
40
127
|
let currentSetHasPolyline = false;
|
|
41
128
|
let currentSetLineDescId;
|
|
42
129
|
let currentSetInlineWidth;
|
|
@@ -47,22 +134,20 @@ export const queryNet = async (filePath, pattern) => {
|
|
|
47
134
|
}
|
|
48
135
|
if (line.includes("<Set ")) {
|
|
49
136
|
const netName = attr(line, "net");
|
|
50
|
-
insideMatchedSet = netName
|
|
137
|
+
insideMatchedSet = Boolean(netName && matchedNames.has(netName) && !skipLayers.has(currentLayerName));
|
|
138
|
+
currentSetNetName = netName ?? "";
|
|
51
139
|
currentSetHasPolyline = false;
|
|
52
140
|
currentSetLineDescId = undefined;
|
|
53
141
|
currentSetInlineWidth = undefined;
|
|
54
142
|
currentSetGeometry = attr(line, "geometry");
|
|
55
143
|
}
|
|
56
144
|
if (insideMatchedSet) {
|
|
145
|
+
const acc = accumulators.get(currentSetNetName);
|
|
57
146
|
if (line.includes("<PinRef ")) {
|
|
58
147
|
const compRef = attr(line, "componentRef");
|
|
59
148
|
const pin = attr(line, "pin");
|
|
60
149
|
if (compRef && pin) {
|
|
61
|
-
|
|
62
|
-
if (!pinsSeen.has(key)) {
|
|
63
|
-
pinsSeen.add(key);
|
|
64
|
-
pins.push({ refdes: compRef, pin });
|
|
65
|
-
}
|
|
150
|
+
addPin(acc, compRef, pin);
|
|
66
151
|
}
|
|
67
152
|
}
|
|
68
153
|
if (line.includes("<Polyline")) {
|
|
@@ -82,15 +167,15 @@ export const queryNet = async (filePath, pattern) => {
|
|
|
82
167
|
if (platingStatus === "VIA") {
|
|
83
168
|
const diameter = numAttr(line, "diameter");
|
|
84
169
|
const key = currentSetGeometry ?? `dia_${diameter ?? "unknown"}`;
|
|
85
|
-
viaMap.set(key, (viaMap.get(key) ?? 0) + 1);
|
|
170
|
+
acc.viaMap.set(key, (acc.viaMap.get(key) ?? 0) + 1);
|
|
86
171
|
}
|
|
87
172
|
}
|
|
88
173
|
if (line.includes("</Set>")) {
|
|
89
174
|
if (currentSetHasPolyline && currentLayerName) {
|
|
90
|
-
if (!routeMap.has(currentLayerName)) {
|
|
91
|
-
routeMap.set(currentLayerName, { widths: new Set(), segments: 0 });
|
|
175
|
+
if (!acc.routeMap.has(currentLayerName)) {
|
|
176
|
+
acc.routeMap.set(currentLayerName, { widths: new Set(), segments: 0 });
|
|
92
177
|
}
|
|
93
|
-
const layerRoute = routeMap.get(currentLayerName);
|
|
178
|
+
const layerRoute = acc.routeMap.get(currentLayerName);
|
|
94
179
|
layerRoute.segments++;
|
|
95
180
|
if (currentSetLineDescId) {
|
|
96
181
|
const width = lineDescDict.get(currentSetLineDescId);
|
|
@@ -106,35 +191,53 @@ export const queryNet = async (filePath, pattern) => {
|
|
|
106
191
|
}
|
|
107
192
|
}
|
|
108
193
|
});
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
194
|
+
// Assemble results
|
|
195
|
+
const matches = [...accumulators.entries()]
|
|
196
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
197
|
+
.map(([netName, acc]) => {
|
|
198
|
+
const routing = [];
|
|
199
|
+
for (const [layerName, data] of [...acc.routeMap.entries()].sort(([a], [b]) => a.localeCompare(b))) {
|
|
200
|
+
routing.push({
|
|
201
|
+
layerName,
|
|
202
|
+
traceWidths: [...data.widths].sort((a, b) => a - b),
|
|
203
|
+
segmentCount: data.segments,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
const vias = [];
|
|
207
|
+
for (const [padstackRef, count] of [...acc.viaMap.entries()].sort(([a], [b]) => a.localeCompare(b))) {
|
|
208
|
+
vias.push({ padstackRef, count });
|
|
209
|
+
}
|
|
210
|
+
const totalSegments = routing.reduce((sum, r) => sum + r.segmentCount, 0);
|
|
211
|
+
const totalVias = vias.reduce((sum, v) => sum + v.count, 0);
|
|
212
|
+
// Merge PhyNetPoint layers with routing-derived layers
|
|
213
|
+
const layerSet = new Set(acc.phyNetLayers);
|
|
214
|
+
for (const r of routing)
|
|
215
|
+
layerSet.add(r.layerName);
|
|
216
|
+
const layersUsed = [...layerSet].sort();
|
|
217
|
+
const result = {
|
|
218
|
+
netName,
|
|
219
|
+
pins: groupPinsByRefdes(acc.pins),
|
|
220
|
+
layersUsed,
|
|
221
|
+
};
|
|
222
|
+
if (routing.length > 0) {
|
|
223
|
+
result.routing = routing;
|
|
224
|
+
}
|
|
225
|
+
if (vias.length > 0) {
|
|
226
|
+
result.vias = vias;
|
|
227
|
+
}
|
|
228
|
+
if (totalSegments > 0) {
|
|
229
|
+
result.totalSegments = totalSegments;
|
|
230
|
+
}
|
|
231
|
+
if (totalVias > 0) {
|
|
232
|
+
result.totalVias = totalVias;
|
|
233
|
+
}
|
|
234
|
+
return result;
|
|
235
|
+
});
|
|
236
|
+
return { pattern, units: "MICRON", matches };
|
|
134
237
|
};
|
|
135
238
|
export const register = (server) => {
|
|
136
239
|
server.registerTool("query_net", {
|
|
137
|
-
description: "Query
|
|
240
|
+
description: "Query nets by name pattern in an IPC-2581 file. Returns grouped connected pins, routing per layer (trace widths, segment counts), and via information. Rejects patterns that match all nets.",
|
|
138
241
|
inputSchema: {
|
|
139
242
|
file: z.string().describe("Path to IPC-2581 XML file"),
|
|
140
243
|
pattern: z
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-net.js","sourceRoot":"","sources":["../../src/tools/query-net.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"query-net.js","sourceRoot":"","sources":["../../src/tools/query-net.ts"],"names":[],"mappings":"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"}
|