agent-skill-manager 1.6.0 → 1.6.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,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-esvwvw47.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-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: "${$}"
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(`
@@ -27,7 +27,7 @@ as instructions for when and how to use this skill.
27
27
  ## Instructions
28
28
 
29
29
  - Step-by-step instructions for the agent
30
- `}async function G0($,Q){await Q1(Q,{recursive:!0});let K=q1(Q,"SKILL.md"),q=X1($);await Z1(K,q,"utf-8")}async function M0($){try{return await K1($),!0}catch{return!1}}import{readdir as Y1,stat as z1}from"fs/promises";import{join as U1}from"path";async function V1($){let Q=0;try{let q=(await Y1($,{recursive:!0})).map(async(z)=>{try{let Y=await z1(U1($,z));if(Y.isFile())return Y.size}catch{}return 0});Q=(await Promise.all(q)).reduce((z,Y)=>z+Y,0)}catch{}return Q}async function j0($,Q){let K={},q={global:0,project:0},Z={},z=$.map(async(V)=>{K[V.provider]=(K[V.provider]||0)+1,q[V.scope]++;let J=await V1(V.path);return Z[V.path]=J,J}),U=(await Promise.all(z)).reduce((V,J)=>V+J,0);return{totalSkills:$.length,byProvider:K,byScope:q,totalDiskBytes:U,perSkillDiskBytes:Z,duplicateGroups:Q.duplicateGroups.length,duplicateInstances:Q.totalDuplicateInstances}}function J1($){if($<1024)return`${$} B`;if($<1048576)return`${($/1024).toFixed(1)} KB`;if($<1073741824)return`${($/1048576).toFixed(1)} MB`;return`${($/1073741824).toFixed(1)} GB`}function d($,Q,K=20){let q=Math.round($/Q*K),Z=K-q;return X.green("".repeat(q))+X.dim("".repeat(Z))}var B0={claude:"Claude Code",codex:"Codex",openclaw:"OpenClaw",agents:"Agents"};function F0($){let Q=[];Q.push(""),Q.push(X.blueBold(" Skill Statistics")),Q.push(X.dim(" "+"-".repeat(20))),Q.push(""),Q.push(` ${X.bold("Total:")} ${X.cyan(String($.totalSkills))} skills`),Q.push(` ${X.bold("Disk:")} ${X.cyan(J1($.totalDiskBytes))}`),Q.push(""),Q.push(X.bold(" By Provider"));let K=Object.entries($.byProvider).sort((V,J)=>J[1]-V[1]),q=Math.max(...K.map(([,V])=>V)),Z=Math.max(...K.map(([V])=>(B0[V]||V).length));for(let[V,J]of K){let W=B0[V]||V,M=W0(V,W.padEnd(Z)),B=String(J).padStart(4);Q.push(` ${M} ${B} ${d(J,q)}`)}Q.push(""),Q.push(X.bold(" By Scope"));let z=Math.max($.byScope.global,$.byScope.project),Y=String($.byScope.global).padStart(4),U=String($.byScope.project).padStart(4);if(Q.push(` ${"global ".padEnd(Z)} ${Y} ${d($.byScope.global,z)}`),Q.push(` ${"project".padEnd(Z)} ${U} ${d($.byScope.project,z)}`),Q.push(""),Q.push(X.bold(" Duplicates")),$.duplicateGroups>0)Q.push(` ${X.yellow(`${$.duplicateGroups} group(s), ${$.duplicateInstances} total instance(s)`)}`),Q.push(X.dim(` Run ${X.bold("asm audit")} to review`));else Q.push(` ${X.green("None")}`);return Q.push(""),Q.join(`
30
+ `}async function G0($,Q){await Q1(Q,{recursive:!0});let K=q1(Q,"SKILL.md"),q=X1($);await Z1(K,q,"utf-8")}async function M0($){try{return await K1($),!0}catch{return!1}}import{readdir as Y1,stat as z1}from"fs/promises";import{join as U1}from"path";async function V1($){let Q=0;try{let q=(await Y1($,{recursive:!0})).map(async(z)=>{try{let Y=await z1(U1($,z));if(Y.isFile())return Y.size}catch{}return 0});Q=(await Promise.all(q)).reduce((z,Y)=>z+Y,0)}catch{}return Q}async function j0($,Q){let K={},q={global:0,project:0},Z={},z=$.map(async(V)=>{K[V.provider]=(K[V.provider]||0)+1,q[V.scope]++;let J=await V1(V.path);return Z[V.path]=J,J}),U=(await Promise.all(z)).reduce((V,J)=>V+J,0);return{totalSkills:$.length,byProvider:K,byScope:q,totalDiskBytes:U,perSkillDiskBytes:Z,duplicateGroups:Q.duplicateGroups.length,duplicateInstances:Q.totalDuplicateInstances}}function J1($){if($<1024)return`${$} B`;if($<1048576)return`${($/1024).toFixed(1)} KB`;if($<1073741824)return`${($/1048576).toFixed(1)} MB`;return`${($/1073741824).toFixed(1)} GB`}function d($,Q,K=20){let q=Math.round($/Q*K),Z=K-q;return X.green("#".repeat(q))+X.dim("-".repeat(Z))}var B0={claude:"Claude Code",codex:"Codex",openclaw:"OpenClaw",agents:"Agents"};function F0($){let Q=[];Q.push(""),Q.push(X.blueBold(" Skill Statistics")),Q.push(X.dim(" "+"-".repeat(20))),Q.push(""),Q.push(` ${X.bold("Total:")} ${X.cyan(String($.totalSkills))} skills`),Q.push(` ${X.bold("Disk:")} ${X.cyan(J1($.totalDiskBytes))}`),Q.push(""),Q.push(X.bold(" By Provider"));let K=Object.entries($.byProvider).sort((V,J)=>J[1]-V[1]),q=Math.max(...K.map(([,V])=>V)),Z=Math.max(...K.map(([V])=>(B0[V]||V).length));for(let[V,J]of K){let W=B0[V]||V,M=W0(V,W.padEnd(Z)),B=String(J).padStart(4);Q.push(` ${M} ${B} ${d(J,q)}`)}Q.push(""),Q.push(X.bold(" By Scope"));let z=Math.max($.byScope.global,$.byScope.project),Y=String($.byScope.global).padStart(4),U=String($.byScope.project).padStart(4);if(Q.push(` ${"global ".padEnd(Z)} ${Y} ${d($.byScope.global,z)}`),Q.push(` ${"project".padEnd(Z)} ${U} ${d($.byScope.project,z)}`),Q.push(""),Q.push(X.bold(" Duplicates")),$.duplicateGroups>0)Q.push(` ${X.yellow(`${$.duplicateGroups} group(s), ${$.duplicateInstances} total instance(s)`)}`),Q.push(X.dim(` Run ${X.bold("asm audit")} to review`));else Q.push(` ${X.green("None")}`);return Q.push(""),Q.join(`
31
31
  `)}import{access as G1,lstat as M1,readFile as B1,rm as W1,symlink as j1}from"fs/promises";import{join as O0}from"path";async function _0($){let Q;try{Q=await M1($)}catch{throw Error(`Path does not exist: ${$}`)}if(!Q.isDirectory())throw Error(`Path is not a directory: ${$}`);let K=O0($,"SKILL.md"),q;try{q=await B1(K,"utf-8")}catch{throw Error(`No SKILL.md found in ${$}`)}let Z=N(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 v($,Q,K,q){let Z=O0(Q,K),z=!1;try{await G1(Z),z=!0}catch{}if(z){if(!q)throw Error(`Target already exists: ${Z}. Use --force to overwrite.`);await W1(Z,{recursive:!0,force:!0})}await j1($,Z,"dir")}function F1($){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,flat:!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 z=Q[q];if(z==="global"||z==="project"||z==="both")K.flags.scope=z;else j(`Invalid scope: "${z}". Must be global, project, or both.`),process.exit(2)}else if(Z==="--sort"){q++;let z=Q[q];if(z==="name"||z==="version"||z==="location")K.flags.sort=z;else j(`Invalid sort: "${z}". 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==="--flat")K.flags.flat=!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(X.red(`Error: ${$}`))}function O1(){console.log(`${X.blueBold("agent-skill-manager")} (${X.bold("asm")}) ${i}
32
32
 
33
33
  Interactive TUI and CLI for managing installed skills for AI coding agents.
@@ -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-menf8e4q.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-af7dwsh4.js");