@tech-leads-club/agent-skills 0.1.0-beta.2 → 0.1.0-beta.4

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,297 @@
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/github/license/tech-leads-club/agent-skills?style=flat-square" alt="license" />
4
+ <img src="https://img.shields.io/github/actions/workflow/status/tech-leads-club/agent-skills/ci.yml?style=flat-square" alt="build status" />
5
+ <img src="https://img.shields.io/badge/node-%3E%3D22-brightgreen?style=flat-square" alt="node version" />
6
+ </p>
7
+
8
+ <h1 align="center">🧠 Agent Skills</h1>
9
+
10
+ <p align="center">
11
+ <strong>A curated collection of skills for AI coding agents</strong>
12
+ </p>
13
+
14
+ <p align="center">
15
+ Extend the capabilities of <b>Antigravity</b>, <b>Claude Code</b>, <b>Cursor</b>, <b>GitHub Copilot</b>, and more with reusable, packaged instructions.
16
+ </p>
17
+
18
+ ---
19
+
20
+ ## ✨ What are Skills?
21
+
22
+ 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.
23
+
24
+ ```
25
+ skills/
26
+ spec-driven-dev/
27
+ SKILL.md ← Main instructions
28
+ templates/ ← File templates
29
+ references/ ← On-demand documentation
30
+ ```
31
+
32
+ ## 🚀 Quick Start
33
+
34
+ ### Install Skills in Your Project
35
+
36
+ ```bash
37
+ npx @tech-leads-club/agent-skills
38
+ ```
39
+
40
+ This launches an interactive wizard with 5 steps:
41
+
42
+ 1. **Browse categories** — Filter skills by category or select "All"
43
+ 2. **Select skills** — Choose which skills to install
44
+ 3. **Choose agents** — Pick target agents (Cursor, Claude Code, etc.)
45
+ 4. **Installation method** — Symlink (recommended) or Copy
46
+ 5. **Scope** — Global (user home) or Local (project only)
47
+
48
+ Each step shows a **← Back** option to return to the previous step and revise your choices. A confirmation summary is shown before installation.
49
+
50
+ ### CLI Options
51
+
52
+ ```bash
53
+ # Interactive mode (default)
54
+ npx @tech-leads-club/agent-skills
55
+
56
+ # Install globally (to ~/.agent/skills, ~/.claude/skills, etc.)
57
+ npx @tech-leads-club/agent-skills install -g
58
+
59
+ # List available skills
60
+ npx @tech-leads-club/agent-skills list
61
+
62
+ # Install a specific skill
63
+ npx @tech-leads-club/agent-skills install -s spec-driven-dev
64
+
65
+ # Install to specific agents
66
+ npx @tech-leads-club/agent-skills install -a antigravity cursor
67
+
68
+ # Use copy instead of symlink
69
+ npx @tech-leads-club/agent-skills install --copy
70
+
71
+ # Remove skills (interactive)
72
+ npx @tech-leads-club/agent-skills remove
73
+
74
+ # Remove a specific skill
75
+ npx @tech-leads-club/agent-skills remove -s spec-driven-dev
76
+
77
+ # Remove from global installation
78
+ npx @tech-leads-club/agent-skills remove -g -s spec-driven-dev
79
+
80
+ # Show help
81
+ npx @tech-leads-club/agent-skills --help
82
+ npx @tech-leads-club/agent-skills install --help
83
+ npx @tech-leads-club/agent-skills remove --help
84
+ ```
85
+
86
+ ---
87
+
88
+ ## 📦 Available Skills
89
+
90
+ Skills are organized by category for easier navigation.
91
+
92
+ ### 🔧 Development
93
+
94
+ | Skill | Description |
95
+ |-------|-------------|
96
+ | **spec-driven-dev** | Specification-driven development workflow with 4 phases: specify → design → tasks → implement+validate |
97
+
98
+ ### 🛠 Skill & Agent Creation
99
+
100
+ | Skill | Description |
101
+ |-------|-------------|
102
+ | **skill-creator** | Meta-skill for creating new skills following best practices |
103
+ | **subagent-creator** | Create specialized subagents for complex tasks |
104
+ | **cursor-skill-creator** | Cursor-specific skill creation |
105
+ | **cursor-subagent-creator** | Cursor-specific subagent creation |
106
+
107
+ ---
108
+
109
+ ## 🛠 For Contributors
110
+
111
+ ### Prerequisites
112
+
113
+ - **Node.js** ≥ 22
114
+ - **npm** (comes with Node.js)
115
+
116
+ ### Setup
117
+
118
+ ```bash
119
+ # Clone the repository
120
+ git clone https://github.com/tech-leads-club/agent-skills.git
121
+ cd agent-skills
122
+
123
+ # Install dependencies
124
+ npm ci
125
+
126
+ # Build all packages
127
+ npm run build
128
+ ```
129
+
130
+ ### Development Commands
131
+
132
+ | Command | Description |
133
+ |---------|-------------|
134
+ | `npm run start:dev` | Run CLI locally (interactive mode) |
135
+ | `npm run g <name>` | Generate a new skill |
136
+ | `npm run build` | Build all packages |
137
+ | `npm run test` | Run all tests |
138
+ | `npm run lint` | Lint codebase |
139
+ | `npm run lint:fix` | Fix lint issues |
140
+ | `npm run format` | Format code with Prettier |
141
+ | `npm run release:dry` | Preview release (dry-run) |
142
+
143
+ ### Creating a New Skill
144
+
145
+ Use the NX generator:
146
+
147
+ ```bash
148
+ # Basic usage (will prompt for category)
149
+ nx g @tech-leads-club/skill-plugin:skill my-awesome-skill
150
+
151
+ # With category specified
152
+ nx g @tech-leads-club/skill-plugin:skill my-awesome-skill --category=development
153
+
154
+ # With all options
155
+ nx g @tech-leads-club/skill-plugin:skill my-skill \
156
+ --description="What my skill does" \
157
+ --category=development
158
+ ```
159
+
160
+ The generator will:
161
+ - Create `skills/my-skill/SKILL.md` with the correct template structure
162
+ - Assign the skill to the specified category (creating it if needed)
163
+ - If no category is specified, the skill will appear as "Uncategorized"
164
+
165
+ ### Skill Structure
166
+
167
+ ```
168
+ skills/my-skill/
169
+ ├── SKILL.md # Required: main instructions
170
+ ├── scripts/ # Optional: executable scripts
171
+ ├── references/ # Optional: on-demand documentation
172
+ ├── templates/ # Optional: file templates
173
+ └── assets/ # Optional: images, files
174
+ ```
175
+
176
+ ### Skill Categories
177
+
178
+ Skills are organized into categories for better navigation in the CLI. Categories are defined in `skills/categories.json`.
179
+
180
+ #### Adding a Skill to a Category
181
+
182
+ Edit `skills/categories.json` and add your skill to the `skills` map:
183
+
184
+ ```json
185
+ {
186
+ "categories": [
187
+ { "id": "development", "name": "Development", "priority": 1 },
188
+ { "id": "creation", "name": "Skill & Agent Creation", "priority": 2 }
189
+ ],
190
+ "skills": {
191
+ "my-new-skill": "development"
192
+ }
193
+ }
194
+ ```
195
+
196
+ #### Creating a New Category
197
+
198
+ Add a new entry to the `categories` array:
199
+
200
+ ```json
201
+ {
202
+ "id": "my-category",
203
+ "name": "My Category",
204
+ "description": "Optional description",
205
+ "priority": 3
206
+ }
207
+ ```
208
+
209
+ - `id`: Unique identifier (kebab-case)
210
+ - `name`: Display name in the CLI
211
+ - `description`: Optional description
212
+ - `priority`: Display order (lower = first)
213
+
214
+ ### SKILL.md Format
215
+
216
+ ```markdown
217
+ ---
218
+ name: my-skill
219
+ description: What this skill does. Use when user says "trigger phrase".
220
+ ---
221
+
222
+ # My Skill
223
+
224
+ Brief description.
225
+
226
+ ## Process
227
+
228
+ 1. Step one
229
+ 2. Step two
230
+ 3. ...
231
+ ```
232
+
233
+ ### Best Practices
234
+
235
+ - **Keep SKILL.md under 500 lines** — use `references/` for detailed docs
236
+ - **Write specific descriptions** — include trigger phrases
237
+ - **Assume the agent is smart** — only add what it doesn't already know
238
+ - **Prefer scripts over inline code** — reduces context window usage
239
+
240
+ ---
241
+
242
+ ## 📁 Project Structure
243
+
244
+ ```
245
+ agent-skills/
246
+ ├── packages/
247
+ │ └── cli/ # @tech-leads-club/agent-skills CLI package
248
+ ├── tools/
249
+ │ └── skill-plugin/ # NX generator plugin
250
+ ├── skills/ # Skill definitions
251
+ │ ├── categories.json # Skill category mappings
252
+ │ └── [skill-name]/ # Individual skill folders
253
+ ├── .github/
254
+ │ └── workflows/
255
+ │ ├── ci.yml # CI: lint, test, build
256
+ │ └── release.yml # Release: version, publish
257
+ ├── nx.json # NX configuration
258
+ └── package.json # Root package.json
259
+ ```
260
+
261
+ ---
262
+
263
+ ## 🔄 Release Process
264
+
265
+ This project uses **NX Release** with **Conventional Commits** for automated versioning:
266
+
267
+ | Commit Prefix | Version Bump | Example |
268
+ |---------------|--------------|---------|
269
+ | `feat:` | Minor (0.X.0) | `feat: add new skill` |
270
+ | `fix:` | Patch (0.0.X) | `fix: correct symlink path` |
271
+ | `feat!:` | Major (X.0.0) | `feat!: breaking API change` |
272
+ | `docs:` | No bump | `docs: update README` |
273
+ | `chore:` | No bump | `chore: update deps` |
274
+
275
+ Releases are automated via GitHub Actions when merging to `main`.
276
+
277
+ ---
278
+
279
+ ## 🤝 Contributing
280
+
281
+ 1. **Fork** the repository
282
+ 2. **Create** a feature branch (`git checkout -b feat/amazing-skill`)
283
+ 3. **Commit** with conventional commits (`git commit -m "feat: add amazing skill"`)
284
+ 4. **Push** to your fork (`git push origin feat/amazing-skill`)
285
+ 5. **Open** a Pull Request
286
+
287
+ ---
288
+
289
+ ## 📄 License
290
+
291
+ MIT © [Tech Leads Club](https://github.com/tech-leads-club)
292
+
293
+ ---
294
+
295
+ <p align="center">
296
+ <sub>Built with ❤️ by the Tech Leads Club community</sub>
297
+ </p>
package/index.js CHANGED
@@ -1,22 +1,26 @@
1
- import{Command as re}from"commander";import{cpSync as x,existsSync as h,mkdirSync as O,readdirSync as pe,symlinkSync as M}from"node:fs";import{join as S,relative as G}from"node:path";import{existsSync as m}from"node:fs";import{homedir as B}from"node:os";import{join as i}from"node:path";var r=B(),y={cursor:{name:"cursor",displayName:"Cursor",description:"AI-first code editor built on VS Code",skillsDir:".cursor/skills",globalSkillsDir:i(r,".cursor/skills"),detectInstalled:()=>m(i(r,".cursor"))},"claude-code":{name:"claude-code",displayName:"Claude Code",description:"Anthropic's agentic coding tool",skillsDir:".claude/skills",globalSkillsDir:i(r,".claude/skills"),detectInstalled:()=>m(i(r,".claude"))},"github-copilot":{name:"github-copilot",displayName:"GitHub Copilot",description:"AI pair programmer by GitHub/Microsoft",skillsDir:".github/skills",globalSkillsDir:i(r,".copilot/skills"),detectInstalled:()=>m(i(r,".copilot"))||m(i(process.cwd(),".github"))},windsurf:{name:"windsurf",displayName:"Windsurf",description:"AI IDE with Cascade flow (Codeium)",skillsDir:".windsurf/skills",globalSkillsDir:i(r,".codeium/windsurf/skills"),detectInstalled:()=>m(i(r,".codeium/windsurf"))},cline:{name:"cline",displayName:"Cline",description:"Autonomous AI coding agent for VS Code",skillsDir:".cline/skills",globalSkillsDir:i(r,".cline/skills"),detectInstalled:()=>m(i(r,".cline"))},aider:{name:"aider",displayName:"Aider",description:"AI pair programming in terminal",skillsDir:".aider/skills",globalSkillsDir:i(r,".aider/skills"),detectInstalled:()=>m(i(r,".aider"))},codex:{name:"codex",displayName:"OpenAI Codex",description:"OpenAI's coding agent",skillsDir:".codex/skills",globalSkillsDir:i(r,".codex/skills"),detectInstalled:()=>m(i(r,".codex"))},gemini:{name:"gemini",displayName:"Gemini CLI",description:"Google's AI coding assistant",skillsDir:".gemini/skills",globalSkillsDir:i(r,".gemini/skills"),detectInstalled:()=>m(i(r,".gemini"))},antigravity:{name:"antigravity",displayName:"Antigravity",description:"Google's agentic coding (VS Code)",skillsDir:".agent/skills",globalSkillsDir:i(r,".agent/skills"),detectInstalled:()=>m(i(r,".gemini/antigravity"))||m(i(process.cwd(),".agent"))},roo:{name:"roo",displayName:"Roo Code",description:"AI coding assistant for VS Code",skillsDir:".roo/skills",globalSkillsDir:i(r,".roo/skills"),detectInstalled:()=>m(i(r,".roo"))},kilocode:{name:"kilocode",displayName:"Kilo Code",description:"AI coding agent with auto-launch",skillsDir:".kilocode/skills",globalSkillsDir:i(r,".kilocode/skills"),detectInstalled:()=>m(i(r,".kilocode"))||m(i(process.cwd(),".kilocode"))},"amazon-q":{name:"amazon-q",displayName:"Amazon Q",description:"AWS AI coding assistant",skillsDir:".amazonq/skills",globalSkillsDir:i(r,".amazonq/skills"),detectInstalled:()=>m(i(r,".amazonq"))},augment:{name:"augment",displayName:"Augment",description:"AI code assistant with context engine",skillsDir:".augment/skills",globalSkillsDir:i(r,".augment/skills"),detectInstalled:()=>m(i(r,".augment"))},tabnine:{name:"tabnine",displayName:"Tabnine",description:"AI code completions with privacy focus",skillsDir:".tabnine/skills",globalSkillsDir:i(r,".tabnine/skills"),detectInstalled:()=>m(i(r,".tabnine"))},opencode:{name:"opencode",displayName:"OpenCode",description:"Open-source AI coding terminal",skillsDir:".opencode/skills",globalSkillsDir:i(r,".config/opencode/skills"),detectInstalled:()=>m(i(r,".config/opencode"))},sourcegraph:{name:"sourcegraph",displayName:"Sourcegraph Cody",description:"AI assistant with codebase context",skillsDir:".sourcegraph/skills",globalSkillsDir:i(r,".sourcegraph/skills"),detectInstalled:()=>m(i(r,".sourcegraph"))}};function w(){return Object.entries(y).filter(([,l])=>l.detectInstalled()).map(([l])=>l)}function f(l){return y[l]}function N(){return Object.keys(y).sort((l,t)=>y[l].displayName.localeCompare(y[t].displayName))}var q=".tlc-skills";function C(l,t){let c=[];for(let o of t.agents){let u=f(o),s=t.global?u.globalSkillsDir:S(process.cwd(),u.skillsDir);h(s)||O(s,{recursive:!0});for(let n of l){let d=F(n,o,s,t.method);c.push(d)}}return c}function F(l,t,c,o){let u=f(t),s=S(c,l.name);try{if(h(s))return{agent:u.displayName,skill:l.name,path:s,method:o,success:!0,error:"Already exists"};if(o==="symlink"){let n=S(process.cwd(),q),d=S(n,l.name);h(n)||O(n,{recursive:!0}),h(d)||x(l.path,d,{recursive:!0});let g=G(c,d);M(g,s)}else x(l.path,s,{recursive:!0});return{agent:u.displayName,skill:l.name,path:s,method:o,success:!0}}catch(n){return{agent:u.displayName,skill:l.name,path:s,method:o,success:!1,error:n instanceof Error?n.message:String(n)}}}import{ConfirmPrompt as J,MultiSelectPrompt as Z,SelectPrompt as ee}from"@clack/core";import e from"picocolors";import{existsSync as I,readdirSync as H,readFileSync as K}from"node:fs";import{dirname as W,join as A}from"node:path";import{fileURLToPath as Y}from"node:url";var U=Y(import.meta.url),_=W(U);function X(){let l=A(_,"..","..","..","skills");if(I(l))return l;let t=A(_,"..","skills");if(I(t))return t;throw new Error(`Skills directory not found. Checked: ${l}, ${t}`)}function k(){let l=X(),t=[];if(!I(l))return t;let c=H(l,{withFileTypes:!0});for(let o of c){if(!o.isDirectory())continue;let u=A(l,o.name,"SKILL.md");if(!I(u))continue;let s=K(u,"utf-8"),{name:n,description:d}=Q(s);t.push({name:n||o.name,description:d||"No description",path:A(l,o.name)})}return t}function Q(l){let t=l.match(/^---\n([\s\S]*?)\n---/);if(!t)return{};let c=t[1],o=c.match(/^name:\s*(.+)$/m),u=c.match(/^description:\s*(.+)$/m);return{name:o?.[1]?.trim(),description:u?.[1]?.trim()}}function P(l){return k().find(c=>c.name===l)}var a="\u2502",b="\u2514",le="\u25CF",se="\u25CB",te="\u25FC",ne="\u25FB",$=e.blue("\u25C6"),L=`
2
- ${e.bold(e.blue("\u25C6 TECH LEADS CLUB"))}
3
- ${e.bold(e.white("Agent Skills"))}
4
- `;function R(l,t){return l.length<=t?l:l.slice(0,t-3)+"..."}async function E(l,t,c=[]){let o=(s,n)=>{let d=n==="selected"||n==="selected-active",g=n==="active"||n==="selected-active",p=d?e.blue(te):e.dim(ne),D=g?e.blue(s.label):s.label,z=g&&s.hint?e.dim(` (${s.hint})`):"";return`${p} ${D}${z}`};return new Z({options:t,initialValues:c,render(){let s=`${e.blue(a)}
5
- ${e.blue($)} ${e.bold(l)}
6
- `;switch(this.state){case"submit":return`${s}${e.blue(a)} ${this.options.filter(n=>this.value.includes(n.value)).map(n=>n.label).join(e.dim(", "))}
7
- ${e.blue(a)}`;case"cancel":return`${s}${e.blue(a)} ${e.strikethrough(e.dim("cancelled"))}
8
- ${e.blue(a)}`;default:return`${s}${this.options.map((n,d)=>{let g=this.value.includes(n.value),p=d===this.cursor,D=g&&p?"selected-active":g?"selected":p?"active":"inactive";return`${e.blue(a)} ${o(n,D)}`}).join(`
1
+ import{Command as Jt}from"commander";import{cp as De,lstat as dt,mkdir as le,readdir as Pe,readlink as yt,rm as E,symlink as kt}from"node:fs/promises";import{homedir as bt,platform as St}from"node:os";import{join as A,normalize as xe,relative as ht,resolve as z,sep as $t}from"node:path";import{existsSync as m}from"node:fs";import{homedir as ot}from"node:os";import{join as g}from"node:path";import{existsSync as fe}from"node:fs";import{dirname as Ze,join as de,parse as et,resolve as tt}from"node:path";function D(e=process.cwd()){let t=tt(e),o=et(t).root;for(;t!==o;){if((fe(de(t,"package.json"))||fe(de(t,".git")))&&!t.endsWith("packages/cli"))return t;t=Ze(t)}return e}var f=ot(),h=D(),B={cursor:{name:"cursor",displayName:"Cursor",description:"AI-first code editor built on VS Code",skillsDir:".cursor/skills",globalSkillsDir:g(f,".cursor/skills"),detectInstalled:()=>m(g(f,".cursor"))||m(g(h,".cursor"))},"claude-code":{name:"claude-code",displayName:"Claude Code",description:"Anthropic's agentic coding tool",skillsDir:".claude/skills",globalSkillsDir:g(f,".claude/skills"),detectInstalled:()=>m(g(f,".claude"))||m(g(h,".claude"))},"github-copilot":{name:"github-copilot",displayName:"GitHub Copilot",description:"AI pair programmer by GitHub/Microsoft",skillsDir:".github/skills",globalSkillsDir:g(f,".copilot/skills"),detectInstalled:()=>m(g(f,".copilot"))||m(g(h,".github"))},windsurf:{name:"windsurf",displayName:"Windsurf",description:"AI IDE with Cascade flow (Codeium)",skillsDir:".windsurf/skills",globalSkillsDir:g(f,".codeium/windsurf/skills"),detectInstalled:()=>m(g(f,".codeium/windsurf"))||m(g(h,".windsurf"))},cline:{name:"cline",displayName:"Cline",description:"Autonomous AI coding agent for VS Code",skillsDir:".cline/skills",globalSkillsDir:g(f,".cline/skills"),detectInstalled:()=>m(g(f,".cline"))||m(g(h,".cline"))},aider:{name:"aider",displayName:"Aider",description:"AI pair programming in terminal",skillsDir:".aider/skills",globalSkillsDir:g(f,".aider/skills"),detectInstalled:()=>m(g(f,".aider"))||m(g(h,".aider"))},codex:{name:"codex",displayName:"OpenAI Codex",description:"OpenAI's coding agent",skillsDir:".codex/skills",globalSkillsDir:g(f,".codex/skills"),detectInstalled:()=>m(g(f,".codex"))||m(g(h,".codex"))},gemini:{name:"gemini",displayName:"Gemini CLI",description:"Google's AI coding assistant",skillsDir:".gemini/skills",globalSkillsDir:g(f,".gemini/skills"),detectInstalled:()=>m(g(f,".gemini"))||m(g(h,".gemini"))},antigravity:{name:"antigravity",displayName:"Antigravity",description:"Google's agentic coding (VS Code)",skillsDir:".agent/skills",globalSkillsDir:g(f,".agent/skills"),detectInstalled:()=>m(g(f,".gemini/antigravity"))||m(g(h,".agent"))},roo:{name:"roo",displayName:"Roo Code",description:"AI coding assistant for VS Code",skillsDir:".roo/skills",globalSkillsDir:g(f,".roo/skills"),detectInstalled:()=>m(g(f,".roo"))||m(g(h,".roo"))},kilocode:{name:"kilocode",displayName:"Kilo Code",description:"AI coding agent with auto-launch",skillsDir:".kilocode/skills",globalSkillsDir:g(f,".kilocode/skills"),detectInstalled:()=>m(g(f,".kilocode"))||m(g(h,".kilocode"))},"amazon-q":{name:"amazon-q",displayName:"Amazon Q",description:"AWS AI coding assistant",skillsDir:".amazonq/skills",globalSkillsDir:g(f,".amazonq/skills"),detectInstalled:()=>m(g(f,".amazonq"))||m(g(h,".amazonq"))},augment:{name:"augment",displayName:"Augment",description:"AI code assistant with context engine",skillsDir:".augment/skills",globalSkillsDir:g(f,".augment/skills"),detectInstalled:()=>m(g(f,".augment"))||m(g(h,".augment"))},tabnine:{name:"tabnine",displayName:"Tabnine",description:"AI code completions with privacy focus",skillsDir:".tabnine/skills",globalSkillsDir:g(f,".tabnine/skills"),detectInstalled:()=>m(g(f,".tabnine"))||m(g(h,".tabnine"))},opencode:{name:"opencode",displayName:"OpenCode",description:"Open-source AI coding terminal",skillsDir:".opencode/skills",globalSkillsDir:g(f,".config/opencode/skills"),detectInstalled:()=>m(g(f,".config/opencode"))||m(g(h,".opencode"))||m(g(h,".config/opencode"))},sourcegraph:{name:"sourcegraph",displayName:"Sourcegraph Cody",description:"AI assistant with codebase context",skillsDir:".sourcegraph/skills",globalSkillsDir:g(f,".sourcegraph/skills"),detectInstalled:()=>m(g(f,".sourcegraph"))||m(g(h,".sourcegraph"))}};function ye(){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 nt}from"node:child_process";import{existsSync as ke}from"node:fs";import{join as be}from"node:path";var lt="@tech-leads-club/agent-skills";function it(){try{return nt("npm root -g",{encoding:"utf-8"}).trim()}catch{return null}}function Se(){let e=it();if(!e)return null;let t=be(e,lt,"skills");return ke(t)?t:null}function ee(){return Se()!==null}function he(e){let t=Se();if(!t)return null;let o=be(t,e);return ke(o)?o:null}import{mkdir as st,readFile as rt,writeFile as at}from"node:fs/promises";import{homedir as ct}from"node:os";import{dirname as gt,join as ut}from"node:path";var mt=".agents",pt=".skill-lock.json",ft=1;function Ae(){return ut(ct(),mt,pt)}function $e(){return{version:ft,skills:{}}}async function we(){let e=Ae();try{let t=await rt(e,"utf-8"),o=JSON.parse(t);return typeof o.version!="number"||!o.skills?$e():o}catch{return $e()}}async function Ie(e){let t=Ae();await st(gt(t),{recursive:!0}),await at(t,JSON.stringify(e,null,2),"utf-8")}async function Ce(e,t="local"){let o=await we(),n=new Date().toISOString(),l=o.skills[e];o.skills[e]={name:e,source:t,installedAt:l?.installedAt??n,updatedAt:n},await Ie(o)}async function ve(e){let t=await we();return e in t.skills?(delete t.skills[e],await Ie(t),!0):!1}var te=A(".agents","skills"),At=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=xe(z(e)),n=xe(z(t));return n.startsWith(o+$t)||n===o}async function Te(e,t){try{try{if((await dt(t)).isSymbolicLink()){let r=await yt(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=ht(o,e),l=St()==="win32"?"junction":void 0;return await kt(n,t,l),!0}catch{return!1}}async function ne(e,t){await le(t,{recursive:!0});let o=await Pe(e,{withFileTypes:!0});for(let n of o){if(At.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 De(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 wt(a,l,r,t.method,n,t.global);o.push(c),c.success&&await Ce(a.name,"local")}}return o}async function wt(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 d=he(e.name);if(d&&await Te(d,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 De(e.path,u,{recursive:!0}),!await Te(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(d){return{agent:r.displayName,skill:e.name,path:c,method:n,success:!1,error:d instanceof Error?d.message:String(d)}}}async function Le(e,t){let o=P(e),n=t?o.globalSkillsDir:A(D(),o.skillsDir);try{return(await Pe(n,{withFileTypes:!0})).filter(i=>i.isDirectory()||i.isSymbolicLink()).map(i=>i.name)}catch{return[]}}function It(e,t={}){let o=ie(e),n=t.global?bt():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=It(e,o);try{await E(r,{recursive:!0,force:!0})}catch{}for(let a of t){let c=P(a),d=o.global?c.globalSkillsDir:A(i,c.skillsDir),u=A(d,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 ve(e),n}import b from"picocolors";import{existsSync as ge,readFileSync as Ct,writeFileSync as Lo}from"node:fs";import{dirname as vt,join as Ee}from"node:path";import{fileURLToPath as xt}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 Tt=xt(import.meta.url),_e=vt(Tt);function Dt(){let e=Ee(_e,"..","..","..",re);if(ge(e))return e;let t=Ee(_e,"..",re);return ge(t)?t:e}function Ne(){let e=Dt();if(!ge(e))return{categories:[],skills:{}};try{let t=Ct(e,"utf-8");return JSON.parse(t)}catch{return{categories:[],skills:{}}}}function Re(e){return Ne().skills[e]??V}function W(e){let t=Ne(),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 Pt,readFileSync as Lt}from"node:fs";import{dirname as Et,join as U}from"node:path";import{fileURLToPath as _t}from"node:url";var Nt=_t(import.meta.url),Oe=Et(Nt);function Rt(){let e=U(Oe,"..","..","..",ae);if(K(e))return e;let t=U(Oe,"..",ae);if(K(t))return t;throw new Error(`Skills directory not found. Checked: ${e}, ${t}`)}function x(){let e=Rt(),t=[];if(!K(e))return t;let o=Pt(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=Lt(l,"utf-8"),{name:r,description:a}=Ot(i),c=r||n.name;t.push({name:c,description:a||"No description",path:U(e,n.name),category:Re(c)})}return t}function Ot(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 Be(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 Gt,MultiSelectPrompt as Ft,SelectPrompt as jt}from"@clack/core";import s from"picocolors";import Bt from"gradient-string";import G from"picocolors";var Ge=Bt([{color:"#1e3a8a",pos:0},{color:"#3b82f6",pos:.3},{color:"#0ea5e9",pos:.5},{color:"#06b6d4",pos:.7},{color:"#22d3ee",pos:1}]),k="\u2502",F="\u2514",Fe="\u25CF",je="\u25CB",ze="\u25FC",Me="\u25FB",T=G.blue("\u25C6");function y(e=""){console.log(e?`${G.blue(k)} ${e}`:G.blue(k))}function C(e=""){console.log(`${G.blue(F)} ${e}`)}function v(){C(G.gray("Cancelled"))}function I(e){return typeof e=="symbol"}async function q(e,t,o,n=!0){let l=(a,c)=>{let d=c?s.blue(Fe):s.gray(je),u=c?s.blue(a.label):s.white(a.label),$=c&&a.hint?s.dim(s.gray(` - ${a.hint}`)):"";return`${d} ${u}${$}`},r=await new jt({options:t,initialValue:o,render(){let a=`${s.blue(k)}
2
+ ${T} ${s.white(s.bold(e))}
3
+ `,c=n?"esc = back, ":"";switch(this.state){case"submit":return`${a}${s.blue(k)} ${s.blue(this.options.find(d=>d.value===this.value)?.label)}
4
+ ${s.blue(k)}`;case"cancel":return`${a}${s.blue(k)} ${s.strikethrough(s.gray("back"))}
5
+ ${s.blue(k)}`;default:return`${a}${this.options.map((d,u)=>`${s.blue(k)} ${l(d,u===this.cursor)}`).join(`
9
6
  `)}
10
- ${e.blue(b)} ${e.dim("(\u2191\u2193 navigate, space select, enter confirm)")}`}}}).prompt()}async function ie(l,t,c){let o=(s,n)=>{let d=n?e.blue(le):e.dim(se),g=n?e.blue(s.label):s.label,p=n&&s.hint?e.dim(` - ${s.hint}`):"";return`${d} ${g}${p}`};return new ee({options:t,initialValue:c,render(){let s=`${e.blue(a)}
11
- ${e.blue($)} ${e.bold(l)}
12
- `;switch(this.state){case"submit":return`${s}${e.blue(a)} ${this.options.find(n=>n.value===this.value)?.label}
13
- ${e.blue(a)}`;case"cancel":return`${s}${e.blue(a)} ${e.strikethrough(e.dim("cancelled"))}
14
- ${e.blue(a)}`;default:return`${s}${this.options.map((n,d)=>`${e.blue(a)} ${o(n,d===this.cursor)}`).join(`
7
+ ${s.blue(k)}
8
+ ${s.blue(F)} ${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 d=c==="selected"||c==="selected-active",u=c==="active"||c==="selected-active",$=d?s.blue(ze):s.gray(Me),S=u?s.blue(a.label):s.white(a.label),O=u&&a.hint?s.dim(s.gray(` (${a.hint})`)):"";return`${$} ${S}${O}`},r=await new Ft({options:t,initialValues:o,render(){let a=`${s.blue(k)}
9
+ ${T} ${s.white(s.bold(e))}
10
+ `,c=n?"esc = back, ":"";switch(this.state){case"submit":return`${a}${s.blue(k)} ${this.options.filter(d=>this.value.includes(d.value)).map(d=>s.blue(String(d.value))).join(s.gray(", "))}
11
+ ${s.blue(k)}`;case"cancel":return`${a}${s.blue(k)} ${s.strikethrough(s.gray("back"))}
12
+ ${s.blue(k)}`;default:return`${a}${this.options.map((d,u)=>{let $=this.value.includes(d.value),S=u===this.cursor,O=$&&S?"selected-active":$?"selected":S?"active":"inactive";return`${s.blue(k)} ${l(d,O)}`}).join(`
15
13
  `)}
16
- ${e.blue(b)}`}}}).prompt()}async function oe(l,t=!1){return new J({active:"Yes",inactive:"No",initialValue:t,render(){let o=`${e.blue(a)}
17
- ${e.blue($)} ${e.bold(l)}
18
- `;switch(this.state){case"submit":return`${o}${e.blue(a)} ${this.value?"Yes":"No"}
19
- ${e.blue(a)}`;case"cancel":return`${o}${e.blue(a)} ${e.strikethrough(e.dim("cancelled"))}
20
- ${e.blue(a)}`;default:return`${o}${e.blue(a)} ${this.value?`${e.blue("\u25CF Yes")} / \u25CB No`:`\u25CB Yes / ${e.blue("\u25CF No")}`}
21
- ${e.blue(b)} ${e.dim("(\u2190\u2192 to change, enter to confirm)")}`}}}).prompt()}async function j(){console.clear(),console.log(L),console.log(`${e.blue(a)}`),console.log(`${e.blue(a)} ${e.dim("Install curated skills to your AI coding agents")}`),console.log(`${e.blue(a)}`);let l=k();if(l.length===0)return console.log(`${e.blue(b)} ${e.red("No skills available")}`),null;let t=w(),c=N();if(t.length>0){let d=t.slice(0,5).map(p=>f(p).displayName).join(", "),g=t.length>5?` +${t.length-5} more`:"";console.log(`${e.blue(a)} ${e.blue("\u25CF")} Detected: ${e.bold(d)}${g}`),console.log(`${e.blue(a)}`)}let o=await E(`Which skills do you want to install? ${e.dim(`(${l.length} available)`)}`,l.map(d=>({value:d.name,label:d.name,hint:R(d.description,200)})));if(typeof o=="symbol")return console.log(`${e.blue(b)} ${e.dim("Cancelled")}`),null;let u=await E(`Where to install? ${e.dim(`(${o.length} skill(s) selected)`)}`,c.map(d=>{let g=f(d),p=t.includes(d);return{value:d,label:p?`${g.displayName} ${e.blue("\u25CF")}`:g.displayName,hint:R(g.description,50)}}),t.length>0?t:["cursor","claude-code"]);if(typeof u=="symbol")return console.log(`${e.blue(b)} ${e.dim("Cancelled")}`),null;let s=await ie("Installation method",[{value:"symlink",label:"Symlink",hint:"recommended - shared source"},{value:"copy",label:"Copy",hint:"independent copies"}],"symlink");if(typeof s=="symbol")return console.log(`${e.blue(b)} ${e.dim("Cancelled")}`),null;let n=await oe("Install globally? (user home vs this project)",!1);return typeof n=="symbol"?(console.log(`${e.blue(b)} ${e.dim("Cancelled")}`),null):(console.log(`${e.blue(a)}`),{agents:u,skills:o,method:s,global:n})}function T(l){let t=l.filter(s=>s.success&&!s.error),c=l.filter(s=>s.success&&s.error==="Already exists"),o=l.filter(s=>!s.success);if(console.log(),t.length>0)for(let s of t)console.log(`${e.blue($)} ${e.bold(s.skill)} \u2192 ${s.agent}`);if(c.length>0)for(let s of c)console.log(`${e.dim($)} ${s.skill} \u2192 ${s.agent} ${e.dim("(exists)")}`);if(o.length>0)for(let s of o)console.log(`${e.red("\u2717")} ${s.skill} \u2192 ${s.agent}: ${s.error}`);let u=new Set(l.map(s=>s.agent)).size;console.log(),console.log(`${e.blue(b)} ${e.blue("\u2713")} ${e.bold(`${t.length} skill(s)`)} installed to ${e.bold(`${u} agent(s)`)}`)}function V(){let l=k();if(console.clear(),console.log(L),l.length===0){console.log(`${e.blue(a)} ${e.yellow("No skills found")}`);return}console.log(`${e.blue(a)}`),console.log(`${e.blue(a)} ${e.bold(`${l.length} skills available:`)}`),console.log(`${e.blue(a)}`);for(let t of l)console.log(`${e.blue(a)} ${e.blue("\u25C6")} ${e.bold(t.name)}`),console.log(`${e.blue(a)} ${e.dim(t.description)}`);console.log(`${e.blue(a)}`),console.log(`${e.blue(b)} ${e.dim('Run "npx @tech-leads-club/agent-skills" to install')}`)}var v=new re;v.name("tlc-skills").description("Install TLC Agent Skills to your AI coding agents").version("0.0.1");v.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 l=>{if(l.skill||l.agent)await ae(l);else{let t=await j();if(!t)return;let c=k().filter(u=>t.skills.includes(u.name)),o=C(c,t);T(o)}});v.command("list").alias("ls").description("List available skills").action(()=>{V()});async function ae(l){let t=k(),c=t;if(l.skill){let n=P(l.skill);n||(console.error(`Skill "${l.skill}" not found.`),console.log("Available skills:",t.map(d=>d.name).join(", ")),process.exit(1)),c=[n]}let o=l.agent||["antigravity","claude-code","cursor"],u=l.copy?"copy":"symlink",s=C(c,{agents:o,skills:c.map(n=>n.name),method:u,global:l.global});T(s)}v.parse();
14
+ ${s.blue(k)}
15
+ ${s.blue(F)} ${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 Gt({active:"Yes",inactive:"No",initialValue:t,render(){let n=`${s.blue(k)}
16
+ ${T} ${s.white(s.bold(e))}
17
+ `;switch(this.state){case"submit":return`${n}${s.blue(k)} ${s.blue(this.value?"Yes":"No")}
18
+ ${s.blue(k)}`;case"cancel":return`${n}${s.blue(k)} ${s.strikethrough(s.gray("cancelled"))}
19
+ ${s.blue(k)}`;default:return`${n}${s.blue(k)} ${this.value?`${s.blue("\u25CF Yes")} ${s.dim(s.gray("/"))} ${s.gray("\u25CB")} ${s.white("No")}`:`${s.gray("\u25CB")} ${s.white("Yes")} ${s.dim(s.gray("/"))} ${s.blue("\u25CF No")}`}
20
+ ${s.blue(k)}
21
+ ${s.blue(F)} ${s.dim(s.gray("(\u2190\u2192 to change, enter to confirm)"))}`}}}).prompt()}import zt from"figlet";import N from"picocolors";function Mt(){let e=zt.textSync("Tech Leads Club",{font:"Larry 3D",horizontalLayout:"default"});return`
22
+ ${Ge.multiline(e)}
23
+ ${N.white(N.bold("Tech Leads Club"))} ${N.blue("\u203A")} ${N.bold(N.blue("Agent Skills"))}
24
+ ${N.white("Curated skills to power up your AI coding agents")}
25
+ `}function R(){console.clear(),console.log(Mt()),y()}import{createRequire as Vt}from"node:module";import Wt from"package-json";var Kt="@tech-leads-club/agent-skills";async function Ve(e){try{let t=await Wt(Kt);return t.version!==e?t.version:null}catch{return null}}function We(){try{return Vt(import.meta.url)("../package.json").version||"0.0.0"}catch{return"0.0.0"}}import p from"picocolors";function Ke(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(),C(`${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&&C(`${p.blue("\u2713")} ${p.white("Skill removed successfully")}`)}import Ut 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} ${Ut.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 Le(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 Ue(){R(),await Yt();let e=x();if(e.length===0)return C(b.red("No skills available")),null;let t=ye(),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}]`),d=r>1;switch(r){case 1:{let u=await qt({allSkills:e,stepIndicator:c,currentCategory:i.category});if(u===null)return null;i.category=u,r++;break}case 2:{let u=await Ye({state:i,allSkills:e,installedSkills:l,stepIndicator:c,allowBack:d});if(u===Symbol.for("back")){r--;break}if(u===null)return null;i.skills=u,r++;break}case 3:{let u=await qe({allAgents:o,installedAgents:t,currentAgents:i.agents,stepIndicator:c,allowBack:d});if(u===Symbol.for("back")){r--;break}if(u===null)return null;i.agents=u,r++;break}case 4:{let u=await He({state:i,stepIndicator:c,allowBack:d});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 Yt(){let e=We(),t=await Ve(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 qt({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)?(v(),null):r}async function Ye({state:e,allSkills:t,installedSkills:o,stepIndicator:n,allowBack:l}){let r=e.category===pe?t:t.filter(S=>S.category===e.category),a=[{value:me,label:`${b.cyan("\u25C9")} ${b.bold("All Skills")}`,hint:`select all ${r.length} skills`},...r.map(S=>{let O=o.has(S.name);return{value:S.name,label:O?`${S.name} ${b.green("\u25CF installed")}`:S.name,hint:Y(S.description,150)}})],c=e.skills.length>0?e.skills:[],d=await _(`${n} Select skills to install`,a,c,l);if(d===Symbol.for("back"))return Symbol.for("back");if(I(d))return v(),null;let u=d,$=u.includes(me)?r.map(S=>S.name):u.filter(S=>S!==me);return $.length===0&&y(b.yellow("\u26A0 Please select at least one skill")),$.length===0?Ye({state:e,allSkills:t,installedSkills:o,stepIndicator:n,allowBack:l}):$}async function qe({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 v(),null;let a=r;return a.length===0?(y(b.yellow("\u26A0 Please select at least one agent")),qe({allAgents:e,installedAgents:t,currentAgents:o,stepIndicator:n,allowBack:l})):a}async function He({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 v(),null;e.method=l,Ke(e);let i=await Ht(e);if(i===Symbol.for("back"))return He({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)?(v(),null):r?(y(),{agents:e.agents,skills:e.skills,method:e.method,global:e.global}):!1}async function Ht(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 Je(){R();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()}C(w.gray('Run "npx @tech-leads-club/agent-skills" to install'))}import Xe from"picocolors";async function Qe(e){R();let t=L(),o=await X(t,e);if(o.size===0){y(Xe.yellow("No skills installed")),C();return}let n=Array.from(o),l=await _(`Which skills do you want to remove? ${Xe.gray(`(${n.length} installed)`)}`,n.map(a=>({value:a,label:a})),[],!1);if(I(l)||l.length===0){v();return}let i=await _("Remove from which agents?",Q(t).map(a=>({...a,hint:void 0})),t,!0);if(I(i)){v();return}let r=await H(`Remove ${l.length} skill(s) from ${i.length} agent(s)?`,!1);if(I(r)||!r){v();return}y();for(let a of l){let c=await M(a,i,{global:e});J(a,c)}}var j=new Jt;j.name("tlc-agent-skills").description("Install TLC Agent Skills to your AI coding agents").version("0.0.1");j.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 Xt(e);else{let t=await Ue();if(!t)return;let o=x().filter(l=>t.skills.includes(l.name)),n=await se(o,t);ue(n)}});j.command("list").alias("ls").description("List available skills").action(async()=>{await Je()});j.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 Qe(e.global)});async function Xt(e){let t=x(),o=t;if(e.skill){let r=Be(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)}j.parse();
22
26
  //# sourceMappingURL=index.js.map
package/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/index.ts", "../src/installer.ts", "../src/agents.ts", "../src/prompts.ts", "../src/skills.ts"],
4
- "sourcesContent": ["import { Command } from 'commander'\n\nimport { installSkills } from './installer'\nimport { runInteractiveInstall, showAvailableSkills, showInstallResults } from './prompts'\nimport { discoverSkills, getSkillByName } from './skills'\nimport type { AgentType } from './types'\n\nconst program = new Command()\n\nprogram.name('tlc-skills').description('Install TLC Agent Skills to your AI coding agents').version('0.0.1')\n\nprogram\n .command('install', { isDefault: true })\n .description('Interactive skill installation (default)')\n .option('-g, --global', 'Install globally to user home', false)\n .option('-s, --skill <name>', 'Install a specific skill')\n .option('-a, --agent <agents...>', 'Target specific agents')\n .option('--copy', 'Use copy instead of symlink', false)\n .action(async (options) => {\n if (options.skill || options.agent) {\n // Non-interactive mode\n await runNonInteractive(options)\n } else {\n // Interactive mode\n const installOptions = await runInteractiveInstall()\n if (!installOptions) return\n const skills = discoverSkills().filter((s) => installOptions.skills.includes(s.name))\n const results = installSkills(skills, installOptions)\n showInstallResults(results)\n }\n })\n\nprogram\n .command('list')\n .alias('ls')\n .description('List available skills')\n .action(() => {\n showAvailableSkills()\n })\n\nasync function runNonInteractive(options: { skill?: string; agent?: string[]; global: boolean; copy: boolean }) {\n const allSkills = discoverSkills()\n let skills = allSkills\n\n if (options.skill) {\n const skill = getSkillByName(options.skill)\n if (!skill) {\n console.error(`Skill \"${options.skill}\" not found.`)\n console.log('Available skills:', allSkills.map((s) => s.name).join(', '))\n process.exit(1)\n }\n skills = [skill]\n }\n\n const agents = (options.agent || ['antigravity', 'claude-code', 'cursor']) as AgentType[]\n const method = options.copy ? 'copy' : 'symlink'\n\n const results = installSkills(skills, {\n agents,\n skills: skills.map((s) => s.name),\n method,\n global: options.global,\n })\n\n showInstallResults(results)\n}\n\nprogram.parse()\n", "import { cpSync, existsSync, mkdirSync, readdirSync, symlinkSync } from 'node:fs'\nimport { join, relative } from 'node:path'\n\nimport { getAgentConfig } from './agents'\nimport type { AgentType, InstallOptions, SkillInfo } from './types'\n\nconst TLC_SKILLS_DIR = '.tlc-skills'\n\nexport interface InstallResult {\n agent: string\n skill: string\n path: string\n method: 'symlink' | 'copy'\n success: boolean\n error?: string\n}\n\nexport function installSkills(skills: SkillInfo[], options: InstallOptions): InstallResult[] {\n const results: InstallResult[] = []\n\n for (const agent of options.agents) {\n const config = getAgentConfig(agent)\n const targetDir = options.global ? config.globalSkillsDir : join(process.cwd(), config.skillsDir)\n if (!existsSync(targetDir)) mkdirSync(targetDir, { recursive: true })\n for (const skill of skills) {\n const result = installSkillForAgent(skill, agent, targetDir, options.method)\n results.push(result)\n }\n }\n\n return results\n}\n\nfunction installSkillForAgent(\n skill: SkillInfo,\n agent: AgentType,\n targetDir: string,\n method: 'symlink' | 'copy',\n): InstallResult {\n const config = getAgentConfig(agent)\n const skillTargetPath = join(targetDir, skill.name)\n\n try {\n if (existsSync(skillTargetPath)) {\n return {\n agent: config.displayName,\n skill: skill.name,\n path: skillTargetPath,\n method,\n success: true,\n error: 'Already exists',\n }\n }\n\n if (method === 'symlink') {\n // For symlinks, we first copy to .tlc-skills then symlink\n const canonicalDir = join(process.cwd(), TLC_SKILLS_DIR)\n const canonicalSkillPath = join(canonicalDir, skill.name)\n if (!existsSync(canonicalDir)) mkdirSync(canonicalDir, { recursive: true })\n if (!existsSync(canonicalSkillPath)) cpSync(skill.path, canonicalSkillPath, { recursive: true })\n const relativePath = relative(targetDir, canonicalSkillPath)\n symlinkSync(relativePath, skillTargetPath)\n } else {\n cpSync(skill.path, skillTargetPath, { recursive: true })\n }\n\n return {\n agent: config.displayName,\n skill: skill.name,\n path: skillTargetPath,\n method,\n success: true,\n }\n } catch (error) {\n return {\n agent: config.displayName,\n skill: skill.name,\n path: skillTargetPath,\n method,\n success: false,\n error: error instanceof Error ? error.message : String(error),\n }\n }\n}\n\nexport function listInstalledSkills(agent: AgentType, global: boolean): string[] {\n const config = getAgentConfig(agent)\n const targetDir = global ? config.globalSkillsDir : join(process.cwd(), config.skillsDir)\n if (!existsSync(targetDir)) return []\n return readdirSync(targetDir, { withFileTypes: true })\n .filter((entry) => entry.isDirectory() || entry.isSymbolicLink())\n .map((entry) => entry.name)\n}\n", "import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\n\nimport type { AgentConfig, AgentType } from './types'\n\nconst home = homedir()\n\nexport const agents: Record<AgentType, AgentConfig> = {\n // Tier 1: Most popular AI coding agents\n cursor: {\n name: 'cursor',\n displayName: 'Cursor',\n description: 'AI-first code editor built on VS Code',\n skillsDir: '.cursor/skills',\n globalSkillsDir: join(home, '.cursor/skills'),\n detectInstalled: () => existsSync(join(home, '.cursor')),\n },\n 'claude-code': {\n name: 'claude-code',\n displayName: 'Claude Code',\n description: \"Anthropic's agentic coding tool\",\n skillsDir: '.claude/skills',\n globalSkillsDir: join(home, '.claude/skills'),\n detectInstalled: () => existsSync(join(home, '.claude')),\n },\n 'github-copilot': {\n name: 'github-copilot',\n displayName: 'GitHub Copilot',\n description: 'AI pair programmer by GitHub/Microsoft',\n skillsDir: '.github/skills',\n globalSkillsDir: join(home, '.copilot/skills'),\n detectInstalled: () => existsSync(join(home, '.copilot')) || existsSync(join(process.cwd(), '.github')),\n },\n windsurf: {\n name: 'windsurf',\n displayName: 'Windsurf',\n description: 'AI IDE with Cascade flow (Codeium)',\n skillsDir: '.windsurf/skills',\n globalSkillsDir: join(home, '.codeium/windsurf/skills'),\n detectInstalled: () => existsSync(join(home, '.codeium/windsurf')),\n },\n cline: {\n name: 'cline',\n displayName: 'Cline',\n description: 'Autonomous AI coding agent for VS Code',\n skillsDir: '.cline/skills',\n globalSkillsDir: join(home, '.cline/skills'),\n detectInstalled: () => existsSync(join(home, '.cline')),\n },\n\n // Tier 2: Rising stars\n aider: {\n name: 'aider',\n displayName: 'Aider',\n description: 'AI pair programming in terminal',\n skillsDir: '.aider/skills',\n globalSkillsDir: join(home, '.aider/skills'),\n detectInstalled: () => existsSync(join(home, '.aider')),\n },\n codex: {\n name: 'codex',\n displayName: 'OpenAI Codex',\n description: \"OpenAI's coding agent\",\n skillsDir: '.codex/skills',\n globalSkillsDir: join(home, '.codex/skills'),\n detectInstalled: () => existsSync(join(home, '.codex')),\n },\n gemini: {\n name: 'gemini',\n displayName: 'Gemini CLI',\n description: \"Google's AI coding assistant\",\n skillsDir: '.gemini/skills',\n globalSkillsDir: join(home, '.gemini/skills'),\n detectInstalled: () => existsSync(join(home, '.gemini')),\n },\n antigravity: {\n name: 'antigravity',\n displayName: 'Antigravity',\n description: \"Google's agentic coding (VS Code)\",\n skillsDir: '.agent/skills',\n globalSkillsDir: join(home, '.agent/skills'),\n detectInstalled: () => existsSync(join(home, '.gemini/antigravity')) || existsSync(join(process.cwd(), '.agent')),\n },\n roo: {\n name: 'roo',\n displayName: 'Roo Code',\n description: 'AI coding assistant for VS Code',\n skillsDir: '.roo/skills',\n globalSkillsDir: join(home, '.roo/skills'),\n detectInstalled: () => existsSync(join(home, '.roo')),\n },\n kilocode: {\n name: 'kilocode',\n displayName: 'Kilo Code',\n description: 'AI coding agent with auto-launch',\n skillsDir: '.kilocode/skills',\n globalSkillsDir: join(home, '.kilocode/skills'),\n detectInstalled: () => existsSync(join(home, '.kilocode')) || existsSync(join(process.cwd(), '.kilocode')),\n },\n\n // Tier 3: Enterprise & specialized\n 'amazon-q': {\n name: 'amazon-q',\n displayName: 'Amazon Q',\n description: 'AWS AI coding assistant',\n skillsDir: '.amazonq/skills',\n globalSkillsDir: join(home, '.amazonq/skills'),\n detectInstalled: () => existsSync(join(home, '.amazonq')),\n },\n augment: {\n name: 'augment',\n displayName: 'Augment',\n description: 'AI code assistant with context engine',\n skillsDir: '.augment/skills',\n globalSkillsDir: join(home, '.augment/skills'),\n detectInstalled: () => existsSync(join(home, '.augment')),\n },\n tabnine: {\n name: 'tabnine',\n displayName: 'Tabnine',\n description: 'AI code completions with privacy focus',\n skillsDir: '.tabnine/skills',\n globalSkillsDir: join(home, '.tabnine/skills'),\n detectInstalled: () => existsSync(join(home, '.tabnine')),\n },\n opencode: {\n name: 'opencode',\n displayName: 'OpenCode',\n description: 'Open-source AI coding terminal',\n skillsDir: '.opencode/skills',\n globalSkillsDir: join(home, '.config/opencode/skills'),\n detectInstalled: () => existsSync(join(home, '.config/opencode')),\n },\n sourcegraph: {\n name: 'sourcegraph',\n displayName: 'Sourcegraph Cody',\n description: 'AI assistant with codebase context',\n skillsDir: '.sourcegraph/skills',\n globalSkillsDir: join(home, '.sourcegraph/skills'),\n detectInstalled: () => existsSync(join(home, '.sourcegraph')),\n },\n}\n\nexport function detectInstalledAgents(): AgentType[] {\n return (Object.entries(agents) as [AgentType, AgentConfig][])\n .filter(([, config]) => config.detectInstalled())\n .map(([type]) => type)\n}\n\nexport function getAgentConfig(type: AgentType): AgentConfig {\n return agents[type]\n}\n\nexport function getAllAgentTypes(): AgentType[] {\n return (Object.keys(agents) as AgentType[]).sort((a, b) => agents[a].displayName.localeCompare(agents[b].displayName))\n}\n", "import { ConfirmPrompt, MultiSelectPrompt, SelectPrompt } from '@clack/core'\nimport pc from 'picocolors'\n\nimport { detectInstalledAgents, getAgentConfig, getAllAgentTypes } from './agents'\nimport { discoverSkills } from './skills'\nimport type { AgentType, InstallOptions } from './types'\n\nconst S_BAR = '\u2502'\nconst S_BAR_END = '\u2514'\nconst S_RADIO_ACTIVE = '\u25CF'\nconst S_RADIO_INACTIVE = '\u25CB'\nconst S_CHECKBOX_ACTIVE = '\u25FC'\nconst S_CHECKBOX_INACTIVE = '\u25FB'\n\nconst symbol = pc.blue('\u25C6')\n\nconst LOGO = `\n ${pc.bold(pc.blue('\u25C6 TECH LEADS CLUB'))}\n ${pc.bold(pc.white('Agent Skills'))}\n`\n\nfunction truncate(text: string, maxLength: number): string {\n if (text.length <= maxLength) return text\n return text.slice(0, maxLength - 3) + '...'\n}\n\ninterface Option<T> {\n value: T\n label: string\n hint?: string\n}\n\nasync function blueMultiSelect<T>(\n message: string,\n options: Option<T>[],\n initialValues: T[] = [],\n): Promise<T[] | symbol> {\n const opt = (option: Option<T>, state: 'active' | 'selected' | 'cancelled' | 'inactive' | 'selected-active') => {\n const isSelected = state === 'selected' || state === 'selected-active'\n const isActive = state === 'active' || state === 'selected-active'\n const checkbox = isSelected ? pc.blue(S_CHECKBOX_ACTIVE) : pc.dim(S_CHECKBOX_INACTIVE)\n const label = isActive ? pc.blue(option.label) : option.label\n const hint = isActive && option.hint ? pc.dim(` (${option.hint})`) : ''\n return `${checkbox} ${label}${hint}`\n }\n\n const prompt = new MultiSelectPrompt({\n options,\n initialValues,\n render() {\n const title = `${pc.blue(S_BAR)}\\n${pc.blue(symbol)} ${pc.bold(message)}\\n`\n\n switch (this.state) {\n case 'submit':\n return `${title}${pc.blue(S_BAR)} ${this.options\n .filter((o) => this.value.includes(o.value))\n .map((o) => o.label)\n .join(pc.dim(', '))}\\n${pc.blue(S_BAR)}`\n case 'cancel':\n return `${title}${pc.blue(S_BAR)} ${pc.strikethrough(pc.dim('cancelled'))}\\n${pc.blue(S_BAR)}`\n default:\n return `${title}${this.options\n .map((option, i) => {\n const isSelected = this.value.includes(option.value)\n const isActive = i === this.cursor\n const state =\n isSelected && isActive ? 'selected-active' : isSelected ? 'selected' : isActive ? 'active' : 'inactive'\n return `${pc.blue(S_BAR)} ${opt(option as Option<T>, state)}`\n })\n .join('\\n')}\\n${pc.blue(S_BAR_END)} ${pc.dim('(\u2191\u2193 navigate, space select, enter confirm)')}`\n }\n },\n })\n\n return prompt.prompt() as Promise<T[] | symbol>\n}\n\nasync function blueSelect<T>(message: string, options: Option<T>[], initialValue?: T): Promise<T | symbol> {\n const opt = (option: Option<T>, isActive: boolean) => {\n const radio = isActive ? pc.blue(S_RADIO_ACTIVE) : pc.dim(S_RADIO_INACTIVE)\n const label = isActive ? pc.blue(option.label) : option.label\n const hint = isActive && option.hint ? pc.dim(` - ${option.hint}`) : ''\n return `${radio} ${label}${hint}`\n }\n\n const prompt = new SelectPrompt({\n options,\n initialValue,\n render() {\n const title = `${pc.blue(S_BAR)}\\n${pc.blue(symbol)} ${pc.bold(message)}\\n`\n\n switch (this.state) {\n case 'submit':\n return `${title}${pc.blue(S_BAR)} ${this.options.find((o) => o.value === this.value)?.label}\\n${pc.blue(S_BAR)}`\n case 'cancel':\n return `${title}${pc.blue(S_BAR)} ${pc.strikethrough(pc.dim('cancelled'))}\\n${pc.blue(S_BAR)}`\n default:\n return `${title}${this.options\n .map((option, i) => `${pc.blue(S_BAR)} ${opt(option as Option<T>, i === this.cursor)}`)\n .join('\\n')}\\n${pc.blue(S_BAR_END)}`\n }\n },\n })\n\n return prompt.prompt() as Promise<T | symbol>\n}\n\nasync function blueConfirm(message: string, initialValue = false): Promise<boolean | symbol> {\n const prompt = new ConfirmPrompt({\n active: 'Yes',\n inactive: 'No',\n initialValue,\n render() {\n const title = `${pc.blue(S_BAR)}\\n${pc.blue(symbol)} ${pc.bold(message)}\\n`\n\n switch (this.state) {\n case 'submit':\n return `${title}${pc.blue(S_BAR)} ${this.value ? 'Yes' : 'No'}\\n${pc.blue(S_BAR)}`\n case 'cancel':\n return `${title}${pc.blue(S_BAR)} ${pc.strikethrough(pc.dim('cancelled'))}\\n${pc.blue(S_BAR)}`\n default:\n return `${title}${pc.blue(S_BAR)} ${this.value ? `${pc.blue('\u25CF Yes')} / \u25CB No` : `\u25CB Yes / ${pc.blue('\u25CF No')}`}\\n${pc.blue(S_BAR_END)} ${pc.dim('(\u2190\u2192 to change, enter to confirm)')}`\n }\n },\n })\n\n return prompt.prompt() as Promise<boolean | symbol>\n}\n\nexport async function runInteractiveInstall(): Promise<InstallOptions | null> {\n console.clear()\n console.log(LOGO)\n console.log(`${pc.blue(S_BAR)}`)\n console.log(`${pc.blue(S_BAR)} ${pc.dim('Install curated skills to your AI coding agents')}`)\n console.log(`${pc.blue(S_BAR)}`)\n\n const skills = discoverSkills()\n if (skills.length === 0) {\n console.log(`${pc.blue(S_BAR_END)} ${pc.red('No skills available')}`)\n return null\n }\n\n const installedAgents = detectInstalledAgents()\n const allAgents = getAllAgentTypes()\n\n if (installedAgents.length > 0) {\n const agentNames = installedAgents\n .slice(0, 5)\n .map((a) => getAgentConfig(a).displayName)\n .join(', ')\n const more = installedAgents.length > 5 ? ` +${installedAgents.length - 5} more` : ''\n console.log(`${pc.blue(S_BAR)} ${pc.blue('\u25CF')} Detected: ${pc.bold(agentNames)}${more}`)\n console.log(`${pc.blue(S_BAR)}`)\n }\n\n // Step 1\n const selectedSkills = await blueMultiSelect(\n `Which skills do you want to install? ${pc.dim(`(${skills.length} available)`)}`,\n skills.map((skill) => ({ value: skill.name, label: skill.name, hint: truncate(skill.description, 200) })),\n )\n\n if (typeof selectedSkills === 'symbol') {\n console.log(`${pc.blue(S_BAR_END)} ${pc.dim('Cancelled')}`)\n return null\n }\n\n // Step 2\n const selectedAgents = await blueMultiSelect(\n `Where to install? ${pc.dim(`(${selectedSkills.length} skill(s) selected)`)}`,\n allAgents.map((type) => {\n const config = getAgentConfig(type)\n const isInstalled = installedAgents.includes(type)\n return {\n value: type,\n label: isInstalled ? `${config.displayName} ${pc.blue('\u25CF')}` : config.displayName,\n hint: truncate(config.description, 50),\n }\n }),\n installedAgents.length > 0 ? installedAgents : ['cursor', 'claude-code'],\n )\n\n if (typeof selectedAgents === 'symbol') {\n console.log(`${pc.blue(S_BAR_END)} ${pc.dim('Cancelled')}`)\n return null\n }\n\n // Step 3\n const method = await blueSelect(\n 'Installation method',\n [\n { value: 'symlink', label: 'Symlink', hint: 'recommended - shared source' },\n { value: 'copy', label: 'Copy', hint: 'independent copies' },\n ],\n 'symlink',\n )\n\n if (typeof method === 'symbol') {\n console.log(`${pc.blue(S_BAR_END)} ${pc.dim('Cancelled')}`)\n return null\n }\n\n // Step 4\n const global = await blueConfirm('Install globally? (user home vs this project)', false)\n\n if (typeof global === 'symbol') {\n console.log(`${pc.blue(S_BAR_END)} ${pc.dim('Cancelled')}`)\n return null\n }\n\n console.log(`${pc.blue(S_BAR)}`)\n\n return {\n agents: selectedAgents as AgentType[],\n skills: selectedSkills as string[],\n method: method as 'symlink' | 'copy',\n global: global as boolean,\n }\n}\n\nexport function showInstallResults(\n results: Array<{\n agent: string\n skill: string\n path: string\n method: string\n success: boolean\n error?: string\n }>,\n) {\n const successful = results.filter((r) => r.success && !r.error)\n const alreadyExists = results.filter((r) => r.success && r.error === 'Already exists')\n const failed = results.filter((r) => !r.success)\n\n console.log()\n\n if (successful.length > 0) {\n for (const r of successful) {\n console.log(`${pc.blue(symbol)} ${pc.bold(r.skill)} \u2192 ${r.agent}`)\n }\n }\n\n if (alreadyExists.length > 0) {\n for (const r of alreadyExists) {\n console.log(`${pc.dim(symbol)} ${r.skill} \u2192 ${r.agent} ${pc.dim('(exists)')}`)\n }\n }\n\n if (failed.length > 0) {\n for (const r of failed) {\n console.log(`${pc.red('\u2717')} ${r.skill} \u2192 ${r.agent}: ${r.error}`)\n }\n }\n\n const totalAgents = new Set(results.map((r) => r.agent)).size\n\n console.log()\n console.log(\n `${pc.blue(S_BAR_END)} ${pc.blue('\u2713')} ${pc.bold(`${successful.length} skill(s)`)} installed to ${pc.bold(`${totalAgents} agent(s)`)}`,\n )\n}\n\nexport function showAvailableSkills() {\n const skills = discoverSkills()\n\n console.clear()\n console.log(LOGO)\n\n if (skills.length === 0) {\n console.log(`${pc.blue(S_BAR)} ${pc.yellow('No skills found')}`)\n return\n }\n\n console.log(`${pc.blue(S_BAR)}`)\n console.log(`${pc.blue(S_BAR)} ${pc.bold(`${skills.length} skills available:`)}`)\n console.log(`${pc.blue(S_BAR)}`)\n\n for (const skill of skills) {\n console.log(`${pc.blue(S_BAR)} ${pc.blue('\u25C6')} ${pc.bold(skill.name)}`)\n console.log(`${pc.blue(S_BAR)} ${pc.dim(skill.description)}`)\n }\n\n console.log(`${pc.blue(S_BAR)}`)\n console.log(`${pc.blue(S_BAR_END)} ${pc.dim('Run \"npx @tech-leads-club/agent-skills\" to install')}`)\n}\n", "import { existsSync, readdirSync, readFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nimport type { SkillInfo } from './types'\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = dirname(__filename)\n\nexport function getSkillsDirectory(): string {\n const devSkillsDir = join(__dirname, '..', '..', '..', 'skills')\n if (existsSync(devSkillsDir)) return devSkillsDir\n const pkgSkillsDir = join(__dirname, '..', 'skills')\n if (existsSync(pkgSkillsDir)) return pkgSkillsDir\n throw new Error(`Skills directory not found. Checked: ${devSkillsDir}, ${pkgSkillsDir}`)\n}\n\nexport function discoverSkills(): SkillInfo[] {\n const skillsDir = getSkillsDirectory()\n const skills: SkillInfo[] = []\n if (!existsSync(skillsDir)) return skills\n const entries = readdirSync(skillsDir, { withFileTypes: true })\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n const skillMdPath = join(skillsDir, entry.name, 'SKILL.md')\n if (!existsSync(skillMdPath)) continue\n const content = readFileSync(skillMdPath, 'utf-8')\n const { name, description } = parseSkillFrontmatter(content)\n\n skills.push({\n name: name || entry.name,\n description: description || 'No description',\n path: join(skillsDir, entry.name),\n })\n }\n\n return skills\n}\n\nfunction parseSkillFrontmatter(content: string): { name?: string; description?: string } {\n const frontmatterMatch = content.match(/^---\\n([\\s\\S]*?)\\n---/)\n if (!frontmatterMatch) return {}\n const frontmatter = frontmatterMatch[1]\n const nameMatch = frontmatter.match(/^name:\\s*(.+)$/m)\n const descMatch = frontmatter.match(/^description:\\s*(.+)$/m)\n return { name: nameMatch?.[1]?.trim(), description: descMatch?.[1]?.trim() }\n}\n\nexport function getSkillByName(name: string): SkillInfo | undefined {\n const skills = discoverSkills()\n return skills.find((s) => s.name === name)\n}\n"],
5
- "mappings": "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",
6
- "names": ["Command", "cpSync", "existsSync", "mkdirSync", "readdirSync", "symlinkSync", "join", "relative", "existsSync", "homedir", "join", "home", "agents", "detectInstalledAgents", "config", "type", "getAgentConfig", "getAllAgentTypes", "a", "b", "TLC_SKILLS_DIR", "installSkills", "skills", "options", "results", "agent", "config", "getAgentConfig", "targetDir", "join", "existsSync", "mkdirSync", "skill", "result", "installSkillForAgent", "method", "skillTargetPath", "canonicalDir", "canonicalSkillPath", "cpSync", "relativePath", "relative", "symlinkSync", "error", "ConfirmPrompt", "MultiSelectPrompt", "SelectPrompt", "pc", "existsSync", "readdirSync", "readFileSync", "dirname", "join", "fileURLToPath", "__filename", "__dirname", "getSkillsDirectory", "devSkillsDir", "pkgSkillsDir", "discoverSkills", "skillsDir", "skills", "entries", "entry", "skillMdPath", "content", "name", "description", "parseSkillFrontmatter", "frontmatterMatch", "frontmatter", "nameMatch", "descMatch", "getSkillByName", "s", "S_BAR", "S_BAR_END", "S_RADIO_ACTIVE", "S_RADIO_INACTIVE", "S_CHECKBOX_ACTIVE", "S_CHECKBOX_INACTIVE", "symbol", "pc", "LOGO", "truncate", "text", "maxLength", "blueMultiSelect", "message", "options", "initialValues", "opt", "option", "state", "isSelected", "isActive", "checkbox", "label", "hint", "MultiSelectPrompt", "title", "o", "i", "blueSelect", "initialValue", "radio", "SelectPrompt", "blueConfirm", "ConfirmPrompt", "runInteractiveInstall", "skills", "discoverSkills", "installedAgents", "detectInstalledAgents", "allAgents", "getAllAgentTypes", "agentNames", "a", "getAgentConfig", "more", "selectedSkills", "skill", "selectedAgents", "type", "config", "isInstalled", "method", "global", "showInstallResults", "results", "successful", "r", "alreadyExists", "failed", "totalAgents", "showAvailableSkills", "program", "Command", "options", "runNonInteractive", "installOptions", "runInteractiveInstall", "skills", "discoverSkills", "s", "results", "installSkills", "showInstallResults", "showAvailableSkills", "allSkills", "skill", "getSkillByName", "agents", "method"]
3
+ "sources": ["../src/index.ts", "../src/installer.ts", "../src/agents.ts", "../src/project-root.ts", "../src/global-path.ts", "../src/lockfile.ts", "../src/prompts/install.ts", "../src/categories.ts", "../../../libs/core/src/lib/constants.ts", "../src/skills.ts", "../src/ui/formatting.ts", "../src/ui/input.ts", "../src/ui/styles.ts", "../src/ui/screen.ts", "../src/update-check.ts", "../src/prompts/results.ts", "../src/prompts/utils.ts", "../src/prompts/list.ts", "../src/prompts/remove.ts"],
4
+ "sourcesContent": ["import { Command } from 'commander'\n\nimport { installSkills, removeSkill } from './installer'\nimport { runInteractiveInstall } from './prompts/install'\nimport { showAvailableSkills } from './prompts/list'\nimport { runInteractiveRemove } from './prompts/remove'\nimport { showInstallResults, showRemoveResults } from './prompts/results'\nimport { discoverSkills, getSkillByName } from './skills'\nimport type { AgentType } from './types'\n\nconst program = new Command()\n\nprogram.name('tlc-agent-skills').description('Install TLC Agent Skills to your AI coding agents').version('0.0.1')\n\nprogram\n .command('install', { isDefault: true })\n .description('Interactive skill installation (default)')\n .option('-g, --global', 'Install globally to user home', false)\n .option('-s, --skill <name>', 'Install a specific skill')\n .option('-a, --agent <agents...>', 'Target specific agents')\n .option('--copy', 'Use copy instead of symlink', false)\n .action(async (options) => {\n if (options.skill || options.agent) {\n await runNonInteractive(options)\n } else {\n const installOptions = await runInteractiveInstall()\n if (!installOptions) return\n const skills = discoverSkills().filter((s) => installOptions.skills.includes(s.name))\n const results = await installSkills(skills, installOptions)\n showInstallResults(results)\n }\n })\n\nprogram\n .command('list')\n .alias('ls')\n .description('List available skills')\n .action(async () => {\n await showAvailableSkills()\n })\n\nprogram\n .command('remove')\n .alias('rm')\n .description('Remove installed skills')\n .option('-g, --global', 'Remove from global installation', false)\n .option('-s, --skill <name>', 'Remove a specific skill')\n .option('-a, --agent <agents...>', 'Target specific agents')\n .action(async (options) => {\n if (options.skill) {\n const agents = (options.agent || ['antigravity', 'claude-code', 'cursor']) as AgentType[]\n const results = await removeSkill(options.skill, agents, { global: options.global })\n showRemoveResults(options.skill, results)\n } else {\n await runInteractiveRemove(options.global)\n }\n })\n\nasync function runNonInteractive(options: { skill?: string; agent?: string[]; global: boolean; copy: boolean }) {\n const allSkills = discoverSkills()\n let skills = allSkills\n\n if (options.skill) {\n const skill = getSkillByName(options.skill)\n if (!skill) {\n console.error(`Skill \"${options.skill}\" not found.`)\n console.log('Available skills:', allSkills.map((s) => s.name).join(', '))\n process.exit(1)\n }\n skills = [skill]\n }\n\n const agents = (options.agent || ['antigravity', 'claude-code', 'cursor']) as AgentType[]\n const method = options.copy ? 'copy' : 'symlink'\n\n const results = await installSkills(skills, {\n agents,\n skills: skills.map((s) => s.name),\n method,\n global: options.global,\n })\n\n showInstallResults(results)\n}\n\nprogram.parse()\n", "import { cp, lstat, mkdir, readdir, readlink, rm, symlink } from 'node:fs/promises'\nimport { homedir, platform } from 'node:os'\nimport { join, normalize, relative, resolve, sep } from 'node:path'\n\nimport { getAgentConfig } from './agents'\nimport { getGlobalSkillPath, isGloballyInstalled } from './global-path'\nimport { addSkillToLock, removeSkillFromLock } from './lockfile'\nimport { findProjectRoot } from './project-root'\nimport type { AgentType, InstallOptions, InstallResult, SkillInfo } from './types'\n\nconst AGENTS_SKILLS_DIR = join('.agents', 'skills')\nconst EXCLUDE_FILES = new Set(['README.md', 'metadata.json', 'SKILL.md'])\n\nfunction sanitizeName(name: string): string {\n let sanitized = name.replace(/[/\\\\]/g, '')\n sanitized = sanitized.replace(/[\\0:]/g, '')\n sanitized = sanitized.replace(/^[.\\s]+|[.\\s]+$/g, '')\n sanitized = sanitized.replace(/^\\.+/, '')\n if (!sanitized || sanitized.length === 0) sanitized = 'unnamed-skill'\n return sanitized.substring(0, 255)\n}\n\nfunction isPathSafe(basePath: string, targetPath: string): boolean {\n const normalizedBase = normalize(resolve(basePath))\n const normalizedTarget = normalize(resolve(targetPath))\n return normalizedTarget.startsWith(normalizedBase + sep) || normalizedTarget === normalizedBase\n}\n\nasync function createSymlink(target: string, linkPath: string): Promise<boolean> {\n try {\n try {\n const stats = await lstat(linkPath)\n if (stats.isSymbolicLink()) {\n const existingTarget = await readlink(linkPath)\n if (resolve(existingTarget) === resolve(target)) return true\n await rm(linkPath)\n } else {\n await rm(linkPath, { recursive: true })\n }\n } catch (err: unknown) {\n if ((err as { code?: string })?.code === 'ELOOP') {\n try {\n await rm(linkPath, { force: true })\n } catch {\n // ignore\n }\n }\n }\n\n const linkDir = join(linkPath, '..')\n await mkdir(linkDir, { recursive: true })\n const relativePath = relative(linkDir, target)\n const type = platform() === 'win32' ? 'junction' : undefined\n await symlink(relativePath, linkPath, type)\n return true\n } catch {\n return false\n }\n}\n\nasync function copyDirectory(src: string, dest: string): Promise<void> {\n await mkdir(dest, { recursive: true })\n const entries = await readdir(src, { withFileTypes: true })\n\n for (const entry of entries) {\n if (EXCLUDE_FILES.has(entry.name) || entry.name.startsWith('_')) continue\n const srcPath = join(src, entry.name)\n const destPath = join(dest, entry.name)\n\n if (entry.isDirectory()) {\n await copyDirectory(srcPath, destPath)\n } else {\n await cp(srcPath, destPath)\n }\n }\n}\n\nexport async function installSkills(skills: SkillInfo[], options: InstallOptions): Promise<InstallResult[]> {\n const results: InstallResult[] = []\n const projectRoot = findProjectRoot()\n\n for (const agent of options.agents) {\n const config = getAgentConfig(agent)\n const targetDir = options.global ? config.globalSkillsDir : join(projectRoot, config.skillsDir)\n\n for (const skill of skills) {\n const result = await installSkillForAgent(skill, agent, targetDir, options.method, projectRoot, options.global)\n results.push(result)\n if (result.success) await addSkillToLock(skill.name, 'local')\n }\n }\n\n return results\n}\n\nasync function installSkillForAgent(\n skill: SkillInfo,\n agent: AgentType,\n targetDir: string,\n method: 'symlink' | 'copy',\n projectRoot: string,\n global: boolean,\n): Promise<InstallResult> {\n const config = getAgentConfig(agent)\n const safeSkillName = sanitizeName(skill.name)\n const skillTargetPath = join(targetDir, safeSkillName)\n\n if (!isPathSafe(targetDir, skillTargetPath) && !global) {\n if (!isPathSafe(projectRoot, skillTargetPath) && !global) {\n return {\n agent: config.displayName,\n skill: skill.name,\n path: skillTargetPath,\n method,\n success: false,\n error: 'Security: Invalid skill destination path',\n }\n }\n }\n\n try {\n if (method === 'symlink') {\n const globalSkillPath = getGlobalSkillPath(skill.name)\n\n if (globalSkillPath) {\n const success = await createSymlink(globalSkillPath, skillTargetPath)\n if (success) {\n return {\n agent: config.displayName,\n skill: skill.name,\n path: skillTargetPath,\n method,\n success: true,\n usedGlobalSymlink: true,\n }\n }\n }\n\n const canonicalDir = join(projectRoot, AGENTS_SKILLS_DIR, safeSkillName)\n await mkdir(canonicalDir, { recursive: true })\n await cp(skill.path, canonicalDir, { recursive: true })\n const symlinkCreated = await createSymlink(canonicalDir, skillTargetPath)\n\n if (!symlinkCreated) {\n try {\n await rm(skillTargetPath, { recursive: true, force: true })\n } catch {\n // ignore\n }\n\n await copyDirectory(skill.path, skillTargetPath)\n\n return {\n agent: config.displayName,\n skill: skill.name,\n path: skillTargetPath,\n method: 'copy',\n success: true,\n symlinkFailed: true,\n }\n }\n\n return {\n agent: config.displayName,\n skill: skill.name,\n path: skillTargetPath,\n method,\n success: true,\n usedGlobalSymlink: false,\n }\n } else {\n await copyDirectory(skill.path, skillTargetPath)\n return {\n agent: config.displayName,\n skill: skill.name,\n path: skillTargetPath,\n method,\n success: true,\n }\n }\n } catch (error) {\n return {\n agent: config.displayName,\n skill: skill.name,\n path: skillTargetPath,\n method,\n success: false,\n error: error instanceof Error ? error.message : String(error),\n }\n }\n}\n\nexport async function listInstalledSkills(agent: AgentType, global: boolean): Promise<string[]> {\n const config = getAgentConfig(agent)\n const targetDir = global ? config.globalSkillsDir : join(findProjectRoot(), config.skillsDir)\n\n try {\n const entries = await readdir(targetDir, { withFileTypes: true })\n return entries.filter((entry) => entry.isDirectory() || entry.isSymbolicLink()).map((entry) => entry.name)\n } catch {\n return []\n }\n}\n\nexport async function isSkillInstalled(\n skillName: string,\n agent: AgentType,\n options: { global?: boolean } = {},\n): Promise<boolean> {\n const config = getAgentConfig(agent)\n const safeSkillName = sanitizeName(skillName)\n const targetBase = options.global ? config.globalSkillsDir : join(findProjectRoot(), config.skillsDir)\n const skillDir = join(targetBase, safeSkillName)\n\n if (!isPathSafe(targetBase, skillDir)) return false\n\n try {\n await lstat(skillDir)\n return true\n } catch {\n return false\n }\n}\n\nexport function getInstallPath(skillName: string, agent: AgentType, options: { global?: boolean } = {}): string {\n const config = getAgentConfig(agent)\n const safeSkillName = sanitizeName(skillName)\n const targetBase = options.global ? config.globalSkillsDir : join(findProjectRoot(), config.skillsDir)\n const installPath = join(targetBase, safeSkillName)\n\n if (!isPathSafe(targetBase, installPath)) {\n throw new Error('Invalid skill name: potential path traversal detected')\n }\n\n return installPath\n}\n\nexport function getCanonicalPath(skillName: string, options: { global?: boolean } = {}): string {\n const safeSkillName = sanitizeName(skillName)\n const baseDir = options.global ? homedir() : findProjectRoot()\n const canonicalPath = join(baseDir, AGENTS_SKILLS_DIR, safeSkillName)\n\n if (!isPathSafe(join(baseDir, AGENTS_SKILLS_DIR), canonicalPath)) {\n throw new Error('Invalid skill name: potential path traversal detected')\n }\n\n return canonicalPath\n}\n\nexport async function removeSkill(\n skillName: string,\n agents: AgentType[],\n options: { global?: boolean } = {},\n): Promise<{ agent: string; success: boolean; error?: string }[]> {\n const results: { agent: string; success: boolean; error?: string }[] = []\n const safeSkillName = sanitizeName(skillName)\n const projectRoot = findProjectRoot()\n\n const canonicalPath = getCanonicalPath(skillName, options)\n try {\n await rm(canonicalPath, { recursive: true, force: true })\n } catch {\n // Ignore\n }\n\n for (const agent of agents) {\n const config = getAgentConfig(agent)\n const targetDir = options.global ? config.globalSkillsDir : join(projectRoot, config.skillsDir)\n const skillPath = join(targetDir, safeSkillName)\n\n try {\n await rm(skillPath, { recursive: true, force: true })\n results.push({ agent: config.displayName, success: true })\n } catch (error) {\n results.push({\n agent: config.displayName,\n success: false,\n error: error instanceof Error ? error.message : String(error),\n })\n }\n }\n\n await removeSkillFromLock(skillName)\n return results\n}\n\nexport { isGloballyInstalled }\n", "import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\n\nimport { findProjectRoot } from './project-root'\nimport type { AgentConfig, AgentType } from './types'\n\nconst home = homedir()\nconst projectRoot = findProjectRoot()\n\nexport const agents: Record<AgentType, AgentConfig> = {\n // Tier 1: Most popular AI coding agents\n cursor: {\n name: 'cursor',\n displayName: 'Cursor',\n description: 'AI-first code editor built on VS Code',\n skillsDir: '.cursor/skills',\n globalSkillsDir: join(home, '.cursor/skills'),\n detectInstalled: () => existsSync(join(home, '.cursor')) || existsSync(join(projectRoot, '.cursor')),\n },\n 'claude-code': {\n name: 'claude-code',\n displayName: 'Claude Code',\n description: \"Anthropic's agentic coding tool\",\n skillsDir: '.claude/skills',\n globalSkillsDir: join(home, '.claude/skills'),\n detectInstalled: () => existsSync(join(home, '.claude')) || existsSync(join(projectRoot, '.claude')),\n },\n 'github-copilot': {\n name: 'github-copilot',\n displayName: 'GitHub Copilot',\n description: 'AI pair programmer by GitHub/Microsoft',\n skillsDir: '.github/skills',\n globalSkillsDir: join(home, '.copilot/skills'),\n detectInstalled: () => existsSync(join(home, '.copilot')) || existsSync(join(projectRoot, '.github')),\n },\n windsurf: {\n name: 'windsurf',\n displayName: 'Windsurf',\n description: 'AI IDE with Cascade flow (Codeium)',\n skillsDir: '.windsurf/skills',\n globalSkillsDir: join(home, '.codeium/windsurf/skills'),\n detectInstalled: () => existsSync(join(home, '.codeium/windsurf')) || existsSync(join(projectRoot, '.windsurf')),\n },\n cline: {\n name: 'cline',\n displayName: 'Cline',\n description: 'Autonomous AI coding agent for VS Code',\n skillsDir: '.cline/skills',\n globalSkillsDir: join(home, '.cline/skills'),\n detectInstalled: () => existsSync(join(home, '.cline')) || existsSync(join(projectRoot, '.cline')),\n },\n\n // Tier 2: Rising stars\n aider: {\n name: 'aider',\n displayName: 'Aider',\n description: 'AI pair programming in terminal',\n skillsDir: '.aider/skills',\n globalSkillsDir: join(home, '.aider/skills'),\n detectInstalled: () => existsSync(join(home, '.aider')) || existsSync(join(projectRoot, '.aider')),\n },\n codex: {\n name: 'codex',\n displayName: 'OpenAI Codex',\n description: \"OpenAI's coding agent\",\n skillsDir: '.codex/skills',\n globalSkillsDir: join(home, '.codex/skills'),\n detectInstalled: () => existsSync(join(home, '.codex')) || existsSync(join(projectRoot, '.codex')),\n },\n gemini: {\n name: 'gemini',\n displayName: 'Gemini CLI',\n description: \"Google's AI coding assistant\",\n skillsDir: '.gemini/skills',\n globalSkillsDir: join(home, '.gemini/skills'),\n detectInstalled: () => existsSync(join(home, '.gemini')) || existsSync(join(projectRoot, '.gemini')),\n },\n antigravity: {\n name: 'antigravity',\n displayName: 'Antigravity',\n description: \"Google's agentic coding (VS Code)\",\n skillsDir: '.agent/skills',\n globalSkillsDir: join(home, '.agent/skills'),\n detectInstalled: () => existsSync(join(home, '.gemini/antigravity')) || existsSync(join(projectRoot, '.agent')),\n },\n roo: {\n name: 'roo',\n displayName: 'Roo Code',\n description: 'AI coding assistant for VS Code',\n skillsDir: '.roo/skills',\n globalSkillsDir: join(home, '.roo/skills'),\n detectInstalled: () => existsSync(join(home, '.roo')) || existsSync(join(projectRoot, '.roo')),\n },\n kilocode: {\n name: 'kilocode',\n displayName: 'Kilo Code',\n description: 'AI coding agent with auto-launch',\n skillsDir: '.kilocode/skills',\n globalSkillsDir: join(home, '.kilocode/skills'),\n detectInstalled: () => existsSync(join(home, '.kilocode')) || existsSync(join(projectRoot, '.kilocode')),\n },\n\n // Tier 3: Enterprise & specialized\n 'amazon-q': {\n name: 'amazon-q',\n displayName: 'Amazon Q',\n description: 'AWS AI coding assistant',\n skillsDir: '.amazonq/skills',\n globalSkillsDir: join(home, '.amazonq/skills'),\n detectInstalled: () => existsSync(join(home, '.amazonq')) || existsSync(join(projectRoot, '.amazonq')),\n },\n augment: {\n name: 'augment',\n displayName: 'Augment',\n description: 'AI code assistant with context engine',\n skillsDir: '.augment/skills',\n globalSkillsDir: join(home, '.augment/skills'),\n detectInstalled: () => existsSync(join(home, '.augment')) || existsSync(join(projectRoot, '.augment')),\n },\n tabnine: {\n name: 'tabnine',\n displayName: 'Tabnine',\n description: 'AI code completions with privacy focus',\n skillsDir: '.tabnine/skills',\n globalSkillsDir: join(home, '.tabnine/skills'),\n detectInstalled: () => existsSync(join(home, '.tabnine')) || existsSync(join(projectRoot, '.tabnine')),\n },\n opencode: {\n name: 'opencode',\n displayName: 'OpenCode',\n description: 'Open-source AI coding terminal',\n skillsDir: '.opencode/skills',\n globalSkillsDir: join(home, '.config/opencode/skills'),\n detectInstalled: () =>\n existsSync(join(home, '.config/opencode')) ||\n existsSync(join(projectRoot, '.opencode')) ||\n existsSync(join(projectRoot, '.config/opencode')),\n },\n sourcegraph: {\n name: 'sourcegraph',\n displayName: 'Sourcegraph Cody',\n description: 'AI assistant with codebase context',\n skillsDir: '.sourcegraph/skills',\n globalSkillsDir: join(home, '.sourcegraph/skills'),\n detectInstalled: () => existsSync(join(home, '.sourcegraph')) || existsSync(join(projectRoot, '.sourcegraph')),\n },\n}\n\nexport function detectInstalledAgents(): AgentType[] {\n return (Object.entries(agents) as [AgentType, AgentConfig][])\n .filter(([, config]) => config.detectInstalled())\n .map(([type]) => type)\n}\n\nexport function getAgentConfig(type: AgentType): AgentConfig {\n return agents[type]\n}\n\nexport function getAllAgentTypes(): AgentType[] {\n return (Object.keys(agents) as AgentType[]).sort((a, b) => agents[a].displayName.localeCompare(agents[b].displayName))\n}\n", "import { existsSync } from 'node:fs'\nimport { dirname, join, parse, resolve } from 'node:path'\n\nexport function findProjectRoot(startDir: string = process.cwd()): string {\n let currentDir = resolve(startDir)\n const root = parse(currentDir).root\n\n while (currentDir !== root) {\n if (existsSync(join(currentDir, 'package.json')) || existsSync(join(currentDir, '.git'))) {\n // Special check: ignore packages/cli/package.json if we are developing\n // This is a heuristic for the dev environment of this repo specifically\n const isCliPackage = currentDir.endsWith('packages/cli')\n if (!isCliPackage) return currentDir\n }\n currentDir = dirname(currentDir)\n }\n\n return startDir\n}\n", "import { execSync } from 'node:child_process'\nimport { existsSync } from 'node:fs'\nimport { join } from 'node:path'\n\nconst PACKAGE_NAME = '@tech-leads-club/agent-skills'\n\nexport function getNpmGlobalRoot(): string | null {\n try {\n return execSync('npm root -g', { encoding: 'utf-8' }).trim()\n } catch {\n return null\n }\n}\n\nexport function getGlobalSkillsPath(): string | null {\n const npmGlobalRoot = getNpmGlobalRoot()\n if (!npmGlobalRoot) return null\n const skillsPath = join(npmGlobalRoot, PACKAGE_NAME, 'skills')\n return existsSync(skillsPath) ? skillsPath : null\n}\n\nexport function isGloballyInstalled(): boolean {\n return getGlobalSkillsPath() !== null\n}\n\nexport function getGlobalSkillPath(skillName: string): string | null {\n const skillsPath = getGlobalSkillsPath()\n if (!skillsPath) return null\n const skillPath = join(skillsPath, skillName)\n return existsSync(skillPath) ? skillPath : null\n}\n", "import { mkdir, readFile, writeFile } from 'node:fs/promises'\nimport { homedir } from 'node:os'\nimport { dirname, join } from 'node:path'\n\nconst AGENTS_DIR = '.agents'\nconst LOCK_FILE = '.skill-lock.json'\nconst CURRENT_VERSION = 1\n\nexport interface SkillLockEntry {\n name: string\n source: string\n installedAt: string\n updatedAt: string\n}\n\nexport interface SkillLockFile {\n version: number\n skills: Record<string, SkillLockEntry>\n}\n\nfunction getSkillLockPath(): string {\n return join(homedir(), AGENTS_DIR, LOCK_FILE)\n}\n\nfunction createEmptyLockFile(): SkillLockFile {\n return { version: CURRENT_VERSION, skills: {} }\n}\n\nexport async function readSkillLock(): Promise<SkillLockFile> {\n const lockPath = getSkillLockPath()\n\n try {\n const content = await readFile(lockPath, 'utf-8')\n const parsed = JSON.parse(content) as SkillLockFile\n if (typeof parsed.version !== 'number' || !parsed.skills) return createEmptyLockFile()\n return parsed\n } catch {\n return createEmptyLockFile()\n }\n}\n\nexport async function writeSkillLock(lock: SkillLockFile): Promise<void> {\n const lockPath = getSkillLockPath()\n await mkdir(dirname(lockPath), { recursive: true })\n await writeFile(lockPath, JSON.stringify(lock, null, 2), 'utf-8')\n}\n\nexport async function addSkillToLock(skillName: string, source: string = 'local'): Promise<void> {\n const lock = await readSkillLock()\n const now = new Date().toISOString()\n const existingEntry = lock.skills[skillName]\n\n lock.skills[skillName] = {\n name: skillName,\n source,\n installedAt: existingEntry?.installedAt ?? now,\n updatedAt: now,\n }\n\n await writeSkillLock(lock)\n}\n\nexport async function removeSkillFromLock(skillName: string): Promise<boolean> {\n const lock = await readSkillLock()\n if (!(skillName in lock.skills)) return false\n delete lock.skills[skillName]\n await writeSkillLock(lock)\n return true\n}\n\nexport async function getSkillFromLock(skillName: string): Promise<SkillLockEntry | null> {\n const lock = await readSkillLock()\n return lock.skills[skillName] ?? null\n}\n\nexport async function getAllLockedSkills(): Promise<Record<string, SkillLockEntry>> {\n const lock = await readSkillLock()\n return lock.skills\n}\n", "import pc from 'picocolors'\n\nimport { detectInstalledAgents, getAllAgentTypes } from '../agents'\nimport { groupSkillsByCategory } from '../categories'\nimport { isGloballyInstalled } from '../installer'\nimport { discoverSkills } from '../skills'\nimport type { AgentType, InstallOptions } from '../types'\nimport { truncate } from '../ui/formatting'\nimport { blueConfirm, blueMultiSelectWithBack, blueSelectWithBack, isCancelled } from '../ui/input'\nimport { initScreen } from '../ui/screen'\nimport { logBar, logBarEnd, logCancelled } from '../ui/styles'\nimport { checkForUpdates, getCurrentVersion } from '../update-check'\nimport { showInstallationSummary } from './results'\nimport { buildAgentOptions, getAllInstalledSkillNames } from './utils'\n\ntype WizardState = {\n category: string\n skills: string[]\n agents: AgentType[]\n method: 'symlink' | 'copy'\n global: boolean\n}\n\nconst ALL_SKILLS_VALUE = '__all_skills__'\nconst ALL_CATEGORIES_VALUE = '__all__'\n\nexport async function runInteractiveInstall(): Promise<InstallOptions | null> {\n initScreen()\n await checkEnvironment()\n\n const allSkills = discoverSkills()\n if (allSkills.length === 0) {\n logBarEnd(pc.red('No skills available'))\n return null\n }\n\n const installedAgents = detectInstalledAgents()\n const allAgents = getAllAgentTypes()\n const targetAgents = installedAgents.length > 0 ? installedAgents : allAgents\n const installedSkills = await getAllInstalledSkillNames(targetAgents)\n\n const state: WizardState = {\n category: ALL_CATEGORIES_VALUE,\n skills: [],\n agents: installedAgents.length > 0 ? installedAgents : (['cursor', 'claude-code'] as AgentType[]),\n method: 'symlink',\n global: false,\n }\n\n let currentStep = 1\n const totalSteps = 4\n\n while (currentStep <= totalSteps) {\n const stepIndicator = pc.gray(`[${currentStep}/${totalSteps}]`)\n const allowBack = currentStep > 1\n\n switch (currentStep) {\n case 1: {\n const result = await selectCategoryStep({ allSkills, stepIndicator, currentCategory: state.category })\n if (result === null) return null\n state.category = result\n currentStep++\n break\n }\n\n case 2: {\n const result = await selectSkillsStep({\n state,\n allSkills,\n installedSkills,\n stepIndicator,\n allowBack,\n })\n\n if (result === Symbol.for('back')) {\n currentStep--\n break\n }\n\n if (result === null) return null\n\n state.skills = result as string[]\n currentStep++\n break\n }\n\n case 3: {\n const result = await selectAgentsStep({\n allAgents,\n installedAgents,\n currentAgents: state.agents,\n stepIndicator,\n allowBack,\n })\n\n if (result === Symbol.for('back')) {\n currentStep--\n break\n }\n\n if (result === null) return null\n\n state.agents = result as AgentType[]\n currentStep++\n break\n }\n\n case 4: {\n const result = await configureInstallationStep({\n state,\n stepIndicator,\n allowBack,\n })\n\n if (result === Symbol.for('back')) {\n state.method = 'symlink'\n currentStep--\n break\n }\n\n if (result === null) return null\n if (result === false) {\n currentStep = 1\n break\n }\n\n return result as InstallOptions\n }\n }\n }\n\n return null\n}\n\nasync function checkEnvironment() {\n const currentVersion = getCurrentVersion()\n const latestVersion = await checkForUpdates(currentVersion)\n\n if (latestVersion) {\n logBar(\n `${pc.yellow('\u26A0')} ${pc.yellow('Update available:')} ${pc.gray(currentVersion)} \u2192 ${pc.green(latestVersion)}`,\n )\n logBar(` ${pc.gray('Run: npm update -g @tech-leads-club/agent-skills')}`)\n logBar()\n } else if (!isGloballyInstalled()) {\n logBar(`${pc.yellow('\u26A0')} ${pc.yellow('Not installed globally')}`)\n logBar(` ${pc.yellow(\"Skills won't auto-update. Install globally:\")}`)\n logBar(` ${pc.yellow('npm i -g @tech-leads-club/agent-skills')}`)\n logBar()\n }\n}\n\ninterface SelectCategoryProps {\n allSkills: ReturnType<typeof discoverSkills>\n stepIndicator: string\n currentCategory: string\n}\n\nasync function selectCategoryStep({\n allSkills,\n stepIndicator,\n currentCategory,\n}: SelectCategoryProps): Promise<string | null> {\n const groupedSkills = groupSkillsByCategory(allSkills)\n const categoryList = Array.from(groupedSkills.keys())\n\n const categoryOptions = [\n { value: ALL_CATEGORIES_VALUE, label: `${pc.cyan('\u25C9')} All skills`, hint: `${allSkills.length} available` },\n ...categoryList.map((cat) => {\n const skillCount = groupedSkills.get(cat)?.length ?? 0\n return { value: cat.id, label: `${pc.cyan('\u25B8')} ${cat.name}`, hint: `${skillCount} skill(s)` }\n }),\n ]\n\n const selectedCategory = await blueSelectWithBack(\n `${stepIndicator} Browse by category`,\n categoryOptions,\n currentCategory,\n false,\n )\n\n if (isCancelled(selectedCategory)) {\n logCancelled()\n return null\n }\n\n return selectedCategory as string\n}\n\ninterface SelectSkillsProps {\n state: WizardState\n allSkills: ReturnType<typeof discoverSkills>\n installedSkills: Set<string>\n stepIndicator: string\n allowBack: boolean\n}\n\nasync function selectSkillsStep({\n state,\n allSkills,\n installedSkills,\n stepIndicator,\n allowBack,\n}: SelectSkillsProps): Promise<string[] | symbol | null> {\n const showAllCategories = state.category === ALL_CATEGORIES_VALUE\n const filteredSkills = showAllCategories ? allSkills : allSkills.filter((skill) => skill.category === state.category)\n\n const skillOptions = [\n {\n value: ALL_SKILLS_VALUE,\n label: `${pc.cyan('\u25C9')} ${pc.bold('All Skills')}`,\n hint: `select all ${filteredSkills.length} skills`,\n },\n ...filteredSkills.map((skill) => {\n const isInstalled = installedSkills.has(skill.name)\n return {\n value: skill.name,\n label: isInstalled ? `${skill.name} ${pc.green('\u25CF installed')}` : skill.name,\n hint: truncate(skill.description, 150),\n }\n }),\n ]\n\n const initialSkills = state.skills.length > 0 ? state.skills : []\n\n const selectedSkills = await blueMultiSelectWithBack(\n `${stepIndicator} Select skills to install`,\n skillOptions,\n initialSkills,\n allowBack,\n )\n\n if (selectedSkills === Symbol.for('back')) return Symbol.for('back')\n\n if (isCancelled(selectedSkills)) {\n logCancelled()\n return null\n }\n\n const skillsArray = selectedSkills as string[]\n\n const validSkills = skillsArray.includes(ALL_SKILLS_VALUE)\n ? filteredSkills.map((s) => s.name)\n : skillsArray.filter((s) => s !== ALL_SKILLS_VALUE)\n\n if (validSkills.length === 0) logBar(pc.yellow('\u26A0 Please select at least one skill'))\n if (validSkills.length === 0) return selectSkillsStep({ state, allSkills, installedSkills, stepIndicator, allowBack })\n return validSkills\n}\n\ninterface SelectAgentsProps {\n allAgents: AgentType[]\n installedAgents: AgentType[]\n currentAgents: AgentType[]\n stepIndicator: string\n allowBack: boolean\n}\n\nasync function selectAgentsStep({\n allAgents,\n installedAgents,\n currentAgents,\n stepIndicator,\n allowBack,\n}: SelectAgentsProps): Promise<AgentType[] | symbol | null> {\n const agentOptions = buildAgentOptions(allAgents, installedAgents)\n\n const selectedAgents = await blueMultiSelectWithBack(\n `${stepIndicator} Where to install?`,\n agentOptions,\n currentAgents,\n allowBack,\n )\n\n if (selectedAgents === Symbol.for('back')) return Symbol.for('back')\n\n if (isCancelled(selectedAgents)) {\n logCancelled()\n return null\n }\n\n const validAgents = selectedAgents as AgentType[]\n\n if (validAgents.length === 0) {\n logBar(pc.yellow('\u26A0 Please select at least one agent'))\n return selectAgentsStep({ allAgents, installedAgents, currentAgents, stepIndicator, allowBack })\n }\n\n return validAgents\n}\n\ninterface ConfigureProps {\n state: WizardState\n stepIndicator: string\n allowBack: boolean\n}\n\nasync function configureInstallationStep({\n state,\n stepIndicator,\n allowBack,\n}: ConfigureProps): Promise<InstallOptions | symbol | null | false> {\n const methodOptions = [\n { value: 'symlink', label: 'Symlink', hint: 'shared source (recommended)' },\n { value: 'copy', label: 'Copy', hint: 'independent copies' },\n ]\n\n const method = await blueSelectWithBack(\n `${stepIndicator} Installation method`,\n methodOptions,\n state.method,\n allowBack,\n )\n\n if (method === Symbol.for('back')) return Symbol.for('back')\n\n if (isCancelled(method)) {\n logCancelled()\n return null\n }\n\n state.method = method as 'symlink' | 'copy'\n showInstallationSummary(state)\n const scopeResult = await selectScope(state)\n if (scopeResult === Symbol.for('back')) return configureInstallationStep({ state, stepIndicator, allowBack })\n if (scopeResult === null) return null\n state.global = scopeResult === 'global'\n const confirm = await blueConfirm(pc.white('Proceed with installation?'), true)\n\n if (isCancelled(confirm)) {\n logCancelled()\n return null\n }\n\n if (!confirm) return false\n logBar()\n\n return { agents: state.agents, skills: state.skills, method: state.method, global: state.global }\n}\n\nasync function selectScope(state: WizardState): Promise<'local' | 'global' | symbol | null> {\n const scopeOptions = [\n { value: 'local', label: 'Local', hint: 'this project only' },\n { value: 'global', label: 'Global', hint: 'user home directory' },\n ]\n\n const scope = await blueSelectWithBack('Installation scope', scopeOptions, state.global ? 'global' : 'local', true)\n if (scope === Symbol.for('back')) return Symbol.for('back')\n if (isCancelled(scope)) return null\n return scope as 'local' | 'global'\n}\n", "import { existsSync, readFileSync, writeFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nimport {\n DEFAULT_CATEGORY,\n DEFAULT_CATEGORY_ID,\n SKILLS_CATEGORIES_FILE,\n formatCategoryName,\n} from '@tech-leads-club/core'\n\nimport type { CategoriesConfig, CategoryInfo } from './types'\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = dirname(__filename)\n\nexport function getCategoriesFilePath(): string {\n const devPath = join(__dirname, '..', '..', '..', SKILLS_CATEGORIES_FILE)\n if (existsSync(devPath)) return devPath\n const pkgPath = join(__dirname, '..', SKILLS_CATEGORIES_FILE)\n if (existsSync(pkgPath)) return pkgPath\n return devPath\n}\n\nexport function loadCategoriesConfig(): CategoriesConfig {\n const filePath = getCategoriesFilePath()\n if (!existsSync(filePath)) return { categories: [], skills: {} }\n\n try {\n const content = readFileSync(filePath, 'utf-8')\n return JSON.parse(content) as CategoriesConfig\n } catch {\n return { categories: [], skills: {} }\n }\n}\n\nexport function saveCategoriesConfig(config: CategoriesConfig): void {\n const filePath = getCategoriesFilePath()\n const content = JSON.stringify({ $schema: './categories.schema.json', ...config }, null, 2)\n writeFileSync(filePath, content + '\\n', 'utf-8')\n}\n\nexport function getCategories(): CategoryInfo[] {\n const config = loadCategoriesConfig()\n const categories = [...config.categories]\n categories.sort((a, b) => (a.priority ?? 100) - (b.priority ?? 100))\n return categories\n}\n\nexport function getCategoryById(id: string): CategoryInfo | undefined {\n const config = loadCategoriesConfig()\n return config.categories.find((cat) => cat.id === id)\n}\n\nexport function getSkillCategoryId(skillName: string): string {\n const config = loadCategoriesConfig()\n return config.skills[skillName] ?? DEFAULT_CATEGORY_ID\n}\n\nexport function getSkillCategory(skillName: string): CategoryInfo {\n const categoryId = getSkillCategoryId(skillName)\n const category = getCategoryById(categoryId)\n return category ?? DEFAULT_CATEGORY\n}\n\nexport function categoryExists(categoryId: string): boolean {\n const config = loadCategoriesConfig()\n return config.categories.some((cat) => cat.id === categoryId)\n}\n\nexport function addCategory(category: CategoryInfo): boolean {\n const config = loadCategoriesConfig()\n if (config.categories.some((cat) => cat.id === category.id)) return false\n config.categories.push(category)\n saveCategoriesConfig(config)\n return true\n}\n\nexport function assignSkillToCategory(skillName: string, categoryId: string, categoryName?: string): void {\n const config = loadCategoriesConfig()\n\n if (!config.categories.some((cat) => cat.id === categoryId)) {\n const newCategory: CategoryInfo = {\n id: categoryId,\n name: categoryName ?? formatCategoryName(categoryId),\n priority: Math.max(0, ...config.categories.map((c) => c.priority ?? 0)) + 1,\n }\n config.categories.push(newCategory)\n }\n\n config.skills[skillName] = categoryId\n saveCategoriesConfig(config)\n}\n\nexport function groupSkillsByCategory<T extends { name: string; category?: string }>(\n skills: T[],\n): Map<CategoryInfo, T[]> {\n const config = loadCategoriesConfig()\n const grouped = new Map<CategoryInfo, T[]>()\n const sortedCategories = [...config.categories].sort((a, b) => (a.priority ?? 100) - (b.priority ?? 100))\n\n for (const category of sortedCategories) {\n grouped.set(category, [])\n }\n\n grouped.set(DEFAULT_CATEGORY, [])\n\n for (const skill of skills) {\n const categoryId = skill.category ?? config.skills[skill.name] ?? DEFAULT_CATEGORY_ID\n const category = sortedCategories.find((c) => c.id === categoryId) ?? DEFAULT_CATEGORY\n const group = grouped.get(category) ?? []\n group.push(skill)\n grouped.set(category, group)\n }\n\n for (const [category, skillList] of grouped) {\n if (skillList.length === 0) grouped.delete(category)\n }\n\n return grouped\n}\n", "import type { CategoryInfo } from './types'\n\nexport const SKILLS_CATEGORIES_FILE = 'skills/categories.json'\nexport const SKILLS_ROOT_DIR = 'skills'\nexport const DEFAULT_CATEGORY_ID = 'uncategorized'\n\nexport const DEFAULT_CATEGORY: CategoryInfo = {\n id: DEFAULT_CATEGORY_ID,\n name: 'Uncategorized',\n description: 'Skills without a specific category',\n priority: 999,\n}\n", "import { existsSync, readdirSync, readFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nimport { SKILLS_ROOT_DIR } from '@tech-leads-club/core'\n\nimport { getSkillCategoryId } from './categories'\nimport type { SkillInfo } from './types'\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = dirname(__filename)\n\nexport function getSkillsDirectory(): string {\n const devSkillsDir = join(__dirname, '..', '..', '..', SKILLS_ROOT_DIR)\n if (existsSync(devSkillsDir)) return devSkillsDir\n const pkgSkillsDir = join(__dirname, '..', SKILLS_ROOT_DIR)\n if (existsSync(pkgSkillsDir)) return pkgSkillsDir\n throw new Error(`Skills directory not found. Checked: ${devSkillsDir}, ${pkgSkillsDir}`)\n}\n\nexport function discoverSkills(): SkillInfo[] {\n const skillsDir = getSkillsDirectory()\n const skills: SkillInfo[] = []\n if (!existsSync(skillsDir)) return skills\n const entries = readdirSync(skillsDir, { withFileTypes: true })\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n const skillMdPath = join(skillsDir, entry.name, 'SKILL.md')\n if (!existsSync(skillMdPath)) continue\n const content = readFileSync(skillMdPath, 'utf-8')\n const { name, description } = parseSkillFrontmatter(content)\n\n const skillName = name || entry.name\n skills.push({\n name: skillName,\n description: description || 'No description',\n path: join(skillsDir, entry.name),\n category: getSkillCategoryId(skillName),\n })\n }\n\n return skills\n}\n\nfunction parseSkillFrontmatter(content: string): { name?: string; description?: string } {\n const frontmatterMatch = content.match(/^---\\n([\\s\\S]*?)\\n---/)\n if (!frontmatterMatch) return {}\n const frontmatter = frontmatterMatch[1]\n const nameMatch = frontmatter.match(/^name:\\s*(.+)$/m)\n const descMatch = frontmatter.match(/^description:\\s*(.+)$/m)\n return { name: nameMatch?.[1]?.trim(), description: descMatch?.[1]?.trim() }\n}\n\nexport function getSkillByName(name: string): SkillInfo | undefined {\n const skills = discoverSkills()\n return skills.find((s) => s.name === name)\n}\n", "export function truncate(text: string, maxLength: number): string {\n return text.length <= maxLength ? text : text.slice(0, maxLength - 3) + '...'\n}\n", "import { ConfirmPrompt, MultiSelectPrompt, SelectPrompt } from '@clack/core'\nimport pc from 'picocolors'\n\nimport {\n S_BAR,\n S_BAR_END,\n S_CHECKBOX_ACTIVE,\n S_CHECKBOX_INACTIVE,\n S_RADIO_ACTIVE,\n S_RADIO_INACTIVE,\n SYMBOL,\n} from './styles'\n\nexport interface Option<T> {\n value: T\n label: string\n hint?: string\n}\n\nexport function isCancelled<T>(value: T | symbol): value is symbol {\n return typeof value === 'symbol'\n}\n\nexport async function blueSelectWithBack<T>(\n message: string,\n options: Option<T>[],\n initialValue?: T,\n allowBack = true,\n): Promise<T | symbol> {\n const opt = (option: Option<T>, isActive: boolean) => {\n const radio = isActive ? pc.blue(S_RADIO_ACTIVE) : pc.gray(S_RADIO_INACTIVE)\n const label = isActive ? pc.blue(option.label) : pc.white(option.label)\n const hint = isActive && option.hint ? pc.dim(pc.gray(` - ${option.hint}`)) : ''\n return `${radio} ${label}${hint}`\n }\n\n const prompt = new SelectPrompt({\n options,\n initialValue,\n render() {\n const title = `${pc.blue(S_BAR)}\\n${SYMBOL} ${pc.white(pc.bold(message))}\\n`\n const backHint = allowBack ? 'esc = back, ' : ''\n\n switch (this.state) {\n case 'submit':\n return `${title}${pc.blue(S_BAR)} ${pc.blue(this.options.find((o) => o.value === this.value)?.label)}\\n${pc.blue(S_BAR)}`\n case 'cancel':\n return `${title}${pc.blue(S_BAR)} ${pc.strikethrough(pc.gray('back'))}\\n${pc.blue(S_BAR)}`\n default:\n return `${title}${this.options\n .map((option, i) => `${pc.blue(S_BAR)} ${opt(option as Option<T>, i === this.cursor)}`)\n .join(\n '\\n',\n )}\\n${pc.blue(S_BAR)}\\n${pc.blue(S_BAR_END)} ${pc.dim(pc.gray(`(\u2191\u2193 navigate, ${backHint}enter confirm)`))}`\n }\n },\n })\n\n const result = await prompt.prompt()\n if (typeof result === 'symbol' && allowBack) return Symbol.for('back')\n return result as T | symbol\n}\n\nexport async function blueMultiSelectWithBack<T>(\n message: string,\n options: Option<T>[],\n initialValues: T[] = [],\n allowBack = true,\n): Promise<T[] | symbol> {\n const opt = (option: Option<T>, state: 'active' | 'selected' | 'cancelled' | 'inactive' | 'selected-active') => {\n const isSelected = state === 'selected' || state === 'selected-active'\n const isActive = state === 'active' || state === 'selected-active'\n const checkbox = isSelected ? pc.blue(S_CHECKBOX_ACTIVE) : pc.gray(S_CHECKBOX_INACTIVE)\n const label = isActive ? pc.blue(option.label) : pc.white(option.label)\n const hint = isActive && option.hint ? pc.dim(pc.gray(` (${option.hint})`)) : ''\n return `${checkbox} ${label}${hint}`\n }\n\n const prompt = new MultiSelectPrompt({\n options,\n initialValues,\n render() {\n const title = `${pc.blue(S_BAR)}\\n${SYMBOL} ${pc.white(pc.bold(message))}\\n`\n const backHint = allowBack ? 'esc = back, ' : ''\n\n switch (this.state) {\n case 'submit':\n return `${title}${pc.blue(S_BAR)} ${this.options\n .filter((o) => this.value.includes(o.value))\n .map((o) => pc.blue(String(o.value)))\n .join(pc.gray(', '))}\\n${pc.blue(S_BAR)}`\n case 'cancel':\n return `${title}${pc.blue(S_BAR)} ${pc.strikethrough(pc.gray('back'))}\\n${pc.blue(S_BAR)}`\n default:\n return `${title}${this.options\n .map((option, i) => {\n const isSelected = this.value.includes(option.value)\n const isActive = i === this.cursor\n const state =\n isSelected && isActive ? 'selected-active' : isSelected ? 'selected' : isActive ? 'active' : 'inactive'\n return `${pc.blue(S_BAR)} ${opt(option as Option<T>, state)}`\n })\n .join(\n '\\n',\n )}\\n${pc.blue(S_BAR)}\\n${pc.blue(S_BAR_END)} ${pc.dim(pc.gray(`(\u2191\u2193 navigate, space select, ${backHint}enter confirm)`))}`\n }\n },\n })\n\n const result = await prompt.prompt()\n if (typeof result === 'symbol' && allowBack) return Symbol.for('back')\n return result as T[] | symbol\n}\n\nexport async function blueConfirm(message: string, initialValue = false): Promise<boolean | symbol> {\n const prompt = new ConfirmPrompt({\n active: 'Yes',\n inactive: 'No',\n initialValue,\n render() {\n const title = `${pc.blue(S_BAR)}\\n${SYMBOL} ${pc.white(pc.bold(message))}\\n`\n\n switch (this.state) {\n case 'submit':\n return `${title}${pc.blue(S_BAR)} ${pc.blue(this.value ? 'Yes' : 'No')}\\n${pc.blue(S_BAR)}`\n case 'cancel':\n return `${title}${pc.blue(S_BAR)} ${pc.strikethrough(pc.gray('cancelled'))}\\n${pc.blue(S_BAR)}`\n default:\n return `${title}${pc.blue(S_BAR)} ${\n this.value\n ? `${pc.blue('\u25CF Yes')} ${pc.dim(pc.gray('/'))} ${pc.gray('\u25CB')} ${pc.white('No')}`\n : `${pc.gray('\u25CB')} ${pc.white('Yes')} ${pc.dim(pc.gray('/'))} ${pc.blue('\u25CF No')}`\n }\\n${pc.blue(S_BAR)}\\n${pc.blue(S_BAR_END)} ${pc.dim(pc.gray('(\u2190\u2192 to change, enter to confirm)'))}`\n }\n },\n })\n\n return prompt.prompt() as Promise<boolean | symbol>\n}\n", "import gradient from 'gradient-string'\nimport pc from 'picocolors'\n\ninterface Gradient {\n (text: string, options?: unknown): string\n multiline(text: string, options?: unknown): string\n}\n\nexport const crystalGradient: Gradient = gradient([\n { color: '#1e3a8a', pos: 0 },\n { color: '#3b82f6', pos: 0.3 },\n { color: '#0ea5e9', pos: 0.5 },\n { color: '#06b6d4', pos: 0.7 },\n { color: '#22d3ee', pos: 1 },\n]) as Gradient\n\nexport const S_BAR = '\u2502'\nexport const S_BAR_END = '\u2514'\nexport const S_RADIO_ACTIVE = '\u25CF'\nexport const S_RADIO_INACTIVE = '\u25CB'\nexport const S_CHECKBOX_ACTIVE = '\u25FC'\nexport const S_CHECKBOX_INACTIVE = '\u25FB'\nexport const SYMBOL = pc.blue('\u25C6')\n\nexport function logBar(message = ''): void {\n console.log(message ? `${pc.blue(S_BAR)} ${message}` : pc.blue(S_BAR))\n}\n\nexport function logBarEnd(message = ''): void {\n console.log(`${pc.blue(S_BAR_END)} ${message}`)\n}\n\nexport function logCancelled(): void {\n logBarEnd(pc.gray('Cancelled'))\n}\n", "import figlet from 'figlet'\nimport pc from 'picocolors'\n\nimport { crystalGradient, logBar } from './styles'\n\nexport function generateLogo(): string {\n const asciiArt = figlet.textSync('Tech Leads Club', { font: 'Larry 3D', horizontalLayout: 'default' })\n return `\n${crystalGradient.multiline(asciiArt)}\n ${pc.white(pc.bold('Tech Leads Club'))} ${pc.blue('\u203A')} ${pc.bold(pc.blue('Agent Skills'))}\n ${pc.white('Curated skills to power up your AI coding agents')}\n`\n}\n\nexport function initScreen(): void {\n console.clear()\n console.log(generateLogo())\n logBar()\n}\n", "import { createRequire } from 'node:module'\nimport packageJson from 'package-json'\n\nconst PACKAGE_NAME = '@tech-leads-club/agent-skills'\n\nexport async function checkForUpdates(currentVersion: string): Promise<string | null> {\n try {\n const result = await packageJson(PACKAGE_NAME)\n if (result.version !== currentVersion) return result.version\n return null\n } catch {\n // Silently fail if offline or registry unavailable\n return null\n }\n}\n\nexport function getCurrentVersion(): string {\n try {\n const require = createRequire(import.meta.url)\n const pkg = require('../package.json')\n return pkg.version || '0.0.0'\n } catch {\n return '0.0.0'\n }\n}\n", "import pc from 'picocolors'\n\nimport { logBar, logBarEnd, S_BAR, SYMBOL } from '../ui/styles'\n\ninterface InstallationSummaryOptions {\n skills: string[]\n agents: string[]\n method: string\n}\n\nexport function showInstallationSummary(options: InstallationSummaryOptions): void {\n logBar()\n logBar(pc.blue(pc.bold('\uD83D\uDCCB Installation Summary')))\n logBar()\n logBar(`${pc.blue(S_BAR)} ${pc.white(pc.bold('Skills:'))} ${pc.gray(options.skills.join(', '))}`)\n logBar(`${pc.blue(S_BAR)} ${pc.white(pc.bold('Agents:'))} ${pc.gray(options.agents.join(', '))}`)\n logBar(`${pc.blue(S_BAR)} ${pc.white(pc.bold('Method:'))} ${pc.cyan(options.method)}`)\n logBar()\n}\n\nexport function showInstallResults(\n results: Array<{\n agent: string\n skill: string\n path: string\n method: string\n success: boolean\n error?: string\n }>,\n): void {\n const successful = results.filter((r) => r.success && !r.error)\n const alreadyExists = results.filter((r) => r.success && r.error === 'Already exists')\n const failed = results.filter((r) => !r.success)\n\n console.log()\n\n for (const r of successful) {\n console.log(`${SYMBOL} ${pc.white(pc.bold(r.skill))} ${pc.gray('\u2192')} ${pc.white(r.agent)}`)\n }\n\n for (const r of alreadyExists) {\n console.log(`${pc.gray(SYMBOL)} ${r.skill} \u2192 ${r.agent} ${pc.gray('(exists)')}`)\n }\n\n for (const r of failed) {\n console.log(`${pc.red('\u2717')} ${r.skill} \u2192 ${r.agent}: ${r.error}`)\n }\n\n const totalAgents = new Set(results.map((r) => r.agent)).size\n\n console.log()\n logBarEnd(\n `${pc.blue('\u2713')} ${pc.white(pc.bold(`${successful.length} skill(s)`))} ${pc.white('installed to')} ${pc.white(pc.bold(`${totalAgents} agent(s)`))}`,\n )\n}\n\nexport function showRemoveResults(\n skillName: string,\n results: Array<{ agent: string; success: boolean; error?: string }>,\n): void {\n const successful = results.filter((r) => r.success)\n const failed = results.filter((r) => !r.success)\n\n if (successful.length > 0) {\n console.log(\n `${SYMBOL} ${pc.white(pc.bold(skillName))} ${pc.gray('removed from')} ${successful.map((r) => r.agent).join(', ')}`,\n )\n }\n\n for (const r of failed) {\n console.log(`${pc.red('\u2717')} ${skillName} \u2192 ${r.agent}: ${r.error}`)\n }\n\n if (successful.length > 0 && failed.length === 0) {\n logBarEnd(`${pc.blue('\u2713')} ${pc.white('Skill removed successfully')}`)\n }\n}\n", "import pc from 'picocolors'\n\nimport { getAgentConfig } from '../agents'\nimport { listInstalledSkills } from '../installer'\nimport type { AgentType } from '../types'\nimport { truncate } from '../ui/formatting'\nimport type { Option } from '../ui/input'\n\nexport function buildAgentOptions(agents: AgentType[], detectedAgents: AgentType[] = []): Option<AgentType>[] {\n return agents.map((type) => {\n const config = getAgentConfig(type)\n const isDetected = detectedAgents.includes(type)\n return {\n value: type,\n label: isDetected ? `${config.displayName} ${pc.green('\u25CF detected')}` : config.displayName,\n hint: truncate(config.description, 50),\n }\n })\n}\n\nexport async function getInstalledSkillNames(agents: AgentType[], global: boolean): Promise<Set<string>> {\n const installed = new Set<string>()\n for (const agent of agents) {\n const skills = await listInstalledSkills(agent, global)\n skills.forEach((skill) => installed.add(skill))\n }\n return installed\n}\n\nexport async function getAllInstalledSkillNames(agents: AgentType[]): Promise<Set<string>> {\n const [globalSkills, localSkills] = await Promise.all([\n getInstalledSkillNames(agents, true),\n getInstalledSkillNames(agents, false),\n ])\n return new Set([...globalSkills, ...localSkills])\n}\n", "import pc from 'picocolors'\n\nimport { getAllAgentTypes } from '../agents'\nimport { groupSkillsByCategory } from '../categories'\nimport { discoverSkills } from '../skills'\nimport { initScreen } from '../ui/screen'\nimport { logBar, logBarEnd, S_BAR } from '../ui/styles'\nimport { getAllInstalledSkillNames } from './utils'\n\nexport async function showAvailableSkills(): Promise<void> {\n initScreen()\n const skills = discoverSkills()\n\n if (skills.length === 0) {\n logBar(pc.yellow('No skills found'))\n return\n }\n\n logBar(pc.bold(`${skills.length} skills available:`))\n logBar()\n\n const allAgents = getAllAgentTypes()\n const installedSkills = await getAllInstalledSkillNames(allAgents)\n const groupedSkills = groupSkillsByCategory(skills)\n\n for (const [category, categorySkills] of groupedSkills) {\n logBar(`${pc.cyan('\u25B8')} ${pc.bold(pc.cyan(category.name))}`)\n\n for (const skill of categorySkills) {\n const installedBadge = installedSkills.has(skill.name) ? ` ${pc.green('\u25CF installed')}` : ''\n logBar(` ${pc.blue('\u25C6')} ${pc.bold(skill.name)}${installedBadge}`)\n console.log(`${pc.blue(S_BAR)} ${pc.dim(pc.gray(skill.description))}`)\n }\n\n logBar()\n }\n\n logBarEnd(pc.gray('Run \"npx @tech-leads-club/agent-skills\" to install'))\n}\n", "import pc from 'picocolors'\n\nimport { getAllAgentTypes } from '../agents'\nimport { removeSkill } from '../installer'\nimport type { AgentType } from '../types'\nimport { blueConfirm, blueMultiSelectWithBack, isCancelled } from '../ui/input'\nimport { initScreen } from '../ui/screen'\nimport { logBar, logBarEnd, logCancelled } from '../ui/styles'\nimport { showRemoveResults } from './results'\nimport { buildAgentOptions, getInstalledSkillNames } from './utils'\n\nexport async function runInteractiveRemove(global: boolean): Promise<void> {\n initScreen()\n const allAgents = getAllAgentTypes()\n const installedSkills = await getInstalledSkillNames(allAgents, global)\n\n if (installedSkills.size === 0) {\n logBar(pc.yellow('No skills installed'))\n logBarEnd()\n return\n }\n\n const skillsArray = Array.from(installedSkills)\n\n // Step 1\n const selectedSkills = await blueMultiSelectWithBack(\n `Which skills do you want to remove? ${pc.gray(`(${skillsArray.length} installed)`)}`,\n skillsArray.map((name) => ({ value: name, label: name })),\n [],\n false,\n )\n\n if (isCancelled(selectedSkills) || (selectedSkills as string[]).length === 0) {\n logCancelled()\n return\n }\n\n // Step 2\n const selectedAgents = await blueMultiSelectWithBack(\n 'Remove from which agents?',\n buildAgentOptions(allAgents).map((opt) => ({ ...opt, hint: undefined })),\n allAgents,\n true,\n )\n\n if (isCancelled(selectedAgents)) {\n logCancelled()\n return\n }\n\n // Step 3\n const confirm = await blueConfirm(\n `Remove ${selectedSkills.length} skill(s) from ${selectedAgents.length} agent(s)?`,\n false,\n )\n\n if (isCancelled(confirm) || !confirm) {\n logCancelled()\n return\n }\n\n logBar()\n\n for (const skillName of selectedSkills) {\n const results = await removeSkill(skillName, selectedAgents as AgentType[], { global })\n showRemoveResults(skillName, results)\n }\n}\n"],
5
+ "mappings": "AAAA,OAAS,WAAAA,OAAe,YCAxB,OAAS,MAAAC,GAAI,SAAAC,GAAO,SAAAC,GAAO,WAAAC,GAAS,YAAAC,GAAU,MAAAC,EAAI,WAAAC,OAAe,mBACjE,OAAS,WAAAC,GAAS,YAAAC,OAAgB,UAClC,OAAS,QAAAC,EAAM,aAAAC,GAAW,YAAAC,GAAU,WAAAC,EAAS,OAAAC,OAAW,YCFxD,OAAS,cAAAC,MAAkB,UAC3B,OAAS,WAAAC,OAAe,UACxB,OAAS,QAAAC,MAAY,YCFrB,OAAS,cAAAC,OAAkB,UAC3B,OAAS,WAAAC,GAAS,QAAAC,GAAM,SAAAC,GAAO,WAAAC,OAAe,YAEvC,SAASC,EAAgBC,EAAmB,QAAQ,IAAI,EAAW,CACxE,IAAIC,EAAaH,GAAQE,CAAQ,EAC3BE,EAAOL,GAAMI,CAAU,EAAE,KAE/B,KAAOA,IAAeC,GAAM,CAC1B,IAAIR,GAAWE,GAAKK,EAAY,cAAc,CAAC,GAAKP,GAAWE,GAAKK,EAAY,MAAM,CAAC,IAIjF,CADiBA,EAAW,SAAS,cAAc,EACpC,OAAOA,EAE5BA,EAAaN,GAAQM,CAAU,CACjC,CAEA,OAAOD,CACT,CDXA,IAAMG,EAAOC,GAAQ,EACfC,EAAcC,EAAgB,EAEvBC,EAAyC,CAEpD,OAAQ,CACN,KAAM,SACN,YAAa,SACb,YAAa,wCACb,UAAW,iBACX,gBAAiBC,EAAKL,EAAM,gBAAgB,EAC5C,gBAAiB,IAAMM,EAAWD,EAAKL,EAAM,SAAS,CAAC,GAAKM,EAAWD,EAAKH,EAAa,SAAS,CAAC,CACrG,EACA,cAAe,CACb,KAAM,cACN,YAAa,cACb,YAAa,kCACb,UAAW,iBACX,gBAAiBG,EAAKL,EAAM,gBAAgB,EAC5C,gBAAiB,IAAMM,EAAWD,EAAKL,EAAM,SAAS,CAAC,GAAKM,EAAWD,EAAKH,EAAa,SAAS,CAAC,CACrG,EACA,iBAAkB,CAChB,KAAM,iBACN,YAAa,iBACb,YAAa,yCACb,UAAW,iBACX,gBAAiBG,EAAKL,EAAM,iBAAiB,EAC7C,gBAAiB,IAAMM,EAAWD,EAAKL,EAAM,UAAU,CAAC,GAAKM,EAAWD,EAAKH,EAAa,SAAS,CAAC,CACtG,EACA,SAAU,CACR,KAAM,WACN,YAAa,WACb,YAAa,qCACb,UAAW,mBACX,gBAAiBG,EAAKL,EAAM,0BAA0B,EACtD,gBAAiB,IAAMM,EAAWD,EAAKL,EAAM,mBAAmB,CAAC,GAAKM,EAAWD,EAAKH,EAAa,WAAW,CAAC,CACjH,EACA,MAAO,CACL,KAAM,QACN,YAAa,QACb,YAAa,yCACb,UAAW,gBACX,gBAAiBG,EAAKL,EAAM,eAAe,EAC3C,gBAAiB,IAAMM,EAAWD,EAAKL,EAAM,QAAQ,CAAC,GAAKM,EAAWD,EAAKH,EAAa,QAAQ,CAAC,CACnG,EAGA,MAAO,CACL,KAAM,QACN,YAAa,QACb,YAAa,kCACb,UAAW,gBACX,gBAAiBG,EAAKL,EAAM,eAAe,EAC3C,gBAAiB,IAAMM,EAAWD,EAAKL,EAAM,QAAQ,CAAC,GAAKM,EAAWD,EAAKH,EAAa,QAAQ,CAAC,CACnG,EACA,MAAO,CACL,KAAM,QACN,YAAa,eACb,YAAa,wBACb,UAAW,gBACX,gBAAiBG,EAAKL,EAAM,eAAe,EAC3C,gBAAiB,IAAMM,EAAWD,EAAKL,EAAM,QAAQ,CAAC,GAAKM,EAAWD,EAAKH,EAAa,QAAQ,CAAC,CACnG,EACA,OAAQ,CACN,KAAM,SACN,YAAa,aACb,YAAa,+BACb,UAAW,iBACX,gBAAiBG,EAAKL,EAAM,gBAAgB,EAC5C,gBAAiB,IAAMM,EAAWD,EAAKL,EAAM,SAAS,CAAC,GAAKM,EAAWD,EAAKH,EAAa,SAAS,CAAC,CACrG,EACA,YAAa,CACX,KAAM,cACN,YAAa,cACb,YAAa,oCACb,UAAW,gBACX,gBAAiBG,EAAKL,EAAM,eAAe,EAC3C,gBAAiB,IAAMM,EAAWD,EAAKL,EAAM,qBAAqB,CAAC,GAAKM,EAAWD,EAAKH,EAAa,QAAQ,CAAC,CAChH,EACA,IAAK,CACH,KAAM,MACN,YAAa,WACb,YAAa,kCACb,UAAW,cACX,gBAAiBG,EAAKL,EAAM,aAAa,EACzC,gBAAiB,IAAMM,EAAWD,EAAKL,EAAM,MAAM,CAAC,GAAKM,EAAWD,EAAKH,EAAa,MAAM,CAAC,CAC/F,EACA,SAAU,CACR,KAAM,WACN,YAAa,YACb,YAAa,mCACb,UAAW,mBACX,gBAAiBG,EAAKL,EAAM,kBAAkB,EAC9C,gBAAiB,IAAMM,EAAWD,EAAKL,EAAM,WAAW,CAAC,GAAKM,EAAWD,EAAKH,EAAa,WAAW,CAAC,CACzG,EAGA,WAAY,CACV,KAAM,WACN,YAAa,WACb,YAAa,0BACb,UAAW,kBACX,gBAAiBG,EAAKL,EAAM,iBAAiB,EAC7C,gBAAiB,IAAMM,EAAWD,EAAKL,EAAM,UAAU,CAAC,GAAKM,EAAWD,EAAKH,EAAa,UAAU,CAAC,CACvG,EACA,QAAS,CACP,KAAM,UACN,YAAa,UACb,YAAa,wCACb,UAAW,kBACX,gBAAiBG,EAAKL,EAAM,iBAAiB,EAC7C,gBAAiB,IAAMM,EAAWD,EAAKL,EAAM,UAAU,CAAC,GAAKM,EAAWD,EAAKH,EAAa,UAAU,CAAC,CACvG,EACA,QAAS,CACP,KAAM,UACN,YAAa,UACb,YAAa,yCACb,UAAW,kBACX,gBAAiBG,EAAKL,EAAM,iBAAiB,EAC7C,gBAAiB,IAAMM,EAAWD,EAAKL,EAAM,UAAU,CAAC,GAAKM,EAAWD,EAAKH,EAAa,UAAU,CAAC,CACvG,EACA,SAAU,CACR,KAAM,WACN,YAAa,WACb,YAAa,iCACb,UAAW,mBACX,gBAAiBG,EAAKL,EAAM,yBAAyB,EACrD,gBAAiB,IACfM,EAAWD,EAAKL,EAAM,kBAAkB,CAAC,GACzCM,EAAWD,EAAKH,EAAa,WAAW,CAAC,GACzCI,EAAWD,EAAKH,EAAa,kBAAkB,CAAC,CACpD,EACA,YAAa,CACX,KAAM,cACN,YAAa,mBACb,YAAa,qCACb,UAAW,sBACX,gBAAiBG,EAAKL,EAAM,qBAAqB,EACjD,gBAAiB,IAAMM,EAAWD,EAAKL,EAAM,cAAc,CAAC,GAAKM,EAAWD,EAAKH,EAAa,cAAc,CAAC,CAC/G,CACF,EAEO,SAASK,IAAqC,CACnD,OAAQ,OAAO,QAAQH,CAAM,EAC1B,OAAO,CAAC,CAAC,CAAEI,CAAM,IAAMA,EAAO,gBAAgB,CAAC,EAC/C,IAAI,CAAC,CAACC,CAAI,IAAMA,CAAI,CACzB,CAEO,SAASC,EAAeD,EAA8B,CAC3D,OAAOL,EAAOK,CAAI,CACpB,CAEO,SAASE,GAAgC,CAC9C,OAAQ,OAAO,KAAKP,CAAM,EAAkB,KAAK,CAACQ,EAAGC,IAAMT,EAAOQ,CAAC,EAAE,YAAY,cAAcR,EAAOS,CAAC,EAAE,WAAW,CAAC,CACvH,CEjKA,OAAS,YAAAC,OAAgB,qBACzB,OAAS,cAAAC,OAAkB,UAC3B,OAAS,QAAAC,OAAY,YAErB,IAAMC,GAAe,gCAEd,SAASC,IAAkC,CAChD,GAAI,CACF,OAAOJ,GAAS,cAAe,CAAE,SAAU,OAAQ,CAAC,EAAE,KAAK,CAC7D,MAAQ,CACN,OAAO,IACT,CACF,CAEO,SAASK,IAAqC,CACnD,IAAMC,EAAgBF,GAAiB,EACvC,GAAI,CAACE,EAAe,OAAO,KAC3B,IAAMC,EAAaL,GAAKI,EAAeH,GAAc,QAAQ,EAC7D,OAAOF,GAAWM,CAAU,EAAIA,EAAa,IAC/C,CAEO,SAASC,IAA+B,CAC7C,OAAOH,GAAoB,IAAM,IACnC,CAEO,SAASI,GAAmBC,EAAkC,CACnE,IAAMH,EAAaF,GAAoB,EACvC,GAAI,CAACE,EAAY,OAAO,KACxB,IAAMI,EAAYT,GAAKK,EAAYG,CAAS,EAC5C,OAAOT,GAAWU,CAAS,EAAIA,EAAY,IAC7C,CC9BA,OAAS,SAAAC,GAAO,YAAAC,GAAU,aAAAC,OAAiB,mBAC3C,OAAS,WAAAC,OAAe,UACxB,OAAS,WAAAC,GAAS,QAAAC,OAAY,YAE9B,IAAMC,GAAa,UACbC,GAAY,mBACZC,GAAkB,EAcxB,SAASC,IAA2B,CAClC,OAAOJ,GAAKF,GAAQ,EAAGG,GAAYC,EAAS,CAC9C,CAEA,SAASG,IAAqC,CAC5C,MAAO,CAAE,QAASF,GAAiB,OAAQ,CAAC,CAAE,CAChD,CAEA,eAAsBG,IAAwC,CAC5D,IAAMC,EAAWH,GAAiB,EAElC,GAAI,CACF,IAAMI,EAAU,MAAMZ,GAASW,EAAU,OAAO,EAC1CE,EAAS,KAAK,MAAMD,CAAO,EACjC,OAAI,OAAOC,EAAO,SAAY,UAAY,CAACA,EAAO,OAAeJ,GAAoB,EAC9EI,CACT,MAAQ,CACN,OAAOJ,GAAoB,CAC7B,CACF,CAEA,eAAsBK,GAAeC,EAAoC,CACvE,IAAMJ,EAAWH,GAAiB,EAClC,MAAMT,GAAMI,GAAQQ,CAAQ,EAAG,CAAE,UAAW,EAAK,CAAC,EAClD,MAAMV,GAAUU,EAAU,KAAK,UAAUI,EAAM,KAAM,CAAC,EAAG,OAAO,CAClE,CAEA,eAAsBC,GAAeC,EAAmBC,EAAiB,QAAwB,CAC/F,IAAMH,EAAO,MAAML,GAAc,EAC3BS,EAAM,IAAI,KAAK,EAAE,YAAY,EAC7BC,EAAgBL,EAAK,OAAOE,CAAS,EAE3CF,EAAK,OAAOE,CAAS,EAAI,CACvB,KAAMA,EACN,OAAAC,EACA,YAAaE,GAAe,aAAeD,EAC3C,UAAWA,CACb,EAEA,MAAML,GAAeC,CAAI,CAC3B,CAEA,eAAsBM,GAAoBJ,EAAqC,CAC7E,IAAMF,EAAO,MAAML,GAAc,EACjC,OAAMO,KAAaF,EAAK,QACxB,OAAOA,EAAK,OAAOE,CAAS,EAC5B,MAAMH,GAAeC,CAAI,EAClB,IAHiC,EAI1C,CJ1DA,IAAMO,GAAoBC,EAAK,UAAW,QAAQ,EAC5CC,GAAgB,IAAI,IAAI,CAAC,YAAa,gBAAiB,UAAU,CAAC,EAExE,SAASC,GAAaC,EAAsB,CAC1C,IAAIC,EAAYD,EAAK,QAAQ,SAAU,EAAE,EACzC,OAAAC,EAAYA,EAAU,QAAQ,SAAU,EAAE,EAC1CA,EAAYA,EAAU,QAAQ,mBAAoB,EAAE,EACpDA,EAAYA,EAAU,QAAQ,OAAQ,EAAE,GACpC,CAACA,GAAaA,EAAU,SAAW,KAAGA,EAAY,iBAC/CA,EAAU,UAAU,EAAG,GAAG,CACnC,CAEA,SAASC,GAAWC,EAAkBC,EAA6B,CACjE,IAAMC,EAAiBC,GAAUC,EAAQJ,CAAQ,CAAC,EAC5CK,EAAmBF,GAAUC,EAAQH,CAAU,CAAC,EACtD,OAAOI,EAAiB,WAAWH,EAAiBI,EAAG,GAAKD,IAAqBH,CACnF,CAEA,eAAeK,GAAcC,EAAgBC,EAAoC,CAC/E,GAAI,CACF,GAAI,CAEF,IADc,MAAMC,GAAMD,CAAQ,GACxB,eAAe,EAAG,CAC1B,IAAME,EAAiB,MAAMC,GAASH,CAAQ,EAC9C,GAAIL,EAAQO,CAAc,IAAMP,EAAQI,CAAM,EAAG,MAAO,GACxD,MAAMK,EAAGJ,CAAQ,CACnB,MACE,MAAMI,EAAGJ,EAAU,CAAE,UAAW,EAAK,CAAC,CAE1C,OAASK,EAAc,CACrB,GAAKA,GAA2B,OAAS,QACvC,GAAI,CACF,MAAMD,EAAGJ,EAAU,CAAE,MAAO,EAAK,CAAC,CACpC,MAAQ,CAER,CAEJ,CAEA,IAAMM,EAAUrB,EAAKe,EAAU,IAAI,EACnC,MAAMO,GAAMD,EAAS,CAAE,UAAW,EAAK,CAAC,EACxC,IAAME,EAAeC,GAASH,EAASP,CAAM,EACvCW,EAAOC,GAAS,IAAM,QAAU,WAAa,OACnD,aAAMC,GAAQJ,EAAcR,EAAUU,CAAI,EACnC,EACT,MAAQ,CACN,MAAO,EACT,CACF,CAEA,eAAeG,GAAcC,EAAaC,EAA6B,CACrE,MAAMR,GAAMQ,EAAM,CAAE,UAAW,EAAK,CAAC,EACrC,IAAMC,EAAU,MAAMC,GAAQH,EAAK,CAAE,cAAe,EAAK,CAAC,EAE1D,QAAWI,KAASF,EAAS,CAC3B,GAAI9B,GAAc,IAAIgC,EAAM,IAAI,GAAKA,EAAM,KAAK,WAAW,GAAG,EAAG,SACjE,IAAMC,EAAUlC,EAAK6B,EAAKI,EAAM,IAAI,EAC9BE,EAAWnC,EAAK8B,EAAMG,EAAM,IAAI,EAElCA,EAAM,YAAY,EACpB,MAAML,GAAcM,EAASC,CAAQ,EAErC,MAAMC,GAAGF,EAASC,CAAQ,CAE9B,CACF,CAEA,eAAsBE,GAAcC,EAAqBC,EAAmD,CAC1G,IAAMC,EAA2B,CAAC,EAC5BC,EAAcC,EAAgB,EAEpC,QAAWC,KAASJ,EAAQ,OAAQ,CAClC,IAAMK,EAASC,EAAeF,CAAK,EAC7BG,EAAYP,EAAQ,OAASK,EAAO,gBAAkB5C,EAAKyC,EAAaG,EAAO,SAAS,EAE9F,QAAWG,KAAST,EAAQ,CAC1B,IAAMU,EAAS,MAAMC,GAAqBF,EAAOJ,EAAOG,EAAWP,EAAQ,OAAQE,EAAaF,EAAQ,MAAM,EAC9GC,EAAQ,KAAKQ,CAAM,EACfA,EAAO,SAAS,MAAME,GAAeH,EAAM,KAAM,OAAO,CAC9D,CACF,CAEA,OAAOP,CACT,CAEA,eAAeS,GACbF,EACAJ,EACAG,EACAK,EACAV,EACAW,EACwB,CACxB,IAAMR,EAASC,EAAeF,CAAK,EAC7BU,EAAgBnD,GAAa6C,EAAM,IAAI,EACvCO,EAAkBtD,EAAK8C,EAAWO,CAAa,EAErD,GAAI,CAAChD,GAAWyC,EAAWQ,CAAe,GAAK,CAACF,GAC1C,CAAC/C,GAAWoC,EAAaa,CAAe,GAAK,CAACF,EAChD,MAAO,CACL,MAAOR,EAAO,YACd,MAAOG,EAAM,KACb,KAAMO,EACN,OAAAH,EACA,QAAS,GACT,MAAO,0CACT,EAIJ,GAAI,CACF,GAAIA,IAAW,UAAW,CACxB,IAAMI,EAAkBC,GAAmBT,EAAM,IAAI,EAErD,GAAIQ,GACc,MAAM1C,GAAc0C,EAAiBD,CAAe,EAElE,MAAO,CACL,MAAOV,EAAO,YACd,MAAOG,EAAM,KACb,KAAMO,EACN,OAAAH,EACA,QAAS,GACT,kBAAmB,EACrB,EAIJ,IAAMM,EAAezD,EAAKyC,EAAa1C,GAAmBsD,CAAa,EAKvE,GAJA,MAAM/B,GAAMmC,EAAc,CAAE,UAAW,EAAK,CAAC,EAC7C,MAAMrB,GAAGW,EAAM,KAAMU,EAAc,CAAE,UAAW,EAAK,CAAC,EAGlD,CAFmB,MAAM5C,GAAc4C,EAAcH,CAAe,EAEnD,CACnB,GAAI,CACF,MAAMnC,EAAGmC,EAAiB,CAAE,UAAW,GAAM,MAAO,EAAK,CAAC,CAC5D,MAAQ,CAER,CAEA,aAAM1B,GAAcmB,EAAM,KAAMO,CAAe,EAExC,CACL,MAAOV,EAAO,YACd,MAAOG,EAAM,KACb,KAAMO,EACN,OAAQ,OACR,QAAS,GACT,cAAe,EACjB,CACF,CAEA,MAAO,CACL,MAAOV,EAAO,YACd,MAAOG,EAAM,KACb,KAAMO,EACN,OAAAH,EACA,QAAS,GACT,kBAAmB,EACrB,CACF,KACE,cAAMvB,GAAcmB,EAAM,KAAMO,CAAe,EACxC,CACL,MAAOV,EAAO,YACd,MAAOG,EAAM,KACb,KAAMO,EACN,OAAAH,EACA,QAAS,EACX,CAEJ,OAASO,EAAO,CACd,MAAO,CACL,MAAOd,EAAO,YACd,MAAOG,EAAM,KACb,KAAMO,EACN,OAAAH,EACA,QAAS,GACT,MAAOO,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,CAC9D,CACF,CACF,CAEA,eAAsBC,GAAoBhB,EAAkBS,EAAoC,CAC9F,IAAMR,EAASC,EAAeF,CAAK,EAC7BG,EAAYM,EAASR,EAAO,gBAAkB5C,EAAK0C,EAAgB,EAAGE,EAAO,SAAS,EAE5F,GAAI,CAEF,OADgB,MAAMZ,GAAQc,EAAW,CAAE,cAAe,EAAK,CAAC,GACjD,OAAQb,GAAUA,EAAM,YAAY,GAAKA,EAAM,eAAe,CAAC,EAAE,IAAKA,GAAUA,EAAM,IAAI,CAC3G,MAAQ,CACN,MAAO,CAAC,CACV,CACF,CAmCO,SAAS2B,GAAiBC,EAAmBC,EAAgC,CAAC,EAAW,CAC9F,IAAMC,EAAgBC,GAAaH,CAAS,EACtCI,EAAUH,EAAQ,OAASI,GAAQ,EAAIC,EAAgB,EACvDC,EAAgBC,EAAKJ,EAASK,GAAmBP,CAAa,EAEpE,GAAI,CAACQ,GAAWF,EAAKJ,EAASK,EAAiB,EAAGF,CAAa,EAC7D,MAAM,IAAI,MAAM,uDAAuD,EAGzE,OAAOA,CACT,CAEA,eAAsBI,EACpBX,EACAY,EACAX,EAAgC,CAAC,EAC+B,CAChE,IAAMY,EAAiE,CAAC,EAClEX,EAAgBC,GAAaH,CAAS,EACtCc,EAAcR,EAAgB,EAE9BC,EAAgBR,GAAiBC,EAAWC,CAAO,EACzD,GAAI,CACF,MAAMc,EAAGR,EAAe,CAAE,UAAW,GAAM,MAAO,EAAK,CAAC,CAC1D,MAAQ,CAER,CAEA,QAAWS,KAASJ,EAAQ,CAC1B,IAAMK,EAASC,EAAeF,CAAK,EAC7BG,EAAYlB,EAAQ,OAASgB,EAAO,gBAAkBT,EAAKM,EAAaG,EAAO,SAAS,EACxFG,EAAYZ,EAAKW,EAAWjB,CAAa,EAE/C,GAAI,CACF,MAAMa,EAAGK,EAAW,CAAE,UAAW,GAAM,MAAO,EAAK,CAAC,EACpDP,EAAQ,KAAK,CAAE,MAAOI,EAAO,YAAa,QAAS,EAAK,CAAC,CAC3D,OAASI,EAAO,CACdR,EAAQ,KAAK,CACX,MAAOI,EAAO,YACd,QAAS,GACT,MAAOI,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,CAC9D,CAAC,CACH,CACF,CAEA,aAAMC,GAAoBtB,CAAS,EAC5Ba,CACT,CK5RA,OAAOU,MAAQ,aCAf,OAAS,cAAAC,GAAY,gBAAAC,GAAc,iBAAAC,OAAqB,UACxD,OAAS,WAAAC,GAAS,QAAAC,OAAY,YAC9B,OAAS,iBAAAC,OAAqB,WCAvB,IAAMC,GAAyB,yBACzBC,GAAkB,SAClBC,EAAsB,gBAEtBC,GAAiC,CAC5C,GAAID,EACJ,KAAM,gBACN,YAAa,qCACb,SAAU,GACZ,EDEA,IAAME,GAAaC,GAAc,YAAY,GAAG,EAC1CC,GAAYC,GAAQH,EAAU,EAE7B,SAASI,IAAgC,CAC9C,IAAMC,EAAUC,GAAKJ,GAAW,KAAM,KAAM,KAAMK,EAAsB,EACxE,GAAIC,GAAWH,CAAO,EAAG,OAAOA,EAChC,IAAMI,EAAUH,GAAKJ,GAAW,KAAMK,EAAsB,EAC5D,OAAIC,GAAWC,CAAO,EAAUA,EACzBJ,CACT,CAEO,SAASK,IAAyC,CACvD,IAAMC,EAAWP,GAAsB,EACvC,GAAI,CAACI,GAAWG,CAAQ,EAAG,MAAO,CAAE,WAAY,CAAC,EAAG,OAAQ,CAAC,CAAE,EAE/D,GAAI,CACF,IAAMC,EAAUC,GAAaF,EAAU,OAAO,EAC9C,OAAO,KAAK,MAAMC,CAAO,CAC3B,MAAQ,CACN,MAAO,CAAE,WAAY,CAAC,EAAG,OAAQ,CAAC,CAAE,CACtC,CACF,CAoBO,SAASE,GAAmBC,EAA2B,CAE5D,OADeC,GAAqB,EACtB,OAAOD,CAAS,GAAKE,CACrC,CAqCO,SAASC,EACdC,EACwB,CACxB,IAAMC,EAASC,GAAqB,EAC9BC,EAAU,IAAI,IACdC,EAAmB,CAAC,GAAGH,EAAO,UAAU,EAAE,KAAK,CAACI,EAAGC,KAAOD,EAAE,UAAY,MAAQC,EAAE,UAAY,IAAI,EAExG,QAAWC,KAAYH,EACrBD,EAAQ,IAAII,EAAU,CAAC,CAAC,EAG1BJ,EAAQ,IAAIK,GAAkB,CAAC,CAAC,EAEhC,QAAWC,KAAST,EAAQ,CAC1B,IAAMU,EAAaD,EAAM,UAAYR,EAAO,OAAOQ,EAAM,IAAI,GAAKE,EAC5DJ,EAAWH,EAAiB,KAAM,GAAM,EAAE,KAAOM,CAAU,GAAKF,GAChEI,EAAQT,EAAQ,IAAII,CAAQ,GAAK,CAAC,EACxCK,EAAM,KAAKH,CAAK,EAChBN,EAAQ,IAAII,EAAUK,CAAK,CAC7B,CAEA,OAAW,CAACL,EAAUM,CAAS,IAAKV,EAC9BU,EAAU,SAAW,GAAGV,EAAQ,OAAOI,CAAQ,EAGrD,OAAOJ,CACT,CExHA,OAAS,cAAAW,EAAY,eAAAC,GAAa,gBAAAC,OAAoB,UACtD,OAAS,WAAAC,GAAS,QAAAC,MAAY,YAC9B,OAAS,iBAAAC,OAAqB,WAO9B,IAAMC,GAAaC,GAAc,YAAY,GAAG,EAC1CC,GAAYC,GAAQH,EAAU,EAE7B,SAASI,IAA6B,CAC3C,IAAMC,EAAeC,EAAKJ,GAAW,KAAM,KAAM,KAAMK,EAAe,EACtE,GAAIC,EAAWH,CAAY,EAAG,OAAOA,EACrC,IAAMI,EAAeH,EAAKJ,GAAW,KAAMK,EAAe,EAC1D,GAAIC,EAAWC,CAAY,EAAG,OAAOA,EACrC,MAAM,IAAI,MAAM,wCAAwCJ,CAAY,KAAKI,CAAY,EAAE,CACzF,CAEO,SAASC,GAA8B,CAC5C,IAAMC,EAAYP,GAAmB,EAC/BQ,EAAsB,CAAC,EAC7B,GAAI,CAACJ,EAAWG,CAAS,EAAG,OAAOC,EACnC,IAAMC,EAAUC,GAAYH,EAAW,CAAE,cAAe,EAAK,CAAC,EAE9D,QAAWI,KAASF,EAAS,CAC3B,GAAI,CAACE,EAAM,YAAY,EAAG,SAC1B,IAAMC,EAAcV,EAAKK,EAAWI,EAAM,KAAM,UAAU,EAC1D,GAAI,CAACP,EAAWQ,CAAW,EAAG,SAC9B,IAAMC,EAAUC,GAAaF,EAAa,OAAO,EAC3C,CAAE,KAAAG,EAAM,YAAAC,CAAY,EAAIC,GAAsBJ,CAAO,EAErDK,EAAYH,GAAQJ,EAAM,KAChCH,EAAO,KAAK,CACV,KAAMU,EACN,YAAaF,GAAe,iBAC5B,KAAMd,EAAKK,EAAWI,EAAM,IAAI,EAChC,SAAUQ,GAAmBD,CAAS,CACxC,CAAC,CACH,CAEA,OAAOV,CACT,CAEA,SAASS,GAAsBJ,EAA0D,CACvF,IAAMO,EAAmBP,EAAQ,MAAM,uBAAuB,EAC9D,GAAI,CAACO,EAAkB,MAAO,CAAC,EAC/B,IAAMC,EAAcD,EAAiB,CAAC,EAChCE,EAAYD,EAAY,MAAM,iBAAiB,EAC/CE,EAAYF,EAAY,MAAM,wBAAwB,EAC5D,MAAO,CAAE,KAAMC,IAAY,CAAC,GAAG,KAAK,EAAG,YAAaC,IAAY,CAAC,GAAG,KAAK,CAAE,CAC7E,CAEO,SAASC,GAAeT,EAAqC,CAElE,OADeT,EAAe,EAChB,KAAMmB,GAAMA,EAAE,OAASV,CAAI,CAC3C,CCzDO,SAASW,EAASC,EAAcC,EAA2B,CAChE,OAAOD,EAAK,QAAUC,EAAYD,EAAOA,EAAK,MAAM,EAAGC,EAAY,CAAC,EAAI,KAC1E,CCFA,OAAS,iBAAAC,GAAe,qBAAAC,GAAmB,gBAAAC,OAAoB,cAC/D,OAAOC,MAAQ,aCDf,OAAOC,OAAc,kBACrB,OAAOC,MAAQ,aAOR,IAAMC,GAA4BF,GAAS,CAChD,CAAE,MAAO,UAAW,IAAK,CAAE,EAC3B,CAAE,MAAO,UAAW,IAAK,EAAI,EAC7B,CAAE,MAAO,UAAW,IAAK,EAAI,EAC7B,CAAE,MAAO,UAAW,IAAK,EAAI,EAC7B,CAAE,MAAO,UAAW,IAAK,CAAE,CAC7B,CAAC,EAEYG,EAAQ,SACRC,EAAY,SACZC,GAAiB,SACjBC,GAAmB,SACnBC,GAAoB,SACpBC,GAAsB,SACtBC,EAASR,EAAG,KAAK,QAAG,EAE1B,SAASS,EAAOC,EAAU,GAAU,CACzC,QAAQ,IAAIA,EAAU,GAAGV,EAAG,KAAKE,CAAK,CAAC,KAAKQ,CAAO,GAAKV,EAAG,KAAKE,CAAK,CAAC,CACxE,CAEO,SAASS,EAAUD,EAAU,GAAU,CAC5C,QAAQ,IAAI,GAAGV,EAAG,KAAKG,CAAS,CAAC,KAAKO,CAAO,EAAE,CACjD,CAEO,SAASE,GAAqB,CACnCD,EAAUX,EAAG,KAAK,WAAW,CAAC,CAChC,CDfO,SAASa,EAAeC,EAAoC,CACjE,OAAO,OAAOA,GAAU,QAC1B,CAEA,eAAsBC,EACpBC,EACAC,EACAC,EACAC,EAAY,GACS,CACrB,IAAMC,EAAM,CAACC,EAAmBC,IAAsB,CACpD,IAAMC,EAAQD,EAAWE,EAAG,KAAKC,EAAc,EAAID,EAAG,KAAKE,EAAgB,EACrEC,EAAQL,EAAWE,EAAG,KAAKH,EAAO,KAAK,EAAIG,EAAG,MAAMH,EAAO,KAAK,EAChEO,EAAON,GAAYD,EAAO,KAAOG,EAAG,IAAIA,EAAG,KAAK,MAAMH,EAAO,IAAI,EAAE,CAAC,EAAI,GAC9E,MAAO,GAAGE,CAAK,IAAII,CAAK,GAAGC,CAAI,EACjC,EAwBMC,EAAS,MAtBA,IAAIC,GAAa,CAC9B,QAAAb,EACA,aAAAC,EACA,QAAS,CACP,IAAMa,EAAQ,GAAGP,EAAG,KAAKQ,CAAK,CAAC;AAAA,EAAKC,CAAM,IAAIT,EAAG,MAAMA,EAAG,KAAKR,CAAO,CAAC,CAAC;AAAA,EAClEkB,EAAWf,EAAY,eAAiB,GAE9C,OAAQ,KAAK,MAAO,CAClB,IAAK,SACH,MAAO,GAAGY,CAAK,GAAGP,EAAG,KAAKQ,CAAK,CAAC,KAAKR,EAAG,KAAK,KAAK,QAAQ,KAAMW,GAAMA,EAAE,QAAU,KAAK,KAAK,GAAG,KAAK,CAAC;AAAA,EAAKX,EAAG,KAAKQ,CAAK,CAAC,GAC1H,IAAK,SACH,MAAO,GAAGD,CAAK,GAAGP,EAAG,KAAKQ,CAAK,CAAC,KAAKR,EAAG,cAAcA,EAAG,KAAK,MAAM,CAAC,CAAC;AAAA,EAAKA,EAAG,KAAKQ,CAAK,CAAC,GAC3F,QACE,MAAO,GAAGD,CAAK,GAAG,KAAK,QACpB,IAAI,CAACV,EAAQe,IAAM,GAAGZ,EAAG,KAAKQ,CAAK,CAAC,KAAKZ,EAAIC,EAAqBe,IAAM,KAAK,MAAM,CAAC,EAAE,EACtF,KACC;AAAA,CACF,CAAC;AAAA,EAAKZ,EAAG,KAAKQ,CAAK,CAAC;AAAA,EAAKR,EAAG,KAAKa,CAAS,CAAC,KAAKb,EAAG,IAAIA,EAAG,KAAK,2BAAiBU,CAAQ,gBAAgB,CAAC,CAAC,EAChH,CACF,CACF,CAAC,EAE2B,OAAO,EACnC,OAAI,OAAOL,GAAW,UAAYV,EAAkB,OAAO,IAAI,MAAM,EAC9DU,CACT,CAEA,eAAsBS,EACpBtB,EACAC,EACAsB,EAAqB,CAAC,EACtBpB,EAAY,GACW,CACvB,IAAMC,EAAM,CAACC,EAAmBmB,IAAgF,CAC9G,IAAMC,EAAaD,IAAU,YAAcA,IAAU,kBAC/ClB,EAAWkB,IAAU,UAAYA,IAAU,kBAC3CE,EAAWD,EAAajB,EAAG,KAAKmB,EAAiB,EAAInB,EAAG,KAAKoB,EAAmB,EAChFjB,EAAQL,EAAWE,EAAG,KAAKH,EAAO,KAAK,EAAIG,EAAG,MAAMH,EAAO,KAAK,EAChEO,EAAON,GAAYD,EAAO,KAAOG,EAAG,IAAIA,EAAG,KAAK,KAAKH,EAAO,IAAI,GAAG,CAAC,EAAI,GAC9E,MAAO,GAAGqB,CAAQ,IAAIf,CAAK,GAAGC,CAAI,EACpC,EAiCMC,EAAS,MA/BA,IAAIgB,GAAkB,CACnC,QAAA5B,EACA,cAAAsB,EACA,QAAS,CACP,IAAMR,EAAQ,GAAGP,EAAG,KAAKQ,CAAK,CAAC;AAAA,EAAKC,CAAM,IAAIT,EAAG,MAAMA,EAAG,KAAKR,CAAO,CAAC,CAAC;AAAA,EAClEkB,EAAWf,EAAY,eAAiB,GAE9C,OAAQ,KAAK,MAAO,CAClB,IAAK,SACH,MAAO,GAAGY,CAAK,GAAGP,EAAG,KAAKQ,CAAK,CAAC,KAAK,KAAK,QACvC,OAAQG,GAAM,KAAK,MAAM,SAASA,EAAE,KAAK,CAAC,EAC1C,IAAKA,GAAMX,EAAG,KAAK,OAAOW,EAAE,KAAK,CAAC,CAAC,EACnC,KAAKX,EAAG,KAAK,IAAI,CAAC,CAAC;AAAA,EAAKA,EAAG,KAAKQ,CAAK,CAAC,GAC3C,IAAK,SACH,MAAO,GAAGD,CAAK,GAAGP,EAAG,KAAKQ,CAAK,CAAC,KAAKR,EAAG,cAAcA,EAAG,KAAK,MAAM,CAAC,CAAC;AAAA,EAAKA,EAAG,KAAKQ,CAAK,CAAC,GAC3F,QACE,MAAO,GAAGD,CAAK,GAAG,KAAK,QACpB,IAAI,CAACV,EAAQe,IAAM,CAClB,IAAMK,EAAa,KAAK,MAAM,SAASpB,EAAO,KAAK,EAC7CC,EAAWc,IAAM,KAAK,OACtBI,EACJC,GAAcnB,EAAW,kBAAoBmB,EAAa,WAAanB,EAAW,SAAW,WAC/F,MAAO,GAAGE,EAAG,KAAKQ,CAAK,CAAC,KAAKZ,EAAIC,EAAqBmB,CAAK,CAAC,EAC9D,CAAC,EACA,KACC;AAAA,CACF,CAAC;AAAA,EAAKhB,EAAG,KAAKQ,CAAK,CAAC;AAAA,EAAKR,EAAG,KAAKa,CAAS,CAAC,KAAKb,EAAG,IAAIA,EAAG,KAAK,yCAA+BU,CAAQ,gBAAgB,CAAC,CAAC,EAC9H,CACF,CACF,CAAC,EAE2B,OAAO,EACnC,OAAI,OAAOL,GAAW,UAAYV,EAAkB,OAAO,IAAI,MAAM,EAC9DU,CACT,CAEA,eAAsBiB,EAAY9B,EAAiBE,EAAe,GAAkC,CAuBlG,OAtBe,IAAI6B,GAAc,CAC/B,OAAQ,MACR,SAAU,KACV,aAAA7B,EACA,QAAS,CACP,IAAMa,EAAQ,GAAGP,EAAG,KAAKQ,CAAK,CAAC;AAAA,EAAKC,CAAM,IAAIT,EAAG,MAAMA,EAAG,KAAKR,CAAO,CAAC,CAAC;AAAA,EAExE,OAAQ,KAAK,MAAO,CAClB,IAAK,SACH,MAAO,GAAGe,CAAK,GAAGP,EAAG,KAAKQ,CAAK,CAAC,KAAKR,EAAG,KAAK,KAAK,MAAQ,MAAQ,IAAI,CAAC;AAAA,EAAKA,EAAG,KAAKQ,CAAK,CAAC,GAC5F,IAAK,SACH,MAAO,GAAGD,CAAK,GAAGP,EAAG,KAAKQ,CAAK,CAAC,KAAKR,EAAG,cAAcA,EAAG,KAAK,WAAW,CAAC,CAAC;AAAA,EAAKA,EAAG,KAAKQ,CAAK,CAAC,GAChG,QACE,MAAO,GAAGD,CAAK,GAAGP,EAAG,KAAKQ,CAAK,CAAC,KAC9B,KAAK,MACD,GAAGR,EAAG,KAAK,YAAO,CAAC,IAAIA,EAAG,IAAIA,EAAG,KAAK,GAAG,CAAC,CAAC,IAAIA,EAAG,KAAK,QAAG,CAAC,IAAIA,EAAG,MAAM,IAAI,CAAC,GAC7E,GAAGA,EAAG,KAAK,QAAG,CAAC,IAAIA,EAAG,MAAM,KAAK,CAAC,IAAIA,EAAG,IAAIA,EAAG,KAAK,GAAG,CAAC,CAAC,IAAIA,EAAG,KAAK,WAAM,CAAC,EACnF;AAAA,EAAKA,EAAG,KAAKQ,CAAK,CAAC;AAAA,EAAKR,EAAG,KAAKa,CAAS,CAAC,KAAKb,EAAG,IAAIA,EAAG,KAAK,4CAAkC,CAAC,CAAC,EACtG,CACF,CACF,CAAC,EAEa,OAAO,CACvB,CE1IA,OAAOwB,OAAY,SACnB,OAAOC,MAAQ,aAIR,SAASC,IAAuB,CACrC,IAAMC,EAAWC,GAAO,SAAS,kBAAmB,CAAE,KAAM,WAAY,iBAAkB,SAAU,CAAC,EACrG,MAAO;AAAA,EACPC,GAAgB,UAAUF,CAAQ,CAAC;AAAA,IACjCG,EAAG,MAAMA,EAAG,KAAK,iBAAiB,CAAC,CAAC,IAAIA,EAAG,KAAK,QAAG,CAAC,IAAIA,EAAG,KAAKA,EAAG,KAAK,cAAc,CAAC,CAAC;AAAA,IACxFA,EAAG,MAAM,kDAAkD,CAAC;AAAA,CAEhE,CAEO,SAASC,GAAmB,CACjC,QAAQ,MAAM,EACd,QAAQ,IAAIL,GAAa,CAAC,EAC1BM,EAAO,CACT,CClBA,OAAS,iBAAAC,OAAqB,cAC9B,OAAOC,OAAiB,eAExB,IAAMC,GAAe,gCAErB,eAAsBC,GAAgBC,EAAgD,CACpF,GAAI,CACF,IAAMC,EAAS,MAAMJ,GAAYC,EAAY,EAC7C,OAAIG,EAAO,UAAYD,EAAuBC,EAAO,QAC9C,IACT,MAAQ,CAEN,OAAO,IACT,CACF,CAEO,SAASC,IAA4B,CAC1C,GAAI,CAGF,OAFgBN,GAAc,YAAY,GAAG,EACzB,iBAAiB,EAC1B,SAAW,OACxB,MAAQ,CACN,MAAO,OACT,CACF,CCxBA,OAAOO,MAAQ,aAUR,SAASC,GAAwBC,EAA2C,CACjFC,EAAO,EACPA,EAAOC,EAAG,KAAKA,EAAG,KAAK,gCAAyB,CAAC,CAAC,EAClDD,EAAO,EACPA,EAAO,GAAGC,EAAG,KAAKC,CAAK,CAAC,KAAKD,EAAG,MAAMA,EAAG,KAAK,SAAS,CAAC,CAAC,IAAIA,EAAG,KAAKF,EAAQ,OAAO,KAAK,IAAI,CAAC,CAAC,EAAE,EACjGC,EAAO,GAAGC,EAAG,KAAKC,CAAK,CAAC,KAAKD,EAAG,MAAMA,EAAG,KAAK,SAAS,CAAC,CAAC,IAAIA,EAAG,KAAKF,EAAQ,OAAO,KAAK,IAAI,CAAC,CAAC,EAAE,EACjGC,EAAO,GAAGC,EAAG,KAAKC,CAAK,CAAC,KAAKD,EAAG,MAAMA,EAAG,KAAK,SAAS,CAAC,CAAC,IAAIA,EAAG,KAAKF,EAAQ,MAAM,CAAC,EAAE,EACtFC,EAAO,CACT,CAEO,SAASG,GACdC,EAQM,CACN,IAAMC,EAAaD,EAAQ,OAAQE,GAAMA,EAAE,SAAW,CAACA,EAAE,KAAK,EACxDC,EAAgBH,EAAQ,OAAQE,GAAMA,EAAE,SAAWA,EAAE,QAAU,gBAAgB,EAC/EE,EAASJ,EAAQ,OAAQE,GAAM,CAACA,EAAE,OAAO,EAE/C,QAAQ,IAAI,EAEZ,QAAWA,KAAKD,EACd,QAAQ,IAAI,GAAGI,CAAM,IAAIR,EAAG,MAAMA,EAAG,KAAKK,EAAE,KAAK,CAAC,CAAC,IAAIL,EAAG,KAAK,QAAG,CAAC,IAAIA,EAAG,MAAMK,EAAE,KAAK,CAAC,EAAE,EAG5F,QAAWA,KAAKC,EACd,QAAQ,IAAI,GAAGN,EAAG,KAAKQ,CAAM,CAAC,IAAIH,EAAE,KAAK,WAAMA,EAAE,KAAK,IAAIL,EAAG,KAAK,UAAU,CAAC,EAAE,EAGjF,QAAWK,KAAKE,EACd,QAAQ,IAAI,GAAGP,EAAG,IAAI,QAAG,CAAC,IAAIK,EAAE,KAAK,WAAMA,EAAE,KAAK,KAAKA,EAAE,KAAK,EAAE,EAGlE,IAAMI,EAAc,IAAI,IAAIN,EAAQ,IAAKE,GAAMA,EAAE,KAAK,CAAC,EAAE,KAEzD,QAAQ,IAAI,EACZK,EACE,GAAGV,EAAG,KAAK,QAAG,CAAC,IAAIA,EAAG,MAAMA,EAAG,KAAK,GAAGI,EAAW,MAAM,WAAW,CAAC,CAAC,IAAIJ,EAAG,MAAM,cAAc,CAAC,IAAIA,EAAG,MAAMA,EAAG,KAAK,GAAGS,CAAW,WAAW,CAAC,CAAC,EACnJ,CACF,CAEO,SAASE,EACdC,EACAT,EACM,CACN,IAAMC,EAAaD,EAAQ,OAAQE,GAAMA,EAAE,OAAO,EAC5CE,EAASJ,EAAQ,OAAQE,GAAM,CAACA,EAAE,OAAO,EAE3CD,EAAW,OAAS,GACtB,QAAQ,IACN,GAAGI,CAAM,IAAIR,EAAG,MAAMA,EAAG,KAAKY,CAAS,CAAC,CAAC,IAAIZ,EAAG,KAAK,cAAc,CAAC,IAAII,EAAW,IAAKC,GAAMA,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC,EACnH,EAGF,QAAWA,KAAKE,EACd,QAAQ,IAAI,GAAGP,EAAG,IAAI,QAAG,CAAC,IAAIY,CAAS,WAAMP,EAAE,KAAK,KAAKA,EAAE,KAAK,EAAE,EAGhED,EAAW,OAAS,GAAKG,EAAO,SAAW,GAC7CG,EAAU,GAAGV,EAAG,KAAK,QAAG,CAAC,IAAIA,EAAG,MAAM,4BAA4B,CAAC,EAAE,CAEzE,CC5EA,OAAOa,OAAQ,aAQR,SAASC,EAAkBC,EAAqBC,EAA8B,CAAC,EAAwB,CAC5G,OAAOD,EAAO,IAAKE,GAAS,CAC1B,IAAMC,EAASC,EAAeF,CAAI,EAC5BG,EAAaJ,EAAe,SAASC,CAAI,EAC/C,MAAO,CACL,MAAOA,EACP,MAAOG,EAAa,GAAGF,EAAO,WAAW,IAAIG,GAAG,MAAM,iBAAY,CAAC,GAAKH,EAAO,YAC/E,KAAMI,EAASJ,EAAO,YAAa,EAAE,CACvC,CACF,CAAC,CACH,CAEA,eAAsBK,EAAuBR,EAAqBS,EAAuC,CACvG,IAAMC,EAAY,IAAI,IACtB,QAAWC,KAASX,GACH,MAAMY,GAAoBD,EAAOF,CAAM,GAC/C,QAASI,GAAUH,EAAU,IAAIG,CAAK,CAAC,EAEhD,OAAOH,CACT,CAEA,eAAsBI,EAA0Bd,EAA2C,CACzF,GAAM,CAACe,EAAcC,CAAW,EAAI,MAAM,QAAQ,IAAI,CACpDR,EAAuBR,EAAQ,EAAI,EACnCQ,EAAuBR,EAAQ,EAAK,CACtC,CAAC,EACD,OAAO,IAAI,IAAI,CAAC,GAAGe,EAAc,GAAGC,CAAW,CAAC,CAClD,CVZA,IAAMC,GAAmB,iBACnBC,GAAuB,UAE7B,eAAsBC,IAAwD,CAC5EC,EAAW,EACX,MAAMC,GAAiB,EAEvB,IAAMC,EAAYC,EAAe,EACjC,GAAID,EAAU,SAAW,EACvB,OAAAE,EAAUC,EAAG,IAAI,qBAAqB,CAAC,EAChC,KAGT,IAAMC,EAAkBC,GAAsB,EACxCC,EAAYC,EAAiB,EAC7BC,EAAeJ,EAAgB,OAAS,EAAIA,EAAkBE,EAC9DG,EAAkB,MAAMC,EAA0BF,CAAY,EAE9DG,EAAqB,CACzB,SAAUf,GACV,OAAQ,CAAC,EACT,OAAQQ,EAAgB,OAAS,EAAIA,EAAmB,CAAC,SAAU,aAAa,EAChF,OAAQ,UACR,OAAQ,EACV,EAEIQ,EAAc,EACZC,EAAa,EAEnB,KAAOD,GAAeC,GAAY,CAChC,IAAMC,EAAgBX,EAAG,KAAK,IAAIS,CAAW,IAAIC,CAAU,GAAG,EACxDE,EAAYH,EAAc,EAEhC,OAAQA,EAAa,CACnB,IAAK,GAAG,CACN,IAAMI,EAAS,MAAMC,GAAmB,CAAE,UAAAjB,EAAW,cAAAc,EAAe,gBAAiBH,EAAM,QAAS,CAAC,EACrG,GAAIK,IAAW,KAAM,OAAO,KAC5BL,EAAM,SAAWK,EACjBJ,IACA,KACF,CAEA,IAAK,GAAG,CACN,IAAMI,EAAS,MAAME,GAAiB,CACpC,MAAAP,EACA,UAAAX,EACA,gBAAAS,EACA,cAAAK,EACA,UAAAC,CACF,CAAC,EAED,GAAIC,IAAW,OAAO,IAAI,MAAM,EAAG,CACjCJ,IACA,KACF,CAEA,GAAII,IAAW,KAAM,OAAO,KAE5BL,EAAM,OAASK,EACfJ,IACA,KACF,CAEA,IAAK,GAAG,CACN,IAAMI,EAAS,MAAMG,GAAiB,CACpC,UAAAb,EACA,gBAAAF,EACA,cAAeO,EAAM,OACrB,cAAAG,EACA,UAAAC,CACF,CAAC,EAED,GAAIC,IAAW,OAAO,IAAI,MAAM,EAAG,CACjCJ,IACA,KACF,CAEA,GAAII,IAAW,KAAM,OAAO,KAE5BL,EAAM,OAASK,EACfJ,IACA,KACF,CAEA,IAAK,GAAG,CACN,IAAMI,EAAS,MAAMI,GAA0B,CAC7C,MAAAT,EACA,cAAAG,EACA,UAAAC,CACF,CAAC,EAED,GAAIC,IAAW,OAAO,IAAI,MAAM,EAAG,CACjCL,EAAM,OAAS,UACfC,IACA,KACF,CAEA,GAAII,IAAW,KAAM,OAAO,KAC5B,GAAIA,IAAW,GAAO,CACpBJ,EAAc,EACd,KACF,CAEA,OAAOI,CACT,CACF,CACF,CAEA,OAAO,IACT,CAEA,eAAejB,IAAmB,CAChC,IAAMsB,EAAiBC,GAAkB,EACnCC,EAAgB,MAAMC,GAAgBH,CAAc,EAEtDE,GACFE,EACE,GAAGtB,EAAG,OAAO,QAAG,CAAC,KAAKA,EAAG,OAAO,mBAAmB,CAAC,IAAIA,EAAG,KAAKkB,CAAc,CAAC,WAAMlB,EAAG,MAAMoB,CAAa,CAAC,EAC9G,EACAE,EAAO,MAAMtB,EAAG,KAAK,kDAAkD,CAAC,EAAE,EAC1EsB,EAAO,GACGC,GAAoB,IAC9BD,EAAO,GAAGtB,EAAG,OAAO,QAAG,CAAC,KAAKA,EAAG,OAAO,wBAAwB,CAAC,EAAE,EAClEsB,EAAO,MAAMtB,EAAG,OAAO,6CAA6C,CAAC,EAAE,EACvEsB,EAAO,MAAMtB,EAAG,OAAO,wCAAwC,CAAC,EAAE,EAClEsB,EAAO,EAEX,CAQA,eAAeR,GAAmB,CAChC,UAAAjB,EACA,cAAAc,EACA,gBAAAa,CACF,EAAgD,CAC9C,IAAMC,EAAgBC,EAAsB7B,CAAS,EAC/C8B,EAAe,MAAM,KAAKF,EAAc,KAAK,CAAC,EAE9CG,EAAkB,CACtB,CAAE,MAAOnC,GAAsB,MAAO,GAAGO,EAAG,KAAK,QAAG,CAAC,cAAe,KAAM,GAAGH,EAAU,MAAM,YAAa,EAC1G,GAAG8B,EAAa,IAAKE,GAAQ,CAC3B,IAAMC,EAAaL,EAAc,IAAII,CAAG,GAAG,QAAU,EACrD,MAAO,CAAE,MAAOA,EAAI,GAAI,MAAO,GAAG7B,EAAG,KAAK,QAAG,CAAC,IAAI6B,EAAI,IAAI,GAAI,KAAM,GAAGC,CAAU,WAAY,CAC/F,CAAC,CACH,EAEMC,EAAmB,MAAMC,EAC7B,GAAGrB,CAAa,sBAChBiB,EACAJ,EACA,EACF,EAEA,OAAIS,EAAYF,CAAgB,GAC9BG,EAAa,EACN,MAGFH,CACT,CAUA,eAAehB,GAAiB,CAC9B,MAAAP,EACA,UAAAX,EACA,gBAAAS,EACA,cAAAK,EACA,UAAAC,CACF,EAAyD,CAEvD,IAAMuB,EADoB3B,EAAM,WAAaf,GACFI,EAAYA,EAAU,OAAQuC,GAAUA,EAAM,WAAa5B,EAAM,QAAQ,EAE9G6B,EAAe,CACnB,CACE,MAAO7C,GACP,MAAO,GAAGQ,EAAG,KAAK,QAAG,CAAC,IAAIA,EAAG,KAAK,YAAY,CAAC,GAC/C,KAAM,cAAcmC,EAAe,MAAM,SAC3C,EACA,GAAGA,EAAe,IAAKC,GAAU,CAC/B,IAAME,EAAchC,EAAgB,IAAI8B,EAAM,IAAI,EAClD,MAAO,CACL,MAAOA,EAAM,KACb,MAAOE,EAAc,GAAGF,EAAM,IAAI,IAAIpC,EAAG,MAAM,kBAAa,CAAC,GAAKoC,EAAM,KACxE,KAAMG,EAASH,EAAM,YAAa,GAAG,CACvC,CACF,CAAC,CACH,EAEMI,EAAgBhC,EAAM,OAAO,OAAS,EAAIA,EAAM,OAAS,CAAC,EAE1DiC,EAAiB,MAAMC,EAC3B,GAAG/B,CAAa,4BAChB0B,EACAG,EACA5B,CACF,EAEA,GAAI6B,IAAmB,OAAO,IAAI,MAAM,EAAG,OAAO,OAAO,IAAI,MAAM,EAEnE,GAAIR,EAAYQ,CAAc,EAC5B,OAAAP,EAAa,EACN,KAGT,IAAMS,EAAcF,EAEdG,EAAcD,EAAY,SAASnD,EAAgB,EACrD2C,EAAe,IAAKU,GAAMA,EAAE,IAAI,EAChCF,EAAY,OAAQE,GAAMA,IAAMrD,EAAgB,EAGpD,OADIoD,EAAY,SAAW,GAAGtB,EAAOtB,EAAG,OAAO,yCAAoC,CAAC,EAChF4C,EAAY,SAAW,EAAU7B,GAAiB,CAAE,MAAAP,EAAO,UAAAX,EAAW,gBAAAS,EAAiB,cAAAK,EAAe,UAAAC,CAAU,CAAC,EAC9GgC,CACT,CAUA,eAAe5B,GAAiB,CAC9B,UAAAb,EACA,gBAAAF,EACA,cAAA6C,EACA,cAAAnC,EACA,UAAAC,CACF,EAA4D,CAC1D,IAAMmC,EAAeC,EAAkB7C,EAAWF,CAAe,EAE3DgD,EAAiB,MAAMP,EAC3B,GAAG/B,CAAa,qBAChBoC,EACAD,EACAlC,CACF,EAEA,GAAIqC,IAAmB,OAAO,IAAI,MAAM,EAAG,OAAO,OAAO,IAAI,MAAM,EAEnE,GAAIhB,EAAYgB,CAAc,EAC5B,OAAAf,EAAa,EACN,KAGT,IAAMgB,EAAcD,EAEpB,OAAIC,EAAY,SAAW,GACzB5B,EAAOtB,EAAG,OAAO,yCAAoC,CAAC,EAC/CgB,GAAiB,CAAE,UAAAb,EAAW,gBAAAF,EAAiB,cAAA6C,EAAe,cAAAnC,EAAe,UAAAC,CAAU,CAAC,GAG1FsC,CACT,CAQA,eAAejC,GAA0B,CACvC,MAAAT,EACA,cAAAG,EACA,UAAAC,CACF,EAAoE,CAClE,IAAMuC,EAAgB,CACpB,CAAE,MAAO,UAAW,MAAO,UAAW,KAAM,6BAA8B,EAC1E,CAAE,MAAO,OAAQ,MAAO,OAAQ,KAAM,oBAAqB,CAC7D,EAEMC,EAAS,MAAMpB,EACnB,GAAGrB,CAAa,uBAChBwC,EACA3C,EAAM,OACNI,CACF,EAEA,GAAIwC,IAAW,OAAO,IAAI,MAAM,EAAG,OAAO,OAAO,IAAI,MAAM,EAE3D,GAAInB,EAAYmB,CAAM,EACpB,OAAAlB,EAAa,EACN,KAGT1B,EAAM,OAAS4C,EACfC,GAAwB7C,CAAK,EAC7B,IAAM8C,EAAc,MAAMC,GAAY/C,CAAK,EAC3C,GAAI8C,IAAgB,OAAO,IAAI,MAAM,EAAG,OAAOrC,GAA0B,CAAE,MAAAT,EAAO,cAAAG,EAAe,UAAAC,CAAU,CAAC,EAC5G,GAAI0C,IAAgB,KAAM,OAAO,KACjC9C,EAAM,OAAS8C,IAAgB,SAC/B,IAAME,EAAU,MAAMC,EAAYzD,EAAG,MAAM,4BAA4B,EAAG,EAAI,EAE9E,OAAIiC,EAAYuB,CAAO,GACrBtB,EAAa,EACN,MAGJsB,GACLlC,EAAO,EAEA,CAAE,OAAQd,EAAM,OAAQ,OAAQA,EAAM,OAAQ,OAAQA,EAAM,OAAQ,OAAQA,EAAM,MAAO,GAH3E,EAIvB,CAEA,eAAe+C,GAAY/C,EAAiE,CAM1F,IAAMkD,EAAQ,MAAM1B,EAAmB,qBALlB,CACnB,CAAE,MAAO,QAAS,MAAO,QAAS,KAAM,mBAAoB,EAC5D,CAAE,MAAO,SAAU,MAAO,SAAU,KAAM,qBAAsB,CAClE,EAE2ExB,EAAM,OAAS,SAAW,QAAS,EAAI,EAClH,OAAIkD,IAAU,OAAO,IAAI,MAAM,EAAU,OAAO,IAAI,MAAM,EACtDzB,EAAYyB,CAAK,EAAU,KACxBA,CACT,CW9VA,OAAOC,MAAQ,aASf,eAAsBC,IAAqC,CACzDC,EAAW,EACX,IAAMC,EAASC,EAAe,EAE9B,GAAID,EAAO,SAAW,EAAG,CACvBE,EAAOC,EAAG,OAAO,iBAAiB,CAAC,EACnC,MACF,CAEAD,EAAOC,EAAG,KAAK,GAAGH,EAAO,MAAM,oBAAoB,CAAC,EACpDE,EAAO,EAEP,IAAME,EAAYC,EAAiB,EAC7BC,EAAkB,MAAMC,EAA0BH,CAAS,EAC3DI,EAAgBC,EAAsBT,CAAM,EAElD,OAAW,CAACU,EAAUC,CAAc,IAAKH,EAAe,CACtDN,EAAO,GAAGC,EAAG,KAAK,QAAG,CAAC,IAAIA,EAAG,KAAKA,EAAG,KAAKO,EAAS,IAAI,CAAC,CAAC,EAAE,EAE3D,QAAWE,KAASD,EAAgB,CAClC,IAAME,EAAiBP,EAAgB,IAAIM,EAAM,IAAI,EAAI,IAAIT,EAAG,MAAM,kBAAa,CAAC,GAAK,GACzFD,EAAO,KAAKC,EAAG,KAAK,QAAG,CAAC,IAAIA,EAAG,KAAKS,EAAM,IAAI,CAAC,GAAGC,CAAc,EAAE,EAClE,QAAQ,IAAI,GAAGV,EAAG,KAAKW,CAAK,CAAC,SAASX,EAAG,IAAIA,EAAG,KAAKS,EAAM,WAAW,CAAC,CAAC,EAAE,CAC5E,CAEAV,EAAO,CACT,CAEAa,EAAUZ,EAAG,KAAK,oDAAoD,CAAC,CACzE,CCtCA,OAAOa,OAAQ,aAWf,eAAsBC,GAAqBC,EAAgC,CACzEC,EAAW,EACX,IAAMC,EAAYC,EAAiB,EAC7BC,EAAkB,MAAMC,EAAuBH,EAAWF,CAAM,EAEtE,GAAII,EAAgB,OAAS,EAAG,CAC9BE,EAAOC,GAAG,OAAO,qBAAqB,CAAC,EACvCC,EAAU,EACV,MACF,CAEA,IAAMC,EAAc,MAAM,KAAKL,CAAe,EAGxCM,EAAiB,MAAMC,EAC3B,uCAAuCJ,GAAG,KAAK,IAAIE,EAAY,MAAM,aAAa,CAAC,GACnFA,EAAY,IAAKG,IAAU,CAAE,MAAOA,EAAM,MAAOA,CAAK,EAAE,EACxD,CAAC,EACD,EACF,EAEA,GAAIC,EAAYH,CAAc,GAAMA,EAA4B,SAAW,EAAG,CAC5EI,EAAa,EACb,MACF,CAGA,IAAMC,EAAiB,MAAMJ,EAC3B,4BACAK,EAAkBd,CAAS,EAAE,IAAKe,IAAS,CAAE,GAAGA,EAAK,KAAM,MAAU,EAAE,EACvEf,EACA,EACF,EAEA,GAAIW,EAAYE,CAAc,EAAG,CAC/BD,EAAa,EACb,MACF,CAGA,IAAMI,EAAU,MAAMC,EACpB,UAAUT,EAAe,MAAM,kBAAkBK,EAAe,MAAM,aACtE,EACF,EAEA,GAAIF,EAAYK,CAAO,GAAK,CAACA,EAAS,CACpCJ,EAAa,EACb,MACF,CAEAR,EAAO,EAEP,QAAWc,KAAaV,EAAgB,CACtC,IAAMW,EAAU,MAAMC,EAAYF,EAAWL,EAA+B,CAAE,OAAAf,CAAO,CAAC,EACtFuB,EAAkBH,EAAWC,CAAO,CACtC,CACF,ClBzDA,IAAMG,EAAU,IAAIC,GAEpBD,EAAQ,KAAK,kBAAkB,EAAE,YAAY,mDAAmD,EAAE,QAAQ,OAAO,EAEjHA,EACG,QAAQ,UAAW,CAAE,UAAW,EAAK,CAAC,EACtC,YAAY,0CAA0C,EACtD,OAAO,eAAgB,gCAAiC,EAAK,EAC7D,OAAO,qBAAsB,0BAA0B,EACvD,OAAO,0BAA2B,wBAAwB,EAC1D,OAAO,SAAU,8BAA+B,EAAK,EACrD,OAAO,MAAOE,GAAY,CACzB,GAAIA,EAAQ,OAASA,EAAQ,MAC3B,MAAMC,GAAkBD,CAAO,MAC1B,CACL,IAAME,EAAiB,MAAMC,GAAsB,EACnD,GAAI,CAACD,EAAgB,OACrB,IAAME,EAASC,EAAe,EAAE,OAAQC,GAAMJ,EAAe,OAAO,SAASI,EAAE,IAAI,CAAC,EAC9EC,EAAU,MAAMC,GAAcJ,EAAQF,CAAc,EAC1DO,GAAmBF,CAAO,CAC5B,CACF,CAAC,EAEHT,EACG,QAAQ,MAAM,EACd,MAAM,IAAI,EACV,YAAY,uBAAuB,EACnC,OAAO,SAAY,CAClB,MAAMY,GAAoB,CAC5B,CAAC,EAEHZ,EACG,QAAQ,QAAQ,EAChB,MAAM,IAAI,EACV,YAAY,yBAAyB,EACrC,OAAO,eAAgB,kCAAmC,EAAK,EAC/D,OAAO,qBAAsB,yBAAyB,EACtD,OAAO,0BAA2B,wBAAwB,EAC1D,OAAO,MAAOE,GAAY,CACzB,GAAIA,EAAQ,MAAO,CACjB,IAAMW,EAAUX,EAAQ,OAAS,CAAC,cAAe,cAAe,QAAQ,EAClEO,EAAU,MAAMK,EAAYZ,EAAQ,MAAOW,EAAQ,CAAE,OAAQX,EAAQ,MAAO,CAAC,EACnFa,EAAkBb,EAAQ,MAAOO,CAAO,CAC1C,MACE,MAAMO,GAAqBd,EAAQ,MAAM,CAE7C,CAAC,EAEH,eAAeC,GAAkBD,EAA+E,CAC9G,IAAMe,EAAYV,EAAe,EAC7BD,EAASW,EAEb,GAAIf,EAAQ,MAAO,CACjB,IAAMgB,EAAQC,GAAejB,EAAQ,KAAK,EACrCgB,IACH,QAAQ,MAAM,UAAUhB,EAAQ,KAAK,cAAc,EACnD,QAAQ,IAAI,oBAAqBe,EAAU,IAAKT,GAAMA,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC,EACxE,QAAQ,KAAK,CAAC,GAEhBF,EAAS,CAACY,CAAK,CACjB,CAEA,IAAML,EAAUX,EAAQ,OAAS,CAAC,cAAe,cAAe,QAAQ,EAClEkB,EAASlB,EAAQ,KAAO,OAAS,UAEjCO,EAAU,MAAMC,GAAcJ,EAAQ,CAC1C,OAAAO,EACA,OAAQP,EAAO,IAAKE,GAAMA,EAAE,IAAI,EAChC,OAAAY,EACA,OAAQlB,EAAQ,MAClB,CAAC,EAEDS,GAAmBF,CAAO,CAC5B,CAEAT,EAAQ,MAAM",
6
+ "names": ["Command", "cp", "lstat", "mkdir", "readdir", "readlink", "rm", "symlink", "homedir", "platform", "join", "normalize", "relative", "resolve", "sep", "existsSync", "homedir", "join", "existsSync", "dirname", "join", "parse", "resolve", "findProjectRoot", "startDir", "currentDir", "root", "home", "homedir", "projectRoot", "findProjectRoot", "agents", "join", "existsSync", "detectInstalledAgents", "config", "type", "getAgentConfig", "getAllAgentTypes", "a", "b", "execSync", "existsSync", "join", "PACKAGE_NAME", "getNpmGlobalRoot", "getGlobalSkillsPath", "npmGlobalRoot", "skillsPath", "isGloballyInstalled", "getGlobalSkillPath", "skillName", "skillPath", "mkdir", "readFile", "writeFile", "homedir", "dirname", "join", "AGENTS_DIR", "LOCK_FILE", "CURRENT_VERSION", "getSkillLockPath", "createEmptyLockFile", "readSkillLock", "lockPath", "content", "parsed", "writeSkillLock", "lock", "addSkillToLock", "skillName", "source", "now", "existingEntry", "removeSkillFromLock", "AGENTS_SKILLS_DIR", "join", "EXCLUDE_FILES", "sanitizeName", "name", "sanitized", "isPathSafe", "basePath", "targetPath", "normalizedBase", "normalize", "resolve", "normalizedTarget", "sep", "createSymlink", "target", "linkPath", "lstat", "existingTarget", "readlink", "rm", "err", "linkDir", "mkdir", "relativePath", "relative", "type", "platform", "symlink", "copyDirectory", "src", "dest", "entries", "readdir", "entry", "srcPath", "destPath", "cp", "installSkills", "skills", "options", "results", "projectRoot", "findProjectRoot", "agent", "config", "getAgentConfig", "targetDir", "skill", "result", "installSkillForAgent", "addSkillToLock", "method", "global", "safeSkillName", "skillTargetPath", "globalSkillPath", "getGlobalSkillPath", "canonicalDir", "error", "listInstalledSkills", "getCanonicalPath", "skillName", "options", "safeSkillName", "sanitizeName", "baseDir", "homedir", "findProjectRoot", "canonicalPath", "join", "AGENTS_SKILLS_DIR", "isPathSafe", "removeSkill", "agents", "results", "projectRoot", "rm", "agent", "config", "getAgentConfig", "targetDir", "skillPath", "error", "removeSkillFromLock", "pc", "existsSync", "readFileSync", "writeFileSync", "dirname", "join", "fileURLToPath", "SKILLS_CATEGORIES_FILE", "SKILLS_ROOT_DIR", "DEFAULT_CATEGORY_ID", "DEFAULT_CATEGORY", "__filename", "fileURLToPath", "__dirname", "dirname", "getCategoriesFilePath", "devPath", "join", "SKILLS_CATEGORIES_FILE", "existsSync", "pkgPath", "loadCategoriesConfig", "filePath", "content", "readFileSync", "getSkillCategoryId", "skillName", "loadCategoriesConfig", "DEFAULT_CATEGORY_ID", "groupSkillsByCategory", "skills", "config", "loadCategoriesConfig", "grouped", "sortedCategories", "a", "b", "category", "DEFAULT_CATEGORY", "skill", "categoryId", "DEFAULT_CATEGORY_ID", "group", "skillList", "existsSync", "readdirSync", "readFileSync", "dirname", "join", "fileURLToPath", "__filename", "fileURLToPath", "__dirname", "dirname", "getSkillsDirectory", "devSkillsDir", "join", "SKILLS_ROOT_DIR", "existsSync", "pkgSkillsDir", "discoverSkills", "skillsDir", "skills", "entries", "readdirSync", "entry", "skillMdPath", "content", "readFileSync", "name", "description", "parseSkillFrontmatter", "skillName", "getSkillCategoryId", "frontmatterMatch", "frontmatter", "nameMatch", "descMatch", "getSkillByName", "s", "truncate", "text", "maxLength", "ConfirmPrompt", "MultiSelectPrompt", "SelectPrompt", "pc", "gradient", "pc", "crystalGradient", "S_BAR", "S_BAR_END", "S_RADIO_ACTIVE", "S_RADIO_INACTIVE", "S_CHECKBOX_ACTIVE", "S_CHECKBOX_INACTIVE", "SYMBOL", "logBar", "message", "logBarEnd", "logCancelled", "isCancelled", "value", "blueSelectWithBack", "message", "options", "initialValue", "allowBack", "opt", "option", "isActive", "radio", "pc", "S_RADIO_ACTIVE", "S_RADIO_INACTIVE", "label", "hint", "result", "SelectPrompt", "title", "S_BAR", "SYMBOL", "backHint", "o", "i", "S_BAR_END", "blueMultiSelectWithBack", "initialValues", "state", "isSelected", "checkbox", "S_CHECKBOX_ACTIVE", "S_CHECKBOX_INACTIVE", "MultiSelectPrompt", "blueConfirm", "ConfirmPrompt", "figlet", "pc", "generateLogo", "asciiArt", "figlet", "crystalGradient", "pc", "initScreen", "logBar", "createRequire", "packageJson", "PACKAGE_NAME", "checkForUpdates", "currentVersion", "result", "getCurrentVersion", "pc", "showInstallationSummary", "options", "logBar", "pc", "S_BAR", "showInstallResults", "results", "successful", "r", "alreadyExists", "failed", "SYMBOL", "totalAgents", "logBarEnd", "showRemoveResults", "skillName", "pc", "buildAgentOptions", "agents", "detectedAgents", "type", "config", "getAgentConfig", "isDetected", "pc", "truncate", "getInstalledSkillNames", "global", "installed", "agent", "listInstalledSkills", "skill", "getAllInstalledSkillNames", "globalSkills", "localSkills", "ALL_SKILLS_VALUE", "ALL_CATEGORIES_VALUE", "runInteractiveInstall", "initScreen", "checkEnvironment", "allSkills", "discoverSkills", "logBarEnd", "pc", "installedAgents", "detectInstalledAgents", "allAgents", "getAllAgentTypes", "targetAgents", "installedSkills", "getAllInstalledSkillNames", "state", "currentStep", "totalSteps", "stepIndicator", "allowBack", "result", "selectCategoryStep", "selectSkillsStep", "selectAgentsStep", "configureInstallationStep", "currentVersion", "getCurrentVersion", "latestVersion", "checkForUpdates", "logBar", "isGloballyInstalled", "currentCategory", "groupedSkills", "groupSkillsByCategory", "categoryList", "categoryOptions", "cat", "skillCount", "selectedCategory", "blueSelectWithBack", "isCancelled", "logCancelled", "filteredSkills", "skill", "skillOptions", "isInstalled", "truncate", "initialSkills", "selectedSkills", "blueMultiSelectWithBack", "skillsArray", "validSkills", "s", "currentAgents", "agentOptions", "buildAgentOptions", "selectedAgents", "validAgents", "methodOptions", "method", "showInstallationSummary", "scopeResult", "selectScope", "confirm", "blueConfirm", "scope", "pc", "showAvailableSkills", "initScreen", "skills", "discoverSkills", "logBar", "pc", "allAgents", "getAllAgentTypes", "installedSkills", "getAllInstalledSkillNames", "groupedSkills", "groupSkillsByCategory", "category", "categorySkills", "skill", "installedBadge", "S_BAR", "logBarEnd", "pc", "runInteractiveRemove", "global", "initScreen", "allAgents", "getAllAgentTypes", "installedSkills", "getInstalledSkillNames", "logBar", "pc", "logBarEnd", "skillsArray", "selectedSkills", "blueMultiSelectWithBack", "name", "isCancelled", "logCancelled", "selectedAgents", "buildAgentOptions", "opt", "confirm", "blueConfirm", "skillName", "results", "removeSkill", "showRemoveResults", "program", "Command", "options", "runNonInteractive", "installOptions", "runInteractiveInstall", "skills", "discoverSkills", "s", "results", "installSkills", "showInstallResults", "showAvailableSkills", "agents", "removeSkill", "showRemoveResults", "runInteractiveRemove", "allSkills", "skill", "getSkillByName", "method"]
7
7
  }
package/package.json CHANGED
@@ -1,12 +1,16 @@
1
1
  {
2
2
  "name": "@tech-leads-club/agent-skills",
3
- "version": "0.1.0-beta.2",
4
- "description": "CLI to install skills for AI coding agents",
3
+ "version": "0.1.0-beta.4",
4
+ "description": "CLI to install and manage skills for AI coding agents",
5
5
  "author": "Tech Leads Club",
6
6
  "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/tech-leads-club/agent-skills.git"
10
+ },
7
11
  "type": "module",
8
12
  "bin": {
9
- "tlc-skills": "./dist/index.js"
13
+ "tlc-skills": "./index.js"
10
14
  },
11
15
  "engines": {
12
16
  "node": ">=22"
@@ -29,8 +33,12 @@
29
33
  "dependencies": {
30
34
  "@clack/core": "^0.5.0",
31
35
  "@clack/prompts": "^0.11.0",
36
+ "@types/figlet": "1.7.0",
32
37
  "chalk": "^5.6.2",
33
38
  "commander": "^14.0.2",
39
+ "figlet": "^1.10.0",
40
+ "gradient-string": "^3.0.0",
41
+ "package-json": "^10.0.1",
34
42
  "picocolors": "^1.1.1",
35
43
  "tsx": "4.21.0",
36
44
  "@jest/globals": "30.2.0"
@@ -0,0 +1,24 @@
1
+ {
2
+ "$schema": "./categories.schema.json",
3
+ "categories": [
4
+ {
5
+ "id": "development",
6
+ "name": "Development",
7
+ "description": "Skills for software development workflows",
8
+ "priority": 1
9
+ },
10
+ {
11
+ "id": "creation",
12
+ "name": "Skill & Agent Creation",
13
+ "description": "Skills for creating new skills and subagents",
14
+ "priority": 2
15
+ }
16
+ ],
17
+ "skills": {
18
+ "spec-driven-dev": "development",
19
+ "skill-creator": "creation",
20
+ "subagent-creator": "creation",
21
+ "cursor-skill-creator": "creation",
22
+ "cursor-subagent-creator": "creation"
23
+ }
24
+ }
@@ -0,0 +1,50 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "title": "Skill Categories",
4
+ "description": "Schema for skill categories configuration",
5
+ "type": "object",
6
+ "required": [
7
+ "categories",
8
+ "skills"
9
+ ],
10
+ "properties": {
11
+ "categories": {
12
+ "type": "array",
13
+ "description": "List of available categories",
14
+ "items": {
15
+ "type": "object",
16
+ "required": [
17
+ "id",
18
+ "name"
19
+ ],
20
+ "properties": {
21
+ "id": {
22
+ "type": "string",
23
+ "description": "Unique identifier for the category (kebab-case)",
24
+ "pattern": "^[a-z][a-z0-9-]*$"
25
+ },
26
+ "name": {
27
+ "type": "string",
28
+ "description": "Display name for the category"
29
+ },
30
+ "description": {
31
+ "type": "string",
32
+ "description": "Brief description of the category"
33
+ },
34
+ "priority": {
35
+ "type": "integer",
36
+ "description": "Display order priority (lower = first)",
37
+ "minimum": 0
38
+ }
39
+ }
40
+ }
41
+ },
42
+ "skills": {
43
+ "type": "object",
44
+ "description": "Mapping of skill names to category IDs",
45
+ "additionalProperties": {
46
+ "type": "string"
47
+ }
48
+ }
49
+ }
50
+ }
package/CHANGELOG.md DELETED
@@ -1,112 +0,0 @@
1
- ## 0.1.0-beta.2 (2026-01-25)
2
-
3
- ### 🚀 Features
4
-
5
- - add .nvmrc file with Node.js version ([2b0071d](https://github.com/tech-leads-club/agent-skills/commit/2b0071d))
6
- - add TypeScript configuration for project setup ([1abc21f](https://github.com/tech-leads-club/agent-skills/commit/1abc21f))
7
- - add guide for creating AI subagents with isolated context ([0c130d8](https://github.com/tech-leads-club/agent-skills/commit/0c130d8))
8
- - add spec-driven development skill for feature planning ([dfaac3f](https://github.com/tech-leads-club/agent-skills/commit/dfaac3f))
9
- - add design, implementation, task, and validation documentation ([e5f7904](https://github.com/tech-leads-club/agent-skills/commit/e5f7904))
10
- - add skill-creator guide for effective AI agent skills ([b0b5674](https://github.com/tech-leads-club/agent-skills/commit/b0b5674))
11
- - update cursor skill creator description and name for clarity ([997b35e](https://github.com/tech-leads-club/agent-skills/commit/997b35e))
12
- - add cursor subagent creator skill for complex workflows ([6e1b6f0](https://github.com/tech-leads-club/agent-skills/commit/6e1b6f0))
13
- - implement skill installation and listing functionality ([ba9cb2c](https://github.com/tech-leads-club/agent-skills/commit/ba9cb2c))
14
- - implement interactive skill installation and listing commands ([945f255](https://github.com/tech-leads-club/agent-skills/commit/945f255))
15
- - add agent configuration and detection functionality ([b35851a](https://github.com/tech-leads-club/agent-skills/commit/b35851a))
16
- - add interactive skill installation and management prompts ([fe52459](https://github.com/tech-leads-club/agent-skills/commit/fe52459))
17
- - implement skill discovery and management functions ([4fd5139](https://github.com/tech-leads-club/agent-skills/commit/4fd5139))
18
- - add interfaces for agent configuration and skill management ([74ea8f8](https://github.com/tech-leads-club/agent-skills/commit/74ea8f8))
19
- - add TypeScript configuration for testing with Jest ([32aa9a1](https://github.com/tech-leads-club/agent-skills/commit/32aa9a1))
20
- - add TypeScript configuration for CLI package ([f23d900](https://github.com/tech-leads-club/agent-skills/commit/f23d900))
21
- - add initial CLI package configuration for agent skills ([072af1d](https://github.com/tech-leads-club/agent-skills/commit/072af1d))
22
- - add Jest configuration for CLI testing ([b7d098e](https://github.com/tech-leads-club/agent-skills/commit/b7d098e))
23
- - add release workflow for automated deployment on push ([195cad7](https://github.com/tech-leads-club/agent-skills/commit/195cad7))
24
- - add CI configuration for validating skills structure ([66fa03b](https://github.com/tech-leads-club/agent-skills/commit/66fa03b))
25
- - add TypeScript configuration for project setup ([2a7ee33](https://github.com/tech-leads-club/agent-skills/commit/2a7ee33))
26
- - add comprehensive README for agent skills documentation ([7f7063d](https://github.com/tech-leads-club/agent-skills/commit/7f7063d))
27
- - add symlink for AGENTS.md to CLAUDE.md ([a429576](https://github.com/tech-leads-club/agent-skills/commit/a429576))
28
- - add AGENTS.md for guidance on AI coding agents ([3e0917d](https://github.com/tech-leads-club/agent-skills/commit/3e0917d))
29
- - add initial configuration ([4584775](https://github.com/tech-leads-club/agent-skills/commit/4584775))
30
- - add nx configuration for project management and build processes ([c937d0e](https://github.com/tech-leads-club/agent-skills/commit/c937d0e))
31
- - add Jest configuration for project testing ([c5141b9](https://github.com/tech-leads-club/agent-skills/commit/c5141b9))
32
- - add Jest preset configuration for TypeScript testing ([df7f962](https://github.com/tech-leads-club/agent-skills/commit/df7f962))
33
- - add ESLint configuration for TypeScript with recommended rules ([7e04b65](https://github.com/tech-leads-club/agent-skills/commit/7e04b65))
34
-
35
- ### ❤️ Thank You
36
-
37
- - Felipe Rodrigues @felipfr
38
-
39
- ## 0.1.0-beta.1 (2026-01-25)
40
-
41
- ### 🚀 Features
42
-
43
- - add .nvmrc file with Node.js version ([2b0071d](https://github.com/tech-leads-club/agent-skills/commit/2b0071d))
44
- - add TypeScript configuration for project setup ([1abc21f](https://github.com/tech-leads-club/agent-skills/commit/1abc21f))
45
- - add guide for creating AI subagents with isolated context ([0c130d8](https://github.com/tech-leads-club/agent-skills/commit/0c130d8))
46
- - add spec-driven development skill for feature planning ([dfaac3f](https://github.com/tech-leads-club/agent-skills/commit/dfaac3f))
47
- - add design, implementation, task, and validation documentation ([e5f7904](https://github.com/tech-leads-club/agent-skills/commit/e5f7904))
48
- - add skill-creator guide for effective AI agent skills ([b0b5674](https://github.com/tech-leads-club/agent-skills/commit/b0b5674))
49
- - update cursor skill creator description and name for clarity ([997b35e](https://github.com/tech-leads-club/agent-skills/commit/997b35e))
50
- - add cursor subagent creator skill for complex workflows ([6e1b6f0](https://github.com/tech-leads-club/agent-skills/commit/6e1b6f0))
51
- - implement skill installation and listing functionality ([ba9cb2c](https://github.com/tech-leads-club/agent-skills/commit/ba9cb2c))
52
- - implement interactive skill installation and listing commands ([945f255](https://github.com/tech-leads-club/agent-skills/commit/945f255))
53
- - add agent configuration and detection functionality ([b35851a](https://github.com/tech-leads-club/agent-skills/commit/b35851a))
54
- - add interactive skill installation and management prompts ([fe52459](https://github.com/tech-leads-club/agent-skills/commit/fe52459))
55
- - implement skill discovery and management functions ([4fd5139](https://github.com/tech-leads-club/agent-skills/commit/4fd5139))
56
- - add interfaces for agent configuration and skill management ([74ea8f8](https://github.com/tech-leads-club/agent-skills/commit/74ea8f8))
57
- - add TypeScript configuration for testing with Jest ([32aa9a1](https://github.com/tech-leads-club/agent-skills/commit/32aa9a1))
58
- - add TypeScript configuration for CLI package ([f23d900](https://github.com/tech-leads-club/agent-skills/commit/f23d900))
59
- - add initial CLI package configuration for agent skills ([072af1d](https://github.com/tech-leads-club/agent-skills/commit/072af1d))
60
- - add Jest configuration for CLI testing ([b7d098e](https://github.com/tech-leads-club/agent-skills/commit/b7d098e))
61
- - add release workflow for automated deployment on push ([195cad7](https://github.com/tech-leads-club/agent-skills/commit/195cad7))
62
- - add CI configuration for validating skills structure ([66fa03b](https://github.com/tech-leads-club/agent-skills/commit/66fa03b))
63
- - add TypeScript configuration for project setup ([2a7ee33](https://github.com/tech-leads-club/agent-skills/commit/2a7ee33))
64
- - add comprehensive README for agent skills documentation ([7f7063d](https://github.com/tech-leads-club/agent-skills/commit/7f7063d))
65
- - add symlink for AGENTS.md to CLAUDE.md ([a429576](https://github.com/tech-leads-club/agent-skills/commit/a429576))
66
- - add AGENTS.md for guidance on AI coding agents ([3e0917d](https://github.com/tech-leads-club/agent-skills/commit/3e0917d))
67
- - add initial configuration ([4584775](https://github.com/tech-leads-club/agent-skills/commit/4584775))
68
- - add nx configuration for project management and build processes ([c937d0e](https://github.com/tech-leads-club/agent-skills/commit/c937d0e))
69
- - add Jest configuration for project testing ([c5141b9](https://github.com/tech-leads-club/agent-skills/commit/c5141b9))
70
- - add Jest preset configuration for TypeScript testing ([df7f962](https://github.com/tech-leads-club/agent-skills/commit/df7f962))
71
- - add ESLint configuration for TypeScript with recommended rules ([7e04b65](https://github.com/tech-leads-club/agent-skills/commit/7e04b65))
72
-
73
- ### ❤️ Thank You
74
-
75
- - Felipe Rodrigues @felipfr
76
-
77
- ## 0.1.0-beta.0 (2026-01-25)
78
-
79
- ### 🚀 Features
80
-
81
- - add TypeScript configuration for project setup ([1abc21f](https://github.com/tech-leads-club/agent-skills/commit/1abc21f))
82
- - add guide for creating AI subagents with isolated context ([0c130d8](https://github.com/tech-leads-club/agent-skills/commit/0c130d8))
83
- - add spec-driven development skill for feature planning ([dfaac3f](https://github.com/tech-leads-club/agent-skills/commit/dfaac3f))
84
- - add design, implementation, task, and validation documentation ([e5f7904](https://github.com/tech-leads-club/agent-skills/commit/e5f7904))
85
- - add skill-creator guide for effective AI agent skills ([b0b5674](https://github.com/tech-leads-club/agent-skills/commit/b0b5674))
86
- - update cursor skill creator description and name for clarity ([997b35e](https://github.com/tech-leads-club/agent-skills/commit/997b35e))
87
- - add cursor subagent creator skill for complex workflows ([6e1b6f0](https://github.com/tech-leads-club/agent-skills/commit/6e1b6f0))
88
- - implement skill installation and listing functionality ([ba9cb2c](https://github.com/tech-leads-club/agent-skills/commit/ba9cb2c))
89
- - implement interactive skill installation and listing commands ([945f255](https://github.com/tech-leads-club/agent-skills/commit/945f255))
90
- - add agent configuration and detection functionality ([b35851a](https://github.com/tech-leads-club/agent-skills/commit/b35851a))
91
- - add interactive skill installation and management prompts ([fe52459](https://github.com/tech-leads-club/agent-skills/commit/fe52459))
92
- - implement skill discovery and management functions ([4fd5139](https://github.com/tech-leads-club/agent-skills/commit/4fd5139))
93
- - add interfaces for agent configuration and skill management ([74ea8f8](https://github.com/tech-leads-club/agent-skills/commit/74ea8f8))
94
- - add TypeScript configuration for testing with Jest ([32aa9a1](https://github.com/tech-leads-club/agent-skills/commit/32aa9a1))
95
- - add TypeScript configuration for CLI package ([f23d900](https://github.com/tech-leads-club/agent-skills/commit/f23d900))
96
- - add initial CLI package configuration for agent skills ([072af1d](https://github.com/tech-leads-club/agent-skills/commit/072af1d))
97
- - add Jest configuration for CLI testing ([b7d098e](https://github.com/tech-leads-club/agent-skills/commit/b7d098e))
98
- - add release workflow for automated deployment on push ([195cad7](https://github.com/tech-leads-club/agent-skills/commit/195cad7))
99
- - add CI configuration for validating skills structure ([66fa03b](https://github.com/tech-leads-club/agent-skills/commit/66fa03b))
100
- - add TypeScript configuration for project setup ([2a7ee33](https://github.com/tech-leads-club/agent-skills/commit/2a7ee33))
101
- - add comprehensive README for agent skills documentation ([7f7063d](https://github.com/tech-leads-club/agent-skills/commit/7f7063d))
102
- - add symlink for AGENTS.md to CLAUDE.md ([a429576](https://github.com/tech-leads-club/agent-skills/commit/a429576))
103
- - add AGENTS.md for guidance on AI coding agents ([3e0917d](https://github.com/tech-leads-club/agent-skills/commit/3e0917d))
104
- - add initial configuration ([4584775](https://github.com/tech-leads-club/agent-skills/commit/4584775))
105
- - add nx configuration for project management and build processes ([c937d0e](https://github.com/tech-leads-club/agent-skills/commit/c937d0e))
106
- - add Jest configuration for project testing ([c5141b9](https://github.com/tech-leads-club/agent-skills/commit/c5141b9))
107
- - add Jest preset configuration for TypeScript testing ([df7f962](https://github.com/tech-leads-club/agent-skills/commit/df7f962))
108
- - add ESLint configuration for TypeScript with recommended rules ([7e04b65](https://github.com/tech-leads-club/agent-skills/commit/7e04b65))
109
-
110
- ### ❤️ Thank You
111
-
112
- - Felipe Rodrigues @felipfr