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.
main
Colby Knox
altium-lane: reference/altium-0.2.87.json (schematic_review reads the drawing)
d6fa39f
11d ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186
{
"bridge": "altium",
"version": "0.2.87",
"verbs": [
{
"example": {},
"hint": "Cheapest health call - answers from ab's window list plus the agent heartbeat; never touches the script engine.",
"input": {},
"longRunning": false,
"name": "altium_status",
"output": {
"agentAlive": "bool",
"licenceState": "string",
"licensed": "bool",
"running": "bool"
},
"pitfalls": [
"'running' can be true while 'licensed' is false - a trial lease can be stranded by a crash."
],
"related": [
"altium_readiness",
"altium_agent_status",
"altium_instances"
],
"statusVerb": null,
"summary": "Is Altium running, licensed, and is the resident agent alive?",
"timeoutSeconds": 15
},
{
"example": {},
"hint": "With several running, other verbs REFUSE without instance:<pid|key|word> - guessing means acting inside another AI thread's Altium.",
"input": {},
"longRunning": false,
"name": "altium_instances",
"output": {
"count": "int",
"instances": "[{pid, key, edition, licensed, agentAlive, ...}]"
},
"pitfalls": [
"Develop writes NO licence tail when it HOLDS the seat - blank licenceState there means licensed."
],
"related": [
"altium_status"
],
"statusVerb": null,
"summary": "Every running Altium (Designer + Designer Develop can run together).",
"timeoutSeconds": 15
},
{
"example": {
"text": "Begin PCBServer.GetCurrentPCBBoard.ViewManager_FullUpdate; End;"
},
"hint": "Single quotes only (no double quotes). A Var block before Begin is allowed. Capture output by writing a file, not by returning a value. Pass filePath: after an export the OutJob is current and GetCurrentPCBBoard is Nil.",
"input": {
"filePath": "optional: the document to make current first (a .PcbDoc for PCBServer.GetCurrentPCBBoard)",
"text": "string - [Var X : Integer;] Begin ... End;",
"timeout": "int seconds"
},
"longRunning": false,
"name": "altium_eval",
"output": {
"errorCode": "script_error",
"errorShot": "PNG of Altium's error box",
"success": "bool (false + errorShot when Altium raised an error box)"
},
"pitfalls": [
"An undeclared identifier HALTS the engine with a modal that Try/Except cannot catch.",
"ShowMessage blocks the loop behind a modal - never use it."
],
"related": [
"altium_run_command"
],
"statusVerb": null,
"summary": "Run a DelphiScript snippet inside Altium (optional Var block, then Begin ... End;) on the CURRENT document, or on filePath opened first.",
"timeoutSeconds": 30
},
{
"example": {
"command": "PCB:Zoom",
"params": {
"Action": "All"
}
},
"hint": "Params are pipe-joined key=value pairs. altium_list_commands searches the catalog.",
"input": {
"command": "string - e.g. PCB:Zoom",
"filePath": "optional: the document to make current first (PCB: processes need a board current)",
"params": "string or object"
},
"longRunning": false,
"name": "altium_run_command",
"output": {
"success": "bool"
},
"pitfalls": [
"Some processes open a modal dialog and block the loop until it is answered."
],
"related": [
"altium_eval",
"altium_list_commands"
],
"statusVerb": null,
"summary": "Run an Altium process (Server:Command) through the agent, on the CURRENT document or on filePath opened first.",
"timeoutSeconds": 60
},
{
"example": {},
"hint": "Check before and after altium_install_library / altium_uninstall_library without a screenshot.",
"input": {},
"longRunning": false,
"name": "altium_list_installed_libraries",
"output": {
"count": "int",
"libraries": "[path]"
},
"pitfalls": [
"Needs the agent (it reads IntegratedLibraryManager inside Altium)."
],
"related": [
"altium_uninstall_library",
"altium_install_library",
"altium_install_library_bundle"
],
"statusVerb": null,
"summary": "Every library in Altium's Installed Libraries list (read-only).",
"timeoutSeconds": 30
},
{
"example": {
"libraryName": "Adom_ToF"
},
"hint": "Any open document for a removed library is closed first. Close Altium with a plain altium_close afterwards: a close that discards changes can drop the unregistration.",
"input": {
"dryRun": "bool",
"libraryName": "file stem: matches X.SchLib AND X.PcbLib",
"libraryPath": "exact registered path"
},
"longRunning": false,
"name": "altium_uninstall_library",
"output": {
"closedDocuments": "[path]",
"notInstalled": "bool",
"remaining": "int",
"removed": "[path]"
},
"pitfalls": [
"Nothing matching answers notInstalled:true (success), so a cleanup can run twice.",
"discardChanges:true on altium_close can bring the removed library back on the next launch."
],
"related": [
"altium_list_installed_libraries",
"altium_install_library",
"altium_close"
],
"statusVerb": null,
"summary": "Remove libraries from Altium's Installed Libraries: the inverse of install_library / install_library_bundle. Library files are never touched.",
"timeoutSeconds": 60
},
{
"example": {
"name": "SCH Library"
},
"hint": "One UIA search reads the tab's existence AND selection, then at most one SelectionItemPattern select and one verify, all inside a 24 s budget: every exit is a named answer (panel_not_found, panel_search_timeout, ui_select_gated, panel_not_selected), never ab's generic timeout.",
"input": {
"ensureId": "string optional - panel ID for Client:CustomizeResources (e.g. TSchLibPanel) when the panel may not exist yet",
"name": "string - the tab caption exactly as painted, e.g. 'SCH Library'"
},
"longRunning": false,
"name": "altium_panel",
"output": {
"elapsedSec": "float",
"lane": "already | ui_select | ui_select_raised",
"selected": "bool",
"verified": "bool (false when the tab exposes no selection state)"
},
"pitfalls": [
"ab gates desktop_ui_select behind the shell approval grant; without it the verb reports ui_select_gated instead of pretending.",
"A plain click does not switch panel tabs - that is why this verb exists.",
"On Altium Designer Develop the UI Automation search does not finish in time (panel_search_timeout, measured 2026-10-15); opening a library document already brings its library panel to the front.",
"lane ui_select_raised means ab fell back to a synthetic click that foregrounded Altium; the dispatch wrapper hands the user's window back."
],
"related": [
"altium_show_symbol",
"altium_show_footprint",
"altium_run_command"
],
"statusVerb": null,
"summary": "Activate a docked panel TAB (SCH Library, PCB Library, Components, Projects, Properties) in the BACKGROUND - the 'ganged-up view' needs the right panels in front, and no Altium server process switches a tab.",
"timeoutSeconds": 30
},
{
"example": {},
"hint": "The primitive every board view derives from; board_summary / rules_by_kind / layers_in_use are shaped from the same read.",
"input": {
"limit": "int",
"sections": "string csv - optional"
},
"longRunning": false,
"name": "altium_read_board",
"output": {
"data": "object - the agent's payload",
"roundtripMs": "int",
"success": "bool"
},
"pitfalls": [
"Needs a .PcbDoc current."
],
"related": [
"altium_board_summary",
"altium_review_board"
],
"statusVerb": null,
"summary": "ONE round trip: components, nets, layers, copper, rules, occupancy, outline.",
"timeoutSeconds": 120
},
{
"example": {
"includeSchematic": true
},
"hint": "PARTIAL results by design: skipped says which checks had no data; a clean result means the checks that RAN found nothing.",
"input": {
"board": "path - optional",
"checks": "[string] - optional filter",
"includeSchematic": "bool",
"sheet": "path - optional"
},
"longRunning": false,
"name": "altium_review_board",
"output": {
"counts": "{}",
"findings": "[{check, severity, message, ...}]",
"notImplemented": "{}",
"skipped": "{}"
},
"pitfalls": [
"Altium holds ONE current document - the review activates board and sheet in turn."
],
"related": [
"altium_read_board",
"altium_cross_check"
],
"statusVerb": null,
"summary": "Design-review checks (14) over one board read; schematic checks with includeSchematic.",
"timeoutSeconds": 120
},
{
"example": {},
"hint": "Check the step counts: models:0 fails the call - a symbol with no footprint model places with nothing attached. Importing again REPLACES the symbol and the footprint's 3D body (add_body step: bodiesNow 1); boards that place the part need PCB:UpdateFootprints.",
"input": {
"comment": "string",
"description": "string",
"footprintSpec": "path",
"params": "{}",
"pcbLib": "path",
"schLib": "path",
"step": "path",
"symbolSpec": "path"
},
"longRunning": false,
"name": "altium_import_part",
"output": {
"footprint": "string",
"steps": "[] - the add_body step carries replacedBodies, bodiesNow, sameNameFootprints",
"symbol": "string"
},
"pitfalls": [
"add_models APPENDS on every call (not idempotent) - repair is remove_symbol + re-import.",
"The add_body step's sameNameFootprints > 1 means the library holds stale footprints of that name: the body went to the FIRST only.",
"The first part into a NEW library can silently skip models+params if the bridge restarted mid-flight - verify with read_symbol."
],
"related": [
"altium_read_symbol",
"altium_show_symbol"
],
"statusVerb": null,
"summary": "One call imports a whole part: footprint spec + STEP + symbol modes + models + params + save.",
"timeoutSeconds": 300
},
{
"example": {
"footprintName": "VL53L5CX;VL53L7CX;VL53L8CX",
"hMm": 14,
"libraryPath": "C:/lib/Adom_ToF.PcbLib",
"pcbPath": "C:/proj/tof.PcbDoc",
"wMm": 39
},
"hint": "Three parts on one board: footprintName 'VL53L5CX;VL53L7CX;VL53L8CX' + pcbPath, then altium_show_3d_board {filePath: pcbPath}. Run it again with the same pcbPath to ADD parts: they land right of the current ones, designators continue (U4...).",
"input": {
"assigns": "des=NET;...",
"footprintName": "string | 'A;B;C'",
"hMm": "number (new board only)",
"libraryPath": "path (.PcbLib)",
"pcbPath": "path (.PcbDoc) - existing = append, new = create+save",
"stubs": "des=x,y;...",
"wMm": "number (new board only)"
},
"longRunning": false,
"name": "altium_test_board",
"output": {
"appended": "bool",
"bodiesOnComp": "int",
"count": "int",
"existingParts": "int",
"padsOnComp": "int",
"pcb": "path",
"placed": "string",
"saved": "bool (checked on disk)"
},
"pitfalls": [
"assigns/stubs apply to the LAST part placed.",
"pcb is empty when pcbPath is omitted: the board exists only unsaved as PCB<n>.PcbDoc.",
"Appending ignores wMm/hMm and does not grow the outline: parts can land outside it - resize with altium_board_shape if needed.",
"Each part's name is its own Comment (moves with the part) and its Pattern is the footprint name.",
"errorCode not_saved: the board was built but the file did not land; the folder is created automatically."
],
"related": [
"altium_place_on_sch",
"altium_show_3d_board",
"altium_add_body"
],
"statusVerb": null,
"summary": "Place one footprint, or a ';' list, from the open PcbLib on ONE board: a NEW board (wMm x hMm outline) when pcbPath is new or omitted, APPENDED to the existing board when pcbPath already exists (issue 11).",
"timeoutSeconds": 240
},
{
"example": {
"libraryPath": "C:/lib/Adom_ToF.PcbLib"
},
"hint": "altium_save the PcbLib afterwards; footprint_primitives on a placed part should then report layerId 74 for the vias.",
"input": {
"footprintName": "string (optional filter)",
"libraryPath": "path (.PcbLib)"
},
"longRunning": false,
"name": "altium_plate_vias",
"output": {
"fixed": "Fp:Pad;...",
"holes": "int",
"plated": "int"
},
"pitfalls": [
"Read-modify in place: run once per library install."
],
"related": [
"altium_normalize_bodies",
"altium_footprint_primitives",
"altium_save"
],
"statusVerb": null,
"summary": "Make every drilled pad in a PcbLib a plated MULTI-LAYER pad (all footprints, or footprintName). adom-lbr writes heatsink vias as pads with a hole; Altium loaded them on the Top Layer, so a thermal pad's vias were not through-holes until this ran.",
"timeoutSeconds": 90
},
{
"example": {
"humanIsPresent": true,
"stage": "launch"
},
"hint": "Call it with no args and follow _next. The human's part ENDS at the installer's Finish button; licensing is yours.",
"input": {
"humanIsPresent": "bool, REQUIRED true for stage launch: the UAC prompt auto-denies in ~2 minutes",
"installerPath": "optional path; default = newest AltiumDesignerSetup*.exe in Downloads",
"stage": "auto (default) | preflight | get_installer | launch | wait | license"
},
"longRunning": false,
"name": "altium_install",
"output": {
"_next": "[string]",
"licensed": "bool",
"needsHuman": "[string] - only ever a password, the UAC prompt, or clicks in an elevated window",
"stage": "string",
"toast": "{displayed, _hint}"
},
"pitfalls": [
"needsHuman may only name a password/2FA, the UAC prompt, or clicks inside an ELEVATED window. Release, Assign, Use License, Refresh and save prompts are ordinary clicks: do them.",
"LOOK before you ask: 'Sign Out' on the licence page means the user is ALREADY signed in (the installer's browser sign-in carries over).",
"'There are no seats available' means another running Altium holds the account's single On-Demand seat: altium_close it there, then stage license again.",
"Never use the installer's unattended switches: they take the account password on the command line.",
"A toast only reaches the machine it is shown on. Check toast.displayed and ALSO tell the user in chat."
],
"related": [
"altium_ensure_licensed",
"altium_license",
"altium_launch",
"altium_readiness"
],
"statusVerb": null,
"summary": "Install Altium Designer on this machine, STAGED, with the rules in the verb (from 0.2.29). stage: preflight | get_installer | launch | wait | license, or omit it and 'auto' picks the stage from the machine's state. The verb looks before it asks, verifies the installer's Authenticode signature (Valid, CN=Altium LLC) before anything runs, refuses to launch into an empty room, toasts the human itself and says truthfully whether the toast displayed, and does the licensing clicks (Refresh / Use License) ITSELF.",
"timeoutSeconds": 120
},
{
"example": {},
"hint": "netWorks:true is the pass. The agent is stopped afterwards by design; the next verb restarts it.",
"input": {},
"longRunning": false,
"name": "altium_selftest_script_error",
"output": {
"autoRecovered": "bool",
"dialogsLeft": "int",
"errorShot": "base64 png (halted outcome only)",
"netWorks": "bool",
"outcome": "halted_and_recovered | contained_by_agent | unhandled"
},
"pitfalls": [
"It really does halt the engine for a moment: do not run it while a user is mid-edit in Altium.",
"By design this is the SLOWEST verb in the catalog: it halts the engine, waits for the halt to be seen, recovers it and verifies by restarting the agent. Altium Designer Develop parks SILENTLY (no Error box), so the halt is only seen when the wait expires \u2014 measured 18 s to over 60 s on the same machine. Its budget is 180 s for that reason; a timeout here means the safety net is broken, not that it was slow."
],
"related": [
"altium_agent_recover",
"altium_dialog_log",
"altium_agent_status"
],
"statusVerb": null,
"summary": "Regression test for the script-error safety net (from 0.2.23): makes the agent raise a REAL DelphiScript runtime error on purpose and checks that the bridge photographs Altium's Error box, stops the halted script itself and leaves no dialog behind. Flashes one error box for under a second. Run it after any change to agent.rs / dialogs.rs and once on every new Altium build.",
"timeoutSeconds": 180
},
{
"example": {},
"hint": "polylines should equal what add_symbol_art reported and polyBboxMil should sit inside bodyRectMil.",
"input": {
"libraryPath": "path (.SchLib)",
"models": "bool, default false (the model walk halts the engine on some builds)",
"symbolName": "string"
},
"longRunning": false,
"name": "altium_symbol_prims",
"output": {
"bodyRectMil": "[l, b, r, t] - the union of the current display mode's rectangles (mode 0, as a sheet draws it)",
"lines": "int",
"models": "[\"PCBLIB:NAME\"]",
"pins": "int",
"polyBboxMil": "[..]",
"polylines": "int",
"rectangles": "int"
},
"pitfalls": [],
"related": [
"altium_add_symbol_art",
"altium_set_models",
"altium_read_symbol"
],
"statusVerb": null,
"summary": "Read a SchLib component's drawing: primitive counts by kind, body rectangle, polyline bounding box, display mode and the footprint models. Read-only, use it to verify add_symbol_art / set_models.",
"timeoutSeconds": 60
},
{
"example": {},
"hint": "altium_save the SchLib afterwards.",
"input": {
"footprint": "string (PcbLib footprint name)",
"libraryPath": "path (.SchLib)",
"symbolName": "string"
},
"longRunning": false,
"name": "altium_set_models",
"output": {
"footprint": "string",
"removed": "int"
},
"pitfalls": [
"Removes every existing model, including 3D-only ones."
],
"related": [
"altium_symbol_prims",
"altium_set_params",
"altium_add_models"
],
"statusVerb": null,
"summary": "Replace every footprint model on a SchLib component with ONE PCBLIB model (set_params footprint and add_models APPEND, which is how a symbol ends up with two).",
"timeoutSeconds": 60
},
{
"example": {
"kicadSym": "C:/lib/VL53L5CX.kicad_sym",
"libraryPath": "C:/lib/Adom_ToF.SchLib",
"symbolName": "VL53L5CX"
},
"hint": "Run once per part right after assemble-altium / build_symbol_modes, then altium_save the SchLib and altium_show_symbol to check.",
"input": {
"clear": "bool, default true: remove the component's existing polylines/lines first",
"kicadSym": "Windows path to the .kicad_sym that carries the baked outline (stage it with send_files)",
"libraryPath": "path (.SchLib)",
"mode": "lines (default) | polyline",
"symbolName": "string (LibReference)"
},
"longRunning": false,
"name": "altium_add_symbol_art",
"output": {
"bodyRectMil": "[x0,y0,x1,y1]",
"points": "int",
"polylines": "int"
},
"pitfalls": [
"clear:true (default) also removes hand-drawn lines on the symbol; only the pins and the body rectangle survive.",
"The KiCad symbol must already carry the outline (adom-symbol create bakes it; --outline-name none for side-etched chips)."
],
"related": [
"altium_show_symbol",
"altium_symbol_prims",
"altium_save"
],
"statusVerb": null,
"summary": "Draw the chip-outline artwork (the chip-thumbnailer polylines adom-symbol baked into the KiCad symbol) into a SchLib component, fitted to its body rectangle, so the Altium symbol shows the same chip as KiCad and Fusion.",
"timeoutSeconds": 180
},
{
"example": {
"libraryPath": "C:/lib/Adom_ToF.SchLib",
"schPath": "C:/proj/tof.SchDoc",
"symbolName": "VL53L5CX;VL53L7CX;VL53L8CX"
},
"hint": "Three parts on one sheet: symbolName 'VL53L5CX;VL53L7CX;VL53L8CX' + schPath, then altium_show_schematic {filePath: schPath}.",
"input": {
"description": "string (what the sheet shows, 2-3 sentences)",
"drawnBy": "string",
"libraryPath": "path (.SchLib)",
"number": "string (DocumentNumber)",
"revision": "string",
"schPath": "path (.SchDoc, optional save)",
"symbolName": "string | 'A;B;C'",
"title": "string (Title)"
},
"longRunning": false,
"name": "altium_place_on_sch",
"output": {
"count": "int",
"designator": "string",
"placed": "string",
"primitives": "int",
"sch": "path"
},
"pitfalls": [
"Every call creates a NEW SchDoc; there is no append-to-sheet yet.",
"The SchLib must be the current document (the verb opens it)."
],
"related": [
"altium_test_board",
"altium_show_schematic",
"altium_read_schematic"
],
"statusVerb": null,
"summary": "Place one symbol, or a ';' list of symbols, from the open SchLib on ONE new sheet (sheet sized FROM the measured parts: 500 mil gaps, 600 mil margins, A4 minimum; parts inside the frame as U1..Un with the part number as Comment); fills the title block from title/number/revision/drawnBy and places description as a text frame; saves to schPath when given. When schPath names an EXISTING .SchDoc the symbols are APPENDED to it (right of the current ones, designators continuing; sheet size and title block untouched, issue 11).",
"timeoutSeconds": 90
},
{
"example": {},
"hint": "Never foregrounds: a minimized Altium is restored INTO THE BACKGROUND and the user's window handed straight back.",
"input": {
"libraryPath": "path",
"symbolName": "string"
},
"longRunning": false,
"name": "altium_show_symbol",
"output": {
"shot": "{image: base64 png, width, height}",
"success": "bool",
"windowEtiquette": "background"
},
"pitfalls": [
"A capture under 400px wide is refused as proof_unavailable - a title-bar sliver is not evidence."
],
"related": [
"altium_show_footprint",
"altium_show_3d_chip",
"altium_show_library"
],
"statusVerb": null,
"summary": "Open a SchLib member in the Symbol editor and capture a background proof.",
"timeoutSeconds": 60
},
{
"example": {
"preset": "showcase3d"
},
"hint": "Runs IN-BRIDGE (~40ms per step to the agent) so timing is tight enough to narrate over. Steps: zoom_all/in/out, view_2d/3d, isometric, top/bottom/front/back/left/right, rotate90, ortho, orbit_left/right/up/down, rolls, pans, flip.",
"input": {
"lane": "pcb (default) | sch",
"pauseMs": "int default per-step pause",
"preset": "punch_in|showcase3d|orbit|flip|finale",
"steps": "[string | {step, pauseMs}]"
},
"longRunning": false,
"name": "altium_animate_view",
"output": {
"elapsedSec": "float",
"stepsRun": "int"
},
"pitfalls": [
"Driving camera steps one-by-one from a container adds ~1.4s of jitter per step - that is what this verb exists to avoid.",
"sch lane supports zoom steps only; everything else needs a PCB document current."
],
"related": [
"altium_demo",
"altium_foreground",
"altium_run_command"
],
"statusVerb": null,
"summary": "Camera/zoom choreography on the current document - native Altium camera commands, animated by Altium itself.",
"timeoutSeconds": 120
},
{
"example": {
"reason": "John asked to watch the import live"
},
"hint": "For a human who asked to WATCH (a live demo, a walkthrough). Everything else stays background.",
"input": {
"reason": "string >=10 chars, written for the HUMAN (required)"
},
"longRunning": false,
"name": "altium_foreground",
"output": {
"windowEtiquette": "foreground"
},
"pitfalls": [
"Refused without a real reason - same rule as ab's desktop_caption."
],
"related": [
"altium_demo",
"altium_animate_view"
],
"statusVerb": null,
"summary": "Bring Altium in front of the user - the sanctioned exception to the never-foreground rule.",
"timeoutSeconds": 15
},
{
"example": {
"live": true,
"stage": 0
},
"hint": "live SYNC MODEL: pre-cache narration with `adom-tts load` (one marker per stop), then per stop fire `adom-tts cue <id> <n> --confirm` in the background and IMMEDIATELY make nextCall - the prefetched cue starts instantly and the ~5-17s of on-screen motion runs under the voice; advance when BOTH finish. If Altium is cold, the first call answers status:launching with a narrate line - speak it, poll again in ~20s.",
"input": {
"live": "bool",
"stage": "int 0-5"
},
"longRunning": false,
"name": "altium_demo",
"output": {
"done": "bool",
"narrate": "string - speak this",
"nextCall": "{verb, args}",
"nextNarrate": "string"
},
"pitfalls": [
"The caller owns the VOICE (adom-tts) - the bridge never synthesizes speech.",
"After done:true, restore the user's own document (altium_activate_document)."
],
"related": [
"altium_animate_view",
"altium_foreground",
"altium_show_symbol"
],
"statusVerb": null,
"summary": "The tour. Default: one background beat per call with a screenshot. live:true = the narrated FOREGROUND show: ab caption + document + in-bridge camera choreography per stop, returning the narration text for YOUR TTS.",
"timeoutSeconds": 180
},
{
"example": {
"action": "use_license"
},
"hint": "One On-Demand seat serves EVERY Altium app on this machine. use_license claims a free seat.",
"input": {
"action": "show|refresh|use_license|start_trial|sign_out"
},
"longRunning": false,
"name": "altium_license",
"output": {
"shot": "{image: base64 png, width, height}",
"success": "bool",
"windowEtiquette": "background"
},
"pitfalls": [
"NEVER kill an Altium holding the seat: the lease strands, the page shows Seats 0/1 while every claim fails. altium_close releases it."
],
"related": [
"altium_ensure_licensed",
"altium_license_status",
"altium_close"
],
"statusVerb": null,
"summary": "Drive the License Management page (UIA first - no cursor, no foreground).",
"timeoutSeconds": 60
},
{
"example": {},
"hint": "A save prompt on close NAMES the documents - read it; on a shared machine one may belong to another AI thread. Never defaulted.",
"input": {
"acceptSeatLoss": "bool",
"discardChanges": "bool, default false: press Save None + confirm on 'Confirm Save Locally'",
"force": "bool",
"instance": "pid, when several Altiums run",
"waitSec": "float, default 20"
},
"longRunning": false,
"name": "altium_close",
"output": {
"closedInSec": "float",
"engineFreed": "object|null",
"errorCode": "unsaved_changes | close_blocked_by_dialog | altium_modal_orphan | modal_orphan_survived_quit | close_timeout",
"stuckModalOrphan": "{pid,tid,hwnd} when Altium was wedged in a modal loop and the bridge ended it gracefully"
},
"pitfalls": [
"force:true without acceptSeatLoss is refused: a kill strands the On-Demand seat.",
"errorCode altium_modal_orphan = Altium is stuck inside a modal loop whose dialog is GONE (its main window is disabled, nothing on screen to answer). No menu, keystroke or -R reaches it and it still holds the seat. With discardChanges:true the bridge ends it by posting WM_QUIT - Altium's own shutdown, which RELEASES the seat. Never reach for force/taskkill first."
],
"related": [
"altium_license",
"altium_launch"
],
"statusVerb": null,
"summary": "Polite close (releases the licence seat). Frees a script engine parked on a breakpoint first (Altium refuses to close over one). discardChanges:true answers Altium's save prompts with Save None for callers whose modified documents are ALL their own; force needs acceptSeatLoss.",
"timeoutSeconds": 120
},
{
"example": {
"capture": true,
"installId": "Lib-1757350000000",
"libraryName": "Lib",
"zipPath": "C:\\Users\\me\\adom-wiki-libs\\Lib-altium.zip"
},
"hint": "Launches a closed Altium first (up to 240s), then registers and opens the library. Past ab's budget the verb keeps running: poll altium_status until lastInstall.installId matches, then altium_install_receipt for the full receipt.",
"input": {
"capture": "bool",
"captureMaxWidth": "int",
"installId": "string - echoed in the receipt so a client can match it",
"libraryName": "string",
"zipPath": "string - staged zip"
},
"longRunning": true,
"name": "altium_install_library_bundle",
"output": {
"atMs": "int",
"components": "[names]",
"installId": "string",
"phasesMs": "{launch, licence, unpack, register, open, list, panel, capture, agentStop}",
"shot": "{image, ...}",
"shown": "bool",
"symbolCount": "int",
"thumbnailDataUrl": "string",
"totalMs": "int"
},
"pitfalls": [
"The receipt lives in bridge memory; a bridge restart clears it."
],
"related": [
"altium_install_receipt",
"altium_status",
"altium_install_library"
],
"statusVerb": "altium_status",
"summary": "One-click install of a wiki library bundle (zip of .SchLib/.PcbLib): unpack, register, open the library, prove it with a frame.",
"timeoutSeconds": 330
},
{
"example": {},
"hint": "Read after altium_status shows lastInstall with your installId.",
"input": {},
"longRunning": false,
"name": "altium_install_receipt",
"output": {
"receipt": "object|null - the install_library_bundle reply"
},
"pitfalls": [],
"related": [
"altium_install_library_bundle",
"altium_status"
],
"statusVerb": null,
"summary": "The last bundle install's full receipt (proof frame included), for a client whose install call outlived ab's budget.",
"timeoutSeconds": 10
},
{
"example": {},
"hint": "Static; safe to call any time.",
"input": {},
"longRunning": false,
"name": "altium_describe",
"output": {
"verbs": "[{name, summary, input, output, ...}]"
},
"pitfalls": [],
"related": [
"altium_status"
],
"statusVerb": null,
"summary": "This list - the bridge's verbs and schemas for ab's Verbs tab.",
"timeoutSeconds": 5
},
{
"example": {},
"hint": "Follow _hint: not installed -> altium_install; not running -> altium_launch; licensed:false -> altium_ensure_licensed; agent down -> just call the verb you need (it bootstraps the agent) or altium_agent_start. ready:true -> altium_state.",
"input": {},
"longRunning": false,
"name": "altium_readiness",
"output": {
"adVersion": "string | null",
"agentAlive": "bool - the selected instance",
"agentLiveWorkspaces": "[{workspace, heartbeatAgeSec}] - only when a loop lives outside the selection",
"agentResidentAnywhere": "bool - any workspace",
"install": "{base_dir, exe, system_dir, major} | null",
"installed": "bool",
"licenceState": "string",
"licensed": "bool | null",
"ready": "bool - all four true",
"running": "bool"
},
"pitfalls": [
"agentAlive is the SELECTED instance's view. agentResidentAnywhere:true beside agentAlive:false means a loop lives in another workspace: close through altium_close, never the window X."
],
"related": [
"altium_status",
"altium_launch",
"altium_ensure_licensed",
"altium_agent_start"
],
"statusVerb": null,
"summary": "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.",
"timeoutSeconds": 15
},
{
"example": {},
"hint": "installs:[] means Altium is not installed (altium_install). Otherwise altium_readiness for the verdict and altium_instances when several Altiums run.",
"input": {},
"longRunning": false,
"name": "altium_diagnostics",
"output": {
"agent": "the altium_agent_status reply",
"cacheDir": "path",
"env": "{LOCALAPPDATA, APPDATA, USERPROFILE, ProgramFiles, ADOM_BIND_HOST, ADOM_DIRECT_API_URL}",
"installs": "[{base_dir, exe, system_dir, major}] newest major first",
"windows": "[{hwnd, title, kind, className, pid, rect}]"
},
"pitfalls": [
"Instance-exempt: it runs with no instance selected, so agent.alive reads the legacy workspace; agent.liveWorkspaces is the union that counts."
],
"related": [
"altium_readiness",
"altium_agent_status",
"altium_instances"
],
"statusVerb": null,
"summary": "Bridge-side facts for a bug report: environment variables, every Altium install found, Altium's windows, the agent status block and the cache directory.",
"timeoutSeconds": 15
},
{
"example": {},
"hint": "hasModalDialogs:true means the agent loop and every -R request are frozen behind it: altium_check_dialogs for the pictures, then altium_dismiss_dialogs {button, titles}. Otherwise the main window's title names the current document.",
"input": {},
"longRunning": false,
"name": "altium_window_info",
"output": {
"dialogs": "[{hwnd, title, body, buttons, category, safeAction, ownedByMainInstance}]",
"hasModalDialogs": "bool - a dialog owned by the main instance",
"windows": "[{hwnd, title, kind, className, pid, rect}]"
},
"pitfalls": [
"Altium PAINTS its dialog text, so body is often empty here; altium_check_dialogs attaches a PNG per dialog."
],
"related": [
"altium_check_dialogs",
"altium_dismiss_dialogs",
"altium_state"
],
"statusVerb": null,
"summary": "Altium's top-level windows plus any open dialogs, without screenshots. The cheap way to ask 'is a modal blocking the engine?'.",
"timeoutSeconds": 15
},
{
"example": {
"screenshots": false
},
"hint": "Look before acting: logical.data.focusedDocument is what the board/schematic read verbs would read; altium_activate_document {path} changes it. Poll with screenshots:false.",
"input": {
"screenshots": "bool, default true"
},
"longRunning": false,
"name": "altium_state",
"output": {
"agentAlive": "bool - union over every workspace",
"agentWorkspace": "path | null - where logical came from",
"dialogs": "[..]",
"drivingBadge": "{active}",
"licence": "{running, licensed, state, adVersion, edition, document, hwnd, pid}",
"liveWorkspaces": "[{workspace, heartbeatAgeSec}]",
"logical": "agent reply; data = {focusedDocument, focusedProject, documents:[{path, kind, project, open}]} | null when no agent is alive",
"shots": "[{title, hwnd, kind, image: base64 png, width, height}]",
"windows": "[..]"
},
"pitfalls": [
"logical is null when no agent is resident: state never bootstraps one. Call any agent-backed verb or altium_agent_start first.",
"shots[] are full-size base64 PNGs of every main and dialog window; pass screenshots:false when you only need the data."
],
"related": [
"altium_status",
"altium_window_info",
"altium_activate_document",
"altium_agent_start"
],
"statusVerb": null,
"summary": "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, focused project, open documents).",
"timeoutSeconds": 60
},
{
"example": {},
"hint": "READ dialogs[].shot, decide, then altium_dismiss_dialogs {button, titles:[..]}. A script 'Error' box: altium_agent_recover. A save prompt on close: see altium_close discardChanges.",
"input": {
"screenshots": "bool, default true"
},
"longRunning": false,
"name": "altium_check_dialogs",
"output": {
"dialogs": "[{hwnd, pid, title, className, body, buttons, category, safeAction, meaning, ownedByMainInstance, rect, shot: base64 png}]",
"dialogsDetected": "int"
},
"pitfalls": [
"category and safeAction are suggestions. A save_prompt is never auto-answered: it names documents that may belong to the user or another AI thread.",
"Known nuisance boxes are pressed by the standing reaper before you ever see them; altium_dialog_log lists those."
],
"related": [
"altium_dismiss_dialogs",
"altium_dialog_log",
"altium_agent_recover",
"altium_window_info"
],
"statusVerb": null,
"summary": "List every Altium dialog currently open, classified, each with a screenshot (the only way to READ one: Altium paints its dialog text).",
"timeoutSeconds": 30
},
{
"example": {
"button": "OK",
"titles": [
"Error"
]
},
"hint": "ALWAYS pass titles. Then altium_check_dialogs to confirm nothing is left, and repeat the verb that was blocked.",
"input": {
"button": "string, default 'OK' - the button's accessible name",
"titles": "[string] - optional title substrings; only matching dialogs are pressed"
},
"longRunning": false,
"name": "altium_dismiss_dialogs",
"output": {
"detected": "int",
"pressed": "[{title, hwnd, button, ok}]"
},
"pitfalls": [
"Without titles the button is pressed on EVERY detected Altium dialog, save prompts included.",
"hwnd is NOT read by this verb, although other verbs' hints say {hwnd, button}: target a dialog with titles.",
"success is true even when nothing was pressed or the click failed: check pressed[].ok."
],
"related": [
"altium_check_dialogs",
"altium_close",
"altium_agent_recover"
],
"statusVerb": null,
"summary": "Press one named button (default OK) on the detected Altium dialogs through UIA - no cursor, no focus steal. titles narrows it to dialogs whose title contains one of the strings.",
"timeoutSeconds": 30
},
{
"example": {},
"hint": "Cold start is about 60 s. Next: altium_readiness; licensed:false -> altium_ensure_licensed. Most verbs need this first (errorCode altium_not_running).",
"input": {
"background": "bool, default TRUE: remember the user's foreground window and restore it once Altium is up. Pass false only when the user asked to SEE Altium come up.",
"install": "optional: develop | designer | a folder name (AD26, ADDevelop) | a path, when several Altiums are installed",
"waitSec": "number, default 180"
},
"longRunning": false,
"name": "altium_launch",
"output": {
"alreadyRunning": "bool",
"foregroundReturnedTo": "hwnd|null",
"licence": "{running, licensed, state, adVersion, edition, hwnd, pid}",
"startedInSec": "float",
"windowEtiquette": "background once the user's window is handed back; foreground only with background:false"
},
"pitfalls": [
"Altium foregrounds ITSELF at startup and offers no switch for it, so the window jumps over the user's work for a few seconds even with background:true \u2014 the bridge can only hand the focus back afterwards. Call it once; never in a retry loop.",
"errorCode host_app_not_installed -> altium_install. launch_timeout = no main window after waitSec.",
"A 'Workspace Unavailable' box at launch (altium_dialog_log) means another running Altium holds the seat: this one is view-only and opens fail with view_only_no_author_seat."
],
"related": [
"altium_readiness",
"altium_ensure_licensed",
"altium_close",
"altium_install"
],
"statusVerb": null,
"summary": "Start Altium (the newest numbered install, or the one install names) and wait for its main window, then hand the user's own window back. Answers alreadyRunning when one is up.",
"timeoutSeconds": 240
},
{
"example": {
"dryRun": true
},
"hint": "This is the manifest's uninstall hook; nothing to call afterwards. To revoke the Altium 365 grant remotely call altium_a365_logout BEFORE this.",
"input": {
"dryRun": "bool - report only, delete nothing"
},
"longRunning": false,
"name": "altium_uninstall",
"output": {
"dryRun": "bool",
"note": "string",
"removed": "[path]"
},
"pitfalls": [
"A resident agent is stopped even with dryRun:true; only the delete is skipped."
],
"related": [
"altium_a365_logout",
"altium_agent_stop"
],
"statusVerb": null,
"summary": "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 never touched.",
"timeoutSeconds": 30
},
{
"example": {
"limit": 10
},
"hint": "Read it after a surprise: enginePreviouslyParked on a reply, an agent_script_error, or an open that failed view-only ('Workspace Unavailable' shows here). A dialog that reached the user and is NOT listed is a catalog gap: report it.",
"input": {
"limit": "int, default 25"
},
"longRunning": false,
"name": "altium_dialog_log",
"output": {
"reaped": "[{title, category, pressed, ok, note, at}]",
"running": "bool"
},
"pitfalls": [
"An in-memory ring of the last 200 events: a bridge restart clears it.",
"Save prompts and unknown dialogs never appear here as pressed: the reaper does not touch them."
],
"related": [
"altium_check_dialogs",
"altium_status",
"altium_agent_recover"
],
"statusVerb": null,
"summary": "What the standing dialog reaper (and the bridge's own recoveries) pressed, newest last: nuisance boxes, script-error boxes, discarded save prompts, silent engine halts cleared.",
"timeoutSeconds": 10
},
{
"example": {},
"hint": "After success altium_eval / altium_run_command / altium_state go through the agent in milliseconds. Do NOT use altium_run_script while it is up.",
"input": {
"waitSec": "int, default 45 - how long to wait for the first heartbeat"
},
"longRunning": false,
"name": "altium_agent_start",
"output": {
"alreadyRunning": "bool",
"generation": "string - AdomAgent_<digest>",
"install": "object - the rendered script",
"startedInSec": "float",
"strayHelpersKilled": "[pid]"
},
"pitfalls": [
"The bootstrap ACTIVATES Altium for a moment (it opens the .PrjScr in the script editor); the bridge hands the user's foreground window back.",
"no_heartbeat = the engine halted behind a script Error modal: altium_check_dialogs, then altium_agent_recover.",
"The loop exits by itself 15 s after the last request (while it runs Altium ignores the user's clicks, #27); the next verb restarts it in 2.5-4 s. Call altium_agent_stop when you hand Altium back to the user."
],
"related": [
"altium_agent_status",
"altium_agent_stop",
"altium_agent_recover",
"altium_eval"
],
"statusVerb": null,
"summary": "Bootstrap the resident DelphiScript agent inside Altium (renders the script, runs it through the -R lane, waits for the heartbeat). Optional: every agent-backed verb does this on demand.",
"timeoutSeconds": 120
},
{
"example": {},
"hint": "Call it when you hand Altium back to the user: while the loop is resident Altium ignores their clicks (it also stops by itself 15 s after the last verb). Needed before altium_run_script (the -R lanes refuse while a loop is resident). altium_close stops every workspace's loop itself. The next agent-backed verb restarts the agent. Clears the 'Adom is driving' taskbar badge.",
"input": {},
"longRunning": false,
"name": "altium_agent_stop",
"output": {
"stoppedInSec": "float",
"wasRunning": "bool"
},
"pitfalls": [
"'the loop did not exit' -> altium_agent_recover.",
"With several Altiums running pass instance: to stop the right loop."
],
"related": [
"altium_agent_start",
"altium_agent_status",
"altium_run_script",
"altium_close"
],
"statusVerb": null,
"summary": "Stop the selected instance's resident agent loop (drops a stop file and waits up to 12 s for the heartbeat to go stale).",
"timeoutSeconds": 20
},
{
"example": {},
"hint": "alive with responsive:false = the loop is busy inside a long Altium process: wait, do not start a second agent. Not alive: call the verb you need, it bootstraps.",
"input": {},
"longRunning": false,
"name": "altium_agent_status",
"output": {
"alive": "bool - selected instance",
"heartbeat": "{ageSec, tick, ...} | null",
"liveWorkspaces": "[{workspace, heartbeatAgeSec}]",
"residentAnywhere": "bool",
"responsive": "bool",
"workspace": "path"
},
"pitfalls": [
"residentAnywhere:true with alive:false is a freeze-on-close hazard: altium_close tears every loop down before the app exits."
],
"related": [
"altium_agent_start",
"altium_agent_recover",
"altium_readiness"
],
"statusVerb": null,
"summary": "Is the agent loop alive and responsive, in which workspace, and is any loop resident anywhere? Read-only; never starts the agent.",
"timeoutSeconds": 10
},
{
"example": {
"reason": "agent_timeout on read_board"
},
"hint": "Use after agent_timeout / no_heartbeat / instance_busy, or when Altium sits on AdomAgent_*.pas in its debugger. Then call your verb again: it restarts the agent. Never ask the user to click.",
"input": {
"reason": "string - optional, recorded in steps"
},
"longRunning": false,
"name": "altium_agent_recover",
"output": {
"steps": "[{reason} | {dialog, pressed} | {editScriptStop, exited, sec} | busy-notice reap]"
},
"pitfalls": [
"A modal orphan (main window disabled, no dialog on screen) answers nothing: recover refuses with altium_modal_orphan instead of firing -R hand-offs that all bounce off 'another instance is busy'. Escape it with altium_close {discardChanges:true}.",
"It presses OK on EVERY Altium dialog it finds, not only the script Error box: altium_check_dialogs first if a save prompt may be up.",
"An agent_script_error reply was ALREADY recovered by the bridge (autoRecovered): do not recover again, and do not resend the same command - it will halt again."
],
"related": [
"altium_check_dialogs",
"altium_agent_start",
"altium_dialog_log",
"altium_selftest_script_error"
],
"statusVerb": null,
"summary": "Un-halt the script engine: clear the PCB transaction, press OK on open Altium dialogs, send EditScript:Stop, reap the busy notice and delete stale request files.",
"timeoutSeconds": 60
},
{
"example": {
"prjscr": "C:/scripts/MyTool.PrjScr",
"proc": "Main"
},
"hint": "While the agent is resident use altium_eval / altium_run_command instead (or altium_agent_stop first). Scripts return nothing: have yours write a file and read that.",
"input": {
"prjscr": "absolute path to a .PrjScr on this machine (required)",
"proc": "string, default 'Main'",
"timeout": "seconds, default 60"
},
"longRunning": false,
"name": "altium_run_script",
"output": {
"arg": "string - the -R argument sent",
"helperSec": "float",
"modalsPreempted": "[{title, body}] - bridge-caused boxes cleared in flight"
},
"pitfalls": [
"Refused with agent_resident while ANY agent loop is alive: a second script raises 'Another script executing now' on the user's screen.",
"ONE SHOT: instance_busy means the running instance did not accept the request. Do not retry in a loop; each attempt costs the user a busy notice."
],
"related": [
"altium_eval",
"altium_run_command",
"altium_agent_stop",
"altium_agent_recover"
],
"statusVerb": null,
"summary": "One shot: run a procedure of YOUR OWN .PrjScr through Altium's -R command line. Only for when the agent is NOT resident.",
"timeoutSeconds": 60
},
{
"example": {
"query": "zoom",
"server": "PCB"
},
"hint": "Run a hit with altium_run_command {command, params}; hits[].params shows the Name=Value pairs Altium's own menus pass.",
"input": {
"limit": "int, default 50",
"query": "string - substring over command, captions, descriptions and params",
"server": "string - e.g. PCB, Sch, WorkspaceManager"
},
"longRunning": false,
"name": "altium_list_commands",
"output": {
"count": "int",
"hits": "[{command, server, captions, shortcuts, params, descriptions}]",
"servers": "{server: count}",
"total": "int - distinct commands"
},
"pitfalls": [
"Reads files, not Altium: works with Altium closed but answers host_app_not_installed without an install.",
"Being listed does not make a process safe: some open a modal that blocks the agent (PCB:DesignRuleCheck - use altium_run_drc)."
],
"related": [
"altium_run_command",
"altium_eval"
],
"statusVerb": null,
"summary": "Search Altium's process-launcher catalog (about 1,100 Server:Command entries parsed from the install's System/*.rcs files) by text and/or server.",
"timeoutSeconds": 30
},
{
"example": {
"filePath": "C:/proj/board.PcbDoc"
},
"hint": "Then the verb for that document: altium_read_board / altium_read_schematic / altium_list_library. status:in_progress -> poll altium_status or altium_window_info until it is current.",
"input": {
"filePath": "absolute Windows path (alias: path)",
"timeout": "seconds; the wait is capped at 45"
},
"longRunning": false,
"name": "altium_open_document",
"output": {
"data": "{path, objectKind, kind, shown: bool, lane}",
"roundtripMs": "int",
"status": "'in_progress' when Altium is still opening it",
"windowEtiquette": "background"
},
"pitfalls": [
"Only .PcbDoc .SchDoc .PcbLib .SchLib .OutJob .Pcb3DLib .Prj* .LibPkg .txt .pas .rep are accepted; anything else is refused as unsupported_document (Altium would raise a 'File type not recognised' modal).",
"success:true with data.shown:false on a non-project means the document did NOT open (this verb does not turn that into an error). In a view-only Altium that is every new document: see view_only_no_author_seat."
],
"related": [
"altium_activate_document",
"altium_close_document",
"altium_state",
"altium_show_2d_board"
],
"statusVerb": null,
"summary": "Open a document or project by path through the agent and show it without focusing it. An already-open document is activated, not reloaded.",
"timeoutSeconds": 60
},
{
"example": {
"filePath": "C:/proj/board.PrjPcb"
},
"hint": "Then altium_compile {projectPath} for ERC, or altium_open_document one of its sheets. altium_state lists the project's documents.",
"input": {
"filePath": "absolute Windows path (alias: path)",
"timeout": "seconds; the wait is capped at 45"
},
"longRunning": false,
"name": "altium_open_project",
"output": {
"data": "{path, objectKind: 'Project', shown: false, note}",
"roundtripMs": "int",
"windowEtiquette": "background"
},
"pitfalls": [
"data.shown:false is NORMAL for a project: projects have no document view."
],
"related": [
"altium_open_document",
"altium_compile",
"altium_show_project",
"altium_state"
],
"statusVerb": null,
"summary": "Open a project (.PrjPcb / .PrjScr / .PrjMbd / .PrjHar / .LibPkg) by path. Same handler as altium_open_document.",
"timeoutSeconds": 60
},
{
"example": {
"path": "C:/proj/tof.SchDoc"
},
"hint": "altium_save {filePath} first if anything is worth keeping. After re-running altium_place_on_sch / altium_test_board to the same path, close the stale document before altium_show_*.",
"input": {
"path": "absolute path of the open document (required)"
},
"longRunning": false,
"name": "altium_close_document",
"output": {
"data": "{closed: bool, path} | {closed: false, note: 'not open: <path>'}",
"roundtripMs": "int"
},
"pitfalls": [
"Unsaved edits are DISCARDED without a prompt.",
"success:true with closed:false means the document was not open."
],
"related": [
"altium_save",
"altium_open_document",
"altium_state"
],
"statusVerb": null,
"summary": "Close ONE open document by path through its document handle. Never saves.",
"timeoutSeconds": 30
},
{
"example": {
"path": "C:/proj/board.PcbDoc"
},
"hint": "Activate the .PcbDoc, then altium_read_board; activate the .SchDoc, then altium_read_schematic. After a demo or a show_* call, activate the user's own document again.",
"input": {
"path": "full path of the document (aliases: document, name)",
"timeout": "seconds; the wait is capped at 45"
},
"longRunning": false,
"name": "altium_activate_document",
"output": {
"data": "{path, objectKind, kind, shown}",
"lane": "agent",
"status": "'in_progress' when still opening",
"windowEtiquette": "background"
},
"pitfalls": [
"Needs the FULL path with a supported extension; a bare document name is refused.",
"It is the same agent 'open': a path that is not open yet gets opened."
],
"related": [
"altium_open_document",
"altium_state",
"altium_read_board",
"altium_read_schematic"
],
"statusVerb": null,
"summary": "Make a document current - the quiet lane (one in-process agent call, no cursor, no OS foreground). Board and schematic read verbs act on the CURRENT document.",
"timeoutSeconds": 60
},
{
"example": {},
"hint": "Use verbTimes.p90 to choose a timeout for a slow verb on THIS machine, and active[] to see what a long call is doing. Never touches Altium.",
"input": {},
"longRunning": false,
"name": "altium_progress",
"output": {
"active": "[progress blocks of phases in flight]",
"history": "{phase: {warm|cold: {samples, p50, p90}}}",
"verbTimes": "{verb: {count, p50, p90, max, failures}} - p90 descending, top 40"
},
"pitfalls": [],
"related": [
"altium_status",
"altium_describe"
],
"statusVerb": null,
"summary": "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.",
"timeoutSeconds": 10
},
{
"example": {},
"hint": "Start here on an unknown board, then altium_review_board for findings or altium_component_data / altium_net_connections for detail.",
"input": {
"limit": "int, default 2000",
"raw": "bool - return the unshaped agent payload",
"sections": "string csv - optional"
},
"longRunning": false,
"name": "altium_board_summary",
"output": {
"roundtripMs": "int",
"summary": "{board, components, componentsTop, componentsBottom, nets, copperLayersInUse, copperLayersInUseNames, layersWithPrimitives, copperLayersAddressable, rules, rulesEnabled}"
},
"pitfalls": [
"Needs a .PcbDoc current (altium_activate_document).",
"copperLayersAddressable is what Altium CAN address (top + 30 mid + 16 planes + bottom), not this board's stack: report copperLayersInUse."
],
"related": [
"altium_read_board",
"altium_layers_in_use",
"altium_rules_by_kind",
"altium_review_board"
],
"statusVerb": null,
"summary": "One-screen summary of the current board, shaped from one read_board round trip: component counts by side, nets, copper layers actually in use, rule counts.",
"timeoutSeconds": 120
},
{
"example": {},
"hint": "Use it to answer 'what clearance/width does this board enforce'. altium_read_rules gives the flat list including disabled rules; altium_run_drc checks the board against them.",
"input": {
"limit": "int, default 2000",
"sections": "string csv - optional"
},
"longRunning": false,
"name": "altium_rules_by_kind",
"output": {
"board": "path",
"roundtripMs": "int",
"rulesByKind": "{KindName: [{name, kind, enabled, priority, scope1, scope2, comment}]}"
},
"pitfalls": [
"Needs a .PcbDoc current.",
"Disabled rules are dropped; a rule kind the bridge has no name for appears as 'kind <n>'."
],
"related": [
"altium_read_rules",
"altium_run_drc",
"altium_board_summary"
],
"statusVerb": null,
"summary": "The current board's ENABLED design rules grouped by rule kind (Clearance, Width, RoutingVias, ...), each group sorted by priority. Shaped from one read_board round trip.",
"timeoutSeconds": 120
},
{
"example": {},
"hint": "The honest answer to 'how many layers is this board'. altium_set_layer_visibility {layerId} to isolate one, then altium_show_2d_board for a frame.",
"input": {
"limit": "int, default 2000",
"sections": "string csv - optional"
},
"longRunning": false,
"name": "altium_layers_in_use",
"output": {
"board": "path",
"copperLayersInUse": "[{layerId, name, primitives}]",
"layersWithPrimitives": "[{layerId, name, primitives}]",
"roundtripMs": "int"
},
"pitfalls": [
"Needs a .PcbDoc current.",
"A floor, not the stack: an empty inner plane carries no primitives and is invisible here."
],
"related": [
"altium_board_summary",
"altium_layers",
"altium_copper_layers",
"altium_set_layer_visibility"
],
"statusVerb": null,
"summary": "Which layers of the current board actually carry primitives: copper layers with copper (densest first) and every layer with anything on it.",
"timeoutSeconds": 120
},
{
"example": {},
"hint": "Then altium_cross_check {board, sheet} to compare against the layout, or altium_schematic_data {designator} for one part's pins.",
"input": {
"limit": "int, default 500",
"params": "bool, default true - include component parameters",
"sections": "string csv, default 'components'"
},
"longRunning": false,
"name": "altium_read_schematic",
"output": {
"components": "[{designator, libReference, comment, ...}]",
"count": "int",
"designators": "[string]",
"document": "string",
"roundtripMs": "int"
},
"pitfalls": [
"The CURRENT sheet only: a hierarchical parent holds sheet symbols, not parts. Read each leaf sheet.",
"Needs a .SchDoc current; 'no current schematic' -> altium_open_document / altium_show_schematic."
],
"related": [
"altium_schematic_data",
"altium_cross_check",
"altium_show_schematic",
"altium_activate_document"
],
"statusVerb": null,
"summary": "Components on the CURRENT schematic sheet (designator, library reference, comment, position, parameters) in one agent round trip.",
"timeoutSeconds": 90
},
{
"example": {
"board": "C:/proj/board.PcbDoc",
"sheet": "C:/proj/main.SchDoc"
},
"hint": "Pass BOTH paths: with neither, one of the two reads has no current document and the call fails at stage board or sheet. Follow differences with altium_component_data / altium_schematic_data.",
"input": {
"board": "path to the .PcbDoc - optional, else the current board",
"sheet": "path to the .SchDoc - optional, else the current sheet",
"timeout": "seconds per step, default 45"
},
"longRunning": false,
"name": "altium_cross_check",
"output": {
"board": "path",
"boardComponents": "int",
"matched": "int",
"onBoardNotOnSheet": "[designator]",
"onSheetNotOnBoard": "[designator]",
"sameProject": "bool | null - same folder",
"schematicComponents": "int",
"sheet": "string"
},
"pitfalls": [
"The schematic side is ONE sheet: on a hierarchical design run it per leaf sheet before calling anything missing.",
"_warning means sheet and board sit in different folders, probably different projects: every difference is then meaningless.",
"With paths given it leaves the SHEET current; altium_activate_document the board again before board verbs."
],
"related": [
"altium_read_board",
"altium_read_schematic",
"altium_review_board"
],
"statusVerb": null,
"summary": "Compare one schematic sheet's designators with a board's. Altium holds ONE current document, so the verb activates the board, reads it, then activates the sheet and reads that.",
"timeoutSeconds": 120
},
{
"example": {},
"hint": "Then altium_component_data {designator} or altium_component_pins {designator}.",
"input": {},
"longRunning": false,
"name": "altium_list_designators",
"output": {
"data": "{count, designators: [string]}",
"roundtripMs": "int"
},
"pitfalls": [
"Needs a .PcbDoc current: 'no current PCB board' carries the _hint to open one."
],
"related": [
"altium_component_data",
"altium_component_pins",
"altium_read_board"
],
"statusVerb": null,
"summary": "Every component designator on the current board.",
"timeoutSeconds": 90
},
{
"example": {
"designator": "U1"
},
"hint": "Then altium_component_pins {designator} for pad-level nets, or altium_footprint_primitives {designator} for the geometry.",
"input": {
"designator": "string - optional; omit for every component",
"limit": "int, default 500"
},
"longRunning": false,
"name": "altium_component_data",
"output": {
"data": "{component: {designator, pattern, comment, layerId, bottom, xMil, yMil, rotation, wMil, hMil, pads, nets}} | {count, components: [..]}",
"roundtripMs": "int"
},
"pitfalls": [
"Needs a .PcbDoc current.",
"Units are mils; the designator match ignores case. limit only applies to the all-components form."
],
"related": [
"altium_list_designators",
"altium_component_pins",
"altium_footprint_primitives"
],
"statusVerb": null,
"summary": "Placement data for one board component, or for all of them: footprint pattern, comment, layer/side, position, rotation, size, pad count and the nets on its pads.",
"timeoutSeconds": 90
},
{
"example": {
"designator": "U1"
},
"hint": "Use pins[].net with altium_net_connections {net} to follow a signal across the board.",
"input": {
"designator": "string (required), e.g. U1"
},
"longRunning": false,
"name": "altium_component_pins",
"output": {
"data": "{designator, count, pins: [{name, net, xMil, yMil, layerId, wMil, hMil, holeMil}]}",
"roundtripMs": "int"
},
"pitfalls": [
"Needs a .PcbDoc current.",
"holeMil 0 = an SMD pad."
],
"related": [
"altium_component_data",
"altium_net_connections",
"altium_footprint_primitives"
],
"statusVerb": null,
"summary": "Every pad of one board component with its net, position, layer, size and hole.",
"timeoutSeconds": 90
},
{
"example": {},
"hint": "Then altium_net_connections {net} for the pads of one net.",
"input": {},
"longRunning": false,
"name": "altium_list_nets",
"output": {
"data": "{count, nets: [{name, pads}]}",
"roundtripMs": "int"
},
"pitfalls": [
"Needs a .PcbDoc current.",
"Pad counts are tallied over pads: a net with no pads on it does not appear."
],
"related": [
"altium_net_connections",
"altium_read_board"
],
"statusVerb": null,
"summary": "Every net on the current board with its pad count.",
"timeoutSeconds": 90
},
{
"example": {
"net": "GND"
},
"hint": "Pass net on anything but a small board. The span string is 'minX,minY,maxX,maxY,pads' in mils: a quick measure of how far a net travels.",
"input": {
"limit": "int, default 4000 - caps pads",
"net": "string - optional net name"
},
"longRunning": false,
"name": "altium_net_connections",
"output": {
"data": "{count, pads: [{net, pad: 'U1.3', xMil, yMil}], nets: [{net, minXminYmaxXmaxYpads}]}",
"roundtripMs": "int"
},
"pitfalls": [
"Needs a .PcbDoc current.",
"limit truncates silently: count is what was returned, not what exists."
],
"related": [
"altium_list_nets",
"altium_component_pins"
],
"statusVerb": null,
"summary": "Every pad on the board with its net and owner (Designator.Pad), plus a bounding span and the airline length (minimum spanning tree over its pads, airlineMm) per net. net filters to one net.",
"timeoutSeconds": 120
},
{
"example": {},
"hint": "ids feed altium_set_layer_visibility {layerId}. For what is actually used, altium_layers_in_use.",
"input": {},
"longRunning": false,
"name": "altium_layers",
"output": {
"data": "{layers: [{name, id, kind, displayed}]}",
"roundtripMs": "int"
},
"pitfalls": [
"Needs a .PcbDoc current.",
"The fixed layer set, not the stackup: thickness and dielectric detail are not read."
],
"related": [
"altium_copper_layers",
"altium_layers_in_use",
"altium_set_layer_visibility"
],
"statusVerb": null,
"summary": "The current board's layer set with ids, names, kind and whether each is displayed.",
"timeoutSeconds": 90
},
{
"example": {},
"hint": "Do not count these as the board's layers: altium_layers_in_use says which carry copper.",
"input": {},
"longRunning": false,
"name": "altium_copper_layers",
"output": {
"data": "{layers: [{name, id, kind, displayed}]}",
"roundtripMs": "int"
},
"pitfalls": [
"Needs a .PcbDoc current.",
"A capability list (the same on any board), not the stack in use."
],
"related": [
"altium_layers",
"altium_layers_in_use"
],
"statusVerb": null,
"summary": "Every copper layer Altium can address on the current board (top, mid 1-30, planes 1-16, bottom) with names and visibility.",
"timeoutSeconds": 90
},
{
"example": {},
"hint": "Open the board first (altium_show_2d_board). dk1000 is the dielectric constant times 1000 (4200 = 4.2).",
"input": {},
"longRunning": false,
"name": "altium_layer_stack",
"output": {
"data": "{copperLayers, totalUm, layers: [{name, copperUm, dielectricUm (the dielectric BELOW this layer), dk1000 (dielectric constant x 1000), material}]}"
},
"pitfalls": [
"Solder mask and overlay layers are not part of this list; the copper and the dielectric under each are."
],
"related": [
"altium_layers",
"altium_copper_layers",
"altium_read_rules"
],
"statusVerb": null,
"summary": "The CURRENT board's stack-up: copper layers in order with copper thickness and the dielectric under each (height, constant, material), and the total thickness. For impedance, current capacity and fab quotes.",
"timeoutSeconds": 60
},
{
"example": {},
"hint": "altium_rules_by_kind groups the enabled ones under readable kind names; altium_run_drc checks the board against them.",
"input": {},
"longRunning": false,
"name": "altium_read_rules",
"output": {
"data": "{count, rules: [{name, kind: int, enabled, priority, scope1, scope2, comment, descriptor}]}",
"roundtripMs": "int"
},
"pitfalls": [
"Needs a .PcbDoc current.",
"kind is Altium's TRuleKind ORDINAL; the values are in descriptor, as Altium words them."
],
"related": [
"altium_rules_by_kind",
"altium_run_drc"
],
"statusVerb": null,
"summary": "Every design rule on the current board, flat, disabled ones included: name, kind ordinal, enabled, priority, both scope expressions, comment, and Altium's descriptor with the rule's VALUES (e.g. 'Clearance Constraint (Gap=6mil) (All),(All)').",
"timeoutSeconds": 90
},
{
"example": {
"displayed": false,
"layerId": 1
},
"hint": "Then altium_show_2d_board {filePath} for a frame of the result. Restore what you hid: visibility is view state the user keeps seeing.",
"input": {
"displayed": "bool, default true",
"layerId": "int (required) - an id from altium_layers"
},
"longRunning": false,
"name": "altium_set_layer_visibility",
"output": {
"data": "{layerId, name, displayed}",
"roundtripMs": "int"
},
"pitfalls": [
"Needs a .PcbDoc current.",
"Only pass ids that altium_layers returned: the id is not range-checked before the layer object is read."
],
"related": [
"altium_layers",
"altium_layers_in_use",
"altium_show_2d_board"
],
"statusVerb": null,
"summary": "Show or hide one layer of the current board (by layer id) and refresh the view and the layer tabs.",
"timeoutSeconds": 60
},
{
"example": {
"expectPath": "C:/designs/buck/buck.PcbDoc"
},
"hint": "Layers use KiCad names (F.Cu, B.Cu, In<n>.Cu; *.Cu = a multi-layer pad) with Altium's layerId alongside. Coordinates are Altium's own frame (y up), in mm. This is the read AI Flow's Altium lane calls before and after every edit.",
"input": {
"expectPath": "string (optional) - refuse with wrong_board unless this .PcbDoc is the current board"
},
"longRunning": false,
"name": "altium_routing_state",
"output": {
"altiumRatsnest": "int - Altium's own count",
"boardId": "string (the .PcbDoc path)",
"components": "[{ref, x, y, rotation, side, pattern}]",
"counts": "{tracks, arcs, vias, pads, components, polygons, nets}",
"isolatedCopper": "[{net, layer, at{x,y}}] - pours that touch nothing else of their net: not counted in unconnected",
"outline": "[[x,y]]",
"pads": "[{ref, name, x, y, sizeX, sizeY, rotation, layer, drill, net}]",
"polygons": "[{net, layer, points[[x,y]]}]",
"revision": "string - pass as expectedRevision to the edit verbs",
"splitNets": "[{net, groups}]",
"tracks": "[{start{x,y}, end{x,y}, width, layer, net}]",
"unconnected": "int - connections still to make, from the copper",
"vias": "[{position{x,y}, size, drill, layers[2], net}]"
},
"pitfalls": [
"Needs a .PcbDoc current (altium_show_2d_board {filePath}).",
"Footprint-internal tracks and arcs are left out; only free copper is listed.",
"unconnected is computed from the copper (Altium's ratsnest skips parts off the board; its count rides along as altiumRatsnest). A pour that reaches nothing else of its net is listed under isolatedCopper and not counted. Re-read after an edit for a fresh count."
],
"related": [
"altium_read_board",
"altium_net_connections",
"altium_footprint_primitives"
],
"statusVerb": null,
"summary": "The WHOLE current board as data, in mm: tracks, arcs, vias, pads (with owner and net), components (ref, x, y, rotation, side), polygon pours, the outline, the unrouted (ratsnest) count, and a revision hash.",
"timeoutSeconds": 180
},
{
"example": {
"net": "VOUT",
"paths": [
[
{
"pad": "L1.2"
},
[
120.0,
90.0
],
{
"pad": "C6.1"
}
]
],
"width": 0.5
},
"hint": "Coordinates are mm in Altium's frame, the same as altium_routing_state. There is no clearance check here yet: run your own DRC (AI Flow's gate) or altium_run_drc after.",
"input": {
"boardId": "string (optional) - refused with board_mismatch unless this is the current board",
"expectPath": "string (optional)",
"expectedRevision": "string (optional) - the revision you last read; refused with stale_board if the board changed",
"layer": "F.Cu|B.Cu|In<n>.Cu or an Altium layer id (default F.Cu)",
"net": "string (required)",
"paths": "[[waypoint,...]] - a waypoint is [x,y], {x,y,layer} or {pad:\"U1.3\"}",
"viaDrill": "mm (default 0.3)",
"viaSize": "mm (default 0.6)",
"width": "mm (default 0.25)"
},
"longRunning": false,
"name": "altium_route_net",
"output": {
"applied": "int",
"counts": "{tracks, vias, ...}",
"failed": "int",
"results": "[ok|err:...] per segment/via",
"revision": "string - the board after the edit",
"state": "the full altium_routing_state after",
"unconnected": "int"
},
"pitfalls": [
"Needs the board current.",
"A net name must already exist on the board (nets come from the schematic / pads)."
],
"related": [
"altium_routing_state",
"altium_place_vias",
"altium_remove_items",
"altium_ripup_nets"
],
"statusVerb": null,
"summary": "Route one net as tracks, segment by segment; a waypoint on another layer drops a via there. One undo step, read back.",
"timeoutSeconds": 300
},
{
"example": {
"from": "U1.8",
"gridMm": 0.25,
"net": "N1",
"to": "U2.1"
},
"hint": "A plan changes nothing: read it, then call again with apply:true, or pass routeNet to altium_route_net yourself. Pours are not obstacles: repour after. The path is orthogonal on the grid: a 0.5 mm pitch part needs gridMm 0.1 to escape its pads. found:false says why (no room at this grid and clearance, or the search bound).",
"input": {
"allowVias": "bool, default true",
"apply": "bool, default false - route it with altium_route_net, guarded by the revision it was planned on",
"avoidPours": "true keeps out of every other net's pour, [net] out of those nets' pours only; default false (a route may cross them, crossesPours names each)",
"clearanceMm": "only raises the board's rule",
"edgeClearanceMm": "mm from the outline",
"filePath": "the .PcbDoc (opened first; else the current board)",
"from": "Ref.Pad (required), e.g. U1.3",
"gridMm": "search grid, default 0.5; 0.1 for fine-pitch pads",
"layers": "[F.Cu, B.Cu, In<n>.Cu] - default F.Cu and B.Cu",
"maxNodes": "search bound, default 50000",
"net": "string (required)",
"pourCost": "number, default 0 - each mm inside another net's pour costs 1 + pourCost mm: a preference, not a wall",
"smooth": "bool, default true - straighten the grid path into straight and 45-degree runs with the same clearance; false keeps the grid path",
"to": "Ref.Pad (required)",
"viaDrillMm": "mm, default the Routing Via rule, else 0.3",
"viaSizeMm": "mm, default the board's Routing Via rule, else 0.6",
"widthMm": "track width, default the board's Width rule (Preferred), else 0.25"
},
"longRunning": false,
"name": "altium_plan_route",
"output": {
"applied": "{success, applied, failed, unconnected} - with apply",
"crossesPours": "[the other nets' pours the route runs through: check after the repour that none split]",
"engine": "string",
"found": "bool",
"lengthMm": "float",
"reason": "string - why no path, when found is false",
"revision": "string - pass as expectedRevision",
"routeNet": "altium_route_net's own arguments {net, layer, width, viaSize, viaDrill, paths}",
"viaAt": "[[x, y]]",
"vias": "int"
},
"pitfalls": [
"Pours are ignored: a route through a pour's area cuts it until the repour.",
"A coarse grid misses paths between fine-pitch pads: try gridMm 0.1 before giving up."
],
"related": [
"altium_route_net",
"altium_routing_state",
"altium_repour",
"altium_routing_drc",
"altium_route_pair"
],
"statusVerb": null,
"summary": "Find a path for one net between two pads, clear of other nets' copper by the board's clearance rule, on the copper layers you allow, with vias between them (the standard's shared planner). A plan: apply:true routes it.",
"timeoutSeconds": 300
},
{
"example": {
"ic": "U1"
},
"hint": "A plan changes nothing: read placements, leftOut and validation, then call again with apply:true (or pass moveArgs to altium_move_parts). The tracks to the caps' old spots stay: rip up and route again (altium_plan_route), then repour. Name caps to place one the default set left out.",
"input": {
"apply": "bool, default false - move them with altium_move_parts, guarded by the revision planned on",
"caps": "[designator] - optional; default every cap between one of the IC's power nets and ground, leaving out signal caps (a crystal's load caps) and caps nearer another IC on the same supply",
"filePath": "the .PcbDoc (opened first; else the current board)",
"gapMm": "mm outside the IC's box, default 0.3",
"ic": "the IC's designator (required), e.g. U1"
},
"longRunning": false,
"name": "altium_place_decoupling",
"output": {
"applied": "{success, applied, failed, mismatches} - with apply",
"engine": "string",
"leftOut": "[{cap, reason: signal_net | nearer_another_ic}]",
"moveArgs": "altium_move_parts' own arguments {parts, expectedRevision}",
"placements": "[{cap, net, pin, side, x, y, rotation, powerPad, padToPinMm, slidMm, from}]",
"skipped": "[{cap, reason: other_side | no_shared_power_net | no_free_spot}]",
"validation": "placement_check on the moved board, what concerns the caps"
},
"pitfalls": [
"Boxes are pads plus 3D bodies: Altium courtyards are not read.",
"A cap on the other side from the IC is skipped (other_side): flip it first if it should move."
],
"related": [
"altium_move_parts",
"altium_placement_check",
"altium_plan_route",
"altium_ripup_nets",
"altium_repour",
"altium_check_clearance"
],
"statusVerb": null,
"summary": "Put an IC's decoupling caps beside the power pins they serve: each cap just outside the IC, power pad facing its pin, lined up with it, sliding along the side when the spot is taken (the standard's shared planner). A plan checked with placement_check; apply:true moves them.",
"timeoutSeconds": 300
},
{
"example": {
"ref": "U3"
},
"hint": "A plan changes nothing: read conflicts first. apply:true routes every call (each one undo step) and refuses while conflicts are listed. Tracks and pours are not checked: repour and run altium_routing_drc after. Via-in-pad needs filled and capped vias: tell the user first.",
"input": {
"apply": "bool, default false - route every call as one undo step, guarded by the revision planned on; refused while conflicts are listed",
"clearanceMm": "to other nets' pads",
"escapeLayer": "copper layer the vias reach (default the first inner layer, else the other side)",
"filePath": "the .PcbDoc (opened first; else the current board)",
"includeRouted": "bool, default false - plan pins their net already reaches too",
"pitchMm": "override the measured pitch",
"ref": "the package's designator (required)",
"stubMm": "stub length",
"style": "dogbone | via_in_pad (BGA)",
"surfaceOuterRing": "bool (BGA): the outer ring escapes on the surface",
"viaDrillMm": "via drill",
"viaMm": "via diameter",
"viaPerimeter": "bool: a via at the end of every perimeter stub",
"widthMm": "stub width"
},
"longRunning": false,
"name": "altium_plan_fanout",
"output": {
"applied": "{success, applied, failed, calls} - with apply: every call as one undo step",
"callCount": "int",
"calls": "[altium_route_net arguments], one per net",
"conflicts": "[vias or stubs closer than clearanceMm to another net's pad, track, arc or via]",
"crossesPours": "[pours the stubs run into]",
"engine": "string",
"escapeLayer": "string",
"minViaToPadMm": "float",
"package": "bga | perimeter",
"pads": "[{pad, net, action, why?}] - action skip with why \"already routed\" for pins their net already reaches (includeRouted plans them)",
"pitchMm": "float",
"revision": "string",
"viaCount": "int",
"warnings": "[string]"
},
"pitfalls": [
"Repour before DRC: a hatched pour's net-less pieces re-pour round the new copper only on the repour.",
"Via in pad (style via_in_pad) costs filled, capped vias at the fab."
],
"related": [
"altium_route_net",
"altium_plan_route",
"altium_routing_state",
"altium_repour",
"altium_routing_drc",
"altium_layer_stack"
],
"statusVerb": null,
"summary": "Plan a BGA's or a QFN/QFP's escape (the standard's shared planner): the outer ring on the surface and a dogbone via (or via in pad) for each inner ball, an outward stub per perimeter pad (with a via for ground or viaPerimeter), a via grid in an exposed pad. route_net calls, one per net, each via and stub measured against other nets' pads. apply:true routes them.",
"timeoutSeconds": 300
},
{
"example": {
"quantities": [
5,
30
]
},
"hint": "No rates are built in, so none can go stale: read the fab's current prices from its page, pass them as prices with the date read, and the reply prices the quantities from them. altium_fab_check compares the same numbers with a fab's limits. altium_jlcpcb_order makes the order files.",
"input": {
"assembly": "bool, default false",
"basicParts": "int: parts the assembler stocks as basic",
"filePath": "the .PcbDoc (opened first; else the current board)",
"prices": "a price record {vendor, url, read, currency, pcb: [{layers, setup, perM2, promo?}], thickness?, assembly?, excludes?} read from the fab's page with its date; without one the reply is the numbers only",
"quantities": "[int], default [5, 10, 30, 100]"
},
"longRunning": false,
"name": "altium_estimate_cost",
"output": {
"board": "{widthMm, heightMm, areaMm2, layers, thicknessMm, minTrackMm, minGapMm, minDrillMm, holes, vias, smdParts, thtParts, smdJoints, thtJoints, uniqueParts, assemblySides}",
"engine": "string",
"notes": "[string]",
"prices": "[{quantity, ...}] - only with a price record",
"rough": "bool",
"source": "{name, url, read} of the record"
},
"pitfalls": [
"A rough estimate only: get a real quote before ordering."
],
"related": [
"altium_fab_check",
"altium_jlcpcb_order",
"altium_layer_stack",
"altium_board_report"
],
"statusVerb": null,
"summary": "The numbers a fab quote needs (size, copper layers, thickness, smallest track, gap and drill, holes, parts and joints) from the board, and a rough price table at the quantities asked when you pass a price record read from the fab's own page (the standard's shared estimator; it has no rates of its own).",
"timeoutSeconds": 120
},
{
"example": {
"analysis": {
"points": 20,
"start": 10,
"stop": 1000000.0,
"sweep": "dec",
"type": "ac"
},
"probes": [
{
"net": "OUT"
}
],
"schematic": "C:/proj/Filter.SchDoc"
},
"hint": "With analysis, the project's documents are closed, the analysis is written into its .simcfg (for this sheet and the project) and the project is reopened: Altium reads the file only on opening. Unsaved documents of that project refuse it (unsaved_changes). AC y is in dB with phase beside it. Every part needs a simulation model (Altium's generic R, C, L, sources and the models of its simulation libraries).",
"input": {
"analysis": "{type: op} | {type: dc, source: V1, start, stop, step} | {type: ac, sweep: dec|oct|lin, points, start, stop} (Hz) | {type: tran, step, stop, start?} (s) | {type: noise, source: V9 (the input source), output: OUT (a net), reference?: 0, sweep?, points?, start, stop} (Hz: onoise/inoise spectra in V/rtHz and their totals); omitted: the analyses the design carries. {type: raw} is refused (not_supported): Altium netlists the schematic itself",
"monteCarlo": "{runs (1-100), distribution?: gauss|uniform, seed?, tolerances?: {resistor, capacitor, inductor, transistor, dcSource, digital} in percent}: the analysis again with every part drawn within its tolerance; each run its own signal (v(out)_m1 ...) with the drawn values in step",
"points": "int, default 200: a ceiling per signal (the first, last and extreme points are kept)",
"probes": "[{net: OUT} | {current: R3} | {signal: \"v(out)\"}]; with an analysis they become the signals the run keeps; omitted: the signals the design's own simulation setup keeps (an operating point keeps every node and current)",
"schematic": "the .SchDoc to simulate (filePath works too); it must belong to a .PrjPcb beside it",
"sweep": "{parameter: C6 (a part's value) or a sheet parameter, start, stop, step, scale?: lin|dec|oct}: the analysis again for each value (step is the increment for lin, points per decade or octave for dec and oct); 50 runs at most",
"temperatures": "{start, stop, step} in degrees C: the analysis again at each temperature"
},
"longRunning": false,
"name": "altium_simulate",
"output": {
"available": "[every signal of the run]",
"engine": "string",
"missing": "[probes the run did not have]",
"netlist": "path of the .nsx it ran",
"notSimulated": "[parts the netlister left out: no simulation model]",
"results": "path of Altium's .sdf",
"signals": "[{signal, analysis, x, y, xUnit, yUnit, phase? (AC, degrees unwrapped), step? (a sweep step, e.g. C6 = 1e-10)}]: in a sweep each run is its own signal (v(out)_p1, v(out)_p2 ...)"
},
"pitfalls": [
"A part with no simulation model stops the netlister: simulation_failed, and Altium's Messages name it.",
"The run also opens Altium's results document; it is saved beside the project (Simulation folder) and closed."
],
"related": [
"altium_export_spice",
"altium_compile",
"altium_open_project"
],
"statusVerb": null,
"summary": "Run a circuit simulation of a schematic sheet in Altium's mixed-signal simulator (Advanced Sim) and return the signals as data: an operating point, a DC sweep, an AC sweep or a transient, as the standard's simulate gives them.",
"timeoutSeconds": 900
},
{
"example": {
"outputPath": "C:/proj/Filter.cir",
"schematic": "C:/proj/Filter.SchDoc"
},
"hint": "Altium writes this netlist only as part of a run, so the sheet is simulated too (its results land in the project's Simulation folder). Models come inline (.model, .subckt) or as includes. elements are exact; analyses are the lines Altium wrote, which can lag a sheet's newest settings by a run (measured: a transient ran while the file still read its earlier .AC): altium_simulate reports the analysis that ran.",
"input": {
"outputPath": "optional: copy the netlist here",
"schematic": "the .SchDoc (filePath works too); it must belong to a .PrjPcb beside it"
},
"longRunning": false,
"name": "altium_export_spice",
"output": {
"analyses": "[.AC / .TRAN / .DC / .OP lines]",
"elements": "[element lines]",
"format": "string",
"includes": "[.INCLUDE / .LIB lines]",
"path": "the netlist"
},
"pitfalls": [
"A part with no simulation model stops the netlister: export_failed."
],
"related": [
"altium_simulate"
],
"statusVerb": null,
"summary": "The schematic's SPICE netlist from Altium's mixed-signal simulator (the .nsx its Mixed Sim output writes): elements, analyses, models.",
"timeoutSeconds": 900
},
{
"example": {
"filePath": "C:/proj/Board.PcbDoc",
"refs": [
"U1"
]
},
"hint": "Plan first: each differing part's diff names the pads added, removed or changed (moved, resized, reshaped, redrilled, surface or through-hole) and a 3D body count that differs. apply:true replaces every differing part and reads them back: each must sit where it did and match its library. Save with altium_save.",
"input": {
"apply": "bool, default false: a plan; true replaces every differing footprint",
"expectedRevision": "string: refuse with stale_board if the board changed since the plan",
"filePath": "the .PcbDoc (required)",
"libraries": "[.PcbLib]: several",
"libraryPath": "a .PcbLib to take footprints from (default: the .PcbLibs the board's project lists; a part's own source library first)",
"refs": "[\"U1\"] (default every footprint)"
},
"longRunning": false,
"name": "altium_update_footprints_from_library",
"output": {
"differs": "int",
"footprints": "[{ref, footprint, library, status: up_to_date | differs | library_not_found, diff?: {padsAdded, padsRemoved, padsChanged: [{pad, changes}], bodies3d?}, why?}]",
"mutated": "bool",
"plan": "bool",
"problems": "[read-back problems] (apply)",
"replaced": "[{ref, replaced, netsKept, netsBefore}] (apply)",
"revision": "string"
},
"pitfalls": [
"A pad new in the library has no net, and a removed pad's net goes with it: read padsAdded and padsRemoved before apply.",
"Tracks are not moved to follow pads that moved: run altium_routing_drc after."
],
"related": [
"altium_edit_footprint",
"altium_footprint_from_land_pattern",
"altium_swap_footprint",
"altium_routing_drc",
"altium_save"
],
"statusVerb": null,
"summary": "Compare each placed footprint with its library's current one and, with apply:true, replace the ones that differ, keeping where the part sits (position, rotation, side), its designator and comment, its pad nets by pad number and its schematic link. KiCad's verb of the same name.",
"timeoutSeconds": 600
},
{
"example": {
"filePath": "C:/proj/Main.SchDoc",
"ops": [
{
"at": [
100,
80
],
"designator": "R9",
"libReference": "RES",
"op": "sch_place_part"
},
{
"op": "sch_connect_pins",
"pairs": [
{
"from": "R9.1",
"to": "U1.3"
}
]
}
]
},
"hint": "A part placed in op 0 can be wired in op 1. A failing op takes the batch back (errorCode op_failed, restored true); if Undo cannot bring the sheet back, errorCode partial says which ops ran. The sheet is left unsaved: altium_save keeps it.",
"input": {
"dryRun": "bool: check every op and answer the plan, change nothing",
"erc": "bool, default true: compile before and after for ercBefore / ercAfter (false skips both)",
"filePath": "the .SchDoc (required; sheet accepted)",
"ops": "[{op: sch_place_part | sch_connect_pins | sch_connect | sch_edit | sch_edit_label | sch_junction | sch_bus | sch_bus_entry | sch_connect_to_bus | sch_text | sch_delete_wire | sch_split_wire | sch_move_region | sch_reset_fields | sch_update_from_library | sch_swap_part | sch_fix_connectivity | annotate, ...that verb's arguments}] (required)",
"projectPath": "the .PrjPcb (default the project beside the sheet that lists it)"
},
"longRunning": false,
"name": "altium_sch_batch",
"output": {
"ercAfter": "and after",
"ercBefore": "{class: n} the sheet's Messages before",
"failedOp": "the index of the op that failed",
"mutated": "bool",
"restored": "bool: the sheet is as it was before the batch",
"results": "[{op, output}] in order",
"undoSteps": "int"
},
"pitfalls": [
"Altium edits the open sheet: the batch is one Undo step per op, not one for the whole batch.",
"An op naming another sheet is refused: a batch edits one sheet."
],
"related": [
"altium_sch_place_part",
"altium_sch_connect_pins",
"altium_build_schematic",
"altium_run_erc",
"altium_save"
],
"statusVerb": null,
"summary": "Apply a list of schematic edits to one sheet in order, all or nothing: each op is a schematic verb with its own arguments, seeing the sheet as the earlier ops left it. When one fails, Altium's Undo takes back the ops already applied and the sheet is checked back to where it was.",
"timeoutSeconds": 900
},
{
"example": {
"errorsOnly": true,
"sinceOffset": 0
},
"hint": "Carry next from call to call. The panel empties on every compile, so each call captures what is new into the bridge's own file and offsets are bytes of that file: they stay valid across compiles and restarts.",
"input": {
"errorsOnly": "bool: only errors and warnings",
"maxBytes": "int, default 200000",
"sinceOffset": "int, default 0: where the last call stopped (its next)"
},
"longRunning": false,
"name": "altium_log_tail",
"output": {
"entries": "[{level: error | warning | info, text, source: messages | <log file>, class?, document?, at}] oldest first",
"next": "the offset to pass next time",
"sources": "{messagesPanel, logFiles, captured}",
"truncated": "bool"
},
"pitfalls": [
"The Messages panel is read only while the agent is resident; with Altium closed only its log files are read.",
"Dialogs the bridge answered are in altium_dialog_log, not here."
],
"related": [
"altium_dialog_log",
"altium_compile",
"altium_run_drc",
"altium_diagnostics"
],
"statusVerb": null,
"summary": "What Altium said about itself since an offset: its Messages panel (compile, ERC, DRC and script messages) and its own log files, so a verb that looks successful while Altium complains is caught.",
"timeoutSeconds": 60
},
{
"example": {
"limit": 10
},
"hint": "p90 is the headline: a p50 of 15 s beside a p90 of 400 s is two code paths under one name. failures counts runs that answered success:false.",
"input": {
"limit": "int, default 40: how many verbs"
},
"longRunning": false,
"name": "altium_verb_times",
"output": {
"log": "the log file",
"since": "Unix seconds: when the log starts",
"verbs": "[{verb, count, p50Sec, p90Sec, maxSec, lastSec, failures}]"
},
"pitfalls": [
"Times are this machine's: a slower box or a bigger board moves them."
],
"related": [
"altium_diagnostics",
"altium_progress"
],
"statusVerb": null,
"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.",
"timeoutSeconds": 15
},
{
"example": {},
"hint": "The bridge host may run it after an install or update; running it again changes nothing that is already done.",
"input": {},
"longRunning": false,
"name": "altium_prewarm",
"output": {
"ready": "bool",
"running": "bool",
"steps": "[{step: detect | agent_files | first_run_dialogs | agent, done, skipped?, why?}]"
},
"pitfalls": [
"With Altium closed it only detects and writes the agent: the first verb that needs Altium still launches it."
],
"related": [
"altium_readiness",
"altium_agent_start",
"altium_launch"
],
"statusVerb": null,
"summary": "Get this machine ready for a fast first call: find the install, write the agent's script, and with Altium running answer its first-run boxes and make the agent resident. Idempotent; never opens a document or launches Altium.",
"timeoutSeconds": 120
},
{
"example": {
"filePath": "C:/proj/Board.PcbDoc",
"side": "top"
},
"hint": "The picture is of the board as saved in its project. One call per side for a review.",
"input": {
"filePath": "the .PcbDoc (required)",
"outputDir": "folder",
"side": "top | bottom (left, right, front and back are refused: Altium's 3D print looks straight down or up)",
"width": "px, default 1600"
},
"longRunning": false,
"name": "altium_render_board",
"output": {
"height": "px",
"optionsNotApplied": "[the standard's options Altium has no way to apply: height, quality, background, zoom, perspective, format, refs, marginMm, rotate]",
"path": "the PNG",
"width": "px"
},
"pitfalls": [
"Parts with no 3D body show as bare pads (altium_bodies lists them).",
"No framing on parts and no turned view: altium_show_3d_board opens a window for that."
],
"related": [
"altium_render_board_3d",
"altium_show_3d_board",
"altium_render_board_layers"
],
"statusVerb": null,
"summary": "A rendered 3D picture of a board from the top or bottom, by Altium's own 3D print with no window (render_board_3d under the standard's name).",
"timeoutSeconds": 300
},
{
"example": {
"fab": "jlcpcb",
"filePath": "C:/proj/Board.PcbDoc"
},
"hint": "Pair it with altium_bom (JLCPCB BOM) and the Gerbers for an assembly order; altium_export_manufacturing writes all three from an OutJob. Read: nothing on the board changes.",
"input": {
"excludeDnp": "bool, default true: leave out parts not fitted in the variant",
"fab": "jlcpcb: also write JLCPCB's CPL columns",
"filePath": "the .PcbDoc (required)",
"format": "csv | ascii (default csv); gerber is refused: Altium writes no Gerber placement file",
"outputDir": "folder (default 'Pick Place' beside the board)",
"projectPath": "the .PrjPcb (default the project beside the board that lists it)",
"side": "both | front | back, default both",
"smdOnly": "bool: leave out parts with a plated hole",
"units": "mm | in, default mm",
"variant": "the project variant whose not-fitted parts are left out (Altium marks DNP per variant)"
},
"longRunning": false,
"name": "altium_export_pos",
"output": {
"excluded": "{dnp: [ref], throughHole: [ref]}",
"files": "[path]",
"parts": "{front, back, total}",
"variant": "the variant used or null"
},
"pitfalls": [
"Rotations follow Altium's convention: a fab may turn some packages; check its preview.",
"DNP is per variant in Altium: with no variant every part is fitted."
],
"related": [
"altium_export_manufacturing",
"altium_bom",
"altium_assembly_check",
"altium_jlcpcb_order"
],
"statusVerb": null,
"summary": "The board's pick-and-place (component position, CPL) file: each part's reference point from the board origin, its rotation and side, as Altium's Pick Place output gives them; optionally JLCPCB's CPL beside it.",
"timeoutSeconds": 120
},
{
"example": {
"libraryPath": "C:/lib/Parts.SchLib"
},
"hint": "Rules: no_pads, zero_size_pad, unnumbered_pad, duplicate_pad_number, no_courtyard (Mechanical 15), no_silkscreen, no_3d_body, origin_off_part, no_description; no_pins, unnumbered_pin, duplicate_pin_number, no_part_number, no_footprint, footprint_not_found, pin_without_pad, pad_without_pin. Read-only.",
"input": {
"footprintLibraries": "[.PcbLib] for a SchLib: where the linked footprints are (default the .PcbLibs in the SchLib's folder); footprintLibrary for one",
"libraryPath": "the .PcbLib or .SchLib (required; filePath accepted too)",
"names": "[name] (default every footprint or symbol)"
},
"longRunning": false,
"name": "altium_lint_library",
"output": {
"checked": "int",
"errors": "int",
"findings": "[{name, kind: footprint|symbol, rule, severity: error|warning|info, detail}]",
"footprintLibraries": "[path] (SchLib)",
"infos": "int",
"ok": "bool: no errors and every item read",
"unread": "[{name, error}]",
"warnings": "int"
},
"pitfalls": [
"Each item is one read (about half a second): a library of hundreds takes minutes; names picks a few.",
"duplicate_pad_number is right for one pin on several pads (a thermal pad): it is a warning, not an error."
],
"related": [
"altium_read_footprint",
"altium_read_symbol",
"altium_edit_footprint",
"altium_pin_pad_check",
"altium_list_library"
],
"statusVerb": null,
"summary": "Check a .PcbLib or .SchLib before it ships: footprints without pads, courtyard, silkscreen or 3D body, with duplicate or missing pad numbers, an origin off the part or no description; symbols without pins or a footprint, with duplicate pin numbers or no part number, and pins that no pad of the linked footprint answers. KiCad's verb of the same name (KiCad's checks that the file parses; an Altium library always does, so this one checks what is in it).",
"timeoutSeconds": 600
},
{
"example": {
"parts": [
{
"ref": "U1",
"rotation": 90,
"x": 112.0,
"y": 92.0
}
]
},
"hint": "Rotation is absolute, not a delta. A part flipped to the bottom is mirrored by Altium; give the rotation you want as seen from the top.",
"input": {
"boardId": "string (optional) - refused with board_mismatch unless this is the current board",
"expectPath": "string (optional)",
"expectedRevision": "string (optional) - the revision you last read; refused with stale_board if the board changed",
"parts": "[{ref, x, y, rotation, side?: top|bottom, flip?: bool}] - mm and degrees, Altium's frame; or {ref, dx, dy} to move by an offset; rotation and side kept when left out"
},
"longRunning": false,
"name": "altium_move_parts",
"output": {
"mismatches": "[{ref, asked, got}] when a part did not land where asked (errorCode readback_mismatch)",
"results": "[ok|err:...]",
"revision": "string"
},
"pitfalls": [
"Flipping a part leaves its tracks where they were: they no longer reach its pads on the other side. Re-route after a flip."
],
"related": [
"altium_routing_state",
"altium_route_net"
],
"statusVerb": null,
"summary": "Move, rotate and flip placed components (side top or bottom; flip:true turns a part over); each part is read back to 0.001 mm, the exact rotation and its side. One undo step.",
"timeoutSeconds": 300
},
{
"example": {
"vias": [
{
"drill": 0.3,
"net": "GND",
"size": 0.6,
"x": 110.0,
"y": 90.0
}
]
},
"hint": "Through vias, top to bottom, on the named net. Heatsink vias under a pad: place them here, then pour or route to them.",
"input": {
"boardId": "string (optional) - refused with board_mismatch unless this is the current board",
"expectPath": "string (optional)",
"expectedRevision": "string (optional) - the revision you last read; refused with stale_board if the board changed",
"vias": "[{net, x, y, size, drill}] - mm"
},
"longRunning": false,
"name": "altium_place_vias",
"output": {
"counts": "{vias, ...}",
"results": "[ok|err:...]",
"revision": "string"
},
"pitfalls": [],
"related": [
"altium_route_net",
"altium_routing_state"
],
"statusVerb": null,
"summary": "Place vias (through, top to bottom). One undo step, read back.",
"timeoutSeconds": 300
},
{
"example": {
"vias": [
{
"x": 110.0,
"y": 90.0
}
]
},
"hint": "Undo a bad segment or via without touching the rest of the net; altium_ripup_nets clears a whole net.",
"input": {
"boardId": "string (optional) - refused with board_mismatch unless this is the current board",
"expectPath": "string (optional)",
"expectedRevision": "string (optional) - the revision you last read; refused with stale_board if the board changed",
"tracks": "[{start{x,y}, end{x,y}, layer}]",
"vias": "[{position{x,y}}] or [{x,y}]"
},
"longRunning": false,
"name": "altium_remove_items",
"output": {
"results": "[ok|err:not found]",
"revision": "string"
},
"pitfalls": [
"Matching is exact to the internal unit: pass the coordinates you read, not rounded ones."
],
"related": [
"altium_ripup_nets",
"altium_routing_state"
],
"statusVerb": null,
"summary": "Delete specific free tracks and vias, given exactly as altium_routing_state returned them. One undo step.",
"timeoutSeconds": 300
},
{
"example": {
"nets": [
"SW",
"VOUT"
]
},
"hint": "Pours are not touched.",
"input": {
"boardId": "string (optional) - refused with board_mismatch unless this is the current board",
"expectPath": "string (optional)",
"expectedRevision": "string (optional) - the revision you last read; refused with stale_board if the board changed",
"nets": "[string]"
},
"longRunning": false,
"name": "altium_ripup_nets",
"output": {
"results": "[ok:<deleted count>]",
"revision": "string"
},
"pitfalls": [],
"related": [
"altium_remove_items",
"altium_route_net"
],
"statusVerb": null,
"summary": "Delete every free track, arc and via on each named net. One undo step.",
"timeoutSeconds": 300
},
{
"example": {
"cutouts": [
{
"layer": "F.Cu",
"name": "Kelvin tap",
"points": [
[
20,
2
],
[
22,
2
],
[
22,
4
],
[
20,
4
]
]
}
],
"pours": [
{
"connect": "relief",
"layer": "B.Cu",
"net": "GND",
"points": [
[
0,
0
],
[
28,
0
],
[
28,
20
],
[
0,
20
]
],
"reliefGap": 0.25,
"reliefWidth": 0.35
},
{
"connect": "direct",
"layer": "F.Cu",
"net": "SW",
"order": 1,
"points": [
[
10,
5
],
[
16,
5
],
[
16,
9
],
[
10,
9
]
]
}
]
},
"hint": "connect writes a PolygonConnect rule 'AdomPC <name>' scoped IsNamedPolygon('<name>') that outranks the board's own, so a power patch can join its pads solid while the ground pour keeps spokes. Without connect the board's Polygon Connect Style applies (Altium's default is 4 relief spokes of 10 mil, a current neck). Clearance comes from the board's Clearance rule. Dead copper is removed unless removeDead is false.",
"input": {
"cutouts": "(optional) [{layer, points:[[x,y]...] mm, name?}] - areas every pour on that layer stays out of (KiCad's pour keepout); landed before the pours",
"expectedRevision": "string (optional) - refused with stale_board if the board changed since you read it",
"pours": "[{net, layer (F.Cu|B.Cu|In<n>.Cu), points:[[x,y]...] mm, order?: pour order (1 = poured first), name?: polygon name, connect?: direct|relief|none, reliefWidth?: mm spoke width, reliefGap?: mm air gap (not settable by script on AD 26: Altium keeps 10 mil and notes[] says so), reliefEntries?: 2|4, removeDead?: bool (default true), removeSmallIslands?: bool (default false: connected copper of any size stays, as in KiCad; true = Altium's own 2500 sq mil island filter), minNeck?: mm - copper narrower than this is removed (KiCad's zone min thickness), solidPads?: [[x1,y1,x2,y2]] mm - pads completely inside each rect join THIS pour solid whatever its connect (KiCad's small solid joint zone over a pad; Altium pours nothing for a same-net polygon inside another)}]"
},
"longRunning": false,
"name": "altium_apply_pours",
"output": {
"filledAreaByLayerMm2": "{F.Cu: mm2, ...}",
"results": "[ok:<polygon name>|err:...]",
"revision": "string",
"unfilled": "[zone] that poured nothing",
"zones": "[{net, layer, outline, filledMm2, islands, filled}]"
},
"pitfalls": [
"Needs the board current.",
"The outline need not repeat its first point.",
"A name already on the board gets a ' 2' suffix: read the real name from results."
],
"related": [
"altium_pour_state",
"altium_repour",
"altium_remove_pours",
"altium_routing_state",
"altium_set_design_rules"
],
"statusVerb": null,
"summary": "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); answers each pour's real poured copper area. One undo step.",
"timeoutSeconds": 600
},
{
"example": {},
"hint": "filledMm2 is regions minus holes, computed from Altium's own poured geometry.",
"input": {},
"longRunning": false,
"name": "altium_pour_state",
"output": {
"filledAreaByLayerMm2": "{layer: mm2}",
"unfilled": "[zone]",
"zones": "[{net, name, layer, pourIndex, outline, filledMm2, islands, filled}]"
},
"pitfalls": [
"Needs the board current.",
"A shelved or unpoured polygon reads filledMm2 0."
],
"related": [
"altium_apply_pours",
"altium_repour"
],
"statusVerb": null,
"summary": "Every polygon pour with the copper it actually poured: filled area per pour and per layer, and the pours that poured nothing.",
"timeoutSeconds": 180
},
{
"example": {
"pours": [
{
"net": "GND"
}
]
},
"hint": "Use before re-pouring a changed plan; the connect rules of removed pours go with them. altium_ripup_nets clears copper.",
"input": {
"cutouts": "(optional) \"all\" or [{layer}] - only the cutouts apply_pours landed (named Adom...)",
"expectedRevision": "string (optional) - refused with stale_board if the board changed since you read it",
"pours": "(optional) \"all\" or [{net, layer?} | {name} - one pour by the name apply_pours answered]"
},
"longRunning": false,
"name": "altium_remove_pours",
"output": {
"cutoutsRemoved": "int",
"removed": "int",
"revision": "string",
"rulesRemoved": "int - AdomPC connect rules whose pour is gone"
},
"pitfalls": [],
"related": [
"altium_apply_pours",
"altium_ripup_nets"
],
"statusVerb": null,
"summary": "Delete polygon pours by net (and layer), or all of them, and the pour keepouts (cutouts) apply_pours made. Tracks and vias are untouched.",
"timeoutSeconds": 300
},
{
"example": {},
"hint": "Run after moving parts or copper that pours flow around. Altium evaluates rule queries through its scripting system, so a repour from inside the resident agent ignores every scoped rule (a pour's own connect style, net-class clearances); this verb stops the agent, repours, and starts it again (a few seconds). apply_pours does the same on its own when it wrote connect rules.",
"input": {
"inScript": "bool (default false) - repour from inside the agent instead (scoped rules then match nothing)"
},
"longRunning": false,
"name": "altium_repour",
"output": {
"filledAreaByLayerMm2": "{...}",
"run": "{helperExited, seconds, agentStart}",
"unfilled": "[...]",
"zones": "[...]"
},
"pitfalls": [
"Needs the board current.",
"The agent restarts: a verb sent meanwhile waits for it."
],
"related": [
"altium_pour_state",
"altium_apply_pours"
],
"statusVerb": null,
"summary": "Repour every polygon on the board (Altium's Repour All) and answer the copper after. Runs outside the script engine so scoped rules apply.",
"timeoutSeconds": 600
},
{
"example": {
"full": true
},
"hint": "Without full, this reads online DRC's live violations (fast). full:true runs the batch check through Altium's DRC dialog first.",
"input": {
"full": "bool (default false) - run Altium's batch DRC on this board first"
},
"longRunning": false,
"name": "altium_routing_drc",
"output": {
"clean": "bool - no violations and nothing unrouted",
"errors": "int",
"unconnected": "int",
"violations": "[{rule, description, at{x,y} mm}]"
},
"pitfalls": [
"Needs the board current.",
"violations[] is capped at 500; errors is the real count."
],
"related": [
"altium_routing_state",
"altium_run_drc"
],
"statusVerb": null,
"summary": "Design-rule violations on the current board WITH locations, plus the unrouted (ratsnest) count, as one clean/not-clean answer.",
"timeoutSeconds": 300
},
{
"example": {
"libraryPath": "C:/designs/buck/Buck.PcbLib",
"nets": {
"GND": [
"U1.1"
]
},
"outline": {
"cornerRadius": 1,
"rect": [
0,
0,
28,
20
]
},
"parts": [
{
"footprint": "SOT-23-6",
"ref": "U1",
"rotation": 0,
"x": 12,
"y": 10
}
],
"pcbPath": "C:/designs/buck/buck.PcbDoc"
},
"hint": "The board AI Flow's Altium project builds from its netlist. Footprint pad names must match the netlist's pin numbers (R1.1 = pad 1 of R1). Coordinates are Altium's frame (y up).",
"input": {
"libraryPath": "string (required) - the .PcbLib holding every footprint",
"nets": "{net: [\"R1.1\", \"U1.3\", ...]}",
"outline": "{rect:[x0,y0,w,h], cornerRadius?} or {points:[[x,y]...]} (mm)",
"parts": "[{ref, footprint, x, y, rotation, comment?}] (mm, degrees; x,y is the footprint's own origin)",
"pcbPath": "string (required) - the .PcbDoc to write"
},
"longRunning": false,
"name": "altium_build_board",
"output": {
"counts": "{...}",
"missingParts": "[ref]",
"padsWired": "int",
"placed": "int",
"revision": "string",
"unconnected": "int - the ratsnest to route",
"wrongPins": "[{pin, want, got}]"
},
"pitfalls": [
"The library must open in this Altium; a footprint missing from it refuses the whole build (footprint_not_found).",
"A new board each call: pcbPath is overwritten."
],
"related": [
"altium_routing_state",
"altium_set_outline",
"altium_install_library"
],
"statusVerb": null,
"summary": "Build a NEW board from a parts list and a netlist: outline (rounded corners allowed), every footprint from one PcbLib placed by its own origin, pad nets assigned, saved; then read back pin by pin.",
"timeoutSeconds": 900
},
{
"example": {
"outline": {
"cornerRadius": 1,
"rect": [
0,
0,
28,
20
]
}
},
"hint": "Rounding corners: pass the same rectangle with cornerRadius (1 mm is a common default).",
"input": {
"expectedRevision": "string (optional) - refused with stale_board if the board changed",
"outline": "{rect:[x0,y0,w,h], cornerRadius?} or {points:[[x,y]...]} (mm)"
},
"longRunning": false,
"name": "altium_set_outline",
"output": {
"outlineEdges": "[{kind: line|arc, ...}]",
"revision": "string",
"vertices": "int"
},
"pitfalls": [
"Needs the board current."
],
"related": [
"altium_build_board",
"altium_routing_state",
"altium_repour"
],
"statusVerb": null,
"summary": "Reshape the current board's outline (a rectangle with rounded corners, or a polygon). One undo step.",
"timeoutSeconds": 120
},
{
"example": {
"clearance": 0.15,
"edgeClearance": 0.3,
"hole": {
"min": 0.2
},
"trackWidth": {
"min": 0.15
},
"via": {
"diameter": {
"min": 0.45
},
"drill": {
"min": 0.2
}
}
},
"hint": "AI Flow's `rules use` calls this with the fab pack's numbers (adom/pcb-design-rules). Each kind is written separately, so one this Altium build lacks fails alone.",
"input": {
"annularRing": "mm",
"clearance": "mm",
"costlier": "with fab: allow JLCPCB's surcharged small vias (0.15/0.25 mm) instead of 0.3/0.5",
"edgeClearance": "mm - copper to the board edge (the rule it creates is scoped OnCopper; silkscreen keeps its own rules)",
"fab": "jlcpcb - fill every value left out from JLCPCB's published limits for this board's layers and copper weight",
"hole": "{min, max?} mm",
"holeToHole": "mm",
"polygonConnect": "the board's catch-all polygon connect style: direct|relief|none, or {style, reliefWidth: mm, reliefEntries: 2|4} (per-pour rules from apply_pours keep theirs)",
"trackWidth": "{min, preferred?, max?} mm",
"via": "{diameter:{min, preferred?, max?}, drill:{min, preferred?, max?}} mm"
},
"longRunning": false,
"name": "altium_set_design_rules",
"output": {
"failed": "[{kind, error}]",
"landed": "[{kind, rulesWritten}]",
"rules": "the board's rules after"
},
"pitfalls": [
"Needs the board current.",
"Every existing rule of a kind gets the values; rule scopes are kept, except an Adom edge rule an earlier bridge scoped to All, which becomes OnCopper (#26)."
],
"related": [
"altium_read_rules",
"altium_rules_by_kind",
"altium_build_board"
],
"statusVerb": null,
"summary": "Write a fab's design rules into the current board: clearance, track width, routing via style, hole size, annular ring, hole-to-hole and board-edge clearance (mm).",
"timeoutSeconds": 300
},
{
"example": {
"gap": 0.3,
"kind": "clearance",
"name": "SW node",
"scope1": "InNet('SW')",
"scope2": "All"
},
"hint": "AI Flow's net clearances (a switch node kept farther from everything) land here. A scope with a typo matches nothing and DRC then passes silently: check it in the rules editor (Test Queries).",
"input": {
"comment": "optional",
"drill": "mm (via)",
"gap": "mm (clearance; diffpair: the pair's gap)",
"kind": "clearance|width|length|matched|diffpair|via|polyconnect",
"max": "mm (width, optional; length: required)",
"maxDrill": "via, optional",
"maxGap": "diffpair, optional",
"maxSize": "via, optional",
"maxUncoupled": "mm, diffpair, optional",
"maxWidth": "diffpair, optional",
"min": "mm (width; length)",
"minDrill": "via, optional",
"minGap": "diffpair, optional",
"minSize": "via, optional",
"minWidth": "diffpair, optional",
"name": "string - the rule is named 'Adom <name>'; the same name replaces it",
"preferred": "mm (width, optional)",
"reliefEntries": "2 | 4, polyconnect relief",
"reliefWidth": "mm, polyconnect relief spokes",
"remove": "bool - delete the Adom rule of this kind and name instead",
"scope1": "Altium query, e.g. InNet('SW'), InNetClass('DDR_D0'), InDifferentialPair('USB')",
"scope2": "query (default All; clearance, and polyconnect: the polygon, e.g. InPolygon('GND pour'))",
"size": "mm (via)",
"style": "polyconnect: direct | relief | none",
"tolerance": "mm (matched)",
"width": "mm (diffpair)"
},
"longRunning": false,
"name": "altium_add_rule",
"output": {
"name": "string",
"priority": "int (1 = first of its kind)"
},
"pitfalls": [
"Needs the board current.",
"One rule per call."
],
"related": [
"altium_set_design_rules",
"altium_read_rules",
"altium_routing_drc"
],
"statusVerb": null,
"summary": "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 group, a differential pair's width and gap, a routing via style, or how a net's pads join a pour (direct, relief, none).",
"timeoutSeconds": 60
},
{
"example": {
"libraryPath": "C:\\work\\library\\Buck.SchLib",
"nets": {
"VIN": [
"U1.3"
]
},
"parts": [
{
"block": "core",
"comment": "TPS54202",
"ref": "U1",
"symbol": "TPS54202DDCR"
}
],
"schPath": "C:\\work\\Buck.SchDoc"
},
"hint": "One column per block, each part with a wire stub and a net label on every connected pin; designator above, value below; title block filled. The compiled netlist is the proof: success means it matches the given nets.",
"input": {
"drawnBy": "optional",
"libraryPath": "string - the project .SchLib",
"nets": "{net: [\"U1.3\", ...]} - pins of parts not on the sheet are ignored",
"number": "optional",
"parts": "[{ref, symbol: LibReference in the SchLib, block?: column name (input, core, output...), comment?: value, footprint?: its footprint in pcbLibPath (the part's PCB model link)}]",
"pcbLibPath": "(optional)",
"pcbPath": "(optional) the board, listed in the project",
"projectPath": "(optional) .PrjPcb, default beside the sheet",
"revision": "optional",
"schPath": "string - the .SchDoc to write",
"title": "optional"
},
"longRunning": false,
"name": "altium_build_schematic",
"output": {
"compileErrors": "[..]",
"labels": "int",
"mismatches": "[{net, missing, extra}]",
"pinsWithoutNet": "ref.pin;...",
"placed": "int",
"project": "path",
"sch": "path",
"wires": "int"
},
"pitfalls": [
"The SchLib must hold every symbol (altium_import_part).",
"Parts are placed unrotated."
],
"related": [
"altium_schematic_data",
"altium_compile",
"altium_build_board"
],
"statusVerb": null,
"summary": "Draw a design's schematic from its netlist with the project library's symbols, inside a new project (.PrjPcb with the board and libraries), compile it, and check its netlist pin by pin.",
"timeoutSeconds": 900
},
{
"example": {
"pcbPath": "C:\\work\\Buck.PcbDoc",
"projectPath": "C:\\work\\Buck.PrjPcb"
},
"hint": "Pull files[] with pull_file and check them against the board (layers, drill hits, every placed part in the pick and place and the BOM) before handing them over. AI Flow's `altium export` does both.",
"input": {
"bomColumns": "(optional) [column or parameter name] - default Comment, Description, Designator, Footprint, Quantity, MPN, Manufacturer, Mouser/DigiKey/LCSC Part #",
"clean": "bool (default true) - empty the output folder first",
"formats": "[odb, ipc2581] - more fab formats beside the Gerbers (ODB++ folder + .tgz, IPC-2581 .cvg); default Gerbers only",
"pcbPath": "its .PcbDoc",
"projectPath": "the .PrjPcb",
"silkPrep": "bool (default true) - Altium's Silkscreen Preparation first (silk off the pads, text moved where it fits)",
"silkPrepCheck": "bool (default false) - DRC silk counts before/after in silkPrep",
"timeout": "seconds, default 300"
},
"longRunning": false,
"name": "altium_export_manufacturing",
"output": {
"dialogs": "[..]",
"elapsedSec": "float",
"files": "[relative paths]",
"outjob": "path",
"outputDir": "path"
},
"pitfalls": [
"The board must be a document of the project.",
"The BOM is the compiled project's (schematic parts); board-only pads are not in it."
],
"related": [
"altium_run_outjob",
"altium_build_schematic",
"altium_routing_state"
],
"statusVerb": null,
"summary": "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 (composed from this Altium's own OutJob templates, every output on one medium that opens nothing).",
"timeoutSeconds": 600
},
{
"example": {
"net": "SW",
"zoom": true
},
"hint": "AI Flow's net walkthrough lights each loaded net in turn. Altium draws a selection in its highlight colour.",
"input": {
"margin": "mm, default 1",
"net": "string (optional) - empty or absent clears",
"zoom": "bool - frame the net (altium_zoom_to)"
},
"longRunning": false,
"name": "altium_select_net",
"output": {
"byKind": "{tracks, arcs, vias, pads, pours, other}",
"net": "string",
"selected": "int",
"zoom": "[l, b, r, t] mm when zoom"
},
"pitfalls": [
"Needs the board current.",
"Pour regions are counted once, as their polygon."
],
"related": [
"altium_zoom_to",
"altium_routing_state",
"altium_list_nets"
],
"statusVerb": null,
"summary": "Select one net as a whole on the current board (tracks, arcs, vias, pads, pours) and nothing else, optionally framing it; no net clears the selection.",
"timeoutSeconds": 120
},
{
"example": {},
"hint": "The input to a silkscreen plan (AI Flow's `altium silkscreen`), and its check after landing: compare each box with the pads and vias from routing_state.",
"input": {},
"longRunning": false,
"name": "altium_silk_state",
"output": {
"components": "[{ref, pattern, x, y, rotation, side, body:[l,b,r,t], name:{text,x,y,size,rotation,shown,box}, comment:{...}}]",
"lines": "[{side, x1, y1, x2, y2, width, raw}]",
"texts": "[{side, text, x, y, size, rotation, mirror, box, raw}]"
},
"pitfalls": [
"Needs the board current.",
"raw is the exact handle apply_silkscreen's remove takes."
],
"related": [
"altium_apply_silkscreen",
"altium_routing_state"
],
"statusVerb": null,
"summary": "The silkscreen as it stands: every part's body box, its designator and comment (text, location, size, rotation, shown, Altium's measured box), and the free overlay texts and lines on both faces.",
"timeoutSeconds": 180
},
{
"example": {
"lines": [
{
"x1": 1,
"x2": 5,
"y1": 1,
"y2": 1
}
],
"names": [
{
"ref": "U1",
"size": 0.8,
"x": 12.0,
"y": 14.2
}
]
},
"hint": "A text's location is its lower left before rotation (for 90 degrees: the box's lower right). Stroke width is a seventh of the height.",
"input": {
"comments": "[same] - the value",
"lines": "[{x1, y1, x2, y2, width?: mm (0.15), side?}]",
"names": "[{ref, x, y, size, rotation?, show?}] - the designator's own location, mm",
"remove": "{texts:[raw], lines:[raw]} - silk_state raw handles of earlier free items",
"texts": "[{text, x, y, size, rotation?, side?: top|bottom}]"
},
"longRunning": false,
"name": "altium_apply_silkscreen",
"output": {
"after": "silk_state",
"applied": "int",
"failed": "int",
"results": "[ok|err:...]"
},
"pitfalls": [
"Needs the board current.",
"Removal matches the raw handle exactly: pass what silk_state answered."
],
"related": [
"altium_silk_state",
"altium_routing_drc"
],
"statusVerb": null,
"summary": "Land a silkscreen plan in one undo step: designators and comments moved, sized and turned (or hidden), free overlay texts and lines added (bottom texts mirrored), earlier ones removed; answers silk_state after.",
"timeoutSeconds": 600
},
{
"example": {
"margin": 0.5,
"net": "SW"
},
"hint": "For a close look at a joint or a camera shot of one part or net; altium_run_command PCB:Zoom Action=All frames the whole board.",
"input": {
"margin": "mm (default 1)",
"net": "(optional) a net: its pads, tracks and vias",
"rect": "(optional) [x1, y1, x2, y2] mm",
"ref": "(optional) a designator, e.g. U1",
"refs": "(optional) [designator]"
},
"longRunning": false,
"name": "altium_zoom_to",
"output": {
"rect": "[left, bottom, right, top] mm framed"
},
"pitfalls": [
"Needs the board current.",
"Coordinates are Altium's (y up), as routing_state reports them."
],
"related": [
"altium_routing_state",
"altium_run_command",
"altium_animate_view"
],
"statusVerb": null,
"summary": "Frame the PCB view on a rectangle, a part (or several) or a whole net, with a margin.",
"timeoutSeconds": 60
},
{
"example": {
"designator": "U1"
},
"hint": "Use it to verify an imported footprint on a altium_test_board: pad layerId 74 = multi-layer (plated through), which is what altium_plate_vias produces.",
"input": {
"designator": "string (required) - a component on the current board, e.g. U1"
},
"longRunning": false,
"name": "altium_footprint_primitives",
"output": {
"data": "{designator, pattern, count, otherPrimitives, primitives: [{kind: track|arc|pad|text, layerId, ...}]}",
"roundtripMs": "int"
},
"pitfalls": [
"Needs a .PcbDoc current: it reads a placed component, not a PcbLib member (altium_pcb_report reads libraries).",
"3D bodies, fills and regions only show up in otherPrimitives."
],
"related": [
"altium_component_pins",
"altium_plate_vias",
"altium_test_board",
"altium_pcb_report"
],
"statusVerb": null,
"summary": "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 kinds are counted.",
"timeoutSeconds": 120
},
{
"example": {
"designator": "U1"
},
"hint": "Pin-level view of a sheet. params[] is empty unless you pass params:true; altium_read_schematic is the fuller parameter view.",
"input": {
"designator": "string - optional filter",
"filePath": "path to the .SchDoc - optional, made current first (alias sheet)",
"limit": "int, default 500",
"paramBudgetSec": "number, default 60 (0-100): the time Altium gets for parameters and descriptions; parts past it come back with their parameters read from the saved file (paramsFromFile, paramsSkipped, paramsComplete false) instead of the call timing out",
"paramNamesOnly": "bool, default false - parameter names without values (a library with blob parameters reads fast)",
"params": "bool, default false - include each component's parameters",
"pins": "bool, default true"
},
"longRunning": false,
"name": "altium_schematic_data",
"output": {
"data": "{document, count, components: [{designator, partId, libReference, comment, description (empty for a workspace-managed part), kind (ComponentKind: 0 Standard, 1 Mechanical, 2 Graphical, 3 Net Tie BOM, 4 Net Tie, 5 Standard no BOM, 6 Jumper), itemGuid, vaultGuid, sourceLibrary, xMil, yMil, orientation, pins: [{number, name, electrical (0 Input, 1 IO, 2 Output, 3 OpenCollector, 4 Passive, 5 HiZ, 6 OpenEmitter, 7 Power), xMil, yMil, orientation, lengthMil}], params: []}]}",
"roundtripMs": "int"
},
"pitfalls": [
"One sheet per call. Without filePath the current document must be a .SchDoc: a schematic library is refused (no_current_schematic), not read as an empty sheet.",
"electrical is Altium's pin-type ordinal, not a name."
],
"related": [
"altium_read_schematic",
"altium_cross_check",
"altium_show_schematic"
],
"statusVerb": null,
"summary": "Components on a schematic sheet (filePath, else the CURRENT sheet) with their pins (number, name, electrical type), position and orientation. designator filters to one part.",
"timeoutSeconds": 120
},
{
"example": {
"filePath": "C:/proj/board.PrjPcb"
},
"hint": "A project has no document view of its own: follow with altium_show_schematic / altium_show_2d_board {filePath} for something to look at, or altium_compile {projectPath}.",
"input": {
"filePath": "path to a .PrjPcb - default: the bundled Bluetooth Sentinel example",
"timeout": "seconds, default 60"
},
"longRunning": false,
"name": "altium_show_project",
"output": {
"dialogs": "[..]",
"dialogsDetected": "int",
"document": "string",
"elapsedSec": "float",
"path": "string",
"shot": "{image: base64 png, width, height}",
"steps": "[{open, result, ms}]",
"surface": "project",
"title": "string",
"windowEtiquette": "background"
},
"pitfalls": [
"ALWAYS pass filePath for the user's work: the default opens Altium's example project in their session.",
"Measured live 2026-09-20: opening documents RAISES Altium over the user's work even though the reply says background. One call per proof; never loop show_* verbs.",
"success:false with dialogs[] means a box came up during the open: read it before anything else."
],
"related": [
"altium_show_schematic",
"altium_show_2d_board",
"altium_compile",
"altium_open_project"
],
"statusVerb": null,
"summary": "Open a project (.PrjPcb) through the agent and return a proof frame of Altium's main window. With no filePath it opens Altium's bundled example project (Bluetooth Sentinel).",
"timeoutSeconds": 120
},
{
"example": {
"filePath": "C:/proj/tof.SchDoc"
},
"hint": "LOOK at shot.image before claiming anything. Then altium_read_schematic for the data, or altium_animate_view {lane:'sch'} for zoom moves.",
"input": {
"filePath": "path to a .SchDoc - default: the bundled example sheet",
"timeout": "seconds, default 60"
},
"longRunning": false,
"name": "altium_show_schematic",
"output": {
"dialogs": "[..]",
"dialogsDetected": "int",
"document": "string",
"elapsedSec": "float",
"path": "string",
"shot": "{image: base64 png, width, height}",
"steps": "[{open | process, ...}]",
"surface": "schematic",
"title": "string",
"windowEtiquette": "background"
},
"pitfalls": [
"ALWAYS pass filePath: the default opens Altium's example design in the user's session.",
"Measured live 2026-09-20: it RAISES Altium over the user's work. One call per proof; never loop it.",
"After re-generating a sheet at the same path, altium_close_document the stale one first or the frame shows the OLD document."
],
"related": [
"altium_read_schematic",
"altium_place_on_sch",
"altium_animate_view",
"altium_show_2d_board"
],
"statusVerb": null,
"summary": "Open a .SchDoc, zoom to fit, and return a proof frame. With no filePath it opens the bundled Bluetooth Sentinel top sheet.",
"timeoutSeconds": 120
},
{
"example": {
"filePath": "C:/proj/tof.PcbDoc"
},
"hint": "It also makes the board the CURRENT document, so altium_read_board / altium_board_summary work right after. altium_show_3d_board for the 3D frame.",
"input": {
"filePath": "path to a .PcbDoc - default: the bundled example board",
"timeout": "seconds, default 120"
},
"longRunning": false,
"name": "altium_show_2d_board",
"output": {
"dialogs": "[..]",
"dialogsDetected": "int",
"document": "string",
"elapsedSec": "float",
"path": "string",
"shot": "{image: base64 png, width, height}",
"steps": "[{open | process, ...}]",
"surface": "2d_board",
"title": "string",
"windowEtiquette": "background"
},
"pitfalls": [
"ALWAYS pass filePath: the default opens Altium's example board in the user's session.",
"Measured live 2026-09-20: it RAISES Altium over the user's work. One call per proof; never loop it."
],
"related": [
"altium_show_3d_board",
"altium_read_board",
"altium_set_layer_visibility",
"altium_animate_view"
],
"statusVerb": null,
"summary": "Open a .PcbDoc, switch to 2D, zoom to fit, and return a proof frame. With no filePath it opens the bundled Bluetooth Sentinel board.",
"timeoutSeconds": 120
},
{
"example": {
"filePath": "C:/proj/tof.PcbDoc"
},
"hint": "The proof for altium_test_board {pcbPath}: check every part shows a body. Missing body = the footprint has none (altium_add_body). altium_animate_view {preset:'showcase3d'} for motion.",
"input": {
"filePath": "path to a .PcbDoc - default: the bundled example board",
"timeout": "seconds, default 120"
},
"longRunning": false,
"name": "altium_show_3d_board",
"output": {
"dialogs": "[..]",
"dialogsDetected": "int",
"document": "string",
"elapsedSec": "float",
"path": "string",
"shot": "{image: base64 png, width, height}",
"steps": "[{open | process, ...}]",
"surface": "3d_board",
"title": "string",
"windowEtiquette": "background"
},
"pitfalls": [
"ALWAYS pass filePath: the default opens Altium's example board in the user's session.",
"Measured live 2026-09-20: it RAISES Altium over the user's work. One call per proof; never loop it.",
"It leaves the board in 3D mode for the user; altium_show_2d_board switches back."
],
"related": [
"altium_show_2d_board",
"altium_test_board",
"altium_add_body",
"altium_animate_view"
],
"statusVerb": null,
"summary": "Open a .PcbDoc, switch to 3D, zoom to fit, and return a proof frame. With no filePath it opens the bundled Bluetooth Sentinel board.",
"timeoutSeconds": 120
},
{
"example": {
"libraryPath": "C:/lib/Adom_ToF.SchLib"
},
"hint": "Then altium_show_symbol / altium_show_footprint / altium_show_3d_chip {libraryPath, name} for one member. altium_list_library gives the names without a frame.",
"input": {
"libraryPath": "path to a .SchLib/.PcbLib (alias: filePath) - default: the bundled SpiritLevel SchLib",
"timeout": "seconds, default 60"
},
"longRunning": false,
"name": "altium_show_library",
"output": {
"componentCount": "int",
"components": "[string] up to 200",
"dialogs": "[..]",
"path": "string",
"selected": "string",
"shot": "{image: base64 png, width, height}",
"steps": "[..]",
"surface": "library",
"windowEtiquette": "background"
},
"pitfalls": [
"ALWAYS pass libraryPath: the default opens Altium's example library in the user's session.",
"Measured live 2026-09-20: it RAISES Altium over the user's work. One call per proof; never loop it.",
"errorCode proof_unavailable = opened and selected correctly, only the capture failed (window minimized)."
],
"related": [
"altium_list_library",
"altium_show_symbol",
"altium_show_footprint",
"altium_show_3d_chip"
],
"statusVerb": null,
"summary": "Open a .SchLib or .PcbLib (kind taken from the extension), select its first component, return a proof frame and the component names.",
"timeoutSeconds": 120
},
{
"example": {
"footprintName": "VL53L5CX",
"libraryPath": "C:/lib/Adom_ToF.PcbLib"
},
"hint": "Check pads, silkscreen and courtyard in shot.image; altium_pcb_report {path, name} gives the numbers. altium_show_3d_chip for the body.",
"input": {
"footprintName": "string (alias: name) - default: the first footprint of YOUR library, SO-G3 in the demo library",
"libraryPath": "path to a .PcbLib (alias: filePath) - default: the bundled SpiritLevel PcbLib",
"timeout": "seconds, default 60"
},
"longRunning": false,
"name": "altium_show_footprint",
"output": {
"available": "[string] - when the name was not found",
"dialogs": "[..]",
"path": "string",
"selected": "string",
"shot": "{image: base64 png, width, height}",
"steps": "[..]",
"surface": "footprint",
"windowEtiquette": "background"
},
"pitfalls": [
"Measured live 2026-09-20: it RAISES Altium over the user's work. One call per proof; never loop it.",
"A wrong footprintName fails with available[] (up to 50 names): pick from it.",
"An empty-looking canvas usually means a 3D body sits 50000 mil from the pads: altium_normalize_bodies."
],
"related": [
"altium_show_3d_chip",
"altium_pcb_report",
"altium_build_footprint",
"altium_list_library"
],
"statusVerb": null,
"summary": "Open a PcbLib member in the footprint editor in 2D, zoom to fit, and capture a proof frame.",
"timeoutSeconds": 120
},
{
"example": {
"footprintName": "VL53L5CX",
"libraryPath": "C:/lib/Adom_ToF.PcbLib"
},
"hint": "The proof after altium_add_body / altium_import_part {step}. Pads with no body in the frame: altium_pcb_report to see whether a body exists, altium_normalize_bodies if it sits off the pads.",
"input": {
"footprintName": "string (alias: name) - default: the first footprint of YOUR library, SO-G3 in the demo library",
"libraryPath": "path to a .PcbLib (alias: filePath) - default: the bundled SpiritLevel PcbLib",
"timeout": "seconds, default 60"
},
"longRunning": false,
"name": "altium_show_3d_chip",
"output": {
"available": "[string] - when the name was not found",
"dialogs": "[..]",
"path": "string",
"selected": "string",
"shot": "{image: base64 png, width, height}",
"steps": "[..]",
"surface": "3d_chip",
"windowEtiquette": "background"
},
"pitfalls": [
"Measured live 2026-09-20: it RAISES Altium over the user's work. One call per proof; never loop it.",
"It leaves the library editor in 3D mode; altium_show_footprint switches back to 2D."
],
"related": [
"altium_show_footprint",
"altium_add_body",
"altium_normalize_bodies",
"altium_pcb_report"
],
"statusVerb": null,
"summary": "Open a PcbLib member in the footprint editor in 3D, zoom to fit, and capture a proof frame of the part's 3D body.",
"timeoutSeconds": 120
},
{
"example": {
"libraryPath": "C:/lib/Adom_ToF.PcbLib"
},
"hint": "Use the exact names with altium_show_symbol / altium_read_symbol / altium_show_footprint / altium_pcb_report.",
"input": {
"libraryPath": "path to a .SchLib/.PcbLib (alias: filePath) - default: the bundled SpiritLevel SchLib",
"limit": "int, default 500"
},
"longRunning": false,
"name": "altium_list_library",
"output": {
"data": "{kind: sch|pcb, count, names: [string]}",
"kind": "sch | pcb",
"path": "string",
"roundtripMs": "int"
},
"pitfalls": [
"It makes the library the current document.",
"count is the true total; names[] stops at limit."
],
"related": [
"altium_show_library",
"altium_read_symbol",
"altium_pcb_report"
],
"statusVerb": null,
"summary": "Names of every component in a .SchLib or every footprint in a .PcbLib (kind taken from the extension). Opens the library; no screenshot.",
"timeoutSeconds": 60
},
{
"example": {
"filePath": "C:/lib/Adom_ToF.SchLib"
},
"hint": "Pass filePath every time: every library authoring verb leaves the library UNSAVED. Then altium_check_dialogs - a 'Save As' box means the document never had a path.",
"input": {
"filePath": "path - optional; opened and made current before the save"
},
"longRunning": false,
"name": "altium_save",
"output": {
"data": "{process, params}",
"roundtripMs": "int"
},
"pitfalls": [
"Without filePath it saves whatever has focus, which may be the user's document rather than yours.",
"success only means the save process was dispatched; a Save As dialog blocks the engine until answered."
],
"related": [
"altium_close_document",
"altium_check_dialogs",
"altium_close"
],
"statusVerb": null,
"summary": "Save the focused document, or the document at filePath (opened first if need be, saved by its path, never whatever happens to have focus).",
"timeoutSeconds": 60
},
{
"example": {
"hMm": 14,
"pcbPath": "C:/proj/tof.PcbDoc",
"wMm": 39
},
"hint": "Then altium_save {filePath: pcbPath} and altium_show_2d_board {filePath} to see it. altium_pcb_report {want:'board'} reads outlineMil back.",
"input": {
"hMm": "number, default 15",
"mechOutline": "bool - also draw the rectangle as 0.1 mm tracks on Mechanical 1 so the fab Gerber (.GM1) has an outline",
"pcbPath": "path to a .PcbDoc - optional; opened first",
"timeout": "seconds, default 120",
"wMm": "number, default 15",
"x0Mm": "number, default 0",
"y0Mm": "number, default 0"
},
"longRunning": false,
"name": "altium_board_shape",
"output": {
"data": "{outlineMil: [left, bottom, right, top] read from the outline vertices, outlineSource, mechOutlineTracks}",
"roundtripMs": "int"
},
"pitfalls": [
"errorCode no_board_outline: the current document is a PcbLib (its internal board has no outline) - pass pcbPath.",
"bad_size = wMm/hMm not greater than 0; bad_number = a value was not numeric.",
"It REPLACES the outline; the previous shape is not kept.",
"The board shape alone is NOT plotted into any Gerber: pass mechOutline:true (once, at the final size: each call adds a new set of tracks)."
],
"related": [
"altium_test_board",
"altium_pcb_report",
"altium_show_2d_board",
"altium_save"
],
"statusVerb": null,
"summary": "Redefine the CURRENT board's outline as a wMm x hMm rectangle at (x0Mm, y0Mm) by rewriting the board outline's segments.",
"timeoutSeconds": 120
},
{
"example": {
"name": "VL53L5CX",
"path": "C:/lib/Adom_ToF.PcbLib"
},
"hint": "bodies[] rows follow bodyCols (layerId,wMil,hMil,leftMil,bottomMil,standoffMil,overallMil,hasModel). A body whose leftMil is ~50000 away from padsBboxMil needs altium_normalize_bodies.",
"input": {
"name": "string - footprint name filter (library form)",
"path": "path to a .PcbLib or .PcbDoc - optional; opened first",
"timeout": "seconds, default 60",
"want": "'board' - report the focused BOARD even though a PcbLib is also answering"
},
"longRunning": false,
"name": "altium_pcb_report",
"output": {
"data": "{kind: library, components: [{name, pads, padsBboxMil, census, bodies}], bodyCols} | {kind: board, outlineMil, components: [{.., pads, padsBboxMil, nets, bodies}], census, tracks, bodyCols}",
"roundtripMs": "int"
},
"pitfalls": [
"Altium's GetCurrentPCBLibrary answers even when a BOARD is focused: pass want:'board' for a .PcbDoc or you get the library report.",
"A footprint with bodies:[] places with no 3D model."
],
"related": [
"altium_footprint_primitives",
"altium_normalize_bodies",
"altium_add_body",
"altium_show_3d_chip"
],
"statusVerb": null,
"summary": "Numbers instead of pixels: for a PcbLib, every footprint's pads, pad bounding box, primitive census and 3D bodies; for a board, outline, components with nets and bodies, census and tracks.",
"timeoutSeconds": 60
},
{
"example": {
"projectPath": "C:/proj/board.PrjPcb"
},
"hint": "Zero messages = clean. Fix what messages[] names, recompile, then altium_run_drc for the board side.",
"input": {
"limit": "int, default 200 messages",
"objectKind": "string, default 'Project'",
"projectPath": "path to a .PrjPcb (alias: filePath) - default: the bundled Bluetooth Sentinel example",
"timeout": "seconds"
},
"longRunning": false,
"name": "altium_compile",
"output": {
"byClass": "{class: n}",
"elapsedSec": "float",
"messageCount": "int",
"messages": "[{class, source, document, text}]",
"project": "path",
"windowEtiquette": "background"
},
"pitfalls": [
"ALWAYS pass projectPath: the default compiles Altium's example project in the user's session.",
"messages[] is the WHOLE Messages panel after the compile, capped at limit; messageCount is the true total."
],
"related": [
"altium_run_erc",
"altium_run_drc",
"altium_open_project",
"altium_cross_check"
],
"statusVerb": null,
"summary": "Compile a project and return Altium's Messages panel (ERC + connectivity) with counts by class. With no path it compiles Altium's bundled example project.",
"timeoutSeconds": 180
},
{
"example": {
"projectPath": "C:/proj/board.PrjPcb"
},
"hint": "byClass gives the error/warning split; read messages[].text and .document for each. Then altium_run_drc for the layout.",
"input": {
"limit": "int, default 200 messages",
"objectKind": "string, default 'Project'",
"projectPath": "path to a .PrjPcb (alias: filePath) - default: the bundled Bluetooth Sentinel example",
"timeout": "seconds"
},
"longRunning": false,
"name": "altium_run_erc",
"output": {
"byClass": "{class: n}",
"elapsedSec": "float",
"messageCount": "int",
"messages": "[{class, source, document, text}]",
"project": "path",
"windowEtiquette": "background"
},
"pitfalls": [
"ALWAYS pass projectPath: the default compiles Altium's example project.",
"Needs the PROJECT path, not a sheet: a free .SchDoc has no project to compile."
],
"related": [
"altium_compile",
"altium_run_drc",
"altium_review_board"
],
"statusVerb": null,
"summary": "Electrical rules check. Same handler as altium_compile: in Altium, compiling the project IS the ERC.",
"timeoutSeconds": 180
},
{
"example": {
"filePath": "C:/proj/board.PcbDoc"
},
"hint": "violationCount is the true total; violations[] stops at limit. Altium also opens its HTML DRC report as a new document: altium_state shows it, altium_close_document {path} removes it.",
"input": {
"filePath": "path to a .PcbDoc - default: the bundled Bluetooth Sentinel board",
"limit": "int, default 200 violations",
"timeout": "seconds to wait for the DRC, default 180"
},
"longRunning": false,
"name": "altium_run_drc",
"output": {
"board": "path",
"dialogs": "[..]",
"elapsedSec": "float",
"steps": "[..]",
"violationCount": "int",
"violations": "[{rule, description}]",
"windowEtiquette": "background"
},
"pitfalls": [
"ALWAYS pass filePath: the default runs DRC on Altium's example board.",
"drc_dialog_not_found = the DRC dialog never opened; check that a PCB is focused (altium_window_info).",
"Never run PCB:DesignRuleCheck through altium_run_command: the modal freezes the agent with nobody to click it."
],
"related": [
"altium_read_rules",
"altium_rules_by_kind",
"altium_review_board",
"altium_compile"
],
"statusVerb": null,
"summary": "Run the design rule check on a board and read the violation markers back. PCB:DesignRuleCheck opens a MODAL; the bridge clicks 'Run Design Rule Check' through UIA in the background, waits for the agent, re-activates the board and reads the violations.",
"timeoutSeconds": 300
},
{
"example": {
"medium": "Folder Structure",
"outjobPath": "C:/proj/Fabrication.OutJob",
"projectPath": "C:/proj/board.PrjPcb"
},
"hint": "files[] is the proof. Pull what you need with ab's pull_file. OutJobs OPEN what they generate (CAMtastic, PDFs): altium_state afterwards and altium_close_document the viewers.",
"input": {
"medium": "string, default 'Folder Structure' - the OutputMedium name inside the OutJob",
"objectKind": "string, default 'OutputBatch'",
"outjobPath": "path to an .OutJob (alias: filePath) - default: the bundled example Fabrication.OutJob",
"projectPath": "path to the .PrjPcb the OutJob belongs to; opened first",
"timeout": "seconds, default 300"
},
"longRunning": false,
"name": "altium_run_outjob",
"output": {
"agent": "{outjob, medium, objectKind}",
"dialogs": "[..]",
"elapsedSec": "float",
"files": "[relative paths] up to 60",
"medium": "string",
"outjob": "path",
"outputDir": "path | null",
"windowEtiquette": "background"
},
"pitfalls": [
"Pass projectPath with your own OutJob: outputDir/files are looked up beside the PROJECT, and without it beside the OutJob.",
"medium must be the name of an output medium inside the OutJob. The agent cannot tell whether it ran: files[] is the only proof.",
"A dialog in dialogs[] means a medium needed a decision (printer, PDF path): read dialogs[].shot."
],
"related": [
"altium_export_gerber",
"altium_export_bom",
"altium_export_step",
"altium_check_dialogs"
],
"statusVerb": null,
"summary": "Run one output medium of an .OutJob (gerbers, drill, BOM, PDFs...) and list what it wrote under 'Project Outputs for <project>'.",
"timeoutSeconds": 600
},
{
"example": {
"outjobPath": "C:/proj/Fabrication.OutJob",
"projectPath": "C:/proj/board.PrjPcb"
},
"hint": "Check files[] for the gerber and NC drill files, then pull them with ab's pull_file. Close the CAMtastic documents the OutJob opened (altium_state, altium_close_document).",
"input": {
"medium": "string, default 'Folder Structure'",
"outjobPath": "path to an .OutJob - default: the bundled example Fabrication.OutJob",
"projectPath": "path to the .PrjPcb",
"timeout": "seconds, default 300"
},
"longRunning": false,
"name": "altium_export_gerber",
"output": {
"dialogs": "[..]",
"elapsedSec": "float",
"files": "[relative paths]",
"outjob": "path",
"outputDir": "path | null",
"surface": "gerber"
},
"pitfalls": [
"There is NO board-path argument: without outjobPath it exports Altium's EXAMPLE design. The user's project needs its own OutJob.",
"OutJobs open what they generate: expect CAM documents left open in the user's session."
],
"related": [
"altium_run_outjob",
"altium_export_bom",
"altium_export_step",
"altium_run_drc"
],
"statusVerb": null,
"summary": "Gerber/drill export: altium_run_outjob with the fabrication OutJob and the 'Folder Structure' medium as defaults.",
"timeoutSeconds": 300
},
{
"example": {
"boards": 10,
"projectPath": "C:/proj/board.PrjPcb"
},
"hint": "Parameter names are matched across libraries (MPN = Manufacturer Part Number = Mfr Part #; Mouser Part # / Digi-Key Part Number; LCSC Part # / JLCPCB Part #). Missing numbers: look them up (adom-parts-search search <MPN>) and write them back with altium_sheet_params, then run this again.",
"input": {
"boards": "int, default 1 - multiplies the quantities in the Mouser/DigiKey files",
"outputDir": "path - default <project folder>\\BOM",
"pcbPath": "path - optional, default the project's board",
"projectPath": "path to the .PrjPcb (required)",
"timeout": "seconds per sheet read, default 120",
"variant": "string - optional, a project variant's description (Not Fitted parts become DNP, alternates are listed)",
"write": "bool, default true"
},
"longRunning": false,
"name": "altium_bom",
"output": {
"alternates": "[{designator, alternatePart}]",
"checks": "{missingMpn, missingManufacturer, missingPartNumbers{mouser, digikey, lcsc}, inconsistent[{field, designators, values}], dnp, excludedKinds, sheetNotOnBoard, boardNotOnSheet}",
"files": "[path]",
"fittedParts": "int",
"lines": "[{quantity, designators, value, comment, description, footprint, package, mpn, manufacturer, mouser, digikey, lcsc, libReference}]",
"variants": "[string]"
},
"pitfalls": [
"Graphical, Net Tie (no BOM) and Standard (no BOM) components are left out (checks.excludedKinds).",
"DNP: a variant's Not Fitted parts, or a DNP / Do Not Populate / Fitted=false parameter.",
"Variants are read from the .PrjPcb text; alternate parts are listed, not substituted.",
"CPL rotations are Altium's: JLCPCB's preview may need per-footprint corrections.",
"A multi-channel (repeated) sheet is read once: its copies' designators land in checks.boardNotOnSheet.",
"Only the parameters a BOM needs are read (some libraries carry huge blob parameters); a workspace-managed part's description comes from a Description parameter, never its vault."
],
"related": [
"altium_sheet_params",
"altium_export_manufacturing",
"altium_read_schematic"
],
"statusVerb": null,
"summary": "The project's bill of materials read straight from Altium: every schematic sheet the .PrjPcb lists (placed parts and their parameters) merged with the board (footprint, position, side), a variant applied, grouped one line per manufacturer part number, checked for what an order needs, and written as bom.csv, bom-jlcpcb.csv + cpl-jlcpcb.csv, bom-mouser.csv and bom-digikey.csv (+ bom.json).",
"timeoutSeconds": 600
},
{
"example": {
"designator": "U2",
"library": "C:/proj/Lib.SchLib",
"sheet": "C:/proj/Main.SchDoc",
"symbol": "TPS54202DDCR",
"x": 3000,
"y": 4000
},
"hint": "Then wire it: altium_sch_connect {sheet, connections:[{designator, pin, net}]}; number a '?' designator with altium_annotate; push it to the board with altium_update_pcb.",
"input": {
"comment": "string, default the library's",
"designator": "string, default the library's (e.g. R?)",
"footprint": "a PcbLib footprint name to link instead of the library's own",
"library": "path to the .SchLib (required)",
"partId": "int, default 1 (a multi-part component's part)",
"pcbLib": "path of the .PcbLib the footprint lives in (optional)",
"rotation": "0|90|180|270",
"save": "bool, default true",
"sheet": "path to the .SchDoc (required)",
"symbol": "the component's name in that library (required)",
"x": "mil, default 1000 (snapped to 100)",
"y": "mil, default 1000"
},
"longRunning": false,
"name": "altium_sch_place_part",
"output": {
"atMil": "[x, y]",
"designator": "string",
"footprints": "[string]",
"libref": "string",
"pins": "int",
"saved": "bool"
},
"pitfalls": [
"Places part 1 of a multi-part component unless partId says otherwise.",
"Sheet coordinates are mils from the sheet's lower-left corner; altium_schematic_data shows where the other parts are."
],
"related": [
"altium_sch_connect",
"altium_annotate",
"altium_update_pcb",
"altium_list_library"
],
"statusVerb": null,
"summary": "Place a component from a .SchLib onto an EXISTING sheet at a position, with its library parameters (MPN, Manufacturer, distributor numbers) and its footprint link.",
"timeoutSeconds": 120
},
{
"example": {
"kinds": [
"wires",
"labels"
],
"sheet": "C:/proj/Main.SchDoc"
},
"hint": "The ids feed sch_delete_wire, sch_edit_label, sch_junction and sch_edit. Parts are in schematic_data.",
"input": {
"kinds": "[wires, buses, busEntries, labels, powerPorts, junctions, noConnects, texts, sheets] (default all)",
"sheet": "path to the schematic sheet file (required)"
},
"longRunning": false,
"name": "altium_sch_items",
"output": {
"busEntries": "[{id, at, end}]",
"buses": "[{id, from, to}]",
"counts": "{kind: int}",
"junctions": "[{id, at}]",
"labels": "[{id, text, kind: local|global|hierarchical, at, rotation}]",
"noConnects": "[{id, at}]",
"powerPorts": "[{id, net, at}]",
"sheets": "[{id, name, file, at, sizeMm}]",
"texts": "[{id, text, at}]",
"wires": "[{id, from, to}]"
},
"pitfalls": [
"A wire is one straight segment: a polyline drawn in the editor is several wires sharing ends.",
"Altium items have no stable id: an id is the item's kind plus a hash of its geometry, valid until the item changes; every edit answers the new ids."
],
"related": [
"altium_schematic_data",
"altium_sch_pins",
"altium_sch_delete_wire",
"altium_sch_edit_label"
],
"statusVerb": null,
"summary": "List a sheet's wiring items with ids and coordinates: wires, buses, bus entries, net labels (local, global, hierarchical), power ports, junctions, no-connect markers, texts and sheet symbols. Read only. Coordinates are mm in the sheet's frame (Altium's own, y up), the EDA Bridge Standard's schematic frame.",
"timeoutSeconds": 120
},
{
"example": {
"references": [
"U1",
"R5"
],
"sheet": "C:/proj/Main.SchDoc"
},
"hint": "at is where a wire or label must land on the pin. connectedPins lists the other pins on the same copper on this sheet.",
"input": {
"connections": "bool, default true: add what touches each pin",
"references": "[\"U1\", \"R5\"] (default every part)",
"sheet": "path to the schematic sheet file (required)"
},
"longRunning": false,
"name": "altium_sch_pins",
"output": {
"pins": "[{ref, number, name, type, at: [x, y], direction: right|left|up|down as seen, hidden, touching: [{kind, id}], nets: [string], connectedPins: [Ref.Pin]}]"
},
"pitfalls": [
"Nets here come from this sheet's wires and labels only: netlist gives the project-wide nets.",
"Hidden power pins (hidden:true) connect by name, not by wire."
],
"related": [
"altium_sch_connect_pins",
"altium_sch_connect",
"altium_schematic_data",
"altium_netlist"
],
"statusVerb": null,
"summary": "Every pin of the named parts on a sheet: its absolute position (rotation and mirror applied), number, name, electrical type, the side it leaves the body, and the wires, labels and nets touching it. Read only. Coordinates are mm in the sheet's frame (Altium's own, y up), the EDA Bridge Standard's schematic frame.",
"timeoutSeconds": 120
},
{
"example": {
"at": [
109.22,
73.66
],
"sheet": "C:/proj/Power.SchDoc"
},
"hint": "Read with the tool's own rules: wire ends join wires and wire middles (a T), labels and junction dots join a wire anywhere along it, pins join wire ends.",
"input": {
"at": "[x, y] mm on the sheet (the tool's sheet origin, y up) (required)",
"sheet": "path to the schematic sheet file (required)",
"toleranceMm": "number, default 0.05"
},
"longRunning": false,
"name": "altium_sch_trace_point",
"output": {
"crossingWithoutJunction": "bool: two wires cross here without connecting",
"items": "[{kind, id, at}]",
"nearest": "[x, y]: the nearest connectable point, when nothing is within tolerance",
"nets": "[{name, pins: [Ref.Pin], labels, powerPorts, wires, leavesSheet: bool}]"
},
"pitfalls": [
"One sheet only: a net that leaves through a global, hierarchical or power label (leavesSheet:true) continues on other sheets. netlist gives the compiled net."
],
"related": [
"altium_sch_pins",
"altium_netlist"
],
"statusVerb": null,
"summary": "Everything electrically connected at a point on a sheet: the wires, labels, pins, junctions, sheet pins and no-connect markers there, and for each net they belong to the whole net with its name. Read only. Coordinates are mm in the sheet's frame (Altium's own, y up), the EDA Bridge Standard's schematic frame.",
"timeoutSeconds": 120
},
{
"example": {
"points": [
[
110.49,
60.96
]
],
"sheet": "C:/proj/Main.SchDoc"
},
"hint": "The wiring verbs add the dots they need on their own; use this for a T made by hand, or to clean up.",
"input": {
"dryRun": "bool, default false: answer the plan and change nothing",
"points": "[[x, y], ...] mm: where to add dots",
"remove": "[id or [x, y], ...]: dots to remove",
"save": "bool, default true: save the sheet after the edit",
"sheet": "path to the schematic sheet file (required)"
},
"longRunning": false,
"name": "altium_sch_junction",
"output": {
"added": "[{id, at}]",
"notNeeded": "[[x, y]]: added dots where fewer than three items meet (legal, but they join nothing extra)",
"removed": "[id]",
"saved": "bool",
"skipped": "[[x, y]]: points that already had a dot"
},
"pitfalls": [
"Items join only where their coordinates match exactly: use pin ends from sch_pins, or points on the sheet's grid."
],
"related": [
"altium_sch_items",
"altium_sch_split_wire",
"altium_sch_delete_wire"
],
"statusVerb": null,
"summary": "Add junction dots at points, or remove dots by id or point. One undo step. Coordinates are mm in the sheet's frame (Altium's own, y up), the EDA Bridge Standard's schematic frame.",
"timeoutSeconds": 120
},
{
"example": {
"label": "D[0..7]",
"points": [
[
203.2,
50.8
],
[
203.2,
101.6
]
],
"sheet": "C:/proj/Main.SchDoc"
},
"hint": "A bus carries the nets its label names, and each member wire needs its own label. sch_connect_to_bus does the member wires, entries and labels for a set of pins.",
"input": {
"dryRun": "bool, default false: answer the plan and change nothing",
"label": "\"D[0..7]\" or \"{SDA SCL}\": the nets the bus carries",
"points": "[[x, y], [x, y], ...] mm (required)",
"save": "bool, default true: save the sheet after the edit",
"sheet": "path to the schematic sheet file (required)"
},
"longRunning": false,
"name": "altium_sch_bus",
"output": {
"ids": "[bus segment id]",
"label": "{id, text} or null",
"saved": "bool"
},
"pitfalls": [
"A bus with no label carries nothing: ERC reports its members as unconnected."
],
"related": [
"altium_sch_bus_entry",
"altium_sch_connect_to_bus",
"altium_sch_delete_wire",
"altium_sch_items"
],
"statusVerb": null,
"summary": "Draw a bus as a polyline (one bus segment per pair of points), optionally with a bus label such as D[0..7] or a group {SDA SCL} at its first point. One undo step. Coordinates are mm in the sheet's frame (Altium's own, y up), the EDA Bridge Standard's schematic frame.",
"timeoutSeconds": 120
},
{
"example": {
"entries": [
{
"at": [
200.66,
63.5
],
"direction": "up-right"
}
],
"sheet": "C:/proj/Main.SchDoc"
},
"hint": "end is the bus side of each entry; onBus says whether it lands on a bus segment.",
"input": {
"dryRun": "bool, default false: answer the plan and change nothing",
"entries": "[{at: [x, y] mm (the wire end), direction: up-right|down-right|up-left|down-left as seen (default down-right)}] (required)",
"save": "bool, default true: save the sheet after the edit",
"sheet": "path to the schematic sheet file (required)"
},
"longRunning": false,
"name": "altium_sch_bus_entry",
"output": {
"added": "[{id, at, end: [x, y] (the bus side), onBus: bool}]",
"saved": "bool"
},
"pitfalls": [
"The bus side must touch a bus and the other end a wire end, exactly, or ERC reports the entry as unconnected."
],
"related": [
"altium_sch_bus",
"altium_sch_connect_to_bus",
"altium_sch_items"
],
"statusVerb": null,
"summary": "Add 45-degree bus entries: the short diagonal that joins a member wire's end to a bus. One undo step. Coordinates are mm in the sheet's frame (Altium's own, y up), the EDA Bridge Standard's schematic frame.",
"timeoutSeconds": 120
},
{
"example": {
"at": [
110.49,
60.96
],
"sheet": "C:/proj/Main.SchDoc"
},
"hint": "Split a wire where a new branch should join it, then wire to the cut.",
"input": {
"at": "[x, y] mm on the sheet (the tool's sheet origin, y up) (required)",
"dryRun": "bool, default false: answer the plan and change nothing",
"id": "the wire's id, when several wires pass through the point",
"junction": "bool, default true",
"save": "bool, default true: save the sheet after the edit",
"sheet": "path to the schematic sheet file (required)"
},
"longRunning": false,
"name": "altium_sch_split_wire",
"output": {
"ids": "[first half (keeps the wire's id), second half (new id)]",
"junction": "{id, at} or null",
"saved": "bool"
},
"pitfalls": [
"The point must lie on the wire and not at either end (not_on_wire otherwise).",
"Both halves get new ids: Altium ids follow geometry."
],
"related": [
"altium_sch_delete_wire",
"altium_sch_junction",
"altium_sch_items"
],
"statusVerb": null,
"summary": "Split the wire through a point into two wires there, with a junction dot at the cut, so a new branch can end on a wire end. One undo step. Coordinates are mm in the sheet's frame (Altium's own, y up), the EDA Bridge Standard's schematic frame.",
"timeoutSeconds": 120
},
{
"example": {
"from": [
100.33,
60.96
],
"sheet": "C:/proj/Main.SchDoc",
"to": [
120.65,
60.96
]
},
"hint": "Read ids with sch_items. from/to matches one segment, not a whole route.",
"input": {
"at": "[x, y] mm: every wire passing through the point",
"dryRun": "bool, default false: answer the plan and change nothing",
"from": "[x, y] mm, with to: the wire with exactly these ends (either order)",
"ids": "[wire id, ...]",
"save": "bool, default true: save the sheet after the edit",
"sheet": "path to the schematic sheet file (required)",
"to": "[x, y] mm"
},
"longRunning": false,
"name": "altium_sch_delete_wire",
"output": {
"deleted": "[{id, from, to}]",
"junctionsRemoved": "[[x, y]]",
"saved": "bool"
},
"pitfalls": [
"A polyline drawn in the editor is several wires sharing ends: from/to names one segment of it.",
"An Altium wire is one polyline: deleting it removes all its segments; split it first to cut one out."
],
"related": [
"altium_sch_items",
"altium_sch_split_wire",
"altium_sch_junction",
"altium_sch_connect_pins"
],
"statusVerb": null,
"summary": "Delete wires or bus segments by id, by their two ends, or every wire through a point, and remove junction dots that no longer join three or more items. One undo step. Coordinates are mm in the sheet's frame (Altium's own, y up), the EDA Bridge Standard's schematic frame.",
"timeoutSeconds": 120
},
{
"example": {
"edits": [
{
"by": [
0,
2.54
],
"net": "VOUT"
}
],
"sheet": "C:/proj/Main.SchDoc"
},
"hint": "text picks every label with that text (or the one at at); net picks every label of the net. Read ids with sch_items.",
"input": {
"dryRun": "bool, default false: answer the plan and change nothing",
"edits": "[{id | text (with at?: [x, y] to pick one) | net (every label of the net), rotation?: 0|90|180|270, to?: [x, y] mm (one label only), by?: [dx, dy] mm, rename?: string}] (required)",
"save": "bool, default true: save the sheet after the edit",
"sheet": "path to the schematic sheet file (required)"
},
"longRunning": false,
"name": "altium_sch_edit_label",
"output": {
"edited": "[{id, text, at, rotation}]",
"failed": "[{edit, error}]",
"saved": "bool"
},
"pitfalls": [
"A label joins a net only where it sits on a wire or a pin end: moving it off disconnects it.",
"rename changes only the labels picked: other labels with the old name stay on the old net."
],
"related": [
"altium_sch_items",
"altium_sch_connect",
"altium_sch_edit"
],
"statusVerb": null,
"summary": "Edit net labels: rotate, move to a point or by a delta, rename, or move every label of a net at once. One undo step. Coordinates are mm in the sheet's frame (Altium's own, y up), the EDA Bridge Standard's schematic frame.",
"timeoutSeconds": 120
},
{
"example": {
"sheet": "C:/proj/Main.SchDoc",
"texts": [
{
"at": [
50.8,
30.48
],
"bold": true,
"sizeMm": 2.54,
"text": "USB input stage"
}
]
},
"hint": "Net names are labels, not text: use sch_connect for them. Newlines in text become line breaks.",
"input": {
"dryRun": "bool, default false: answer the plan and change nothing",
"save": "bool, default true: save the sheet after the edit",
"sheet": "path to the schematic sheet file (required)",
"texts": "[{text, at: [x, y] mm, rotation?: 0|90|180|270, sizeMm?: 1.27, justify?: \"left bottom\", bold?: false, italic?: false}] (required)"
},
"longRunning": false,
"name": "altium_sch_text",
"output": {
"added": "[{id, text, at}]",
"saved": "bool"
},
"pitfalls": [
"Altium sizes text in points; sizeMm is converted (10 pt is about 2.54 mm). Text is one line."
],
"related": [
"altium_sch_items",
"altium_sch_edit_label"
],
"statusVerb": null,
"summary": "Add free text to a sheet (a note, a title, a design comment) with size, angle, justification, bold and italic. Text has no electrical meaning. One undo step. Coordinates are mm in the sheet's frame (Altium's own, y up), the EDA Bridge Standard's schematic frame.",
"timeoutSeconds": 120
},
{
"example": {
"pairs": [
{
"from": "U1.1",
"to": "R2.1"
},
{
"first": "v",
"from": "U1.2",
"to": "C3.1"
}
],
"sheet": "C:/proj/Main.SchDoc"
},
"hint": "Pins are matched by number, then by name. Aligned pins get one straight wire; otherwise the route turns once. Check the result with sch_pins (connectedPins) or run_erc.",
"input": {
"dryRun": "bool, default false: answer the plan and change nothing",
"pairs": "[{from: \"U1.1\", to: \"R5.2\", first?: h|v (the leg to draw first; default along the axis the from pin points), via?: [[x, y], ...] mm waypoints}] (required)",
"save": "bool, default true: save the sheet after the edit",
"sheet": "path to the schematic sheet file (required)"
},
"longRunning": false,
"name": "altium_sch_connect_pins",
"output": {
"failed": "[{from, to, error}]",
"junctionsAdded": "[[x, y]]",
"routes": "[{from, to, points: [[x, y]], ids: [wire id]}]",
"saved": "bool",
"wired": "int"
},
"pitfalls": [
"The route does not avoid part bodies or other wires: a leg running along another wire merges the two nets. Steer with first or via, and check with sch_pins."
],
"related": [
"altium_sch_pins",
"altium_sch_connect",
"altium_sch_delete_wire",
"altium_run_erc"
],
"statusVerb": null,
"summary": "Wire pins to pins on a sheet by Ref.Pin: an L-shaped route (one horizontal and one vertical leg) for each pair, with a junction dot wherever a route meets an existing wire in a T. One undo step. Coordinates are mm in the sheet's frame (Altium's own, y up), the EDA Bridge Standard's schematic frame.",
"timeoutSeconds": 120
},
{
"example": {
"busLabel": "D[0..1]",
"pins": [
"U1.1",
"U1.7"
],
"prefix": "D",
"sheet": "C:/proj/Main.SchDoc"
},
"hint": "Members name the nets: members lists them in pin order, or prefix plus start counts up. Refused with entry_off_bus when an entry would miss the bus: extend the bus with sch_bus first.",
"input": {
"bus": "id of the bus segment (default the only bus on the sheet)",
"busLabel": "\"D[0..7]\": also label the bus",
"dryRun": "bool, default false: answer the plan and change nothing",
"entry": "up|down (a vertical bus) or left|right (a horizontal bus): the way the entries lean",
"members": "[\"D0\", \"D1\"]: the member names in pin order",
"pins": "[\"U1.1\", \"U1.2\"] Ref.Pin, in member order (required)",
"prefix": "\"D\": or name members prefix + number",
"save": "bool, default true: save the sheet after the edit",
"sheet": "path to the schematic sheet file (required)",
"start": "int, default 0: the first number with prefix"
},
"longRunning": false,
"name": "altium_sch_connect_to_bus",
"output": {
"busLabel": "string or null",
"connected": "[{pin, member, wireId, entryId}]",
"failed": "[{pin, error}]",
"saved": "bool"
},
"pitfalls": [
"Pins should face the bus; a pin facing away gets a wire across its own part.",
"Two pins at the same height on a vertical bus share an entry point and collide: offset them or lean the entries differently."
],
"related": [
"altium_sch_bus",
"altium_sch_bus_entry",
"altium_sch_pins"
],
"statusVerb": null,
"summary": "Fan pins onto a bus: for each pin a wire running to the bus, a 45-degree bus entry onto it and a member label (D0, D1 ...) on the wire. One undo step. Coordinates are mm in the sheet's frame (Altium's own, y up), the EDA Bridge Standard's schematic frame.",
"timeoutSeconds": 120
},
{
"example": {
"box": [
90,
40,
160,
120
],
"by": [
25.4,
0
],
"sheet": "C:/proj/Main.SchDoc"
},
"hint": "Parts move by their anchor point. Move by a pure dx or a pure dy to keep stretched wires straight.",
"input": {
"box": "[x1, y1, x2, y2] mm (required)",
"by": "[dx, dy] mm (required)",
"dryRun": "bool, default false: answer the plan and change nothing",
"junctions": "bool, default true: move junctions and no-connect markers",
"labels": "bool, default true: move labels and texts",
"save": "bool, default true: save the sheet after the edit",
"sheet": "path to the schematic sheet file (required)",
"wires": "bool, default true: move wires, buses and bus entries"
},
"longRunning": false,
"name": "altium_sch_move_region",
"output": {
"moved": "{parts, wires, buses, busEntries, labels, texts, junctions, noConnects, sheets: [id]}",
"saved": "bool"
},
"pitfalls": [
"A wire with one end in the box stretches diagonally when dx and dy are both non-zero.",
"Keep the move on the sheet's grid, or pins and wires stop meeting.",
"A multi-part component whose parts sit on both sides of the edge splits up."
],
"related": [
"altium_sch_edit",
"altium_sch_items"
],
"statusVerb": null,
"summary": "Move everything inside a box by (dx, dy): parts, wire ends inside the box (wires crossing its edge stretch), labels, junctions, no-connect markers, texts, bus entries and sheet symbols. One undo step. Coordinates are mm in the sheet's frame (Altium's own, y up), the EDA Bridge Standard's schematic frame.",
"timeoutSeconds": 120
},
{
"example": {
"dryRun": false,
"sheet": "C:/proj/Power.SchDoc",
"toleranceMm": 0.5
},
"hint": "Only dangling wire ends move. Read the moves before applying them: diagonal:true means the snapped wire is no longer horizontal or vertical. Check with run_erc after.",
"input": {
"dryRun": "bool, default TRUE",
"save": "bool, default true: save the sheet after the edit",
"sheet": "path to the schematic sheet file (required)",
"toleranceMm": "number, default 0.5"
},
"longRunning": false,
"name": "altium_sch_fix_connectivity",
"output": {
"moves": "[{wireId, from, to, onto: {kind, id}, diagonal: bool}]",
"saved": "bool",
"unresolved": "[[x, y]]: dangling ends with nothing close"
},
"pitfalls": [
"dryRun defaults to true: nothing changes until dryRun:false.",
"A wide tolerance can snap onto the wrong pin: keep it under half the sheet's grid."
],
"related": [
"altium_sch_trace_point",
"altium_run_erc"
],
"statusVerb": null,
"summary": "Snap near-miss wire ends onto the pin, label, sheet pin or wire end they almost touch, within a tolerance. dryRun (the default) lists the moves; dryRun:false makes them. Coordinates are mm in the sheet's frame (Altium's own, y up), the EDA Bridge Standard's schematic frame.",
"timeoutSeconds": 120
},
{
"example": {
"paper": "A3",
"rev": "B",
"sheet": "C:/proj/Main.SchDoc",
"title": "Main board"
},
"hint": "With no change arguments it only reads. An empty string removes a title-block field. Each sheet of a hierarchy has its own page.",
"input": {
"comments": "[string]: comment lines in order",
"company": "string",
"date": "string",
"dryRun": "bool, default false: answer the plan and change nothing",
"heightMm": "number (custom paper)",
"orientation": "portrait|landscape",
"paper": "A5 to A0, A to E, USLetter, USLegal, USLedger or custom",
"rev": "string",
"save": "bool, default true: save the sheet after the edit",
"sheet": "path to the schematic sheet file (required)",
"title": "string",
"widthMm": "number (custom paper)"
},
"longRunning": false,
"name": "altium_sch_page",
"output": {
"changed": "bool",
"heightMm": "number",
"orientation": "string",
"paper": "string",
"saved": "bool",
"titleBlock": "{title, date, rev, company, comments}",
"widthMm": "number"
},
"pitfalls": [
"Shrinking the paper moves nothing: items outside the new frame stay where they are (render_schematic shows it).",
"Altium's title block shows Title, Date, Revision and CompanyName; comments are kept as parameters Comment1, Comment2... A5 has no Altium sheet style and is set as a custom size."
],
"related": [],
"statusVerb": null,
"summary": "Read or set a sheet's page: paper size, orientation and title block (title, date, revision, company, comment lines). Millimetres, the sheet's frame (y up).",
"timeoutSeconds": 300
},
{
"example": {
"project": "C:/proj/Board.PrjPcb",
"sheet": "C:/proj/Power.SchDoc",
"sheetName": "Power",
"title": "Power"
},
"hint": "Without project the sheet stands alone. With project it is linked from the root sheet as a child sheet with the next page number.",
"input": {
"at": "[x, y] mm: where the sheet symbol goes on the root",
"comments": "[string]",
"company": "string",
"date": "string",
"dryRun": "bool, default false: answer the plan and change nothing",
"heightMm": "number (custom)",
"orientation": "portrait|landscape",
"paper": "A4, A3 ... USLetter or custom",
"project": "path: add the sheet to this project under its root sheet",
"rev": "string",
"sheet": "path of the sheet to create (required)",
"sheetName": "string: the sheet symbol's name in the root",
"title": "string",
"widthMm": "number (custom)"
},
"longRunning": false,
"name": "altium_sch_create",
"output": {
"created": "bool",
"page": "int",
"sheet": "path",
"sheetSymbol": "{id, name, at} or null"
},
"pitfalls": [
"Never overwrites: an existing file is refused.",
"A new child sheet has no pins on its symbol: add hierarchical ports inside, then sch_sheet_pins {import:true}.",
"Made from Altium's ANSI B Landscape template and resized; the page number is one past the project's highest."
],
"related": [],
"statusVerb": null,
"summary": "Create an empty schematic sheet with a paper size and title block; optionally add it to a project as a child sheet of the root. It places no parts or nets (build_schematic does). Millimetres, the sheet's frame (y up).",
"timeoutSeconds": 300
},
{
"example": {
"project": "C:/proj/Board.PrjPcb",
"renumber": true
},
"hint": "Pass the root sheet or the project. renumber writes only the numbers that change.",
"input": {
"dryRun": "bool, default false: answer the plan and change nothing",
"project": "path to the project (instead of sheet)",
"renumber": "bool, default false",
"sheet": "path to the root sheet"
},
"longRunning": false,
"name": "altium_sch_hierarchy",
"output": {
"duplicatePages": "[int]",
"problems": "[{sheet, problem: missing|unreadable|recursive}]",
"renumbered": "[{sheet, from, to}]",
"tree": "[{name, file, id, path, page, at, sizeMm, pins: [{name, kind}], children: [...]}]"
},
"pitfalls": [
"A sheet file used by two sheet symbols appears twice in the tree (one instance each) but is one file.",
"Read from the saved files without Altium: save open sheets first."
],
"related": [],
"statusVerb": null,
"summary": "The sheet tree of a design, recursively: each sheet's name, file, id, instance path, page number, position, size and pins. renumber:true renumbers pages depth-first from the root. Millimetres, the sheet's frame (y up).",
"timeoutSeconds": 300
},
{
"example": {
"import": true,
"sheet": "C:/proj/Main.SchDoc",
"sheetSymbol": "Power"
},
"hint": "Inputs go on the left edge and outputs on the right by default, in the first free slot. A pin joins the child's hierarchical port of the same name; wire it on the parent side at its at.",
"input": {
"action": "list|add|edit|delete, default list",
"at": "[x, y] mm: snapped to the nearest edge point",
"dryRun": "bool, default false: answer the plan and change nothing",
"import": "bool",
"kind": "input|output|bidirectional|tri_state|passive",
"name": "string: the pin",
"newName": "string (edit)",
"save": "bool, default true: save the sheet after the edit",
"sheet": "path to the parent sheet (required)",
"sheetSymbol": "the sheet symbol's name or id (default: validate checks every one)",
"side": "left|right|top|bottom",
"validate": "bool"
},
"longRunning": false,
"name": "altium_sch_sheet_pins",
"output": {
"added": "[name]",
"pins": "[{id, name, kind, side, at}]",
"problems": "[{sheetSymbol, pin, problem: no_port|no_pin|kind_mismatch}]",
"saved": "bool"
},
"pitfalls": [
"Renaming a pin does not rename the port inside the child sheet: validate afterwards.",
"A pin moved or deleted leaves its parent-side wire dangling.",
"Altium has no tri-state or passive sheet entry: tri_state is stored as bidirectional, passive as unspecified."
],
"related": [],
"statusVerb": null,
"summary": "A sheet symbol's pins: list, add, edit (rename, kind, move along an edge) or delete. import:true adds a pin for every hierarchical port inside the child sheet that the symbol lacks; validate:true reports ports without pins, pins without ports and kind mismatches. Millimetres, the sheet's frame (y up).",
"timeoutSeconds": 300
},
{
"example": {
"references": [
"R5",
"C3"
],
"sheet": "C:/proj/Main.SchDoc"
},
"hint": "Font and visibility stay as they are; only position, angle and justification move.",
"input": {
"all": "bool: every part on the sheet",
"dryRun": "bool, default false: answer the plan and change nothing",
"fields": "[designator, value] by default; other field names as the tool names them",
"references": "[\"R5\", \"C3\"]",
"save": "bool, default true: save the sheet after the edit",
"sheet": "path to the schematic sheet file (required)"
},
"longRunning": false,
"name": "altium_sch_reset_fields",
"output": {
"reset": "[{ref, field}]",
"saved": "bool"
},
"pitfalls": [
"The library's offsets are what the symbol's author drew; the tool's automatic field placement may put them elsewhere.",
"Positions come from the part's library file (its library path); parts from integrated or database libraries have none and are reported."
],
"related": [],
"statusVerb": null,
"summary": "Put parts' designator and value text (or the named fields) back where the library symbol places them, through each part's rotation and mirror. One undo step. Millimetres, the sheet's frame (y up).",
"timeoutSeconds": 300
},
{
"example": {
"dryRun": true,
"sheet": "C:/proj/Main.SchDoc"
},
"hint": "Run with dryRun first. A symbol whose new version drops a placed pin is refused unless force:true. Check the sheet afterwards with run_erc.",
"input": {
"dryRun": "bool, default false: answer the plan and change nothing",
"force": "bool, default false: update even when a placed pin would be dropped",
"library": "path to one library to take them all from (with symbols)",
"save": "bool, default true: save the sheet after the edit",
"sheet": "path to the schematic sheet file (required)",
"symbols": "[library symbol name or id, ...] (default all)"
},
"longRunning": false,
"name": "altium_sch_update_from_library",
"output": {
"changed": "[{symbol, pinsAdded, pinsRemoved}]",
"notFound": "[symbol]",
"refused": "[{symbol, droppedPins}]",
"saved": "bool",
"unchanged": "[symbol]"
},
"pitfalls": [
"A pin that moved in the library moves off its wire: check with sch_pins or run_erc after an update that reports changes.",
"Altium cannot compare graphics from the sheet: a symbol with the same pins is reported unchanged unless named in symbols or library is given, which re-places it anyway."
],
"related": [],
"statusVerb": null,
"summary": "Update the placed symbols on a sheet from their libraries (all, or the listed ones) and report which changed, which already matched and which no library has. Millimetres, the sheet's frame (y up).",
"timeoutSeconds": 300
},
{
"example": {
"baseline": "compare",
"sheet": "C:/proj/Power.SchDoc"
},
"hint": "A sub-sheet renders with its real designators. compare renders at the baseline's width and passes when driftPercent <= threshold. show_* verbs open a window; this one does not.",
"input": {
"baseline": "set|compare",
"drawingSheet": "bool, default true: include the frame and title block",
"outputDir": "folder for the image (default beside the project)",
"sheet": "path to the schematic sheet file (required)",
"threshold": "percent of pixels, default 0.5 (compare)",
"width": "int px, default 2000"
},
"longRunning": false,
"name": "altium_render_schematic",
"output": {
"changedRegionMm": "[x1, y1, x2, y2] (compare)",
"diffPng": "path: the changed pixels in red (compare)",
"driftPercent": "number (compare)",
"height": "int",
"pass": "bool (compare)",
"png": "path",
"rendererChanged": "bool: the tool's plotter changed since the baseline",
"width": "int"
},
"pitfalls": [
"Anti-aliasing differs between tool versions: rendererChanged:true means drift may not be a design change.",
"A baseline is per sheet and per width; a paper size change reads as 100 percent drift.",
"Altium prints the sheet to PDF (through its project when one beside it lists the sheet) and Windows renders it.",
"Windows scales the image by the display's scale factor; the bridge asks again to correct it, so width is within a pixel of the one asked (800 px is 799 at 150%): compare uses the baseline's own size.",
"Altium's print now and then leaves the title block's special strings (=Title, sheet numbers) unfilled; a failed comparison prints once more and keeps the closer image (reprinted:true), so drift confined to the title block is usually that."
],
"related": [
"altium_export_pdf",
"altium_show_schematic"
],
"statusVerb": null,
"summary": "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 compare reports the pixel drift, the changed region and a diff image.",
"timeoutSeconds": 400
},
{
"example": {
"expectedRevision": "<rev>",
"filePath": "C:/proj/Board.PcbDoc",
"refs": [
"TP3"
]
},
"hint": "Each removed part lists the nets its pads carried. A locked part is refused (part_locked) unless allowLocked:true.",
"input": {
"allowLocked": "bool, default false",
"dryRun": "bool, default false: answer the plan and change nothing",
"expectedRevision": "string: the revision you last read (routing_state); refused with stale_board if the board changed",
"filePath": "path to the board file (default: the board open in the tool)",
"refs": "[\"R7\", \"R8\"] (required)"
},
"longRunning": false,
"name": "altium_remove_parts",
"output": {
"failed": "[{ref, error}]",
"removed": "[{ref, nets: [string]}]",
"revision": "string: the board's new revision"
},
"pitfalls": [
"Tracks and vias that met the pads stay: routing_state shows what is left dangling.",
"A part still in the schematic comes back at the next update_pcb.",
"Altium's lock is the part's Moveable flag."
],
"related": [
"altium_routing_state",
"altium_move_parts"
],
"statusVerb": null,
"summary": "Remove placed parts from the board by designator, as one undo step. The library is not touched (that is remove_footprint).",
"timeoutSeconds": 300
},
{
"example": {
"edits": [
{
"dnp": true,
"ref": "R7",
"value": "4k7"
}
],
"expectedRevision": "<rev>",
"filePath": "C:/proj/Board.PcbDoc"
},
"hint": "Fields the tool requires (designator, value) cannot be removed. Read the parts first with component_data.",
"input": {
"dryRun": "bool, default false: answer the plan and change nothing",
"edits": "[{ref, value?, newRef?, fields?: {name: value | null (remove)}, dnp?: bool, excludeFromBom?: bool, excludeFromPos?: bool, mount?: smd|through_hole|other, locked?: bool}] (required)",
"expectedRevision": "string: the revision you last read (routing_state); refused with stale_board if the board changed",
"filePath": "path to the board file (default: the board open in the tool)"
},
"longRunning": false,
"name": "altium_edit_parts",
"output": {
"edited": "[{ref, before, after}]",
"failed": "[{ref, error}]",
"revision": "string: the board's new revision"
},
"pitfalls": [
"Board-side edits of what the schematic owns are lost at the next update_pcb: change the schematic instead (sch_edit).",
"A designator already taken is refused.",
"On Altium the board edits designator, value (comment), the lock and BOM exclusion (component kind Standard (no BOM)); do-not-populate is a variant (altium_variants), mounting comes from the footprint and parameters from the schematic: those answer not_supported per field."
],
"related": [
"altium_routing_state",
"altium_move_parts"
],
"statusVerb": null,
"summary": "Edit placed parts: value, designator, any field (add, change, remove), do-not-populate, exclusion from the BOM or position files, mounting type and the lock. One undo step.",
"timeoutSeconds": 300
},
{
"example": {
"expectedRevision": "<rev>",
"filePath": "C:/proj/Board.PcbDoc",
"mode": "top",
"refs": [
"C4",
"C5",
"C6"
]
},
"hint": "Without to, left takes the group's smallest x, right the largest, top the highest edge and bottom the lowest (y up); centre lines take the mean. distribute keeps the outer two in place.",
"input": {
"allowOutside": "bool, default false",
"allowOverlap": "bool, default false",
"by": "courtyard|anchor, default courtyard",
"dryRun": "bool, default false: answer the plan and change nothing",
"expectedRevision": "string: the revision you last read (routing_state); refused with stale_board if the board changed",
"filePath": "path to the board file (default: the board open in the tool)",
"gapMm": "number: the spacing for distribute (default even spacing between the outer two)",
"mode": "left|right|top|bottom|centerX|centerY|distributeX|distributeY (required)",
"refs": "[\"C1\", \"C2\", \"C3\"] (required)",
"to": "mm: the line to align on (default from the group)"
},
"longRunning": false,
"name": "altium_align_parts",
"output": {
"mismatches": "[{ref, asked, got}]",
"revision": "string: the board's new revision",
"targets": "[{ref, x, y}]"
},
"pitfalls": [
"Rotation and side are kept: align parts of the same orientation for a clean row.",
"A courtyard collision or a part off the board is refused, as in move_parts.",
"Altium courtyards are not read: the part box is its pads' extent."
],
"related": [
"altium_routing_state",
"altium_move_parts"
],
"statusVerb": null,
"summary": "Line parts up on a common left, right, top, bottom or centre line, or space them evenly, by courtyard box or by anchor point. One undo step, with move_parts' checks.",
"timeoutSeconds": 300
},
{
"example": {
"count": 4,
"filePath": "C:/proj/Board.PcbDoc"
},
"hint": "New inner layers are signal layers In1.Cu ... Read the result with layer_stack.",
"input": {
"count": "2|4|6|8 (required)",
"dryRun": "bool, default false: answer the plan and change nothing",
"expectedRevision": "string: the revision you last read (routing_state); refused with stale_board if the board changed",
"filePath": "path to the board file (default: the board open in the tool)"
},
"longRunning": false,
"name": "altium_set_layer_count",
"output": {
"layers": "[string]: the copper layers now",
"revision": "string: the board's new revision",
"stackup": "the new stack-up, as layer_stack answers it"
},
"pitfalls": [
"A layer being removed that still carries copper or graphics is refused (layers_in_use, with the counts per layer).",
"New dielectrics are generic: re-check an impedance-controlled stack-up with layer_stack.",
"Net classes and design rules are not changed.",
"Altium adds inner signal layers (Mid-Layers) and removes inner layers from the bottom up; the board thickness is kept by spreading the dielectrics evenly."
],
"related": [
"altium_routing_state",
"altium_move_parts"
],
"statusVerb": null,
"summary": "Set the board's copper layer count (2, 4, 6 or 8): the layer table and the stack-up, keeping the board thickness.",
"timeoutSeconds": 300
},
{
"example": {
"box": [
10,
10,
30,
25
],
"expectedRevision": "<rev>",
"filePath": "C:/proj/Board.PcbDoc",
"offset": [
25,
0
],
"refPattern": {
"from": "CH1_*",
"to": "CH2_*"
}
},
"hint": "A track is copied when both ends are in the box, a via when its centre is. Without a remap the copy keeps its nets. Dry-run first and check netMap.",
"input": {
"box": "[x1, y1, x2, y2] mm (required): the source",
"dryRun": "bool, default false: answer the plan and change nothing",
"expectedRevision": "string: the revision you last read (routing_state); refused with stale_board if the board changed",
"filePath": "path to the board file (default: the board open in the tool)",
"keepUnmappedNets": "bool, default false",
"layers": "[layer]: copy only these",
"netMap": "{\"SIG\": \"SIG2\"}: overrides",
"offset": "[dx, dy] mm (required)",
"refMap": "{\"U1\": \"U5\"}: pair parts, so each pad's net maps to the partner pad's net",
"refPattern": "{from: \"CH1_*\", to: \"CH2_*\"}: pair parts by designator pattern",
"validate": "bool, default true: run the tool's DRC on the result before committing"
},
"longRunning": false,
"name": "altium_copy_routing",
"output": {
"copied": "{tracks: int, vias: int}",
"drc": "{ran, newErrors}",
"netMap": "{from: to}: the pairing used",
"revision": "string: the board's new revision",
"skipped": "[{item, why}]"
},
"pitfalls": [
"Only through vias are copied: blind and buried vias are skipped.",
"The copy connects only where the target pads sit at the same offset: place the target channel identically first (replicate_layout).",
"One source net mapping to two target nets is refused (net_map_conflict) unless netMap settles it.",
"Arcs are listed under skipped, not copied, on Altium yet.",
"validate runs Altium's batch DRC before and after: a copy that adds errors is taken back out (rolledBack:true)."
],
"related": [
"altium_routing_state",
"altium_move_parts"
],
"statusVerb": null,
"summary": "Copy the tracks and vias inside a box to an offset, remapping nets by pairing parts (a designator map or pattern), so a repeated channel gets the same routing. One undo step.",
"timeoutSeconds": 300
},
{
"example": {
"filePath": "C:/proj/Board.PcbDoc",
"mode": "pads",
"refs": [
"U1"
],
"thresholdMm": 0.2
},
"hint": "The standard's shared check on the board model and the parts' 3D bodies: courtyard mode compares part boxes (pads plus bodies) on the same side, pads mode compares pad copper of different parts on a shared layer by its real outline (round pads as circles or stadiums, turned pads turned).",
"input": {
"filePath": "path to the board file (default: the board open in the tool)",
"includeSameNet": "bool, default false (pads)",
"maxPairs": "int, default 200",
"mode": "courtyard|pads, default courtyard",
"refs": "[\"U1\", \"C3\"]: keep pairs that involve one of these (default every part)",
"thresholdMm": "number, default 0.25 (courtyard) or 0.2 (pads)"
},
"longRunning": false,
"name": "altium_check_clearance",
"output": {
"clean": "bool",
"engine": "string",
"measuredOn": "what was compared",
"pairs": "[{a, b, distanceMm, overlapping: bool, touching: bool}] closest first",
"pairsChecked": "int",
"thresholdMm": "number",
"truncated": "bool",
"violationCount": "int"
},
"pitfalls": [
"Altium courtyards are not read: a part is its pads plus its 3D body. The tool's DRC (run_drc, Component Clearance) is the authority."
],
"related": [
"altium_routing_state",
"altium_move_parts",
"altium_place_decoupling",
"altium_placement_check"
],
"statusVerb": null,
"summary": "Measure the gaps between parts, courtyard to courtyard or pad copper to pad copper, for the listed parts or the whole board, and report every pair under a threshold, closest first.",
"timeoutSeconds": 300
},
{
"example": {
"dryRun": true,
"filePath": "C:/proj/Board.PcbDoc",
"layer": "Dwgs.User"
},
"hint": "Board-level graphics only; graphics inside parts are footprint_primitives. An unknown id refuses the whole call (unknown_ids).",
"input": {
"dryRun": "bool, default false: answer the plan and change nothing",
"expectedRevision": "string: the revision you last read (routing_state); refused with stale_board if the board changed",
"filePath": "path to the board file (default: the board open in the tool)",
"ids": "[id]",
"kinds": "[line|rect|circle|arc|polygon|text|dimension]",
"layer": "\"F.SilkS\": every graphic on this layer"
},
"longRunning": false,
"name": "altium_remove_graphics",
"output": {
"removed": "[{id, kind, layer, points}]",
"revision": "string: the board's new revision"
},
"pitfalls": [
"Removing Edge.Cuts graphics removes the board outline.",
"A layer or kind filter without ids removes every match: dry-run it first.",
"With no ids, layer or kinds it only lists the board graphics with their ids (Altium items have none: an id is a hash of kind, layer and geometry)."
],
"related": [
"altium_routing_state",
"altium_move_parts"
],
"statusVerb": null,
"summary": "Remove board graphics (lines, rectangles, circles, arcs, polygons, texts, dimensions) by id, or every one on a layer and of a kind. One undo step.",
"timeoutSeconds": 300
},
{
"example": {
"filePath": "C:/proj/Board.PcbDoc"
},
"hint": "Send the archive to a fab that takes ODB++ instead of Gerbers. export_manufacturing makes the Gerber set.",
"input": {
"compression": "zip|tgz|none, default zip",
"filePath": "path to the board file (default: the board open in the tool)",
"outputDir": "folder for the output (default beside the board)",
"units": "mm|in, default mm"
},
"longRunning": false,
"name": "altium_export_odb",
"output": {
"files": "[path]",
"outputDir": "path"
},
"pitfalls": [
"Run run_drc first: the file carries the board's errors with it.",
"Altium writes it with its manufacturing template's settings: units, compression and version options are reported under optionsNotApplied.",
"The board must be a document of a .PrjPcb in its folder."
],
"related": [
"altium_export_manufacturing",
"altium_run_drc"
],
"statusVerb": null,
"summary": "Export the board as ODB++ (copper, drill, stack-up, netlist and parts in one archive) through the tool's own exporter.",
"timeoutSeconds": 600
},
{
"example": {
"bomFields": {
"mpn": "MPN"
},
"filePath": "C:/proj/Board.PcbDoc"
},
"hint": "Name the part fields with bomFields, or the BOM inside the file carries no part numbers.",
"input": {
"bomFields": "{mpn, manufacturer, distributorPn, distributor}: the part field names that carry these, so the embedded BOM is useful to the fab",
"compress": "bool, default false: zip the XML",
"filePath": "path to the board file (default: the board open in the tool)",
"outputDir": "folder for the output (default beside the board)",
"units": "mm|in, default mm",
"version": "B|C, default C"
},
"longRunning": false,
"name": "altium_export_ipc2581",
"output": {
"file": "path"
},
"pitfalls": [
"Run run_drc first: the file carries the board's errors with it.",
"Altium writes it with its manufacturing template's settings: units, compression and version options are reported under optionsNotApplied.",
"The board must be a document of a .PrjPcb in its folder."
],
"related": [
"altium_export_manufacturing",
"altium_run_drc"
],
"statusVerb": null,
"summary": "Export the board as IPC-2581: one XML file with copper, drill, stack-up, netlist and BOM, through the tool's own exporter.",
"timeoutSeconds": 600
},
{
"example": {
"dimensionsMm": {
"A": 1.75,
"D": 4.9,
"E": 6.0,
"E1": 3.9,
"e": 1.27,
"pins": 8
},
"family": "soic",
"outputPath": "C:/lib/SOIC8.step"
},
"hint": "The body is in the package's own frame (IPC-7351 zero orientation, pin 1 top-left, seated on z = 0), ready for add_body. Compare bboxMm with the datasheet's body size before attaching it.",
"input": {
"dimensionsMm": "{letter: mm}: the package drawing's JEDEC letters (A height, A1 standoff, D body length, E lead span, E1 body width, D1 body length of a QFP, b lead width, e pitch, L lead length, c lead thickness, D2/E2 exposed pad) plus pins (rows, cols for a BGA); a missing one takes the family's default",
"family": "chip | soic | qfn | qfp | bga | sot23 | dfn | melf | ecap | crystal | header (required; an unknown one is answered with the families the bridge supports)",
"marking": "text on the top face (an MPN or a value code); a newline starts a second line. Capitals, digits and - + / . in a segment font, sized to fit the top",
"markingStyle": "raised (30 um proud, the default) | engraved (a 5 um layer flush on the top: the body is not cut)",
"outputPath": "the .step file to write (required)"
},
"longRunning": false,
"name": "altium_generate_body",
"output": {
"bboxMm": "{x, y, z}",
"dimensionsMm": "{letter: mm}: every dimension used, defaults included",
"families": "[string] (when family is unknown)",
"family": "string",
"marking": "string | null",
"solids": "int",
"stepPath": "path"
},
"pitfalls": [
"A wrong dimension gives a plausible but wrong body: nothing checks it against a datasheet.",
"Written by the bridge, no CAD tool needed: plain prisms (round cans and balls are many-sided), a dark body and bright leads.",
"A marking is real geometry in a segment font: very small text on a small package is unreadable, which is not an error; characters the font does not draw are listed under notApplied."
],
"related": [
"altium_add_body",
"altium_bodies",
"altium_export_step"
],
"statusVerb": null,
"summary": "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 header), to IPC-7351 proportions, and write it as a STEP file.",
"timeoutSeconds": 60
},
{
"example": {
"libraryPath": "C:/lib/Parts.PcbLib",
"metadata": {
"description": "SOIC-8, wider pads"
},
"name": "SOIC8",
"pads": [
{
"number": "1",
"set": {
"sizeMm": [
1.6,
0.6
]
}
}
]
},
"hint": "Operations run in the order pads, addPads, renumber, graphics, metadata, models. An edited pad keeps its id. Positions are mm from the footprint's origin, as read_footprint gives them.",
"input": {
"addPads": "[pad]: {number, at, sizeMm, shape, drillMm, layers, rotation, type}",
"dryRun": "bool, default false: answer the plan and change nothing",
"graphics": "[{layer, mode: append|replace|delete, widthMm?, shapes: [{type: line {start, end} | arc {center, radius, startAngle, endAngle} | rect {start, end} | circle {center, radius} | poly {points}}]}]",
"libraryPath": "path to the footprint library (required)",
"metadata": "{description?, tags?, attributes?}",
"models": "{mode: replace|append|delete, list: [{path, offset, scale, rotate}]}",
"name": "the footprint's name (required)",
"pads": "[{number, set?: {sizeMm, at, shape, drillMm, layers, rotation, type, newNumber}, delete?: true}]",
"renumber": "{map: {\"1\": \"A1\"}} | {sequential: true, start?: 1}"
},
"longRunning": false,
"name": "altium_edit_footprint",
"output": {
"changes": "[string]: what was done, in order (ok:... or err:...)",
"footprint": "{pads, graphics, courtyardMm} read back",
"notApplied": "[string]"
},
"pitfalls": [
"Boards that already use the footprint keep their own copy: update them with swap_footprint.",
"Graphics replace and delete touch shapes only, never text on that layer.",
"An Altium footprint has no tags or BOM attributes (they belong to the placed part): those are reported under notApplied.",
"Models are aligned onto the pads by add_body: offset, scale and rotate are reported under notApplied."
],
"related": [
"altium_read_footprint",
"altium_swap_footprint",
"altium_add_body"
],
"statusVerb": null,
"summary": "Edit a library footprint in place: change, delete, add or renumber pads; add, replace or delete graphics on a layer; set its description; replace, add or delete 3D models. Everything not edited stays as it was.",
"timeoutSeconds": 300
},
{
"example": {
"at": [
5,
15
],
"layer": "F.SilkS",
"svgPath": "C:/art/logo.svg",
"widthMm": 12
},
"hint": "Filled shapes import; text and images are listed in skipped (convert text to paths first). A shape inside another becomes a hole.",
"input": {
"anchor": "topleft|center, default topleft: which point of the artwork at names",
"at": "[x, y] mm (required)",
"dryRun": "bool, default false: answer the plan and change nothing",
"expectedRevision": "string: the revision you last read (routing_state); refused with stale_board if the board changed",
"filePath": "path to the board file (default: the board open in the tool)",
"layer": "default F.SilkS",
"mirror": "bool, default true on bottom layers",
"net": "a net for artwork on copper",
"scale": "number, default 1",
"svg": "the SVG text (instead of svgPath)",
"svgPath": "path to the .svg",
"toleranceMm": "number, default 0.02: curve flattening",
"widthMm": "number: the artwork's width (or scale)"
},
"longRunning": false,
"name": "altium_import_svg",
"output": {
"holes": "int",
"ids": "[id]",
"polygons": "int",
"revision": "string: the board's new revision",
"sizeMm": "[w, h]",
"skipped": "[{element, why}]"
},
"pitfalls": [
"Stroke-only artwork imports nothing: give the SVG filled shapes.",
"On copper the shapes are graphics: give net to tie them to a net, and run run_drc.",
"On a bottom layer the artwork is mirrored so it reads correctly from the back; mirror:false keeps it as drawn.",
"Without widthMm the size comes from the SVG's width in mm or in, else 96 px to the inch."
],
"related": [
"altium_routing_state",
"altium_remove_graphics",
"altium_render_board_layers"
],
"statusVerb": null,
"summary": "Import SVG artwork (a logo, a label) as filled polygons on a silkscreen, copper, mask or user layer, at a position and size; curves flattened, holes kept. One undo step.",
"timeoutSeconds": 300
},
{
"example": {
"filePath": "C:/proj/Board.PcbDoc",
"uniquePins": true
},
"hint": "Ask the fixture or assembly house which options it needs; uniquePins is the common one.",
"input": {
"filePath": "path to the board file (default: the board open in the tool)",
"flipBottomPads": "bool, default false",
"outputDir": "folder for the output (default beside the board)",
"uniquePins": "bool, default false: rename duplicate pad numbers (several fixture tools need it)",
"useDrillOrigin": "bool, default false: coordinates from the drill origin instead of the board's origin"
},
"longRunning": false,
"name": "altium_export_gencad",
"output": {
"counts": "{components, shapes, pads, signals, routes, vias, copperWithoutNet}",
"file": "path",
"optionsNotApplied": "[option]"
},
"pitfalls": [
"Run run_drc first: the file carries the board's errors with it.",
"Altium has no GenCAD exporter: the bridge writes it from the board model, in inches. useDrillOrigin is reported under optionsNotApplied."
],
"related": [
"altium_export_manufacturing",
"altium_export_ipc356"
],
"statusVerb": null,
"summary": "Export the board as GenCAD 1.4, the input of test-fixture tools and some assembly houses' CAM.",
"timeoutSeconds": 300
},
{
"example": {
"contours": true,
"filePath": "C:/proj/Board.PcbDoc",
"layers": [
"Edge.Cuts"
]
},
"hint": "One file per layer, named after the board and the layer. For an enclosure drawing export Edge.Cuts with contours:true.",
"input": {
"contours": "bool, default false: join outline segments into polylines (most CAM and laser tools want it)",
"excludeDesignators": "bool, default false",
"excludeValues": "bool, default false",
"filePath": "path to the board file (default: the board open in the tool)",
"layers": "[\"Edge.Cuts\", \"F.Cu\"]: layer names (required; there is no sensible default)",
"outputDir": "folder for the output (default a DXF folder beside the board)",
"titleBlock": "bool, default false",
"units": "mm|in, default mm",
"useDrillOrigin": "bool, default false"
},
"longRunning": false,
"name": "altium_export_dxf",
"output": {
"files": "[{layer, path, entities}]",
"optionsNotApplied": "[option]",
"unknownLayers": "[name]"
},
"pitfalls": [
"The board's DXF only: a mechanical DXF of a 3D design is a different job and not this verb.",
"Written from the board model, not Altium's exporter: texts are not drawn, and titleBlock and useDrillOrigin are reported under optionsNotApplied."
],
"related": [
"altium_render_board_layers",
"altium_export_step"
],
"statusVerb": null,
"summary": "Export chosen board layers to DXF, one file per layer (the outline, panel drawings, stencils, enclosure work).",
"timeoutSeconds": 300
},
{
"example": {
"filePath": "C:/proj/Board.PcbDoc"
},
"hint": "Send it with the Gerbers when the fab tests boards against the netlist. Altium writes it as its Test Point Report in IPC-D-356A, every pad and via on both sides.",
"input": {
"filePath": "path to the board file (default: the board open in the tool)",
"outputDir": "folder for the output (default beside the board)"
},
"longRunning": false,
"name": "altium_export_ipc356",
"output": {
"file": "path",
"files": "[path]"
},
"pitfalls": [
"Run run_drc first: the file carries the board's errors with it.",
"The board must be a document of a .PrjPcb in its folder."
],
"related": [
"altium_export_manufacturing",
"altium_netlist",
"altium_run_drc"
],
"statusVerb": null,
"summary": "Export the IPC-D-356 netlist of the board, for bare-board electrical test (flying probe or bed of nails).",
"timeoutSeconds": 600
},
{
"example": {},
"hint": "Cheap. Call it before an edit verb to make sure the right document is in front.",
"input": {},
"longRunning": false,
"name": "altium_document_info",
"output": {
"kind": "project | schematic | board | library | model | other",
"modified": "bool: it has unsaved changes",
"name": "string",
"path": "file path or cloud location | null",
"project": "string | null",
"saved": "bool: it exists as a file or a cloud item",
"version": "int | null: the saved version, where the tool keeps versions"
},
"pitfalls": [
"A schematic and a board of one design are separate documents in some tools: kind says which one is in front.",
"Altium keeps no version numbers for local files: version is null."
],
"related": [],
"statusVerb": null,
"summary": "The active document: its name, what kind it is, whether it has unsaved changes, where it is saved and which version it is. Read only; opens nothing.",
"timeoutSeconds": 300
},
{
"example": {
"save": true
},
"hint": "Use it to start from a clean editor. keptOpen tells you what still needs a decision.",
"input": {
"discardUnsaved": "bool, default false: close changed documents without saving (their changes are lost)",
"includeScratch": "bool, default false: also close never-saved scratch documents",
"save": "bool, default false: save each changed document, then close it",
"under": "folder: only the documents in it (a project folder)"
},
"longRunning": false,
"name": "altium_close_all_documents",
"output": {
"closed": "[name]",
"keptOpen": "[{name, why: unsaved changes | scratch}]",
"saved": "[name]"
},
"pitfalls": [
"discardUnsaved loses changes that exist nowhere else: ask the person first.",
"A scratch document was never saved, so closing one with unsaved changes loses it entirely.",
"Altium closes a document without a dialog: a changed one stays open unless save or discardUnsaved says otherwise."
],
"related": [],
"statusVerb": null,
"summary": "Close every open document without a save dialog. Unsaved work is never lost by default: a document with unsaved changes stays open and is listed, unless save or discardUnsaved says what to do with it.",
"timeoutSeconds": 300
},
{
"example": {
"project": "C:/proj/Board.PrjPcb"
},
"hint": "Read this before renaming, snapshotting or editing a project.",
"input": {
"project": "path to the project file, its folder or any of its documents (required)"
},
"longRunning": false,
"name": "altium_project_info",
"output": {
"board": "{layers, parts, nets, sizeMm}",
"files": "[{path, bytes, modified}]",
"modified": "date",
"name": "string",
"netClasses": "[string]",
"open": "bool: the tool has a document of this project open",
"sheets": "the sheet tree, as sch_hierarchy answers it",
"textVariables": "{name: value}"
},
"pitfalls": [
"The board's layers, parts, nets and size come from Altium when it has the board open; net classes are listed by altium_net_classes."
],
"related": [],
"statusVerb": null,
"summary": "A project at a glance: name, files with sizes and dates, the sheet tree, the board (layers, parts, nets, size), text variables, net classes, last change, and whether the tool has it open. Read only.",
"timeoutSeconds": 300
},
{
"example": {
"layers": 4,
"name": "widget",
"parentDir": "C:/Users/me/Documents/Projects"
},
"hint": "Next: draw the outline (set_outline), then place and route. fabRules is recorded, not applied.",
"input": {
"dryRun": "bool, default false: answer the plan and change nothing",
"fabRules": "a fab name from adom/pcb-design-rules, recorded to apply once the board has content",
"layers": "int, default 2",
"name": "string (required): the project and folder name",
"parentDir": "folder to create the project in (required)",
"textVariables": "{\"REV\": \"A\"}",
"title": "string"
},
"longRunning": false,
"name": "altium_project_create",
"output": {
"files": "[path]",
"project": "path"
},
"pitfalls": [
"A folder that already holds a project is refused.",
"The board has no outline yet: set it before routing or exporting.",
"The sheet comes from Altium's ANSI B template, the board is Altium's default new board with its layer count set; text variables are project parameters."
],
"related": [],
"statusVerb": null,
"summary": "Create a new project folder with a project file, an empty schematic and an empty board (2 to 32 copper layers), with a title and text variables.",
"timeoutSeconds": 300
},
{
"example": {
"dryRun": true,
"newName": "widget-v2",
"project": "C:/proj/Old.PrjPcb"
},
"hint": "Dry-run first: the plan lists every file renamed and what changes inside each. Close the project in the tool first.",
"input": {
"dryRun": "bool, default false: answer the plan and change nothing",
"newName": "string (required)",
"project": "path to the project file (required)"
},
"longRunning": false,
"name": "altium_project_rename",
"output": {
"changed": "[{file, what}]",
"renamed": "[{from, to}]"
},
"pitfalls": [
"Child sheet files keep their names; only the documents named after the project are renamed.",
"The folder keeps its name.",
"Take a project_snapshot first if the project is not under version control.",
"Refused while Altium has any document of the project open."
],
"related": [],
"statusVerb": null,
"summary": "Rename a project: the project file, the root sheet, the board and the tool's side files, with the references inside them updated. Refused while the tool has the project open.",
"timeoutSeconds": 300
},
{
"example": {
"label": "before-routing",
"project": "C:/proj/Board.PrjPcb"
},
"hint": "Take one before a risky edit (a rename, a big re-route). Libraries in sub-folders are referenced, not copied.",
"input": {
"label": "string: added to the folder name",
"pdfs": "bool, default true",
"project": "path to the project file (required)"
},
"longRunning": false,
"name": "altium_project_snapshot",
"output": {
"files": "[path]",
"folder": "path",
"pdfs": "{made: [path], skipped: why}"
},
"pitfalls": [
"A snapshot of an open project holds what is saved on disk, not unsaved edits: save first.",
"The PDF holds every sheet and the board's composite print (altium_export_pdf)."
],
"related": [],
"statusVerb": null,
"summary": "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.",
"timeoutSeconds": 300
},
{
"example": {
"filePath": "C:/proj/Board.PcbDoc",
"ref": "U3"
},
"hint": "Reads the open board when the tool serves it, else the file.",
"input": {
"filePath": "path to the board file (default: the board open in the tool)",
"path": "the symbol's sheet path",
"ref": "\"U1\"",
"schematic": "path to a sheet of the project (default the project's)",
"select": "bool, default false: also select the matches in the tool",
"symbolId": "the schematic symbol's id"
},
"longRunning": false,
"name": "altium_cross_probe",
"output": {
"matches": "[{board: {ref, id, side, x, y, rotation}, schematic: {sheet, id, ref, symbol, value}, linked: bool}]",
"symbolWithoutPart": "[ref]"
},
"pitfalls": [
"linked:false means the board part has no link to a symbol: placed by hand, or update_pcb never ran.",
"Sheets are read from their saved files; a part matched by designator alone is linked:false."
],
"related": [],
"statusVerb": null,
"summary": "From a schematic part to the board part linked to it, and back, by designator, the schematic symbol's id or its sheet path; optionally select them in the tool.",
"timeoutSeconds": 300
},
{
"example": {
"libId": "Package_SO:SOIC-8_3.9x4.9mm_P1.27mm"
},
"hint": "Read before edit_footprint, and to check pin 1 and the pad numbers against the symbol.",
"input": {
"libId": "\"Lib:Name\": resolved through the project's and then the global library table",
"libraryPath": "path to the footprint library",
"name": "the footprint's name (with libraryPath)",
"project": "path to the project, for libId"
},
"longRunning": false,
"name": "altium_read_footprint",
"output": {
"attributes": "{mount, excludeFromBom, excludeFromPos, dnp}",
"courtyardMm": "[x1, y1, x2, y2]",
"graphics": "{layer: count}",
"layers": "[string]",
"models": "[{path, offset, scale, rotate}]",
"name": "string",
"pads": "[{number, type, shape, at, sizeMm, drillMm, layers, rotation}]",
"properties": "{name: value}"
},
"pitfalls": [
"Altium has no library table: give libraryPath and name (libId is not used). courtyardMm is the footprint's bounding box."
],
"related": [],
"statusVerb": null,
"summary": "Every detail of one library footprint: pads (number, type, shape, position, size, drill, layers), the layers it uses, its courtyard box, graphics per layer, attributes, properties and 3D models. The library mirror of read_symbol; footprint_primitives reads a part placed on the board.",
"timeoutSeconds": 300
},
{
"example": {
"filePath": "C:/proj/Board.PcbDoc",
"side": "top"
},
"hint": "One call per side: top and bottom for a review. A flat image of chosen layers is render_board_layers; show_3d_board opens a window instead.",
"input": {
"background": "default|transparent|opaque",
"filePath": "path to the board file (default: the board open in the tool)",
"format": "png|jpg, default png",
"height": "int px, default 900",
"outputDir": "folder for the output (default beside the board)",
"perspective": "bool, default false",
"quality": "basic|high, default basic (high raytraces and is much slower)",
"side": "top|bottom|left|right|front|back, default top",
"width": "int px, default 1600",
"zoom": "number, default 1.0"
},
"longRunning": false,
"name": "altium_render_board_3d",
"output": {
"height": "int",
"image": "path",
"side": "string",
"width": "int"
},
"pitfalls": [
"Parts without a 3D model render as bare pads: check them with bodies first.",
"Altium's PCB 3D Print looks straight down at the top or up at the bottom: other sides need a window (altium_show_3d_board). height, quality, background, zoom, perspective and format are reported under optionsNotApplied.",
"The board must be a document of a .PrjPcb in its folder."
],
"related": [
"altium_show_3d_board",
"altium_export_pdf"
],
"statusVerb": null,
"summary": "Render a 3D picture of the board from one side to an image file, through the tool's own renderer, without opening a window.",
"timeoutSeconds": 600
},
{
"example": {
"dpi": 300,
"format": "png",
"preset": "assembly_top"
},
"hint": "Each preset is a fixed set of layers, so two bridges draw the same view. For a 3D picture use render_board_3d. The show_* verbs open a window; this one does not.",
"input": {
"area": "board | extent (default board: the outline plus 1 mm; extent prints every object, rooms and parts off the board too)",
"dpi": "int, default 300 (png)",
"filePath": "path to the board (optional; default the open board)",
"format": "png | svg (default png)",
"layers": "[layer]: copper by its standard name (F.Cu, In1.Cu, B.Cu) or any layer by the tool's own id; overrides preset",
"listPresets": "bool: answer the presets and their layers, and make no image",
"mirror": "bool, default false: draw the board as seen from below",
"monochrome": "bool, default false",
"outputPath": "the image file to write (default beside the board)",
"preset": "all | top_copper | bottom_copper | top_silkscreen | bottom_silkscreen | top_soldermask | bottom_soldermask | top_paste | bottom_paste | outline | drill | assembly_top | assembly_bottom | fabrication (default all)"
},
"longRunning": false,
"name": "altium_render_board_layers",
"output": {
"format": "png | svg",
"heightPx": "int (png)",
"layers": "[layer]: what was drawn",
"path": "path",
"preset": "string, or custom when layers was given",
"presets": "{name: description} (listPresets)",
"widthPx": "int (png)"
},
"pitfalls": [
"Mirroring is never automatic: a bottom preset is drawn as seen from the top unless mirror is true.",
"Inner copper layers appear only when listed in layers.",
"PNG only (svg is refused): Altium prints to PDF and Windows renders it. The print fills an A4 landscape page; dpi sets the image width from that page.",
"The board must be a document of a .PrjPcb in its folder."
],
"related": [
"altium_show_3d_board",
"altium_export_pdf"
],
"statusVerb": null,
"summary": "Render chosen board layers to an image file without opening a window: a preset view (copper, silkscreen, solder mask, paste, outline, drill, assembly or fabrication, of either side) or a list of layers, as png or svg.",
"timeoutSeconds": 600
},
{
"example": {
"libraryPath": "C:/libs/power.lbr",
"parts": [
"TPS54202"
],
"views": [
"symbol",
"footprint",
"3d"
]
},
"hint": "The four pictures a reviewer checks before a part is used: the pin names on the symbol, the pad shapes, the body on its pads, and every pin mapped to a pad.",
"input": {
"libraryPath": "path to the library (required)",
"outputDir": "folder for the images (default beside the library)",
"parts": "[part name] (required)",
"views": "[symbol, footprint, 3d, device] (default all four)"
},
"longRunning": false,
"name": "altium_library_views",
"output": {
"captured": "[{part, view, path, ok, error?}]"
},
"pitfalls": [
"The 3d view needs a body on the part (add_body): a part without one is reported with ok false, not drawn empty.",
"Altium has no device view: it is reported ok false and points to altium_pin_pad_check.",
"From a .SchLib, the footprint is the symbol's PCB model, found in a .PcbLib beside the library."
],
"related": [
"altium_show_symbol",
"altium_show_footprint",
"altium_show_3d_chip"
],
"statusVerb": null,
"summary": "Pictures of library parts for review, each as an image file: the schematic symbol, the footprint (pads and layers), the 3D body seated on the footprint, and the device view that maps symbol pins to pads.",
"timeoutSeconds": 900
},
{
"example": {
"part": "IN-S42ATA"
},
"hint": "Use it to hand one part to another project or another tool.",
"input": {
"footprint": "a footprint name (default the symbol's own)",
"footprintLibrary": "the .PcbLib that holds the footprint (default: one beside libraryPath that has it)",
"libraryPath": "path to the .SchLib that holds the part (required on Altium)",
"outputDir": "folder for the files",
"part": "the part's symbol name or library id (required)",
"what": "[symbol, footprint, model] (default all three)"
},
"longRunning": false,
"name": "altium_export_library_part",
"output": {
"exports": "{symbol: path, footprint: path, model: path}",
"missing": "[what]"
},
"pitfalls": [
"success is false when any piece asked for is missing; exports still carries what was written.",
"Altium has no global library table: libraryPath (the .SchLib) is required; the footprint is the symbol's PCB model, from a .PcbLib beside it unless footprintLibrary names one.",
"model is the STEP file the 3D body came from: a body embedded with no source file left is reported missing (the .PcbLib still carries it)."
],
"related": [
"altium_xcopy_footprint",
"altium_sch_place_part",
"altium_update_pcb"
],
"statusVerb": null,
"summary": "Export one library part into its own small library files: a symbol library with only its symbol, a footprint library with only its footprint, and its 3D model file.",
"timeoutSeconds": 900
},
{
"example": {
"part": "IN-S42ATR"
},
"hint": "The board keeps the footprint's 3D model, so render_board_3d and show_3d_board show the real part. One part by design.",
"input": {
"footprint": "a footprint name (default the symbol's own)",
"footprintLibrary": "the .PcbLib that holds the footprint (default: one beside libraryPath that has it)",
"libraryPath": "path to the .SchLib that holds the part (required on Altium)",
"outputDir": "folder (default the user's projects folder)",
"overwrite": "bool, default false: replace a project of that name",
"part": "the part's symbol name or library id (required)",
"projectName": "string (default from the part)"
},
"longRunning": false,
"name": "altium_create_part_project",
"output": {
"board": "path",
"project": "path",
"schematic": "path"
},
"pitfalls": [
"The part's symbol and footprint must both be in a library the tool can find.",
"An existing project of that name is refused unless overwrite:true.",
"Altium has no global library table: libraryPath (the .SchLib) is required; both libraries are added to the new project so its change order finds the footprint.",
"The default folder is part-projects beside the library."
],
"related": [
"altium_xcopy_footprint",
"altium_sch_place_part",
"altium_update_pcb"
],
"statusVerb": null,
"summary": "Generate a small real project (schematic and board) around one library part, so the part can be shown and tested in every view: schematic, 2D board and 3D board.",
"timeoutSeconds": 900
},
{
"example": {
"connections": [
{
"designator": "U2",
"kind": "power",
"net": "GND",
"pin": "1"
},
{
"designator": "U2",
"net": "VIN",
"pin": "VIN"
}
],
"sheet": "C:/proj/Main.SchDoc"
},
"hint": "Net labels with the same text connect across the project; power ports connect by net name everywhere. Check the result with altium_compile (ERC) or altium_schematic_data.",
"input": {
"connections": "[{designator, pin (number or name), net, kind: label|power|wire|noerc|port (default label), io?: input|output|bidirectional (port), stubMil (default 200)}] (required)",
"save": "bool, default true",
"sheet": "path to the .SchDoc (required)"
},
"longRunning": false,
"name": "altium_sch_connect",
"output": {
"connected": "int",
"failed": "[..]",
"results": "[{designator, pin, net, kind, result, endMil}]",
"saved": "bool"
},
"pitfalls": [
"A pin that already has a wire gets a second stub; read the sheet first when unsure.",
"A part rotated after connecting leaves its stubs behind."
],
"related": [
"altium_sch_place_part",
"altium_compile",
"altium_schematic_data"
],
"statusVerb": null,
"summary": "Connect pins of placed parts: a wire stub from each pin's outer end plus a net label (kind label), a power port (kind power: GND-like nets get a ground symbol) or the stub alone (kind wire); or mark a pin left open on purpose with a No ERC marker (kind noerc, no net). One undo step.",
"timeoutSeconds": 90
},
{
"example": {
"edits": [
{
"action": "comment",
"designator": "R5",
"text": "10k"
},
{
"action": "delete",
"designator": "C9"
}
],
"sheet": "C:/proj/Main.SchDoc"
},
"hint": "Wires do not follow a moved part; reconnect with altium_sch_connect. Renames and deletions reach the board with altium_update_pcb.",
"input": {
"edits": "[{designator, action: move|moveBy|rotate|designator|comment|delete, x,y | dx,dy | degrees | to | text}] (required)",
"save": "bool, default true",
"sheet": "path to the .SchDoc (required)"
},
"longRunning": false,
"name": "altium_sch_edit",
"output": {
"applied": "int",
"failed": "[..]",
"results": "[{designator, action, result}]",
"saved": "bool"
},
"pitfalls": [
"Every part of a multi-part component with that designator is changed together."
],
"related": [
"altium_sch_connect",
"altium_update_pcb",
"altium_sheet_params"
],
"statusVerb": null,
"summary": "Change placed parts on a sheet: move (to x,y mil), moveBy (dx,dy), rotate (degrees), rename (designator), re-comment (comment), delete. One undo step.",
"timeoutSeconds": 90
},
{
"example": {
"designator": "C10",
"library": "C:/proj/Lib.SchLib",
"sheet": "C:/proj/Main.SchDoc",
"symbol": "CC0402-100NF"
},
"hint": "Then altium_update_pcb carries the new part's footprint and parameters to the board. A workspace part: altium_workspace_place it beside, connect, then altium_sch_edit delete the old one.",
"input": {
"designator": "the part to replace (required)",
"footprint": "optional footprint name",
"keepComment": "bool, default false (the new part's own comment)",
"library": "path to the .SchLib (required)",
"pcbLib": "optional .PcbLib for that footprint",
"save": "bool, default true",
"sheet": "path to the .SchDoc (required)",
"symbol": "the new part's name in it (required)"
},
"longRunning": false,
"name": "altium_sch_swap_part",
"output": {
"newPinsNotOnOld": "[pin]",
"now": "{libReference, footprints}",
"oldPinsNotOnNew": "[pin]",
"pinsJoined": "[{pin, from, to}]"
},
"pitfalls": [
"Pins are matched by number.",
"Multi-part components are refused."
],
"related": [
"altium_sch_place_part",
"altium_sch_edit",
"altium_sch_connect",
"altium_update_pcb"
],
"statusVerb": null,
"summary": "Replace a placed part with another library part (a different value, package or symbol) at the same place, designator and rotation, keeping its connections: where a new pin ends elsewhere, a wire joins it to where the old pin ended.",
"timeoutSeconds": 120
},
{
"example": {
"designators": [
"U1",
"L1"
],
"sheet": "C:/proj/Main.SchDoc"
},
"hint": "To find which sheet holds a part, altium_bom (or altium_schematic_data per sheet) lists every designator with its sheet.",
"input": {
"designators": "[string] or 'R1,U2' (required)",
"sheet": "path to the .SchDoc (required)",
"shot": "bool, default true"
},
"longRunning": false,
"name": "altium_sch_zoom",
"output": {
"notOnSheet": "[string]",
"parts": "[{designator, xMil, yMil}]",
"shot": "frame of Altium's main window"
},
"pitfalls": [],
"related": [
"altium_zoom_to",
"altium_schematic_data",
"altium_sch_edit"
],
"statusVerb": null,
"summary": "Find parts on a sheet: select them (everything else deselected), frame the view on them and return a proof frame. The schematic half of cross-probing (the board half: altium_zoom_to).",
"timeoutSeconds": 60
},
{
"example": {
"name": "Lite",
"notFitted": [
"R5",
"C9",
"J2"
],
"projectPath": "C:/proj/board.PrjPcb"
},
"hint": "altium_bom {variant} then gives that build's BOM (not-fitted parts dropped). Saves the project's documents, closes and reopens the project to load the change.",
"input": {
"fitted": "[designators] to put back (their variation is dropped)",
"name": "variant name; omit to list",
"notFitted": "[designators] to mark Not Fitted (alias dnp)",
"projectPath": "path to the .PrjPcb (required)",
"remove": "bool - delete the variant"
},
"longRunning": false,
"name": "altium_variants",
"output": {
"altium": "{variants:[{name, variations:[{designator, kind}]}]} as Altium reads them (kind 1 = not fitted, 2 = alternate)",
"variants": "[{name, notFitted, alternates}]"
},
"pitfalls": [
"Variants with parameter variations are refused (edit those in Altium's Variant Management).",
"Parts are named by their sheet's unique id: on a multi-channel (repeated) sheet every channel gets the same variation.",
"Alternate parts are listed but not created here."
],
"related": [
"altium_bom",
"altium_export_manufacturing",
"altium_run_outjob"
],
"statusVerb": null,
"summary": "Assembly variants of a project (which parts are fitted on which build): list them, make or change one with not-fitted parts (or put parts back), or remove one. Altium's script API cannot create variants, so the bridge writes them into the .PrjPcb, reloads the project and reads back what Altium holds.",
"timeoutSeconds": 300
},
{
"example": {
"mech": 1,
"widthMm": 0.1
},
"hint": "altium_export_manufacturing checks the outline Gerbers and calls this itself when they are empty (addOutline:false stops it). altium_save keeps the outline.",
"input": {
"filePath": "path to the .PcbDoc - optional",
"mech": "mechanical layer number, default 1",
"replace": "bool - draw even when the layer already holds primitives",
"widthMm": "line width, default 0.1"
},
"longRunning": false,
"name": "altium_board_outline",
"output": {
"alreadyThere": "primitives the layer held",
"drawn": "segments drawn",
"layer": "string"
},
"pitfalls": [
"A layer that already holds anything is left alone unless replace:true (it may be the outline already, drawn by hand)."
],
"related": [
"altium_export_manufacturing",
"altium_set_outline",
"altium_board_shape"
],
"statusVerb": null,
"summary": "Draw the board shape as tracks and arcs on a mechanical layer: the outline a fab house reads from the Gerbers. A board built by script has its shape but nothing on an outline layer, so its GM1/GKO Gerbers are empty.",
"timeoutSeconds": 60
},
{
"example": {
"netClass": "Power",
"widthMm": 0.5
},
"hint": "Run altium_routing_drc {full:true} after: wider copper can break clearance to neighbours.",
"input": {
"filePath": "path to the .PcbDoc - optional",
"layer": "top | bottom | mid N - optional, default every layer",
"netClass": "class name (its nets)",
"nets": "[string] board net names",
"widthMm": "number (required)"
},
"longRunning": false,
"name": "altium_set_track_width",
"output": {
"byNet": "{NET: count}",
"changed": "int",
"drcAfter": "{errors, unconnected}"
},
"pitfalls": [
"Copper inside footprints (pads' own tracks) is left alone."
],
"related": [
"altium_net_classes",
"altium_route_net",
"altium_routing_drc",
"altium_add_rule"
],
"statusVerb": null,
"summary": "Set the width of the EXISTING tracks and arcs on nets or a net class (rules only steer new routing). Widen power nets after routing, or thin a net that fails clearance.",
"timeoutSeconds": 120
},
{
"example": {
"query": "100nF 0402"
},
"hint": "Then altium_workspace_place {sheet, query, pick} puts one on a sheet. Altium's 365 API is a closed beta; the signed-in Altium reaches the workspace itself (altium_signin_status).",
"input": {
"limit": "int, default 25",
"query": "text: an MPN, a value and package ('100nF 0402'), a part name (required)"
},
"longRunning": false,
"name": "altium_workspace_search",
"output": {
"count": "int",
"results": "[{index, name, description, footprint}]"
},
"pitfalls": [
"Takes 5-40 s (Altium's WPF panel answers UI Automation slowly; slower when the panel must first be opened).",
"It types into the panel's search box: Altium comes to the front."
],
"related": [
"altium_workspace_place",
"altium_signin_status",
"altium_bom"
],
"statusVerb": null,
"summary": "Search the Altium 365 workspace's components (the shared cloud library Altium is signed in to) through Altium's own Components panel: name, description and footprint per result.",
"timeoutSeconds": 180
},
{
"example": {
"query": "100nF 0402 50V",
"sheet": "C:/proj/Main.SchDoc",
"x": 3000,
"y": 2000
},
"hint": "Then altium_annotate (for a '?'), altium_sch_connect, altium_update_pcb. A part from a local .SchLib goes on with altium_sch_place_part instead.",
"input": {
"designator": "optional, else Altium's ('C?')",
"pick": "result index (0-based) or text its name contains; default the first",
"query": "the search (required; an MPN finds one part)",
"save": "bool, default true",
"sheet": "path to the .SchDoc (required)",
"x": "mils",
"y": "mils"
},
"longRunning": false,
"name": "altium_workspace_place",
"output": {
"picked": "{name, description, footprint}",
"placed": "{designator, libReference, comment, itemGuid, sourceLibrary, xMil, yMil}"
},
"pitfalls": [
"Takes 15-70 s. Uses real clicks (double-click the result, click the sheet): Altium comes to the front.",
"The part lands near the view's lower-left corner first, then moves to x,y: wires do not follow, so connect it after."
],
"related": [
"altium_workspace_search",
"altium_sch_place_part",
"altium_annotate",
"altium_sch_connect",
"altium_update_pcb"
],
"statusVerb": null,
"summary": "Put a part from the Altium 365 workspace on a sheet: search, pick a result, place it (Altium's own placement, so the part keeps its workspace link, parameters and footprint), move it to x,y and name it.",
"timeoutSeconds": 300
},
{
"example": {
"pcbPath": "C:/proj/Board.PcbDoc",
"projectPath": "C:/proj/Board.PrjPcb"
},
"hint": "A pin with no pad is a net that can never reach copper: change the footprint (altium_swap_footprint) or renumber the symbol's pins before routing.",
"input": {
"pcbPath": "its .PcbDoc",
"projectPath": "the .PrjPcb"
},
"longRunning": false,
"name": "altium_pin_pad_check",
"output": {
"matching": "int",
"mismatches": "[{ref, pinsWithoutPad, padsWithoutPin, pins, pads}]",
"ok": "bool - every pin has a pad",
"onBoardOnly": "[ref]",
"onSheetsOnly": "[ref]"
},
"pitfalls": [
"Mounting and thermal pads (MH*, MP*, SH*, EP*, PAD*, TAB*, unnamed or 0) are expected to have no pin."
],
"related": [
"altium_schematic_review",
"altium_update_pcb",
"altium_swap_footprint",
"altium_component_pins"
],
"statusVerb": null,
"summary": "Do the footprints fit their symbols? Part by part, the symbol's pin numbers (from the sheet files) against the footprint's pad names (from the board): pins with no pad, pads with no pin, and parts on only the sheets or only the board.",
"timeoutSeconds": 200
},
{
"example": {
"matchTo": "DP",
"net": "DN"
},
"hint": "Then altium_net_lengths (the pair or group), altium_routing_drc. For a matched group, tune each short net to the longest (matchTo).",
"input": {
"clearance": "to other copper, default 0.2",
"dryRun": "bool - plan only",
"expectedRevision": "optional",
"filePath": "the .PcbDoc (opened first; else the current board)",
"matchTo": "or: a net whose length to match",
"maxAmplitudeMm": "bump height limit, default 3",
"net": "the net to lengthen",
"pitchMm": "one bump's length along the track (default 4 x width, at least 4 x clearance + 2 x width)",
"targetMm": "the length it should have"
},
"longRunning": false,
"name": "altium_length_tune",
"output": {
"changed": "bool",
"errorMm": "number",
"lengthBeforeMm": "number",
"lengthMm": "number",
"plan": "{layer, replaces, bumps, amplitudeMm, pitchMm, side, addsMm, points}",
"targetMm": "number"
},
"pitfalls": [
"Only lengthens: a net already longer than its target is left alone.",
"One serpentine per call, in one track; call again to add more elsewhere."
],
"related": [
"altium_net_lengths",
"altium_route_pair",
"altium_add_rule",
"altium_routing_drc"
],
"statusVerb": null,
"summary": "Lengthen a routed net to a target length, or to match another net (a pair's skew, a DDR byte lane): a serpentine in its longest straight track that has room beside it, the bumps sized to add exactly the length missing, every bump clear of other copper and inside the board.",
"timeoutSeconds": 120
},
{
"example": {
"apply": true,
"powerWidthMm": 0.6
},
"hint": "Then scope rules to them (InNetClass('Power')), size the pairs with altium_impedance {apply}, and check power with altium_current_capacity.",
"input": {
"apply": "bool - write the classes and pairs (default: propose only)",
"filePath": "the .PcbDoc (opened first; else the current board)",
"powerWidthMm": "the Power class's width rule, default 0.5"
},
"longRunning": false,
"name": "altium_auto_classes",
"output": {
"applied": "bool",
"proposal": "{classes:{GND, Power, Clock, HighSpeed}, pairs:[{name, pos, neg}], unclassified}",
"written": "[{class|pair, success}]"
},
"pitfalls": [
"Names only: a net called N1 stays unclassified. Read the proposal before apply."
],
"related": [
"altium_net_classes",
"altium_diff_pairs",
"altium_impedance",
"altium_add_rule",
"altium_current_capacity"
],
"statusVerb": null,
"summary": "Net classes from the nets' own names: GND, Power (VCC, VDD, 3V3, VBAT...), Clock, HighSpeed (USB, Ethernet, HDMI, PCIe, DDR, MIPI, LVDS, SATA...) and the differential pairs their _P/_N, +/-, DP/DN names spell; a proposal first, written as Altium net classes (Power with a width rule) and pairs with apply.",
"timeoutSeconds": 180
},
{
"example": {
"marginMm": 0.25
},
"hint": "Move what it names (altium_move_parts, altium_find_space for a clear spot), then route.",
"input": {
"edgeMm": "pad to board edge, default 0.5",
"filePath": "the .PcbDoc (opened first; else the current board)",
"marginMm": "courtyard margin round each part, default 0.1 (parts closer than 0.2 mm are flagged)"
},
"longRunning": false,
"name": "altium_placement_check",
"output": {
"courtyardOverlaps": "[{parts, side, overlapMm}]",
"nearEdge": "[{ref, padToEdgeMm}]",
"offOrOverEdge": "[{ref, where}]",
"ok": "bool",
"onMountingHoles": "[{ref, hole}]",
"parts": "int"
},
"pitfalls": [
"A part's box is its pads and its 3D body, so an L-shaped part reads as its bounding box; on or off the board is judged by its pads."
],
"related": [
"altium_move_parts",
"altium_find_space",
"altium_height_check",
"altium_board_features"
],
"statusVerb": null,
"summary": "Review the placement before routing: parts whose courtyards (pads and body, grown by a margin) overlap on the same side, parts off the board or over its edge, pads too close to the edge for assembly and depanelling, and parts on a mounting hole.",
"timeoutSeconds": 180
},
{
"example": {
"pcbPath": "C:/proj/Board.PcbDoc",
"projectPath": "C:/proj/Board.PrjPcb"
},
"hint": "Open the file in a browser or send it; each section names the verb to run for its full detail.",
"input": {
"out": "the .html to write (default '<board> report.html' beside the project)",
"pcbPath": "its .PcbDoc",
"projectPath": "the .PrjPcb"
},
"longRunning": false,
"name": "altium_board_report",
"output": {
"elapsedSec": "number",
"needsWork": "int",
"pass": "int",
"picture": "bool",
"report": "path",
"sections": "[{title, ok (true|false|null = info), summary}]"
},
"pitfalls": [
"Runs Altium's full batch DRC and frames the board in Altium's window for the picture (no focus taken).",
"Takes about a minute on a small board."
],
"related": [
"altium_fab_check",
"altium_assembly_check",
"altium_schematic_review",
"altium_pin_pad_check",
"altium_return_path",
"altium_copper_balance",
"altium_height_check",
"altium_routing_drc"
],
"statusVerb": null,
"summary": "One shareable page per board: every check run against the live board and its project (Altium's DRC, JLCPCB fab limits and assembly tiers, the schematic review, symbols against footprints, impedance widths, return paths, copper balance, 3D heights) with a picture of the board, written as a single HTML file.",
"timeoutSeconds": 900
},
{
"example": {
"pitchMm": 1.1,
"ref": "U3"
},
"hint": "Pour the pad's net on the far side (altium_apply_pours) so the heat has somewhere to go, ask the fab to tent or plug vias in pads, then altium_routing_drc. adom-fields solves the heat itself.",
"input": {
"drill": "mm (default the board's via rule)",
"dryRun": "bool - plan only",
"expectedRevision": "optional",
"filePath": "the .PcbDoc (opened first; else the current board)",
"insetMm": "from the pad's edge, default 0.1",
"pad": "the pad's name (default the part's largest pad)",
"pitchMm": "default via size + 0.5, at least 1.0",
"ref": "the part (e.g. U3)",
"size": "via diameter mm (default the board's via rule)"
},
"longRunning": false,
"name": "altium_thermal_vias",
"output": {
"applied": "int",
"failed": "int",
"planned": "{part, pad, net, padMm, vias, pitchMm, via, points}"
},
"pitfalls": [
"Open vias in a pad wick solder away from it during reflow: tent or plug them, or keep drills at 0.3 mm or smaller."
],
"related": [
"altium_apply_pours",
"altium_board_features",
"altium_routing_drc",
"altium_current_capacity"
],
"statusVerb": null,
"summary": "A thermal via grid in a part's exposed pad (the ground or thermal pad under a QFN, DFN, PowerPAD or regulator): centred, inset from the pad's edge, sized by the board's Routing Via rule, on the pad's net.",
"timeoutSeconds": 120
},
{
"example": {
"diffOhms": 90,
"from": {
"neg": "U1.15",
"pos": "U1.14"
},
"neg": "USB_DN",
"pos": "USB_DP",
"to": {
"neg": "J1.2",
"pos": "J1.3"
},
"via": [
[
20,
10
],
[
30,
10
]
]
},
"hint": "Then altium_net_lengths for the routed skew, altium_add_rule {kind:\"diffpair\"} to hold width and gap, and altium_routing_drc.",
"input": {
"clearance": "to other nets' pads when checking the plan, default 0.15",
"diffOhms": "solve width (and gap = width unless given) for this differential impedance on the layer",
"fanMm": "fan-out length at each end, default 1",
"force": "bool - route even when the plan check finds problems",
"from": "{pos: \"U1.3\", neg: \"U1.4\"} the source pads",
"gap": "mm",
"layer": "F.Cu (default) | B.Cu | In<n>.Cu",
"neg": "the negative net",
"pos": "the positive net",
"rule": "bool, default true - add a width rule for the two nets (+/-10%) so the board's own width rule does not flag the pair",
"to": "{pos, neg} the destination pads",
"via": "[[x,y]...] centreline waypoints mm (optional)",
"width": "mm"
},
"longRunning": false,
"name": "altium_route_pair",
"output": {
"gapMm": "number",
"lengthsMm": "{pos, neg}",
"revision": "string",
"sizedFor": "the impedance row used | null",
"skewMm": "number",
"widthMm": "number"
},
"pitfalls": [
"One layer per call; split a pair that changes layer into two calls at the via pair.",
"The waypoints are the pair's centreline, so keep them clear of other copper by half the pair's width."
],
"related": [
"altium_route_net",
"altium_impedance",
"altium_diff_pairs",
"altium_net_lengths",
"altium_add_rule"
],
"statusVerb": null,
"summary": "Route a differential pair as a pair: one centreline from the source pads' midpoint through waypoints to the destination pads' midpoint, each net offset to its own side at width + gap with mitred corners and a short fan-out from each pad; width and gap given or solved from the stack-up for a target impedance; both lengths and the skew answered.",
"timeoutSeconds": 120
},
{
"example": {
"projectPath": "C:/proj/Board.PrjPcb"
},
"hint": "Fix on the sheets (altium_sch_connect, altium_sch_place_part for a missing capacitor), then altium_update_pcb. altium_run_erc is Altium's own ERC with its rules.",
"input": {
"projectPath": "the .PrjPcb (its sheets are read from file; the netlist is Altium's compile)"
},
"longRunning": false,
"name": "altium_schematic_review",
"output": {
"decoupling": "[{net, ics, capacitors, ok}]",
"errors": "[{check, pin|net, ...}]",
"nets": "int",
"ok": "bool - no errors",
"pins": "int",
"sheets": "[path]",
"warnings": "[{check, ...}]"
},
"pitfalls": [
"Pins named NC, N/C or DNC are expected to float.",
"Ground nets are recognised by name (GND, AGND, DGND, PGND, VSS, 0V, *_GND)."
],
"related": [
"altium_netlist",
"altium_read_sheet_file",
"altium_run_erc",
"altium_sch_connect",
"altium_update_pcb"
],
"statusVerb": null,
"summary": "Review the schematic before Update PCB: every placed pin (read from the sheet files, with its electrical type) against Altium's compiled netlist. Errors: power pins on no net, outputs driving each other. Warnings: pins on no net, one-pin nets, inputs nothing drives, IC supplies with no decoupling capacitor to ground.",
"timeoutSeconds": 300
},
{
"example": {
"pcbPath": "C:/proj/Board.PcbDoc",
"projectPath": "C:/proj/Board.PrjPcb"
},
"hint": "Fix what issues lists and run it again; when ready, upload the zip, then the BOM and CPL for assembly and check rotations in JLCPCB's preview.",
"input": {
"outputDir": "the order folder (default 'JLCPCB order <board>' beside the project; emptied first)",
"pcbPath": "its .PcbDoc",
"projectPath": "the .PrjPcb",
"variant": "an assembly variant for the BOM (optional)"
},
"longRunning": false,
"name": "altium_jlcpcb_order",
"output": {
"assemblyService": "economic | standard | null",
"bomFiles": "[..] incl. bom-jlcpcb.csv, cpl-jlcpcb.csv",
"folder": "path",
"gerberZip": "{path, files}",
"issues": "[{from, what, at?}]",
"orderForm": "{layers, dimensionsMm, outerCopperOz, minTrackSpaceMm, minHoleMm}",
"ready": "bool - fab fits, an assembly tier passes, no issues"
},
"pitfalls": [
"Runs Silkscreen Preparation on the board (through export_manufacturing) and writes the order folder fresh each time.",
"Takes a minute or two: the manufacturing export is most of it."
],
"related": [
"altium_fab_check",
"altium_assembly_check",
"altium_export_manufacturing",
"altium_bom",
"altium_panelize"
],
"statusVerb": null,
"summary": "A JLCPCB order in one call: the board checked against JLCPCB's fab limits, the Gerbers and drill zipped the way JLCPCB's order page takes them, the JLCPCB BOM and pick-and-place (CPL), the assembly-tier check, and the order-form values, in one folder with every issue in one list.",
"timeoutSeconds": 900
},
{
"example": {
"filePath": "C:/proj/Board.PcbDoc",
"projectPath": "C:/proj/Board.PrjPcb"
},
"hint": "Fix what the rules mark false: panelize a small board (altium_panelize, then panelMm), add fiducials (altium_board_features), find LCSC numbers (adom-parts-search). Then altium_bom (JLCPCB BOM) and altium_export_manufacturing (pick and place), and check every part's rotation in JLCPCB's preview.",
"input": {
"filePath": "the .PcbDoc (opened first; else the current board)",
"panelMm": "[w, h] when it ships in a panel (altium_panelize's panelMm)",
"projectPath": "the .PrjPcb - checks every purchased BOM line has an LCSC number (altium_bom)"
},
"longRunning": false,
"name": "altium_assembly_check",
"output": {
"board": "{parts, bottomSideParts, finestPitch, smallestChip, tinyFootprints, fiducials, throughHoleParts}",
"economic": "{ok, rules:[{rule, ok, detail}]}",
"linesWithoutLcsc": "[..]",
"service": "economic | standard | null",
"standard": "{ok, rules}"
},
"pitfalls": [
"Pitch is the closest pad centres within one part of 3 or more SMD pads; package size is read from footprint names and two-pad parts' pad spacing.",
"Rotations are not checked: JLCPCB's preview is the authority on orientation."
],
"related": [
"altium_bom",
"altium_export_manufacturing",
"altium_panelize",
"altium_board_features",
"altium_fab_check"
],
"statusVerb": null,
"summary": "Ready for JLCPCB assembly? The board against both JLCPCB PCBA tiers as published (Economic and Standard): board or panel size, thickness and layers, parts on one or both sides, the smallest package and the finest pin pitch, fiducials, and the parts with no LCSC number; answers the cheapest tier every rule allows.",
"timeoutSeconds": 300
},
{
"example": {
"edge": true,
"freqGHz": 2.4,
"nets": [
"ANT_RF"
],
"viaNet": "GND"
},
"hint": "Then altium_repour so the pours join the vias, and altium_run_drc. altium_return_path shows where a net still runs over a gap.",
"input": {
"clearance": "to other copper, mm, default 0.2",
"drill": "mm, default 0.3",
"dryRun": "bool - plan only",
"edge": "bool - a fence round the board edge too",
"edgeInsetMm": "edge fence: distance in from the edge (default via radius + 0.5)",
"expectedRevision": "optional",
"filePath": "the .PcbDoc (opened first; else the current board)",
"freqGHz": "the highest frequency: pitch = lambda/20 in FR-4",
"nets": "[net] - the tracks to fence (e.g. [ANT_RF])",
"offsetMm": "track centreline to via centre (default half the widest track + clearance + via radius + 0.1)",
"pitchMm": "pitch, default 2 (a cap when freqGHz is given)",
"size": "via diameter mm, default 0.6",
"viaNet": "the net the vias tie to (usually GND), required"
},
"longRunning": false,
"name": "altium_via_fence",
"output": {
"applied": "int",
"failed": "int",
"planned": "{vias, candidates, pitchMm, offsetMm, points}"
},
"pitfalls": [
"Vias go through (top to bottom); a pour on viaNet should exist on the layers they join.",
"Spots too close to other copper, pads or the edge are skipped, not forced."
],
"related": [
"altium_return_path",
"altium_board_features",
"altium_repour",
"altium_run_drc",
"altium_apply_pours"
],
"statusVerb": null,
"summary": "A via fence for EMC: a row of ground vias on both sides of RF or fast nets' tracks, and/or round the board edge, at a pitch from the frequency (lambda/20) or given; each via clear of other copper and pads, the same net's vias and the edge.",
"timeoutSeconds": 180
},
{
"example": {
"size": 1.0
},
"hint": "Then altium_silkscreen_prep (it clips silk off the mask) and altium_fab_check {fab:\"jlcpcb\"} for text height and line width. For unplaced parts try refs with a smaller size, or move the part.",
"input": {
"dryRun": "bool - plan only",
"filePath": "the .PcbDoc (opened first; else the current board)",
"gap": "label to part, mm, default 0.2",
"minSize": "mm - parts with no spot at size step down by 0.1 to this (default: size, no shrinking)",
"padClearance": "label to any pad, mm, default 0.15",
"refs": "[ref] - only these (default every part)",
"size": "text height mm, default 1.0 (JLCPCB's minimum)"
},
"longRunning": false,
"name": "altium_silk_designators",
"output": {
"onPadsAfter": "[{ref, pad}] - must be empty",
"onPadsBefore": "[{ref, pad}]",
"placed": "int",
"planned": "dryRun: [{ref, x, y, size, rotation, side, at}]",
"unplaced": "[{ref, why}]"
},
"pitfalls": [
"Labels are tried above, below, right, left and at the corners of the part's body and pads, big parts first.",
"Bottom-side labels are mirrored by Altium; onPadsAfter checks them with Altium's own boxes."
],
"related": [
"altium_silk_state",
"altium_apply_silkscreen",
"altium_silkscreen_prep",
"altium_fab_check"
],
"statusVerb": null,
"summary": "Place every reference designator the way assembly houses want: one size, upright, beside its own part, clear of every pad (JLCPCB: 0.15 mm), every other part's body and the other designators, inside the board; read back from Altium's own text boxes. Parts with no clear spot are reported, not forced onto pads.",
"timeoutSeconds": 600
},
{
"example": {},
"hint": "Pour the lighter layer of an unbalanced pair (altium_apply_pours: a GND pour, or copper thieving) or ask the fab for thieving; then run it again.",
"input": {
"filePath": "the .PcbDoc (opened first; else the current board)",
"resolutionMm": "raster cell, default 0.1"
},
"longRunning": false,
"name": "altium_copper_balance",
"output": {
"balanced": "bool",
"boardMm2": "number",
"layers": "[{layer, copperMm2, percent, plane?}]",
"pairs": "[{layers, percent, differencePoints, ok}] - layer 1 with n, 2 with n-1...",
"poursWithoutRegions": "[{net, layer}] - pours not poured, or hatched from tracks (counted through their tracks)"
},
"pitfalls": [
"A raster of the live board's copper: within a cell of the true area (0.1 mm default).",
"A pour counts only once poured (regions); a hatched pour built from tracks is counted through its tracks only when the board lists them."
],
"related": [
"altium_apply_pours",
"altium_pour_state",
"altium_layer_stack",
"altium_fab_check"
],
"statusVerb": null,
"summary": "How much of each copper layer is copper (tracks, pads, vias and what Altium actually poured, inside the outline; a plane counts full), and how far apart each mirrored pair of layers is: the copper balance a fab asks about because an unbalanced stack bows and twists in reflow.",
"timeoutSeconds": 180
},
{
"example": {
"nets": [
"USB_DP",
"USB_DN",
"CLK"
]
},
"hint": "Extend or join the pour under the net (altium_apply_pours), reroute it over solid copper (altium_route_net), or add a stitching via or capacitor where it changes reference.",
"input": {
"filePath": "the .PcbDoc (opened first; else the current board)",
"nets": "[net] - only these (default every signal net)",
"referenceNets": "[net] - the reference nets (default: every net that owns a pour or a plane)",
"resolutionMm": "raster cell and sampling step, default 0.1"
},
"longRunning": false,
"name": "altium_return_path",
"output": {
"layersWithNoReferenceCopper": "[layer]",
"nets": "[{net, layer, lengthMm, unreferencedMm, percent, firstGapAt}] worst first",
"ok": "bool",
"referenceNets": "[net]"
},
"pitfalls": [
"Reference copper is pours, planes, the reference nets' own copper and net-less copper (a hatched pour's tracks): another signal's track under a net is not a reference.",
"Checks the two neighbouring copper layers; a board with no pours or planes has nothing to reference (layersWithNoReferenceCopper)."
],
"related": [
"altium_apply_pours",
"altium_pour_state",
"altium_route_net",
"altium_net_lengths",
"altium_board_features"
],
"statusVerb": null,
"summary": "Where signal tracks lose their reference: for every signal net, the length of track on each layer that runs over no pour or plane copper on either neighbouring layer (a split, a gap, a void), with where the first gap starts. The return current detours around those gaps: loop area, emissions, crosstalk.",
"timeoutSeconds": 180
},
{
"example": {
"refs": [
"U1",
"J1"
]
},
"hint": "The input the 3D checks read: height_check, placement_check. Several boxes for a part made of several bodies.",
"input": {
"filePath": "the .PcbDoc (opened first; else the current board)",
"refs": "[string] (optional) - only these parts"
},
"longRunning": false,
"name": "altium_bodies",
"output": {
"bodies": "[{ref, side, x0, y0, x1, y1, z0, z1}] mm",
"count": "int",
"noBody": "[ref]"
},
"pitfalls": [
"Boxes, not shapes: a round body is its bounding box."
],
"related": [
"altium_height_check",
"altium_placement_check",
"altium_add_body"
],
"statusVerb": null,
"summary": "Every part's 3D bodies as boxes in mm (the EDA Bridge Standard's bodies model): footprint rectangle in the board frame and the height range above the surface the part sits on, plus the parts that have no 3D body.",
"timeoutSeconds": 120
},
{
"example": {
"maxBottomMm": 2,
"maxTopMm": 8,
"minGapMm": 0.25,
"regions": [
{
"maxMm": 3,
"name": "display boss",
"rect": [
10,
10,
30,
25
]
}
]
},
"hint": "Move or swap what overLimit and regionHits name (altium_move_parts, altium_swap_footprint); separate colliding parts. Parts in noBody need a body (altium_add_body) before the check means anything for them.",
"input": {
"filePath": "the .PcbDoc (opened first; else the current board)",
"limit": "how many of the tallest parts to list (default 25)",
"maxBottomMm": "limit below the bottom side",
"maxTopMm": "height limit above the top side",
"minGapMm": "report bodies closer than this (default 0: collisions only)",
"regions": "[{rect:[x1,y1,x2,y2] mm, maxMm, side?: top|bottom, name?}] - lid features over part of the board"
},
"longRunning": false,
"name": "altium_height_check",
"output": {
"collisions": "[{parts, overlapMm, at}]",
"heights": "[{ref, side, heightMm, rect}]",
"noBody": "[ref] - parts with no 3D body (no height)",
"ok": "bool",
"overLimit": "[{ref, side, heightMm, limitMm, overByMm}]",
"regionHits": "[{region, ref, heightMm, maxMm}]",
"tallest": "{top, bottom}",
"tooClose": "[{parts, gapMm, at}]"
},
"pitfalls": [
"Bodies are compared as boxes, each body its own box; Altium's Component Clearance DRC checks the real shapes.",
"A height is the body's top above the surface its part sits on; the board's own thickness is not included."
],
"related": [
"altium_add_body",
"altium_move_parts",
"altium_find_space",
"altium_run_drc",
"altium_show_3d_board"
],
"statusVerb": null,
"summary": "Will it fit the enclosure? Each part's height from its 3D bodies (top and bottom side), the parts over a height limit board-wide or under a lid feature in a region, and part bodies that collide or come closer than a gap.",
"timeoutSeconds": 120
},
{
"example": {
"nets": {
"GND": 3,
"SW": 3,
"VIN": 3
},
"riseC": 10
},
"hint": "Widen what shortOn names (altium_set_track_width, altium_add_rule kind width) or pour the net (altium_apply_pours); a layer change needs neededPerLayerChange vias side by side (altium_place_vias).",
"input": {
"filePath": "the .PcbDoc (opened first; else the current board)",
"nets": "{net: amps}, e.g. {VIN: 3, GND: 3}",
"platingUm": "via barrel plating, default 25",
"riseC": "allowed temperature rise, default 10"
},
"longRunning": false,
"name": "altium_current_capacity",
"output": {
"nets": "[{net, amps, layers:[{layer, copperUm, narrowestMm, at, neededMm, ok}], shortOn, ok, vias:{count, smallestDrillMm, ampsEach, neededPerLayerChange}, poursOn}]",
"ok": "bool"
},
"pitfalls": [
"IPC-2221 (conservative, the chart fabs quote); IPC-2152 allows more on inner layers next to planes.",
"Reads tracks and arcs: a pour on the same layer (poursOn) may already carry the current."
],
"related": [
"altium_routing_state",
"altium_layer_stack",
"altium_set_track_width",
"altium_add_rule",
"altium_apply_pours",
"altium_place_vias"
],
"statusVerb": null,
"summary": "Will this trace carry the current? For each power net and its current: the narrowest track on every layer it is routed on against the width IPC-2221 needs for the allowed temperature rise (with each layer's real copper weight), and what one of its vias carries.",
"timeoutSeconds": 120
},
{
"example": {
"apply": {
"name": "USB 90",
"scope": "InDifferentialPair('USB')"
},
"diff": 90,
"z0": 50
},
"hint": "Then altium_add_rule or apply writes the rules; altium_diff_pairs lists the pairs to scope them to. Tell the fab the target impedance: it tunes the stack-up with its own solver.",
"input": {
"apply": "{scope: Altium query e.g. InNetClass('RF') or InDifferentialPair('USB'), name?} - one rule per layer at +/-10%",
"diff": "differential ohm, e.g. 90 or 100",
"filePath": "the .PcbDoc (opened first; else the current board)",
"gapMm": "fix the pair gap (default: gap = width)",
"layers": "[layer names] (default every copper layer)",
"z0": "single-ended ohm (default 50 when diff is not given)"
},
"longRunning": false,
"name": "altium_impedance",
"output": {
"applied": "[{layer, rule, success}] | null",
"layers": "[{layer, model, copperUm, dielectricMm:[above, below], width, z0, diffWidth, diffGap, zdiff}]"
},
"pitfalls": [
"Closed-form models (Hammerstad-Jensen, Wheeler, IPC-2141 coupling): within a few percent of a field solver on FR-4; uncoated (mask lowers outer layers 1 to 3 ohm).",
"Inner layers assume planes on both neighbours."
],
"related": [
"altium_layer_stack",
"altium_add_rule",
"altium_diff_pairs",
"altium_net_classes"
],
"statusVerb": null,
"summary": "Controlled impedance from the board's own stack-up: the track width each copper layer needs for a single-ended target (50 ohm default) and the width and gap for a differential pair (90 ohm USB, 100 ohm Ethernet/LVDS), microstrip outside and stripline inside; optionally written as width or diff-pair rules per layer.",
"timeoutSeconds": 120
},
{
"example": {
"cols": 3,
"panelPath": "C:/proj/Panel.PcbDoc",
"pcbPath": "C:/proj/Board.PcbDoc",
"projectPath": "C:/proj/Board.PrjPcb",
"railMm": 5,
"rows": 3,
"separation": "vscore"
},
"hint": "Fix what jlcpcb.rules marks false (panel under 70 mm: more rows or wider rails; copper under 0.4 mm from a cut; rounded corners on a V-cut) and run it again with overwrite:true. Then altium_export_manufacturing {projectPath, pcbPath: the panel}.",
"input": {
"cols": "default 2",
"gapMm": "between boards, default 2 (vscore: 0)",
"overwrite": "bool - replace an existing panelPath (closed in Altium unsaved first); without it an existing file is refused",
"panelPath": "the new panel .PcbDoc",
"pcbPath": "the board's .PcbDoc",
"projectPath": "a .PrjPcb the panel joins (so altium_export_manufacturing can make its Gerbers)",
"railMm": "rail width, default 5 (0 for none)",
"rows": "default 1",
"separation": "none (default) | vscore (boards edge to edge, V-CUT lines across the panel on Mechanical 1 with 'V-CUT' written at both ends, as JLCPCB asks) | tabs (mouse bites: 0.6 mm holes five to a tab, the rout path drawn on Mechanical 1)",
"toolingHoles": "default true: 2 mm unplated holes and 1 mm fiducials when rails are 5 mm or wider"
},
"longRunning": false,
"name": "altium_panelize",
"output": {
"boardMm": "[w, h] of one board's outline",
"boardsAt": "[[x, y]] each board's outline corner from the panel's corner",
"jlcpcb": "{rules:[{rule, ok (true|false|null = a note), detail}], fits}",
"nearestCopperToEdge": "{mm, at}",
"panelMm": "[w, h]",
"panelPath": "path",
"project": "{path, added}",
"saved": "bool",
"separation": "{kind, cutsX, cutsY | tabs, holes, routLines, applied, failed}",
"warnings": "[{copperOutsideOutline}]"
},
"pitfalls": [
"Opens the board, then creates and saves the panel; without projectPath the saved panel is closed (open it with altium_open_document).",
"tabs refuses a board that draws its own outline on a mechanical layer: every copy brings it along closed and a router would cut each board free.",
"JLCPCB's rules as published (V-cut standards and mouse-bite guide, read 2026-10-23): V-cut panels 70 to 475 mm, 0.6 mm boards or thicker, copper 0.4 mm (1.0 recommended) from a cut, at most 25 cuts a side; mouse bites 0.6 mm holes 5 to a set, gaps of 1.2 mm or more."
],
"related": [
"altium_fab_check",
"altium_export_manufacturing",
"altium_board_features",
"altium_set_outline"
],
"statusVerb": null,
"summary": "Step and repeat a board into a manufacturing panel: a new .PcbDoc holding Altium's own embedded board array of the board (rows x cols), with rails, the panel frame on the outline layer, three tooling holes and three fiducials; boards separated by JLCPCB-style V-score lines or mouse-bite tabs, with JLCPCB's rules checked. The array stays linked to the board.",
"timeoutSeconds": 240
},
{
"example": {
"fab": "jlcpcb"
},
"hint": "Computed by the EDA Bridge Standard's shared engine (adom-eda-checks). Fab limits come from adom/pcb-design-rules' records, bundled with the bridge: each finding names the vendor's page and the date it was read. limits adds or overrides any limit. The measured values are what a fab's order form asks for.",
"input": {
"copperOz": "outer copper weight for the preset (default: read from the stack)",
"fab": "a vendor adom/pcb-design-rules covers (jlcpcb, pcbway, osh-park, eurocircuits, aisler, allpcb, elecrow, nextpcb, seeed-fusion, advanced-circuits-4pcb, sierra-circuits, macrofab, adom-3rdpartyfab): its record for this board's layer count (source page and date read in the reply); or a record object from that page",
"filePath": "the .PcbDoc (opened first)",
"limits": "{minTrack, minClearance, minViaDrill, minViaDiameter, minViaAnnularRing, minPadHole, minPadAnnularRing, minSmdPad, minEdgeClearance, minHoleToHoleVia, minHoleToHolePad, maxDrill, minSilkLine, minSilkText, maxLayers, minBoardMm:[w,h], maxBoardMm:[w,h]} in mm - any fab's numbers; with fab, these override the preset",
"process": "the record's process (default standard)"
},
"longRunning": false,
"name": "altium_fab_check",
"output": {
"costlierOrBelowRecommended": "[{feature, boardMm, note}]",
"fab": "{name, service, copperOz, source, read, notes} | null",
"fits": "bool | null",
"measured": "{track, viaDrill, viaDiameter, viaAnnularRing, padHole, padAnnularRing, smdPad, edgeClearance, holeToHoleVia, holeToHolePad, largestDrill, silkText, silkLine: {mm, at}, clearanceRule, copperLayers, boardSize, counts}",
"outsideLimits": "[{limit, limitMm, boardMm, at}]"
},
"pitfalls": [
"Measures the board as it is now, from the live document: routed copper, vias and pads.",
"Board size is the outline's bounding box."
],
"related": [
"altium_routing_state",
"altium_read_rules",
"altium_layer_stack",
"altium_export_manufacturing",
"altium_run_drc"
],
"statusVerb": null,
"summary": "Before ordering: the board's fab-relevant minimums measured from the live board (narrowest track, smallest via drill, diameter and annular ring, smallest pad hole and ring, smallest SMD pad, clearance rule, copper layers, board size), each with where it is; with a fab's limits, which ones fall short.",
"timeoutSeconds": 180
},
{
"example": {
"params": true,
"path": "C:\\\\work\\\\Power.SchDoc"
},
"hint": "The saved file, not the live sheet: an open Altium's unsaved edits are not in it (altium_schematic_data reads those). Useful when Altium is closed, busy or slow, and to check UniqueIDs before Update PCB.",
"input": {
"params": "bool, default false - every parameter with its value",
"path": "the .SchDoc (alias filePath)",
"pins": "bool, default true - each part's own pins plus the shared part 0"
},
"longRunning": false,
"name": "altium_read_sheet_file",
"output": {
"components": "[{designator, libReference, comment, description, uniqueId, partId, partCount, xMil, yMil, orientation, sourceLibrary, params?, pins?}]",
"count": "int",
"elapsedMs": "int",
"format": "the file header"
},
"pitfalls": [
"Binary .SchDoc only (Altium's default); an ASCII-format sheet is refused by name.",
"No connectivity: nets come from altium_netlist."
],
"related": [
"altium_schematic_data",
"altium_part_parameters",
"altium_bom",
"altium_netlist"
],
"statusVerb": null,
"summary": "Read a schematic sheet straight from its .SchDoc file, without Altium (it need not be installed or running): every part with its designator, library reference, comment, UniqueID, part number, position, parameters and pins, in milliseconds.",
"timeoutSeconds": 30
},
{
"example": {
"members": [
"U1",
"R1",
"C1"
],
"name": "CH1",
"room": true
},
"hint": "Use a class per channel or block: rules scope with InComponentClass('<name>'), and the room shows the block's area to the user and to DRC.",
"input": {
"filePath": "the .PcbDoc (opened first)",
"members": "[designators]",
"name": "class name (omit to list)",
"remove": "bool - delete the class and its room",
"room": "true (fit around the members' pads, 1 mm margin) | {marginMm} | {rect: [x1, y1, x2, y2] mm}"
},
"longRunning": false,
"name": "altium_component_classes",
"output": {
"classes": "[{name, members}] (list)",
"members": "[designator]",
"missing": "[designator not on the board]",
"room": "Altium's description of the room rule",
"roomMm": "[x1, y1, x2, y2]"
},
"pitfalls": [
"The room is a confinement rule ('Adom room <name>', top layer): a part outside it is a DRC violation, not a move.",
"The same name replaces the class and its room."
],
"related": [
"altium_net_classes",
"altium_replicate_layout",
"altium_add_rule",
"altium_find_space"
],
"statusVerb": null,
"summary": "List, make or remove component classes on the board, each optionally with a room: a placement area that keeps its parts together (fitted around the parts or a rectangle). The classes scope rules and group a channel for replicate_layout.",
"timeoutSeconds": 120
},
{
"example": {
"filePath": "C:\\\\work\\\\Board.PcbDoc"
},
"hint": "Add teardrops after routing and before the final pour and DRC: altium_repour, then altium_run_drc.",
"input": {
"filePath": "the .PcbDoc (opened first)",
"force": "bool, default false: add even where a teardrop breaks a rule",
"remove": "bool, default false (add)",
"save": "bool, default true",
"selectedOnly": "bool, default false (all)",
"smdPads": "bool, default true",
"tJunctions": "bool, default true",
"tracks": "bool, default true",
"vias": "bool, default true"
},
"longRunning": false,
"name": "altium_teardrops",
"output": {
"dialogsLeft": "[anything Altium asked]",
"steps": "[mode, objects, toggles, OK]",
"teardropsAfter": "int",
"teardropsBefore": "int"
},
"pitfalls": [
"Altium's own sizes are used (via 70% width / 30% length, pads 200% / 100%, curved).",
"force:true places teardrops that violate clearance: leave it off unless the user asks."
],
"related": [
"altium_repour",
"altium_run_drc",
"altium_routing_state",
"altium_selection"
],
"statusVerb": null,
"summary": "Add (or remove) teardrops with Altium's own Tools > Teardrops: on vias and through-hole pads, SMD pads, track width changes and T-junctions, for the whole board or the selection; teardrops counted before and after.",
"timeoutSeconds": 300
},
{
"example": {
"groups": [
{
"nets": [
"D0",
"D1",
"D2",
"D3"
],
"toleranceMm": 0.25
}
]
},
"hint": "Lengthen the short nets of a group with altium_route_net (a detour) until spreadMm is within tolerance; Altium's interactive length tuning is the hand alternative.",
"input": {
"filePath": "the .PcbDoc (opened first)",
"groups": "[{nets:[..], toleranceMm?: 0.5}] - matched-length groups (a DDR byte lane, a parallel bus)",
"nets": "[net] - default every routed net",
"pairs": "[{name?, pos, neg}] - default the board's differential pairs"
},
"longRunning": false,
"name": "altium_net_lengths",
"output": {
"groups": "[{nets:[{net, lengthMm, shortByMm}], spreadMm, withinTolerance, longest}]",
"groupsOutOfTolerance": "int",
"nets": "[{net, lengthMm, byLayer, vias, segments}]",
"pairs": "[{name, pos, neg, posMm, negMm, skewMm}]"
},
"pitfalls": [
"A net with branches sums every branch: a multi-pin net's length is its total copper, not pin to pin.",
"Vias are counted, not added to the length."
],
"related": [
"altium_routing_state",
"altium_route_net",
"altium_diff_pairs",
"altium_add_rule"
],
"statusVerb": null,
"summary": "Routed length of every net (or the ones named) on the live board, by layer with its vias; the skew inside each differential pair; and the spread of matched-length groups against a tolerance.",
"timeoutSeconds": 180
},
{
"example": {
"filePath": "C:\\\\work\\\\Board.PcbDoc"
},
"hint": "Run it before fab outputs and before 3D or screenshot renders: fabs trim silk off pads anyway, but a board that shows ink on copper looks wrong.",
"input": {
"check": "bool, default true: DRC before and after",
"clipLocked": "bool, default false",
"deleteOutsideBoard": "bool, default true",
"filePath": "the .PcbDoc (opened first)",
"minRemainingMil": "shortest silk segment kept (Altium's default 5.9 mil)",
"moveText": "bool, default true: move text off pads (within Altium's Max Distance) instead of clipping it",
"save": "bool, default true",
"selectedOnly": "bool, default false"
},
"longRunning": false,
"name": "altium_silkscreen_prep",
"output": {
"after": "{same}",
"before": "{silkToSolderMask, silkToSilk, silkToBoardRegion, maskSliver}",
"dialogsLeft": "[anything Altium asked]",
"silkOffCopper": "bool",
"steps": "[toggles, OK]"
},
"pitfalls": [
"It uses the board's SilkToSolderMaskClearance rule (Use Design Rules stays on).",
"Text that cannot move within Max Distance stays and is counted in after.silkToSolderMask."
],
"related": [
"altium_silk_state",
"altium_apply_silkscreen",
"altium_run_drc",
"altium_export_manufacturing"
],
"statusVerb": null,
"summary": "Clean the silkscreen off the copper with Altium's own Tools > Silkscreen Preparation: silk clipped clear of every mask opening (pad) by the board's silk rule, designators moved off pads where they fit, silk outside the board deleted; the silkscreen DRC hits counted before and after.",
"timeoutSeconds": 600
},
{
"example": {
"expect": {
"GND": [
"U1.4",
"U10.4"
],
"VBUS": [
"U1.1",
"U10.1"
]
},
"projectPath": "C:\\\\work\\\\Board.PrjPcb"
},
"hint": "Use it to check a schematic the AI drew or edited before altium_update_pcb: expect the nets you meant and read mismatches.",
"input": {
"expect": "optional {net: [\"U1.3\", ...]}: compare pin by pin",
"net": "optional: one net",
"projectPath": ".PrjPcb (required)"
},
"longRunning": false,
"name": "altium_netlist",
"output": {
"compileErrors": "[messages]",
"mismatches": "[{net, missing, extra} | {net, unexpected}] (expect)",
"netCount": "int",
"nets": "{net: [pin]}"
},
"pitfalls": [
"Unnamed nets read as Altium names them (NetU2_3).",
"Compiles the project first: the reply is the design as Altium sees it now."
],
"related": [
"altium_compile",
"altium_schematic_data",
"altium_sch_connect",
"altium_sch_sheet_symbol",
"altium_update_pcb"
],
"statusVerb": null,
"summary": "The compiled netlist of a project: every net with its pins (Designator.Pin) across every sheet, the hierarchy resolved; or one net; or compare with the nets you expect.",
"timeoutSeconds": 300
},
{
"example": {
"child": "Power.SchDoc",
"entries": [
{
"io": "input",
"name": "VIN",
"net": "VBUS"
},
{
"io": "output",
"name": "3V3",
"net": "3V3"
},
{
"io": "passive",
"name": "GND",
"net": "GND"
}
],
"projectPath": "C:\\work\\Board.PrjPcb",
"sheet": "C:\\work\\Top.SchDoc"
},
"hint": "Then connect the child's circuit to its ports (altium_sch_connect kind:'port', or a wire to stubEndMil) and altium_compile {projectPath}: entries and ports join by name.",
"input": {
"child": "the child .SchDoc (required; a name alone sits beside the parent)",
"entries": "[{name, io: input|output|bidirectional|passive, side?: left|right (default inputs left), net?: a parent net to join (a stub and a net label), stubMil?: 300}]",
"name": "the symbol's designator (default the child's name)",
"ports": "bool, default true: put a port on the child for each entry it lacks",
"portsAt": "{left, right, top} mil on the child (defaults 1000, 15000, 9500)",
"projectPath": ".PrjPcb: lists the child when it is not listed yet",
"save": "bool, default true",
"sheet": "the parent .SchDoc (required)",
"widthMil": "default 1400",
"x": "mil, the symbol's top-left corner (default 2000)",
"y": "mil (default 8000)"
},
"longRunning": false,
"name": "altium_sch_sheet_symbol",
"output": {
"childCreated": "bool",
"ports": "{placed:[{name, io, atMil, stubEndMil}], alreadyThere:[name]}",
"steps": "[childCreated | addedToProject]",
"symbol": "{name, file, atMil, sizeMil, entries:[{name, side, io, net, atMil}]}"
},
"pitfalls": [
"Altium never places a sheet entry by itself (its position stays 0,0 and it draws nowhere): the bridge puts each one on the symbol's edge, 100 mil apart.",
"Ports already on the child (by name) are reported in alreadyThere, not doubled."
],
"related": [
"altium_sch_connect",
"altium_compile",
"altium_schematic_data",
"altium_build_schematic"
],
"statusVerb": null,
"summary": "Make a design hierarchical: a sheet symbol on the parent sheet for a child sheet, its entries joined to the parent's nets, and matching ports on the child. A child that does not exist yet is made from Altium's sheet template and added to the project.",
"timeoutSeconds": 240
},
{
"example": {
"fiducials": [
{
"x": 5,
"y": 5
},
{
"x": 45,
"y": 25
}
],
"mountingHoles": {
"corners": {
"inset": 4
},
"drill": 3.2
},
"stitching": {
"net": "GND",
"pitch": 4
}
},
"hint": "dryRun first to see the stitching grid. After stitching, altium_repour so the net's pours join through the vias, then altium_run_drc.",
"input": {
"dryRun": "bool - plan only",
"expectPath": "optional",
"expectedRevision": "optional",
"fiducials": "[{x, y, size?: 1, opening?: 2 (mask opening diameter), side?: top|bottom}]",
"filePath": "the .PcbDoc (opened first; expectPath is opened too)",
"keepouts": "[{rect: [x1, y1, x2, y2] mm, layer?: all (the Keep-Out layer, default) | F.Cu | B.Cu | In<n>.Cu}] - stitching in the same call keeps out of them",
"mountingHoles": "[{x, y, drill?: 3.2, plated?: false, pad?: drill+2.8 when plated, net?}] or {corners: {inset: 4}, drill?, plated?, net?}",
"stitching": "{net (required), pitch?: 5, size?: 0.6, drill?: 0.3, clearance?: 0.3, edge?: 1 (from the outline), region?: [[x,y],..], max?: 400, underParts?: false (vias stay out of each part's pad box)}"
},
"longRunning": false,
"name": "altium_board_features",
"output": {
"applied": "int",
"planned": "{mountingHoles, fiducials, stitching:{count, points}}",
"results": "[ok|err:..] per item",
"state": "routing_state after"
},
"pitfalls": [
"Stitching keeps the pad clearance conservative (a pad's circumscribed circle) and does not look at pours: pours of other nets repour around the vias.",
"Unplated holes are bare holes (pad = drill); plated holes take a ring and can join a net (e.g. GND)."
],
"related": [
"altium_place_vias",
"altium_repour",
"altium_run_drc",
"altium_routing_state"
],
"statusVerb": null,
"summary": "Add the furniture every real board needs in one undo step: mounting holes (at points or the four corners), fiducials, keepout areas, and a stitching-via grid on a net that keeps clear of every other net's copper, every pad and the board edge.",
"timeoutSeconds": 180
},
{
"example": {
"clearanceMm": 0.3,
"near": "U1",
"part": "C10"
},
"hint": "Move the part with altium_move_parts {parts:[{ref, x, y, rotation}]} to a spot, then altium_routing_drc. Extents follow Altium's Component Clearance rule: 3D bodies and pads, or every primitive but text for a part with no body.",
"input": {
"check": "bool - report overlaps instead",
"clearanceMm": "default 0.25",
"copper": "bool, default true - avoid that side's tracks and vias",
"count": "default 5",
"edgeMm": "from the outline, default 0.3",
"near": "designator to place beside (or at: {x, y} mm)",
"part": "designator of the part to place (its own size and origin), or sizeMm: [w, h]",
"precise": "bool, with check - also run Altium's batch DRC and list its Component Clearance violations (primitive to primitive)",
"radiusMm": "search radius, default 10",
"side": "top | bottom (default the part's)"
},
"longRunning": false,
"name": "altium_find_space",
"output": {
"outsideOutline": "[designator] (check)",
"overlaps": "[[a, b]] (check)",
"spots": "[{x, y (the part origin, for move_parts), distanceMm, extent}]"
},
"pitfalls": [
"A part with no 3D body is measured by its silkscreen outline too, as Altium does: dense boards report silk-to-silk overlaps.",
"Rotations are kept: rotate first if the part should sit another way."
],
"related": [
"altium_move_parts",
"altium_routing_state",
"altium_routing_drc"
],
"statusVerb": null,
"summary": "Free spots on the board for a part near another (clear of every other part on that side, of that side's tracks and vias, and inside the outline), nearest first; or check:true lists parts that already overlap or leave the outline.",
"timeoutSeconds": 180
},
{
"example": {},
"hint": "Lets the user point at parts in Altium and say 'these': move them with altium_move_parts {ref, dx, dy}, replicate them with altium_replicate_layout.",
"input": {
"filePath": "optional: the document to make current first",
"select": "[refs] - optional: select exactly these first (everything else deselected), to show the user which parts you mean"
},
"longRunning": false,
"name": "altium_selection",
"output": {
"kind": "board | sheet",
"selected": "[{ref, x, y, rotation, side, footprint, widthMm, heightMm}] or [{designator, xMil, yMil, orientation, libReference, comment}]"
},
"pitfalls": [
"Only components are reported (selected tracks and vias are not)."
],
"related": [
"altium_move_parts",
"altium_replicate_layout",
"altium_zoom_to"
],
"statusVerb": null,
"summary": "What the user has selected in the current board (components with position mm, rotation, side, footprint, size) or sheet (components with location mils and orientation).",
"timeoutSeconds": 60
},
{
"example": {
"minImprovementMm": 0.5
},
"hint": "Rotate with altium_move_parts {parts:[{ref, rotation}]} (position kept).",
"input": {
"filePath": "optional .PcbDoc",
"minImprovementMm": "default 0.6",
"parts": "[refs] - optional, default every 2-pad part",
"planeNetPads": "a net with more pads than this is treated as a plane (nearest-pad distance), default 12"
},
"longRunning": false,
"name": "altium_check_orientation",
"output": {
"checked": "int",
"suggestions": "[{ref, rotation, suggested, airlineNowMm, airlineThenMm, savesMm}]"
},
"pitfalls": [
"Routed copper is not considered: on a routed board these are hints."
],
"related": [
"altium_move_parts",
"altium_find_space",
"altium_routing_state"
],
"statusVerb": null,
"summary": "Advisory: 2-pad parts whose rotation could be better. Each orthogonal rotation is scored in place by airline length (a routable net's MST with the pad there; a plane-like net's distance to its nearest pad); parts whose best rotation saves minImprovementMm are listed. Nothing is moved.",
"timeoutSeconds": 120
},
{
"example": {
"source": [
"U1",
"R1",
"C1"
],
"targets": [
[
"U2",
"R2",
"C2"
],
[
"U3",
"R3",
"C3"
]
]
},
"hint": "Read the channels with altium_selection or altium_component_data; route the targets after (routing is not copied). Check with altium_find_space {check:true}.",
"input": {
"anchor": "optional ref from source (default the first)",
"filePath": "optional .PcbDoc",
"source": "[refs] of the placed channel (2 or more)",
"targets": "[[refs], ...] - each in the same order as source"
},
"longRunning": false,
"name": "altium_replicate_layout",
"output": {
"footprintMismatches": "[..] parts whose footprint differs from their source part",
"moved": "int",
"moves": "[{ref, x, y, rotation}]"
},
"pitfalls": [
"Routing and pours are not copied."
],
"related": [
"altium_move_parts",
"altium_selection",
"altium_find_space"
],
"statusVerb": null,
"summary": "Copy one channel's placement to matching channels: each target keeps its anchor part where it is and every other part takes the source's offset and rotation from the anchor (turned by the anchors' rotation difference).",
"timeoutSeconds": 180
},
{
"example": {
"outjobPath": "C:/proj/board.OutJob"
},
"hint": "Run a container with altium_run_outjob {outjobPath, projectPath, medium:'<container name>'}.",
"input": {
"outjobPath": "path to the .OutJob (required)"
},
"longRunning": false,
"name": "altium_outjob_info",
"output": {
"groups": "[{name, variant, containers: [{name, type, outputs}], outputs: [{type, name, document, enabled, inMedia, settings}]}]"
},
"pitfalls": [
"Reads the saved file: an OutJob open in Altium with unsaved edits is read as saved."
],
"related": [
"altium_run_outjob",
"altium_export_manufacturing"
],
"statusVerb": null,
"summary": "An OutJob's containers (output media), the outputs in each, and their key settings (units, decimals, plotted layer count), read from the .OutJob file: Altium need not be running.",
"timeoutSeconds": 30
},
{
"example": {
"query": "LM358"
},
"hint": "altium_show_symbol / altium_read_symbol on the best match; it is a style reference for a new symbol too.",
"input": {
"kind": "symbol (default) | footprint",
"libraries": "[paths] - optional, default the installed libraries",
"query": "part of the name (required)"
},
"longRunning": false,
"name": "altium_find_symbol",
"output": {
"best": "the exact match, else the shortest name containing it",
"matches": "[{name, library, exact}]"
},
"pitfalls": [
".IntLib files are not searched (altium_extract_intlib gives their sources); the Altium 365 workspace is searched with altium_workspace_search."
],
"related": [
"altium_show_symbol",
"altium_read_symbol",
"altium_list_library",
"altium_workspace_search"
],
"statusVerb": null,
"summary": "Find symbols (or footprints with kind:'footprint') by part of their name across libraries: the given ones, or every installed .SchLib/.PcbLib.",
"timeoutSeconds": 300
},
{
"example": {
"name": "MPN",
"projectPath": "C:/proj/board.PrjPcb"
},
"hint": "Change values with altium_sheet_params; altium_bom groups the purchasing ones by MPN.",
"input": {
"name": "a parameter name - optional",
"projectPath": "path to the .PrjPcb (required)"
},
"longRunning": false,
"name": "altium_part_parameters",
"output": {
"names": "[{name, parts}]",
"values": "[{designator, value, sheet}] (with name)"
},
"pitfalls": [],
"related": [
"altium_sheet_params",
"altium_bom",
"altium_schematic_data"
],
"statusVerb": null,
"summary": "The parameter names a project's parts carry (with how many parts carry each), or with name, that parameter's value on every part.",
"timeoutSeconds": 300
},
{
"example": {
"clearance": 0.3,
"name": "Power",
"nets": [
"VIN",
"VOUT",
"GND",
"SW"
],
"width": 0.5
},
"hint": "Rules land first among their kind, so they outrank the board-wide ones. Existing tracks keep their width: re-route the class's nets or check with altium_run_drc. altium_save keeps it.",
"input": {
"clearance": "mm - optional rule 'Adom <name> clearance' (class to All)",
"filePath": "path to the .PcbDoc - optional, else the current board",
"name": "class name; omit to list",
"nets": "[string] board net names (required to make one)",
"remove": "bool - delete the class and its two rules",
"width": "mm (0.5) or {min, preferred, max} in mm - optional rule 'Adom <name> width'"
},
"longRunning": false,
"name": "altium_net_classes",
"output": {
"classes": "[{name, superClass, nets}] (list)",
"members": "int",
"notOnBoard": "[string] nets that were not found",
"rules": "[{kind, success, ..}]",
"scope": "InNetClass('<name>')"
},
"pitfalls": [
"Net names must exist on the board (altium_list_nets); missing ones are reported in notOnBoard, not created.",
"A class made on the board, not in the schematic, can be removed by a later change order if the project's comparator removes board-only classes."
],
"related": [
"altium_add_rule",
"altium_list_nets",
"altium_read_rules",
"altium_diff_pairs",
"altium_set_design_rules"
],
"statusVerb": null,
"summary": "Net classes on the current board: list them with their nets, or make one (replacing a class of that name) with an optional width and clearance rule scoped to it, or remove one with its rules. Power nets wider, a high-voltage class with more clearance.",
"timeoutSeconds": 90
},
{
"example": {
"name": "USB",
"neg": "USB_DN",
"pos": "USB_DP"
},
"hint": "Pair impedance and gap come from Altium's Differential Pairs Routing rule; set width/clearance for the pair's nets with altium_net_classes or altium_add_rule.",
"input": {
"filePath": "path to the .PcbDoc - optional",
"name": "pair name; omit to list",
"neg": "negative net (e.g. USB_N)",
"pos": "positive net (e.g. USB_P)",
"remove": "bool"
},
"longRunning": false,
"name": "altium_diff_pairs",
"output": {
"pair": "string",
"pairs": "[{name, pos, neg}] (list)",
"replaced": "bool"
},
"pitfalls": [
"Both nets must exist on the board."
],
"related": [
"altium_net_classes",
"altium_list_nets",
"altium_add_rule"
],
"statusVerb": null,
"summary": "Differential pairs on the current board: list them, define one from two nets (replacing a pair of that name), or remove one. Altium's differential-pair router and rules work on these.",
"timeoutSeconds": 90
},
{
"example": {
"filePath": "C:/proj/board.PcbDoc",
"strategy": "Default 2 Layer Board"
},
"hint": "Look at the result before keeping it (altium_show_2d_board) and check it with altium_routing_drc. Altium's rules drive Situs: set them first (altium_set_design_rules, altium_add_rule).",
"input": {
"filePath": "path to the .PcbDoc - optional, else the current board",
"lockPreroutes": "bool, default true - existing tracks are kept",
"ripupViolations": "bool, default false",
"save": "bool, default false",
"strategy": "Default 2 Layer Board | Default Multi Layer Board | Default 2 Layer With Edge Connectors | General Orthogonal | Via Miser | Cleanup (default: the dialog's current)",
"timeout": "seconds, default 600"
},
"longRunning": false,
"name": "altium_autoroute",
"output": {
"after": "{unconnected, errors}",
"before": "{unconnected, errors}",
"saved": "bool",
"steps": "[..]"
},
"pitfalls": [
"Parts outside the board outline get routed to where they sit: place them first (altium_move_parts).",
"With lockPreroutes:false Situs rips up and reroutes existing tracks."
],
"related": [
"altium_route_net",
"altium_routing_drc",
"altium_set_design_rules",
"altium_save"
],
"statusVerb": null,
"summary": "Altium's own autorouter (Situs) on the current board: picks a strategy, keeps existing routing locked by default, routes, and answers the unconnected count and DRC errors before and after. Not saved unless save:true.",
"timeoutSeconds": 900
},
{
"example": {
"projectPath": "C:/proj/board.PrjPcb"
},
"hint": "Then altium_update_pcb carries the designators to the board.",
"input": {
"dryRun": "bool, default false",
"projectPath": "path to the .PrjPcb (required)",
"save": "bool, default true"
},
"longRunning": false,
"name": "altium_annotate",
"output": {
"planned": "[..] (dryRun)",
"renamed": "[{sheet, from, to, result}]",
"skippedMultiPart": "[{sheet, designator, libReference, partId}]"
},
"pitfalls": [
"Multi-part components with '?' are left alone (their parts share one designator); use Altium's Tools > Annotation for those."
],
"related": [
"altium_sch_place_part",
"altium_update_pcb",
"altium_sch_edit"
],
"statusVerb": null,
"summary": "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.",
"timeoutSeconds": 300
},
{
"example": {
"set": {
"Revision": "B",
"Title": "12 V to 5 V buck"
},
"sheet": "C:/proj/Main.SchDoc"
},
"hint": "The title block shows them through =Title, =DocumentNumber, =Revision ... special strings.",
"input": {
"save": "bool, default true",
"set": "{name: value} (optional; missing parameters are added)",
"sheet": "path to the .SchDoc (required)"
},
"longRunning": false,
"name": "altium_doc_params",
"output": {
"params": "[{name, value}]",
"saved": "bool",
"set": "int"
},
"pitfalls": [],
"related": [
"altium_sch_edit",
"altium_export_pdf"
],
"statusVerb": null,
"summary": "Read or set a sheet's document parameters: the title block (Title, DocumentNumber, Revision, DrawnBy, Author, CompanyName, ...).",
"timeoutSeconds": 60
},
{
"example": {
"projectPath": "C:/proj/board.PrjPcb"
},
"hint": "Preview first (the default): removeParts are board parts on no sheet (test pads, fiducials, mounting holes) that the change order would DELETE; it refuses them unless allowRemovals:true. New parts land beside the board outline: place them (altium_move_parts) and check with altium_routing_drc.",
"input": {
"allowRemovals": "bool, default false - let the change order delete board parts that are on no sheet",
"execute": "bool, default false - false only previews",
"projectPath": "path to the .PrjPcb (required)",
"timeout": "seconds, default 300"
},
"longRunning": false,
"name": "altium_update_pcb",
"output": {
"afterExecute": "[string]",
"board": "path",
"changeOrder": "[string] - the dialog's first page (groups carry counts)",
"dialogs": "[..] - anything Altium asked",
"executed": "bool",
"preview": "{addParts, removeParts, sheetParts, boardParts}",
"steps": "[..]"
},
"pitfalls": [
"Save the sheets first (the sch_* verbs save by default).",
"The project must contain a .PcbDoc."
],
"related": [
"altium_annotate",
"altium_sch_place_part",
"altium_move_parts",
"altium_routing_drc"
],
"statusVerb": null,
"summary": "Design > Update PCB Document from the schematic (the engineering change order): parts added, removed or renamed, nets and footprints updated on the board. Previews by default; execute:true runs it (Execute Changes, Close), refusing to delete board parts unless allowRemovals:true.",
"timeoutSeconds": 600
},
{
"example": {
"projectPath": "C:/proj/board.PrjPcb"
},
"hint": "Pull the file with ab's pull_file.",
"input": {
"assembly": "bool, default false - Altium's Assembly Drawings output (needs a board in the project)",
"board": "bool, default false - the composite print",
"fabrication": "bool, default false - Altium's PCB Print fabrication drawing",
"output": "path of the .pdf, default <project>.pdf beside it",
"projectPath": "path to the .PrjPcb (required)",
"timeout": "seconds, default 300"
},
"longRunning": false,
"name": "altium_export_pdf",
"output": {
"assembly": "bool",
"board": "bool",
"fabrication": "bool",
"outputBytes": "int",
"pdfPath": "path",
"sheets": "int"
},
"pitfalls": [],
"related": [
"altium_run_outjob",
"altium_export_manufacturing"
],
"statusVerb": null,
"summary": "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 its fabrication print, from an OutJob in a throwaway project; the user's project is not touched.",
"timeoutSeconds": 600
},
{
"example": {
"designators": [
"R1",
"R2"
],
"params": {
"MPN": "RC0402FR-0710KL",
"Manufacturer": "YAGEO",
"Mouser Part #": "603-RC0402FR-0710KL"
},
"projectPath": "C:/proj/board.PrjPcb"
},
"hint": "The board picks the new parameters up with Design > Update PCB Document; altium_bom reads the sheets, so it shows them at once.",
"input": {
"designators": "[string] or 'R1,R2' (required; every part of a multi-part component)",
"params": "{name: value} or 'Key=Value;Key=Value' (required)",
"projectPath": "path to the .PrjPcb: each designator is found on whichever sheet holds it",
"save": "bool, default true",
"sheet": "path to a .SchDoc - or",
"timeout": "seconds, default 90"
},
"longRunning": false,
"name": "altium_sheet_params",
"output": {
"notFound": "[designator]",
"sheets": "[{sheet, designators, paramsSet}]",
"updated": "[designator]"
},
"pitfalls": [
"Sheet parameters, not the library: altium_set_params changes a library part."
],
"related": [
"altium_bom",
"altium_read_schematic",
"altium_set_params"
],
"statusVerb": null,
"summary": "Write parameters onto PLACED parts on the schematic sheets (the BOM write-back): MPN, Manufacturer, Mouser/DigiKey/LCSC numbers, anything. A missing parameter is added hidden; one undo step per sheet; each touched sheet is saved.",
"timeoutSeconds": 300
},
{
"example": {
"outjobPath": "C:/proj/Assembly.OutJob",
"projectPath": "C:/proj/board.PrjPcb"
},
"hint": "files[] names the BOM the OutJob wrote; pull it with ab's pull_file. For part data without an OutJob, altium_read_schematic returns parameters per component.",
"input": {
"medium": "string, default 'Folder Structure'",
"outjobPath": "path to an .OutJob - default: the bundled example Assembly.OutJob",
"projectPath": "path to the .PrjPcb",
"timeout": "seconds, default 300"
},
"longRunning": false,
"name": "altium_export_bom",
"output": {
"dialogs": "[..]",
"elapsedSec": "float",
"files": "[relative paths]",
"outjob": "path",
"outputDir": "path | null",
"surface": "bom"
},
"pitfalls": [
"Without outjobPath it exports the BOM of Altium's EXAMPLE design.",
"The default OutJob is the example's Assembly.OutJob, which runs every output in that medium, not only a BOM."
],
"related": [
"altium_run_outjob",
"altium_export_gerber",
"altium_read_schematic"
],
"statusVerb": null,
"summary": "Bill of materials export: altium_run_outjob with the assembly OutJob and the 'Folder Structure' medium as defaults.",
"timeoutSeconds": 300
},
{
"example": {
"filePath": "C:/proj/board.PcbDoc",
"output": "C:/proj/board.step"
},
"hint": "outputExists and products[] are the proof; then pull the file with ab's pull_file. Save the board first: the export reads the file on disk.",
"input": {
"componentsOption": "int, Altium ExportComponentOptions, default 0 (all)",
"copperOption": "int, Altium ExportCopperOption, default 0 (no copper)",
"filePath": "path to a .PcbDoc (saved state is exported) - default: the bundled example board",
"folded": "bool, default false",
"holes": "bool, default true (mechanical, electrical and free pad holes)",
"lane": "outjob | extension, default outjob",
"modelsOption": "int, Altium ExportModelsOption, default 2 (template default)",
"nameOccurrences": "bool, default true - name each component occurrence after its designator, as KiCad's STEP does (step2glb --molecule finds MP1-MP4 by it)",
"output": "path - default: <board>.step",
"singlePart": "bool, default false (one merged part)",
"suffix": "string, required with suffixType custom",
"suffixType": "none | board | custom | id, default none - Altium always names parts by DESIGNATOR; this only picks the suffix",
"timeout": "seconds, default 300"
},
"longRunning": false,
"name": "altium_export_step",
"output": {
"elapsedSec": "float",
"lane": "string",
"occurrences": "{named: int} - component occurrences named after their designator",
"output": "path",
"outputBytes": "int",
"outputExists": "bool",
"products": "[string] - STEP PRODUCT names (how parts are named)"
},
"pitfalls": [
"Part names are designators (J1, U3...), never the Comment or footprint: Altium has no option for that (suffixType 0-3 measured).",
"Altium leaves every assembly occurrence unnamed; the bridge names each board component's occurrence after its designator (0.2.54), so tools that find parts by occurrence name (step2glb --molecule's MP1-MP4 anchoring) work as on a KiCad STEP.",
"The throwaway project and OutJob are closed afterwards and the temp folder removed; the user's own project is never opened or changed.",
"pcb_not_found / step_not_written / bad_args are named; dialogs from the OutJob come back under outjob.dialogs."
],
"related": [
"altium_run_outjob",
"altium_save",
"altium_show_3d_board"
],
"statusVerb": null,
"summary": "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 dialog, no click (measured on AD 26.9.1). lane:'extension' is the older AdomBridge .NET extension path.",
"timeoutSeconds": 360
},
{
"example": {
"filePath": "C:/lib/VL53L5CX.kicad_sym"
},
"hint": "Output lands in 'Imported <stem>' beside the source. Then link footprints with altium_set_params {footprint}. For Adom parts prefer altium_import_part, which needs no extension.",
"input": {
"filePath": "path to a .kicad_sym / .kicad_sch / .kicad_pcb (required)",
"mode": "string, default 'Import'",
"timeout": "seconds, default 300"
},
"longRunning": false,
"name": "altium_import_kicad",
"output": {
"elapsedSec": "float",
"result": "string - the extension's result file"
},
"pitfalls": [
"Footprints are NOT imported by Altium's KiCad importer.",
"Same extension caveat as altium_export_step: on AD 26.9.1 it answered extension_timeout."
],
"related": [
"altium_extension_ping",
"altium_install_extension",
"altium_import_part",
"altium_set_params"
],
"statusVerb": null,
"summary": "Import a KiCad file with Altium's own KiCad importer, driven through the AdomBridge .NET extension.",
"timeoutSeconds": 300
},
{
"example": {},
"hint": "Sequence: altium_close, altium_install_extension, altium_launch, altium_extension_ping. Only altium_export_step and altium_import_kicad need it.",
"input": {
"remove": "bool, default false - uninstall instead"
},
"longRunning": false,
"name": "altium_install_extension",
"output": {
"output": "string - installer stdout tail",
"removed": "bool",
"stderr": "string"
},
"pitfalls": [
"Refused with altium_running while any Altium is up (it holds AdomBridge.dll open); remove:true is allowed while running.",
"A failed extension load can stop Altium starting: put extension/REMOVE-AdomBridge.cmd on the Desktop first.",
"It was unregistered on AD 26.9.1 after coinciding with a 'Could not start Vault Explorer' warning: install only when you need those two verbs."
],
"related": [
"altium_extension_ping",
"altium_export_step",
"altium_import_kicad",
"altium_close"
],
"statusVerb": null,
"summary": "Install, update or remove the AdomBridge .NET extension (the PowerShell installer shipped beside the bridge). Altium must be CLOSED.",
"timeoutSeconds": 200
},
{
"example": {},
"hint": "success -> altium_export_step / altium_import_kicad will work. installedOnDisk:true with extension_timeout = installed but not loading on this Altium build.",
"input": {},
"longRunning": false,
"name": "altium_extension_ping",
"output": {
"elapsedSec": "float",
"installedOnDisk": "bool",
"result": "string"
},
"pitfalls": [
"It spawns an X2 -R helper against the running instance: do not loop it."
],
"related": [
"altium_install_extension",
"altium_export_step",
"altium_import_kicad"
],
"statusVerb": null,
"summary": "Does the AdomBridge .NET extension answer? Sends AdomBridge:Ping through the -R lane and waits up to 30 s for its result file.",
"timeoutSeconds": 60
},
{
"example": {
"libraryPath": "C:/lib/Test.PcbLib",
"name": "R0603",
"pads": "1,-30,0,35,37,rect,0;2,30,0,35,37,rect,0"
},
"hint": "The footprint is registered but the library is NOT saved: altium_save {filePath: libraryPath}. Then altium_add_body for 3D and altium_show_footprint to check. For a real part use altium_build_footprint (spec with silkscreen and courtyard).",
"input": {
"description": "string",
"footprints": "[{name, pads, ...}] - optional: make several in one call (each over the shared args)",
"libraryPath": "path to a .PcbLib (required)",
"name": "string (required)",
"pads": "'des,x_mil,y_mil,w_mil,h_mil,rect|round,hole_mil;...' - hole 0 = SMD",
"timeout": "seconds, default 90"
},
"longRunning": false,
"name": "altium_create_footprint",
"output": {
"data": "{footprint, library, libraryState: opened|created, pads: int}",
"shot": "{image: base64 png, width, height}",
"windowEtiquette": "background"
},
"pitfalls": [
"errorCode bad_number = a pad field that must be a number was not; nothing is created.",
"Units are MILS here; altium_build_footprint specs are millimetres.",
"A fresh library carries the stray PCBComponent_1: altium_cleanup_libs."
],
"related": [
"altium_build_footprint",
"altium_add_body",
"altium_save",
"altium_show_footprint"
],
"statusVerb": null,
"summary": "Create one footprint from a pad list in a PcbLib (the library is created and saved if the path does not exist) and return a proof frame.",
"timeoutSeconds": 90
},
{
"example": {
"libraryPath": "C:/lib/Test.SchLib",
"name": "CH340G",
"pins": "1,GND,left,100;2,TXD,left,200;16,VCC,right,100"
},
"hint": "Library is UNSAVED: altium_set_params {footprint, params}, then altium_save {filePath: libraryPath}. For multi-mode symbols use altium_build_symbol_modes.",
"input": {
"bodyHeightMil": "int, default 600",
"bodyWidthMil": "int, default 800",
"description": "string",
"designator": "string, default 'U'",
"libraryPath": "path to a .SchLib (required)",
"name": "string (required)",
"pins": "'des,name,left|right|top|bottom,offset_mil[,part[,hiddenNet]];...' - part 1..N makes a multi-part symbol (a dual op-amp: its A pins part 1, B pins part 2), 0 puts a pin on every part (power); hiddenNet hides the pin and joins it to that net by name (shared power pins: '8,V+,left,300,0,VCC', or the compiler reports duplicate pins)",
"symbols": "[{name, pins, ...}] - optional: make several in one call (each over the shared args)",
"timeout": "seconds, default 90"
},
"longRunning": false,
"name": "altium_create_symbol",
"output": {
"data": "{symbol, library, libraryState: opened|created, pins: int}",
"shot": "{image: base64 png, width, height}",
"windowEtiquette": "background"
},
"pitfalls": [
"A fresh library carries the stray Component_1: altium_cleanup_libs.",
"Pin offsets are mils along the chosen side; check shot.image for overlapping pins."
],
"related": [
"altium_build_symbol_modes",
"altium_set_params",
"altium_read_symbol",
"altium_save"
],
"statusVerb": null,
"summary": "Create one rectangular symbol from a pin list in a SchLib (the library is created and saved if the path does not exist) and return a proof frame.",
"timeoutSeconds": 90
},
{
"example": {
"body": {
"height": 1.75,
"l": 4.9,
"w": 3.9
},
"family": "dual",
"libraryPath": "C:\\\\lib\\\\Parts.PcbLib",
"name": "SOIC-8_3.9x4.9mm_P1.27mm",
"padLength": 1.55,
"padWidth": 0.6,
"pins": 8,
"pitch": 1.27,
"span": 5.4
},
"hint": "dryRun first and compare padTable with the datasheet drawing; then build, check shot.image, altium_save the library and link it with altium_set_models.",
"input": {
"ballPad": "bga pad diameter mm",
"body": "{w, l, height?, standoff?} mm - silkscreen, fab, courtyard, 3D",
"cols": "bga",
"courtyard": "margin mm, default 0.25",
"description": "optional",
"dryRun": "bool - return the pad table and spec only",
"exposedPad": "{w, h, x?, y?, number?}",
"family": "chip | dual | sot | quad | bga",
"leftPins": "sot",
"libraryPath": ".PcbLib (required unless dryRun; created if missing)",
"missing": "bga ['B2', ...]",
"name": "footprint name (required)",
"padLength": "mm, along the lead (across the row)",
"padShape": "roundrect (default) | rect | round | oval",
"padWidth": "mm, along the row",
"pins": "dual/quad total",
"pinsPerSideX": "quad, top/bottom",
"pinsPerSideY": "quad, left/right",
"pitch": "mm",
"polarized": "chip: add the pin-1 dot",
"rightPins": "sot",
"rows": "bga",
"silkClearance": "default 0.2",
"silkWidth": "default 0.15",
"span": "mm, pad centre to pad centre across the rows (quad: left-right)",
"spanY": "quad, top-bottom (default span)"
},
"longRunning": false,
"name": "altium_footprint_from_land_pattern",
"output": {
"body3d": "{success}",
"shot": "{image}",
"spec": "the staged spec path",
"summary": "{pads, courtyardMm, silkLines, padTable:[[name, x, y, w, h]]}"
},
"pitfalls": [
"The numbers are the datasheet's RECOMMENDED LAND PATTERN, not the package outline: pad size and the pad-centre span.",
"Pin 1 is top-left (Y up), counter-clockwise, the IPC convention."
],
"related": [
"altium_build_footprint",
"altium_create_footprint",
"altium_add_body",
"altium_set_models",
"altium_save",
"altium_show_footprint"
],
"statusVerb": null,
"summary": "Build a complete footprint from the land pattern a datasheet prints: pads numbered the standard way (chip, dual SOIC/TSSOP/DFN, SOT, quad QFP/QFN, BGA), an exposed pad, the courtyard, silkscreen kept clear of the copper with a pin-1 dot, a fab outline with a pin-1 chamfer, and an extruded 3D body when the height is given.",
"timeoutSeconds": 300
},
{
"example": {
"libraryPath": "C:/lib/Adom_ToF.PcbLib",
"spec": "C:/lib/specs/VL53L5CX.fp.txt"
},
"hint": "Stage the spec with ab's send_files first. Then altium_add_body {step}, altium_plate_vias for thermal vias, altium_save. altium_import_part does all of it in one call.",
"input": {
"libraryPath": "path to a .PcbLib (required; created if missing)",
"spec": "Windows path to the spec (tools/kicad2altium.py output; mm, Y up) (required)",
"timeout": "seconds, default 240"
},
"longRunning": false,
"name": "altium_build_footprint",
"output": {
"data": "{footprint, description, library, libraryState, pads, throughHolePads, drawingPrimitives}",
"shot": "{image: base64 png, width, height}",
"windowEtiquette": "background"
},
"pitfalls": [
"The footprint name comes from the spec's META line, not from an argument.",
"Pads with a repeated designator are legal and all map to that pin (the heatsink-via convention).",
"Library is left UNSAVED."
],
"related": [
"altium_import_part",
"altium_add_body",
"altium_plate_vias",
"altium_show_footprint"
],
"statusVerb": null,
"summary": "Build a complete footprint (pads, silkscreen, courtyard, arcs) in a PcbLib from a kicad2altium spec file on this machine, and return a proof frame.",
"timeoutSeconds": 240
},
{
"example": {
"libraryPath": "C:/lib/Adom_ToF.SchLib",
"spec": "C:/lib/specs/VL53L5CX.sym.txt"
},
"hint": "Then altium_add_symbol_art for the chip outline, altium_add_models / altium_set_models for the footprint, altium_save. altium_symbol_mode {mode} frames each alternate.",
"input": {
"libraryPath": "path to a .SchLib (required; created if missing)",
"spec": "Windows path to the spec (tools/symbol_modes.py output; mils, Y up) (required)",
"timeout": "seconds, default 240"
},
"longRunning": false,
"name": "altium_build_symbol_modes",
"output": {
"data": "{libref, library, libraryState, modes, pins, lines, displayModeCount}",
"shot": "{image: base64 png, width, height}",
"windowEtiquette": "background"
},
"pitfalls": [
"libref comes from the spec's META line.",
"Compare data.displayModeCount with data.modes before trusting the alternates.",
"Library is left UNSAVED."
],
"related": [
"altium_import_part",
"altium_add_symbol_art",
"altium_symbol_mode",
"altium_add_models"
],
"statusVerb": null,
"summary": "Build ONE SchLib component with N display modes (Normal + Alternate 1..N-1) from a symbol_modes spec file on this machine, and return a proof frame.",
"timeoutSeconds": 240
},
{
"example": {
"footprintName": "VL53L5CX",
"libraryPath": "C:/lib/Adom_ToF.PcbLib",
"step": "C:/lib/VL53L5CX.step"
},
"hint": "altium_save {filePath: libraryPath}, then altium_show_3d_chip to look at it; boards that already place the part need PCB:UpdateFootprints. Never engrave the MPN into the STEP.",
"input": {
"bhMil": "int, default 100 - box depth",
"bwMil": "int, default 100 - box width",
"footprintName": "string - required when the library holds more than one footprint",
"hMil": "int, default 40 - box height",
"keepExisting": "bool, default false - ADD next to the existing bodies instead of replacing them (a deliberate second body)",
"libraryPath": "path to a .PcbLib (required)",
"soMil": "int, default 0 - standoff",
"step": "Windows path to a .step - optional",
"timeout": "seconds, default 90"
},
"longRunning": false,
"name": "altium_add_body",
"output": {
"_hint": "string - what was replaced, and a WARNING when bodies are still stacked",
"data": "{footprint, body, replacedBodies, keptExisting, bodiesBefore, sameNameFootprints, bodiesNow, bodiesOnCanvas}",
"normalized": "string - the shifts applied",
"replacedBodies": "int - old bodies removed before the add",
"shot": "{image: base64 png, width, height}"
},
"pitfalls": [
"It REPLACES by default (from 0.2.52): data.replacedBodies says how many old bodies went and data.bodiesNow should read 1. keepExisting:true is the only way to stack a second body.",
"A bad step path ('could not load model') removes nothing: the old body stays.",
"data.sameNameFootprints > 1 = several footprints share the name and only the FIRST got the body: altium_remove_footprint the stale copies.",
"Without footprintName it acts on the only footprint in the library (name_required when there are several).",
"'could not load model' = the STEP path is not on THIS machine: stage it with send_files."
],
"related": [
"altium_normalize_bodies",
"altium_show_3d_chip",
"altium_pcb_report",
"altium_import_part",
"altium_footprint_primitives"
],
"statusVerb": null,
"summary": "Put a 3D body on a footprint of a PcbLib: a STEP model, or an extruded box when no step is given. It REPLACES the footprint's existing 3D bodies (a re-import never stacks a second model) unless keepExisting:true. The bridge then re-aligns bodies onto the pads (normalize_bodies) and returns a frame.",
"timeoutSeconds": 90
},
{
"example": {
"libraryPath": "C:/lib/Adom_ToF.SchLib",
"models": [
{
"description": "LGA-16 6.4x3.0",
"name": "VL53L5CX",
"pcblib": "C:/lib/Adom_ToF.PcbLib"
}
],
"params": {
"Manufacturer Part Number": "VL53L5CXV0GC/1"
},
"symbolName": "VL53L5CX"
},
"hint": "Check data.models is what you sent, then altium_save. To REPLACE the footprint use altium_set_models.",
"input": {
"comment": "string",
"description": "string",
"libraryPath": "path to a .SchLib (required)",
"models": "[{name, pcblib, description}]",
"params": "{key: value}",
"symbolName": "string (required)",
"timeout": "seconds, default 120"
},
"longRunning": false,
"name": "altium_add_models",
"output": {
"data": "{libref, models: int, params: int}",
"shot": "{image: base64 png, width, height}"
},
"pitfalls": [
"NOT idempotent: every call APPENDS another implementation. Repair = altium_set_models, or altium_remove_symbol + re-import.",
"';' and '|' inside a description are rewritten (they are the spec separators).",
"altium_read_symbol does not report models; use altium_symbol_prims {models:true}."
],
"related": [
"altium_set_models",
"altium_set_params",
"altium_symbol_prims",
"altium_remove_symbol"
],
"statusVerb": null,
"summary": "Attach one or more PCBLIB footprint models, parameters, comment and description to a SchLib component (Altium's several-footprints-per-symbol mechanism).",
"timeoutSeconds": 120
},
{
"example": {
"libraryPath": "C:/lib/Adom_ToF.PcbLib"
},
"hint": "altium_add_body already runs it. Use it on libraries built elsewhere when altium_show_footprint shows an empty canvas; then altium_save.",
"input": {
"footprintName": "string - optional filter",
"libraryPath": "path to a .PcbLib - optional; opened first",
"timeout": "seconds, default 120"
},
"longRunning": false,
"name": "altium_normalize_bodies",
"output": {
"data": "{moved: int, shifts: string}",
"roundtripMs": "int"
},
"pitfalls": [
"Without libraryPath it acts on whatever PcbLib is current ('no PCB library is current' otherwise).",
"It centres bodies on the pad-cluster centre: a deliberately offset body is moved too."
],
"related": [
"altium_add_body",
"altium_pcb_report",
"altium_show_3d_chip",
"altium_save"
],
"statusVerb": null,
"summary": "Move every 3D body of a PcbLib's footprints (or one footprint) onto its pad cluster. A body added through the canvas lands 50000 mil from the pads in the stored frame, which makes Zoom All frame 50 inches of nothing.",
"timeoutSeconds": 120
},
{
"example": {
"comment": "VL53L5CX",
"libraryPath": "C:/lib/Adom_ToF.SchLib",
"params": {
"LCSC Part #": "C2888092",
"Manufacturer": "ST"
},
"symbolName": "VL53L5CX"
},
"hint": "Unsaved: altium_save {filePath: libraryPath}. 'LCSC Part #' and 'Manufacturer Part Number' are the JLC/BOM keys. altium_read_symbol shows the result.",
"input": {
"comment": "string",
"footprint": "string - PcbLib footprint name to link",
"libraryPath": "path to a .SchLib (required)",
"params": "{key: value} or 'Key=Value;Key=Value'",
"symbolName": "string - omit for the FIRST component",
"timeout": "seconds, default 90"
},
"longRunning": false,
"name": "altium_set_params",
"output": {
"data": "{component, paramsSet: int, footprint}",
"roundtripMs": "int"
},
"pitfalls": [
"footprint APPENDS an implementation on every call; use altium_set_models to end up with exactly one.",
"Parameters are created HIDDEN (visible ones pile up over the symbol): altium_set_visibility to show one.",
"Without symbolName it edits the first component in the library."
],
"related": [
"altium_read_symbol",
"altium_set_visibility",
"altium_set_models",
"altium_save"
],
"statusVerb": null,
"summary": "Set parameters on a SchLib component, optionally its comment, and optionally link a footprint by name.",
"timeoutSeconds": 90
},
{
"example": {
"libraryPath": "C:/lib/Adom_ToF.SchLib",
"param": "Manufacturer Part Number",
"symbolName": "VL53L5CX",
"visible": true
},
"hint": "altium_save afterwards; altium_show_symbol to see where the text landed.",
"input": {
"libraryPath": "path to a .SchLib - optional; opened first",
"param": "string - the parameter name",
"symbolName": "string",
"timeout": "seconds, default 90",
"visible": "bool, default true"
},
"longRunning": false,
"name": "altium_set_visibility",
"output": {
"data": "{param, visible: '1'|'0'}",
"roundtripMs": "int"
},
"pitfalls": [
"'parameter not found' = the name must match a parameter altium_read_symbol lists.",
"Visible parameters stack over the symbol body: show few."
],
"related": [
"altium_set_params",
"altium_read_symbol",
"altium_show_symbol"
],
"statusVerb": null,
"summary": "Show or hide one named parameter on a SchLib component.",
"timeoutSeconds": 90
},
{
"example": {
"libraryPath": "C:/lib/Adom_ToF.SchLib",
"symbolName": "VL53L5CX"
},
"hint": "The verification step after altium_import_part / altium_set_params: models[] shows which footprint the symbol is bound to (type PCBLIB, isCurrent true for the one a placed part uses). For the drawing use altium_symbol_prims.",
"input": {
"libraryPath": "path to a .SchLib - optional; opened first",
"symbolName": "string",
"timeout": "seconds, default 90"
},
"longRunning": false,
"name": "altium_read_symbol",
"output": {
"data": "{libref, description, displayModeCount, pinsMode0: int, pins: [{des, name, electrical: 0 Input, 1 IO, 2 Output, 3 OpenCollector, 4 Passive, 5 HiZ, 6 OpenEmitter, 7 Power}], params: [{name, value, hidden}], models: [{type, name, isCurrent}]}",
"roundtripMs": "int"
},
"pitfalls": [
"The SCH Library panel's Model pane can lag behind altium_show_symbol; models[] here is the symbol's own record.",
"Only mode 0 pins are listed."
],
"related": [
"altium_symbol_prims",
"altium_set_params",
"altium_list_library",
"altium_show_symbol"
],
"statusVerb": null,
"summary": "Read a SchLib component back: description, display-mode count, the pins of mode 0 (designator, name, electrical type), every parameter with its hidden flag, and its model links (footprints, 3D, sim).",
"timeoutSeconds": 90
},
{
"example": {
"from": "VL53L5CX",
"libraryPath": "C:/lib/Adom_ToF.SchLib",
"to": "VL53L7CX"
},
"hint": "Then altium_set_params on the clone (its own MPN and comment) and altium_save.",
"input": {
"from": "string - existing LibReference",
"libraryPath": "path to a .SchLib - optional; opened first",
"timeout": "seconds, default 90",
"to": "string - new LibReference"
},
"longRunning": false,
"name": "altium_clone_symbol",
"output": {
"data": "{from, to, primitives: int, displayModeCount}",
"roundtripMs": "int"
},
"pitfalls": [
"'target already exists' - pick another name or altium_remove_symbol first.",
"Same library only; there is no cross-library symbol copy."
],
"related": [
"altium_rename_symbol",
"altium_remove_symbol",
"altium_set_params",
"altium_save"
],
"statusVerb": null,
"summary": "Copy a symbol inside the current SchLib under a new name, all display modes included.",
"timeoutSeconds": 90
},
{
"example": {
"from": "Component_1",
"libraryPath": "C:/lib/Adom_ToF.SchLib",
"to": "VL53L5CX"
},
"hint": "altium_save, then altium_list_library to confirm.",
"input": {
"from": "string",
"libraryPath": "path to a .SchLib - optional; opened first",
"timeout": "seconds, default 90",
"to": "string"
},
"longRunning": false,
"name": "altium_rename_symbol",
"output": {
"data": "{renamed: string}",
"roundtripMs": "int"
},
"pitfalls": [
"'to' is NOT checked: an empty or already-used name is applied as given. altium_list_library first."
],
"related": [
"altium_clone_symbol",
"altium_rename_footprint",
"altium_list_library",
"altium_save"
],
"statusVerb": null,
"summary": "Rename a component (LibReference) in the current SchLib.",
"timeoutSeconds": 90
},
{
"example": {
"from": "PCBComponent_1",
"libraryPath": "C:/lib/Adom_ToF.PcbLib",
"to": "VL53L5CX"
},
"hint": "altium_save, then re-link symbols that referenced the old name: altium_set_models {footprint: <new name>}.",
"input": {
"from": "string",
"libraryPath": "path to a .PcbLib - optional; opened first",
"timeout": "seconds, default 90",
"to": "string"
},
"longRunning": false,
"name": "altium_rename_footprint",
"output": {
"data": "{renamed: string}",
"roundtripMs": "int"
},
"pitfalls": [
"'to' is NOT checked: an empty or already-used name is applied as given.",
"Symbols link footprints BY NAME: a rename silently breaks their models."
],
"related": [
"altium_copy_footprint",
"altium_rename_symbol",
"altium_set_models",
"altium_save"
],
"statusVerb": null,
"summary": "Rename a footprint in the current PcbLib.",
"timeoutSeconds": 90
},
{
"example": {
"libraryPath": "C:/lib/Adom_ToF.SchLib",
"symbolName": "VL53L5CX"
},
"hint": "The repair step for a symbol with duplicate models: remove, altium_import_part again, altium_save.",
"input": {
"libraryPath": "path to a .SchLib - optional; opened first",
"symbolName": "string",
"timeout": "seconds, default 60"
},
"longRunning": false,
"name": "altium_remove_symbol",
"output": {
"data": "{removed: string}",
"roundtripMs": "int"
},
"pitfalls": [
"No undo through the bridge; the library is unsaved until altium_save, so altium_close_document without saving is the way back."
],
"related": [
"altium_import_part",
"altium_cleanup_libs",
"altium_list_library",
"altium_save"
],
"statusVerb": null,
"summary": "Delete one component from the current SchLib.",
"timeoutSeconds": 60
},
{
"example": {
"footprintName": "VL53L5CX",
"libraryPath": "C:/lib/Adom_ToF.PcbLib"
},
"hint": "altium_save afterwards. Symbols that linked it keep a dangling model: altium_set_models.",
"input": {
"footprintName": "string",
"libraryPath": "path to a .PcbLib - optional; opened first",
"timeout": "seconds, default 90"
},
"longRunning": false,
"name": "altium_remove_footprint",
"output": {
"data": "{removed: string}",
"roundtripMs": "int"
},
"pitfalls": [
"No undo through the bridge; closing the library without saving is the way back."
],
"related": [
"altium_remove_symbol",
"altium_cleanup_libs",
"altium_list_library",
"altium_save"
],
"statusVerb": null,
"summary": "Delete one footprint from the current PcbLib.",
"timeoutSeconds": 90
},
{
"example": {
"from": "VL53L5CX",
"libraryPath": "C:/lib/Adom_ToF.PcbLib",
"to": "VL53L5CX_HANDSOLDER"
},
"hint": "For a footprint from ANOTHER library use altium_xcopy_footprint. Then altium_save.",
"input": {
"from": "string",
"libraryPath": "path to a .PcbLib - optional; opened first",
"timeout": "seconds, default 90",
"to": "string"
},
"longRunning": false,
"name": "altium_copy_footprint",
"output": {
"data": "{from, to, primitives: int}",
"roundtripMs": "int"
},
"pitfalls": [
"'target already exists' - choose another name or altium_remove_footprint first."
],
"related": [
"altium_xcopy_footprint",
"altium_rename_footprint",
"altium_pcb_report"
],
"statusVerb": null,
"summary": "Duplicate a footprint inside the current PcbLib under a new name (every primitive replicated).",
"timeoutSeconds": 90
},
{
"example": {
"from": "LGA-16",
"fromLib": "C:/lib/Vendor.PcbLib",
"to": "VL53L5CX",
"toLib": "C:/lib/Adom_ToF.PcbLib"
},
"hint": "altium_pcb_report {path: toLib, name} to confirm pads and bodies arrived, then altium_save {filePath: toLib}.",
"input": {
"from": "string - footprint name in the source",
"fromLib": "path to the source .PcbLib",
"timeout": "seconds, default 120",
"to": "string - default: same as from",
"toLib": "path to the destination .PcbLib - optional; else the current PcbLib"
},
"longRunning": false,
"name": "altium_xcopy_footprint",
"output": {
"data": "{to, primitives: int}",
"roundtripMs": "int"
},
"pitfalls": [
"'open the destination PcbLib first' = pass toLib.",
"'target already exists' in the destination: pass a different to."
],
"related": [
"altium_copy_footprint",
"altium_pcb_report",
"altium_save"
],
"statusVerb": null,
"summary": "Copy a footprint ACROSS libraries: from fromLib into toLib (opened and made current), optionally under a new name.",
"timeoutSeconds": 120
},
{
"example": {
"assigns": "1=GND;2=VDD",
"footprintName": "VL53L5CX",
"libraryPath": "C:/lib/Adom_ToF.PcbLib",
"pcbPath": "C:/proj/tof.PcbDoc"
},
"hint": "Built for single-part test boards (altium_test_board): iterate on a footprint and re-prove with altium_show_3d_board. altium_save the board afterwards.",
"input": {
"assigns": "'padDes=NET;...'",
"footprintName": "string",
"libraryPath": "path to the .PcbLib holding the new footprint",
"pcbPath": "path to the .PcbDoc - optional; opened first",
"timeout": "seconds, default 240"
},
"longRunning": false,
"name": "altium_swap_footprint",
"output": {
"data": "{placed, padsOnComp, bodiesOnComp}",
"windowEtiquette": "background"
},
"pitfalls": [
"There is NO designator argument: on a multi-part board it replaces whichever component the iterator returns first.",
"Nets come ONLY from assigns (padDes=NET, all pads sharing a designator get the net): pads you do not list end up with no net."
],
"related": [
"altium_test_board",
"altium_show_3d_board",
"altium_footprint_primitives"
],
"statusVerb": null,
"summary": "Replace the FIRST component on the current board with a footprint from a PcbLib at the same position, re-assigning nets by pad designator. Tracks are untouched, so the wiring survives.",
"timeoutSeconds": 240
},
{
"example": {
"libraryPath": "C:/lib/Adom_ToF.SchLib",
"mode": 1
},
"hint": "Select the component first with altium_show_symbol {libraryPath, symbolName}, then one call per mode up to displayModeCount-1.",
"input": {
"libraryPath": "path to a .SchLib - optional; opened first",
"mode": "int, default 0",
"timeout": "seconds, default 60"
},
"longRunning": false,
"name": "altium_symbol_mode",
"output": {
"data": "{mode, displayModeCount, libref}",
"shot": "{image: base64 png, width, height}",
"windowEtiquette": "background"
},
"pitfalls": [
"There is no symbolName argument: it acts on the component current in the editor.",
"Leave it on mode 0 when done: the editor keeps showing the last mode to the user."
],
"related": [
"altium_show_symbol",
"altium_build_symbol_modes",
"altium_read_symbol"
],
"statusVerb": null,
"summary": "Show one display mode (0 = Normal, 1.. = alternates) of the CURRENT SchLib component in the editor and capture a frame. Drives the editor's own mode toggle, because setting DisplayMode alone does not repaint.",
"timeoutSeconds": 60
},
{
"example": {
"libraryPath": "C:/lib/Adom_ToF.SchLib"
},
"hint": "Run once per new library after the first import, then altium_save and altium_list_library.",
"input": {
"libraryPath": "path to a .SchLib/.PcbLib - optional; opened first",
"timeout": "seconds, default 90"
},
"longRunning": false,
"name": "altium_cleanup_libs",
"output": {
"data": "{removed: int}",
"roundtripMs": "int"
},
"pitfalls": [
"The SchLib side removes ANY component named Component_1 without checking that it is empty.",
"removed:0 is normal on a library that was already clean."
],
"related": [
"altium_list_library",
"altium_remove_symbol",
"altium_remove_footprint",
"altium_save"
],
"statusVerb": null,
"summary": "Remove the factory-default stray every fresh library carries: Component_1 from the current SchLib and an empty (no pads) PCBComponent_1 from the current PcbLib.",
"timeoutSeconds": 90
},
{
"example": {
"libraryPath": "C:/lib/Adom_ToF.SchLib"
},
"hint": "Takes effect live, no restart. For a wiki bundle zip use altium_install_library_bundle (unpack + register + proof).",
"input": {
"libraryPath": "path to a .IntLib/.SchLib/.PcbLib/.DbLib (required)",
"timeout": "seconds, default 90"
},
"longRunning": false,
"name": "altium_install_library",
"output": {
"data": "{installed: path}",
"roundtripMs": "int"
},
"pitfalls": [
"'library not found' = the path must exist on THIS machine.",
"Registers the file where it is: moving or deleting it later leaves a dead entry."
],
"related": [
"altium_install_library_bundle",
"altium_list_library",
"altium_show_library"
],
"statusVerb": null,
"summary": "Register a library file in Altium's Installed Libraries (IntegratedLibraryManager.InstallLibrary) so its parts appear in the Components panel.",
"timeoutSeconds": 150
},
{
"example": {
"libpkgPath": "C:/lib/Adom_ToF.LibPkg",
"output": "C:/lib/out"
},
"hint": "Then altium_install_library {libraryPath: <the .IntLib>}. Check the file exists: the reply does not verify it was written.",
"input": {
"libpkgPath": "path to a .LibPkg (required)",
"output": "destination directory",
"timeout": "seconds, default 300"
},
"longRunning": false,
"name": "altium_compile_intlib",
"output": {
"data": "{libpkg, outputDir}",
"roundtripMs": "int"
},
"pitfalls": [
"The LibPkg is opened as a project in the user's workspace and stays open.",
"success only means the compile was dispatched; verify the .IntLib on disk."
],
"related": [
"altium_extract_intlib",
"altium_install_library"
],
"statusVerb": null,
"summary": "Compile a .LibPkg into an integrated library (.IntLib).",
"timeoutSeconds": 300
},
{
"example": {
"intlibPath": "C:/lib/Vendor.IntLib"
},
"hint": "Then altium_list_library / altium_read_symbol on the extracted sources.",
"input": {
"intlibPath": "path to an .IntLib (required)",
"timeout": "seconds, default 300"
},
"longRunning": false,
"name": "altium_extract_intlib",
"output": {
"data": "{intlib, sources: [path]}",
"roundtripMs": "int"
},
"pitfalls": [
"sources[] lists EVERY .SchLib/.PcbLib in any open project, not only the ones this call extracted."
],
"related": [
"altium_compile_intlib",
"altium_list_library",
"altium_install_library"
],
"statusVerb": null,
"summary": "Extract the editable .SchLib/.PcbLib sources from a compiled .IntLib (Altium writes them next to the IntLib and opens them).",
"timeoutSeconds": 300
},
{
"example": {
"footprintName": "VL53L5CX",
"libraryPath": "C:/lib/Adom_ToF.PcbLib",
"pcbPath": "C:/proj/one.PcbDoc"
},
"hint": "Prefer altium_test_board (outline, several parts, nets). bodiesOnComp:0 with libBodies>0 means the body did not copy: report it.",
"input": {
"footprintName": "string",
"libraryPath": "path to a .PcbLib (required)",
"pcbPath": "path to save the new .PcbDoc - optional",
"timeout": "seconds, default 90"
},
"longRunning": false,
"name": "altium_place_on_pcb",
"output": {
"data": "{pcb, placed, libFile, libBodies, primitives, padsOnComp, bodiesOnComp}",
"shot": "{image: base64 png, width, height}",
"windowEtiquette": "background"
},
"pitfalls": [
"Every call creates a NEW PcbDoc; without pcbPath it exists only unsaved.",
"'footprint not found in PcbLib' - names from altium_list_library."
],
"related": [
"altium_test_board",
"altium_place_on_sch",
"altium_show_3d_board"
],
"statusVerb": null,
"summary": "Place ONE footprint from a PcbLib on a new board and return a proof frame. The single-part predecessor of altium_test_board.",
"timeoutSeconds": 90
},
{
"example": {},
"hint": "Read shot.image for the product row (Trial/Full, days left, seat n/n): that lives ONLY on the page. Not licensed -> altium_ensure_licensed.",
"input": {},
"longRunning": false,
"name": "altium_license_status",
"output": {
"licenceState": "string",
"licensed": "bool | null",
"running": "bool",
"seatStuck": "'possible' | null",
"shot": "{image: base64 png, ...}",
"summary": "string"
},
"pitfalls": [
"It brings up the License Management page inside Altium (when the agent is resident), replacing the view the user had.",
"One On-Demand seat serves every Altium on the account: 'no seats available' usually means ANOTHER running Altium holds it - altium_close that one."
],
"related": [
"altium_ensure_licensed",
"altium_license",
"altium_instances"
],
"statusVerb": null,
"summary": "Plain-language answer to 'what Altium licence am I on?': the state from the window title plus a capture of the License Management page.",
"timeoutSeconds": 60
},
{
"example": {},
"hint": "success -> drive. errorCode no_seat_available: find the Altium holding the seat (altium_instances here, or another machine) and altium_close it, then call again. errorCode no_licence_on_account: the account has only the Viewer; ask the user (admin assigns a licence, trial, or the other Altium build). errorCode no_author_seat (Develop): every workspace Author seat is taken; ask the user.",
"input": {
"allowSignInReset": "bool - if no seat is free, Sign Out (the human must sign back in)",
"allowTrial": "bool - if no seat is free, open the trial flow in the browser",
"launchWaitSec": "int, default 240"
},
"longRunning": false,
"name": "altium_ensure_licensed",
"output": {
"alreadyLicensed": "bool",
"licenceState": "string",
"needsHuman": "string - only for browser sign-in / trial activation / a licence the account lacks",
"page": "{notUsingLicence, requestAccessBanner, viewerOnly} read off the licence page",
"seatStuck": "bool",
"shot": "{..}",
"steps": "[..]",
"summary": "string"
},
"pitfalls": [
"One On-Demand seat serves EVERY Altium on the account. A KILLED Altium strands the seat (page shows Seats 0/1 while every claim fails): altium_close releases it, waiting does not.",
"allowSignInReset:true signs the user OUT and ends with needsHuman (browser sign-in). Use it only when nothing else holds the seat.",
"It may launch Altium, which raises Altium over the user's work once."
],
"related": [
"altium_license",
"altium_license_status",
"altium_instances",
"altium_close"
],
"statusVerb": null,
"summary": "One call to get a usable Altium: launch if needed, then claim a seat (Use License via UIA). Optional escalations: sign out to force a seat release, or start the free-trial flow.",
"timeoutSeconds": 300
},
{
"example": {},
"hint": "Follow nextAction and call again until stage is done. Not installed -> altium_install (the staged install verb; its licence stage does the clicks itself).",
"input": {},
"longRunning": false,
"name": "altium_setup_trial",
"output": {
"licenceState": "string",
"needsHuman": "string - when a person must act",
"nextAction": "string",
"stage": "install | launch | signin | done",
"summary": "string"
},
"pitfalls": [
"Signed in but unlicensed, it starts the free-trial flow in the BROWSER and answers trial_needs_browser: a person names the workspace, accepts terms and clicks Activate.",
"stage launch answers success:true without launching anything: call altium_launch yourself."
],
"related": [
"altium_install",
"altium_ensure_licensed",
"altium_signin_status",
"altium_launch"
],
"statusVerb": null,
"summary": "Onboarding state machine: from nothing to a working trial. Each call reports the stage it found (install | launch | signin | done) and the ONE next action; human steps are named, not faked.",
"timeoutSeconds": 300
},
{
"example": {},
"hint": "To see WHO is signed in: altium_license {action:'show'} and read the page ('Sign Out' visible = already signed in). Not connected to a workspace -> altium_connect_workspace.",
"input": {},
"longRunning": false,
"name": "altium_signin",
"output": {
"currentUserProcess": "object - only when the agent is resident",
"licenceState": "string",
"licensed": "bool | null",
"running": "bool",
"workspaceConnected": "bool",
"workspaceMenu": "string"
},
"pitfalls": [
"Despite the name there are no credential arguments and nothing is typed or clicked.",
"Never ask the user for their Altium password: the browser flow is theirs."
],
"related": [
"altium_signin_status",
"altium_license",
"altium_connect_workspace",
"altium_install"
],
"statusVerb": null,
"summary": "Report-only alias of altium_signin_status: it does NOT sign anyone in. Signing in to Altium is a browser flow only the human can complete.",
"timeoutSeconds": 300
},
{
"example": {},
"hint": "workspaceConnected:false -> altium_connect_workspace opens the picker. The signed-in account name is on the License Management page: altium_license {action:'show'}.",
"input": {},
"longRunning": false,
"name": "altium_signin_status",
"output": {
"currentUserProcess": "object - only when the agent is resident",
"licenceState": "string",
"licensed": "bool | null",
"running": "bool",
"workspace": "null - the name is not read",
"workspaceConnected": "bool",
"workspaceMenu": "string"
},
"pitfalls": [
"workspaceConnected is inferred from the ABSENCE of a 'Not Connected' menu item: a UIA miss reads as connected."
],
"related": [
"altium_connect_workspace",
"altium_license",
"altium_license_status"
],
"statusVerb": null,
"summary": "Account and Altium 365 workspace connection as Altium's own UI reports it: licence state from the title, and whether the workspace menu reads 'Not Connected'.",
"timeoutSeconds": 60
},
{
"example": {},
"hint": "Click the wanted row with ab's desktop_click {space:'image', shotId, x, y} straight away, then altium_signin_status to confirm.",
"input": {},
"longRunning": false,
"name": "altium_connect_workspace",
"output": {
"picker": "{hwnd, title, className: TWorkspacesForm, rect}",
"shot": "ab desktop_screenshot_window reply: image + coordMap/shotId",
"windowEtiquette": "background"
},
"pitfalls": [
"picker_not_open usually means Altium is ALREADY connected (the menu shows the workspace name).",
"The picker is a popup: it closes on focus loss, so click before doing anything else.",
"A workspace with no free Author seat connects view-only: new documents then fail with view_only_no_author_seat."
],
"related": [
"altium_signin_status",
"altium_a365_status",
"altium_license"
],
"statusVerb": null,
"summary": "Open Altium's workspace picker (the 'Not Connected' menu) and return a screenshot with a coordMap. The list is a custom control with no UIA children, so the caller clicks the row.",
"timeoutSeconds": 60
},
{
"example": {
"workspace": "acme.365.altium.com"
},
"hint": "Then altium_a365_status to prove the token is live. Preferred over a manual token: altium_a365_oauth_begin {clientId, workspace}.",
"input": {
"token": "string - optional developer token",
"workspace": "string - e.g. acme.365.altium.com (required unless already stored)"
},
"longRunning": false,
"name": "altium_a365_configure",
"output": {
"hasToken": "bool",
"workspace": "string"
},
"pitfalls": [
"The token is written to a365.json in the bridge cache: altium_uninstall deletes it, altium_a365_logout removes it.",
"Never echo a token back to the user or into a log."
],
"related": [
"altium_a365_status",
"altium_a365_oauth_begin",
"altium_a365_query"
],
"statusVerb": null,
"summary": "Store the Altium 365 workspace domain and, optionally, a Bearer token created by hand in the workspace web UI (Admin - Developer). Local-only; tokens never appear in replies.",
"timeoutSeconds": 15
},
{
"example": {
"clientId": "<your Altium-issued client id>",
"workspace": "acme.365.altium.com"
},
"hint": "Open authorizeUrl in the user's EXISTING browser only after this returns, then poll altium_a365_oauth_status until status is authorized.",
"input": {
"clientId": "string - an Altium-issued public OAuth client id (or the stored one)",
"selectWorkspace": "strict (default) | optional | none",
"timeout": "int seconds, default 300 - how long to wait for the consent",
"workspace": "string - e.g. acme.365.altium.com (or the stored one)"
},
"longRunning": false,
"name": "altium_a365_oauth_begin",
"output": {
"authorizeUrl": "string",
"status": "waiting",
"workspace": "string"
},
"pitfalls": [
"a365_client_id_required: OAuth clients come from Altium's Developer Center enrollment. Never reuse a first-party client id.",
"a365_oauth_in_progress: one flow at a time - altium_a365_oauth_cancel the old one first.",
"The consent page is the human's step; tokens never appear in any reply."
],
"related": [
"altium_a365_oauth_status",
"altium_a365_oauth_cancel",
"altium_a365_status"
],
"statusVerb": null,
"summary": "Start the Altium 365 OAuth (PKCE + ActionWait) sign-in: the bridge starts listening FIRST, then returns the authorize URL for the user's browser. Works with Altium closed.",
"timeoutSeconds": 30
},
{
"example": {},
"hint": "Poll every few seconds while waiting. authorized -> altium_a365_library_overview proves the workspace-scoped token. error -> read errorCode, then altium_a365_oauth_begin again.",
"input": {},
"longRunning": false,
"name": "altium_a365_oauth_status",
"output": {
"claims": "object - unverified token claim summary (authorized)",
"error": "string (error)",
"errorCode": "string (error)",
"status": "idle | waiting | authorized | cancelled | error",
"workspace": "string"
},
"pitfalls": [
"success is false only for status error; waiting and idle are success:true.",
"State lives in bridge memory: a bridge restart mid-flow reads idle."
],
"related": [
"altium_a365_oauth_begin",
"altium_a365_oauth_cancel",
"altium_a365_library_overview"
],
"statusVerb": null,
"summary": "State of the OAuth flow started by altium_a365_oauth_begin: idle | waiting | authorized | cancelled | error.",
"timeoutSeconds": 10
},
{
"example": {},
"hint": "Poll altium_a365_oauth_status until it reads cancelled, then altium_a365_oauth_begin again if wanted.",
"input": {},
"longRunning": false,
"name": "altium_a365_oauth_cancel",
"output": {
"alreadyStopped": "bool",
"status": "cancelling | <current status>"
},
"pitfalls": [
"The worker notices the cancel between long-polls (up to about 75 s)."
],
"related": [
"altium_a365_oauth_begin",
"altium_a365_oauth_status"
],
"statusVerb": null,
"summary": "Cancel a waiting OAuth flow.",
"timeoutSeconds": 10
},
{
"example": {},
"hint": "Call when altium_a365_query answers a365_graphql_http 401 or altium_a365_status shows tokenLive:false, then retry.",
"input": {},
"longRunning": false,
"name": "altium_a365_refresh",
"output": {
"claims": "object - unverified token claim summary",
"workspace": "string"
},
"pitfalls": [
"a365_refresh_not_configured = no OAuth grant stored (a manual developer token cannot be refreshed).",
"a365_refresh_failed usually means the grant was revoked: altium_a365_oauth_begin again."
],
"related": [
"altium_a365_status",
"altium_a365_query",
"altium_a365_oauth_begin"
],
"statusVerb": null,
"summary": "Exchange the stored refresh token for a new access token (and store a rotated refresh token if one comes back).",
"timeoutSeconds": 60
},
{
"example": {},
"hint": "altium_a365_status afterwards should read hasToken:false. Sign in again with altium_a365_oauth_begin.",
"input": {},
"longRunning": false,
"name": "altium_a365_logout",
"output": {
"revoked": "bool - a remote revocation happened",
"workspace": "string"
},
"pitfalls": [
"If the remote revocation fails (a365_revoke_failed / a365_network_error) the LOCAL tokens are kept on purpose: retry.",
"This is the Altium 365 API grant only; it does not sign Altium Designer out or release a licence seat."
],
"related": [
"altium_a365_status",
"altium_a365_oauth_begin",
"altium_uninstall"
],
"statusVerb": null,
"summary": "Revoke the refresh grant at Altium and remove every cached OAuth token. Workspace and client id stay configured.",
"timeoutSeconds": 60
},
{
"example": {},
"hint": "hasToken:false -> altium_a365_oauth_begin (or altium_a365_configure {token}). tokenLive:false with hasRefreshToken -> altium_a365_refresh. Live -> altium_a365_library_overview / altium_a365_query.",
"input": {},
"longRunning": false,
"name": "altium_a365_status",
"output": {
"clientConfigured": "bool",
"configured": "bool",
"endpoint": "string - the GraphQL URL",
"hasRefreshToken": "bool",
"hasToken": "bool",
"probe": "object - probe data or error",
"tokenLive": "bool",
"workspace": "string | null"
},
"pitfalls": [
"Independent of Altium Designer: this lane works while X2.exe is closed and says nothing about the desktop licence seat."
],
"related": [
"altium_a365_oauth_begin",
"altium_a365_refresh",
"altium_a365_query",
"altium_a365_configure"
],
"statusVerb": null,
"summary": "Is the Altium 365 lane configured, is there a token, and is it LIVE (probed with a one-row GraphQL query)?",
"timeoutSeconds": 60
},
{
"example": {
"query": "{ desProjects(first: 10) { nodes { name } } }"
},
"hint": "Discover fields first with altium_a365_library_schema (or https://<workspace>/api/voyager). a365_graphql_http / a365_network_error -> altium_a365_status, then altium_a365_refresh.",
"input": {
"query": "string - GraphQL (required)",
"timeout": "int seconds, default 60",
"variables": "object"
},
"longRunning": false,
"name": "altium_a365_query",
"output": {
"data": "object | null",
"errors": "[..] | null"
},
"pitfalls": [
"success is false whenever the reply carries errors[], even with partial data.",
"Mutations change the user's shared workspace for everyone: know the rollback/delete mutation before running one.",
"a365_not_configured = no workspace or token stored."
],
"related": [
"altium_a365_library_schema",
"altium_a365_library_overview",
"altium_a365_refresh",
"altium_a365_files_upload"
],
"statusVerb": null,
"summary": "Run one GraphQL query or mutation against the workspace's GraphQL gateway (https://<workspace>/svc/napi/gateway/graphql/) with the stored token.",
"timeoutSeconds": 60
},
{
"example": {
"filePath": "C:/lib/Adom_ToF.SchLib"
},
"hint": "Pass fileId straight into the matching mutation via altium_a365_query {query, variables}. Do not parse or persist it.",
"input": {
"filePath": "path on THIS machine (required)",
"maxBytes": "int, default 104857600 (100 MB)",
"timeout": "int seconds, default 120"
},
"longRunning": false,
"name": "altium_a365_files_upload",
"output": {
"expiresAfterHoursInactive": "24",
"fileId": "string - opaque"
},
"pitfalls": [
"a365_file_not_found: the path must be on the bridge's machine - stage it with send_files.",
"The id expires after 24 h of inactivity."
],
"related": [
"altium_a365_query",
"altium_a365_library_schema"
],
"statusVerb": null,
"summary": "Upload one local file to the workspace's Files Service and get a temporary opaque file id to pass to a library mutation.",
"timeoutSeconds": 120
},
{
"example": {},
"hint": "The proof that a fresh OAuth token is workspace-scoped. Then altium_a365_library_schema before attempting any mutation.",
"input": {},
"longRunning": false,
"name": "altium_a365_library_overview",
"output": {
"data": "{desLibrary: {name, description, updatedAt, components: {nodes: [{id, name}]}, footprints: {totalCount}, symbols: {totalCount}}}",
"errors": "[..] | null"
},
"pitfalls": [
"Same error codes as altium_a365_query (a365_not_configured, a365_graphql_http, a365_network_error)."
],
"related": [
"altium_a365_status",
"altium_a365_library_schema",
"altium_a365_query"
],
"statusVerb": null,
"summary": "One fixed read-only query: the workspace library's name, description, update time, component ids/names and footprint/symbol totals.",
"timeoutSeconds": 60
},
{
"example": {},
"hint": "Pick the mutation, understand its input types AND its rollback/delete counterpart, upload inputs with altium_a365_files_upload, then altium_a365_query.",
"input": {
"timeout": "int seconds, default 60"
},
"longRunning": false,
"name": "altium_a365_library_schema",
"output": {
"mutations": "[{name, description, args: [{name, type}]}]",
"queries": "[{name, description}]"
},
"pitfalls": [
"A name filter over introspection: a relevant field named differently is not listed - the full schema is at https://<workspace>/api/voyager."
],
"related": [
"altium_a365_query",
"altium_a365_files_upload",
"altium_a365_library_overview"
],
"statusVerb": null,
"summary": "Read-only schema map: the GraphQL queries and mutations whose names mention lib, component, symbol, footprint, part or datasheet, with mutation argument types.",
"timeoutSeconds": 60
}
]
}