UNPKG

@lunora/cli

Version:

The Lunora CLI: init, dev, deploy, codegen, migrate, seed, doctor, insights, logs, registry, and the rest of the project commands

8 lines (7 loc) 5.62 kB
import{writeFileSync as h,existsSync as S,readFileSync as b}from"node:fs";import{isAbsolute as w,join as p}from"node:path";import{byCodepoint as y,scoreAdvisor as x,parseAdvisorMap as j,compareToBaseline as A}from"@lunora/advisor";import{runCodegen as F}from"@lunora/codegen";import{d as M}from"../packem_shared/command-DwC11Cwe.mjs";import{v as R,p as D,l as k,i as E}from"../packem_shared/output-format-DfogXx0p.mjs";import{D as f}from"../packem_shared/cli-oqj4ysM9.mjs";const l={clean:"·",exempt:"–",failing:"✗",warned:"!"},u=(e,r)=>e.length>=r?e:e+" ".repeat(r-e.length),B=e=>`${e.id} (${e.visibility} ${e.kind})`,g=e=>{let r=0;for(const n of e)r=Math.max(r,n.id.length);return r},m=(e,r)=>` ${u(String(e.score),3)} ${l[e.coverage]} ${u(e.id,r)} ${e.visibility} ${e.kind}`,T=e=>{if(!e.comparable)return[` baseline not comparable (${e.reason}) — regenerate it; this run cannot verify anything`];if(!e.regressed)return[` no regression against baseline (score ${e.scoreDelta>=0?"+":""}${String(e.scoreDelta)})`];const r=[` REGRESSED against baseline (score ${e.scoreDelta>=0?"+":""}${String(e.scoreDelta)})`];for(const n of e.dropped)r.push(` ${n.id}: ${String(n.before)}${String(n.after)}`);for(const n of e.newFailing)r.push(` ${n}: now failing`);for(const n of e.worsened)r.push(` ${n}: more findings than the baseline`);return e.projectRegressed&&r.push(" project: new schema/config rules fired"),r},C=(e,r)=>{const n=e.procedures.filter(i=>i.coverage!=="clean"&&i.coverage!=="exempt"),o=g(n),t=[`advisor health ${String(e.score)}/100 — ${e.grade}`,` ${String(e.summary.clean)} clean · ${String(e.summary.warned)} warned · ${String(e.summary.failing)} failing · ${String(e.summary.exempt)} exempt (${String(e.summary.procedures)} procedures, ${String(e.summary.rulesFired)} rules fired)`];return e.project.checks.length>0&&t.push("",` project ${String(e.project.score)}/100 — ${e.project.checks.map(i=>i.name).join(", ")}`),n.length>0&&t.push("",...n.map(i=>m(i,o)),""," run with --all for every procedure, or --entry <file#export> for one"),r!==void 0&&t.push("",...T(r)),t.join(` `)},J=e=>e.coverage==="exempt"?[` exempt: ${e.exemptReason===void 0||e.exemptReason===""?"no reason given":e.exemptReason}`]:e.checks.map(r=>{const n=r.occurrences>1?`, ×${String(r.occurrences)}`:"";return` ${r.name} (−${String(r.weight)}${n})`}),L=e=>{const r=new Map;for(const n of e){const o=r.get(n.file);o===void 0?r.set(n.file,[n]):o.push(n)}return[...r].toSorted(([n],[o])=>y(n,o))},N=e=>{const r=g(e.procedures),n=[`advisor health ${String(e.score)}/100 — ${e.grade}`,"",` legend: ${l.clean} clean ${l.warned} warned ${l.failing} failing ${l.exempt} exempt`];for(const[o,t]of L(e.procedures)){n.push("",` ${o}`);for(const i of t)n.push(m(i,r),...J(i))}return n.join(` `)},P=(e,r)=>{const n=e.procedures.find(t=>t.id===r);if(n===void 0){const t=e.procedures.slice(0,10).map(i=>` ${i.id}`);return[`no procedure ${r} in the map. Known ids:`,...t,e.procedures.length>10?" …":""].filter(Boolean).join(` `)}const o=[`${B(n)}${String(n.score)}/100, ${n.coverage}`,` weight in the global mean: ${String(n.weight)}`];if(n.checks.length===0)return o.push(""," no rule fired"),o.join(` `);o.push(""," rules fired:");for(const t of n.checks)o.push(` [${t.level}] ${t.name}${String(t.weight)}${t.occurrences>1?` (×${String(t.occurrences)})`:""}`);return o.join(` `)},I=new Date(0).toISOString(),$=(e,r)=>w(r)?r:p(e,r),_=e=>{if(e===void 0)return{value:void 0};if(e===null||e==="")return{error:"--min-score needs a value between 0 and 100"};const r=Number(e);return Number.isFinite(r)&&r>=0&&r<=100?{value:r}:{error:"--min-score must be a number between 0 and 100"}},H=(e,r,n)=>{const o=$(r,n===null||n===""?f:n);if(!S(o))return{error:`baseline not found at ${o} — generate one with \`lunora advisor\` and commit it`};const t=j(JSON.parse(b(o,"utf8")));return t===void 0?{error:`baseline at ${o} is malformed — regenerate it with \`lunora advisor\``}:{comparison:A(e,t)}},K=e=>`baseline is not comparable (${e}) — regenerate it; this run verified nothing`,O=(e,r,n)=>r.entry!==void 0?P(e,r.entry):r.all===!0?N(e):C(e,n),q=e=>{const r=e.cwd??process.cwd(),n=E(e.format),o=k(e.format,e.logger),t=R("advisor",e.format);if(t!==void 0)return e.logger.error(t),{error:t};const i=_(e.minScore);if("error"in i)return e.logger.error(i.error),{error:i.error};const{advisorContext:d,advisories:v}=F({dryRun:!0,projectRoot:r});if(d===void 0){const s="advisor evidence unavailable — codegen ran with linting disabled";return e.logger.error(s),{error:s}}const a=x(d.procedureProtections??[],v,{generatedAt:e.generatedAt??I}),c={map:a};if(e.baseline!==void 0){const s=H(a,r,e.baseline);if("error"in s)return e.logger.error(s.error),{...c,error:s.error};c.comparison=s.comparison,s.comparison.comparable||e.logger.error(K(s.comparison.reason))}if(e.write!==!1){const s=$(r,e.out??f);h(s,`${JSON.stringify(a,void 0,4)} `,"utf8"),c.written=s}return c.belowMinScore=i.value!==void 0&&a.score<i.value,c.belowMinScore&&o.error(`advisor score ${String(a.score)} is below the required ${String(i.value)}`),n?(D(c),c):(o.info(O(a,e,c.comparison)),c.written!==void 0&&o.success(`wrote ${c.written}`),c)},G=e=>e.error!==void 0||e.belowMinScore===!0?!0:e.comparison!==void 0&&(!e.comparison.comparable||e.comparison.regressed),Z=M(({cwd:e,logger:r,options:n})=>{const o=q({all:n.all,baseline:n.baseline,cwd:e,entry:n.entry,format:n.format,logger:r,minScore:n.minScore,out:n.out,write:n.write});return{code:G(o)?1:0}});export{Z as execute,q as runAdvisorCommand};