From fc035018ba0000f5666d761406559a4966b13f26 Mon Sep 17 00:00:00 2001 From: ankan roy Date: Wed, 5 Aug 2026 16:18:34 +0530 Subject: [PATCH 1/3] Show differential pair netlist warnings --- cli/check/netlist/register.ts | 55 +++++++++----------------- lib/shared/circuit-json-diagnostics.ts | 11 ++++-- tests/analyze-circuit-json.test.ts | 16 +++++++- tests/cli/check/check-netlist.test.ts | 37 ++++++++++++++++- 4 files changed, 76 insertions(+), 43 deletions(-) diff --git a/cli/check/netlist/register.ts b/cli/check/netlist/register.ts index 95636fc1c..5d95e2cff 100644 --- a/cli/check/netlist/register.ts +++ b/cli/check/netlist/register.ts @@ -1,20 +1,16 @@ -import { convertCircuitJsonToReadableNetlist } from "circuit-json-to-readable-netlist" import { - categorizeErrorOrWarning, type DrcCategory, + categorizeErrorOrWarning, } from "@tscircuit/circuit-json-util" import type { PlatformConfig } from "@tscircuit/props" import type { AnyCircuitElement } from "circuit-json" +import { convertCircuitJsonToReadableNetlist } from "circuit-json-to-readable-netlist" import type { Command } from "commander" -import { getOrGenerateCircuitJson } from "lib/shared/get-or-generate-circuit-json" -import { getPlatformConfigWithCliDefaults } from "lib/shared/get-platform-config-with-cli-defaults" -import { getEntrypoint } from "lib/shared/get-entrypoint" import { - analyzeCircuitJson, type CircuitJsonIssue, + analyzeCircuitJson, } from "lib/shared/circuit-json-diagnostics" -import path from "node:path" -import { findCircuitProjectDir } from "lib/shared/circuit-json-build-cache" +import { getCircuitJsonForCheck, resolveCheckInputFilePath } from "../shared" const normalizeCategory = (category: string): DrcCategory => category === "netlist" || @@ -24,43 +20,28 @@ const normalizeCategory = (category: string): DrcCategory => ? category : "unknown" +const isDifferentialPairConnectionWarning = (issue: CircuitJsonIssue) => + [issue.type, issue.error_type, issue.warning_type].includes( + "source_property_ignored_warning", + ) && + (issue.property_name === "positiveConnection" || + issue.property_name === "negativeConnection") + const isNetlistDiagnostic = (issue: CircuitJsonIssue) => + isDifferentialPairConnectionWarning(issue) || normalizeCategory(categorizeErrorOrWarning(issue)) === "netlist" -const resolveInputFilePath = async (file?: string) => { - if (file) { - return path.isAbsolute(file) ? file : path.resolve(process.cwd(), file) - } - - const entrypoint = await getEntrypoint({ - projectDir: process.cwd(), - }) - - if (!entrypoint) { - throw new Error("No input file provided and no entrypoint found") - } - - return entrypoint -} - export const checkNetlist = async (file?: string) => { - const resolvedInputFilePath = await resolveInputFilePath(file) - - const platformConfigWithCliDefaults = getPlatformConfigWithCliDefaults( - { + const resolvedInputFilePath = await resolveCheckInputFilePath(file) + const typedCircuitJson = (await getCircuitJsonForCheck({ + filePath: resolvedInputFilePath, + platformConfig: { pcbDisabled: true, routingDisabled: true, placementDrcChecksDisabled: true, } satisfies PlatformConfig, - { projectDir: findCircuitProjectDir(resolvedInputFilePath) }, - ) - - const { circuitJson } = await getOrGenerateCircuitJson({ - filePath: resolvedInputFilePath, - platformConfig: platformConfigWithCliDefaults, - }) - - const typedCircuitJson = circuitJson as AnyCircuitElement[] + allowPrebuiltCircuitJson: true, + })) as AnyCircuitElement[] const diagnostics = analyzeCircuitJson(typedCircuitJson) const netlistErrors = diagnostics.errors.filter(isNetlistDiagnostic) const netlistWarnings = diagnostics.warnings.filter(isNetlistDiagnostic) diff --git a/lib/shared/circuit-json-diagnostics.ts b/lib/shared/circuit-json-diagnostics.ts index f41e211b6..3473ef123 100644 --- a/lib/shared/circuit-json-diagnostics.ts +++ b/lib/shared/circuit-json-diagnostics.ts @@ -20,14 +20,17 @@ export function analyzeCircuitJson(circuitJson: any[]): { const hasWarningType = typeof item.warning_type === "string" const isTypedError = typeof t === "string" && t.endsWith("_error") const isTypedWarning = typeof t === "string" && t.endsWith("_warning") + const hasWarningInErrorType = + typeof item.error_type === "string" && + item.error_type.endsWith("_warning") - if (hasErrorType || isTypedError) { - errors.push(item as CircuitJsonIssue) + if (hasWarningType || isTypedWarning || hasWarningInErrorType) { + warnings.push(item as CircuitJsonIssue) continue } - if (hasWarningType || isTypedWarning) { - warnings.push(item as CircuitJsonIssue) + if (hasErrorType || isTypedError) { + errors.push(item as CircuitJsonIssue) } } diff --git a/tests/analyze-circuit-json.test.ts b/tests/analyze-circuit-json.test.ts index de59d603d..39ba6d499 100644 --- a/tests/analyze-circuit-json.test.ts +++ b/tests/analyze-circuit-json.test.ts @@ -1,4 +1,4 @@ -import { test, expect } from "bun:test" +import { expect, test } from "bun:test" import { analyzeCircuitJson } from "lib/shared/circuit-json-diagnostics" const sample = [ @@ -39,3 +39,17 @@ test("analyzeCircuitJson does not double-count items with both type and error me expect(errors).toHaveLength(1) expect(warnings).toHaveLength(1) }) + +test("analyzeCircuitJson treats warning-shaped error_type metadata as a warning", () => { + const { errors, warnings } = analyzeCircuitJson([ + { + type: "source_property_ignored_warning", + error_type: "source_property_ignored_warning", + property_name: "positiveConnection", + message: "ambiguous differential-pair trace", + }, + ]) + + expect(errors).toHaveLength(0) + expect(warnings).toHaveLength(1) +}) diff --git a/tests/cli/check/check-netlist.test.ts b/tests/cli/check/check-netlist.test.ts index 29420419e..936b49ae7 100644 --- a/tests/cli/check/check-netlist.test.ts +++ b/tests/cli/check/check-netlist.test.ts @@ -1,6 +1,6 @@ import { expect, test } from "bun:test" -import path from "node:path" import { writeFile } from "node:fs/promises" +import path from "node:path" import { getCliTestFixture } from "../../fixtures/get-cli-test-fixture" const circuitCode = ` @@ -75,3 +75,38 @@ test("check netlist filters out placement diagnostics", async () => { expect(stdout).not.toContain("pcb_component_outside_board_error") expect(stdout).not.toContain("Component R1 extends outside board boundaries") }, 20_000) + +test("check netlist displays ambiguous differential-pair trace warnings", async () => { + const { tmpDir, runCommand } = await getCliTestFixture() + const circuitPath = path.join(tmpDir, "differential-pair.circuit.json") + const warningMessage = + 'Differential pair "USB_DATA" positiveConnection references trace "DP_FROM_J1", which is ambiguous because it connects to 3 terminal pins: .J1 > .DP, .TP1 > .pin1, and .U1 > .DP.' + + await writeFile( + circuitPath, + JSON.stringify([ + { + type: "source_property_ignored_warning", + source_property_ignored_warning_id: "source_property_ignored_warning_0", + source_component_id: "source_component_j1", + property_name: "positiveConnection", + error_type: "source_property_ignored_warning", + message: warningMessage, + }, + ]), + ) + + const { stdout, stderr, exitCode } = await runCommand( + `tsci check netlist ${circuitPath}`, + ) + + expect(exitCode).toBe(0) + expect(stderr).toBe("") + expect(stdout).toContain("Errors: 0") + expect(stdout).toContain("Warnings: 1") + expect(stdout).toContain( + `- source_property_ignored_warning: ${warningMessage}`, + ) + expect(stdout).not.toContain("Remove the extra connection") + expect(stdout).not.toContain("prefer a pin selector") +}, 20_000) From b7ae9f93829ffc78caa3d67305939af42c41fb3f Mon Sep 17 00:00:00 2001 From: ankan roy Date: Wed, 5 Aug 2026 16:32:37 +0530 Subject: [PATCH 2/3] Tighten netlist warning classification --- cli/check/netlist/register.ts | 11 ++++----- lib/shared/circuit-json-diagnostics.ts | 5 +--- tests/analyze-circuit-json.test.ts | 2 +- tests/cli/check/check-netlist.test.ts | 33 ++++++++++++++++++++------ 4 files changed, 32 insertions(+), 19 deletions(-) diff --git a/cli/check/netlist/register.ts b/cli/check/netlist/register.ts index 5d95e2cff..9d8798015 100644 --- a/cli/check/netlist/register.ts +++ b/cli/check/netlist/register.ts @@ -3,7 +3,6 @@ import { categorizeErrorOrWarning, } from "@tscircuit/circuit-json-util" import type { PlatformConfig } from "@tscircuit/props" -import type { AnyCircuitElement } from "circuit-json" import { convertCircuitJsonToReadableNetlist } from "circuit-json-to-readable-netlist" import type { Command } from "commander" import { @@ -21,9 +20,7 @@ const normalizeCategory = (category: string): DrcCategory => : "unknown" const isDifferentialPairConnectionWarning = (issue: CircuitJsonIssue) => - [issue.type, issue.error_type, issue.warning_type].includes( - "source_property_ignored_warning", - ) && + issue.type === "source_property_ignored_warning" && (issue.property_name === "positiveConnection" || issue.property_name === "negativeConnection") @@ -33,7 +30,7 @@ const isNetlistDiagnostic = (issue: CircuitJsonIssue) => export const checkNetlist = async (file?: string) => { const resolvedInputFilePath = await resolveCheckInputFilePath(file) - const typedCircuitJson = (await getCircuitJsonForCheck({ + const typedCircuitJson = await getCircuitJsonForCheck({ filePath: resolvedInputFilePath, platformConfig: { pcbDisabled: true, @@ -41,7 +38,7 @@ export const checkNetlist = async (file?: string) => { placementDrcChecksDisabled: true, } satisfies PlatformConfig, allowPrebuiltCircuitJson: true, - })) as AnyCircuitElement[] + }) const diagnostics = analyzeCircuitJson(typedCircuitJson) const netlistErrors = diagnostics.errors.filter(isNetlistDiagnostic) const netlistWarnings = diagnostics.warnings.filter(isNetlistDiagnostic) @@ -76,7 +73,7 @@ export const registerCheckNetlist = (program: Command) => { .find((c) => c.name() === "check")! .command("netlist") .description("Partially build and validate the netlist") - .argument("[file]", "Path to the entry file") + .argument("[file]", "Path to the entry file or prebuilt Circuit JSON") .action(async (file?: string) => { try { const output = await checkNetlist(file) diff --git a/lib/shared/circuit-json-diagnostics.ts b/lib/shared/circuit-json-diagnostics.ts index 3473ef123..06a353a43 100644 --- a/lib/shared/circuit-json-diagnostics.ts +++ b/lib/shared/circuit-json-diagnostics.ts @@ -20,11 +20,8 @@ export function analyzeCircuitJson(circuitJson: any[]): { const hasWarningType = typeof item.warning_type === "string" const isTypedError = typeof t === "string" && t.endsWith("_error") const isTypedWarning = typeof t === "string" && t.endsWith("_warning") - const hasWarningInErrorType = - typeof item.error_type === "string" && - item.error_type.endsWith("_warning") - if (hasWarningType || isTypedWarning || hasWarningInErrorType) { + if (hasWarningType || isTypedWarning) { warnings.push(item as CircuitJsonIssue) continue } diff --git a/tests/analyze-circuit-json.test.ts b/tests/analyze-circuit-json.test.ts index 39ba6d499..e91594c2e 100644 --- a/tests/analyze-circuit-json.test.ts +++ b/tests/analyze-circuit-json.test.ts @@ -40,7 +40,7 @@ test("analyzeCircuitJson does not double-count items with both type and error me expect(warnings).toHaveLength(1) }) -test("analyzeCircuitJson treats warning-shaped error_type metadata as a warning", () => { +test("analyzeCircuitJson prefers a warning type over error_type metadata", () => { const { errors, warnings } = analyzeCircuitJson([ { type: "source_property_ignored_warning", diff --git a/tests/cli/check/check-netlist.test.ts b/tests/cli/check/check-netlist.test.ts index 936b49ae7..ddc3e2f6e 100644 --- a/tests/cli/check/check-netlist.test.ts +++ b/tests/cli/check/check-netlist.test.ts @@ -79,8 +79,9 @@ test("check netlist filters out placement diagnostics", async () => { test("check netlist displays ambiguous differential-pair trace warnings", async () => { const { tmpDir, runCommand } = await getCliTestFixture() const circuitPath = path.join(tmpDir, "differential-pair.circuit.json") - const warningMessage = - 'Differential pair "USB_DATA" positiveConnection references trace "DP_FROM_J1", which is ambiguous because it connects to 3 terminal pins: .J1 > .DP, .TP1 > .pin1, and .U1 > .DP.' + const positiveConnectionMessage = "ambiguous positive differential-pair trace" + const negativeConnectionMessage = "ambiguous negative differential-pair trace" + const unrelatedWarningMessage = "ignored footprint property" await writeFile( circuitPath, @@ -91,7 +92,23 @@ test("check netlist displays ambiguous differential-pair trace warnings", async source_component_id: "source_component_j1", property_name: "positiveConnection", error_type: "source_property_ignored_warning", - message: warningMessage, + message: positiveConnectionMessage, + }, + { + type: "source_property_ignored_warning", + source_property_ignored_warning_id: "source_property_ignored_warning_1", + source_component_id: "source_component_j1", + property_name: "negativeConnection", + error_type: "source_property_ignored_warning", + message: negativeConnectionMessage, + }, + { + type: "source_property_ignored_warning", + source_property_ignored_warning_id: "source_property_ignored_warning_2", + source_component_id: "source_component_j1", + property_name: "footprint", + error_type: "source_property_ignored_warning", + message: unrelatedWarningMessage, }, ]), ) @@ -103,10 +120,12 @@ test("check netlist displays ambiguous differential-pair trace warnings", async expect(exitCode).toBe(0) expect(stderr).toBe("") expect(stdout).toContain("Errors: 0") - expect(stdout).toContain("Warnings: 1") + expect(stdout).toContain("Warnings: 2") + expect(stdout).toContain( + `- source_property_ignored_warning: ${positiveConnectionMessage}`, + ) expect(stdout).toContain( - `- source_property_ignored_warning: ${warningMessage}`, + `- source_property_ignored_warning: ${negativeConnectionMessage}`, ) - expect(stdout).not.toContain("Remove the extra connection") - expect(stdout).not.toContain("prefer a pin selector") + expect(stdout).not.toContain(unrelatedWarningMessage) }, 20_000) From 0b3ad23fe4b61a83883ea1e76f49be2a29043c49 Mon Sep 17 00:00:00 2001 From: ankan roy Date: Wed, 5 Aug 2026 16:46:56 +0530 Subject: [PATCH 3/3] Exercise netlist warnings through released Core --- bun.lock | 64 ++++++++-------- cli/check/netlist/register.ts | 76 +++++++++++++------ package.json | 2 +- ...rcuit-json-warning-type-precedence.test.ts | 16 ++++ tests/analyze-circuit-json.test.ts | 16 +--- ...t-differential-pair-classification.test.ts | 17 +++++ ...netlist-differential-pair-warnings.test.ts | 40 ++++++++++ tests/cli/check/check-netlist.test.ts | 56 +------------- 8 files changed, 160 insertions(+), 127 deletions(-) create mode 100644 tests/analyze-circuit-json-warning-type-precedence.test.ts create mode 100644 tests/cli/check/check-netlist-differential-pair-classification.test.ts create mode 100644 tests/cli/check/check-netlist-differential-pair-warnings.test.ts diff --git a/bun.lock b/bun.lock index 0d43c0e33..2b3ef8429 100644 --- a/bun.lock +++ b/bun.lock @@ -79,7 +79,7 @@ "spicets": "^0.0.4", "stepts": "^0.0.3", "tempy": "^3.1.0", - "tscircuit": "0.0.2142-libonly", + "tscircuit": "0.0.2232-libonly", "tsx": "^4.7.1", "typed-ky": "^0.0.4", "zod": "^3.23.8", @@ -317,11 +317,11 @@ "@tscircuit/alphabet": ["@tscircuit/alphabet@0.0.25", "", { "peerDependencies": { "typescript": "^5.0.0" } }, "sha512-PWLjptI6AlLEtF/wjN1N8uC+n3G7vtg0j3xKE1fgWHDhahtnlQRqHDrtPSLlkIR9aJjRfjplzLuaUEaCRvJmZA=="], - "@tscircuit/capacity-autorouter": ["@tscircuit/capacity-autorouter@0.0.710", "", { "dependencies": { "fast-json-stable-stringify": "^2.1.0", "object-hash": "^3.0.0", "stack-svgs": "^0.0.1" } }, "sha512-+mK6pc8hQdo7G6iIRzvIV2EH6TOM215oQv12VObB2k0rl1m/5oiw9f66GlBGUYxGRbob7YVJZ2G5AH554nZ9/Q=="], + "@tscircuit/capacity-autorouter": ["@tscircuit/capacity-autorouter@0.0.750", "", { "dependencies": { "fast-json-stable-stringify": "^2.1.0", "object-hash": "^3.0.0", "stack-svgs": "^0.0.1" } }, "sha512-FfORoxv0dHJfN8Bs2Mm+4+EBB/NBACWicUnZc1vds3LrjHPAT8O5zJyS07z3clO+rY47psjgbT8jIRwUG7R+ig=="], "@tscircuit/check-shorts": ["@tscircuit/check-shorts@https://jscdn.tscircuit.com/@tscircuit/check-shorts/0.0.12.tgz", { "peerDependencies": { "@resvg/resvg-js": "^2.6.2", "@tscircuit/circuit-json-util": "*", "@tscircuit/math-utils": "*", "circuit-json": "*", "circuit-json-to-connectivity-map": "*", "circuit-json-to-gerber": "*", "circuit-to-canvas": "*", "circuit-to-svg": "*", "fast-png": "^8.0.0", "gerber-to-svg": "*", "react": "^19.2.7", "transformation-matrix": "^2.16.1", "typescript": "^5" } }, "sha512-vtMbDVT9wiC69eg/kHcOYgRzU18oK8gR7pEvg/q5u/Zetzkmu1R/dulM0kj/HrfW32tjNg2+G6LHSY3UYoXwrg=="], - "@tscircuit/checks": ["@tscircuit/checks@0.0.145", "", { "peerDependencies": { "@flatten-js/core": "*", "@tscircuit/math-utils": "*", "circuit-json": "*", "circuit-json-to-connectivity-map": "*", "typescript": "^5.5.3" } }, "sha512-HKdugkjGSrx4HyyrrtDi4pXmORZGx9kA/4zKRUnk7qqqaIyF7OKXGSKW1nIxv+O2oSHOu4z9lpMCEYkHmPUdrQ=="], + "@tscircuit/checks": ["@tscircuit/checks@0.0.151", "", { "peerDependencies": { "@flatten-js/core": "*", "@tscircuit/math-utils": "*", "circuit-json": "*", "circuit-json-to-connectivity-map": "*", "typescript": "^5.5.3" } }, "sha512-+qgG5HtgTgkVWl7T2UQhtjgqZDnUYHS62jEy6BdIsH1XoOSTTl9vEJmEMmmymeIeAmOfPZC92BjcI+0vO+6Ihw=="], "@tscircuit/circuit-json-placement-analysis": ["@tscircuit/circuit-json-placement-analysis@0.0.6", "", { "dependencies": { "flatbush": "^4.5.1", "rbush": "^4.0.1" }, "peerDependencies": { "typescript": "^5" } }, "sha512-ICqLrrDIGD+Re+I0knzIxRdYBu3uJgn/k4U474U/A4rg73CqA/W6XnmveiXAixl7mbCUAO2rijiX3XYAQzlLUg=="], @@ -331,7 +331,7 @@ "@tscircuit/circuit-json-util": ["@tscircuit/circuit-json-util@0.0.97", "", { "dependencies": { "parsel-js": "^1.1.2" }, "peerDependencies": { "circuit-json": "*", "transformation-matrix": "*", "zod": "3" } }, "sha512-qg0R/X4mCwb43f53+W3FkxUNRvgGz1WNjpQfKi+QXnoqISw6EZ1Y7VcSynO8S2d8hPGV9Mk5DUOjTPjlEUrrGA=="], - "@tscircuit/copper-pour-solver": ["@tscircuit/copper-pour-solver@0.0.39", "", { "dependencies": { "@tscircuit/manifold-2d": "^0.0.6" }, "peerDependencies": { "typescript": "^5" } }, "sha512-Z8+3UrK919QbwJkGyHsb8DGuHqE66iCylpbF/v132PuvrRbHo+phmOfP9nEQjI63ldh976EsT26qw535H15M1g=="], + "@tscircuit/copper-pour-solver": ["@tscircuit/copper-pour-solver@0.0.42", "", { "dependencies": { "@tscircuit/manifold-2d": "^0.0.6" }, "peerDependencies": { "typescript": "^5" } }, "sha512-FHsX32w/8upaPad+SkFe82JEWKCuRLzduDxJAZITPL9IdX9v/uMXiKGp2DQgoQ9kBgRHxyRcoRiaC6qCoEaq6Q=="], "@tscircuit/core": ["@tscircuit/core@0.0.1453", "", { "dependencies": { "@flatten-js/core": "^1.6.2", "@lume/kiwi": "^0.4.3", "calculate-cell-boundaries": "^0.0.13", "calculate-packing": "^0.0.77", "css-select": "5.1.0", "format-si-unit": "^0.0.7", "nanoid": "^5.0.7", "performance-now": "^2.1.0", "react-reconciler": "^0.32.0", "svg-path-commander": "^2.1.11", "transformation-matrix": "^2.16.1", "zod": "^3.25.67" }, "peerDependencies": { "@tscircuit/capacity-autorouter": "*", "@tscircuit/checks": "*", "@tscircuit/circuit-json-util": "*", "@tscircuit/footprinter": "*", "@tscircuit/infgrid-ijump-astar": "*", "@tscircuit/matchpack": "*", "@tscircuit/math-utils": "*", "@tscircuit/props": "*", "@tscircuit/schematic-match-adapt": "*", "bpc-graph": "*", "circuit-json": "*", "circuit-json-to-bpc": "*", "circuit-json-to-connectivity-map": "*", "schematic-symbols": "*", "typescript": "^5.0.0" } }, "sha512-YxuNytUKla8Il+S/svf3NNom+eJXAULR9JTPduupG5Wvt39UDi+q/GPqfgfHn8WWkZzFrpJ+RmiQhx+WZRWyFQ=="], @@ -341,13 +341,15 @@ "@tscircuit/fake-snippets": ["@tscircuit/fake-snippets@0.0.182", "", {}, "sha512-DHGb1aAUm9KUKhUEiULZbbsUi3xeFnH0w11srz0boV2+Ceu0h8yn2oGvnpsAjlMFq/pmPg3HJayldHHGnw/n4A=="], + "@tscircuit/fanout-solver": ["@tscircuit/fanout-solver@0.0.11", "", { "dependencies": { "@tscircuit/capacity-autorouter": "0.0.718", "@tscircuit/solver-utils": "0.0.19", "graphics-debug": "0.0.96" }, "peerDependencies": { "typescript": "^5" } }, "sha512-qNlkFixA16wRUxjaWgUSdx1ICP1Vgc58v0pxkg17kuCErPpGtboSc6F58fNPnE96q7CuoiWudRsrr8cUTHJ7Ew=="], + "@tscircuit/file-server": ["@tscircuit/file-server@0.0.32", "", { "dependencies": { "winterspec": "^0.0.86", "zod": "^3.23.8", "zustand": "^4.5.5", "zustand-hoist": "^2.0.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "bin": { "file-server": "dist/cli.js" } }, "sha512-RQDYRjwENDvVK/p0Wtw5rWCZAW2ZL2iKYspEhFr/oWiOC54brtQnL4udgwvyibE0qJxg8v3xR0AxOoebn3HeAA=="], "@tscircuit/footprinter": ["@tscircuit/footprinter@0.0.374", "", { "dependencies": { "@tscircuit/mm": "^0.0.8", "zod": "^3.23.8" }, "peerDependencies": { "circuit-json": "*" } }, "sha512-TqcB8fBoquEWCOIttNSvq3OD+g3j9INFn0Zn//Jmje8U42TW7SpxW5vF+N04zoCmIQ3WkMpeC2032zD4uYbg5Q=="], "@tscircuit/image-utils": ["@tscircuit/image-utils@0.0.8", "", { "dependencies": { "@flatten-js/core": "^1.6.2", "color-diff": "^1.4.0", "fast-png": "^8.0.0", "svg-path-commander": "^2.1.11", "transformation-matrix": "^2.16.1" } }, "sha512-/a/dyd0Ly+YSk73pNXi0M02nfaiZ1NQ8PVNDBTOHHESyTOrNHiVAT+NWxsWi44gHZ/ivLegAmjxSSbSSGfU+sQ=="], - "@tscircuit/infer-cable-insertion-point": ["@tscircuit/infer-cable-insertion-point@0.0.2", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-k3JwlGtsdHRRZELJzjXBKP+9xdzn+v4dqllhJIFMcrMvlBIaOTt8CbxLO+vcxPvz8Csf+yFChnTos8/vYcSgNg=="], + "@tscircuit/infer-cable-insertion-point": ["@tscircuit/infer-cable-insertion-point@0.0.3", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-ENVSKEgVx5/isMC+ttHNPCK+Os3MjALEM1MDI5M9JKMDjGqq5iPjxb5qwD3/GFwkc5Xl/DtRdOyKFC1lvrw1hg=="], "@tscircuit/infgrid-ijump-astar": ["@tscircuit/infgrid-ijump-astar@0.0.35", "", {}, "sha512-PZx3GyD7mDNEhLJn8+7n8NjrieOvrX03g7Gx1cvwXv9mmgSC4M+yTA0WC4DgOvcRdTnarf0R8xvwtDeJ4tMK9Q=="], @@ -357,7 +359,7 @@ "@tscircuit/manifold-2d": ["@tscircuit/manifold-2d@0.0.6", "", {}, "sha512-kYny1hDwPHOwRfMQtbfLh0nvCQ7nM91kkHy7pnj1UrqM6rcgDymZVCZB7ib5Cx1aZFIs8xCCF7lA51tq+giDcw=="], - "@tscircuit/matchpack": ["@tscircuit/matchpack@0.0.43", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-X0V2d9N1TiJncjB4jhsqrHUSX0HfQ1IAfsHxVZTV4h1wEbTtrO5tluX22Pjlul6pQecKBBCzt3Nje5O5eEAZHQ=="], + "@tscircuit/matchpack": ["@tscircuit/matchpack@0.0.64", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-p6YM1Aicv/CfSMuO9qX9UFdKQemFg8GXLG7Kb7CnkNOWefbt8Z3k+AmaGB6OlIG3ZJUckeY241YgxD9tgei3wA=="], "@tscircuit/math-utils": ["@tscircuit/math-utils@0.0.36", "", { "peerDependencies": { "typescript": "^5.0.0" } }, "sha512-HwHS3do6CLQFnLGd0f3+kQzGfENFllpt5ZFWF9gfw2k5Rc5VSxSJi8/MLfHEgaMgrnMCZ5Hqh3DlUD6U3pMXyg=="], @@ -365,7 +367,7 @@ "@tscircuit/mm": ["@tscircuit/mm@0.0.8", "", { "peerDependencies": { "typescript": "^5.0.0" } }, "sha512-nl7nxE7AhARbKuobflI0LUzoir7+wJyvwfPw6bzA/O0Q3YTcH3vBkU/Of+V/fp6ht+AofiCXj7YAH9E446138Q=="], - "@tscircuit/ngspice-spice-engine": ["@tscircuit/ngspice-spice-engine@0.0.19", "", { "peerDependencies": { "@tscircuit/props": "*", "circuit-json": "*", "typescript": "^5" } }, "sha512-HV/HrShlvQWSNJtjBJqBmFIvRUHOZYoIGjNdNaNhN7EvHpJ2MdVmqU/c4D+DzOVU/J7vg8R6yLvUHixXvH5LFg=="], + "@tscircuit/ngspice-spice-engine": ["@tscircuit/ngspice-spice-engine@0.0.20", "", { "peerDependencies": { "@tscircuit/props": "*", "circuit-json": "*", "spicets": "*", "typescript": "^5" } }, "sha512-dXjH51Wl95B6yEVkWCz65DpAHWTJRLHDyD/09eJUpGwLcYfd1F9m4E0XWbuiYZ8wKygYlACTozrSX9n3/LtfwA=="], "@tscircuit/props": ["@tscircuit/props@0.0.612", "", { "peerDependencies": { "circuit-json": "*", "react": "*", "zod": "*" } }, "sha512-IGQbizDpQPXWXifdrmUEiU9W1tkyz98t6TeJhp+4gyfK405whQgvX4pjTFujV+ch2qy6zYt/TzHE+8A8RsdaFQ=="], @@ -375,7 +377,7 @@ "@tscircuit/schematic-match-adapt": ["@tscircuit/schematic-match-adapt@0.0.22", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-37R3qEY0BRiG1VeqHYzbl53H+cVT8VWLjTwrxkP0cuV7+V+T3HG29B4Y9XtcyoQCkVe2ZcvWd9qMCBqrHRFVjg=="], - "@tscircuit/schematic-trace-solver": ["@tscircuit/schematic-trace-solver@0.0.106", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-gbg+TdepfjE6QNZOFOxTrlXcKG09vZfcQ+j1XgZVyz0HmPb+u/EsDJMf6Q/DYejbFK9fZ29OXaUYE9/fK+rRbg=="], + "@tscircuit/schematic-trace-solver": ["@tscircuit/schematic-trace-solver@0.0.122", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-uVFVaz3RWgyWMwNPKcWcFedHq4tSpOpUuaCovVlOGm+8JYVHVmjoRMwYAuzsQ2wWLAQqFAKxsp+ICOIXn1YsAg=="], "@tscircuit/simple-3d-svg": ["@tscircuit/simple-3d-svg@0.0.41", "", { "dependencies": { "fast-xml-parser": "^5.2.5", "fflate": "^0.8.2" } }, "sha512-2iwhHhMLElq5t0fcC0Gr7cCpZhEOAKh+6NN0NIJ9YWUCcsB7UN8uYko7jqNTxDlYOe6E0ZYaDZWsQ3amOZ3dlw=="], @@ -479,7 +481,7 @@ "calculate-elbow": ["calculate-elbow@0.0.12", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-UkGS4EhabJn1WR6+UyoWpcxhKMx6MxM7+rK+3G0JcaPLMiYlvv5pEuc91unC/nH7kLGHV9xsVavhr5jJ50o+HA=="], - "calculate-packing": ["calculate-packing@0.0.79", "", { "peerDependencies": { "@tscircuit/circuit-json-util": "*", "typescript": "^5" } }, "sha512-4HoPxGHomdof5rSScJlUvnnUbIQbXHLgE564dyb1AK3BVMuk9Izf74OXHIX8+NdTce9mpDhVyY7JzmogR18K1Q=="], + "calculate-packing": ["calculate-packing@0.0.82", "", { "peerDependencies": { "@tscircuit/circuit-json-util": "*", "typescript": "^5" } }, "sha512-W5iau7cIYUTHjtHbyQokvi5exLqt+r3GFlZ5IkRyLAFN0DImV0B7glYbFkXcFuupLa6P0teiXEhRBUqJdWIPAA=="], "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="], @@ -1025,7 +1027,7 @@ "scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="], - "schematic-symbols": ["schematic-symbols@0.0.233", "", { "peerDependencies": { "typescript": "^5.5.4" } }, "sha512-RW+gYkjqIEvB/9sEvkz0WeakAgVhrP0i1WpVnMi9Blblkrm3p4aQoc4oLgotbv3dlyXGPdjIiNED96wzky1ong=="], + "schematic-symbols": ["schematic-symbols@0.0.238", "", { "peerDependencies": { "typescript": "^5.5.4" } }, "sha512-yBDHwZW5HUffT2XXT0WzS/4TF2MjIwRq1kKvK2Kbhfg3JPGDgs1QYlSG33OcibLfG1URB8acIrH+C2wKiw1YiA=="], "semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], @@ -1115,7 +1117,7 @@ "ts-morph": ["ts-morph@21.0.1", "", { "dependencies": { "@ts-morph/common": "~0.22.0", "code-block-writer": "^12.0.0" } }, "sha512-dbDtVdEAncKctzrVZ+Nr7kHpHkv+0JDJb2MjjpBaj8bFeCkePU9rHfMklmhuLFnpeq/EJZk2IhStY6NzqgjOkg=="], - "tscircuit": ["tscircuit@0.0.2142-libonly", "", { "dependencies": { "@flatten-js/core": "^1.6.2", "@lume/kiwi": "^0.4.3", "@resvg/resvg-js": "^2.6.2", "@rollup/plugin-commonjs": "^29.0.0", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.3", "@rollup/plugin-typescript": "^12.3.0", "@tscircuit/alphabet": "0.0.25", "@tscircuit/capacity-autorouter": "^0.0.710", "@tscircuit/checks": "0.0.145", "@tscircuit/circuit-json-util": "^0.0.100", "@tscircuit/copper-pour-solver": "0.0.39", "@tscircuit/core": "^0.0.1495", "@tscircuit/create-fdm-enclosure": "0.0.3", "@tscircuit/eval": "^0.0.1050", "@tscircuit/footprinter": "^0.0.380", "@tscircuit/image-utils": "^0.0.8", "@tscircuit/infer-cable-insertion-point": "^0.0.2", "@tscircuit/infgrid-ijump-astar": "^0.0.35", "@tscircuit/internal-dynamic-import": "^0.0.11", "@tscircuit/krt-wasm": "^0.1.1", "@tscircuit/matchpack": "^0.0.43", "@tscircuit/math-utils": "^0.0.36", "@tscircuit/miniflex": "^0.0.4", "@tscircuit/ngspice-spice-engine": "^0.0.19", "@tscircuit/props": "^0.0.589", "@tscircuit/runframe": "^0.0.2263", "@tscircuit/schematic-match-adapt": "^0.0.18", "@tscircuit/schematic-trace-solver": "^0.0.106", "@tscircuit/simple-3d-svg": "^0.0.41", "@tscircuit/solver-utils": "^0.0.16", "@tscircuit/soup-util": "^0.0.41", "bpc-graph": "^0.0.57", "calculate-cell-boundaries": "^0.0.13", "calculate-elbow": "^0.0.12", "calculate-packing": "^0.0.79", "circuit-json": "^0.0.453", "circuit-json-to-bpc": "^0.0.13", "circuit-json-to-connectivity-map": "^0.0.23", "circuit-json-to-gltf": "^0.0.107", "circuit-json-to-simple-3d": "^0.0.9", "circuit-json-to-spice": "^0.0.43", "circuit-to-svg": "^0.0.391", "comlink": "^4.4.2", "connectivity-map": "^1.0.0", "css-select": "5.1.0", "debug": "^4.3.6", "flatbush": "^4.5.0", "format-si-unit": "^0.0.7", "graphics-debug": "^0.0.95", "jscad-planner": "^0.0.13", "kicad-component-converter": "^0.1.40", "kicad-to-circuit-json": "^0.0.113", "kicadts": "^0.0.51", "minicssgrid": "^0.0.9", "performance-now": "^2.1.0", "poppygl": "^0.0.26", "react": "^19.1.0", "react-dom": "^19.1.0", "rollup": "^4.53.2", "rollup-plugin-dts": "^6.2.3", "s-expression": "^3.1.1", "schematic-symbols": "^0.0.233", "spicets": "^0.0.2", "spicey": "^0.0.14", "sucrase": "^3.35.0", "svg-path-commander": "^2.1.11", "transformation-matrix": "^2.16.1", "tslib": "^2.8.1", "zod": "^3.25.67" }, "peerDependencies": { "typescript": "^5.0.0" } }, "sha512-wKL3soRyqa6xuxuPJY4Y5AGA0KTtCMgwQsWYO6vJgw5sSQo2qAAJzxgKtqjmBs4S/sAU60dZ/+aSYDhXy/5C2A=="], + "tscircuit": ["tscircuit@0.0.2232-libonly", "", { "dependencies": { "@flatten-js/core": "^1.6.2", "@lume/kiwi": "^0.4.3", "@resvg/resvg-js": "^2.6.2", "@rollup/plugin-commonjs": "^29.0.0", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.3", "@rollup/plugin-typescript": "^12.3.0", "@tscircuit/alphabet": "0.0.25", "@tscircuit/capacity-autorouter": "^0.0.750", "@tscircuit/checks": "0.0.151", "@tscircuit/circuit-json-util": "^0.0.104", "@tscircuit/copper-pour-solver": "0.0.42", "@tscircuit/core": "^0.0.1601", "@tscircuit/create-fdm-enclosure": "0.0.3", "@tscircuit/eval": "^0.0.1132", "@tscircuit/fanout-solver": "0.0.11", "@tscircuit/footprinter": "^0.0.409", "@tscircuit/image-utils": "^0.0.8", "@tscircuit/infer-cable-insertion-point": "^0.0.3", "@tscircuit/infgrid-ijump-astar": "^0.0.35", "@tscircuit/internal-dynamic-import": "^0.0.11", "@tscircuit/krt-wasm": "^0.1.1", "@tscircuit/matchpack": "^0.0.64", "@tscircuit/math-utils": "^0.0.36", "@tscircuit/miniflex": "^0.0.4", "@tscircuit/ngspice-spice-engine": "^0.0.20", "@tscircuit/props": "^0.0.612", "@tscircuit/runframe": "^0.0.2365", "@tscircuit/schematic-match-adapt": "^0.0.18", "@tscircuit/schematic-trace-solver": "^0.0.122", "@tscircuit/simple-3d-svg": "^0.0.41", "@tscircuit/solver-utils": "^0.0.16", "@tscircuit/soup-util": "^0.0.41", "bpc-graph": "^0.0.57", "calculate-cell-boundaries": "^0.0.13", "calculate-elbow": "^0.0.12", "calculate-packing": "^0.0.82", "circuit-json": "^0.0.464", "circuit-json-to-bpc": "^0.0.13", "circuit-json-to-connectivity-map": "^0.0.27", "circuit-json-to-gltf": "^0.0.111", "circuit-json-to-pnp-csv": "^0.0.8", "circuit-json-to-simple-3d": "^0.0.9", "circuit-json-to-spice": "^0.0.45", "circuit-to-svg": "^0.0.396", "comlink": "^4.4.2", "connectivity-map": "^1.0.0", "css-select": "5.1.0", "debug": "^4.3.6", "flatbush": "^4.5.0", "format-si-unit": "^0.0.7", "graphics-debug": "^0.0.95", "jscad-planner": "^0.0.13", "kicad-component-converter": "^0.1.40", "kicad-to-circuit-json": "^0.0.117", "kicadts": "^0.0.53", "minicssgrid": "^0.0.9", "performance-now": "^2.1.0", "poppygl": "^0.0.26", "react": "^19.1.0", "react-dom": "^19.1.0", "rollup": "^4.53.2", "rollup-plugin-dts": "^6.2.3", "s-expression": "^3.1.1", "schematic-symbols": "^0.0.238", "spicets": "^0.0.4", "spicey": "^0.0.14", "sucrase": "^3.35.0", "svg-path-commander": "^2.1.11", "transformation-matrix": "^2.16.1", "tslib": "^2.8.1", "zod": "^3.25.67" }, "peerDependencies": { "typescript": "^5.0.0" } }, "sha512-xcAS3IeejEIulJy2rj/hh4EvD+FbB+iBBPpSrXR+c3mEvCfTmRBZ5vqMG1Bo6pOPGGpjH+3kc7IckRhwENit4w=="], "tslib": ["tslib@1.14.1", "", {}, "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="], @@ -1199,6 +1201,12 @@ "@tscircuit/create-fdm-enclosure/jscad-planner": ["jscad-planner@0.0.14", "", { "peerDependencies": { "typescript": "^5.0.0" } }, "sha512-HrS5C1iTrmIZDlvNk065vg36qjIHyeiil60MyW7wccNGaGJSy2SYgWqPNvLU58tUTTTKWECWgd1Wzah80z4Z3A=="], + "@tscircuit/fanout-solver/@tscircuit/capacity-autorouter": ["@tscircuit/capacity-autorouter@0.0.718", "", { "dependencies": { "fast-json-stable-stringify": "^2.1.0", "object-hash": "^3.0.0", "stack-svgs": "^0.0.1" } }, "sha512-DxWzF6sa+0ktVgIXaBEBa5jqyQacNaEPMPZFLjb2js0zUj2PcfihfaFBb456RTNDwRqEsjEIrqlvmAknMsiVVw=="], + + "@tscircuit/fanout-solver/@tscircuit/solver-utils": ["@tscircuit/solver-utils@0.0.19", "", { "peerDependencies": { "graphics-debug": "*", "typescript": "^5" } }, "sha512-UPUVgRRIrylSMJfKw7QwhSCvlODD+uAAwXc9jpOG06ipqteeeLRkj/HtHns31KQfLjRCSsGTvxMYBjmhaDDLGg=="], + + "@tscircuit/fanout-solver/graphics-debug": ["graphics-debug@0.0.96", "", { "dependencies": { "@react-hook/resize-observer": "^2.0.2", "@tscircuit/alphabet": "^0.0.25", "@types/react-router-dom": "^5.3.3", "fast-png": "^8.0.0", "polished": "^4.3.1", "react-router-dom": "^6.28.0", "react-supergrid": "^1.0.10", "svgson": "^5.3.1", "transformation-matrix": "^3.0.0", "use-mouse-matrix-transform": "^1.3.0" }, "peerDependencies": { "bun-match-svg": "*", "looks-same": "^9.0.1", "typescript": "^5.0.0" }, "bin": { "graphics-debug": "dist/cli/cli.js", "gd": "dist/cli/cli.js" } }, "sha512-o3CKFIWtbSL1GSrDYaaYMUidjtCM5PClqvc9/vZVakUT1c61I935bcE++8DnLTXoevJMM1+92y8Uinxl//SuBQ=="], + "@tscircuit/runframe/@tscircuit/eval": ["@tscircuit/eval@0.0.1131", "", { "peerDependencies": { "@tscircuit/core": "*", "circuit-json": "*", "typescript": "^5.0.0", "zod": "3" } }, "sha512-ZfoUQTFgAv2/u7wzFuOlS04+kUE4Pg1an317WmrtsI49L6vaFp3o8ZbvAHhRbQEZzl4/vsa+siCY6nImIIBRkA=="], "@tscircuit/runframe/@tscircuit/solver-utils": ["@tscircuit/solver-utils@0.0.7", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-SB5+A92BMsozxOWfi6iXrcVv1UAFfbBAbKlWHG9TXWquEvAVPSukeCZJ08Yhq0b22T4qkMNy5bZWshXwlO+BuQ=="], @@ -1291,37 +1299,33 @@ "sucrase/commander": ["commander@4.1.1", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="], - "tscircuit/@tscircuit/circuit-json-util": ["@tscircuit/circuit-json-util@0.0.100", "", { "dependencies": { "parsel-js": "^1.1.2" }, "peerDependencies": { "circuit-json": "*", "transformation-matrix": "*", "zod": "3" } }, "sha512-IBedcQurZcQi27MK15OtXzIdRO6OyhyP2jRf+kdgWKZJIvmEH1OgEbsqFh+atiSOMEY9IYlnB1Cv5qZi4MFQrw=="], - - "tscircuit/@tscircuit/core": ["@tscircuit/core@0.0.1495", "", { "dependencies": { "@flatten-js/core": "^1.6.2", "@lume/kiwi": "^0.4.3", "calculate-cell-boundaries": "^0.0.13", "calculate-packing": "^0.0.79", "css-select": "5.1.0", "format-si-unit": "^0.0.7", "nanoid": "^5.0.7", "performance-now": "^2.1.0", "react-reconciler": "^0.32.0", "svg-path-commander": "^2.1.11", "transformation-matrix": "^2.16.1", "zod": "^3.25.67" }, "peerDependencies": { "@tscircuit/capacity-autorouter": "*", "@tscircuit/checks": "*", "@tscircuit/circuit-json-util": "*", "@tscircuit/create-fdm-enclosure": "*", "@tscircuit/footprinter": "*", "@tscircuit/infgrid-ijump-astar": "*", "@tscircuit/matchpack": "*", "@tscircuit/math-utils": "*", "@tscircuit/props": "*", "@tscircuit/schematic-match-adapt": "*", "bpc-graph": "*", "circuit-json": "*", "circuit-json-to-bpc": "*", "circuit-json-to-connectivity-map": "*", "schematic-symbols": "*", "typescript": "^5.0.0" } }, "sha512-UmRqqVZFH01UL7aVYYRojaSaFCy6mDPUEv0rVSR+g67hlztSLR61CtdcrO0kbqmJuhn/VXrJLtDa2eBXcYcj/g=="], + "tscircuit/@tscircuit/circuit-json-util": ["@tscircuit/circuit-json-util@0.0.104", "", { "dependencies": { "parsel-js": "^1.1.2" }, "peerDependencies": { "circuit-json": "*", "transformation-matrix": "*", "zod": "3" } }, "sha512-mJM4s29CHZLGpQvt49PaDk6l7QWv2xZUXYNRby1sqrEoMvEQAs4kqa5cVPRRwtfMkb7K9VKX03HAFBFaHZPmhA=="], - "tscircuit/@tscircuit/eval": ["@tscircuit/eval@0.0.1050", "", { "peerDependencies": { "@tscircuit/core": "*", "circuit-json": "*", "typescript": "^5.0.0", "zod": "3" } }, "sha512-xuOkFjYLNIDpig2hcGcI0mQs39p1P+icZuBvgiRf+oZZnw8VfGzVwMU/erIrLpOFmlqg4X1PUIFZZ13L5NpPEg=="], + "tscircuit/@tscircuit/core": ["@tscircuit/core@0.0.1601", "", { "dependencies": { "@flatten-js/core": "^1.6.2", "@lume/kiwi": "^0.4.3", "calculate-cell-boundaries": "^0.0.13", "calculate-packing": "^0.0.82", "css-select": "5.1.0", "format-si-unit": "^0.0.7", "nanoid": "^5.0.7", "performance-now": "^2.1.0", "react-reconciler": "^0.32.0", "svg-path-commander": "^2.1.11", "transformation-matrix": "^2.16.1", "zod": "^3.25.67" }, "peerDependencies": { "@tscircuit/capacity-autorouter": "*", "@tscircuit/checks": "*", "@tscircuit/circuit-json-util": "*", "@tscircuit/create-fdm-enclosure": "*", "@tscircuit/footprinter": "*", "@tscircuit/infgrid-ijump-astar": "*", "@tscircuit/matchpack": "*", "@tscircuit/math-utils": "*", "@tscircuit/props": "*", "@tscircuit/schematic-match-adapt": "*", "bpc-graph": "*", "circuit-json": "*", "circuit-json-to-bpc": "*", "circuit-json-to-connectivity-map": "*", "circuit-json-to-spice": "*", "schematic-symbols": "*", "spicets": "*", "typescript": "^5.0.0" } }, "sha512-XPPeWHqDtU8f9piYs7xIIF69+IGDxDUMeP07kYPNXUnMr3QvPQ4EDUP+c5UazMumzRBHPrC8jO1Nl8GUfhnOjQ=="], - "tscircuit/@tscircuit/footprinter": ["@tscircuit/footprinter@0.0.380", "", { "dependencies": { "@tscircuit/mm": "^0.0.8", "zod": "^3.23.8" }, "peerDependencies": { "circuit-json": "*" } }, "sha512-gnb2T2fN4K9aiuuNY2XJBspNgxqTu63u4zj+RTCabY+3TpB7VFAwBuBjW3jKoLNIlHd0KGkNmroEdtxnVZlOCQ=="], + "tscircuit/@tscircuit/eval": ["@tscircuit/eval@0.0.1132", "", { "peerDependencies": { "@tscircuit/core": "*", "circuit-json": "*", "typescript": "^5.0.0", "zod": "3" } }, "sha512-NeHOpjai0fkjDY6opYNX1H3rEwkUS8rBDgZpprUsNlEvWsih+sbsIyPIWvAOVMGNQ2tvuxgUb2hIeALLO2ZZHA=="], - "tscircuit/@tscircuit/props": ["@tscircuit/props@0.0.589", "", { "peerDependencies": { "circuit-json": "*", "react": "*", "zod": "*" } }, "sha512-xpu4R5R5ajZ6wVtMLluwFCF9Y8EGxlCzGGufhbWOYcOGFCdcggWC/CXY5eIYKYSpVVroSi4uYNSoojdSOsPUPw=="], + "tscircuit/@tscircuit/footprinter": ["@tscircuit/footprinter@0.0.409", "", { "dependencies": { "@tscircuit/mm": "^0.0.8", "zod": "^3.23.8" }, "peerDependencies": { "circuit-json": "*" } }, "sha512-6VsrtGsvBj7MCIXxo9ofZkdkQj/eUK4u9fHrRPo/Q+ePJB4qEl8QMAa4ih9PEWTv4OuZniAQnkaMbS6zwGkUfg=="], - "tscircuit/@tscircuit/runframe": ["@tscircuit/runframe@0.0.2263", "", { "dependencies": { "@tscircuit/eval": "^0.0.1050", "@tscircuit/solver-utils": "^0.0.7" } }, "sha512-3aWTxJaLs2GZC0dKyr67gt+LGtwCE+rb4Hf9Onz5883WGuVeeNJEtIbJB8o0cmPsV9jwBiq+EKkuh+9w6sbUqA=="], + "tscircuit/@tscircuit/runframe": ["@tscircuit/runframe@0.0.2365", "", { "dependencies": { "@tscircuit/eval": "^0.0.1132", "@tscircuit/solver-utils": "^0.0.7", "debug": "^4.4.0" } }, "sha512-ugeiOvh2pVQ2K/k9c0q1jrG05eaiqFW1hAWPMj6HoRPXK8qne5EAxJcBcHy0e3ZQqCiWSRdgIJzLe9rmpAkLug=="], "tscircuit/@tscircuit/schematic-match-adapt": ["@tscircuit/schematic-match-adapt@0.0.18", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-LpXF7aSmP4xUZN1gdrU/YdAnotJ+oKW2a4YzGB6wNTXnw5+Yn0w/bPnReT4A+nNUrVJ9kyjgnXQkSlkhiejQGg=="], - "tscircuit/circuit-json": ["circuit-json@0.0.453", "", { "peerDependencies": { "format-si-unit": "*" } }, "sha512-BxdRuD6WPlUXfwQjwZzX0dA9V6CsmusH5SK4UT34oheCU/XPGi+SZuUHfUTqvKd+V8LcCa68+Hjkdld7x4BG1Q=="], - - "tscircuit/circuit-json-to-connectivity-map": ["circuit-json-to-connectivity-map@0.0.23", "", { "dependencies": { "@tscircuit/math-utils": "^0.0.9" }, "peerDependencies": { "typescript": "^5.9.3" } }, "sha512-DSOiXaXOTvjU+7et8ITXb2LjgKto6cQzLv3hReYdXuUNtLw2GVnpOly1G83VcIBcSQ4hRVHI4VMKRyZB3XVzdg=="], + "tscircuit/circuit-json-to-connectivity-map": ["circuit-json-to-connectivity-map@0.0.27", "", { "dependencies": { "@tscircuit/math-utils": "^0.0.9" }, "peerDependencies": { "typescript": "^5.9.3" } }, "sha512-DxAcRjtKjzuB4IQluF2hSOvVxlwiIkXCcLDsdHWwyDXp+dEfGx+BfDzPrflk2sbgSOuLJUBfj2FJInWPFCh70Q=="], - "tscircuit/circuit-json-to-gltf": ["circuit-json-to-gltf@0.0.107", "", { "dependencies": { "@jscad/modeling": "^2.12.6", "earcut": "^3.0.2", "jscad-electronics": "^0.0.135", "jscad-planner": "^0.0.14", "jscad-to-gltf": "^0.0.5", "occt-import-js": "^0.0.23" }, "peerDependencies": { "@resvg/resvg-js": "2", "@resvg/resvg-wasm": "2", "@tscircuit/circuit-json-util": "*", "circuit-json": "*", "circuit-to-svg": "*", "typescript": "^5" }, "optionalPeers": ["@resvg/resvg-js", "@resvg/resvg-wasm"] }, "sha512-YuER0b6d+bYk/S/FAClS3RPW3ipo/CQb+OoNZiNkNqObsuRh6N/UxQeo/M1NXh+b0j2tfeL0nlSIkfSmKx9lyQ=="], + "tscircuit/circuit-json-to-gltf": ["circuit-json-to-gltf@0.0.111", "", { "dependencies": { "@jscad/modeling": "^2.12.6", "earcut": "^3.0.2", "jscad-electronics": "^0.0.135", "jscad-planner": "^0.0.14", "jscad-to-gltf": "^0.0.5", "occt-import-js": "^0.0.23" }, "peerDependencies": { "@resvg/resvg-js": "2", "@resvg/resvg-wasm": "2", "@tscircuit/circuit-json-util": "*", "circuit-json": "*", "circuit-to-svg": "*", "typescript": "^5" }, "optionalPeers": ["@resvg/resvg-js", "@resvg/resvg-wasm"] }, "sha512-EKIw/Bflz9NWmM7dNvFiKMVkNPF5Jbnze/Y2IjkwRGesi/Ep+8tR6q3flDgnHBTdNcPlT33RiYXXfH8mYOb3kg=="], - "tscircuit/circuit-json-to-spice": ["circuit-json-to-spice@0.0.43", "", { "dependencies": { "circuit-json-to-connectivity-map": "^0.0.22" }, "peerDependencies": { "@tscircuit/circuit-json-util": "*", "circuit-json": "*", "typescript": "^5.0.0" } }, "sha512-lYXOplosjiYhpWe8IUJ8s9E9G0OH4c+Ygn60lnpco1TEjwD+byUTp3dCk6qDw5VNG5QUdGUD1pe95HoFMzL/TA=="], + "tscircuit/circuit-json-to-pnp-csv": ["circuit-json-to-pnp-csv@0.0.8", "", { "dependencies": { "papaparse": "^5.4.1" }, "peerDependencies": { "@tscircuit/soup-util": "*", "typescript": "^5.0.0" } }, "sha512-m3ycvl5Cx1woE3qNdf457f2r/6WBxBxwbbkYbXbB/a+eEe7Y1Kk9BIq8GBsq7j25MTBeR0mbDMGL6yZGqSAVDA=="], - "tscircuit/circuit-to-svg": ["circuit-to-svg@0.0.391", "", { "dependencies": { "@types/node": "^22.5.5", "bun-types": "^1.1.40", "calculate-elbow": "0.0.12", "debug": "^4.4.3", "svg-path-commander": "^2.1.11", "svgson": "^5.3.1", "transformation-matrix": "^2.16.1" }, "peerDependencies": { "@tscircuit/alphabet": "*" } }, "sha512-TMh2vieRiFXQ0Pjkp9eCDT6oyyJ0BGYtZHDfzZNubcJH5JjYNTV9116BG6Vkv+Lot2nz3aUnZplg9+4Z6gTJIQ=="], + "tscircuit/circuit-to-svg": ["circuit-to-svg@0.0.396", "", { "dependencies": { "@types/node": "^22.5.5", "bun-types": "^1.1.40", "calculate-elbow": "0.0.12", "debug": "^4.4.3", "svg-path-commander": "^2.1.11", "svgson": "^5.3.1", "transformation-matrix": "^2.16.1" }, "peerDependencies": { "@tscircuit/alphabet": "*" } }, "sha512-idE7yFgwqNp26edgQpEW1pMYJL/agWXTRQi88cPjdo6FpVuZJr2+MCQpmXMlQRhGYqyBEH2KHsPsiF+hA8cvAQ=="], "tscircuit/format-si-unit": ["format-si-unit@0.0.7", "", { "peerDependencies": { "typescript": "^5.0.0" } }, "sha512-wTi2TqGqPG9LvUwhshiMlaert+1kWtxMEzIpKIkVbmOz4bopcDtqpDKV06JT6xpGIquOSFbkV1fQoMHq6UJZ1g=="], - "tscircuit/kicadts": ["kicadts@0.0.51", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-QQjMRad5zcfvoj8+8UI11bc5vLvboru9jbNYvsJ/9e35QyFJ5x3DmyJCDJp7GE8s7UdUmwct5QRT13VbSCbLOA=="], + "tscircuit/kicad-to-circuit-json": ["kicad-to-circuit-json@0.0.117", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-JXIGIix7t39kcpqFEQP9m/eWqN/2MqeCFME628xbhrXRu8nNBSGD54vozKNh9GsFVqIpzGxciS6SGVxWrA+osw=="], - "tscircuit/poppygl": ["poppygl@0.0.26", "", { "dependencies": { "fast-png": "^8.0.0", "gl-matrix": "^3.4.4", "pureimage": "^0.4.18", "readable-stream": "^4.7.0" }, "peerDependencies": { "typescript": "^5" } }, "sha512-5jnQuKpDCfFT0b9aCm/AidGdzwjw/I3obFpc10j66FY7ZtDPMRekHYU76BzfKDyV5iU8BBWQzxX+8lS9+EEkbg=="], + "tscircuit/kicadts": ["kicadts@0.0.53", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-qXBtGBc11LhG93dF4iXlVeWbVjk5UUmeUANpP+cgvbRxZa+w7p2UvSCK7/4uv7KzGKhxzSJouEPSAZdastlXag=="], - "tscircuit/spicets": ["spicets@0.0.2", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-Or30bFInG8QFfgQOj+84fsVMyKC6pFa879PnwyLy0EXWUF3KHKQlqMUSfjuD7KS9bTbGQCVe3eEVrfdHqS7TWQ=="], + "tscircuit/poppygl": ["poppygl@0.0.26", "", { "dependencies": { "fast-png": "^8.0.0", "gl-matrix": "^3.4.4", "pureimage": "^0.4.18", "readable-stream": "^4.7.0" }, "peerDependencies": { "typescript": "^5" } }, "sha512-5jnQuKpDCfFT0b9aCm/AidGdzwjw/I3obFpc10j66FY7ZtDPMRekHYU76BzfKDyV5iU8BBWQzxX+8lS9+EEkbg=="], "tscircuit/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], @@ -1347,6 +1351,8 @@ "@tscircuit/create-fdm-enclosure/graphics-debug/transformation-matrix": ["transformation-matrix@3.1.0", "", {}, "sha512-oYubRWTi2tYFHAL2J8DLvPIqIYcYZ0fSOi2vmSy042Ho4jBW2ce6VP7QfD44t65WQz6bw5w1Pk22J7lcUpaTKA=="], + "@tscircuit/fanout-solver/graphics-debug/transformation-matrix": ["transformation-matrix@3.1.0", "", {}, "sha512-oYubRWTi2tYFHAL2J8DLvPIqIYcYZ0fSOi2vmSy042Ho4jBW2ce6VP7QfD44t65WQz6bw5w1Pk22J7lcUpaTKA=="], + "bl/readable-stream/string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="], "calculate-cell-boundaries/react-dom/scheduler": ["scheduler@0.23.2", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ=="], @@ -1393,8 +1399,6 @@ "tscircuit/circuit-json-to-gltf/jscad-planner": ["jscad-planner@0.0.14", "", { "peerDependencies": { "typescript": "^5.0.0" } }, "sha512-HrS5C1iTrmIZDlvNk065vg36qjIHyeiil60MyW7wccNGaGJSy2SYgWqPNvLU58tUTTTKWECWgd1Wzah80z4Z3A=="], - "tscircuit/circuit-json-to-spice/circuit-json-to-connectivity-map": ["circuit-json-to-connectivity-map@0.0.22", "", { "dependencies": { "@tscircuit/math-utils": "^0.0.9" }, "peerDependencies": { "typescript": "^5.0.0" } }, "sha512-HN8DiISjZZLTglGEkYNRpKeQ/DMG4dDo5j4Hck0UGSJbpux9aFwtJOGszMf06Inh/gu5oKBrpZJIeWxaNacKUg=="], - "tscircuit/circuit-to-svg/@types/node": ["@types/node@22.20.1", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q=="], "tscircuit/poppygl/readable-stream": ["readable-stream@4.7.0", "", { "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="], @@ -1465,8 +1469,6 @@ "prebuild-install/tar-fs/tar-stream/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], - "tscircuit/circuit-json-to-spice/circuit-json-to-connectivity-map/@tscircuit/math-utils": ["@tscircuit/math-utils@0.0.9", "", { "peerDependencies": { "typescript": "^5.0.0" } }, "sha512-sPzfXndijet8z29X6f5vnSZddiso2tRg7m6rB+268bVj60mxnxUMD14rKuMlLn6n84fMOpD/X7pRTZUfi6M+Tg=="], - "tscircuit/circuit-to-svg/@types/node/undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], "tscircuit/poppygl/readable-stream/string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="], diff --git a/cli/check/netlist/register.ts b/cli/check/netlist/register.ts index 9d8798015..1916a4dff 100644 --- a/cli/check/netlist/register.ts +++ b/cli/check/netlist/register.ts @@ -1,44 +1,70 @@ -import { - type DrcCategory, - categorizeErrorOrWarning, -} from "@tscircuit/circuit-json-util" +import path from "node:path" +import { categorizeErrorOrWarning } from "@tscircuit/circuit-json-util" import type { PlatformConfig } from "@tscircuit/props" +import type { AnyCircuitElement } from "circuit-json" import { convertCircuitJsonToReadableNetlist } from "circuit-json-to-readable-netlist" import type { Command } from "commander" +import { findCircuitProjectDir } from "lib/shared/circuit-json-build-cache" import { type CircuitJsonIssue, analyzeCircuitJson, } from "lib/shared/circuit-json-diagnostics" -import { getCircuitJsonForCheck, resolveCheckInputFilePath } from "../shared" +import { getEntrypoint } from "lib/shared/get-entrypoint" +import { getOrGenerateCircuitJson } from "lib/shared/get-or-generate-circuit-json" +import { getPlatformConfigWithCliDefaults } from "lib/shared/get-platform-config-with-cli-defaults" + +export function isNetlistDiagnostic(issue: CircuitJsonIssue) { + if (categorizeErrorOrWarning(issue) === "netlist") { + return true + } + + if (issue.type !== "source_property_ignored_warning") { + return false + } + + switch (issue.property_name) { + case "positiveConnection": + case "negativeConnection": + return true + default: + return false + } +} + +const resolveInputFilePath = async (file?: string) => { + if (file) { + return path.isAbsolute(file) ? file : path.resolve(process.cwd(), file) + } -const normalizeCategory = (category: string): DrcCategory => - category === "netlist" || - category === "pin_specification" || - category === "placement" || - category === "routing" - ? category - : "unknown" + const entrypoint = await getEntrypoint({ + projectDir: process.cwd(), + }) -const isDifferentialPairConnectionWarning = (issue: CircuitJsonIssue) => - issue.type === "source_property_ignored_warning" && - (issue.property_name === "positiveConnection" || - issue.property_name === "negativeConnection") + if (!entrypoint) { + throw new Error("No input file provided and no entrypoint found") + } -const isNetlistDiagnostic = (issue: CircuitJsonIssue) => - isDifferentialPairConnectionWarning(issue) || - normalizeCategory(categorizeErrorOrWarning(issue)) === "netlist" + return entrypoint +} export const checkNetlist = async (file?: string) => { - const resolvedInputFilePath = await resolveCheckInputFilePath(file) - const typedCircuitJson = await getCircuitJsonForCheck({ - filePath: resolvedInputFilePath, - platformConfig: { + const resolvedInputFilePath = await resolveInputFilePath(file) + + const platformConfigWithCliDefaults = getPlatformConfigWithCliDefaults( + { pcbDisabled: true, routingDisabled: true, placementDrcChecksDisabled: true, } satisfies PlatformConfig, - allowPrebuiltCircuitJson: true, + { projectDir: findCircuitProjectDir(resolvedInputFilePath) }, + ) + + const { circuitJson } = await getOrGenerateCircuitJson({ + filePath: resolvedInputFilePath, + platformConfig: platformConfigWithCliDefaults, }) + + const typedCircuitJson = circuitJson as AnyCircuitElement[] const diagnostics = analyzeCircuitJson(typedCircuitJson) const netlistErrors = diagnostics.errors.filter(isNetlistDiagnostic) const netlistWarnings = diagnostics.warnings.filter(isNetlistDiagnostic) @@ -73,7 +99,7 @@ export const registerCheckNetlist = (program: Command) => { .find((c) => c.name() === "check")! .command("netlist") .description("Partially build and validate the netlist") - .argument("[file]", "Path to the entry file or prebuilt Circuit JSON") + .argument("[file]", "Path to the entry file") .action(async (file?: string) => { try { const output = await checkNetlist(file) diff --git a/package.json b/package.json index 7201899e5..b082a0aa9 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,7 @@ "spicets": "^0.0.4", "stepts": "^0.0.3", "tempy": "^3.1.0", - "tscircuit": "0.0.2142-libonly", + "tscircuit": "0.0.2232-libonly", "tsx": "^4.7.1", "typed-ky": "^0.0.4", "zod": "^3.23.8" diff --git a/tests/analyze-circuit-json-warning-type-precedence.test.ts b/tests/analyze-circuit-json-warning-type-precedence.test.ts new file mode 100644 index 000000000..6c7a2be90 --- /dev/null +++ b/tests/analyze-circuit-json-warning-type-precedence.test.ts @@ -0,0 +1,16 @@ +import { expect, test } from "bun:test" +import { analyzeCircuitJson } from "lib/shared/circuit-json-diagnostics" + +test("analyzeCircuitJson prefers a warning type over error_type metadata", () => { + const { errors, warnings } = analyzeCircuitJson([ + { + type: "source_property_ignored_warning", + error_type: "source_property_ignored_warning", + property_name: "positiveConnection", + message: "ambiguous differential-pair trace", + }, + ]) + + expect(errors).toHaveLength(0) + expect(warnings).toHaveLength(1) +}) diff --git a/tests/analyze-circuit-json.test.ts b/tests/analyze-circuit-json.test.ts index e91594c2e..de59d603d 100644 --- a/tests/analyze-circuit-json.test.ts +++ b/tests/analyze-circuit-json.test.ts @@ -1,4 +1,4 @@ -import { expect, test } from "bun:test" +import { test, expect } from "bun:test" import { analyzeCircuitJson } from "lib/shared/circuit-json-diagnostics" const sample = [ @@ -39,17 +39,3 @@ test("analyzeCircuitJson does not double-count items with both type and error me expect(errors).toHaveLength(1) expect(warnings).toHaveLength(1) }) - -test("analyzeCircuitJson prefers a warning type over error_type metadata", () => { - const { errors, warnings } = analyzeCircuitJson([ - { - type: "source_property_ignored_warning", - error_type: "source_property_ignored_warning", - property_name: "positiveConnection", - message: "ambiguous differential-pair trace", - }, - ]) - - expect(errors).toHaveLength(0) - expect(warnings).toHaveLength(1) -}) diff --git a/tests/cli/check/check-netlist-differential-pair-classification.test.ts b/tests/cli/check/check-netlist-differential-pair-classification.test.ts new file mode 100644 index 000000000..54b5bce4c --- /dev/null +++ b/tests/cli/check/check-netlist-differential-pair-classification.test.ts @@ -0,0 +1,17 @@ +import { expect, test } from "bun:test" +import { isNetlistDiagnostic } from "cli/check/netlist/register" + +test("only differential-pair connection properties are netlist warnings", () => { + const createPropertyWarning = (property_name: string) => ({ + type: "source_property_ignored_warning", + property_name, + }) + + expect(isNetlistDiagnostic(createPropertyWarning("positiveConnection"))).toBe( + true, + ) + expect(isNetlistDiagnostic(createPropertyWarning("negativeConnection"))).toBe( + true, + ) + expect(isNetlistDiagnostic(createPropertyWarning("footprint"))).toBe(false) +}) diff --git a/tests/cli/check/check-netlist-differential-pair-warnings.test.ts b/tests/cli/check/check-netlist-differential-pair-warnings.test.ts new file mode 100644 index 000000000..2c4e8e1fb --- /dev/null +++ b/tests/cli/check/check-netlist-differential-pair-warnings.test.ts @@ -0,0 +1,40 @@ +import { expect, test } from "bun:test" +import { writeFile } from "node:fs/promises" +import path from "node:path" +import { getCliTestFixture } from "../../fixtures/get-cli-test-fixture" + +const circuitCode = ` +export default () => ( + + + + + + + + + + +) +` + +test("check netlist displays Core differential-pair warnings", async () => { + const { tmpDir, runCommand } = await getCliTestFixture() + const circuitPath = path.join(tmpDir, "differential-pair.tsx") + + await writeFile(circuitPath, circuitCode) + + const { stdout, stderr, exitCode } = await runCommand( + `tsci check netlist ${circuitPath}`, + ) + + expect(exitCode).toBe(0) + expect(stderr).toBe("") + expect(stdout).toContain("Errors: 0") + expect(stdout).toContain("Warnings: 1") + expect(stdout).toContain("- source_property_ignored_warning:") +}, 20_000) diff --git a/tests/cli/check/check-netlist.test.ts b/tests/cli/check/check-netlist.test.ts index ddc3e2f6e..29420419e 100644 --- a/tests/cli/check/check-netlist.test.ts +++ b/tests/cli/check/check-netlist.test.ts @@ -1,6 +1,6 @@ import { expect, test } from "bun:test" -import { writeFile } from "node:fs/promises" import path from "node:path" +import { writeFile } from "node:fs/promises" import { getCliTestFixture } from "../../fixtures/get-cli-test-fixture" const circuitCode = ` @@ -75,57 +75,3 @@ test("check netlist filters out placement diagnostics", async () => { expect(stdout).not.toContain("pcb_component_outside_board_error") expect(stdout).not.toContain("Component R1 extends outside board boundaries") }, 20_000) - -test("check netlist displays ambiguous differential-pair trace warnings", async () => { - const { tmpDir, runCommand } = await getCliTestFixture() - const circuitPath = path.join(tmpDir, "differential-pair.circuit.json") - const positiveConnectionMessage = "ambiguous positive differential-pair trace" - const negativeConnectionMessage = "ambiguous negative differential-pair trace" - const unrelatedWarningMessage = "ignored footprint property" - - await writeFile( - circuitPath, - JSON.stringify([ - { - type: "source_property_ignored_warning", - source_property_ignored_warning_id: "source_property_ignored_warning_0", - source_component_id: "source_component_j1", - property_name: "positiveConnection", - error_type: "source_property_ignored_warning", - message: positiveConnectionMessage, - }, - { - type: "source_property_ignored_warning", - source_property_ignored_warning_id: "source_property_ignored_warning_1", - source_component_id: "source_component_j1", - property_name: "negativeConnection", - error_type: "source_property_ignored_warning", - message: negativeConnectionMessage, - }, - { - type: "source_property_ignored_warning", - source_property_ignored_warning_id: "source_property_ignored_warning_2", - source_component_id: "source_component_j1", - property_name: "footprint", - error_type: "source_property_ignored_warning", - message: unrelatedWarningMessage, - }, - ]), - ) - - const { stdout, stderr, exitCode } = await runCommand( - `tsci check netlist ${circuitPath}`, - ) - - expect(exitCode).toBe(0) - expect(stderr).toBe("") - expect(stdout).toContain("Errors: 0") - expect(stdout).toContain("Warnings: 2") - expect(stdout).toContain( - `- source_property_ignored_warning: ${positiveConnectionMessage}`, - ) - expect(stdout).toContain( - `- source_property_ignored_warning: ${negativeConnectionMessage}`, - ) - expect(stdout).not.toContain(unrelatedWarningMessage) -}, 20_000)