@tech-leads-club/agent-skills 0.0.0-snapshot-5

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 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/README.md ADDED
@@ -0,0 +1,313 @@
1
+ <p align="center">
2
+ <img src="https://img.shields.io/npm/v/@tech-leads-club/agent-skills?style=flat-square&color=blue" alt="npm version" />
3
+ <img src="https://img.shields.io/npm/dt/@tech-leads-club/agent-skills?style=flat-square&color=blue" alt="total downloads" />
4
+ <img src="https://img.shields.io/npm/dm/@tech-leads-club/agent-skills?style=flat-square&color=blue" alt="monthly downloads" />
5
+ <img src="https://img.shields.io/github/license/tech-leads-club/agent-skills?style=flat-square" alt="license" />
6
+ <img src="https://img.shields.io/github/actions/workflow/status/tech-leads-club/agent-skills/ci.yml?style=flat-square" alt="build status" />
7
+ </p>
8
+
9
+ <p align="center">
10
+ <img src="https://img.shields.io/badge/node-%3E%3D22-brightgreen?style=flat-square&logo=node.js" alt="node version" />
11
+ <img src="https://img.shields.io/badge/TypeScript-100%25-blue?style=flat-square&logo=typescript" alt="typescript" />
12
+ <img src="https://img.shields.io/badge/Nx%20Cloud-Enabled-blue?style=flat-square&logo=nx" alt="nx cloud" />
13
+ <img src="https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=flat-square" alt="semantic-release" />
14
+ </p>
15
+
16
+ <p align="center">
17
+ <img src="https://img.shields.io/github/stars/tech-leads-club/agent-skills?style=flat-square&color=yellow" alt="github stars" />
18
+ <img src="https://img.shields.io/github/contributors/tech-leads-club/agent-skills?style=flat-square&color=orange" alt="contributors" />
19
+ <img src="https://img.shields.io/github/last-commit/tech-leads-club/agent-skills?style=flat-square" alt="last commit" />
20
+ <img src="https://img.shields.io/badge/AI-Powered%20Skills-purple?style=flat-square&logo=openai" alt="ai powered" />
21
+ </p>
22
+
23
+ <h1 align="center">🧠 Agent Skills</h1>
24
+
25
+ <p align="center">
26
+ <strong>A curated collection of skills for AI coding agents</strong>
27
+ </p>
28
+
29
+ <p align="center">
30
+ Extend the capabilities of <b>Antigravity</b>, <b>Claude Code</b>, <b>Cursor</b>, <b>GitHub Copilot</b>, and more with reusable, packaged instructions.
31
+ </p>
32
+
33
+ ---
34
+
35
+ ## ✨ What are Skills?
36
+
37
+ Skills are packaged instructions and resources that extend AI agent capabilities. Think of them as **plugins for your AI assistant** — they teach your agent new workflows, patterns, and specialized knowledge.
38
+
39
+ ```
40
+ skills/
41
+ spec-driven-dev/
42
+ SKILL.md ← Main instructions
43
+ templates/ ← File templates
44
+ references/ ← On-demand documentation
45
+ ```
46
+
47
+ ## 🚀 Quick Start
48
+
49
+ ### Install Skills in Your Project
50
+
51
+ ```bash
52
+ npx @tech-leads-club/agent-skills
53
+ ```
54
+
55
+ This launches an interactive wizard with 5 steps:
56
+
57
+ 1. **Browse categories** — Filter skills by category or select "All"
58
+ 2. **Select skills** — Choose which skills to install
59
+ 3. **Choose agents** — Pick target agents (Cursor, Claude Code, etc.)
60
+ 4. **Installation method** — Symlink (recommended) or Copy
61
+ 5. **Scope** — Global (user home) or Local (project only)
62
+
63
+ Each step shows a **← Back** option to return to the previous step and revise your choices. A confirmation summary is shown before installation.
64
+
65
+ ### CLI Options
66
+
67
+ ```bash
68
+ # Interactive mode (default)
69
+ npx @tech-leads-club/agent-skills
70
+
71
+ # Install globally (to ~/.agent/skills, ~/.claude/skills, etc.)
72
+ npx @tech-leads-club/agent-skills install -g
73
+
74
+ # List available skills
75
+ npx @tech-leads-club/agent-skills list
76
+
77
+ # Install a specific skill
78
+ npx @tech-leads-club/agent-skills install -s spec-driven-dev
79
+
80
+ # Install to specific agents
81
+ npx @tech-leads-club/agent-skills install -a antigravity cursor
82
+
83
+ # Use copy instead of symlink
84
+ npx @tech-leads-club/agent-skills install --copy
85
+
86
+ # Remove skills (interactive)
87
+ npx @tech-leads-club/agent-skills remove
88
+
89
+ # Remove a specific skill
90
+ npx @tech-leads-club/agent-skills remove -s spec-driven-dev
91
+
92
+ # Remove from global installation
93
+ npx @tech-leads-club/agent-skills remove -g -s spec-driven-dev
94
+
95
+ # Show help
96
+ npx @tech-leads-club/agent-skills --help
97
+ npx @tech-leads-club/agent-skills install --help
98
+ npx @tech-leads-club/agent-skills remove --help
99
+ ```
100
+
101
+ ---
102
+
103
+ ## 📦 Available Skills
104
+
105
+ Skills are organized by category for easier navigation.
106
+
107
+ ### 🔧 Development
108
+
109
+ | Skill | Description |
110
+ |-------|-------------|
111
+ | **spec-driven-dev** | Specification-driven development workflow with 4 phases: specify → design → tasks → implement+validate |
112
+
113
+ ### 🛠 Skill & Agent Creation
114
+
115
+ | Skill | Description |
116
+ |-------|-------------|
117
+ | **skill-creator** | Meta-skill for creating new skills following best practices |
118
+ | **subagent-creator** | Create specialized subagents for complex tasks |
119
+ | **cursor-skill-creator** | Cursor-specific skill creation |
120
+ | **cursor-subagent-creator** | Cursor-specific subagent creation |
121
+
122
+ ---
123
+
124
+ ## 🛠 For Contributors
125
+
126
+ ### Prerequisites
127
+
128
+ - **Node.js** ≥ 22
129
+ - **npm** (comes with Node.js)
130
+
131
+ ### Setup
132
+
133
+ ```bash
134
+ # Clone the repository
135
+ git clone https://github.com/tech-leads-club/agent-skills.git
136
+ cd agent-skills
137
+
138
+ # Install dependencies
139
+ npm ci
140
+
141
+ # Build all packages
142
+ npm run build
143
+ ```
144
+
145
+ ### Development Commands
146
+
147
+ | Command | Description |
148
+ |---------|-------------|
149
+ | `npm run start:dev` | Run CLI locally (interactive mode) |
150
+ | `npm run g <name>` | Generate a new skill |
151
+ | `npm run build` | Build all packages |
152
+ | `npm run test` | Run all tests |
153
+ | `npm run lint` | Lint codebase |
154
+ | `npm run lint:fix` | Fix lint issues |
155
+ | `npm run format` | Format code with Prettier |
156
+ | `npm run release:dry` | Preview release (dry-run) |
157
+
158
+ ### Creating a New Skill
159
+
160
+ Use the NX generator:
161
+
162
+ ```bash
163
+ # Basic usage (will prompt for category)
164
+ nx g @tech-leads-club/skill-plugin:skill my-awesome-skill
165
+
166
+ # With category specified
167
+ nx g @tech-leads-club/skill-plugin:skill my-awesome-skill --category=development
168
+
169
+ # With all options
170
+ nx g @tech-leads-club/skill-plugin:skill my-skill \
171
+ --description="What my skill does" \
172
+ --category=development
173
+ ```
174
+
175
+ The generator will:
176
+
177
+ - Create `skills/my-skill/SKILL.md` with the correct template structure
178
+ - Assign the skill to the specified category (creating it if needed)
179
+ - If no category is specified, the skill will appear as "Uncategorized"
180
+
181
+ ### Skill Structure
182
+
183
+ ```
184
+ skills/my-skill/
185
+ ├── SKILL.md # Required: main instructions
186
+ ├── scripts/ # Optional: executable scripts
187
+ ├── references/ # Optional: on-demand documentation
188
+ ├── templates/ # Optional: file templates
189
+ └── assets/ # Optional: images, files
190
+ ```
191
+
192
+ ### Skill Categories
193
+
194
+ Skills are organized into categories for better navigation in the CLI. Categories are defined in `skills/categories.json`.
195
+
196
+ #### Adding a Skill to a Category
197
+
198
+ Edit `skills/categories.json` and add your skill to the `skills` map:
199
+
200
+ ```json
201
+ {
202
+ "categories": [
203
+ { "id": "development", "name": "Development", "priority": 1 },
204
+ { "id": "creation", "name": "Skill & Agent Creation", "priority": 2 }
205
+ ],
206
+ "skills": {
207
+ "my-new-skill": "development"
208
+ }
209
+ }
210
+ ```
211
+
212
+ #### Creating a New Category
213
+
214
+ Add a new entry to the `categories` array:
215
+
216
+ ```json
217
+ {
218
+ "id": "my-category",
219
+ "name": "My Category",
220
+ "description": "Optional description",
221
+ "priority": 3
222
+ }
223
+ ```
224
+
225
+ - `id`: Unique identifier (kebab-case)
226
+ - `name`: Display name in the CLI
227
+ - `description`: Optional description
228
+ - `priority`: Display order (lower = first)
229
+
230
+ ### SKILL.md Format
231
+
232
+ ```markdown
233
+ ---
234
+ name: my-skill
235
+ description: What this skill does. Use when user says "trigger phrase".
236
+ ---
237
+
238
+ # My Skill
239
+
240
+ Brief description.
241
+
242
+ ## Process
243
+
244
+ 1. Step one
245
+ 2. Step two
246
+ 3. ...
247
+ ```
248
+
249
+ ### Best Practices
250
+
251
+ - **Keep SKILL.md under 500 lines** — use `references/` for detailed docs
252
+ - **Write specific descriptions** — include trigger phrases
253
+ - **Assume the agent is smart** — only add what it doesn't already know
254
+ - **Prefer scripts over inline code** — reduces context window usage
255
+
256
+ ---
257
+
258
+ ## 📁 Project Structure
259
+
260
+ ```
261
+ agent-skills/
262
+ ├── packages/
263
+ │ └── cli/ # @tech-leads-club/agent-skills CLI package
264
+ ├── tools/
265
+ │ └── skill-plugin/ # NX generator plugin
266
+ ├── skills/ # Skill definitions
267
+ │ ├── categories.json # Skill category mappings
268
+ │ └── [skill-name]/ # Individual skill folders
269
+ ├── .github/
270
+ │ └── workflows/
271
+ │ ├── ci.yml # CI: lint, test, build
272
+ │ └── release.yml # Release: version, publish
273
+ ├── nx.json # NX configuration
274
+ └── package.json # Root package.json
275
+ ```
276
+
277
+ ---
278
+
279
+ ## 🔄 Release Process
280
+
281
+ This project uses **NX Release** with **Conventional Commits** for automated versioning:
282
+
283
+ | Commit Prefix | Version Bump | Example |
284
+ |---------------|--------------|---------|
285
+ | `feat:` | Minor (0.X.0) | `feat: add new skill` |
286
+ | `fix:` | Patch (0.0.X) | `fix: correct symlink path` |
287
+ | `feat!:` | Major (X.0.0) | `feat!: breaking API change` |
288
+ | `docs:` | No bump | `docs: update README` |
289
+ | `chore:` | No bump | `chore: update deps` |
290
+
291
+ Releases are automated via GitHub Actions when merging to `main`.
292
+
293
+ ---
294
+
295
+ ## 🤝 Contributing
296
+
297
+ 1. **Fork** the repository
298
+ 2. **Create** a feature branch (`git checkout -b feat/amazing-skill`)
299
+ 3. **Commit** with conventional commits (`git commit -m "feat: add amazing skill"`)
300
+ 4. **Push** to your fork (`git push origin feat/amazing-skill`)
301
+ 5. **Open** a Pull Request
302
+
303
+ ---
304
+
305
+ ## 📄 License
306
+
307
+ MIT © [Tech Leads Club](https://github.com/tech-leads-club)
308
+
309
+ ---
310
+
311
+ <p align="center">
312
+ <sub>Built with ❤️ by the Tech Leads Club community</sub>
313
+ </p>
package/index.js ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env node
2
+ import{Command as Qt}from"commander";var de={name:"@tech-leads-club/agent-skills",version:"0.0.0-snapshot-5",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)}
3
+ ${T} ${s.white(s.bold(e))}
4
+ `,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)}
5
+ ${s.blue(k)}`;case"cancel":return`${a}${s.blue(k)} ${s.strikethrough(s.gray("back"))}
6
+ ${s.blue(k)}`;default:return`${a}${this.options.map((f,u)=>`${s.blue(k)} ${l(f,u===this.cursor)}`).join(`
7
+ `)}
8
+ ${s.blue(k)}
9
+ ${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)}
10
+ ${T} ${s.white(s.bold(e))}
11
+ `,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(", "))}
12
+ ${s.blue(k)}`;case"cancel":return`${a}${s.blue(k)} ${s.strikethrough(s.gray("back"))}
13
+ ${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(`
14
+ `)}
15
+ ${s.blue(k)}
16
+ ${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)}
17
+ ${T} ${s.white(s.bold(e))}
18
+ `;switch(this.state){case"submit":return`${n}${s.blue(k)} ${s.blue(this.value?"Yes":"No")}
19
+ ${s.blue(k)}`;case"cancel":return`${n}${s.blue(k)} ${s.strikethrough(s.gray("cancelled"))}
20
+ ${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")}`}
21
+ ${s.blue(k)}
22
+ ${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`
23
+ ${Ge.multiline(e)}
24
+ ${N.white(N.bold("Tech Leads Club"))} ${N.blue("\u203A")} ${N.bold(N.blue("Agent Skills"))}
25
+ ${N.white("Curated skills to power up your AI coding agents")}
26
+ `}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();
27
+ //# sourceMappingURL=index.js.map