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.5 kB
import{writeFileSync as h,existsSync as S,readFileSync as p}from"node:fs";import{isAbsolute as v,join as w}from"node:path";import{byCodepoint as b,scoreAdvisor as y,parseAdvisorMap as x,compareToBaseline as j}from"@lunora/advisor";import{runCodegen as A}from"@lunora/codegen";import{d as M}from"../packem_shared/command-Mmxzxyr5.mjs";import{EXIT_CODE as D}from"../packem_shared/EXIT_CODE-08cwt3MK.mjs";import{D as u}from"../packem_shared/cli-DOpChqUe.mjs";const l={clean:"·",exempt:"–",failing:"✗",warned:"!"},d=(e,r)=>e.length>=r?e:e+" ".repeat(r-e.length),E=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}`,R=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},F=(e,r)=>{const n=e.procedures.filter(i=>i.coverage!=="clean"&&i.coverage!=="exempt"),t=f(n),o=[`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&&o.push("",` project ${String(e.project.score)}/100 — ${e.project.checks.map(i=>i.name).join(", ")}`),n.length>0&&o.push("",...n.map(i=>g(i,t)),""," run with --all for every procedure, or --entry <file#export> for one"),r!==void 0&&o.push("",...R(r)),o.join(` `)},k=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})`}),T=e=>{const r=new Map;for(const n of e){const t=r.get(n.file);t===void 0?r.set(n.file,[n]):t.push(n)}return[...r].toSorted(([n],[t])=>b(n,t))},B=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[t,o]of T(e.procedures)){n.push("",` ${t}`);for(const i of o)n.push(g(i,r),...k(i))}return n.join(` `)},C=(e,r)=>{const n=e.procedures.find(o=>o.id===r);if(n===void 0){const o=e.procedures.slice(0,10).map(i=>` ${i.id}`);return[`no procedure ${r} in the map. Known ids:`,...o,e.procedures.length>10?" …":""].filter(Boolean).join(` `)}const t=[`${E(n)}${String(n.score)}/100, ${n.coverage}`,` weight in the global mean: ${String(n.weight)}`];if(n.checks.length===0)return t.push(""," no rule fired"),t.join(` `);t.push(""," rules fired:");for(const o of n.checks)t.push(` [${o.level}] ${o.name}${String(o.weight)}${o.occurrences>1?` (×${String(o.occurrences)})`:""}`);return t.join(` `)},I=new Date(0).toISOString(),m=(e,r)=>v(r)?r:w(e,r),L=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"}},N=(e,r,n)=>{const t=m(r,n===null||n===""?u:n);if(!S(t))return{error:`baseline not found at ${t} — generate one with \`lunora advisor\` and commit it`};const o=x(JSON.parse(p(t,"utf8")));return o===void 0?{error:`baseline at ${t} is malformed — regenerate it with \`lunora advisor\``}:{comparison:j(e,o)}},P=e=>`baseline is not comparable (${e}) — regenerate it; this run verified nothing`,_=(e,r,n)=>r.entry!==void 0?C(e,r.entry):r.all===!0?B(e):F(e,n),G=e=>{const r=e.cwd??process.cwd(),n=e.format==="json",{logger:t}=e,o=L(e.minScore);if("error"in o)return e.logger.error(o.error),{code:D.USAGE,error:o.error};const{advisorContext:i,advisories:$}=A({dryRun:!0,projectRoot:r}),a=y(i?.procedureProtections??[],$,{generatedAt:e.generatedAt??I}),s={map:a};if(e.baseline!==void 0){const c=N(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(P(c.comparison.reason))}if(e.write!==!1){const c=m(r,e.out??u);h(c,`${JSON.stringify(a,void 0,4)} `,"utf8"),s.written=c}return s.belowMinScore=o.value!==void 0&&a.score<o.value,s.belowMinScore&&t.error(`advisor score ${String(a.score)} is below the required ${String(o.value)}`),n||(t.info(_(a,e,s.comparison)),s.written!==void 0&&t.success(`wrote ${s.written}`)),s},H=e=>e.error!==void 0||e.belowMinScore===!0?!0:e.comparison!==void 0&&(!e.comparison.comparable||e.comparison.regressed),z=M(({cwd:e,format:r,logger:n,options:t})=>{const o=G({all:t.all,baseline:t.baseline,cwd:e,entry:t.entry,format:r,logger:n,minScore:t.minScore,out:t.out,write:t.write});return{code:o.code??(H(o)?1:0),data:{belowMinScore:o.belowMinScore,comparison:o.comparison,map:o.map,written:o.written},error:o.error}});export{z as execute,G as runAdvisorCommand};