Skip to content

10 Reference: edakit.toml, the project files and the commands

For you when you set up or change a project, and for Claude when it looks something up: every key of edakit.toml, the board file, the schematic file and the requirements file, what each command reads and writes, and where a project keeps its files. The short way: the steps.

10.1 edakit.toml

Lookup: --config PATH, $EDAKIT_CONFIG, then edakit.toml in the current directory or a parent. Relative paths are relative to it. edakit.toml is the table of contents: what the project is, which boards it has, where their files are. What one role decides lives in a file of its own, with one owner and one hash (8.2):

File Content Written by Hash
edakit.toml project, boards with their EasyEDA documents, where the files are, release settings, the project's scripts and agents new-project, you –
hardware/requirements.toml what the circuit must do: needs and requirements with their evidence (3.6, 10.4), named in [project] requirements; required before a release (DOCS.file) the skill requirements drafts, only you accept circuit
hardware/graph.toml the circuit with its purpose, the hand-over to the layout, the ground net and the check settings (3.1); before edakit graph convert, the same graph as hardware/graph.json circuit designer circuit
hardware/graph.json beside a TOML graph the resolved graph, generated: pin numbers, every pin map (3.1) – never edited edakit graph json --write, edakit graph convert –
hardware/parts/, hardware/sim.json parts database (4), simulation scenarios (5) part-selector, circuit designer circuit
hardware/schematic.toml arrangement of the schematic: blocks, notes, pin table (10.3) circuit designer –
hardware/boards/<name>.toml one board: outline, holes, placement, routing, pours, silkscreen (10.2) PCB designer layout
hardware/boards/<name>.geometry.json the footprint geometry of the board's parts as placed in the PCB: boxes, pads, holes (7.4) – beside the board file, with its name edakit pcb dump layout
the SVGs of [[silk.art]] artwork on the silkscreen (7.7), drawn by hand or by a project script PCB designer layout
hardware/signoff.json sign-offs and accepted warnings, each bound to the hash of its scope (8.2) – below reviewers, you –
hardware/firmware.json the firmware contract, with [firmware] (3.5) edakit firmware –
hardware/scripts.lock the stamps of the project scripts (8.6) – below edakit run, edakit scripts stamp, the steps that run an input first –
  • hardware/signoff.json – the scope is circuit, electrical (M-6), layout or fab (8.2); an accepted warning with parts {designator: LCSC} is bound to those parts too. rehashed records a change of the hash method (the gate writes it for hash_ignore).
  • hardware/scripts.lock – per script its cmd, the script itself and the hashes of what it reads, at its last run; after an easyeda script ran through edakit run, what it changed and what is from before it (8.6). pcb dump and route all take off what they made again; route all and route pours mark a change of pcb:<b> gone.

Complete example: tests/fixtures/led-bar. The smallest project – a circuit without a board of its own, written by hand – is in 2.7: [project] with name, graph and requirements, and [boards.main] with wired = true. A key edakit does not know is an error with the list of the known ones – a typo does not fall back to a default unnoticed. An edakit.toml that still holds the board, the schematic or the checks (the earlier one-file form) is refused with a list of what goes where.

[project]

Key Default Meaning
name – (required) EasyEDA project (friendly name)
company "" title block of the schematics
quantity 5 boards per order (stock checks PARTS.stock)
distributors ["lcsc"] where the agent part-selector searches, in this order: lcsc, rs, farnell, mouser, digikey, reichelt (4.2)
lock auto EasyEDA claim between Claude sessions: auto (when CLAUDE_CODE_SESSION_ID is set) or off
agreements true the working agreements (11.4), one line each, in the context of every Claude Code session in the project – below
graph hardware/graph.json the hardware graph (3.1): a .json file, or a .toml file with the same keys – below
parts hardware/parts parts database, one JSON per part (LCSC number or manufacturer part number)
sim hardware/sim.json simulation config (chapter 5)
sim_plugin – optional Python file with MODELS and checks (5.1)
schematic hardware/schematic.toml the schematic file (10.3)
signoff hardware/signoff.json the sign-off file (8.2)
requirements – the requirements file (3.6, 10.4), e.g. "hardware/requirements.toml"; required – below
domains – the domains the project switches on besides core, e.g. ["usb"] – below
artifacts build/edakit caches, previews, routing files, exports, Gerber exports (not versioned)
reports build/release gate runs
datasheets <artifacts>/datasheets the datasheets edakit part fetch keeps, <key>.pdf and <key>.json (4.6); a folder in the repository versions them
stock hardware/stock.json the stock snapshot of edakit stock (PARTS.stock, 4.2); versioned, outside the circuit hash
stock_margin_pct 0 PARTS.stock warns when the assembler's stock is below the need plus this margin
stock_max_age_days 14 an older snapshot (or snapshot row) is pending in PARTS.stock – it blocks the release, not edakit check
spare_pct 0 edakit order: spares on every cart line, in % of quantity sets (rounded up)
toolchain easyeda the EDA tool the boards are drawn in: easyeda (EasyEDA Pro through the bridge) or kicad (KiCad 10, chapter 16) – below
edakit – the edakit the project needs: comparisons such as ">=0.4" or ">=0.4, <0.5" (>=, >, <=, <, ==), another form is an error; a running edakit that does not meet it is the note STRUCT.edakit of edakit check, and the SessionStart hook says so (2.3)
  • agreements – the plugin hook adds them at session start; false turns them off, not the lines of the project's scripts and agents the hook adds after them (11.4).
  • graph – a .toml graph holds components, nets and cables as tables keyed by designator and name – [components.R1], [nets."+5V"] – and is read to the same graph as the JSON; a key twice is an error with its line. The skill new-project writes hardware/graph.toml, edakit graph convert moves a JSON project to it (3.1). Beside a TOML graph edakit graph json --write keeps the resolved graph.json, which the pre-commit hook checks (edakit graph json --check). A TOML graph counts in the circuit hash with its data (8.2); edakit convert has nothing to do on it, edakit block add writes into it with its comments kept (14.5).
  • requirements – a variant names the main project's file and its own, as the requirements file shows (10.4). With the key, edakit req lists the file, edakit check checks it (DOCS.ref to DOCS.derived), the gate evaluates every requirement (8.7) and the circuit hash covers it. A file named here must exist and be valid, else edakit req, edakit check and the gate stop. Without the key DOCS.file is open: edakit check passes, --release and the gate do not release (8.7).
  • domains – from edakit/domains: usb, radio, audio, guitar, motors, power, cables, mains. What each switches on: its severities, the facts it requires of the parts, its hints and the reviewers' questions; edakit domains lists them. Without the key every domain the graph suggests is on; with it a domain the graph suggests and the list leaves out is a note STRUCT.domain and reports nothing.
  • toolchain – with kicad, edakit writes one KiCad project per board into <artifacts>/kicad/<board>/ and calls kicad-cli, and the EasyEDA document names of [boards.<name>] are refused.

The name of the ground net is in the graph (ground, default GND), with the circuit it belongs to; nets that are ground on purpose besides it (an analog ground) in grounds (3.1, PATH.unfed) – edakit block add adds those of a block (its graph.grounds, the lipo-charger's cell minus, 14.5). The configuration a part runs in is in the graph too: a component's config names one of its entry's configs (3.1, 4.1), and its states where the simulation holds the outputs of a part with behaviour logic (3.1, 5.1).

[boards.<name>]

Key Default Meaning
title the board name page name of the board schematic
template generated_<name> schematic generated from the graph (EasyEDA only)
schematic layout_<name> board schematic, the PCB is linked to it (EasyEDA only)
pcb <name> PCB document in EasyEDA (EasyEDA only – a KiCad board is <artifacts>/kicad/<name>/, 16.3)
file hardware/boards/<name>.toml the board file (10.2); while it does not exist the board has no layout yet – a file named here must exist
bought false true: a bought board on a cable (4.5) – below
wired false true: a hand-wired board, no PCB of its own – panel parts, jacks, pots, a strip on a cable (4.5) – below
  • bought – in the graph, checks and simulation like any board, made by nobody: no template, schematic, pcb, file or board file (each an error). Stages S and L/F, the manifest, the fab and the layout hash leave it out; layout commands refuse it with --board and skip it without; edakit order writes no BOM and edakit cost no PCB or assembly for it.
  • wired – as bought in the graph, checks and simulation, made by nobody, with the same errors and the same boards left out. Its parts are the project's, each in the carts (hand_assembly.md: "hand-wired, no PCB"). Built on a perfboard its board file holds the plan of the perfboard, [perfboard] (10.2, 7.9) – file may name it then.
  • Not both keys on one board; STRUCT.board/wired notes a bought board without a module.

[release]

  • layout_files – further files in the layout hash; the board files, their artwork and the footprint geometry are always in it.
  • state_files – further files in the circuit hash.
  • hash_ignore ([]) – keys left out of the circuit hash at any depth of the graph and the parts entries, e.g. ["notes", "sources", "description", "verified", "datasheet"] – only keys no check and no review reads; empty: the bytes are hashed (8.2).
  • assembly – a table: sides (both), smd_only, paste_gap_mm (0.4: SMD pads of different parts on an assembled side, GEO.spacing), pcba – the assembler's class of the order (PARTS.stock), one of the planned maker's classes, JLCPCB's "economic" and "standard"; by default from sides by the profile's class_of_sides (at JLCPCB one side Economic, two Standard), else the maker's first class.
  • [[stages]] – {id, name, cmd, advisory, timeout, about}: project checks of phase export before S (8.1).
  • maker_files ("all") – "all": stage F writes odb_<board>.zip and bom_<board>_mpn.csv for every board with an assembly side (assembly sides not empty, parts to place), whatever the makers of [cart] makers – the release can be quoted or ordered at AISLER, Eurocircuits or PCBWay as it is; SYNC.odb holds the ODB++ to the run as a note while no maker of [cart] makers takes it, and neither file is in the fab hash. "cart": only for a maker of [cart] makers that takes them. One more EasyEDA export per assembled board in every gate run (8.4).
  • archive – "none": gate runs are build output, nothing of them is committed, and what is ordered is published with edakit release publish; "git": a released run is committed, and edakit release current names one git does not track yet (8.3).
  • publish – edakit release publish of this project reads it, a variant's own is not read (8.3). variants (true: the variants below the project too – folders with an edakit.toml of their own); decisions (the decision log, e.g. "docs/decisions.md": the release notes list the decisions ## D-… since the previous release; without it none); credit (true: the notes end with "Released with edakit X.Y.Z" and its link; false: without).

[cost]

Optional: the order estimate of edakit cost (8.4). Without the table the gate and every command are as before. With it the gate has an information row "estimated order cost" in stage P, and above budget a warning to accept. An estimate edakit cannot make – a rate missing, the project's fee table in another currency – fails; a planned maker without a fee table is information.

Key Default Meaning
fees hardware/fees/<maker>.json over the shipped edakit/fees/jlcpcb.json the project's own fee table, laid over the shipped table of the planned maker – below
budget – the most the whole order may cost, in currency; above it edakit cost exits 2 and the gate warns
currency "USD" the currency of the estimate
rates {} the value of one unit of another currency in currency, e.g. { EUR = 1.15 }; needed for the fee table's USD and for every [[extra]] in another currency
shipping, coupon 0 per order, in currency
vat_pct 0 import VAT on the assembler's order (boards + shipping − coupon)
pcb_price the board line of a checked quote of the current release, else the fee table the quoted price of the PCBs (all quantity of them) – a number, or { board = price }; wins over the quote

fees: the table has the shipped table's form and its currency, every value with date and source. Per fee the value with the newest date wins, per PCB size the newest price where its pcb.qty is the shipped table's; the board its PCB prices are for stays the shipped table's pcb.board. edakit cart actual writes the real costs of the project's orders into it (8.4). A maker without a shipped fee table is not priced, with or without it.

[order]

The project's choice of order keys for every board – the keys of [order] of a board file (10.2) but the board's own (tab_zones, size_mm, layers), e.g. [order] mask = "black" for all boards. A board file's [order] wins per key. With the table every made board has an order form: fab/<board>/order.md, order.json and FILES.order.

[cart]

Optional: the makers of the boards (8.4). Without the table the maker is JLCPCB, the makers are ["jlcpcb"], and every check runs as before.

Key Default Meaning
maker "jlcpcb" the maker the boards are planned for: its checks fail (PARTS.stock, FILES.order, PARTS.fact/mpn, SYNC.odb), its form is order.md, [release] assembly.pcba is one of its classes, edakit cost prices with its fee table
makers [maker] every maker whose checks and files the gate runs and writes; a finding for a maker other than maker is a warning, and edakit cart prepare for that maker stops on it
ship_to – the country the order goes to, as the form names it; edakit cart prepare needs it
shipping {} per maker, the name of its shipping method: { jlcpcb = "DHL Express" }; edakit cart prepare needs it for the maker
tolerance 0.10 per price line, in the maker's currency, before ORDER.quote warns
profiles {} a project's own maker profiles, { name = "hardware/makers/name.toml" }, beside the shipped ones (jlcpcb, pcbway, eurocircuits, aisler in edakit/makers/)
needed_by – the date the order must arrive by, "2026-12-10": after a combined shipment edakit order check names the cheapest of LCSC's methods that arrives by then (8.4)

A maker's profile holds no defaults of the board. What it holds:

  • the form: its labels and words for edakit's keys (fields), the values it offers, its limits (rules: thicknesses, remark, placeholder, tooling holes per class), the combinations it refuses (excludes), the fields of the page edakit does not set, each with its reason (ignore);
  • the files it takes (files), the uploads its pages name nowhere (unshown, ORDER.files holds them by their hash), those a bare board's form names nowhere either (unshown_bare: JLCPCB's Gerber, which its cart line names), files that go up in the cart (upload = "after_cart", PCBWay);
  • the BOM's columns and the number the maker matches parts by (bom, match "lcsc" or "mpn"), a part matching only in its review after the cart (matching = "review", PCBWay), its zero orientation and the turn per footprint of its own CPL (cpl: zero, turns), how a part not to place is marked (dnp = "omit": left out of BOM and CPL, else the job lists it);
  • its assembly classes, whose parts catalogue PARTS.stock asks (catalogue), what it states about RoHS and REACH (compliance, 15.5);
  • the one cart button the skill cart may press and the ones it must not touch (cart, never), its seat and currency, its fee table (fees).
  • what the maker asks to confirm after the order ([confirm]: its order page, the two buttons and what each opens, the viewer of the placement, how it marks pin 1 and a diode's anode) – read by the skill cart's mode confirm, checked by edakit cart confirm (8.4, step 5); a profile without it: the maker asks nothing after the order

recorded is the day ordering step 0 read the form; false marks a profile whose words are not yet read off it, and FILES.order names it as information. Per field:

  • more = true – lists only some of the form's values (a "More Options" not read): another value is not checked;
  • when – the field shows only while another key has one of the values it names (a dialog behind an option);
  • checkout – asked at checkout only: in order.md, not read back before the cart;
  • assembly – asked only with assembly on (JLCPCB's Quote & Order): for a bare board a checkout field.

A key the profile does not know is refused, in a project's own profile too. No credentials anywhere: you are logged in in your browser, edakit never sees an account.

[[extra]]

Items off the board that belong to the order – a cable, feet, a module that is plugged in: item, supplier, per_set (pieces per board set) – these three are required –, code (the supplier's order code), spare (pieces on top), moq (the supplier's minimum), step (its pack size), unit_price and its currency (default [cost] currency). edakit order puts each into the cart of its supplier, edakit cost prices the cart quantity: ceil(per_set × quantity × (1 + spare_pct/100)) + spare, at least moq, a multiple of step.

[firmware]

Opt-in: the board's firmware contract (3.5). Without the table edakit firmware exits 1 and nothing else changes.

Key Default Meaning
mcu the one part with pins of the role gpio the MCU the contract describes
out hardware/firmware.json where edakit firmware writes it, relative to edakit.toml
gpio "(\\d+)" regex over the MCU pin's name, its first group is the GPIO number (GP26_ADC0 → 26); no match: null

[docs]

Values quoted from the design data (6.6). Without the table no document is read; placeholders in the schematic notes work without it.

Key Default Meaning
files [] Markdown files with value blocks <!--edakit SOURCE [FORMAT]-->value<!--/edakit-->, relative to edakit.toml
decimal "." "," writes quoted numbers with a decimal comma

[scripts.<name>]

Optional: a project script that touches edakit's flow – it writes a file edakit reads, derives something from edakit's data, changes the project library or the copper of the PCB in EasyEDA, or is a check of its own (8.6). Without the table nothing changes.

edakit check and the gate resolve the entries with edakit's steps into one order, report what keeps them from it, and compare each script's stamp in hardware/scripts.lock: an input outdated or never run is an error, a derive or easyeda script a warning. edakit scripts lists them. edakit run runs input, derive and easyeda scripts – an easyeda script only so, under the EasyEDA claim – and records each run. The steps that read what an input writes run it first when it is outdated (--no-scripts: none); edakit scripts stamp records a run made by hand. The gate runs the checks (8.1).

Key For Meaning
kind every entry input, derive, easyeda or check (8.6); the kind sim is [project] sim_plugin
cmd every entry the command as a list, run in the project directory – python or python3 as its first word is edakit's own interpreter, where edakit runs the entry (8.6); a check gets EDAKIT_RUN, the gate run's folder (8.1)
about every entry one sentence why the script exists, citing a decision
writes input, derive, easyeda (required) what it makes: paths; an input also board:<b>; an easyeda script changes project-library:<b> (not footprints:<b>, the geometry pcb dump measures) or pcb:<b>, copper it places in the PCB – vias, a pour – with files beside it, such as the list of what it placed; <b> a made board
reads every kind (optional) what its result is made from: edakit's data (8.6, each with a hash; the project library and pcb:<b> have none offline), files and folders – the script itself, the first file cmd names, counts anyway
after every kind (optional) other entries of [scripts] this one runs after – needed when several write the same file or change the same data
check input, derive, easyeda (optional) an exact check command, when the stamp is not enough (not run yet)
id check (required) its ID in the protocol: no stage of the gate (P, G, E, S, L, F), no sign-off (M-…), no code of the catalog, and none twice – [[release.stages]] included
phase check (required) export, order or acceptance – below
at check (optional) phase export only: "before S" (default) or "after F" – below
advisory check (optional) true: a failure is an advisory finding – listed in section 2 of the protocol, it does not hold up the release
  • phase – export: a stage of the gate, its failure holds up the release; order: a line of the protocol's list after uploading, before paying, which M-2 works through; acceptance: a line of the acceptance list after delivery, which M-4 works through. Neither of the last two runs in the gate (8.1, 8.5).
  • at – "before S": between E and S, where [[release.stages]] run; "after F": after stage F, only in edakit gate --eda, to read the run's manufacturing files (gerber:<b>, in fab/<b>/ of $EDAKIT_RUN).

A field of another kind is a finding of edakit check, a key no kind has an error of edakit.toml.

[agents.<name>]

Optional: an agent of the project – it signs a sign-off of its own, or takes over one of edakit's reviews (8.6). edakit check and the gate check the entries (ID agents), the gate requires their sign-offs – each counts only when done_by names its agent (8.2) –, and edakit scripts shows who reviews where, for the skills that start the agents. Without the table nothing changes.

Key For Meaning
file every agent the agent file, relative to edakit.toml, e.g. .claude/agents/pcb-pruefer.md: it exists, and the name in its front matter is the entry's name – the skills start the agent by it
about every agent one sentence what the agent checks
signs every agent the sign-off its OK is: an ID of its own, M-<number> (M-7), or edakit's review it takes over – M-1, M-5, M-6 – with replaces; never your M-2 or M-4; one agent per sign-off
replaces with M-1, M-5, M-6 the edakit agent it takes the place of, at each of its hook points: electrical-reviewer (M-1), pcb-reviewer (M-5 – the round reviews too), regulatory-reviewer (M-6)
scope with an ID of its own circuit, layout or fab: the hash its sign-off is bound to (8.2), and where it reviews – below
phase every agent export: the release waits for its sign-off; acceptance: a line of the acceptance list after delivery (8.5), whatever its scope. edakit's review: export
after every agent (optional) other entries of [agents] this one reviews after, at a hook point both review at; not one that reviews only later

scope decides where the agent reviews: circuit in the circuit review before the layout, layout in the round review after a layout round, fab in the layout review between the two gate runs (8.6). edakit's review keeps the scope of the sign-off file.

A key no agent has is an error of edakit.toml; what an entry signs and where it reviews is checked by edakit check.

edakit.local.toml

What only your checkout knows, beside edakit.toml: today your inventory (8.4). It is in .gitignore – edakit inventory template puts it there – and edakit order notes when git tracks it after all. Without the file, or without [inventory], nothing changes.

[inventory]
files = ["~/Parts/inventory.xlsx", "~/Parts/inventory_*.md"]   # one path or a list of paths and globs
lcsc_map = "~/Parts/lcsc.csv"   # optional: a table with ID and LCSC, for an inventory without an LCSC column

[inventory.columns]             # optional: your own column names
id = "Teil"
quantity = "Anzahl"
Key Meaning
files the inventory: .md, .html, .csv, .xlsx or .ods; relative to the project or from ~; a glob takes every file it matches. A file that is not there, a glob that matches nothing, a file without a table with ID and Quantity: edakit order stops
lcsc_map a table with the columns ID and LCSC in any of those formats: the LCSC number of a row by its ID, the inventory left as it is; an ID mapped to two numbers stops
columns the names of id, quantity, lcsc, name, description and link in your files, compared without case; default ID, Quantity, LCSC, Name, Description, Link

10.2 The board file

hardware/boards/<name>.toml: what the PCB designer decides (14.1). The layout hash covers it, the SVGs its [[silk.art]] places and the footprint geometry beside it (<name>.geometry.json, written by pcb dump, 7.4) – a change voids the sign-offs with scope layout; the layout review M-5 with scope fab (8.2) lapses when the manufacturing files change, or the settings of [order] that change the board as made: thickness, colours, finish, mark.

Keys of the board file

The keys stand at the top of the file, without a prefix ([place], [[holes]]):

Key Default Meaning
revision – board revision, printed with the title (silk.board_label); without it no board label
view top side the plan is drawn from; bottom mirrors x and rotations
edge_ok [] parts that may touch or overhang the outline
on_headers [] parts that stand on pin headers: an SMD part of their side may sit under them, clear of header_keep_mm around each of their through-hole pins; a through-hole part under them stays an overlap (7.4)
header_keep_mm 1.27 half width of the square around each through-hole pin of an on_headers part that SMD parts of its side stay out of (mm)
silk_overlap_mm 0 how far the boxes (silkscreen included) of two SMD parts of one side may reach into each other, in x and in y, before the plan check reports them (mm); with a through-hole part it does not apply (7.4)
near_mm 6 maximum gap for near (of the plan and of the graph's layout) and the decoupling of SYNC.plan
edge_mm 1 maximum distance from the outline for the graph's layout.edge (SYNC.plan)
park [10, -15] where new parts are dropped (mm, EasyEDA coordinates)
outline – rect = [w, h] (+ origin, corner_radius, arc_steps) or polygon = [[x, y], …]
[[holes]] [] x, y, d (3.2), keep (radius free of parts and copper; default d)
tooling – holes = [[x, y], …], d (1.152), mask (0.148), keep (1.5)
place {} REF = {x, y, rot, side, lock, auto} every part of the board (SYNC.plan); auto – below
near {} PART = "HOST" or a list – the layout's own, between fixed parts; the circuit's are layout.near of the graph
uniform { led = "row" } polarised parts that point the same way, per kind of the parts entry (7.4) – below
routing see below Freerouting rules
[[pours]] GND on both layers net, layers, plane, fanout, stitch, priority, line_mil, pour_only, clearance_mm, min_width_mm – below
pour_regions false nets that share a pour layer get outlines of their own area, claimed in priority order (7.6); no plane on such a layer
pour_min_piece_mm2 2.0 with pour_regions: the smallest piece (outside the net's own copper and clearance) that gets an outline
pour_inset_mm edge clearance + 0.1 how far the pours lie inside the outline (mm), 7.6 – below
silk {} designators, board label, artwork and texts on the silkscreen (7.7) – below
[looks] – the side people look at: visible ("top" or "bottom", required in the table), max_track_m and max_vias (optional limits) – below
[[loops]] [] a, b (pads "D1.2"), max_mm, what – check GEO.loop; the circuit's are layout.loops of the graph
copper see below copper per layer in the Gerber files, check GEO.pour
order – every field of the maker's order form as a key (below, 8.4), over [order] of edakit.toml; with the table – or with [cart] – the gate writes fab/<board>/order.md and runs FILES.order
thickness_mm 1.6 board thickness (mm) – below
net_classes see below track widths from the simulated currents
  • place – auto = true marks a spot nobody designed, a row pcb place or pcb autolayout wrote: a later pcb place may move it, every other command treats it as any row (7.4).
  • uniform – "row": parts of the kind side by side on one line (centres within 1 mm) have their plus pin towards the same side; "+x", "-x", "+y", "-y": the cathode or minus pin of every part of the kind points that way, seen from the side the part sits on. A part counts with exactly one pin anode or plus… and one cathode or minus…. The table names every kind it checks – without led the LEDs are not compared (7.4).
  • [[pours]] – net, layers, plane (bool), fanout (false: with plane, every SMD pad of the net on the other layer gets a protected via to the plane and a stub, 7.5), stitch (layer; on a layer shared with pour_regions also the pieces no net claims, each with a via, 7.6), priority, line_mil, pour_only (false: the net gets no tracks, its pour connects it; on every entry of the net, not with plane), clearance_mm (0.25: what the computed pour keeps from foreign copper – the EasyEDA copper-area rule), min_width_mm (0.25: the narrowest neck it fills). The last two also hold for every pour on a shared layer with pour_regions.
  • pour_inset_mm – the outline of pcb pour and route pours and every computed pour. Without it routing.edge_clearance_um / 1000 + 0.1; along an [order] tab zone tab_copper_mm + 0.05 instead, where that is more. The tracks keep edge_clearance_um either way (7.6).
  • [looks] – route check prints the track length per side and the vias, and the visible side's row; stage L gives the row too; above a limit a warning (7.5, 8.1). Stage L checks the side's print against the board file (GEO.silk: the board label, [[silk.texts]] of the side and, with [silk] designators on it, designators and group labels; no designator shown there while designators is the other side, 7.7). Without the table nothing is reported.
  • thickness_mm – the mechanical model mech_<board>.json takes the lead protrusion from it (lead length_mm − thickness_mm, 7.4), and with order the order form and the fab hash (8.2). FILES.order fails a thickness the maker's form does not have (JLCPCB, FR-4, 2 layers: 0.4, 0.6, 0.8, 1.0, 1.2, 1.6, 2.0).

The plan of a perfboard

The board file of a hand-wired board (wired = true) built on a perfboard (7.9) holds only these keys:

Key Default Meaning
[perfboard] – kind (a file of edakit/perfboards/: pad-per-hole, 3-hole-strips), holes = [columns, rows] of the piece used, cut_step_mm (optional: the cut list's step, a whole number of mm, default the kind's 1 mm)
[[holes]] – mounting holes: x, y in mm, x right and y up from the board's lower left corner seen from the top; d (3.2); keep – the diameter kept free around it, default 1.875 × d (an M3 nut)
[place] – designator = { at = "P9", rot = 270 } – the hole of pin 1, the rotation counterclockwise from the top; span for an axial part's lead span in holes – or { anode = "L3", cathode = "L2" }, the holes of two roles
[[wire]] – net, path (holes), side – bottom (default): a straight row of bridges between neighbouring holes, top: an insulated wire, its ends and the bends between them –, color
[near], near_mm, edge_mm, edge_ok 6, 1 the hand-over, as on a PCB
revision – as on a PCB

[silk]

The silkscreen's keys, described in 7.7:

  • designators (side), hide (sides), label_h_mm (1.0), gap_mm (0.25), groups {label: [refs]}, priority (["TP"]);
  • unlabelled ({designator = reason}, none): a part of the designators side without a visible designator or group label is a GEO.silk warning;
  • solder_side (false): true labels the through-hole parts of the other side on the designators side too;
  • place ({}): REF = {x, y, rot, side}, a designator at a fixed spot, as [place] fixes a part – plan mm, the rotation EasyEDA gets, the side it prints on (the designators side). The rest is placed around it; one on a pad, beyond the board or on a text is a finding;
  • board_label ("{title} rev {revision}"; also {project}, {board}; "" = none), board_label_corner (bottom-left, seen from the printed side), board_label_h_mm (1.2), board_label_side (the designators side; "top" or "bottom"), board_label_region (the whole board; a polygon [[x, y], …] in plan mm the label must lie in, board_label_corner then means its corner);
  • [[art]] ({svg, x, y, width_mm, rot, side, fit}): fit = "content" scales the bounds of the drawn shapes to width_mm and centres them on x, y; "viewbox" does so with the SVG's viewBox – art drawn in a frame keeps its place in it. svg is required (the path from the project root); an entry without it, or with another key, is an error of the board file when edakit loads it – pcb plan and check name it offline;
  • [[texts]] ({text, x, y, h_mm (1.2), rot, side, font}): font is default (stroke font) or a font family EasyEDA knows.

[routing], [copper], [net_classes]

[routing], the Freerouting rules:

  • clearance_mil (6.5) – also the least gap between pads of different parts (GEO.spacing);
  • signal_mil (10), via ([24, 12]), passes (40), attempts (5), layer_cost ({TOP = [1.0, 1.8], BOTTOM = [1.5, 2.5]}), classes ({NAME = {width_mil, nets}});
  • edge_clearance_um (400) – tracks and vias from the outline, in the DSN and in Freerouting; the pours keep pour_inset_mm;
  • widths – "classes": the DSN takes the widths of classes and signal_mil; "sim": every class at least the IPC-2221 width of its nets' simulated currents, a net outside the classes that needs more than signal_mil a class of its own – needs net_currents.json (7.5);
  • hand_solder_keep_mm (0 = off) – GEO.spacing: vias and pads of other nets at least this far, in mm, from the pads of bom: false parts on their solder side – a through-hole pad's the side its part does not sit on, an SMD pad's its own; route dsn writes via keep-outs around them (7.5);
  • smd_via_keep_mm (0.3, 0 = off) – GEO.spacing/margin, only with [order] vias = "untented": every via, of any net, at least this far, in mm, from the SMD pads the assembler reflows on an assembled side; route dsn writes via keep-outs around them, the fanout keeps the distance, route check and the gate warn (7.5);
  • drc_rules (none: GEO.drc as before) – "check": the gate reads the rule set of EasyEDA's DRC with the DRC, and GEO.drc holds it to these rules – clearance, edge clearance, track widths, via, classes (7.5); "write": route all writes that rule set into EasyEDA before its DRC, reads it back after a reload, and the gate checks it as with "check";
  • [[routing.keepouts]] ({layer, what = "wire"|"all", rect | polygon, windows, window_mm, pour}), [[routing.fixed_wires]] ({net, layer, width_mil, points}). pour (true): false keeps the pours out of the area too – a NO_POURS region on its layer in EasyEDA, a rule area in KiCad, the area as written, windows not cut out (7.2).

[copper], copper per layer in the Gerber files (GEO.pour warns beyond each limit):

  • max_bare_mm (5) – the largest copper-free circle inside the pour outline of a layer that [[pours]] pours, and of a seen face it does not pour (the side [looks] visible names, both sides without [looks]);
  • max_bare_mm2 (20) – the largest copper-free piece there in mm² that a pour could fill, opened with a disc of 2 × clearance_mm + min_width_mm of [[pours]] (0.75 mm on a face without pour);
  • min_cover ({TOP = %, BOTTOM = %}, none) – the least copper share of the board area per layer.

[net_classes]: NAME = {min_a, width_mm} – class by the largest simulated current, practical minimum width (default POWER ≥ 0.3 A 0.6 mm, SUPPLY ≥ 0.1 A 0.4 mm, SIGNAL 0.25 mm). force = {NET = "CLASS"} pins a net to a class (e.g. a switching node).

[order] of the board file

[order]: every question a maker's order form asks, as a key in edakit's words with edakit's default – the board edakit assumes when nothing is said, the same for every maker (8.4). Three layers, the later one wins per key: these defaults, [order] of edakit.toml (every board, 10.1), [order] of the board file.

One default depends on the board: on a board with [looks] mark is "remove" – no order number on a board people look at, decided in the files and so in the fab hash before the gate and M-5, not at the form. order.md names [looks] as where it comes from, and a mark in either [order] wins.

The maker's profile only translates a value into its word (edakit/makers/<maker>.toml, edakit cart fields); a value the maker does not offer is a finding of FILES.order for that maker. "Board": the key changes the board as made – fab/<board>/order.json has thickness_mm, mask, silkscreen, finish and mark whenever the board has [order], and every other such key where its value differs from the default; so a project that sets none of them keeps its fab hash (8.2).

Key Default Values Board
material, tg "FR-4", "TG135" strings, edakit's words, which each profile translates ✓
layers, size_mm – (derived) only to check: the copper layers and [w, h] of the run's Gerber files (FILES.order, ± 0.1 mm) –
quantity [project] quantity PCBs ordered, a whole number –
delivery "single" "single", "panel_by_maker" with panel = {x, y, rails_mm}; "panel_by_customer" fails FILES.order (edakit draws no panel) ✓
mask, silkscreen "green", the print on the mask ("white", on a white mask "black") mask "green", "purple", "red", "yellow", "blue", "white", "black"; silkscreen "white", "black" – FILES.order fails a pair the maker does not print ✓
finish "LeadFree HASL" edakit's words "HASL(with lead)", "LeadFree HASL", "ENIG" – JLCPCB's own; each other profile translates them (PCBWay: "HASL lead free") ✓
copper_oz, inner_copper_oz 1, 0.5 (inner: from 4 layers) oz ✓
vias "tented" "untented", "plugged", "epoxy_filled" ✓
outline_tolerance "regular" "precision" ✓
gold_fingers, castellated, edge_plating false true or false ✓
mark "default"; on a board with [looks] "remove" "specify": at the maker's placeholder (PCBWay: WayWayWay), "remove" – the maker's order number; JLCPCB below ✓
barcode, serial_number "none", false "qr", "datamatrix"; true or false – for traceability, printed by the maker where there is room (JLCPCB since May 2026) ✓
electrical_test, quality "flying_probe", "ipc2" edakit's words, which each profile translates –
confirm_production_file, paper_between false true or false –
packaging "standard" edakit's words, which each profile translates (JLCPCB: "With JLCPCB logo") –
remark "" text to the maker (JLCPCB: at most 200 ASCII characters) –
tab_zones, tab_copper_mm [], 1.0 {from = [x, y], to = [x, y]}, two points on the outline in plan mm – below; tab_zones in the board file only –
pcba_quantity quantity boards assembled, at most quantity; another number than [project] quantity warns (PARTS.stock counts that many sets) –
confirm_placement true edakit's choice: the maker shows its placement before it builds, a second look beside M-2 –
photo_confirmation, depanel, function_test false true or false –
conformal_coating false true or false ✓
pcba_packaging "antistatic_bag" edakit's words, which each profile translates –
customs none { category = "DIY", hs_code = "902300" }: the shipment's customs description, yours – below –
  • mark – JLCPCB prints none since May 2026: "Remove Mark" for both "default" and "remove", "specify" refused, and its former JLCJLCJLCJLC on a silkscreen warns.
  • tab_zones – the shorter stretch of the outline between the two points: no copper of either side within tab_copper_mm of it (FILES.order); the pours keep tab_copper_mm + 0.05 mm from it (7.6).
  • customs – an entry of the maker's form (JLCPCB's "Product Description": its profile lists them, fields.customs). FILES.order fails one the form does not offer, and names the key as information where the form asks it and the key is not set: the skill cart then asks you at the cart. Not in order.json – it describes the shipment, not the board.

Not keys of [order], but fields of the form all the same: the thickness (thickness_mm of the board file), the assembly class and side ([release] assembly, the class one of the maker's classes), the tooling holes ([tooling]: by the customer, else by the maker), bake (the stock snapshot, MSL ≥ 5), the country and shipping method ([cart]). edakit cart fields prints them all with their source. The parts not to place (bom: false) are no field: the job lists them for a maker whose files still hold them (AISLER's ODB++), the skill marks them on its page.

10.3 The schematic file

hardware/schematic.toml, the arrangement of the schematic. It changes no hash – the drawing explains the circuit, it is not the circuit. Without the file edakit schematic draw arranges the schematic by itself (6.5).

  • stub (10) – stub length of the template.
  • frame (true) – false draws the SVG of schematic draw without the sheet border and the title block (6.5).
  • style ("labels") – the drawing of schematic draw, the SVG only (6.5): "labels" (stubs and flags), "wires" (every connection a wire, routed and coloured) or "mixed" (wires, labels for buses); one word for every board or a table by board, {main = "labels", panel = "wires"}.
  • [layout] – rows (rows → columns → blocks {title, start}), power_flags ({NET = "Ground"|"Power"}), near ({CAP = "PART"}), stacked (blocks whose trees stand one below the other), [layout.notes] ({block title = [lines]}), [layout.pin_table] (component, block, prefix, notes {NET = "function"}).
  • A note may quote the design data (6.6): {graph:R1.value}, {part:C90107.values.vrext_v}, {sim:max SIM.state * D2 LED current*}, optionally with a format, a requirement's text {req:R-1}.

10.4 The requirements file

hardware/requirements.toml, named in [project] requirements: what the circuit must do (3.6) – only the circuit, what firmware and mechanics must do stays in the project's own documents. edakit req lists it, edakit check checks it (DOCS.ref to DOCS.derived, 3.3), the gate evaluates every requirement's evidence (8.7), and the circuit hash covers it byte for byte (8.2). A key edakit does not know is an error, as in edakit.toml. From the example of the tests (tests/test_requirements.py, for the circuit of led-bar):

[[need]]
id = "N-1"
text = "The bar runs from a USB charger or from the USB port of a laptop."
who = "whoever uses the bar"
source = "README.md: the supply"
status = "accepted"

[[requirement]]
id = "R-1"
text = "Runs from the USB port of a laptop with all eight LEDs on."
source = "README.md"
from = ["N-1", "USB 2.0: 500 mA per port"]
binding = "must"
verify = [{ rows = "LIM.i * J1 current from the supply" },
          { accept = "on the USB port of a laptop: all eight LEDs on, the port stays on" }]
status = "accepted"
Key In Meaning
id both, required N-<n> in a [[need]], R-<n> in a [[requirement]], without a leading zero; unique across the files of the project, a variant's own included; stable – a dropped entry keeps its number
text both, required a need in the words of those who want it; a requirement as one statement in the words and at the level of detail of who stated it – the maker, a user, a chosen standard (3.6) –, no number edakit or the design derived: those reach it through verify
who need who wants it
source both where it was found and who stated it: a document, a decision, you with a date – an entry inferred from the circuit says so until you confirm it; on a requirement next to from, which says where it comes from
from requirement a list of where it comes from: needs (N-2), decisions (D-8), a standard (USB 2.0: 500 mA), a sign-off (M-6)
binding requirement, required must, should or may
verify requirement a list of what tests it – below; edakit req shows it as written, the gate evaluates it (8.7)
status both draft (written, not approved – also an entry without status), accepted (only you set it), dropped – below
reason both why; required with dropped

verify, one kind per entry:

  • { rows = "…" } – rows of the gate protocol, a pattern over "ID scenario item check" as accept match them (8.2); the rows of the simulation are those of edakit sim --json <file> (its checks: id, scenario, item, check), e.g. SIM.state fresh/on/vf-min D1 LED on. SIM.state's items are designators and nets – an LED's checks LED on, LED dark, LED current (…), a regulator's output voltage (…), a blocking diode's diode blocks –, so SIM.state * D1 LED on is D1 lit in every scenario that turns it on, SIM.state used/* D? LED on every LED at the end voltage;
  • { signoff = "M-1" } – a manual check, which counts when its note names the requirement's ID after "requirements met:";
  • { script = "…" } – a project script of kind check or the id of a [[release.stages]]: it passes when the check passed in the gate's run, one of phase order or acceptance once M-2 or M-4 is signed;
  • { accept = "…" } – a step of the acceptance test, on the list of protocol section 6.

status: a value that is written must be one of the three. A draft binds nothing yet: DOCS.ref to DOCS.derived only warn about it, the gate lists it and neither blocks nor asks for an acceptance (8.7). From accepted on, the findings are errors and the binding counts.

A variant – a project of its own with its own edakit.toml in a folder below the main project – names the main project's file and its own: requirements = ["../../hardware/requirements.toml", "hardware/requirements.toml"]. edakit req lists both, in that order; an ID stands in only one of them.

10.5 Commands

Every command that reads a project: --config, -v (MCP traffic).

  • Exit codes: 0 ok, 2 findings, 1 error. 3 from edakit lock and from edakit run of an easyeda script (another session holds EasyEDA), from edakit cart check (the review of the order is open), and from route all|drc and silk apply|check when the DRC's only item is EasyEDA waiting for the import acknowledgement after writing the Channel IDs (schematic = PCB; Design → Import Changes once – 7.5).
  • uv from snap: inside Claude Code edakit … 2>&1 | cat.
  • Progress: the long commands – route all, gate, pcb apply, silk apply, export, schematic create|layout – print [x.x min] step n/m: <step> before each step (11.3).
  • Project scripts: with [scripts], pcb place|parts|plan|apply, route all, silk apply|preview and gate run the input scripts that write what they read first, when those are outdated or never ran, and stop when one fails; --no-scripts runs none (8.6).

Each command below: its synopsis and help line, generated from the command line itself, then per action what it reads and writes and whether it needs EasyEDA (✓ or no). edakit COMMAND -h prints the same synopsis.

On KiCad: the commands marked ✓ run on the board's KiCad project and kicad-cli, without bridge and claim – what each does there is in the KiCad flow (16.4). pcb autolayout and lock have no KiCad side; KICAD_CLI names another kicad-cli.

edakit --version

edakit --version – EasyEDA: no

  • Reads: edakit/__init__.py; from a git clone away from the version's tag its commit
  • Writes: – (prints edakit 0.2.0, or edakit 0.2.0+g1a2b3c4 from such a clone – the string a gate run writes into its manifest, 2.3)

edakit version

edakit version [--write] [--offline] [--json JSON] [{pin,unpin}] [target]

What runs, what the plugin installed per scope, the newest version and what changed since – its When updating lines first –, where the project pins edakit.

edakit version [pin [current|latest|X.Y.Z] | unpin] [--write] [--offline] [--json JSON] – EasyEDA: no; network: the tags and the newest changelog from GitHub

  • Reads: the running edakit; Claude Code's ~/.claude/plugins/installed_plugins.json (or under $CLAUDE_CONFIG_DIR): edakit per scope, the one a session in this repository uses marked "in effect here"; git ls-remote --tags of tgd1975/edakit and the newest version's CHANGELOG.md; in the repository .claude/settings.json (the marketplace's ref), every tgd1975/edakit@<ref> in the files that start edakit – CI, hooks, shell scripts, YAML, Makefile, pyproject.toml, a $NAME read from the same file –, and [project] edakit of each edakit.toml
  • Writes: – (prints what runs, the plugin per scope, the newest version, the changelog's sections in between with their When updating: lines first, the pins and the update command for the scope in effect; --json: the same as data. Exit 2 when the edakit in effect is behind the newest, the pins disagree or differ from what runs, or a requirement is not met; --offline or no network: the newest version stays unknown, 2.3)
  • pin – Writes with --write, else lists: [project] edakit = "==X" in every edakit.toml of the repository; every git+https://github.com/tgd1975/edakit call in the files that start edakit at @vX – an unpinned one too, a $NAME changed where it is set –; the marketplace's ref out of .claude/settings.json, which would hold the plugin for every project on the machine. X: current (default) the edakit in effect here, latest the newest tag, or a version tag that exists
  • unpin – Writes with --write, else lists: ==X becomes >=X, the calls lose their ref (a $NAME becomes main), the settings' ref goes

edakit hook

edakit hook [{check,install,run}]

The project's pre-commit hook: edakit's block written or renewed (install), what is missing (check), the steps of the staged configurations (run – the block calls it).

edakit hook [check|install|run] – EasyEDA: no

  • check (default) – Reads: the pre-commit hook in core.hooksPath or .githooks/, edakit's block in it, the git config. Writes: – (each of missing, no block, outdated, inactive; exit 2 when one is found – the line the session start prints, 2.7)
  • install – Reads: the same. Writes: edakit's block into the hook – a new hook, after the header of one the project has, or the older block renewed –, the hook made executable, git config core.hooksPath when unset; names every line outside the block that runs edakit itself, for the project to take out. A step the session may not do – Claude Code guards git's configuration, a sandbox refuses a write – is a line failed: … with the command to run in a terminal of your own, and exit 1
  • run – what the block calls. Reads: the staged paths, every edakit.toml of the repository and the files each names. Writes: what its steps write. A configuration runs when its edakit.toml, its hardware/, the main project's hardware/ or a file it names is staged: edakit check, edakit sim, with a TOML graph edakit graph json --check, with [firmware] edakit firmware --check, with [docs] edakit docs; exit 2 when a step fails, which blocks the commit

edakit check

edakit check [--release] [--json JSON] [--coverage]

Rule checks on the graph (stages P, G).

edakit check [--release] [--coverage] [--json F] – EasyEDA: no

  • Reads: graph, parts (pins, identity STRUCT.identity), pin table; if there: footprint geometry and library footprints (GEO.hole, GEO.formed), library symbols (STRUCT.entry), the footprint data of parts entries with the footprint geometry (PARTS.footprint, SYNC.footprint); [scripts], [[release.stages]] and sim_plugin with the board files' [[silk.art]], hardware/scripts.lock and what the scripts read (8.6); [agents] and the agent files (8.6); with [project] requirements the requirements files and the sign-off file's manual checks (DOCS.ref, DOCS.need, DOCS.evidence, DOCS.draft, DOCS.derived; a file missing or not valid: exit 1); <artifacts>/sim/result.json while its inputs are unchanged – the cables' currents of the coverage report (3.3), no simulation of its own
  • Writes: – (--json: the findings); exit 1 on errors, with --release also on pending findings (3.3)

edakit rules

edakit rules [ids ...]

The engines and codes of the catalog.

edakit rules [CODE …] – EasyEDA: no

  • Reads: the catalog edakit/catalog/codes.toml: engines and codes; an old check ID (G-4) the codes that replace it (10.7; no project needed)
  • Writes: –

edakit explain

edakit explain ids [ids ...]

Rule, why, fix and sources of a code.

edakit explain CODE … – EasyEDA: no

  • Reads: the catalog: rule, why, fix, sources and severity of a code; an old check ID names its codes (no project needed)
  • Writes: –

edakit graph

edakit graph [--json JSON] [--write] [--check] [--dry-run] {show,json,convert} [name]

What the graph says about one part or net; the resolved graph as JSON; a JSON graph moved to TOML.

edakit graph show NAME [--json F] – EasyEDA: no

  • Reads: graph, parts entries, the checks of edakit check
  • Writes: – (one part or net: type, board, part number and parts entry with kind, limits and values, every pin with name, role and net – or the net's range, fn, cables and pins –, the accepts, and the findings whose place is the name or that may be accepted on it)

edakit graph json [--write|--check] – EasyEDA: no

  • Reads: graph, parts entries
  • Writes: – (the resolved graph on stdout: {"graph": …} with pin numbers wherever the graph names a pin, every component's pin map – its parts entry's where the graph has none –, the lists in the order of the file); --write: beside a TOML graph the generated hardware/graph.json, never over a JSON graph (exit 1); --check: exit 2 when the committed file differs, with what differs, nothing written – for the pre-commit hook of a project with a TOML graph. The generated file is derived: neither in the circuit hash nor the data name graph of the scripts (3.1)

edakit graph convert [--dry-run] – EasyEDA: no

  • Reads: the JSON graph, parts entries, edakit.toml, sign-off file
  • Writes: hardware/graph.toml (components, nets and cables keyed by designator and name, pins by name or role, a pin map only where it differs from the entry's, long text over several lines, the convention pin_reference rewritten), [project] graph in edakit.toml (a line edit, comments kept), hardware/graph.json again as the resolved graph generated from it; when the files were the signed ones, the sign-offs of scope 'circuit' keep counting – the new circuit hash goes into the sign-off file, both into rehashed; --dry-run: the TOML and what would change
  • Refused with what to fix for null, a name twice or a pin that names none, and when the TOML would not read back to the same graph
  • Left by hand after it: with [firmware] edakit firmware (the contract's state_sha256 is the new circuit hash – convert says so), and the project scripts that read graph show as outdated once – edakit run or edakit scripts stamp (8.6)

edakit domains

edakit domains [--review {electrical,regulatory,pcb}]

The domains of the project: on, off, suggested; the reviewers' questions.

edakit domains [--review R] – EasyEDA: no

  • Reads: graph, parts, edakit/domains
  • Writes: – (the domains on and off, suggested; with --review electrical, regulatory or pcb the questions of the enabled domains for that review)

edakit convert

edakit convert [--write]

Graph, parts entries and sign-off file into the form of the restructuring.

edakit convert [--write] – EasyEDA: no

  • Reads: graph, parts entries, sign-off file, documents, schematic notes, requirements files
  • Writes: --write: the files in the form of the restructuring (limits and values with units, accept by code, locks, codes in quotes and rows patterns), each with its own indent; when they were the signed ones, the sign-offs of scope 'circuit' keep counting – the new circuit hash goes into the sign-off file, both into rehashed; without: the list

edakit mutate

edakit mutate [--sim] [--json JSON]

Mistakes built into a copy of the design one at a time: what no code catches.

edakit mutate [--sim] [--json F] – EasyEDA: no

  • Reads: graph, parts, with --sim the simulation config
  • Writes: – (mistakes built into a copy one at a time – every part left out, diodes, LEDs and polarized capacitors turned round, resistors ×100 and ÷100, nets shorted to ground – and those that raise no new error, warning or pending finding listed: what no code catches; in memory)

edakit block

edakit block [--as INSTANCE] [--connect PORT=NET [PORT=NET ...]] [--without DES [DES ...]] [--board BOARD] [--file FILE] [--dry-run] {list,show,add} [name]

Building blocks: list, show, or add one to the graph.

edakit block list|show NAME – EasyEDA: no

  • Reads: the block library (no project needed)
  • Writes: –

edakit block add NAME --as I [--connect PORT=NET …] [--without DES …] [--board B] [--file F] [--dry-run] – EasyEDA: no

  • Reads: graph, parts, block
  • Writes: graph (formatting kept – a TOML graph with its comments and arrangement –, the block's graph.grounds added to grounds), missing parts entries; --without leaves out optional parts of the block (14.5)

edakit part

edakit part [--update] [--by BY] [--url URL] [--all] [--json JSON] [--basic] [--min-stock MIN_STOCK] [--limit LIMIT] [--connector CONNECTOR] [--name NAME] [--board BOARD] [--write] {import,diff,fetch,search,datasheet,own,footprint,build,lint,add,sign} [source] [new]

The library's data of an LCSC number, a footprint swap compared, datasheets, a catalogue search, own parts, own footprints as data, entries of edakit's parts library.

edakit part lint [KEY …] – EasyEDA: no

  • Reads: parts entries, the schema edakit/catalog/kinds.toml – each of an entry's configs as the entry it makes
  • Writes: – (PARTS.schema per problem; exit 2 on problems)

edakit part add [KEY] [--update] – EasyEDA: no

  • Reads: edakit's parts library edakit/parts/ and its signed.toml (4.1)
  • Writes: without KEY – (lists every library entry with kind, MPN and whether it is signed or a draft); with KEY hardware/parts/<KEY>.json, the copy with its library version – refused where the project has the entry, --update replaces it and names what changed

edakit part sign KEY --by NAME – EasyEDA: no

  • Reads: the library entry
  • Writes: edakit/parts/signed.toml: the signature of NAME with the entry's SHA-256 (4.1)

edakit part import LCSC [--update] – EasyEDA: no – (internet)

  • Reads: EasyEDA's public component data of that number (4.2)
  • Writes: a new hardware/parts/<LCSC>.json, else nothing (--update: the fields it lacks); <artifacts>/library/<LCSC>.json, <artifacts>/footprints/<footprint>.json; exit 2 = the entry differs

edakit part diff OLD NEW [--json F] – EasyEDA: no

  • Reads: geometry of both (the dump of a placed part, else the footprint data of the entry, else the library footprint of part import), their parts entries (roles, lead), graph
  • Writes: – (F: the comparison as JSON); exit 0 = drop-in, 2 = something to decide (7.3)

edakit part footprint KEY [--board B] [--write] – EasyEDA: no

  • Reads: the footprint geometry of a placed part of KEY (--board: that board's), else the library footprint of part import; with the dump also the library footprint, for shapes and sizes (4.5)
  • Writes: – (prints the footprint as data); --write: footprint_data and a line of sources in the parts entry. Refused for an entry that has the data; exit 2 when PARTS.footprint finds something missing

edakit part build KEY [--board B] [--write] – EasyEDA: – / ✓ with --write

  • Reads: the entry's footprint_data, pins and symbol (PARTS.footprint must pass), the graph (the parts of the board that use it); with --write the board's template in EasyEDA, where the carrier is placed (4.5)
  • Writes: – (prints what it would build); --write: the copy of the carrier in the project library – footprint, with "symbol": "box" symbol –, the project saved; with [scripts] the change of project-library:<b> in hardware/scripts.lock (8.6). Exit 2 when the copy read back differs from the data; not run against EasyEDA yet

edakit part fetch KEY [--url U] | --all – EasyEDA: no – (internet)

  • Reads: the parts entry (mpn, datasheet.url, lcsc, verified.datasheet_sha256); the sources of 4.6
  • Writes: <datasheets>/<KEY>.pdf and .json (a failed download keeps the earlier copy, exit 2; variant or changed since the sign-off: exit 2)

edakit part search "KEYWORDS" [--basic] [--min-stock N] [--limit 25] [--json F] – EasyEDA: no – (internet)

  • Reads: JLCPCB's public parts catalogue (4.2)
  • Writes: – (F: the hits); exit 2 = no hits

edakit part datasheet [--connector C …] [--name N] – EasyEDA: no

  • Reads: graph, parts, sim config, board file (4.5)
  • Writes: hardware/datasheet/<N>.json and .md; without --connector every datasheet renewed

edakit part own PATH [--name N] – EasyEDA: no

  • Reads: the board's project at PATH: its datasheet, state, git, gate runs
  • Writes: hardware/parts/<N>.json

edakit stock

edakit stock [--board BOARD] [--refresh] [--lcsc C [C ...]]

Ask JLCPCB about every assembled part and write the stock snapshot (PARTS.stock).

edakit stock [--board B] [--refresh] – EasyEDA: no

  • Reads: graph, parts, the snapshot; JLCPCB's catalogue and part pages (network) – only with JLCPCB among [cart] makers (exit 1 otherwise)
  • Writes: hardware/stock.json ([project] stock): the parts missing, unread or older than stock_max_age_days, with --refresh all

edakit stock --lcsc C… – EasyEDA: no

  • Reads: JLCPCB's catalogue and part pages (no project needed)
  • Writes: – (prints listed, class, stock, MSL, PCBA type, X-ray, attrition)

edakit cost

edakit cost [--board BOARD] [--json JSON]

Estimate the order: PCB, PCBA fees, parts, extras, shipping, VAT; drivers, budget.

edakit cost [--board B] [--json F] – EasyEDA: no

  • Reads: graph, parts, board files (outline, sides, [order]: quantity PCBs, pcba_quantity assembled), the stock snapshot, the fee table of the planned maker with the project's own over it (newest value per fee), the PCB price of a checked quote of the current release, [cost], [[extra]]
  • Writes: <artifacts>/cost.json (the change since the last estimate is printed; not_in_price per board whose [order] differs from the fee table's board, 8.4); exit 2 above budget, exit 1 for a maker without a fee table; with --board that board alone – no order total, no cost.json, no budget check

edakit order

edakit order [--out OUT] [--supplier SUPPLIER] [--with CONFIG] [{check}]

Assembler's BOM, one cart per other supplier, hand-assembly list for all sets; check: the supplier's cart as the skill cart read it back (ORDER.basket).

edakit order [--out DIR] [--with CONFIG …] – EasyEDA: no

  • Reads: graph, parts (order), board files (side), [[extra]], spare_pct; with --with the same of each other project's edakit.toml; the inventory of edakit.local.toml (8.4)
  • Writes: <artifacts>/order/ or DIR: bom_<board>.csv (the SYNC.bom BOM; none for a bought or hand-wired board), cart_<supplier>.csv, hand_assembly.md; with --with the carts of all projects in the same files and hand_assembly_<project>.md for each other project

edakit inventory

edakit inventory [QUERY ...]

Your parts on hand, named in edakit.local.toml: the project's hand-soldered parts and extras against them; QUERY: the rows holding every word; template FILE: a new empty inventory (.md, .xlsx, .ods).

edakit inventory [WORDS …], edakit inventory template FILE – EasyEDA: no

  • Reads: edakit.local.toml and the inventory it names (10.1); graph, parts, [[extra]], spare_pct as edakit order
  • Writes: nothing – template a new .md, .xlsx or .ods with the header row, files in edakit.local.toml when it names none, and both in .gitignore
  • Exit: 0; 1 without an inventory, with one edakit cannot read, or a query no row holds

edakit cart

edakit cart [--board BOARD] [--maker MAKER] [--cart] [--from SOURCE] [--sign BY] [--note NOTE] {fields,prepare,check,confirm,actual,compare}

The order at the maker: the form's fields, the job of the skill cart, its check, the maker's confirmations after the order (M-2), the real cost, the makers' quotes compared – up to the maker's cart, never further.

edakit cart fields [--board B] [--maker M] – EasyEDA: no

  • Reads: [order] of edakit.toml and the board file, thickness_mm, [release] assembly, [tooling], the stock snapshot, [cart], the maker's profile; the Gerber files of the current release (else the newest run) for layers and size
  • Writes: – (prints every field of the maker's form: its label, the maker's word, where it comes from, edakit's key and value)

edakit cart prepare [--board B] [--maker M] – EasyEDA: no

  • Reads: the current release (manifest, makers.json, the board's upload files and order.json), the circuit and layout hash now, the sign-off file (M-6), [cart], the maker's profile, the estimate
  • Writes: <reports>/<run>/fab/<board>/cart/<maker>/job.json; exit 1 with the reason when the order cannot be placed against the release (8.4)

edakit cart check [--board B] [--maker M] [--cart] – EasyEDA: no

  • Reads: job.json, quote.json, quote_page.txt, regulatory.md, with --cart cart.json of the order's folder; the manifest
  • Writes: check.md, check.json; with --cart and every check passed the order record hardware/orders/<date>-<board>-<maker>.json. Exit 0 passed, warnings and notes included (in check.md), 2 a check of ORDER.form to ORDER.review failed, 3 ORDER.form to ORDER.finish passed and the review of the order (ORDER.review) is open

edakit cart confirm [--board B] [--maker M] [--sign BY] [--note TEXT] – EasyEDA: no

  • Reads: job.json, confirm.json and confirm_page.txt of the order's folder (the current release's, else the run the order record names), the graph and parts entries for the parts of the polarity sheet, the sign-off file
  • Writes: confirm.md, confirm_check.json; with --sign and every check passed M-2 in the sign-off file (done_by, date, note), bound to the job's fab hash. Exit 2 when a check fails – nothing signed; 1 when the sign-off file's fab sign-offs are bound to another run's files (8.4, step 5)

edakit cart actual [--board B] [--maker M] [--from FILE] – EasyEDA: no

  • Reads: job.json, quote.json, actual.json and actual_page.txt of the order's folder (the current release's, else the run the order record names) – with --from a saved order page or invoice (HTML; PDF with pdftotext) whose text edakit reads itself; [cost], the fee table
  • Writes: actual.md; the project's fee table ([cost] fees, else hardware/fees/<maker>.json) with what maps one to one; the order number and the totals in the order record. Exit 2 when ORDER.read fails – the fee table and the order record stay as they are, and actual.md says why

edakit cart compare [--board B] – EasyEDA: no

  • Reads: the current release; per maker of [cart] makers its order folder (job.json, quote.json, check.json); [cost] currency and rates
  • Writes: <reports>/<run>/fab/<board>/cart/compare.md; prints the quotes side by side – the board total as quoted and in [cost] currency, the order total, the lines a maker marked or did not match, the lead time, whether edakit cart check passed on that quote – and the lowest board total; nothing asked of a maker (8.4)

edakit sim

edakit sim [--json JSON] [--keep KEEP]

Simulation (stage E).

edakit sim [--json F] [--keep DIR] – EasyEDA: no

  • Reads: graph, parts, sim config, plugin; with copper route/<board>.ses, route/<board>_board.json and the board file's pours
  • Writes: <artifacts>/sim/net_currents.json, <artifacts>/sim/result.json (the whole result with the hash of its inputs, 6.6 – with cable_currents, the highest current through a wire of each cable); with --keep each netlist and ngspice log, for a transient run its waveforms (<run>.dat)

edakit docs

edakit docs [--write]

Values quoted from the design data in documents and notes (DOCS.quote).

edakit docs [--write] – EasyEDA: no

  • Reads: [docs] files, the schematic notes, graph, parts; for sim: the saved simulation result (or a new run); for req: the files of [project] requirements
  • Writes: with --write the value blocks of [docs] files

edakit firmware

edakit firmware [--check]

The board's firmware contract from the graph ([firmware] in edakit.toml).

edakit firmware [--check] – EasyEDA: no

  • Reads: graph, parts, [firmware]; for state_sha256 the files of the circuit hash
  • Writes: [firmware] out (not with --check: exit 2 on drift)

edakit req

edakit req [ids ...]

What the circuit must do: needs and requirements with status, binding and evidence ([project] requirements in edakit.toml).

edakit req [ID …] – EasyEDA: no

  • Reads: the files of [project] requirements (10.4)
  • Writes: – (prints the needs and requirements with status, binding and verify as written – the gate evaluates it, 8.7; with IDs the chain of each, 3.6); exit 1 without the key, with a file missing or not valid, or an ID not in the files

edakit scripts

edakit scripts [{stamp}] [names ...]

The project's scripts ([scripts.]): state and order; stamp records a run.

edakit scripts – EasyEDA: no

  • Reads: [scripts], [[release.stages]], sim_plugin, the board files' [[silk.art]], hardware/scripts.lock, what the scripts read; [agents] and the agent files (8.6)
  • Writes: – (prints every script with kind, state – current, outdated, never run –, about, cmd and its last run; the order; with [agents] every agent with what it signs, and who reviews where – each hook point with its agents in the order to start them; exit 2 when a script is outdated or never ran or the entries of [scripts] or [agents] do not resolve, 1 when the lock cannot be read)

edakit scripts stamp NAME … – EasyEDA: no

  • Reads: the same
  • Writes: hardware/scripts.lock: the stamp of each script named – it ran by hand; refused, writing nothing, for a check, entries that do not resolve, or a script whose writes are not there

edakit run

edakit run NAME [NAME ...]

Run project scripts ([scripts.]) in their order and record their runs; an easyeda script under the EasyEDA claim.

edakit run NAME … – EasyEDA: no – (an easyeda script changes EasyEDA itself, under the claim)

  • Reads: the same
  • Writes: runs the scripts named in their order, in the project directory (python = edakit's), and records each run: its stamp; for an easyeda script also its change of project-library:<b> or pcb:<b> (8.6); <artifacts>/scripts/<name>.log per script. Refused for a check, a name not in [scripts], entries that do not resolve; a failed script records nothing and stops the run; exit 2 when a script named is still outdated, 3 when another session holds EasyEDA

edakit handover

edakit handover [--board BOARD]

The hand-over from the circuit to the layout: state, sign-offs, requirements.

edakit handover [--board B] – EasyEDA: no

  • Reads: graph, parts, sign-offs
  • Writes: –

edakit schematic

edakit schematic [--board BOARD] [--schematic SCHEMATIC] [--source SOURCE] [--target TARGET] [--only ONLY] [--dry-run] [--reread] [--force] [--out OUT] [--no-frame] [--no-pins] [--refresh-devices] [--create-project] [--save] [--json JSON] [--wait WAIT] {create,check,copy,layout,draw}

Generate, check, copy or lay out a schematic in EasyEDA – or draw it without.

edakit schematic create [--board] [--only] [--dry-run] [--save] [--create-project] [--refresh-devices] – EasyEDA: ✓

  • Reads: graph
  • Writes: template, device_cache.json, schematic_map_<name>.json; --save only when the netlist equals the graph, then reads the save opened again and exits 2 when it differs (6.1)

edakit schematic check [--schematic] [--no-pins] [--json F] – EasyEDA: ✓ read

  • Reads: graph, schematic as saved – its tab closed and opened again, one with unsaved changes read as drawn and named (6.2)
  • Writes: –

edakit schematic copy [--source] [--target] [--save] – EasyEDA: ✓

  • Reads: schematic
  • Writes: copy; a source EasyEDA cannot read: nothing, exit 1 naming schematic layout --save (6.3)

edakit schematic layout [--dry-run] [--reread] [--force] [--save] – EasyEDA: ✓ / –

  • Reads: graph, schematic, cached geometry
  • Writes: board schematic, layout_preview_<name>.svg; --save only when the netlist equals the graph (6.1)

edakit schematic draw [--board] [--out F] [--force] [--no-frame] – EasyEDA: no

  • Reads: graph, parts, the schematic file if there; for a {sim:…} note the saved simulation result
  • Writes: schematic_<board>.svg (or F)

edakit perfboard

edakit perfboard [--board BOARD]

The plan of a hand-wired board on a perfboard ([perfboard] in its board file): checked against the graph, drawn, its cut, build and test lists.

edakit perfboard [--board B] – EasyEDA: no

  • Reads: the board file of every hand-wired board with [perfboard] (or of B), the kind of edakit/perfboards/, graph, parts entries (footprint_data, body, joined), the footprint geometry beside the board file and the library cache of part import, <artifacts>/sim/net_currents.json
  • Writes: <artifacts>/perfboard/<board>/top.svg, bottom.svg, cut.svg (the cut list at 1:1), build.md (7.9); exit 1 on an error

edakit pcb

edakit pcb [--board BOARD] [--write] [--ref REF] [--only ONLY] [--rest] [--verify-all] [--no-scripts] {dump,plan,place,parts,nets,apply,tooling,pour,autolayout,takeover}

Placement plan, parts and nets sync, fixed parts, tooling holes, pours.

edakit pcb dump [--ref] – EasyEDA: ✓

  • Reads: PCB; the parts entries (which have footprint data)
  • Writes: hardware/boards/<board>.geometry.json, beside the board file and versioned (parts end at 0°/TOP; through-hole pads with hole [w, l] mm and plated; the pads of a part whose entry has footprint data with shape, w, h, rot, layer); a <artifacts>/pcb_geometry_<board>.json from before is moved there (7.4)

edakit pcb plan – EasyEDA: no

  • Reads: plan, geometry (the dump; for parts not in it the footprint data of their entry, else the library footprints of part import), net currents, graph (layout, SYNC.plan), parts entries (body, lead length_mm, mate)
  • Writes: pcb_plan_<board>.png/.json, pcb_netclasses_<board>.json, mech_<board>.json (7.4)

edakit pcb place [--rest] [--write] [--only C1,R1] – EasyEDA: no

  • Reads: plan, geometry as pcb plan reads it, graph (layout.near, decoupling of SYNC.plan), [near]; with --rest also the graph's nets and [release] assembly sides
  • Writes: with --write: rows with auto = true at the end of [place] – with --rest for every part of the board without a row, or with an auto row: by airline length, then moves and swaps while it falls (7.4)

edakit pcb parts [--write] – EasyEDA: ✓

  • Reads: board schematic, PCB, graph
  • Writes: PCB parts, UniqueIds, geometry

edakit pcb nets [--write] – EasyEDA: ✓

  • Reads: graph, PCB
  • Writes: pad nets

edakit pcb apply [--verify-all] – EasyEDA: ✓

  • Reads: plan, geometry
  • Writes: outline, holes, tooling, fixed parts

edakit pcb autolayout – EasyEDA: ✓

  • Reads: graph, board file
  • Writes: positions of the unlocked parts; once they stand still, a row with auto = true at the end of [place] for every part of the board without one (7.4)

edakit pcb takeover [--write] – EasyEDA: ✓ read

  • Reads: PCB, graph, board file
  • Writes: with --write: a fixed row at the end of [place] for every part of the board without one, where EasyEDA has it – once, for a board placed before (7.4)

edakit pcb tooling / pour – EasyEDA: ✓

  • Reads: plan; pour with pour_regions: board file and SES of route
  • Writes: tooling holes / pours (unfilled)

edakit route

edakit route [--board BOARD] [--net NET] [--passes PASSES] [--threads THREADS] [--clearance CLEARANCE] [--no-optimizer] [--cleanup] [--no-scripts] {all,read,dsn,route,check,diagnose,apply,verify,pours,fill,reload,drc,save}

Route with Freerouting and write the result into EasyEDA.

edakit route all|read|dsn|route|check|apply|verify [--cleanup]|pours|fill|reload|drc|save [--passes N] [--threads 4] [--clearance MIL] [--no-optimizer] – EasyEDA: ✓ / – (dsn, route, check offline)

  • Reads: PCB, rules (--passes, --clearance over [routing] passes, clearance_mil); net_currents.json (check: GEO.width offline; widths = "sim")
  • Writes: route/<board>_board.json, .dsn, .ses, _routing.png, _drc.json, _netlist_diff.json (with an Import Changes item); tracks, vias, pours; with [scripts], all and pours mark a change of pcb:<b> gone in hardware/scripts.lock – the pours filled anew over the copper of easyeda scripts (8.6)
  • fill: the pours of [[pours]] already in the PCB filled one per call – no new pours, no NO_POURS regions –, the tooling holes set again, the PCB saved – the PCB saved and loaded again first; after pours or all stopped with "no-copper" (7.6, M-13). A pour whose net has no pad, via or track on its layer is named as the board's

edakit route diagnose [--net N] – EasyEDA: no

  • Reads: route/<board>_board.json, the board file's rules, the last SES
  • Writes: route/<board>_diagnose/ (a PNG per open connection, congestion.png, diagnose.json), 7.5

edakit silk

edakit silk [--board BOARD] [--no-scripts] {apply,check,preview}

Designators where there is room, silkscreen check on the Gerber export.

edakit silk apply|check – EasyEDA: ✓

  • Reads: PCB, Gerber export
  • Writes: designators, silk_<board>_<side>.png, gerber_<board>/; apply: silk_footprints_<board>/ (the print it found, for GEO.silk)

edakit silk preview – EasyEDA: no

  • Reads: board file, the last Gerber export (gerber_<board>/)
  • Writes: silk_preview_<board>_<side>.png: artwork, texts and the fixed designators of [silk.place] (exit 2 when one is in the way, 7.7)

edakit export

edakit export [--board BOARD]

Documentation and manufacturing files from EasyEDA.

edakit export [--board] – EasyEDA: ✓ read

  • Reads: schematic, PCB, project file
  • Writes: <artifacts>/export/; with a maker that takes ODB++ also odb_<board>.zip (easyeda_export_odb, 2.5; on KiCad kicad-cli, 16.5)

edakit gate

edakit gate [--eda] [--no-scripts]

Release gate: all stages, test protocol, manufacturing files.

edakit gate [--eda] – EasyEDA: – / ✓ (--easyeda, the old name, still works)

  • Reads: everything; with [project] requirements the requirements files (8.7 – a file missing or not valid: exit 1 before a run)
  • Writes: <reports>/<run>/, with stage_<id>.txt the output of each project check that ran (8.1); a RELEASED run supersedes the earlier ones in their fab/manifest.json (8.3)

edakit release

edakit release [--reason REASON] [--draft] [--tag TAG] [--dry-run] [--built TAG] {current,withdraw,verify,publish} [items ...]

The current release: show it, withdraw a run, check the files to upload, publish what is ordered.

edakit release current – EasyEDA: no

  • Reads: the manifests under reports; the real cost of its orders (cart/<maker>/actual.json); with [release] archive = "git" what git tracks of the run
  • Writes: – (with an order's real cost: estimate, quote and actual beside the release; with archive = "git" and a run git does not track yet "not in git yet: git add -f …"). Exit 2 without a current release

edakit release withdraw RUN --reason TEXT – EasyEDA: no

  • Reads: the run's manifest
  • Writes: its fab/manifest.json: status, withdrawn {reason, by, date}

edakit release verify FILE…|DIR… – EasyEDA: no

  • Reads: the files (a folder: its .zip and .csv files), the manifests
  • Writes: –

edakit release publish [--draft] [--dry-run] [--tag T] – EasyEDA: no – (gh, git)

  • Reads: git (a clean tree, HEAD on its remote branch – not with --draft); per project and variant below it the current release, its upload files (release verify), polarity sheet, manifest and order form; the graph's purpose; with [release] publish.decisions the decision log at HEAD and at the previous release's tag; through gh the repository's tags and the previous release's SHA256SUMS and manifests
  • Writes: build/publish/<tag>/: the files, SHA256SUMS, notes.md; the GitHub release <tag> (default today, -2 … when the remote has it) as a pre-release on HEAD – --draft a draft without tag, --dry-run nothing uploaded. Exit 2: a file refused or a project without a current release, nothing staged (8.3)

edakit release publish --built TAG – EasyEDA: no – (gh)

  • Reads: –
  • Writes: the release TAG no longer a pre-release: a board of it has been built and works (M-4)

edakit fab

edakit fab [--board BOARD] [--out OUT] [--offline] [{diff}] [runs ...]

Stages L and F for one board; diff: where the manufacturing files of two runs differ.

edakit fab --board B --out DIR [--offline] – EasyEDA: ✓ / –

  • Reads: PCB, exports, route/<board>_board.json (GEO.spacing), silk_strings_<board>.json and silk_footprints_<board>/ (GEO.silk), the stock snapshot (order.md), with [routing] drc_rules the rule set of EasyEDA's DRC (GEO.drc)
  • Writes: DIR/<board>/, with [order] or [cart] also order.md, with [order] order.json (the settings in the fab hash), with [routing] drc_rules also drc_rules.json; with a maker of [cart] makers whose profile takes the MPN BOM bom_<board>_mpn.csv, with one whose [cpl] zero is its own cpl_<board>_<maker>.csv (SYNC.cpl), with one that takes ODB++ odb_<board>.zip (SYNC.odb); with [release] maker_files = "all" (default) the MPN BOM and the ODB++ of every board with an assembly side

edakit fab diff RUN_A RUN_B [--board B] – EasyEDA: no

  • Reads: fab/<board>/ of two gate runs: Gerber layers, drill files, BOM, CPL, the order settings (order.json)
  • Writes: –

edakit lock

edakit lock [--note NOTE] [--auto] [{status,claim,release,yield,hook}] [chat]

EasyEDA claim between parallel Claude sessions.

edakit lock [status|claim|release|yield CHAT|hook] [--note] [--auto] – EasyEDA: no

  • Reads: – (hook: tool name and, for easyeda_api_call, its path; library lookups of READ_ONLY_TOOLS/READ_ONLY_API pass without a claim, 11.2)
  • Writes: ~/.local/state/edakit/easyeda-lock.json

edakit proposal

edakit proposal [--feature] [--out OUT] {template,seal,verify} [file]

Rule and feature proposals for the edakit repository: template, seal, verify.

edakit proposal template [--feature]|seal FILE [--out F]|verify FILE|- – EasyEDA: no

  • Reads: a rule or feature proposal (no project needed)
  • Writes: seal: the issue body with its SHA-256

edakit doctor

edakit doctor [--offline]

Check the tool chain.

edakit doctor [--offline] – EasyEDA: ✓ read (not with --offline)

  • Reads: tool chain; BRIDGE_TIMEOUT_MS of the running easyeda-mcp-pro servers (/proc/<pid>/environ); with EasyEDA running, through an own server that claims nothing: easyeda_bridge_status, easyeda_health_check (connected, extension against server version, registry) and, while the claim is free or yours, DMT_Project.getCurrentProjectInfo ([MaxDepth] = the original extension) – 2.5, 12
  • Writes: –

10.6 Files in a project

edakit.toml                 the table of contents: project, boards, where the files are
edakit.local.toml           this checkout's settings – the inventory (10.1); in .gitignore, never committed
hardware/requirements.toml  what the circuit must do: needs and requirements, if [project] requirements names it
hardware/graph.toml         the hardware graph (only source of parts and connections), ground net, check settings;
                            hardware/graph.json in a project that has not converted
hardware/graph.json         beside a TOML graph: the resolved graph, generated (edakit graph json --write), never edited
hardware/parts/*.json       parts database; an own footprint as data in its entry (footprint_data, 4.5)
hardware/datasheet/<name>.* the board as a part for other projects: parts entry and datasheet (edakit part datasheet)
hardware/sim.json           simulation scenarios
hardware/stock.json         what the assembler said about the parts, dated (edakit stock, PARTS.stock)
hardware/orders/*.json      the order records: run, hashes, maker, regulatory verdict, cart line, real cost
                            (edakit cart)
hardware/fees/<maker>.json  the project's fee table from its own orders (edakit cart actual); [cost] fees names another
hardware/makers/*.toml      a maker's profile of the project's own, named in [cart] profiles (edakit ships jlcpcb,
                            pcbway, eurocircuits and aisler in edakit/makers/)
hardware/schematic.toml     arrangement of the schematic
hardware/boards/<name>.toml one board: outline, holes, placement, routing, pours, silkscreen
hardware/boards/<name>.geometry.json
                            its footprint geometry, as edakit pcb dump measured it (in the layout hash)
hardware/signoff.json       manual checks and accepted warnings, bound to hashes
hardware/firmware.json      the firmware contract, if [firmware] is set (edakit firmware)
hardware/scripts.lock       the stamps of the project scripts and the changes of easyeda scripts, if [scripts] is set
                            (edakit run, edakit scripts stamp)
.claude/agents/<name>.md    the project's own agents; those that sign a sign-off are registered in [agents]
docs/decisions.md           numbered decisions (or wherever the project keeps them)
build/edakit/               artifacts (not versioned): caches, previews, routing, exports, cost.json;
                            library/ and footprints/: the library's symbols and footprints (edakit part import);
                            datasheets/: the datasheets edakit part fetch keeps (unless [project] datasheets names
                            another folder); scripts/: the output of each project script's last run (edakit run)
build/release/<run>/        gate runs – build output, not versioned (with [release] archive = "git" the released
                            ones are committed); fab/manifest.json says which one is current;
                            pictures/ the schematic and the board as SVG and PNG (protocol section 12, 8.3);
                            fab/<board>/cart/<maker>/ the files of an order: job, quote, page texts, screenshots,
                            regulatory review, check, cart line, real cost (edakit cart, 8.4)
build/publish/<tag>/        what edakit release publish published: per board the upload files, polarity_<board>.png,
                            manifest_<board>.json, order_<board>.md, the run's pictures; SHA256SUMS, notes.md – the
                            folder to upload to the maker from (not versioned; the GitHub release keeps it, 8.3)

10.7 Check IDs of before

Until the restructuring into engines and codes (14.2) the checks had IDs per stage – P-…, G-…, E-…, S-…, L-…, F-…, and H-… for the hints. Protocols, decisions and sign-off files of before name them; edakit explain G-8 names the codes that replace one, and edakit convert rewrites a project's graph, parts entries, sign-off file and documents once. Generated from the catalog:

before now
P-1 STRUCT.entry
P-2 FILES.sheet
P-3 SYNC.source
P-4 PARTS.stock
P-5 PARTS.supplier
P-6 STRUCT.identity, STRUCT.prefix
P-7 GEO.hole, PARTS.fact
P-8 GEO.formed
P-9 PARTS.footprint
P-10 SYNC.footprint
P-11 PARTS.fact, PARTS.schema
P-12 PARTS.fact
G-1 STRUCT.name, STRUCT.pin, STRUCT.net, STRUCT.board, STRUCT.ref, STRUCT.purpose
G-2 STRUCT.lock
G-3 LIM.v
G-4 LVL.undefined
G-5 LVL.contention
G-6 REQ.missing
G-8 LIM.v
G-9 PARTS.verified
G-10 PATH.reverse
G-11 REQ.missing, REQ.value
G-12 LVL.boot
G-13 REQ.missing
G-14 REQ.missing, REQ.value, REQ.forbidden, PARTS.schema
G-15 REQ.function, PARTS.fact
G-16 STRUCT.ref, PATH.unfed, PATH.ground
G-17 LIM.i
G-18 REQ.missing, PARTS.fact, PARTS.schema
G-19 DOCS.quote
G-20 DOCS.ref
G-21 DOCS.need
G-22 DOCS.evidence
G-23 DOCS.draft
G-24 LIM.eirp, PARTS.schema
G-25 STRUCT.ref, STRUCT.purpose, LIM.band
E-1 SIM.config, SIM.converge, SIM.copper
E-2 LIM.v, LIM.i, LIM.p, LIM.t
E-3 LIM.i, LIM.t, LIM.range, LIM.declared, LIM.backfeed, LVL.threshold, LVL.direction, SIM.config, SIM.state
E-4 SIM.driver
E-5 LIM.v, LIM.i, LIM.range
S-2 SYNC.schematic
L-1 SYNC.pcb
L-2 GEO.copper
L-3 GEO.drc
L-4 SYNC.footprint
L-5 GEO.width
L-7 SYNC.plan
L-8 GEO.mark
L-9 GEO.hole
L-10 SYNC.footprint
L-11 GEO.loop
L-12 SYNC.plan
L-13 GEO.spacing
L-14 GEO.spacing
L-15 GEO.pour
L-16 GEO.spacing, GEO.ring
L-17 GEO.silk
L-18 GEO.spacing
L-19 GEO.silk
L-20 SYNC.plan
F-1 SYNC.bom
F-2 PARTS.stock
F-3 SYNC.cpl
F-4 FILES.manifest
F-5 FILES.set
F-6 FILES.order
F-7 SYNC.odb
H-1 HINT.bulk
H-2 HINT.gate
H-3 HINT.debounce
H-4 HINT.inductive
H-5 HINT.switcher
H-6 HINT.lithium
H-7 HINT.esd
H-8 HINT.two_supplies
H-9 HINT.readback
B-1 ORDER.form
B-2 ORDER.parts
B-3 ORDER.quote
B-4 ORDER.read
B-5 ORDER.files
B-6 ORDER.finish
B-7 ORDER.review