@tech-leads-club/agent-skills 0.5.2 → 0.6.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/README.md +70 -73
- package/index.js +23 -23
- package/index.js.map +4 -4
- package/package.json +3 -2
- package/skills/(cloud)/aws-advisor/SKILL.md +206 -0
- package/skills/(cloud)/aws-advisor/references/checklists.md +238 -0
- package/skills/(cloud)/aws-advisor/references/decision-trees.md +214 -0
- package/skills/(cloud)/aws-advisor/references/mcp-guide.md +156 -0
- package/skills/(cloud)/aws-advisor/scripts/architecture_validator.py +312 -0
- package/skills/(cloud)/aws-advisor/scripts/cost_considerations.py +330 -0
- package/skills/(cloud)/aws-advisor/scripts/generate_diagram.py +368 -0
- package/skills/(cloud)/aws-advisor/scripts/security_review.py +244 -0
- package/skills/(cloud)/aws-advisor/scripts/well_architected_review.py +325 -0
- package/skills/(development)/coding-guidelines/SKILL.md +74 -0
- package/skills/(development)/docs-writer/SKILL.md +39 -0
- package/skills/(development)/docs-writer/references/style-guide.md +72 -0
- package/skills/(tooling)/nx-ci-monitor/SKILL.md +449 -0
- package/skills/(tooling)/nx-generate/SKILL.md +228 -0
- package/skills/(tooling)/nx-run-tasks/SKILL.md +58 -0
- package/skills/(tooling)/nx-workspace/SKILL.md +140 -0
- package/skills/(tooling)/nx-workspace/reference/best-practices.md +451 -0
- package/skills/(tooling)/nx-workspace/reference/ci-cd.md +387 -0
- package/skills/(tooling)/nx-workspace/reference/commands.md +378 -0
- package/skills/(tooling)/nx-workspace/reference/configuration.md +314 -0
- package/skills/(tooling)/run-nx-generator/SKILL.md +87 -0
- package/skills/(web-automation)/playwright-skill/API_REFERENCE.md +653 -0
- package/skills/(web-automation)/playwright-skill/SKILL.md +447 -0
- package/skills/(web-automation)/playwright-skill/lib/helpers.js +441 -0
- package/skills/(web-automation)/playwright-skill/package.json +26 -0
- package/skills/(web-automation)/playwright-skill/run.js +228 -0
- package/skills/_category.json +27 -0
- package/skills/categories.json +0 -24
- package/skills/categories.schema.json +0 -50
- /package/skills/{cursor-skill-creator → (creation)/cursor-skill-creator}/SKILL.md +0 -0
- /package/skills/{cursor-subagent-creator → (creation)/cursor-subagent-creator}/SKILL.md +0 -0
- /package/skills/{skill-creator → (creation)/skill-creator}/SKILL.md +0 -0
- /package/skills/{subagent-creator → (creation)/subagent-creator}/SKILL.md +0 -0
- /package/skills/{spec-driven-dev → (development)/spec-driven-dev}/SKILL.md +0 -0
- /package/skills/{spec-driven-dev → (development)/spec-driven-dev}/references/design.md +0 -0
- /package/skills/{spec-driven-dev → (development)/spec-driven-dev}/references/implement.md +0 -0
- /package/skills/{spec-driven-dev → (development)/spec-driven-dev}/references/specify.md +0 -0
- /package/skills/{spec-driven-dev → (development)/spec-driven-dev}/references/tasks.md +0 -0
- /package/skills/{spec-driven-dev → (development)/spec-driven-dev}/references/validate.md +0 -0
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<img src="https://img.shields.io/npm/dt/@tech-leads-club/agent-skills?style=flat-square&color=blue" alt="total downloads" />
|
|
4
4
|
<img src="https://img.shields.io/npm/dm/@tech-leads-club/agent-skills?style=flat-square&color=blue" alt="monthly downloads" />
|
|
5
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/
|
|
6
|
+
<img src="https://img.shields.io/github/actions/workflow/status/tech-leads-club/agent-skills/release.yml?style=flat-square" alt="build status" />
|
|
7
7
|
</p>
|
|
8
8
|
|
|
9
9
|
<p align="center">
|
|
@@ -38,10 +38,11 @@ Skills are packaged instructions and resources that extend AI agent capabilities
|
|
|
38
38
|
|
|
39
39
|
```
|
|
40
40
|
skills/
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
(category-name)/
|
|
42
|
+
spec-driven-dev/
|
|
43
|
+
SKILL.md ← Main instructions
|
|
44
|
+
templates/ ← File templates
|
|
45
|
+
references/ ← On-demand documentation
|
|
45
46
|
```
|
|
46
47
|
|
|
47
48
|
## 🚀 Quick Start
|
|
@@ -68,7 +69,7 @@ Each step shows a **← Back** option to return to the previous step and revise
|
|
|
68
69
|
# Interactive mode (default)
|
|
69
70
|
npx @tech-leads-club/agent-skills
|
|
70
71
|
|
|
71
|
-
# Install globally (to ~/.
|
|
72
|
+
# Install globally (to ~/.gemini/antigravity/global_skills, ~/.claude/skills, etc.)
|
|
72
73
|
npx @tech-leads-club/agent-skills install -g
|
|
73
74
|
|
|
74
75
|
# List available skills
|
|
@@ -100,24 +101,19 @@ npx @tech-leads-club/agent-skills remove --help
|
|
|
100
101
|
|
|
101
102
|
---
|
|
102
103
|
|
|
103
|
-
## 📦
|
|
104
|
+
## 📦 Discovering Skills
|
|
104
105
|
|
|
105
|
-
|
|
106
|
+
Use the CLI to browse and install available skills:
|
|
106
107
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|-------|-------------|
|
|
111
|
-
| **spec-driven-dev** | Specification-driven development workflow with 4 phases: specify → design → tasks → implement+validate |
|
|
108
|
+
```bash
|
|
109
|
+
# Interactive mode — browse categories and select skills
|
|
110
|
+
npx @tech-leads-club/agent-skills
|
|
112
111
|
|
|
113
|
-
|
|
112
|
+
# List all available skills
|
|
113
|
+
npx @tech-leads-club/agent-skills list
|
|
114
|
+
```
|
|
114
115
|
|
|
115
|
-
|
|
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 |
|
|
116
|
+
Skills are organized by category (development, creation, automation, etc.) and the collection is constantly growing.
|
|
121
117
|
|
|
122
118
|
---
|
|
123
119
|
|
|
@@ -144,16 +140,16 @@ npm run build
|
|
|
144
140
|
|
|
145
141
|
### Development Commands
|
|
146
142
|
|
|
147
|
-
| Command
|
|
148
|
-
|
|
149
|
-
| `npm run start:dev`
|
|
150
|
-
| `npm run g <name>`
|
|
151
|
-
| `npm run build`
|
|
152
|
-
| `npm run test`
|
|
153
|
-
| `npm run lint`
|
|
154
|
-
| `npm run lint:fix`
|
|
155
|
-
| `npm run format`
|
|
156
|
-
| `npm run release:dry` | Preview release (dry-run)
|
|
143
|
+
| Command | Description |
|
|
144
|
+
| --------------------- | ---------------------------------- |
|
|
145
|
+
| `npm run start:dev` | Run CLI locally (interactive mode) |
|
|
146
|
+
| `npm run g <name>` | Generate a new skill |
|
|
147
|
+
| `npm run build` | Build all packages |
|
|
148
|
+
| `npm run test` | Run all tests |
|
|
149
|
+
| `npm run lint` | Lint codebase |
|
|
150
|
+
| `npm run lint:fix` | Fix lint issues |
|
|
151
|
+
| `npm run format` | Format code with Prettier |
|
|
152
|
+
| `npm run release:dry` | Preview release (dry-run) |
|
|
157
153
|
|
|
158
154
|
### Creating a New Skill
|
|
159
155
|
|
|
@@ -174,57 +170,49 @@ nx g @tech-leads-club/skill-plugin:skill my-skill \
|
|
|
174
170
|
|
|
175
171
|
The generator will:
|
|
176
172
|
|
|
177
|
-
- Create
|
|
178
|
-
-
|
|
179
|
-
- If no category is specified, the skill will appear as "Uncategorized"
|
|
173
|
+
- Create the skill folder inside the specified category (e.g., `skills/(development)/my-skill/`)
|
|
174
|
+
- Create `SKILL.md` with the correct template structure
|
|
175
|
+
- If no category is specified, the skill will be created at the root of the `skills/` directory and appear as "Uncategorized" in the CLI.
|
|
180
176
|
|
|
181
177
|
### Skill Structure
|
|
182
178
|
|
|
183
179
|
```
|
|
184
|
-
skills/
|
|
185
|
-
├──
|
|
186
|
-
|
|
187
|
-
├──
|
|
188
|
-
├──
|
|
189
|
-
|
|
180
|
+
skills/
|
|
181
|
+
├── (category-name)/ # Category folder (starts and ends with parenthesis)
|
|
182
|
+
│ └── my-skill/ # Individual skill folder
|
|
183
|
+
│ ├── SKILL.md # Required: main instructions
|
|
184
|
+
│ ├── scripts/ # Optional: executable scripts
|
|
185
|
+
│ ├── references/ # Optional: on-demand documentation
|
|
186
|
+
│ └── ...
|
|
187
|
+
└── uncategorized-skill/ # Uncategorized skills stay at the root
|
|
190
188
|
```
|
|
191
189
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
Skills are organized into categories for better navigation in the CLI. Categories are defined in `skills/categories.json`.
|
|
190
|
+
Skills are organized into categories using the file-system structure, inspired by the Next.js App Router conventions.
|
|
195
191
|
|
|
196
|
-
####
|
|
192
|
+
#### Folder Convention
|
|
197
193
|
|
|
198
|
-
|
|
194
|
+
To put a skill in a category, place its folder inside a directory named with parentheses:
|
|
199
195
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
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
|
-
```
|
|
196
|
+
- ✅ `skills/(development)/spec-driven-dev/` -> Category: **development**
|
|
197
|
+
- ✅ `skills/(creation)/skill-creator/` -> Category: **creation**
|
|
198
|
+
- ❌ `skills/my-skill/` -> **Uncategorized**
|
|
211
199
|
|
|
212
|
-
####
|
|
200
|
+
#### Category Metadata
|
|
213
201
|
|
|
214
|
-
|
|
202
|
+
Optional metadata (display name, description, priority) for categories can be defined in `skills/_category.json`:
|
|
215
203
|
|
|
216
204
|
```json
|
|
217
205
|
{
|
|
218
|
-
"
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
206
|
+
"(development)": {
|
|
207
|
+
"name": "Development",
|
|
208
|
+
"description": "Skills for software development workflows",
|
|
209
|
+
"priority": 1
|
|
210
|
+
}
|
|
222
211
|
}
|
|
223
212
|
```
|
|
224
213
|
|
|
225
|
-
- `
|
|
226
|
-
- `
|
|
227
|
-
- `description`: Optional description
|
|
214
|
+
- `name`: Display name in the CLI (defaults to the folder name without parentheses)
|
|
215
|
+
- `description`: Optional description shown in the CLI
|
|
228
216
|
- `priority`: Display order (lower = first)
|
|
229
217
|
|
|
230
218
|
### SKILL.md Format
|
|
@@ -264,8 +252,9 @@ agent-skills/
|
|
|
264
252
|
├── tools/
|
|
265
253
|
│ └── skill-plugin/ # NX generator plugin
|
|
266
254
|
├── skills/ # Skill definitions
|
|
267
|
-
│ ├──
|
|
268
|
-
│
|
|
255
|
+
│ ├── (category-name)/ # Categorized skills
|
|
256
|
+
│ ├── _category.json # Category metadata (optional)
|
|
257
|
+
│ └── [skill-name]/ # Uncategorized skill folders
|
|
269
258
|
├── .github/
|
|
270
259
|
│ └── workflows/
|
|
271
260
|
│ ├── ci.yml # CI: lint, test, build
|
|
@@ -280,13 +269,13 @@ agent-skills/
|
|
|
280
269
|
|
|
281
270
|
This project uses **NX Release** with **Conventional Commits** for automated versioning:
|
|
282
271
|
|
|
283
|
-
| Commit Prefix | Version Bump
|
|
284
|
-
|
|
285
|
-
| `feat:`
|
|
286
|
-
| `fix:`
|
|
287
|
-
| `feat!:`
|
|
288
|
-
| `docs:`
|
|
289
|
-
| `chore:`
|
|
272
|
+
| Commit Prefix | Version Bump | Example |
|
|
273
|
+
| ------------- | ------------- | ---------------------------- |
|
|
274
|
+
| `feat:` | Minor (0.X.0) | `feat: add new skill` |
|
|
275
|
+
| `fix:` | Patch (0.0.X) | `fix: correct symlink path` |
|
|
276
|
+
| `feat!:` | Major (X.0.0) | `feat!: breaking API change` |
|
|
277
|
+
| `docs:` | No bump | `docs: update README` |
|
|
278
|
+
| `chore:` | No bump | `chore: update deps` |
|
|
290
279
|
|
|
291
280
|
Releases are automated via GitHub Actions when merging to `main`.
|
|
292
281
|
|
|
@@ -302,6 +291,14 @@ Releases are automated via GitHub Actions when merging to `main`.
|
|
|
302
291
|
|
|
303
292
|
---
|
|
304
293
|
|
|
294
|
+
## 🛡️ Content & Authorship
|
|
295
|
+
|
|
296
|
+
This repository is a collection of curated skills intended to benefit the community. We deeply respect the intellectual property and wishes of all creators.
|
|
297
|
+
|
|
298
|
+
If you are the author of any content included here and would like it **removed** or **updated**, please [open an issue](https://github.com/tech-leads-club/agent-skills/issues/new) or contact the maintainers. We will address your request immediately.
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
305
302
|
## 📄 License
|
|
306
303
|
|
|
307
304
|
MIT © [Tech Leads Club](https://github.com/tech-leads-club)
|
package/index.js
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{Command as Qt}from"commander";var ke={name:"@tech-leads-club/agent-skills",version:"0.5.2",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 _e,lstat as kt,mkdir as re,readdir as Ne,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 Le,relative as At,resolve as V,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 be}from"node:fs";import{dirname as tt,join as he,parse as nt,resolve as ot}from"node:path";function D(e=process.cwd()){let t=ot(e),n=nt(t).root;for(;t!==n;){if((be(he(t,"package.json"))||be(he(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 Se(){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 $e}from"node:fs";import{join as Ae}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 we(){let e=rt();if(!e)return null;let t=Ae(e,st,"skills");return $e(t)?t:null}function oe(){return we()!==null}function Ie(e){let t=we();if(!t)return null;let n=Ae(t,e);return $e(n)?n: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 Ce(){return pt(ut(),dt,ft)}function ve(){return{version:yt,skills:{}}}async function xe(){let e=Ce();try{let t=await ct(e,"utf-8"),n=JSON.parse(t);return typeof n.version!="number"||!n.skills?ve():n}catch{return ve()}}async function Te(e){let t=Ce();await at(mt(t),{recursive:!0}),await gt(t,JSON.stringify(e,null,2),"utf-8")}async function De(e,t="local"){let n=await xe(),o=new Date().toISOString(),l=n.skills[e];n.skills[e]={name:e,source:t,installedAt:l?.installedAt??o,updatedAt:o},await Te(n)}async function Pe(e){let t=await xe();return e in t.skills?(delete t.skills[e],await Te(t),!0):!1}var le=A(".agents","skills"),It=new Set(["README.md","metadata.json","SKILL.md"]);function ae(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 ie(e,t){let n=Le(V(e)),o=Le(V(t));return o.startsWith(n+wt)||o===n}async function Ee(e,t){try{try{if((await kt(t)).isSymbolicLink()){let r=await bt(t);if(V(r)===V(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 n=A(t,"..");await re(n,{recursive:!0});let o=At(n,e),l=$t()==="win32"?"junction":void 0;return await ht(o,t,l),!0}catch{return!1}}async function se(e,t){await re(t,{recursive:!0});let n=await Ne(e,{withFileTypes:!0});for(let o of n){if(It.has(o.name)||o.name.startsWith("_"))continue;let l=A(e,o.name),i=A(t,o.name);o.isDirectory()?await se(l,i):await _e(l,i)}}async function ce(e,t){let n=[],o=D();for(let l of t.agents){let i=P(l),r=t.global?i.globalSkillsDir:A(o,i.skillsDir);for(let a of e){let c=await vt(a,l,r,t.method,o,t.global);n.push(c),c.success&&await De(a.name,"local")}}return n}async function vt(e,t,n,o,l,i){let r=P(t),a=ae(e.name),c=A(n,a);if(!ie(n,c)&&!i&&!ie(l,c)&&!i)return{agent:r.displayName,skill:e.name,path:c,method:o,success:!1,error:"Security: Invalid skill destination path"};try{if(o==="symlink"){let f=Ie(e.name);if(f&&await Ee(f,c))return{agent:r.displayName,skill:e.name,path:c,method:o,success:!0,usedGlobalSymlink:!0};let u=A(l,le,a);if(await re(u,{recursive:!0}),await _e(e.path,u,{recursive:!0}),!await Ee(u,c)){try{await E(c,{recursive:!0,force:!0})}catch{}return await se(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:o,success:!0,usedGlobalSymlink:!1}}else return await se(e.path,c),{agent:r.displayName,skill:e.name,path:c,method:o,success:!0}}catch(f){return{agent:r.displayName,skill:e.name,path:c,method:o,success:!1,error:f instanceof Error?f.message:String(f)}}}async function Oe(e,t){let n=P(e),o=t?n.globalSkillsDir:A(D(),n.skillsDir);try{return(await Ne(o,{withFileTypes:!0})).filter(i=>i.isDirectory()||i.isSymbolicLink()).map(i=>i.name)}catch{return[]}}function Ct(e,t={}){let n=ae(e),o=t.global?St():D(),l=A(o,le,n);if(!ie(A(o,le),l))throw new Error("Invalid skill name: potential path traversal detected");return l}async function W(e,t,n={}){let o=[],l=ae(e),i=D(),r=Ct(e,n);try{await E(r,{recursive:!0,force:!0})}catch{}for(let a of t){let c=P(a),f=n.global?c.globalSkillsDir:A(i,c.skillsDir),u=A(f,l);try{await E(u,{recursive:!0,force:!0}),o.push({agent:c.displayName,success:!0})}catch($){o.push({agent:c.displayName,success:!1,error:$ instanceof Error?$.message:String($)})}}return await Pe(e),o}import b from"picocolors";import{existsSync as q,readFileSync as xt,writeFileSync as Nn}from"node:fs";import{dirname as Tt,join as ue}from"node:path";import{fileURLToPath as Dt}from"node:url";var K="skills/categories.json",U="skills",Y="uncategorized",ge={id:Y,name:"Uncategorized",description:"Skills without a specific category",priority:999};var Pt=Dt(import.meta.url),me=Tt(Pt);function Lt(){let e=ue(me,"..","..","..",K);if(q(e))return e;let t=ue(me,"..",K);if(q(t))return t;let n=ue(me,K);return q(n)?n:e}function Re(){let e=Lt();if(!q(e))return{categories:[],skills:{}};try{let t=xt(e,"utf-8");return JSON.parse(t)}catch{return{categories:[],skills:{}}}}function Be(e){return Re().skills[e]??Y}function H(e){let t=Re(),n=new Map,o=[...t.categories].sort((l,i)=>(l.priority??100)-(i.priority??100));for(let l of o)n.set(l,[]);n.set(ge,[]);for(let l of e){let i=l.category??t.skills[l.name]??Y,r=o.find(c=>c.id===i)??ge,a=n.get(r)??[];a.push(l),n.set(r,a)}for(let[l,i]of n)i.length===0&&n.delete(l);return n}import{existsSync as j,readdirSync as Et,readFileSync as _t}from"node:fs";import{dirname as Nt,join as G}from"node:path";import{fileURLToPath as Ot}from"node:url";var Rt=Ot(import.meta.url),pe=Nt(Rt);function Bt(){let e=G(pe,"..","..","..",U);if(j(e))return e;let t=G(pe,"..",U);if(j(t))return t;let n=G(pe,U);if(j(n))return n;throw new Error(`Skills directory not found. Checked: ${n}, ${t}`)}function x(){let e=Bt(),t=[];if(!j(e))return t;let n=Et(e,{withFileTypes:!0});for(let o of n){if(!o.isDirectory())continue;let l=G(e,o.name,"SKILL.md");if(!j(l))continue;let i=_t(l,"utf-8"),{name:r,description:a}=jt(i),c=r||o.name;t.push({name:c,description:a||"No description",path:G(e,o.name),category:Be(c)})}return t}function jt(e){let t=e.match(/^---\n([\s\S]*?)\n---/);if(!t)return{};let n=t[1],o=n.match(/^name:\s*(.+)$/m),l=n.match(/^description:\s*(.+)$/m);return{name:o?.[1]?.trim(),description:l?.[1]?.trim()}}function je(e){return x().find(n=>n.name===e)}function J(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 F 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",z="\u2514",Fe="\u25CF",ze="\u25CB",Me="\u25FC",Ve="\u25FB",T=F.blue("\u25C6");function y(e=""){console.log(e?`${F.blue(k)} ${e}`:F.blue(k))}function v(e=""){console.log(`${F.blue(z)} ${e}`)}function C(){v(F.gray("Cancelled"))}function I(e){return typeof e=="symbol"}async function X(e,t,n,o=!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:n,render(){let a=`${s.blue(k)}
|
|
3
|
-
${
|
|
4
|
-
`,
|
|
5
|
-
${s.blue(
|
|
6
|
-
${s.blue(
|
|
2
|
+
import{Command as mn}from"commander";var bt={name:"@tech-leads-club/agent-skills",version:"0.6.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 Ie,lstat as Ae,mkdir as $e,readdir as we,readlink as Ce,rm as N,symlink as ve}from"node:fs/promises";import{homedir as Te,platform as xe}from"node:os";import{join as $,normalize as _t,relative as De,resolve as q,sep as Pe}from"node:path";import{existsSync as m}from"node:fs";import{homedir as ae}from"node:os";import{join as c}from"node:path";import{existsSync as ht}from"node:fs";import{dirname as ie,join as St,parse as se,resolve as re}from"node:path";function R(t=process.cwd()){let e=re(t),n=se(e).root;for(;e!==n;){if((ht(St(e,"package.json"))||ht(St(e,".git")))&&!e.endsWith("packages/cli"))return e;e=ie(e)}return t}var d=ae(),h=R(),z={cursor:{name:"cursor",displayName:"Cursor",description:"AI-first code editor built on VS Code",skillsDir:".cursor/skills",globalSkillsDir:c(d,".cursor/skills"),detectInstalled:()=>m(c(d,".cursor"))||m(c(h,".cursor"))},"claude-code":{name:"claude-code",displayName:"Claude Code",description:"Anthropic's agentic coding tool",skillsDir:".claude/skills",globalSkillsDir:c(d,".claude/skills"),detectInstalled:()=>m(c(d,".claude"))||m(c(h,".claude"))},"github-copilot":{name:"github-copilot",displayName:"GitHub Copilot",description:"AI pair programmer by GitHub/Microsoft",skillsDir:".github/skills",globalSkillsDir:c(d,".copilot/skills"),detectInstalled:()=>m(c(d,".copilot"))||m(c(h,".github"))},windsurf:{name:"windsurf",displayName:"Windsurf",description:"AI IDE with Cascade flow (Codeium)",skillsDir:".windsurf/skills",globalSkillsDir:c(d,".codeium/windsurf/skills"),detectInstalled:()=>m(c(d,".codeium/windsurf"))||m(c(h,".windsurf"))},cline:{name:"cline",displayName:"Cline",description:"Autonomous AI coding agent for VS Code",skillsDir:".cline/skills",globalSkillsDir:c(d,".cline/skills"),detectInstalled:()=>m(c(d,".cline"))||m(c(h,".cline"))},aider:{name:"aider",displayName:"Aider",description:"AI pair programming in terminal",skillsDir:".aider/skills",globalSkillsDir:c(d,".aider/skills"),detectInstalled:()=>m(c(d,".aider"))||m(c(h,".aider"))},codex:{name:"codex",displayName:"OpenAI Codex",description:"OpenAI's coding agent",skillsDir:".codex/skills",globalSkillsDir:c(d,".codex/skills"),detectInstalled:()=>m(c(d,".codex"))||m(c(h,".codex"))},gemini:{name:"gemini",displayName:"Gemini CLI",description:"Google's AI coding assistant",skillsDir:".gemini/skills",globalSkillsDir:c(d,".gemini/skills"),detectInstalled:()=>m(c(d,".gemini"))||m(c(h,".gemini"))},antigravity:{name:"antigravity",displayName:"Antigravity",description:"Google's agentic coding (VS Code)",skillsDir:".agent/skills",globalSkillsDir:c(d,".gemini/antigravity/global_skills"),detectInstalled:()=>m(c(d,".gemini/antigravity"))||m(c(h,".agent"))},roo:{name:"roo",displayName:"Roo Code",description:"AI coding assistant for VS Code",skillsDir:".roo/skills",globalSkillsDir:c(d,".roo/skills"),detectInstalled:()=>m(c(d,".roo"))||m(c(h,".roo"))},kilocode:{name:"kilocode",displayName:"Kilo Code",description:"AI coding agent with auto-launch",skillsDir:".kilocode/skills",globalSkillsDir:c(d,".kilocode/skills"),detectInstalled:()=>m(c(d,".kilocode"))||m(c(h,".kilocode"))},"amazon-q":{name:"amazon-q",displayName:"Amazon Q",description:"AWS AI coding assistant",skillsDir:".amazonq/skills",globalSkillsDir:c(d,".amazonq/skills"),detectInstalled:()=>m(c(d,".amazonq"))||m(c(h,".amazonq"))},augment:{name:"augment",displayName:"Augment",description:"AI code assistant with context engine",skillsDir:".augment/skills",globalSkillsDir:c(d,".augment/skills"),detectInstalled:()=>m(c(d,".augment"))||m(c(h,".augment"))},tabnine:{name:"tabnine",displayName:"Tabnine",description:"AI code completions with privacy focus",skillsDir:".tabnine/skills",globalSkillsDir:c(d,".tabnine/skills"),detectInstalled:()=>m(c(d,".tabnine"))||m(c(h,".tabnine"))},opencode:{name:"opencode",displayName:"OpenCode",description:"Open-source AI coding terminal",skillsDir:".opencode/skills",globalSkillsDir:c(d,".config/opencode/skills"),detectInstalled:()=>m(c(d,".config/opencode"))||m(c(h,".opencode"))||m(c(h,".config/opencode"))},sourcegraph:{name:"sourcegraph",displayName:"Sourcegraph Cody",description:"AI assistant with codebase context",skillsDir:".sourcegraph/skills",globalSkillsDir:c(d,".sourcegraph/skills"),detectInstalled:()=>m(c(d,".sourcegraph"))||m(c(h,".sourcegraph"))}};function It(){return Object.entries(z).filter(([,t])=>t.detectInstalled()).map(([t])=>t)}function _(t){return z[t]}function O(){return Object.keys(z).sort((t,e)=>z[t].displayName.localeCompare(z[e].displayName))}import{execSync as ce}from"node:child_process";import{existsSync as At}from"node:fs";import{join as $t}from"node:path";var ge="@tech-leads-club/agent-skills";function ue(){try{return ce("npm root -g",{encoding:"utf-8"}).trim()}catch{return null}}function wt(){let t=ue();if(!t)return null;let e=$t(t,ge,"skills");return At(e)?e:null}function st(){return wt()!==null}function Ct(t){let e=wt();if(!e)return null;let n=$t(e,t);return At(n)?n:null}import{mkdir as me,readFile as pe,writeFile as de}from"node:fs/promises";import{homedir as fe}from"node:os";import{dirname as ye,join as ke}from"node:path";var be=".agents",he=".skill-lock.json",Se=1;function Tt(){return ke(fe(),be,he)}function vt(){return{version:Se,skills:{}}}async function xt(){let t=Tt();try{let e=await pe(t,"utf-8"),n=JSON.parse(e);return typeof n.version!="number"||!n.skills?vt():n}catch{return vt()}}async function Dt(t){let e=Tt();await me(ye(e),{recursive:!0}),await de(e,JSON.stringify(t,null,2),"utf-8")}async function Pt(t,e="local"){let n=await xt(),l=new Date().toISOString(),i=n.skills[t];n.skills[t]={name:t,source:e,installedAt:i?.installedAt??l,updatedAt:l},await Dt(n)}async function Rt(t){let e=await xt();return t in e.skills?(delete e.skills[t],await Dt(e),!0):!1}var rt=$(".agents","skills"),ct=t=>(t.replace(/[/\\]/g,"").replace(/[\0:]/g,"").replace(/^[.\s]+|[.\s]+$/g,"").replace(/^\.+/,"")||"unnamed-skill").substring(0,255),at=(t,e)=>{let n=_t(q(t)),l=_t(q(e));return l.startsWith(n+Pe)||l===n},Et=async(t,e)=>{try{await Re(e,t),await $e($(e,".."),{recursive:!0});let n=De($(e,".."),t),l=xe()==="win32"?"junction":void 0;return await ve(n,e,l),!0}catch{return!1}},Re=async(t,e)=>{try{if((await Ae(t)).isSymbolicLink()){let l=await Ce(t);if(q(l)===q(e))return;await N(t)}else await N(t,{recursive:!0})}catch(n){n?.code==="ELOOP"&&await N(t,{force:!0}).catch(()=>{})}},V=async(t,e)=>{await N(e,{recursive:!0,force:!0}),await Ie(t,e,{recursive:!0})},_e=(t,e)=>`${t}-${e?"global":"local"}`,L=(t,e,n={})=>({agent:t.config.displayName,skill:t.skill.name,path:t.skillTargetPath,method:e,success:!0,...n}),Ot=(t,e,n)=>({agent:t.config.displayName,skill:t.skill.name,path:t.skillTargetPath,method:e,success:!1,error:n instanceof Error?n.message:String(n)}),Ee={"symlink-global":async t=>{let e=Ct(t.skill.name),n=e||t.skill.path;return await Et(n,t.skillTargetPath)?L(t,"symlink",{usedGlobalSymlink:!!e}):(await V(t.skill.path,t.skillTargetPath),L(t,"copy",{symlinkFailed:!0}))},"symlink-local":async t=>{let e=$(t.projectRoot,rt,t.safeSkillName);return await V(t.skill.path,e),await Et(e,t.skillTargetPath)?L(t,"symlink",{usedGlobalSymlink:!1}):(await V(t.skill.path,t.skillTargetPath),L(t,"copy",{symlinkFailed:!0}))},"copy-global":async t=>(await V(t.skill.path,t.skillTargetPath),L(t,"copy")),"copy-local":async t=>(await V(t.skill.path,t.skillTargetPath),L(t,"copy"))},Oe=(t,e,n,l)=>l||at(t,e)||at(n,e)?null:"Security: Invalid skill destination path",Le=async(t,e,n,l,i,o)=>{let r=_(e),a=ct(t.name),u=$(n,a),k={skill:t,config:r,safeSkillName:a,skillTargetPath:u,projectRoot:i},g=Oe(n,u,i,o);if(g)return Ot(k,l,g);try{let I=_e(l,o);return await Ee[I](k)}catch(I){return Ot(k,l,I)}},gt=async(t,e)=>{let n=R(),l=[];for(let i of e.agents){let o=_(i),r=e.global?o.globalSkillsDir:$(n,o.skillsDir);for(let a of t){let u=await Le(a,i,r,e.method,n,e.global);l.push(u),u.success&&await Pt(a.name,"local")}}return l},Lt=async(t,e)=>{let n=_(t),l=e?n.globalSkillsDir:$(R(),n.skillsDir);try{return(await we(l,{withFileTypes:!0})).filter(o=>o.isDirectory()||o.isSymbolicLink()).map(o=>o.name)}catch{return[]}};var Ne=(t,e={})=>{let n=ct(t),l=e.global?Te():R(),i=$(l,rt,n);if(!at($(l,rt),i))throw new Error("Invalid skill name: potential path traversal detected");return i},J=async(t,e,n={})=>{let l=ct(t),i=R();await N(Ne(t,n),{recursive:!0,force:!0}).catch(()=>{});let o=await Promise.all(e.map(async r=>{let a=_(r),u=n.global?a.globalSkillsDir:$(i,a.skillsDir),k=$(u,l);try{return await N(k,{recursive:!0,force:!0}),{agent:a.displayName,success:!0}}catch(g){return{agent:a.displayName,success:!1,error:g instanceof Error?g.message:String(g)}}}));return await Rt(t),o};import b from"picocolors";import{existsSync as K,readdirSync as Fe,readFileSync as Be,writeFileSync as Un}from"node:fs";import{dirname as je,join as X}from"node:path";import{fileURLToPath as Ge}from"node:url";var T="skills",Y="uncategorized",F=/^\(([a-z][a-z0-9-]*)\)$/,Nt="_category.json",ut={id:Y,name:"Uncategorized",description:"Skills without a specific category",priority:999};function mt(t){return t.split("-").map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(" ")}var Me=Ge(import.meta.url),pt=je(Me);function Ft(){let t=X(pt,"..","..","..",T);if(K(t))return t;let e=X(pt,"..",T);if(K(e))return e;let n=X(pt,T);return K(n)?n:t}function Bt(){let t=Ft(),e=X(t,Nt);if(!K(e))return{};try{let n=Be(e,"utf-8");return JSON.parse(n)}catch{return{}}}function ze(t){let e=t.match(F);return e?e[1]:null}function Ve(t){return F.test(t)}function Ye(){let t=Ft();if(!K(t))return[];let e=Bt(),n=Fe(t,{withFileTypes:!0}),l=[],i=0;for(let o of n){if(!o.isDirectory()||!Ve(o.name))continue;let r=ze(o.name);if(!r)continue;let a=e[o.name]??{};l.push({id:r,name:a.name??mt(r),description:a.description,priority:a.priority??i}),i++}return l.sort((o,r)=>(o.priority??100)-(r.priority??100)),l}function Q(t){let e=Ye(),n=new Map;for(let l of e)n.set(l,[]);n.set(ut,[]);for(let l of t){let i=l.category??Y,o=e.find(a=>a.id===i)??ut,r=n.get(o)??[];r.push(l),n.set(o,r)}for(let[l,i]of n)i.length===0&&n.delete(l);return n}import{existsSync as E,readdirSync as jt,readFileSync as Gt}from"node:fs";import{dirname as Ke,join as x}from"node:path";import{fileURLToPath as Ue}from"node:url";var We=Ue(import.meta.url),dt=Ke(We);function He(){let t=x(dt,"..","..","..",T);if(E(t))return t;let e=x(dt,"..",T);if(E(e))return e;let n=x(dt,T);if(E(n))return n;throw new Error(`Skills directory not found. Checked: ${n}, ${e}`)}function qe(t){let e=t.match(F);return e?e[1]:null}function Je(t){return F.test(t)}function Xe(t,e){let n=[];if(!E(t))return n;let l=jt(t,{withFileTypes:!0});for(let i of l){if(!i.isDirectory())continue;let o=x(t,i.name,"SKILL.md");if(!E(o))continue;let r=Gt(o,"utf-8"),{name:a,description:u}=Mt(r);n.push({name:a||i.name,description:u||"No description",path:x(t,i.name),category:e})}return n}function D(){let t=He(),e=[];if(!E(t))return e;let n=jt(t,{withFileTypes:!0});for(let l of n)if(l.isDirectory())if(Je(l.name)){let i=qe(l.name);if(i){let o=x(t,l.name),r=Xe(o,i);e.push(...r)}}else{let i=x(t,l.name,"SKILL.md");if(E(i)){let o=Gt(i,"utf-8"),{name:r,description:a}=Mt(o);e.push({name:r||l.name,description:a||"No description",path:x(t,l.name),category:Y})}}return e}function Mt(t){let e=t.match(/^---\n([\s\S]*?)\n---/);if(!e)return{};let n=e[1],l=n.match(/^name:\s*(.+)$/m),i=n.match(/^description:\s*(.+)$/m);return{name:l?.[1]?.trim(),description:i?.[1]?.trim()}}function zt(t){return D().find(e=>e.name===t)}function Z(t,e){return t.length<=e?t:t.slice(0,e-3)+"..."}import{ConfirmPrompt as Ze,MultiSelectPrompt as tn,SelectPrompt as en}from"@clack/core";import s from"picocolors";import Qe from"gradient-string";import U from"picocolors";var Vt=Qe([{color:"#1e3a8a",pos:0},{color:"#3b82f6",pos:.3},{color:"#0ea5e9",pos:.5},{color:"#06b6d4",pos:.7},{color:"#22d3ee",pos:1}]),y="\u2502",W="\u2514",Yt="\u25CF",Kt="\u25CB",Ut="\u25FC",Wt="\u25FB",P=U.blue("\u25C6");function f(t=""){console.log(t?`${U.blue(y)} ${t}`:U.blue(y))}function C(t=""){console.log(`${U.blue(W)} ${t}`)}function v(){C(U.gray("Cancelled"))}function w(t){return typeof t=="symbol"}async function tt(t,e,n,l=!0){let i=(a,u)=>{let k=u?s.blue(Yt):s.gray(Kt),g=u?s.blue(a.label):s.white(a.label),I=u&&a.hint?s.dim(s.gray(` - ${a.hint}`)):"";return`${k} ${g}${I}`},r=await new en({options:e,initialValue:n,render(){let a=`${s.blue(y)}
|
|
3
|
+
${P} ${s.white(s.bold(t))}
|
|
4
|
+
`,u=l?"esc = back, ":"";switch(this.state){case"submit":return`${a}${s.blue(y)} ${s.blue(this.options.find(k=>k.value===this.value)?.label)}
|
|
5
|
+
${s.blue(y)}`;case"cancel":return`${a}${s.blue(y)} ${s.strikethrough(s.gray("back"))}
|
|
6
|
+
${s.blue(y)}`;default:return`${a}${this.options.map((k,g)=>`${s.blue(y)} ${i(k,g===this.cursor)}`).join(`
|
|
7
7
|
`)}
|
|
8
|
-
${s.blue(
|
|
9
|
-
${s.blue(
|
|
10
|
-
${
|
|
11
|
-
`,
|
|
12
|
-
${s.blue(
|
|
13
|
-
${s.blue(
|
|
8
|
+
${s.blue(y)}
|
|
9
|
+
${s.blue(W)} ${s.dim(s.gray(`(\u2191\u2193 navigate, ${u}enter confirm)`))}`}}}).prompt();return typeof r=="symbol"&&l?Symbol.for("back"):r}async function B(t,e,n=[],l=!0){let i=(a,u)=>{let k=u==="selected"||u==="selected-active",g=u==="active"||u==="selected-active",I=k?s.blue(Ut):s.gray(Wt),S=g?s.blue(a.label):s.white(a.label),M=g&&a.hint?s.dim(s.gray(` (${a.hint})`)):"";return`${I} ${S}${M}`},r=await new tn({options:e,initialValues:n,render(){let a=`${s.blue(y)}
|
|
10
|
+
${P} ${s.white(s.bold(t))}
|
|
11
|
+
`,u=l?"esc = back, ":"";switch(this.state){case"submit":return`${a}${s.blue(y)} ${this.options.filter(k=>this.value.includes(k.value)).map(k=>s.blue(String(k.value))).join(s.gray(", "))}
|
|
12
|
+
${s.blue(y)}`;case"cancel":return`${a}${s.blue(y)} ${s.strikethrough(s.gray("back"))}
|
|
13
|
+
${s.blue(y)}`;default:return`${a}${this.options.map((k,g)=>{let I=this.value.includes(k.value),S=g===this.cursor,M=I&&S?"selected-active":I?"selected":S?"active":"inactive";return`${s.blue(y)} ${i(k,M)}`}).join(`
|
|
14
14
|
`)}
|
|
15
|
-
${s.blue(
|
|
16
|
-
${s.blue(
|
|
17
|
-
${
|
|
18
|
-
`;switch(this.state){case"submit":return`${
|
|
19
|
-
${s.blue(
|
|
20
|
-
${s.blue(
|
|
21
|
-
${s.blue(
|
|
22
|
-
${s.blue(
|
|
23
|
-
${
|
|
24
|
-
${
|
|
25
|
-
${
|
|
26
|
-
`}function
|
|
15
|
+
${s.blue(y)}
|
|
16
|
+
${s.blue(W)} ${s.dim(s.gray(`(\u2191\u2193 navigate, space select, ${u}enter confirm)`))}`}}}).prompt();return typeof r=="symbol"&&l?Symbol.for("back"):r}async function et(t,e=!1){return new Ze({active:"Yes",inactive:"No",initialValue:e,render(){let l=`${s.blue(y)}
|
|
17
|
+
${P} ${s.white(s.bold(t))}
|
|
18
|
+
`;switch(this.state){case"submit":return`${l}${s.blue(y)} ${s.blue(this.value?"Yes":"No")}
|
|
19
|
+
${s.blue(y)}`;case"cancel":return`${l}${s.blue(y)} ${s.strikethrough(s.gray("cancelled"))}
|
|
20
|
+
${s.blue(y)}`;default:return`${l}${s.blue(y)} ${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(y)}
|
|
22
|
+
${s.blue(W)} ${s.dim(s.gray("(\u2190\u2192 to change, enter to confirm)"))}`}}}).prompt()}import nn from"figlet";import j from"picocolors";function ln(){let t=nn.textSync("Tech Leads Club",{font:"Larry 3D",horizontalLayout:"default"});return`
|
|
23
|
+
${Vt.multiline(t)}
|
|
24
|
+
${j.white(j.bold("Tech Leads Club"))} ${j.blue("\u203A")} ${j.bold(j.blue("Agent Skills"))}
|
|
25
|
+
${j.white("Curated skills to power up your AI coding agents")}
|
|
26
|
+
`}function G(){console.clear(),console.log(ln()),f()}import{createRequire as on}from"node:module";import sn from"package-json";var rn="@tech-leads-club/agent-skills";async function Ht(t){try{let e=await sn(rn);return e.version!==t?e.version:null}catch{return null}}function qt(){try{let t=on(import.meta.url);try{return t("./package.json").version||"0.0.0"}catch{return t("../package.json").version||"0.0.0"}}catch{return"0.0.0"}}import p from"picocolors";function Jt(t){f(),f(p.blue(p.bold("\u{1F4CB} Installation Summary"))),f(),f(`${p.blue(y)} ${p.white(p.bold("Skills:"))} ${p.gray(t.skills.join(", "))}`),f(`${p.blue(y)} ${p.white(p.bold("Agents:"))} ${p.gray(t.agents.join(", "))}`),f(`${p.blue(y)} ${p.white(p.bold("Method:"))} ${p.cyan(t.method)}`),f()}function ft(t){let e=t.filter(o=>o.success&&!o.error),n=t.filter(o=>o.success&&o.error==="Already exists"),l=t.filter(o=>!o.success);console.log();for(let o of e)console.log(`${P} ${p.white(p.bold(o.skill))} ${p.gray("\u2192")} ${p.white(o.agent)}`);for(let o of n)console.log(`${p.gray(P)} ${o.skill} \u2192 ${o.agent} ${p.gray("(exists)")}`);for(let o of l)console.log(`${p.red("\u2717")} ${o.skill} \u2192 ${o.agent}: ${o.error}`);let i=new Set(t.map(o=>o.agent)).size;console.log(),C(`${p.blue("\u2713")} ${p.white(p.bold(`${e.length} skill(s)`))} ${p.white("installed to")} ${p.white(p.bold(`${i} agent(s)`))}`)}function nt(t,e){let n=e.filter(i=>i.success),l=e.filter(i=>!i.success);n.length>0&&console.log(`${P} ${p.white(p.bold(t))} ${p.gray("removed from")} ${n.map(i=>i.agent).join(", ")}`);for(let i of l)console.log(`${p.red("\u2717")} ${t} \u2192 ${i.agent}: ${i.error}`);n.length>0&&l.length===0&&C(`${p.blue("\u2713")} ${p.white("Skill removed successfully")}`)}import an from"picocolors";function ot(t,e=[]){return t.map(n=>{let l=_(n),i=e.includes(n);return{value:n,label:i?`${l.displayName} ${an.green("\u25CF detected")}`:l.displayName,hint:Z(l.description,50)}})}async function lt(t,e){let n=new Set;for(let l of t)(await Lt(l,e)).forEach(o=>n.add(o));return n}async function it(t){let[e,n]=await Promise.all([lt(t,!0),lt(t,!1)]);return new Set([...e,...n])}var yt="__all_skills__",kt="__all__";async function Xt(){G(),await cn();let t=D();if(t.length===0)return C(b.red("No skills available")),null;let e=It(),n=O(),l=e.length>0?e:n,i=await it(l),o={category:kt,skills:[],agents:e.length>0?e:["cursor","claude-code"],method:"symlink",global:!1},r=1,a=4;for(;r<=a;){let u=b.gray(`[${r}/${a}]`),k=r>1;switch(r){case 1:{let g=await gn({allSkills:t,stepIndicator:u,currentCategory:o.category});if(g===null)return null;o.category=g,r++;break}case 2:{let g=await Qt({state:o,allSkills:t,installedSkills:i,stepIndicator:u,allowBack:k});if(g===Symbol.for("back")){r--;break}if(g===null)return null;o.skills=g,r++;break}case 3:{let g=await Zt({allAgents:n,installedAgents:e,currentAgents:o.agents,stepIndicator:u,allowBack:k});if(g===Symbol.for("back")){r--;break}if(g===null)return null;o.agents=g,r++;break}case 4:{let g=await te({state:o,stepIndicator:u,allowBack:k});if(g===Symbol.for("back")){o.method="symlink",r--;break}if(g===null)return null;if(g===!1){r=1;break}return g}}}return null}async function cn(){let t=qt(),e=await Ht(t);e?(f(`${b.yellow("\u26A0")} ${b.yellow("Update available:")} ${b.gray(t)} \u2192 ${b.green(e)}`),f(` ${b.gray("Run: npm update -g @tech-leads-club/agent-skills")}`),f()):st()||(f(`${b.yellow("\u26A0")} ${b.yellow("Not installed globally")}`),f(` ${b.yellow("Skills won't auto-update. Install globally:")}`),f(` ${b.yellow("npm i -g @tech-leads-club/agent-skills")}`),f())}async function gn({allSkills:t,stepIndicator:e,currentCategory:n}){let l=Q(t),i=Array.from(l.keys()),o=[{value:kt,label:`${b.cyan("\u25C9")} All skills`,hint:`${t.length} available`},...i.map(a=>{let u=l.get(a)?.length??0;return{value:a.id,label:`${b.cyan("\u25B8")} ${a.name}`,hint:`${u} skill(s)`}})],r=await tt(`${e} Browse by category`,o,n,!1);return w(r)?(v(),null):r}async function Qt({state:t,allSkills:e,installedSkills:n,stepIndicator:l,allowBack:i}){let r=t.category===kt?e:e.filter(S=>S.category===t.category),a=[{value:yt,label:`${b.cyan("\u25C9")} ${b.bold("All Skills")}`,hint:`select all ${r.length} skills`},...r.map(S=>{let M=n.has(S.name);return{value:S.name,label:M?`${S.name} ${b.green("\u25CF installed")}`:S.name,hint:Z(S.description,150)}})],u=t.skills.length>0?t.skills:[],k=await B(`${l} Select skills to install`,a,u,i);if(k===Symbol.for("back"))return Symbol.for("back");if(w(k))return v(),null;let g=k,I=g.includes(yt)?r.map(S=>S.name):g.filter(S=>S!==yt);return I.length===0&&f(b.yellow("\u26A0 Please select at least one skill")),I.length===0?Qt({state:t,allSkills:e,installedSkills:n,stepIndicator:l,allowBack:i}):I}async function Zt({allAgents:t,installedAgents:e,currentAgents:n,stepIndicator:l,allowBack:i}){let o=ot(t,e),r=await B(`${l} Where to install?`,o,n,i);if(r===Symbol.for("back"))return Symbol.for("back");if(w(r))return v(),null;let a=r;return a.length===0?(f(b.yellow("\u26A0 Please select at least one agent")),Zt({allAgents:t,installedAgents:e,currentAgents:n,stepIndicator:l,allowBack:i})):a}async function te({state:t,stepIndicator:e,allowBack:n}){let l=[{value:"symlink",label:"Symlink",hint:"shared source (recommended)"},{value:"copy",label:"Copy",hint:"independent copies"}],i=await tt(`${e} Installation method`,l,t.method,n);if(i===Symbol.for("back"))return Symbol.for("back");if(w(i))return v(),null;t.method=i,Jt(t);let o=await un(t);if(o===Symbol.for("back"))return te({state:t,stepIndicator:e,allowBack:n});if(o===null)return null;t.global=o==="global";let r=await et(b.white("Proceed with installation?"),!0);return w(r)?(v(),null):r?(f(),{agents:t.agents,skills:t.skills,method:t.method,global:t.global}):!1}async function un(t){let n=await tt("Installation scope",[{value:"local",label:"Local",hint:"this project only"},{value:"global",label:"Global",hint:"user home directory"}],t.global?"global":"local",!0);return n===Symbol.for("back")?Symbol.for("back"):w(n)?null:n}import A from"picocolors";async function ee(){G();let t=D();if(t.length===0){f(A.yellow("No skills found"));return}f(A.bold(`${t.length} skills available:`)),f();let e=O(),n=await it(e),l=Q(t);for(let[i,o]of l){f(`${A.cyan("\u25B8")} ${A.bold(A.cyan(i.name))}`);for(let r of o){let a=n.has(r.name)?` ${A.green("\u25CF installed")}`:"";f(` ${A.blue("\u25C6")} ${A.bold(r.name)}${a}`),console.log(`${A.blue(y)} ${A.dim(A.gray(r.description))}`)}f()}C(A.gray('Run "npx @tech-leads-club/agent-skills" to install'))}import ne from"picocolors";async function le(t){G();let e=O(),n=await lt(e,t);if(n.size===0){f(ne.yellow("No skills installed")),C();return}let l=Array.from(n),i=await B(`Which skills do you want to remove? ${ne.gray(`(${l.length} installed)`)}`,l.map(a=>({value:a,label:a})),[],!1);if(w(i)||i.length===0){v();return}let o=await B("Remove from which agents?",ot(e).map(a=>({...a,hint:void 0})),e,!0);if(w(o)){v();return}let r=await et(`Remove ${i.length} skill(s) from ${o.length} agent(s)?`,!1);if(w(r)||!r){v();return}f();for(let a of i){let u=await J(a,o,{global:t});nt(a,u)}}var H=new mn;H.name("tlc-agent-skills").description("Install TLC Agent Skills to your AI coding agents").version(bt.version);H.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 t=>{if(t.skill||t.agent)await pn(t);else{let e=await Xt();if(!e)return;let n=D().filter(i=>e.skills.includes(i.name)),l=await gt(n,e);ft(l)}});H.command("list").alias("ls").description("List available skills").action(async()=>{await ee()});H.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 t=>{if(t.skill){let e=t.agent||["antigravity","claude-code","cursor"],n=await J(t.skill,e,{global:t.global});nt(t.skill,n)}else await le(t.global)});async function pn(t){let e=D(),n=e;if(t.skill){let r=zt(t.skill);r||(console.error(`Skill "${t.skill}" not found.`),console.log("Available skills:",e.map(a=>a.name).join(", ")),process.exit(1)),n=[r]}let l=t.agent||["antigravity","claude-code","cursor"],i=t.copy?"copy":"symlink",o=await gt(n,{agents:l,skills:n.map(r=>r.name),method:i,global:t.global});ft(o)}H.parse();
|
|
27
27
|
//# sourceMappingURL=index.js.map
|