flins 0.0.1 → 0.0.2
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/dist/index.js +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -98,5 +98,5 @@ ${P.default.cyan(Jf)}
|
|
|
98
98
|
`}}}}).prompt()},_D;var p=W(()=>{yy();yy();P=O(h(),1),Bf=O(Or(),1);Dy=tn(),fb=c("◆","*"),Ji=c("■","x"),xi=c("▲","x"),Ly=c("◇","o"),rb=c("┌","T"),j=c("│","|"),Jf=c("└","—"),SD=c("┐","T"),$D=c("┘","—"),Sy=c("●",">"),ef=c("○"," "),yb=c("◻","[•]"),$y=c("◼","[+]"),ly=c("◻","[ ]"),lD=c("▪","•"),TD=c("─","-"),LD=c("╮","+"),wD=c("├","+"),RD=c("╯","+"),ID=c("╰","+"),oD=c("╭","+"),ib=c("●","•"),nb=c("◆","*"),bb=c("▲","!"),Db=c("■","x"),iy=/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/y,sf=/[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y,pf=/\t{1,1000}/y,ny=/[\u{1F1E6}-\u{1F1FF}]{2}|\u{1F3F4}[\u{E0061}-\u{E007A}]{2}[\u{E0030}-\u{E0039}\u{E0061}-\u{E007A}]{1,3}\u{E007F}|(?:\p{Emoji}\uFE0F\u20E3?|\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation})(?:\u200D(?:\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F\u20E3?))*/yu,df=/(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y,Tb=/\p{M}+/gu,Lb={limit:1/0,ellipsis:""},wb={limit:1/0,ellipsis:"",ellipsisWidth:0},Ry=`${Ib}8;;`,Pi=new RegExp(`(?:\\${Qi}(?<code>\\d+)m|\\${Ry}(?<uri>.*)${wy})`,"y");w={message:(f=[],{symbol:r=P.default.gray(j),secondarySymbol:y=P.default.gray(j),output:i=process.stdout,spacing:n=1,withGuide:b}={})=>{let S=[],D=(b??$f.withGuide)!==!1,$=D?y:"",l=D?`${r} `:"",T=D?`${y} `:"";for(let _=0;_<n;_++)S.push($);let o=Array.isArray(f)?f:f.split(`
|
|
99
99
|
`);if(o.length>0){let[_,...I]=o;_.length>0?S.push(`${l}${_}`):S.push(D?r:"");for(let L of I)L.length>0?S.push(`${T}${L}`):S.push(D?y:"")}i.write(`${S.join(`
|
|
100
100
|
`)}
|
|
101
|
-
`)},info:(f,r)=>{w.message(f,{...r,symbol:P.default.blue(ib)})},success:(f,r)=>{w.message(f,{...r,symbol:P.default.green(nb)})},step:(f,r)=>{w.message(f,{...r,symbol:P.default.green(Ly)})},warn:(f,r)=>{w.message(f,{...r,symbol:P.default.yellow(bb)})},warning:(f,r)=>{w.warn(f,r)},error:(f,r)=>{w.message(f,{...r,symbol:P.default.red(Db)})}},Yb=P.default.magenta,PD={light:c("─","-"),heavy:c("━","="),block:c("█","#")},_D=`${P.default.gray(j)} `});function Ui(f){let r=f.match(/github\.com\/([^/]+)\/([^/]+)\/tree\/([^/]+)(?:\/(.+))?$/);if(r){let[,S,D,$,l]=r;return{type:"github",url:`https://github.com/${S}/${D}.git`,branch:$,subpath:l}}let y=f.match(/github\.com\/([^/]+)\/([^/]+)/);if(y){let[,S,D]=y,$=D.replace(/\.git$/,"");return{type:"github",url:`https://github.com/${S}/${$}.git`}}let i=f.match(/gitlab\.com\/([^/]+)\/([^/]+)\/-\/tree\/([^/]+)(?:\/(.+))?$/);if(i){let[,S,D,$,l]=i;return{type:"gitlab",url:`https://gitlab.com/${S}/${D}.git`,branch:$,subpath:l}}let n=f.match(/gitlab\.com\/([^/]+)\/([^/]+)/);if(n){let[,S,D]=n,$=D.replace(/\.git$/,"");return{type:"gitlab",url:`https://gitlab.com/${S}/${$}.git`}}let b=f.match(/^([^/]+)\/([^/]+)(?:\/(.+))?$/);if(b&&!f.includes(":")){let[,S,D,$]=b;return{type:"github",url:`https://github.com/${S}/${D}.git`,subpath:$}}return{type:"git",url:f}}import{join as Zb}from"path";import{rmSync as Qb}from"fs";import{tmpdir as Xb}from"os";import{spawn as Iy}from"child_process";async function ir(f,r){let y=Zb(Xb(),`flins-${Date.now()}`),i=["clone","--depth","1"];if(r)i.push("--branch",r);return i.push(f,y),await new Promise((n,b)=>{let S=Iy("git",i,{stdio:"pipe"});S.on("close",(D)=>{if(D===0)n();else b(Error(`Failed to clone repository: ${f}`))}),S.on("error",b)}),y}async function Bi(f,r="main"){return await new Promise((i,n)=>{let b="",S=Iy("git",["ls-remote",f,`refs/heads/${r}`],{stdio:"pipe"});S.stdout?.on("data",(D)=>{b+=D.toString()}),S.on("close",(D)=>{if(D===0&&b.trim())i(b.trim().split(/\s+/)[0]??"");else n(Error(`Failed to get latest commit from ${f}`))}),S.on("error",n)})}async function nr(f){return await new Promise((y,i)=>{let n="",b=Iy("git",["rev-parse","HEAD"],{cwd:f,stdio:"pipe"});b.stdout?.on("data",(S)=>{n+=S.toString()}),b.on("close",(S)=>{if(S===0&&n.trim())y(n.trim());else i(Error("Failed to get commit hash"))}),b.on("error",i)})}async function br(f){Qb(f,{recursive:!0,force:!0})}var oy=()=>{};var Ki;var ji=W(()=>{Ki={opencode:{name:"opencode",displayName:"OpenCode",configDir:"~/.config/opencode",skillsDir:".opencode/skill",globalSkillsDir:"~/.config/opencode/skill",commandsDir:".opencode/command",globalCommandsDir:"~/.config/opencode/command"},"claude-code":{name:"claude-code",displayName:"Claude Code",configDir:"~/.claude",skillsDir:".claude/skills",globalSkillsDir:"~/.claude/skills",commandsDir:".claude/commands",globalCommandsDir:"~/.claude/commands"},codex:{name:"codex",displayName:"Codex",configDir:"~/.codex",skillsDir:".codex/skills",globalSkillsDir:"~/.codex/skills"},cursor:{name:"cursor",displayName:"Cursor",configDir:"~/.cursor",skillsDir:".cursor/skills",globalSkillsDir:"~/.cursor/skills"},amp:{name:"amp",displayName:"Amp",configDir:"~/.config/agents",skillsDir:".agents/skills",globalSkillsDir:"~/.config/agents/skills"},kilo:{name:"kilo",displayName:"Kilo Code",configDir:"~/.kilocode",skillsDir:".kilocode/skills",globalSkillsDir:"~/.kilocode/skills"},roo:{name:"roo",displayName:"Roo Code",configDir:"~/.roo",skillsDir:".roo/skills",globalSkillsDir:"~/.roo/skills"},goose:{name:"goose",displayName:"Goose",configDir:"~/.config/goose",skillsDir:".goose/skills",globalSkillsDir:"~/.config/goose/skills"},antigravity:{name:"antigravity",displayName:"Antigravity",configDir:"~/.gemini/antigravity",skillsDir:".agent/skills",globalSkillsDir:"~/.gemini/antigravity/skills"},copilot:{name:"copilot",displayName:"GitHub Copilot",configDir:"~/.copilot",skillsDir:".github/skills",globalSkillsDir:"~/.copilot/skills"},gemini:{name:"gemini",displayName:"Gemini CLI",configDir:"~/.gemini",skillsDir:".gemini/skills",globalSkillsDir:"~/.gemini/skills"},windsurf:{name:"windsurf",displayName:"Windsurf",configDir:"~/.codeium/windsurf",skillsDir:".windsurf/skills",globalSkillsDir:"~/.codeium/windsurf/skills"},trae:{name:"trae",displayName:"Trae",configDir:"~/.trae",skillsDir:".trae/skills",globalSkillsDir:"~/.trae/skills"},factory:{name:"factory",displayName:"Factory Droid",configDir:"~/.factory",skillsDir:".factory/skills",globalSkillsDir:"~/.factory/skills",commandsDir:".factory/commands",globalCommandsDir:"~/.factory/commands"},letta:{name:"letta",displayName:"Letta",configDir:"~/.letta",skillsDir:".skills",globalSkillsDir:"~/.letta/skills"},qoder:{name:"qoder",displayName:"Qoder",configDir:"~/.qoder",skillsDir:".qoder/skills",globalSkillsDir:"~/.qoder/skills"}}});import{homedir as zb}from"os";import{existsSync as Ub}from"fs";function Ei(){let f={},r=Ki;for(let[y,i]of Object.entries(r)){let n=y;f[n]={name:i.name,displayName:i.displayName,configDir:i.configDir.replace("~",Dr),skillsDir:i.skillsDir,globalSkillsDir:i.globalSkillsDir.replace("~",Dr),commandsDir:i.commandsDir,globalCommandsDir:i.globalCommandsDir?.replace("~",Dr),detectInstalled:async()=>{let b=i.configDir.replace("~",Dr);return Ub(b)}}}return f}var Dr,Hi;var Py=W(()=>{ji();Dr=zb(),Hi=process.env.DIRECTORY_URL||"https://flins.
|
|
102
|
-
`)){let S=b.indexOf(":");if(S===-1)continue;let D=b.slice(0,S).trim(),$=b.slice(S+1).trim();if($.startsWith('"')&&$.endsWith('"')||$.startsWith("'")&&$.endsWith("'"))n[D]=$.slice(1,-1);else if(D==="metadata")try{let l={},T=$.replace(/^\{|\}$/g,"").trim();if(T){for(let o of T.split(",")){let[_,I]=o.split("=").map((L)=>L.trim());if(_&&I)l[_]=I.replace(/^['"]|["']$/g,"")}n[D]=JSON.stringify(l)}}catch{n[D]=$}else n[D]=$}return{data:n,content:i}}function Sr(f,r){try{let{data:y}=_y(r);if(!y.name||!y.description)return null;return{name:y.name,description:y.description,path:jb(f),metadata:y.metadata?JSON.parse(y.metadata):void 0}}catch{return null}}function lf(f){return f.name||Bb(f.path)}var $r=()=>{};import{readdir as Gi,readFile as qy,stat as Kb}from"fs/promises";import{join as Tf}from"path";function Gb(f){let r=[f];for(let i of Eb)r.push(Tf(f,i));let y=new Set;for(let i of Object.values(z))y.add(Tf(f,i.skillsDir));return r.push(...y),r}async function Jy(f){try{let r=Tf(f,"SKILL.md");return(await Kb(r)).isFile()}catch{return!1}}async function ci(f,r=0,y=5){let i=[];if(r>y)return i;try{if(await Jy(f))i.push(f);let n=await Gi(f,{withFileTypes:!0});for(let b of n)if(b.isDirectory()&&!Hb.includes(b.name)){let S=await ci(Tf(f,b.name),r+1,y);i.push(...S)}}catch{}return i}async function lr(f,r){let y=[],i=new Set,n=r?Tf(f,r):f;if(await Jy(n)){let S=Tf(n,"SKILL.md"),D=await qy(S,"utf-8"),$=Sr(S,D);if($)return y.push($),y}let b=Gb(n);for(let S of b)try{let D=await Gi(S,{withFileTypes:!0});for(let $ of D)if($.isDirectory()){let l=Tf(S,$.name);if(await Jy(l)){let T=Tf(l,"SKILL.md"),o=await qy(T,"utf-8"),_=Sr(T,o);if(_&&!i.has(_.name))y.push(_),i.add(_.name)}}}catch{}if(y.length===0){let S=await ci(n);for(let D of S){let $=Tf(D,"SKILL.md"),l=await qy($,"utf-8"),T=Sr($,l);if(T&&!i.has(T.name))y.push(T),i.add(T.name)}}return y}var Hb,Eb;var xy=W(()=>{yf();$r();Hb=["node_modules",".git","dist","build","__pycache__"],Eb=["skills","skills/.curated","skills/.experimental","skills/.system"]});import{basename as cb}from"path";function Wi(f,r){try{let{data:y}=_y(r);return{name:y.name||cb(f,".md"),description:y.description,path:f,type:"markdown"}}catch{return null}}function xf(f){return f.name}var Yy=W(()=>{$r()});import{readdir as Vi,readFile as Wb}from"fs/promises";import{join as ky,extname as Vb}from"path";async function gi(f,r=0){let y=[];if(r>Cb)return y;try{let i=await Vi(f,{withFileTypes:!0});for(let n of i){if(gb.includes(n.name))continue;let b=ky(f,n.name);if(n.isDirectory())if(n.name==="commands")y.push(b);else{let S=await gi(b,r+1);y.push(...S)}}}catch{}return y}async function Fb(f){let r=[];try{let y=await Vi(f,{withFileTypes:!0});for(let i of y){if(Nb.has(i.name))continue;if(!i.isFile())continue;let n=ky(f,i.name);if(Vb(i.name).toLowerCase()!==".md")continue;try{let S=await Wb(n,"utf-8"),D=Wi(n,S);if(D)r.push(D)}catch{continue}}}catch{}return r}async function Tr(f,r){let y=[],i=new Set,n=r?ky(f,r):f,b=await gi(n);for(let S of b){let D=await Fb(S);for(let $ of D)if(!i.has($.name))y.push($),i.add($.name)}return y}var gb,Nb,Cb=5;var Zy=W(()=>{Yy();gb=["node_modules",".git","dist","build","__pycache__"],Nb=new Set(["README.md","readme.md",".DS_Store"])});import{mkdir as Ci,cp as Ob,access as ub,readdir as vb}from"fs/promises";import{join as Ni}from"path";async function Fi(f,r){await Ci(r,{recursive:!0});let y=await vb(f,{withFileTypes:!0});for(let i of y){if(hb(i.name))continue;let n=Ni(f,i.name),b=Ni(r,i.name);if(i.isDirectory())await Fi(n,b);else await Ob(n,b)}}async function Oi(f,r){try{return await Ci(r,{recursive:!0}),await Fi(f,r),{success:!0,path:r}}catch(y){return{success:!1,path:r,error:y instanceof Error?y.message:"Unknown error"}}}async function ui(f){try{return await ub(f),!0}catch{return!1}}var Ab,hb=(f)=>{if(Ab.has(f))return!0;if(f.startsWith("_"))return!0;return!1};var vi=W(()=>{Ab=new Set(["README.md","metadata.json"])});import{join as Ai}from"path";async function Lr(f,r,y){let i=z[r],n=y.global?i.globalSkillsDir:i.skillsDir,b=Ai(n,f.name);return{...await Oi(f.path,b),originalPath:f.path}}async function hi(f,r,y){let i=Qy(f,r,y);return ui(i)}function Qy(f,r,y){let i=z[r],n=y.global?i.globalSkillsDir:i.skillsDir;return Ai(n,f)}var Xy=W(()=>{yf();vi()});import{mkdir as mb,cp as ab}from"fs/promises";import{join as sb,dirname as pb}from"path";function wr(f){return mi.includes(f)}function ai(){return mi.filter((f)=>z[f]?.commandsDir)}async function db(f){await mb(f,{recursive:!0})}async function tb(f,r){try{return await db(pb(r)),await ab(f,r),{success:!0,path:r}}catch(y){return{success:!1,path:r,error:y instanceof Error?y.message:"Unknown error"}}}async function eb(f,r,y){let i=z[r],n=y.global?i.globalCommandsDir:i.commandsDir,b=sb(n,`${f.name}.md`);return tb(f.path,b)}async function Rr(f,r,y){if(!wr(r))return{success:!1,path:"",originalPath:f.path,error:`Agent ${r} does not support commands`};if(!z[r].commandsDir)return{success:!1,path:"",originalPath:f.path,error:`Agent ${r} has no commands directory configured`};return{...await eb(f,r,y),originalPath:f.path}}var mi;var My=W(()=>{yf();mi=["claude-code","opencode","factory"]});async function si(){let f=[];for(let[r,y]of Object.entries(z))if(await y.detectInstalled())f.push(r);return f}var pi=W(()=>{yf()});import{resolve as f0}from"path";import{homedir as r0}from"os";function Ir(f){if(f.startsWith("~"))return f.replace("~",r0());return f}function If(f){return f.type==="global"?Ir(f.path):f0(process.cwd(),f.path)}var or=()=>{};import{homedir as y0}from"os";import{join as _r}from"path";import{existsSync as qr,readFileSync as i0,writeFileSync as ti,mkdirSync as n0,readdirSync as di}from"fs";function ei(){if(!qr(zy))n0(zy,{recursive:!0})}function Kf(){if(ei(),!qr(Pr)){let f={lastUpdate:new Date().toISOString(),skills:{}};return ti(Pr,JSON.stringify(f,null,2)),f}try{let f=i0(Pr,"utf-8");return JSON.parse(f)}catch{return{lastUpdate:new Date().toISOString(),skills:{}}}}function Jr(f){ei(),f.lastUpdate=new Date().toISOString(),ti(Pr,JSON.stringify(f,null,2))}function Uy(f,r,y,i,n,b="skill"){let S=Kf(),D=b==="skill"?`skill:${f.toLowerCase()}`:`command:${f.toLowerCase()}`,$=!1,l;if(!S.skills[D])S.skills[D]={url:r,subpath:y,branch:i,commit:n};else{if(S.skills[D].branch!==i)l=S.skills[D].branch,S.skills[D].branch=i,S.skills[D].commit=n,$=!0;if(S.skills[D].url=r,y)S.skills[D].subpath=y}return Jr(S),{updated:$,previousBranch:l}}function xr(f,r){let y=Kf(),i=r==="skill"?`skill:${f.toLowerCase()}`:`command:${f.toLowerCase()}`;delete y.skills[i],Jr(y)}function f1(f,r,y){let i=Kf(),n=r==="skill"?`skill:${f.toLowerCase()}`:`command:${f.toLowerCase()}`;if(i.skills[n])i.skills[n].commit=y,Jr(i)}function Yr(){return Kf()}function of(f,r){let y=[];for(let[i,n]of Object.entries(z))if(r==="skill"){let b=Ir(n.globalSkillsDir);if(qr(b))try{let D=di(b,{withFileTypes:!0}).find(($)=>$.isDirectory()&&$.name.toLowerCase()===f.toLowerCase());if(D)y.push({agent:i,installableType:"skill",type:"global",path:_r(n.globalSkillsDir,D.name)})}catch{}}else{let b=n.globalCommandsDir;if(b){let S=Ir(b);if(qr(S))try{let $=di(S,{withFileTypes:!0}).find((l)=>{return l.name.replace(/\.md$/,"").toLowerCase()===f.toLowerCase()});if($)y.push({agent:i,installableType:"command",type:"global",path:_r(b,$.name)})}catch{}}}return y}async function r1(){let f=Kf(),r=[];for(let[y,i]of Object.entries(f.skills)){let n=y.split(":");if(n.length!==2)continue;let b=n[0]==="skill"?"skill":"command",S=n[1];if(of(S,b).length===0)r.push(y)}for(let y of r)delete f.skills[y];if(r.length>0)Jr(f)}var zy,Pr;var kr=W(()=>{or();yf();zy=_r(y0(),".flins"),Pr=_r(zy,"skills.lock")});import{join as Zr,resolve as b0}from"path";import{existsSync as Qr,readFileSync as D0,writeFileSync as S0,rmSync as $0,readdirSync as y1}from"fs";function By(f){let r=f||process.cwd();return b0(r,l0)}function Xr(f){let r=By(f);if(!Qr(r))return null;try{let y=D0(r,"utf-8"),i=JSON.parse(y);if(!i.version||!i.skills)return null;return i}catch{return null}}function jy(f,r){let y=By(r);f.version=i1,S0(y,JSON.stringify(f,null,2))}function Ky(f,r,y,i,n,b,S){let D=Xr(S);if(!D)D={version:i1,skills:{}};let $=b==="skill"?`skill:${f.toLowerCase()}`:`command:${f.toLowerCase()}`,l=!1,T;if(!D.skills[$])D.skills[$]={url:r,subpath:y,branch:i,commit:n};else{if(D.skills[$].branch!==i)T=D.skills[$].branch,D.skills[$].branch=i,D.skills[$].commit=n,l=!0;if(D.skills[$].url=r,D.skills[$].commit=n,y)D.skills[$].subpath=y}return jy(D,S),{updated:l,previousBranch:T}}function n1(f,r,y){let i=Xr(y);if(!i)return;let n=r==="skill"?`skill:${f.toLowerCase()}`:`command:${f.toLowerCase()}`;if(delete i.skills[n],Object.keys(i.skills).length>0)jy(i,y);else{let b=By(y);if(Qr(b))try{$0(b,{force:!0})}catch{}}}function b1(f,r,y,i){let n=Xr(i);if(!n)return;let b=r==="skill"?`skill:${f.toLowerCase()}`:`command:${f.toLowerCase()}`,S=n.skills[b];if(S)S.commit=y,jy(n,i)}function Mr(f){return Xr(f)}function Yf(f,r,y){let i=[],n=y||process.cwd();for(let[b,S]of Object.entries(z))if(r==="skill"){let D=Zr(n,S.skillsDir);if(Qr(D))try{let l=y1(D,{withFileTypes:!0}).find((T)=>T.isDirectory()&&T.name.toLowerCase()===f.toLowerCase());if(l)i.push({agent:b,installableType:"skill",type:"project",path:Zr(S.skillsDir,l.name)})}catch{}}else{let D=S.commandsDir;if(D){let $=Zr(n,D);if(Qr($))try{let T=y1($,{withFileTypes:!0}).find((o)=>{return o.name.replace(/\.md$/,"").toLowerCase()===f.toLowerCase()});if(T)i.push({agent:b,installableType:"command",type:"project",path:Zr(D,T.name)})}catch{}}}return i}var i1="1.0.0",l0="skills.lock";var zr=W(()=>{yf()});async function D1(f,r){let y={tempDir:null,spinner:rf()};try{y.spinner.start("Parsing source...");let i=Ui(f),n=i.branch??"main";y.spinner.stop(`Source: ${Q.default.cyan(i.url)}${i.subpath?` (${i.subpath})`:""}${i.branch?` @ ${Q.default.cyan(i.branch)}`:""}`),y.spinner.start("Cloning repository..."),y.tempDir=await ir(i.url,i.branch),y.spinner.stop("Repository cloned");let b=await nr(y.tempDir);y.spinner.start("Discovering skills and commands...");let S=await lr(y.tempDir,i.subpath),D=await Tr(y.tempDir,i.subpath);if(S.length===0&&D.length===0)return y.spinner.stop(Q.default.red("No skills or commands found")),E(Q.default.red("No valid skills found. Skills require a SKILL.md with name and description.")),{success:!1,installed:0,failed:0,results:[]};let $=D.length>0;if(y.spinner.stop(`Found ${Q.default.green(S.length)} skill${S.length!==1?"s":""}`+($?` and ${Q.default.yellow(D.length)} command${D.length!==1?"s":""}`:"")),r.list){if(S.length>0){w.step(Q.default.bold("Available Skills"));for(let q of S)w.message(` ${Q.default.cyan(lf(q))}`),w.message(` ${Q.default.dim(q.description)}`)}if(D.length>0){w.step(Q.default.bold("Available Commands"));for(let q of D)w.message(` ${Q.default.cyan(xf(q))}`),w.message(` ${Q.default.dim(q.description||`Command: ${q.name}`)}`)}return E("Use --skill <name> to install specific skills or commands"),{success:!0,installed:0,failed:0,results:[]}}let l=await T0(S,r),T=l?await w0(r,y):null,o=D.length>0?await L0(D,r):null,_=o?await R0(r,y):null;if(!l&&!o)return{success:!1,installed:0,failed:0,results:[]};if(l&&!T)return{success:!1,installed:0,failed:0,results:[]};if(o&&!_)return{success:!1,installed:0,failed:0,results:[]};let I=await I0(r);if(I===null)return{success:!1,installed:0,failed:0,results:[]};if(!await o0(r,l,T,o,_,I))return{success:!1,installed:0,failed:0,results:[]};if(o&&o.length>0)w.warn(Q.default.yellow("Commands may change significantly or be removed - your feedback helps shape future releases"));y.spinner.start("Installing...");let R=await P0(l||[],T||[],o||[],_||[],I,i,b,n);return y.spinner.stop("Installation complete"),R}finally{if(y.tempDir)await br(y.tempDir)}}async function T0(f,r){if(f.length===0)return null;let y=[];if(r.skill&&r.skill.length>0){if(y=f.filter((i)=>r.skill.some((n)=>i.name.toLowerCase()===n.toLowerCase()||lf(i).toLowerCase()===n.toLowerCase())),y.length===0){w.error(`No matching skills found for: ${r.skill.join(", ")}`),w.info("Available skills:");for(let i of f)w.message(` - ${lf(i)}`);return null}w.info(`Selected ${y.length} skill${y.length!==1?"s":""}: ${y.map((i)=>Q.default.cyan(lf(i))).join(", ")}`)}else if(f.length===1){y=f;let i=f[0];w.info(`Skill: ${Q.default.cyan(lf(i))}`),w.message(Q.default.dim(i.description))}else if(r.yes||r.force)y=f,w.info(`Installing all ${f.length} skills`);else{let i=f.map((b)=>({value:b,label:lf(b),hint:b.description.length>60?b.description.slice(0,57)+"...":b.description})),n=await e({message:"Select skills to install",options:i,required:!1});if(V(n))return N("Installation cancelled"),null;if(!n||n.length===0)return w.info("No skills selected"),null;y=n}return y}async function L0(f,r){if(f.length===0)return null;w.warn(Q.default.yellow("⚠ Commands may change significantly or be removed - your feedback helps shape future releases")),w.message(Q.default.dim("See: https://github.com/senahq/flins#commands-experimental"));let y=[];if(r.skill&&r.skill.length>0)y=f.filter((i)=>r.skill.some((n)=>i.name.toLowerCase()===n.toLowerCase()||xf(i).toLowerCase()===n.toLowerCase()));if(y.length===0&&!r.yes&&!r.force){let i=f.map((b)=>({value:b,label:xf(b),hint:(b.description||`Command: ${b.name}`).slice(0,55)})),n=await e({message:"Select commands to install",options:i,required:!1});if(V(n))return N("Installation cancelled"),null;if(!n||n.length===0)return w.info("No commands selected"),null;y=n}else if(r.yes||r.force)y=f,w.info(`Installing all ${f.length} commands`);if(y.length>0)w.info(`Selected ${y.length} command${y.length!==1?"s":""}: ${y.map((i)=>Q.default.yellow(xf(i))).join(", ")}`);return y.length>0?y:null}async function w0(f,r){if(f.agent&&f.agent.length>0){let i=Object.keys(z),n=f.agent.filter((b)=>!i.includes(b));if(n.length>0)return w.error(`Invalid agents: ${n.join(", ")}`),w.info(`Valid agents: ${i.join(", ")}`),null;return f.agent}r.spinner.start("Detecting installed agents...");let y=await si();if(r.spinner.stop(`Detected ${y.length} agent${y.length!==1?"s":""}`),y.length===0)if(f.yes||f.force){let n=Object.keys(z);return w.info("Installing to all agents (none detected)"),n}else{w.warn("No coding agents detected. You can still install skills.");let n=Object.entries(z).map(([S,D])=>({value:S,label:D.displayName})),b=await e({message:"Select agents to install skills to",options:n,required:!0});if(V(b))return N("Installation cancelled"),null;return b}else if(y.length===1||f.yes||f.force){if(y.length===1){let i=y[0];w.info(`Installing skills to: ${Q.default.cyan(z[i].displayName)}`)}else w.info(`Installing skills to: ${y.map((i)=>Q.default.cyan(z[i].displayName)).join(", ")}`);return y}else{let i=y.map((b)=>({value:b,label:z[b].displayName,hint:z[b].skillsDir})),n=await e({message:"Select agents to install skills to",options:i,required:!0,initialValues:y});if(V(n))return N("Installation cancelled"),null;return n}}async function R0(f,r){let y=ai();if(f.agent&&f.agent.length>0){let D=Object.keys(z),$=f.agent.filter((o)=>!D.includes(o));if($.length>0)return w.error(`Invalid agents: ${$.join(", ")}`),w.info(`Valid agents: ${D.join(", ")}`),null;let l=f.agent.filter((o)=>wr(o));if(l.length===0)return w.error("Commands are only supported by: "+y.map((o)=>z[o].displayName).join(", ")),null;let T=f.agent.filter((o)=>!wr(o));if(T.length>0)w.warn(`Filtering out agents that don't support commands: ${T.join(", ")}`);return l}let i=y.filter((D)=>z[D]?.commandsDir);if(i.length===0)return w.warn("No agents with command support detected"),[];if(f.yes||f.force)return w.info(`Installing commands to: ${i.map((D)=>Q.default.cyan(z[D].displayName)).join(", ")}`),i;w.warn(Q.default.yellow("⚠ Commands may work differently across agents or be removed - your feedback helps shape future releases")),w.message(Q.default.dim("https://github.com/senahq/flins#commands-experimental"));let b=i.map((D)=>({value:D,label:z[D].displayName,hint:z[D].commandsDir||""})),S=await e({message:"Select agents to install commands to",options:b,required:!0,initialValues:i});if(V(S))return N("Installation cancelled"),null;return w.info(`Installing commands to: ${S.map((D)=>Q.default.cyan(z[D].displayName)).join(", ")}`),S}async function I0(f){let r=f.global??!1;if(f.global===void 0&&!(f.yes||f.force)){let y=await zi({message:"Installation scope",options:[{value:!1,label:"Project",hint:"Install in current directory (committed with your project)"},{value:!0,label:"Global",hint:"Install in home directory (available across all projects)"}]});if(V(y))return N("Installation cancelled"),null;r=y}return r}async function o0(f,r,y,i,n,b){if(w.step(Q.default.bold("Installation Summary")),r&&r.length>0&&y){w.message(Q.default.bold(Q.default.cyan("Skills")));for(let D of r){w.message(` ${Q.default.cyan(lf(D))}`);for(let $ of y){let l=Qy(D.name,$,{global:b}),o=await hi(D.name,$,{global:b})?Q.default.yellow(" (will overwrite)"):"";w.message(` ${Q.default.dim("→")} ${z[$].displayName}: ${Q.default.dim(l)}${o}`)}}}if(i&&i.length>0&&n&&n.length>0){w.message(Q.default.bold(Q.default.yellow("Commands (Experimental)")));for(let D of i){w.message(` ${Q.default.yellow(xf(D))} ${Q.default.dim("[experimental]")}`);for(let $ of n){let l=`${z[$].commandsDir}/${D.name}.md`;w.message(` ${Q.default.dim("→")} ${z[$].displayName}: ${Q.default.dim(l)}`)}}}if(!(f.yes||f.force)){let D=await Rf({message:"Proceed with installation?"});if(V(D)||!D)return N("Installation cancelled"),!1}return!0}async function P0(f,r,y,i,n,b,S,D){let $=[...f.flatMap((L)=>r.map((R)=>Lr(L,R,{global:n}))),...y.flatMap((L)=>i.map((R)=>Rr(L,R,{global:n})))],l=await Promise.all($),T=l.map((L,R)=>{let q=Math.floor(R/Math.max(r.length,i.length)),J=R%Math.max(r.length,i.length),x=R<f.length*r.length,k=x?f[q%f.length]:y[q%y.length],M=x?r:i,U=M[J%M.length];return{skill:x?lf(k):xf(k),agent:z[U].displayName,...L,installableType:x?"skill":"command"}}),o=new Map;for(let[L,R]of l.entries()){if(!R.success)continue;let q=L<f.length*r.length;if(n)if(q){let J=Math.floor(L/r.length),x=f[J%f.length],k=Uy(x.name,b.url,b.subpath,D,S,"skill");if(k.updated&&k.previousBranch){let M=o.get(x.name);o.set(x.name,{previous:M?.previous??k.previousBranch,current:M?.current??D})}}else{let J=Math.floor((L-f.length*r.length)/i.length),x=y[J%y.length];Uy(x.name,b.url,b.subpath,D,S,"command")}}if(!n)for(let[L,R]of l.entries()){if(!R.success)continue;if(L<f.length*r.length){let J=Math.floor(L/r.length),x=f[J%f.length];Ky(x.name,b.url,b.subpath,D,S,"skill")}else{let J=Math.floor((L-f.length*r.length)/i.length),x=y[J%y.length];Ky(x.name,b.url,b.subpath,D,S,"command")}}let _=T.filter((L)=>L.success),I=T.filter((L)=>!L.success);if(o.size>0)for(let[L,{previous:R,current:q}]of o)w.warn(Q.default.yellow(` ${Q.default.cyan(L)}: ${Q.default.dim(R)} → ${Q.default.green(q)}`));if(_.length>0){let L=_.filter((J)=>J.installableType==="skill").length,R=_.filter((J)=>J.installableType==="command").length,q=[];if(L>0)q.push(`${L} skill${L!==1?"s":""}`);if(R>0)q.push(`${R} command${R!==1?"s":""}`);w.success(Q.default.green(`Successfully installed ${q.join(" and ")}`));for(let J of _){let x=J.installableType==="command"?Q.default.yellow("⚡"):Q.default.green("✓");w.message(` ${x} ${J.skill} → ${J.agent}`),w.message(` ${Q.default.dim(J.path)}`)}}if(I.length>0){w.error(Q.default.red(`Failed to install ${I.length} item${I.length!==1?"s":""}`));for(let L of I)w.message(` ${Q.default.red("✗")} ${L.skill} → ${L.agent}`),w.message(` ${Q.default.dim(L.error)}`)}if(_.length>0)E(Q.default.green("Installation complete"));else E(Q.default.yellow("No items were installed"));return{success:I.length===0,installed:_.length,failed:I.length,results:T}}var Q;var S1=W(()=>{p();oy();xy();Zy();$r();Yy();Xy();My();pi();yf();kr();zr();Q=O(h(),1)});async function $1(){let f=Date.now();if(Hf&&Hy&&f<Hy)return Hf;try{let r=await fetch(Hi,{signal:AbortSignal.timeout(5000)});if(!r.ok)throw Error(`Failed to fetch directory: ${r.status}`);let y=await r.json();return Hf=y,Hy=f+_0,y}catch(r){if(Hf)return Hf;throw r}}async function l1(f){return(await $1()).find((i)=>i.name.toLowerCase()===f.toLowerCase())?.source??null}function T1(f){return/^[a-z0-9-]+$/i.test(f)&&!f.includes("/")&&!f.includes(":")}async function Ur(){return $1()}var Hf=null,Hy=null,_0=300000;var Ey=W(()=>{Py()});var L1={};G1(L1,{installCommand:()=>Gy});async function Gy(f,r){if(!r.silent)m(Lf.default.bgCyan(Lf.default.black(" flins ")));try{let y=f;if(T1(f)){if(!r.silent)w.info(`Looking up "${Lf.default.cyan(f)}" in flins directory...`);let n=await l1(f);if(!n){w.error(`Skill "${Lf.default.cyan(f)}" not found in directory.`);let b=await Ur();if(b.length>0){w.info("Available skills:");for(let S of b)w.message(` ${Lf.default.cyan(S.name)} - ${Lf.default.dim(S.description)}`)}process.exit(1)}if(y=n,!r.silent)w.success(`Found: ${Lf.default.cyan(y)}`)}let i=await D1(y,r);if(!i.success&&i.installed===0&&i.failed===0)process.exit(1);if(i.failed>0)process.exit(1)}catch(y){if(w.error(y instanceof Error?y.message:"Unknown error occurred"),!r.silent)E(Lf.default.red("Couldn't install skill"));process.exit(1)}}var Lf;var cy=W(()=>{p();S1();Ey();Lf=O(h(),1)});var ey=O(ty(),1),{program:d,createCommand:W0,createArgument:V0,createOption:g0,CommanderError:N0,InvalidArgumentError:C0,InvalidOptionArgumentError:F0,Command:O0,Argument:u0,Option:v0,Help:A0}=ey.default;var fi={name:"flins",version:"0.0.1",description:"Universal skill installer for AI coding agents - Claude, Cursor, Copilot, and more",keywords:["agent-skills","ai-agents","claude","cli","coding-assistant","copilot","cursor","github-copilot","skills"],homepage:"https://github.com/flinstech/flins#readme",bugs:{url:"https://github.com/flinstech/flins/issues"},license:"MIT",author:"flins",repository:{type:"git",url:"git+https://github.com/flinstech/flins.git"},bin:{flins:"./dist/index.js"},files:["dist","README.md"],type:"module",module:"src/index.ts",scripts:{build:"bun build src/index.ts --outdir dist --target node --minify",dev:"bun src/index.ts",typecheck:"tsgo --noEmit",prepublishOnly:"bun run build",lint:"oxlint","lint:fix":"oxlint --fix",fmt:"oxfmt","fmt:check":"oxfmt --check"},dependencies:{"@clack/prompts":"^1.0.0-alpha.9",commander:"^14.0.2",picocolors:"^1.1.1"},devDependencies:{"@types/bun":"latest","@typescript/native-preview":"^7.0.0-dev.20260116.1","bun-types":"^1.3.6",oxfmt:"^0.24.0",oxlint:"^1.39.0"}};cy();p();var Br=O(h(),1);p();oy();xy();Zy();Xy();My();kr();zr();var X=O(h(),1);import{join as Y0}from"path";function Zf(f){if(f.startsWith("skill:"))return{type:"skill",name:f.slice(6),installableType:"skill"};if(f.startsWith("command:"))return{type:"command",name:f.slice(8),installableType:"command"};return null}yf();import{existsSync as w1,readdirSync as q0,statSync as R1}from"fs";function J0(f){if(!w1(f))return!1;try{if(!R1(f).isDirectory())return!1;let y=q0(f);if(y.length===0)return!1;return y.includes("SKILL.md")}catch{return!1}}function x0(f){if(!w1(f))return!1;try{if(!R1(f).isFile())return!1;return f.endsWith(".md")}catch{return!1}}function Pf(f,r){return r==="skill"?J0(f):x0(f)}or();p();var Qf=O(h(),1);function Ef(){w.warn("No skills installed yet. Get started by installing a skill:"),w.message(` ${Qf.default.cyan("npx flins@latest <repo>")} # Install in current project`),w.message(` ${Qf.default.cyan("npx flins@latest <repo> --global")} # Install globally for all projects`),w.message(` ${Qf.default.dim("Examples:")}`),w.message(` ${Qf.default.cyan("npx flins@latest expo")} # Install from flins directory`),w.message(` ${Qf.default.cyan("npx flins@latest search")} # Browse available skills`)}var s=(f,r,y)=>{return f===1?r:y??`${r}s`};function o1(){let f=[],r=new Set,y=Mr();if(y)for(let[n,b]of Object.entries(y.skills)){let S=Zf(n);if(S)f.push({skillName:S.name,url:b.url,subpath:b.subpath,branch:b.branch,commit:b.commit,isLocal:!0,installableType:S.installableType}),r.add(`${S.installableType}:${S.name.toLowerCase()}`)}let i=Yr();for(let[n,b]of Object.entries(i.skills)){let S=Zf(n),D=S?`${S.installableType}:${S.name.toLowerCase()}`:n.toLowerCase();if(!r.has(D))f.push({skillName:S?.name??n,url:b.url,subpath:b.subpath,branch:b.branch,commit:b.commit,isLocal:!1,installableType:S?.installableType??"skill"})}return f}async function I1(f,r,y,i,n,b){let D=(n?Yf(f,b):of(f,b)).map((l)=>{let T=If(l);return{agent:z[l.agent].displayName,path:T,exists:Pf(T,l.installableType)}});if(D.filter((l)=>l.exists).length===0)return{skillName:f,currentCommit:i,latestCommit:i,status:"orphaned",installableType:b,installations:D};try{let l=await Bi(r,y);return{skillName:f,currentCommit:i,latestCommit:l,status:l===i?"latest":"update-available",installableType:b,installations:D}}catch(l){return{skillName:f,currentCommit:i,latestCommit:i,status:"error",installableType:b,installations:D,error:l instanceof Error?l.message:"Unknown error"}}}async function Wy(f){let r=o1(),y=[],i;if(f&&f.length>0){let b=new Set(f.map((S)=>S.toLowerCase()));i=r.filter(({skillName:S})=>b.has(S.toLowerCase()))}else i=r;if(i.length===0)return[];let n=rf();if(i.length===1){let{skillName:b,url:S,branch:D,commit:$,isLocal:l,installableType:T}=i[0];n.start(`Checking ${X.default.cyan(b)}...`);let o=await I1(b,S,D,$,l,T);n.stop(o.status==="latest"?X.default.green("Up to date"):X.default.yellow("Update available")),y.push(o)}else{n.start(`Checking ${i.length} ${s(i.length,"skill")}...`);for(let{skillName:b,url:S,branch:D,commit:$,isLocal:l,installableType:T}of i){let o=await I1(b,S,D,$,l,T);y.push(o)}n.stop("Check complete")}return y}async function P1(f,r={}){let y=o1(),i=[],n;if(f&&f.length>0){let I=new Set(f.map((L)=>L.toLowerCase()));n=y.filter(({skillName:L})=>I.has(L.toLowerCase()))}else n=y;if(n.length===0)return w.warn("No skills found to update"),E(X.default.yellow("Nothing to update")),[];let b=await Wy(f),S=b.filter((I)=>I.status==="update-available");if(S.length===0){let I=b.filter((L)=>L.status==="orphaned");if(I.length>0){w.warn(`${I.length} skill${I.length>1?"s":""} ${I.length>1?"have":"has"} no valid installations`);for(let L of I)w.message(` ${X.default.yellow("○")} ${X.default.cyan(L.skillName)} - files were removed`)}return w.success(X.default.green("All skills are up to date")),E(X.default.green("Already up to date")),[]}w.step(X.default.bold("Updates Available"));let D=S.map((I)=>({value:I.skillName,label:I.skillName,hint:`${I.currentCommit.slice(0,7)} → ${I.latestCommit.slice(0,7)}`})),$,l=r.yes||r.force;if(l)$=S.map((I)=>I.skillName);else{let I=await e({message:"Select skills to update",options:D,required:!0,initialValues:S.map((L)=>L.skillName)});if(V(I))return N("Update cancelled"),[];$=I}w.step(X.default.bold("Will Update"));for(let I of $){let L=S.find((R)=>R.skillName===I);if(L)w.message(` ${X.default.cyan(L.skillName)}`),w.message(` ${X.default.dim("Current:")} ${X.default.yellow(L.currentCommit.slice(0,7))} ${X.default.dim("→")} ${X.default.green(L.latestCommit.slice(0,7))}`)}if(!l){let I=await Rf({message:"Proceed with update?"});if(V(I)||!I)return N("Update cancelled"),[]}let T=rf();T.start(`Updating ${$.length} ${s($.length,"skill")}...`);for(let{skillName:I,url:L,subpath:R,isLocal:q,installableType:J}of n){let x=b.find((H)=>H.skillName===I);if(!x||x.status!=="update-available"){if(x?.status==="latest")i.push({skillName:I,success:!0,updated:0,failed:0});else i.push({skillName:I,success:!1,updated:0,failed:0});continue}if(!$.includes(I))continue;let k=null,M=0,U=0;try{k=await ir(L);let H=await nr(k),Y=R?Y0(k,R):k,Z=await lr(Y),F=await Tr(Y),C=Z.find((B)=>B.name.toLowerCase()===I.toLowerCase()),g=F.find((B)=>B.name.toLowerCase()===I.toLowerCase());if(!C&&!g)throw Error("Skill or command not found in repository");let nf=q?Yf(I,J):of(I,J);for(let B of nf){let A=If(B);if(!Pf(A,B.installableType)){if(!q)xr(I,J);continue}let a;if(B.installableType==="command"&&g)a=await Rr(g,B.agent,{global:B.type==="global"});else if(C)a=await Lr(C,B.agent,{global:B.type==="global"});else{U++;continue}if(a.success)M++;else U++}if(q)b1(I,J,H);else f1(I,J,H);i.push({skillName:I,success:U===0,updated:M,failed:U})}catch(H){i.push({skillName:I,success:!1,updated:M,failed:U+1,error:H instanceof Error?H.message:"Unknown error"})}finally{if(k)await br(k)}}T.stop("Update complete");let o=i.filter((I)=>I.success&&I.updated>0),_=i.filter((I)=>!I.success||I.failed>0);if(o.length>0){w.success(X.default.green(`Updated ${o.length} ${s(o.length,"skill")}`));for(let I of o)w.message(` ${X.default.green("✓")} ${X.default.cyan(I.skillName)} (${I.updated} ${s(I.updated,"installation")})`)}if(_.length>0){w.error(X.default.red(`Failed to update ${_.length} ${s(_.length,"skill")}`));for(let I of _)if(w.message(` ${X.default.red("✗")} ${X.default.cyan(I.skillName)}`),I.error)w.message(` ${X.default.dim(I.error)}`)}if(o.length>0)E(X.default.green("Skills updated successfully"));else E(X.default.yellow("No skills were updated"));return i}async function _1(f,r=!1){if(f.length===0){Ef();return}w.step(X.default.bold("Skills Status"));for(let y of f){let i={latest:X.default.green("✓"),"update-available":X.default.yellow("↓"),error:X.default.red("✗"),orphaned:X.default.dim("○")}[y.status],n={latest:X.default.green("latest"),"update-available":X.default.yellow("update available"),error:X.default.red("error"),orphaned:X.default.dim("orphaned")}[y.status],b=y.installations.filter((D)=>D.exists),S=y.installations.filter((D)=>!D.exists);if(!r){let D=b.length,$=D>0?` (${D} ${s(D,"installation")})`:"";w.message(`${i} ${X.default.cyan(y.installableType+":"+y.skillName)}${X.default.dim($)} - ${n}`)}else{if(w.message(`${i} ${X.default.cyan(y.installableType+":"+y.skillName)}`),w.message(` Status: ${n}`),y.status==="update-available")w.message(` ${X.default.dim("Commit:")} ${X.default.yellow(y.currentCommit.slice(0,7))} ${X.default.dim("→")} ${X.default.green(y.latestCommit.slice(0,7))}`);else if(y.status==="latest")w.message(` ${X.default.dim("Commit:")} ${y.currentCommit.slice(0,7)}`);if(y.error)w.message(` ${X.default.red(y.error)}`);if(b.length>0){w.message(` ${X.default.dim("Installed in:")}`);for(let D of b)w.message(` ${X.default.dim("•")} ${D.agent}: ${X.default.dim(D.path)}`)}if(S.length>0){w.message(` ${X.default.yellow("Missing installations:")}`);for(let D of S)w.message(` ${X.default.dim("•")} ${D.agent}: ${X.default.dim(D.path)}`)}}}if(!r)w.info(`Use ${X.default.cyan("--verbose")} or ${X.default.cyan("-v")} for detailed information`)}async function q1(f={}){let r=rf();r.start("Checking for orphaned entries..."),await r1(),r.stop(X.default.green("State cleaned up"))}async function J1(f,r){if(!r.silent)m(Br.default.bgCyan(Br.default.black(" flins ")));try{await P1(f.length>0?f:void 0,r)}catch(y){if(w.error(y instanceof Error?y.message:"Unknown error occurred"),!r.silent)E(Br.default.red("Couldn't update skill(s)"));process.exit(1)}}p();var Gf=O(h(),1);async function x1(f,r={}){if(!r.silent)m(Gf.default.bgCyan(Gf.default.black(" flins ")));try{let y=await Wy(f.length>0?f:void 0),i=r.verbose||f.length>0;if(await _1(y,i),!r.silent)E(Gf.default.green("All checks complete"))}catch(y){if(w.error(y instanceof Error?y.message:"Unknown error occurred"),!r.silent)E(Gf.default.red("Couldn't check status"));process.exit(1)}}p();var jr=O(h(),1);p();kr();zr();var K=O(h(),1);import{existsSync as k0,rmSync as Z0}from"fs";yf();or();function Y1(){let f=[],r=new Set,y=Mr();if(y)for(let[n,b]of Object.entries(y.skills)){let S=Zf(n);if(S)f.push({skillName:S.name,url:b.url,subpath:b.subpath,branch:b.branch,commit:b.commit,isLocal:!0,installableType:S.installableType}),r.add(`${S.installableType}:${S.name.toLowerCase()}`)}let i=Yr();for(let[n,b]of Object.entries(i.skills)){let S=Zf(n),D=S?`${S.installableType}:${S.name.toLowerCase()}`:n.toLowerCase();if(!r.has(D))f.push({skillName:S?.name??n,url:b.url,subpath:b.subpath,branch:b.branch,commit:b.commit,isLocal:!1,installableType:S?.installableType??"skill"})}return f}async function Q0(f){try{if(k0(f))Z0(f,{recursive:!0,force:!0});return{success:!0}}catch(r){return{success:!1,error:r instanceof Error?r.message:"Unknown error"}}}async function k1(f=[],r={}){let y=Y1(),i=[];if(y.length===0)return Ef(),[];let n;if(f.length>0){let _=new Set(f.map((I)=>I.toLowerCase()));n=y.filter(({skillName:I})=>_.has(I.toLowerCase()))}else{let I=y.map(({skillName:R,isLocal:q,installableType:J})=>{let k=(q?Yf(R,J):of(R,J)).map((M)=>({installation:M,resolvedPath:If(M)})).filter(({installation:M,resolvedPath:U})=>Pf(U,M.installableType));return{value:R,label:R,hint:k.length>0?`${k.length} ${s(k.length,"installation")}`:"no valid installations"}}).filter((R)=>R.hint!=="no valid installations");if(I.length===0)return w.warn("No valid installations found"),[];if(r.yes||r.force)n=y.filter(({skillName:R})=>I.some((q)=>q.value===R));else{let R=await e({message:"Select skills to remove",options:I,required:!0,initialValues:I.map((J)=>J.value)});if(V(R))return N("Remove cancelled"),[];let q=R;n=y.filter(({skillName:J})=>q.includes(J))}}if(n.length===0){if(f.length>0){w.error(`No matching skills found for: ${f.join(", ")}`),w.info("Tracked skills:");for(let _ of y)w.message(` - ${K.default.cyan(_.skillName)}`)}return[]}w.step(K.default.bold("Skills to Remove"));let b=[];for(let{skillName:_,isLocal:I,installableType:L}of n){let q=(I?Yf(_,L):of(_,L)).map((J)=>({installation:J,resolvedPath:If(J)})).filter(({installation:J,resolvedPath:x})=>Pf(x,J.installableType));if(q.length>0){b.push({skillName:_,isLocal:I,installableType:L,installations:q}),w.message(` ${K.default.cyan(_)}`);for(let{resolvedPath:J}of q)w.message(` ${K.default.dim("→")} ${J}`)}}if(b.length===0)return w.warn("No installations match the specified criteria"),[];let S=f.length===0,D,$=r.yes||r.force;if($||S)D=b.map(({skillName:_})=>_);else{let _=b.map(({skillName:L,installations:R})=>({value:L,label:L,hint:`${R.length} ${s(R.length,"installation")}`})),I=await e({message:"Select skills to remove",options:_,required:!0,initialValues:b.map(({skillName:L})=>L)});if(V(I))return N("Remove cancelled"),[];D=I}w.step(K.default.bold("Will Remove"));for(let _ of D){let I=b.find((L)=>L.skillName===_);if(I){w.message(` ${K.default.cyan(I.skillName)}`);for(let{resolvedPath:L}of I.installations)w.message(` ${K.default.dim("→")} ${L}`)}}if(!$){let _=await Rf({message:"Remove these skills?"});if(V(_)||!_)return N("Remove cancelled"),[]}let l=rf();l.start(`Removing ${D.length} skill${D.length>1?"s":""}...`);for(let{skillName:_,isLocal:I,installableType:L,installations:R}of b){if(!D.includes(_))continue;let q={skillName:_,success:!0,removed:0,failed:0,installations:[]};for(let{installation:J,resolvedPath:x}of R){let k=await Q0(x);if(q.installations.push({agent:z[J.agent].displayName,path:x,removed:k.success,error:k.error}),k.success)q.removed++;else q.failed++,q.success=!1}if(q.removed>0)if(I)n1(_,L);else xr(_,L);i.push(q)}l.stop("Remove complete");let T=i.filter((_)=>_.success&&_.removed>0),o=i.filter((_)=>!_.success||_.failed>0);if(T.length>0){w.success(K.default.green(`Removed ${T.length} ${s(T.length,"skill")}`));for(let _ of T)w.message(` ${K.default.green("✓")} ${K.default.cyan(_.skillName)}`),w.message(` ${K.default.dim(`${_.removed} ${s(_.removed,"installation")} removed`)}`)}if(o.length>0){w.error(K.default.red(`Failed to remove ${o.length} ${s(o.length,"skill")}`));for(let _ of o){w.message(` ${K.default.red("✗")} ${K.default.cyan(_.skillName)}`);for(let I of _.installations.filter((L)=>!L.removed))if(I.error)w.message(` ${K.default.dim(I.error)}`)}}if(T.length>0)E(K.default.green("Skills removed successfully"));else E(K.default.yellow("No skills were removed"));return i}async function Z1(){let f=Y1();if(f.length===0){Ef();return}w.step(K.default.bold("Installed Skills and Commands"));let r=[],y=[];for(let{skillName:i,isLocal:n,installableType:b}of f)if(n)r.push({skillName:i,installableType:b});else y.push({skillName:i,installableType:b});if(r.length>0){if(y.length>0)w.message(K.default.bold(K.default.cyan("Local (from ./skills.lock)")));for(let{skillName:i,installableType:n}of r){w.message(`${K.default.green("✓")} ${K.default.cyan(n+":"+i)} ${n==="command"?K.default.yellow("(experimental)"):""}`);let S=Yf(i,n).map((D)=>({installation:D,resolvedPath:If(D)})).filter(({installation:D,resolvedPath:$})=>Pf($,D.installableType));if(S.length>0){w.message(` ${K.default.dim("Installed in:")}`);for(let{installation:D,resolvedPath:$}of S)w.message(` ${K.default.dim("•")} ${z[D.agent].displayName}: ${K.default.dim($)}`)}}}if(y.length>0){if(r.length>0)w.message(K.default.bold(K.default.cyan("Global (from ~/.flins/skills.lock)")));for(let{skillName:i,installableType:n}of y){let b=n==="command"?K.default.yellow("⚡"):K.default.green("✓");w.message(`${b} ${K.default.cyan(i)}`);let D=of(i,n).map(($)=>({installation:$,resolvedPath:If($)})).filter(({installation:$,resolvedPath:l})=>Pf(l,$.installableType));if(D.length>0){w.message(` ${K.default.dim("Installed in:")}`);for(let{installation:$,resolvedPath:l}of D)w.message(` ${K.default.dim("•")} ${z[$.agent].displayName}: ${K.default.dim(l)}`)}}}}async function Q1(f,r){if(!r.silent)m(jr.default.bgCyan(jr.default.black(" flins ")));try{await k1(f,r)}catch(y){if(w.error(y instanceof Error?y.message:"Unknown error occurred"),!r.silent)E(jr.default.red("Couldn't remove skill(s)"));process.exit(1)}}p();var cf=O(h(),1);async function X1(){m(cf.default.bgCyan(cf.default.black(" flins ")));try{await Z1(),E(cf.default.green("Showing all installed skills"))}catch(f){w.error(f instanceof Error?f.message:"Unknown error occurred"),E(cf.default.red("Couldn't list skills")),process.exit(1)}}p();Ey();var v=O(h(),1);async function M1(){m(v.default.bgCyan(v.default.black(" flins ")));try{let f=rf();f.start("Loading skill directory...");let r=await Ur();if(f.stop("Directory loaded"),r.length===0){w.warn("No skills found in directory"),E("Check back later for new skills");return}let y=await Mi({message:"Select a skill to view details:",options:r.map((D)=>({value:D.name,label:D.name,hint:`${D.author} - ${D.description.slice(0,50)}${D.description.length>50?"...":""}`})),placeholder:"Type to search..."});if(V(y)){N("Search cancelled");return}let i=Array.isArray(y)&&y.length>0?y[0]:y;if(!i){N("No selection made");return}let n=r.find((D)=>D.name===i);if(!n)return;X0(n);let b=await Rf({message:"Install this skill?"});if(V(b)||!b){E("Install anytime with "+v.default.green(`flins add ${n.name}`));return}let{installCommand:S}=await Promise.resolve().then(() => (cy(),L1));await S(n.name,{})}catch(f){w.error(f instanceof Error?f.message:"Failed to fetch directory"),E(v.default.red("Couldn't load directory")),process.exit(1)}}function X0(f){if(w.step(v.default.bold("Skill Details")),w.message(`${v.default.cyan(f.name)}`),w.message(` ${v.default.dim(f.description)}`),f.tags.length>0)w.message(` ${v.default.bold("Tags:")} ${f.tags.map((r)=>v.default.green(r)).join(", ")}`);w.message(` ${v.default.bold("Author:")} ${v.default.yellow(f.author)}`),w.message(` ${v.default.bold("Source:")} ${v.default.dim(f.source)}`),w.message(` ${v.default.dim("Install with:")} ${v.default.green(`flins add ${f.name}`)}`)}p();var Wf=O(h(),1);async function z1(f={}){if(!f.silent)m(Wf.default.bgCyan(Wf.default.black(" flins ")));try{if(await q1(f),!f.silent)E(Wf.default.green("State cleaned up"))}catch(r){if(w.error(r instanceof Error?r.message:"Unknown error occurred"),!f.silent)E(Wf.default.red("Cleanup failed"));process.exit(1)}}var M0=fi.version;d.name("flins").description("Universal skill package manager for AI coding agents. Install, manage, and update custom skills across Claude Code, Cursor, Copilot, Gemini, Windsurf, Trae, Factory, Letta, OpenCode, Codex, and 8+ more AI development tools from a single unified interface.").version(M0).action(()=>{d.help()});d.command("add <source>",{isDefault:!1}).description("Install skills from git repository").alias("a").option("-g, --global","Install skill globally (user-level) instead of project-level").option("-a, --agent <agents...>","Specify target agents (auto-detects if omitted). Supports: claude-code, cursor, copilot, gemini, windsurf, trae, factory, letta, opencode, codex, antigravity, amp, kilo, roo, goose, qoder").option("-s, --skill <skills...>","Install specific skills by name (skip interactive selection)").option("-l, --list","List all available skills in the source repository without installing").option("-y, --yes","Auto-confirm all prompts (non-interactive mode)").option("-f, --force","Skip all confirmations").option("--silent","Suppress banner and non-error output").action(async(f,r)=>{await Gy(f,r)});d.command("update [skills...]").description("Update installed skills to their latest versions from git sources").option("-y, --yes","Auto-confirm all prompts (non-interactive mode)").option("-f, --force","Skip all confirmations").option("--silent","Suppress banner and non-error output").action(async(f,r)=>{await J1(f,r)});d.command("outdated [skills...]").description("Check installation status, available updates, and orphaned skills").option("-v, --verbose","Show detailed information including installation paths").action(async(f,r)=>{await x1(f,r)});d.command("remove [skills...]").description("Uninstall skills from your AI coding agents").option("-y, --yes","Auto-confirm all prompts (non-interactive mode)").option("-f, --force","Skip all confirmations").option("--silent","Suppress banner and non-error output").action(async(f,r)=>{await Q1(f,r)});d.command("list").description("List all installed skills across your AI coding agents").action(async()=>{await X1()});d.command("search").description("Browse and discover available skills from the flins directory").action(async()=>{await M1()});d.command("clean").description("Remove orphaned skill entries from state tracking").option("-y, --yes","Auto-confirm all prompts (non-interactive mode)").option("-f, --force","Skip all confirmations").option("--silent","Suppress banner and non-error output").action(async(f)=>{await z1(f)});d.parse();
|
|
101
|
+
`)},info:(f,r)=>{w.message(f,{...r,symbol:P.default.blue(ib)})},success:(f,r)=>{w.message(f,{...r,symbol:P.default.green(nb)})},step:(f,r)=>{w.message(f,{...r,symbol:P.default.green(Ly)})},warn:(f,r)=>{w.message(f,{...r,symbol:P.default.yellow(bb)})},warning:(f,r)=>{w.warn(f,r)},error:(f,r)=>{w.message(f,{...r,symbol:P.default.red(Db)})}},Yb=P.default.magenta,PD={light:c("─","-"),heavy:c("━","="),block:c("█","#")},_D=`${P.default.gray(j)} `});function Ui(f){let r=f.match(/github\.com\/([^/]+)\/([^/]+)\/tree\/([^/]+)(?:\/(.+))?$/);if(r){let[,S,D,$,l]=r;return{type:"github",url:`https://github.com/${S}/${D}.git`,branch:$,subpath:l}}let y=f.match(/github\.com\/([^/]+)\/([^/]+)/);if(y){let[,S,D]=y,$=D.replace(/\.git$/,"");return{type:"github",url:`https://github.com/${S}/${$}.git`}}let i=f.match(/gitlab\.com\/([^/]+)\/([^/]+)\/-\/tree\/([^/]+)(?:\/(.+))?$/);if(i){let[,S,D,$,l]=i;return{type:"gitlab",url:`https://gitlab.com/${S}/${D}.git`,branch:$,subpath:l}}let n=f.match(/gitlab\.com\/([^/]+)\/([^/]+)/);if(n){let[,S,D]=n,$=D.replace(/\.git$/,"");return{type:"gitlab",url:`https://gitlab.com/${S}/${$}.git`}}let b=f.match(/^([^/]+)\/([^/]+)(?:\/(.+))?$/);if(b&&!f.includes(":")){let[,S,D,$]=b;return{type:"github",url:`https://github.com/${S}/${D}.git`,subpath:$}}return{type:"git",url:f}}import{join as Zb}from"path";import{rmSync as Qb}from"fs";import{tmpdir as Xb}from"os";import{spawn as Iy}from"child_process";async function ir(f,r){let y=Zb(Xb(),`flins-${Date.now()}`),i=["clone","--depth","1"];if(r)i.push("--branch",r);return i.push(f,y),await new Promise((n,b)=>{let S=Iy("git",i,{stdio:"pipe"});S.on("close",(D)=>{if(D===0)n();else b(Error(`Failed to clone repository: ${f}`))}),S.on("error",b)}),y}async function Bi(f,r="main"){return await new Promise((i,n)=>{let b="",S=Iy("git",["ls-remote",f,`refs/heads/${r}`],{stdio:"pipe"});S.stdout?.on("data",(D)=>{b+=D.toString()}),S.on("close",(D)=>{if(D===0&&b.trim())i(b.trim().split(/\s+/)[0]??"");else n(Error(`Failed to get latest commit from ${f}`))}),S.on("error",n)})}async function nr(f){return await new Promise((y,i)=>{let n="",b=Iy("git",["rev-parse","HEAD"],{cwd:f,stdio:"pipe"});b.stdout?.on("data",(S)=>{n+=S.toString()}),b.on("close",(S)=>{if(S===0&&n.trim())y(n.trim());else i(Error("Failed to get commit hash"))}),b.on("error",i)})}async function br(f){Qb(f,{recursive:!0,force:!0})}var oy=()=>{};var Ki;var ji=W(()=>{Ki={opencode:{name:"opencode",displayName:"OpenCode",configDir:"~/.config/opencode",skillsDir:".opencode/skill",globalSkillsDir:"~/.config/opencode/skill",commandsDir:".opencode/command",globalCommandsDir:"~/.config/opencode/command"},"claude-code":{name:"claude-code",displayName:"Claude Code",configDir:"~/.claude",skillsDir:".claude/skills",globalSkillsDir:"~/.claude/skills",commandsDir:".claude/commands",globalCommandsDir:"~/.claude/commands"},codex:{name:"codex",displayName:"Codex",configDir:"~/.codex",skillsDir:".codex/skills",globalSkillsDir:"~/.codex/skills"},cursor:{name:"cursor",displayName:"Cursor",configDir:"~/.cursor",skillsDir:".cursor/skills",globalSkillsDir:"~/.cursor/skills"},amp:{name:"amp",displayName:"Amp",configDir:"~/.config/agents",skillsDir:".agents/skills",globalSkillsDir:"~/.config/agents/skills"},kilo:{name:"kilo",displayName:"Kilo Code",configDir:"~/.kilocode",skillsDir:".kilocode/skills",globalSkillsDir:"~/.kilocode/skills"},roo:{name:"roo",displayName:"Roo Code",configDir:"~/.roo",skillsDir:".roo/skills",globalSkillsDir:"~/.roo/skills"},goose:{name:"goose",displayName:"Goose",configDir:"~/.config/goose",skillsDir:".goose/skills",globalSkillsDir:"~/.config/goose/skills"},antigravity:{name:"antigravity",displayName:"Antigravity",configDir:"~/.gemini/antigravity",skillsDir:".agent/skills",globalSkillsDir:"~/.gemini/antigravity/skills"},copilot:{name:"copilot",displayName:"GitHub Copilot",configDir:"~/.copilot",skillsDir:".github/skills",globalSkillsDir:"~/.copilot/skills"},gemini:{name:"gemini",displayName:"Gemini CLI",configDir:"~/.gemini",skillsDir:".gemini/skills",globalSkillsDir:"~/.gemini/skills"},windsurf:{name:"windsurf",displayName:"Windsurf",configDir:"~/.codeium/windsurf",skillsDir:".windsurf/skills",globalSkillsDir:"~/.codeium/windsurf/skills"},trae:{name:"trae",displayName:"Trae",configDir:"~/.trae",skillsDir:".trae/skills",globalSkillsDir:"~/.trae/skills"},factory:{name:"factory",displayName:"Factory Droid",configDir:"~/.factory",skillsDir:".factory/skills",globalSkillsDir:"~/.factory/skills",commandsDir:".factory/commands",globalCommandsDir:"~/.factory/commands"},letta:{name:"letta",displayName:"Letta",configDir:"~/.letta",skillsDir:".skills",globalSkillsDir:"~/.letta/skills"},qoder:{name:"qoder",displayName:"Qoder",configDir:"~/.qoder",skillsDir:".qoder/skills",globalSkillsDir:"~/.qoder/skills"}}});import{homedir as zb}from"os";import{existsSync as Ub}from"fs";function Ei(){let f={},r=Ki;for(let[y,i]of Object.entries(r)){let n=y;f[n]={name:i.name,displayName:i.displayName,configDir:i.configDir.replace("~",Dr),skillsDir:i.skillsDir,globalSkillsDir:i.globalSkillsDir.replace("~",Dr),commandsDir:i.commandsDir,globalCommandsDir:i.globalCommandsDir?.replace("~",Dr),detectInstalled:async()=>{let b=i.configDir.replace("~",Dr);return Ub(b)}}}return f}var Dr,Hi;var Py=W(()=>{ji();Dr=zb(),Hi=process.env.DIRECTORY_URL||"https://flins.tech/directory.json"});var z;var yf=W(()=>{Py();z=Ei()});import{basename as Bb,dirname as jb}from"path";function _y(f){let r=f.match(/^---\n([\s\S]+?)\n---\n([\s\S]*)$/);if(!r)return{data:{},content:f};let y=r[1],i=r[2],n={};for(let b of y.split(`
|
|
102
|
+
`)){let S=b.indexOf(":");if(S===-1)continue;let D=b.slice(0,S).trim(),$=b.slice(S+1).trim();if($.startsWith('"')&&$.endsWith('"')||$.startsWith("'")&&$.endsWith("'"))n[D]=$.slice(1,-1);else if(D==="metadata")try{let l={},T=$.replace(/^\{|\}$/g,"").trim();if(T){for(let o of T.split(",")){let[_,I]=o.split("=").map((L)=>L.trim());if(_&&I)l[_]=I.replace(/^['"]|["']$/g,"")}n[D]=JSON.stringify(l)}}catch{n[D]=$}else n[D]=$}return{data:n,content:i}}function Sr(f,r){try{let{data:y}=_y(r);if(!y.name||!y.description)return null;return{name:y.name,description:y.description,path:jb(f),metadata:y.metadata?JSON.parse(y.metadata):void 0}}catch{return null}}function lf(f){return f.name||Bb(f.path)}var $r=()=>{};import{readdir as Gi,readFile as qy,stat as Kb}from"fs/promises";import{join as Tf}from"path";function Gb(f){let r=[f];for(let i of Eb)r.push(Tf(f,i));let y=new Set;for(let i of Object.values(z))y.add(Tf(f,i.skillsDir));return r.push(...y),r}async function Jy(f){try{let r=Tf(f,"SKILL.md");return(await Kb(r)).isFile()}catch{return!1}}async function ci(f,r=0,y=5){let i=[];if(r>y)return i;try{if(await Jy(f))i.push(f);let n=await Gi(f,{withFileTypes:!0});for(let b of n)if(b.isDirectory()&&!Hb.includes(b.name)){let S=await ci(Tf(f,b.name),r+1,y);i.push(...S)}}catch{}return i}async function lr(f,r){let y=[],i=new Set,n=r?Tf(f,r):f;if(await Jy(n)){let S=Tf(n,"SKILL.md"),D=await qy(S,"utf-8"),$=Sr(S,D);if($)return y.push($),y}let b=Gb(n);for(let S of b)try{let D=await Gi(S,{withFileTypes:!0});for(let $ of D)if($.isDirectory()){let l=Tf(S,$.name);if(await Jy(l)){let T=Tf(l,"SKILL.md"),o=await qy(T,"utf-8"),_=Sr(T,o);if(_&&!i.has(_.name))y.push(_),i.add(_.name)}}}catch{}if(y.length===0){let S=await ci(n);for(let D of S){let $=Tf(D,"SKILL.md"),l=await qy($,"utf-8"),T=Sr($,l);if(T&&!i.has(T.name))y.push(T),i.add(T.name)}}return y}var Hb,Eb;var xy=W(()=>{yf();$r();Hb=["node_modules",".git","dist","build","__pycache__"],Eb=["skills","skills/.curated","skills/.experimental","skills/.system"]});import{basename as cb}from"path";function Wi(f,r){try{let{data:y}=_y(r);return{name:y.name||cb(f,".md"),description:y.description,path:f,type:"markdown"}}catch{return null}}function xf(f){return f.name}var Yy=W(()=>{$r()});import{readdir as Vi,readFile as Wb}from"fs/promises";import{join as ky,extname as Vb}from"path";async function gi(f,r=0){let y=[];if(r>Cb)return y;try{let i=await Vi(f,{withFileTypes:!0});for(let n of i){if(gb.includes(n.name))continue;let b=ky(f,n.name);if(n.isDirectory())if(n.name==="commands")y.push(b);else{let S=await gi(b,r+1);y.push(...S)}}}catch{}return y}async function Fb(f){let r=[];try{let y=await Vi(f,{withFileTypes:!0});for(let i of y){if(Nb.has(i.name))continue;if(!i.isFile())continue;let n=ky(f,i.name);if(Vb(i.name).toLowerCase()!==".md")continue;try{let S=await Wb(n,"utf-8"),D=Wi(n,S);if(D)r.push(D)}catch{continue}}}catch{}return r}async function Tr(f,r){let y=[],i=new Set,n=r?ky(f,r):f,b=await gi(n);for(let S of b){let D=await Fb(S);for(let $ of D)if(!i.has($.name))y.push($),i.add($.name)}return y}var gb,Nb,Cb=5;var Zy=W(()=>{Yy();gb=["node_modules",".git","dist","build","__pycache__"],Nb=new Set(["README.md","readme.md",".DS_Store"])});import{mkdir as Ci,cp as Ob,access as ub,readdir as vb}from"fs/promises";import{join as Ni}from"path";async function Fi(f,r){await Ci(r,{recursive:!0});let y=await vb(f,{withFileTypes:!0});for(let i of y){if(hb(i.name))continue;let n=Ni(f,i.name),b=Ni(r,i.name);if(i.isDirectory())await Fi(n,b);else await Ob(n,b)}}async function Oi(f,r){try{return await Ci(r,{recursive:!0}),await Fi(f,r),{success:!0,path:r}}catch(y){return{success:!1,path:r,error:y instanceof Error?y.message:"Unknown error"}}}async function ui(f){try{return await ub(f),!0}catch{return!1}}var Ab,hb=(f)=>{if(Ab.has(f))return!0;if(f.startsWith("_"))return!0;return!1};var vi=W(()=>{Ab=new Set(["README.md","metadata.json"])});import{join as Ai}from"path";async function Lr(f,r,y){let i=z[r],n=y.global?i.globalSkillsDir:i.skillsDir,b=Ai(n,f.name);return{...await Oi(f.path,b),originalPath:f.path}}async function hi(f,r,y){let i=Qy(f,r,y);return ui(i)}function Qy(f,r,y){let i=z[r],n=y.global?i.globalSkillsDir:i.skillsDir;return Ai(n,f)}var Xy=W(()=>{yf();vi()});import{mkdir as mb,cp as ab}from"fs/promises";import{join as sb,dirname as pb}from"path";function wr(f){return mi.includes(f)}function ai(){return mi.filter((f)=>z[f]?.commandsDir)}async function db(f){await mb(f,{recursive:!0})}async function tb(f,r){try{return await db(pb(r)),await ab(f,r),{success:!0,path:r}}catch(y){return{success:!1,path:r,error:y instanceof Error?y.message:"Unknown error"}}}async function eb(f,r,y){let i=z[r],n=y.global?i.globalCommandsDir:i.commandsDir,b=sb(n,`${f.name}.md`);return tb(f.path,b)}async function Rr(f,r,y){if(!wr(r))return{success:!1,path:"",originalPath:f.path,error:`Agent ${r} does not support commands`};if(!z[r].commandsDir)return{success:!1,path:"",originalPath:f.path,error:`Agent ${r} has no commands directory configured`};return{...await eb(f,r,y),originalPath:f.path}}var mi;var My=W(()=>{yf();mi=["claude-code","opencode","factory"]});async function si(){let f=[];for(let[r,y]of Object.entries(z))if(await y.detectInstalled())f.push(r);return f}var pi=W(()=>{yf()});import{resolve as f0}from"path";import{homedir as r0}from"os";function Ir(f){if(f.startsWith("~"))return f.replace("~",r0());return f}function If(f){return f.type==="global"?Ir(f.path):f0(process.cwd(),f.path)}var or=()=>{};import{homedir as y0}from"os";import{join as _r}from"path";import{existsSync as qr,readFileSync as i0,writeFileSync as ti,mkdirSync as n0,readdirSync as di}from"fs";function ei(){if(!qr(zy))n0(zy,{recursive:!0})}function Kf(){if(ei(),!qr(Pr)){let f={lastUpdate:new Date().toISOString(),skills:{}};return ti(Pr,JSON.stringify(f,null,2)),f}try{let f=i0(Pr,"utf-8");return JSON.parse(f)}catch{return{lastUpdate:new Date().toISOString(),skills:{}}}}function Jr(f){ei(),f.lastUpdate=new Date().toISOString(),ti(Pr,JSON.stringify(f,null,2))}function Uy(f,r,y,i,n,b="skill"){let S=Kf(),D=b==="skill"?`skill:${f.toLowerCase()}`:`command:${f.toLowerCase()}`,$=!1,l;if(!S.skills[D])S.skills[D]={url:r,subpath:y,branch:i,commit:n};else{if(S.skills[D].branch!==i)l=S.skills[D].branch,S.skills[D].branch=i,S.skills[D].commit=n,$=!0;if(S.skills[D].url=r,y)S.skills[D].subpath=y}return Jr(S),{updated:$,previousBranch:l}}function xr(f,r){let y=Kf(),i=r==="skill"?`skill:${f.toLowerCase()}`:`command:${f.toLowerCase()}`;delete y.skills[i],Jr(y)}function f1(f,r,y){let i=Kf(),n=r==="skill"?`skill:${f.toLowerCase()}`:`command:${f.toLowerCase()}`;if(i.skills[n])i.skills[n].commit=y,Jr(i)}function Yr(){return Kf()}function of(f,r){let y=[];for(let[i,n]of Object.entries(z))if(r==="skill"){let b=Ir(n.globalSkillsDir);if(qr(b))try{let D=di(b,{withFileTypes:!0}).find(($)=>$.isDirectory()&&$.name.toLowerCase()===f.toLowerCase());if(D)y.push({agent:i,installableType:"skill",type:"global",path:_r(n.globalSkillsDir,D.name)})}catch{}}else{let b=n.globalCommandsDir;if(b){let S=Ir(b);if(qr(S))try{let $=di(S,{withFileTypes:!0}).find((l)=>{return l.name.replace(/\.md$/,"").toLowerCase()===f.toLowerCase()});if($)y.push({agent:i,installableType:"command",type:"global",path:_r(b,$.name)})}catch{}}}return y}async function r1(){let f=Kf(),r=[];for(let[y,i]of Object.entries(f.skills)){let n=y.split(":");if(n.length!==2)continue;let b=n[0]==="skill"?"skill":"command",S=n[1];if(of(S,b).length===0)r.push(y)}for(let y of r)delete f.skills[y];if(r.length>0)Jr(f)}var zy,Pr;var kr=W(()=>{or();yf();zy=_r(y0(),".flins"),Pr=_r(zy,"skills.lock")});import{join as Zr,resolve as b0}from"path";import{existsSync as Qr,readFileSync as D0,writeFileSync as S0,rmSync as $0,readdirSync as y1}from"fs";function By(f){let r=f||process.cwd();return b0(r,l0)}function Xr(f){let r=By(f);if(!Qr(r))return null;try{let y=D0(r,"utf-8"),i=JSON.parse(y);if(!i.version||!i.skills)return null;return i}catch{return null}}function jy(f,r){let y=By(r);f.version=i1,S0(y,JSON.stringify(f,null,2))}function Ky(f,r,y,i,n,b,S){let D=Xr(S);if(!D)D={version:i1,skills:{}};let $=b==="skill"?`skill:${f.toLowerCase()}`:`command:${f.toLowerCase()}`,l=!1,T;if(!D.skills[$])D.skills[$]={url:r,subpath:y,branch:i,commit:n};else{if(D.skills[$].branch!==i)T=D.skills[$].branch,D.skills[$].branch=i,D.skills[$].commit=n,l=!0;if(D.skills[$].url=r,D.skills[$].commit=n,y)D.skills[$].subpath=y}return jy(D,S),{updated:l,previousBranch:T}}function n1(f,r,y){let i=Xr(y);if(!i)return;let n=r==="skill"?`skill:${f.toLowerCase()}`:`command:${f.toLowerCase()}`;if(delete i.skills[n],Object.keys(i.skills).length>0)jy(i,y);else{let b=By(y);if(Qr(b))try{$0(b,{force:!0})}catch{}}}function b1(f,r,y,i){let n=Xr(i);if(!n)return;let b=r==="skill"?`skill:${f.toLowerCase()}`:`command:${f.toLowerCase()}`,S=n.skills[b];if(S)S.commit=y,jy(n,i)}function Mr(f){return Xr(f)}function Yf(f,r,y){let i=[],n=y||process.cwd();for(let[b,S]of Object.entries(z))if(r==="skill"){let D=Zr(n,S.skillsDir);if(Qr(D))try{let l=y1(D,{withFileTypes:!0}).find((T)=>T.isDirectory()&&T.name.toLowerCase()===f.toLowerCase());if(l)i.push({agent:b,installableType:"skill",type:"project",path:Zr(S.skillsDir,l.name)})}catch{}}else{let D=S.commandsDir;if(D){let $=Zr(n,D);if(Qr($))try{let T=y1($,{withFileTypes:!0}).find((o)=>{return o.name.replace(/\.md$/,"").toLowerCase()===f.toLowerCase()});if(T)i.push({agent:b,installableType:"command",type:"project",path:Zr(D,T.name)})}catch{}}}return i}var i1="1.0.0",l0="skills.lock";var zr=W(()=>{yf()});async function D1(f,r){let y={tempDir:null,spinner:rf()};try{y.spinner.start("Parsing source...");let i=Ui(f),n=i.branch??"main";y.spinner.stop(`Source: ${Q.default.cyan(i.url)}${i.subpath?` (${i.subpath})`:""}${i.branch?` @ ${Q.default.cyan(i.branch)}`:""}`),y.spinner.start("Cloning repository..."),y.tempDir=await ir(i.url,i.branch),y.spinner.stop("Repository cloned");let b=await nr(y.tempDir);y.spinner.start("Discovering skills and commands...");let S=await lr(y.tempDir,i.subpath),D=await Tr(y.tempDir,i.subpath);if(S.length===0&&D.length===0)return y.spinner.stop(Q.default.red("No skills or commands found")),E(Q.default.red("No valid skills found. Skills require a SKILL.md with name and description.")),{success:!1,installed:0,failed:0,results:[]};let $=D.length>0;if(y.spinner.stop(`Found ${Q.default.green(S.length)} skill${S.length!==1?"s":""}`+($?` and ${Q.default.yellow(D.length)} command${D.length!==1?"s":""}`:"")),r.list){if(S.length>0){w.step(Q.default.bold("Available Skills"));for(let q of S)w.message(` ${Q.default.cyan(lf(q))}`),w.message(` ${Q.default.dim(q.description)}`)}if(D.length>0){w.step(Q.default.bold("Available Commands"));for(let q of D)w.message(` ${Q.default.cyan(xf(q))}`),w.message(` ${Q.default.dim(q.description||`Command: ${q.name}`)}`)}return E("Use --skill <name> to install specific skills or commands"),{success:!0,installed:0,failed:0,results:[]}}let l=await T0(S,r),T=l?await w0(r,y):null,o=D.length>0?await L0(D,r):null,_=o?await R0(r,y):null;if(!l&&!o)return{success:!1,installed:0,failed:0,results:[]};if(l&&!T)return{success:!1,installed:0,failed:0,results:[]};if(o&&!_)return{success:!1,installed:0,failed:0,results:[]};let I=await I0(r);if(I===null)return{success:!1,installed:0,failed:0,results:[]};if(!await o0(r,l,T,o,_,I))return{success:!1,installed:0,failed:0,results:[]};if(o&&o.length>0)w.warn(Q.default.yellow("Commands may change significantly or be removed - your feedback helps shape future releases"));y.spinner.start("Installing...");let R=await P0(l||[],T||[],o||[],_||[],I,i,b,n);return y.spinner.stop("Installation complete"),R}finally{if(y.tempDir)await br(y.tempDir)}}async function T0(f,r){if(f.length===0)return null;let y=[];if(r.skill&&r.skill.length>0){if(y=f.filter((i)=>r.skill.some((n)=>i.name.toLowerCase()===n.toLowerCase()||lf(i).toLowerCase()===n.toLowerCase())),y.length===0){w.error(`No matching skills found for: ${r.skill.join(", ")}`),w.info("Available skills:");for(let i of f)w.message(` - ${lf(i)}`);return null}w.info(`Selected ${y.length} skill${y.length!==1?"s":""}: ${y.map((i)=>Q.default.cyan(lf(i))).join(", ")}`)}else if(f.length===1){y=f;let i=f[0];w.info(`Skill: ${Q.default.cyan(lf(i))}`),w.message(Q.default.dim(i.description))}else if(r.yes||r.force)y=f,w.info(`Installing all ${f.length} skills`);else{let i=f.map((b)=>({value:b,label:lf(b),hint:b.description.length>60?b.description.slice(0,57)+"...":b.description})),n=await e({message:"Select skills to install",options:i,required:!1});if(V(n))return N("Installation cancelled"),null;if(!n||n.length===0)return w.info("No skills selected"),null;y=n}return y}async function L0(f,r){if(f.length===0)return null;w.warn(Q.default.yellow("⚠ Commands may change significantly or be removed - your feedback helps shape future releases")),w.message(Q.default.dim("See: https://github.com/senahq/flins#commands-experimental"));let y=[];if(r.skill&&r.skill.length>0)y=f.filter((i)=>r.skill.some((n)=>i.name.toLowerCase()===n.toLowerCase()||xf(i).toLowerCase()===n.toLowerCase()));if(y.length===0&&!r.yes&&!r.force){let i=f.map((b)=>({value:b,label:xf(b),hint:(b.description||`Command: ${b.name}`).slice(0,55)})),n=await e({message:"Select commands to install",options:i,required:!1});if(V(n))return N("Installation cancelled"),null;if(!n||n.length===0)return w.info("No commands selected"),null;y=n}else if(r.yes||r.force)y=f,w.info(`Installing all ${f.length} commands`);if(y.length>0)w.info(`Selected ${y.length} command${y.length!==1?"s":""}: ${y.map((i)=>Q.default.yellow(xf(i))).join(", ")}`);return y.length>0?y:null}async function w0(f,r){if(f.agent&&f.agent.length>0){let i=Object.keys(z),n=f.agent.filter((b)=>!i.includes(b));if(n.length>0)return w.error(`Invalid agents: ${n.join(", ")}`),w.info(`Valid agents: ${i.join(", ")}`),null;return f.agent}r.spinner.start("Detecting installed agents...");let y=await si();if(r.spinner.stop(`Detected ${y.length} agent${y.length!==1?"s":""}`),y.length===0)if(f.yes||f.force){let n=Object.keys(z);return w.info("Installing to all agents (none detected)"),n}else{w.warn("No coding agents detected. You can still install skills.");let n=Object.entries(z).map(([S,D])=>({value:S,label:D.displayName})),b=await e({message:"Select agents to install skills to",options:n,required:!0});if(V(b))return N("Installation cancelled"),null;return b}else if(y.length===1||f.yes||f.force){if(y.length===1){let i=y[0];w.info(`Installing skills to: ${Q.default.cyan(z[i].displayName)}`)}else w.info(`Installing skills to: ${y.map((i)=>Q.default.cyan(z[i].displayName)).join(", ")}`);return y}else{let i=y.map((b)=>({value:b,label:z[b].displayName,hint:z[b].skillsDir})),n=await e({message:"Select agents to install skills to",options:i,required:!0,initialValues:y});if(V(n))return N("Installation cancelled"),null;return n}}async function R0(f,r){let y=ai();if(f.agent&&f.agent.length>0){let D=Object.keys(z),$=f.agent.filter((o)=>!D.includes(o));if($.length>0)return w.error(`Invalid agents: ${$.join(", ")}`),w.info(`Valid agents: ${D.join(", ")}`),null;let l=f.agent.filter((o)=>wr(o));if(l.length===0)return w.error("Commands are only supported by: "+y.map((o)=>z[o].displayName).join(", ")),null;let T=f.agent.filter((o)=>!wr(o));if(T.length>0)w.warn(`Filtering out agents that don't support commands: ${T.join(", ")}`);return l}let i=y.filter((D)=>z[D]?.commandsDir);if(i.length===0)return w.warn("No agents with command support detected"),[];if(f.yes||f.force)return w.info(`Installing commands to: ${i.map((D)=>Q.default.cyan(z[D].displayName)).join(", ")}`),i;w.warn(Q.default.yellow("⚠ Commands may work differently across agents or be removed - your feedback helps shape future releases")),w.message(Q.default.dim("https://github.com/senahq/flins#commands-experimental"));let b=i.map((D)=>({value:D,label:z[D].displayName,hint:z[D].commandsDir||""})),S=await e({message:"Select agents to install commands to",options:b,required:!0,initialValues:i});if(V(S))return N("Installation cancelled"),null;return w.info(`Installing commands to: ${S.map((D)=>Q.default.cyan(z[D].displayName)).join(", ")}`),S}async function I0(f){let r=f.global??!1;if(f.global===void 0&&!(f.yes||f.force)){let y=await zi({message:"Installation scope",options:[{value:!1,label:"Project",hint:"Install in current directory (committed with your project)"},{value:!0,label:"Global",hint:"Install in home directory (available across all projects)"}]});if(V(y))return N("Installation cancelled"),null;r=y}return r}async function o0(f,r,y,i,n,b){if(w.step(Q.default.bold("Installation Summary")),r&&r.length>0&&y){w.message(Q.default.bold(Q.default.cyan("Skills")));for(let D of r){w.message(` ${Q.default.cyan(lf(D))}`);for(let $ of y){let l=Qy(D.name,$,{global:b}),o=await hi(D.name,$,{global:b})?Q.default.yellow(" (will overwrite)"):"";w.message(` ${Q.default.dim("→")} ${z[$].displayName}: ${Q.default.dim(l)}${o}`)}}}if(i&&i.length>0&&n&&n.length>0){w.message(Q.default.bold(Q.default.yellow("Commands (Experimental)")));for(let D of i){w.message(` ${Q.default.yellow(xf(D))} ${Q.default.dim("[experimental]")}`);for(let $ of n){let l=`${z[$].commandsDir}/${D.name}.md`;w.message(` ${Q.default.dim("→")} ${z[$].displayName}: ${Q.default.dim(l)}`)}}}if(!(f.yes||f.force)){let D=await Rf({message:"Proceed with installation?"});if(V(D)||!D)return N("Installation cancelled"),!1}return!0}async function P0(f,r,y,i,n,b,S,D){let $=[...f.flatMap((L)=>r.map((R)=>Lr(L,R,{global:n}))),...y.flatMap((L)=>i.map((R)=>Rr(L,R,{global:n})))],l=await Promise.all($),T=l.map((L,R)=>{let q=Math.floor(R/Math.max(r.length,i.length)),J=R%Math.max(r.length,i.length),x=R<f.length*r.length,k=x?f[q%f.length]:y[q%y.length],M=x?r:i,U=M[J%M.length];return{skill:x?lf(k):xf(k),agent:z[U].displayName,...L,installableType:x?"skill":"command"}}),o=new Map;for(let[L,R]of l.entries()){if(!R.success)continue;let q=L<f.length*r.length;if(n)if(q){let J=Math.floor(L/r.length),x=f[J%f.length],k=Uy(x.name,b.url,b.subpath,D,S,"skill");if(k.updated&&k.previousBranch){let M=o.get(x.name);o.set(x.name,{previous:M?.previous??k.previousBranch,current:M?.current??D})}}else{let J=Math.floor((L-f.length*r.length)/i.length),x=y[J%y.length];Uy(x.name,b.url,b.subpath,D,S,"command")}}if(!n)for(let[L,R]of l.entries()){if(!R.success)continue;if(L<f.length*r.length){let J=Math.floor(L/r.length),x=f[J%f.length];Ky(x.name,b.url,b.subpath,D,S,"skill")}else{let J=Math.floor((L-f.length*r.length)/i.length),x=y[J%y.length];Ky(x.name,b.url,b.subpath,D,S,"command")}}let _=T.filter((L)=>L.success),I=T.filter((L)=>!L.success);if(o.size>0)for(let[L,{previous:R,current:q}]of o)w.warn(Q.default.yellow(` ${Q.default.cyan(L)}: ${Q.default.dim(R)} → ${Q.default.green(q)}`));if(_.length>0){let L=_.filter((J)=>J.installableType==="skill").length,R=_.filter((J)=>J.installableType==="command").length,q=[];if(L>0)q.push(`${L} skill${L!==1?"s":""}`);if(R>0)q.push(`${R} command${R!==1?"s":""}`);w.success(Q.default.green(`Successfully installed ${q.join(" and ")}`));for(let J of _){let x=J.installableType==="command"?Q.default.yellow("⚡"):Q.default.green("✓");w.message(` ${x} ${J.skill} → ${J.agent}`),w.message(` ${Q.default.dim(J.path)}`)}}if(I.length>0){w.error(Q.default.red(`Failed to install ${I.length} item${I.length!==1?"s":""}`));for(let L of I)w.message(` ${Q.default.red("✗")} ${L.skill} → ${L.agent}`),w.message(` ${Q.default.dim(L.error)}`)}if(_.length>0)E(Q.default.green("Installation complete"));else E(Q.default.yellow("No items were installed"));return{success:I.length===0,installed:_.length,failed:I.length,results:T}}var Q;var S1=W(()=>{p();oy();xy();Zy();$r();Yy();Xy();My();pi();yf();kr();zr();Q=O(h(),1)});async function $1(){let f=Date.now();if(Hf&&Hy&&f<Hy)return Hf;try{let r=await fetch(Hi,{signal:AbortSignal.timeout(5000)});if(!r.ok)throw Error(`Failed to fetch directory: ${r.status}`);let y=await r.json();return Hf=y,Hy=f+_0,y}catch(r){if(Hf)return Hf;throw r}}async function l1(f){return(await $1()).find((i)=>i.name.toLowerCase()===f.toLowerCase())?.source??null}function T1(f){return/^[a-z0-9-]+$/i.test(f)&&!f.includes("/")&&!f.includes(":")}async function Ur(){return $1()}var Hf=null,Hy=null,_0=300000;var Ey=W(()=>{Py()});var L1={};G1(L1,{installCommand:()=>Gy});async function Gy(f,r){if(!r.silent)m(Lf.default.bgCyan(Lf.default.black(" flins ")));try{let y=f;if(T1(f)){if(!r.silent)w.info(`Looking up "${Lf.default.cyan(f)}" in flins directory...`);let n=await l1(f);if(!n){w.error(`Skill "${Lf.default.cyan(f)}" not found in directory.`);let b=await Ur();if(b.length>0){w.info("Available skills:");for(let S of b)w.message(` ${Lf.default.cyan(S.name)} - ${Lf.default.dim(S.description)}`)}process.exit(1)}if(y=n,!r.silent)w.success(`Found: ${Lf.default.cyan(y)}`)}let i=await D1(y,r);if(!i.success&&i.installed===0&&i.failed===0)process.exit(1);if(i.failed>0)process.exit(1)}catch(y){if(w.error(y instanceof Error?y.message:"Unknown error occurred"),!r.silent)E(Lf.default.red("Couldn't install skill"));process.exit(1)}}var Lf;var cy=W(()=>{p();S1();Ey();Lf=O(h(),1)});var ey=O(ty(),1),{program:d,createCommand:W0,createArgument:V0,createOption:g0,CommanderError:N0,InvalidArgumentError:C0,InvalidOptionArgumentError:F0,Command:O0,Argument:u0,Option:v0,Help:A0}=ey.default;var fi={name:"flins",version:"0.0.2",description:"Universal skill installer for AI coding agents - Claude, Cursor, Copilot, and more",keywords:["agent-skills","ai-agents","claude","cli","coding-assistant","copilot","cursor","github-copilot","skills"],homepage:"https://github.com/flinstech/flins#readme",bugs:{url:"https://github.com/flinstech/flins/issues"},license:"MIT",author:"flins",repository:{type:"git",url:"git+https://github.com/flinstech/flins.git"},bin:{flins:"./dist/index.js"},files:["dist","README.md"],type:"module",module:"src/index.ts",scripts:{build:"bun build src/index.ts --outdir dist --target node --minify",dev:"bun src/index.ts",typecheck:"tsgo --noEmit",prepublishOnly:"bun run build",lint:"oxlint","lint:fix":"oxlint --fix",fmt:"oxfmt","fmt:check":"oxfmt --check"},dependencies:{"@clack/prompts":"^1.0.0-alpha.9",commander:"^14.0.2",picocolors:"^1.1.1"},devDependencies:{"@types/bun":"latest","@typescript/native-preview":"^7.0.0-dev.20260116.1","bun-types":"^1.3.6",oxfmt:"^0.24.0",oxlint:"^1.39.0"}};cy();p();var Br=O(h(),1);p();oy();xy();Zy();Xy();My();kr();zr();var X=O(h(),1);import{join as Y0}from"path";function Zf(f){if(f.startsWith("skill:"))return{type:"skill",name:f.slice(6),installableType:"skill"};if(f.startsWith("command:"))return{type:"command",name:f.slice(8),installableType:"command"};return null}yf();import{existsSync as w1,readdirSync as q0,statSync as R1}from"fs";function J0(f){if(!w1(f))return!1;try{if(!R1(f).isDirectory())return!1;let y=q0(f);if(y.length===0)return!1;return y.includes("SKILL.md")}catch{return!1}}function x0(f){if(!w1(f))return!1;try{if(!R1(f).isFile())return!1;return f.endsWith(".md")}catch{return!1}}function Pf(f,r){return r==="skill"?J0(f):x0(f)}or();p();var Qf=O(h(),1);function Ef(){w.warn("No skills installed yet. Get started by installing a skill:"),w.message(` ${Qf.default.cyan("npx flins@latest <repo>")} # Install in current project`),w.message(` ${Qf.default.cyan("npx flins@latest <repo> --global")} # Install globally for all projects`),w.message(` ${Qf.default.dim("Examples:")}`),w.message(` ${Qf.default.cyan("npx flins@latest expo")} # Install from flins directory`),w.message(` ${Qf.default.cyan("npx flins@latest search")} # Browse available skills`)}var s=(f,r,y)=>{return f===1?r:y??`${r}s`};function o1(){let f=[],r=new Set,y=Mr();if(y)for(let[n,b]of Object.entries(y.skills)){let S=Zf(n);if(S)f.push({skillName:S.name,url:b.url,subpath:b.subpath,branch:b.branch,commit:b.commit,isLocal:!0,installableType:S.installableType}),r.add(`${S.installableType}:${S.name.toLowerCase()}`)}let i=Yr();for(let[n,b]of Object.entries(i.skills)){let S=Zf(n),D=S?`${S.installableType}:${S.name.toLowerCase()}`:n.toLowerCase();if(!r.has(D))f.push({skillName:S?.name??n,url:b.url,subpath:b.subpath,branch:b.branch,commit:b.commit,isLocal:!1,installableType:S?.installableType??"skill"})}return f}async function I1(f,r,y,i,n,b){let D=(n?Yf(f,b):of(f,b)).map((l)=>{let T=If(l);return{agent:z[l.agent].displayName,path:T,exists:Pf(T,l.installableType)}});if(D.filter((l)=>l.exists).length===0)return{skillName:f,currentCommit:i,latestCommit:i,status:"orphaned",installableType:b,installations:D};try{let l=await Bi(r,y);return{skillName:f,currentCommit:i,latestCommit:l,status:l===i?"latest":"update-available",installableType:b,installations:D}}catch(l){return{skillName:f,currentCommit:i,latestCommit:i,status:"error",installableType:b,installations:D,error:l instanceof Error?l.message:"Unknown error"}}}async function Wy(f){let r=o1(),y=[],i;if(f&&f.length>0){let b=new Set(f.map((S)=>S.toLowerCase()));i=r.filter(({skillName:S})=>b.has(S.toLowerCase()))}else i=r;if(i.length===0)return[];let n=rf();if(i.length===1){let{skillName:b,url:S,branch:D,commit:$,isLocal:l,installableType:T}=i[0];n.start(`Checking ${X.default.cyan(b)}...`);let o=await I1(b,S,D,$,l,T);n.stop(o.status==="latest"?X.default.green("Up to date"):X.default.yellow("Update available")),y.push(o)}else{n.start(`Checking ${i.length} ${s(i.length,"skill")}...`);for(let{skillName:b,url:S,branch:D,commit:$,isLocal:l,installableType:T}of i){let o=await I1(b,S,D,$,l,T);y.push(o)}n.stop("Check complete")}return y}async function P1(f,r={}){let y=o1(),i=[],n;if(f&&f.length>0){let I=new Set(f.map((L)=>L.toLowerCase()));n=y.filter(({skillName:L})=>I.has(L.toLowerCase()))}else n=y;if(n.length===0)return w.warn("No skills found to update"),E(X.default.yellow("Nothing to update")),[];let b=await Wy(f),S=b.filter((I)=>I.status==="update-available");if(S.length===0){let I=b.filter((L)=>L.status==="orphaned");if(I.length>0){w.warn(`${I.length} skill${I.length>1?"s":""} ${I.length>1?"have":"has"} no valid installations`);for(let L of I)w.message(` ${X.default.yellow("○")} ${X.default.cyan(L.skillName)} - files were removed`)}return w.success(X.default.green("All skills are up to date")),E(X.default.green("Already up to date")),[]}w.step(X.default.bold("Updates Available"));let D=S.map((I)=>({value:I.skillName,label:I.skillName,hint:`${I.currentCommit.slice(0,7)} → ${I.latestCommit.slice(0,7)}`})),$,l=r.yes||r.force;if(l)$=S.map((I)=>I.skillName);else{let I=await e({message:"Select skills to update",options:D,required:!0,initialValues:S.map((L)=>L.skillName)});if(V(I))return N("Update cancelled"),[];$=I}w.step(X.default.bold("Will Update"));for(let I of $){let L=S.find((R)=>R.skillName===I);if(L)w.message(` ${X.default.cyan(L.skillName)}`),w.message(` ${X.default.dim("Current:")} ${X.default.yellow(L.currentCommit.slice(0,7))} ${X.default.dim("→")} ${X.default.green(L.latestCommit.slice(0,7))}`)}if(!l){let I=await Rf({message:"Proceed with update?"});if(V(I)||!I)return N("Update cancelled"),[]}let T=rf();T.start(`Updating ${$.length} ${s($.length,"skill")}...`);for(let{skillName:I,url:L,subpath:R,isLocal:q,installableType:J}of n){let x=b.find((H)=>H.skillName===I);if(!x||x.status!=="update-available"){if(x?.status==="latest")i.push({skillName:I,success:!0,updated:0,failed:0});else i.push({skillName:I,success:!1,updated:0,failed:0});continue}if(!$.includes(I))continue;let k=null,M=0,U=0;try{k=await ir(L);let H=await nr(k),Y=R?Y0(k,R):k,Z=await lr(Y),F=await Tr(Y),C=Z.find((B)=>B.name.toLowerCase()===I.toLowerCase()),g=F.find((B)=>B.name.toLowerCase()===I.toLowerCase());if(!C&&!g)throw Error("Skill or command not found in repository");let nf=q?Yf(I,J):of(I,J);for(let B of nf){let A=If(B);if(!Pf(A,B.installableType)){if(!q)xr(I,J);continue}let a;if(B.installableType==="command"&&g)a=await Rr(g,B.agent,{global:B.type==="global"});else if(C)a=await Lr(C,B.agent,{global:B.type==="global"});else{U++;continue}if(a.success)M++;else U++}if(q)b1(I,J,H);else f1(I,J,H);i.push({skillName:I,success:U===0,updated:M,failed:U})}catch(H){i.push({skillName:I,success:!1,updated:M,failed:U+1,error:H instanceof Error?H.message:"Unknown error"})}finally{if(k)await br(k)}}T.stop("Update complete");let o=i.filter((I)=>I.success&&I.updated>0),_=i.filter((I)=>!I.success||I.failed>0);if(o.length>0){w.success(X.default.green(`Updated ${o.length} ${s(o.length,"skill")}`));for(let I of o)w.message(` ${X.default.green("✓")} ${X.default.cyan(I.skillName)} (${I.updated} ${s(I.updated,"installation")})`)}if(_.length>0){w.error(X.default.red(`Failed to update ${_.length} ${s(_.length,"skill")}`));for(let I of _)if(w.message(` ${X.default.red("✗")} ${X.default.cyan(I.skillName)}`),I.error)w.message(` ${X.default.dim(I.error)}`)}if(o.length>0)E(X.default.green("Skills updated successfully"));else E(X.default.yellow("No skills were updated"));return i}async function _1(f,r=!1){if(f.length===0){Ef();return}w.step(X.default.bold("Skills Status"));for(let y of f){let i={latest:X.default.green("✓"),"update-available":X.default.yellow("↓"),error:X.default.red("✗"),orphaned:X.default.dim("○")}[y.status],n={latest:X.default.green("latest"),"update-available":X.default.yellow("update available"),error:X.default.red("error"),orphaned:X.default.dim("orphaned")}[y.status],b=y.installations.filter((D)=>D.exists),S=y.installations.filter((D)=>!D.exists);if(!r){let D=b.length,$=D>0?` (${D} ${s(D,"installation")})`:"";w.message(`${i} ${X.default.cyan(y.installableType+":"+y.skillName)}${X.default.dim($)} - ${n}`)}else{if(w.message(`${i} ${X.default.cyan(y.installableType+":"+y.skillName)}`),w.message(` Status: ${n}`),y.status==="update-available")w.message(` ${X.default.dim("Commit:")} ${X.default.yellow(y.currentCommit.slice(0,7))} ${X.default.dim("→")} ${X.default.green(y.latestCommit.slice(0,7))}`);else if(y.status==="latest")w.message(` ${X.default.dim("Commit:")} ${y.currentCommit.slice(0,7)}`);if(y.error)w.message(` ${X.default.red(y.error)}`);if(b.length>0){w.message(` ${X.default.dim("Installed in:")}`);for(let D of b)w.message(` ${X.default.dim("•")} ${D.agent}: ${X.default.dim(D.path)}`)}if(S.length>0){w.message(` ${X.default.yellow("Missing installations:")}`);for(let D of S)w.message(` ${X.default.dim("•")} ${D.agent}: ${X.default.dim(D.path)}`)}}}if(!r)w.info(`Use ${X.default.cyan("--verbose")} or ${X.default.cyan("-v")} for detailed information`)}async function q1(f={}){let r=rf();r.start("Checking for orphaned entries..."),await r1(),r.stop(X.default.green("State cleaned up"))}async function J1(f,r){if(!r.silent)m(Br.default.bgCyan(Br.default.black(" flins ")));try{await P1(f.length>0?f:void 0,r)}catch(y){if(w.error(y instanceof Error?y.message:"Unknown error occurred"),!r.silent)E(Br.default.red("Couldn't update skill(s)"));process.exit(1)}}p();var Gf=O(h(),1);async function x1(f,r={}){if(!r.silent)m(Gf.default.bgCyan(Gf.default.black(" flins ")));try{let y=await Wy(f.length>0?f:void 0),i=r.verbose||f.length>0;if(await _1(y,i),!r.silent)E(Gf.default.green("All checks complete"))}catch(y){if(w.error(y instanceof Error?y.message:"Unknown error occurred"),!r.silent)E(Gf.default.red("Couldn't check status"));process.exit(1)}}p();var jr=O(h(),1);p();kr();zr();var K=O(h(),1);import{existsSync as k0,rmSync as Z0}from"fs";yf();or();function Y1(){let f=[],r=new Set,y=Mr();if(y)for(let[n,b]of Object.entries(y.skills)){let S=Zf(n);if(S)f.push({skillName:S.name,url:b.url,subpath:b.subpath,branch:b.branch,commit:b.commit,isLocal:!0,installableType:S.installableType}),r.add(`${S.installableType}:${S.name.toLowerCase()}`)}let i=Yr();for(let[n,b]of Object.entries(i.skills)){let S=Zf(n),D=S?`${S.installableType}:${S.name.toLowerCase()}`:n.toLowerCase();if(!r.has(D))f.push({skillName:S?.name??n,url:b.url,subpath:b.subpath,branch:b.branch,commit:b.commit,isLocal:!1,installableType:S?.installableType??"skill"})}return f}async function Q0(f){try{if(k0(f))Z0(f,{recursive:!0,force:!0});return{success:!0}}catch(r){return{success:!1,error:r instanceof Error?r.message:"Unknown error"}}}async function k1(f=[],r={}){let y=Y1(),i=[];if(y.length===0)return Ef(),[];let n;if(f.length>0){let _=new Set(f.map((I)=>I.toLowerCase()));n=y.filter(({skillName:I})=>_.has(I.toLowerCase()))}else{let I=y.map(({skillName:R,isLocal:q,installableType:J})=>{let k=(q?Yf(R,J):of(R,J)).map((M)=>({installation:M,resolvedPath:If(M)})).filter(({installation:M,resolvedPath:U})=>Pf(U,M.installableType));return{value:R,label:R,hint:k.length>0?`${k.length} ${s(k.length,"installation")}`:"no valid installations"}}).filter((R)=>R.hint!=="no valid installations");if(I.length===0)return w.warn("No valid installations found"),[];if(r.yes||r.force)n=y.filter(({skillName:R})=>I.some((q)=>q.value===R));else{let R=await e({message:"Select skills to remove",options:I,required:!0,initialValues:I.map((J)=>J.value)});if(V(R))return N("Remove cancelled"),[];let q=R;n=y.filter(({skillName:J})=>q.includes(J))}}if(n.length===0){if(f.length>0){w.error(`No matching skills found for: ${f.join(", ")}`),w.info("Tracked skills:");for(let _ of y)w.message(` - ${K.default.cyan(_.skillName)}`)}return[]}w.step(K.default.bold("Skills to Remove"));let b=[];for(let{skillName:_,isLocal:I,installableType:L}of n){let q=(I?Yf(_,L):of(_,L)).map((J)=>({installation:J,resolvedPath:If(J)})).filter(({installation:J,resolvedPath:x})=>Pf(x,J.installableType));if(q.length>0){b.push({skillName:_,isLocal:I,installableType:L,installations:q}),w.message(` ${K.default.cyan(_)}`);for(let{resolvedPath:J}of q)w.message(` ${K.default.dim("→")} ${J}`)}}if(b.length===0)return w.warn("No installations match the specified criteria"),[];let S=f.length===0,D,$=r.yes||r.force;if($||S)D=b.map(({skillName:_})=>_);else{let _=b.map(({skillName:L,installations:R})=>({value:L,label:L,hint:`${R.length} ${s(R.length,"installation")}`})),I=await e({message:"Select skills to remove",options:_,required:!0,initialValues:b.map(({skillName:L})=>L)});if(V(I))return N("Remove cancelled"),[];D=I}w.step(K.default.bold("Will Remove"));for(let _ of D){let I=b.find((L)=>L.skillName===_);if(I){w.message(` ${K.default.cyan(I.skillName)}`);for(let{resolvedPath:L}of I.installations)w.message(` ${K.default.dim("→")} ${L}`)}}if(!$){let _=await Rf({message:"Remove these skills?"});if(V(_)||!_)return N("Remove cancelled"),[]}let l=rf();l.start(`Removing ${D.length} skill${D.length>1?"s":""}...`);for(let{skillName:_,isLocal:I,installableType:L,installations:R}of b){if(!D.includes(_))continue;let q={skillName:_,success:!0,removed:0,failed:0,installations:[]};for(let{installation:J,resolvedPath:x}of R){let k=await Q0(x);if(q.installations.push({agent:z[J.agent].displayName,path:x,removed:k.success,error:k.error}),k.success)q.removed++;else q.failed++,q.success=!1}if(q.removed>0)if(I)n1(_,L);else xr(_,L);i.push(q)}l.stop("Remove complete");let T=i.filter((_)=>_.success&&_.removed>0),o=i.filter((_)=>!_.success||_.failed>0);if(T.length>0){w.success(K.default.green(`Removed ${T.length} ${s(T.length,"skill")}`));for(let _ of T)w.message(` ${K.default.green("✓")} ${K.default.cyan(_.skillName)}`),w.message(` ${K.default.dim(`${_.removed} ${s(_.removed,"installation")} removed`)}`)}if(o.length>0){w.error(K.default.red(`Failed to remove ${o.length} ${s(o.length,"skill")}`));for(let _ of o){w.message(` ${K.default.red("✗")} ${K.default.cyan(_.skillName)}`);for(let I of _.installations.filter((L)=>!L.removed))if(I.error)w.message(` ${K.default.dim(I.error)}`)}}if(T.length>0)E(K.default.green("Skills removed successfully"));else E(K.default.yellow("No skills were removed"));return i}async function Z1(){let f=Y1();if(f.length===0){Ef();return}w.step(K.default.bold("Installed Skills and Commands"));let r=[],y=[];for(let{skillName:i,isLocal:n,installableType:b}of f)if(n)r.push({skillName:i,installableType:b});else y.push({skillName:i,installableType:b});if(r.length>0){if(y.length>0)w.message(K.default.bold(K.default.cyan("Local (from ./skills.lock)")));for(let{skillName:i,installableType:n}of r){w.message(`${K.default.green("✓")} ${K.default.cyan(n+":"+i)} ${n==="command"?K.default.yellow("(experimental)"):""}`);let S=Yf(i,n).map((D)=>({installation:D,resolvedPath:If(D)})).filter(({installation:D,resolvedPath:$})=>Pf($,D.installableType));if(S.length>0){w.message(` ${K.default.dim("Installed in:")}`);for(let{installation:D,resolvedPath:$}of S)w.message(` ${K.default.dim("•")} ${z[D.agent].displayName}: ${K.default.dim($)}`)}}}if(y.length>0){if(r.length>0)w.message(K.default.bold(K.default.cyan("Global (from ~/.flins/skills.lock)")));for(let{skillName:i,installableType:n}of y){let b=n==="command"?K.default.yellow("⚡"):K.default.green("✓");w.message(`${b} ${K.default.cyan(i)}`);let D=of(i,n).map(($)=>({installation:$,resolvedPath:If($)})).filter(({installation:$,resolvedPath:l})=>Pf(l,$.installableType));if(D.length>0){w.message(` ${K.default.dim("Installed in:")}`);for(let{installation:$,resolvedPath:l}of D)w.message(` ${K.default.dim("•")} ${z[$.agent].displayName}: ${K.default.dim(l)}`)}}}}async function Q1(f,r){if(!r.silent)m(jr.default.bgCyan(jr.default.black(" flins ")));try{await k1(f,r)}catch(y){if(w.error(y instanceof Error?y.message:"Unknown error occurred"),!r.silent)E(jr.default.red("Couldn't remove skill(s)"));process.exit(1)}}p();var cf=O(h(),1);async function X1(){m(cf.default.bgCyan(cf.default.black(" flins ")));try{await Z1(),E(cf.default.green("Showing all installed skills"))}catch(f){w.error(f instanceof Error?f.message:"Unknown error occurred"),E(cf.default.red("Couldn't list skills")),process.exit(1)}}p();Ey();var v=O(h(),1);async function M1(){m(v.default.bgCyan(v.default.black(" flins ")));try{let f=rf();f.start("Loading skill directory...");let r=await Ur();if(f.stop("Directory loaded"),r.length===0){w.warn("No skills found in directory"),E("Check back later for new skills");return}let y=await Mi({message:"Select a skill to view details:",options:r.map((D)=>({value:D.name,label:D.name,hint:`${D.author} - ${D.description.slice(0,50)}${D.description.length>50?"...":""}`})),placeholder:"Type to search..."});if(V(y)){N("Search cancelled");return}let i=Array.isArray(y)&&y.length>0?y[0]:y;if(!i){N("No selection made");return}let n=r.find((D)=>D.name===i);if(!n)return;X0(n);let b=await Rf({message:"Install this skill?"});if(V(b)||!b){E("Install anytime with "+v.default.green(`flins add ${n.name}`));return}let{installCommand:S}=await Promise.resolve().then(() => (cy(),L1));await S(n.name,{})}catch(f){w.error(f instanceof Error?f.message:"Failed to fetch directory"),E(v.default.red("Couldn't load directory")),process.exit(1)}}function X0(f){if(w.step(v.default.bold("Skill Details")),w.message(`${v.default.cyan(f.name)}`),w.message(` ${v.default.dim(f.description)}`),f.tags.length>0)w.message(` ${v.default.bold("Tags:")} ${f.tags.map((r)=>v.default.green(r)).join(", ")}`);w.message(` ${v.default.bold("Author:")} ${v.default.yellow(f.author)}`),w.message(` ${v.default.bold("Source:")} ${v.default.dim(f.source)}`),w.message(` ${v.default.dim("Install with:")} ${v.default.green(`flins add ${f.name}`)}`)}p();var Wf=O(h(),1);async function z1(f={}){if(!f.silent)m(Wf.default.bgCyan(Wf.default.black(" flins ")));try{if(await q1(f),!f.silent)E(Wf.default.green("State cleaned up"))}catch(r){if(w.error(r instanceof Error?r.message:"Unknown error occurred"),!f.silent)E(Wf.default.red("Cleanup failed"));process.exit(1)}}var M0=fi.version;d.name("flins").description("Universal skill package manager for AI coding agents. Install, manage, and update custom skills across Claude Code, Cursor, Copilot, Gemini, Windsurf, Trae, Factory, Letta, OpenCode, Codex, and 8+ more AI development tools from a single unified interface.").version(M0).action(()=>{d.help()});d.command("add <source>",{isDefault:!1}).description("Install skills from git repository").alias("a").option("-g, --global","Install skill globally (user-level) instead of project-level").option("-a, --agent <agents...>","Specify target agents (auto-detects if omitted). Supports: claude-code, cursor, copilot, gemini, windsurf, trae, factory, letta, opencode, codex, antigravity, amp, kilo, roo, goose, qoder").option("-s, --skill <skills...>","Install specific skills by name (skip interactive selection)").option("-l, --list","List all available skills in the source repository without installing").option("-y, --yes","Auto-confirm all prompts (non-interactive mode)").option("-f, --force","Skip all confirmations").option("--silent","Suppress banner and non-error output").action(async(f,r)=>{await Gy(f,r)});d.command("update [skills...]").description("Update installed skills to their latest versions from git sources").option("-y, --yes","Auto-confirm all prompts (non-interactive mode)").option("-f, --force","Skip all confirmations").option("--silent","Suppress banner and non-error output").action(async(f,r)=>{await J1(f,r)});d.command("outdated [skills...]").description("Check installation status, available updates, and orphaned skills").option("-v, --verbose","Show detailed information including installation paths").action(async(f,r)=>{await x1(f,r)});d.command("remove [skills...]").description("Uninstall skills from your AI coding agents").option("-y, --yes","Auto-confirm all prompts (non-interactive mode)").option("-f, --force","Skip all confirmations").option("--silent","Suppress banner and non-error output").action(async(f,r)=>{await Q1(f,r)});d.command("list").description("List all installed skills across your AI coding agents").action(async()=>{await X1()});d.command("search").description("Browse and discover available skills from the flins directory").action(async()=>{await M1()});d.command("clean").description("Remove orphaned skill entries from state tracking").option("-y, --yes","Auto-confirm all prompts (non-interactive mode)").option("-f, --force","Skip all confirmations").option("--silent","Suppress banner and non-error output").action(async(f)=>{await z1(f)});d.parse();
|