@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.48 kB
JavaScript
import{writeFileSync as v,existsSync as S,readFileSync as b}from"node:fs";import{isAbsolute as p,join as w}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 u}from"../packem_shared/cli-DIb5Ay4K.mjs";const l={clean:"·",exempt:"–",failing:"✗",warned:"!"},d=(e,r)=>e.length>=r?e:e+" ".repeat(r-e.length),B=e=>`${e.id} (${e.visibility} ${e.kind})`,f=e=>{let r=0;for(const n of e)r=Math.max(r,n.id.length);return r},g=(e,r)=>` ${d(String(e.score),3)} ${l[e.coverage]} ${d(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=f(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=>g(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=f(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(g(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(),m=(e,r)=>p(r)?r:w(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=m(r,n===null||n===""?u: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:$,advisories:h}=F({dryRun:!0,projectRoot:r}),a=x($?.procedureProtections??[],h,{generatedAt:e.generatedAt??I}),s={map:a};if(e.baseline!==void 0){const c=H(a,r,e.baseline);if("error"in c)return e.logger.error(c.error),{...s,error:c.error};s.comparison=c.comparison,c.comparison.comparable||e.logger.error(K(c.comparison.reason))}if(e.write!==!1){const c=m(r,e.out??u);v(c,`${JSON.stringify(a,void 0,4)}
`,"utf8"),s.written=c}return s.belowMinScore=i.value!==void 0&&a.score<i.value,s.belowMinScore&&o.error(`advisor score ${String(a.score)} is below the required ${String(i.value)}`),n?(D(s),s):(o.info(O(a,e,s.comparison)),s.written!==void 0&&o.success(`wrote ${s.written}`),s)},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};