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