agent-skill-manager 1.4.1 → 1.5.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.
- package/dist/agent-skill-manager.js +50 -46
- package/dist/chunk-5d41n7xa.js +90 -0
- package/dist/chunk-95dyppsz.js +8 -0
- package/dist/chunk-9pkjdwkv.js +90 -0
- package/dist/chunk-ajgr5x1f.js +8 -0
- package/dist/chunk-j1ngzqjc.js +8 -0
- package/dist/chunk-kv6faz1t.js +8 -0
- package/dist/chunk-npfpnsn4.js +90 -0
- package/dist/chunk-qfn7hb5z.js +90 -0
- package/dist/chunk-s1n7e69d.js +90 -0
- package/dist/chunk-sx2p5bqv.js +8 -0
- package/package.json +1 -1
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
// @bun
|
|
3
|
-
import{a as
|
|
3
|
+
import{a as N,c as R,d as A0,e as g,f as E0,g as L0,h as o,i as T0,j as Y,k as n,l as H0,m as y,n as t,o as I0,q as C0,r as R0,s as l}from"./chunk-95dyppsz.js";import{A as F,B as F0,t as L,u as T,v as O0,w as E,x as _0,y as p,z as m}from"./chunk-zh7g5bam.js";import{execFile as N0}from"child_process";import{promisify as S0}from"util";import{mkdtemp as b0,readdir as s,readFile as b,rm as S,cp as D0,access as u,stat as a,lstat as f0,symlink as k0,mkdir as P0}from"fs/promises";import{join as H,relative as h0}from"path";import{tmpdir as v0}from"os";var e=S0(N0),u0=/^[a-zA-Z0-9_-]+$/,m0=/^[a-zA-Z0-9._-]+$/,c0=/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/,i=128,d0=/^https?:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\/tree\/(.+))?\/?$/;function r($){let Q=d0.exec($);if(Q){let[,M,G,B]=Q,_=G.endsWith(".git")?G.slice(0,-4):G;$=`github:${M}/${_}${B?`#${B}`:""}`}if(!$.startsWith("github:"))throw Error(`Invalid source format. Got: "${$}"
|
|
4
4
|
Supported formats:
|
|
5
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(!
|
|
7
|
-
`);for(let X=0;X<V.length;X++)for(let{category:z,pattern:J}of
|
|
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(`
|
|
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(!u0.test(z))throw Error(`Invalid source: owner contains invalid characters: "${z}". Allowed: [a-zA-Z0-9_-]`);if(!m0.test(J))throw Error(`Invalid source: repo contains invalid characters: "${J}". Allowed: [a-zA-Z0-9._-]`);let W={owner:z,repo:J,ref:V,cloneUrl:`https://github.com/${z}/${J}.git`};return E(`install: parsed source -> owner=${z} repo=${J} ref=${V}`),W}function D($){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>i)throw Error(`Invalid skill name: exceeds maximum length of ${i} characters`);if(!c0.test($))throw Error(`Invalid skill name: "${$}" does not match allowed pattern [a-zA-Z0-9][a-zA-Z0-9._-]*`);return $}async function $0(){try{await e("git",["--version"]),E("install: git available")}catch{throw Error("git is required for installing skills. Install git from https://git-scm.com")}}async function Q0($){E(`install: cloning ${$.cloneUrl}${$.ref?` (ref: ${$.ref})`:""}`);let Q=await b0(H(v0(),"asm-install-")),K=["clone","--depth","1"];if($.ref)K.push("--branch",$.ref);K.push($.cloneUrl,Q);try{await e("git",K,{timeout:60000})}catch(q){await k(Q);let Z=q.killed?"Clone timed out after 60 seconds":`Clone failed: ${q.stderr||q.message}`;throw Error(Z)}return Q}async function f($){let Q=H($,"SKILL.md"),K;try{K=await b(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",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 Z0($,Q=3){let K=[];async function q(Z,V,X){let z;try{z=await s(Z)}catch{return}for(let J of z){if(J===".git"||J==="node_modules")continue;let W=H(Z,J);try{if(!(await a(W)).isDirectory())continue}catch{continue}let M=V?`${V}/${J}`:J,G=X+1,B=H(W,"SKILL.md");try{let _=await b(B,"utf-8"),U=N(_);K.push({relPath:M,name:U.name||J,version:U.version||"0.0.0",description:(U.description||"").replace(/\s*\n\s*/g," ").trim()})}catch{if(G<Q)await q(W,M,G)}}}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?:\/\//}],g0=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 o0($){let Q=[];async function K(q,Z){let V;try{V=await s(q)}catch{return}for(let X of V){if(X===".git")continue;if(X==="node_modules")continue;let z=H(q,X),J=Z?`${Z}/${X}`:X;try{let W=await a(z);if(W.isDirectory())await K(z,J);else if(W.isFile()){let M=X.includes(".")?`.${X.split(".").pop().toLowerCase()}`:"";if(g0.has(M))continue;if(W.size>524288)continue;try{let G=await b(z,"utf-8");Q.push({relPath:J,content:G})}catch{}}}catch{continue}}}return await K($,""),Q}async function K0($){let Q=[],K=await o0($);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 p0)if(J.test(V[X])){let W=V[X].trim();Q.push({category:z,file:q,line:X+1,match:W.length>100?W.slice(0,100)+"…":W})}}return Q}async function c($){let Q=`github:${$.source.owner}/${$.source.repo}${$.source.ref?`#${$.source.ref}`:""}`;if($.force)try{await u($.targetDir),await S($.targetDir,{recursive:!0,force:!0})}catch{}let K=$.sourceDir;try{await D0(K,$.targetDir,{recursive:!0})}catch(z){throw Error(`Failed to install: ${z.message}`)}let q=H($.targetDir,".git");try{await S(q,{recursive:!0,force:!0})}catch{}E(`install: copied files to ${$.targetDir}`);let Z=H($.targetDir,"SKILL.md");try{await u(Z)}catch{throw Error("Installation verification failed: SKILL.md not found at target")}let V=await b(Z,"utf-8"),X=N(V);return{success:!0,path:$.targetDir,name:X.name||$.skillName,version:X.version||"0.0.0",provider:$.providerLabel,source:Q}}async function q0($,Q){let K=await c($);for(let q of Q){if(q.name===$.providerName)continue;let Z=m(q.global),V=H(Z,$.skillName);await P0(Z,{recursive:!0});try{if((await f0(V)).isSymbolicLink())await S(V);else{E(`install: skipping ${V} — existing non-symlink directory`);continue}}catch{}let X=h0(Z,$.targetDir);await k0(X,V,"dir"),E(`install: symlinked ${V} -> ${X}`)}return K.provider=`All (${Q.map((q)=>q.label).join(", ")})`,K}async function k($){try{await S($,{recursive:!0,force:!0})}catch{}}async function P($,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==="all")return{provider:q.find((z)=>z.name==="agents")||q[0],allProviders:q};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}, all`)}if(!X.enabled)throw Error(`Provider "${Q}" is disabled. Enable it in your config or choose another provider.`);return{provider:X,allProviders:null}}if(q.length===1)return{provider:q[0],allProviders:null};if(!K){let X=q.map((z)=>z.name).join(", ");throw Error(`--provider is required in non-interactive mode. Available: ${X}, all`)}console.error(`
|
|
8
|
+
Select a provider:`);for(let X=0;X<q.length;X++)console.error(` ${X+1}) ${q[X].label} (${q[X].name})`);console.error(` ${q.length+1}) All providers (shared .agents/skills/ + symlinks)`),process.stderr.write(`
|
|
9
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
|
|
11
|
-
Use --force to overwrite.`)}catch(K){if(K.message?.includes("--force"))throw K;E(`install: target ${$} — no conflict`)}}import{readFile as
|
|
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
|
|
10
|
+
`))process.stdin.removeAllListeners("data"),process.stdin.pause(),X(z.trim())}),process.stdin.resume()}),V=parseInt(Z,10)-1;if(V===q.length)return{provider:q.find((z)=>z.name==="agents")||q[0],allProviders:q};if(isNaN(V)||V<0||V>=q.length)throw Error("Invalid selection. Aborting.");return{provider:q[V],allProviders:null}}function V0($,Q,K,q,Z,V){let X=m(Z.global),z=H(X,q);return{source:$,tempDir:Q,sourceDir:K,targetDir:z,skillName:q,force:V,providerName:Z.name,providerLabel:Z.label}}async function X0($,Q){try{if(await u($),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 n0}from"fs/promises";import{join as t0}from"path";var Y0=500;function l0($){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 z0($){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=t0($.path,"SKILL.md"),Z=await n0(q,"utf-8");if(!l0(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>Y0)Q.push({category:"high-file-count",message:`Skill has ${K} files (threshold: ${Y0})`});return Q}function J0($){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 i0,writeFile as s0,access as a0}from"fs/promises";import{join as e0}from"path";function r0($){return`---
|
|
13
13
|
name: ${$}
|
|
14
14
|
version: 0.1.0
|
|
15
15
|
description: ""
|
|
@@ -27,8 +27,8 @@ 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
|
|
31
|
-
`)}import{access as
|
|
30
|
+
`}async function U0($,Q){await i0(Q,{recursive:!0});let K=e0(Q,"SKILL.md"),q=r0($);await s0(K,q,"utf-8")}async function W0($){try{return await a0($),!0}catch{return!1}}import{readdir as $1,stat as Q1}from"fs/promises";import{join as Z1}from"path";async function K1($){let Q=0;try{let q=(await $1($,{recursive:!0})).map(async(V)=>{try{let X=await Q1(Z1($,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 G0($,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 W=await K1(J.path);return Z[J.path]=W,W}),z=(await Promise.all(V)).reduce((J,W)=>J+W,0);return{totalSkills:$.length,byProvider:K,byScope:q,totalDiskBytes:z,perSkillDiskBytes:Z,duplicateGroups:Q.duplicateGroups.length,duplicateInstances:Q.totalDuplicateInstances}}function q1($){if($<1024)return`${$} B`;if($<1048576)return`${($/1024).toFixed(1)} KB`;if($<1073741824)return`${($/1048576).toFixed(1)} MB`;return`${($/1073741824).toFixed(1)} GB`}function B0($){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",q1($.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 V1,lstat as X1,readFile as Y1,rm as z1,symlink as J1}from"fs/promises";import{join as M0}from"path";async function j0($){let Q;try{Q=await X1($)}catch{throw Error(`Path does not exist: ${$}`)}if(!Q.isDirectory())throw Error(`Path is not a directory: ${$}`);let K=M0($,"SKILL.md"),q;try{q=await Y1(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 h($,Q,K,q){let Z=M0(Q,K),V=!1;try{await V1(Z),V=!0}catch{}if(V){if(!q)throw Error(`Target already exists: ${Z}. Use --force to overwrite.`);await z1(Z,{recursive:!0,force:!0})}await J1($,Z,"dir")}function U1($){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 W1(){console.log(`${Y.blueBold("agent-skill-manager")} (${Y.bold("asm")}) ${l}
|
|
32
32
|
|
|
33
33
|
Interactive TUI and CLI for managing installed skills for AI coding agents.
|
|
34
34
|
|
|
@@ -60,7 +60,7 @@ ${Y.bold("Global Options:")}
|
|
|
60
60
|
--no-color Disable ANSI colors
|
|
61
61
|
--sort <field> Sort by: name, version, or location (default: name)
|
|
62
62
|
-y, --yes Skip confirmation prompts
|
|
63
|
-
-V, --verbose Show debug output`)}function
|
|
63
|
+
-V, --verbose Show debug output`)}function G1(){console.log(`${Y.bold("Usage:")} asm list [options]
|
|
64
64
|
|
|
65
65
|
List all discovered skills.
|
|
66
66
|
|
|
@@ -69,7 +69,7 @@ ${Y.bold("Options:")}
|
|
|
69
69
|
-s, --scope <s> Filter: global, project, or both (default: both)
|
|
70
70
|
--json Output as JSON array
|
|
71
71
|
--no-color Disable ANSI colors
|
|
72
|
-
-V, --verbose Show debug output`)}function
|
|
72
|
+
-V, --verbose Show debug output`)}function B1(){console.log(`${Y.bold("Usage:")} asm search <query> [options]
|
|
73
73
|
|
|
74
74
|
Search skills by name, description, or provider.
|
|
75
75
|
|
|
@@ -78,7 +78,7 @@ ${Y.bold("Options:")}
|
|
|
78
78
|
-s, --scope <s> Filter: global, project, or both (default: both)
|
|
79
79
|
--json Output as JSON array
|
|
80
80
|
--no-color Disable ANSI colors
|
|
81
|
-
-V, --verbose Show debug output`)}function
|
|
81
|
+
-V, --verbose Show debug output`)}function M1(){console.log(`${Y.bold("Usage:")} asm inspect <skill-name> [options]
|
|
82
82
|
|
|
83
83
|
Show detailed information for a skill. The <skill-name> is the directory name.
|
|
84
84
|
|
|
@@ -86,7 +86,7 @@ ${Y.bold("Options:")}
|
|
|
86
86
|
-s, --scope <s> Filter: global, project, or both (default: both)
|
|
87
87
|
--json Output as JSON object
|
|
88
88
|
--no-color Disable ANSI colors
|
|
89
|
-
-V, --verbose Show debug output`)}function
|
|
89
|
+
-V, --verbose Show debug output`)}function j1(){console.log(`${Y.bold("Usage:")} asm uninstall <skill-name> [options]
|
|
90
90
|
|
|
91
91
|
Remove a skill and its associated rule files.
|
|
92
92
|
|
|
@@ -94,7 +94,7 @@ ${Y.bold("Options:")}
|
|
|
94
94
|
-y, --yes Skip confirmation prompt
|
|
95
95
|
-s, --scope <s> Filter: global, project, or both (default: both)
|
|
96
96
|
--no-color Disable ANSI colors
|
|
97
|
-
-V, --verbose Show debug output`)}function
|
|
97
|
+
-V, --verbose Show debug output`)}function O1(){console.log(`${Y.bold("Usage:")} asm audit [subcommand] [options]
|
|
98
98
|
|
|
99
99
|
Detect and optionally remove duplicate skills.
|
|
100
100
|
|
|
@@ -105,7 +105,7 @@ ${Y.bold("Options:")}
|
|
|
105
105
|
--json Output as JSON
|
|
106
106
|
-y, --yes Auto-remove duplicates, keeping one instance per group
|
|
107
107
|
--no-color Disable ANSI colors
|
|
108
|
-
-V, --verbose Show debug output`)}function
|
|
108
|
+
-V, --verbose Show debug output`)}function _1(){console.log(`${Y.bold("Usage:")} asm config <subcommand>
|
|
109
109
|
|
|
110
110
|
Manage configuration.
|
|
111
111
|
|
|
@@ -116,15 +116,15 @@ ${Y.bold("Subcommands:")}
|
|
|
116
116
|
edit Open config in $EDITOR
|
|
117
117
|
|
|
118
118
|
${Y.bold("Options:")}
|
|
119
|
-
-V, --verbose Show debug output`)}async function
|
|
120
|
-
${Y.yellow(
|
|
121
|
-
`+"
|
|
122
|
-
`);console.log(await
|
|
123
|
-
${Y.bold("Proceed with removal?")} [y/N] `);let z=await
|
|
124
|
-
Done.`))}function
|
|
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
|
|
126
|
-
Auto-removing duplicates...`));for(let V of Z.duplicateGroups){let X=
|
|
127
|
-
Done.`))}}async function
|
|
119
|
+
-V, --verbose Show debug output`)}async function x0($){for(let Q of $)Q.warnings=await z0(Q)}async function F1($){if($.flags.help){G1();return}let Q=await F(),K=await R(Q,$.flags.scope);await x0(K);let q=g(K,$.flags.sort);if($.flags.json)console.log(y(q));else{let Z=n(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 A1($){if($.flags.help){B1();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 F(),q=await R(K,$.flags.scope),Z=A0(q,Q),V=g(Z,$.flags.sort);if($.flags.json)console.log(y(V));else console.log(n(V))}async function E1($){if($.flags.help){M1();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 F(),Z=(await R(K,$.flags.scope)).filter((V)=>V.dirName===Q);if(Z.length===0)j(`Skill "${Q}" not found.`),process.exit(1);if(await x0(Z),$.flags.json)console.log(y(Z.length===1?Z[0]:Z));else for(let V=0;V<Z.length;V++){if(V>0)console.log(`
|
|
121
|
+
`+"-".repeat(40)+`
|
|
122
|
+
`);console.log(await H0(Z[V]))}}async function L1($){if($.flags.help){j1();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 F(),q=await R(K,$.flags.scope),Z=L0(Q,q,K),V=await T0(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 w();if(z.toLowerCase()!=="y"&&z.toLowerCase()!=="yes")console.error("Aborted."),process.exit(0)}let X=await o(Z);for(let z of X)console.error(z);console.error(Y.green(`
|
|
124
|
+
Done.`))}function w(){return new Promise(($)=>{let Q="",K=!1;function q(){process.stdin.removeListener("data",V),process.stdin.removeListener("end",X),process.stdin.pause(),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 T1($){if($.flags.help){O1();return}let Q=$.subcommand??"duplicates";if(Q!=="duplicates")j(`Unknown audit subcommand: "${Q}". Use: duplicates`),process.exit(2);let K=await F(),q=await R(K,"both"),Z=t(q);if($.flags.json){console.log(R0(Z));return}if(console.log(C0(Z)),$.flags.yes&&Z.duplicateGroups.length>0){console.error(Y.bold(`
|
|
126
|
+
Auto-removing duplicates...`));for(let V of Z.duplicateGroups){let X=I0(V.instances);for(let z=1;z<X.length;z++){let J=X[z],W=E0(J,K),M=await o(W);for(let G of M)console.error(G)}}console.error(Y.green(`
|
|
127
|
+
Done.`))}}async function H1($){if($.flags.help){_1();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 F();console.log(y(K));break}case"path":{console.log(p());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 w();if(q.toLowerCase()!=="y"&&q.toLowerCase()!=="yes")console.error("Aborted."),process.exit(0)}let K=_0();await F0(K),console.error(Y.green("Config reset to defaults."));break}case"edit":{let K=process.env.VISUAL||process.env.EDITOR||"vi",q=p();await F();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 I1(){console.log(`${Y.bold("Usage:")} asm install <source> [options]
|
|
128
128
|
|
|
129
129
|
Install a skill from a GitHub repository.
|
|
130
130
|
|
|
@@ -134,7 +134,8 @@ ${Y.bold("Source Format:")}
|
|
|
134
134
|
https://github.com/owner/repo Install via HTTPS URL
|
|
135
135
|
|
|
136
136
|
${Y.bold("Options:")}
|
|
137
|
-
-p, --provider <name> Target provider (claude, codex, openclaw, agents)
|
|
137
|
+
-p, --provider <name> Target provider (claude, codex, openclaw, agents, all)
|
|
138
|
+
Use "all" to install to all providers (shared + symlinks)
|
|
138
139
|
--name <name> Override skill directory name
|
|
139
140
|
--path <subdir> Install skill from a subdirectory of the repo
|
|
140
141
|
--all Install all skills found in the repo
|
|
@@ -148,34 +149,37 @@ ${Y.bold("Single-skill repo:")}
|
|
|
148
149
|
asm install github:user/my-skill
|
|
149
150
|
asm install github:user/my-skill#v1.0.0 -p claude
|
|
150
151
|
asm install https://github.com/user/my-skill
|
|
152
|
+
asm install github:user/my-skill -p all ${Y.dim("(install to all providers)")}
|
|
151
153
|
|
|
152
154
|
${Y.bold("Multi-skill repo:")}
|
|
153
155
|
asm install github:user/skills --path skills/code-review
|
|
154
156
|
asm install github:user/skills --all -p claude -y
|
|
157
|
+
asm install github:user/skills --all -p all -y ${Y.dim("(all skills, all providers)")}
|
|
155
158
|
asm install https://github.com/user/skills --all
|
|
156
|
-
asm install github:user/skills ${Y.dim("(interactive picker)")}`)}async function
|
|
157
|
-
${Y.bold("Install preview:")}`),console.error(` Name: ${
|
|
158
|
-
${Y.yellow(Y.bold("Security warnings:"))}`);let O=new Map;for(let
|
|
159
|
-
${Y.yellow(`[${
|
|
160
|
-
${Y.bold("Proceed with installation?")} [y/N] `);let O=await
|
|
161
|
-
Installing to ${
|
|
162
|
-
`);for(let
|
|
163
|
-
Installing all ${
|
|
164
|
-
${Y.bold(`Install all ${
|
|
165
|
-
Enter skill number (or "all"): `);let
|
|
159
|
+
asm install github:user/skills ${Y.dim("(interactive picker)")}`)}async function d($,Q,K,q,Z,V,X,z,J,W){let M=await f(Z),G=W!==void 0,B=await K0(Z),_=Z===q?null:Z.split("/").pop(),U=V||_||K.repo,A=D(U),I=V0(K,q,Z,A,z,$.flags.force);if(await X0(I.targetDir,I.force),G){let O=`[${W.index}/${W.total}]`,x=B.length>0?` ${Y.yellow(`(${B.length} warning${B.length>1?"s":""})`)}`:"";console.error(`${Y.dim(O)} ${Y.bold(M.name)} v${M.version}${x}`)}else{if(console.error(`Found skill: ${M.name} v${M.version}`),console.error(`
|
|
160
|
+
${Y.bold("Install preview:")}`),console.error(` Name: ${M.name}`),console.error(` Version: ${M.version}`),M.description)console.error(` Description: ${M.description}`);if(console.error(` Source: ${Q}`),J)console.error(` Provider: All (${J.map((O)=>O.label).join(", ")})`),console.error(` Primary: ${z.label} (${z.name})`),console.error(` Symlinks: ${J.filter((O)=>O.name!==z.name).map((O)=>O.label).join(", ")}`);else console.error(` Provider: ${z.label} (${z.name})`);if(console.error(` Target: ${I.targetDir}`),B.length>0){console.error(`
|
|
161
|
+
${Y.yellow(Y.bold("Security warnings:"))}`);let O=new Map;for(let x of B){let C=O.get(x.category)||[];C.push(x),O.set(x.category,C)}for(let[x,C]of O){console.error(`
|
|
162
|
+
${Y.yellow(`[${x}]`)} (${C.length} match${C.length>1?"es":""})`);for(let v of C.slice(0,5))console.error(` ${Y.dim(v.file)}:${v.line} -- ${v.match}`);if(C.length>5)console.error(` ... and ${C.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(`
|
|
163
|
+
${Y.bold("Proceed with installation?")} [y/N] `);let O=await w();if(O.toLowerCase()!=="y"&&O.toLowerCase()!=="yes")console.error("Aborted."),process.exit(0)}}if(!G)console.error(`
|
|
164
|
+
Installing to ${I.targetDir}...`);if(J)return await q0(I,J);return await c(I)}async function C1($){if($.flags.help){I1();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)k(K).finally(()=>process.exit(1));else process.exit(1)};process.on("SIGINT",q),process.on("SIGTERM",q);try{let Z=r(Q);console.error(`Parsing source: ${Q}`),await $0(),console.error(`Cloning ${Z.cloneUrl}${Z.ref?` (ref: ${Z.ref})`:""}...`),K=await Q0(Z);let V=await F(),{provider:X,allProviders:z}=await P(V,$.flags.provider,!!process.stdin.isTTY),{join:J}=await import("path"),W=[];if($.flags.path){let M=J(K,$.flags.path);try{await f(M)}catch{throw Error(`No SKILL.md found at path "${$.flags.path}" in the repository.`)}let G=await d($,Q,Z,K,M,$.flags.name,V,X,z);W.push(G)}else{let M=!1;try{await f(K),M=!0}catch{}if(M){let G=await d($,Q,Z,K,K,$.flags.name,V,X,z);W.push(G)}else{console.error("No SKILL.md at repository root. Scanning for skills...");let G=await Z0(K);if(G.length===0)throw Error("No skills found in this repository. Skills must have a SKILL.md file.");console.error(`Found ${G.length} skill(s):
|
|
165
|
+
`);for(let U=0;U<G.length;U++)if(console.error(` ${Y.bold(`${U+1})`)} ${G[U].name} v${G[U].version} ${Y.dim(`(${G[U].relPath})`)}`),G[U].description)console.error(` ${G[U].description}`);let B;if($.flags.all){if(B=G.map((U)=>U.relPath),console.error(`
|
|
166
|
+
Installing all ${B.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(`
|
|
167
|
+
${Y.bold(`Install all ${B.length} skills?`)} [y/N] `);let U=await w();if(U.toLowerCase()!=="y"&&U.toLowerCase()!=="yes")console.error("Aborted."),process.exit(0)}}else if(process.stdin.isTTY){process.stderr.write(`
|
|
168
|
+
Enter skill number (or "all"): `);let U=await w();if(U.toLowerCase()==="all")B=G.map((A)=>A.relPath);else{let A=parseInt(U,10)-1;if(isNaN(A)||A<0||A>=G.length)throw Error("Invalid selection. Aborting.");B=[G[A].relPath]}}else j(`Repository contains ${G.length} skills. Use --path <subdir> to pick one or --all to install all.
|
|
166
169
|
Available skills:
|
|
167
|
-
${
|
|
168
|
-
`)}`),process.exit(2);
|
|
169
|
-
${"
|
|
170
|
-
|
|
171
|
-
|
|
170
|
+
${G.map((U)=>` --path ${U.relPath}`).join(`
|
|
171
|
+
`)}`),process.exit(2);if(B.length>1){if(console.error(`
|
|
172
|
+
${Y.bold("Install settings:")}`),console.error(` Source: ${Q}`),z)console.error(` Provider: All (${z.map((U)=>U.label).join(", ")})`),console.error(` Primary: ${X.label} (${X.name})`),console.error(` Symlinks: ${z.filter((U)=>U.name!==X.name).map((U)=>U.label).join(", ")}`);else console.error(` Provider: ${X.label} (${X.name})`);console.error("")}let _=[];for(let U=0;U<B.length;U++){let A=B[U],I=J(K,A);try{let O=await d($,Q,Z,K,I,B.length===1?$.flags.name:null,V,X,z,B.length>1?{index:U+1,total:B.length}:void 0);W.push(O)}catch(O){if(_.push(A),console.error(Y.red(` x Failed: ${A} -- ${O.message}`)),B.length===1)throw O}}if(B.length>1&&_.length>0){console.error(`
|
|
173
|
+
${Y.yellow(`${_.length} skill(s) failed to install:`)}`);for(let U of _)console.error(` - ${U}`)}}}if(process.removeListener("SIGINT",q),process.removeListener("SIGTERM",q),$.flags.json)console.log(JSON.stringify(W.length===1?W[0]:W,null,2));else if(W.length===1)console.error(Y.green(`
|
|
174
|
+
Done! Installed "${W[0].name}" to ${W[0].path}`));else console.error(`
|
|
175
|
+
${Y.green(`Done! Installed ${W.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 k(K)}}function R1(){console.log(`${Y.bold("Usage:")} asm export [options]
|
|
172
176
|
|
|
173
177
|
Export skill inventory as a portable JSON manifest.
|
|
174
178
|
|
|
175
179
|
${Y.bold("Options:")}
|
|
176
180
|
-s, --scope <s> Filter: global, project, or both (default: both)
|
|
177
181
|
--no-color Disable ANSI colors
|
|
178
|
-
-V, --verbose Show debug output`)}async function
|
|
182
|
+
-V, --verbose Show debug output`)}async function x1($){if($.flags.help){R1();return}let Q=await F(),K=await R(Q,$.flags.scope),q=J0(K);console.log(JSON.stringify(q,null,2))}function w1(){console.log(`${Y.bold("Usage:")} asm init <name> [options]
|
|
179
183
|
|
|
180
184
|
Scaffold a new skill directory with a SKILL.md template.
|
|
181
185
|
|
|
@@ -184,8 +188,8 @@ ${Y.bold("Options:")}
|
|
|
184
188
|
--path <dir> Scaffold in specified directory instead of provider path
|
|
185
189
|
-f, --force Overwrite if skill already exists
|
|
186
190
|
--no-color Disable ANSI colors
|
|
187
|
-
-V, --verbose Show debug output`)}async function
|
|
188
|
-
${Y.bold("Overwrite?")} [y/N] `);let Z=await
|
|
191
|
+
-V, --verbose Show debug output`)}async function y1($){if($.flags.help){w1();return}let Q=$.subcommand;if(!Q)j("Missing required argument: <name>"),console.error('Run "asm init --help" for usage.'),process.exit(2);let K=D(Q),q;if($.flags.path){let{resolve:Z}=await import("path");q=Z($.flags.path)}else{let Z=await F(),{provider:V}=await P(Z,$.flags.provider,!!process.stdin.isTTY),{join:X}=await import("path"),{resolveProviderPath:z}=await import("./chunk-zh7g5bam.js"),J=z(Z.providers.find((W)=>W.name===V.name).global);q=X(J,K)}if(await W0(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}`)}
|
|
192
|
+
${Y.bold("Overwrite?")} [y/N] `);let Z=await w();if(Z.toLowerCase()!=="y"&&Z.toLowerCase()!=="yes")console.error("Aborted."),process.exit(0)}}await U0(K,q),console.error(Y.green(`Done! Created skill "${K}" at ${q}`))}function N1(){console.log(`${Y.bold("Usage:")} asm stats [options]
|
|
189
193
|
|
|
190
194
|
Show aggregate skill metrics dashboard.
|
|
191
195
|
|
|
@@ -193,7 +197,7 @@ ${Y.bold("Options:")}
|
|
|
193
197
|
--json Output as JSON
|
|
194
198
|
-s, --scope <s> Filter: global, project, or both (default: both)
|
|
195
199
|
--no-color Disable ANSI colors
|
|
196
|
-
-V, --verbose Show debug output`)}async function
|
|
200
|
+
-V, --verbose Show debug output`)}async function S1($){if($.flags.help){N1();return}let Q=await F(),K=await R(Q,$.flags.scope);if(K.length===0){console.log("No skills found.");return}let q=t(K),Z=await G0(K,q);if($.flags.json)console.log(y(Z));else console.log(B0(Z))}function b1(){console.log(`${Y.bold("Usage:")} asm link <path> [options]
|
|
197
201
|
|
|
198
202
|
Symlink a local skill directory into an agent's skill folder.
|
|
199
203
|
|
|
@@ -203,5 +207,5 @@ ${Y.bold("Options:")}
|
|
|
203
207
|
-f, --force Overwrite if target already exists
|
|
204
208
|
--json Output as JSON
|
|
205
209
|
--no-color Disable ANSI colors
|
|
206
|
-
-V, --verbose Show debug output`)}async function
|
|
207
|
-
${Y.bold("Overwrite?")} [y/N] `);let
|
|
210
|
+
-V, --verbose Show debug output`)}async function D1($){if($.flags.help){b1();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 j0(Z),X=$.flags.name?D($.flags.name):q(Z),z=await F(),{provider:J}=await P(z,$.flags.provider,!!process.stdin.isTTY),{resolveProviderPath:W}=await import("./chunk-zh7g5bam.js"),M=W(z.providers.find((_)=>_.name===J.name).global),{join:G}=await import("path"),B=G(M,X);if(!$.flags.force){let _=!1;try{let{access:U}=await import("fs/promises");await U(B),_=!0}catch{}if(_){if(!process.stdin.isTTY)j(`Target already exists: ${B}. Use --force to overwrite.`),process.exit(2);process.stderr.write(`${Y.yellow(`Target already exists: ${B}`)}
|
|
211
|
+
${Y.bold("Overwrite?")} [y/N] `);let U=await w();if(U.toLowerCase()!=="y"&&U.toLowerCase()!=="yes")console.error("Aborted."),process.exit(0);await h(Z,M,X,!0)}else await h(Z,M,X,!1)}else await h(Z,M,X,!0);if($.flags.json)console.log(y({success:!0,name:X,symlinkPath:B,targetPath:Z}));else console.error(Y.green(`Done! Linked "${X}" -> ${Z}`)),console.error(` Symlink: ${B}`),console.error(Y.dim(` If you move or delete the source, run "asm uninstall ${X}" to clean up.`))}async function w0($){let Q=U1($);if(Q.flags.noColor)globalThis.__CLI_NO_COLOR=!0;if(Q.flags.verbose)O0(!0);if(Q.flags.version){console.log(`asm ${l}`);return}if(!Q.command&&Q.flags.help){W1();return}if(!Q.command)return;switch(Q.command){case"list":await F1(Q);break;case"search":await A1(Q);break;case"inspect":await E1(Q);break;case"uninstall":await L1(Q);break;case"audit":await T1(Q);break;case"install":await C1(Q);break;case"config":await H1(Q);break;case"export":await x1(Q);break;case"init":await y1(Q);break;case"stats":await S1(Q);break;case"link":await D1(Q);break;default:j(`Unknown command: "${Q.command}"`),console.error('Run "asm --help" for usage.'),process.exit(2)}}function y0($){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(y0(process.argv))await w0(process.argv);else await import("./chunk-9pkjdwkv.js");
|