agent-skill-manager 1.4.0 → 1.4.1

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.
@@ -1,13 +1,15 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
- import{a as R,c as I,d as j0,e as u,f as O0,g as _0,h as m,i as T0,j as Y,k as c,l as A0,m as C,n as d,o as F0,q as E0,r as L0,s as p}from"./chunk-221zx7k2.js";import{A as _,B as M0,t as T,u as A,v as W0,w as E,x as G0,y as h,z as o}from"./chunk-zh7g5bam.js";import{execFile as R0}from"child_process";import{promisify as x0}from"util";import{mkdtemp as w0,readdir as n,readFile as w,rm as v,cp as y0,access as f,stat as t}from"fs/promises";import{join as L}from"path";import{tmpdir as N0}from"os";var l=x0(R0),S0=/^[a-zA-Z0-9_-]+$/,b0=/^[a-zA-Z0-9._-]+$/,D0=/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/,g=128;function i($){if(!$.startsWith("github:"))throw Error(`Invalid source: must start with "github:". Got: "${$}"
4
- Format: github:owner/repo[#ref]`);let Q=$.slice(7),K=Q.indexOf("#"),q,Z=null;if(K!==-1){if(q=Q.slice(0,K),Z=Q.slice(K+1),!Z)throw Error("Invalid source: ref cannot be empty after #")}else q=Q;let V=q.indexOf("/");if(V===-1)throw Error(`Invalid source: format must be github:owner/repo. Got: "${$}"`);let X=q.slice(0,V),U=q.slice(V+1);if(!X)throw Error("Invalid source: owner cannot be empty");if(!U)throw Error("Invalid source: repo cannot be empty");if(!S0.test(X))throw Error(`Invalid source: owner contains invalid characters: "${X}". Allowed: [a-zA-Z0-9_-]`);if(!b0.test(U))throw Error(`Invalid source: repo contains invalid characters: "${U}". Allowed: [a-zA-Z0-9._-]`);let z={owner:X,repo:U,ref:Z,cloneUrl:`https://github.com/${X}/${U}.git`};return E(`install: parsed source → owner=${X} repo=${U} ref=${Z}`),z}function y($){if(!$)throw Error("Invalid skill name: name cannot be empty");if($.includes("\x00"))throw Error("Invalid skill name: contains unsafe characters (null byte)");if($.includes(".."))throw Error("Invalid skill name: contains unsafe characters (..)");if($.includes("/")||$.includes("\\"))throw Error("Invalid skill name: contains unsafe characters (path separator)");if($.startsWith("."))throw Error("Invalid skill name: must not start with a dot");if($.length>g)throw Error(`Invalid skill name: exceeds maximum length of ${g} characters`);if(!D0.test($))throw Error(`Invalid skill name: "${$}" does not match allowed pattern [a-zA-Z0-9][a-zA-Z0-9._-]*`);return $}async function s(){try{await l("git",["--version"]),E("install: git available")}catch{throw Error("git is required for installing skills. Install git from https://git-scm.com")}}async function a($){E(`install: cloning ${$.cloneUrl}${$.ref?` (ref: ${$.ref})`:""}`);let Q=await w0(L(N0(),"asm-install-")),K=["clone","--depth","1"];if($.ref)K.push("--branch",$.ref);K.push($.cloneUrl,Q);try{await l("git",K,{timeout:60000})}catch(q){await S(Q);let Z=q.killed?"Clone timed out after 60 seconds":`Clone failed: ${q.stderr||q.message}`;throw Error(Z)}return Q}async function N($){let Q=L($,"SKILL.md"),K;try{K=await w(Q,"utf-8")}catch{throw Error("Not a valid skill: SKILL.md not found in repository root")}let q=R(K),Z=$.split("/").pop()||"unknown",V=q.name||Z,X=q.version||"0.0.0";return E(`install: validated skill "${V}" v${X}`),{name:V,version:X,description:(q.description||"").replace(/\s*\n\s*/g," ").trim()}}async function e($,Q=3){let K=[];async function q(Z,V,X){let U;try{U=await n(Z)}catch{return}for(let z of U){if(z===".git"||z==="node_modules")continue;let J=L(Z,z);try{if(!(await t(J)).isDirectory())continue}catch{continue}let B=V?`${V}/${z}`:z,O=X+1,W=L(J,"SKILL.md");try{let M=await w(W,"utf-8"),j=R(M);K.push({relPath:B,name:j.name||z,version:j.version||"0.0.0",description:(j.description||"").replace(/\s*\n\s*/g," ").trim()})}catch{if(O<Q)await q(J,B,O)}}}return await q($,"",0),K.sort((Z,V)=>Z.name.localeCompare(V.name)),K}var P0=[{category:"Shell commands",pattern:/\b(bash|sh\s+-c)\b/},{category:"Shell commands",pattern:/\bexec\(/},{category:"Shell commands",pattern:/\bchild_process\b/},{category:"Shell commands",pattern:/\bBun\.spawn\b/},{category:"Code execution",pattern:/\beval\(/},{category:"Code execution",pattern:/\bFunction\(/},{category:"Code execution",pattern:/\bnew\s+Function\b/},{category:"Credentials",pattern:/\b(API_KEY|SECRET|TOKEN|PASSWORD)\s*[=:]/},{category:"External URLs",pattern:/https?:\/\//}],v0=new Set([".png",".jpg",".jpeg",".gif",".ico",".bmp",".webp",".mp3",".mp4",".wav",".avi",".mov",".zip",".tar",".gz",".bz2",".7z",".exe",".dll",".so",".dylib",".woff",".woff2",".ttf",".eot",".pdf",".doc",".docx"]);async function f0($){let Q=[];async function K(q,Z){let V;try{V=await n(q)}catch{return}for(let X of V){if(X===".git")continue;if(X==="node_modules")continue;let U=L(q,X),z=Z?`${Z}/${X}`:X;try{let J=await t(U);if(J.isDirectory())await K(U,z);else if(J.isFile()){let B=X.includes(".")?`.${X.split(".").pop().toLowerCase()}`:"";if(v0.has(B))continue;if(J.size>524288)continue;try{let O=await w(U,"utf-8");Q.push({relPath:z,content:O})}catch{}}}catch{continue}}}return await K($,""),Q}async function r($){let Q=[],K=await f0($);for(let{relPath:q,content:Z}of K){let V=Z.split(`
5
- `);for(let X=0;X<V.length;X++)for(let{category:U,pattern:z}of P0)if(z.test(V[X])){let J=V[X].trim();Q.push({category:U,file:q,line:X+1,match:J.length>100?J.slice(0,100)+"…":J})}}return Q}async function $0($){let Q=`github:${$.source.owner}/${$.source.repo}${$.source.ref?`#${$.source.ref}`:""}`;if($.force)try{await f($.targetDir),await v($.targetDir,{recursive:!0,force:!0})}catch{}let K=$.sourceDir;try{await y0(K,$.targetDir,{recursive:!0})}catch(U){throw Error(`Failed to install: ${U.message}`)}let q=L($.targetDir,".git");try{await v(q,{recursive:!0,force:!0})}catch{}E(`install: copied files to ${$.targetDir}`);let Z=L($.targetDir,"SKILL.md");try{await f(Z)}catch{throw Error("Installation verification failed: SKILL.md not found at target")}let V=await w(Z,"utf-8"),X=R(V);return{success:!0,path:$.targetDir,name:X.name||$.skillName,version:X.version||"0.0.0",provider:$.providerLabel,source:Q}}async function S($){try{await v($,{recursive:!0,force:!0})}catch{}}async function b($,Q,K){let q=$.providers.filter((X)=>X.enabled);if(q.length===0)throw Error("No providers are enabled. Enable a provider in your config.");if(Q){let X=$.providers.find((U)=>U.name===Q);if(!X){let U=$.providers.map((z)=>z.name).join(", ");throw Error(`Unknown provider: "${Q}". Valid providers: ${U}`)}if(!X.enabled)throw Error(`Provider "${Q}" is disabled. Enable it in your config or choose another provider.`);return X}if(q.length===1)return q[0];if(!K){let X=q.map((U)=>U.name).join(", ");throw Error(`--provider is required in non-interactive mode. Available: ${X}`)}console.error(`
3
+ import{a as x,c as I,d as j0,e as u,f as O0,g as _0,h as m,i as A0,j as Y,k as c,l as F0,m as C,n as d,o as T0,q as E0,r as L0,s as p}from"./chunk-s1gskd5a.js";import{A as _,B as M0,t as A,u as F,v as B0,w as E,x as G0,y as h,z as o}from"./chunk-zh7g5bam.js";import{execFile as x0}from"child_process";import{promisify as R0}from"util";import{mkdtemp as w0,readdir as n,readFile as w,rm as v,cp as y0,access as f,stat as t}from"fs/promises";import{join as L}from"path";import{tmpdir as N0}from"os";var l=R0(x0),S0=/^[a-zA-Z0-9_-]+$/,b0=/^[a-zA-Z0-9._-]+$/,D0=/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/,g=128,P0=/^https?:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\/tree\/(.+))?\/?$/;function i($){let Q=P0.exec($);if(Q){let[,U,M,W]=Q,G=M.endsWith(".git")?M.slice(0,-4):M;$=`github:${U}/${G}${W?`#${W}`:""}`}if(!$.startsWith("github:"))throw Error(`Invalid source format. Got: "${$}"
4
+ Supported formats:
5
+ github:owner/repo[#ref]
6
+ https://github.com/owner/repo`);let K=$.slice(7),q=K.indexOf("#"),Z,V=null;if(q!==-1){if(Z=K.slice(0,q),V=K.slice(q+1),!V)throw Error("Invalid source: ref cannot be empty after #")}else Z=K;let X=Z.indexOf("/");if(X===-1)throw Error(`Invalid source: format must be github:owner/repo. Got: "${$}"`);let z=Z.slice(0,X),J=Z.slice(X+1);if(!z)throw Error("Invalid source: owner cannot be empty");if(!J)throw Error("Invalid source: repo cannot be empty");if(!S0.test(z))throw Error(`Invalid source: owner contains invalid characters: "${z}". Allowed: [a-zA-Z0-9_-]`);if(!b0.test(J))throw Error(`Invalid source: repo contains invalid characters: "${J}". Allowed: [a-zA-Z0-9._-]`);let B={owner:z,repo:J,ref:V,cloneUrl:`https://github.com/${z}/${J}.git`};return E(`install: parsed source → owner=${z} repo=${J} ref=${V}`),B}function y($){if(!$)throw Error("Invalid skill name: name cannot be empty");if($.includes("\x00"))throw Error("Invalid skill name: contains unsafe characters (null byte)");if($.includes(".."))throw Error("Invalid skill name: contains unsafe characters (..)");if($.includes("/")||$.includes("\\"))throw Error("Invalid skill name: contains unsafe characters (path separator)");if($.startsWith("."))throw Error("Invalid skill name: must not start with a dot");if($.length>g)throw Error(`Invalid skill name: exceeds maximum length of ${g} characters`);if(!D0.test($))throw Error(`Invalid skill name: "${$}" does not match allowed pattern [a-zA-Z0-9][a-zA-Z0-9._-]*`);return $}async function s(){try{await l("git",["--version"]),E("install: git available")}catch{throw Error("git is required for installing skills. Install git from https://git-scm.com")}}async function a($){E(`install: cloning ${$.cloneUrl}${$.ref?` (ref: ${$.ref})`:""}`);let Q=await w0(L(N0(),"asm-install-")),K=["clone","--depth","1"];if($.ref)K.push("--branch",$.ref);K.push($.cloneUrl,Q);try{await l("git",K,{timeout:60000})}catch(q){await S(Q);let Z=q.killed?"Clone timed out after 60 seconds":`Clone failed: ${q.stderr||q.message}`;throw Error(Z)}return Q}async function N($){let Q=L($,"SKILL.md"),K;try{K=await w(Q,"utf-8")}catch{throw Error("Not a valid skill: SKILL.md not found in repository root")}let q=x(K),Z=$.split("/").pop()||"unknown",V=q.name||Z,X=q.version||"0.0.0";return E(`install: validated skill "${V}" v${X}`),{name:V,version:X,description:(q.description||"").replace(/\s*\n\s*/g," ").trim()}}async function e($,Q=3){let K=[];async function q(Z,V,X){let z;try{z=await n(Z)}catch{return}for(let J of z){if(J===".git"||J==="node_modules")continue;let B=L(Z,J);try{if(!(await t(B)).isDirectory())continue}catch{continue}let U=V?`${V}/${J}`:J,M=X+1,W=L(B,"SKILL.md");try{let G=await w(W,"utf-8"),O=x(G);K.push({relPath:U,name:O.name||J,version:O.version||"0.0.0",description:(O.description||"").replace(/\s*\n\s*/g," ").trim()})}catch{if(M<Q)await q(B,U,M)}}}return await q($,"",0),K.sort((Z,V)=>Z.name.localeCompare(V.name)),K}var v0=[{category:"Shell commands",pattern:/\b(bash|sh\s+-c)\b/},{category:"Shell commands",pattern:/\bexec\(/},{category:"Shell commands",pattern:/\bchild_process\b/},{category:"Shell commands",pattern:/\bBun\.spawn\b/},{category:"Code execution",pattern:/\beval\(/},{category:"Code execution",pattern:/\bFunction\(/},{category:"Code execution",pattern:/\bnew\s+Function\b/},{category:"Credentials",pattern:/\b(API_KEY|SECRET|TOKEN|PASSWORD)\s*[=:]/},{category:"External URLs",pattern:/https?:\/\//}],f0=new Set([".png",".jpg",".jpeg",".gif",".ico",".bmp",".webp",".mp3",".mp4",".wav",".avi",".mov",".zip",".tar",".gz",".bz2",".7z",".exe",".dll",".so",".dylib",".woff",".woff2",".ttf",".eot",".pdf",".doc",".docx"]);async function k0($){let Q=[];async function K(q,Z){let V;try{V=await n(q)}catch{return}for(let X of V){if(X===".git")continue;if(X==="node_modules")continue;let z=L(q,X),J=Z?`${Z}/${X}`:X;try{let B=await t(z);if(B.isDirectory())await K(z,J);else if(B.isFile()){let U=X.includes(".")?`.${X.split(".").pop().toLowerCase()}`:"";if(f0.has(U))continue;if(B.size>524288)continue;try{let M=await w(z,"utf-8");Q.push({relPath:J,content:M})}catch{}}}catch{continue}}}return await K($,""),Q}async function r($){let Q=[],K=await k0($);for(let{relPath:q,content:Z}of K){let V=Z.split(`
7
+ `);for(let X=0;X<V.length;X++)for(let{category:z,pattern:J}of v0)if(J.test(V[X])){let B=V[X].trim();Q.push({category:z,file:q,line:X+1,match:B.length>100?B.slice(0,100)+"…":B})}}return Q}async function $0($){let Q=`github:${$.source.owner}/${$.source.repo}${$.source.ref?`#${$.source.ref}`:""}`;if($.force)try{await f($.targetDir),await v($.targetDir,{recursive:!0,force:!0})}catch{}let K=$.sourceDir;try{await y0(K,$.targetDir,{recursive:!0})}catch(z){throw Error(`Failed to install: ${z.message}`)}let q=L($.targetDir,".git");try{await v(q,{recursive:!0,force:!0})}catch{}E(`install: copied files to ${$.targetDir}`);let Z=L($.targetDir,"SKILL.md");try{await f(Z)}catch{throw Error("Installation verification failed: SKILL.md not found at target")}let V=await w(Z,"utf-8"),X=x(V);return{success:!0,path:$.targetDir,name:X.name||$.skillName,version:X.version||"0.0.0",provider:$.providerLabel,source:Q}}async function S($){try{await v($,{recursive:!0,force:!0})}catch{}}async function b($,Q,K){let q=$.providers.filter((X)=>X.enabled);if(q.length===0)throw Error("No providers are enabled. Enable a provider in your config.");if(Q){let X=$.providers.find((z)=>z.name===Q);if(!X){let z=$.providers.map((J)=>J.name).join(", ");throw Error(`Unknown provider: "${Q}". Valid providers: ${z}`)}if(!X.enabled)throw Error(`Provider "${Q}" is disabled. Enable it in your config or choose another provider.`);return X}if(q.length===1)return q[0];if(!K){let X=q.map((z)=>z.name).join(", ");throw Error(`--provider is required in non-interactive mode. Available: ${X}`)}console.error(`
6
8
  Select a provider:`);for(let X=0;X<q.length;X++)console.error(` ${X+1}) ${q[X].label} (${q[X].name})`);process.stderr.write(`
7
- Enter number: `);let Z=await new Promise((X)=>{let U="";process.stdin.setEncoding("utf-8"),process.stdin.on("data",(z)=>{if(U+=z,U.includes(`
8
- `))process.stdin.removeAllListeners("data"),X(U.trim())}),process.stdin.resume()}),V=parseInt(Z,10)-1;if(isNaN(V)||V<0||V>=q.length)throw Error("Invalid selection. Aborting.");return q[V]}function Q0($,Q,K,q,Z,V){let X=o(Z.global),U=L(X,q);return{source:$,tempDir:Q,sourceDir:K,targetDir:U,skillName:q,force:V,providerName:Z.name,providerLabel:Z.label}}async function Z0($,Q){try{if(await f($),E(`install: target ${$} — conflict (exists)${Q?", force overwrite":""}`),!Q)throw Error(`Skill already exists at: ${$}
9
- Use --force to overwrite.`)}catch(K){if(K.message?.includes("--force"))throw K;E(`install: target ${$} — no conflict`)}}import{readFile as k0}from"fs/promises";import{join as h0}from"path";var K0=500;function u0($){let Q=$.split(`
10
- `),K=!1,q=!1;for(let Z of Q){if(Z.trim()==="---")if(!K){K=!0;continue}else{q=!0;continue}if(q&&Z.trim().length>0)return!0}return!1}async function q0($){let Q=[];if(!$.description||$.description.trim()==="")Q.push({category:"missing-description",message:"Skill has no description in SKILL.md frontmatter"});if(!$.version||$.version==="0.0.0")Q.push({category:"missing-version",message:"Skill has no version (or default 0.0.0) in SKILL.md frontmatter"});try{let q=h0($.path,"SKILL.md"),Z=await k0(q,"utf-8");if(!u0(Z))Q.push({category:"empty-body",message:"SKILL.md contains only frontmatter with no body content"})}catch{}let K=$.fileCount;if(K!==void 0&&K>K0)Q.push({category:"high-file-count",message:`Skill has ${K} files (threshold: ${K0})`});return Q}function V0($){let Q=$.map((K)=>({name:K.name,version:K.version,dirName:K.dirName,provider:K.provider,scope:K.scope,path:K.path,isSymlink:K.isSymlink,symlinkTarget:K.symlinkTarget}));return{version:1,exportedAt:new Date().toISOString(),skills:Q}}import{mkdir as m0,writeFile as c0,access as d0}from"fs/promises";import{join as p0}from"path";function g0($){return`---
9
+ Enter number: `);let Z=await new Promise((X)=>{let z="";process.stdin.setEncoding("utf-8"),process.stdin.on("data",(J)=>{if(z+=J,z.includes(`
10
+ `))process.stdin.removeAllListeners("data"),X(z.trim())}),process.stdin.resume()}),V=parseInt(Z,10)-1;if(isNaN(V)||V<0||V>=q.length)throw Error("Invalid selection. Aborting.");return q[V]}function Q0($,Q,K,q,Z,V){let X=o(Z.global),z=L(X,q);return{source:$,tempDir:Q,sourceDir:K,targetDir:z,skillName:q,force:V,providerName:Z.name,providerLabel:Z.label}}async function Z0($,Q){try{if(await f($),E(`install: target ${$} — conflict (exists)${Q?", force overwrite":""}`),!Q)throw Error(`Skill already exists at: ${$}
11
+ Use --force to overwrite.`)}catch(K){if(K.message?.includes("--force"))throw K;E(`install: target ${$} — no conflict`)}}import{readFile as h0}from"fs/promises";import{join as u0}from"path";var K0=500;function m0($){let Q=$.split(`
12
+ `),K=!1,q=!1;for(let Z of Q){if(Z.trim()==="---")if(!K){K=!0;continue}else{q=!0;continue}if(q&&Z.trim().length>0)return!0}return!1}async function q0($){let Q=[];if(!$.description||$.description.trim()==="")Q.push({category:"missing-description",message:"Skill has no description in SKILL.md frontmatter"});if(!$.version||$.version==="0.0.0")Q.push({category:"missing-version",message:"Skill has no version (or default 0.0.0) in SKILL.md frontmatter"});try{let q=u0($.path,"SKILL.md"),Z=await h0(q,"utf-8");if(!m0(Z))Q.push({category:"empty-body",message:"SKILL.md contains only frontmatter with no body content"})}catch{}let K=$.fileCount;if(K!==void 0&&K>K0)Q.push({category:"high-file-count",message:`Skill has ${K} files (threshold: ${K0})`});return Q}function V0($){let Q=$.map((K)=>({name:K.name,version:K.version,dirName:K.dirName,provider:K.provider,scope:K.scope,path:K.path,isSymlink:K.isSymlink,symlinkTarget:K.symlinkTarget}));return{version:1,exportedAt:new Date().toISOString(),skills:Q}}import{mkdir as c0,writeFile as d0,access as p0}from"fs/promises";import{join as g0}from"path";function o0($){return`---
11
13
  name: ${$}
12
14
  version: 0.1.0
13
15
  description: ""
@@ -25,8 +27,8 @@ as instructions for when and how to use this skill.
25
27
  ## Instructions
26
28
 
27
29
  - Step-by-step instructions for the agent
28
- `}async function X0($,Q){await m0(Q,{recursive:!0});let K=p0(Q,"SKILL.md"),q=g0($);await c0(K,q,"utf-8")}async function Y0($){try{return await d0($),!0}catch{return!1}}import{readdir as o0,stat as n0}from"fs/promises";import{join as t0}from"path";async function l0($){let Q=0;try{let q=(await o0($,{recursive:!0})).map(async(V)=>{try{let X=await n0(t0($,V));if(X.isFile())return X.size}catch{}return 0});Q=(await Promise.all(q)).reduce((V,X)=>V+X,0)}catch{}return Q}async function U0($,Q){let K={},q={global:0,project:0},Z={},V=$.map(async(z)=>{K[z.provider]=(K[z.provider]||0)+1,q[z.scope]++;let J=await l0(z.path);return Z[z.path]=J,J}),U=(await Promise.all(V)).reduce((z,J)=>z+J,0);return{totalSkills:$.length,byProvider:K,byScope:q,totalDiskBytes:U,perSkillDiskBytes:Z,duplicateGroups:Q.duplicateGroups.length,duplicateInstances:Q.totalDuplicateInstances}}function i0($){if($<1024)return`${$} B`;if($<1048576)return`${($/1024).toFixed(1)} KB`;if($<1073741824)return`${($/1048576).toFixed(1)} MB`;return`${($/1073741824).toFixed(1)} GB`}function z0($){let Q=[],K=(q,Z)=>`${Y.bold(q+":")} ${Z}`;Q.push(Y.bold("Skill Statistics")),Q.push(""),Q.push(K("Total Skills",String($.totalSkills))),Q.push(K("Disk Usage",i0($.totalDiskBytes))),Q.push(""),Q.push(Y.bold("By Provider:"));for(let[q,Z]of Object.entries($.byProvider).sort((V,X)=>X[1]-V[1]))Q.push(` ${q}: ${Z}`);if(Q.push(""),Q.push(Y.bold("By Scope:")),Q.push(` global: ${$.byScope.global}`),Q.push(` project: ${$.byScope.project}`),Q.push(""),Q.push(Y.bold("Duplicates:")),$.duplicateGroups>0)Q.push(` ${Y.yellow(`${$.duplicateGroups} group(s), ${$.duplicateInstances} total instance(s)`)}`);else Q.push(` ${Y.green("None")}`);return Q.join(`
29
- `)}import{access as s0,lstat as a0,readFile as e0,rm as r0,symlink as $1}from"fs/promises";import{join as B0}from"path";async function J0($){let Q;try{Q=await a0($)}catch{throw Error(`Path does not exist: ${$}`)}if(!Q.isDirectory())throw Error(`Path is not a directory: ${$}`);let K=B0($,"SKILL.md"),q;try{q=await e0(K,"utf-8")}catch{throw Error(`No SKILL.md found in ${$}`)}let Z=R(q);if(!Z.name)throw Error(`Invalid SKILL.md in ${$}: missing "name" in frontmatter`);return{name:Z.name,version:Z.version||"0.0.0"}}async function D($,Q,K,q){let Z=B0(Q,K),V=!1;try{await s0(Z),V=!0}catch{}if(V){if(!q)throw Error(`Target already exists: ${Z}. Use --force to overwrite.`);await r0(Z,{recursive:!0,force:!0})}await $1($,Z,"dir")}function Q1($){let Q=$.slice(2),K={command:null,subcommand:null,positional:[],flags:{help:!1,version:!1,json:!1,yes:!1,noColor:!1,scope:"both",sort:"name",provider:null,name:null,force:!1,path:null,all:!1,verbose:!1}},q=0;while(q<Q.length){let Z=Q[q];if(Z==="--help"||Z==="-h")K.flags.help=!0;else if(Z==="--version"||Z==="-v")K.flags.version=!0;else if(Z==="--json")K.flags.json=!0;else if(Z==="--yes"||Z==="-y")K.flags.yes=!0;else if(Z==="--no-color")K.flags.noColor=!0;else if(Z==="--scope"||Z==="-s"){q++;let V=Q[q];if(V==="global"||V==="project"||V==="both")K.flags.scope=V;else G(`Invalid scope: "${V}". Must be global, project, or both.`),process.exit(2)}else if(Z==="--sort"){q++;let V=Q[q];if(V==="name"||V==="version"||V==="location")K.flags.sort=V;else G(`Invalid sort: "${V}". Must be name, version, or location.`),process.exit(2)}else if(Z==="--provider"||Z==="-p")q++,K.flags.provider=Q[q]||null;else if(Z==="--name")q++,K.flags.name=Q[q]||null;else if(Z==="--force"||Z==="-f")K.flags.force=!0;else if(Z==="--path")q++,K.flags.path=Q[q]||null;else if(Z==="--all")K.flags.all=!0;else if(Z==="--verbose"||Z==="-V")K.flags.verbose=!0;else if(Z.startsWith("-"))G(`Unknown option: ${Z}`),console.error('Run "asm --help" for usage.'),process.exit(2);else if(!K.command)K.command=Z;else if(!K.subcommand)K.subcommand=Z;else K.positional.push(Z);q++}return K}function G($){console.error(Y.red(`Error: ${$}`))}function Z1(){console.log(`${Y.blueBold("agent-skill-manager")} (${Y.bold("asm")}) ${p}
30
+ `}async function X0($,Q){await c0(Q,{recursive:!0});let K=g0(Q,"SKILL.md"),q=o0($);await d0(K,q,"utf-8")}async function Y0($){try{return await p0($),!0}catch{return!1}}import{readdir as n0,stat as t0}from"fs/promises";import{join as l0}from"path";async function i0($){let Q=0;try{let q=(await n0($,{recursive:!0})).map(async(V)=>{try{let X=await t0(l0($,V));if(X.isFile())return X.size}catch{}return 0});Q=(await Promise.all(q)).reduce((V,X)=>V+X,0)}catch{}return Q}async function z0($,Q){let K={},q={global:0,project:0},Z={},V=$.map(async(J)=>{K[J.provider]=(K[J.provider]||0)+1,q[J.scope]++;let B=await i0(J.path);return Z[J.path]=B,B}),z=(await Promise.all(V)).reduce((J,B)=>J+B,0);return{totalSkills:$.length,byProvider:K,byScope:q,totalDiskBytes:z,perSkillDiskBytes:Z,duplicateGroups:Q.duplicateGroups.length,duplicateInstances:Q.totalDuplicateInstances}}function s0($){if($<1024)return`${$} B`;if($<1048576)return`${($/1024).toFixed(1)} KB`;if($<1073741824)return`${($/1048576).toFixed(1)} MB`;return`${($/1073741824).toFixed(1)} GB`}function J0($){let Q=[],K=(q,Z)=>`${Y.bold(q+":")} ${Z}`;Q.push(Y.bold("Skill Statistics")),Q.push(""),Q.push(K("Total Skills",String($.totalSkills))),Q.push(K("Disk Usage",s0($.totalDiskBytes))),Q.push(""),Q.push(Y.bold("By Provider:"));for(let[q,Z]of Object.entries($.byProvider).sort((V,X)=>X[1]-V[1]))Q.push(` ${q}: ${Z}`);if(Q.push(""),Q.push(Y.bold("By Scope:")),Q.push(` global: ${$.byScope.global}`),Q.push(` project: ${$.byScope.project}`),Q.push(""),Q.push(Y.bold("Duplicates:")),$.duplicateGroups>0)Q.push(` ${Y.yellow(`${$.duplicateGroups} group(s), ${$.duplicateInstances} total instance(s)`)}`);else Q.push(` ${Y.green("None")}`);return Q.join(`
31
+ `)}import{access as a0,lstat as e0,readFile as r0,rm as $1,symlink as Q1}from"fs/promises";import{join as U0}from"path";async function W0($){let Q;try{Q=await e0($)}catch{throw Error(`Path does not exist: ${$}`)}if(!Q.isDirectory())throw Error(`Path is not a directory: ${$}`);let K=U0($,"SKILL.md"),q;try{q=await r0(K,"utf-8")}catch{throw Error(`No SKILL.md found in ${$}`)}let Z=x(q);if(!Z.name)throw Error(`Invalid SKILL.md in ${$}: missing "name" in frontmatter`);return{name:Z.name,version:Z.version||"0.0.0"}}async function D($,Q,K,q){let Z=U0(Q,K),V=!1;try{await a0(Z),V=!0}catch{}if(V){if(!q)throw Error(`Target already exists: ${Z}. Use --force to overwrite.`);await $1(Z,{recursive:!0,force:!0})}await Q1($,Z,"dir")}function Z1($){let Q=$.slice(2),K={command:null,subcommand:null,positional:[],flags:{help:!1,version:!1,json:!1,yes:!1,noColor:!1,scope:"both",sort:"name",provider:null,name:null,force:!1,path:null,all:!1,verbose:!1}},q=0;while(q<Q.length){let Z=Q[q];if(Z==="--help"||Z==="-h")K.flags.help=!0;else if(Z==="--version"||Z==="-v")K.flags.version=!0;else if(Z==="--json")K.flags.json=!0;else if(Z==="--yes"||Z==="-y")K.flags.yes=!0;else if(Z==="--no-color")K.flags.noColor=!0;else if(Z==="--scope"||Z==="-s"){q++;let V=Q[q];if(V==="global"||V==="project"||V==="both")K.flags.scope=V;else j(`Invalid scope: "${V}". Must be global, project, or both.`),process.exit(2)}else if(Z==="--sort"){q++;let V=Q[q];if(V==="name"||V==="version"||V==="location")K.flags.sort=V;else j(`Invalid sort: "${V}". Must be name, version, or location.`),process.exit(2)}else if(Z==="--provider"||Z==="-p")q++,K.flags.provider=Q[q]||null;else if(Z==="--name")q++,K.flags.name=Q[q]||null;else if(Z==="--force"||Z==="-f")K.flags.force=!0;else if(Z==="--path")q++,K.flags.path=Q[q]||null;else if(Z==="--all")K.flags.all=!0;else if(Z==="--verbose"||Z==="-V")K.flags.verbose=!0;else if(Z.startsWith("-"))j(`Unknown option: ${Z}`),console.error('Run "asm --help" for usage.'),process.exit(2);else if(!K.command)K.command=Z;else if(!K.subcommand)K.subcommand=Z;else K.positional.push(Z);q++}return K}function j($){console.error(Y.red(`Error: ${$}`))}function K1(){console.log(`${Y.blueBold("agent-skill-manager")} (${Y.bold("asm")}) ${p}
30
32
 
31
33
  Interactive TUI and CLI for managing installed skills for AI coding agents.
32
34
 
@@ -58,7 +60,7 @@ ${Y.bold("Global Options:")}
58
60
  --no-color Disable ANSI colors
59
61
  --sort <field> Sort by: name, version, or location (default: name)
60
62
  -y, --yes Skip confirmation prompts
61
- -V, --verbose Show debug output`)}function K1(){console.log(`${Y.bold("Usage:")} asm list [options]
63
+ -V, --verbose Show debug output`)}function q1(){console.log(`${Y.bold("Usage:")} asm list [options]
62
64
 
63
65
  List all discovered skills.
64
66
 
@@ -67,7 +69,7 @@ ${Y.bold("Options:")}
67
69
  -s, --scope <s> Filter: global, project, or both (default: both)
68
70
  --json Output as JSON array
69
71
  --no-color Disable ANSI colors
70
- -V, --verbose Show debug output`)}function q1(){console.log(`${Y.bold("Usage:")} asm search <query> [options]
72
+ -V, --verbose Show debug output`)}function V1(){console.log(`${Y.bold("Usage:")} asm search <query> [options]
71
73
 
72
74
  Search skills by name, description, or provider.
73
75
 
@@ -76,7 +78,7 @@ ${Y.bold("Options:")}
76
78
  -s, --scope <s> Filter: global, project, or both (default: both)
77
79
  --json Output as JSON array
78
80
  --no-color Disable ANSI colors
79
- -V, --verbose Show debug output`)}function V1(){console.log(`${Y.bold("Usage:")} asm inspect <skill-name> [options]
81
+ -V, --verbose Show debug output`)}function X1(){console.log(`${Y.bold("Usage:")} asm inspect <skill-name> [options]
80
82
 
81
83
  Show detailed information for a skill. The <skill-name> is the directory name.
82
84
 
@@ -84,7 +86,7 @@ ${Y.bold("Options:")}
84
86
  -s, --scope <s> Filter: global, project, or both (default: both)
85
87
  --json Output as JSON object
86
88
  --no-color Disable ANSI colors
87
- -V, --verbose Show debug output`)}function X1(){console.log(`${Y.bold("Usage:")} asm uninstall <skill-name> [options]
89
+ -V, --verbose Show debug output`)}function Y1(){console.log(`${Y.bold("Usage:")} asm uninstall <skill-name> [options]
88
90
 
89
91
  Remove a skill and its associated rule files.
90
92
 
@@ -92,7 +94,7 @@ ${Y.bold("Options:")}
92
94
  -y, --yes Skip confirmation prompt
93
95
  -s, --scope <s> Filter: global, project, or both (default: both)
94
96
  --no-color Disable ANSI colors
95
- -V, --verbose Show debug output`)}function Y1(){console.log(`${Y.bold("Usage:")} asm audit [subcommand] [options]
97
+ -V, --verbose Show debug output`)}function z1(){console.log(`${Y.bold("Usage:")} asm audit [subcommand] [options]
96
98
 
97
99
  Detect and optionally remove duplicate skills.
98
100
 
@@ -103,7 +105,7 @@ ${Y.bold("Options:")}
103
105
  --json Output as JSON
104
106
  -y, --yes Auto-remove duplicates, keeping one instance per group
105
107
  --no-color Disable ANSI colors
106
- -V, --verbose Show debug output`)}function U1(){console.log(`${Y.bold("Usage:")} asm config <subcommand>
108
+ -V, --verbose Show debug output`)}function J1(){console.log(`${Y.bold("Usage:")} asm config <subcommand>
107
109
 
108
110
  Manage configuration.
109
111
 
@@ -114,21 +116,22 @@ ${Y.bold("Subcommands:")}
114
116
  edit Open config in $EDITOR
115
117
 
116
118
  ${Y.bold("Options:")}
117
- -V, --verbose Show debug output`)}async function I0($){for(let Q of $)Q.warnings=await q0(Q)}async function z1($){if($.flags.help){K1();return}let Q=await _(),K=await I(Q,$.flags.scope);await I0(K);let q=u(K,$.flags.sort);if($.flags.json)console.log(C(q));else{let Z=c(q),V=q.filter((X)=>X.warnings&&X.warnings.length>0);if(V.length>0)Z+=`
118
- ${Y.yellow(`⚠ ${V.length} skill${V.length===1?"":"s"} with warnings — use --json for details`)}`;console.log(Z)}}async function B1($){if($.flags.help){q1();return}let Q=$.subcommand;if(!Q)G("Missing required argument: <query>"),console.error('Run "asm search --help" for usage.'),process.exit(2);let K=await _(),q=await I(K,$.flags.scope),Z=j0(q,Q),V=u(Z,$.flags.sort);if($.flags.json)console.log(C(V));else console.log(c(V))}async function J1($){if($.flags.help){V1();return}let Q=$.subcommand;if(!Q)G("Missing required argument: <skill-name>"),console.error('Run "asm inspect --help" for usage.'),process.exit(2);let K=await _(),Z=(await I(K,$.flags.scope)).filter((V)=>V.dirName===Q);if(Z.length===0)G(`Skill "${Q}" not found.`),process.exit(1);if(await I0(Z),$.flags.json)console.log(C(Z.length===1?Z[0]:Z));else for(let V=0;V<Z.length;V++){if(V>0)console.log(`
119
+ -V, --verbose Show debug output`)}async function I0($){for(let Q of $)Q.warnings=await q0(Q)}async function U1($){if($.flags.help){q1();return}let Q=await _(),K=await I(Q,$.flags.scope);await I0(K);let q=u(K,$.flags.sort);if($.flags.json)console.log(C(q));else{let Z=c(q),V=q.filter((X)=>X.warnings&&X.warnings.length>0);if(V.length>0)Z+=`
120
+ ${Y.yellow(`⚠ ${V.length} skill${V.length===1?"":"s"} with warnings — use --json for details`)}`;console.log(Z)}}async function W1($){if($.flags.help){V1();return}let Q=$.subcommand;if(!Q)j("Missing required argument: <query>"),console.error('Run "asm search --help" for usage.'),process.exit(2);let K=await _(),q=await I(K,$.flags.scope),Z=j0(q,Q),V=u(Z,$.flags.sort);if($.flags.json)console.log(C(V));else console.log(c(V))}async function B1($){if($.flags.help){X1();return}let Q=$.subcommand;if(!Q)j("Missing required argument: <skill-name>"),console.error('Run "asm inspect --help" for usage.'),process.exit(2);let K=await _(),Z=(await I(K,$.flags.scope)).filter((V)=>V.dirName===Q);if(Z.length===0)j(`Skill "${Q}" not found.`),process.exit(1);if(await I0(Z),$.flags.json)console.log(C(Z.length===1?Z[0]:Z));else for(let V=0;V<Z.length;V++){if(V>0)console.log(`
119
121
  `+"─".repeat(40)+`
120
- `);console.log(await A0(Z[V]))}}async function W1($){if($.flags.help){X1();return}let Q=$.subcommand;if(!Q)G("Missing required argument: <skill-name>"),console.error('Run "asm uninstall --help" for usage.'),process.exit(2);let K=await _(),q=await I(K,$.flags.scope),Z=_0(Q,q,K),V=await T0(Z);if(V.length===0)G(`Skill "${Q}" not found or nothing to remove.`),process.exit(1);console.error(Y.bold("Removal plan:"));for(let U of V)console.error(` ${Y.red("•")} ${U}`);if(!$.flags.yes){if(!process.stdin.isTTY)G("Cannot prompt for confirmation in non-interactive mode. Use --yes to skip."),process.exit(2);process.stderr.write(`
121
- ${Y.bold("Proceed with removal?")} [y/N] `);let U=await H();if(U.toLowerCase()!=="y"&&U.toLowerCase()!=="yes")console.error("Aborted."),process.exit(0)}let X=await m(Z);for(let U of X)console.error(U);console.error(Y.green(`
122
- Done.`))}function H(){return new Promise(($)=>{let Q="",K=!1;function q(){process.stdin.removeListener("data",V),process.stdin.removeListener("end",X),clearTimeout(U)}function Z(z){if(K)return;K=!0,q(),$(z)}function V(z){if(Q+=z,Q.includes(`
123
- `))Z(Q.trim())}function X(){Z(Q.trim())}let U=setTimeout(()=>{Z(Q.trim())},30000);process.stdin.setEncoding("utf-8"),process.stdin.on("data",V),process.stdin.on("end",X),process.stdin.resume()})}async function G1($){if($.flags.help){Y1();return}let Q=$.subcommand??"duplicates";if(Q!=="duplicates")G(`Unknown audit subcommand: "${Q}". Use: duplicates`),process.exit(2);let K=await _(),q=await I(K,"both"),Z=d(q);if($.flags.json){console.log(L0(Z));return}if(console.log(E0(Z)),$.flags.yes&&Z.duplicateGroups.length>0){console.error(Y.bold(`
124
- Auto-removing duplicates...`));for(let V of Z.duplicateGroups){let X=F0(V.instances);for(let U=1;U<X.length;U++){let z=X[U],J=O0(z,K),B=await m(J);for(let O of B)console.error(O)}}console.error(Y.green(`
125
- Done.`))}}async function M1($){if($.flags.help){U1();return}let Q=$.subcommand;if(!Q)G("Missing subcommand. Use: show, path, reset, or edit."),console.error('Run "asm config --help" for usage.'),process.exit(2);switch(Q){case"show":{let K=await _();console.log(C(K));break}case"path":{console.log(h());break}case"reset":{if(!$.flags.yes){if(!process.stdin.isTTY)G("Cannot prompt for confirmation in non-interactive mode. Use --yes to skip."),process.exit(2);process.stderr.write(`${Y.bold("Reset config to defaults?")} [y/N] `);let q=await H();if(q.toLowerCase()!=="y"&&q.toLowerCase()!=="yes")console.error("Aborted."),process.exit(0)}let K=G0();await M0(K),console.error(Y.green("Config reset to defaults."));break}case"edit":{let K=process.env.VISUAL||process.env.EDITOR||"vi",q=h();await _();let{spawn:Z}=await import("child_process");await new Promise((V,X)=>{let U=Z(K,[q],{stdio:"inherit"});U.on("close",()=>V()),U.on("error",X)});break}default:G(`Unknown config subcommand: "${Q}". Use: show, path, reset, or edit.`),process.exit(2)}}function j1(){console.log(`${Y.bold("Usage:")} asm install <source> [options]
122
+ `);console.log(await F0(Z[V]))}}async function G1($){if($.flags.help){Y1();return}let Q=$.subcommand;if(!Q)j("Missing required argument: <skill-name>"),console.error('Run "asm uninstall --help" for usage.'),process.exit(2);let K=await _(),q=await I(K,$.flags.scope),Z=_0(Q,q,K),V=await A0(Z);if(V.length===0)j(`Skill "${Q}" not found or nothing to remove.`),process.exit(1);console.error(Y.bold("Removal plan:"));for(let z of V)console.error(` ${Y.red("•")} ${z}`);if(!$.flags.yes){if(!process.stdin.isTTY)j("Cannot prompt for confirmation in non-interactive mode. Use --yes to skip."),process.exit(2);process.stderr.write(`
123
+ ${Y.bold("Proceed with removal?")} [y/N] `);let z=await H();if(z.toLowerCase()!=="y"&&z.toLowerCase()!=="yes")console.error("Aborted."),process.exit(0)}let X=await m(Z);for(let z of X)console.error(z);console.error(Y.green(`
124
+ Done.`))}function H(){return new Promise(($)=>{let Q="",K=!1;function q(){process.stdin.removeListener("data",V),process.stdin.removeListener("end",X),clearTimeout(z)}function Z(J){if(K)return;K=!0,q(),$(J)}function V(J){if(Q+=J,Q.includes(`
125
+ `))Z(Q.trim())}function X(){Z(Q.trim())}let z=setTimeout(()=>{Z(Q.trim())},30000);process.stdin.setEncoding("utf-8"),process.stdin.on("data",V),process.stdin.on("end",X),process.stdin.resume()})}async function M1($){if($.flags.help){z1();return}let Q=$.subcommand??"duplicates";if(Q!=="duplicates")j(`Unknown audit subcommand: "${Q}". Use: duplicates`),process.exit(2);let K=await _(),q=await I(K,"both"),Z=d(q);if($.flags.json){console.log(L0(Z));return}if(console.log(E0(Z)),$.flags.yes&&Z.duplicateGroups.length>0){console.error(Y.bold(`
126
+ Auto-removing duplicates...`));for(let V of Z.duplicateGroups){let X=T0(V.instances);for(let z=1;z<X.length;z++){let J=X[z],B=O0(J,K),U=await m(B);for(let M of U)console.error(M)}}console.error(Y.green(`
127
+ Done.`))}}async function j1($){if($.flags.help){J1();return}let Q=$.subcommand;if(!Q)j("Missing subcommand. Use: show, path, reset, or edit."),console.error('Run "asm config --help" for usage.'),process.exit(2);switch(Q){case"show":{let K=await _();console.log(C(K));break}case"path":{console.log(h());break}case"reset":{if(!$.flags.yes){if(!process.stdin.isTTY)j("Cannot prompt for confirmation in non-interactive mode. Use --yes to skip."),process.exit(2);process.stderr.write(`${Y.bold("Reset config to defaults?")} [y/N] `);let q=await H();if(q.toLowerCase()!=="y"&&q.toLowerCase()!=="yes")console.error("Aborted."),process.exit(0)}let K=G0();await M0(K),console.error(Y.green("Config reset to defaults."));break}case"edit":{let K=process.env.VISUAL||process.env.EDITOR||"vi",q=h();await _();let{spawn:Z}=await import("child_process");await new Promise((V,X)=>{let z=Z(K,[q],{stdio:"inherit"});z.on("close",()=>V()),z.on("error",X)});break}default:j(`Unknown config subcommand: "${Q}". Use: show, path, reset, or edit.`),process.exit(2)}}function O1(){console.log(`${Y.bold("Usage:")} asm install <source> [options]
126
128
 
127
129
  Install a skill from a GitHub repository.
128
130
 
129
131
  ${Y.bold("Source Format:")}
130
- github:owner/repo Install from default branch
131
- github:owner/repo#ref Install from specific branch or tag
132
+ github:owner/repo Install from default branch
133
+ github:owner/repo#ref Install from specific branch or tag
134
+ https://github.com/owner/repo Install via HTTPS URL
132
135
 
133
136
  ${Y.bold("Options:")}
134
137
  -p, --provider <name> Target provider (claude, codex, openclaw, agents)
@@ -144,33 +147,35 @@ ${Y.bold("Options:")}
144
147
  ${Y.bold("Single-skill repo:")}
145
148
  asm install github:user/my-skill
146
149
  asm install github:user/my-skill#v1.0.0 -p claude
150
+ asm install https://github.com/user/my-skill
147
151
 
148
152
  ${Y.bold("Multi-skill repo:")}
149
153
  asm install github:user/skills --path skills/code-review
150
154
  asm install github:user/skills --all -p claude -y
151
- asm install github:user/skills ${Y.dim("(interactive picker)")}`)}async function k($,Q,K,q,Z,V,X,U){let z=await N(Z);console.error(`Found skill: ${z.name} v${z.version}`);let J=await r(Z),B=Z===q?null:Z.split("/").pop(),O=V||B||K.repo,W=y(O),M=Q0(K,q,Z,W,U,$.flags.force);if(await Z0(M.targetDir,M.force),console.error(`
152
- ${Y.bold("Install preview:")}`),console.error(` Name: ${z.name}`),console.error(` Version: ${z.version}`),console.error(` Description: ${z.description||"(none)"}`),console.error(` Source: ${Q}`),console.error(` Provider: ${U.label} (${U.name})`),console.error(` Target: ${M.targetDir}`),J.length>0){console.error(`
153
- ${Y.yellow(Y.bold("Security warnings:"))}`);let j=new Map;for(let x of J){let F=j.get(x.category)||[];F.push(x),j.set(x.category,F)}for(let[x,F]of j){console.error(`
154
- ${Y.yellow(`[${x}]`)} (${F.length} match${F.length>1?"es":""})`);for(let P of F.slice(0,5))console.error(` ${Y.dim(P.file)}:${P.line} — ${P.match}`);if(F.length>5)console.error(` ... and ${F.length-5} more`)}}if(!$.flags.yes&&!$.flags.all){if(!process.stdin.isTTY)G("Cannot prompt for confirmation in non-interactive mode. Use --yes to skip."),process.exit(2);process.stderr.write(`
155
- ${Y.bold("Proceed with installation?")} [y/N] `);let j=await H();if(j.toLowerCase()!=="y"&&j.toLowerCase()!=="yes")console.error("Aborted."),process.exit(0)}return console.error(`
156
- Installing to ${M.targetDir}...`),await $0(M)}async function O1($){if($.flags.help){j1();return}let Q=$.subcommand;if(!Q)G("Missing required argument: <source>"),console.error('Run "asm install --help" for usage.'),process.exit(2);let K=null,q=()=>{if(K)S(K).finally(()=>process.exit(1));else process.exit(1)};process.on("SIGINT",q),process.on("SIGTERM",q);try{let Z=i(Q);console.error(`Parsing source: ${Q}`),await s(),console.error(`Cloning ${Z.cloneUrl}${Z.ref?` (ref: ${Z.ref})`:""}...`),K=await a(Z);let V=await _(),X=await b(V,$.flags.provider,!!process.stdin.isTTY),{join:U}=await import("path"),z=[];if($.flags.path){let J=U(K,$.flags.path);try{await N(J)}catch{throw Error(`No SKILL.md found at path "${$.flags.path}" in the repository.`)}let B=await k($,Q,Z,K,J,$.flags.name,V,X);z.push(B)}else{let J=!1;try{await N(K),J=!0}catch{}if(J){let B=await k($,Q,Z,K,K,$.flags.name,V,X);z.push(B)}else{console.error("No SKILL.md at repository root. Scanning for skills...");let B=await e(K);if(B.length===0)throw Error("No skills found in this repository. Skills must have a SKILL.md file.");console.error(`Found ${B.length} skill(s):
157
- `);for(let W=0;W<B.length;W++)if(console.error(` ${Y.bold(`${W+1})`)} ${B[W].name} v${B[W].version} ${Y.dim(`(${B[W].relPath})`)}`),B[W].description)console.error(` ${B[W].description}`);let O;if($.flags.all){if(O=B.map((W)=>W.relPath),console.error(`
158
- Installing all ${O.length} skills...`),!$.flags.yes){if(!process.stdin.isTTY)G("Cannot prompt for confirmation in non-interactive mode. Use --yes to skip."),process.exit(2);process.stderr.write(`
159
- ${Y.bold(`Install all ${O.length} skills?`)} [y/N] `);let W=await H();if(W.toLowerCase()!=="y"&&W.toLowerCase()!=="yes")console.error("Aborted."),process.exit(0)}}else if(process.stdin.isTTY){process.stderr.write(`
160
- Enter skill number (or "all"): `);let W=await H();if(W.toLowerCase()==="all")O=B.map((M)=>M.relPath);else{let M=parseInt(W,10)-1;if(isNaN(M)||M<0||M>=B.length)throw Error("Invalid selection. Aborting.");O=[B[M].relPath]}}else G(`Repository contains ${B.length} skills. Use --path <subdir> to pick one or --all to install all.
155
+ asm install https://github.com/user/skills --all
156
+ asm install github:user/skills ${Y.dim("(interactive picker)")}`)}async function k($,Q,K,q,Z,V,X,z){let J=await N(Z);console.error(`Found skill: ${J.name} v${J.version}`);let B=await r(Z),U=Z===q?null:Z.split("/").pop(),M=V||U||K.repo,W=y(M),G=Q0(K,q,Z,W,z,$.flags.force);if(await Z0(G.targetDir,G.force),console.error(`
157
+ ${Y.bold("Install preview:")}`),console.error(` Name: ${J.name}`),console.error(` Version: ${J.version}`),console.error(` Description: ${J.description||"(none)"}`),console.error(` Source: ${Q}`),console.error(` Provider: ${z.label} (${z.name})`),console.error(` Target: ${G.targetDir}`),B.length>0){console.error(`
158
+ ${Y.yellow(Y.bold("Security warnings:"))}`);let O=new Map;for(let R of B){let T=O.get(R.category)||[];T.push(R),O.set(R.category,T)}for(let[R,T]of O){console.error(`
159
+ ${Y.yellow(`[${R}]`)} (${T.length} match${T.length>1?"es":""})`);for(let P of T.slice(0,5))console.error(` ${Y.dim(P.file)}:${P.line} — ${P.match}`);if(T.length>5)console.error(` ... and ${T.length-5} more`)}}if(!$.flags.yes&&!$.flags.all){if(!process.stdin.isTTY)j("Cannot prompt for confirmation in non-interactive mode. Use --yes to skip."),process.exit(2);process.stderr.write(`
160
+ ${Y.bold("Proceed with installation?")} [y/N] `);let O=await H();if(O.toLowerCase()!=="y"&&O.toLowerCase()!=="yes")console.error("Aborted."),process.exit(0)}return console.error(`
161
+ Installing to ${G.targetDir}...`),await $0(G)}async function _1($){if($.flags.help){O1();return}let Q=$.subcommand;if(!Q)j("Missing required argument: <source>"),console.error('Run "asm install --help" for usage.'),process.exit(2);let K=null,q=()=>{if(K)S(K).finally(()=>process.exit(1));else process.exit(1)};process.on("SIGINT",q),process.on("SIGTERM",q);try{let Z=i(Q);console.error(`Parsing source: ${Q}`),await s(),console.error(`Cloning ${Z.cloneUrl}${Z.ref?` (ref: ${Z.ref})`:""}...`),K=await a(Z);let V=await _(),X=await b(V,$.flags.provider,!!process.stdin.isTTY),{join:z}=await import("path"),J=[];if($.flags.path){let B=z(K,$.flags.path);try{await N(B)}catch{throw Error(`No SKILL.md found at path "${$.flags.path}" in the repository.`)}let U=await k($,Q,Z,K,B,$.flags.name,V,X);J.push(U)}else{let B=!1;try{await N(K),B=!0}catch{}if(B){let U=await k($,Q,Z,K,K,$.flags.name,V,X);J.push(U)}else{console.error("No SKILL.md at repository root. Scanning for skills...");let U=await e(K);if(U.length===0)throw Error("No skills found in this repository. Skills must have a SKILL.md file.");console.error(`Found ${U.length} skill(s):
162
+ `);for(let W=0;W<U.length;W++)if(console.error(` ${Y.bold(`${W+1})`)} ${U[W].name} v${U[W].version} ${Y.dim(`(${U[W].relPath})`)}`),U[W].description)console.error(` ${U[W].description}`);let M;if($.flags.all){if(M=U.map((W)=>W.relPath),console.error(`
163
+ Installing all ${M.length} skills...`),!$.flags.yes){if(!process.stdin.isTTY)j("Cannot prompt for confirmation in non-interactive mode. Use --yes to skip."),process.exit(2);process.stderr.write(`
164
+ ${Y.bold(`Install all ${M.length} skills?`)} [y/N] `);let W=await H();if(W.toLowerCase()!=="y"&&W.toLowerCase()!=="yes")console.error("Aborted."),process.exit(0)}}else if(process.stdin.isTTY){process.stderr.write(`
165
+ Enter skill number (or "all"): `);let W=await H();if(W.toLowerCase()==="all")M=U.map((G)=>G.relPath);else{let G=parseInt(W,10)-1;if(isNaN(G)||G<0||G>=U.length)throw Error("Invalid selection. Aborting.");M=[U[G].relPath]}}else j(`Repository contains ${U.length} skills. Use --path <subdir> to pick one or --all to install all.
161
166
  Available skills:
162
- ${B.map((W)=>` --path ${W.relPath}`).join(`
163
- `)}`),process.exit(2);for(let W of O){let M=U(K,W);console.error(`
164
- ${"─".repeat(40)}`);try{let j=await k($,Q,Z,K,M,O.length===1?$.flags.name:null,V,X);z.push(j),console.error(Y.green(`✓ Installed "${j.name}" to ${j.path}`))}catch(j){if(console.error(Y.red(`✗ Failed to install from ${W}: ${j.message}`)),O.length===1)throw j}}}}if(process.removeListener("SIGINT",q),process.removeListener("SIGTERM",q),$.flags.json)console.log(JSON.stringify(z.length===1?z[0]:z,null,2));else if(z.length===1)console.error(Y.green(`
165
- ✓ Installed "${z[0].name}" to ${z[0].path}`));else console.error(`
166
- ${Y.green(`✓ Installed ${z.length} skill(s) successfully.`)}`)}catch(Z){if(process.removeListener("SIGINT",q),process.removeListener("SIGTERM",q),$.flags.json)console.log(JSON.stringify({success:!1,error:Z.message},null,2));else G(Z.message);process.exit(1)}finally{if(K)await S(K)}}function _1(){console.log(`${Y.bold("Usage:")} asm export [options]
167
+ ${U.map((W)=>` --path ${W.relPath}`).join(`
168
+ `)}`),process.exit(2);for(let W of M){let G=z(K,W);console.error(`
169
+ ${"─".repeat(40)}`);try{let O=await k($,Q,Z,K,G,M.length===1?$.flags.name:null,V,X);J.push(O),console.error(Y.green(`✓ Installed "${O.name}" to ${O.path}`))}catch(O){if(console.error(Y.red(`✗ Failed to install from ${W}: ${O.message}`)),M.length===1)throw O}}}}if(process.removeListener("SIGINT",q),process.removeListener("SIGTERM",q),$.flags.json)console.log(JSON.stringify(J.length===1?J[0]:J,null,2));else if(J.length===1)console.error(Y.green(`
170
+ ✓ Installed "${J[0].name}" to ${J[0].path}`));else console.error(`
171
+ ${Y.green(`✓ Installed ${J.length} skill(s) successfully.`)}`)}catch(Z){if(process.removeListener("SIGINT",q),process.removeListener("SIGTERM",q),$.flags.json)console.log(JSON.stringify({success:!1,error:Z.message},null,2));else j(Z.message);process.exit(1)}finally{if(K)await S(K)}}function A1(){console.log(`${Y.bold("Usage:")} asm export [options]
167
172
 
168
173
  Export skill inventory as a portable JSON manifest.
169
174
 
170
175
  ${Y.bold("Options:")}
171
176
  -s, --scope <s> Filter: global, project, or both (default: both)
172
177
  --no-color Disable ANSI colors
173
- -V, --verbose Show debug output`)}async function T1($){if($.flags.help){_1();return}let Q=await _(),K=await I(Q,$.flags.scope),q=V0(K);console.log(JSON.stringify(q,null,2))}function A1(){console.log(`${Y.bold("Usage:")} asm init <name> [options]
178
+ -V, --verbose Show debug output`)}async function F1($){if($.flags.help){A1();return}let Q=await _(),K=await I(Q,$.flags.scope),q=V0(K);console.log(JSON.stringify(q,null,2))}function T1(){console.log(`${Y.bold("Usage:")} asm init <name> [options]
174
179
 
175
180
  Scaffold a new skill directory with a SKILL.md template.
176
181
 
@@ -179,8 +184,8 @@ ${Y.bold("Options:")}
179
184
  --path <dir> Scaffold in specified directory instead of provider path
180
185
  -f, --force Overwrite if skill already exists
181
186
  --no-color Disable ANSI colors
182
- -V, --verbose Show debug output`)}async function F1($){if($.flags.help){A1();return}let Q=$.subcommand;if(!Q)G("Missing required argument: <name>"),console.error('Run "asm init --help" for usage.'),process.exit(2);let K=y(Q),q;if($.flags.path){let{resolve:Z}=await import("path");q=Z($.flags.path)}else{let Z=await _(),V=await b(Z,$.flags.provider,!!process.stdin.isTTY),{join:X}=await import("path"),{resolveProviderPath:U}=await import("./chunk-zh7g5bam.js"),z=U(Z.providers.find((J)=>J.name===V.name).global);q=X(z,K)}if(await Y0(q)){if(!$.flags.force){if(!process.stdin.isTTY)G(`Directory already exists: ${q}. Use --force to overwrite.`),process.exit(2);process.stderr.write(`${Y.yellow(`Directory already exists: ${q}`)}
183
- ${Y.bold("Overwrite?")} [y/N] `);let Z=await H();if(Z.toLowerCase()!=="y"&&Z.toLowerCase()!=="yes")console.error("Aborted."),process.exit(0)}}await X0(K,q),console.error(Y.green(`✓ Created skill "${K}" at ${q}`))}function E1(){console.log(`${Y.bold("Usage:")} asm stats [options]
187
+ -V, --verbose Show debug output`)}async function E1($){if($.flags.help){T1();return}let Q=$.subcommand;if(!Q)j("Missing required argument: <name>"),console.error('Run "asm init --help" for usage.'),process.exit(2);let K=y(Q),q;if($.flags.path){let{resolve:Z}=await import("path");q=Z($.flags.path)}else{let Z=await _(),V=await b(Z,$.flags.provider,!!process.stdin.isTTY),{join:X}=await import("path"),{resolveProviderPath:z}=await import("./chunk-zh7g5bam.js"),J=z(Z.providers.find((B)=>B.name===V.name).global);q=X(J,K)}if(await Y0(q)){if(!$.flags.force){if(!process.stdin.isTTY)j(`Directory already exists: ${q}. Use --force to overwrite.`),process.exit(2);process.stderr.write(`${Y.yellow(`Directory already exists: ${q}`)}
188
+ ${Y.bold("Overwrite?")} [y/N] `);let Z=await H();if(Z.toLowerCase()!=="y"&&Z.toLowerCase()!=="yes")console.error("Aborted."),process.exit(0)}}await X0(K,q),console.error(Y.green(`✓ Created skill "${K}" at ${q}`))}function L1(){console.log(`${Y.bold("Usage:")} asm stats [options]
184
189
 
185
190
  Show aggregate skill metrics dashboard.
186
191
 
@@ -188,7 +193,7 @@ ${Y.bold("Options:")}
188
193
  --json Output as JSON
189
194
  -s, --scope <s> Filter: global, project, or both (default: both)
190
195
  --no-color Disable ANSI colors
191
- -V, --verbose Show debug output`)}async function L1($){if($.flags.help){E1();return}let Q=await _(),K=await I(Q,$.flags.scope);if(K.length===0){console.log("No skills found.");return}let q=d(K),Z=await U0(K,q);if($.flags.json)console.log(C(Z));else console.log(z0(Z))}function I1(){console.log(`${Y.bold("Usage:")} asm link <path> [options]
196
+ -V, --verbose Show debug output`)}async function I1($){if($.flags.help){L1();return}let Q=await _(),K=await I(Q,$.flags.scope);if(K.length===0){console.log("No skills found.");return}let q=d(K),Z=await z0(K,q);if($.flags.json)console.log(C(Z));else console.log(J0(Z))}function H1(){console.log(`${Y.bold("Usage:")} asm link <path> [options]
192
197
 
193
198
  Symlink a local skill directory into an agent's skill folder.
194
199
 
@@ -198,5 +203,5 @@ ${Y.bold("Options:")}
198
203
  -f, --force Overwrite if target already exists
199
204
  --json Output as JSON
200
205
  --no-color Disable ANSI colors
201
- -V, --verbose Show debug output`)}async function H1($){if($.flags.help){I1();return}let Q=$.subcommand;if(!Q)G("Missing required argument: <path>"),console.error('Run "asm link --help" for usage.'),process.exit(2);let{resolve:K,basename:q}=await import("path"),Z=K(Q),V=await J0(Z),X=$.flags.name?y($.flags.name):q(Z),U=await _(),z=await b(U,$.flags.provider,!!process.stdin.isTTY),{resolveProviderPath:J}=await import("./chunk-zh7g5bam.js"),B=J(U.providers.find((M)=>M.name===z.name).global),{join:O}=await import("path"),W=O(B,X);if(!$.flags.force){let M=!1;try{let{access:j}=await import("fs/promises");await j(W),M=!0}catch{}if(M){if(!process.stdin.isTTY)G(`Target already exists: ${W}. Use --force to overwrite.`),process.exit(2);process.stderr.write(`${Y.yellow(`Target already exists: ${W}`)}
202
- ${Y.bold("Overwrite?")} [y/N] `);let j=await H();if(j.toLowerCase()!=="y"&&j.toLowerCase()!=="yes")console.error("Aborted."),process.exit(0);await D(Z,B,X,!0)}else await D(Z,B,X,!1)}else await D(Z,B,X,!0);if($.flags.json)console.log(C({success:!0,name:X,symlinkPath:W,targetPath:Z}));else console.error(Y.green(`✓ Linked "${X}" → ${Z}`)),console.error(` Symlink: ${W}`),console.error(Y.dim(` If you move or delete the source, run "asm uninstall ${X}" to clean up.`))}async function H0($){let Q=Q1($);if(Q.flags.noColor)globalThis.__CLI_NO_COLOR=!0;if(Q.flags.verbose)W0(!0);if(Q.flags.version){console.log(`asm ${p}`);return}if(!Q.command&&Q.flags.help){Z1();return}if(!Q.command)return;switch(Q.command){case"list":await z1(Q);break;case"search":await B1(Q);break;case"inspect":await J1(Q);break;case"uninstall":await W1(Q);break;case"audit":await G1(Q);break;case"install":await O1(Q);break;case"config":await M1(Q);break;case"export":await T1(Q);break;case"init":await F1(Q);break;case"stats":await L1(Q);break;case"link":await H1(Q);break;default:G(`Unknown command: "${Q.command}"`),console.error('Run "asm --help" for usage.'),process.exit(2)}}function C0($){let Q=$.slice(2);if(Q.length===0)return!1;let K=["list","search","inspect","uninstall","audit","config","install","export","init","stats","link"],q=Q[0];if(K.includes(q))return!0;if(q==="--help"||q==="-h")return!0;if(q==="--version"||q==="-v")return!0;if(q.startsWith("-")||q.length>0)return!0;return!1}if(C0(process.argv))await H0(process.argv);else await import("./chunk-yvfqvjev.js");
206
+ -V, --verbose Show debug output`)}async function C1($){if($.flags.help){H1();return}let Q=$.subcommand;if(!Q)j("Missing required argument: <path>"),console.error('Run "asm link --help" for usage.'),process.exit(2);let{resolve:K,basename:q}=await import("path"),Z=K(Q),V=await W0(Z),X=$.flags.name?y($.flags.name):q(Z),z=await _(),J=await b(z,$.flags.provider,!!process.stdin.isTTY),{resolveProviderPath:B}=await import("./chunk-zh7g5bam.js"),U=B(z.providers.find((G)=>G.name===J.name).global),{join:M}=await import("path"),W=M(U,X);if(!$.flags.force){let G=!1;try{let{access:O}=await import("fs/promises");await O(W),G=!0}catch{}if(G){if(!process.stdin.isTTY)j(`Target already exists: ${W}. Use --force to overwrite.`),process.exit(2);process.stderr.write(`${Y.yellow(`Target already exists: ${W}`)}
207
+ ${Y.bold("Overwrite?")} [y/N] `);let O=await H();if(O.toLowerCase()!=="y"&&O.toLowerCase()!=="yes")console.error("Aborted."),process.exit(0);await D(Z,U,X,!0)}else await D(Z,U,X,!1)}else await D(Z,U,X,!0);if($.flags.json)console.log(C({success:!0,name:X,symlinkPath:W,targetPath:Z}));else console.error(Y.green(`✓ Linked "${X}" → ${Z}`)),console.error(` Symlink: ${W}`),console.error(Y.dim(` If you move or delete the source, run "asm uninstall ${X}" to clean up.`))}async function H0($){let Q=Z1($);if(Q.flags.noColor)globalThis.__CLI_NO_COLOR=!0;if(Q.flags.verbose)B0(!0);if(Q.flags.version){console.log(`asm ${p}`);return}if(!Q.command&&Q.flags.help){K1();return}if(!Q.command)return;switch(Q.command){case"list":await U1(Q);break;case"search":await W1(Q);break;case"inspect":await B1(Q);break;case"uninstall":await G1(Q);break;case"audit":await M1(Q);break;case"install":await _1(Q);break;case"config":await j1(Q);break;case"export":await F1(Q);break;case"init":await E1(Q);break;case"stats":await I1(Q);break;case"link":await C1(Q);break;default:j(`Unknown command: "${Q.command}"`),console.error('Run "asm --help" for usage.'),process.exit(2)}}function C0($){let Q=$.slice(2);if(Q.length===0)return!1;let K=["list","search","inspect","uninstall","audit","config","install","export","init","stats","link"],q=Q[0];if(K.includes(q))return!0;if(q==="--help"||q==="-h")return!0;if(q==="--version"||q==="-v")return!0;if(q.startsWith("-")||q.length>0)return!0;return!1}if(C0(process.argv))await H0(process.argv);else await import("./chunk-my862t5h.js");
@@ -0,0 +1,8 @@
1
+ import{w as I,z as X}from"./chunk-zh7g5bam.js";import{readdir as P,stat as C,lstat as N,readlink as R,readFile as K,realpath as _}from"fs/promises";import{join as H,resolve as w}from"path";function U(o){let c={},t=o.split(`
2
+ `),$=!1,S=!1,j=null,A=[],B="none",f=-1;function L(){if(j){let p=A.join(" ").trim();if(p)c[j]=p;j=null,A=[],B="none",f=-1}}for(let p of t){if(p.trim()==="---")if(!S){S=!0,$=!0;continue}else{L();break}if(!$)continue;if(B!=="none"&&j){let G=p.replace(/^\s*/,""),z=p.length-G.length;if(z>0&&G.length>0){if(f===-1)f=z;A.push(G);continue}else if(G.length===0)continue;else L()}let v=p.match(/^(\w[\w-]*):\s*(.*?)\s*$/);if(v){L();let G=v[1],z=v[2];if(z==="|"||z===">")j=G,A=[],B=z==="|"?"literal":"folded";else if(z==="|+"||z===">+"||z==="|-"||z===">-")j=G,A=[],B=z.startsWith("|")?"literal":"folded";else{let T=z.replace(/^["']|["']$/g,"");if(T)c[G]=T}}}return L(),c}function E(o,c){let t=[];for(let $ of o.providers){if(!$.enabled){I(`scan: skipping disabled provider "${$.name}"`);continue}if(c==="global"||c==="both"){let S=X($.global);I(`scan: adding location ${S} (${$.label}, global)`),t.push({dir:S,location:`global-${$.name}`,scope:"global",providerName:$.name,providerLabel:$.label})}if(c==="project"||c==="both"){let S=X($.project);I(`scan: adding location ${S} (${$.label}, project)`),t.push({dir:S,location:`project-${$.name}`,scope:"project",providerName:$.name,providerLabel:$.label})}}for(let $ of o.customPaths)if(c===$.scope||c==="both"){let S=X($.path);I(`scan: adding custom location ${S} (${$.label}, ${$.scope})`),t.push({dir:S,location:`${$.scope}-custom`,scope:$.scope,providerName:"custom",providerLabel:$.label})}return t}async function O(o){try{return(await P(o,{recursive:!0})).length}catch{return 0}}async function M(o){let c=[];I(`scanning: ${o.dir} (${o.location})`);let t;try{t=await P(o.dir)}catch{return I(`scanning: ${o.dir} — not found, skipping`),c}for(let $ of t){let S=H(o.dir,$);try{if(!(await C(S)).isDirectory()){I(` skip: "${$}" — not a directory`);continue}}catch{I(` skip: "${$}" — stat failed`);continue}let j=H(S,"SKILL.md"),A;try{A=await K(j,"utf-8")}catch{I(` skip: "${$}" — no SKILL.md`);continue}let B=U(A),f=!1,L=null;try{if((await N(S)).isSymbolicLink())f=!0,L=await R(S)}catch{}let p=w(S),v;try{v=await _(S)}catch{v=p}c.push({name:B.name||$,version:B.version||"0.0.0",description:(B.description||"").replace(/\s*\n\s*/g," ").trim(),dirName:$,path:p,originalPath:S,location:o.location,scope:o.scope,provider:o.providerName,providerLabel:o.providerLabel,isSymlink:f,symlinkTarget:L,realPath:v})}return I(`found ${c.length} skill(s) in ${o.dir}`),c}async function Ao(o,c){let t=E(o,c);return(await Promise.all(t.map(M))).flat()}function Bo(o,c){if(!c.trim())return o;let t=c.toLowerCase();return o.filter(($)=>$.name.toLowerCase().includes(t)||$.description.toLowerCase().includes(t)||$.location.toLowerCase().includes(t)||$.providerLabel.toLowerCase().includes(t))}function h(o,c){let t=o.split("."),$=c.split("."),S=Math.max(t.length,$.length);for(let j=0;j<S;j++){let A=parseInt(t[j]??"0",10),B=parseInt($[j]??"0",10);if(isNaN(A)||isNaN(B))return o.localeCompare(c);if(A!==B)return A-B}return 0}function vo(o,c){let t=[...o];switch(c){case"name":t.sort(($,S)=>$.name.localeCompare(S.name));break;case"version":t.sort(($,S)=>h($.version,S.version));break;case"location":t.sort(($,S)=>$.location.localeCompare(S.location));break}return t}import{rm as q,readFile as D,writeFile as F,access as x,lstat as V}from"fs/promises";import{join as y,resolve as Z,dirname as n}from"path";import{homedir as m}from"os";var r=m();function b(o,c){let t={directories:[],ruleFiles:[],agentsBlocks:[]};t.directories.push({path:o.originalPath,isSymlink:o.isSymlink});let $=o.dirName;if(o.scope==="project")t.ruleFiles.push(Z(".cursor","rules",`${$}.mdc`),Z(".windsurf","rules",`${$}.md`),Z(".github","instructions",`${$}.instructions.md`)),t.agentsBlocks.push({file:Z("AGENTS.md"),skillName:$});if(o.scope==="global"){for(let A of c.providers){if(!A.enabled)continue;let B=X(A.global),f=y(n(B),"AGENTS.md");t.agentsBlocks.push({file:f,skillName:$})}let S=y(r,".codex","AGENTS.md");if(!t.agentsBlocks.some((A)=>A.file===S))t.agentsBlocks.push({file:S,skillName:$})}return t}function Xo(o,c,t){let $=c.filter((f)=>f.dirName===o);if($.length===0)return{directories:[],ruleFiles:[],agentsBlocks:[]};let S={directories:[],ruleFiles:[],agentsBlocks:[]},j=new Set,A=new Set,B=new Set;for(let f of $){let L=b(f,t);for(let p of L.directories)if(!j.has(p.path))j.add(p.path),S.directories.push(p);for(let p of L.ruleFiles)if(!A.has(p))A.add(p),S.ruleFiles.push(p);for(let p of L.agentsBlocks){let v=`${p.file}::${p.skillName}`;if(!B.has(v))B.add(v),S.agentsBlocks.push(p)}}return S}async function Y(o){try{return await x(o),!0}catch{return!1}}async function a(o,c){if(!await Y(o))return;let t=await D(o,"utf-8");for(let $ of["agent-skill-manager","skill-manager","pskills"]){let S=`<!-- ${$}: ${c} -->`,j=`<!-- /${$}: ${c} -->`,A=t.indexOf(S),B=t.indexOf(j);if(A===-1||B===-1)continue;let f=A;if(f>0&&t[f-1]===`
3
+ `)f--;let p=B+j.length;if(p<t.length&&t[p]===`
4
+ `)p++;t=t.slice(0,f)+t.slice(p)}await F(o,t,"utf-8")}async function Yo(o){let c=[];for(let t of o.directories)try{if(t.isSymlink)await q(t.path),c.push(`Removed symlink: ${t.path}`);else await q(t.path,{recursive:!0,force:!0}),c.push(`Removed directory: ${t.path}`)}catch($){c.push(`Failed to remove ${t.path}: ${$.message}`)}for(let t of o.ruleFiles)if(await Y(t))try{await q(t),c.push(`Removed rule file: ${t}`)}catch($){c.push(`Failed to remove ${t}: ${$.message}`)}for(let t of o.agentsBlocks)try{await a(t.file,t.skillName),c.push(`Cleaned AGENTS.md block in: ${t.file}`)}catch($){c.push(`Failed to clean AGENTS.md block: ${$.message}`)}return c}async function Zo(o){let c=[];for(let t of o.directories)if(await Y(t.path)){let S=(await V(t.path)).isSymbolicLink()?"symlink":"directory";c.push(`${t.path} (${S})`)}for(let t of o.ruleFiles)if(await Y(t))c.push(t);for(let t of o.agentsBlocks)if(await Y(t.file)){let $=await D(t.file,"utf-8");if($.includes(`<!-- agent-skill-manager: ${t.skillName} -->`)||$.includes(`<!-- skill-manager: ${t.skillName} -->`)||$.includes(`<!-- pskills: ${t.skillName} -->`))c.push(`${t.file} (AGENTS.md block)`)}return c}var Q=()=>{if(process.env.NO_COLOR!==void 0)return!1;if(globalThis.__CLI_NO_COLOR)return!1;if(!process.stdout.isTTY)return!1;return!0},W={bold:(o)=>Q()?`\x1B[1m${o}\x1B[0m`:o,cyan:(o)=>Q()?`\x1B[36m${o}\x1B[0m`:o,green:(o)=>Q()?`\x1B[32m${o}\x1B[0m`:o,yellow:(o)=>Q()?`\x1B[33m${o}\x1B[0m`:o,dim:(o)=>Q()?`\x1B[2m${o}\x1B[0m`:o,red:(o)=>Q()?`\x1B[31m${o}\x1B[0m`:o,blueBold:(o)=>Q()?`\x1B[1m\x1B[34m${o}\x1B[0m`:o};function To(o){if(o.length===0)return"No skills found.";let c=["Name","Version","Provider","Scope","Type","Path"],t=o.map((f)=>[f.name,f.version,f.providerLabel,f.scope,f.isSymlink?"symlink":"directory",f.path]),$=c.map((f,L)=>Math.max(f.length,...t.map((p)=>p[L].length))),S=(f,L)=>f.padEnd(L),j=c.map((f,L)=>S(f,$[L])).join(" "),A=$.map((f)=>"─".repeat(f)).join("──"),B=t.map((f)=>f.map((L,p)=>S(L,$[p])).join(" "));return[Q()?W.bold(j):j,A,...B].join(`
5
+ `)}async function Uo(o){let c=[],t=(S,j)=>`${Q()?W.bold(S+":"):S+":"} ${j}`;if(c.push(t("Name",o.name)),c.push(t("Version",o.version)),c.push(t("Provider",o.providerLabel)),c.push(t("Scope",o.scope)),c.push(t("Location",o.location)),c.push(t("Path",o.path)),c.push(t("Type",o.isSymlink?"symlink":"directory")),o.isSymlink&&o.symlinkTarget)c.push(t("Symlink Target",o.symlinkTarget));let $=o.fileCount??await O(o.path);if(c.push(t("File Count",String($))),o.description)c.push(""),c.push(t("Description",o.description));if(o.warnings&&o.warnings.length>0){c.push(""),c.push(Q()?W.bold("Warnings:"):"Warnings:");for(let S of o.warnings)c.push(` ${Q()?W.yellow("⚠"):"!"} [${S.category}] ${S.message}`)}return c.join(`
6
+ `)}function Ho(o){return JSON.stringify(o,null,2)}function yo(o){let c=[],t=new Set,$=new Map,S=[];for(let f of o){let L=$.get(f.realPath);if(L){if(f.isSymlink)continue;if(L.isSymlink)S[S.indexOf(L)]=f,$.set(f.realPath,f);else S.push(f)}else $.set(f.realPath,f),S.push(f)}let j=new Map;for(let f of S){let L=j.get(f.dirName)??[];L.push(f),j.set(f.dirName,L)}for(let[f,L]of j)if(new Set(L.map((v)=>v.location)).size>=2){c.push({key:f,reason:"same-dirName",instances:L});for(let v of L)t.add(v.path)}let A=new Map;for(let f of S){if(!f.name)continue;let L=A.get(f.name)??[];L.push(f),A.set(f.name,L)}for(let[f,L]of A){if(new Set(L.map((z)=>z.dirName)).size<2)continue;let v=L.filter((z)=>!t.has(z.path));if(v.length<2)continue;if(new Set(v.map((z)=>z.dirName)).size<2)continue;c.push({key:f,reason:"same-frontmatterName",instances:v})}c.sort((f,L)=>{if(f.reason!==L.reason)return f.reason==="same-dirName"?-1:1;return f.key.localeCompare(L.key)});let B=c.reduce((f,L)=>f+L.instances.length,0);return{scannedAt:new Date().toISOString(),totalSkills:o.length,duplicateGroups:c,totalDuplicateInstances:B}}function u(o){return[...o].sort((c,t)=>{if(c.scope!==t.scope)return c.scope==="global"?-1:1;let $=c.providerLabel.localeCompare(t.providerLabel);if($!==0)return $;return c.path.localeCompare(t.path)})}function d(o){return o==="same-dirName"?"same dirName":"same name"}function Do(o){if(o.duplicateGroups.length===0)return W.green("No duplicate skills found.");let c=[];c.push(W.bold(`Found ${o.duplicateGroups.length} duplicate group(s) (${o.totalDuplicateInstances} total instances):`)),c.push("");for(let t of o.duplicateGroups){c.push(W.yellow(` Group: "${t.key}" (${d(t.reason)})`));let $=u(t.instances);for(let S=0;S<$.length;S++){let j=$[S],A=S===0?W.green(" (recommended keep)"):"";c.push(` ${W.dim("•")} ${j.path} [${j.providerLabel}/${j.scope}]${A}`)}c.push("")}return c.join(`
7
+ `)}function go(o){return JSON.stringify(o,null,2)}import{readFileSync as i}from"fs";import{resolve as k,dirname as s}from"path";import{fileURLToPath as e}from"url";import{execSync as l}from"child_process";var oo=s(e(import.meta.url)),g="1.4.1";try{let o=i(k(oo,"../../package.json"),"utf-8");g=JSON.parse(o).version}catch{}var J="6768b68";try{J=l("git rev-parse --short HEAD",{encoding:"utf-8"}).trim()||J}catch{}var to=g,co=J,wo=`v${to} (${co})`;
8
+ export{U as a,O as b,Ao as c,Bo as d,vo as e,b as f,Xo as g,Yo as h,Zo as i,W as j,To as k,Uo as l,Ho as m,yo as n,u as o,d as p,Do as q,go as r,wo as s};