skill
EDA Bridge Standard: one way for an AI to drive every PCB tool
Public Made by Adomby adom
The standard every Adom EDA bridge follows so one AI can drive Altium, KiCad, Fusion 360 and any future PCB tool the same way: shared verb names in tiers, the board model JSON, reply and refusal conventions, and a coverage table of each bridge against the Altium reference.
← Commit history
standard 0.26.0: six #29 verbs join (verb_times, prewarm, render_board, align_footprints, export_pos, edit_placed_footprint)
5 files changed
+335−14
README.md+5−4@@ -60,12 +60,12 @@ verb by verb: [docs/coverage.md](docs/coverage.md). <!-- coverage:start (tools/generate.py writes this) --> | Tier | Verbs | Altium | KiCad | Fusion 360 | |---|---|---|---|---|-| **core** | 94 | 94 | 90 | 91 |-| **native** | 47 | 47 | 44 | 42 |+| **core** | 95 | 94 | 90 | 91 |+| **native** | 50 | 47 | 47 | 42 | | **checks** | 38 | 38 | 38 | 38 |-| **app** | 62 | 62 | 51 | 53 |+| **app** | 64 | 62 | 53 | 55 | | **platform** | 18 | 18 | 0 | 1 |-| standard (all but platform) | 241 | 241 | 223 | 224 |+| standard (all but platform) | 247 | 241 | 228 | 226 | <!-- coverage:end --> The **checks** tier is where the other bridges are furthest behind, and it is the cheapest to close: those verbs are@@ -158,6 +158,7 @@ Decisions so far (proposals from the KiCad and Fusion bridges, 2026-10-27; issue ## Status +Version 0.26.0: six verbs from kicad-lane join the standard (#29): `verb_times` and `prewarm` (app), `render_board`, `align_footprints` and `export_pos` (native), `edit_placed_footprint` (core). Version 0.25.1: regenerated on kicad-lane's latest #29 equivalents (panel, activate_document). Version 0.25.0: the reference is Altium bridge 0.2.84, which brings two verbs into the standard: `update_footprints_from_library` (core, #27) and `lint_library` (checks, #28). The standard is 241 verbs. Version 0.24.4: coverage reads Fusion 360 bridge 1.13.26 and kicad-lane's first #29 equivalents (KiCad 219); tiers for `update_footprints_from_library` (core, #27) and `lint_library` (checks, #28), which enter the standard with Altium's 0.2.84 reference.
docs/coverage.md+11−5@@ -1,17 +1,17 @@ # Coverage: every standard verb on each bridge -Altium bridge 0.2.84 (the reference), KiCad bridge 1.0.89, Fusion 360 bridge 1.13.26. 56 verbs came from other bridges' proposals (tools/proposed/); they are marked *proposed*.+Altium bridge 0.2.84 (the reference), KiCad bridge 1.0.89, Fusion 360 bridge 1.13.26. 62 verbs came from other bridges' proposals (tools/proposed/); they are marked *proposed*. `exact` is the same job under the same or an equivalent name; `partial` does part of it or does it differently (`verbs/coverage.json` names what in `note`); `unsupported` answers `not_supported` for the whole job and is not counted; blank is missing. Generated by `tools/generate.py` from `verbs/coverage.json`; do not edit by hand. | Tier | Verbs | Altium | KiCad | Fusion 360 | |---|---|---|---|---|-| **core** | 94 | 94 | 90 | 91 |-| **native** | 47 | 47 | 44 | 42 |+| **core** | 95 | 94 | 90 | 91 |+| **native** | 50 | 47 | 47 | 42 | | **checks** | 38 | 38 | 38 | 38 |-| **app** | 62 | 62 | 51 | 53 |+| **app** | 64 | 62 | 53 | 55 | | **platform** | 18 | 18 | 0 | 1 |-| standard (all but platform) | 241 | 241 | 223 | 224 |+| standard (all but platform) | 247 | 241 | 228 | 226 | ## core @@ -39,6 +39,7 @@ Read and edit the design. Every bridge provides these: they are how an AI sees a | `doc_params` | Read or set a sheet's document parameters: the title block (Title, DocumentNumber, Revision, DrawnBy, Author, CompanyName, ...). | `altium_doc_params` | `kicad_doc_params` (partial) | `fusion_doc_params` (partial) | | `edit_footprint` *proposed* | Edit a library footprint in place: change, delete, add or renumber pads; add, replace or delete graphics on a layer; set its description, tags and... | `altium_edit_footprint` | `kicad_fp_edit` | `fusion_edit_footprint` (partial) | | `edit_parts` *proposed* | Edit placed parts: value, designator, any field (add, change, remove), do-not-populate, exclusion from the BOM or position files, mounting type and the... | `altium_edit_parts` | `kicad_edit_parts` | `fusion_edit_parts` (partial) |+| `edit_placed_footprint` *proposed* | Edit parts placed on a board: value, reference, any field (add, change, remove), DNP, exclude from BOM or position files, the mounting type, and the lock.... | | | | | `find_symbol` | Find symbols (or footprints with kind:'footprint') by part of their name across libraries: the given ones, or every installed .SchLib/.PcbLib. | `altium_find_symbol` | `kicad_find_symbol` | `fusion_find_symbol` (partial) | | `footprint_primitives` | Geometry dump of one PLACED component: its tracks, arcs, pads (with solder and paste mask expansion in um) and texts in mils with layer ids; other primitive... | `altium_footprint_primitives` | `kicad_footprint_graphics` (partial) | `fusion_footprint_primitives` | | `generate_body` *proposed* | Make a part's 3D body from its package family and its datasheet dimensions (chip, SOIC, QFN, QFP, BGA, SOT-23, DFN, MELF, electrolytic can, crystal, pin... | `altium_generate_body` | `kicad_generate_body` | `fusion_generate_body` |@@ -121,6 +122,7 @@ Wraps the EDA tool's own feature (its DRC, ERC, Gerbers, pours, Update PCB). Eve | Verb | What it does | Altium | KiCad | Fusion 360 | |---|---|---|---|---| | `add_rule` | Add one SCOPED design rule that set_design_rules' board-wide values cannot express: a net's or class's clearance or width, a length limit, a matched-length... | `altium_add_rule` | `kicad_add_rule` | `fusion_add_rule` |+| `align_footprints` *proposed* | Align placed parts on a common left, right, top, bottom or centre line, or distribute them evenly, by courtyard box or anchor, through the bridge's checked... | | `kicad_align_footprints` | | | `annotate` | Number every '?' designator (R?, C?, U?) across the project's sheets: the lowest free number per prefix, top-left first on each sheet. dryRun shows the plan. | `altium_annotate` | `kicad_annotate` | `fusion_annotate` | | `apply_pours` | Add solid polygon pours from outlines and pour them, each with its own connect style (solid joints or thermal spokes), plus pour keepouts (polygon cutouts);... | `altium_apply_pours` | `kicad_add_zone / kicad_apply_zone_plan` | `fusion_apply_pours` (partial) | | `autoroute` | Altium's own autorouter (Situs) on the current board: picks a strategy, keeps existing routing locked by default, routes, and answers the unconnected count... | `altium_autoroute` | `kicad_autoroute` | `fusion_autoroute` |@@ -140,6 +142,7 @@ Wraps the EDA tool's own feature (its DRC, ERC, Gerbers, pours, Update PCB). Eve | `export_manufacturing` | A project's manufacturing set in one call: Gerbers, NC drill, pick and place (CSV, mm) and the BOM, from an OutJob the bridge writes beside the project... | `altium_export_manufacturing` | `kicad_export_manufacturing` | `fusion_export_gerbers / fusion_export_cpl / fusion_export_bom` (partial) | | `export_odb` *proposed* | Export the board as ODB++ (copper, drill, stack-up, netlist and parts in one archive) through the tool's own exporter. | `altium_export_odb` | `kicad_export_odb` | `fusion_export_odb` | | `export_pdf` | Every sheet of a project as one PDF, plus on request the board's composite print, Altium's assembly drawings (top and bottom, designators on the parts) and... | `altium_export_pdf` | `kicad_export_pdf` | `fusion_export_pdf` (partial) |+| `export_pos` *proposed* | Export the pick-and-place (component position, CPL) file of a board, optionally in a fab's assembly format (JLCPCB's columns). | | `kicad_export_pos` | | | `export_step` | Headless STEP export of a board. Default lane 'outjob': Altium's own ExportSTEP output run from a throwaway project in %TEMP% that points at the board - no... | `altium_export_step` | `kicad_export_step` | `fusion_export_step` | | `install_library` | Register a library file in Altium's Installed Libraries (IntegratedLibraryManager.InstallLibrary) so its parts appear in the Components panel. | `altium_install_library` | `kicad_install_library` | `fusion_install_library_bundle` (partial) | | `install_library_bundle` | One-click install of a wiki library bundle (zip of .SchLib/.PcbLib): unpack, register, open the library, prove it with a frame. | `altium_install_library_bundle` | `kicad_install_library_bundle` | `fusion_install_library_bundle` |@@ -151,6 +154,7 @@ Wraps the EDA tool's own feature (its DRC, ERC, Gerbers, pours, Update PCB). Eve | `pour_state` | Every polygon pour with the copper it actually poured: filled area per pour and per layer, and the pours that poured nothing. | `altium_pour_state` | `kicad_pour_state` | `fusion_pour_state` | | `project_snapshot` *proposed* | A dated copy of the project's documents into <project>/snapshots/<stamp>[-label]/, with PDFs of the schematic and the board made by the tool. | `altium_project_snapshot` | `kicad_project_snapshot` | `fusion_project_snapshot` (partial) | | `remove_pours` | Delete polygon pours by net (and layer), or all of them, and the pour keepouts (cutouts) apply_pours made. Tracks and vias are untouched. | `altium_remove_pours` | `kicad_remove_zone` | `fusion_remove_pours` |+| `render_board` *proposed* | A rendered 3D picture (PNG or JPG) of a board from one side, made by the tool's own renderer with no window: optionally framed on parts, turned for an... | | `kicad_render_board` | | | `render_board_3d` *proposed* | Render a 3D picture of the board from one side to an image file, through the tool's own renderer, without opening a window. | `altium_render_board_3d` | `kicad_render_board_3d` | `fusion_render_board_3d` | | `render_board_layers` *proposed* | Render chosen board layers to an image file without opening a window: a preset view (copper, silkscreen, solder mask, paste, outline, drill, assembly or... | `altium_render_board_layers` | `kicad_export_svg` (partial) | `fusion_export_board_image` (partial) | | `render_schematic` *proposed* | Render a sheet to an image without opening a window, through the tool's own plotter, and keep visual baselines: baseline set stores the image, baseline... | `altium_render_schematic` | `kicad_render_schematic` | `fusion_render_schematic` |@@ -254,6 +258,7 @@ Driving the application itself (launch, licence, dialogs, windows, views). Each | `open_document` | Open a document or project by path through the agent and show it without focusing it. An already-open document is activated, not reloaded. | `altium_open_document` | `kicad_open_board / kicad_open_schematic` (partial) | `fusion_open_document` | | `open_project` | Open a project (.PrjPcb / .PrjScr / .PrjMbd / .PrjHar / .LibPkg) by path. Same handler as altium_open_document. | `altium_open_project` | `kicad_open_board / kicad_open_schematic` (partial) | `fusion_open_cloud_file` (partial) | | `panel` | Activate a docked panel TAB (SCH Library, PCB Library, Components, Projects, Properties) in the BACKGROUND - the 'ganged-up view' needs the right panels in... | `altium_panel` | `kicad_send_key` (partial) | unsupported |+| `prewarm` *proposed* | Get this machine ready for a fast first call: detect the tool, seed its first-run settings, dismiss first-run wizards and repair what the first real call... | | `kicad_prewarm` | `fusion_prewarm` | | `progress` | The bridge's timing book: phases in flight right now (percent/ETA blocks ab paints on the taskbar), measured phase history and per-verb run statistics. | `altium_progress` | `kicad_progress` | `fusion_progress` | | `readiness` | The one-call gate: is Altium installed, running, licensed, and is the resident agent alive? Answers with Altium closed and never touches the script engine. | `altium_readiness` | `kicad_readiness` | `fusion_readiness` | | `run_command` | Run an Altium process (Server:Command) through the agent, on the CURRENT document or on filePath opened first. | `altium_run_command` | `kicad_send_key` (partial) | `fusion_run_command` |@@ -279,6 +284,7 @@ Driving the application itself (launch, licence, dialogs, windows, views). Each | `state` | The whole picture in one call: licence state, windows, dialogs, a screenshot of every main/dialog window, and the agent's logical state (focused document,... | `altium_state` | `kicad_state` | `fusion_state` | | `status` | Is Altium running, licensed, and is the resident agent alive? | `altium_status` | `kicad_status` | `fusion_status` | | `uninstall` | Remove the bridge's own cache directory (agent workspaces, rendered agent scripts, the Altium 365 token file). Altium Designer and the user's designs are... | `altium_uninstall` | `kicad_uninstall` | `fusion_uninstall` |+| `verb_times` *proposed* | Measured run times of this bridge's verbs on this machine: per verb the count, p50, p90, max, last and failures, from its own run log, slowest p90 first. | | `kicad_verb_times` | `fusion_verb_times` | | `window_info` | Altium's top-level windows plus any open dialogs, without screenshots. The cheap way to ask 'is a modal blocking the engine?'. | `altium_window_info` | `kicad_window_info` | `fusion_check_dialogs` (partial) | | `zoom_to` | Frame the PCB view on a rectangle, a part (or several) or a whole net, with a margin. | `altium_zoom_to` | `kicad_zoom_to` | `fusion_zoom_to` |
package.json+1−1@@ -1,6 +1,6 @@ { "slug": "eda-bridge-standard",- "version": "0.25.1",+ "version": "0.26.0", "type": "skill", "title": "EDA Bridge Standard: one way for an AI to drive every PCB tool", "description": "The standard every Adom EDA bridge follows so one AI can drive Altium, KiCad, Fusion 360 and any future PCB tool the same way: shared verb names in tiers, the board model JSON, reply and refusal conventions, and a coverage table of each bridge against the Altium reference.",
verbs/coverage.json+71−2@@ -1,10 +1,10 @@ {- "standard": "0.25.1",+ "standard": "0.26.0", "reference": { "bridge": "altium", "version": "0.2.84" },- "proposed": 56,+ "proposed": 62, "compared": { "kicad": "1.0.89", "fusion360": "1.13.26"@@ -364,6 +364,14 @@ "note": "value, designator, fields and lock; dnp, excludeFromBom, excludeFromPos and mount refused (Fusion keeps them in assembly variants)" } },+ {+ "name": "edit_placed_footprint",+ "tier": "core",+ "source": "proposed",+ "altium": null,+ "kicad": null,+ "fusion360": null+ }, { "name": "find_symbol", "tier": "core",@@ -1656,6 +1664,17 @@ "match": "exact" } },+ {+ "name": "align_footprints",+ "tier": "native",+ "source": "proposed",+ "altium": null,+ "kicad": {+ "verb": "kicad_align_footprints",+ "match": "exact"+ },+ "fusion360": null+ }, { "name": "annotate", "tier": "native",@@ -1985,6 +2004,17 @@ "note": "sheets and the board composite; Fusion has no assembly-drawing or fabrication-print output" } },+ {+ "name": "export_pos",+ "tier": "native",+ "source": "proposed",+ "altium": null,+ "kicad": {+ "verb": "kicad_export_pos",+ "match": "exact"+ },+ "fusion360": null+ }, { "name": "export_step", "tier": "native",@@ -2178,6 +2208,17 @@ "match": "exact" } },+ {+ "name": "render_board",+ "tier": "native",+ "source": "proposed",+ "altium": null,+ "kicad": {+ "verb": "kicad_render_board",+ "match": "exact"+ },+ "fusion360": null+ }, { "name": "render_board_3d", "tier": "native",@@ -3707,6 +3748,20 @@ "note": "Altium's docked panel tabs; Fusion's editors show their own panels, and the bridge opens a surface (library, symbol, footprint, board, schematic, 3D) with fusion_show_* in the background" } },+ {+ "name": "prewarm",+ "tier": "app",+ "source": "proposed",+ "altium": null,+ "kicad": {+ "verb": "kicad_prewarm",+ "match": "exact"+ },+ "fusion360": {+ "verb": "fusion_prewarm",+ "match": "exact"+ }+ }, { "name": "progress", "tier": "app",@@ -4136,6 +4191,20 @@ "match": "exact" } },+ {+ "name": "verb_times",+ "tier": "app",+ "source": "proposed",+ "altium": null,+ "kicad": {+ "verb": "kicad_verb_times",+ "match": "exact"+ },+ "fusion360": {+ "verb": "fusion_verb_times",+ "match": "exact"+ }+ }, { "name": "window_info", "tier": "app",
verbs/standard.json+247−2@@ -1,10 +1,10 @@ {- "standard": "0.25.1",+ "standard": "0.26.0", "reference": { "bridge": "altium", "version": "0.2.84" },- "proposed": 56,+ "proposed": 62, "compared": { "kicad": "1.0.89", "fusion360": "1.13.26"@@ -805,6 +805,57 @@ "altium-lane" ] },+ {+ "name": "edit_placed_footprint",+ "tier": "core",+ "source": "proposed",+ "summary": "Edit parts placed on a board: value, reference, any field (add, change, remove), DNP, exclude from BOM or position files, the mounting type, and the lock. (edit_footprint edits a library footprint; this edits the board's copies.)",+ "input": {+ "filePath": "the board (required)",+ "refs": "[ref] or ref (required)",+ "value": "string",+ "newReference": "string",+ "fields": "{name: value | null to remove}",+ "dnp": "bool",+ "excludeFromBom": "bool",+ "excludeFromPosFiles": "bool",+ "attributes": "{type: smd | through_hole | unspecified, ...}",+ "locked": "bool",+ "expectedRevision": "string",+ "dryRun": "bool"+ },+ "output": {+ "edited": "[{ref, before, after}]",+ "revision": "string",+ "mutated": "bool"+ },+ "hint": "One undo step live, or one write. The schematic is not changed: the next update from the schematic overwrites value and fields that differ there.",+ "pitfalls": [+ "A mandatory field (Reference, Value, Footprint) cannot be removed."+ ],+ "related": [+ "edit_footprint",+ "sheet_params",+ "part_parameters"+ ],+ "example": {+ "filePath": "C:/proj/board.kicad_pcb",+ "refs": [+ "R7"+ ],+ "dnp": true,+ "fields": {+ "LCSC": "C25804"+ }+ },+ "longRunning": false,+ "timeoutSeconds": null,+ "proposedBy": "kicad-lane",+ "since": "0.25.1",+ "agreedBy": [+ "standard-lane"+ ]+ }, { "name": "find_symbol", "tier": "core",@@ -3672,6 +3723,55 @@ "longRunning": false, "timeoutSeconds": 60 },+ {+ "name": "align_footprints",+ "tier": "native",+ "source": "proposed",+ "summary": "Align placed parts on a common left, right, top, bottom or centre line, or distribute them evenly, by courtyard box or anchor, through the bridge's checked move (revision, courtyard collisions, board outline, one undo step).",+ "input": {+ "filePath": "the board (required)",+ "refs": "[ref], at least two (required)",+ "mode": "left | right | top | bottom | centerX | centerY | distributeX | distributeY (required)",+ "by": "courtyard | anchor, default courtyard",+ "to": "mm: the line to align on; default the group's own edge or centre",+ "gap": "mm between neighbours (distribute)",+ "expectedRevision": "string",+ "dryRun": "bool",+ "allowOverlap": "bool, default false",+ "allowOutside": "bool, default false"+ },+ "output": {+ "moves": "[{ref, from, to}]",+ "revision": "string",+ "mutated": "bool"+ },+ "hint": "Without to, left and top take the group's minimum edge, right and bottom its maximum, centerX and centerY the mean centre; distribute keeps the outer two in place unless gap is given.",+ "pitfalls": [+ "A move that would collide or leave the outline is refused unless allowOverlap or allowOutside."+ ],+ "related": [+ "move_footprint",+ "placement_check",+ "find_space"+ ],+ "example": {+ "filePath": "C:/proj/board.kicad_pcb",+ "refs": [+ "C1",+ "C2",+ "C3"+ ],+ "mode": "distributeX",+ "gap": 1.0+ },+ "longRunning": false,+ "timeoutSeconds": null,+ "proposedBy": "kicad-lane",+ "since": "0.25.1",+ "agreedBy": [+ "standard-lane"+ ]+ }, { "name": "annotate", "tier": "native",@@ -4426,6 +4526,46 @@ "longRunning": false, "timeoutSeconds": 600 },+ {+ "name": "export_pos",+ "tier": "native",+ "source": "proposed",+ "summary": "Export the pick-and-place (component position, CPL) file of a board, optionally in a fab's assembly format (JLCPCB's columns).",+ "input": {+ "filePath": "the board (required)",+ "side": "both | front | back, default both",+ "format": "csv | ascii | gerber, default csv",+ "units": "mm | in, default mm",+ "smdOnly": "bool",+ "excludeDnp": "bool, default true",+ "fab": "jlcpcb: also write the fab's own CPL columns",+ "outputDir": "folder"+ },+ "output": {+ "files": "[path]",+ "parts": "int per side"+ },+ "hint": "Pair it with a BOM and Gerbers for an assembly order; export_manufacturing writes all three in one call.",+ "pitfalls": [+ "Rotations follow the tool's convention; a fab may need its own offsets per package."+ ],+ "related": [+ "export_manufacturing",+ "bom",+ "assembly_check"+ ],+ "example": {+ "filePath": "C:/proj/board.kicad_pcb",+ "fab": "jlcpcb"+ },+ "longRunning": false,+ "timeoutSeconds": null,+ "proposedBy": "kicad-lane",+ "since": "0.25.1",+ "agreedBy": [+ "standard-lane"+ ]+ }, { "name": "export_step", "tier": "native",@@ -4836,6 +4976,55 @@ "longRunning": false, "timeoutSeconds": 300 },+ {+ "name": "render_board",+ "tier": "native",+ "source": "proposed",+ "summary": "A rendered 3D picture (PNG or JPG) of a board from one side, made by the tool's own renderer with no window: optionally framed on parts, turned for an isometric view, raytraced.",+ "input": {+ "filePath": "the board (required)",+ "side": "top | bottom | left | right | front | back, default top",+ "width": "px, default 1600",+ "height": "px, default 900",+ "quality": "basic | high (raytraced)",+ "background": "default | transparent | opaque",+ "zoom": "float",+ "perspective": "bool",+ "format": "png | jpg",+ "refs": "[ref]: frame these parts (camera on their pads' centre, zoomed to them)",+ "marginMm": "mm round framed parts, default 2",+ "rotate": "'x,y,z' degrees, e.g. '-45,0,45' for isometric",+ "outputDir": "folder for the image"+ },+ "output": {+ "path": "the image",+ "framed": "{refs, pivot, zoom} when refs was given"+ },+ "hint": "One call per side (top and bottom for a review). refs frames parts for a close look; quality high raytraces and takes longer.",+ "pitfalls": [+ "The picture is of the saved board file: unsaved edits are not in it."+ ],+ "related": [+ "zoom_to",+ "library_views",+ "render_schematic"+ ],+ "example": {+ "filePath": "C:/proj/board.kicad_pcb",+ "side": "top",+ "refs": [+ "J1"+ ],+ "rotate": "-45,0,45"+ },+ "longRunning": false,+ "timeoutSeconds": null,+ "proposedBy": "kicad-lane",+ "since": "0.25.1",+ "agreedBy": [+ "standard-lane"+ ]+ }, { "name": "render_board_3d", "tier": "native",@@ -8123,6 +8312,32 @@ "longRunning": false, "timeoutSeconds": 30 },+ {+ "name": "prewarm",+ "tier": "app",+ "source": "proposed",+ "summary": "Get this machine ready for a fast first call: detect the tool, seed its first-run settings, dismiss first-run wizards and repair what the first real call would otherwise do slowly. Idempotent.",+ "input": {},+ "output": {+ "steps": "[{step, done, skipped?, why?}]",+ "ready": "bool"+ },+ "hint": "The bridge host may run it once after an install or update; running it again changes nothing. Everything it does is what the first real verb would otherwise do in the user's face.",+ "pitfalls": [+ "It never opens a document or takes the foreground."+ ],+ "related": [+ "verb_times"+ ],+ "example": {},+ "longRunning": false,+ "timeoutSeconds": null,+ "proposedBy": "kicad-lane",+ "since": "0.25.1",+ "agreedBy": [+ "standard-lane"+ ]+ }, { "name": "progress", "tier": "app",@@ -8947,6 +9162,36 @@ "longRunning": false, "timeoutSeconds": 30 },+ {+ "name": "verb_times",+ "tier": "app",+ "source": "proposed",+ "summary": "Measured run times of this bridge's verbs on this machine: per verb the count, p50, p90, max, last and failures, from its own run log, slowest p90 first.",+ "input": {+ "limit": "int, default 40: how many verbs"+ },+ "output": {+ "verbs": "[{verb, count, p50Sec, p90Sec, maxSec, lastSec, failures}]",+ "since": "when the log starts"+ },+ "hint": "p90 is the headline: a p50 of 15 s next to a p90 of 400 s is two code paths under one name. failures counts runs that returned success:false; a verb that fails fast is a different bug from a slow one.",+ "pitfalls": [+ "Times are this machine's: a slower box or a bigger board moves them."+ ],+ "related": [+ "prewarm"+ ],+ "example": {+ "limit": 20+ },+ "longRunning": false,+ "timeoutSeconds": null,+ "proposedBy": "kicad-lane",+ "since": "0.25.1",+ "agreedBy": [+ "standard-lane"+ ]+ }, { "name": "window_info", "tier": "app",