npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

eda-copilot-backend

v0.4.0

Published

Component search, schematic layout and PCB placement for EDA Copilot integrations

Readme

EDA Copilot Backend

Independent Node.js library for component search, schematic assembly and PCB placement. The EasyEDA extension and MCP live in a different repository; copper routing belongs to eda-copilot-router.

import { componentSearch, extractCircuit, makePcbLayout, disposeBackend } from 'eda-copilot-backend';

const components = await componentSearch({ MPN: 'STM32F103C8T6' });
try {
  const layout = await makePcbLayout({ code: placementDsl, circuit, footprints }, {
    onProgress: progress => console.error(progress.content),
  });
} finally {
  await disposeBackend();
}

Entry points: ., /components, /schematic, /pcb, /types. All runtime dependencies belong to this package. Component/UUID resolution uses public EasyEDA APIs; supplied footprints allow offline placement. No private Copilot server, LLM credentials or database is required.

Use validatePcbLayoutIntent({ code, circuit, footprints?, existingPlacement? }) for offline structured DSL diagnostics, or detectCircuitPatterns({ circuit, footprints? }) to reuse deterministic recognition independently. The catalog contains 57 conservative checks. See PCB intent validation for English diagnostics and scope limits.

Development

See the architecture map to find the existing implementation before changing a module.

npm ci
npm run native:build
npm run check
npm run test:package

Node >=20.19 is required. Rust/Cargo and the platform C/C++ toolchain are needed only to build the native solver from source. npm run dev watches TypeScript and copies its assets; rebuild Rust separately when changing native code.

The repository contains its own src/types. component.ts, circuit.ts, lcsc.ts and reused.ts were copied from the original copilot-server/src/types during extraction. They are normal source files maintained here, not aliases or generated links. The existing lightweight Zod preprocess helpers are local. There is no @copilot/shared dependency and no EasyEDA repository checkout is required to build or test this package.

npm run test:package builds a local npm archive from existing build outputs, installs only that archive into an isolated consumer with install scripts disabled, and exercises public APIs, declarations, workers, assets and the native solver. API calls use local fixtures. It does not publish anything.

npm run test:recovery selects native CPU/GPU recovery checks, including GPU-disabled calls and unavailable CUDA/Vulkan drivers. Hardware fault-injection checks require the matching PCB_BLOCK_GPU_TESTS, PCB_BOARD_GPU_TESTS, PCB_POST_PLACE_GPU_TESTS and PCB_CUDA_GPU_TESTS flags set to 1 on a compatible GPU host; otherwise they are skipped. Failures remain visible rather than updating quality references to accept them. The installed-archive check also exercises PCB workers with GPU disabled and with both GPU drivers unavailable.

Real board examples are in tests/pcb-layout; run npm run test:pcb-layout -- --list, selected fixture names, or --all. These optional examples query the public footprint catalogue and require network access.

Native releases

.github/workflows/ci.yml builds and tests Windows x64, Linux x64 on Ubuntu 22.04 (glibc 2.35 baseline), macOS Intel and macOS arm64 on Node 20/24. .github/workflows/publish.yml runs only on a v* tag. It waits for CI, collects all four .node binaries into one package, runs npm run check:release and tests the archive before publishing. There is no install-time Rust compilation.

npm run check:release deliberately fails in a checkout containing only its host binary or known legacy binaries. It checks all four binaries for current native API names, executes the host's numeric/score/refiner contracts, and verifies dependency independence and the release tag/version. Foreign contract values and runtime behavior require target-platform CI; installed declarations are checked by test:package. npm pack is available for local single-platform development archives, but those are not universal releases.

Releases are published on npm. npm Trusted Publishing (OIDC) is configured for biosshot/eda-copilot-backend, workflow publish.yml. Version 0.1.0 was published manually; subsequent versions are published from matching v* tags after the portability matrix, archive checks and release checks pass. npm versions are immutable, so bump the package and lockfile versions before creating a new tag. No tag or publish command is needed for local development. Linux/macOS support is conditional on successful CI, not inferred from a Windows test. Windows ARM64, Linux ARM64 and Alpine/musl are not currently part of the supported complete Copilot stack.

EasyEDA Copilot integration

Place this repository beside easyeda-copilot and copilot-router. In EasyEDA Copilot, npm run deps:local selects sibling file dependencies; npm run deps:release selects pinned published versions. MCP does not bundle this package or duplicate its runtime dependencies. Read EasyEDA Copilot's docs/local-development.md for the full workflow.

PCB_BOARD_PACKER_NATIVE_PATH is an optional developer override. Normal assets resolve relative to this package, independently of the current directory. Always call disposeBackend() when the host shuts down to close worker pools. PCB_LAYOUT_WORKERS, PCB_LAYOUT_WORKER_QUEUE_SIZE, PCB_LAYOUT_WORKER_TIMEOUT_MS and EDA_BACKEND_LOG_LEVEL configure runtime behavior.

PCB_BOARD_PACKER_THREADS controls native board-level beam-search parallelism (default and maximum: half the available logical CPUs, rounded down, capped at eight, minimum one; 1 selects serial execution). Independent beam states use native Rust threads with private geometry and micro-router caches. Results are merged in input order to preserve deterministic tie-breaking. Local orientation scoring and repair-variant scoring are also parallel; movement commits and lazy route refinement remain sequential. Set PCB_BOARD_PACKER_PROFILE=1 to log separate beam, local-improvement and repair elapsed times. More threads require additional cache memory; this setting is separate from PCB_LAYOUT_SUBTREE_WORKERS, which uses isolated Node processes for block/module placement.

Post-placement refinement makes one TypeScript-to-Rust call for the entire search. TypeScript compiles invariant geometry, constraints and JavaScript collation ranks once; Rust generates candidates, checks hard constraints, scores/routes them, caches route baselines, selects moves and emits diagnostics. Each native worker reuses a private world and updates/rolls back only changed components. Candidate groups sharing a baseline stay on one worker. Results are merged in original order; accepted moves and iterations remain sequential. PCB_POST_PLACE_THREADS selects native refinement threads (fallback: PCB_BOARD_PACKER_THREADS, then PCB_LAYOUT_SUBTREE_WORKERS, then half the available logical CPUs (rounded down, maximum eight, minimum one)). 0/1 selects one thread. The synchronous API uses one thread. Routing jobs within each candidate remain sequential. No Node process pool, per-candidate addon conversion or TypeScript callback is used in this loop. The subtree pool remains process-based because loading the addon in multiple Node worker threads caused heap corruption on Windows.

With PCB_BOARD_PACKER_PROFILE=1, post-place logs include candidate counts, hard/bound/feasibility/improvement rejections, baseline cache hits, and timings for geometry, scoring, routing and iteration wall time. Worker timings are summed work time, not elapsed wall time. Top-level encodingMs measures the one-time TypeScript compilation; native totalMs excludes addon conversion. Per-iteration encoding fields are zero because there is no TypeScript/native boundary there. These metrics are also saved in post-place stage data. Parallel batches only use the fixed minimum-improvement bound, so they can route more candidates than an incumbent- pruned serial search; speedup must be measured. The iteration limit is now adaptive, using all components and physical footprint pads (including fixed components) as a workload estimate:

| Maximum components | Maximum pads | Pass limit | |---:|---:|---:| | 50 | 250 | 16 | | 100 | 500 | 12 | | 150 | 1000 | 8 | | 250 | 1500 | 5 | | Above either final threshold | | 3 |

Both limits in a row must hold. localImproveIterations is an additional upper bound; zero still disables search. Early stop on no improvement remains. Rust enforces a 30-second wall-time budget shared by all threads, iterations and optional fixed-opportunity diagnostics. Workers check the deadline between candidates and expensive evaluation stages. In-flight native work is allowed to finish, so return may slightly exceed the budget; this is not a process-kill timeout. The best completed candidate from a partial pass may be committed, and uncommitted scratch poses are rolled back. Deadline-limited results can vary with scheduling; fully evaluated searches retain deterministic reduction. One-time TypeScript compilation and addon conversion are outside this native budget. Profiles report workload counts, requested/adaptive/effective pass limits, timeoutMs, timedOut, stopReason, and generated versus attempted candidates. The enclosing placement worker timeout still applies.

Run node --import tsx scripts/benchmark-post-place.ts [output.json] from this repository to compare one/two native threads on a synthetic 256-part route-obstacle fixture. It verifies identical placements, diagnostics and moves; its timings do not predict a particular production board.

scripts/benchmark-native-post-place.ts snapshot.json [output.json] uses a saved { input, placements } board snapshot, bounds candidate generation to six named components and two passes, and verifies identical output between serial and parallel Rust. It does not apply placement or run the global solver. The retired TypeScript implementation is archived locally under ignored .artifacts/retired-typescript-refiner/; tracked code has no dependency on it.

Placement concurrency is capped at min(8, floor(available CPUs / 2)), minimum one, including explicit environment overrides. Subtree workers can still be disabled with zero.