agent-skill-manager 1.6.1 → 1.6.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/README.md CHANGED
@@ -32,7 +32,7 @@
32
32
  **agent-skill-manager** (`asm`) is an interactive TUI and CLI for managing installed skills across AI coding agents — [Claude Code](https://docs.anthropic.com/en/docs/claude-code), [Codex](https://github.com/openai/codex), [OpenClaw](https://github.com/openclaw), and more. Built with [OpenTUI](https://github.com/nicholasgasior/opentui) and [Bun](https://bun.sh).
33
33
 
34
34
  <p align="center">
35
- <img src="assets/screenshots/agent-skill-manager.png" alt="agent-skill-manager TUI dashboard" width="800" />
35
+ <img src="assets/screenshots/asm-list.png" alt="agent-skill-manager TUI dashboard" width="800" />
36
36
  </p>
37
37
 
38
38
  ## Features
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
- import{a as N,c as w,d as L0,e as o,f as E0,g as I0,h as n,i as C0,j as X,k as W0,l as R0,m as t,n as w0,o as y0,p as x0,q as R,r as l,s as N0,u as S0,v as D0,w as i}from"./chunk-407rbrad.js";import{A as H,B as H0,C as g,D as m,E as _,F as T0,x as T,y as L,z as A0}from"./chunk-t7727aqn.js";import{execFile as P0}from"child_process";import{promisify as v0}from"util";import{mkdtemp as h0,readdir as e,readFile as D,rm as S,cp as u0,access as u,stat as a,lstat as m0,symlink as c0,mkdir as d0}from"fs/promises";import{join as E,relative as p0}from"path";import{tmpdir as g0}from"os";var r=v0(P0),o0=/^[a-zA-Z0-9_-]+$/,n0=/^[a-zA-Z0-9._-]+$/,t0=/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/,s=128,l0=/^https?:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\/tree\/(.+))?\/?$/;function $0($){let Q=l0.exec($);if(Q){let[,W,M,B]=Q,O=M.endsWith(".git")?M.slice(0,-4):M;$=`github:${W}/${O}${B?`#${B}`:""}`}if(!$.startsWith("github:"))throw Error(`Invalid source format. Got: "${$}"
3
+ import{a as N,c as w,d as L0,e as o,f as E0,g as I0,h as n,i as C0,j as X,k as W0,l as R0,m as t,n as w0,o as y0,p as x0,q as R,r as l,s as N0,u as S0,v as D0,w as i}from"./chunk-z33xk2hv.js";import{A as H,B as H0,C as g,D as m,E as _,F as T0,x as T,y as L,z as A0}from"./chunk-t7727aqn.js";import{execFile as P0}from"child_process";import{promisify as v0}from"util";import{mkdtemp as h0,readdir as e,readFile as D,rm as S,cp as u0,access as u,stat as a,lstat as m0,symlink as c0,mkdir as d0}from"fs/promises";import{join as E,relative as p0}from"path";import{tmpdir as g0}from"os";var r=v0(P0),o0=/^[a-zA-Z0-9_-]+$/,n0=/^[a-zA-Z0-9._-]+$/,t0=/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/,s=128,l0=/^https?:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\/tree\/(.+))?\/?$/;function $0($){let Q=l0.exec($);if(Q){let[,W,M,B]=Q,O=M.endsWith(".git")?M.slice(0,-4):M;$=`github:${W}/${O}${B?`#${B}`:""}`}if(!$.startsWith("github:"))throw Error(`Invalid source format. Got: "${$}"
4
4
  Supported formats:
5
5
  github:owner/repo[#ref]
6
6
  https://github.com/owner/repo`);let K=$.slice(7),q=K.indexOf("#"),Z,z=null;if(q!==-1){if(Z=K.slice(0,q),z=K.slice(q+1),!z)throw Error("Invalid source: ref cannot be empty after #")}else Z=K;let Y=Z.indexOf("/");if(Y===-1)throw Error(`Invalid source: format must be github:owner/repo. Got: "${$}"`);let U=Z.slice(0,Y),V=Z.slice(Y+1);if(!U)throw Error("Invalid source: owner cannot be empty");if(!V)throw Error("Invalid source: repo cannot be empty");if(!o0.test(U))throw Error(`Invalid source: owner contains invalid characters: "${U}". Allowed: [a-zA-Z0-9_-]`);if(!n0.test(V))throw Error(`Invalid source: repo contains invalid characters: "${V}". Allowed: [a-zA-Z0-9._-]`);let J={owner:U,repo:V,ref:z,cloneUrl:`https://github.com/${U}/${V}.git`};return H(`install: parsed source -> owner=${U} repo=${V} ref=${z}`),J}function b($){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>s)throw Error(`Invalid skill name: exceeds maximum length of ${s} characters`);if(!t0.test($))throw Error(`Invalid skill name: "${$}" does not match allowed pattern [a-zA-Z0-9][a-zA-Z0-9._-]*`);return $}async function Q0(){try{await r("git",["--version"]),H("install: git available")}catch{throw Error("git is required for installing skills. Install git from https://git-scm.com")}}async function Z0($){H(`install: cloning ${$.cloneUrl}${$.ref?` (ref: ${$.ref})`:""}`);let Q=await h0(E(g0(),"asm-install-")),K=["clone","--depth","1"];if($.ref)K.push("--branch",$.ref);K.push($.cloneUrl,Q);try{await r("git",K,{timeout:60000})}catch(q){await f(Q);let Z=q.killed?"Clone timed out after 60 seconds":`Clone failed: ${q.stderr||q.message}`;throw Error(Z)}return Q}async function k($){let Q=E($,"SKILL.md"),K;try{K=await D(Q,"utf-8")}catch{throw Error("Not a valid skill: SKILL.md not found in repository root")}let q=N(K),Z=$.split("/").pop()||"unknown",z=q.name||Z,Y=q.version||"0.0.0";return H(`install: validated skill "${z}" v${Y}`),{name:z,version:Y,description:(q.description||"").replace(/\s*\n\s*/g," ").trim()}}async function K0($,Q=3){let K=[];async function q(Z,z,Y){let U;try{U=await e(Z)}catch{return}for(let V of U){if(V===".git"||V==="node_modules")continue;let J=E(Z,V);try{if(!(await a(J)).isDirectory())continue}catch{continue}let W=z?`${z}/${V}`:V,M=Y+1,B=E(J,"SKILL.md");try{let O=await D(B,"utf-8"),G=N(O);K.push({relPath:W,name:G.name||V,version:G.version||"0.0.0",description:(G.description||"").replace(/\s*\n\s*/g," ").trim()})}catch{if(M<Q)await q(J,W,M)}}}return await q($,"",0),K.sort((Z,z)=>Z.name.localeCompare(z.name)),K}var i0=[{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?:\/\//}],s0=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 e0($){let Q=[];async function K(q,Z){let z;try{z=await e(q)}catch{return}for(let Y of z){if(Y===".git")continue;if(Y==="node_modules")continue;let U=E(q,Y),V=Z?`${Z}/${Y}`:Y;try{let J=await a(U);if(J.isDirectory())await K(U,V);else if(J.isFile()){let W=Y.includes(".")?`.${Y.split(".").pop().toLowerCase()}`:"";if(s0.has(W))continue;if(J.size>524288)continue;try{let M=await D(U,"utf-8");Q.push({relPath:V,content:M})}catch{}}}catch{continue}}}return await K($,""),Q}async function q0($){let Q=[],K=await e0($);for(let{relPath:q,content:Z}of K){let z=Z.split(`
@@ -275,4 +275,4 @@ ${X.bold("Examples:")}
275
275
  asm link ./my-skill ${X.dim("Link (interactive provider)")}
276
276
  asm link ./my-skill -p claude ${X.dim("Link to Claude Code")}
277
277
  asm link ./my-skill --name alias ${X.dim("Link with custom name")}`)}async function u1($){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),z=await _0(Z),Y=$.flags.name?b($.flags.name):q(Z),U=await _(),{provider:V}=await P(U,$.flags.provider,!!process.stdin.isTTY),{resolveProviderPath:J}=await import("./chunk-t7727aqn.js"),W=J(U.providers.find((O)=>O.name===V.name).global),{join:M}=await import("path"),B=M(W,Y);if(!$.flags.force){let O=!1;try{let{access:G}=await import("fs/promises");await G(B),O=!0}catch{}if(O){if(!process.stdin.isTTY)j(`Target already exists: ${B}. Use --force to overwrite.`),process.exit(2);process.stderr.write(`${X.yellow(`Target already exists: ${B}`)}
278
- ${X.bold("Overwrite?")} [y/N] `);let G=await x();if(G.toLowerCase()!=="y"&&G.toLowerCase()!=="yes")console.error("Aborted."),process.exit(0);await v(Z,W,Y,!0)}else await v(Z,W,Y,!1)}else await v(Z,W,Y,!0);if($.flags.json)console.log(R({success:!0,name:Y,symlinkPath:B,targetPath:Z}));else console.error(X.green(`Done! Linked "${Y}" -> ${Z}`)),console.error(` Symlink: ${B}`),console.error(X.dim(` If you move or delete the source, run "asm uninstall ${Y}" to clean up.`))}async function k0($){let Q=F1($);if(Q.flags.noColor)globalThis.__CLI_NO_COLOR=!0;if(Q.flags.verbose)A0(!0);if(Q.flags.version){console.log(`asm ${i}`);return}if(!Q.command&&Q.flags.help){O1();return}if(!Q.command)return;switch(Q.command){case"list":await I1(Q);break;case"search":await C1(Q);break;case"inspect":await R1(Q);break;case"uninstall":await w1(Q);break;case"audit":await y1(Q);break;case"install":await S1(Q);break;case"config":await x1(Q);break;case"export":await b1(Q);break;case"init":await f1(Q);break;case"stats":await v1(Q);break;case"link":await u1(Q);break;default:j(`Unknown command: "${Q.command}"`),console.error('Run "asm --help" for usage.'),process.exit(2)}}function f0($){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(f0(process.argv))await k0(process.argv);else await import("./chunk-af7dwsh4.js");
278
+ ${X.bold("Overwrite?")} [y/N] `);let G=await x();if(G.toLowerCase()!=="y"&&G.toLowerCase()!=="yes")console.error("Aborted."),process.exit(0);await v(Z,W,Y,!0)}else await v(Z,W,Y,!1)}else await v(Z,W,Y,!0);if($.flags.json)console.log(R({success:!0,name:Y,symlinkPath:B,targetPath:Z}));else console.error(X.green(`Done! Linked "${Y}" -> ${Z}`)),console.error(` Symlink: ${B}`),console.error(X.dim(` If you move or delete the source, run "asm uninstall ${Y}" to clean up.`))}async function k0($){let Q=F1($);if(Q.flags.noColor)globalThis.__CLI_NO_COLOR=!0;if(Q.flags.verbose)A0(!0);if(Q.flags.version){console.log(`asm ${i}`);return}if(!Q.command&&Q.flags.help){O1();return}if(!Q.command)return;switch(Q.command){case"list":await I1(Q);break;case"search":await C1(Q);break;case"inspect":await R1(Q);break;case"uninstall":await w1(Q);break;case"audit":await y1(Q);break;case"install":await S1(Q);break;case"config":await x1(Q);break;case"export":await b1(Q);break;case"init":await f1(Q);break;case"stats":await v1(Q);break;case"link":await u1(Q);break;default:j(`Unknown command: "${Q.command}"`),console.error('Run "asm --help" for usage.'),process.exit(2)}}function f0($){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(f0(process.argv))await k0(process.argv);else await import("./chunk-np9dyaew.js");
@@ -0,0 +1,12 @@
1
+ import{A as D,D as H}from"./chunk-t7727aqn.js";import{readdir as h,stat as n,lstat as a,readlink as r,readFile as i,realpath as l}from"fs/promises";import{join as v,resolve as s}from"path";function W($){let L={},S=$.split(`
2
+ `),j=!1,A=!1,Q=null,Z=[],X="none",c=-1;function z(){if(Q){let G=Z.join(" ").trim();if(G)L[Q]=G;Q=null,Z=[],X="none",c=-1}}for(let G of S){if(G.trim()==="---")if(!A){A=!0,j=!0;continue}else{z();break}if(!j)continue;if(X!=="none"&&Q){let T=G.replace(/^\s*/,""),J=G.length-T.length;if(J>0&&T.length>0){if(c===-1)c=J;Z.push(T);continue}else if(T.length===0)continue;else z()}let U=G.match(/^(\w[\w-]*):\s*(.*?)\s*$/);if(U){z();let T=U[1],J=U[2];if(J==="|"||J===">")Q=T,Z=[],X=J==="|"?"literal":"folded";else if(J==="|+"||J===">+"||J==="|-"||J===">-")Q=T,Z=[],X=J.startsWith("|")?"literal":"folded";else{let f=J.replace(/^["']|["']$/g,"");if(f)L[T]=f}}}return z(),L}function e($,L){let S=[];for(let j of $.providers){if(!j.enabled){D(`scan: skipping disabled provider "${j.name}"`);continue}if(L==="global"||L==="both"){let A=H(j.global);D(`scan: adding location ${A} (${j.label}, global)`),S.push({dir:A,location:`global-${j.name}`,scope:"global",providerName:j.name,providerLabel:j.label})}if(L==="project"||L==="both"){let A=H(j.project);D(`scan: adding location ${A} (${j.label}, project)`),S.push({dir:A,location:`project-${j.name}`,scope:"project",providerName:j.name,providerLabel:j.label})}}for(let j of $.customPaths)if(L===j.scope||L==="both"){let A=H(j.path);D(`scan: adding custom location ${A} (${j.label}, ${j.scope})`),S.push({dir:A,location:`${j.scope}-custom`,scope:j.scope,providerName:"custom",providerLabel:j.label})}return S}async function P($){try{return(await h($,{recursive:!0})).length}catch{return 0}}async function $$($){let L=[];D(`scanning: ${$.dir} (${$.location})`);let S;try{S=await h($.dir)}catch{return D(`scanning: ${$.dir} — not found, skipping`),L}for(let j of S){let A=v($.dir,j);try{if(!(await n(A)).isDirectory()){D(` skip: "${j}" — not a directory`);continue}}catch{D(` skip: "${j}" — stat failed`);continue}let Q=v(A,"SKILL.md"),Z;try{Z=await i(Q,"utf-8")}catch{D(` skip: "${j}" — no SKILL.md`);continue}let X=W(Z),c=!1,z=null;try{if((await a(A)).isSymbolicLink())c=!0,z=await r(A)}catch{}let G=s(A),U;try{U=await l(A)}catch{U=G}L.push({name:X.name||j,version:X.version||"0.0.0",description:(X.description||"").replace(/\s*\n\s*/g," ").trim(),dirName:j,path:G,originalPath:A,location:$.location,scope:$.scope,provider:$.providerName,providerLabel:$.providerLabel,isSymlink:c,symlinkTarget:z,realPath:U})}return D(`found ${L.length} skill(s) in ${$.dir}`),L}async function V$($,L){let S=e($,L);return(await Promise.all(S.map($$))).flat()}function P$($,L){if(!L.trim())return $;let S=L.toLowerCase();return $.filter((j)=>j.name.toLowerCase().includes(S)||j.description.toLowerCase().includes(S)||j.location.toLowerCase().includes(S)||j.providerLabel.toLowerCase().includes(S))}function L$($,L){let S=$.split("."),j=L.split("."),A=Math.max(S.length,j.length);for(let Q=0;Q<A;Q++){let Z=parseInt(S[Q]??"0",10),X=parseInt(j[Q]??"0",10);if(isNaN(Z)||isNaN(X))return $.localeCompare(L);if(Z!==X)return Z-X}return 0}function C$($,L){let S=[...$];switch(L){case"name":S.sort((j,A)=>j.name.localeCompare(A.name));break;case"version":S.sort((j,A)=>L$(j.version,A.version));break;case"location":S.sort((j,A)=>j.location.localeCompare(A.location));break}return S}import{rm as C,readFile as t,writeFile as S$,access as j$,lstat as A$}from"fs/promises";import{join as b,resolve as _,dirname as c$}from"path";import{homedir as z$}from"os";var G$=z$();function Q$($,L){let S={directories:[],ruleFiles:[],agentsBlocks:[]};S.directories.push({path:$.originalPath,isSymlink:$.isSymlink});let j=$.dirName;if($.scope==="project")S.ruleFiles.push(_(".cursor","rules",`${j}.mdc`),_(".windsurf","rules",`${j}.md`),_(".github","instructions",`${j}.instructions.md`)),S.agentsBlocks.push({file:_("AGENTS.md"),skillName:j});if($.scope==="global"){for(let Z of L.providers){if(!Z.enabled)continue;let X=H(Z.global),c=b(c$(X),"AGENTS.md");S.agentsBlocks.push({file:c,skillName:j})}let A=b(G$,".codex","AGENTS.md");if(!S.agentsBlocks.some((Z)=>Z.file===A))S.agentsBlocks.push({file:A,skillName:j})}return S}function h$($,L,S){let j=L.filter((c)=>c.dirName===$);if(j.length===0)return{directories:[],ruleFiles:[],agentsBlocks:[]};let A={directories:[],ruleFiles:[],agentsBlocks:[]},Q=new Set,Z=new Set,X=new Set;for(let c of j){let z=Q$(c,S);for(let G of z.directories)if(!Q.has(G.path))Q.add(G.path),A.directories.push(G);for(let G of z.ruleFiles)if(!Z.has(G))Z.add(G),A.ruleFiles.push(G);for(let G of z.agentsBlocks){let U=`${G.file}::${G.skillName}`;if(!X.has(U))X.add(U),A.agentsBlocks.push(G)}}return A}async function O($){try{return await j$($),!0}catch{return!1}}async function X$($,L){if(!await O($))return;let S=await t($,"utf-8");for(let j of["agent-skill-manager","skill-manager","pskills"]){let A=`<!-- ${j}: ${L} -->`,Q=`<!-- /${j}: ${L} -->`,Z=S.indexOf(A),X=S.indexOf(Q);if(Z===-1||X===-1)continue;let c=Z;if(c>0&&S[c-1]===`
3
+ `)c--;let G=X+Q.length;if(G<S.length&&S[G]===`
4
+ `)G++;S=S.slice(0,c)+S.slice(G)}await S$($,S,"utf-8")}async function b$($){let L=[];for(let S of $.directories)try{if(S.isSymlink)await C(S.path),L.push(`Removed symlink: ${S.path}`);else await C(S.path,{recursive:!0,force:!0}),L.push(`Removed directory: ${S.path}`)}catch(j){L.push(`Failed to remove ${S.path}: ${j.message}`)}for(let S of $.ruleFiles)if(await O(S))try{await C(S),L.push(`Removed rule file: ${S}`)}catch(j){L.push(`Failed to remove ${S}: ${j.message}`)}for(let S of $.agentsBlocks)try{await X$(S.file,S.skillName),L.push(`Cleaned AGENTS.md block in: ${S.file}`)}catch(j){L.push(`Failed to clean AGENTS.md block: ${j.message}`)}return L}async function t$($){let L=[];for(let S of $.directories)if(await O(S.path)){let A=(await A$(S.path)).isSymbolicLink()?"symlink":"directory";L.push(`${S.path} (${A})`)}for(let S of $.ruleFiles)if(await O(S))L.push(S);for(let S of $.agentsBlocks)if(await O(S.file)){let j=await t(S.file,"utf-8");if(j.includes(`<!-- agent-skill-manager: ${S.skillName} -->`)||j.includes(`<!-- skill-manager: ${S.skillName} -->`)||j.includes(`<!-- pskills: ${S.skillName} -->`))L.push(`${S.file} (AGENTS.md block)`)}return L}var B=()=>{if(process.env.NO_COLOR!==void 0)return!1;if(globalThis.__CLI_NO_COLOR)return!1;if(!process.stdout.isTTY)return!1;return!0},Y={bold:($)=>B()?`\x1B[1m${$}\x1B[0m`:$,cyan:($)=>B()?`\x1B[36m${$}\x1B[0m`:$,green:($)=>B()?`\x1B[32m${$}\x1B[0m`:$,yellow:($)=>B()?`\x1B[33m${$}\x1B[0m`:$,dim:($)=>B()?`\x1B[2m${$}\x1B[0m`:$,red:($)=>B()?`\x1B[31m${$}\x1B[0m`:$,blueBold:($)=>B()?`\x1B[1m\x1B[34m${$}\x1B[0m`:$,magenta:($)=>B()?`\x1B[35m${$}\x1B[0m`:$,bgDim:($)=>B()?`\x1B[48;5;236m${$}\x1B[0m`:$};var m={claude:Y.blueBold,codex:Y.cyan,openclaw:Y.yellow,agents:Y.green,custom:Y.magenta};function w($,L){return(m[$]||Y.dim)(L)}function y($,L){if(!B())return`[${L}]`;return(m[$]||Y.dim)(`[${L}]`)}function K($){let L=process.env.HOME||process.env.USERPROFILE||"";if(L&&$.startsWith(L))return"~"+$.slice(L.length);return $}function o$($){if($.length===0)return"No skills found.";let L=["Name","Version","Provider","Scope","Type","Path"],S=$.map((c)=>[c.name,c.version,c.providerLabel,c.scope,c.isSymlink?"symlink":"directory",K(c.path)]),j=L.map((c,z)=>Math.max(c.length,...S.map((G)=>G[z].length))),A=(c,z)=>c.padEnd(z),Q=L.map((c,z)=>A(c,j[z])).join(" "),Z=j.map((c)=>"-".repeat(c)).join("--"),X=S.map((c)=>c.map((z,G)=>A(z,j[G])).join(" "));return[B()?Y.bold(Q):Q,Z,...X].join(`
5
+ `)}function g($){let L=new Map;for(let j of $){let A=`${j.dirName}||${j.scope}`,Q=L.get(A)??[];Q.push(j),L.set(A,Q)}let S=[];for(let[,j]of L){let A=j[0],Q=new Set(j.map((X)=>X.scope)),Z=new Set(j.map((X)=>X.isSymlink?"symlink":"directory"));S.push({name:A.name,version:A.version,providers:j.map((X)=>({provider:X.provider,label:X.providerLabel})),scope:Q.size>1?"mixed":A.scope,type:Z.size>1?"mixed":A.isSymlink?"symlink":"directory",path:K(A.path),warningCount:j.reduce((X,c)=>X+(c.warnings?.length??0),0)})}return S}function p$($){if($.length===0)return"No skills found.";let L=g($),S=[],j=Math.max(4,...L.map((I)=>I.name.length)),A=Math.max(7,...L.map((I)=>I.version.length)),Q=7,Z=9,X=L.map((I)=>I.providers.map((N)=>y(N.provider,N.label)).join(" ")),c=L.map((I)=>I.providers.map((N)=>`[${N.label}]`).join(" ")),z=Math.max(9,...c.map((I)=>I.length)),G=(I,N)=>I.padEnd(N),U=`${G("Name",j)} ${G("Version",A)} ${G("Providers",z)} ${G("Scope",Q)} ${G("Type",Z)}`;S.push(B()?Y.bold(U):U),S.push(`${"-".repeat(j)} ${"-".repeat(A)} ${"-".repeat(z)} ${"-".repeat(Q)} ${"-".repeat(Z)}`);for(let I=0;I<L.length;I++){let N=L[I],F=G(N.name,j),q=G(N.version,A),V=z-c[I].length,p=X[I]+" ".repeat(Math.max(0,V)),k=G(N.scope,Q),u=G(N.type,Z),d=N.warningCount>0?` ${Y.yellow(`(${N.warningCount} warning${N.warningCount>1?"s":""})`)}`:"";S.push(`${F} ${q} ${p} ${k} ${u}${d}`)}let T=L.length,J=$.length,f=new Set($.map((I)=>I.provider)),E=$.filter((I)=>I.scope==="global").length,M=$.filter((I)=>I.scope==="project").length;S.push("");let R=`${J} skills (${T} unique) across ${f.size} providers | ${E} global, ${M} project`;return S.push(Y.dim(R)),S.join(`
6
+ `)}function Y$($,L){if(!B()||!L)return $;let S=$.toLowerCase().indexOf(L.toLowerCase());if(S===-1)return $;let j=$.slice(0,S),A=$.slice(S,S+L.length),Q=$.slice(S+L.length);return`${j}${Y.bold(Y.yellow(A))}${Q}`}function k$($,L){if($.length===0)return`No skills matching "${L}". Try ${Y.bold("asm list")} to see all skills.`;let S=g($),j=[];j.push(Y.dim(`Found ${$.length} result${$.length===1?"":"s"} (${S.length} unique) matching "${L}"`)+`
7
+ `);let A=Math.max(4,...S.map((J)=>J.name.length)),Q=Math.max(7,...S.map((J)=>J.version.length)),Z=S.map((J)=>J.providers.map((f)=>y(f.provider,f.label)).join(" ")),X=S.map((J)=>J.providers.map((f)=>`[${f.label}]`).join(" ")),c=Math.max(9,...X.map((J)=>J.length)),z=7,G=9,U=(J,f)=>J.padEnd(f),T=`${U("Name",A)} ${U("Version",Q)} ${U("Providers",c)} ${U("Scope",z)} ${U("Type",G)}`;j.push(B()?Y.bold(T):T),j.push(`${"-".repeat(A)} ${"-".repeat(Q)} ${"-".repeat(c)} ${"-".repeat(z)} ${"-".repeat(G)}`);for(let J=0;J<S.length;J++){let f=S[J],E=Y$(f.name,L),M=A-f.name.length,R=E+" ".repeat(Math.max(0,M)),I=U(f.version,Q),N=c-X[J].length,F=Z[J]+" ".repeat(Math.max(0,N)),q=U(f.scope,z),V=U(f.type,G);j.push(`${R} ${I} ${F} ${q} ${V}`)}return j.join(`
8
+ `)}async function Z$($){let L=[],S=(A,Q)=>`${B()?Y.bold(A+":"):A+":"} ${Q}`;if(L.push(S("Name",$.name)),L.push(S("Version",$.version)),L.push(S("Provider",$.providerLabel)),L.push(S("Scope",$.scope)),L.push(S("Location",$.location)),L.push(S("Path",K($.path))),L.push(S("Type",$.isSymlink?"symlink":"directory")),$.isSymlink&&$.symlinkTarget)L.push(S("Symlink Target",$.symlinkTarget));let j=$.fileCount??await P($.path);if(L.push(S("File Count",String(j))),$.description)L.push(""),L.push(S("Description",$.description));if($.warnings&&$.warnings.length>0){L.push(""),L.push(B()?Y.bold("Warnings:"):"Warnings:");for(let A of $.warnings)L.push(` ${B()?Y.yellow("!"):"!"} [${A.category}] ${A.message}`)}return L.join(`
9
+ `)}async function u$($){if($.length===0)return"No skills found.";if($.length===1)return Z$($[0]);let L=[],S=(z,G)=>`${B()?Y.bold(z+":"):z+":"} ${G}`,j=$[0],A=j.name;L.push(""),L.push(B()?Y.blueBold(` ${A}`):` ${A}`),L.push(B()?Y.dim(" "+"-".repeat(A.length+2)):" "+"-".repeat(A.length+2)),L.push(""),L.push(S(" Version",B()?Y.green(j.version):j.version));let Q=j.fileCount??await P(j.path);L.push(S(" File Count",String(Q)));let Z=$.map((z)=>y(z.provider,z.providerLabel)).join(" ");if(L.push(S(" Installed in",Z)),j.description){L.push(""),L.push(B()?Y.bold(" Description:"):" Description:");let z=J$(j.description,72);for(let G of z)L.push(" "+G)}L.push("");let X=` Installations (${$.length})`;L.push(B()?Y.bold(X):X);for(let z=0;z<$.length;z++){let G=$[z],U=w(G.provider,G.providerLabel),T=G.isSymlink?B()?Y.yellow("symlink"):"symlink":B()?Y.green("directory"):"directory",J=Y.dim(G.scope);if(L.push(` ${U} (${J}, ${T})`),L.push(` ${Y.dim("Path:")} ${K(G.path)}`),G.isSymlink&&G.symlinkTarget)L.push(` ${Y.dim("Target:")} ${G.symlinkTarget}`)}let c=$.flatMap((z)=>{if(!z.warnings||z.warnings.length===0)return[];return z.warnings.map((G)=>({...G,provider:z.providerLabel}))});if(c.length>0){L.push("");let z=` Warnings (${c.length})`;L.push(B()?Y.bold(z):z);for(let G of c){let U=B()?Y.yellow("!"):"!";L.push(` ${U} [${G.category}] ${G.message}`)}}return L.push(""),L.join(`
10
+ `)}function J$($,L){let S=$.split(/\s+/),j=[],A="";for(let Q of S)if(A.length+Q.length+1>L&&A.length>0)j.push(A),A=Q;else A=A?A+" "+Q:Q;if(A)j.push(A);return j}function d$($){return JSON.stringify($,null,2)}function r$($){let L=[],S=new Set,j=new Map,A=[];for(let c of $){let z=j.get(c.realPath);if(z){if(c.isSymlink)continue;if(z.isSymlink)A[A.indexOf(z)]=c,j.set(c.realPath,c);else A.push(c)}else j.set(c.realPath,c),A.push(c)}let Q=new Map;for(let c of A){let z=Q.get(c.dirName)??[];z.push(c),Q.set(c.dirName,z)}for(let[c,z]of Q)if(new Set(z.map((U)=>U.location)).size>=2){L.push({key:c,reason:"same-dirName",instances:z});for(let U of z)S.add(U.path)}let Z=new Map;for(let c of A){if(!c.name)continue;let z=Z.get(c.name)??[];z.push(c),Z.set(c.name,z)}for(let[c,z]of Z){if(new Set(z.map((J)=>J.dirName)).size<2)continue;let U=z.filter((J)=>!S.has(J.path));if(U.length<2)continue;if(new Set(U.map((J)=>J.dirName)).size<2)continue;L.push({key:c,reason:"same-frontmatterName",instances:U})}L.sort((c,z)=>{if(c.reason!==z.reason)return c.reason==="same-dirName"?-1:1;return c.key.localeCompare(z.key)});let X=L.reduce((c,z)=>c+z.instances.length,0);return{scannedAt:new Date().toISOString(),totalSkills:$.length,duplicateGroups:L,totalDuplicateInstances:X}}function U$($){return[...$].sort((L,S)=>{if(L.scope!==S.scope)return L.scope==="global"?-1:1;let j=L.providerLabel.localeCompare(S.providerLabel);if(j!==0)return j;return L.path.localeCompare(S.path)})}function B$($){return $==="same-dirName"?"same dirName":"same name"}function i$($){if($.duplicateGroups.length===0)return Y.green("No duplicate skills found.");let L=[];L.push(""),L.push(Y.bold(` Found ${$.duplicateGroups.length} duplicate group(s) (${$.totalDuplicateInstances} total instances):`)),L.push("");for(let S of $.duplicateGroups){L.push(` ${Y.yellow(`"${S.key}"`)} ${Y.dim(`(${B$(S.reason)})`)}`);let j=U$(S.instances);for(let A=0;A<j.length;A++){let Q=j[A],Z=w(Q.provider,Q.providerLabel),X=A===0?Y.green(" [keep]"):Y.dim(" "),c=Y.dim(`(${Q.scope})`);L.push(` ${X} ${Z} ${c} ${Y.dim(K(Q.path))}`)}L.push("")}return L.push(Y.dim(` Run ${Y.bold("asm audit -y")} to auto-remove duplicates`)),L.push(""),L.join(`
11
+ `)}function l$($){return JSON.stringify($,null,2)}import{readFileSync as I$}from"fs";import{resolve as T$,dirname as f$}from"path";import{fileURLToPath as N$}from"url";import{execSync as D$}from"child_process";var H$=f$(N$(import.meta.url)),o="1.6.2";try{let $=I$(T$(H$,"../../package.json"),"utf-8");o=JSON.parse($).version}catch{}var x="6a96964";try{x=D$("git rev-parse --short HEAD",{encoding:"utf-8",stdio:["pipe","pipe","ignore"]}).trim()||x}catch{}var K$=o,O$=x,jL=`v${K$} (${O$})`;
12
+ export{W as a,P as b,V$ as c,P$ as d,C$ as e,Q$ as f,h$ as g,b$ as h,t$ as i,Y as j,w as k,K as l,o$ as m,p$ as n,k$ as o,u$ as p,d$ as q,r$ as r,U$ as s,B$ as t,i$ as u,l$ as v,jL as w};