@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 +21 -0
- package/README.md +313 -0
- package/index.js +27 -0
- package/index.js.map +7 -0
- package/package.json +48 -0
- package/skills/categories.json +24 -0
- package/skills/categories.schema.json +50 -0
- package/skills/cursor-skill-creator/SKILL.md +379 -0
- package/skills/cursor-subagent-creator/SKILL.md +683 -0
- package/skills/skill-creator/SKILL.md +173 -0
- package/skills/spec-driven-dev/SKILL.md +43 -0
- package/skills/spec-driven-dev/references/design.md +140 -0
- package/skills/spec-driven-dev/references/implement.md +66 -0
- package/skills/spec-driven-dev/references/specify.md +116 -0
- package/skills/spec-driven-dev/references/tasks.md +221 -0
- package/skills/spec-driven-dev/references/validate.md +126 -0
- package/skills/subagent-creator/SKILL.md +283 -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/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
|