@tscircuit/cli 0.1.1809 → 0.1.1811

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.
@@ -13055,11 +13055,12 @@ function createLocalCacheEngine(cacheDir = path8.join(process.cwd(), ".tscircuit
13055
13055
  }
13056
13056
  };
13057
13057
  }
13058
- function getPlatformConfigWithCliDefaults(userConfig) {
13058
+ function getPlatformConfigWithCliDefaults(userConfig, options) {
13059
13059
  const basePlatformConfig = getPlatformConfig();
13060
+ const cacheDir = options?.projectDir ? path8.join(options.projectDir, ".tscircuit", "cache") : undefined;
13060
13061
  const defaultConfig = {
13061
13062
  ...basePlatformConfig,
13062
- localCacheEngine: createLocalCacheEngine(),
13063
+ localCacheEngine: createLocalCacheEngine(cacheDir),
13063
13064
  footprintFileParserMap: {
13064
13065
  ...basePlatformConfig.footprintFileParserMap,
13065
13066
  kicad_mod: {
@@ -17395,7 +17396,7 @@ var handleBuildFile = async (filePath, outputPath, glbOutputPath, stepOutputPath
17395
17396
  await registerStaticAssetLoaders();
17396
17397
  const projectConfig = await loadRuntimeProjectConfig(projectDir);
17397
17398
  const platformConfig = mergePlatformConfigs(projectConfig?.platformConfig, options?.platformConfig);
17398
- const platformConfigWithCliDefaults = getPlatformConfigWithCliDefaults(platformConfig);
17399
+ const platformConfigWithCliDefaults = getPlatformConfigWithCliDefaults(platformConfig, { projectDir });
17399
17400
  const normalizedInputPath = filePath.toLowerCase().replaceAll("\\", "/");
17400
17401
  const isPrebuiltCircuitJson = normalizedInputPath.endsWith(".circuit.json") || normalizedInputPath.endsWith("/circuit.json");
17401
17402
  const circuitJson = isPrebuiltCircuitJson ? loadCircuitJsonFromInputFile(filePath) : (await generateCircuitJson({
package/dist/cli/main.js CHANGED
@@ -118506,7 +118506,7 @@ var import_perfect_cli = __toESM2(require_dist2(), 1);
118506
118506
  // lib/getVersion.ts
118507
118507
  import { createRequire as createRequire2 } from "node:module";
118508
118508
  // package.json
118509
- var version = "0.1.1808";
118509
+ var version = "0.1.1809";
118510
118510
  var package_default = {
118511
118511
  name: "@tscircuit/cli",
118512
118512
  version,
@@ -118521,7 +118521,7 @@ var package_default = {
118521
118521
  "@tscircuit/check-shorts": "https://jscdn.tscircuit.com/@tscircuit/check-shorts/0.0.12.tgz",
118522
118522
  "@tscircuit/circuit-json-placement-analysis": "^0.0.6",
118523
118523
  "@tscircuit/circuit-json-routing-analysis": "^0.0.6",
118524
- "@tscircuit/circuit-json-schematic-placement-analysis": "github:tscircuit/circuit-json-schematic-placement-analysis#b6d5fe675adc26a2fc988aa081e6fb51e6bf696a",
118524
+ "@tscircuit/circuit-json-schematic-placement-analysis": "github:tscircuit/circuit-json-schematic-placement-analysis#bb0b41d80c9714695b498e182c2a558f1e0ceb2d",
118525
118525
  "@tscircuit/eval": "^0.0.1016",
118526
118526
  "@tscircuit/fake-snippets": "^0.0.182",
118527
118527
  "@tscircuit/file-server": "^0.0.32",
@@ -129875,11 +129875,12 @@ function createLocalCacheEngine(cacheDir = path19.join(process.cwd(), ".tscircui
129875
129875
  }
129876
129876
  };
129877
129877
  }
129878
- function getPlatformConfigWithCliDefaults(userConfig) {
129878
+ function getPlatformConfigWithCliDefaults(userConfig, options) {
129879
129879
  const basePlatformConfig = getPlatformConfig();
129880
+ const cacheDir = options?.projectDir ? path19.join(options.projectDir, ".tscircuit", "cache") : undefined;
129880
129881
  const defaultConfig = {
129881
129882
  ...basePlatformConfig,
129882
- localCacheEngine: createLocalCacheEngine(),
129883
+ localCacheEngine: createLocalCacheEngine(cacheDir),
129883
129884
  footprintFileParserMap: {
129884
129885
  ...basePlatformConfig.footprintFileParserMap,
129885
129886
  kicad_mod: {
@@ -130887,7 +130888,7 @@ var buildFile = async (input, output, projectDir, options) => {
130887
130888
  const parsed = JSON.parse(fs28.readFileSync(input, "utf-8"));
130888
130889
  circuitJson = Array.isArray(parsed) ? parsed : [];
130889
130890
  }
130890
- const platformConfigWithCliDefaults = getPlatformConfigWithCliDefaults(options?.platformConfig);
130891
+ const platformConfigWithCliDefaults = getPlatformConfigWithCliDefaults(options?.platformConfig, { projectDir });
130891
130892
  if (!isPrebuiltCircuitJson) {
130892
130893
  const result = await generateCircuitJson({
130893
130894
  filePath: input,
@@ -136388,7 +136389,7 @@ var checkNetlist = async (file) => {
136388
136389
  pcbDisabled: true,
136389
136390
  routingDisabled: true,
136390
136391
  placementDrcChecksDisabled: true
136391
- });
136392
+ }, { projectDir: findCircuitProjectDir(resolvedInputFilePath) });
136392
136393
  const { circuitJson } = await getOrGenerateCircuitJson({
136393
136394
  filePath: resolvedInputFilePath,
136394
136395
  platformConfig: platformConfigWithCliDefaults
@@ -136465,7 +136466,9 @@ var getCircuitJsonForCheck = async ({
136465
136466
  const parsedJson = JSON.parse(fs43.readFileSync(filePath, "utf-8"));
136466
136467
  return Array.isArray(parsedJson) ? parsedJson : [];
136467
136468
  }
136468
- const platformConfigWithCliDefaults = getPlatformConfigWithCliDefaults(platformConfig);
136469
+ const platformConfigWithCliDefaults = getPlatformConfigWithCliDefaults(platformConfig, {
136470
+ projectDir: findCircuitProjectDir(filePath)
136471
+ });
136469
136472
  const { circuitJson } = await getOrGenerateCircuitJson({
136470
136473
  filePath,
136471
136474
  platformConfig: platformConfigWithCliDefaults,
@@ -283393,8 +283396,22 @@ import {
283393
283396
 
283394
283397
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/utils/placements.ts
283395
283398
  import { cju as cju7 } from "@tscircuit/circuit-json-util";
283399
+
283400
+ // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/utils/schematic-sheets.ts
283401
+ var getSchematicSheetNamesById = (circuitJson) => {
283402
+ const map = new Map;
283403
+ for (const element of circuitJson) {
283404
+ if (element.type === "schematic_sheet" && element.name) {
283405
+ map.set(element.schematic_sheet_id, element.name);
283406
+ }
283407
+ }
283408
+ return map;
283409
+ };
283410
+
283411
+ // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/utils/placements.ts
283396
283412
  var isSchematicBox = (el3) => el3.type === "schematic_box";
283397
283413
  var isSchematicComponent = (el3) => el3.type === "schematic_component";
283414
+ var getSchematicSheetId = (el3) => el3.schematic_sheet_id;
283398
283415
  var getSourceComponentName = (circuitJson, sourceComponentId) => {
283399
283416
  if (!sourceComponentId)
283400
283417
  return;
@@ -283413,37 +283430,69 @@ var getSourceComponentMetadata = (schematicBox, circuitJson) => {
283413
283430
  sourceComponentName: sourceComponent?.name
283414
283431
  };
283415
283432
  };
283416
- var schematicComponentToPlacement = (schematicComponent, circuitJson, schematicBox) => ({
283417
- lineItemType: "SchematicBoxPlacement",
283418
- positionAnchor: "center",
283419
- schX: schematicComponent.center.x,
283420
- schY: schematicComponent.center.y,
283421
- width: schematicBox?.width ?? schematicComponent.size.width,
283422
- height: schematicBox?.height ?? schematicComponent.size.height,
283423
- sourceComponentId: schematicComponent.source_component_id,
283424
- sourceComponentName: getSourceComponentName(circuitJson, schematicComponent.source_component_id),
283425
- schematicComponentId: schematicComponent.schematic_component_id,
283426
- schematicSymbolId: schematicBox?.schematic_symbol_id ?? schematicComponent.schematic_symbol_id,
283427
- subcircuitId: schematicComponent.subcircuit_id ?? schematicBox?.subcircuit_id
283428
- });
283429
- var schematicBoxToPlacement = (schematicBox, circuitJson) => ({
283430
- lineItemType: "SchematicBoxPlacement",
283431
- positionAnchor: "center",
283432
- schX: schematicBox.x,
283433
- schY: schematicBox.y,
283434
- width: schematicBox.width,
283435
- height: schematicBox.height,
283436
- ...getSourceComponentMetadata(schematicBox, circuitJson),
283437
- schematicComponentId: schematicBox.schematic_component_id,
283438
- schematicSymbolId: schematicBox.schematic_symbol_id,
283439
- subcircuitId: schematicBox.subcircuit_id
283440
- });
283433
+ var schematicComponentToPlacement = (schematicComponent, circuitJson, schematicSheetNameById, schematicBox) => {
283434
+ let schematicSheetId = getSchematicSheetId(schematicComponent);
283435
+ if (schematicSheetId === undefined && schematicBox) {
283436
+ schematicSheetId = getSchematicSheetId(schematicBox);
283437
+ }
283438
+ let schematicSheetName;
283439
+ if (schematicSheetId) {
283440
+ schematicSheetName = schematicSheetNameById.get(schematicSheetId);
283441
+ }
283442
+ const placement = {
283443
+ lineItemType: "SchematicBoxPlacement",
283444
+ positionAnchor: "center",
283445
+ schX: schematicComponent.center.x,
283446
+ schY: schematicComponent.center.y,
283447
+ width: schematicBox?.width ?? schematicComponent.size.width,
283448
+ height: schematicBox?.height ?? schematicComponent.size.height,
283449
+ sourceComponentId: schematicComponent.source_component_id,
283450
+ sourceComponentName: getSourceComponentName(circuitJson, schematicComponent.source_component_id),
283451
+ schematicComponentId: schematicComponent.schematic_component_id,
283452
+ schematicSymbolId: schematicBox?.schematic_symbol_id ?? schematicComponent.schematic_symbol_id,
283453
+ subcircuitId: schematicComponent.subcircuit_id ?? schematicBox?.subcircuit_id
283454
+ };
283455
+ if (schematicSheetId) {
283456
+ placement.schematicSheetId = schematicSheetId;
283457
+ }
283458
+ if (schematicSheetName) {
283459
+ placement.schematicSheetName = schematicSheetName;
283460
+ }
283461
+ return placement;
283462
+ };
283463
+ var schematicBoxToPlacement = (schematicBox, circuitJson, schematicSheetNameById) => {
283464
+ const schematicSheetId = getSchematicSheetId(schematicBox);
283465
+ let schematicSheetName;
283466
+ if (schematicSheetId) {
283467
+ schematicSheetName = schematicSheetNameById.get(schematicSheetId);
283468
+ }
283469
+ const placement = {
283470
+ lineItemType: "SchematicBoxPlacement",
283471
+ positionAnchor: "center",
283472
+ schX: schematicBox.x,
283473
+ schY: schematicBox.y,
283474
+ width: schematicBox.width,
283475
+ height: schematicBox.height,
283476
+ ...getSourceComponentMetadata(schematicBox, circuitJson),
283477
+ schematicComponentId: schematicBox.schematic_component_id,
283478
+ schematicSymbolId: schematicBox.schematic_symbol_id,
283479
+ subcircuitId: schematicBox.subcircuit_id
283480
+ };
283481
+ if (schematicSheetId) {
283482
+ placement.schematicSheetId = schematicSheetId;
283483
+ }
283484
+ if (schematicSheetName) {
283485
+ placement.schematicSheetName = schematicSheetName;
283486
+ }
283487
+ return placement;
283488
+ };
283441
283489
  var buildSolverContext = (circuitJson) => {
283442
283490
  const schematicBoxes = circuitJson.filter(isSchematicBox);
283491
+ const schematicSheetNameById = getSchematicSheetNamesById(circuitJson);
283443
283492
  const schematicComponentIds = new Set(circuitJson.filter(isSchematicComponent).map((sc2) => sc2.schematic_component_id));
283444
283493
  const componentPlacements = [
283445
- ...circuitJson.filter(isSchematicComponent).map((sc2) => schematicComponentToPlacement(sc2, circuitJson, schematicBoxes.find((sb3) => sb3.schematic_component_id === sc2.schematic_component_id))),
283446
- ...schematicBoxes.filter((sb3) => !sb3.schematic_component_id || !schematicComponentIds.has(sb3.schematic_component_id)).map((sb3) => schematicBoxToPlacement(sb3, circuitJson))
283494
+ ...circuitJson.filter(isSchematicComponent).map((sc2) => schematicComponentToPlacement(sc2, circuitJson, schematicSheetNameById, schematicBoxes.find((sb3) => sb3.schematic_component_id === sc2.schematic_component_id))),
283495
+ ...schematicBoxes.filter((sb3) => !sb3.schematic_component_id || !schematicComponentIds.has(sb3.schematic_component_id)).map((sb3) => schematicBoxToPlacement(sb3, circuitJson, schematicSheetNameById))
283447
283496
  ];
283448
283497
  return { circuitJson, componentPlacements };
283449
283498
  };
@@ -283712,6 +283761,8 @@ class SchematicBoxOverlapSolver extends BaseSolver7 {
283712
283761
  return `<OverlapCorrectionSuggestion ${attrs.join(" ")} />`;
283713
283762
  }
283714
283763
  getComponentOverlap(firstComponent, secondComponent) {
283764
+ if (firstComponent.schematicSheetId !== secondComponent.schematicSheetId)
283765
+ return null;
283715
283766
  const a3 = this.getCenteredRectBounds(firstComponent);
283716
283767
  const b3 = this.getCenteredRectBounds(secondComponent);
283717
283768
  const overlapWidth = Math.min(a3.right, b3.right) - Math.max(a3.left, b3.left);
@@ -284346,6 +284397,7 @@ class VerboseNetLabelSolver extends BaseSolver11 {
284346
284397
  VERBOSE_NET_LABEL_MESSAGE = "Create trace with schDisplayLabel";
284347
284398
  netLabels;
284348
284399
  tokenToInvolvedPin;
284400
+ schematicSheetNameById;
284349
284401
  currentIndex = 0;
284350
284402
  seen = new Set;
284351
284403
  constructor(params2) {
@@ -284354,6 +284406,7 @@ class VerboseNetLabelSolver extends BaseSolver11 {
284354
284406
  const { circuitJson } = params2.ctx;
284355
284407
  this.netLabels = circuitJson.filter((el3) => this.isSchematicNetLabel(el3));
284356
284408
  this.tokenToInvolvedPin = this.buildTokenToInvolvedPinMap(circuitJson);
284409
+ this.schematicSheetNameById = getSchematicSheetNamesById(circuitJson);
284357
284410
  this.solved = this.netLabels.length === 0;
284358
284411
  }
284359
284412
  _step() {
@@ -284363,13 +284416,20 @@ class VerboseNetLabelSolver extends BaseSolver11 {
284363
284416
  return;
284364
284417
  }
284365
284418
  this.solved = this.currentIndex >= this.netLabels.length;
284366
- if (!label.text.includes("/") || this.seen.has(label.text))
284419
+ const seenKey = `${label.schematic_sheet_id ?? ""}:${label.text}`;
284420
+ if (!label.text.includes("/") || this.seen.has(seenKey))
284367
284421
  return;
284368
- this.seen.add(label.text);
284422
+ this.seen.add(seenKey);
284423
+ let schematicSheetName;
284424
+ if (label.schematic_sheet_id) {
284425
+ schematicSheetName = this.schematicSheetNameById.get(label.schematic_sheet_id);
284426
+ }
284369
284427
  const issue = {
284370
284428
  lineItemType: "VerboseSchematicNetLabel",
284371
284429
  schematicNetLabelId: label.schematic_net_label_id,
284372
284430
  sourceNetId: label.source_net_id,
284431
+ schematicSheetId: label.schematic_sheet_id,
284432
+ schematicSheetName,
284373
284433
  text: label.text,
284374
284434
  involvedPins: this.getInvolvedPins(label.text, this.tokenToInvolvedPin),
284375
284435
  schX: label.center.x,
@@ -284383,6 +284443,7 @@ class VerboseNetLabelSolver extends BaseSolver11 {
284383
284443
  addAttr(attrs, "message", issue.message, { escape: false });
284384
284444
  addAttr(attrs, "text", issue.text);
284385
284445
  addAttr(attrs, "involvedPins", issue.involvedPins.join(","));
284446
+ addAttr(attrs, "schSheetName", issue.schematicSheetName);
284386
284447
  addAttr(attrs, "schX", issue.schX);
284387
284448
  addAttr(attrs, "schY", issue.schY);
284388
284449
  return `<VerboseSchematicNetLabel ${attrs.join(" ")} />`;
@@ -284482,8 +284543,9 @@ class DiodeResistorAlignmentSolver extends BaseSolver12 {
284482
284543
  return;
284483
284544
  const start = firstEdge.from;
284484
284545
  const end = lastEdge.to;
284485
- const startSourceCompId = this.findSourceComponentIdNearPoint(start);
284486
- const endSourceCompId = this.findSourceComponentIdNearPoint(end);
284546
+ const schematicSheetId = trace.schematic_sheet_id;
284547
+ const startSourceCompId = this.findSourceComponentIdNearPoint(start, schematicSheetId);
284548
+ const endSourceCompId = this.findSourceComponentIdNearPoint(end, schematicSheetId);
284487
284549
  if (!startSourceCompId || !endSourceCompId)
284488
284550
  return;
284489
284551
  const startFtype = this.sourceComponentFtypeById.get(startSourceCompId);
@@ -284498,8 +284560,8 @@ class DiodeResistorAlignmentSolver extends BaseSolver12 {
284498
284560
  const resistorBox = this.schematicBoxBySourceComponentId.get(resistorCompId);
284499
284561
  if (!diodeBox || !resistorBox)
284500
284562
  return;
284501
- const diodePort = this.findNearestPort(DIODE_FTYPES.has(startFtype) ? start : end);
284502
- const resistorPort = this.findNearestPort(startFtype === "simple_resistor" ? start : end);
284563
+ const diodePort = this.findNearestPort(DIODE_FTYPES.has(startFtype) ? start : end, schematicSheetId);
284564
+ const resistorPort = this.findNearestPort(startFtype === "simple_resistor" ? start : end, schematicSheetId);
284503
284565
  if (!diodePort?.center || !resistorPort?.center)
284504
284566
  return;
284505
284567
  const diodeName = diodeBox.sourceComponentName ?? diodeCompId;
@@ -284541,10 +284603,12 @@ class DiodeResistorAlignmentSolver extends BaseSolver12 {
284541
284603
  static dist(a3, b3) {
284542
284604
  return Math.sqrt((a3.x - b3.x) ** 2 + (a3.y - b3.y) ** 2);
284543
284605
  }
284544
- findNearestPort(point9) {
284606
+ findNearestPort(point9, schematicSheetId) {
284545
284607
  let nearest;
284546
284608
  let minDist = Infinity;
284547
284609
  for (const port of this.schematicPorts) {
284610
+ if (port.schematic_sheet_id !== schematicSheetId)
284611
+ continue;
284548
284612
  if (!port.center)
284549
284613
  continue;
284550
284614
  const d3 = DiodeResistorAlignmentSolver.dist(point9, port.center);
@@ -284555,8 +284619,8 @@ class DiodeResistorAlignmentSolver extends BaseSolver12 {
284555
284619
  }
284556
284620
  return nearest;
284557
284621
  }
284558
- findSourceComponentIdNearPoint(point9) {
284559
- const nearest = this.findNearestPort(point9);
284622
+ findSourceComponentIdNearPoint(point9, schematicSheetId) {
284623
+ const nearest = this.findNearestPort(point9, schematicSheetId);
284560
284624
  if (!nearest || !nearest.source_port_id)
284561
284625
  return;
284562
284626
  return this.sourceComponentIdBySourcePortId.get(nearest.source_port_id);
@@ -284651,6 +284715,8 @@ class ComponentNetLabelCollisionSolver extends BaseSolver13 {
284651
284715
  }
284652
284716
  }
284653
284717
  detectPair(compA, compB) {
284718
+ if (compA.schematicSheetId !== compB.schematicSheetId)
284719
+ return;
284654
284720
  this.rawCollisions.push(...this.detectLabelLabel(compA, compB));
284655
284721
  this.rawCollisions.push(...this.detectBoxLabel(compA, compB));
284656
284722
  this.rawCollisions.push(...this.detectBoxLabel(compB, compA));
@@ -284871,7 +284937,8 @@ class ComponentNetLabelCollisionSolver extends BaseSolver13 {
284871
284937
  portPositions.push({
284872
284938
  componentId: port.schematic_component_id,
284873
284939
  cx: port.center.x,
284874
- cy: port.center.y
284940
+ cy: port.center.y,
284941
+ schematicSheetId: port.schematic_sheet_id
284875
284942
  });
284876
284943
  }
284877
284944
  const result = new Map;
@@ -284882,7 +284949,7 @@ class ComponentNetLabelCollisionSolver extends BaseSolver13 {
284882
284949
  if (!label.anchor_position)
284883
284950
  continue;
284884
284951
  const { x: anchorX, y: anchorY } = label.anchor_position;
284885
- const matches = portPositions.filter((port) => Math.hypot(port.cx - anchorX, port.cy - anchorY) < MATCH_EPSILON);
284952
+ const matches = portPositions.filter((port) => port.schematicSheetId === label.schematic_sheet_id && Math.hypot(port.cx - anchorX, port.cy - anchorY) < MATCH_EPSILON);
284886
284953
  if (matches.length === 0)
284887
284954
  continue;
284888
284955
  const componentIds = new Set(matches.map((match) => match.componentId));
@@ -285003,6 +285070,7 @@ class SchematicPlacementAnalysis {
285003
285070
  addAttr(attrs, "schY", lineItem.schY);
285004
285071
  addAttr(attrs, "width", lineItem.width);
285005
285072
  addAttr(attrs, "height", lineItem.height);
285073
+ addAttr(attrs, "schSheetName", lineItem.schematicSheetName);
285006
285074
  return `<SchematicBoxPlacement ${attrs.join(" ")} />`;
285007
285075
  }
285008
285076
  schematicIssuesToString(issue) {
@@ -287548,7 +287616,9 @@ var loadCircuitJsonForFootprinter = async (inputPath) => {
287548
287616
  const { circuitJson } = await generateCircuitJson({
287549
287617
  filePath: inputPath,
287550
287618
  injectedProps: { name: "CONVERT" },
287551
- platformConfig: getPlatformConfigWithCliDefaults()
287619
+ platformConfig: getPlatformConfigWithCliDefaults(undefined, {
287620
+ projectDir: findCircuitProjectDir(inputPath)
287621
+ })
287552
287622
  });
287553
287623
  const pcbComponentCount = circuitJson.filter((element) => element.type === "pcb_component").length;
287554
287624
  if (pcbComponentCount > 1) {
@@ -291368,17 +291438,25 @@ Rebuilding KiCad PCM assets...`));
291368
291438
  };
291369
291439
 
291370
291440
  // lib/server/createHttpServer.ts
291441
+ var RUNFRAME_CACHE_PATH = "/api/cache";
291371
291442
  var resolveLocalTscircuitStandalonePath = (projectDir) => {
291372
291443
  if (!projectDir)
291373
291444
  return;
291374
291445
  try {
291375
291446
  const projectRequire = createRequire5(path62.join(projectDir, "package.json"));
291376
- const browserBundlePath = path62.join(path62.dirname(projectRequire.resolve("tscircuit/package.json")), "dist", "browser.min.js");
291447
+ const browserBundlePath = projectRequire.resolve("tscircuit/browser");
291377
291448
  if (fs56.existsSync(browserBundlePath))
291378
291449
  return browserBundlePath;
291379
291450
  } catch {}
291380
291451
  return;
291381
291452
  };
291453
+ var readRequestBody = async (req) => {
291454
+ const chunks = [];
291455
+ for await (const chunk of req) {
291456
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
291457
+ }
291458
+ return Buffer.concat(chunks).toString("utf8");
291459
+ };
291382
291460
  var createHttpServer = async ({
291383
291461
  port = 3020,
291384
291462
  defaultMainComponentPath,
@@ -291387,10 +291465,42 @@ var createHttpServer = async ({
291387
291465
  entryFile
291388
291466
  }) => {
291389
291467
  const fileServerHandler = getNodeHandler(stdin_default, {});
291468
+ const localCacheEngine = projectDir ? createLocalCacheEngine(path62.join(projectDir, ".tscircuit", "cache")) : undefined;
291390
291469
  const pcmProxy = kicadPcm && projectDir && entryFile ? createKicadPcmProxy({ projectDir, entryFile, port }) : null;
291391
291470
  const server = http.createServer(async (req, res2) => {
291392
291471
  const requestHost = req.headers.host ?? `localhost:${port}`;
291393
291472
  const url2 = new URL(req.url, `http://${requestHost}`);
291473
+ if (url2.pathname === RUNFRAME_CACHE_PATH) {
291474
+ const key = url2.searchParams.get("key");
291475
+ if (!localCacheEngine || !key) {
291476
+ res2.writeHead(400, { "Content-Type": "text/plain; charset=utf-8" });
291477
+ res2.end("A project directory and cache key are required");
291478
+ return;
291479
+ }
291480
+ if (req.method === "GET") {
291481
+ const value = await localCacheEngine.getItem(key);
291482
+ if (value === null) {
291483
+ res2.writeHead(404);
291484
+ res2.end();
291485
+ return;
291486
+ }
291487
+ res2.writeHead(200, {
291488
+ "Content-Type": "text/plain; charset=utf-8",
291489
+ "Cache-Control": "no-store"
291490
+ });
291491
+ res2.end(value);
291492
+ return;
291493
+ }
291494
+ if (req.method === "POST") {
291495
+ await localCacheEngine.setItem(key, await readRequestBody(req));
291496
+ res2.writeHead(204);
291497
+ res2.end();
291498
+ return;
291499
+ }
291500
+ res2.writeHead(405, { Allow: "GET, POST" });
291501
+ res2.end();
291502
+ return;
291503
+ }
291394
291504
  if (url2.pathname === "/api/files/upsert-multipart" && req.method === "POST") {
291395
291505
  try {
291396
291506
  const request = new Request(url2.toString(), {
@@ -294384,10 +294494,13 @@ var registerExport = (program2) => {
294384
294494
  const projectConfig2 = await loadRuntimeProjectConfig(process.cwd());
294385
294495
  const commandPlatformConfig = options.disablePartsEngine === true ? { partsEngineDisabled: true } : undefined;
294386
294496
  const platformConfig2 = mergePlatformConfigs(projectConfig2?.platformConfig, commandPlatformConfig);
294497
+ const platformConfigWithCliDefaults = getPlatformConfigWithCliDefaults(platformConfig2, {
294498
+ projectDir: findCircuitProjectDir(file)
294499
+ });
294387
294500
  if (formatOption === "spice") {
294388
294501
  const { circuitJson } = await getOrGenerateCircuitJson({
294389
294502
  filePath: file,
294390
- platformConfig: getPlatformConfigWithCliDefaults(platformConfig2)
294503
+ platformConfig: platformConfigWithCliDefaults
294391
294504
  });
294392
294505
  if (circuitJson) {
294393
294506
  const spiceString = getSpiceWithPaddedSim(circuitJson);
@@ -294406,7 +294519,7 @@ var registerExport = (program2) => {
294406
294519
  filePath: file,
294407
294520
  format,
294408
294521
  outputPath: options.output,
294409
- platformConfig: platformConfig2,
294522
+ platformConfig: platformConfigWithCliDefaults,
294410
294523
  pcbSnapshotSettings: options.showCourtyards ? { showCourtyards: true } : undefined,
294411
294524
  onExit: (code) => process.exit(code),
294412
294525
  onError: (message) => console.error(message),
@@ -316850,7 +316963,9 @@ var registerSimulate = (program3) => {
316850
316963
  const { circuitJson } = await getOrGenerateCircuitJson({
316851
316964
  filePath: file,
316852
316965
  saveToFile: false,
316853
- platformConfig: getPlatformConfigWithCliDefaults(platformConfig2)
316966
+ platformConfig: getPlatformConfigWithCliDefaults(platformConfig2, {
316967
+ projectDir: findCircuitProjectDir(file)
316968
+ })
316854
316969
  });
316855
316970
  if (!circuitJson) {
316856
316971
  console.log("error: Failed to generate circuit JSON");
@@ -317021,7 +317136,7 @@ var processSnapshotFile = async ({
317021
317136
  const parsed = JSON.parse(fs72.readFileSync(file, "utf-8"));
317022
317137
  circuitJson = Array.isArray(parsed) ? parsed : [];
317023
317138
  } else {
317024
- const platformConfigWithCliDefaults = getPlatformConfigWithCliDefaults(platformConfig2);
317139
+ const platformConfigWithCliDefaults = getPlatformConfigWithCliDefaults(platformConfig2, { projectDir });
317025
317140
  const result = await getOrGenerateCircuitJson({
317026
317141
  filePath: file,
317027
317142
  platformConfig: platformConfigWithCliDefaults
@@ -3895,11 +3895,12 @@ function createLocalCacheEngine(cacheDir = path7.join(process.cwd(), ".tscircuit
3895
3895
  }
3896
3896
  };
3897
3897
  }
3898
- function getPlatformConfigWithCliDefaults(userConfig) {
3898
+ function getPlatformConfigWithCliDefaults(userConfig, options) {
3899
3899
  const basePlatformConfig = getPlatformConfig();
3900
+ const cacheDir = options?.projectDir ? path7.join(options.projectDir, ".tscircuit", "cache") : undefined;
3900
3901
  const defaultConfig = {
3901
3902
  ...basePlatformConfig,
3902
- localCacheEngine: createLocalCacheEngine(),
3903
+ localCacheEngine: createLocalCacheEngine(cacheDir),
3903
3904
  footprintFileParserMap: {
3904
3905
  ...basePlatformConfig.footprintFileParserMap,
3905
3906
  kicad_mod: {
@@ -4074,7 +4075,7 @@ var processSnapshotFile = async ({
4074
4075
  const parsed = JSON.parse(fs9.readFileSync(file, "utf-8"));
4075
4076
  circuitJson = Array.isArray(parsed) ? parsed : [];
4076
4077
  } else {
4077
- const platformConfigWithCliDefaults = getPlatformConfigWithCliDefaults(platformConfig);
4078
+ const platformConfigWithCliDefaults = getPlatformConfigWithCliDefaults(platformConfig, { projectDir });
4078
4079
  const result = await getOrGenerateCircuitJson({
4079
4080
  filePath: file,
4080
4081
  platformConfig: platformConfigWithCliDefaults