@tech-leads-club/agent-skills 0.1.0-beta.3 → 0.1.0
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/LICENSE +21 -0
- package/index.js +26 -0
- package/index.js.map +7 -0
- package/package.json +9 -10
- package/CHANGELOG.md +0 -146
- package/dist/CHANGELOG.md +0 -146
- package/dist/index.js +0 -26
- package/dist/index.js.map +0 -7
- package/dist/package-lock.json +0 -2561
- package/dist/package.json +0 -48
- package/jest.config.ts +0 -15
- package/project.json +0 -58
- package/src/__tests__/agents.spec.ts +0 -74
- package/src/__tests__/categories.spec.ts +0 -224
- package/src/__tests__/global-path.spec.ts +0 -93
- package/src/__tests__/installer.spec.ts +0 -100
- package/src/__tests__/skills.spec.ts +0 -68
- package/src/__tests__/update-check.spec.ts +0 -45
- package/src/agents.ts +0 -162
- package/src/categories.ts +0 -121
- package/src/global-path.ts +0 -31
- package/src/index.ts +0 -86
- package/src/installer.ts +0 -287
- package/src/lockfile.ts +0 -79
- package/src/project-root.ts +0 -19
- package/src/prompts/install.ts +0 -351
- package/src/prompts/list.ts +0 -39
- package/src/prompts/remove.ts +0 -68
- package/src/prompts/results.ts +0 -77
- package/src/prompts/utils.ts +0 -36
- package/src/skills.ts +0 -58
- package/src/types.ts +0 -21
- package/src/ui/formatting.ts +0 -3
- package/src/ui/input.ts +0 -139
- package/src/ui/screen.ts +0 -19
- package/src/ui/styles.ts +0 -35
- package/src/update-check.ts +0 -25
- package/tsconfig.json +0 -16
- package/tsconfig.spec.json +0 -18
- /package/{dist/README.md → README.md} +0 -0
- /package/{dist/skills → skills}/categories.json +0 -0
- /package/{dist/skills → skills}/categories.schema.json +0 -0
- /package/{dist/skills → skills}/cursor-skill-creator/SKILL.md +0 -0
- /package/{dist/skills → skills}/cursor-subagent-creator/SKILL.md +0 -0
- /package/{dist/skills → skills}/skill-creator/SKILL.md +0 -0
- /package/{dist/skills → skills}/spec-driven-dev/SKILL.md +0 -0
- /package/{dist/skills → skills}/spec-driven-dev/references/design.md +0 -0
- /package/{dist/skills → skills}/spec-driven-dev/references/implement.md +0 -0
- /package/{dist/skills → skills}/spec-driven-dev/references/specify.md +0 -0
- /package/{dist/skills → skills}/spec-driven-dev/references/tasks.md +0 -0
- /package/{dist/skills → skills}/spec-driven-dev/references/validate.md +0 -0
- /package/{dist/skills → skills}/subagent-creator/SKILL.md +0 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Tech Leads Club
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import{Command as Qt}from"commander";var de={name:"@tech-leads-club/agent-skills",version:"0.1.0",description:"CLI to install and manage skills for AI coding agents",author:"Tech Leads Club",license:"MIT",repository:{type:"git",url:"git+https://github.com/tech-leads-club/agent-skills.git"},type:"module",bin:{"tlc-skills":"./index.js"},engines:{node:">=22"},publishConfig:{access:"public"},scripts:{build:"nx build",dev:"tsx src/index.ts",test:"NODE_OPTIONS='--experimental-vm-modules' jest",typecheck:"tsc --noEmit"},keywords:["ai","agents","skills","cli"],dependencies:{"@clack/core":"^0.5.0","@clack/prompts":"^0.11.0",chalk:"^5.6.2",commander:"^14.0.2",figlet:"^1.10.0","gradient-string":"^3.0.0","package-json":"^10.0.1",picocolors:"^1.1.1"},devDependencies:{"@types/figlet":"^1.7.0","@types/node":"^22",tsx:"^4.21.0",typescript:"^5.9.3"}};import{cp as Pe,lstat as kt,mkdir as le,readdir as Le,readlink as bt,rm as E,symlink as ht}from"node:fs/promises";import{homedir as St,platform as $t}from"node:os";import{join as A,normalize as Te,relative as At,resolve as z,sep as wt}from"node:path";import{existsSync as m}from"node:fs";import{homedir as lt}from"node:os";import{join as g}from"node:path";import{existsSync as fe}from"node:fs";import{dirname as tt,join as ye,parse as ot,resolve as nt}from"node:path";function D(e=process.cwd()){let t=nt(e),o=ot(t).root;for(;t!==o;){if((fe(ye(t,"package.json"))||fe(ye(t,".git")))&&!t.endsWith("packages/cli"))return t;t=tt(t)}return e}var d=lt(),S=D(),B={cursor:{name:"cursor",displayName:"Cursor",description:"AI-first code editor built on VS Code",skillsDir:".cursor/skills",globalSkillsDir:g(d,".cursor/skills"),detectInstalled:()=>m(g(d,".cursor"))||m(g(S,".cursor"))},"claude-code":{name:"claude-code",displayName:"Claude Code",description:"Anthropic's agentic coding tool",skillsDir:".claude/skills",globalSkillsDir:g(d,".claude/skills"),detectInstalled:()=>m(g(d,".claude"))||m(g(S,".claude"))},"github-copilot":{name:"github-copilot",displayName:"GitHub Copilot",description:"AI pair programmer by GitHub/Microsoft",skillsDir:".github/skills",globalSkillsDir:g(d,".copilot/skills"),detectInstalled:()=>m(g(d,".copilot"))||m(g(S,".github"))},windsurf:{name:"windsurf",displayName:"Windsurf",description:"AI IDE with Cascade flow (Codeium)",skillsDir:".windsurf/skills",globalSkillsDir:g(d,".codeium/windsurf/skills"),detectInstalled:()=>m(g(d,".codeium/windsurf"))||m(g(S,".windsurf"))},cline:{name:"cline",displayName:"Cline",description:"Autonomous AI coding agent for VS Code",skillsDir:".cline/skills",globalSkillsDir:g(d,".cline/skills"),detectInstalled:()=>m(g(d,".cline"))||m(g(S,".cline"))},aider:{name:"aider",displayName:"Aider",description:"AI pair programming in terminal",skillsDir:".aider/skills",globalSkillsDir:g(d,".aider/skills"),detectInstalled:()=>m(g(d,".aider"))||m(g(S,".aider"))},codex:{name:"codex",displayName:"OpenAI Codex",description:"OpenAI's coding agent",skillsDir:".codex/skills",globalSkillsDir:g(d,".codex/skills"),detectInstalled:()=>m(g(d,".codex"))||m(g(S,".codex"))},gemini:{name:"gemini",displayName:"Gemini CLI",description:"Google's AI coding assistant",skillsDir:".gemini/skills",globalSkillsDir:g(d,".gemini/skills"),detectInstalled:()=>m(g(d,".gemini"))||m(g(S,".gemini"))},antigravity:{name:"antigravity",displayName:"Antigravity",description:"Google's agentic coding (VS Code)",skillsDir:".agent/skills",globalSkillsDir:g(d,".agent/skills"),detectInstalled:()=>m(g(d,".gemini/antigravity"))||m(g(S,".agent"))},roo:{name:"roo",displayName:"Roo Code",description:"AI coding assistant for VS Code",skillsDir:".roo/skills",globalSkillsDir:g(d,".roo/skills"),detectInstalled:()=>m(g(d,".roo"))||m(g(S,".roo"))},kilocode:{name:"kilocode",displayName:"Kilo Code",description:"AI coding agent with auto-launch",skillsDir:".kilocode/skills",globalSkillsDir:g(d,".kilocode/skills"),detectInstalled:()=>m(g(d,".kilocode"))||m(g(S,".kilocode"))},"amazon-q":{name:"amazon-q",displayName:"Amazon Q",description:"AWS AI coding assistant",skillsDir:".amazonq/skills",globalSkillsDir:g(d,".amazonq/skills"),detectInstalled:()=>m(g(d,".amazonq"))||m(g(S,".amazonq"))},augment:{name:"augment",displayName:"Augment",description:"AI code assistant with context engine",skillsDir:".augment/skills",globalSkillsDir:g(d,".augment/skills"),detectInstalled:()=>m(g(d,".augment"))||m(g(S,".augment"))},tabnine:{name:"tabnine",displayName:"Tabnine",description:"AI code completions with privacy focus",skillsDir:".tabnine/skills",globalSkillsDir:g(d,".tabnine/skills"),detectInstalled:()=>m(g(d,".tabnine"))||m(g(S,".tabnine"))},opencode:{name:"opencode",displayName:"OpenCode",description:"Open-source AI coding terminal",skillsDir:".opencode/skills",globalSkillsDir:g(d,".config/opencode/skills"),detectInstalled:()=>m(g(d,".config/opencode"))||m(g(S,".opencode"))||m(g(S,".config/opencode"))},sourcegraph:{name:"sourcegraph",displayName:"Sourcegraph Cody",description:"AI assistant with codebase context",skillsDir:".sourcegraph/skills",globalSkillsDir:g(d,".sourcegraph/skills"),detectInstalled:()=>m(g(d,".sourcegraph"))||m(g(S,".sourcegraph"))}};function ke(){return Object.entries(B).filter(([,e])=>e.detectInstalled()).map(([e])=>e)}function P(e){return B[e]}function L(){return Object.keys(B).sort((e,t)=>B[e].displayName.localeCompare(B[t].displayName))}import{execSync as it}from"node:child_process";import{existsSync as be}from"node:fs";import{join as he}from"node:path";var st="@tech-leads-club/agent-skills";function rt(){try{return it("npm root -g",{encoding:"utf-8"}).trim()}catch{return null}}function Se(){let e=rt();if(!e)return null;let t=he(e,st,"skills");return be(t)?t:null}function ee(){return Se()!==null}function $e(e){let t=Se();if(!t)return null;let o=he(t,e);return be(o)?o:null}import{mkdir as at,readFile as ct,writeFile as gt}from"node:fs/promises";import{homedir as ut}from"node:os";import{dirname as mt,join as pt}from"node:path";var dt=".agents",ft=".skill-lock.json",yt=1;function we(){return pt(ut(),dt,ft)}function Ae(){return{version:yt,skills:{}}}async function Ie(){let e=we();try{let t=await ct(e,"utf-8"),o=JSON.parse(t);return typeof o.version!="number"||!o.skills?Ae():o}catch{return Ae()}}async function ve(e){let t=we();await at(mt(t),{recursive:!0}),await gt(t,JSON.stringify(e,null,2),"utf-8")}async function Ce(e,t="local"){let o=await Ie(),n=new Date().toISOString(),l=o.skills[e];o.skills[e]={name:e,source:t,installedAt:l?.installedAt??n,updatedAt:n},await ve(o)}async function xe(e){let t=await Ie();return e in t.skills?(delete t.skills[e],await ve(t),!0):!1}var te=A(".agents","skills"),It=new Set(["README.md","metadata.json","SKILL.md"]);function ie(e){let t=e.replace(/[/\\]/g,"");return t=t.replace(/[\0:]/g,""),t=t.replace(/^[.\s]+|[.\s]+$/g,""),t=t.replace(/^\.+/,""),(!t||t.length===0)&&(t="unnamed-skill"),t.substring(0,255)}function oe(e,t){let o=Te(z(e)),n=Te(z(t));return n.startsWith(o+wt)||n===o}async function De(e,t){try{try{if((await kt(t)).isSymbolicLink()){let r=await bt(t);if(z(r)===z(e))return!0;await E(t)}else await E(t,{recursive:!0})}catch(i){if(i?.code==="ELOOP")try{await E(t,{force:!0})}catch{}}let o=A(t,"..");await le(o,{recursive:!0});let n=At(o,e),l=$t()==="win32"?"junction":void 0;return await ht(n,t,l),!0}catch{return!1}}async function ne(e,t){await le(t,{recursive:!0});let o=await Le(e,{withFileTypes:!0});for(let n of o){if(It.has(n.name)||n.name.startsWith("_"))continue;let l=A(e,n.name),i=A(t,n.name);n.isDirectory()?await ne(l,i):await Pe(l,i)}}async function se(e,t){let o=[],n=D();for(let l of t.agents){let i=P(l),r=t.global?i.globalSkillsDir:A(n,i.skillsDir);for(let a of e){let c=await vt(a,l,r,t.method,n,t.global);o.push(c),c.success&&await Ce(a.name,"local")}}return o}async function vt(e,t,o,n,l,i){let r=P(t),a=ie(e.name),c=A(o,a);if(!oe(o,c)&&!i&&!oe(l,c)&&!i)return{agent:r.displayName,skill:e.name,path:c,method:n,success:!1,error:"Security: Invalid skill destination path"};try{if(n==="symlink"){let f=$e(e.name);if(f&&await De(f,c))return{agent:r.displayName,skill:e.name,path:c,method:n,success:!0,usedGlobalSymlink:!0};let u=A(l,te,a);if(await le(u,{recursive:!0}),await Pe(e.path,u,{recursive:!0}),!await De(u,c)){try{await E(c,{recursive:!0,force:!0})}catch{}return await ne(e.path,c),{agent:r.displayName,skill:e.name,path:c,method:"copy",success:!0,symlinkFailed:!0}}return{agent:r.displayName,skill:e.name,path:c,method:n,success:!0,usedGlobalSymlink:!1}}else return await ne(e.path,c),{agent:r.displayName,skill:e.name,path:c,method:n,success:!0}}catch(f){return{agent:r.displayName,skill:e.name,path:c,method:n,success:!1,error:f instanceof Error?f.message:String(f)}}}async function Ee(e,t){let o=P(e),n=t?o.globalSkillsDir:A(D(),o.skillsDir);try{return(await Le(n,{withFileTypes:!0})).filter(i=>i.isDirectory()||i.isSymbolicLink()).map(i=>i.name)}catch{return[]}}function Ct(e,t={}){let o=ie(e),n=t.global?St():D(),l=A(n,te,o);if(!oe(A(n,te),l))throw new Error("Invalid skill name: potential path traversal detected");return l}async function M(e,t,o={}){let n=[],l=ie(e),i=D(),r=Ct(e,o);try{await E(r,{recursive:!0,force:!0})}catch{}for(let a of t){let c=P(a),f=o.global?c.globalSkillsDir:A(i,c.skillsDir),u=A(f,l);try{await E(u,{recursive:!0,force:!0}),n.push({agent:c.displayName,success:!0})}catch($){n.push({agent:c.displayName,success:!1,error:$ instanceof Error?$.message:String($)})}}return await xe(e),n}import b from"picocolors";import{existsSync as ge,readFileSync as xt,writeFileSync as No}from"node:fs";import{dirname as Tt,join as _e}from"node:path";import{fileURLToPath as Dt}from"node:url";var re="skills/categories.json",ae="skills",V="uncategorized",ce={id:V,name:"Uncategorized",description:"Skills without a specific category",priority:999};var Pt=Dt(import.meta.url),Ne=Tt(Pt);function Lt(){let e=_e(Ne,"..","..","..",re);if(ge(e))return e;let t=_e(Ne,"..",re);return ge(t)?t:e}function Oe(){let e=Lt();if(!ge(e))return{categories:[],skills:{}};try{let t=xt(e,"utf-8");return JSON.parse(t)}catch{return{categories:[],skills:{}}}}function Re(e){return Oe().skills[e]??V}function W(e){let t=Oe(),o=new Map,n=[...t.categories].sort((l,i)=>(l.priority??100)-(i.priority??100));for(let l of n)o.set(l,[]);o.set(ce,[]);for(let l of e){let i=l.category??t.skills[l.name]??V,r=n.find(c=>c.id===i)??ce,a=o.get(r)??[];a.push(l),o.set(r,a)}for(let[l,i]of o)i.length===0&&o.delete(l);return o}import{existsSync as K,readdirSync as Et,readFileSync as _t}from"node:fs";import{dirname as Nt,join as U}from"node:path";import{fileURLToPath as Ot}from"node:url";var Rt=Ot(import.meta.url),Be=Nt(Rt);function Bt(){let e=U(Be,"..","..","..",ae);if(K(e))return e;let t=U(Be,"..",ae);if(K(t))return t;throw new Error(`Skills directory not found. Checked: ${e}, ${t}`)}function x(){let e=Bt(),t=[];if(!K(e))return t;let o=Et(e,{withFileTypes:!0});for(let n of o){if(!n.isDirectory())continue;let l=U(e,n.name,"SKILL.md");if(!K(l))continue;let i=_t(l,"utf-8"),{name:r,description:a}=jt(i),c=r||n.name;t.push({name:c,description:a||"No description",path:U(e,n.name),category:Re(c)})}return t}function jt(e){let t=e.match(/^---\n([\s\S]*?)\n---/);if(!t)return{};let o=t[1],n=o.match(/^name:\s*(.+)$/m),l=o.match(/^description:\s*(.+)$/m);return{name:n?.[1]?.trim(),description:l?.[1]?.trim()}}function je(e){return x().find(o=>o.name===e)}function Y(e,t){return e.length<=t?e:e.slice(0,t-3)+"..."}import{ConfirmPrompt as Ft,MultiSelectPrompt as zt,SelectPrompt as Mt}from"@clack/core";import s from"picocolors";import Gt from"gradient-string";import j from"picocolors";var Ge=Gt([{color:"#1e3a8a",pos:0},{color:"#3b82f6",pos:.3},{color:"#0ea5e9",pos:.5},{color:"#06b6d4",pos:.7},{color:"#22d3ee",pos:1}]),k="\u2502",G="\u2514",Fe="\u25CF",ze="\u25CB",Me="\u25FC",Ve="\u25FB",T=j.blue("\u25C6");function y(e=""){console.log(e?`${j.blue(k)} ${e}`:j.blue(k))}function v(e=""){console.log(`${j.blue(G)} ${e}`)}function C(){v(j.gray("Cancelled"))}function I(e){return typeof e=="symbol"}async function q(e,t,o,n=!0){let l=(a,c)=>{let f=c?s.blue(Fe):s.gray(ze),u=c?s.blue(a.label):s.white(a.label),$=c&&a.hint?s.dim(s.gray(` - ${a.hint}`)):"";return`${f} ${u}${$}`},r=await new Mt({options:t,initialValue:o,render(){let a=`${s.blue(k)}
|
|
2
|
+
${T} ${s.white(s.bold(e))}
|
|
3
|
+
`,c=n?"esc = back, ":"";switch(this.state){case"submit":return`${a}${s.blue(k)} ${s.blue(this.options.find(f=>f.value===this.value)?.label)}
|
|
4
|
+
${s.blue(k)}`;case"cancel":return`${a}${s.blue(k)} ${s.strikethrough(s.gray("back"))}
|
|
5
|
+
${s.blue(k)}`;default:return`${a}${this.options.map((f,u)=>`${s.blue(k)} ${l(f,u===this.cursor)}`).join(`
|
|
6
|
+
`)}
|
|
7
|
+
${s.blue(k)}
|
|
8
|
+
${s.blue(G)} ${s.dim(s.gray(`(\u2191\u2193 navigate, ${c}enter confirm)`))}`}}}).prompt();return typeof r=="symbol"&&n?Symbol.for("back"):r}async function _(e,t,o=[],n=!0){let l=(a,c)=>{let f=c==="selected"||c==="selected-active",u=c==="active"||c==="selected-active",$=f?s.blue(Me):s.gray(Ve),h=u?s.blue(a.label):s.white(a.label),R=u&&a.hint?s.dim(s.gray(` (${a.hint})`)):"";return`${$} ${h}${R}`},r=await new zt({options:t,initialValues:o,render(){let a=`${s.blue(k)}
|
|
9
|
+
${T} ${s.white(s.bold(e))}
|
|
10
|
+
`,c=n?"esc = back, ":"";switch(this.state){case"submit":return`${a}${s.blue(k)} ${this.options.filter(f=>this.value.includes(f.value)).map(f=>s.blue(String(f.value))).join(s.gray(", "))}
|
|
11
|
+
${s.blue(k)}`;case"cancel":return`${a}${s.blue(k)} ${s.strikethrough(s.gray("back"))}
|
|
12
|
+
${s.blue(k)}`;default:return`${a}${this.options.map((f,u)=>{let $=this.value.includes(f.value),h=u===this.cursor,R=$&&h?"selected-active":$?"selected":h?"active":"inactive";return`${s.blue(k)} ${l(f,R)}`}).join(`
|
|
13
|
+
`)}
|
|
14
|
+
${s.blue(k)}
|
|
15
|
+
${s.blue(G)} ${s.dim(s.gray(`(\u2191\u2193 navigate, space select, ${c}enter confirm)`))}`}}}).prompt();return typeof r=="symbol"&&n?Symbol.for("back"):r}async function H(e,t=!1){return new Ft({active:"Yes",inactive:"No",initialValue:t,render(){let n=`${s.blue(k)}
|
|
16
|
+
${T} ${s.white(s.bold(e))}
|
|
17
|
+
`;switch(this.state){case"submit":return`${n}${s.blue(k)} ${s.blue(this.value?"Yes":"No")}
|
|
18
|
+
${s.blue(k)}`;case"cancel":return`${n}${s.blue(k)} ${s.strikethrough(s.gray("cancelled"))}
|
|
19
|
+
${s.blue(k)}`;default:return`${n}${s.blue(k)} ${this.value?`${s.blue("\u25CF Yes")} ${s.dim(s.gray("/"))} ${s.gray("\u25CB")} ${s.white("No")}`:`${s.gray("\u25CB")} ${s.white("Yes")} ${s.dim(s.gray("/"))} ${s.blue("\u25CF No")}`}
|
|
20
|
+
${s.blue(k)}
|
|
21
|
+
${s.blue(G)} ${s.dim(s.gray("(\u2190\u2192 to change, enter to confirm)"))}`}}}).prompt()}import Vt from"figlet";import N from"picocolors";function Wt(){let e=Vt.textSync("Tech Leads Club",{font:"Larry 3D",horizontalLayout:"default"});return`
|
|
22
|
+
${Ge.multiline(e)}
|
|
23
|
+
${N.white(N.bold("Tech Leads Club"))} ${N.blue("\u203A")} ${N.bold(N.blue("Agent Skills"))}
|
|
24
|
+
${N.white("Curated skills to power up your AI coding agents")}
|
|
25
|
+
`}function O(){console.clear(),console.log(Wt()),y()}import{createRequire as Kt}from"node:module";import Ut from"package-json";var Yt="@tech-leads-club/agent-skills";async function We(e){try{let t=await Ut(Yt);return t.version!==e?t.version:null}catch{return null}}function Ke(){try{return Kt(import.meta.url)("../package.json").version||"0.0.0"}catch{return"0.0.0"}}import p from"picocolors";function Ue(e){y(),y(p.blue(p.bold("\u{1F4CB} Installation Summary"))),y(),y(`${p.blue(k)} ${p.white(p.bold("Skills:"))} ${p.gray(e.skills.join(", "))}`),y(`${p.blue(k)} ${p.white(p.bold("Agents:"))} ${p.gray(e.agents.join(", "))}`),y(`${p.blue(k)} ${p.white(p.bold("Method:"))} ${p.cyan(e.method)}`),y()}function ue(e){let t=e.filter(i=>i.success&&!i.error),o=e.filter(i=>i.success&&i.error==="Already exists"),n=e.filter(i=>!i.success);console.log();for(let i of t)console.log(`${T} ${p.white(p.bold(i.skill))} ${p.gray("\u2192")} ${p.white(i.agent)}`);for(let i of o)console.log(`${p.gray(T)} ${i.skill} \u2192 ${i.agent} ${p.gray("(exists)")}`);for(let i of n)console.log(`${p.red("\u2717")} ${i.skill} \u2192 ${i.agent}: ${i.error}`);let l=new Set(e.map(i=>i.agent)).size;console.log(),v(`${p.blue("\u2713")} ${p.white(p.bold(`${t.length} skill(s)`))} ${p.white("installed to")} ${p.white(p.bold(`${l} agent(s)`))}`)}function J(e,t){let o=t.filter(l=>l.success),n=t.filter(l=>!l.success);o.length>0&&console.log(`${T} ${p.white(p.bold(e))} ${p.gray("removed from")} ${o.map(l=>l.agent).join(", ")}`);for(let l of n)console.log(`${p.red("\u2717")} ${e} \u2192 ${l.agent}: ${l.error}`);o.length>0&&n.length===0&&v(`${p.blue("\u2713")} ${p.white("Skill removed successfully")}`)}import qt from"picocolors";function Q(e,t=[]){return e.map(o=>{let n=P(o),l=t.includes(o);return{value:o,label:l?`${n.displayName} ${qt.green("\u25CF detected")}`:n.displayName,hint:Y(n.description,50)}})}async function X(e,t){let o=new Set;for(let n of e)(await Ee(n,t)).forEach(i=>o.add(i));return o}async function Z(e){let[t,o]=await Promise.all([X(e,!0),X(e,!1)]);return new Set([...t,...o])}var me="__all_skills__",pe="__all__";async function Ye(){O(),await Ht();let e=x();if(e.length===0)return v(b.red("No skills available")),null;let t=ke(),o=L(),n=t.length>0?t:o,l=await Z(n),i={category:pe,skills:[],agents:t.length>0?t:["cursor","claude-code"],method:"symlink",global:!1},r=1,a=4;for(;r<=a;){let c=b.gray(`[${r}/${a}]`),f=r>1;switch(r){case 1:{let u=await Jt({allSkills:e,stepIndicator:c,currentCategory:i.category});if(u===null)return null;i.category=u,r++;break}case 2:{let u=await qe({state:i,allSkills:e,installedSkills:l,stepIndicator:c,allowBack:f});if(u===Symbol.for("back")){r--;break}if(u===null)return null;i.skills=u,r++;break}case 3:{let u=await He({allAgents:o,installedAgents:t,currentAgents:i.agents,stepIndicator:c,allowBack:f});if(u===Symbol.for("back")){r--;break}if(u===null)return null;i.agents=u,r++;break}case 4:{let u=await Je({state:i,stepIndicator:c,allowBack:f});if(u===Symbol.for("back")){i.method="symlink",r--;break}if(u===null)return null;if(u===!1){r=1;break}return u}}}return null}async function Ht(){let e=Ke(),t=await We(e);t?(y(`${b.yellow("\u26A0")} ${b.yellow("Update available:")} ${b.gray(e)} \u2192 ${b.green(t)}`),y(` ${b.gray("Run: npm update -g @tech-leads-club/agent-skills")}`),y()):ee()||(y(`${b.yellow("\u26A0")} ${b.yellow("Not installed globally")}`),y(` ${b.yellow("Skills won't auto-update. Install globally:")}`),y(` ${b.yellow("npm i -g @tech-leads-club/agent-skills")}`),y())}async function Jt({allSkills:e,stepIndicator:t,currentCategory:o}){let n=W(e),l=Array.from(n.keys()),i=[{value:pe,label:`${b.cyan("\u25C9")} All skills`,hint:`${e.length} available`},...l.map(a=>{let c=n.get(a)?.length??0;return{value:a.id,label:`${b.cyan("\u25B8")} ${a.name}`,hint:`${c} skill(s)`}})],r=await q(`${t} Browse by category`,i,o,!1);return I(r)?(C(),null):r}async function qe({state:e,allSkills:t,installedSkills:o,stepIndicator:n,allowBack:l}){let r=e.category===pe?t:t.filter(h=>h.category===e.category),a=[{value:me,label:`${b.cyan("\u25C9")} ${b.bold("All Skills")}`,hint:`select all ${r.length} skills`},...r.map(h=>{let R=o.has(h.name);return{value:h.name,label:R?`${h.name} ${b.green("\u25CF installed")}`:h.name,hint:Y(h.description,150)}})],c=e.skills.length>0?e.skills:[],f=await _(`${n} Select skills to install`,a,c,l);if(f===Symbol.for("back"))return Symbol.for("back");if(I(f))return C(),null;let u=f,$=u.includes(me)?r.map(h=>h.name):u.filter(h=>h!==me);return $.length===0&&y(b.yellow("\u26A0 Please select at least one skill")),$.length===0?qe({state:e,allSkills:t,installedSkills:o,stepIndicator:n,allowBack:l}):$}async function He({allAgents:e,installedAgents:t,currentAgents:o,stepIndicator:n,allowBack:l}){let i=Q(e,t),r=await _(`${n} Where to install?`,i,o,l);if(r===Symbol.for("back"))return Symbol.for("back");if(I(r))return C(),null;let a=r;return a.length===0?(y(b.yellow("\u26A0 Please select at least one agent")),He({allAgents:e,installedAgents:t,currentAgents:o,stepIndicator:n,allowBack:l})):a}async function Je({state:e,stepIndicator:t,allowBack:o}){let n=[{value:"symlink",label:"Symlink",hint:"shared source (recommended)"},{value:"copy",label:"Copy",hint:"independent copies"}],l=await q(`${t} Installation method`,n,e.method,o);if(l===Symbol.for("back"))return Symbol.for("back");if(I(l))return C(),null;e.method=l,Ue(e);let i=await Xt(e);if(i===Symbol.for("back"))return Je({state:e,stepIndicator:t,allowBack:o});if(i===null)return null;e.global=i==="global";let r=await H(b.white("Proceed with installation?"),!0);return I(r)?(C(),null):r?(y(),{agents:e.agents,skills:e.skills,method:e.method,global:e.global}):!1}async function Xt(e){let o=await q("Installation scope",[{value:"local",label:"Local",hint:"this project only"},{value:"global",label:"Global",hint:"user home directory"}],e.global?"global":"local",!0);return o===Symbol.for("back")?Symbol.for("back"):I(o)?null:o}import w from"picocolors";async function Xe(){O();let e=x();if(e.length===0){y(w.yellow("No skills found"));return}y(w.bold(`${e.length} skills available:`)),y();let t=L(),o=await Z(t),n=W(e);for(let[l,i]of n){y(`${w.cyan("\u25B8")} ${w.bold(w.cyan(l.name))}`);for(let r of i){let a=o.has(r.name)?` ${w.green("\u25CF installed")}`:"";y(` ${w.blue("\u25C6")} ${w.bold(r.name)}${a}`),console.log(`${w.blue(k)} ${w.dim(w.gray(r.description))}`)}y()}v(w.gray('Run "npx @tech-leads-club/agent-skills" to install'))}import Qe from"picocolors";async function Ze(e){O();let t=L(),o=await X(t,e);if(o.size===0){y(Qe.yellow("No skills installed")),v();return}let n=Array.from(o),l=await _(`Which skills do you want to remove? ${Qe.gray(`(${n.length} installed)`)}`,n.map(a=>({value:a,label:a})),[],!1);if(I(l)||l.length===0){C();return}let i=await _("Remove from which agents?",Q(t).map(a=>({...a,hint:void 0})),t,!0);if(I(i)){C();return}let r=await H(`Remove ${l.length} skill(s) from ${i.length} agent(s)?`,!1);if(I(r)||!r){C();return}y();for(let a of l){let c=await M(a,i,{global:e});J(a,c)}}var F=new Qt;F.name("tlc-agent-skills").description("Install TLC Agent Skills to your AI coding agents").version(de.version);F.command("install",{isDefault:!0}).description("Interactive skill installation (default)").option("-g, --global","Install globally to user home",!1).option("-s, --skill <name>","Install a specific skill").option("-a, --agent <agents...>","Target specific agents").option("--copy","Use copy instead of symlink",!1).action(async e=>{if(e.skill||e.agent)await Zt(e);else{let t=await Ye();if(!t)return;let o=x().filter(l=>t.skills.includes(l.name)),n=await se(o,t);ue(n)}});F.command("list").alias("ls").description("List available skills").action(async()=>{await Xe()});F.command("remove").alias("rm").description("Remove installed skills").option("-g, --global","Remove from global installation",!1).option("-s, --skill <name>","Remove a specific skill").option("-a, --agent <agents...>","Target specific agents").action(async e=>{if(e.skill){let t=e.agent||["antigravity","claude-code","cursor"],o=await M(e.skill,t,{global:e.global});J(e.skill,o)}else await Ze(e.global)});async function Zt(e){let t=x(),o=t;if(e.skill){let r=je(e.skill);r||(console.error(`Skill "${e.skill}" not found.`),console.log("Available skills:",t.map(a=>a.name).join(", ")),process.exit(1)),o=[r]}let n=e.agent||["antigravity","claude-code","cursor"],l=e.copy?"copy":"symlink",i=await se(o,{agents:n,skills:o.map(r=>r.name),method:l,global:e.global});ue(i)}F.parse();
|
|
26
|
+
//# sourceMappingURL=index.js.map
|
package/index.js.map
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/index.ts", "../package.json", "../src/installer.ts", "../src/agents.ts", "../src/project-root.ts", "../src/global-path.ts", "../src/lockfile.ts", "../src/prompts/install.ts", "../src/categories.ts", "../../../libs/core/src/lib/constants.ts", "../src/skills.ts", "../src/ui/formatting.ts", "../src/ui/input.ts", "../src/ui/styles.ts", "../src/ui/screen.ts", "../src/update-check.ts", "../src/prompts/results.ts", "../src/prompts/utils.ts", "../src/prompts/list.ts", "../src/prompts/remove.ts"],
|
|
4
|
+
"sourcesContent": ["import { Command } from 'commander'\n\nimport pkg from '../package.json' with { type: 'json' }\nimport { installSkills, removeSkill } from './installer'\nimport { runInteractiveInstall } from './prompts/install'\nimport { showAvailableSkills } from './prompts/list'\nimport { runInteractiveRemove } from './prompts/remove'\nimport { showInstallResults, showRemoveResults } from './prompts/results'\nimport { discoverSkills, getSkillByName } from './skills'\nimport type { AgentType } from './types'\n\nconst program = new Command()\n\nprogram.name('tlc-agent-skills').description('Install TLC Agent Skills to your AI coding agents').version(pkg.version)\n\nprogram\n .command('install', { isDefault: true })\n .description('Interactive skill installation (default)')\n .option('-g, --global', 'Install globally to user home', false)\n .option('-s, --skill <name>', 'Install a specific skill')\n .option('-a, --agent <agents...>', 'Target specific agents')\n .option('--copy', 'Use copy instead of symlink', false)\n .action(async (options) => {\n if (options.skill || options.agent) {\n await runNonInteractive(options)\n } else {\n const installOptions = await runInteractiveInstall()\n if (!installOptions) return\n const skills = discoverSkills().filter((s) => installOptions.skills.includes(s.name))\n const results = await installSkills(skills, installOptions)\n showInstallResults(results)\n }\n })\n\nprogram\n .command('list')\n .alias('ls')\n .description('List available skills')\n .action(async () => {\n await showAvailableSkills()\n })\n\nprogram\n .command('remove')\n .alias('rm')\n .description('Remove installed skills')\n .option('-g, --global', 'Remove from global installation', false)\n .option('-s, --skill <name>', 'Remove a specific skill')\n .option('-a, --agent <agents...>', 'Target specific agents')\n .action(async (options) => {\n if (options.skill) {\n const agents = (options.agent || ['antigravity', 'claude-code', 'cursor']) as AgentType[]\n const results = await removeSkill(options.skill, agents, { global: options.global })\n showRemoveResults(options.skill, results)\n } else {\n await runInteractiveRemove(options.global)\n }\n })\n\nasync function runNonInteractive(options: { skill?: string; agent?: string[]; global: boolean; copy: boolean }) {\n const allSkills = discoverSkills()\n let skills = allSkills\n\n if (options.skill) {\n const skill = getSkillByName(options.skill)\n if (!skill) {\n console.error(`Skill \"${options.skill}\" not found.`)\n console.log('Available skills:', allSkills.map((s) => s.name).join(', '))\n process.exit(1)\n }\n skills = [skill]\n }\n\n const agents = (options.agent || ['antigravity', 'claude-code', 'cursor']) as AgentType[]\n const method = options.copy ? 'copy' : 'symlink'\n\n const results = await installSkills(skills, {\n agents,\n skills: skills.map((s) => s.name),\n method,\n global: options.global,\n })\n\n showInstallResults(results)\n}\n\nprogram.parse()\n", "{\n \"name\": \"@tech-leads-club/agent-skills\",\n \"version\": \"0.1.0\",\n \"description\": \"CLI to install and manage skills for AI coding agents\",\n \"author\": \"Tech Leads Club\",\n \"license\": \"MIT\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/tech-leads-club/agent-skills.git\"\n },\n \"type\": \"module\",\n \"bin\": {\n \"tlc-skills\": \"./index.js\"\n },\n \"engines\": {\n \"node\": \">=22\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"scripts\": {\n \"build\": \"nx build\",\n \"dev\": \"tsx src/index.ts\",\n \"test\": \"NODE_OPTIONS='--experimental-vm-modules' jest\",\n \"typecheck\": \"tsc --noEmit\"\n },\n \"keywords\": [\n \"ai\",\n \"agents\",\n \"skills\",\n \"cli\"\n ],\n \"dependencies\": {\n \"@clack/core\": \"^0.5.0\",\n \"@clack/prompts\": \"^0.11.0\",\n \"chalk\": \"^5.6.2\",\n \"commander\": \"^14.0.2\",\n \"figlet\": \"^1.10.0\",\n \"gradient-string\": \"^3.0.0\",\n \"package-json\": \"^10.0.1\",\n \"picocolors\": \"^1.1.1\"\n },\n \"devDependencies\": {\n \"@types/figlet\": \"^1.7.0\",\n \"@types/node\": \"^22\",\n \"tsx\": \"^4.21.0\",\n \"typescript\": \"^5.9.3\"\n }\n}\n", "import { cp, lstat, mkdir, readdir, readlink, rm, symlink } from 'node:fs/promises'\nimport { homedir, platform } from 'node:os'\nimport { join, normalize, relative, resolve, sep } from 'node:path'\n\nimport { getAgentConfig } from './agents'\nimport { getGlobalSkillPath, isGloballyInstalled } from './global-path'\nimport { addSkillToLock, removeSkillFromLock } from './lockfile'\nimport { findProjectRoot } from './project-root'\nimport type { AgentType, InstallOptions, InstallResult, SkillInfo } from './types'\n\nconst AGENTS_SKILLS_DIR = join('.agents', 'skills')\nconst EXCLUDE_FILES = new Set(['README.md', 'metadata.json', 'SKILL.md'])\n\nfunction sanitizeName(name: string): string {\n let sanitized = name.replace(/[/\\\\]/g, '')\n sanitized = sanitized.replace(/[\\0:]/g, '')\n sanitized = sanitized.replace(/^[.\\s]+|[.\\s]+$/g, '')\n sanitized = sanitized.replace(/^\\.+/, '')\n if (!sanitized || sanitized.length === 0) sanitized = 'unnamed-skill'\n return sanitized.substring(0, 255)\n}\n\nfunction isPathSafe(basePath: string, targetPath: string): boolean {\n const normalizedBase = normalize(resolve(basePath))\n const normalizedTarget = normalize(resolve(targetPath))\n return normalizedTarget.startsWith(normalizedBase + sep) || normalizedTarget === normalizedBase\n}\n\nasync function createSymlink(target: string, linkPath: string): Promise<boolean> {\n try {\n try {\n const stats = await lstat(linkPath)\n if (stats.isSymbolicLink()) {\n const existingTarget = await readlink(linkPath)\n if (resolve(existingTarget) === resolve(target)) return true\n await rm(linkPath)\n } else {\n await rm(linkPath, { recursive: true })\n }\n } catch (err: unknown) {\n if ((err as { code?: string })?.code === 'ELOOP') {\n try {\n await rm(linkPath, { force: true })\n } catch {\n // ignore\n }\n }\n }\n\n const linkDir = join(linkPath, '..')\n await mkdir(linkDir, { recursive: true })\n const relativePath = relative(linkDir, target)\n const type = platform() === 'win32' ? 'junction' : undefined\n await symlink(relativePath, linkPath, type)\n return true\n } catch {\n return false\n }\n}\n\nasync function copyDirectory(src: string, dest: string): Promise<void> {\n await mkdir(dest, { recursive: true })\n const entries = await readdir(src, { withFileTypes: true })\n\n for (const entry of entries) {\n if (EXCLUDE_FILES.has(entry.name) || entry.name.startsWith('_')) continue\n const srcPath = join(src, entry.name)\n const destPath = join(dest, entry.name)\n\n if (entry.isDirectory()) {\n await copyDirectory(srcPath, destPath)\n } else {\n await cp(srcPath, destPath)\n }\n }\n}\n\nexport async function installSkills(skills: SkillInfo[], options: InstallOptions): Promise<InstallResult[]> {\n const results: InstallResult[] = []\n const projectRoot = findProjectRoot()\n\n for (const agent of options.agents) {\n const config = getAgentConfig(agent)\n const targetDir = options.global ? config.globalSkillsDir : join(projectRoot, config.skillsDir)\n\n for (const skill of skills) {\n const result = await installSkillForAgent(skill, agent, targetDir, options.method, projectRoot, options.global)\n results.push(result)\n if (result.success) await addSkillToLock(skill.name, 'local')\n }\n }\n\n return results\n}\n\nasync function installSkillForAgent(\n skill: SkillInfo,\n agent: AgentType,\n targetDir: string,\n method: 'symlink' | 'copy',\n projectRoot: string,\n global: boolean,\n): Promise<InstallResult> {\n const config = getAgentConfig(agent)\n const safeSkillName = sanitizeName(skill.name)\n const skillTargetPath = join(targetDir, safeSkillName)\n\n if (!isPathSafe(targetDir, skillTargetPath) && !global) {\n if (!isPathSafe(projectRoot, skillTargetPath) && !global) {\n return {\n agent: config.displayName,\n skill: skill.name,\n path: skillTargetPath,\n method,\n success: false,\n error: 'Security: Invalid skill destination path',\n }\n }\n }\n\n try {\n if (method === 'symlink') {\n const globalSkillPath = getGlobalSkillPath(skill.name)\n\n if (globalSkillPath) {\n const success = await createSymlink(globalSkillPath, skillTargetPath)\n if (success) {\n return {\n agent: config.displayName,\n skill: skill.name,\n path: skillTargetPath,\n method,\n success: true,\n usedGlobalSymlink: true,\n }\n }\n }\n\n const canonicalDir = join(projectRoot, AGENTS_SKILLS_DIR, safeSkillName)\n await mkdir(canonicalDir, { recursive: true })\n await cp(skill.path, canonicalDir, { recursive: true })\n const symlinkCreated = await createSymlink(canonicalDir, skillTargetPath)\n\n if (!symlinkCreated) {\n try {\n await rm(skillTargetPath, { recursive: true, force: true })\n } catch {\n // ignore\n }\n\n await copyDirectory(skill.path, skillTargetPath)\n\n return {\n agent: config.displayName,\n skill: skill.name,\n path: skillTargetPath,\n method: 'copy',\n success: true,\n symlinkFailed: true,\n }\n }\n\n return {\n agent: config.displayName,\n skill: skill.name,\n path: skillTargetPath,\n method,\n success: true,\n usedGlobalSymlink: false,\n }\n } else {\n await copyDirectory(skill.path, skillTargetPath)\n return {\n agent: config.displayName,\n skill: skill.name,\n path: skillTargetPath,\n method,\n success: true,\n }\n }\n } catch (error) {\n return {\n agent: config.displayName,\n skill: skill.name,\n path: skillTargetPath,\n method,\n success: false,\n error: error instanceof Error ? error.message : String(error),\n }\n }\n}\n\nexport async function listInstalledSkills(agent: AgentType, global: boolean): Promise<string[]> {\n const config = getAgentConfig(agent)\n const targetDir = global ? config.globalSkillsDir : join(findProjectRoot(), config.skillsDir)\n\n try {\n const entries = await readdir(targetDir, { withFileTypes: true })\n return entries.filter((entry) => entry.isDirectory() || entry.isSymbolicLink()).map((entry) => entry.name)\n } catch {\n return []\n }\n}\n\nexport async function isSkillInstalled(\n skillName: string,\n agent: AgentType,\n options: { global?: boolean } = {},\n): Promise<boolean> {\n const config = getAgentConfig(agent)\n const safeSkillName = sanitizeName(skillName)\n const targetBase = options.global ? config.globalSkillsDir : join(findProjectRoot(), config.skillsDir)\n const skillDir = join(targetBase, safeSkillName)\n\n if (!isPathSafe(targetBase, skillDir)) return false\n\n try {\n await lstat(skillDir)\n return true\n } catch {\n return false\n }\n}\n\nexport function getInstallPath(skillName: string, agent: AgentType, options: { global?: boolean } = {}): string {\n const config = getAgentConfig(agent)\n const safeSkillName = sanitizeName(skillName)\n const targetBase = options.global ? config.globalSkillsDir : join(findProjectRoot(), config.skillsDir)\n const installPath = join(targetBase, safeSkillName)\n\n if (!isPathSafe(targetBase, installPath)) {\n throw new Error('Invalid skill name: potential path traversal detected')\n }\n\n return installPath\n}\n\nexport function getCanonicalPath(skillName: string, options: { global?: boolean } = {}): string {\n const safeSkillName = sanitizeName(skillName)\n const baseDir = options.global ? homedir() : findProjectRoot()\n const canonicalPath = join(baseDir, AGENTS_SKILLS_DIR, safeSkillName)\n\n if (!isPathSafe(join(baseDir, AGENTS_SKILLS_DIR), canonicalPath)) {\n throw new Error('Invalid skill name: potential path traversal detected')\n }\n\n return canonicalPath\n}\n\nexport async function removeSkill(\n skillName: string,\n agents: AgentType[],\n options: { global?: boolean } = {},\n): Promise<{ agent: string; success: boolean; error?: string }[]> {\n const results: { agent: string; success: boolean; error?: string }[] = []\n const safeSkillName = sanitizeName(skillName)\n const projectRoot = findProjectRoot()\n\n const canonicalPath = getCanonicalPath(skillName, options)\n try {\n await rm(canonicalPath, { recursive: true, force: true })\n } catch {\n // Ignore\n }\n\n for (const agent of agents) {\n const config = getAgentConfig(agent)\n const targetDir = options.global ? config.globalSkillsDir : join(projectRoot, config.skillsDir)\n const skillPath = join(targetDir, safeSkillName)\n\n try {\n await rm(skillPath, { recursive: true, force: true })\n results.push({ agent: config.displayName, success: true })\n } catch (error) {\n results.push({\n agent: config.displayName,\n success: false,\n error: error instanceof Error ? error.message : String(error),\n })\n }\n }\n\n await removeSkillFromLock(skillName)\n return results\n}\n\nexport { isGloballyInstalled }\n", "import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\n\nimport { findProjectRoot } from './project-root'\nimport type { AgentConfig, AgentType } from './types'\n\nconst home = homedir()\nconst projectRoot = findProjectRoot()\n\nexport const agents: Record<AgentType, AgentConfig> = {\n // Tier 1: Most popular AI coding agents\n cursor: {\n name: 'cursor',\n displayName: 'Cursor',\n description: 'AI-first code editor built on VS Code',\n skillsDir: '.cursor/skills',\n globalSkillsDir: join(home, '.cursor/skills'),\n detectInstalled: () => existsSync(join(home, '.cursor')) || existsSync(join(projectRoot, '.cursor')),\n },\n 'claude-code': {\n name: 'claude-code',\n displayName: 'Claude Code',\n description: \"Anthropic's agentic coding tool\",\n skillsDir: '.claude/skills',\n globalSkillsDir: join(home, '.claude/skills'),\n detectInstalled: () => existsSync(join(home, '.claude')) || existsSync(join(projectRoot, '.claude')),\n },\n 'github-copilot': {\n name: 'github-copilot',\n displayName: 'GitHub Copilot',\n description: 'AI pair programmer by GitHub/Microsoft',\n skillsDir: '.github/skills',\n globalSkillsDir: join(home, '.copilot/skills'),\n detectInstalled: () => existsSync(join(home, '.copilot')) || existsSync(join(projectRoot, '.github')),\n },\n windsurf: {\n name: 'windsurf',\n displayName: 'Windsurf',\n description: 'AI IDE with Cascade flow (Codeium)',\n skillsDir: '.windsurf/skills',\n globalSkillsDir: join(home, '.codeium/windsurf/skills'),\n detectInstalled: () => existsSync(join(home, '.codeium/windsurf')) || existsSync(join(projectRoot, '.windsurf')),\n },\n cline: {\n name: 'cline',\n displayName: 'Cline',\n description: 'Autonomous AI coding agent for VS Code',\n skillsDir: '.cline/skills',\n globalSkillsDir: join(home, '.cline/skills'),\n detectInstalled: () => existsSync(join(home, '.cline')) || existsSync(join(projectRoot, '.cline')),\n },\n\n // Tier 2: Rising stars\n aider: {\n name: 'aider',\n displayName: 'Aider',\n description: 'AI pair programming in terminal',\n skillsDir: '.aider/skills',\n globalSkillsDir: join(home, '.aider/skills'),\n detectInstalled: () => existsSync(join(home, '.aider')) || existsSync(join(projectRoot, '.aider')),\n },\n codex: {\n name: 'codex',\n displayName: 'OpenAI Codex',\n description: \"OpenAI's coding agent\",\n skillsDir: '.codex/skills',\n globalSkillsDir: join(home, '.codex/skills'),\n detectInstalled: () => existsSync(join(home, '.codex')) || existsSync(join(projectRoot, '.codex')),\n },\n gemini: {\n name: 'gemini',\n displayName: 'Gemini CLI',\n description: \"Google's AI coding assistant\",\n skillsDir: '.gemini/skills',\n globalSkillsDir: join(home, '.gemini/skills'),\n detectInstalled: () => existsSync(join(home, '.gemini')) || existsSync(join(projectRoot, '.gemini')),\n },\n antigravity: {\n name: 'antigravity',\n displayName: 'Antigravity',\n description: \"Google's agentic coding (VS Code)\",\n skillsDir: '.agent/skills',\n globalSkillsDir: join(home, '.agent/skills'),\n detectInstalled: () => existsSync(join(home, '.gemini/antigravity')) || existsSync(join(projectRoot, '.agent')),\n },\n roo: {\n name: 'roo',\n displayName: 'Roo Code',\n description: 'AI coding assistant for VS Code',\n skillsDir: '.roo/skills',\n globalSkillsDir: join(home, '.roo/skills'),\n detectInstalled: () => existsSync(join(home, '.roo')) || existsSync(join(projectRoot, '.roo')),\n },\n kilocode: {\n name: 'kilocode',\n displayName: 'Kilo Code',\n description: 'AI coding agent with auto-launch',\n skillsDir: '.kilocode/skills',\n globalSkillsDir: join(home, '.kilocode/skills'),\n detectInstalled: () => existsSync(join(home, '.kilocode')) || existsSync(join(projectRoot, '.kilocode')),\n },\n\n // Tier 3: Enterprise & specialized\n 'amazon-q': {\n name: 'amazon-q',\n displayName: 'Amazon Q',\n description: 'AWS AI coding assistant',\n skillsDir: '.amazonq/skills',\n globalSkillsDir: join(home, '.amazonq/skills'),\n detectInstalled: () => existsSync(join(home, '.amazonq')) || existsSync(join(projectRoot, '.amazonq')),\n },\n augment: {\n name: 'augment',\n displayName: 'Augment',\n description: 'AI code assistant with context engine',\n skillsDir: '.augment/skills',\n globalSkillsDir: join(home, '.augment/skills'),\n detectInstalled: () => existsSync(join(home, '.augment')) || existsSync(join(projectRoot, '.augment')),\n },\n tabnine: {\n name: 'tabnine',\n displayName: 'Tabnine',\n description: 'AI code completions with privacy focus',\n skillsDir: '.tabnine/skills',\n globalSkillsDir: join(home, '.tabnine/skills'),\n detectInstalled: () => existsSync(join(home, '.tabnine')) || existsSync(join(projectRoot, '.tabnine')),\n },\n opencode: {\n name: 'opencode',\n displayName: 'OpenCode',\n description: 'Open-source AI coding terminal',\n skillsDir: '.opencode/skills',\n globalSkillsDir: join(home, '.config/opencode/skills'),\n detectInstalled: () =>\n existsSync(join(home, '.config/opencode')) ||\n existsSync(join(projectRoot, '.opencode')) ||\n existsSync(join(projectRoot, '.config/opencode')),\n },\n sourcegraph: {\n name: 'sourcegraph',\n displayName: 'Sourcegraph Cody',\n description: 'AI assistant with codebase context',\n skillsDir: '.sourcegraph/skills',\n globalSkillsDir: join(home, '.sourcegraph/skills'),\n detectInstalled: () => existsSync(join(home, '.sourcegraph')) || existsSync(join(projectRoot, '.sourcegraph')),\n },\n}\n\nexport function detectInstalledAgents(): AgentType[] {\n return (Object.entries(agents) as [AgentType, AgentConfig][])\n .filter(([, config]) => config.detectInstalled())\n .map(([type]) => type)\n}\n\nexport function getAgentConfig(type: AgentType): AgentConfig {\n return agents[type]\n}\n\nexport function getAllAgentTypes(): AgentType[] {\n return (Object.keys(agents) as AgentType[]).sort((a, b) => agents[a].displayName.localeCompare(agents[b].displayName))\n}\n", "import { existsSync } from 'node:fs'\nimport { dirname, join, parse, resolve } from 'node:path'\n\nexport function findProjectRoot(startDir: string = process.cwd()): string {\n let currentDir = resolve(startDir)\n const root = parse(currentDir).root\n\n while (currentDir !== root) {\n if (existsSync(join(currentDir, 'package.json')) || existsSync(join(currentDir, '.git'))) {\n // Special check: ignore packages/cli/package.json if we are developing\n // This is a heuristic for the dev environment of this repo specifically\n const isCliPackage = currentDir.endsWith('packages/cli')\n if (!isCliPackage) return currentDir\n }\n currentDir = dirname(currentDir)\n }\n\n return startDir\n}\n", "import { execSync } from 'node:child_process'\nimport { existsSync } from 'node:fs'\nimport { join } from 'node:path'\n\nconst PACKAGE_NAME = '@tech-leads-club/agent-skills'\n\nexport function getNpmGlobalRoot(): string | null {\n try {\n return execSync('npm root -g', { encoding: 'utf-8' }).trim()\n } catch {\n return null\n }\n}\n\nexport function getGlobalSkillsPath(): string | null {\n const npmGlobalRoot = getNpmGlobalRoot()\n if (!npmGlobalRoot) return null\n const skillsPath = join(npmGlobalRoot, PACKAGE_NAME, 'skills')\n return existsSync(skillsPath) ? skillsPath : null\n}\n\nexport function isGloballyInstalled(): boolean {\n return getGlobalSkillsPath() !== null\n}\n\nexport function getGlobalSkillPath(skillName: string): string | null {\n const skillsPath = getGlobalSkillsPath()\n if (!skillsPath) return null\n const skillPath = join(skillsPath, skillName)\n return existsSync(skillPath) ? skillPath : null\n}\n", "import { mkdir, readFile, writeFile } from 'node:fs/promises'\nimport { homedir } from 'node:os'\nimport { dirname, join } from 'node:path'\n\nconst AGENTS_DIR = '.agents'\nconst LOCK_FILE = '.skill-lock.json'\nconst CURRENT_VERSION = 1\n\nexport interface SkillLockEntry {\n name: string\n source: string\n installedAt: string\n updatedAt: string\n}\n\nexport interface SkillLockFile {\n version: number\n skills: Record<string, SkillLockEntry>\n}\n\nfunction getSkillLockPath(): string {\n return join(homedir(), AGENTS_DIR, LOCK_FILE)\n}\n\nfunction createEmptyLockFile(): SkillLockFile {\n return { version: CURRENT_VERSION, skills: {} }\n}\n\nexport async function readSkillLock(): Promise<SkillLockFile> {\n const lockPath = getSkillLockPath()\n\n try {\n const content = await readFile(lockPath, 'utf-8')\n const parsed = JSON.parse(content) as SkillLockFile\n if (typeof parsed.version !== 'number' || !parsed.skills) return createEmptyLockFile()\n return parsed\n } catch {\n return createEmptyLockFile()\n }\n}\n\nexport async function writeSkillLock(lock: SkillLockFile): Promise<void> {\n const lockPath = getSkillLockPath()\n await mkdir(dirname(lockPath), { recursive: true })\n await writeFile(lockPath, JSON.stringify(lock, null, 2), 'utf-8')\n}\n\nexport async function addSkillToLock(skillName: string, source: string = 'local'): Promise<void> {\n const lock = await readSkillLock()\n const now = new Date().toISOString()\n const existingEntry = lock.skills[skillName]\n\n lock.skills[skillName] = {\n name: skillName,\n source,\n installedAt: existingEntry?.installedAt ?? now,\n updatedAt: now,\n }\n\n await writeSkillLock(lock)\n}\n\nexport async function removeSkillFromLock(skillName: string): Promise<boolean> {\n const lock = await readSkillLock()\n if (!(skillName in lock.skills)) return false\n delete lock.skills[skillName]\n await writeSkillLock(lock)\n return true\n}\n\nexport async function getSkillFromLock(skillName: string): Promise<SkillLockEntry | null> {\n const lock = await readSkillLock()\n return lock.skills[skillName] ?? null\n}\n\nexport async function getAllLockedSkills(): Promise<Record<string, SkillLockEntry>> {\n const lock = await readSkillLock()\n return lock.skills\n}\n", "import pc from 'picocolors'\n\nimport { detectInstalledAgents, getAllAgentTypes } from '../agents'\nimport { groupSkillsByCategory } from '../categories'\nimport { isGloballyInstalled } from '../installer'\nimport { discoverSkills } from '../skills'\nimport type { AgentType, InstallOptions } from '../types'\nimport { truncate } from '../ui/formatting'\nimport { blueConfirm, blueMultiSelectWithBack, blueSelectWithBack, isCancelled } from '../ui/input'\nimport { initScreen } from '../ui/screen'\nimport { logBar, logBarEnd, logCancelled } from '../ui/styles'\nimport { checkForUpdates, getCurrentVersion } from '../update-check'\nimport { showInstallationSummary } from './results'\nimport { buildAgentOptions, getAllInstalledSkillNames } from './utils'\n\ntype WizardState = {\n category: string\n skills: string[]\n agents: AgentType[]\n method: 'symlink' | 'copy'\n global: boolean\n}\n\nconst ALL_SKILLS_VALUE = '__all_skills__'\nconst ALL_CATEGORIES_VALUE = '__all__'\n\nexport async function runInteractiveInstall(): Promise<InstallOptions | null> {\n initScreen()\n await checkEnvironment()\n\n const allSkills = discoverSkills()\n if (allSkills.length === 0) {\n logBarEnd(pc.red('No skills available'))\n return null\n }\n\n const installedAgents = detectInstalledAgents()\n const allAgents = getAllAgentTypes()\n const targetAgents = installedAgents.length > 0 ? installedAgents : allAgents\n const installedSkills = await getAllInstalledSkillNames(targetAgents)\n\n const state: WizardState = {\n category: ALL_CATEGORIES_VALUE,\n skills: [],\n agents: installedAgents.length > 0 ? installedAgents : (['cursor', 'claude-code'] as AgentType[]),\n method: 'symlink',\n global: false,\n }\n\n let currentStep = 1\n const totalSteps = 4\n\n while (currentStep <= totalSteps) {\n const stepIndicator = pc.gray(`[${currentStep}/${totalSteps}]`)\n const allowBack = currentStep > 1\n\n switch (currentStep) {\n case 1: {\n const result = await selectCategoryStep({ allSkills, stepIndicator, currentCategory: state.category })\n if (result === null) return null\n state.category = result\n currentStep++\n break\n }\n\n case 2: {\n const result = await selectSkillsStep({\n state,\n allSkills,\n installedSkills,\n stepIndicator,\n allowBack,\n })\n\n if (result === Symbol.for('back')) {\n currentStep--\n break\n }\n\n if (result === null) return null\n\n state.skills = result as string[]\n currentStep++\n break\n }\n\n case 3: {\n const result = await selectAgentsStep({\n allAgents,\n installedAgents,\n currentAgents: state.agents,\n stepIndicator,\n allowBack,\n })\n\n if (result === Symbol.for('back')) {\n currentStep--\n break\n }\n\n if (result === null) return null\n\n state.agents = result as AgentType[]\n currentStep++\n break\n }\n\n case 4: {\n const result = await configureInstallationStep({\n state,\n stepIndicator,\n allowBack,\n })\n\n if (result === Symbol.for('back')) {\n state.method = 'symlink'\n currentStep--\n break\n }\n\n if (result === null) return null\n if (result === false) {\n currentStep = 1\n break\n }\n\n return result as InstallOptions\n }\n }\n }\n\n return null\n}\n\nasync function checkEnvironment() {\n const currentVersion = getCurrentVersion()\n const latestVersion = await checkForUpdates(currentVersion)\n\n if (latestVersion) {\n logBar(\n `${pc.yellow('\u26A0')} ${pc.yellow('Update available:')} ${pc.gray(currentVersion)} \u2192 ${pc.green(latestVersion)}`,\n )\n logBar(` ${pc.gray('Run: npm update -g @tech-leads-club/agent-skills')}`)\n logBar()\n } else if (!isGloballyInstalled()) {\n logBar(`${pc.yellow('\u26A0')} ${pc.yellow('Not installed globally')}`)\n logBar(` ${pc.yellow(\"Skills won't auto-update. Install globally:\")}`)\n logBar(` ${pc.yellow('npm i -g @tech-leads-club/agent-skills')}`)\n logBar()\n }\n}\n\ninterface SelectCategoryProps {\n allSkills: ReturnType<typeof discoverSkills>\n stepIndicator: string\n currentCategory: string\n}\n\nasync function selectCategoryStep({\n allSkills,\n stepIndicator,\n currentCategory,\n}: SelectCategoryProps): Promise<string | null> {\n const groupedSkills = groupSkillsByCategory(allSkills)\n const categoryList = Array.from(groupedSkills.keys())\n\n const categoryOptions = [\n { value: ALL_CATEGORIES_VALUE, label: `${pc.cyan('\u25C9')} All skills`, hint: `${allSkills.length} available` },\n ...categoryList.map((cat) => {\n const skillCount = groupedSkills.get(cat)?.length ?? 0\n return { value: cat.id, label: `${pc.cyan('\u25B8')} ${cat.name}`, hint: `${skillCount} skill(s)` }\n }),\n ]\n\n const selectedCategory = await blueSelectWithBack(\n `${stepIndicator} Browse by category`,\n categoryOptions,\n currentCategory,\n false,\n )\n\n if (isCancelled(selectedCategory)) {\n logCancelled()\n return null\n }\n\n return selectedCategory as string\n}\n\ninterface SelectSkillsProps {\n state: WizardState\n allSkills: ReturnType<typeof discoverSkills>\n installedSkills: Set<string>\n stepIndicator: string\n allowBack: boolean\n}\n\nasync function selectSkillsStep({\n state,\n allSkills,\n installedSkills,\n stepIndicator,\n allowBack,\n}: SelectSkillsProps): Promise<string[] | symbol | null> {\n const showAllCategories = state.category === ALL_CATEGORIES_VALUE\n const filteredSkills = showAllCategories ? allSkills : allSkills.filter((skill) => skill.category === state.category)\n\n const skillOptions = [\n {\n value: ALL_SKILLS_VALUE,\n label: `${pc.cyan('\u25C9')} ${pc.bold('All Skills')}`,\n hint: `select all ${filteredSkills.length} skills`,\n },\n ...filteredSkills.map((skill) => {\n const isInstalled = installedSkills.has(skill.name)\n return {\n value: skill.name,\n label: isInstalled ? `${skill.name} ${pc.green('\u25CF installed')}` : skill.name,\n hint: truncate(skill.description, 150),\n }\n }),\n ]\n\n const initialSkills = state.skills.length > 0 ? state.skills : []\n\n const selectedSkills = await blueMultiSelectWithBack(\n `${stepIndicator} Select skills to install`,\n skillOptions,\n initialSkills,\n allowBack,\n )\n\n if (selectedSkills === Symbol.for('back')) return Symbol.for('back')\n\n if (isCancelled(selectedSkills)) {\n logCancelled()\n return null\n }\n\n const skillsArray = selectedSkills as string[]\n\n const validSkills = skillsArray.includes(ALL_SKILLS_VALUE)\n ? filteredSkills.map((s) => s.name)\n : skillsArray.filter((s) => s !== ALL_SKILLS_VALUE)\n\n if (validSkills.length === 0) logBar(pc.yellow('\u26A0 Please select at least one skill'))\n if (validSkills.length === 0) return selectSkillsStep({ state, allSkills, installedSkills, stepIndicator, allowBack })\n return validSkills\n}\n\ninterface SelectAgentsProps {\n allAgents: AgentType[]\n installedAgents: AgentType[]\n currentAgents: AgentType[]\n stepIndicator: string\n allowBack: boolean\n}\n\nasync function selectAgentsStep({\n allAgents,\n installedAgents,\n currentAgents,\n stepIndicator,\n allowBack,\n}: SelectAgentsProps): Promise<AgentType[] | symbol | null> {\n const agentOptions = buildAgentOptions(allAgents, installedAgents)\n\n const selectedAgents = await blueMultiSelectWithBack(\n `${stepIndicator} Where to install?`,\n agentOptions,\n currentAgents,\n allowBack,\n )\n\n if (selectedAgents === Symbol.for('back')) return Symbol.for('back')\n\n if (isCancelled(selectedAgents)) {\n logCancelled()\n return null\n }\n\n const validAgents = selectedAgents as AgentType[]\n\n if (validAgents.length === 0) {\n logBar(pc.yellow('\u26A0 Please select at least one agent'))\n return selectAgentsStep({ allAgents, installedAgents, currentAgents, stepIndicator, allowBack })\n }\n\n return validAgents\n}\n\ninterface ConfigureProps {\n state: WizardState\n stepIndicator: string\n allowBack: boolean\n}\n\nasync function configureInstallationStep({\n state,\n stepIndicator,\n allowBack,\n}: ConfigureProps): Promise<InstallOptions | symbol | null | false> {\n const methodOptions = [\n { value: 'symlink', label: 'Symlink', hint: 'shared source (recommended)' },\n { value: 'copy', label: 'Copy', hint: 'independent copies' },\n ]\n\n const method = await blueSelectWithBack(\n `${stepIndicator} Installation method`,\n methodOptions,\n state.method,\n allowBack,\n )\n\n if (method === Symbol.for('back')) return Symbol.for('back')\n\n if (isCancelled(method)) {\n logCancelled()\n return null\n }\n\n state.method = method as 'symlink' | 'copy'\n showInstallationSummary(state)\n const scopeResult = await selectScope(state)\n if (scopeResult === Symbol.for('back')) return configureInstallationStep({ state, stepIndicator, allowBack })\n if (scopeResult === null) return null\n state.global = scopeResult === 'global'\n const confirm = await blueConfirm(pc.white('Proceed with installation?'), true)\n\n if (isCancelled(confirm)) {\n logCancelled()\n return null\n }\n\n if (!confirm) return false\n logBar()\n\n return { agents: state.agents, skills: state.skills, method: state.method, global: state.global }\n}\n\nasync function selectScope(state: WizardState): Promise<'local' | 'global' | symbol | null> {\n const scopeOptions = [\n { value: 'local', label: 'Local', hint: 'this project only' },\n { value: 'global', label: 'Global', hint: 'user home directory' },\n ]\n\n const scope = await blueSelectWithBack('Installation scope', scopeOptions, state.global ? 'global' : 'local', true)\n if (scope === Symbol.for('back')) return Symbol.for('back')\n if (isCancelled(scope)) return null\n return scope as 'local' | 'global'\n}\n", "import { existsSync, readFileSync, writeFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nimport {\n DEFAULT_CATEGORY,\n DEFAULT_CATEGORY_ID,\n SKILLS_CATEGORIES_FILE,\n formatCategoryName,\n} from '@tech-leads-club/core'\n\nimport type { CategoriesConfig, CategoryInfo } from './types'\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = dirname(__filename)\n\nexport function getCategoriesFilePath(): string {\n const devPath = join(__dirname, '..', '..', '..', SKILLS_CATEGORIES_FILE)\n if (existsSync(devPath)) return devPath\n const pkgPath = join(__dirname, '..', SKILLS_CATEGORIES_FILE)\n if (existsSync(pkgPath)) return pkgPath\n return devPath\n}\n\nexport function loadCategoriesConfig(): CategoriesConfig {\n const filePath = getCategoriesFilePath()\n if (!existsSync(filePath)) return { categories: [], skills: {} }\n\n try {\n const content = readFileSync(filePath, 'utf-8')\n return JSON.parse(content) as CategoriesConfig\n } catch {\n return { categories: [], skills: {} }\n }\n}\n\nexport function saveCategoriesConfig(config: CategoriesConfig): void {\n const filePath = getCategoriesFilePath()\n const content = JSON.stringify({ $schema: './categories.schema.json', ...config }, null, 2)\n writeFileSync(filePath, content + '\\n', 'utf-8')\n}\n\nexport function getCategories(): CategoryInfo[] {\n const config = loadCategoriesConfig()\n const categories = [...config.categories]\n categories.sort((a, b) => (a.priority ?? 100) - (b.priority ?? 100))\n return categories\n}\n\nexport function getCategoryById(id: string): CategoryInfo | undefined {\n const config = loadCategoriesConfig()\n return config.categories.find((cat) => cat.id === id)\n}\n\nexport function getSkillCategoryId(skillName: string): string {\n const config = loadCategoriesConfig()\n return config.skills[skillName] ?? DEFAULT_CATEGORY_ID\n}\n\nexport function getSkillCategory(skillName: string): CategoryInfo {\n const categoryId = getSkillCategoryId(skillName)\n const category = getCategoryById(categoryId)\n return category ?? DEFAULT_CATEGORY\n}\n\nexport function categoryExists(categoryId: string): boolean {\n const config = loadCategoriesConfig()\n return config.categories.some((cat) => cat.id === categoryId)\n}\n\nexport function addCategory(category: CategoryInfo): boolean {\n const config = loadCategoriesConfig()\n if (config.categories.some((cat) => cat.id === category.id)) return false\n config.categories.push(category)\n saveCategoriesConfig(config)\n return true\n}\n\nexport function assignSkillToCategory(skillName: string, categoryId: string, categoryName?: string): void {\n const config = loadCategoriesConfig()\n\n if (!config.categories.some((cat) => cat.id === categoryId)) {\n const newCategory: CategoryInfo = {\n id: categoryId,\n name: categoryName ?? formatCategoryName(categoryId),\n priority: Math.max(0, ...config.categories.map((c) => c.priority ?? 0)) + 1,\n }\n config.categories.push(newCategory)\n }\n\n config.skills[skillName] = categoryId\n saveCategoriesConfig(config)\n}\n\nexport function groupSkillsByCategory<T extends { name: string; category?: string }>(\n skills: T[],\n): Map<CategoryInfo, T[]> {\n const config = loadCategoriesConfig()\n const grouped = new Map<CategoryInfo, T[]>()\n const sortedCategories = [...config.categories].sort((a, b) => (a.priority ?? 100) - (b.priority ?? 100))\n\n for (const category of sortedCategories) {\n grouped.set(category, [])\n }\n\n grouped.set(DEFAULT_CATEGORY, [])\n\n for (const skill of skills) {\n const categoryId = skill.category ?? config.skills[skill.name] ?? DEFAULT_CATEGORY_ID\n const category = sortedCategories.find((c) => c.id === categoryId) ?? DEFAULT_CATEGORY\n const group = grouped.get(category) ?? []\n group.push(skill)\n grouped.set(category, group)\n }\n\n for (const [category, skillList] of grouped) {\n if (skillList.length === 0) grouped.delete(category)\n }\n\n return grouped\n}\n", "import type { CategoryInfo } from './types'\n\nexport const SKILLS_CATEGORIES_FILE = 'skills/categories.json'\nexport const SKILLS_ROOT_DIR = 'skills'\nexport const DEFAULT_CATEGORY_ID = 'uncategorized'\n\nexport const DEFAULT_CATEGORY: CategoryInfo = {\n id: DEFAULT_CATEGORY_ID,\n name: 'Uncategorized',\n description: 'Skills without a specific category',\n priority: 999,\n}\n", "import { existsSync, readdirSync, readFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nimport { SKILLS_ROOT_DIR } from '@tech-leads-club/core'\n\nimport { getSkillCategoryId } from './categories'\nimport type { SkillInfo } from './types'\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = dirname(__filename)\n\nexport function getSkillsDirectory(): string {\n const devSkillsDir = join(__dirname, '..', '..', '..', SKILLS_ROOT_DIR)\n if (existsSync(devSkillsDir)) return devSkillsDir\n const pkgSkillsDir = join(__dirname, '..', SKILLS_ROOT_DIR)\n if (existsSync(pkgSkillsDir)) return pkgSkillsDir\n throw new Error(`Skills directory not found. Checked: ${devSkillsDir}, ${pkgSkillsDir}`)\n}\n\nexport function discoverSkills(): SkillInfo[] {\n const skillsDir = getSkillsDirectory()\n const skills: SkillInfo[] = []\n if (!existsSync(skillsDir)) return skills\n const entries = readdirSync(skillsDir, { withFileTypes: true })\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n const skillMdPath = join(skillsDir, entry.name, 'SKILL.md')\n if (!existsSync(skillMdPath)) continue\n const content = readFileSync(skillMdPath, 'utf-8')\n const { name, description } = parseSkillFrontmatter(content)\n\n const skillName = name || entry.name\n skills.push({\n name: skillName,\n description: description || 'No description',\n path: join(skillsDir, entry.name),\n category: getSkillCategoryId(skillName),\n })\n }\n\n return skills\n}\n\nfunction parseSkillFrontmatter(content: string): { name?: string; description?: string } {\n const frontmatterMatch = content.match(/^---\\n([\\s\\S]*?)\\n---/)\n if (!frontmatterMatch) return {}\n const frontmatter = frontmatterMatch[1]\n const nameMatch = frontmatter.match(/^name:\\s*(.+)$/m)\n const descMatch = frontmatter.match(/^description:\\s*(.+)$/m)\n return { name: nameMatch?.[1]?.trim(), description: descMatch?.[1]?.trim() }\n}\n\nexport function getSkillByName(name: string): SkillInfo | undefined {\n const skills = discoverSkills()\n return skills.find((s) => s.name === name)\n}\n", "export function truncate(text: string, maxLength: number): string {\n return text.length <= maxLength ? text : text.slice(0, maxLength - 3) + '...'\n}\n", "import { ConfirmPrompt, MultiSelectPrompt, SelectPrompt } from '@clack/core'\nimport pc from 'picocolors'\n\nimport {\n S_BAR,\n S_BAR_END,\n S_CHECKBOX_ACTIVE,\n S_CHECKBOX_INACTIVE,\n S_RADIO_ACTIVE,\n S_RADIO_INACTIVE,\n SYMBOL,\n} from './styles'\n\nexport interface Option<T> {\n value: T\n label: string\n hint?: string\n}\n\nexport function isCancelled<T>(value: T | symbol): value is symbol {\n return typeof value === 'symbol'\n}\n\nexport async function blueSelectWithBack<T>(\n message: string,\n options: Option<T>[],\n initialValue?: T,\n allowBack = true,\n): Promise<T | symbol> {\n const opt = (option: Option<T>, isActive: boolean) => {\n const radio = isActive ? pc.blue(S_RADIO_ACTIVE) : pc.gray(S_RADIO_INACTIVE)\n const label = isActive ? pc.blue(option.label) : pc.white(option.label)\n const hint = isActive && option.hint ? pc.dim(pc.gray(` - ${option.hint}`)) : ''\n return `${radio} ${label}${hint}`\n }\n\n const prompt = new SelectPrompt({\n options,\n initialValue,\n render() {\n const title = `${pc.blue(S_BAR)}\\n${SYMBOL} ${pc.white(pc.bold(message))}\\n`\n const backHint = allowBack ? 'esc = back, ' : ''\n\n switch (this.state) {\n case 'submit':\n return `${title}${pc.blue(S_BAR)} ${pc.blue(this.options.find((o) => o.value === this.value)?.label)}\\n${pc.blue(S_BAR)}`\n case 'cancel':\n return `${title}${pc.blue(S_BAR)} ${pc.strikethrough(pc.gray('back'))}\\n${pc.blue(S_BAR)}`\n default:\n return `${title}${this.options\n .map((option, i) => `${pc.blue(S_BAR)} ${opt(option as Option<T>, i === this.cursor)}`)\n .join(\n '\\n',\n )}\\n${pc.blue(S_BAR)}\\n${pc.blue(S_BAR_END)} ${pc.dim(pc.gray(`(\u2191\u2193 navigate, ${backHint}enter confirm)`))}`\n }\n },\n })\n\n const result = await prompt.prompt()\n if (typeof result === 'symbol' && allowBack) return Symbol.for('back')\n return result as T | symbol\n}\n\nexport async function blueMultiSelectWithBack<T>(\n message: string,\n options: Option<T>[],\n initialValues: T[] = [],\n allowBack = true,\n): Promise<T[] | symbol> {\n const opt = (option: Option<T>, state: 'active' | 'selected' | 'cancelled' | 'inactive' | 'selected-active') => {\n const isSelected = state === 'selected' || state === 'selected-active'\n const isActive = state === 'active' || state === 'selected-active'\n const checkbox = isSelected ? pc.blue(S_CHECKBOX_ACTIVE) : pc.gray(S_CHECKBOX_INACTIVE)\n const label = isActive ? pc.blue(option.label) : pc.white(option.label)\n const hint = isActive && option.hint ? pc.dim(pc.gray(` (${option.hint})`)) : ''\n return `${checkbox} ${label}${hint}`\n }\n\n const prompt = new MultiSelectPrompt({\n options,\n initialValues,\n render() {\n const title = `${pc.blue(S_BAR)}\\n${SYMBOL} ${pc.white(pc.bold(message))}\\n`\n const backHint = allowBack ? 'esc = back, ' : ''\n\n switch (this.state) {\n case 'submit':\n return `${title}${pc.blue(S_BAR)} ${this.options\n .filter((o) => this.value.includes(o.value))\n .map((o) => pc.blue(String(o.value)))\n .join(pc.gray(', '))}\\n${pc.blue(S_BAR)}`\n case 'cancel':\n return `${title}${pc.blue(S_BAR)} ${pc.strikethrough(pc.gray('back'))}\\n${pc.blue(S_BAR)}`\n default:\n return `${title}${this.options\n .map((option, i) => {\n const isSelected = this.value.includes(option.value)\n const isActive = i === this.cursor\n const state =\n isSelected && isActive ? 'selected-active' : isSelected ? 'selected' : isActive ? 'active' : 'inactive'\n return `${pc.blue(S_BAR)} ${opt(option as Option<T>, state)}`\n })\n .join(\n '\\n',\n )}\\n${pc.blue(S_BAR)}\\n${pc.blue(S_BAR_END)} ${pc.dim(pc.gray(`(\u2191\u2193 navigate, space select, ${backHint}enter confirm)`))}`\n }\n },\n })\n\n const result = await prompt.prompt()\n if (typeof result === 'symbol' && allowBack) return Symbol.for('back')\n return result as T[] | symbol\n}\n\nexport async function blueConfirm(message: string, initialValue = false): Promise<boolean | symbol> {\n const prompt = new ConfirmPrompt({\n active: 'Yes',\n inactive: 'No',\n initialValue,\n render() {\n const title = `${pc.blue(S_BAR)}\\n${SYMBOL} ${pc.white(pc.bold(message))}\\n`\n\n switch (this.state) {\n case 'submit':\n return `${title}${pc.blue(S_BAR)} ${pc.blue(this.value ? 'Yes' : 'No')}\\n${pc.blue(S_BAR)}`\n case 'cancel':\n return `${title}${pc.blue(S_BAR)} ${pc.strikethrough(pc.gray('cancelled'))}\\n${pc.blue(S_BAR)}`\n default:\n return `${title}${pc.blue(S_BAR)} ${\n this.value\n ? `${pc.blue('\u25CF Yes')} ${pc.dim(pc.gray('/'))} ${pc.gray('\u25CB')} ${pc.white('No')}`\n : `${pc.gray('\u25CB')} ${pc.white('Yes')} ${pc.dim(pc.gray('/'))} ${pc.blue('\u25CF No')}`\n }\\n${pc.blue(S_BAR)}\\n${pc.blue(S_BAR_END)} ${pc.dim(pc.gray('(\u2190\u2192 to change, enter to confirm)'))}`\n }\n },\n })\n\n return prompt.prompt() as Promise<boolean | symbol>\n}\n", "import gradient from 'gradient-string'\nimport pc from 'picocolors'\n\ninterface Gradient {\n (text: string, options?: unknown): string\n multiline(text: string, options?: unknown): string\n}\n\nexport const crystalGradient: Gradient = gradient([\n { color: '#1e3a8a', pos: 0 },\n { color: '#3b82f6', pos: 0.3 },\n { color: '#0ea5e9', pos: 0.5 },\n { color: '#06b6d4', pos: 0.7 },\n { color: '#22d3ee', pos: 1 },\n]) as Gradient\n\nexport const S_BAR = '\u2502'\nexport const S_BAR_END = '\u2514'\nexport const S_RADIO_ACTIVE = '\u25CF'\nexport const S_RADIO_INACTIVE = '\u25CB'\nexport const S_CHECKBOX_ACTIVE = '\u25FC'\nexport const S_CHECKBOX_INACTIVE = '\u25FB'\nexport const SYMBOL = pc.blue('\u25C6')\n\nexport function logBar(message = ''): void {\n console.log(message ? `${pc.blue(S_BAR)} ${message}` : pc.blue(S_BAR))\n}\n\nexport function logBarEnd(message = ''): void {\n console.log(`${pc.blue(S_BAR_END)} ${message}`)\n}\n\nexport function logCancelled(): void {\n logBarEnd(pc.gray('Cancelled'))\n}\n", "import figlet from 'figlet'\nimport pc from 'picocolors'\n\nimport { crystalGradient, logBar } from './styles'\n\nexport function generateLogo(): string {\n const asciiArt = figlet.textSync('Tech Leads Club', { font: 'Larry 3D', horizontalLayout: 'default' })\n return `\n${crystalGradient.multiline(asciiArt)}\n ${pc.white(pc.bold('Tech Leads Club'))} ${pc.blue('\u203A')} ${pc.bold(pc.blue('Agent Skills'))}\n ${pc.white('Curated skills to power up your AI coding agents')}\n`\n}\n\nexport function initScreen(): void {\n console.clear()\n console.log(generateLogo())\n logBar()\n}\n", "import { createRequire } from 'node:module'\nimport packageJson from 'package-json'\n\nconst PACKAGE_NAME = '@tech-leads-club/agent-skills'\n\nexport async function checkForUpdates(currentVersion: string): Promise<string | null> {\n try {\n const result = await packageJson(PACKAGE_NAME)\n if (result.version !== currentVersion) return result.version\n return null\n } catch {\n // Silently fail if offline or registry unavailable\n return null\n }\n}\n\nexport function getCurrentVersion(): string {\n try {\n const require = createRequire(import.meta.url)\n const pkg = require('../package.json')\n return pkg.version || '0.0.0'\n } catch {\n return '0.0.0'\n }\n}\n", "import pc from 'picocolors'\n\nimport { logBar, logBarEnd, S_BAR, SYMBOL } from '../ui/styles'\n\ninterface InstallationSummaryOptions {\n skills: string[]\n agents: string[]\n method: string\n}\n\nexport function showInstallationSummary(options: InstallationSummaryOptions): void {\n logBar()\n logBar(pc.blue(pc.bold('\uD83D\uDCCB Installation Summary')))\n logBar()\n logBar(`${pc.blue(S_BAR)} ${pc.white(pc.bold('Skills:'))} ${pc.gray(options.skills.join(', '))}`)\n logBar(`${pc.blue(S_BAR)} ${pc.white(pc.bold('Agents:'))} ${pc.gray(options.agents.join(', '))}`)\n logBar(`${pc.blue(S_BAR)} ${pc.white(pc.bold('Method:'))} ${pc.cyan(options.method)}`)\n logBar()\n}\n\nexport function showInstallResults(\n results: Array<{\n agent: string\n skill: string\n path: string\n method: string\n success: boolean\n error?: string\n }>,\n): void {\n const successful = results.filter((r) => r.success && !r.error)\n const alreadyExists = results.filter((r) => r.success && r.error === 'Already exists')\n const failed = results.filter((r) => !r.success)\n\n console.log()\n\n for (const r of successful) {\n console.log(`${SYMBOL} ${pc.white(pc.bold(r.skill))} ${pc.gray('\u2192')} ${pc.white(r.agent)}`)\n }\n\n for (const r of alreadyExists) {\n console.log(`${pc.gray(SYMBOL)} ${r.skill} \u2192 ${r.agent} ${pc.gray('(exists)')}`)\n }\n\n for (const r of failed) {\n console.log(`${pc.red('\u2717')} ${r.skill} \u2192 ${r.agent}: ${r.error}`)\n }\n\n const totalAgents = new Set(results.map((r) => r.agent)).size\n\n console.log()\n logBarEnd(\n `${pc.blue('\u2713')} ${pc.white(pc.bold(`${successful.length} skill(s)`))} ${pc.white('installed to')} ${pc.white(pc.bold(`${totalAgents} agent(s)`))}`,\n )\n}\n\nexport function showRemoveResults(\n skillName: string,\n results: Array<{ agent: string; success: boolean; error?: string }>,\n): void {\n const successful = results.filter((r) => r.success)\n const failed = results.filter((r) => !r.success)\n\n if (successful.length > 0) {\n console.log(\n `${SYMBOL} ${pc.white(pc.bold(skillName))} ${pc.gray('removed from')} ${successful.map((r) => r.agent).join(', ')}`,\n )\n }\n\n for (const r of failed) {\n console.log(`${pc.red('\u2717')} ${skillName} \u2192 ${r.agent}: ${r.error}`)\n }\n\n if (successful.length > 0 && failed.length === 0) {\n logBarEnd(`${pc.blue('\u2713')} ${pc.white('Skill removed successfully')}`)\n }\n}\n", "import pc from 'picocolors'\n\nimport { getAgentConfig } from '../agents'\nimport { listInstalledSkills } from '../installer'\nimport type { AgentType } from '../types'\nimport { truncate } from '../ui/formatting'\nimport type { Option } from '../ui/input'\n\nexport function buildAgentOptions(agents: AgentType[], detectedAgents: AgentType[] = []): Option<AgentType>[] {\n return agents.map((type) => {\n const config = getAgentConfig(type)\n const isDetected = detectedAgents.includes(type)\n return {\n value: type,\n label: isDetected ? `${config.displayName} ${pc.green('\u25CF detected')}` : config.displayName,\n hint: truncate(config.description, 50),\n }\n })\n}\n\nexport async function getInstalledSkillNames(agents: AgentType[], global: boolean): Promise<Set<string>> {\n const installed = new Set<string>()\n for (const agent of agents) {\n const skills = await listInstalledSkills(agent, global)\n skills.forEach((skill) => installed.add(skill))\n }\n return installed\n}\n\nexport async function getAllInstalledSkillNames(agents: AgentType[]): Promise<Set<string>> {\n const [globalSkills, localSkills] = await Promise.all([\n getInstalledSkillNames(agents, true),\n getInstalledSkillNames(agents, false),\n ])\n return new Set([...globalSkills, ...localSkills])\n}\n", "import pc from 'picocolors'\n\nimport { getAllAgentTypes } from '../agents'\nimport { groupSkillsByCategory } from '../categories'\nimport { discoverSkills } from '../skills'\nimport { initScreen } from '../ui/screen'\nimport { logBar, logBarEnd, S_BAR } from '../ui/styles'\nimport { getAllInstalledSkillNames } from './utils'\n\nexport async function showAvailableSkills(): Promise<void> {\n initScreen()\n const skills = discoverSkills()\n\n if (skills.length === 0) {\n logBar(pc.yellow('No skills found'))\n return\n }\n\n logBar(pc.bold(`${skills.length} skills available:`))\n logBar()\n\n const allAgents = getAllAgentTypes()\n const installedSkills = await getAllInstalledSkillNames(allAgents)\n const groupedSkills = groupSkillsByCategory(skills)\n\n for (const [category, categorySkills] of groupedSkills) {\n logBar(`${pc.cyan('\u25B8')} ${pc.bold(pc.cyan(category.name))}`)\n\n for (const skill of categorySkills) {\n const installedBadge = installedSkills.has(skill.name) ? ` ${pc.green('\u25CF installed')}` : ''\n logBar(` ${pc.blue('\u25C6')} ${pc.bold(skill.name)}${installedBadge}`)\n console.log(`${pc.blue(S_BAR)} ${pc.dim(pc.gray(skill.description))}`)\n }\n\n logBar()\n }\n\n logBarEnd(pc.gray('Run \"npx @tech-leads-club/agent-skills\" to install'))\n}\n", "import pc from 'picocolors'\n\nimport { getAllAgentTypes } from '../agents'\nimport { removeSkill } from '../installer'\nimport type { AgentType } from '../types'\nimport { blueConfirm, blueMultiSelectWithBack, isCancelled } from '../ui/input'\nimport { initScreen } from '../ui/screen'\nimport { logBar, logBarEnd, logCancelled } from '../ui/styles'\nimport { showRemoveResults } from './results'\nimport { buildAgentOptions, getInstalledSkillNames } from './utils'\n\nexport async function runInteractiveRemove(global: boolean): Promise<void> {\n initScreen()\n const allAgents = getAllAgentTypes()\n const installedSkills = await getInstalledSkillNames(allAgents, global)\n\n if (installedSkills.size === 0) {\n logBar(pc.yellow('No skills installed'))\n logBarEnd()\n return\n }\n\n const skillsArray = Array.from(installedSkills)\n\n // Step 1\n const selectedSkills = await blueMultiSelectWithBack(\n `Which skills do you want to remove? ${pc.gray(`(${skillsArray.length} installed)`)}`,\n skillsArray.map((name) => ({ value: name, label: name })),\n [],\n false,\n )\n\n if (isCancelled(selectedSkills) || (selectedSkills as string[]).length === 0) {\n logCancelled()\n return\n }\n\n // Step 2\n const selectedAgents = await blueMultiSelectWithBack(\n 'Remove from which agents?',\n buildAgentOptions(allAgents).map((opt) => ({ ...opt, hint: undefined })),\n allAgents,\n true,\n )\n\n if (isCancelled(selectedAgents)) {\n logCancelled()\n return\n }\n\n // Step 3\n const confirm = await blueConfirm(\n `Remove ${selectedSkills.length} skill(s) from ${selectedAgents.length} agent(s)?`,\n false,\n )\n\n if (isCancelled(confirm) || !confirm) {\n logCancelled()\n return\n }\n\n logBar()\n\n for (const skillName of selectedSkills) {\n const results = await removeSkill(skillName, selectedAgents as AgentType[], { global })\n showRemoveResults(skillName, results)\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["Command", "package_default", "cp", "lstat", "mkdir", "readdir", "readlink", "rm", "symlink", "homedir", "platform", "join", "normalize", "relative", "resolve", "sep", "existsSync", "homedir", "join", "existsSync", "dirname", "join", "parse", "resolve", "findProjectRoot", "startDir", "currentDir", "root", "home", "homedir", "projectRoot", "findProjectRoot", "agents", "join", "existsSync", "detectInstalledAgents", "config", "type", "getAgentConfig", "getAllAgentTypes", "a", "b", "execSync", "existsSync", "join", "PACKAGE_NAME", "getNpmGlobalRoot", "getGlobalSkillsPath", "npmGlobalRoot", "skillsPath", "isGloballyInstalled", "getGlobalSkillPath", "skillName", "skillPath", "mkdir", "readFile", "writeFile", "homedir", "dirname", "join", "AGENTS_DIR", "LOCK_FILE", "CURRENT_VERSION", "getSkillLockPath", "createEmptyLockFile", "readSkillLock", "lockPath", "content", "parsed", "writeSkillLock", "lock", "addSkillToLock", "skillName", "source", "now", "existingEntry", "removeSkillFromLock", "AGENTS_SKILLS_DIR", "join", "EXCLUDE_FILES", "sanitizeName", "name", "sanitized", "isPathSafe", "basePath", "targetPath", "normalizedBase", "normalize", "resolve", "normalizedTarget", "sep", "createSymlink", "target", "linkPath", "lstat", "existingTarget", "readlink", "rm", "err", "linkDir", "mkdir", "relativePath", "relative", "type", "platform", "symlink", "copyDirectory", "src", "dest", "entries", "readdir", "entry", "srcPath", "destPath", "cp", "installSkills", "skills", "options", "results", "projectRoot", "findProjectRoot", "agent", "config", "getAgentConfig", "targetDir", "skill", "result", "installSkillForAgent", "addSkillToLock", "method", "global", "safeSkillName", "skillTargetPath", "globalSkillPath", "getGlobalSkillPath", "canonicalDir", "error", "listInstalledSkills", "getCanonicalPath", "skillName", "options", "safeSkillName", "sanitizeName", "baseDir", "homedir", "findProjectRoot", "canonicalPath", "join", "AGENTS_SKILLS_DIR", "isPathSafe", "removeSkill", "agents", "results", "projectRoot", "rm", "agent", "config", "getAgentConfig", "targetDir", "skillPath", "error", "removeSkillFromLock", "pc", "existsSync", "readFileSync", "writeFileSync", "dirname", "join", "fileURLToPath", "SKILLS_CATEGORIES_FILE", "SKILLS_ROOT_DIR", "DEFAULT_CATEGORY_ID", "DEFAULT_CATEGORY", "__filename", "fileURLToPath", "__dirname", "dirname", "getCategoriesFilePath", "devPath", "join", "SKILLS_CATEGORIES_FILE", "existsSync", "pkgPath", "loadCategoriesConfig", "filePath", "content", "readFileSync", "getSkillCategoryId", "skillName", "loadCategoriesConfig", "DEFAULT_CATEGORY_ID", "groupSkillsByCategory", "skills", "config", "loadCategoriesConfig", "grouped", "sortedCategories", "a", "b", "category", "DEFAULT_CATEGORY", "skill", "categoryId", "DEFAULT_CATEGORY_ID", "group", "skillList", "existsSync", "readdirSync", "readFileSync", "dirname", "join", "fileURLToPath", "__filename", "fileURLToPath", "__dirname", "dirname", "getSkillsDirectory", "devSkillsDir", "join", "SKILLS_ROOT_DIR", "existsSync", "pkgSkillsDir", "discoverSkills", "skillsDir", "skills", "entries", "readdirSync", "entry", "skillMdPath", "content", "readFileSync", "name", "description", "parseSkillFrontmatter", "skillName", "getSkillCategoryId", "frontmatterMatch", "frontmatter", "nameMatch", "descMatch", "getSkillByName", "s", "truncate", "text", "maxLength", "ConfirmPrompt", "MultiSelectPrompt", "SelectPrompt", "pc", "gradient", "pc", "crystalGradient", "S_BAR", "S_BAR_END", "S_RADIO_ACTIVE", "S_RADIO_INACTIVE", "S_CHECKBOX_ACTIVE", "S_CHECKBOX_INACTIVE", "SYMBOL", "logBar", "message", "logBarEnd", "logCancelled", "isCancelled", "value", "blueSelectWithBack", "message", "options", "initialValue", "allowBack", "opt", "option", "isActive", "radio", "pc", "S_RADIO_ACTIVE", "S_RADIO_INACTIVE", "label", "hint", "result", "SelectPrompt", "title", "S_BAR", "SYMBOL", "backHint", "o", "i", "S_BAR_END", "blueMultiSelectWithBack", "initialValues", "state", "isSelected", "checkbox", "S_CHECKBOX_ACTIVE", "S_CHECKBOX_INACTIVE", "MultiSelectPrompt", "blueConfirm", "ConfirmPrompt", "figlet", "pc", "generateLogo", "asciiArt", "figlet", "crystalGradient", "pc", "initScreen", "logBar", "createRequire", "packageJson", "PACKAGE_NAME", "checkForUpdates", "currentVersion", "result", "getCurrentVersion", "pc", "showInstallationSummary", "options", "logBar", "pc", "S_BAR", "showInstallResults", "results", "successful", "r", "alreadyExists", "failed", "SYMBOL", "totalAgents", "logBarEnd", "showRemoveResults", "skillName", "pc", "buildAgentOptions", "agents", "detectedAgents", "type", "config", "getAgentConfig", "isDetected", "pc", "truncate", "getInstalledSkillNames", "global", "installed", "agent", "listInstalledSkills", "skill", "getAllInstalledSkillNames", "globalSkills", "localSkills", "ALL_SKILLS_VALUE", "ALL_CATEGORIES_VALUE", "runInteractiveInstall", "initScreen", "checkEnvironment", "allSkills", "discoverSkills", "logBarEnd", "pc", "installedAgents", "detectInstalledAgents", "allAgents", "getAllAgentTypes", "targetAgents", "installedSkills", "getAllInstalledSkillNames", "state", "currentStep", "totalSteps", "stepIndicator", "allowBack", "result", "selectCategoryStep", "selectSkillsStep", "selectAgentsStep", "configureInstallationStep", "currentVersion", "getCurrentVersion", "latestVersion", "checkForUpdates", "logBar", "isGloballyInstalled", "currentCategory", "groupedSkills", "groupSkillsByCategory", "categoryList", "categoryOptions", "cat", "skillCount", "selectedCategory", "blueSelectWithBack", "isCancelled", "logCancelled", "filteredSkills", "skill", "skillOptions", "isInstalled", "truncate", "initialSkills", "selectedSkills", "blueMultiSelectWithBack", "skillsArray", "validSkills", "s", "currentAgents", "agentOptions", "buildAgentOptions", "selectedAgents", "validAgents", "methodOptions", "method", "showInstallationSummary", "scopeResult", "selectScope", "confirm", "blueConfirm", "scope", "pc", "showAvailableSkills", "initScreen", "skills", "discoverSkills", "logBar", "pc", "allAgents", "getAllAgentTypes", "installedSkills", "getAllInstalledSkillNames", "groupedSkills", "groupSkillsByCategory", "category", "categorySkills", "skill", "installedBadge", "S_BAR", "logBarEnd", "pc", "runInteractiveRemove", "global", "initScreen", "allAgents", "getAllAgentTypes", "installedSkills", "getInstalledSkillNames", "logBar", "pc", "logBarEnd", "skillsArray", "selectedSkills", "blueMultiSelectWithBack", "name", "isCancelled", "logCancelled", "selectedAgents", "buildAgentOptions", "opt", "confirm", "blueConfirm", "skillName", "results", "removeSkill", "showRemoveResults", "program", "Command", "package_default", "options", "runNonInteractive", "installOptions", "runInteractiveInstall", "skills", "discoverSkills", "s", "results", "installSkills", "showInstallResults", "showAvailableSkills", "agents", "removeSkill", "showRemoveResults", "runInteractiveRemove", "allSkills", "skill", "getSkillByName", "method"]
|
|
7
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tech-leads-club/agent-skills",
|
|
3
|
-
"version": "0.1.0
|
|
4
|
-
"description": "CLI to install skills for AI coding agents",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "CLI to install and manage skills for AI coding agents",
|
|
5
5
|
"author": "Tech Leads Club",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -33,17 +33,16 @@
|
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@clack/core": "^0.5.0",
|
|
35
35
|
"@clack/prompts": "^0.11.0",
|
|
36
|
+
"@types/figlet": "1.7.0",
|
|
36
37
|
"chalk": "^5.6.2",
|
|
37
38
|
"commander": "^14.0.2",
|
|
38
39
|
"figlet": "^1.10.0",
|
|
39
40
|
"gradient-string": "^3.0.0",
|
|
40
41
|
"package-json": "^10.0.1",
|
|
41
|
-
"picocolors": "^1.1.1"
|
|
42
|
+
"picocolors": "^1.1.1",
|
|
43
|
+
"tsx": "4.21.0",
|
|
44
|
+
"@jest/globals": "30.2.0"
|
|
42
45
|
},
|
|
43
|
-
"
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"tsx": "^4.21.0",
|
|
47
|
-
"typescript": "^5.9.3"
|
|
48
|
-
}
|
|
49
|
-
}
|
|
46
|
+
"module": "./index.js",
|
|
47
|
+
"main": "./index.js"
|
|
48
|
+
}
|
package/CHANGELOG.md
DELETED
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
## 0.1.0-beta.3 (2026-01-25)
|
|
2
|
-
|
|
3
|
-
### 🚀 Features
|
|
4
|
-
|
|
5
|
-
- add installation summary display for skills and agents ([13dc11f](https://github.com/tech-leads-club/agent-skills/commit/13dc11f))
|
|
6
|
-
- implement interactive installation wizard for skills and agents ([3bdd983](https://github.com/tech-leads-club/agent-skills/commit/3bdd983))
|
|
7
|
-
- add function to display available skills with installation status ([c8896e1](https://github.com/tech-leads-club/agent-skills/commit/c8896e1))
|
|
8
|
-
- implement interactive skill removal process ([5ea69a4](https://github.com/tech-leads-club/agent-skills/commit/5ea69a4))
|
|
9
|
-
- add functions to display installation and removal results ([4606e3c](https://github.com/tech-leads-club/agent-skills/commit/4606e3c))
|
|
10
|
-
- add utility functions for agent options and installed skills ([f54e25c](https://github.com/tech-leads-club/agent-skills/commit/f54e25c))
|
|
11
|
-
- add truncate function for text length management ([70870b0](https://github.com/tech-leads-club/agent-skills/commit/70870b0))
|
|
12
|
-
- implement blue select and confirm prompts with back navigation ([21b05e1](https://github.com/tech-leads-club/agent-skills/commit/21b05e1))
|
|
13
|
-
- add logo generation and screen initialization functions ([359e6a2](https://github.com/tech-leads-club/agent-skills/commit/359e6a2))
|
|
14
|
-
- add gradient styles and logging functions for UI components ([75fb2e5](https://github.com/tech-leads-club/agent-skills/commit/75fb2e5))
|
|
15
|
-
- update skills directory logic and enhance skill discovery ([da1aff9](https://github.com/tech-leads-club/agent-skills/commit/da1aff9))
|
|
16
|
-
- add unit tests for categories configuration and logic ([ca4e001](https://github.com/tech-leads-club/agent-skills/commit/ca4e001))
|
|
17
|
-
- implement category management and skill assignment functionality ([7eb3bb2](https://github.com/tech-leads-club/agent-skills/commit/7eb3bb2))
|
|
18
|
-
- add detailed install result interface for better tracking ([0d48a0b](https://github.com/tech-leads-club/agent-skills/commit/0d48a0b))
|
|
19
|
-
- implement skill lock file management functions ([c8b6e1d](https://github.com/tech-leads-club/agent-skills/commit/c8b6e1d))
|
|
20
|
-
- enhance skill installation process with symlink and copy methods ([195ffa0](https://github.com/tech-leads-club/agent-skills/commit/195ffa0))
|
|
21
|
-
- add remove command for uninstalling skills ([a8be796](https://github.com/tech-leads-club/agent-skills/commit/a8be796))
|
|
22
|
-
- add function to find project root directory ([1cfe620](https://github.com/tech-leads-club/agent-skills/commit/1cfe620))
|
|
23
|
-
- use project root for skill installation paths ([f27e81c](https://github.com/tech-leads-club/agent-skills/commit/f27e81c))
|
|
24
|
-
- enhance agent installation detection for project root ([b7fca84](https://github.com/tech-leads-club/agent-skills/commit/b7fca84))
|
|
25
|
-
- add global path utilities for skill management ([36f45e5](https://github.com/tech-leads-club/agent-skills/commit/36f45e5))
|
|
26
|
-
- implement global symlink handling for skill installation ([b45b92e](https://github.com/tech-leads-club/agent-skills/commit/b45b92e))
|
|
27
|
-
- add update check functionality for package versioning ([e034070](https://github.com/tech-leads-club/agent-skills/commit/e034070))
|
|
28
|
-
- enhance installer tests with global symlink handling ([b44be21](https://github.com/tech-leads-club/agent-skills/commit/b44be21))
|
|
29
|
-
- add project configuration for CLI application ([1ee7ad5](https://github.com/tech-leads-club/agent-skills/commit/1ee7ad5))
|
|
30
|
-
|
|
31
|
-
### ❤️ Thank You
|
|
32
|
-
|
|
33
|
-
- Felipe Rodrigues @felipfr
|
|
34
|
-
|
|
35
|
-
## 0.1.0-beta.2 (2026-01-25)
|
|
36
|
-
|
|
37
|
-
### 🚀 Features
|
|
38
|
-
|
|
39
|
-
- add .nvmrc file with Node.js version ([2b0071d](https://github.com/tech-leads-club/agent-skills/commit/2b0071d))
|
|
40
|
-
- add TypeScript configuration for project setup ([1abc21f](https://github.com/tech-leads-club/agent-skills/commit/1abc21f))
|
|
41
|
-
- add guide for creating AI subagents with isolated context ([0c130d8](https://github.com/tech-leads-club/agent-skills/commit/0c130d8))
|
|
42
|
-
- add spec-driven development skill for feature planning ([dfaac3f](https://github.com/tech-leads-club/agent-skills/commit/dfaac3f))
|
|
43
|
-
- add design, implementation, task, and validation documentation ([e5f7904](https://github.com/tech-leads-club/agent-skills/commit/e5f7904))
|
|
44
|
-
- add skill-creator guide for effective AI agent skills ([b0b5674](https://github.com/tech-leads-club/agent-skills/commit/b0b5674))
|
|
45
|
-
- update cursor skill creator description and name for clarity ([997b35e](https://github.com/tech-leads-club/agent-skills/commit/997b35e))
|
|
46
|
-
- add cursor subagent creator skill for complex workflows ([6e1b6f0](https://github.com/tech-leads-club/agent-skills/commit/6e1b6f0))
|
|
47
|
-
- implement skill installation and listing functionality ([ba9cb2c](https://github.com/tech-leads-club/agent-skills/commit/ba9cb2c))
|
|
48
|
-
- implement interactive skill installation and listing commands ([945f255](https://github.com/tech-leads-club/agent-skills/commit/945f255))
|
|
49
|
-
- add agent configuration and detection functionality ([b35851a](https://github.com/tech-leads-club/agent-skills/commit/b35851a))
|
|
50
|
-
- add interactive skill installation and management prompts ([fe52459](https://github.com/tech-leads-club/agent-skills/commit/fe52459))
|
|
51
|
-
- implement skill discovery and management functions ([4fd5139](https://github.com/tech-leads-club/agent-skills/commit/4fd5139))
|
|
52
|
-
- add interfaces for agent configuration and skill management ([74ea8f8](https://github.com/tech-leads-club/agent-skills/commit/74ea8f8))
|
|
53
|
-
- add TypeScript configuration for testing with Jest ([32aa9a1](https://github.com/tech-leads-club/agent-skills/commit/32aa9a1))
|
|
54
|
-
- add TypeScript configuration for CLI package ([f23d900](https://github.com/tech-leads-club/agent-skills/commit/f23d900))
|
|
55
|
-
- add initial CLI package configuration for agent skills ([072af1d](https://github.com/tech-leads-club/agent-skills/commit/072af1d))
|
|
56
|
-
- add Jest configuration for CLI testing ([b7d098e](https://github.com/tech-leads-club/agent-skills/commit/b7d098e))
|
|
57
|
-
- add release workflow for automated deployment on push ([195cad7](https://github.com/tech-leads-club/agent-skills/commit/195cad7))
|
|
58
|
-
- add CI configuration for validating skills structure ([66fa03b](https://github.com/tech-leads-club/agent-skills/commit/66fa03b))
|
|
59
|
-
- add TypeScript configuration for project setup ([2a7ee33](https://github.com/tech-leads-club/agent-skills/commit/2a7ee33))
|
|
60
|
-
- add comprehensive README for agent skills documentation ([7f7063d](https://github.com/tech-leads-club/agent-skills/commit/7f7063d))
|
|
61
|
-
- add symlink for AGENTS.md to CLAUDE.md ([a429576](https://github.com/tech-leads-club/agent-skills/commit/a429576))
|
|
62
|
-
- add AGENTS.md for guidance on AI coding agents ([3e0917d](https://github.com/tech-leads-club/agent-skills/commit/3e0917d))
|
|
63
|
-
- add initial configuration ([4584775](https://github.com/tech-leads-club/agent-skills/commit/4584775))
|
|
64
|
-
- add nx configuration for project management and build processes ([c937d0e](https://github.com/tech-leads-club/agent-skills/commit/c937d0e))
|
|
65
|
-
- add Jest configuration for project testing ([c5141b9](https://github.com/tech-leads-club/agent-skills/commit/c5141b9))
|
|
66
|
-
- add Jest preset configuration for TypeScript testing ([df7f962](https://github.com/tech-leads-club/agent-skills/commit/df7f962))
|
|
67
|
-
- add ESLint configuration for TypeScript with recommended rules ([7e04b65](https://github.com/tech-leads-club/agent-skills/commit/7e04b65))
|
|
68
|
-
|
|
69
|
-
### ❤️ Thank You
|
|
70
|
-
|
|
71
|
-
- Felipe Rodrigues @felipfr
|
|
72
|
-
|
|
73
|
-
## 0.1.0-beta.1 (2026-01-25)
|
|
74
|
-
|
|
75
|
-
### 🚀 Features
|
|
76
|
-
|
|
77
|
-
- add .nvmrc file with Node.js version ([2b0071d](https://github.com/tech-leads-club/agent-skills/commit/2b0071d))
|
|
78
|
-
- add TypeScript configuration for project setup ([1abc21f](https://github.com/tech-leads-club/agent-skills/commit/1abc21f))
|
|
79
|
-
- add guide for creating AI subagents with isolated context ([0c130d8](https://github.com/tech-leads-club/agent-skills/commit/0c130d8))
|
|
80
|
-
- add spec-driven development skill for feature planning ([dfaac3f](https://github.com/tech-leads-club/agent-skills/commit/dfaac3f))
|
|
81
|
-
- add design, implementation, task, and validation documentation ([e5f7904](https://github.com/tech-leads-club/agent-skills/commit/e5f7904))
|
|
82
|
-
- add skill-creator guide for effective AI agent skills ([b0b5674](https://github.com/tech-leads-club/agent-skills/commit/b0b5674))
|
|
83
|
-
- update cursor skill creator description and name for clarity ([997b35e](https://github.com/tech-leads-club/agent-skills/commit/997b35e))
|
|
84
|
-
- add cursor subagent creator skill for complex workflows ([6e1b6f0](https://github.com/tech-leads-club/agent-skills/commit/6e1b6f0))
|
|
85
|
-
- implement skill installation and listing functionality ([ba9cb2c](https://github.com/tech-leads-club/agent-skills/commit/ba9cb2c))
|
|
86
|
-
- implement interactive skill installation and listing commands ([945f255](https://github.com/tech-leads-club/agent-skills/commit/945f255))
|
|
87
|
-
- add agent configuration and detection functionality ([b35851a](https://github.com/tech-leads-club/agent-skills/commit/b35851a))
|
|
88
|
-
- add interactive skill installation and management prompts ([fe52459](https://github.com/tech-leads-club/agent-skills/commit/fe52459))
|
|
89
|
-
- implement skill discovery and management functions ([4fd5139](https://github.com/tech-leads-club/agent-skills/commit/4fd5139))
|
|
90
|
-
- add interfaces for agent configuration and skill management ([74ea8f8](https://github.com/tech-leads-club/agent-skills/commit/74ea8f8))
|
|
91
|
-
- add TypeScript configuration for testing with Jest ([32aa9a1](https://github.com/tech-leads-club/agent-skills/commit/32aa9a1))
|
|
92
|
-
- add TypeScript configuration for CLI package ([f23d900](https://github.com/tech-leads-club/agent-skills/commit/f23d900))
|
|
93
|
-
- add initial CLI package configuration for agent skills ([072af1d](https://github.com/tech-leads-club/agent-skills/commit/072af1d))
|
|
94
|
-
- add Jest configuration for CLI testing ([b7d098e](https://github.com/tech-leads-club/agent-skills/commit/b7d098e))
|
|
95
|
-
- add release workflow for automated deployment on push ([195cad7](https://github.com/tech-leads-club/agent-skills/commit/195cad7))
|
|
96
|
-
- add CI configuration for validating skills structure ([66fa03b](https://github.com/tech-leads-club/agent-skills/commit/66fa03b))
|
|
97
|
-
- add TypeScript configuration for project setup ([2a7ee33](https://github.com/tech-leads-club/agent-skills/commit/2a7ee33))
|
|
98
|
-
- add comprehensive README for agent skills documentation ([7f7063d](https://github.com/tech-leads-club/agent-skills/commit/7f7063d))
|
|
99
|
-
- add symlink for AGENTS.md to CLAUDE.md ([a429576](https://github.com/tech-leads-club/agent-skills/commit/a429576))
|
|
100
|
-
- add AGENTS.md for guidance on AI coding agents ([3e0917d](https://github.com/tech-leads-club/agent-skills/commit/3e0917d))
|
|
101
|
-
- add initial configuration ([4584775](https://github.com/tech-leads-club/agent-skills/commit/4584775))
|
|
102
|
-
- add nx configuration for project management and build processes ([c937d0e](https://github.com/tech-leads-club/agent-skills/commit/c937d0e))
|
|
103
|
-
- add Jest configuration for project testing ([c5141b9](https://github.com/tech-leads-club/agent-skills/commit/c5141b9))
|
|
104
|
-
- add Jest preset configuration for TypeScript testing ([df7f962](https://github.com/tech-leads-club/agent-skills/commit/df7f962))
|
|
105
|
-
- add ESLint configuration for TypeScript with recommended rules ([7e04b65](https://github.com/tech-leads-club/agent-skills/commit/7e04b65))
|
|
106
|
-
|
|
107
|
-
### ❤️ Thank You
|
|
108
|
-
|
|
109
|
-
- Felipe Rodrigues @felipfr
|
|
110
|
-
|
|
111
|
-
## 0.1.0-beta.0 (2026-01-25)
|
|
112
|
-
|
|
113
|
-
### 🚀 Features
|
|
114
|
-
|
|
115
|
-
- add TypeScript configuration for project setup ([1abc21f](https://github.com/tech-leads-club/agent-skills/commit/1abc21f))
|
|
116
|
-
- add guide for creating AI subagents with isolated context ([0c130d8](https://github.com/tech-leads-club/agent-skills/commit/0c130d8))
|
|
117
|
-
- add spec-driven development skill for feature planning ([dfaac3f](https://github.com/tech-leads-club/agent-skills/commit/dfaac3f))
|
|
118
|
-
- add design, implementation, task, and validation documentation ([e5f7904](https://github.com/tech-leads-club/agent-skills/commit/e5f7904))
|
|
119
|
-
- add skill-creator guide for effective AI agent skills ([b0b5674](https://github.com/tech-leads-club/agent-skills/commit/b0b5674))
|
|
120
|
-
- update cursor skill creator description and name for clarity ([997b35e](https://github.com/tech-leads-club/agent-skills/commit/997b35e))
|
|
121
|
-
- add cursor subagent creator skill for complex workflows ([6e1b6f0](https://github.com/tech-leads-club/agent-skills/commit/6e1b6f0))
|
|
122
|
-
- implement skill installation and listing functionality ([ba9cb2c](https://github.com/tech-leads-club/agent-skills/commit/ba9cb2c))
|
|
123
|
-
- implement interactive skill installation and listing commands ([945f255](https://github.com/tech-leads-club/agent-skills/commit/945f255))
|
|
124
|
-
- add agent configuration and detection functionality ([b35851a](https://github.com/tech-leads-club/agent-skills/commit/b35851a))
|
|
125
|
-
- add interactive skill installation and management prompts ([fe52459](https://github.com/tech-leads-club/agent-skills/commit/fe52459))
|
|
126
|
-
- implement skill discovery and management functions ([4fd5139](https://github.com/tech-leads-club/agent-skills/commit/4fd5139))
|
|
127
|
-
- add interfaces for agent configuration and skill management ([74ea8f8](https://github.com/tech-leads-club/agent-skills/commit/74ea8f8))
|
|
128
|
-
- add TypeScript configuration for testing with Jest ([32aa9a1](https://github.com/tech-leads-club/agent-skills/commit/32aa9a1))
|
|
129
|
-
- add TypeScript configuration for CLI package ([f23d900](https://github.com/tech-leads-club/agent-skills/commit/f23d900))
|
|
130
|
-
- add initial CLI package configuration for agent skills ([072af1d](https://github.com/tech-leads-club/agent-skills/commit/072af1d))
|
|
131
|
-
- add Jest configuration for CLI testing ([b7d098e](https://github.com/tech-leads-club/agent-skills/commit/b7d098e))
|
|
132
|
-
- add release workflow for automated deployment on push ([195cad7](https://github.com/tech-leads-club/agent-skills/commit/195cad7))
|
|
133
|
-
- add CI configuration for validating skills structure ([66fa03b](https://github.com/tech-leads-club/agent-skills/commit/66fa03b))
|
|
134
|
-
- add TypeScript configuration for project setup ([2a7ee33](https://github.com/tech-leads-club/agent-skills/commit/2a7ee33))
|
|
135
|
-
- add comprehensive README for agent skills documentation ([7f7063d](https://github.com/tech-leads-club/agent-skills/commit/7f7063d))
|
|
136
|
-
- add symlink for AGENTS.md to CLAUDE.md ([a429576](https://github.com/tech-leads-club/agent-skills/commit/a429576))
|
|
137
|
-
- add AGENTS.md for guidance on AI coding agents ([3e0917d](https://github.com/tech-leads-club/agent-skills/commit/3e0917d))
|
|
138
|
-
- add initial configuration ([4584775](https://github.com/tech-leads-club/agent-skills/commit/4584775))
|
|
139
|
-
- add nx configuration for project management and build processes ([c937d0e](https://github.com/tech-leads-club/agent-skills/commit/c937d0e))
|
|
140
|
-
- add Jest configuration for project testing ([c5141b9](https://github.com/tech-leads-club/agent-skills/commit/c5141b9))
|
|
141
|
-
- add Jest preset configuration for TypeScript testing ([df7f962](https://github.com/tech-leads-club/agent-skills/commit/df7f962))
|
|
142
|
-
- add ESLint configuration for TypeScript with recommended rules ([7e04b65](https://github.com/tech-leads-club/agent-skills/commit/7e04b65))
|
|
143
|
-
|
|
144
|
-
### ❤️ Thank You
|
|
145
|
-
|
|
146
|
-
- Felipe Rodrigues @felipfr
|