@visulima/vis 3.0.3 → 3.0.5
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.
- package/CHANGELOG.md +23 -0
- package/LICENSE.md +1 -130
- package/dist/bin.js +1 -1
- package/dist/binx.js +1 -1
- package/dist/packem_chunks/catalog.js +1 -1
- package/dist/packem_chunks/cli-exec.js +1 -1
- package/dist/packem_chunks/cli-main.js +172 -171
- package/dist/packem_chunks/fix.js +1 -1
- package/dist/packem_chunks/handler.js +1 -1
- package/dist/packem_chunks/handler10.js +1 -1
- package/dist/packem_chunks/handler11.js +1 -1
- package/dist/packem_chunks/handler12.js +1 -1
- package/dist/packem_chunks/handler13.js +3 -3
- package/dist/packem_chunks/handler14.js +1 -1
- package/dist/packem_chunks/handler15.js +1 -1
- package/dist/packem_chunks/handler16.js +1 -1
- package/dist/packem_chunks/handler17.js +1 -1
- package/dist/packem_chunks/handler18.js +1 -1
- package/dist/packem_chunks/handler19.js +5 -5
- package/dist/packem_chunks/handler2.js +1 -1
- package/dist/packem_chunks/handler21.js +2 -2
- package/dist/packem_chunks/handler24.js +1 -1
- package/dist/packem_chunks/handler27.js +1 -1
- package/dist/packem_chunks/handler28.js +1 -1
- package/dist/packem_chunks/handler29.js +1 -1
- package/dist/packem_chunks/handler3.js +1 -1
- package/dist/packem_chunks/handler33.js +2 -2
- package/dist/packem_chunks/handler34.js +1 -1
- package/dist/packem_chunks/handler45.js +1 -1
- package/dist/packem_chunks/handler46.js +1 -1
- package/dist/packem_chunks/handler48.js +3 -3
- package/dist/packem_chunks/handler5.js +1 -1
- package/dist/packem_chunks/handler50.js +6 -6
- package/dist/packem_chunks/handler51.js +1 -1
- package/dist/packem_chunks/handler54.js +1 -1
- package/dist/packem_chunks/handler55.js +1 -1
- package/dist/packem_chunks/handler57.js +1 -1
- package/dist/packem_chunks/handler58.js +2 -2
- package/dist/packem_chunks/handler59.js +2 -2
- package/dist/packem_chunks/handler6.js +7 -7
- package/dist/packem_chunks/handler62.js +2 -2
- package/dist/packem_chunks/handler64.js +3 -3
- package/dist/packem_chunks/handler66.js +2 -2
- package/dist/packem_chunks/handler68.js +1 -1
- package/dist/packem_chunks/handler69.js +2 -2
- package/dist/packem_chunks/handler7.js +1 -1
- package/dist/packem_chunks/handler70.js +1 -1
- package/dist/packem_chunks/handler71.js +15 -15
- package/dist/packem_chunks/handler72.js +2 -2
- package/dist/packem_chunks/handler74.js +1 -1
- package/dist/packem_chunks/handler75.js +10 -10
- package/dist/packem_chunks/handler76.js +1 -1
- package/dist/packem_chunks/handler77.js +4 -4
- package/dist/packem_chunks/handler78.js +1 -1
- package/dist/packem_chunks/handler9.js +1 -1
- package/dist/packem_chunks/heal-accept.js +1 -1
- package/dist/packem_chunks/heal.js +1 -1
- package/dist/packem_chunks/help-command.js +7 -7
- package/dist/packem_chunks/index5.js +1 -1
- package/dist/packem_chunks/keys-refresh.js +1 -1
- package/dist/packem_chunks/list.js +1 -1
- package/dist/packem_chunks/loader.js +1 -1
- package/dist/packem_chunks/sync2.js +1 -1
- package/dist/packem_chunks/tripwire.js +1 -1
- package/dist/packem_chunks/verify-lockfile.js +1 -1
- package/dist/packem_shared/{affected-selection-BMoQWuHl.js → affected-selection-DIgAsQTu.js} +1 -1
- package/dist/packem_shared/{ai-fix-CKN1JGRh.js → ai-fix-CyUx_ZAB.js} +1 -1
- package/dist/packem_shared/{bin-CN4heKmb.js → bin-CVfNImCA.js} +1 -1
- package/dist/packem_shared/{failure-log-D92tM0ie.js → failure-log-DE_MJCzB.js} +1 -1
- package/dist/packem_shared/{formatBytes-BHAzNIrn-DFIppnY0.js → formatBytes-BHAzNIrn-Bkk_uRS-.js} +1 -1
- package/dist/packem_shared/index-5GrALmsb.js +1 -0
- package/dist/packem_shared/{index-DXPSWMbG.js → index-CIIKPX4H.js} +1 -1
- package/dist/packem_shared/{lifecycle-CfTZQHOG.js → lifecycle-DW8KRF5d.js} +1 -1
- package/dist/packem_shared/{package-version-CJxZ_B7G.js → package-version-CIhwFJn3.js} +1 -1
- package/dist/packem_shared/{packument-C55kVxcQ.js → packument-CHdDsn0O.js} +1 -1
- package/dist/packem_shared/{pm-runner-de-jCq8q.js → pm-runner-d93_73O6.js} +1 -1
- package/dist/packem_shared/{project-name-filter-DsrVo0MY.js → project-name-filter-sYH4Zvsm.js} +1 -1
- package/dist/packem_shared/{provenance-CvfQEJPQ.js → provenance-w-NIPtim.js} +1 -1
- package/dist/packem_shared/{registry-keys-DmBrAlhg.js → registry-keys-_IKDLSbu.js} +1 -1
- package/dist/packem_shared/{resolve-explicit-DYaHAVDg.js → resolve-explicit-ZZEPWdpP.js} +1 -1
- package/dist/packem_shared/{s1ngularity-C8sva2SO.js → s1ngularity-R-zLjQjp.js} +1 -1
- package/dist/packem_shared/{signatures-oZ_2IneN.js → signatures-ijwqxAtF.js} +1 -1
- package/dist/packem_shared/{vis-update-app-zqSa2clT.js → vis-update-app-DNeU8RBQ.js} +1 -1
- package/dist/packem_shared/vis-user-error-CgyYA29v.js +30 -0
- package/index.d.ts +204 -204
- package/index.js +52 -52
- package/package.json +11 -11
- package/dist/packem_shared/index-DjTWo3sH.js +0 -1
- package/dist/packem_shared/vis-user-error-Dkc97rGY.js +0 -30
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import{createRequire as
|
|
2
|
-
`);let s;for(const o of n){if(o.startsWith("#!")||o.startsWith("# Generated by")||o.startsWith("# NOTE:")||o==="set -e"||o==="")continue;const i=
|
|
3
|
-
${o}`:o:s={command:o,id:"(custom)"}}return s&&t.push(s),t},
|
|
4
|
-
`).length,stage:i})}return s.sort((i,r)=>i.stage.localeCompare(r.stage)),{hooksDirectory:t,stages:s}},
|
|
5
|
-
`).find(r=>r.trim()!=="");if(i){const r=i.length>120?`${i.slice(0,117)}...`:i;t.push(` ${r}`)}}return t},
|
|
1
|
+
import{createRequire as ae}from"node:module";import{e as h,z as O}from"../packem_shared/index-DHD8wb6Z.js";import{V as J}from"../packem_shared/vis-user-error-CgyYA29v.js";import{a9 as z,aa as he,ab as X,ac as R,ad as me,ae as pe,af as ke,ag as $e,ah as j,ai as we,aj as Y,ak as Q,al as Z,am as ee,an as te}from"./cli-main.js";import{y as b}from"../packem_shared/isAccessibleSync-DYKTrrvc-CSnBISfV.js";import{m as Ee}from"./ts-loader.js";import{L as ye}from"../packem_shared/index-BisalDCf.js";import{F as ve}from"./catalog.js";import{allKnownTags as Se,tagsFromPaths as Re,NATIVE_BINDING_VERSION as G}from"#native";import{h as ne}from"../packem_shared/writeFileSync-DJoHk3Ks-CgQ-VNNT.js";let ce;const fe=e=>(ce??=ae(import.meta.url))(e),x=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,F=e=>{if(typeof x<"u"&&x.versions&&x.versions.node){const[t,n]=x.versions.node.split(".").map(Number);if(t>22||t===22&&n>=3||t===20&&n>=16)return x.getBuiltinModule(e)}return fe(e)},{readdirSync:q,statSync:M,readFileSync:I,existsSync:T,writeFileSync:y,unlinkSync:le,rmSync:ue,chmodSync:de}=F("node:fs"),{cwd:A}=x,{createInterface:ge}=F("node:readline"),{spawnSync:E}=F("node:child_process"),{basename:be}=F("node:path"),_e=/^# ([^:\s]\S*)(?::\s+(.+))?$/,xe=e=>{const t=[],n=e.split(`
|
|
2
|
+
`);let s;for(const o of n){if(o.startsWith("#!")||o.startsWith("# Generated by")||o.startsWith("# NOTE:")||o==="set -e"||o==="")continue;const i=_e.exec(o);if(i){s&&t.push(s),s={command:"",id:i[1]??"",...i[2]?{name:i[2]}:{}};continue}s?s.command=s.command.length>0?`${s.command}
|
|
3
|
+
${o}`:o:s={command:o,id:"(custom)"}}return s&&t.push(s),t},Ae=(e,t)=>{const n=h(e,t),s=[],o=new Set(z);if(b(n))for(const i of q(n)){if(i.startsWith(".")||i==="_"||!o.has(i))continue;const r=h(n,i);if(!M(r).isFile())continue;const c=O(r),a=xe(c);s.push({blocks:a,rawLineCount:c.split(`
|
|
4
|
+
`).length,stage:i})}return s.sort((i,r)=>i.stage.localeCompare(r.stage)),{hooksDirectory:t,stages:s}},Ie=e=>{const t=[];if(e.stages.length===0)return t.push(`No hooks installed in ${e.hooksDirectory}/.`),t;t.push(`Hooks in ${e.hooksDirectory}/:`);for(const n of e.stages)if(t.push("",`${n.stage} (${n.rawLineCount} lines)`),n.blocks.length===0)t.push(" (empty)");else for(const s of n.blocks){const o=s.name?`${s.id} — ${s.name}`:s.id;t.push(` - ${o}`);const i=s.command.split(`
|
|
5
|
+
`).find(r=>r.trim()!=="");if(i){const r=i.length>120?`${i.slice(0,117)}...`:i;t.push(` ${r}`)}}return t},Oe=(e,t)=>{const n=Ae(A(),e);for(const s of Ie(n))t.info(s)},W=6;if(G!==W)throw new Error(`vis native binding ABI mismatch: expected ${W}, got ${G}. Rebuild via \`pnpm --filter @visulima/vis run build:native\` or reinstall the platform binding package.`);const se={".releaserc":["release-config","vis-config"],".releaserc.json":["release-config","vis-config"],"aube-lock.yaml":["aube-lock","lockfile"],"aube-workspace.yaml":["aube-workspace","vis-config"],"nx.json":["nx-workspace","vis-config"],"packem.config.js":["packem-config","vis-config"],"packem.config.mjs":["packem-config","vis-config"],"packem.config.ts":["packem-config","vis-config"],"pnpm-workspace.yaml":["pnpm-workspace","vis-config"],"project.json":["nx-project","vis-config"],"turbo.json":["turbo-config","vis-config"],"vis.config.js":["vis-config"],"vis.config.ts":["vis-config"]},oe=[[".releaserc.json",["release-config","vis-config"]]],Te=e=>{const t=new Set,n=be(e),s=se[n];if(s)for(const i of s)t.add(i);const o=n.toLowerCase();for(const[i,r]of oe)if(o.endsWith(i))for(const c of r)t.add(c);return t},Fe=new Set([...Object.values(se).flat(),...oe.flatMap(([,e])=>e)]);let N;const Ce=()=>(N||(N=new Set(Se())),N),Ne=e=>{const t=Re([...e]),n=new Map;for(const[s,o]of e.entries()){const i=new Set(t[s]),r=Te(o),c=new Set([...i,...r]);n.set(o,{all:c,prek:i,vis:r})}return n},Pe=e=>Ce().has(e)||Fe.has(e),Me=(e,t)=>{const{all:n}=e;if(t.types&&t.types.length>0){for(const s of t.types)if(!n.has(s))return!1}if(t.typesOr&&t.typesOr.length>0){let s=!1;for(const o of t.typesOr)if(n.has(o)){s=!0;break}if(!s)return!1}if(t.excludeTypes&&t.excludeTypes.length>0){for(const s of t.excludeTypes)if(n.has(s))return!1}return!0},He=e=>{let t=0;const{length:n}=e,s=()=>{for(;t<n&&/\s/.test(e[t]);)t+=1},o=()=>{if(e[t]!=='"')throw new Error(`expected string at ${t}`);t+=1;const a=t;for(;t<n&&e[t]!=='"';)t+=e[t]==="\\"?2:1;const f=e.slice(a,t);return t+=1,JSON.parse(`"${f}"`)},i=()=>{switch(s(),e[t]){case'"':{o();break}case"[":{r();break}case"{":{c();break}default:for(;t<n&&!",}]".includes(e[t])&&!/\s/.test(e[t]);)t+=1}},r=()=>{if(t+=1,s(),e[t]==="]"){t+=1;return}for(;t<n;)if(i(),s(),e[t]===",")t+=1,s();else if(e[t]==="]"){t+=1;return}},c=()=>{t+=1,s();const a=new Set;if(e[t]==="}"){t+=1;return}for(;t<n;){s();const f=o();if(a.has(f))throw new Error(`Duplicate key: ${f}`);if(a.add(f),s(),e[t]!==":")throw new Error(`expected colon at ${t}`);if(t+=1,i(),s(),e[t]===",")t+=1,s();else if(e[t]==="}"){t+=1;return}}};s(),i()},je=(e,t,n)=>{let s=0;for(const o of e){const i=I(h(n.root,o),"utf8");try{JSON.parse(i),He(i)}catch(r){const c=r instanceof Error?r.message:String(r);n.logger.info(`${o}: Failed to json decode (${c})`),s=1}}return s},Be=e=>{const t=E("git",["rev-parse","--git-dir"],{cwd:e,encoding:"utf8"});if(t.status!==0)return!1;const n=t.stdout.trim(),s=n.startsWith("/")?n:h(e,n);return T(h(s,"MERGE_MSG"))?T(h(s,"MERGE_HEAD"))||T(h(s,"rebase-apply"))||T(h(s,"rebase-merge")):!1},Le=["<<<<<<< ","======= ",`=======\r
|
|
6
6
|
`,`=======
|
|
7
|
-
`,">>>>>>> "],
|
|
8
|
-
`);for(let
|
|
9
|
-
`:"");for(const g of
|
|
10
|
-
${
|
|
7
|
+
`,">>>>>>> "],Ge=(e,t,n)=>{if(!t.includes("--assume-in-merge")&&!Be(n.root))return 0;let o=0;for(const i of e){const c=I(h(n.root,i),"utf8").split(`
|
|
8
|
+
`);for(let a=0;a<c.length;a+=1){const f=c[a]+(a<c.length-1?`
|
|
9
|
+
`:"");for(const g of Le)f.startsWith(g)&&(n.logger.info(`${i}:${a+1}: Merge conflict string ${JSON.stringify(g.trim())} found`),o=1)}}return o},We=(e,t,n)=>{let s=0;for(const o of e){const i=h(n.root,o),r=I(i);if(r.length===0)continue;let c=r.length;const a=r[c-1];if(a!==10&&a!==13){y(i,Buffer.concat([r,Buffer.from([10])])),n.logger.info(`Fixing ${o}`),s=1;continue}for(;c>0&&(r[c-1]===10||r[c-1]===13);)c-=1;if(c===0){y(i,Buffer.alloc(0)),n.logger.info(`Fixing ${o}`),s=1;continue}const f=r.subarray(c);let g;f[0]===13&&f[1]===10?g=Buffer.from([13,10]):f[0]===13?g=Buffer.from([13]):g=Buffer.from([10]),!f.equals(g)&&(y(i,Buffer.concat([r.subarray(0,c),g])),n.logger.info(`Fixing ${o}`),s=1)}return s},De={cr:Buffer.from([13]),crlf:Buffer.from([13,10]),lf:Buffer.from([10])},Ke=new Set(["auto","cr","crlf","lf","no"]),Ue=(e,t,n)=>{let s="auto";for(let i=0;i<t.length;i+=1){const r=t[i];if(r==="-f"||r==="--fix"){i+=1;const c=t[i];if(c===void 0)return n.logger.error(`mixed-line-ending: ${r} requires a value (auto|no|lf|crlf|cr)`),2;s=c}else r.startsWith("--fix=")&&(s=r.slice(6))}if(!Ke.has(s))return n.logger.error(`mixed-line-ending: invalid --fix value ${s}`),2;let o=0;for(const i of e){const r=h(n.root,i),c=I(r),a=[],f=l=>{const k=a.find(v=>v.kind===l);k?k.count+=1:a.push({count:1,kind:l})},g=[];let u=0;for(let l=0;l<c.length;l+=1){const k=c[l];k===13&&c[l+1]===10?(g.push({content:c.subarray(u,l),ending:"crlf"}),f("crlf"),l+=1,u=l+1):k===13?(g.push({content:c.subarray(u,l),ending:"cr"}),f("cr"),u=l+1):k===10&&(g.push({content:c.subarray(u,l),ending:"lf"}),f("lf"),u=l+1)}u<c.length&&g.push({content:c.subarray(u),ending:null});const d=a.length>1;if(s==="no"){d&&(n.logger.info(`${i}: mixed line endings`),o=1);continue}let m;if(s==="auto"){if(!d)continue;let l;for(const k of a)(!l||k.count>l.count)&&(l=k);m=l?.kind}else if(m=s,!a.some(k=>k.kind!==m&&k.count>0))continue;const w=De[m],p=[];for(const l of g)p.push(l.content),l.ending!==null&&p.push(w);y(r,Buffer.concat(p)),n.logger.info(`${i}: fixed mixed line endings`),o=1}return o},D=new Set([9,11,12,13,32]),Ve=/\.(?:md|markdown|mdown|mdx)$/i,qe=(e,t,n)=>{let s=0;for(const o of e){const i=Ve.test(o),r=h(n.root,o),c=I(r),a=[];let f=0;for(;f<=c.length;){let u=f;for(;u<c.length&&c[u]!==10;)u+=1;const d=u<c.length&&c[u]===10;let m=u,w=!1;d&&u>f&&c[u-1]===13&&(w=!0,m=u-1);const p=c.subarray(f,m);let l=p.length;for(;l>0&&D.has(p[l-1]);)l-=1;const k=p.some(v=>!D.has(v));if(i&&p.length>=2&&p[p.length-1]===32&&p[p.length-2]===32&&k&&(l=Math.min(l+2,p.length)),a.push(p.subarray(0,l)),w&&a.push(Buffer.from([13])),d&&a.push(Buffer.from([10])),!d)break;f=u+1}const g=Buffer.concat(a);g.equals(c)||(y(r,g),n.logger.info(`Fixing ${o}`),s=1)}return s},ie={"check-json":je,"check-merge-conflict":Ge,"end-of-file-fixer":We,"mixed-line-ending":Ue,"trailing-whitespace":qe},Je=Object.keys(ie).sort(),ze=e=>ie[e],Xe=new Map([["pre-commit/pre-commit-hooks#check-json","check-json"],["pre-commit/pre-commit-hooks#check-merge-conflict","check-merge-conflict"],["pre-commit/pre-commit-hooks#end-of-file-fixer","end-of-file-fixer"],["pre-commit/pre-commit-hooks#mixed-line-ending","mixed-line-ending"],["pre-commit/pre-commit-hooks#trailing-whitespace","trailing-whitespace"]]),Ye=/[<>=!~]=/,Qe=/github\.com[/:]([^/\s]+\/[^/\s.]+)/i,Ze="# Generated by `vis hook migrate` from prek",et=e=>`#!/usr/bin/env sh
|
|
10
|
+
${Ze}
|
|
11
11
|
exec vis hook run ${e} "$@"
|
|
12
|
-
`,B=e=>{for(const t of
|
|
13
|
-
`,"utf8"),{added:o,skipped:i}},
|
|
14
|
-
`),"utf8")},ut=(e,t)=>{y("prek",["--version"],{cwd:e,encoding:"utf8"}).status===0?y("prek",["uninstall"],{cwd:e,encoding:"utf8"}).status===0?t.info("Detached prek via `prek uninstall`."):t.info("`prek uninstall` did not exit cleanly — continuing. You may need to run it manually."):t.info("prek binary not found on PATH — skipping `prek uninstall`. Run it manually if prek is installed elsewhere.")},oe=(e,t,n,s={})=>{const o=B(e),i=s.dryRun===!0;if(!o)return{isError:!0,message:"No prek configuration found (.pre-commit-config.yaml, .pre-commit-config.yml, or prek.toml)"};n.info(`Found prek config at ${o}`);const r=d(e,o),a=O(r),c=ct(r);if(!c)return{isError:!0,message:`Could not parse ${o}`};const{additionalDeps:f,config:g,droppedFilters:u,manualSteps:k,skippedHooks:$}=rt(c),b=Object.keys(g.stages);if(b.length===0&&$.length===0)return{isError:!0,message:`${o} has no hooks to migrate`};if(!i){const p=y("git",["config","--local","core.hooksPath"],{cwd:e,encoding:"utf8"});if(p.status===0){const C=p.stdout?.toString().trim();C&&(C.includes(".prek")||C.includes("prek-hooks"))&&y("git",["config","--local","--unset","core.hooksPath"],{cwd:e})}const _=z(t);if(_.isError)return _;_.message&&n.info(_.message)}const m=d(e,t);i||ee(m),i?n.info(` (would write) ${t}/${S}`):(ge(e,t,g),lt(e,t),n.info(` Wrote ${t}/${S}`));let l=0;for(const p of b){const _=Qe(p);i?n.info(` (would write) ${t}/${p}`):(w(d(m,p),_,{mode:493}),n.info(` Wrote ${t}/${p}`)),l+=1}const{added:h,skipped:E}=i?{added:f.map(p=>p.name),skipped:[]}:ft(e,f,s.useEditorconfig);if(h.length>0){const p=i?"would add":"Added";n.info(`${p} ${h.length} package${h.length===1?"":"s"} to devDependencies: ${h.join(", ")}`),i||n.info("Run your package manager's install (e.g. `pnpm install`) to pick up the new devDependencies.")}E.length>0&&n.info(`Skipped ${E.length} already-declared package${E.length===1?"":"s"}: ${E.join(", ")}`),i||ut(e,n);const G=`${r}.bak`;if(i?n.info(` (would remove) ${o} and back it up to ${o}.bak`):(v(G)||w(G,a,"utf8"),ce(r),n.info(`Removed ${o} (backup at ${o}.bak)`)),$.length>0){n.warn(`Skipped ${$.length} hook${$.length===1?"":"s"} that cannot run without prek:`);for(const p of $)n.warn(` - ${p.repo}::${p.hookId} — ${p.reason}`)}if(u.length>0){n.warn("Partial filter translations:");for(const p of u)n.warn(` - ${p}`)}if(k.length>0){n.warn("Manual follow-up required:");for(const p of k)n.warn(` - ${p}`)}return{isError:!1,message:`${i?"would migrate":"Migration complete:"} ${l} stage script${l===1?"":"s"} ${i?"into":"written to"} ${t}/`}},dt=e=>{const t=[];let n=0;for(let s=0;s<e.length;s+=1)e[s]===0&&(s>n&&t.push(e.subarray(n,s).toString("utf8")),n=s+1);return n<e.length&&t.push(e.subarray(n).toString("utf8")),t},P=(e,t,n)=>{const s=y("git",[...e],{cwd:n,encoding:"buffer"});if(s.status!==0){const o=s.stderr?s.stderr.toString():"";throw new Error(`git ${t} failed${o?`: ${o.trim()}`:""}`)}return s.stdout.length===0?[]:dt(s.stdout)},gt=(e,t)=>{switch(e.kind){case"all":return P(["ls-files","-z"],"ls-files",t);case"range":return P(["diff","--name-only","--diff-filter=ACM","-z",e.fromRef,e.toRef],"diff --from-ref/--to-ref",t);case"staged":return P(["diff","--cached","--name-only","--diff-filter=ACM","-z"],"diff --cached",t);default:{const n=e;throw new Error(`unknown discover mode: ${JSON.stringify(n)}`)}}},D=(e,t)=>{try{return new RegExp(e)}catch(n){const s=n instanceof Error?n.message:String(n);throw new Error(`invalid ${t} regex ${JSON.stringify(e)}: ${s}`,{cause:n})}},ht=e=>e.types&&e.types.length>0||e.typesOr&&e.typesOr.length>0||e.excludeTypes&&e.excludeTypes.length>0||!1,mt=(e,t)=>{let n=e;if(t.files){const i=D(t.files,"files");n=n.filter(r=>i.test(r))}if(t.exclude){const i=D(t.exclude,"exclude");n=n.filter(r=>!i.test(r))}if(!ht(t))return[...n];const s=Fe(n),o={excludeTypes:t.excludeTypes,types:t.types,typesOr:t.typesOr};return n.filter(i=>{const r=s.get(i);return r?Ne(r,o):!1})},pt=32*1024,kt=(e,t)=>{const n=[],s=Math.max(1024,pt-t);let o=[],i=0;for(const r of e){const a=Buffer.byteLength(r,"utf8")+8;i+a>s&&o.length>0&&(n.push(o),o=[],i=0),o.push(r),i+=a}return o.length>0&&n.push(o),n},$t=e=>({error:t=>{e.error(t)},info:t=>{e.info(t)}}),U=(e,t,n)=>n?n.message:t?`terminated by signal ${t}`:`exited with status ${String(e)}`,wt=(e,t,n,s,o)=>{const i=s?o.extraArgs:[];if(!n||t.length===0){const c=y("sh",["-c",e,"sh",...i],{cwd:o.root,stdio:"inherit"});return c.status===null?(o.logger.error(`hook command failed: ${U(c.status,c.signal,c.error)}`),1):c.status}const r=Buffer.byteLength(e,"utf8")+Buffer.byteLength("sh","utf8")+Buffer.byteLength("-c","utf8")+i.reduce((c,f)=>c+Buffer.byteLength(f,"utf8")+8,0)+64;let a=0;for(const c of kt(t,r)){const f=y("sh",["-c",`${e} "$@"`,"sh",...i,...c],{cwd:o.root,stdio:"inherit"});f.status===null?(o.logger.error(`hook command failed: ${U(f.status,f.signal,f.error)}`),a|=1):a|=f.status}return a},yt=(e,t,n)=>{if(e.fail!==void 0)return n.logger.info(e.fail),1;const s=j.has(n.stage);let o;try{o=mt(t,e)}catch(c){const f=c instanceof Error?c.message:String(c);return n.logger.error(`hook "${e.id}": ${f}`),2}if(o.length===0&&e.alwaysRun!==!0&&!s)return 0;const i=e.passFilenames!==!1;if(e.verbose){const c=e.name??e.id;n.logger.info(`+ ${c}`)}if(e.builtin){const c=qe(e.builtin);if(!c)return n.logger.error(`unknown builtin "${e.builtin}" referenced by hook "${e.id}"`),2;const f={logger:$t(n.logger),root:n.root};try{return c(o,e.args??[],f)}catch(g){const u=g instanceof Error?g.message:String(g);return n.logger.error(`builtin "${e.builtin}" crashed: ${u}`),1}}if(e.entry===void 0)return n.logger.error(`hook "${e.id}" has no \`entry\`, \`builtin\`, or \`fail\` to run`),2;const r=(e.args??[]).map(c=>`'${c.replaceAll("'",String.raw`'\''`)}'`).join(" "),a=r?`${e.entry} ${r}`:e.entry;return wt(a,o,i,s,n)},Et=(e,t,n,s)=>{const o=e.stages[t];if(!o||o.length===0)return 0;let i=0;for(const r of o){const a=yt(r,n,s);if(a!==0&&(i|=a,e.failFast))return i}return i},vt="pre-commit",bt=e=>{if(e.lastCommit&&(e.fromRef||e.toRef))throw new Error("--last-commit cannot be combined with --from-ref or --to-ref");const t=e.lastCommit?"HEAD~1":e.fromRef,n=e.lastCommit?"HEAD":e.toRef;if(t&&!n||n&&!t)throw new Error("--from-ref and --to-ref must be specified together");return t&&n?{fromRef:t,kind:"range",toRef:n}:e.allFiles?{kind:"all"}:{kind:"staged"}},St=(e,t,n,s)=>{const o=n.stage??vt,i=X(e,t);if(!i)throw new Error(`No hook config found at ${t}/config.json. Install or migrate hooks first.`);const r=i.stages[o];if(!r||r.length===0)return s.info(`No hooks configured for stage "${o}".`),0;const c=j.has(o)?void 0:bt(n),f=c?.kind==="all"?" (--all-files)":c?.kind==="range"?` (${c.fromRef}..${c.toRef})`:"";s.info(`Running ${o}${f}`);const g=c?gt(c,e):[],u={extraArgs:n.extraArgs??[],logger:s,root:e,stage:o};return Et(i,o,g,u)},Rt=(e,t,n)=>{const s=St(A(),e,t,n);if(s!==0)throw new Error(`Hook stage exited with code ${s}`)},_t=(e=Y)=>{if(y("git",["config","--local","core.hooksPath"]).status!==0)return{isError:!1,message:"No custom hooks path configured"};const{status:n,stderr:s}=y("git",["config","--local","--unset","core.hooksPath"]);if(n===null)return{isError:!0,message:"git command not found"};if(n&&n!==5)return{isError:!0,message:String(s)};const o=d(e,"_");return v(o)&&fe(o,{force:!0,recursive:!0}),{isError:!1,message:""}},xt=new Set(J),At=e=>{const t=y("sh",["-n",e],{encoding:"utf8"});if(t.status===null)return`failed to run "sh -n" (${t.error?.message??"unknown error"})`;if(t.status!==0)return t.stderr.trim()||`sh -n exited with ${t.status}`},It=(e,t)=>{const n=[],s=d(e,t),o=y("git",["config","--local","core.hooksPath"],{cwd:e,encoding:"utf8"});if(o.status===0){const r=o.stdout.trim(),a=`${t}/_`;r&&r!==a&&n.push({kind:"warning",message:`core.hooksPath is "${r}" — expected "${a}". Re-run \`vis hook install\` to fix.`})}else n.push({kind:"warning",message:"core.hooksPath is not set — run `vis hook install`."});if(v(d(s,"_"))||n.push({kind:"error",message:`Dispatcher directory ${t}/_ is missing. Run \`vis hook install\`.`}),!v(s))return n.push({kind:"error",message:`Hooks directory ${t}/ is missing.`}),{issues:n,ok:!1};let i=!1;for(const r of q(s)){if(r.startsWith(".")||r==="_"||r===S||r==="README.md")continue;if(!xt.has(r)){n.push({kind:"warning",message:`Unknown hook "${r}" — not a standard git hook.`,path:d(t,r)});continue}const a=d(s,r);if(!M(a).isFile())continue;i=!0;const c=M(a).mode&511;(c&64)===0&&n.push({kind:"warning",message:`Script is not owner-executable (mode ${c.toString(8)}).`,path:d(t,r)});const f=At(a);f&&n.push({kind:"error",message:`Shell syntax error: ${f}`,path:d(t,r)})}if(i){const r=d(s,S);if(v(r))try{X(e,t)}catch(a){n.push({kind:"error",message:`${S} is malformed: ${a instanceof Error?a.message:String(a)}`,path:d(t,S)})}else n.push({kind:"error",message:`Stage scripts are present but ${t}/${S} is missing. Re-run \`vis hook migrate\`.`})}return{issues:n,ok:!n.some(r=>r.kind==="error")}},Ot=(e,t)=>{if(e.issues.length===0)return[`Hook directory ${t}/ looks good.`];const n=[];for(const s of e.issues){const o=s.kind==="error"?"ERROR":"WARN ",i=s.path?` (${s.path})`:"";n.push(`${o} ${s.message}${i}`)}return n.push("",e.ok?"No errors — warnings only.":`${e.issues.filter(s=>s.kind==="error").length} error(s).`),n},Tt=(e,t)=>{const n=It(A(),e),s=Ot(n,e);for(const o of s)o.startsWith("ERROR")||o.startsWith("WARN")?t.warn(o):t.info(o);if(!n.ok)throw new Error("Hook validation failed")},R=e=>e.hooksDir??Y,V=e=>new Promise(t=>{const n=ue({input:process.stdin,output:process.stdout});n.question(`${e} (y/N) `,s=>{n.close();const o=s.trim().toLowerCase();t(o==="y"||o==="yes")})}),Ft=async(e,t,n)=>{const s=A(),o=Q(s),i=B(s);if(o&&i)throw new Error(`Found both husky (${o}/) and prek (${i}). Remove or migrate one before running \`vis hook install\`.`);if(o){if(t.info(`Existing husky installation found at ${o}/`),await V("Would you like to migrate your husky hooks to vis?")){const c=Z(s,e,t,{useEditorconfig:n});if(c.isError)throw new Error(c.message);c.message&&t.info(c.message);return}t.info("Aborting install. Remove husky first or run 'vis hook migrate' to migrate.");return}if(i){if(t.info(`Existing prek configuration found at ${i}`),await V("Would you like to migrate your prek hooks to vis?")){const c=oe(s,e,t,{useEditorconfig:n});if(c.isError)throw new Error(c.message);c.message&&t.info(c.message);return}t.info("Aborting install. Remove the prek config first or run 'vis hook migrate' to migrate.");return}t.info(`Installing git hooks in ${e}/...`);const r=z(e);if(r.message){if(r.isError)throw new Error(r.message);t.info(r.message);return}v(d(s,e,"pre-commit"))||w(d(s,e,"pre-commit"),`#!/usr/bin/env sh
|
|
15
|
-
`,{mode:493}),t.info("Git hooks installed successfully.")},
|
|
12
|
+
`,B=e=>{for(const t of he)if(b(h(e,t)))return t},tt=e=>we[e]??e,nt=e=>Qe.exec(e)?.[1]??e,st=e=>{if(Ye.test(e))return;if(e.startsWith("@")){const s=e.indexOf("@",1);if(s===-1)return{name:e,version:"latest"};const o=e.slice(s+1).trim();return{name:e.slice(0,s),version:o||"latest"}}const t=e.indexOf("@");if(t===-1)return{name:e,version:"latest"};const n=e.slice(t+1).trim();return{name:e.slice(0,t),version:n||"latest"}},ot=e=>{const t=[];for(const n of[e.types,e.types_or,e.exclude_types])for(const s of n??[])Pe(s)||t.push(s);return t},it=(e,t)=>(e.stages&&e.stages.length>0?e.stages:t??["pre-commit"]).map(s=>tt(s)),rt=(e,t,n)=>{const s=e.id??"<unknown>",o=j.has(t),i={id:s};return e.name&&(i.name=e.name),e.language==="fail"?(i.fail=e.entry??e.name??s,i):(n?i.builtin=n:e.entry&&(i.entry=e.entry),Array.isArray(e.args)&&e.args.length>0&&(i.args=[...e.args]),o||(e.files&&(i.files=e.files),e.exclude&&(i.exclude=e.exclude),e.types&&e.types.length>0&&(i.types=[...e.types]),e.types_or&&e.types_or.length>0&&(i.typesOr=[...e.types_or]),e.exclude_types&&e.exclude_types.length>0&&(i.excludeTypes=[...e.exclude_types])),(e.pass_filenames===!1||o)&&(i.passFilenames=!1),(e.always_run||o)&&(i.alwaysRun=!0),e.verbose&&(i.verbose=!0),i)},at=(e,t,n,s)=>{if(Array.isArray(e.additional_dependencies))for(const o of e.additional_dependencies){const i=st(o);if(!i){s.push(`"${t}": additional_dependency "${o}" uses a pip-style pin and cannot be added to package.json — install manually.`);continue}n.push({hookId:t,name:i.name,raw:o,version:i.version})}},ct=e=>{const t={},n=[],s=[],o=[],i=[];(e.files||e.exclude)&&s.push("top-level files/exclude filter dropped — apply it per hook if needed");for(const c of e.repos??[]){const a=c.repo??"<unknown>",f=a==="local",g=f?void 0:nt(a);for(const u of c.hooks??[]){const d=u.id??"<unknown>";let m;if(f){const l=u.language??"system";if(!pe.has(l)){n.push({hookId:d,reason:`language "${l}" needs an isolated toolchain — run via prek or reimplement as a system command`,repo:a});continue}if(l!=="fail"&&!u.entry){n.push({hookId:d,reason:"missing `entry`",repo:a});continue}}else if(g&&(m=Xe.get(`${g}#${d}`)),!m){n.push({hookId:d,reason:`remote repo "${a}"@${c.rev??"?"} has no bundled equivalent — run via prek or replace with a system command`,repo:a});continue}at(u,d,i,o);const w=ot(u);w.length>0&&s.push(`hook "${d}": unsupported types ${w.join(", ")} — those entries are ignored by the dispatcher`);const p=it(u,e.default_stages);for(const l of p){if(l==="manual")continue;if(!ke.has(l)){n.push({hookId:d,reason:`unsupported stage "${l}"`,repo:a});continue}const k=rt(u,l,m),v=t[l];v?v.push(k):t[l]=[k]}}}const r={stages:t,version:$e};return e.fail_fast&&(r.failFast=!0),{additionalDeps:i,config:r,droppedFilters:s,manualSteps:o,skippedHooks:n}},ft=e=>{const t=ye(e);if(t&&typeof t=="object")return t},lt=e=>{if(e.endsWith(".toml")){const n=Ee(e);return n&&typeof n=="object"?n:void 0}const t=O(e);return ft(t)},ut=(e,t,n)=>{const s=h(e,"package.json"),o=[],i=[];if(!b(s)||t.length===0)return{added:o,skipped:i};const r=O(s),c=JSON.parse(r),a=c.devDependencies??{},f=c.dependencies??{};for(const u of t){if(u.name in a||u.name in f){i.push(u.name);continue}a[u.name]=u.version,o.push(u.name)}if(o.length===0)return{added:o,skipped:i};c.devDependencies=a;const g=ve(s,r,{defaultIndent:" ",useEditorconfig:n});return y(s,`${JSON.stringify(c,void 0,g)}
|
|
13
|
+
`,"utf8"),{added:o,skipped:i}},dt=(e,t)=>{const n=h(e,t);ne(n),y(h(n,"README.md"),["# Vis hook config","","`config.json` is the single source of truth for what each stage","script runs. Auto-generated by `vis hook migrate`. Edit by hand","or re-run the migrator after updating your prek config.","",`Bundled builtins: ${Je.join(", ")}`,""].join(`
|
|
14
|
+
`),"utf8")},gt=(e,t)=>{E("prek",["--version"],{cwd:e,encoding:"utf8"}).status===0?E("prek",["uninstall"],{cwd:e,encoding:"utf8"}).status===0?t.info("Detached prek via `prek uninstall`."):t.info("`prek uninstall` did not exit cleanly — continuing. You may need to run it manually."):t.info("prek binary not found on PATH — skipping `prek uninstall`. Run it manually if prek is installed elsewhere.")},re=(e,t,n,s={})=>{const o=B(e),i=s.dryRun===!0;if(!o)return{isError:!0,message:"No prek configuration found (.pre-commit-config.yaml, .pre-commit-config.yml, or prek.toml)"};n.info(`Found prek config at ${o}`);const r=h(e,o),c=O(r),a=lt(r);if(!a)return{isError:!0,message:`Could not parse ${o}`};const{additionalDeps:f,config:g,droppedFilters:u,manualSteps:d,skippedHooks:m}=ct(a),w=Object.keys(g.stages);if(w.length===0&&m.length===0)return{isError:!0,message:`${o} has no hooks to migrate`};if(!i){const $=E("git",["config","--local","core.hooksPath"],{cwd:e,encoding:"utf8"});if($.status===0){const C=$.stdout?.toString().trim();C&&(C.includes(".prek")||C.includes("prek-hooks"))&&E("git",["config","--local","--unset","core.hooksPath"],{cwd:e})}const S=X(t);if(S.isError)return S;S.message&&(S.isWarning?n.warn(S.message):n.info(S.message))}const p=h(e,t);i||ne(p),i?n.info(` (would write) ${t}/${R}`):(me(e,t,g),dt(e,t),n.info(` Wrote ${t}/${R}`));let l=0;for(const $ of w){const S=et($);i?n.info(` (would write) ${t}/${$}`):(y(h(p,$),S,{mode:493}),n.info(` Wrote ${t}/${$}`)),l+=1}const{added:k,skipped:v}=i?{added:f.map($=>$.name),skipped:[]}:ut(e,f,s.useEditorconfig);if(k.length>0){const $=i?"would add":"Added";n.info(`${$} ${k.length} package${k.length===1?"":"s"} to devDependencies: ${k.join(", ")}`),i||n.info("Run your package manager's install (e.g. `pnpm install`) to pick up the new devDependencies.")}v.length>0&&n.info(`Skipped ${v.length} already-declared package${v.length===1?"":"s"}: ${v.join(", ")}`),i||gt(e,n);const L=`${r}.bak`;if(i?n.info(` (would remove) ${o} and back it up to ${o}.bak`):(b(L)||y(L,c,"utf8"),le(r),n.info(`Removed ${o} (backup at ${o}.bak)`)),m.length>0){n.warn(`Skipped ${m.length} hook${m.length===1?"":"s"} that cannot run without prek:`);for(const $ of m)n.warn(` - ${$.repo}::${$.hookId} — ${$.reason}`)}if(u.length>0){n.warn("Partial filter translations:");for(const $ of u)n.warn(` - ${$}`)}if(d.length>0){n.warn("Manual follow-up required:");for(const $ of d)n.warn(` - ${$}`)}return{isError:!1,message:`${i?"would migrate":"Migration complete:"} ${l} stage script${l===1?"":"s"} ${i?"into":"written to"} ${t}/`}},ht=e=>{const t=[];let n=0;for(let s=0;s<e.length;s+=1)e[s]===0&&(s>n&&t.push(e.subarray(n,s).toString("utf8")),n=s+1);return n<e.length&&t.push(e.subarray(n).toString("utf8")),t},P=(e,t,n)=>{const s=E("git",[...e],{cwd:n,encoding:"buffer"});if(s.status!==0){const o=s.stderr?s.stderr.toString():"";throw new Error(`git ${t} failed${o?`: ${o.trim()}`:""}`)}return s.stdout.length===0?[]:ht(s.stdout)},mt=(e,t)=>{switch(e.kind){case"all":return P(["ls-files","-z"],"ls-files",t);case"range":return P(["diff","--name-only","--diff-filter=ACM","-z",e.fromRef,e.toRef],"diff --from-ref/--to-ref",t);case"staged":return P(["diff","--cached","--name-only","--diff-filter=ACM","-z"],"diff --cached",t);default:{const n=e;throw new Error(`unknown discover mode: ${JSON.stringify(n)}`)}}},K=(e,t)=>{try{return new RegExp(e)}catch(n){const s=n instanceof Error?n.message:String(n);throw new Error(`invalid ${t} regex ${JSON.stringify(e)}: ${s}`,{cause:n})}},pt=e=>e.types&&e.types.length>0||e.typesOr&&e.typesOr.length>0||e.excludeTypes&&e.excludeTypes.length>0||!1,kt=(e,t)=>{let n=e;if(t.files){const i=K(t.files,"files");n=n.filter(r=>i.test(r))}if(t.exclude){const i=K(t.exclude,"exclude");n=n.filter(r=>!i.test(r))}if(!pt(t))return[...n];const s=Ne(n),o={excludeTypes:t.excludeTypes,types:t.types,typesOr:t.typesOr};return n.filter(i=>{const r=s.get(i);return r?Me(r,o):!1})},$t=32*1024,wt=(e,t)=>{const n=[],s=Math.max(1024,$t-t);let o=[],i=0;for(const r of e){const c=Buffer.byteLength(r,"utf8")+8;i+c>s&&o.length>0&&(n.push(o),o=[],i=0),o.push(r),i+=c}return o.length>0&&n.push(o),n},Et=e=>({error:t=>{e.error(t)},info:t=>{e.info(t)}}),U=(e,t,n)=>n?n.message:t?`terminated by signal ${t}`:`exited with status ${String(e)}`,yt=(e,t,n,s,o)=>{const i=s?o.extraArgs:[];if(!n||t.length===0){const a=E("sh",["-c",e,"sh",...i],{cwd:o.root,stdio:"inherit"});return a.status===null?(o.logger.error(`hook command failed: ${U(a.status,a.signal,a.error)}`),1):a.status}const r=Buffer.byteLength(e,"utf8")+Buffer.byteLength("sh","utf8")+Buffer.byteLength("-c","utf8")+i.reduce((a,f)=>a+Buffer.byteLength(f,"utf8")+8,0)+64;let c=0;for(const a of wt(t,r)){const f=E("sh",["-c",`${e} "$@"`,"sh",...i,...a],{cwd:o.root,stdio:"inherit"});f.status===null?(o.logger.error(`hook command failed: ${U(f.status,f.signal,f.error)}`),c|=1):c|=f.status}return c},vt=(e,t,n)=>{if(e.fail!==void 0)return n.logger.info(e.fail),1;const s=j.has(n.stage);let o;try{o=kt(t,e)}catch(a){const f=a instanceof Error?a.message:String(a);return n.logger.error(`hook "${e.id}": ${f}`),2}if(o.length===0&&e.alwaysRun!==!0&&!s)return 0;const i=e.passFilenames!==!1;if(e.verbose){const a=e.name??e.id;n.logger.info(`+ ${a}`)}if(e.builtin){const a=ze(e.builtin);if(!a)return n.logger.error(`unknown builtin "${e.builtin}" referenced by hook "${e.id}"`),2;const f={logger:Et(n.logger),root:n.root};try{return a(o,e.args??[],f)}catch(g){const u=g instanceof Error?g.message:String(g);return n.logger.error(`builtin "${e.builtin}" crashed: ${u}`),1}}if(e.entry===void 0)return n.logger.error(`hook "${e.id}" has no \`entry\`, \`builtin\`, or \`fail\` to run`),2;const r=(e.args??[]).map(a=>`'${a.replaceAll("'",String.raw`'\''`)}'`).join(" "),c=r?`${e.entry} ${r}`:e.entry;return yt(c,o,i,s,n)},bt=(e,t,n,s)=>{const o=e.stages[t];if(!o||o.length===0)return 0;let i=0;for(const r of o){const c=vt(r,n,s);if(c!==0&&(i|=c,e.failFast))return i}return i},St="pre-commit",Rt=e=>{if(e.lastCommit&&(e.fromRef||e.toRef))throw new Error("--last-commit cannot be combined with --from-ref or --to-ref");const t=e.lastCommit?"HEAD~1":e.fromRef,n=e.lastCommit?"HEAD":e.toRef;if(t&&!n||n&&!t)throw new Error("--from-ref and --to-ref must be specified together");return t&&n?{fromRef:t,kind:"range",toRef:n}:e.allFiles?{kind:"all"}:{kind:"staged"}},_t=(e,t,n,s)=>{const o=n.stage??St,i=Y(e,t);if(!i)throw new Error(`No hook config found at ${t}/config.json. Install or migrate hooks first.`);const r=i.stages[o];if(!r||r.length===0)return s.info(`No hooks configured for stage "${o}".`),0;const a=j.has(o)?void 0:Rt(n),f=a?.kind==="all"?" (--all-files)":a?.kind==="range"?` (${a.fromRef}..${a.toRef})`:"";s.info(`Running ${o}${f}`);const g=a?mt(a,e):[],u={extraArgs:n.extraArgs??[],logger:s,root:e,stage:o};return bt(i,o,g,u)},xt=(e,t,n)=>{const s=_t(A(),e,t,n);if(s!==0)throw new Error(`Hook stage exited with code ${s}`)},At=(e=Q)=>{const t=E("git",["config","--local","core.hooksPath"],{encoding:"utf8"});if(t.status!==0)return{isError:!1,message:"No custom hooks path configured"};const n=t.stdout.trim()||`${e}/_`,s=Z(n),{status:o,stderr:i}=E("git",["config","--local","--unset","core.hooksPath"]);if(o===null)return{isError:!0,message:"git command not found"};if(o&&o!==5)return{isError:!0,message:String(i)};const r=[];for(const c of s)if(b(c))try{ue(c,{force:!0,recursive:!0})}catch(a){r.push(`${c} (${a instanceof Error?a.message:String(a)})`)}return r.length>0?{isError:!1,isWarning:!0,message:`could not remove ${r.length} dispatcher director(ies): ${r.join(", ")}`}:{isError:!1,message:""}},It=new Set(z),Ot=e=>{const t=E("sh",["-n",e],{encoding:"utf8"});if(t.status===null)return`failed to run "sh -n" (${t.error?.message??"unknown error"})`;if(t.status!==0)return t.stderr.trim()||`sh -n exited with ${t.status}`},Tt=(e,t)=>{const n=[],s=h(e,t),o=E("git",["config","--local","core.hooksPath"],{cwd:e,encoding:"utf8"}),i=`${t}/_`,r=o.status===0?o.stdout.trim():"";r?r!==i&&!r.endsWith(`/${i}`)&&n.push({kind:"warning",message:`core.hooksPath is "${r}" — expected "${i}". Re-run \`vis hook install\` to fix.`}):n.push({kind:"warning",message:"core.hooksPath is not set — run `vis hook install`."});const c=r||i,a=E("git",["rev-parse","--show-toplevel"],{cwd:e,encoding:"utf8"}),f=a.status===0&&a.stdout.trim()?a.stdout.trim():e,g=h(f,c);for(const d of Z(c,f))b(d)||(d===g?n.push({kind:"error",message:`Dispatcher directory ${c} is missing. Run \`vis hook install\`.`}):n.push({kind:"warning",message:`Worktree ${d} is missing — git runs no hooks there. Run \`vis hook install\` in that worktree.`}));if(!b(s))return n.push({kind:"error",message:`Hooks directory ${t}/ is missing.`}),{issues:n,ok:!1};let u=!1;for(const d of q(s)){if(d.startsWith(".")||d==="_"||d===R||d==="README.md")continue;if(!It.has(d)){n.push({kind:"warning",message:`Unknown hook "${d}" — not a standard git hook.`,path:h(t,d)});continue}const m=h(s,d);if(!M(m).isFile())continue;u=!0;const w=M(m).mode&511;(w&64)===0&&n.push({kind:"warning",message:`Script is not owner-executable (mode ${w.toString(8)}).`,path:h(t,d)});const p=Ot(m);p&&n.push({kind:"error",message:`Shell syntax error: ${p}`,path:h(t,d)})}if(u){const d=h(s,R);if(b(d))try{Y(e,t)}catch(m){n.push({kind:"error",message:`${R} is malformed: ${m instanceof Error?m.message:String(m)}`,path:h(t,R)})}else n.push({kind:"error",message:`Stage scripts are present but ${t}/${R} is missing. Re-run \`vis hook migrate\`.`})}return{issues:n,ok:!n.some(d=>d.kind==="error")}},Ft=(e,t)=>{if(e.issues.length===0)return[`Hook directory ${t}/ looks good.`];const n=[];for(const s of e.issues){const o=s.kind==="error"?"ERROR":"WARN ",i=s.path?` (${s.path})`:"";n.push(`${o} ${s.message}${i}`)}return n.push("",e.ok?"No errors — warnings only.":`${e.issues.filter(s=>s.kind==="error").length} error(s).`),n},Ct=(e,t)=>{const n=Tt(A(),e),s=Ft(n,e);for(const o of s)o.startsWith("ERROR")||o.startsWith("WARN")?t.warn(o):t.info(o);if(!n.ok)throw new Error("Hook validation failed")},_=e=>e.hooksDir??Q,V=e=>new Promise(t=>{const n=ge({input:process.stdin,output:process.stdout});n.question(`${e} (y/N) `,s=>{n.close();const o=s.trim().toLowerCase();t(o==="y"||o==="yes")})}),Nt=async(e,t,n={})=>{const s=A(),o=ee(s),i=B(s);if(o&&i)throw new Error(`Found both husky (${o}/) and prek (${i}). Remove or migrate one before running \`vis hook install\`.`);if(o){if(t.info(`Existing husky installation found at ${o}/`),await V("Would you like to migrate your husky hooks to vis?")){const a=te(s,e,t,{useEditorconfig:n.useEditorconfig});if(a.isError)throw new Error(a.message);a.message&&t.info(a.message);return}t.info("Aborting install. Remove husky first or run 'vis hook migrate' to migrate.");return}if(i){if(t.info(`Existing prek configuration found at ${i}`),await V("Would you like to migrate your prek hooks to vis?")){const a=re(s,e,t,{useEditorconfig:n.useEditorconfig});if(a.isError)throw new Error(a.message);a.message&&t.info(a.message);return}t.info("Aborting install. Remove the prek config first or run 'vis hook migrate' to migrate.");return}t.info(`Installing git hooks in ${e}/...`);const r=X(e,{force:n.force});if(r.isError)throw new J(r.message);r.message&&(r.isWarning?t.warn(r.message):t.info(r.message)),r.installed&&(b(h(s,e,"pre-commit"))||y(h(s,e,"pre-commit"),`#!/usr/bin/env sh
|
|
15
|
+
`,{mode:493}),t.info("Git hooks installed successfully."))},Pt=(e,t,n,s)=>{const o=A(),i=ee(o),r=B(o);if(i&&r)throw new Error(`Found both husky (${i}/) and prek (${r}). Migrate one at a time — rename or remove one before retrying.`);if(!i&&!r)throw new Error("No husky (.husky/) or prek (.pre-commit-config.yaml / prek.toml) configuration found to migrate.");t&&n.info("(dry-run) no files will be written");const c=i?te(o,e,n,{dryRun:t,useEditorconfig:s}):re(o,e,n,{dryRun:t,useEditorconfig:s});if(c.isError)throw new Error(c.message);c.message&&n.info(c.message)},H="# vis:secrets-hook",Mt=`#!/usr/bin/env sh
|
|
16
16
|
${H}
|
|
17
17
|
# Scan staged files for secrets before each commit. Remove this block or the whole file to disable.
|
|
18
18
|
pnpm exec vis secrets --staged --quiet || exit 1
|
|
19
|
-
`,
|
|
19
|
+
`,Ht=(e,t,n)=>{if(e!=="secrets")throw new Error(`Unknown hook add target "${String(e)}". Currently supported: "secrets".`);const s=A(),o=h(s,t,"pre-commit");if(!b(h(s,t)))throw new Error(`Hooks directory ${t}/ does not exist. Run \`vis hook install\` first.`);if(b(o)){const i=O(o);if(i.includes(H)){n.info(`Secrets hook already present in ${o}.`);return}if(/\bvis secrets\b/.test(i)){n.warn(`Found a \`vis secrets\` invocation in ${o} without the managed marker — leaving it untouched.`);return}const r=`${i.trimEnd()}
|
|
20
20
|
|
|
21
21
|
${H}
|
|
22
22
|
pnpm exec vis secrets --staged --quiet || exit 1
|
|
23
|
-
`;
|
|
23
|
+
`;y(o,r),de(o,493),n.info(`Appended secrets scan to ${o}.`);return}y(o,Mt,{mode:493}),n.info(`Created ${o} with a secrets-scan pre-commit check.`)},jt=(e,t)=>{t.info("Removing git hooks...");const n=At(e);if(n.isError)throw new J(n.message);if(n.message){n.isWarning?t.warn(n.message):t.info(n.message);return}t.info("Git hooks removed successfully.")},Bt=async({logger:e,options:t,visConfig:n})=>{await Nt(_(t),e,{force:!!t.force,useEditorconfig:n?.editorconfig??!0})},Lt=({logger:e,options:t})=>{jt(_(t),e)},Gt=({logger:e,options:t,visConfig:n})=>{Pt(_(t),!!t.dryRun,e,n?.editorconfig??!0)},Wt=({logger:e,options:t})=>{Oe(_(t),e)},Dt=({logger:e,options:t})=>{Ct(_(t),e)},Kt=({argument:e,logger:t,options:n})=>{xt(_(n),{allFiles:!!n.allFiles,extraArgs:e.slice(1),fromRef:n.fromRef,lastCommit:!!n.lastCommit,stage:e[0],toRef:n.toRef},t)},Ut=({argument:e,logger:t,options:n})=>{Ht(e[0],_(n),t)},sn=Bt,on=Lt,rn=Gt,an=Wt,cn=Dt,fn=Kt,ln=Ut;export{ln as hookAddExecute,sn as hookInstallExecute,an as hookListExecute,rn as hookMigrateExecute,fn as hookRunExecute,on as hookUninstallExecute,cn as hookValidateExecute};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{createRequire as Tt}from"node:module";import{X as ye,F as T,b as be,q as ft,T as ut}from"../packem_shared/index.server-BAjDJSEu.js";import{e as F,z as xe,l as Ve,U as Mt}from"../packem_shared/index-DHD8wb6Z.js";import{i as je}from"../packem_shared/index-BjdW45xX.js";import{whichBin as Vt}from"#native";import{b as Ut,a as Wt,e as zt}from"../packem_shared/ai-analysis-DSQQDFU9.js";import{a3 as Bt,u as Ht,s as Gt,t as Kt,p as u,c as Qe}from"./cli-main.js";import{y as X}from"../packem_shared/isAccessibleSync-DYKTrrvc-CSnBISfV.js";import{U as et}from"../packem_shared/writeFileSync-DJoHk3Ks-CgQ-VNNT.js";import{L as qt,i as Yt,j as Jt,F as Xt,c as Zt,a as Qt,h as en,d as tn,b as nn}from"./catalog.js";import{d as an,c as rn}from"../packem_shared/pm-runner-
|
|
1
|
+
import{createRequire as Tt}from"node:module";import{X as ye,F as T,b as be,q as ft,T as ut}from"../packem_shared/index.server-BAjDJSEu.js";import{e as F,z as xe,l as Ve,U as Mt}from"../packem_shared/index-DHD8wb6Z.js";import{i as je}from"../packem_shared/index-BjdW45xX.js";import{whichBin as Vt}from"#native";import{b as Ut,a as Wt,e as zt}from"../packem_shared/ai-analysis-DSQQDFU9.js";import{a3 as Bt,u as Ht,s as Gt,t as Kt,p as u,c as Qe}from"./cli-main.js";import{y as X}from"../packem_shared/isAccessibleSync-DYKTrrvc-CSnBISfV.js";import{U as et}from"../packem_shared/writeFileSync-DJoHk3Ks-CgQ-VNNT.js";import{L as qt,i as Yt,j as Jt,F as Xt,c as Zt,a as Qt,h as en,d as tn,b as nn}from"./catalog.js";import{d as an,c as rn}from"../packem_shared/pm-runner-d93_73O6.js";import{s as _}from"../packem_shared/index-B4AjSxHU.js";import{c as gt,s as ve,g as on,p as sn,e as cn}from"../packem_shared/index-CIIKPX4H.js";import{d as ln}from"../packem_shared/anolilab-text-CAM_E6uK.js";import{t as pn,b as dn}from"../packem_shared/cyclonedx-B1vzerwP.js";import{s as gn}from"../packem_shared/scan-progress-5uTRdC1G.js";import{r as mn,A as tt,q as nt}from"../packem_shared/advisories-0ScpWAHV.js";import{p as ht}from"../packem_shared/readJsonSync-CbryXYxN-B2aSeDpC.js";import{l as hn,f as vn,a as wn}from"../packem_shared/dependency-scan-DBH2Qo4I.js";import{r as yn}from"../packem_shared/manifests-BNSmpPF_.js";import{l as Sn,p as An,O as En}from"../packem_shared/osv-bloom-JYIWcH3F.js";import{D as Cn,f as it,e as Nn,i as On}from"../packem_shared/formatBytes-BHAzNIrn-Bkk_uRS-.js";let jt;const Lt=e=>(jt??=Tt(import.meta.url))(e),te=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,Z=e=>{if(typeof te<"u"&&te.versions&&te.versions.node){const[t,n]=te.versions.node.split(".").map(Number);if(t>22||t===22&&n>=3||t===20&&n>=16)return te.getBuiltinModule(e)}return Lt(e)},{spawnSync:_t}=Z("node:child_process"),{createInterface:Dt}=Z("node:readline"),{stripVTControlCharacters:Ft}=Z("node:util"),{createHash:fn}=Z("node:crypto"),{relative:mt,join:un}=Z("node:path"),{readFileSync:vt,existsSync:bn,writeFileSync:xn,renameSync:kn,unlinkSync:$n}=Z("node:fs"),at=(e,t={})=>{Array.isArray(t.extensions)||(t.extensions=["js","mjs","cjs","ts"]);const n=[];for(const i of qt(e,t))n.push(i.path);return n},ke=e=>`${e.packageName}@${e.packageVersion}:${e.vulnerability.id}`,In=e=>e==null||e===!0||e===""||e==="true"||e.toString().toLowerCase()==="all",Rn=(e,t)=>{if(In(t))return e;const n=String(t).trim();if(/^\d+$/.test(n)){const a=Number.parseInt(n,10)-1,r=e[a];return r?[r]:[]}const i=n.toLowerCase();return e.filter(a=>{const{aliases:r,id:o}=a.vulnerability;return o.toLowerCase()===i||(r??[]).some(s=>s.toLowerCase()===i)})},Pn=e=>{const{packageName:t,packageVersion:n,vulnerability:i}=e,a=(i.aliases??[]).join(", ")||"none",r=(i.fixedVersions??[]).join(", ")||"no fixed version published";return`You are a security engineer. Explain this dependency vulnerability for a developer triaging it.
|
|
2
2
|
|
|
3
3
|
Package: ${t}@${n}
|
|
4
4
|
Advisory: ${i.id} (aliases: ${a})
|
|
@@ -303,7 +303,7 @@ ${n.map(r=>` '${r}': '${t[r]}'`).join(`
|
|
|
303
303
|
`)?e:`${e}
|
|
304
304
|
`}
|
|
305
305
|
${i}`},ua=(e,t,n,i)=>{const a=Xt(e,t.length>0?t:void 0),r=t.length>0?JSON.parse(t):{};if(n==="package.json#pnpm.overrides"){const o=r.pnpm??{};o.overrides=i,r.pnpm=o}else n==="package.json#resolutions"?r.resolutions=i:r.overrides=i;return pa(r,a)},ga=(e,t,n)=>{const{filePath:i,surface:a}=$t(e,n),r=da(e,n),o=X(i)?xe(i):"",s=[],l={...r};for(const h of t.entries){const b=r[h.packageName];if(b===h.spec){s.push({...h,previousSpec:b,status:"unchanged"});continue}b===void 0?s.push({...h,status:"added"}):s.push({...h,previousSpec:b,status:"updated"}),l[h.packageName]=h.spec}const p=la(l),g=s.some(h=>h.status!=="unchanged"),w=a==="pnpm-workspace.yaml"?fa(o,p):ua(i,o,a,p);return{changed:g,entries:s,filePath:i,nextContent:w,previousContent:o,surface:a}},ma=e=>{if(!e.changed)return e;if(e.surface==="pnpm-workspace.yaml"&&e.previousContent.length===0)throw new Error(`${e.filePath} not found. Run \`pnpm init\` or create pnpm-workspace.yaml before applying overrides for pnpm v10+.`);const t=`${e.filePath}.tmp`;try{xn(t,e.nextContent),kn(t,e.filePath)}catch(n){try{$n(t)}catch{}throw n}return e},ha=e=>{const t=new Map;for(const i of e){const a=i.vulnerability.fixedVersions[0];if(!a)continue;const r=_.coerce(a),o=r?`^${r.version}`:a;t.set(i.packageName,o)}return{entries:[...t.entries()].sort(([i],[a])=>i.localeCompare(a)).map(([i,a])=>({packageName:i,spec:a}))}},va={critical:ye,high:ut,low:ft,medium:be},De=new Set(["cargo","crates.io","go","maven","npm","pypi","rubygems"]),wa=e=>{const t=(e??"npm").split(",").map(a=>a.trim()).filter(a=>a.length>0),n=t.length>0?t:["npm"],i=n.filter(a=>!De.has(a.toLowerCase()));return{all:n,unsupported:i}},ya={CRITICAL:ye,HIGH:ut,LOW:ft,MODERATE:be,UNKNOWN:T},ba=(e,t,n,i)=>{const a=ya[n.severity]??T,r=i?` ${T("[acknowledged]")}`:"",o=n.fixedVersions??[],s=o.length>0?` (fix: ${o.join(", ")})`:"";return` ${a(n.severity)} ${n.id} — ${e}@${t}${r}
|
|
306
|
-
${n.summary}${s}`},xa=(e,t)=>{const n=Nn(e),i=`${String(Math.round(e.score.overall*100))}%`,a=t?` ${T("[acknowledged]")}`:"",r=e.alerts.length>0?`, ${String(e.alerts.length)} alert${e.alerts.length===1?"":"s"}`:"";return` ${i} ${n}@${e.version} (${On(e.score.overall)}${r})${a}`},ka=new Set(["aube","auto","vis"]),ne=e=>e!==void 0&&ka.has(e),$a=(e,t,n)=>{if(e!==void 0&&!ne(e))throw new Error(`Invalid --backend value '${e}'. Expected one of: aube, auto, vis.`);const i=process.env.VIS_AUDIT_BACKEND;if(i!==void 0&&i!==""&&!ne(i))throw new Error(`Invalid VIS_AUDIT_BACKEND value '${i}'. Expected one of: aube, auto, vis.`);const a=ne(i)?i:void 0,r=ne(t)?t:void 0,s=(ne(e)?e:void 0)??a??r??"auto";return s==="aube"?"aube":s==="vis"?"vis":(n?.install?.backend??process.env.VIS_INSTALLER)==="aube"&&Vt("aube")!==null?"aube":"vis"},Sa=e=>{if(e!==void 0)switch(e){case"critical":return"critical";case"high":return"high";case"low":return"low";case"medium":return"moderate";default:return e}},Aa=(e,t,n)=>{const i=["audit"],a=Sa(t.severity);a!==void 0&&i.push("--audit-level",a),(t.prodOnly===!0||t.prod===!0)&&i.push("--prod"),(t.json===!0||t.format==="json")&&i.push("--json");const r=t.fix===!0;t["fix-transitive"]===!0||t.fixTransitive===!0?i.push("--fix=override"):r&&i.push("--fix=update");const s=[];t.offline===!0&&s.push("--offline (aube has its own offline cache)"),(t.format==="sarif"||t.format==="csaf"||t.format==="cyclonedx"||t.format==="cyclonedx-vex"||t.format==="gitlab"||t.format==="junit")&&s.push(`--format=${String(t.format)} (only json/text is forwarded to aube)`),s.length>0&&u.warn(`Delegating to 'aube audit'. Skipping vis-only flags: ${s.join(", ")}`);const l=_t("aube",i,{cwd:e,stdio:"inherit"});if(l.error){const{code:p}=l.error;return p==="ENOENT"?u.error("Backend 'aube' selected but the 'aube' binary was not found on PATH. Install aube or run with --backend vis."):u.error(`Failed to spawn aube: ${l.error.message}`),1}return l.status??1},Ea=async(e,t,n,i,a)=>{if($a(n.backend,i?.security?.audit?.backend,i)==="aube"){process.exitCode=Aa(t,n);return}const o=n.severity??"low",s=n.format??"table",l=s==="sarif",p=s==="csaf",g=s==="cyclonedx-vex"||s==="cyclonedx",w=s==="gitlab",h=s==="junit",b=s==="json"||!!n.json,x=n.report,m=i?.security?.audit,$=i?.security?.policies,y=n.offline===void 0?!!m?.offlineByDefault:!!n.offline,C=n.db,A=wa(n.ecosystem),L=!!n.prodOnly,G=n.failOn??$?.vulnerability?.failOn,Et=!!n.showFixes,re=!!n.showAccepted,Se=i?.security?.acceptedRisks,Ue=$?.vulnerability?.usage,Ct=n.
|
|
306
|
+
${n.summary}${s}`},xa=(e,t)=>{const n=Nn(e),i=`${String(Math.round(e.score.overall*100))}%`,a=t?` ${T("[acknowledged]")}`:"",r=e.alerts.length>0?`, ${String(e.alerts.length)} alert${e.alerts.length===1?"":"s"}`:"";return` ${i} ${n}@${e.version} (${On(e.score.overall)}${r})${a}`},ka=new Set(["aube","auto","vis"]),ne=e=>e!==void 0&&ka.has(e),$a=(e,t,n)=>{if(e!==void 0&&!ne(e))throw new Error(`Invalid --backend value '${e}'. Expected one of: aube, auto, vis.`);const i=process.env.VIS_AUDIT_BACKEND;if(i!==void 0&&i!==""&&!ne(i))throw new Error(`Invalid VIS_AUDIT_BACKEND value '${i}'. Expected one of: aube, auto, vis.`);const a=ne(i)?i:void 0,r=ne(t)?t:void 0,s=(ne(e)?e:void 0)??a??r??"auto";return s==="aube"?"aube":s==="vis"?"vis":(n?.install?.backend??process.env.VIS_INSTALLER)==="aube"&&Vt("aube")!==null?"aube":"vis"},Sa=e=>{if(e!==void 0)switch(e){case"critical":return"critical";case"high":return"high";case"low":return"low";case"medium":return"moderate";default:return e}},Aa=(e,t,n)=>{const i=["audit"],a=Sa(t.severity);a!==void 0&&i.push("--audit-level",a),(t.prodOnly===!0||t.prod===!0)&&i.push("--prod"),(t.json===!0||t.format==="json")&&i.push("--json");const r=t.fix===!0;t["fix-transitive"]===!0||t.fixTransitive===!0?i.push("--fix=override"):r&&i.push("--fix=update");const s=[];t.offline===!0&&s.push("--offline (aube has its own offline cache)"),(t.format==="sarif"||t.format==="csaf"||t.format==="cyclonedx"||t.format==="cyclonedx-vex"||t.format==="gitlab"||t.format==="junit")&&s.push(`--format=${String(t.format)} (only json/text is forwarded to aube)`),s.length>0&&u.warn(`Delegating to 'aube audit'. Skipping vis-only flags: ${s.join(", ")}`);const l=_t("aube",i,{cwd:e,stdio:"inherit"});if(l.error){const{code:p}=l.error;return p==="ENOENT"?u.error("Backend 'aube' selected but the 'aube' binary was not found on PATH. Install aube or run with --backend vis."):u.error(`Failed to spawn aube: ${l.error.message}`),1}return l.status??1},Ea=async(e,t,n,i,a)=>{if($a(n.backend,i?.security?.audit?.backend,i)==="aube"){process.exitCode=Aa(t,n);return}const o=n.severity??"low",s=n.format??"table",l=s==="sarif",p=s==="csaf",g=s==="cyclonedx-vex"||s==="cyclonedx",w=s==="gitlab",h=s==="junit",b=s==="json"||!!n.json,x=n.report,m=i?.security?.audit,$=i?.security?.policies,y=n.offline===void 0?!!m?.offlineByDefault:!!n.offline,C=n.db,A=wa(n.ecosystem),L=!!n.prodOnly,G=n.failOn??$?.vulnerability?.failOn,Et=!!n.showFixes,re=!!n.showAccepted,Se=i?.security?.acceptedRisks,Ue=$?.vulnerability?.usage,Ct=n.usage===void 0?!!Ue?.enabled:n.usage,I=b||l||p||g||w||h,We=n.explain,Ae=We!==void 0,ze=Ae&&!l&&!p&&!g&&!w&&!h;if(Ae&&y){u.error("`--explain` needs network access and cannot run in offline mode (--offline or security.audit.offlineByDefault)."),process.exitCode=1;return}Ae&&!ze&&u.warn(`\`--explain\` has no effect with --format=${s}; explanations are only rendered in table, json, and HTML output.`);const P=an(t),N=Vn(t,P.name);if(y){const c=C??mn(t);if(!await e.access(c).then(()=>!0).catch(()=>!1)){const f=new tt(c);I?process.stderr.write(`${f.message}
|
|
307
307
|
`):u.error(f.message),process.exitCode=1;return}}!I&&(N.ignoredAdvisories.length>0||N.excludedPackages.length>0)&&u.info(`Loaded ${String(N.ignoredAdvisories.length)} ignored advisor${N.ignoredAdvisories.length===1?"y":"ies"} and ${String(N.excludedPackages.length)} excluded package${N.excludedPackages.length===1?"":"s"} from ${P.name} config.`),!I&&A.unsupported.length>0&&u.warn(`Ecosystems ${A.unsupported.map(c=>`'${c}'`).join(", ")} are not yet supported by the audit matcher. Supported: npm, pypi, crates.io, cargo, maven, go, rubygems.`);const M=hn(t,P.name,{includeDev:!L});if(M.length===0){u.info(`No ${P.name} lockfile entries found. Run ${P.name} install first.`);return}if(!I){const c=L?"production-only packages":"installed packages";u.info(`Scanning ${String(M.length)} ${c}${y?" (offline)":""}…`)}const oe=M.map(c=>({name:c.name,version:c.version})),se=i?.security?.audit?.advisories?.bloom?.mode??"off";let U=[];if(se!=="off")try{const c=await Sn(t,{softFail:se==="on"});if(c){if(U=An(c,oe).map(d=>({name:d.name,version:d.version})),!I&&U.length>0){u.warn(`osv-bloom prefilter flagged ${String(U.length)} package${U.length===1?"":"s"} as possibly malicious (MAL-*). Confirming via the advisory query path…`);const d=10;for(const f of U.slice(0,d))u.warn(` ${ye("[bloom]")} ${f.name}@${f.version}`);U.length>d&&u.warn(` …and ${String(U.length-d)} more (full list in --format json output)`)}}else I||u.info(T("osv-bloom cache absent — skipping prefilter (run `vis advisories bloom sync` to enable)."))}catch(c){if(c instanceof En&&se==="required"){const f=`${c.message} (security.audit.advisories.bloom.mode = "required")`;I?process.stderr.write(`${f}
|
|
308
308
|
`):u.error(f),process.exitCode=1;return}const d=c instanceof Error?c.message:String(c);if(se==="required"){I?process.stderr.write(`osv-bloom prefilter failed: ${d}
|
|
309
309
|
`):u.error(`osv-bloom prefilter failed: ${d}`),process.exitCode=1;return}I||u.warn(`osv-bloom prefilter failed (continuing): ${d}`)}const ce=new Set;y?ce.add("socket").add("deps-dev"):(Qe("socket")&&ce.add("socket"),Qe("depsDev")&&ce.add("deps-dev"));const Ee=Zt(i?.security,{disabled:ce,minimumScore:$?.score?.minimum}),Ce=Ee.length>0,Nt=Ee.map(c=>c.displayName).join(" + "),le=$?.score?.minimum??Cn,K=vn(t,P.name),Ot=[{id:"vulnerabilities",label:y?"Known vulnerabilities (offline OSV cache)":"Known vulnerabilities (OSV)"},...Ce?[{id:"security",label:`Supply-chain reports (${Nt})`}]:[]],V=gn(Ot,{live:!I}),It=Date.now(),q=c=>{const d=Date.now()-c;return d>=1e3?`${(d/1e3).toFixed(1)}s`:`${String(Math.round(d))}ms`};let Ne,Oe;try{const c=Date.now(),d=Date.now();V.start("vulnerabilities"),Ce&&V.start("security");const f=y?Promise.resolve().then(()=>nt(oe,{dbPath:C,ecosystem:A.all.find(v=>De.has(v.toLowerCase()))??"npm",workspaceRoot:t})).then(v=>{let k=0;for(const E of v.values())k+=E.length;return V.finish("vulnerabilities",k>0?"warn":"ok",k>0?`${String(k)} found · ${q(c)}`:`none found · ${q(c)}`),v}).catch(v=>{const k=v instanceof Error?v.message:String(v);if(V.finish("vulnerabilities","error",k),v instanceof tt)throw v;return new Map}):Qt(oe).then(v=>{let k=0;for(const E of v.values())k+=E.length;return V.finish("vulnerabilities",k>0?"warn":"ok",k>0?`${String(k)} found · ${q(c)}`:`none found · ${q(c)}`),v}).catch(v=>{const k=v instanceof Error?v.message:String(v);return V.finish("vulnerabilities","error",k),new Map});[Ne,Oe]=await Promise.all([f,Ce?en(Ee,oe).then(v=>{let k=0,E=0;for(const Y of v.values())k+=Y.alerts.length,Y.score.overall<le&&(E+=1);const j=k+E;return V.finish("security",j>0?"warn":"ok",j>0?`${String(k)} alert${k===1?"":"s"}, ${String(E)} low-score · ${q(d)}`:`clean · ${q(d)}`),v}).catch(v=>{const k=v instanceof Error?v.message:String(v);return V.finish("security","error",k),new Map}):Promise.resolve(new Map)])}finally{V.stop()}b||u.info(T(`Scan completed in ${q(It)}`));const pe=[];for(const c of M){if(Fn(c.name,N))continue;const d=Ne.get(c.name)??[],f=Oe.get(`${c.name}@${c.version}`),v=it(c.name,c.version,Se),k=d.length>0,E=f?f.score.overall<le:!1,j=f?f.alerts.length>0:!1;(k||E||j)&&pe.push({acceptedRisk:v,name:c.name,socketReport:f,version:c.version,vulnerabilities:d})}if(y){const c=A.all.filter(d=>De.has(d.toLowerCase())&&d.toLowerCase()!=="npm");for(const d of c){const f=kt(d),v=Xi(t,f);if(v.length!==0){I||u.info(T(`Scanning ${String(v.length)} ${f} packages…`));try{const k=nt(v.map(E=>({name:E.name,version:E.version})),{dbPath:C,ecosystem:f,workspaceRoot:t});for(const E of v){const j=k.get(E.name)??[];j.length!==0&&pe.push({acceptedRisk:it(E.name,E.version,Se),name:E.name,version:E.version,vulnerabilities:j})}}catch(k){const E=k instanceof Error?k.message:String(k);u.warn(`Failed to scan ${f}: ${E}`)}}}}let O=pe.filter(c=>{const d=c.vulnerabilities.some(k=>ve(k.severity,o)),f=c.socketReport?.alerts.some(k=>ve(k.severity==="medium"?"MODERATE":k.severity.toUpperCase(),o)),v=c.socketReport&&c.socketReport.score.overall<le;return d||f||v});const Rt=n.policies,Be=[],R=await(async()=>{const d=on().map(Y=>`'${Y}'`).join(", "),f=sn(Rt,Y=>{Be.push(Y);const Ze=`Unknown policy '${Y}' — ignoring. Available: ${d}.`;I?process.stderr.write(`vis audit: ${Ze}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{createRequire as gt}from"node:module";import{J as qe,b as _,F as M,q as Ke,X as K,j as vt}from"../packem_shared/index.server-BAjDJSEu.js";import{e as L,z,v as wt,l as Se}from"../packem_shared/index-DHD8wb6Z.js";import{m as kt}from"./ts-loader.js";import{O as bt,
|
|
1
|
+
import{createRequire as gt}from"node:module";import{J as qe,b as _,F as M,q as Ke,X as K,j as vt}from"../packem_shared/index.server-BAjDJSEu.js";import{e as L,z,v as wt,l as Se}from"../packem_shared/index-DHD8wb6Z.js";import{m as kt}from"./ts-loader.js";import{O as bt,ao as Rt,c as me,d as Ce}from"./cli-main.js";import{L as X,G as Et,H as xt,I as At,l as St,r as Ct,c as Tt,k as It,J as Ot,K as ze,R as V,E as he,m as H,n as Ye,M as _t,t as F,N as Nt,O as jt,o as Dt,s as Ut}from"./catalog.js";import{i as le}from"../packem_shared/index-BjdW45xX.js";import{v as Bt,r as Lt,f as Te}from"../packem_shared/ai-analysis-DSQQDFU9.js";import{p as Pt,a as Vt,s as Je}from"../packem_shared/pm-runner-d93_73O6.js";import{a as Mt,r as Ft}from"../packem_shared/command-runtime-CiLVo4ED.js";import{r as Gt,a as Ht,p as Wt}from"../packem_shared/resolve-explicit-ZZEPWdpP.js";import{s as qt}from"../packem_shared/min-release-age-ChzTC7_I.js";import{s as Kt}from"../packem_shared/formatBytes-BHAzNIrn-Bkk_uRS-.js";import{r as zt,s as Yt}from"../packem_shared/typosquats-Cdsnf6aN.js";import{U as Jt,V as Xt,C as Ie,e as Qt}from"../packem_shared/vis-update-app-DNeU8RBQ.js";import{h as Xe,P as Qe}from"../packem_shared/peer-warnings-CmYSxvql.js";import{p as Ze}from"../packem_shared/utils-DQFHJn72.js";import{L as Zt}from"../packem_shared/index-BisalDCf.js";import{y as U}from"../packem_shared/isAccessibleSync-DYKTrrvc-CSnBISfV.js";import{s as ne}from"../packem_shared/index-B4AjSxHU.js";import{r as nn,q as sn}from"../packem_shared/advisories-0ScpWAHV.js";import{U as rn}from"../packem_shared/writeFileSync-DJoHk3Ks-CgQ-VNNT.js";let yt;const $t=e=>(yt??=gt(import.meta.url))(e),ee=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,He=e=>{if(typeof ee<"u"&&ee.versions&&ee.versions.node){const[t,n]=ee.versions.node.split(".").map(Number);if(t>22||t===22&&n>=3||t===20&&n>=16)return ee.getBuiltinModule(e)}return $t(e)},{createInterface:We}=He("node:readline"),{existsSync:en,realpathSync:tn}=He("node:fs"),on=e=>{const t=[];for(const n of e.filters)t.push("--filter",n);return e.workspaceRoot&&t.push("--filter","."),t.push("update"),e.latest&&t.push("--latest"),e.recursive&&t.push("--recursive"),e.interactive&&t.push("--interactive"),e.dev&&t.push("--dev"),e.prod&&t.push("--prod"),e.noOptional&&t.push("--no-optional"),e.noSave&&t.push("--no-save"),t.push(...e.packages),{args:t,bin:"pnpm"}},an=e=>{const t=[];return e.filters.length>0&&t.push("workspace",e.filters[0]),t.push("upgrade"),e.latest&&t.push("--latest"),t.push(...e.packages),{args:t,bin:"yarn"}},cn=e=>{const t=[];if(e.filters.length>0||e.recursive){t.push("workspaces","foreach","--all");for(const n of e.filters)t.push("--include",n)}return t.push("up"),e.interactive&&t.push("--interactive"),t.push(...e.packages),{args:t,bin:"yarn"}},ln=(e,t)=>{const n=["update"];e.latest&&t.push("npm does not support --latest flag. Packages will be updated within their semver range."),e.interactive&&t.push("npm does not support --interactive mode.");for(const s of e.filters)n.push("--workspace",s);return e.recursive&&n.push("--workspaces"),e.workspaceRoot&&n.push("--include-workspace-root"),e.dev&&n.push("--dev"),e.prod&&n.push("--production"),e.noOptional&&n.push("--no-optional"),e.noSave&&n.push("--no-save"),n.push(...e.packages),{args:n,bin:"npm"}},dn=e=>{const t=["update"];e.latest&&t.push("--latest");for(const n of e.filters)t.push("--filter",n);return t.push(...e.packages),{args:t,bin:"bun"}},un=(e,t)=>{const n=["outdated","--update"];return e.latest&&n.push("--latest"),e.interactive&&n.push("--interactive"),e.filters.length>0&&t.push("deno outdated has no --filter flag; ignoring."),(e.dev||e.prod)&&t.push("deno outdated has no --dev / --prod flags; dev/prod is governed by deno.json."),e.noOptional&&t.push("deno outdated has no --no-optional flag; ignoring."),e.noSave&&t.push("deno outdated has no --no-save flag; ignoring."),n.push(...e.packages),{args:n,bin:"deno"}},fn=(e,t,n)=>{const s=[];if(n.global&&e!=="aube"&&e!=="deno")return{command:{args:["update","--global",...n.packages],bin:"npm"},warnings:s};let i;switch(e){case"aube":{const r=Pt(n);i={args:r.args,bin:r.bin},s.push(...r.warnings);break}case"bun":{i=dn(n);break}case"deno":{i=un(n,s);break}case"npm":{i=ln(n,s);break}case"pnpm":{i=on(n);break}case"yarn":{i=t.startsWith("1.")?an(n):cn(n);break}default:{const r=e;throw new Error(`Unsupported package manager: ${String(r)}`)}}return{command:i,warnings:s}},et=e=>{const t=e.indexOf("@");return t<=0?e:e.slice(0,t)},pn=e=>{switch(e){case"docker":case"docker-compose":return"docker";case"github-actions":return"actions";case"gitlab-ci":return"gitlab";default:return}},mn=(e,t)=>{const n=[".github/dependabot.yml",".github/dependabot.yaml"];for(const s of n){const i=L(e,s);if(!U(i))continue;let r;try{r=Zt(z(i))}catch{continue}if(r?.updates){for(const o of r.updates){const a=pn(o["package-ecosystem"]);if(!(!a||!Array.isArray(o.ignore)))for(const p of o.ignore){const c=p["dependency-name"];typeof c=="string"&&c.length>0&&t[a].add(et(c))}}return}}},hn=Object.freeze({"docker-compose":"docker",dockerfile:"docker","github-actions":"actions",gitlabci:"gitlab","gitlabci-include":"gitlab"}),gn=Object.freeze({docker:"docker","github-tags":"actions"}),ge=(e,t)=>{if(t)for(const n of t)typeof n=="string"&&n.length>0&&e.add(et(n))},yn=e=>{let t="",n=0;const{length:s}=e;let i=!1,r="";for(;n<s;){const o=e[n]??"";if(i){if(t+=o,o==="\\"&&n+1<s){t+=e[n+1]??"",n+=2;continue}o===r&&(i=!1),n+=1;continue}if(o==='"'||o==="'"){i=!0,r=o,t+=o,n+=1;continue}if(o==="/"&&e[n+1]==="/"){for(;n<s&&e[n]!==`
|
|
2
2
|
`;)n+=1;continue}if(o==="/"&&e[n+1]==="*"){for(n+=2;n<s&&!(e[n]==="*"&&e[n+1]==="/");)n+=1;n+=2;continue}if(o===","){let a=n+1;for(;a<s&&/\s/.test(e[a]??"");)a+=1;const p=e[a];if(p==="}"||p==="]"){n+=1;continue}}t+=o,n+=1}return t},$n=(e,t)=>{const n=["renovate.json","renovate.json5",".renovaterc",".renovaterc.json"];for(const s of n){const i=L(e,s);if(!U(i))continue;let r;try{const a=z(i);r=JSON.parse(yn(a))}catch{continue}if(!r)continue;if(Array.isArray(r.ignoreDeps))for(const a of["actions","docker","gitlab"])ge(t[a],r.ignoreDeps);const o=[["github-actions","actions"],["dockerfile","docker"],["docker-compose","docker"],["gitlabci","gitlab"],["gitlabci-include","gitlab"]];for(const[a,p]of o){const c=r[a];ge(t[p],c?.ignoreDeps)}if(!Array.isArray(r.packageRules))return;for(const a of r.packageRules){if(a.enabled!==!1)continue;const p=new Set;for(const d of a.matchManagers??[]){const f=hn[d];f&&p.add(f)}for(const d of a.matchDatasources??[]){const f=gn[d];f&&p.add(f)}p.size===0&&(p.add("actions"),p.add("docker"),p.add("gitlab"));const c=[...a.matchPackageNames??[],...a.matchDepNames??[],...a.matchPackagePatterns??[]];for(const d of p)ge(t[d],c)}return}},vn=e=>{const t={actions:new Set,docker:new Set,gitlab:new Set};return mn(e,t),$n(e,t),t},ve=(e,t,n)=>{const s=n[t];if(s.size===0)return!1;if(s.has(e))return!0;for(const i of s)if(/[*?[\]/.+]/.test(i))try{const r=i.replaceAll(/[.+^${}()|]/g,String.raw`\$&`).replaceAll("*",".*").replaceAll("?",".");if(new RegExp(`^${r}$`).test(e))return!0}catch{}return!1},W=e=>{const t=e.trim();if(t==="")return;const n=t.startsWith("v")||t.startsWith("V")?t.slice(1):t,i=(ne.valid(n)?ne.parse(n):void 0)??ne.coerce(n,{includePrerelease:!0});if(i)return{major:i.major,minor:i.minor,normalized:`${String(i.major)}.${String(i.minor)}.${String(i.patch)}${i.prerelease.length>0?`-${i.prerelease.join(".")}`:""}`,patch:i.patch,prerelease:i.prerelease.length>0,raw:t}},wn=(e,t)=>ne.rcompare(e.normalized,t.normalized),we=(e,t,n,s)=>{if(!t&&n!=="latest")return;const i=e.filter(r=>r.prerelease?!1:t?n==="patch"&&(r.major!==t.major||r.minor!==t.minor)||n==="minor"&&r.major!==t.major?!1:ne.gt(r.normalized,t.normalized):!0);if(i.length!==0)return i.toSorted(wn)[0]},ke=(e,t)=>!e||!t?"unknown":t.major!==e.major?"major":t.minor!==e.minor?"minor":t.patch!==e.patch?"patch":"unknown",kn="GitHub Actions",Oe=(e,t)=>`${e}@${t}`,bn=e=>({fixedVersions:e.fixedVersions,id:e.id,severity:e.severity,summary:e.summary}),Rn=(e,t)=>{if(t.length===0)return t;const n=nn(e);if(!en(n))return t;const s=new Map;for(const r of t){const o=r.currentVersion??r.currentRef;o&&s.set(Oe(r.name,o),{name:r.name,version:o})}if(s.size===0)return t;const i=new Map;try{for(const[r,o]of s){const p=sn([o],{ecosystem:kn,workspaceRoot:e}).get(o.name);p&&p.length>0&&i.set(r,p)}}catch{return t}return i.size===0?t:t.map(r=>{const o=r.currentVersion??r.currentRef;if(!o)return r;const a=i.get(Oe(r.name,o));return a?{...r,advisories:a.map(p=>bn(p))}:r})},tt=e=>{if(!e)return{};const t={};for(const n of e.split(",")){const s=/^\s*<([^>]+)>\s*;\s*(.+)$/.exec(n);if(!s)continue;const i=s[1]??"",r=s[2]??"";switch(/rel\s*=\s*"?([^";\s]+)"?/i.exec(r)?.[1]?.toLowerCase()){case"first":{t.first=i;break}case"last":{t.last=i;break}case"next":{t.next=i;break}case"prev":case"previous":{t.previous=i;break}}}return t};class En{token;apiBase;fetchImpl;tagsCache=new Map;commitCache=new Map;constructor(t){this.token=t.token??process.env.GITHUB_TOKEN??process.env.GH_TOKEN,this.apiBase=t.apiBase??"https://api.github.com",this.fetchImpl=t.fetch??fetch}async listTags(t,n){const s=`${t}/${n}`,i=this.tagsCache.get(s);if(i)return i;const r=this.fetchTags(t,n);return this.tagsCache.set(s,r),r}async resolveRef(t,n,s){const i=`${t}/${n}@${s}`,r=this.commitCache.get(i);if(r)return r;const o=this.fetchCommit(t,n,s);return this.commitCache.set(i,o),o}buildHeaders(){const t={Accept:"application/vnd.github+json","User-Agent":"vis-update-actions","X-GitHub-Api-Version":"2022-11-28"};return this.token&&(t.Authorization=`Bearer ${this.token}`),t}async fetchTags(t,n){const s=`${this.apiBase}/repos/${encodeURIComponent(t)}/${encodeURIComponent(n)}/tags?per_page=100`,i={parsed:[],tags:[]},r=[];let o=s,a=0;for(;o&&a<5;){const c=o;let d;try{d=await this.fetchImpl(c,{headers:this.buildHeaders()})}catch{return i}if(!d.ok)return i;let f;try{f=await d.json()}catch{return i}if(!Array.isArray(f))return i;for(const m of f){const g=typeof m.name=="string"?m.name:"",h=typeof m.commit?.sha=="string"?m.commit.sha:"";g!==""&&h!==""&&r.push({name:g,sha:h})}o=tt(d.headers.get("link")).next,a+=1}const p=[];for(const c of r){const d=W(c.name);d&&p.push({...d,sha:c.sha})}return{parsed:p,tags:r}}async fetchCommit(t,n,s){const i=`${this.apiBase}/repos/${encodeURIComponent(t)}/${encodeURIComponent(n)}/commits/${encodeURIComponent(s)}`;try{const r=await this.fetchImpl(i,{headers:this.buildHeaders()});if(!r.ok)return;const o=await r.json();return typeof o.sha!="string"?void 0:{committedAt:o.commit?.committer?.date,sha:o.sha}}catch{return}}}const xn=".github/workflows",An=".github/actions",Sn=/^\s*-?\s*uses:\s*(['"]?)([^'"\s#]+)\1(?:\s*#\s*(.+))?\s*$/,Cn=/^[a-f0-9]{40}$/i,Tn=/actions-up-ignore-next-line(?::\s*(.+))?/i,In=/actions-up-ignore-start/i,On=/actions-up-ignore-end/i,_n=e=>{const t=e.split("/");if(t.length<2)return;const[n,s,...i]=t;if(!(!n||!s))return{owner:n,repo:s,subpath:i.length>0?i.join("/"):void 0}},Nn=(e,t)=>{const n=t.split(/\r?\n/),s=[];let i,r=!1;for(const[o,a]of n.entries()){const p=a??"";if(In.test(p)&&(r=!0),On.test(p)){r=!1;continue}const c=p.trim(),f=c===""||c.startsWith("#")?Tn.exec(p):void 0;if(f){i=f[1]??"actions-up-ignore-next-line";continue}const m=Sn.exec(p);if(!m){i=void 0;continue}const g=m[1]??"",h=g==="'"||g==='"'?g:"",b=m[2]??"",k=m[3]?.trim();if(b.startsWith("./")||b.startsWith("../")||b.startsWith("docker://")){i=void 0;continue}const y=b.lastIndexOf("@");if(y<=0){i=void 0;continue}const A=b.slice(0,y),w=b.slice(y+1),u=_n(A);if(!u){i=void 0;continue}let $=i??(r?"actions-up-ignore-block":void 0);if(k){const l=/^actions-up-ignore(?:-next-line)?(?::\s*(.+))?(?:\s|$)/i.exec(k);l&&($=$??l[1]??"actions-up-ignore")}i=void 0,s.push({file:e,ignoreReason:$,isSha:Cn.test(w),line:o+1,original:`${h}${b}${h}`,owner:u.owner,quote:h,ref:w,repo:u.repo,slug:A,subpath:u.subpath,trailingComment:k&&!$?k:void 0})}return s},_e=e=>e.endsWith(".yml")||e.endsWith(".yaml"),jn=(e,t=[])=>{const n=[],s=new Set,i=a=>{if(s.has(a))return;s.add(a);let p;try{p=z(a)}catch{return}const c=Nn(a,p);n.push(...c)},r=L(e,xn);if(U(r))for(const a of X(r,{includeDirs:!1,includeSymlinks:!1,maxDepth:1}))_e(a.name)&&i(a.path);const o=L(e,An);if(U(o))for(const a of X(o,{includeDirs:!1,includeSymlinks:!1,maxDepth:3}))(a.name==="action.yml"||a.name==="action.yaml")&&i(a.path);for(const a of["action.yml","action.yaml"]){const p=L(e,a);U(p)&&i(p)}for(const a of t){const p=wt(a)?a:L(e,a);if(U(p))for(const c of X(p,{includeDirs:!1,includeSymlinks:!1}))_e(c.name)&&i(c.path)}return n},Dn=40,Un=1440*60*1e3,Bn=new Set(["develop","edge","main","master","stable","trunk"]),Ln=e=>e.length===Dn&&/^[a-f0-9]{40}$/i.test(e)?!1:Bn.has(e.toLowerCase())?!0:W(e)===void 0,Ne=(e,t)=>{for(const n of t)try{if(new RegExp(n).test(e))return!0}catch{if(e.includes(n))return!0}return!1},Pn=(e,t,n,s)=>{const i=s==="sha"||e.isSha,{quote:r}=e;return i?`${r}${e.slug}@${t}${r} # ${n}`:`${r}${e.slug}@${n}${r}`},Vn=async(e,t)=>{const{ignoreRules:n,options:s,references:i,resolverOptions:r}=t,o=[],a=[],p=[];if(i.length===0)return{failed:p,ignored:a,updates:o};const c=new En({apiBase:r?.apiBase,fetch:r?.fetch,token:s.githubToken??r?.token}),d=new Map;for(const y of i){const A=`${y.owner}/${y.repo}`,w=d.get(A)??[];w.push(y),d.set(A,w)}const f=Math.max(1,s.maxConcurrentRequests),m=[...d.keys()];let g=0;const h=async y=>{const A=d.get(y)??[],[w,u]=y.split("/");if(!w||!u)return;let $;try{$=await c.listTags(w,u)}catch{for(const l of A)p.push({file:l.file,reason:`failed to list tags for ${y}`});return}for(const l of A){const S=l.slug;let v;if(l.ignoreReason?v=l.ignoreReason:Ne(S,s.exclude)?v="matched --exclude":s.include.length>0&&!Ne(S,s.include)?v="not matched by --include":s.respectDependabotConfig&&n&&ve(S,"actions",n)&&(v="ignored by dependabot/renovate config"),v){a.push({currentRef:l.ref,currentVersion:l.isSha?l.trailingComment?.replace(/^#\s*/,""):l.ref,ecosystem:"actions",file:l.file,ignored:!0,line:l.line,name:S,newRef:l.ref,newVersion:void 0,original:l.original,reason:v,replacement:l.original,updateType:"unknown"});continue}if(!s.includeBranches&&!l.isSha&&Ln(l.ref)){a.push({currentRef:l.ref,currentVersion:l.ref,ecosystem:"actions",file:l.file,ignored:!0,line:l.line,name:S,newRef:l.ref,newVersion:void 0,original:l.original,reason:"branch reference (use --include-branches)",replacement:l.original,updateType:"unknown"});continue}const C=l.isSha?l.trailingComment?.replace(/^#\s*/,"").split(/\s+/)[0]??"":l.ref,T=W(C);if(l.isSha&&!T&&s.mode!=="latest"){a.push({currentRef:l.ref,currentVersion:void 0,ecosystem:"actions",file:l.file,ignored:!0,line:l.line,name:S,newRef:l.ref,newVersion:void 0,original:l.original,reason:`SHA pin has no version-hint comment; cannot apply --target=${s.mode}`,replacement:l.original,updateType:"unknown"});continue}const E=we($.parsed,T,s.mode);if(!E)continue;if(s.minAgeDays!==void 0){const P=await c.resolveRef(w,u,E.sha),N=P?.committedAt?new Date(P.committedAt).getTime():void 0;if(N&&(Date.now()-N)/Un<s.minAgeDays){a.push({currentRef:l.ref,currentVersion:T?.raw,ecosystem:"actions",file:l.file,ignored:!0,line:l.line,name:S,newRef:l.ref,newVersion:E.raw,original:l.original,reason:`release younger than ${String(s.minAgeDays)} days`,replacement:l.original,updateType:"unknown"});continue}}const I=s.style==="sha"||l.isSha?E.sha:E.raw,O=Pn(l,E.sha,E.raw,s.style);o.push({currentRef:l.ref,currentVersion:T?.raw??l.trailingComment?.replace(/^#\s*/,""),ecosystem:"actions",file:l.file,line:l.line,name:S,newRef:I,newVersion:E.raw,original:l.original,replacement:O,updateType:ke(T,E),url:`https://github.com/${w}/${u}/releases/tag/${E.raw}`})}},b=[];for(let y=0;y<Math.min(f,m.length);y++)b.push((async()=>{for(;g<m.length;){const A=m[g];g+=1,A!==void 0&&await h(A)}})());await Promise.all(b);const k=Rn(e,o);return{failed:p,ignored:a,updates:k}},Mn=e=>e.toSorted((t,n)=>t.file!==n.file?t.file<n.file?-1:1:t.line-n.line),nt=e=>{const t=[],n=[];if(e.length===0)return{applied:t,skipped:n};const s=Mn(e),i=new Map;for(const r of s){const o=i.get(r.file)??[];o.push(r),i.set(r.file,o)}for(const[r,o]of i){let a;try{a=z(r)}catch(m){for(const g of o)n.push({reason:`read failed: ${m.message}`,update:g});continue}const p=a.includes(`\r
|
|
3
3
|
`)?`\r
|
|
4
4
|
`:`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{createRequire as wt}from"node:module";import{a as x,$ as
|
|
1
|
+
import{createRequire as wt}from"node:module";import{a as x,$ as nt,U as yt,v as it,e as P,q as Tt}from"../packem_shared/index-DHD8wb6Z.js";import{y as m,X as E,m as b,v as vt,j as St}from"./catalog.js";import at from"./index.js";import{x as ot}from"../packem_shared/main-BP-w-K-6.js";import{y as B}from"../packem_shared/isAccessibleSync-DYKTrrvc-CSnBISfV.js";import{d as $t}from"./cli-main.js";import{l as At}from"../packem_shared/spinner-BM_0Bj6x.js";import{C as ct,D as O,T as dt}from"../packem_shared/symbols-BXDZ_sKt.js";import{b as z,F as C,q as D,X as L,J as It}from"../packem_shared/index.server-BAjDJSEu.js";import{withEnhancedPath as Mt}from"@visulima/task-runner";let mt;const kt=t=>(mt??=wt(import.meta.url))(t),I=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,G=t=>{if(typeof I<"u"&&I.versions&&I.versions.node){const[e,s]=I.versions.node.split(".").map(Number);if(e>22||e===22&&s>=3||e===20&&s>=16)return I.getBuiltinModule(t)}return kt(t)},{readFileSync:bt,writeFileSync:xt,unlinkSync:Ct}=G("node:fs"),{randomBytes:Et}=G("node:crypto"),{availableParallelism:V}=G("node:os");class A extends Error{constructor(e,s){super(e,s),this.name=this.constructor.name}}class Rt extends A{}class T extends A{}class W extends A{}class R extends A{stderr;constructor(e,s,r){super(e,r),this.stderr=s}}class X extends A{}class $ extends A{commandTitle;constructor(e,s,r){super(s,r),this.commandTitle=e}}const lt=t=>t.includes("/"),F=(t,e)=>e?t.toLowerCase():t,jt=(t,e,s,r={})=>{const n=lt(t),i=r.caseInsensitive===!0,c=F(t,i),a=[];for(const o of e){const l=n?x(s,o):nt(o);at(c,F(l,i))&&a.push(o)}return a},_t=(t,e,s,r={})=>{if(!e||e.length===0)return[...t];const n=r.caseInsensitive===!0;return t.filter(i=>{for(const c of e){const a=lt(c)?x(s,i):nt(i),o=F(c,n);if(at(o,F(a,n)))return!1}return!0})},U=t=>typeof t=="object"&&t!==null&&typeof t.title=="string"&&typeof t.task=="function",_=t=>typeof t=="object"&&t!==null&&typeof t.command=="string"&&typeof t.task!="function",Pt=(t,e)=>{const s=x(t,e);return s===""||!s.startsWith("..")&&!it(s)},Ot=(t,e)=>{let s;for(const r of e)Pt(r,t)&&(s===void 0||r.length>s.length)&&(s=r);return s},Ft=async t=>{let e=0,s=0;const r=()=>(e+=1,`pattern-${e}`),n=()=>(s+=1,`cmd-${s}`),i=(o,l,f,d)=>{if(o.perPackage===!0){const u=t.workspacePackages??[],g=new Map;for(const h of f){const w=Ot(h,u)??t.cwd,k=g.get(w)??[];k.push(x(w,h)),g.set(w,k)}for(const h of[...g.keys()].sort()){const w=x(t.cwd,h)||".";d.push({command:o.command,cwd:h,files:g.get(h)??[],id:n(),source:"string",title:`${o.command} — ${w}`})}return}if(o.cwd!==void 0){const u=yt(t.cwd,o.cwd);d.push({command:o.command,cwd:u,files:f,id:n(),source:"string",title:`${o.command} — ${x(t.cwd,u)||"."}`});return}d.push({command:o.command,files:l,id:n(),source:"string",title:o.command})},c=async(o,l,f,d)=>{if(typeof o=="string"){d.push({command:o,files:l,id:n(),source:"string",title:o});return}if(Array.isArray(o)){for(const u of o)await c(u,l,f,d);return}if(_(o)){i(o,l,f,d);return}if(typeof o=="function"){const u=await o([...l]);if(typeof u=="string"){d.push({command:u,files:l,id:n(),source:"function",title:u});return}if(Array.isArray(u)){for(const g of u)if(typeof g=="string")d.push({command:g,files:l,id:n(),source:"function",title:g});else if(_(g))i(g,l,f,d);else if(U(g))d.push({files:l,id:n(),run:g.task,source:"custom",title:g.title});else throw new T("Task function returned an array with an unsupported entry — expected strings, { command, … }, or { title, task }.");return}if(_(u)){i(u,l,f,d);return}if(U(u)){d.push({files:l,id:n(),run:u.task,source:"custom",title:u.title});return}throw new T("Task function returned an unsupported value — expected string, string[], { command, … }, or { title, task }.")}if(U(o)){d.push({files:l,id:n(),run:o.task,source:"custom",title:o.title});return}throw new T("Unsupported task value — expected string, string[], function, { command, … }, or { title, task }.")},a=[];for(const[o,l]of Object.entries(t.config)){const f=jt(o,t.files,t.cwd,{caseInsensitive:t.caseInsensitive===!0});if(f.length===0)continue;const d=t.relative?f.map(g=>x(t.cwd,g)):f,u=[];await c(l,d,f,u),u.length!==0&&a.push({commands:u,files:d,id:r(),pattern:o,title:`${o} — ${f.length} file${f.length===1?"":"s"}`})}return a},Nt=async t=>{if(t.config!==void 0)return t.config;throw new T(`No staged config provided. Add \`staged\` to your vis.config.ts:
|
|
2
2
|
|
|
3
3
|
import { defineConfig } from "@visulima/vis/config";
|
|
4
4
|
|
|
@@ -6,16 +6,16 @@ import{createRequire as wt}from"node:module";import{a as x,$ as it,U as yt,v as
|
|
|
6
6
|
staged: { "*.ts": "eslint --fix" },
|
|
7
7
|
});
|
|
8
8
|
|
|
9
|
-
Coming from lint-staged or nano-staged? Run \`vis migrate lint-staged\` (or \`vis migrate nano-staged\`) to move the config in and remove the legacy files.`)},K=t=>{if(typeof t!="object"||t===null)throw new T("Staged config must be an object mapping glob patterns to tasks.");const e=Object.entries(t);if(e.length===0)throw new T("Staged config is empty — at least one glob pattern is required.");for(const[s,r]of e){if(!s||s.trim()==="")throw new T("Staged config keys must be non-empty glob patterns.");
|
|
9
|
+
Coming from lint-staged or nano-staged? Run \`vis migrate lint-staged\` (or \`vis migrate nano-staged\`) to move the config in and remove the legacy files.`)},K=t=>{if(typeof t!="object"||t===null)throw new T("Staged config must be an object mapping glob patterns to tasks.");const e=Object.entries(t);if(e.length===0)throw new T("Staged config is empty — at least one glob pattern is required.");for(const[s,r]of e){if(!s||s.trim()==="")throw new T("Staged config keys must be non-empty glob patterns.");ut(s,r)}return t},ut=(t,e)=>{if(typeof e=="string"){if(e.trim()==="")throw new T(`Task for "${t}" is an empty string.`);return}if(Array.isArray(e)){if(e.length===0)throw new T(`Task array for "${t}" is empty.`);for(const s of e)ut(t,s);return}if(typeof e!="function"){if(typeof e=="object"&&e!==null&&typeof e.command=="string"&&typeof e.task=="function")throw new T(`Task for "${t}" sets both \`command\` and \`task\` — use one or the other.`);if(_(e)){if(e.command.trim()==="")throw new T(`Command task for "${t}" has an empty \`command\`.`);return}if(!Dt(e))throw new T(`Invalid task for "${t}" — expected string, string[], function, { command, … }, or { title, task } object.`)}},Dt=t=>typeof t=="object"&&t!==null&&typeof t.title=="string"&&typeof t.task=="function",Y=2048,p=async(t,e)=>{const s=e.input===void 0?void 0:typeof e.input=="string"?e.input:e.input.toString("utf8"),r=await ot("git",[...t],{nodeOptions:{cwd:e.cwd,env:e.env?{...process.env,...e.env}:void 0,stdio:s===void 0?["ignore","pipe","pipe"]:["pipe","pipe","pipe"]},stdin:s}),n=typeof r.exitCode=="number"?r.exitCode:1;if(n!==0&&!e.lenient){const{stderr:i}=r,c=i.length>Y?`${i.slice(0,Y)}…`:i;throw new R(`git ${t.join(" ")} failed with exit code ${n}: ${c.trim()}`,i)}return{exitCode:n,stderr:r.stderr,stdout:r.stdout}},j=async(t,e)=>{const{stdout:s}=await p(t,e);return s.trim()},Lt=async t=>{const e=await p(["rev-parse","--is-inside-work-tree"],{cwd:t,lenient:!0});return e.exitCode===0&&e.stdout.trim()==="true"},Ut=async t=>j(["rev-parse","--absolute-git-dir"],{cwd:t}),ft=async t=>j(["rev-parse","--show-toplevel"],{cwd:t}),J=async t=>j(["write-tree"],{cwd:t}),qt=async t=>{const e=await p(["rev-parse","HEAD^{tree}"],{cwd:t,lenient:!0});return e.exitCode===0?e.stdout.trim():""},M={major:2,minor:32},Gt=t=>{const e=/git version (\d+)\.(\d+)/.exec(t);if(!e)return null;const s=Number.parseInt(e[1]??"",10),r=Number.parseInt(e[2]??"",10);return Number.isNaN(s)||Number.isNaN(r)?null:{major:s,minor:r}},Ht=async t=>{const e=Gt(await j(["--version"],{cwd:t}));if(e===null)return;if(e.major<M.major||e.major===M.major&&e.minor<M.minor)throw new R(`Git ${M.major}.${M.minor} or newer is required; found ${e.major}.${e.minor}.`)},Bt="ACMR",Z=500,zt=async t=>{const{stdout:e}=await p(["diff-files","--raw","-z"],{cwd:t}),s=e.split("\0").filter(n=>n.length>0),r=[];for(let n=0;n<s.length;n+=1){const i=s[n];if(!i?.startsWith(":"))continue;const c=i.slice(1).split(" "),a=c[3],o=c[4],l=s[n+1];n+=1,o==="A"&&a!==void 0&&/^0+$/.test(a)&&l!==void 0&&r.push(l)}return r},Q=async t=>{const{stdout:e}=await p(["ls-files","--others","--exclude-standard","-z"],{cwd:t});return e.split("\0").filter(s=>s.length>0)},Vt=async(t,e)=>{if(t.length===0)return;const s=`${t.join("\0")}\0`;await p(["rm","--cached","--quiet","--pathspec-from-file=-","--pathspec-file-nul","--"],{cwd:e.cwd,input:s})},Wt=async t=>{const e=t.diffFilter??Bt,s=t.diff===void 0?["diff","--name-only","-z",`--diff-filter=${e}`,"--staged"]:["diff","--name-only","-z",`--diff-filter=${e}`,...t.diff.split(/\s+/).filter(Boolean)],{stdout:r}=await p(s,{cwd:t.cwd}),n=r.split("\0").filter(c=>c.length>0);if(n.length===0)return[];const i=t.workTree??await ft(t.cwd);return n.map(c=>it(c)?c:P(i,c))},Xt=async(t,e)=>{if(t.length===0)return null;const s=[];for(let i=0;i<t.length;i+=Z){const c=t.slice(i,i+Z),{stdout:a}=await p(["diff","--binary","--unified=0","--no-color","--no-ext-diff","--src-prefix=a/","--dst-prefix=b/","--patch","--submodule=short","--",...c],{cwd:e.cwd});a.length>0&&s.push(a)}if(s.length===0)return null;const r=s.join(""),n=r.endsWith(`
|
|
10
10
|
`)?r:`${r}
|
|
11
|
-
`;return Buffer.from(n,"utf8")},Kt=async t=>{const{stdout:e}=await
|
|
11
|
+
`;return Buffer.from(n,"utf8")},Kt=async t=>{const{stdout:e}=await p(["status","--porcelain=v1","-z"],{cwd:t}),s=e.split("\0"),r=[];for(let n=0;n<s.length;n+=1){const i=s[n];if(i===void 0||i.length<4)continue;const c=i.charAt(0),a=i.charAt(1),o=i.slice(3),l=c==="R"||c==="C"||a==="R"||a==="C";c!==" "&&c!=="?"&&a!==" "&&a!=="?"&&r.push(o),l&&(n+=1)}return r},Yt=async(t,e)=>{if(t.length===0)return;const s=`${t.join("\0")}\0`;await p(["checkout","--force","--pathspec-from-file=-","--pathspec-file-nul","--"],{cwd:e.cwd,input:s})},Jt=async(t,e)=>{if(await p(["update-index","--again"],{cwd:e.cwd,lenient:!0}),t.length===0)return;const s=`${t.join("\0")}\0`;await p(["add","-u","--pathspec-from-file=-","--pathspec-file-nul","--"],{cwd:e.cwd,input:s})},Zt="vis_staged_automatic_backup",ht=()=>`${Zt}-${process.pid}-${Date.now()}-${Et(3).toString("hex")}`,Qt=async t=>{const e=await j(["stash","create"],{cwd:t});return e.length===0?null:(await p(["stash","store","-m",ht(),e],{cwd:t}),e)},te=async(t,e)=>{const{exitCode:s,stdout:r}=await p(["reflog","--format=%H %gs","refs/stash"],{cwd:t,lenient:!0});if(s!==0)return null;for(const n of r.split(/\r?\n/)){const i=n.indexOf(" ");if(i!==-1&&n.slice(i+1).includes(e))return n.slice(0,i)}return null},ee=async t=>{const e=ht(),{exitCode:s,stdout:r}=await p(["stash","push","--keep-index","--include-untracked","--quiet","-m",e],{cwd:t,lenient:!0});if(s!==0)return null;const n=r.trim();return n.length>0&&/no local changes/i.test(n)?null:te(t,e)},se=async(t,e)=>{const{exitCode:s,stdout:r}=await p(["reflog","--format=%H %gd","refs/stash"],{cwd:t,lenient:!0});if(s!==0)return null;for(const n of r.split(/\r?\n/)){const[i,c]=n.split(/\s+/,2);if(i===e&&c!==void 0)return c}return null},gt=async(t,e)=>{const{exitCode:s}=await p(["rev-parse","--verify","--quiet",`${e}^{commit}`],{cwd:t,lenient:!0});return s===0},re=async(t,e)=>{const s=await se(t,e);if(s===null)return null;const{exitCode:r,stdout:n}=await p(["rev-parse","--verify","--quiet",s],{cwd:t,lenient:!0});return r===0&&n.trim()===e?s:null},q=async(t,e)=>{if(e===null)return;const s=await re(t,e);s!==null&&await p(["stash","drop","--quiet",s],{cwd:t})},ne=async(t,e)=>{if(e===null)throw new W("Backup stash was not found — can't revert working tree.");if(!await gt(t,e))throw new W(`Backup stash ${e} is no longer reachable — can't revert working tree.`);await p(["reset","--hard","HEAD"],{cwd:t}),await p(["stash","apply","--index","--quiet",e],{cwd:t})},ie=async(t,e)=>{e!==null&&await gt(t,e)&&(await p(["stash","apply","--quiet",e],{cwd:t}),await q(t,e))};class ae{stagedFiles=[];partiallyStaged=[];workTree="";gitDir="";preTaskIndexTree="";postTaskIndexTree="";headTree="";revertApplied=!1;warnings=[];cwd;options;patch=null;backupStashSha=null;merge=[];shouldStash;shouldHidePartial;shouldHideUnstaged;shouldHideAll;hideAllStashSha=null;intentToAddPaths=[];preTaskUntracked=new Set;constructor(e){this.cwd=e.cwd??process.cwd(),this.options=e,this.shouldStash=e.stash!==!1&&e.diff===void 0,this.shouldHidePartial=e.hidePartiallyStaged!==!1,this.shouldHideUnstaged=e.hideUnstaged===!0,this.shouldHideAll=e.hideAll===!0}async prepare(){if(!await Lt(this.cwd))throw new R(`Not a git repository: ${this.cwd}`);await Ht(this.cwd),this.workTree=await ft(this.cwd),this.gitDir=await Ut(this.cwd),this.stagedFiles=await Wt({cwd:this.workTree,diff:this.options.diff,diffFilter:this.options.diffFilter,workTree:this.workTree}),this.partiallyStaged=this.stagedFiles.length===0?[]:await Kt(this.workTree),this.snapshotMergeState(),this.intentToAddPaths=await zt(this.workTree),this.intentToAddPaths.length>0&&await Vt(this.intentToAddPaths,{cwd:this.workTree}),this.shouldStash?this.backupStashSha=await Qt(this.workTree):this.partiallyStaged.length>0&&this.warnings.push("Running with --no-stash on partially-staged files — unstaged deltas will be captured to a patch, but if re-applying the patch fails after tasks run the changes cannot be recovered."),this.shouldHideAll?this.hideAllStashSha=await ee(this.workTree):await this.hideUnstagedChanges(),this.preTaskIndexTree=this.stagedFiles.length===0?"":await J(this.workTree),this.postTaskIndexTree=this.preTaskIndexTree,this.headTree=await qt(this.workTree),this.preTaskUntracked=new Set(await Q(this.workTree))}async applyModifications({autoStage:e=!1}={}){if(this.stagedFiles.length===0)return;const s=this.stagedFiles.map(r=>x(this.workTree,r));if(await Jt(s,{cwd:this.workTree}),e){const n=(await Q(this.workTree)).filter(i=>!this.preTaskUntracked.has(i));if(n.length>0){const i=`${n.join("\0")}\0`;await p(["add","--pathspec-from-file=-","--pathspec-file-nul","--"],{cwd:this.workTree,input:i})}}if(this.intentToAddPaths.length>0)try{await p(["add","--intent-to-add","--",...this.intentToAddPaths],{cwd:this.workTree})}catch{}this.postTaskIndexTree=await J(this.workTree)}indexTreeChanged(){return this.preTaskIndexTree.length>0&&this.postTaskIndexTree.length>0&&this.preTaskIndexTree!==this.postTaskIndexTree}postTaskIndexMatchesHead(){return this.postTaskIndexTree.length>0&&this.headTree.length>0&&this.postTaskIndexTree===this.headTree}async restoreUnstagedChanges(){if(this.revertApplied||this.patch===null||this.shouldHideAll)return;const e=["apply","--whitespace=nowarn","--recount","--unidiff-zero"];let s;try{await p(e,{cwd:this.workTree,input:this.patch});return}catch(r){s=r instanceof R?r.stderr:String(r)}try{await p([...e,"--3way"],{cwd:this.workTree,input:this.patch})}catch(r){const n=r instanceof R&&r.stderr?r.stderr:String(r);throw new X(`Failed to re-apply unstaged changes after running tasks. Original changes remain in the backup stash — recover with \`git stash list\` and \`git stash apply\`.
|
|
12
12
|
First attempt: ${s??"(no stderr)"}
|
|
13
|
-
Second attempt: ${n}`,{cause:r})}}async revert(){if(this.backupStashSha!==null){try{await
|
|
14
|
-
`)},c=
|
|
15
|
-
`):
|
|
16
|
-
`)},info({message:
|
|
17
|
-
`);g.length>0&&l.push(g);const h=d.process?.signalCode??null;if(d.aborted||h!==null||u.exitCode===void 0){const
|
|
18
|
-
`)}},
|
|
13
|
+
Second attempt: ${n}`,{cause:r})}}async revert(){if(this.backupStashSha!==null){try{await ne(this.workTree,this.backupStashSha)}catch(e){throw new X("Revert failed while restoring the backup stash. Use `git stash list` to recover manually.",{cause:e})}if(await q(this.workTree,this.backupStashSha),this.intentToAddPaths.length>0)try{await p(["add","--intent-to-add","--",...this.intentToAddPaths],{cwd:this.workTree})}catch{}this.revertApplied=!0}}async cleanup(e){if(this.restoreMergeState(),this.hideAllStashSha!==null)try{await ie(this.workTree,this.hideAllStashSha)}catch{}e&&this.backupStashSha!==null&&!this.revertApplied&&await q(this.workTree,this.backupStashSha)}recoveryHint(){return this.backupStashSha===null?null:`Backup stash is preserved (sha ${this.backupStashSha.slice(0,7)}) — restore with: git stash apply --index ${this.backupStashSha}`}async hideUnstagedChanges(){const e=new Set(this.stagedFiles.map(r=>x(this.workTree,r))),s=this.shouldHideUnstaged?[...e]:this.shouldHidePartial?this.partiallyStaged.filter(r=>e.has(r)):[];s.length!==0&&(this.patch=await Xt(s,{cwd:this.workTree}),this.patch!==null&&await Yt(s,{cwd:this.workTree}))}snapshotMergeState(){this.gitDir.length!==0&&(this.merge=["MERGE_HEAD","MERGE_MODE","MERGE_MSG"].map(e=>{const s=P(this.gitDir,e);return B(s)?{body:bt(s),existed:!0,name:e}:{body:null,existed:!1,name:e}}))}restoreMergeState(){if(!(this.gitDir.length===0||this.merge.length===0))for(const e of this.merge){const s=P(this.gitDir,e.name);try{e.existed&&e.body!==null?xt(s,e.body):B(s)&&Ct(s)}catch{}}}}const oe=t=>{switch(t){case"failed":return"red";case"running":return"cyan";case"skipped":return"yellow";case"success":return"green";default:return"gray"}},tt=t=>{if(t==="running")return m.jsx(At,{type:"dots"});const e=t==="failed"?ct:t==="skipped"?O:t==="success"?dt:O;return m.jsx(b,{color:oe(t),children:e})},et=({state:t,tick:e,verbose:s})=>m.jsxs(E,{flexDirection:"column",children:[[...t.patterns.values()].map(r=>m.jsxs(E,{flexDirection:"column",children:[m.jsxs(E,{children:[tt(r.status),m.jsxs(b,{children:[" ",r.title]})]}),[...r.commands.values()].map(n=>m.jsxs(E,{flexDirection:"column",marginLeft:2,children:[m.jsxs(E,{children:[tt(n.status),m.jsxs(b,{children:[" ",n.title," "]}),n.status!=="pending"&&n.status!=="running"?m.jsxs(b,{color:"gray",children:["(",n.durationMs,"ms)"]}):null]}),s&&n.output?m.jsx(E,{flexDirection:"column",marginLeft:2,children:n.output.split(/\r?\n/).slice(0,20).map((i,c)=>m.jsx(b,{color:"gray",children:i},`${n.id}-line-${c}`))}):null,n.status==="failed"&&n.error?m.jsx(E,{marginLeft:2,children:m.jsx(b,{color:"red",children:n.error.message})}):null]},n.id))]},r.id)),t.infoMessages.map((r,n)=>m.jsx(b,{color:"gray",children:r},`info-${n}`)),t.warnMessages.map((r,n)=>m.jsx(b,{color:"yellow",children:r},`warn-${n}`)),t.errorMessages.map(({message:r},n)=>m.jsx(b,{color:"red",children:r},`err-${n}`))]}),ce=(t={})=>{const e=t.verbose===!0,s={errorMessages:[],infoMessages:[],patterns:new Map,started:!1,warnMessages:[]};let r=0;const n=$t(m.jsx(et,{state:s,tick:r,verbose:e}),{exitOnCtrlC:!1,stdout:process.stderr}),i=()=>{r+=1,n.rerender(m.jsx(et,{state:s,tick:r,verbose:e}))};return{commandEnd({commandId:c,durationMs:a,error:o,output:l,patternId:f,status:d}){const u=s.patterns.get(f)?.commands.get(c);u&&(u.status=d,u.durationMs=a,u.output=l,u.error=o,i())},commandStart({commandId:c,patternId:a}){const o=s.patterns.get(a)?.commands.get(c);o&&(o.status="running",i())},error({error:c,message:a}){s.errorMessages.push({error:c,message:a}),i()},info({message:c}){s.infoMessages.push(c),i()},patternEnd({patternId:c,status:a}){const o=s.patterns.get(c);o&&(o.status=a,i())},patternStart({patternId:c}){const a=s.patterns.get(c);a&&(a.status="running",i())},start({patterns:c}){s.started=!0;for(const a of c){const o=new Map;for(const l of a.commands)o.set(l.id,{durationMs:0,id:l.id,status:"pending",title:l.title});s.patterns.set(a.id,{commands:o,id:a.id,status:"pending",title:a.title})}i()},async stop(){n.unmount(),await n.waitUntilExit()},warn({message:c}){s.warnMessages.push(c),i()}}},st=(t={})=>{const{quiet:e=!1,verbose:s=!1}=t,r=new Map,n=new Map,i=a=>{e||process.stderr.write(`${a}
|
|
14
|
+
`)},c=a=>{switch(a){case"failed":return L(ct);case"running":return D(">");case"skipped":return z(O);case"success":return It(dt);default:return C(O)}};return{commandEnd({commandId:a,durationMs:o,error:l,output:f,status:d}){const u=n.get(a)??a,g=C(`(${o}ms)`);if(i(` ${c(d)} ${u} ${g}`),d==="failed"&&l&&i(C(l.message)),(d==="failed"||s)&&f&&f.trim().length>0)for(const h of f.split(/\r?\n/))i(` ${C(h)}`)},commandStart({commandId:a}){if(!s)return;const o=n.get(a)??a;i(` ${C("…")} ${o}`)},error({error:a,message:o}){e?process.stderr.write(`${L(o)}
|
|
15
|
+
`):i(L(o)),a?.stack&&(s||!e)&&process.stderr.write(`${C(a.stack)}
|
|
16
|
+
`)},info({message:a}){i(C(a))},patternEnd({patternId:a,status:o}){const l=r.get(a)??a;i(`${c(o)} ${l}`)},patternStart({patternId:a}){const o=r.get(a)??a;i(`${D(">")} ${o}`)},start({patterns:a}){if(a.length===0){i(C("No staged files matched any pattern."));return}const o=new Set(a.flatMap(l=>l.files)).size;i(`${D(">")} Running staged tasks on ${o} file${o===1?"":"s"} across ${a.length} pattern${a.length===1?"":"s"}`);for(const l of a){r.set(l.id,l.title);for(const f of l.commands)n.set(f.id,f.title)}},stop(){},warn({message:a}){i(z(a))}}},de=async t=>{const{env:e}=process;if(t.debug===!0||t.quiet===!0||e.NODE_ENV==="test"||e.TERM==="dumb"||e.CI!==void 0||!process.stderr.isTTY)return st({quiet:t.quiet,verbose:t.verbose});try{return ce({verbose:t.verbose})}catch{return st({quiet:t.quiet,verbose:t.verbose})}},le=t=>{const e=[];let s="",r=!1,n=!1;for(let i=0;i<t.length;i+=1){const c=t[i];if(c===void 0)break;if(c==="\\"&&!r&&i+1<t.length){const a=t[i+1];if(a!==void 0){n&&a!=='"'&&a!=="\\"&&(s+=c),s+=a,i+=1;continue}}if(c==='"'&&!r){n=!n;continue}if(c==="'"&&!n){r=!r;continue}if(!r&&!n&&/\s/.test(c)){s.length>0&&(e.push(s),s="");continue}s+=c}if(r||n)throw new T(`Unterminated ${r?"single":"double"} quote in command: ${t}`);return s.length>0&&e.push(s),e},pt=process.platform==="win32"?28e3:131072,ue=(t,e,s)=>{const r=[];let n=[],i=e;const c=s<=0?pt:s;for(const a of t){const o=Buffer.byteLength(a)+1;n.length>0&&i+o>c&&(r.push(n),n=[],i=e),n.push(a),i+=o}return n.length>0&&r.push(n),r},fe=async(t,e,s)=>{const r=le(t);if(r.length===0)throw new $(t,"Empty command for staged task.");const[n,...i]=r;if(n===void 0)throw new $(t,"Empty command for staged task.");const c=Buffer.byteLength(n)+i.reduce((f,d)=>f+Buffer.byteLength(d)+1,0),a=ue(e,c,s.maxArgLength??pt),o=Date.now(),l=[];for(const f of a){if(s.signal?.aborted===!0)throw new $(t,"Task aborted by earlier failure.");const d=ot(n,[...i,...f],{nodeOptions:{cwd:s.cwd,env:he(s.env,s.cwd),killSignal:s.killSignal??"SIGTERM",stdio:["ignore","pipe","pipe"]},...s.signal===void 0?{}:{signal:s.signal}}),u=await d,g=[u.stdout,u.stderr].filter(w=>w.length>0).join(`
|
|
17
|
+
`);g.length>0&&l.push(g);const h=d.process?.signalCode??null;if(d.aborted||h!==null||u.exitCode===void 0){const w=d.aborted?"Task aborted by earlier failure.":h===null?g.trim()||"Task exited without a numeric status code.":`Task killed by signal ${h}.`;throw new $(t,w)}if(u.exitCode!==0)throw new $(t,g.trim()||`Exit code ${u.exitCode} from ${n}`)}return{durationMs:Date.now()-o,output:l.join(`
|
|
18
|
+
`)}},he=(t,e)=>{const s={...process.env};process.stderr.isTTY&&s.FORCE_COLOR===void 0&&s.NO_COLOR===void 0&&(s.FORCE_COLOR="1");const r=t?{...s,...t}:s;return Mt(r,e)},ge=async(t,e,s)=>{const r=we(s.concurrent,t.length),n=[],i=new AbortController;let c=!1,a=0;const o=()=>{c||(c=!0,s.continueOnError||i.abort())};s.externalSignal&&(s.externalSignal.aborted?o():s.externalSignal.addEventListener("abort",()=>{o()},{once:!0}));const l=h=>{for(const w of h.commands)e.commandEnd({commandId:w.id,durationMs:0,patternId:h.id,status:"skipped"})},f=async h=>{if(c){l(h),e.patternEnd({patternId:h.id,status:"skipped"});return}e.patternStart({patternId:h.id});let w="success";for(const k of h.commands){if(c){e.commandEnd({commandId:k.id,durationMs:0,patternId:h.id,status:"skipped"}),w=w==="success"?"skipped":w;continue}e.commandStart({commandId:k.id,patternId:h.id});const v=await pe(k,s,i.signal),S=v.status==="failed"&&i.signal.aborted?{...v,status:"skipped"}:v;if(e.commandEnd({commandId:k.id,durationMs:S.durationMs,error:S.error,output:S.output,patternId:h.id,status:S.status}),S.status==="failed"){n.push(k.title),w="failed",o();break}if(S.status==="skipped"){w=w==="success"?"skipped":w;break}}e.patternEnd({patternId:h.id,status:w})},d=async()=>{for(;a<t.length;){const h=t[a];a+=1,h&&await f(h)}},u=[];for(let h=0;h<Math.min(r,t.length);h+=1)u.push(d());await Promise.all(u);const g=s.externalSignal?.aborted===!0;return{failedCommands:n,success:n.length===0&&!g}},pe=async(t,e,s)=>{const r=Date.now();try{if(t.source==="custom"&&t.run)return await t.run([...t.files]),{durationMs:Date.now()-r,status:"success"};if(t.command){const n=await fe(t.command,t.files,{cwd:t.cwd??e.cwd,killSignal:e.killSignal,maxArgLength:e.maxArgLength,signal:s});return{durationMs:n.durationMs,output:e.verbose?n.output:void 0,status:"success"}}return{durationMs:Date.now()-r,error:new $(t.title,"Command has no invocation target."),status:"failed"}}catch(n){const i=n instanceof Error?n:new Error(String(n));return{durationMs:Date.now()-r,error:i,output:i instanceof $?i.message:void 0,status:"failed"}}},we=(t,e)=>{if(t===!1)return 1;if(t===!0){const r=Math.max(1,typeof V=="function"?V():4);return Math.min(Math.max(1,e),r)}const s=Math.floor(t);return s>0?s:1},me=!0,ke=t=>{try{return!Tt(t)}catch{return!1}},ye=t=>{try{const e=vt(t);return e?St(t,e).map(s=>P(t,s)):[]}catch{return[]}},Te=async(t={})=>{const e=t.cwd??process.cwd(),s=await de(t),r=await Nt(t);typeof r!="function"&&K(r);const n=new ae({...t,cwd:e}),i=new AbortController;let c=!1;const a=d=>{if(c){process.removeListener("SIGINT",a),process.removeListener("SIGTERM",a),process.kill(process.pid,d);return}c=!0,s.warn({message:`Received ${d} — cancelling staged tasks and restoring state. Press Ctrl+C again to abort.`}),i.abort()};process.on("SIGINT",a),process.on("SIGTERM",a);let o={failedCommands:[],ranTasks:!1,success:!0},l=!1,f=!1;try{await n.prepare(),l=!0;for(const v of n.warnings)s.warn({message:v});if(n.stagedFiles.length===0)return t.allowEmpty!==!0&&s.info({message:"No staged files found."}),f=!0,{failedCommands:[],ranTasks:!1,success:!0};const d=ke(e),u=_t(n.stagedFiles,t.ignore,e,{caseInsensitive:d});if(u.length===0&&n.stagedFiles.length>0)return s.info({message:"Every staged file was excluded by the `ignore` list."}),f=!0,{failedCommands:[],ranTasks:!1,success:!0};const g=typeof r=="function"?K(await r([...u])):r,h=await Ft({caseInsensitive:d,config:g,cwd:e,files:u,relative:t.relative,workspacePackages:ye(e)});if(s.start({patterns:h}),h.length===0)return s.info({message:"No staged files matched any pattern."}),f=!0,{failedCommands:[],ranTasks:!1,success:!0};const{failedCommands:w,success:k}=await ge(h,s,{concurrent:t.concurrent??me,continueOnError:t.continueOnError===!0,cwd:e,externalSignal:i.signal,killSignal:t.killSignal,maxArgLength:t.maxArgLength,verbose:t.verbose});if(o={failedCommands:w,ranTasks:!0,success:k},k){if(t.diff===void 0&&(await n.applyModifications({autoStage:t.autoStage===!0}),t.failOnChanges===!0&&n.indexTreeChanged()&&(s.warn({message:"Tasks modified staged content — failing because --fail-on-changes is set."}),o={failedCommands:[...w],ranTasks:!0,success:!1}),t.allowEmpty!==!0&&n.postTaskIndexMatchesHead()))throw new Rt("All staged changes were reverted by tasks. Re-stage changes or rerun with --allow-empty.")}else if(t.revert===!0)s.info({message:"Reverting working tree from backup stash."}),await n.revert();else{const v=n.recoveryHint();v&&s.warn({message:v})}return await n.restoreUnstagedChanges(),f=o.success,o}catch(d){const u=d instanceof Error?d.message:String(d),g=d instanceof Error?d:new Error(u);if(s.error({error:g,message:u}),d instanceof A)return{failedCommands:o.failedCommands,ranTasks:o.ranTasks,success:!1};throw d}finally{if(process.removeListener("SIGINT",a),process.removeListener("SIGTERM",a),l)try{await n.cleanup(f)}catch(d){s.error({error:d,message:"Cleanup failed."})}await s.stop()}},ve="VIS_STAGED_CONCURRENT",rt=t=>{const e=t.trim();if(e==="true"||e==="")return!0;if(e==="false")return!1;const s=Number(e);return Number.isNaN(s)?!0:s},Se=(t,e)=>{const s={};e!==void 0&&(s.config=e);const r=y=>t[y]===void 0?void 0:!!t[y],n=y=>{const N=t[y];return typeof N=="string"&&N.length>0?N:void 0},i=r("allow-empty");i!==void 0&&(s.allowEmpty=i);const c=r("auto-stage");c!==void 0&&(s.autoStage=c);const a=r("continue-on-error");a!==void 0&&(s.continueOnError=a);const o=r("debug");o!==void 0&&(s.debug=o);const l=r("fail-on-changes");l!==void 0&&(s.failOnChanges=l);const f=r("hide-partially-staged");f!==void 0&&(s.hidePartiallyStaged=f);const d=r("hide-unstaged");d!==void 0&&(s.hideUnstaged=d);const u=r("quiet");u!==void 0&&(s.quiet=u);const g=r("relative");g!==void 0&&(s.relative=g);const h=r("revert");h!==void 0&&(s.revert=h);const w=r("stash");w!==void 0&&(s.stash=w);const k=r("verbose");k!==void 0&&(s.verbose=k);const v=n("cwd");v!==void 0&&(s.cwd=v);const S=n("diff");S!==void 0&&(s.diff=S);const H=n("diff-filter");if(H!==void 0&&(s.diffFilter=H),r("force-kill")===!0&&(s.killSignal="SIGKILL"),t.concurrent===void 0){const y=process.env[ve];y!==void 0&&(s.concurrent=rt(y.trim()))}else{const{concurrent:y}=t;s.concurrent=rt(typeof y=="string"?y:typeof y=="number"||typeof y=="boolean"?String(y):"")}return s},Oe=async({options:t,visConfig:e})=>{const r=(e??{}).staged;if(!r)throw new Error(`No "staged" config found in vis.config.ts. Add one:
|
|
19
19
|
|
|
20
20
|
// vis.config.ts
|
|
21
21
|
import { defineConfig } from "@visulima/vis/config";
|
|
@@ -24,4 +24,4 @@ Second attempt: ${n}`,{cause:r})}}async revert(){if(this.backupStashSha!==null){
|
|
|
24
24
|
staged: { '*': 'vis check --fix' },
|
|
25
25
|
});
|
|
26
26
|
|
|
27
|
-
Migrating from lint-staged or nano-staged? Run \`vis migrate lint-staged\` (or \`vis migrate nano-staged\`) to move the config in and remove the legacy files.`);(await
|
|
27
|
+
Migrating from lint-staged or nano-staged? Run \`vis migrate lint-staged\` (or \`vis migrate nano-staged\`) to move the config in and remove the legacy files.`);(await Te(Se(t,r))).success||(process.exitCode=1)};export{Se as buildRunOptions,Oe as default};
|