@visulima/vis 1.0.0-alpha.10 → 1.0.0-alpha.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/CHANGELOG.md +95 -42
  2. package/LICENSE.md +213 -0
  3. package/README.md +8 -4
  4. package/dist/bin.js +9 -1
  5. package/dist/config/index.d.ts +1818 -0
  6. package/dist/config/index.js +2 -0
  7. package/dist/generate/index.d.ts +1 -1
  8. package/dist/generate/index.js +3 -1
  9. package/dist/packem_chunks/applyDefaults.js +336 -0
  10. package/dist/packem_chunks/bin.js +9554 -64
  11. package/dist/packem_chunks/doctor-probe.js +112 -0
  12. package/dist/packem_chunks/fix.js +229 -48
  13. package/dist/packem_chunks/handler.js +99 -1
  14. package/dist/packem_chunks/handler10.js +53 -1
  15. package/dist/packem_chunks/handler11.js +32 -1
  16. package/dist/packem_chunks/handler12.js +100 -2
  17. package/dist/packem_chunks/handler13.js +25 -1
  18. package/dist/packem_chunks/handler14.js +916 -5
  19. package/dist/packem_chunks/handler15.js +206 -1
  20. package/dist/packem_chunks/handler16.js +122 -18
  21. package/dist/packem_chunks/handler17.js +13 -1
  22. package/dist/packem_chunks/handler18.js +106 -1
  23. package/dist/packem_chunks/handler19.js +19 -1
  24. package/dist/packem_chunks/handler2.js +75 -1
  25. package/dist/packem_chunks/handler20.js +29 -1
  26. package/dist/packem_chunks/handler21.js +222 -1
  27. package/dist/packem_chunks/handler22.js +237 -5
  28. package/dist/packem_chunks/handler23.js +101 -1
  29. package/dist/packem_chunks/handler24.js +110 -1
  30. package/dist/packem_chunks/handler25.js +402 -5
  31. package/dist/packem_chunks/handler26.js +13 -1
  32. package/dist/packem_chunks/handler27.js +63 -3
  33. package/dist/packem_chunks/handler28.js +34 -1
  34. package/dist/packem_chunks/handler29.js +458 -7
  35. package/dist/packem_chunks/handler3.js +95 -2
  36. package/dist/packem_chunks/handler30.js +168 -21
  37. package/dist/packem_chunks/handler31.js +530 -3
  38. package/dist/packem_chunks/handler32.js +214 -2
  39. package/dist/packem_chunks/handler33.js +119 -24
  40. package/dist/packem_chunks/handler34.js +630 -2
  41. package/dist/packem_chunks/handler35.js +283 -19
  42. package/dist/packem_chunks/handler36.js +521 -407
  43. package/dist/packem_chunks/handler37.js +762 -22
  44. package/dist/packem_chunks/handler38.js +989 -22
  45. package/dist/packem_chunks/handler39.js +574 -22
  46. package/dist/packem_chunks/handler4.js +90 -4
  47. package/dist/packem_chunks/handler40.js +1685 -3
  48. package/dist/packem_chunks/handler41.js +1088 -10
  49. package/dist/packem_chunks/handler42.js +785 -141
  50. package/dist/packem_chunks/handler43.js +2658 -42
  51. package/dist/packem_chunks/handler44.js +3886 -3
  52. package/dist/packem_chunks/handler45.js +2568 -21
  53. package/dist/packem_chunks/handler46.js +3769 -0
  54. package/dist/packem_chunks/handler47.js +1491 -0
  55. package/dist/packem_chunks/handler5.js +174 -2
  56. package/dist/packem_chunks/handler6.js +95 -13
  57. package/dist/packem_chunks/handler7.js +115 -8
  58. package/dist/packem_chunks/handler8.js +12 -1
  59. package/dist/packem_chunks/handler9.js +29 -1
  60. package/dist/packem_chunks/heal-accept.js +522 -0
  61. package/dist/packem_chunks/heal.js +673 -0
  62. package/dist/packem_chunks/index.js +873 -7
  63. package/dist/packem_chunks/loader.js +23 -1
  64. package/dist/packem_shared/VisUpdateApp-D-Yz_wvg.js +1316 -0
  65. package/dist/packem_shared/_commonjsHelpers-BqLXS_qQ.js +5 -0
  66. package/dist/packem_shared/ai-analysis-CHeB1joD.js +367 -0
  67. package/dist/packem_shared/ai-cache-Be_jexe4.js +142 -0
  68. package/dist/packem_shared/ai-fix-B9iQVcD2.js +379 -0
  69. package/dist/packem_shared/cache-directory-2qvs4goY.js +98 -0
  70. package/dist/packem_shared/catalog-BJTtyi-O.js +1371 -0
  71. package/dist/packem_shared/dependency-scan-A0KSklpG.js +188 -0
  72. package/dist/packem_shared/docker-2iZzc280.js +181 -0
  73. package/dist/packem_shared/failure-log-Cz3Z4SKL.js +100 -0
  74. package/dist/packem_shared/flakiness-goTxXuCX.js +180 -0
  75. package/dist/packem_shared/otel-DCvqCTz_.js +158 -0
  76. package/dist/packem_shared/otelPlugin-DFaLDvJf.js +3 -0
  77. package/dist/packem_shared/registry-CbqXI0rc.js +272 -0
  78. package/dist/packem_shared/run-summary-utils-PVMl4aIh.js +130 -0
  79. package/dist/packem_shared/runtime-check-Cobi3p6l.js +127 -0
  80. package/dist/packem_shared/selectors-SM69TfqC.js +194 -0
  81. package/dist/packem_shared/symbols-Ta7g2nU-.js +14 -0
  82. package/dist/packem_shared/toolchain-BdZd9eBi.js +975 -0
  83. package/dist/packem_shared/typosquats-C-bCh3PX.js +1210 -0
  84. package/dist/packem_shared/use-measured-height-CNP0vT4M.js +20 -0
  85. package/dist/packem_shared/utils-CthVdBPS.js +40 -0
  86. package/dist/packem_shared/xxh3-Ck8mXNg1.js +239 -0
  87. package/index.js +727 -555
  88. package/package.json +35 -17
  89. package/schemas/project.schema.json +8 -10
  90. package/schemas/vis-config.schema.json +132 -8
  91. package/skills/vis/SKILL.md +96 -0
  92. package/templates/buildkite-ci/.buildkite/pipeline.yml.tera +85 -0
  93. package/templates/buildkite-ci/template.yml +20 -0
  94. package/dist/errors/index.d.ts +0 -26
  95. package/dist/errors/index.js +0 -1
  96. package/dist/packem_chunks/config.js +0 -2
  97. package/dist/packem_shared/VisConfigCycleError-CAYNC7d-.js +0 -1
  98. package/dist/packem_shared/VisConfigError-B5LP1zRf.js +0 -1
  99. package/dist/packem_shared/VisConfigLoadError-CeqBSd2Z.js +0 -2
  100. package/dist/packem_shared/VisConfigNotFoundError-DZ9KC527.js +0 -5
  101. package/dist/packem_shared/VisUpdateApp-D-L4_-Iu.js +0 -1
  102. package/dist/packem_shared/_commonjsHelpers-D6W6KoPK.js +0 -1
  103. package/dist/packem_shared/ai-analysis-CGuy7dfE.js +0 -67
  104. package/dist/packem_shared/ai-cache-Bynt6Y9x.js +0 -1
  105. package/dist/packem_shared/cache-directory-D72ZEag2.js +0 -1
  106. package/dist/packem_shared/catalog-BVPerCwG.js +0 -12
  107. package/dist/packem_shared/dependency-scan-Du0tBu64.js +0 -2
  108. package/dist/packem_shared/docker-BcfqH4Av.js +0 -2
  109. package/dist/packem_shared/failure-log-DqYen0LC.js +0 -2
  110. package/dist/packem_shared/flakiness-DSIHZGBT.js +0 -1
  111. package/dist/packem_shared/run-summary-utils-C24Aaf9E.js +0 -1
  112. package/dist/packem_shared/runtime-check-CGHal8SO.js +0 -1
  113. package/dist/packem_shared/selectors-CfH9ZY08.js +0 -3
  114. package/dist/packem_shared/symbols-CQmER5MT.js +0 -1
  115. package/dist/packem_shared/target-merge-DNa-6eWu.js +0 -1
  116. package/dist/packem_shared/toolchain-DQfTQY8E.js +0 -5
  117. package/dist/packem_shared/typosquats-DOR8izpX.js +0 -1
  118. package/dist/packem_shared/use-measured-height-DjYgUOKk.js +0 -1
  119. package/dist/packem_shared/utils-DrNg0XTR.js +0 -1
  120. package/dist/packem_shared/xxh3-DrAUNq4n.js +0 -1
@@ -1,153 +1,797 @@
1
- var ge=Object.defineProperty;var g=(e,t)=>ge(e,"name",{value:t,configurable:!0});import{createRequire as he}from"node:module";import{dim as d,bold as k,cyan as x}from"@visulima/colorize";import{isAccessibleSync as P,ensureDirSync as b,writeFileSync as m,readJsonSync as ae}from"@visulima/fs";import{resolve as _,basename as ve,relative as W,join as c,sep as be,isAbsolute as we}from"@visulima/path";import{p as a,o as le,g as ke,c as xe}from"./bin.js";import{g as Ce}from"../packem_shared/_commonjsHelpers-D6W6KoPK.js";import{downloadTemplate as Se}from"giget";const fe=he(import.meta.url),D=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,V=g(e=>{if(typeof D<"u"&&D.versions&&D.versions.node){const[t,r]=D.versions.node.split(".").map(Number);if(t>22||t===22&&r>=3||t===20&&r>=16)return D.getBuiltinModule(e)}return fe(e)},"__cjs_getBuiltinModule"),{spawnSync:ye}=V("node:child_process"),{createInterface:$e}=V("node:readline"),{readdirSync:_e,chmodSync:je}=V("node:fs");var Pe=Object.defineProperty,z=g((e,t)=>Pe(e,"name",{value:t,configurable:!0}),"e");const Ne={"vis:app":"builtin:app","vis:application":"builtin:app","vis:generator":"builtin:generator","vis:lib":"builtin:library","vis:library":"builtin:library","vis:monorepo":"builtin:monorepo"},Oe=["https://github.com/","https://gitlab.com/","https://bitbucket.org/","https://raw.githubusercontent.com/","https://git.sr.ht/","git@github.com:","git@gitlab.com:","git@bitbucket.org:","git@git.sr.ht:","github:","gh:","gitlab:","bitbucket:","sourcehut:","git:","http://","https://"],qe=z(e=>{for(const t of Oe)if(e.startsWith(t))return!0;return!!(!e.startsWith("@")&&/^[^/#@][^/#]*\/[^/#]+/.test(e))},"isGitUrl"),De=new Set(["sv"]),Te=z(e=>{if(De.has(e)||e.startsWith("create-")||e.startsWith("@")&&e.includes("/create-"))return e;if(e.startsWith("@")){const t=e.indexOf("/");if(t!==-1){const r=e.slice(0,t),i=e.slice(t+1);return`${r}/create-${i}`}return e}return`create-${e}`},"expandCreateShorthand"),Ee=z((e,t=[])=>{if(!e)throw new Error("No template specified.");const r=e.toLowerCase(),i=Ne[r];return i?{args:t,source:r,type:i}:qe(e)?{args:t,source:e,type:"remote:git"}:{args:t,source:Te(e),type:"remote:npm"}},"discoverTemplate"),Ie=z(e=>{switch(e){case"builtin:app":return"apps";case"builtin:generator":case"builtin:library":return"packages";default:return"."}},"inferParentDir");var Re=Object.defineProperty,pe=g((e,t)=>Re(e,"name",{value:t,configurable:!0}),"i$1");const ne=["ability","able","about","above","abroad","absence","absolute","absolutely","absorb","academic","accept","access","accompany","accomplish","according","account","accurate","achieve","achievement","acid","acknowledge","acquire","across","act","action","active","activist","activity","actor","actress","actual","actually","adapt","add","addition","additional","address","adequate","adjust","adjustment","administration","administrator","admire","admission","admit","adolescent","adopt","adult","advance","advanced","advantage","adventure","advertising","advice","advise","adviser","advocate","affair","affect","afford","after","afternoon","again","against","age","agency","agenda","agent","ago","agree","agreement","agricultural","ahead","aid","aide","aim","air","aircraft","airline","airport","album","alive","all","alliance","allow","ally","almost","alone","along","already","also","alter","alternative","although","always","amazing","among","amount","analysis","analyst","analyze","ancient","and","angle","animal","anniversary","announce","annual","another","answer","anticipate","any","anybody","anymore","anyone","anything","anyway","anywhere","apart","apartment","apparent","apparently","appeal","appear","appearance","apple","application","apply","appoint","appointment","appreciate","approach","appropriate","approval","approve","approximately","architect","area","argue","argument","arise","arm","armed","around","arrange","arrangement","arrival","arrive","art","article","artist","artistic","aside","ask","asleep","aspect","assert","assess","assessment","asset","assign","assignment","assist","assistance","assistant","associate","association","assume","assumption","assure","athlete","athletic","atmosphere","attach","attempt","attend","attention","attitude","attorney","attract","attractive","attribute","audience","author","authority","auto","available","average","avoid","award","aware","awareness","away","awesome","baby","back","background","bag","bake","balance","ball","ban","band","bank","bar","barely","barrel","base","baseball","basic","basically","basis","basket","basketball","bathroom","battery","beach","bean","bear","beat","beautiful","beauty","because","become","bed","bedroom","beer","before","begin","beginning","behavior","behind","being","belief","believe","bell","belong","below","belt","bench","bend","beneath","benefit","beside","besides","best","bet","better","between","beyond","big","bike","bill","billion","bind","biological","bird","birth","birthday","bit","bite","black","blade","blanket","blind","block","blow","blue","board","boat","body","bond","bone","book","boom","boot","border","born","borrow","boss","both","bother","bottle","bottom","boundary","bowl","box","boy","boyfriend","brain","branch","brand","bread","break","breakfast","breast","breath","breathe","brick","bridge","brief","briefly","bright","brilliant","bring","broad","brother","brown","brush","buck","budget","build","building","bullet","bunch","bury","bus","business","busy","but","butter","button","buy","buyer","cabin","cabinet","cable","cake","calculate","call","camera","camp","campaign","campus","can","candidate","cap","capability","capable","capacity","capital","captain","capture","car","carbon","card","care","career","careful","carefully","carrier","carry","case","cash","cast","cat","catch","category","cause","ceiling","celebrate","celebration","celebrity","cell","center","central","century","ceremony","certain","certainly","chain","chair","chairman","challenge","chamber","champion","championship","chance","change","changing","channel","chapter","character","characteristic","characterize","charge","charity","chart","chase","cheap","check","cheek","cheese","chef","chemical","chest","chicken","chief","child","childhood","chip","chocolate","choice","cholesterol","choose","church","cigarette","circle","circumstance","cite","citizen","city","civil","civilian","claim","class","classic","classroom","clean","clear","clearly","client","climate","climb","clinic","clinical","clock","close","closely","closer","clothes","clothing","cloud","club","clue","cluster","coach","coal","coalition","coast","coat","code","coffee","cognitive","cold","colleague","collect","collection","collective","college","colonial","color","column","combination","combine","come","comedy","comfort","comfortable","command","commander","comment","commercial","commission","commit","commitment","committee","common","communicate","communication","community","company","compare","comparison","compete","competition","competitive","competitor","complete","completely","complex","complicated","component","compose","composition","comprehensive","computer","concentrate","concentration","concept","concern","concerned","concert","conclude","conclusion","concrete","condition","conduct","conference","confidence","confident","confirm","confront","confusion","congressional","connect","connection","consciousness","consensus","consequence","conservative","consider","considerable","consideration","consist","consistent","constant","constantly","constitute","constitutional","construct","construction","consultant","consume","consumer","consumption","contact","contain","container","contemporary","content","contest","context","continue","continued","contract","contrast","contribute","contribution","control","convention","conventional","conversation","convert","conviction","convince","cook","cookie","cooking","cool","cooperation","cop","cope","copy","core","corn","corner","corporate","corporation","correct","correspondent","cost","cotton","couch","could","council","counselor","count","counter","country","county","couple","courage","course","court","cousin","cover","coverage","cow","crack","craft","cream","create","creation","creative","creature","credit","crew","criteria","crop","cross","crowd","crucial","cultural","culture","cup","curious","current","currently","curriculum","custom","customer","cut","cycle","dad","daily","dance","dare","dark","darkness","data","date","daughter","day","deal","dealer","dear","debate","decade","decide","decision","deck","declare","decrease","deep","deeply","deer","defend","defendant","defense","defensive","define","definitely","definition","degree","delay","deliver","delivery","demand","democracy","democratic","demonstrate","demonstration","deny","department","depend","dependent","depending","depict","depth","deputy","derive","describe","description","desert","deserve","design","designer","desire","desk","desperate","despite","detail","detailed","detect","determine","develop","developing","development","device","devote","dialogue","diet","differ","difference","different","differently","difficult","difficulty","dig","digital","dimension","dining","dinner","direct","direction","directly","director","disability","disagree","disappear","discipline","discourse","discover","discovery","discuss","discussion","dish","dismiss","display","distance","distant","distinct","distinction","distinguish","distribute","distribution","district","diverse","diversity","divide","division","doctor","document","dog","domestic","dominant","dominate","door","double","down","downtown","dozen","draft","drag","drama","dramatic","dramatically","draw","drawing","dream","dress","drink","drive","driver","drop","dry","due","during","dust","duty","each","eager","ear","early","earn","earnings","earth","ease","easily","east","eastern","easy","eat","economic","economics","economist","economy","edge","edition","editor","educate","education","educational","educator","effect","effective","effectively","efficiency","efficient","effort","egg","eight","either","elderly","elect","election","electric","electricity","electronic","element","elementary","eliminate","elite","else","elsewhere","embrace","emerge","emission","emotion","emotional","emphasis","emphasize","employ","employee","employer","employment","empty","enable","encounter","encourage","end","energy","enforcement","engage","engine","engineer","engineering","enhance","enjoy","enormous","enough","ensure","enter","enterprise","entertainment","entire","entirely","entrance","entry","environment","environmental","episode","equal","equally","equipment","era","escape","especially","essay","essential","essentially","establish","establishment","estate","estimate","etc","ethics","ethnic","evaluate","evaluation","even","evening","event","eventually","ever","every","everybody","everyday","everyone","everything","everywhere","evidence","evolution","evolve","exact","exactly","examination","examine","example","exceed","excellent","except","exception","exchange","exciting","executive","exercise","exhibit","exhibition","exist","existence","existing","expand","expansion","expect","expectation","expense","expensive","experience","experiment","expert","explain","explanation","explore","expose","express","expression","extend","extension","extensive","extent","external","extra","extraordinary","extreme","extremely","eye","fabric","face","facility","fact","factor","factory","faculty","fade","fair","fairly","faith","fall","false","familiar","family","famous","fan","fantasy","far","farm","farmer","fashion","fast","fate","father","favor","favorite","feature","federal","fee","feed","feel","feeling","fellow","female","fence","few","fewer","fiber","fiction","field","fifteen","fifth","fifty","figure","file","fill","film","final","finally","finance","financial","find","finding","fine","finger","finish","firm","first","fish","fishing","fit","fitness","five","fix","flag","flame","flat","flavor","flesh","flight","float","floor","flow","flower","fly","focus","folk","follow","following","food","foot","football","for","force","foreign","forest","forever","forget","form","formal","formation","former","formula","forth","fortune","forward","found","foundation","founder","four","fourth","frame","framework","free","freedom","freeze","frequency","frequent","frequently","fresh","friend","friendly","friendship","from","front","fruit","fuel","full","fully","fun","function","fund","fundamental","funding","funeral","funny","furniture","furthermore","future","gain","galaxy","gallery","game","gap","garage","garden","garlic","gas","gate","gather","gaze","gear","gender","gene","general","generally","generate","generation","genetic","gentleman","gently","gesture","get","ghost","giant","gift","gifted","girl","girlfriend","give","given","glad","glance","glass","global","glove","goal","gold","golden","golf","good","government","governor","grab","grade","gradually","graduate","grain","grand","grandfather","grandmother","grant","grass","grave","gray","great","greatest","green","grocery","ground","group","grow","growing","growth","guarantee","guard","guess","guest","guide","guideline","guy","habit","habitat","hair","half","hall","hand","handful","handle","hang","happen","happy","hard","hardly","hat","have","head","headline","headquarters","health","healthy","hear","hearing","heart","heat","heaven","heavily","heavy","heel","height","helicopter","hello","help","helpful","here","heritage","hero","herself","hey","hide","high","highlight","highly","highway","hill","himself","hip","hire","historian","historic","historical","history","hit","hold","hole","holiday","holy","home","honest","honey","honor","hope","horizon","horse","hospital","host","hot","hotel","hour","house","household","housing","how","however","huge","human","humor","hundred","hungry","hunter","hunting","husband","hypothesis","ice","idea","ideal","identification","identify","identity","ignore","illustrate","image","imagination","imagine","immediate","immediately","immigrant","immigration","impact","implement","implication","imply","importance","important","impose","impossible","impress","impression","impressive","improve","improvement","incentive","incident","include","including","income","incorporate","increase","increased","increasing","increasingly","incredible","indeed","independence","independent","index","indicate","indication","individual","industrial","industry","infant","inflation","influence","inform","information","ingredient","initial","initially","initiative","inner","innocent","inquiry","inside","insight","insist","inspire","install","instance","instead","institution","institutional","instruction","instructor","instrument","insurance","intellectual","intelligence","intend","intense","intensity","intention","interaction","interest","interested","interesting","internal","international","interpret","interpretation","intervention","interview","into","introduce","introduction","invest","investigate","investigation","investigator","investment","investor","invite","involve","involved","involvement","iron","island","issue","item","its","itself","jacket","jet","job","join","joint","joke","journal","journalist","journey","joy","judge","judgment","juice","jump","junior","jury","just","justice","justify","keep","key","kick","kid","kind","king","kiss","kitchen","knee","knife","knock","know","knowledge","lab","label","labor","laboratory","lady","lake","land","landscape","language","lap","large","largely","last","late","later","latter","laugh","launch","law","lawn","lawsuit","lawyer","lay","layer","lead","leader","leadership","leading","leaf","league","lean","learn","learning","least","leather","leave","left","leg","legacy","legal","legend","legislation","legitimate","lemon","length","less","lesson","let","letter","level","liberal","library","license","lie","life","lifestyle","lifetime","lift","light","like","likely","limit","limitation","limited","line","link","lip","list","listen","literally","literary","literature","little","live","living","load","loan","local","locate","location","lock","long","look","loose","lose","lost","lot","lots","loud","love","lovely","lover","low","lower","luck","lucky","lunch","lung","machine","magazine","mail","main","mainly","maintain","maintenance","major","majority","make","maker","makeup","male","mall","man","manage","management","manager","manner","manufacturer","manufacturing","many","map","margin","mark","market","marketing","marriage","married","marry","mask","mass","massive","master","match","material","math","matter","may","maybe","mayor","meal","mean","meaning","meanwhile","measure","measurement","meat","mechanism","media","medical","medication","medicine","medium","meet","meeting","member","membership","memory","mental","mention","menu","mere","merely","message","metal","meter","method","middle","might","military","milk","million","mind","mine","minister","minor","minority","minute","miracle","mirror","miss","missile","mission","mix","mixture","mode","model","moderate","modern","modest","mom","moment","money","monitor","month","mood","moon","moral","more","moreover","morning","mortgage","most","mostly","mother","motion","motivation","motor","mount","mountain","mouse","mouth","move","movement","movie","much","multiple","muscle","museum","music","musical","musician","must","mutual","myself","mystery","myth","naked","name","narrative","narrow","nation","national","native","natural","naturally","nature","near","nearby","nearly","necessarily","necessary","neck","need","negative","negotiate","negotiation","neighbor","neighborhood","neither","nerve","net","network","never","nevertheless","new","newly","news","newspaper","next","nice","night","nine","nobody","nod","nomination","none","nonetheless","nor","normal","normally","north","northern","nose","not","note","nothing","notice","notion","novel","now","nowhere","nuclear","number","numerous","nurse","nut","object","objective","obligation","observation","observe","observer","obtain","obvious","obviously","occasion","occasionally","occupation","occupy","occur","ocean","odd","odds","off","offer","office","officer","official","often","oil","okay","old","once","one","ongoing","onion","online","only","onto","open","opening","operate","operating","operation","operator","opinion","opponent","opportunity","oppose","opposite","opposition","option","orange","order","ordinary","organic","organization","organize","orientation","origin","original","originally","other","others","otherwise","ought","our","ourselves","out","outcome","outside","oven","over","overall","overcome","overlook","owe","own","owner","pace","pack","package","page","paint","painter","painting","pair","pale","palm","pan","panel","pant","paper","parent","park","parking","part","participant","participate","participation","particular","particularly","partly","partner","partnership","party","pass","passage","passenger","passion","past","patch","path","patient","pattern","pause","pay","payment","peace","peak","peer","people","pepper","per","perceive","percentage","perception","perfect","perfectly","perform","performance","perhaps","period","permanent","permission","permit","person","personal","personality","personally","personnel","perspective","persuade","pet","phase","phenomenon","philosophy","phone","photo","photograph","photographer","phrase","physical","physically","physician","piano","pick","picture","pie","piece","pile","pilot","pine","pink","pipe","pitch","place","plan","plane","planet","planning","plant","plastic","plate","platform","play","player","please","pleasure","plenty","plot","plus","pocket","poem","poet","poetry","point","pole","police","policy","political","politically","politician","politics","poll","pool","pop","popular","population","porch","port","portion","portrait","portray","pose","position","positive","possess","possibility","possible","possibly","post","pot","potato","potential","potentially","pound","pour","powder","power","powerful","practical","practice","pray","prayer","precisely","predict","prefer","preference","pregnancy","pregnant","preparation","prepare","prescription","presence","present","presentation","preserve","president","presidential","press","pretend","pretty","prevent","previous","previously","price","pride","priest","primarily","primary","prime","principal","principle","print","prior","priority","privacy","private","probably","procedure","proceed","process","produce","producer","product","production","profession","professional","professor","profile","profit","program","progress","project","prominent","promise","promote","prompt","proof","proper","properly","property","proportion","proposal","propose","proposed","prosecutor","prospect","protect","protection","protein","protest","proud","prove","provide","provider","province","provision","psychological","psychologist","psychology","public","publication","publicly","publish","publisher","pull","purchase","pure","purpose","pursue","push","put","qualify","quality","quarter","quarterback","question","quick","quickly","quiet","quietly","quit","quite","quote","race","racial","radical","radio","rail","rain","raise","range","rank","rapid","rapidly","rare","rarely","rate","rather","rating","ratio","raw","reach","react","reaction","read","reader","reading","ready","real","reality","realize","really","reason","reasonable","recall","receive","recent","recently","recipe","recognition","recognize","recommend","recommendation","record","recording","recover","recovery","recruit","red","reduce","reduction","refer","reference","reflect","reflection","reform","refugee","refuse","regard","regarding","regardless","regime","region","regional","register","regular","regularly","regulate","regulation","reinforce","relate","relation","relationship","relative","relatively","relax","release","relevant","relief","religion","religious","rely","remain","remaining","remarkable","remember","remind","remote","remove","repeat","repeatedly","replace","reply","report","reporter","represent","representation","representative","reputation","request","require","requirement","research","researcher","resemble","reservation","resident","resist","resolution","resolve","resort","resource","respect","respond","respondent","response","responsibility","responsible","rest","restaurant","restore","restriction","result","retain","retire","retirement","return","reveal","revenue","review","revolution","rhythm","rice","rich","rid","ride","rifle","right","ring","rise","river","road","rock","role","roll","romantic","roof","room","root","rope","rose","roughly","round","route","routine","row","rub","rule","run","running","rural","rush","sacred","safe","safety","sake","salad","salary","sale","sales","salt","same","sample","sanction","sand","satellite","satisfaction","satisfy","sauce","save","saving","say","scale","scenario","scene","schedule","scheme","scholar","scholarship","school","science","scientific","scientist","scope","score","screen","script","sea","search","season","seat","second","secret","secretary","section","sector","secure","security","see","seed","seek","seem","segment","seize","select","selection","self","sell","senator","send","senior","sense","sensitive","sentence","separate","sequence","series","serious","seriously","serve","service","session","set","setting","settle","settlement","seven","several","shade","shadow","shake","shall","shape","share","sharp","sheet","shelf","shell","shelter","shift","shine","ship","shirt","shoe","shop","shopping","shore","short","shortly","shot","should","shoulder","shout","show","shower","shrug","shut","side","sigh","sight","sign","signal","significance","significant","significantly","silence","silent","silver","similar","similarly","simple","simply","since","sing","singer","single","sink","sir","sister","sit","site","situation","six","size","ski","skill","skin","sky","sleep","slice","slide","slight","slightly","slip","slow","slowly","small","smart","smell","smile","smooth","snap","snow","soccer","social","society","soft","software","soil","solar","solid","solution","solve","some","somebody","somehow","someone","something","sometimes","somewhat","somewhere","son","song","soon","sophisticated","sorry","sort","soul","sound","soup","source","south","southern","space","speak","speaker","special","specialist","species","specific","specifically","speech","speed","spend","spending","spin","spirit","spiritual","split","spokesman","sport","spot","spread","spring","square","squeeze","stability","stable","staff","stage","stair","stake","stand","standard","standing","star","stare","start","state","statement","station","statistics","status","stay","steady","steal","steel","step","stick","still","stir","stock","stomach","stone","stop","storage","store","storm","story","straight","strange","stranger","strategic","strategy","stream","street","strength","strengthen","stretch","string","strip","strong","strongly","structure","student","studio","study","stuff","style","subject","submit","subsequent","substance","substantial","succeed","success","successful","successfully","such","sudden","suddenly","sue","sufficient","sugar","suggest","suggestion","suit","summer","summit","sun","super","supply","support","supporter","suppose","supposed","sure","surely","surface","surgery","surprise","surprised","surprising","surprisingly","surround","survey","survival","survive","survivor","sustain","swear","sweep","sweet","swim","swing","switch","symbol","system","table","tablespoon","tactic","tail","take","tale","talent","talk","tall","tank","tap","tape","target","task","taste","tax","taxpayer","tea","teach","teacher","teaching","team","tear","teaspoon","technical","technique","technology","teen","teenager","telephone","telescope","television","tell","temperature","temporary","ten","tend","tendency","tennis","tent","term","terms","territory","test","testify","testimony","testing","text","than","thank","thanks","that","the","theater","their","them","theme","themselves","then","theory","therapy","there","therefore","thick","thin","thing","think","thinking","third","thirty","though","thought","thousand","three","throat","through","throughout","throw","ticket","tie","tight","time","tiny","tip","tire","tired","tissue","title","today","toe","together","tomato","tomorrow","tone","tongue","tonight","too","tool","tooth","top","topic","toss","total","totally","touch","tough","tour","tourist","tournament","tower","town","toy","trace","track","trade","tradition","traditional","traffic","trail","train","training","transfer","transform","transformation","transition","translate","transportation","travel","treat","treatment","treaty","tree","tremendous","trend","trial","tribe","trip","troop","truck","true","truly","trust","truth","try","tube","tunnel","turn","twelve","twenty","twice","twin","two","type","typical","typically","ultimate","ultimately","unable","uncle","under","undergo","understand","understanding","unfortunately","uniform","union","unique","unit","universal","universe","university","unknown","unless","unlike","unlikely","until","unusual","upon","upper","urban","urge","use","used","useful","user","usual","usually","utility","vacation","valley","valuable","value","variable","variation","variety","various","vary","vast","vegetable","vehicle","venture","version","versus","very","vessel","veteran","via","victory","video","view","viewer","village","virtually","virtue","visible","vision","visit","visitor","visual","vital","voice","volume","volunteer","vote","voter","wage","wait","wake","walk","wall","wander","want","warm","warn","warning","wash","watch","water","wave","way","wealth","wealthy","wear","weather","wedding","week","weekend","weekly","weigh","weight","welcome","welfare","well","west","western","wet","what","whatever","wheel","when","whenever","where","whereas","whether","which","while","whisper","white","who","whole","whom","whose","why","wide","widely","widespread","wife","wild","will","willing","win","wind","window","wine","wing","winner","winter","wipe","wire","wisdom","wise","wish","with","withdraw","within","without","witness","woman","wonder","wonderful","wood","wooden","word","work","worker","working","works","workshop","world","worried","worth","would","wrap","write","writer","writing","yard","yeah","year","yell","yellow","yes","yesterday","yield","young","your","yours","yourself","youth","zone"],Me=pe((e,t)=>Math.floor(e+Math.random()*(t-e+1)),"random");function J(){return ne[Me(0,ne.length-1)]}g(J,"getRandomWord");pe(J,"getRandomWord");var Le=Object.defineProperty,ze=g((e,t)=>Le(e,"name",{value:t,configurable:!0}),"o$1");const Ae=ze(()=>`${J()}-${J()}`,"randomName");var U,oe;function Ge(){return oe||(oe=1,U=["_http_agent","_http_client","_http_common","_http_incoming","_http_outgoing","_http_server","_stream_duplex","_stream_passthrough","_stream_readable","_stream_transform","_stream_wrap","_stream_writable","_tls_common","_tls_wrap","assert","assert/strict","async_hooks","buffer","child_process","cluster","console","constants","crypto","dgram","diagnostics_channel","dns","dns/promises","domain","events","fs","fs/promises","http","http2","https","inspector","inspector/promises","module","net","os","path","path/posix","path/win32","perf_hooks","process","punycode","querystring","readline","readline/promises","repl","stream","stream/consumers","stream/promises","stream/web","string_decoder","sys","timers","timers/promises","tls","trace_events","tty","url","util","util/types","v8","vm","wasi","worker_threads","zlib","node:sea","node:sqlite","node:test","node:test/reporters"]),U}g(Ge,"requireBuiltinModules");var B,se;function Ue(){if(se)return B;se=1;var e=Object.defineProperty,t=g((o,l)=>e(o,"name",{value:l,configurable:!0}),"i");const r=Ge();var i=new RegExp("^(?:@([^/]+?)[/])?([^/]+?)$"),n=["node_modules","favicon.ico"];function u(o){var l=[],s=[];if(o===null)return s.push("name cannot be null"),p(l,s);if(o===void 0)return s.push("name cannot be undefined"),p(l,s);if(typeof o!="string")return s.push("name must be a string"),p(l,s);if(o.length||s.push("name length must be greater than zero"),o.startsWith(".")&&s.push("name cannot start with a period"),o.startsWith("-")&&s.push("name cannot start with a hyphen"),o.match(/^_/)&&s.push("name cannot start with an underscore"),o.trim()!==o&&s.push("name cannot contain leading or trailing spaces"),n.forEach(function(h){o.toLowerCase()===h&&s.push(h+" is not a valid package name")}),r.includes(o.toLowerCase())&&l.push(o+" is a core module name"),o.length>214&&l.push("name can no longer contain more than 214 characters"),o.toLowerCase()!==o&&l.push("name can no longer contain capital letters"),/[~'!()*]/.test(o.split("/").slice(-1)[0])&&l.push(`name can no longer contain special characters ("~'!()*")`),encodeURIComponent(o)!==o){var w=o.match(i);if(w){var $=w[1],y=w[2];if(y.startsWith(".")&&s.push("name cannot start with a period"),encodeURIComponent($)===$&&encodeURIComponent(y)===y)return p(l,s)}s.push("name can only contain URL-friendly characters")}return p(l,s)}g(u,"validate"),t(u,"validate");var p=t(function(o,l){var s={validForNewPackages:l.length===0&&o.length===0,validForOldPackages:l.length===0,warnings:o,errors:l};return s.warnings.length||delete s.warnings,s.errors.length||delete s.errors,s},"done");return B=u,B}g(Ue,"requireLib");var Be=Ue();const Fe=Ce(Be);var Je=Object.defineProperty,I=g((e,t)=>Je(e,"name",{value:t,configurable:!0}),"r$2");const ue=I(e=>e?Fe(e).validForNewPackages:!1,"isValidPackageName"),E=I(e=>e.toLowerCase().trim().replaceAll(/\s+/g,"-").replaceAll(/[^a-z\d\-~]/g,"-").replace(/^[._-]+/,"").replaceAll(/-{2,}/g,"-").replace(/-$/,""),"toValidPackageName"),Ve=new Set([".DS_Store",".git",".gitkeep","Thumbs.db"]),de=I(e=>P(e)?_e(e).every(t=>Ve.has(t)):!0,"isEmptyDir"),We=I((e,t)=>{const r=_(t,e);return{packageName:E(ve(r)),targetDir:r}},"resolveTargetDir"),He=I(e=>de(e),"canSafelyOverwrite");var Ye=Object.defineProperty,A=g((e,t)=>Ye(e,"name",{value:t,configurable:!0}),"l$4");const T=A((e,t)=>new Promise(r=>{e.question(t,i=>{r(i.trim())})}),"ask"),F=A(async(e,t,r=!0)=>{const i=await T(e,` ${t} ${d(r?"[Y/n]":"[y/N]")} `);return i===""?r:i.toLowerCase()==="y"||i.toLowerCase()==="yes"},"confirm"),ce=A(async(e,t,r)=>{process.stderr.write(` ${t}
2
- `);for(const[i,n]of r.entries()){const u=k(x(` ${String(i+1)}.`)),p=n.hint?d(` — ${n.hint}`):"";process.stderr.write(`${u} ${n.label}${p}
3
- `)}for(;;){const i=await T(e,`
4
- ${d(`Enter choice (1-${String(r.length)}):`)} `),n=Number.parseInt(i,10);if(n>=1&&n<=r.length)return r[n-1].value;const u=r.find(p=>p.value===i||p.label.toLowerCase()===i.toLowerCase());if(u)return u.value;process.stderr.write(` ${d("Invalid choice. Try again.")}
5
- `)}},"select"),Ke=A(async e=>{const t=$e({input:process.stdin,output:process.stdout});try{process.stderr.write(`
6
- ${k(x("vis create"))} ${d("— project scaffolding")}
1
+ import { createRequire as __cjs_createRequire } from "node:module";
7
2
 
8
- `);const r=e.inMonorepo?[{hint:"Scaffold via create-vite",label:"Vis Application",value:"vis:app"},{hint:"Reusable package scaffold",label:"Vis Library",value:"vis:library"},{hint:"Code generator scaffold",label:"Vis Generator",value:"vis:generator"},{hint:"Enter an npm create-* package or GitHub URL",label:"Custom template",value:"__custom__"}]:[{hint:"Full workspace setup",label:"Vis Monorepo",value:"vis:monorepo"},{hint:"Scaffold via create-vite",label:"Vis Application",value:"vis:app"},{hint:"Reusable package scaffold",label:"Vis Library",value:"vis:library"},{hint:"Code generator scaffold",label:"Vis Generator",value:"vis:generator"},{hint:"Enter an npm create-* package or GitHub URL",label:"Custom template",value:"__custom__"}];let i=await ce(t,"Select a template:",r);if(i==="__custom__"&&(i=await T(t,`
9
- ${d("Template (npm package or GitHub URL):")} `),!i))throw new Error("No template specified.");const n=Ae(),u=await T(t,`
10
- ${d(`Project name (${n}):`)} `)||n;if(!ue(E(u)))throw new Error(`Invalid project name: "${u}". Must be a valid npm package name.`);const p=E(u),o=await T(t,` ${d(`Target directory (${p}):`)} `)||p;let l=!1;const s=_(e.cwd,o);if(!de(s)&&(l=await F(t,`Directory "${o}" is not empty. Overwrite?`,!1),!l))throw new Error("Aborted — directory not empty.");let w;e.inMonorepo||(e.defaultPm?(w=e.defaultPm,process.stderr.write(` ${d(`Package manager: ${w} (from config)`)}
11
- `)):w=await ce(t,"Package manager:",[{label:"pnpm",value:"pnpm"},{label:"npm",value:"npm"},{label:"yarn",value:"yarn"},{label:"bun",value:"bun"}]));let $=!1;e.inMonorepo||($=await F(t,"Initialize a git repository?",e.defaultGitInit??!1));const y=e.defaultEditor==="vscode",h=await F(t,"Generate VS Code configuration?",y)?"vscode":void 0;return process.stderr.write(`
12
- `),{editor:h,gitInit:$,overwrite:l,pm:w,projectName:u,targetDir:o,template:i}}finally{t.close()}},"runInteractivePrompts");var Qe=Object.defineProperty,S=g((e,t)=>Qe(e,"name",{value:t,configurable:!0}),"i");const Xe=S((e,t)=>{a.info("Scaffolding application via create-vite...");const r=[W(t.cwd,t.targetDir)||".",...e.args];return r.includes("--no-immediate")||r.push("--no-immediate"),le(t.pm,{additionalPackages:[],args:r,package:"create-vite",shellMode:!1,silent:!1},t.cwd,t.logger)},"executeApp"),Ze=S(e=>`${JSON.stringify({devDependencies:{typescript:"^5.0.0",vitest:"^3.0.0"},exports:{".":{default:"./dist/index.js",types:"./dist/index.d.ts"}},files:["dist"],main:"./dist/index.js",name:e,scripts:{build:"tsc",dev:"tsc --watch",test:"vitest run","test:watch":"vitest"},type:"module",types:"./dist/index.d.ts",version:"0.0.1"},null,4)}
13
- `,"libraryPackageJson"),et=S(()=>`${JSON.stringify({compilerOptions:{declaration:!0,declarationMap:!0,esModuleInterop:!0,module:"Node16",moduleResolution:"Node16",outDir:"./dist",rootDir:"./src",skipLibCheck:!0,sourceMap:!0,strict:!0,target:"ES2022"},include:["src/**/*"]},null,4)}
14
- `,"libraryTsconfig"),tt=S(e=>`/**
15
- * ${e} — library entry point.
16
- */
3
+ const __cjs_require = __cjs_createRequire(import.meta.url);
17
4
 
18
- export const greet = (name: string): string => \`Hello from ${e}, \${name}!\`;
19
- `,"librarySrcIndex"),rt=S(e=>`import { describe, expect, it } from "vitest";
5
+ const __cjs_getProcess = typeof globalThis !== "undefined" && typeof globalThis.process !== "undefined" ? globalThis.process : process;
20
6
 
21
- import { greet } from "../src/index";
22
-
23
- describe("${e}", () => {
24
- it("should greet", () => {
25
- expect(greet("world")).toBe("Hello from ${e}, world!");
26
- });
27
- });
28
- `,"libraryTestIndex"),it=S((e,t)=>{const{projectName:r,targetDir:i}=t;return a.info("Scaffolding library package..."),b(i),b(c(i,"src")),b(c(i,"__tests__")),m(c(i,"package.json"),Ze(r)),a.success("Created package.json"),m(c(i,"tsconfig.json"),et()),a.success("Created tsconfig.json"),m(c(i,"src","index.ts"),tt(r)),a.success("Created src/index.ts"),m(c(i,"__tests__","index.test.ts"),rt(r)),a.success("Created __tests__/index.test.ts"),m(c(i,".gitignore"),`node_modules/
29
- dist/
30
- .env
31
- .DS_Store
32
- `),a.success("Created .gitignore"),0},"executeLibrary"),at=S((e,t)=>{switch(e.type){case"builtin:app":return Xe(e,t);case"builtin:library":return it(e,t);default:throw new Error(`Unknown built-in template type: ${e.type}`)}},"executeBuiltin");var nt=Object.defineProperty,R=g((e,t)=>nt(e,"name",{value:t,configurable:!0}),"n$1");const ot=R((e,t)=>`${JSON.stringify({bin:{[e]:"./bin/index.js"},description:t,devDependencies:{typescript:"^5.0.0"},name:e,private:!0,scripts:{build:"tsc",dev:"tsc --watch"},type:"module",version:"0.0.1"},null,4)}
33
- `,"packageJson"),st=R(e=>`#!/usr/bin/env node
34
-
35
- /**
36
- * ${e} — code generator
37
- *
38
- * Usage: npx ${e} [options]
39
- */
40
-
41
- console.log("Hello from ${e}!");
42
- `,"binIndex"),ct=R(()=>`${JSON.stringify({compilerOptions:{declaration:!0,esModuleInterop:!0,module:"Node16",moduleResolution:"Node16",outDir:"./dist",rootDir:"./src",skipLibCheck:!0,strict:!0,target:"ES2022"},include:["src/**/*","bin/**/*"]},null,4)}
43
- `,"tsconfigJson"),lt=R(()=>`/**
44
- * Generator core logic — export functions used by the CLI entry point.
45
- */
46
-
47
- export const generate = (): void => {
48
- // TODO: Implement your generator logic here
49
- };
50
- `,"srcIndex"),pt=R((e,t="")=>{const{projectName:r,targetDir:i}=e;a.info("Scaffolding code generator..."),b(i),b(c(i,"bin")),b(c(i,"src")),m(c(i,"package.json"),ot(r,t||`Code generator: ${r}`)),a.success("Created package.json");const n=c(i,"bin","index.js");return m(n,st(r)),je(n,493),a.success("Created bin/index.js (executable)"),m(c(i,"tsconfig.json"),ct()),a.success("Created tsconfig.json"),m(c(i,"src","index.ts"),lt()),a.success("Created src/index.ts"),0},"executeGeneratorTemplate");var ut=Object.defineProperty,N=g((e,t)=>ut(e,"name",{value:t,configurable:!0}),"n");const dt=N(e=>`${JSON.stringify({devDependencies:{"@visulima/vis":"latest"},name:e,packageManager:"pnpm@latest",private:!0,scripts:{build:"vis run build",dev:"vis run dev",lint:"vis run lint",test:"vis run test"},type:"module",version:"0.0.0"},null,4)}
51
- `,"rootPackageJson"),mt=N(()=>`packages:
52
- - "apps/*"
53
- - "packages/*"
54
- `,"pnpmWorkspaceYaml"),gt=N(()=>`# Dependencies
55
- node_modules/
56
-
57
- # Build output
58
- dist/
59
- .output/
60
-
61
- # Environment
62
- .env
63
- .env.local
64
- .env.*.local
65
-
66
- # IDE
67
- .vscode/*
68
- !.vscode/settings.json
69
- !.vscode/extensions.json
70
- .idea/
71
-
72
- # OS
73
- .DS_Store
74
- Thumbs.db
75
-
76
- # Logs
77
- *.log
78
- npm-debug.log*
79
- pnpm-debug.log*
80
-
81
- # Cache
82
- .turbo/
83
- .cache/
84
- `,"gitignore"),ht=N(()=>`root = true
85
-
86
- [*]
87
- indent_style = space
88
- indent_size = 4
89
- end_of_line = lf
90
- charset = utf-8
91
- trim_trailing_whitespace = true
92
- insert_final_newline = true
93
-
94
- [*.{yml,yaml}]
95
- indent_size = 2
96
-
97
- [*.md]
98
- trim_trailing_whitespace = false
99
- `,"editorconfig"),ft=N(e=>`# ${e}
100
-
101
- A monorepo powered by [vis](https://visulima.com/packages/vis).
102
-
103
- ## Getting Started
104
-
105
- \`\`\`bash
106
- # Install dependencies
107
- pnpm install
108
-
109
- # Run all apps in development mode
110
- pnpm dev
7
+ const __cjs_getBuiltinModule = (module) => {
8
+ // Check if we're in Node.js and version supports getBuiltinModule
9
+ if (typeof __cjs_getProcess !== "undefined" && __cjs_getProcess.versions && __cjs_getProcess.versions.node) {
10
+ const [major, minor] = __cjs_getProcess.versions.node.split(".").map(Number);
11
+ // Node.js 20.16.0+ and 22.3.0+
12
+ if (major > 22 || (major === 22 && minor >= 3) || (major === 20 && minor >= 16)) {
13
+ return __cjs_getProcess.getBuiltinModule(module);
14
+ }
15
+ }
16
+ // Fallback to createRequire
17
+ return __cjs_require(module);
18
+ };
111
19
 
112
- # Build all packages
113
- pnpm build
20
+ const {
21
+ readdirSync,
22
+ writeFileSync
23
+ } = __cjs_getBuiltinModule("node:fs");
24
+ import { readJsonSync, readFileSync, ensureDirSync } from '@visulima/fs';
25
+ import { join, resolve, dirname } from '@visulima/path';
26
+ import { d as discoverWorkspace, b as buildProjectGraph, p as pail } from './bin.js';
27
+ const {
28
+ randomUUID
29
+ } = __cjs_getBuiltinModule("node:crypto");
30
+ import { toXML } from 'jstoxml';
31
+ import { r as resolveFocusProjects } from '../packem_shared/docker-2iZzc280.js';
32
+ import { parseLockFileContent } from '@visulima/package';
33
+ import semver from 'semver';
114
34
 
115
- # Run tests
116
- pnpm test
117
- \`\`\`
35
+ const readJsonSafe = (path) => {
36
+ try {
37
+ return readJsonSync(path);
38
+ } catch {
39
+ return void 0;
40
+ }
41
+ };
42
+ const isSafePackageName = (name) => {
43
+ if (name.length === 0 || name.includes("..") || name.startsWith(".") || name.includes("\0") || name.includes("\\")) {
44
+ return false;
45
+ }
46
+ if (name.startsWith("@")) {
47
+ const slashIndex = name.indexOf("/");
48
+ return slashIndex > 1 && !name.includes("/", slashIndex + 1);
49
+ }
50
+ return !name.includes("/");
51
+ };
52
+ const isSafeVersion = (version) => version.length > 0 && !version.includes("/") && !version.includes("\\") && !version.includes("..") && !version.includes("\0");
53
+ const readPnpmVirtualStore = (workspaceRoot, name, version) => {
54
+ const encodedName = name.replaceAll("/", "+");
55
+ const exactDir = `${encodedName}@${version}`;
56
+ const pnpmRoot = join(workspaceRoot, "node_modules", ".pnpm");
57
+ const exact = readJsonSafe(join(pnpmRoot, exactDir, "node_modules", name, "package.json"));
58
+ if (exact) {
59
+ return exact;
60
+ }
61
+ let directories;
62
+ try {
63
+ directories = readdirSync(pnpmRoot);
64
+ } catch {
65
+ return void 0;
66
+ }
67
+ const prefix = `${exactDir}_`;
68
+ for (const directory of directories) {
69
+ if (!directory.startsWith(prefix)) {
70
+ continue;
71
+ }
72
+ const metadata = readJsonSafe(join(pnpmRoot, directory, "node_modules", name, "package.json"));
73
+ if (metadata) {
74
+ return metadata;
75
+ }
76
+ }
77
+ return void 0;
78
+ };
79
+ const readHoistedCopy = (workspaceRoot, name, version) => {
80
+ const metadata = readJsonSafe(join(workspaceRoot, "node_modules", name, "package.json"));
81
+ return metadata?.version === version ? metadata : void 0;
82
+ };
83
+ const readInstalledPackageMetadata = (workspaceRoot, name, version) => {
84
+ if (!isSafePackageName(name) || !isSafeVersion(version)) {
85
+ return void 0;
86
+ }
87
+ return readPnpmVirtualStore(workspaceRoot, name, version) ?? readHoistedCopy(workspaceRoot, name, version);
88
+ };
118
89
 
119
- ## Structure
90
+ const KNOWN_SPDX_IDS = /* @__PURE__ */ new Set([
91
+ "0BSD",
92
+ "AGPL-3.0",
93
+ "AGPL-3.0-only",
94
+ "AGPL-3.0-or-later",
95
+ "Apache-1.1",
96
+ "Apache-2.0",
97
+ "Artistic-2.0",
98
+ "BlueOak-1.0.0",
99
+ "BSD-2-Clause",
100
+ "BSD-3-Clause",
101
+ "BSL-1.0",
102
+ "CC0-1.0",
103
+ "CC-BY-3.0",
104
+ "CC-BY-4.0",
105
+ "CDDL-1.0",
106
+ "CDDL-1.1",
107
+ "EPL-1.0",
108
+ "EPL-2.0",
109
+ "GPL-2.0",
110
+ "GPL-2.0-only",
111
+ "GPL-2.0-or-later",
112
+ "GPL-3.0",
113
+ "GPL-3.0-only",
114
+ "GPL-3.0-or-later",
115
+ "ISC",
116
+ "LGPL-2.0",
117
+ "LGPL-2.1",
118
+ "LGPL-3.0",
119
+ "MIT",
120
+ "MIT-0",
121
+ "MPL-1.1",
122
+ "MPL-2.0",
123
+ "Python-2.0",
124
+ "Unlicense",
125
+ "WTFPL",
126
+ "Zlib"
127
+ ]);
128
+ const SPDX_ALIASES = {
129
+ apache2: "Apache-2.0",
130
+ "apache 2.0": "Apache-2.0",
131
+ bsd: "BSD-3-Clause",
132
+ "bsd-2": "BSD-2-Clause",
133
+ "bsd-3": "BSD-3-Clause",
134
+ mit: "MIT",
135
+ public: "Unlicense",
136
+ "public domain": "Unlicense"
137
+ };
138
+ const LOWERCASE_SPDX_LOOKUP = (() => {
139
+ const map = /* @__PURE__ */ new Map();
140
+ for (const id of KNOWN_SPDX_IDS) {
141
+ map.set(id.toLowerCase(), id);
142
+ }
143
+ for (const [alias, canonical] of Object.entries(SPDX_ALIASES)) {
144
+ map.set(alias, canonical);
145
+ }
146
+ return map;
147
+ })();
148
+ const normalizeSpdxId = (raw) => {
149
+ const trimmed = raw.trim();
150
+ if (trimmed.length === 0) {
151
+ return void 0;
152
+ }
153
+ if (KNOWN_SPDX_IDS.has(trimmed)) {
154
+ return trimmed;
155
+ }
156
+ return LOWERCASE_SPDX_LOOKUP.get(trimmed.toLowerCase());
157
+ };
158
+ const extractLicenseChoice = (input) => {
159
+ let rawValue;
160
+ if (typeof input.license === "string") {
161
+ rawValue = input.license;
162
+ } else if (input.license && typeof input.license === "object" && typeof input.license.type === "string") {
163
+ rawValue = input.license.type;
164
+ } else if (Array.isArray(input.licenses) && input.licenses.length > 0) {
165
+ const first = input.licenses[0];
166
+ if (first && typeof first.type === "string") {
167
+ rawValue = first.type;
168
+ }
169
+ }
170
+ if (!rawValue) {
171
+ return void 0;
172
+ }
173
+ const trimmed = rawValue.trim();
174
+ if (trimmed.length === 0) {
175
+ return void 0;
176
+ }
177
+ if (/[()]|\b(and|or|with)\b/i.test(trimmed)) {
178
+ return [{ expression: trimmed }];
179
+ }
180
+ const spdxId = normalizeSpdxId(trimmed);
181
+ if (spdxId) {
182
+ return [{ license: { id: spdxId } }];
183
+ }
184
+ return [{ license: { name: trimmed } }];
185
+ };
120
186
 
121
- \`\`\`
122
- ├── apps/ # Applications
123
- ├── packages/ # Shared packages & libraries
124
- ├── pnpm-workspace.yaml
125
- └── package.json
126
- \`\`\`
127
- `,"readmeMd"),yt=N(e=>{const{projectName:t,targetDir:r}=e;return a.info("Scaffolding monorepo workspace..."),b(r),b(c(r,"apps")),b(c(r,"packages")),m(c(r,"package.json"),dt(t)),a.success("Created package.json"),m(c(r,"pnpm-workspace.yaml"),mt()),a.success("Created pnpm-workspace.yaml"),m(c(r,".gitignore"),gt()),a.success("Created .gitignore"),m(c(r,".editorconfig"),ht()),a.success("Created .editorconfig"),m(c(r,"README.md"),ft(t)),a.success("Created README.md"),m(c(r,"apps",".gitkeep"),""),m(c(r,"packages",".gitkeep"),""),0},"executeMonorepoTemplate");var vt=Object.defineProperty,H=g((e,t)=>vt(e,"name",{value:t,configurable:!0}),"s");const bt={"create-nuxt":{monoArgs:["--no-gitInit"]},"create-vite":{args:["--no-immediate"]},sv:{args:["--no-install"],prependCommand:"create"}},wt=H((e,t,r)=>{const i=bt[e];if(!i)return t;const n=[...t];if(i.prependCommand&&!n.includes(i.prependCommand)&&n.unshift(i.prependCommand),i.args)for(const u of i.args)n.includes(u)||n.push(u);if(r&&i.monoArgs)for(const u of i.monoArgs)n.includes(u)||n.push(u);return n},"applyAutoFixes"),kt=H((e,t)=>{const r=W(t.cwd,t.targetDir)||".",i=[...e.args];i.includes(r)||i.unshift(r);const n=wt(e.source,i,t.inMonorepo);return a.info(`Running ${e.source} via ${t.pm.name} dlx...`),le(t.pm,{additionalPackages:[],args:n,package:e.source,shellMode:!1,silent:!1},t.cwd,t.logger)},"executeRemoteNpm"),xt=H(async(e,t)=>{const{createConfig:r}=t;a.info(`Downloading template from ${e.source}...`);try{const i=await Se(e.source,{auth:r?.auth||process.env.GIGET_AUTH||process.env.GITHUB_TOKEN||process.env.GH_TOKEN||void 0,dir:t.targetDir,force:!0,preferOffline:r?.preferOffline,provider:r?.defaultProvider,registry:r?.registry});return a.info(`Downloaded to ${i.dir}`),0}catch(i){const n=i instanceof Error?i.message:String(i);return a.warn(`Failed to download template: ${n}`),1}},"executeRemoteGit");var $t=Object.defineProperty,_t=g((e,t)=>$t(e,"name",{value:t,configurable:!0}),"r");const jt=_t(async(e,t)=>{switch(e.type){case"builtin:app":case"builtin:library":return at(e,t);case"builtin:generator":return pt(t);case"builtin:monorepo":return yt(t);case"remote:git":return xt(e,t);case"remote:npm":return kt(e,t);default:throw new Error(`Unknown template type: ${e.type}`)}},"executeTemplate");var Ct=Object.defineProperty,j=g((e,t)=>Ct(e,"name",{value:t,configurable:!0}),"m");const St=j(e=>{const t=c(e,".vscode");b(t);const r=c(t,"settings.json"),i={"editor.defaultFormatter":"oxc.oxc-vscode","editor.formatOnSave":!0};if(P(r))try{const p=ae(r);m(r,`${JSON.stringify({...i,...p},null,4)}
128
- `),a.success("Merged .vscode/settings.json")}catch{a.warn("Could not merge .vscode/settings.json, skipping")}else m(r,`${JSON.stringify(i,null,4)}
129
- `),a.success("Created .vscode/settings.json");const n=c(t,"extensions.json"),u={recommendations:["oxc.oxc-vscode"]};if(P(n))try{const p=ae(n);m(n,`${JSON.stringify({...p,recommendations:[...new Set([...p.recommendations||[],...u.recommendations])]},null,4)}
130
- `),a.success("Merged .vscode/extensions.json")}catch{a.warn("Could not merge .vscode/extensions.json, skipping")}else m(n,`${JSON.stringify(u,null,4)}
131
- `),a.success("Created .vscode/extensions.json")},"generateVscodeConfig"),Pt=j((e,t)=>{const r=c(e,".ai");b(r);const i=c(r,"instructions");if(P(i))return;const n=`# Project Instructions
187
+ const SRI_TO_CYCLONEDX_ALG = {
188
+ sha256: "SHA-256",
189
+ sha384: "SHA-384",
190
+ sha512: "SHA-512"
191
+ };
192
+ const SRI_HEX_LENGTH = {
193
+ sha256: 64,
194
+ sha384: 96,
195
+ sha512: 128
196
+ };
197
+ const toResolvedPackage = (entry) => {
198
+ const resolved = { name: entry.name, version: entry.version };
199
+ const { integrity } = entry;
200
+ if (integrity && integrity.hex.length === SRI_HEX_LENGTH[integrity.algorithm]) {
201
+ resolved.hash = {
202
+ alg: SRI_TO_CYCLONEDX_ALG[integrity.algorithm],
203
+ content: integrity.hex
204
+ };
205
+ }
206
+ if (entry.dependencies) {
207
+ resolved.dependencies = entry.dependencies;
208
+ }
209
+ if (entry.peerDependencies) {
210
+ resolved.peerDependencies = entry.peerDependencies;
211
+ }
212
+ if (entry.optionalDependencies) {
213
+ resolved.optionalDependencies = entry.optionalDependencies;
214
+ }
215
+ return resolved;
216
+ };
217
+ const LOCKFILE_CANDIDATES = [
218
+ { file: "pnpm-lock.yaml", type: "pnpm" },
219
+ { file: "package-lock.json", type: "npm" },
220
+ { file: "yarn.lock", type: "yarn" },
221
+ { file: "bun.lock", type: "bun" }
222
+ ];
223
+ const readLockfilePackages = (workspaceRoot) => {
224
+ for (const { file, type } of LOCKFILE_CANDIDATES) {
225
+ let content;
226
+ try {
227
+ content = readFileSync(join(workspaceRoot, file));
228
+ } catch {
229
+ continue;
230
+ }
231
+ const packages = /* @__PURE__ */ new Map();
232
+ for (const entry of parseLockFileContent(content, type)) {
233
+ packages.set(`${entry.name}@${entry.version}`, toResolvedPackage(entry));
234
+ }
235
+ return { packages, type };
236
+ }
237
+ return void 0;
238
+ };
132
239
 
133
- This project was scaffolded with vis create.
240
+ const encodeSegment = (input) => input.replaceAll(/[^\w.~-]/g, (char) => {
241
+ const codePoint = char.codePointAt(0) ?? 0;
242
+ return `%${codePoint.toString(16).toUpperCase().padStart(2, "0")}`;
243
+ });
244
+ const toNpmPurl = (packageName, version) => {
245
+ const lowered = packageName.toLowerCase();
246
+ if (lowered.startsWith("@")) {
247
+ const slashIndex = lowered.indexOf("/");
248
+ if (slashIndex > 0) {
249
+ const namespace = lowered.slice(0, slashIndex);
250
+ const name = lowered.slice(slashIndex + 1);
251
+ return `pkg:npm/${encodeSegment(namespace)}/${encodeSegment(name)}@${encodeSegment(version)}`;
252
+ }
253
+ }
254
+ return `pkg:npm/${encodeSegment(lowered)}@${encodeSegment(version)}`;
255
+ };
134
256
 
135
- ## Development
257
+ const stripProtocolPrefix = (specifier) => {
258
+ const colonIndex = specifier.indexOf(":");
259
+ if (colonIndex <= 0) {
260
+ return specifier;
261
+ }
262
+ const prefix = specifier.slice(0, colonIndex);
263
+ return prefix === "npm" ? specifier.slice(colonIndex + 1) : specifier;
264
+ };
265
+ const resolveSpecifier = (name, specifier, index) => {
266
+ const versions = index.get(name);
267
+ if (!versions || versions.size === 0) {
268
+ return void 0;
269
+ }
270
+ if (versions.has(specifier)) {
271
+ return specifier;
272
+ }
273
+ const stripped = stripProtocolPrefix(specifier);
274
+ if (stripped !== specifier && versions.has(stripped)) {
275
+ return stripped;
276
+ }
277
+ const list = [...versions];
278
+ const best = semver.maxSatisfying(list, stripped, { includePrerelease: true });
279
+ if (best) {
280
+ return best;
281
+ }
282
+ return list[0];
283
+ };
136
284
 
137
- - Package manager: ${t}
138
- - Build: \`${t} run build\`
139
- - Test: \`${t} run test\`
140
- - Lint: \`${t} run lint\`
285
+ const CYCLONEDX_SPEC_VERSION = "1.6";
286
+ const CYCLONEDX_BOM_FORMAT = "CycloneDX";
287
+ const CYCLONEDX_SCHEMA_URL = "http://cyclonedx.org/schema/bom-1.6.schema.json";
288
+ const GENERATOR_NAME = "@visulima/vis";
289
+ const readPackageJson = (path) => {
290
+ try {
291
+ return readJsonSync(path);
292
+ } catch {
293
+ return void 0;
294
+ }
295
+ };
296
+ const toAuthorString = (author) => {
297
+ if (!author) {
298
+ return void 0;
299
+ }
300
+ if (typeof author === "string") {
301
+ return author;
302
+ }
303
+ if (typeof author === "object" && author.name) {
304
+ return author.email ? `${author.name} <${author.email}>` : author.name;
305
+ }
306
+ return void 0;
307
+ };
308
+ const toRepositoryUrl = (repository) => {
309
+ if (!repository) {
310
+ return void 0;
311
+ }
312
+ if (typeof repository === "string") {
313
+ return repository;
314
+ }
315
+ return repository.url;
316
+ };
317
+ const toBugsUrl = (bugs) => {
318
+ if (!bugs) {
319
+ return void 0;
320
+ }
321
+ if (typeof bugs === "string") {
322
+ return bugs;
323
+ }
324
+ return bugs.url;
325
+ };
326
+ const buildExternalReferences = (pkg) => {
327
+ const references = [];
328
+ if (pkg.homepage) {
329
+ references.push({ type: "website", url: pkg.homepage });
330
+ }
331
+ const vcs = toRepositoryUrl(pkg.repository);
332
+ if (vcs) {
333
+ references.push({ type: "vcs", url: vcs });
334
+ }
335
+ const issues = toBugsUrl(pkg.bugs);
336
+ if (issues) {
337
+ references.push({ type: "issue-tracker", url: issues });
338
+ }
339
+ return references.length > 0 ? references : void 0;
340
+ };
341
+ const decoratePackageComponent = (component, pkg) => {
342
+ if (!pkg) {
343
+ return;
344
+ }
345
+ if (pkg.description) {
346
+ component.description = pkg.description;
347
+ }
348
+ const author = toAuthorString(pkg.author);
349
+ if (author) {
350
+ component.author = author;
351
+ }
352
+ const license = extractLicenseChoice(pkg);
353
+ if (license) {
354
+ component.licenses = license;
355
+ }
356
+ const references = buildExternalReferences(pkg);
357
+ if (references) {
358
+ component.externalReferences = references;
359
+ }
360
+ };
361
+ const buildCycloneDxBom = (options) => {
362
+ const { focus, generatorVersion, includeDev = false, now = /* @__PURE__ */ new Date(), projectGraph, serialNumber, workspace, workspaceRoot } = options;
363
+ const projectNames = focus && focus.length > 0 ? [...resolveFocusProjects(focus, projectGraph)].sort() : Object.keys(workspace.projects).sort();
364
+ const inScope = new Set(projectNames);
365
+ const projectPackages = /* @__PURE__ */ new Map();
366
+ for (const name of projectNames) {
367
+ const projectConfig = workspace.projects[name];
368
+ if (projectConfig) {
369
+ projectPackages.set(name, readPackageJson(join(workspaceRoot, projectConfig.root, "package.json")));
370
+ }
371
+ }
372
+ const projectComponents = [];
373
+ const projectBomRefs = /* @__PURE__ */ new Map();
374
+ for (const name of projectNames) {
375
+ const projectConfig = workspace.projects[name];
376
+ if (!projectConfig) {
377
+ continue;
378
+ }
379
+ const pkg = projectPackages.get(name);
380
+ const version = pkg?.version ?? "0.0.0";
381
+ const bomRef = toNpmPurl(name, version);
382
+ projectBomRefs.set(name, bomRef);
383
+ const component = {
384
+ "bom-ref": bomRef,
385
+ name,
386
+ purl: bomRef,
387
+ type: projectConfig.projectType === "application" ? "application" : "library",
388
+ version
389
+ };
390
+ decoratePackageComponent(component, pkg);
391
+ projectComponents.push(component);
392
+ }
393
+ const lockfile = readLockfilePackages(workspaceRoot);
394
+ const lockfileByRef = /* @__PURE__ */ new Map();
395
+ const versionIndex = /* @__PURE__ */ new Map();
396
+ if (lockfile) {
397
+ for (const pkg of lockfile.packages.values()) {
398
+ lockfileByRef.set(`${pkg.name}@${pkg.version}`, pkg);
399
+ let versions = versionIndex.get(pkg.name);
400
+ if (!versions) {
401
+ versions = /* @__PURE__ */ new Set();
402
+ versionIndex.set(pkg.name, versions);
403
+ }
404
+ versions.add(pkg.version);
405
+ }
406
+ }
407
+ const requiredSeed = [];
408
+ const optionalSeed = [];
409
+ const directDepEdges = /* @__PURE__ */ new Map();
410
+ for (const name of projectNames) {
411
+ const pkg = projectPackages.get(name);
412
+ if (!pkg) {
413
+ continue;
414
+ }
415
+ const requiredMaps = [pkg.dependencies, pkg.peerDependencies];
416
+ if (includeDev) {
417
+ requiredMaps.push(pkg.devDependencies);
418
+ }
419
+ const edges = /* @__PURE__ */ new Set();
420
+ const seedRef = (target, depMap) => {
421
+ if (!depMap) {
422
+ return;
423
+ }
424
+ for (const [depName, specifier] of Object.entries(depMap)) {
425
+ if (inScope.has(depName)) {
426
+ const ref = projectBomRefs.get(depName);
427
+ if (ref) {
428
+ edges.add(ref);
429
+ }
430
+ continue;
431
+ }
432
+ const resolvedVersion = resolveSpecifier(depName, specifier, versionIndex);
433
+ if (resolvedVersion) {
434
+ edges.add(toNpmPurl(depName, resolvedVersion));
435
+ target.push(`${depName}@${resolvedVersion}`);
436
+ }
437
+ }
438
+ };
439
+ for (const depMap of requiredMaps) {
440
+ seedRef(requiredSeed, depMap);
441
+ }
442
+ seedRef(optionalSeed, pkg.optionalDependencies);
443
+ directDepEdges.set(name, edges);
444
+ }
445
+ const reachableRegistryRefs = /* @__PURE__ */ new Map();
446
+ const registryDepEdges = /* @__PURE__ */ new Map();
447
+ const walk = (seeds, scope) => {
448
+ const queue = [...seeds];
449
+ while (queue.length > 0) {
450
+ const ref = queue.pop();
451
+ const existing = reachableRegistryRefs.get(ref);
452
+ if (existing === "required" || existing === "optional" && scope === "optional") {
453
+ continue;
454
+ }
455
+ reachableRegistryRefs.set(ref, scope);
456
+ const entry = lockfileByRef.get(ref);
457
+ if (!entry) {
458
+ continue;
459
+ }
460
+ const outgoing = registryDepEdges.get(ref) ?? /* @__PURE__ */ new Set();
461
+ const inheritedMaps = [entry.dependencies, entry.peerDependencies];
462
+ for (const depMap of inheritedMaps) {
463
+ if (!depMap) {
464
+ continue;
465
+ }
466
+ for (const [depName, specifiers] of Object.entries(depMap)) {
467
+ for (const specifier of specifiers) {
468
+ const resolvedVersion = resolveSpecifier(depName, specifier, versionIndex);
469
+ if (!resolvedVersion) {
470
+ continue;
471
+ }
472
+ outgoing.add(toNpmPurl(depName, resolvedVersion));
473
+ queue.push(`${depName}@${resolvedVersion}`);
474
+ }
475
+ }
476
+ }
477
+ if (entry.optionalDependencies) {
478
+ for (const [depName, specifiers] of Object.entries(entry.optionalDependencies)) {
479
+ for (const specifier of specifiers) {
480
+ const resolvedVersion = resolveSpecifier(depName, specifier, versionIndex);
481
+ if (!resolvedVersion) {
482
+ continue;
483
+ }
484
+ outgoing.add(toNpmPurl(depName, resolvedVersion));
485
+ optionalSeed.push(`${depName}@${resolvedVersion}`);
486
+ }
487
+ }
488
+ }
489
+ if (outgoing.size > 0) {
490
+ registryDepEdges.set(ref, outgoing);
491
+ }
492
+ }
493
+ };
494
+ walk(requiredSeed, "required");
495
+ walk(optionalSeed, "optional");
496
+ const registryComponents = [];
497
+ const sortedRefs = [...reachableRegistryRefs.keys()].sort();
498
+ for (const ref of sortedRefs) {
499
+ const pkg = lockfileByRef.get(ref);
500
+ if (!pkg) {
501
+ continue;
502
+ }
503
+ const purl = toNpmPurl(pkg.name, pkg.version);
504
+ const component = {
505
+ "bom-ref": purl,
506
+ name: pkg.name,
507
+ purl,
508
+ scope: reachableRegistryRefs.get(ref) ?? "required",
509
+ type: "library",
510
+ version: pkg.version
511
+ };
512
+ if (pkg.hash) {
513
+ component.hashes = [pkg.hash];
514
+ }
515
+ decoratePackageComponent(component, readInstalledPackageMetadata(workspaceRoot, pkg.name, pkg.version));
516
+ registryComponents.push(component);
517
+ }
518
+ const dependencies = [];
519
+ for (const [projectName, edges] of directDepEdges) {
520
+ const ref = projectBomRefs.get(projectName);
521
+ if (!ref) {
522
+ continue;
523
+ }
524
+ const dependsOn = [...edges].sort();
525
+ dependencies.push(dependsOn.length > 0 ? { dependsOn, ref } : { ref });
526
+ }
527
+ for (const ref of sortedRefs) {
528
+ const pkg = lockfileByRef.get(ref);
529
+ if (!pkg) {
530
+ continue;
531
+ }
532
+ const purl = toNpmPurl(pkg.name, pkg.version);
533
+ const outgoing = registryDepEdges.get(ref);
534
+ const dependsOn = outgoing ? [...outgoing].sort() : [];
535
+ dependencies.push(dependsOn.length > 0 ? { dependsOn, ref: purl } : { ref: purl });
536
+ }
537
+ dependencies.sort((a, b) => a.ref.localeCompare(b.ref));
538
+ const rootPkg = readPackageJson(join(workspaceRoot, "package.json"));
539
+ const metadataComponent = (() => {
540
+ if (focus?.length === 1) {
541
+ const match = projectComponents.find((component2) => component2.name === focus[0]);
542
+ if (match) {
543
+ return {
544
+ "bom-ref": match["bom-ref"],
545
+ name: match.name,
546
+ purl: match.purl,
547
+ type: match.type,
548
+ version: match.version
549
+ };
550
+ }
551
+ }
552
+ const rootName = rootPkg?.name ?? "workspace";
553
+ const rootVersion = rootPkg?.version ?? "0.0.0";
554
+ const rootRef = toNpmPurl(rootName, rootVersion);
555
+ const component = {
556
+ "bom-ref": rootRef,
557
+ name: rootName,
558
+ purl: rootRef,
559
+ type: "application",
560
+ version: rootVersion
561
+ };
562
+ decoratePackageComponent(component, rootPkg);
563
+ return component;
564
+ })();
565
+ const metadataRef = metadataComponent["bom-ref"];
566
+ const filteredProjectComponents = metadataRef ? projectComponents.filter((component) => component["bom-ref"] !== metadataRef) : projectComponents;
567
+ return {
568
+ $schema: CYCLONEDX_SCHEMA_URL,
569
+ bomFormat: CYCLONEDX_BOM_FORMAT,
570
+ components: [...filteredProjectComponents, ...registryComponents],
571
+ dependencies,
572
+ metadata: {
573
+ component: metadataComponent,
574
+ lifecycles: [{ phase: "build" }],
575
+ timestamp: now.toISOString(),
576
+ tools: {
577
+ components: [
578
+ {
579
+ name: GENERATOR_NAME,
580
+ type: "application",
581
+ ...generatorVersion ? { version: generatorVersion } : {}
582
+ }
583
+ ]
584
+ }
585
+ },
586
+ serialNumber: serialNumber ?? `urn:uuid:${randomUUID()}`,
587
+ specVersion: CYCLONEDX_SPEC_VERSION,
588
+ version: 1
589
+ };
590
+ };
591
+ const serializeBomToXml = (bom) => {
592
+ const rootAttributes = {
593
+ version: bom.version ?? 1,
594
+ xmlns: "http://cyclonedx.org/schema/bom/1.6"
595
+ };
596
+ if (bom.serialNumber) {
597
+ rootAttributes.serialNumber = bom.serialNumber;
598
+ }
599
+ const content = [];
600
+ if (bom.metadata) {
601
+ content.push(metadataToXmlElement(bom.metadata));
602
+ }
603
+ if (bom.components && bom.components.length > 0) {
604
+ content.push({
605
+ _content: bom.components.map(componentToXmlElement),
606
+ _name: "components"
607
+ });
608
+ }
609
+ if (bom.dependencies && bom.dependencies.length > 0) {
610
+ content.push({
611
+ _content: bom.dependencies.map(dependencyToXmlElement),
612
+ _name: "dependencies"
613
+ });
614
+ }
615
+ const xml = toXML(
616
+ {
617
+ _attrs: rootAttributes,
618
+ _content: content,
619
+ _name: "bom"
620
+ },
621
+ {
622
+ header: true,
623
+ indent: " ",
624
+ selfCloseTags: true
625
+ }
626
+ );
627
+ return `${xml}
628
+ `;
629
+ };
630
+ const metadataToXmlElement = (metadata) => {
631
+ const children = [];
632
+ if (metadata.timestamp) {
633
+ children.push({ timestamp: metadata.timestamp });
634
+ }
635
+ if (metadata.lifecycles && metadata.lifecycles.length > 0) {
636
+ children.push({
637
+ _content: metadata.lifecycles.map((lifecycle) => {
638
+ const entries = [];
639
+ if (lifecycle.phase) {
640
+ entries.push({ phase: lifecycle.phase });
641
+ }
642
+ if (lifecycle.name) {
643
+ entries.push({ name: lifecycle.name });
644
+ }
645
+ if (lifecycle.description) {
646
+ entries.push({ description: lifecycle.description });
647
+ }
648
+ return { _content: entries, _name: "lifecycle" };
649
+ }),
650
+ _name: "lifecycles"
651
+ });
652
+ }
653
+ if (metadata.tools?.components) {
654
+ children.push({
655
+ _content: [
656
+ {
657
+ _content: metadata.tools.components.map(componentToXmlElement),
658
+ _name: "components"
659
+ }
660
+ ],
661
+ _name: "tools"
662
+ });
663
+ }
664
+ if (metadata.component) {
665
+ children.push(componentToXmlElement(metadata.component));
666
+ }
667
+ return { _content: children, _name: "metadata" };
668
+ };
669
+ const componentToXmlElement = (component) => {
670
+ const attributes = { type: component.type };
671
+ if (component["bom-ref"]) {
672
+ attributes["bom-ref"] = component["bom-ref"];
673
+ }
674
+ const children = [];
675
+ if (component.group) {
676
+ children.push({ group: component.group });
677
+ }
678
+ children.push({ name: component.name });
679
+ if (component.version) {
680
+ children.push({ version: component.version });
681
+ }
682
+ if (component.description) {
683
+ children.push({ description: component.description });
684
+ }
685
+ if (component.author) {
686
+ children.push({ author: component.author });
687
+ }
688
+ if (component.hashes && component.hashes.length > 0) {
689
+ children.push({
690
+ _content: component.hashes.map((hash) => {
691
+ return {
692
+ _attrs: { alg: hash.alg },
693
+ _content: hash.content,
694
+ _name: "hash"
695
+ };
696
+ }),
697
+ _name: "hashes"
698
+ });
699
+ }
700
+ const licenses = licensesToXmlElement(component.licenses);
701
+ if (licenses) {
702
+ children.push(licenses);
703
+ }
704
+ if (component.purl) {
705
+ children.push({ purl: component.purl });
706
+ }
707
+ if (component.scope) {
708
+ children.push({ scope: component.scope });
709
+ }
710
+ if (component.externalReferences && component.externalReferences.length > 0) {
711
+ children.push({
712
+ _content: component.externalReferences.map((reference) => {
713
+ return {
714
+ _attrs: { type: reference.type },
715
+ _content: [{ url: reference.url }],
716
+ _name: "reference"
717
+ };
718
+ }),
719
+ _name: "externalReferences"
720
+ });
721
+ }
722
+ return { _attrs: attributes, _content: children, _name: "component" };
723
+ };
724
+ const licensesToXmlElement = (licenses) => {
725
+ if (!licenses || licenses.length === 0) {
726
+ return void 0;
727
+ }
728
+ const entries = [];
729
+ for (const entry of licenses) {
730
+ if ("expression" in entry) {
731
+ entries.push({ expression: entry.expression });
732
+ continue;
733
+ }
734
+ const licenseChildren = [];
735
+ if ("id" in entry.license && entry.license.id) {
736
+ licenseChildren.push({ id: entry.license.id });
737
+ } else if ("name" in entry.license && entry.license.name) {
738
+ licenseChildren.push({ name: entry.license.name });
739
+ }
740
+ entries.push({ _content: licenseChildren, _name: "license" });
741
+ }
742
+ return { _content: entries, _name: "licenses" };
743
+ };
744
+ const dependencyToXmlElement = (dep) => {
745
+ if (dep.dependsOn && dep.dependsOn.length > 0) {
746
+ return {
747
+ _attrs: { ref: dep.ref },
748
+ _content: dep.dependsOn.map((child) => {
749
+ return {
750
+ _attrs: { ref: child },
751
+ _name: "dependency"
752
+ };
753
+ }),
754
+ _name: "dependency"
755
+ };
756
+ }
757
+ return { _attrs: { ref: dep.ref }, _name: "dependency" };
758
+ };
141
759
 
142
- ## Conventions
760
+ const SBOM_FORMATS = ["json", "xml"];
761
+ const isSbomFormat = (value) => SBOM_FORMATS.includes(value);
762
+ const execute = async ({ options, visConfig, workspaceRoot: wsRoot }) => {
763
+ if (!wsRoot) {
764
+ throw new Error("Could not determine workspace root. Run inside a monorepo.");
765
+ }
766
+ const { packageJsons, workspace } = discoverWorkspace(wsRoot, visConfig);
767
+ const projectGraph = buildProjectGraph(wsRoot, workspace, packageJsons);
768
+ const focusRaw = options.focus;
769
+ const focus = focusRaw ? focusRaw.split(",").map((name) => name.trim()).filter(Boolean) : void 0;
770
+ const format = (options.format ?? "json").toLowerCase();
771
+ if (!isSbomFormat(format)) {
772
+ throw new Error(`Unknown --format: "${format}". Expected one of: ${SBOM_FORMATS.join(", ")}.`);
773
+ }
774
+ const bom = buildCycloneDxBom({
775
+ focus,
776
+ includeDev: Boolean(options.includeDev),
777
+ projectGraph,
778
+ workspace,
779
+ workspaceRoot: wsRoot
780
+ });
781
+ const serialized = format === "xml" ? serializeBomToXml(bom) : `${JSON.stringify(bom, void 0, 2)}
782
+ `;
783
+ const output = options.output ?? (format === "xml" ? "sbom.cdx.xml" : "sbom.cdx.json");
784
+ if (output === "-") {
785
+ process.stdout.write(serialized);
786
+ return;
787
+ }
788
+ const outPath = resolve(wsRoot, output);
789
+ ensureDirSync(dirname(outPath));
790
+ writeFileSync(outPath, serialized, "utf8");
791
+ const componentCount = bom.components?.length ?? 0;
792
+ const dependencyCount = bom.dependencies?.length ?? 0;
793
+ pail.success(`SBOM written to ${outPath}`);
794
+ pail.notice(`${componentCount} components, ${dependencyCount} dependency edges`);
795
+ };
143
796
 
144
- - Use TypeScript strict mode
145
- - ESM modules (\`"type": "module"\`)
146
- - Follow Angular-style conventional commits
147
- `;m(i,n),a.success("Created .ai/instructions")},"generateAiInstructions"),Nt=j(e=>{ye("git",["init"],{cwd:e,stdio:"pipe"}).status===0?a.success("Initialized git repository"):a.warn("Failed to initialize git repository")},"initGitRepo"),Ot=j((e,t,r,i=!1)=>(a.info("Installing dependencies..."),ke(t,{dev:!1,filter:[],force:!1,frozenLockfile:!1,ignoreScripts:!1,lockfileOnly:!1,noOptional:!1,offline:i,prod:!1,recursive:!1,silent:!1,workspaceRoot:!1},e,r)===0?(a.success("Dependencies installed"),!0):(a.warn("Dependency installation failed (you can run install manually)"),!1)),"installDependencies"),qt=j(e=>{const t=e.split("#")[0].split("?")[0].replace(/\/+$/,"").replace(/\.git$/,"").split("/").filter(Boolean).at(-1)??"",r=t.includes(":")?t.split(":").pop()??t:t;return E(r)||"my-project"},"extractRepoName"),Dt=j(e=>{if(a.info(""),a.info(" Built-in templates:"),a.info(` ${k(x("vis:monorepo"))} ${d("Full pnpm workspace setup")}`),a.info(` ${k(x("vis:app"))} ${d("Application scaffold via create-vite")}`),a.info(` ${k(x("vis:library"))} ${d("Reusable TypeScript library package")}`),a.info(` ${k(x("vis:generator"))} ${d("Code generator scaffold with bin entry")}`),e&&Object.keys(e).length>0){a.info(""),a.info(" Config aliases (vis.config.ts → create.templates):");for(const[t,r]of Object.entries(e))a.info(` ${k(x(t))}${" ".repeat(Math.max(1,16-t.length))}${d(r)}`)}a.info(""),a.info(" Remote templates:"),a.info(` ${d("Any npm create-* package:")} vis create vite`),a.info(` ${d("GitHub repository:")} vis create user/repo`),a.info(` ${d("GitLab / Bitbucket:")} vis create gitlab:user/repo`),a.info(` ${d("Full URL:")} vis create https://github.com/user/repo`),a.info(""),a.info(` ${d("Template args after --:")} vis create vite -- --template react-ts`),a.info("")},"listTemplates"),Tt=j((e,t,r,i)=>{const n=_(t)===_(e)?"":e;process.stderr.write(`
148
- `),a.success("Project created successfully!"),process.stderr.write(`
149
- `),a.notice("Next steps:"),n&&a.info(` cd ${n}`),i||a.info(` ${r} install`),a.info(` ${r} run dev`),process.stderr.write(`
150
- `)},"printNextSteps"),Ut=j(async({argument:e,logger:t,options:r,rawUnknown:i,visConfig:n,workspaceRoot:u})=>{const p=Array.isArray(e)?e:e?[e]:[],o=n?.create;if(r.list){Dt(o?.templates);return}const l=r.cwd||u||process.cwd(),s=!!u,w=!!process.stdin.isTTY,$=xe(l);let y,h,f,O=o?.defaultEditor,M=o?.gitInit??!1,Y=[],q=$,K=!1;if(p.length===0&&w&&!r.noInteractive){const v=await Ke({cwd:l,defaultEditor:o?.defaultEditor,defaultGitInit:o?.gitInit,defaultPm:o?.defaultPm,inMonorepo:s});y=v.template,h=v.projectName,f=_(l,v.targetDir),O=v.editor??O,M=v.gitInit,K=v.overwrite,v.pm&&(q={name:v.pm,version:$.version})}else{if(p.length===0)throw new Error(`No template specified. Usage: vis create <template> [name] [-- args...]
151
- Use --list to see available templates, or run interactively in a terminal.`);{let v=[...i??[]];if(v.length===0){const re=process.argv.slice(2),ie=re.indexOf("--");ie!==-1&&(v=re.slice(ie+1))}const C=p.indexOf("--"),te=C===-1?p:p.slice(0,C);Y=[...C===-1?[]:p.slice(C+1),...v],y=te[0],h=te[1],h||(h=qt(y)),O=r.editor==="vscode"?"vscode":O,M=!!r.gitInit||M}}if(!y)throw new Error("No template specified.");const L=o?.templates?.[y]??y,Q=Ee(L,Y);if(!f){const v=s?Ie(Q.type):".",C=We(h,_(l,v));f=C.targetDir,h=C.packageName}const X=E(h??"");if(!ue(X))throw new Error(`Invalid project name: "${h}". Use lowercase alphanumeric characters and hyphens.`);h=X;const me=_(f),G=W(_(l),me);if(G===".."||G.startsWith(`..${be}`)||we(G))throw new Error(`Target directory "${f}" is outside the working directory. Use a name without "../" path segments.`);if(!K&&!He(f))throw new Error(`Target directory "${f}" is not empty.
152
- Use a different name or clear the directory first.`);L!==y&&a.info(`Alias: ${k(x(y))} → ${d(L)}`),a.info(`Template: ${k(x(L))}`),a.info(`Project: ${k(h)}`),a.info(`Target: ${d(f)}`),process.stderr.write(`
153
- `);const Z=await jt(Q,{createConfig:o,cwd:l,inMonorepo:s,logger:t,pm:q,projectName:h,targetDir:f});if(Z!==0){process.exitCode=Z;return}O==="vscode"&&St(f),P(f)&&Pt(f,q.name),M&&!s&&Nt(f);let ee=!1;o?.install!==!1&&P(c(f,"package.json"))&&(ee=Ot(f,q,t,o?.preferOffline)),Tt(f,l,q.name,ee)},"execute");export{Ut as default};
797
+ export { execute as default };