skillctl 0.0.3
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/.github/workflows/release.yml +42 -0
- package/BOOTSTRAP.md +308 -0
- package/Cargo.toml +25 -0
- package/EXAMPLES.md +236 -0
- package/LICENSE +71 -0
- package/README.md +236 -0
- package/bin/run.js +20 -0
- package/package.json +22 -0
- package/scripts/install.js +72 -0
- package/src/main.rs +237 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*' # Se activa cuando subes un tag como v0.0.1
|
|
7
|
+
permissions:
|
|
8
|
+
contents: write
|
|
9
|
+
jobs:
|
|
10
|
+
build:
|
|
11
|
+
name: Build for ${{ matrix.os }}
|
|
12
|
+
runs-on: ${{ matrix.os }}
|
|
13
|
+
strategy:
|
|
14
|
+
matrix:
|
|
15
|
+
include:
|
|
16
|
+
- os: ubuntu-latest
|
|
17
|
+
artifact_name: skillctl
|
|
18
|
+
asset_name: skillctl-linux
|
|
19
|
+
- os: macos-latest
|
|
20
|
+
artifact_name: skillctl
|
|
21
|
+
asset_name: skillctl-macos
|
|
22
|
+
- os: windows-latest
|
|
23
|
+
artifact_name: skillctl.exe
|
|
24
|
+
asset_name: skillctl-win.exe
|
|
25
|
+
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v3
|
|
28
|
+
|
|
29
|
+
- name: Install Rust
|
|
30
|
+
uses: dtolnay/rust-toolchain@stable
|
|
31
|
+
|
|
32
|
+
- name: Build
|
|
33
|
+
run: cargo build --release --verbose
|
|
34
|
+
|
|
35
|
+
- name: Upload binaries to Release
|
|
36
|
+
uses: svenstaro/upload-release-action@v2
|
|
37
|
+
with:
|
|
38
|
+
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
|
39
|
+
file: target/release/${{ matrix.artifact_name }}
|
|
40
|
+
asset_name: ${{ matrix.asset_name }}
|
|
41
|
+
tag: ${{ github.ref }}
|
|
42
|
+
overwrite: true
|
package/BOOTSTRAP.md
ADDED
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
# Guía de Bootstrap: Primera Publicación
|
|
2
|
+
|
|
3
|
+
Esta guía te ayudará a publicar la primera versión del proyecto y resolver el problema del "huevo y la gallina".
|
|
4
|
+
|
|
5
|
+
## 🎯 Objetivo
|
|
6
|
+
|
|
7
|
+
Publicar la versión `v0.0.1` del proyecto para que los usuarios puedan ejecutar:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx skillctl init
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## 📋 Pre-requisitos
|
|
14
|
+
|
|
15
|
+
- [x] Cuenta de GitHub
|
|
16
|
+
- [x] Cuenta de NPM (crear en https://www.npmjs.com/signup)
|
|
17
|
+
- [x] Rust instalado (`curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh`)
|
|
18
|
+
- [x] Node.js instalado
|
|
19
|
+
- [x] Git configurado
|
|
20
|
+
|
|
21
|
+
## 🚀 Pasos para la Primera Publicación
|
|
22
|
+
|
|
23
|
+
### Paso 1: Compilar el Binario Rust
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# Asegúrate de estar en la raíz del proyecto
|
|
27
|
+
cd /home/clasing/proyects/umibu/agent-skill
|
|
28
|
+
|
|
29
|
+
# Compilar en modo release
|
|
30
|
+
cargo build --release
|
|
31
|
+
|
|
32
|
+
# Verificar que el binario se creó correctamente
|
|
33
|
+
ls -lh target/release/skill-cli
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**Resultado esperado:**
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
-rwxr-xr-x 1 user user 3.2M Feb 8 22:30 target/release/skillctl
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Paso 2: Probar el Binario Localmente
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# Ejecutar el binario directamente
|
|
46
|
+
./target/release/skillctl --help
|
|
47
|
+
|
|
48
|
+
# Probar el comando init
|
|
49
|
+
./target/release/skillctl init
|
|
50
|
+
|
|
51
|
+
# Verificar que se creó skills.toml
|
|
52
|
+
cat skills.toml
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Paso 3: Preparar el Repositorio
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Asegúrate de que todos los cambios están commiteados
|
|
59
|
+
git status
|
|
60
|
+
|
|
61
|
+
# Si hay cambios pendientes:
|
|
62
|
+
git add .
|
|
63
|
+
git commit -m "Prepare for v0.0.1 release"
|
|
64
|
+
|
|
65
|
+
# Subir a GitHub
|
|
66
|
+
git push origin main
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Paso 4: Crear el Release en GitHub (CRÍTICO)
|
|
70
|
+
|
|
71
|
+
Este es el paso más importante. **Sin este paso, el script de NPM no podrá descargar el binario.**
|
|
72
|
+
|
|
73
|
+
#### Opción A: Manual (Recomendado para la primera vez)
|
|
74
|
+
|
|
75
|
+
1. Ve a tu repositorio: https://github.com/joeldevz/agent-skill
|
|
76
|
+
2. Click en "Releases" (en la barra lateral derecha)
|
|
77
|
+
3. Click en "Draft a new release"
|
|
78
|
+
4. Completa el formulario:
|
|
79
|
+
- **Tag version:** `v0.0.1`
|
|
80
|
+
- **Release title:** `v0.0.1 - Initial Release`
|
|
81
|
+
- **Description:**
|
|
82
|
+
|
|
83
|
+
````markdown
|
|
84
|
+
## 🎉 Primera versión de Skill CLI Tool
|
|
85
|
+
|
|
86
|
+
Gestor de Skills para Agentes de IA.
|
|
87
|
+
|
|
88
|
+
### Características
|
|
89
|
+
|
|
90
|
+
- ✅ Comando `init` para inicializar proyectos
|
|
91
|
+
- ✅ Comando `list` para listar skills
|
|
92
|
+
- ✅ Soporte para Cursor, Antigravity y VSCode
|
|
93
|
+
|
|
94
|
+
### Instalación
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
npx skillctl init
|
|
98
|
+
```
|
|
99
|
+
````
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
5. **IMPORTANTE: Subir los binarios**
|
|
106
|
+
- Click en "Attach binaries by dropping them here or selecting them"
|
|
107
|
+
- Sube el archivo: `target/release/skillctl`
|
|
108
|
+
- **RENOMBRA el archivo a:** `skillctl-linux` (sin extensión)
|
|
109
|
+
|
|
110
|
+
> **Nota:** Para Windows y macOS, necesitarás compilar en esas plataformas o usar GitHub Actions (ver Opción B)
|
|
111
|
+
|
|
112
|
+
6. Click en "Publish release"
|
|
113
|
+
|
|
114
|
+
#### Opción B: Automático con GitHub Actions
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
# Crear y subir el tag
|
|
118
|
+
git tag v0.0.1
|
|
119
|
+
git push origin v0.0.1
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Esto activará el workflow `.github/workflows/release.yml` que:
|
|
123
|
+
|
|
124
|
+
1. Compilará el binario en Linux, Windows y macOS
|
|
125
|
+
2. Subirá automáticamente los binarios al release
|
|
126
|
+
|
|
127
|
+
**Espera a que termine el workflow** (ve a la pestaña "Actions" en GitHub)
|
|
128
|
+
|
|
129
|
+
### Paso 5: Verificar que el Release está Correcto
|
|
130
|
+
|
|
131
|
+
1. Ve a: https://github.com/joeldevz/agent-skill/releases/tag/v0.0.1
|
|
132
|
+
2. Verifica que aparezcan los binarios:
|
|
133
|
+
- `skill-cli-linux`
|
|
134
|
+
- `skill-cli-win.exe` (si usaste GitHub Actions)
|
|
135
|
+
- `skill-cli-macos` (si usaste GitHub Actions)
|
|
136
|
+
|
|
137
|
+
3. **Prueba la URL de descarga:**
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
# Debería descargar el binario (no dar error 404)
|
|
141
|
+
curl -L https://github.com/joeldevz/agent-skill/releases/download/v0.0.1/skillctl-linux -o test-binary
|
|
142
|
+
|
|
143
|
+
# Verificar que se descargó
|
|
144
|
+
ls -lh test-binary
|
|
145
|
+
|
|
146
|
+
# Limpiar
|
|
147
|
+
rm test-binary
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Paso 6: Probar el Script de Instalación NPM
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
# Probar el script de descarga
|
|
154
|
+
node scripts/install.js
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**Resultado esperado:**
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
⬇️ Descargando skillctl desde: https://github.com/joeldevz/agent-skill/releases/download/v0.0.1/skillctl-linux
|
|
161
|
+
✅ Instalación completada.
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**Verificar:**
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
ls -lh bin/skillctl
|
|
168
|
+
# Debería mostrar el binario descargado
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Paso 7: Probar el Wrapper Completo
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
# Probar el wrapper de Node.js
|
|
175
|
+
node bin/run.js --help
|
|
176
|
+
node bin/run.js init
|
|
177
|
+
node bin/run.js list
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Paso 8: Publicar en NPM
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
# Login en NPM (primera vez)
|
|
184
|
+
npm login
|
|
185
|
+
# Introduce tu usuario, contraseña y email
|
|
186
|
+
|
|
187
|
+
# Verificar que estás logueado
|
|
188
|
+
npm whoami
|
|
189
|
+
|
|
190
|
+
# Publicar el paquete
|
|
191
|
+
npm publish
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**Resultado esperado:**
|
|
195
|
+
|
|
196
|
+
```
|
|
197
|
+
+ skillctl@0.0.1
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Paso 9: Probar la Instalación desde NPM
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
# Crear una carpeta de prueba
|
|
204
|
+
mkdir /tmp/test-skill-cli
|
|
205
|
+
cd /tmp/test-skill-cli
|
|
206
|
+
|
|
207
|
+
# Probar con npx (sin instalar)
|
|
208
|
+
npx skillctl init
|
|
209
|
+
|
|
210
|
+
# Verificar que funcionó
|
|
211
|
+
ls -la
|
|
212
|
+
# Debería mostrar skills.toml y .cursor/
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## ✅ Checklist de Verificación
|
|
216
|
+
|
|
217
|
+
- [ ] Binario compilado correctamente
|
|
218
|
+
- [ ] Release v0.0.1 creado en GitHub
|
|
219
|
+
- [ ] Binarios subidos al release (al menos Linux)
|
|
220
|
+
- [ ] URL de descarga funciona (no da 404)
|
|
221
|
+
- [ ] Script `install.js` descarga correctamente
|
|
222
|
+
- [ ] Wrapper `run.js` ejecuta el binario
|
|
223
|
+
- [ ] Publicado en NPM
|
|
224
|
+
- [ ] `npx skill-cli-tool init` funciona
|
|
225
|
+
|
|
226
|
+
## 🐛 Troubleshooting
|
|
227
|
+
|
|
228
|
+
### Error: "404 Not Found" al descargar
|
|
229
|
+
|
|
230
|
+
**Causa:** El release no existe o los binarios no están subidos.
|
|
231
|
+
|
|
232
|
+
**Solución:**
|
|
233
|
+
|
|
234
|
+
1. Verifica que el release existe: https://github.com/joeldevz/agent-skill/releases
|
|
235
|
+
2. Verifica que el tag es exactamente `v0.0.1`
|
|
236
|
+
3. Verifica que el binario se llama exactamente `skillctl-linux`
|
|
237
|
+
|
|
238
|
+
### Error: "Permission denied" al ejecutar el binario
|
|
239
|
+
|
|
240
|
+
**Causa:** El binario no tiene permisos de ejecución.
|
|
241
|
+
|
|
242
|
+
**Solución:**
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
chmod +x bin/skillctl
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Error: "Package name already exists" en NPM
|
|
249
|
+
|
|
250
|
+
**Causa:** El nombre `skill-cli-tool` ya está tomado.
|
|
251
|
+
|
|
252
|
+
**Solución:**
|
|
253
|
+
|
|
254
|
+
1. Cambia el nombre en `package.json`:
|
|
255
|
+
```json
|
|
256
|
+
"name": "@tu-usuario/skillctl"
|
|
257
|
+
```
|
|
258
|
+
2. Publica de nuevo:
|
|
259
|
+
```bash
|
|
260
|
+
npm publish --access public
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### Error: "GITHUB_TOKEN" en GitHub Actions
|
|
264
|
+
|
|
265
|
+
**Causa:** El token no tiene permisos suficientes.
|
|
266
|
+
|
|
267
|
+
**Solución:**
|
|
268
|
+
|
|
269
|
+
1. Ve a Settings → Actions → General
|
|
270
|
+
2. En "Workflow permissions", selecciona "Read and write permissions"
|
|
271
|
+
3. Guarda y vuelve a ejecutar el workflow
|
|
272
|
+
|
|
273
|
+
## 🎉 ¡Éxito!
|
|
274
|
+
|
|
275
|
+
Si llegaste aquí, tu proyecto está publicado y funcionando. Los usuarios ahora pueden ejecutar:
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
npx skillctl init
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
## 📚 Próximos Pasos
|
|
282
|
+
|
|
283
|
+
1. **Implementar el comando `add`** para añadir skills
|
|
284
|
+
2. **Añadir tests** para asegurar calidad
|
|
285
|
+
3. **Mejorar la documentación** con más ejemplos
|
|
286
|
+
4. **Crear un video tutorial** de uso
|
|
287
|
+
5. **Compartir en redes sociales** y comunidades
|
|
288
|
+
|
|
289
|
+
## 🔄 Para Futuras Versiones
|
|
290
|
+
|
|
291
|
+
Cuando quieras publicar `v0.0.2`:
|
|
292
|
+
|
|
293
|
+
1. Actualiza las versiones:
|
|
294
|
+
- `Cargo.toml`: `version = "0.0.2"`
|
|
295
|
+
- `package.json`: `"version": "0.0.2"`
|
|
296
|
+
- `scripts/install.js`: `const VERSION = "v0.0.2"`
|
|
297
|
+
|
|
298
|
+
2. Compila y publica:
|
|
299
|
+
```bash
|
|
300
|
+
cargo build --release
|
|
301
|
+
git add .
|
|
302
|
+
git commit -m "Bump version to 0.0.2"
|
|
303
|
+
git tag v0.0.2
|
|
304
|
+
git push origin main --tags
|
|
305
|
+
npm publish
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
El workflow de GitHub Actions se encargará del resto automáticamente.
|
package/Cargo.toml
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "skillctl"
|
|
3
|
+
version = "0.0.3"
|
|
4
|
+
edition = "2021"
|
|
5
|
+
authors = ["Your Name <your.email@example.com>"]
|
|
6
|
+
description = "Gestor de Skills para Agentes de IA"
|
|
7
|
+
license-file = "LICENSE"
|
|
8
|
+
|
|
9
|
+
[[bin]]
|
|
10
|
+
name = "skillctl"
|
|
11
|
+
path = "src/main.rs"
|
|
12
|
+
|
|
13
|
+
[dependencies]
|
|
14
|
+
clap = { version = "4.5", features = ["derive"] }
|
|
15
|
+
serde = { version = "1.0", features = ["derive"] }
|
|
16
|
+
toml = "0.8"
|
|
17
|
+
anyhow = "1.0"
|
|
18
|
+
reqwest = { version = "0.11", features = ["blocking", "json"] }
|
|
19
|
+
tokio = { version = "1.35", features = ["full"] }
|
|
20
|
+
|
|
21
|
+
[profile.release]
|
|
22
|
+
opt-level = "z" # Optimizar para tamaño
|
|
23
|
+
lto = true # Link Time Optimization
|
|
24
|
+
codegen-units = 1 # Mejor optimización
|
|
25
|
+
strip = true # Eliminar símbolos de debug
|
package/EXAMPLES.md
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
# Ejemplo de Uso: Skillctl
|
|
2
|
+
|
|
3
|
+
## Escenario: Configurar un Proyecto Nuevo
|
|
4
|
+
|
|
5
|
+
### 1. Inicializar el Proyecto
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Crear una nueva carpeta para tu proyecto
|
|
9
|
+
mkdir mi-proyecto-ia
|
|
10
|
+
cd mi-proyecto-ia
|
|
11
|
+
|
|
12
|
+
# Inicializar el gestor de skills
|
|
13
|
+
npx skill-cli-tool init
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
**Resultado:**
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
✅ Proyecto inicializado. Se ha creado 'skills.toml'.
|
|
20
|
+
🚀 Prueba ahora: npx skillctl add <url> --skill <nombre>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**Archivos creados:**
|
|
24
|
+
|
|
25
|
+
- `skills.toml` - Manifiesto de skills
|
|
26
|
+
- `.cursor/skills/` - Carpeta para skills descargadas
|
|
27
|
+
|
|
28
|
+
### 2. Añadir Skills
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# Añadir skill de TypeScript
|
|
32
|
+
npx skillctl add https://github.com/wshobson/agents --skill typescript
|
|
33
|
+
|
|
34
|
+
# Añadir skill de Python
|
|
35
|
+
npx skillctl add https://github.com/wshobson/agents --skill python
|
|
36
|
+
|
|
37
|
+
# Añadir skill personalizada
|
|
38
|
+
npx skillctl add https://github.com/tu-usuario/tu-repo --skill custom-skill
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### 3. Ver Skills Instaladas
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npx agent-skill list
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Resultado:**
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
📦 Skills instaladas (2):
|
|
51
|
+
• typescript (https://github.com/wshobson/agents)
|
|
52
|
+
└─ Branch: main | Path: .cursor/skills/typescript/SKILL.md
|
|
53
|
+
• python (https://github.com/wshobson/agents)
|
|
54
|
+
└─ Branch: main | Path: .cursor/skills/python/SKILL.md
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 4. Sincronizar con Editores
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# Sincronizar con Cursor
|
|
61
|
+
npx agent-skill sync --editors cursor
|
|
62
|
+
|
|
63
|
+
# Sincronizar con múltiples editores
|
|
64
|
+
npx agent-skill sync --editors cursor,antigravity,vscode
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Archivos generados:**
|
|
68
|
+
|
|
69
|
+
- `.cursorrules` - Configuración para Cursor
|
|
70
|
+
- `.antigravity` - Configuración para Antigravity
|
|
71
|
+
- `.github/copilot-instructions.md` - Instrucciones para GitHub Copilot
|
|
72
|
+
|
|
73
|
+
### 5. Actualizar Skills
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# Actualizar todas las skills a sus últimas versiones
|
|
77
|
+
npx agent-skill update
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Resultado:**
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
🔄 Buscando actualizaciones para 2 skills...
|
|
84
|
+
⬇️ Actualizando typescript...
|
|
85
|
+
⬇️ Actualizando python...
|
|
86
|
+
✅ Todas las skills están al día.
|
|
87
|
+
✅ .cursorrules actualizado.
|
|
88
|
+
✅ .antigravity actualizado.
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Estructura del Proyecto Resultante
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
mi-proyecto-ia/
|
|
95
|
+
├── .cursor/
|
|
96
|
+
│ └── skills/
|
|
97
|
+
│ ├── typescript/
|
|
98
|
+
│ │ └── SKILL.md
|
|
99
|
+
│ └── python/
|
|
100
|
+
│ └── SKILL.md
|
|
101
|
+
├── .github/
|
|
102
|
+
│ └── copilot-instructions.md
|
|
103
|
+
├── .cursorrules
|
|
104
|
+
├── .antigravity
|
|
105
|
+
└── skills.toml
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Contenido de `skills.toml`
|
|
109
|
+
|
|
110
|
+
```toml
|
|
111
|
+
# Manifiesto de Skills
|
|
112
|
+
version = "1.0"
|
|
113
|
+
|
|
114
|
+
[skills.typescript]
|
|
115
|
+
url = "https://github.com/wshobson/agents"
|
|
116
|
+
branch = "main"
|
|
117
|
+
local_path = ".cursor/skills/typescript/SKILL.md"
|
|
118
|
+
last_updated = "2026-02-08T22:30:00Z"
|
|
119
|
+
|
|
120
|
+
[skills.python]
|
|
121
|
+
url = "https://github.com/wshobson/agents"
|
|
122
|
+
branch = "main"
|
|
123
|
+
local_path = ".cursor/skills/python/SKILL.md"
|
|
124
|
+
last_updated = "2026-02-08T22:30:00Z"
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Integración con Cursor
|
|
128
|
+
|
|
129
|
+
Una vez sincronizado, Cursor automáticamente:
|
|
130
|
+
|
|
131
|
+
1. Lee el archivo `.cursorrules`
|
|
132
|
+
2. Carga las skills referenciadas
|
|
133
|
+
3. Usa las instrucciones de las skills en sus respuestas
|
|
134
|
+
|
|
135
|
+
**Ejemplo de `.cursorrules` generado:**
|
|
136
|
+
|
|
137
|
+
```markdown
|
|
138
|
+
# Rules generadas por Skillctl
|
|
139
|
+
|
|
140
|
+
## Skill: typescript
|
|
141
|
+
|
|
142
|
+
Reference: .cursor/skills/typescript/SKILL.md
|
|
143
|
+
|
|
144
|
+
## Skill: python
|
|
145
|
+
|
|
146
|
+
Reference: .cursor/skills/python/SKILL.md
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Flujo de Trabajo Diario
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
# Mañana: Actualizar skills
|
|
153
|
+
npx skillctl update
|
|
154
|
+
|
|
155
|
+
# Durante el día: Añadir nueva skill si es necesario
|
|
156
|
+
npx skillctl add <url> --skill <nombre>
|
|
157
|
+
|
|
158
|
+
# Verificar configuración
|
|
159
|
+
npx skillctl list
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Compartir Configuración con el Equipo
|
|
163
|
+
|
|
164
|
+
1. **Commitear `skills.toml`** al repositorio:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
git add skills.toml
|
|
168
|
+
git commit -m "Add skill configuration"
|
|
169
|
+
git push
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
2. **Otros miembros del equipo** solo necesitan:
|
|
173
|
+
```bash
|
|
174
|
+
git pull
|
|
175
|
+
npx agent-skill update # Descarga todas las skills del manifiesto
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Troubleshooting
|
|
179
|
+
|
|
180
|
+
### Problema: "El binario no se encuentra"
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
# Solución: Reinstalar el paquete
|
|
184
|
+
npm install --force skill-cli-tool
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Problema: "No se encontró skills.toml"
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
# Solución: Inicializar el proyecto
|
|
191
|
+
npx skill-cli-tool init
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Problema: Skills desactualizadas
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
# Solución: Forzar actualización
|
|
198
|
+
npx skill-cli-tool update
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Casos de Uso Avanzados
|
|
202
|
+
|
|
203
|
+
### Usar diferentes branches
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
# Editar skills.toml manualmente
|
|
207
|
+
[skills.typescript-beta]
|
|
208
|
+
url = "https://github.com/wshobson/agents"
|
|
209
|
+
branch = "beta" # <-- Cambiar branch
|
|
210
|
+
local_path = ".cursor/skills/typescript-beta/SKILL.md"
|
|
211
|
+
last_updated = "2026-02-08T22:30:00Z"
|
|
212
|
+
|
|
213
|
+
# Actualizar
|
|
214
|
+
npx skill-cli-tool update
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Crear skills personalizadas
|
|
218
|
+
|
|
219
|
+
1. Crear un repositorio con la estructura:
|
|
220
|
+
|
|
221
|
+
```
|
|
222
|
+
mi-skill/
|
|
223
|
+
└── SKILL.md
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
2. Añadir la skill:
|
|
227
|
+
```bash
|
|
228
|
+
npx skill-cli-tool add https://github.com/mi-usuario/mi-skill --skill mi-skill
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Próximos Pasos
|
|
232
|
+
|
|
233
|
+
- Explorar skills disponibles en GitHub
|
|
234
|
+
- Crear tus propias skills personalizadas
|
|
235
|
+
- Compartir configuración con tu equipo
|
|
236
|
+
- Automatizar actualizaciones en CI/CD
|
package/LICENSE
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
LICENCIA DE SOFTWARE PROPIETARIO
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Skill CLI Tool. Todos los derechos reservados.
|
|
4
|
+
|
|
5
|
+
TÉRMINOS Y CONDICIONES DE USO
|
|
6
|
+
|
|
7
|
+
1. CONCESIÓN DE LICENCIA LIMITADA
|
|
8
|
+
|
|
9
|
+
Se concede una licencia limitada, no exclusiva, no transferible y revocable
|
|
10
|
+
para usar este software únicamente para fines personales y no comerciales.
|
|
11
|
+
|
|
12
|
+
2. RESTRICCIONES
|
|
13
|
+
|
|
14
|
+
NO está permitido:
|
|
15
|
+
|
|
16
|
+
a) Usar este software con fines comerciales sin autorización escrita explícita
|
|
17
|
+
b) Modificar, adaptar, traducir o crear obras derivadas del software
|
|
18
|
+
c) Realizar ingeniería inversa, descompilar o desensamblar el software
|
|
19
|
+
d) Redistribuir, sublicenciar, vender, alquilar o prestar el software
|
|
20
|
+
e) Eliminar o alterar avisos de derechos de autor o marcas comerciales
|
|
21
|
+
f) Publicar o compartir el código fuente sin autorización explícita
|
|
22
|
+
g) Usar el software para crear productos o servicios competidores
|
|
23
|
+
|
|
24
|
+
3. USO COMERCIAL
|
|
25
|
+
|
|
26
|
+
Cualquier uso comercial de este software requiere una licencia comercial
|
|
27
|
+
separada. Para obtener una licencia comercial, contacte al titular de los
|
|
28
|
+
derechos de autor.
|
|
29
|
+
|
|
30
|
+
4. PROPIEDAD INTELECTUAL
|
|
31
|
+
|
|
32
|
+
Este software y todos los derechos de propiedad intelectual asociados son
|
|
33
|
+
y permanecerán como propiedad exclusiva del titular de los derechos de autor.
|
|
34
|
+
No se transfiere ningún derecho de propiedad mediante esta licencia.
|
|
35
|
+
|
|
36
|
+
5. CONTRIBUCIONES
|
|
37
|
+
|
|
38
|
+
Cualquier contribución al proyecto se considerará cedida al titular de los
|
|
39
|
+
derechos de autor bajo los mismos términos restrictivos de esta licencia.
|
|
40
|
+
|
|
41
|
+
6. TERMINACIÓN
|
|
42
|
+
|
|
43
|
+
Esta licencia se revocará automáticamente si incumple cualquiera de estos
|
|
44
|
+
términos. Al terminar, debe cesar todo uso del software y destruir todas
|
|
45
|
+
las copias en su posesión.
|
|
46
|
+
|
|
47
|
+
7. GARANTÍA LIMITADA
|
|
48
|
+
|
|
49
|
+
ESTE SOFTWARE SE PROPORCIONA "TAL CUAL", SIN GARANTÍA DE NINGÚN TIPO,
|
|
50
|
+
EXPRESA O IMPLÍCITA, INCLUYENDO PERO NO LIMITADO A GARANTÍAS DE
|
|
51
|
+
COMERCIABILIDAD, IDONEIDAD PARA UN PROPÓSITO PARTICULAR Y NO INFRACCIÓN.
|
|
52
|
+
|
|
53
|
+
8. LIMITACIÓN DE RESPONSABILIDAD
|
|
54
|
+
|
|
55
|
+
EN NINGÚN CASO EL TITULAR DE LOS DERECHOS DE AUTOR SERÁ RESPONSABLE DE
|
|
56
|
+
NINGÚN RECLAMO, DAÑO U OTRA RESPONSABILIDAD, YA SEA EN UNA ACCIÓN DE
|
|
57
|
+
CONTRATO, AGRAVIO O DE OTRO MODO, QUE SURJA DE, FUERA DE O EN CONEXIÓN
|
|
58
|
+
CON EL SOFTWARE O EL USO U OTROS TRATOS EN EL SOFTWARE.
|
|
59
|
+
|
|
60
|
+
9. LEY APLICABLE
|
|
61
|
+
|
|
62
|
+
Esta licencia se regirá e interpretará de acuerdo con las leyes aplicables,
|
|
63
|
+
sin tener en cuenta sus disposiciones sobre conflictos de leyes.
|
|
64
|
+
|
|
65
|
+
10. CONTACTO PARA LICENCIAS COMERCIALES
|
|
66
|
+
|
|
67
|
+
Para consultas sobre licencias comerciales o permisos especiales:
|
|
68
|
+
Email: [TU_EMAIL_AQUI]
|
|
69
|
+
Web: [TU_WEB_AQUI]
|
|
70
|
+
|
|
71
|
+
Al usar este software, usted acepta estar sujeto a los términos de esta licencia.
|
package/README.md
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
# Skillctl: Agent Skill Manager
|
|
2
|
+
|
|
3
|
+
Gestor de Skills para Agentes de IA (Cursor, Antigravity, VSCode Copilot)
|
|
4
|
+
|
|
5
|
+
## 🚀 Inicio Rápido para Usuarios
|
|
6
|
+
|
|
7
|
+
### Instalación y Uso
|
|
8
|
+
|
|
9
|
+
No necesitas instalar nada globalmente. Simplemente usa `npx`:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# 1. Inicializar un nuevo proyecto
|
|
13
|
+
npx skillctl init
|
|
14
|
+
|
|
15
|
+
# 2. Añadir una skill
|
|
16
|
+
npx skillctl add https://github.com/wshobson/agents --skill typescript
|
|
17
|
+
|
|
18
|
+
# 3. Listar skills instaladas
|
|
19
|
+
npx skillctl list
|
|
20
|
+
|
|
21
|
+
# 4. Actualizar todas las skills
|
|
22
|
+
npx skillctl update
|
|
23
|
+
|
|
24
|
+
# 5. Sincronizar con editores
|
|
25
|
+
npx skillctl sync --editors cursor,antigravity
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## 🔧 Desarrollo: Ciclo de Vida del Proyecto
|
|
29
|
+
|
|
30
|
+
### Estructura del Proyecto
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
agent-skill/
|
|
34
|
+
├── src/ # Código Rust
|
|
35
|
+
│ └── main.rs
|
|
36
|
+
├── bin/ # Wrapper Node.js
|
|
37
|
+
│ └── run.js
|
|
38
|
+
├── scripts/ # Scripts de instalación
|
|
39
|
+
│ └── install.js
|
|
40
|
+
├── Cargo.toml # Configuración Rust
|
|
41
|
+
└── package.json # Configuración NPM
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Paso 1: Compilar el Binario Rust
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# Instalar Rust si no lo tienes
|
|
48
|
+
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
|
49
|
+
|
|
50
|
+
# Compilar en modo release
|
|
51
|
+
cargo build --release
|
|
52
|
+
|
|
53
|
+
# El binario estará en: target/release/skillctl
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Paso 2: Crear el Release en GitHub (Primera vez)
|
|
57
|
+
|
|
58
|
+
1. **Asegúrate de que `Cargo.toml` tenga la versión `0.0.1`**
|
|
59
|
+
2. **Compila el binario** (paso anterior)
|
|
60
|
+
3. **Sube tus cambios a GitHub:**
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
git add .
|
|
64
|
+
git commit -m "Initial release v0.0.1"
|
|
65
|
+
git push origin main
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
4. **Crea el Release en GitHub:**
|
|
69
|
+
- Ve a tu repositorio en GitHub
|
|
70
|
+
- Click en "Releases" → "Draft a new release"
|
|
71
|
+
- Tag: `v0.0.1`
|
|
72
|
+
- Title: `v0.0.1 - Initial Release`
|
|
73
|
+
- **Sube los binarios compilados:**
|
|
74
|
+
- `target/release/skillctl` → Renombrar a `skillctl-linux`
|
|
75
|
+
- Para Windows: `target/release/skillctl.exe` → Renombrar a `skillctl-win.exe`
|
|
76
|
+
- Para macOS: compilar en Mac y renombrar a `skillctl-macos`
|
|
77
|
+
- Publica la Release
|
|
78
|
+
|
|
79
|
+
### Paso 3: Probar la Descarga Localmente
|
|
80
|
+
|
|
81
|
+
Antes de publicar en NPM, prueba que el script de descarga funciona:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# Ejecutar el script de instalación manualmente
|
|
85
|
+
node scripts/install.js
|
|
86
|
+
|
|
87
|
+
# Verificar que se descargó el binario
|
|
88
|
+
ls -la bin/
|
|
89
|
+
|
|
90
|
+
# Probar el comando
|
|
91
|
+
node bin/run.js init
|
|
92
|
+
node bin/run.js list
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Paso 4: Publicar en NPM
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# Login en NPM (primera vez)
|
|
99
|
+
npm login
|
|
100
|
+
|
|
101
|
+
# Publicar el paquete
|
|
102
|
+
npm publish
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Paso 5: Automatización con GitHub Actions
|
|
106
|
+
|
|
107
|
+
El archivo `.github/workflows/release.yml` automatiza la compilación y publicación:
|
|
108
|
+
|
|
109
|
+
```yaml
|
|
110
|
+
name: Release
|
|
111
|
+
|
|
112
|
+
on:
|
|
113
|
+
push:
|
|
114
|
+
tags:
|
|
115
|
+
- "v*"
|
|
116
|
+
|
|
117
|
+
jobs:
|
|
118
|
+
build:
|
|
119
|
+
strategy:
|
|
120
|
+
matrix:
|
|
121
|
+
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
122
|
+
runs-on: ${{ matrix.os }}
|
|
123
|
+
|
|
124
|
+
steps:
|
|
125
|
+
- uses: actions/checkout@v3
|
|
126
|
+
|
|
127
|
+
- name: Install Rust
|
|
128
|
+
uses: actions-rs/toolchain@v1
|
|
129
|
+
with:
|
|
130
|
+
toolchain: stable
|
|
131
|
+
|
|
132
|
+
- name: Build
|
|
133
|
+
run: cargo build --release
|
|
134
|
+
|
|
135
|
+
- name: Upload Release Asset
|
|
136
|
+
uses: actions/upload-release-asset@v1
|
|
137
|
+
env:
|
|
138
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
139
|
+
with:
|
|
140
|
+
upload_url: ${{ github.event.release.upload_url }}
|
|
141
|
+
asset_path: ./target/release/skill-cli${{ matrix.os == 'windows-latest' && '.exe' || '' }}
|
|
142
|
+
asset_name: skill-cli-${{ matrix.os == 'ubuntu-latest' && 'linux' || matrix.os == 'windows-latest' && 'win.exe' || 'macos' }}
|
|
143
|
+
asset_content_type: application/octet-stream
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## 🔄 Flujo de Actualización de Versiones
|
|
147
|
+
|
|
148
|
+
1. **Actualiza la versión en ambos archivos:**
|
|
149
|
+
- `Cargo.toml`: `version = "0.0.2"`
|
|
150
|
+
- `package.json`: `"version": "0.0.2"`
|
|
151
|
+
- `scripts/install.js`: `const VERSION = "v0.0.2"`
|
|
152
|
+
|
|
153
|
+
2. **Compila y crea el tag:**
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
cargo build --release
|
|
157
|
+
git add .
|
|
158
|
+
git commit -m "Bump version to 0.0.2"
|
|
159
|
+
git tag v0.0.2
|
|
160
|
+
git push origin main --tags
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
3. **Crea el Release en GitHub** (o usa GitHub Actions)
|
|
164
|
+
|
|
165
|
+
4. **Publica en NPM:**
|
|
166
|
+
```bash
|
|
167
|
+
npm publish
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## 📦 Comandos Disponibles
|
|
171
|
+
|
|
172
|
+
| Comando | Descripción |
|
|
173
|
+
| ---------------------------- | ----------------------------------------------------- |
|
|
174
|
+
| `init` | Inicializa un nuevo proyecto (crea `skills.toml`) |
|
|
175
|
+
| `add <url> --skill <nombre>` | Añade una nueva skill |
|
|
176
|
+
| `list` | Lista todas las skills instaladas |
|
|
177
|
+
| `update` | Actualiza todas las skills desde sus URLs |
|
|
178
|
+
| `sync --editors <lista>` | Sincroniza con editores (cursor, antigravity, vscode) |
|
|
179
|
+
|
|
180
|
+
## 🛠️ Desarrollo Local
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
# Compilar en modo desarrollo
|
|
184
|
+
cargo build
|
|
185
|
+
|
|
186
|
+
# Ejecutar directamente
|
|
187
|
+
cargo run -- init
|
|
188
|
+
cargo run -- list
|
|
189
|
+
|
|
190
|
+
# Probar el wrapper NPM
|
|
191
|
+
node bin/run.js init
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## 📝 Notas Importantes
|
|
195
|
+
|
|
196
|
+
- **El binario debe estar en GitHub Releases** antes de que el script de NPM pueda descargarlo
|
|
197
|
+
- **La versión en `scripts/install.js`** debe coincidir con el tag de GitHub
|
|
198
|
+
- **Los nombres de los binarios** deben seguir el formato: `skill-cli-{platform}.exe`
|
|
199
|
+
- Linux: `skill-cli-linux`
|
|
200
|
+
- Windows: `skill-cli-win.exe`
|
|
201
|
+
- macOS: `skill-cli-macos`
|
|
202
|
+
|
|
203
|
+
## 🤝 Contribuir
|
|
204
|
+
|
|
205
|
+
**IMPORTANTE:** Este es un proyecto de código propietario. Las contribuciones están sujetas a términos especiales:
|
|
206
|
+
|
|
207
|
+
1. Todas las contribuciones se considerarán cedidas al titular de los derechos de autor
|
|
208
|
+
2. Al contribuir, aceptas que tu código se licenciará bajo la misma licencia propietaria
|
|
209
|
+
3. No se permite el uso de contribuciones en proyectos competidores
|
|
210
|
+
4. Contacta con el titular de los derechos antes de realizar contribuciones significativas
|
|
211
|
+
|
|
212
|
+
Para contribuir:
|
|
213
|
+
|
|
214
|
+
1. Contacta primero para discutir los cambios propuestos
|
|
215
|
+
2. Fork el proyecto (solo para desarrollo autorizado)
|
|
216
|
+
3. Crea una rama para tu feature (`git checkout -b feature/AmazingFeature`)
|
|
217
|
+
4. Commit tus cambios (`git commit -m 'Add some AmazingFeature'`)
|
|
218
|
+
5. Push a la rama (`git push origin feature/AmazingFeature`)
|
|
219
|
+
6. Abre un Pull Request (sujeto a revisión y aceptación de términos)
|
|
220
|
+
|
|
221
|
+
## 📄 Licencia
|
|
222
|
+
|
|
223
|
+
**LICENCIA PROPIETARIA - Todos los derechos reservados**
|
|
224
|
+
|
|
225
|
+
Este software está protegido por derechos de autor y se distribuye bajo una licencia propietaria restrictiva.
|
|
226
|
+
|
|
227
|
+
**Restricciones principales:**
|
|
228
|
+
|
|
229
|
+
- ❌ No se permite uso comercial sin licencia
|
|
230
|
+
- ❌ No se permite modificación o redistribución
|
|
231
|
+
- ❌ No se permite ingeniería inversa
|
|
232
|
+
- ✅ Uso personal y no comercial permitido
|
|
233
|
+
|
|
234
|
+
Para uso comercial o permisos especiales, consulta el archivo `LICENSE` o contacta al titular de los derechos.
|
|
235
|
+
|
|
236
|
+
Ver el archivo [LICENSE](LICENSE) para los términos completos.
|
package/bin/run.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { spawn } = require('child_process');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const os = require('os');
|
|
6
|
+
|
|
7
|
+
const extension = os.platform() === 'win32' ? '.exe' : '';
|
|
8
|
+
const binPath = path.join(__dirname, `skillctl${extension}`);
|
|
9
|
+
|
|
10
|
+
if (!require('fs').existsSync(binPath)) {
|
|
11
|
+
console.error('❌ El binario no se encuentra. Intenta ejecutar: npm install --force');
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Ejecutar el binario y pasarle todos los argumentos
|
|
16
|
+
const child = spawn(binPath, process.argv.slice(2), { stdio: 'inherit' });
|
|
17
|
+
|
|
18
|
+
child.on('close', (code) => {
|
|
19
|
+
process.exit(code);
|
|
20
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "skillctl",
|
|
3
|
+
"version": "0.0.3",
|
|
4
|
+
"description": "Gestor de Skills para Agentes de IA",
|
|
5
|
+
"bin": {
|
|
6
|
+
"skillctl": "./bin/run.js"
|
|
7
|
+
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"postinstall": "node scripts/install.js"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"axios": "^1.6.0",
|
|
13
|
+
"tar": "^6.2.0"
|
|
14
|
+
},
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/joeldevz/agent-skill.git"
|
|
18
|
+
},
|
|
19
|
+
"keywords": ["ai", "skills", "cli", "agents", "cursor", "antigravity"],
|
|
20
|
+
"author": "Your Name",
|
|
21
|
+
"license": "PROPRIETARY"
|
|
22
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
const axios = require('axios');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const os = require('os');
|
|
5
|
+
|
|
6
|
+
// Configuración
|
|
7
|
+
const REPO = "joeldevz/agent-skill";
|
|
8
|
+
const VERSION = "v0.0.3"; // ¡CAMBIA ESTO PARA QUE COINCIDA CON TU TAG DE GITHUB!
|
|
9
|
+
const BIN_NAME = "skillctl";
|
|
10
|
+
|
|
11
|
+
// Detectar plataforma
|
|
12
|
+
const platform = os.platform(); // 'darwin', 'linux', 'win32'
|
|
13
|
+
const arch = os.arch(); // 'x64', 'arm64'
|
|
14
|
+
|
|
15
|
+
let urlPlatform = "";
|
|
16
|
+
let extension = "";
|
|
17
|
+
|
|
18
|
+
if (platform === 'win32') {
|
|
19
|
+
urlPlatform = 'win';
|
|
20
|
+
extension = '.exe';
|
|
21
|
+
} else if (platform === 'darwin') {
|
|
22
|
+
urlPlatform = 'macos';
|
|
23
|
+
} else if (platform === 'linux') {
|
|
24
|
+
urlPlatform = 'linux';
|
|
25
|
+
} else {
|
|
26
|
+
console.error('Sistema operativo no soportado');
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Construir URL de descarga (GitHub Releases)
|
|
31
|
+
const fileName = `${BIN_NAME}-${urlPlatform}${extension}`;
|
|
32
|
+
const downloadUrl = `https://github.com/${REPO}/releases/download/${VERSION}/${fileName}`;
|
|
33
|
+
|
|
34
|
+
const binDir = path.join(__dirname, '..', 'bin');
|
|
35
|
+
if (!fs.existsSync(binDir)) {
|
|
36
|
+
fs.mkdirSync(binDir);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const destPath = path.join(binDir, `skillctl${extension}`);
|
|
40
|
+
|
|
41
|
+
console.log(`⬇️ Descargando ${BIN_NAME} desde: ${downloadUrl}`);
|
|
42
|
+
|
|
43
|
+
async function download() {
|
|
44
|
+
try {
|
|
45
|
+
const response = await axios({
|
|
46
|
+
method: 'get',
|
|
47
|
+
url: downloadUrl,
|
|
48
|
+
responseType: 'stream'
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const writer = fs.createWriteStream(destPath);
|
|
52
|
+
response.data.pipe(writer);
|
|
53
|
+
|
|
54
|
+
return new Promise((resolve, reject) => {
|
|
55
|
+
writer.on('finish', () => {
|
|
56
|
+
// Dar permisos de ejecución en Linux/Mac
|
|
57
|
+
if (platform !== 'win32') {
|
|
58
|
+
fs.chmodSync(destPath, 0o755);
|
|
59
|
+
}
|
|
60
|
+
console.log('✅ Instalación completada.');
|
|
61
|
+
resolve();
|
|
62
|
+
});
|
|
63
|
+
writer.on('error', reject);
|
|
64
|
+
});
|
|
65
|
+
} catch (error) {
|
|
66
|
+
console.error('❌ Error descargando el binario. Asegúrate de que la Release exista en GitHub.');
|
|
67
|
+
console.error(error.message);
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
download();
|
package/src/main.rs
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
// src/main.rs (Fragmentos clave)
|
|
2
|
+
use clap::{Parser, Subcommand};
|
|
3
|
+
use serde::{Deserialize, Serialize};
|
|
4
|
+
use std::collections::HashMap;
|
|
5
|
+
use std::fs;
|
|
6
|
+
use std::path::Path;
|
|
7
|
+
use anyhow::Result;
|
|
8
|
+
|
|
9
|
+
// --- MODELO DE DATOS (El Manifiesto) ---
|
|
10
|
+
#[derive(Serialize, Deserialize, Debug)]
|
|
11
|
+
struct SkillManifest {
|
|
12
|
+
version: String,
|
|
13
|
+
skills: HashMap<String, SkillEntry>,
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
#[derive(Serialize, Deserialize, Debug)]
|
|
17
|
+
struct SkillEntry {
|
|
18
|
+
url: String, // URL original del repo
|
|
19
|
+
branch: String, // main, master, etc.
|
|
20
|
+
local_path: String,
|
|
21
|
+
last_updated: String,
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// --- COMANDOS CLI ---
|
|
25
|
+
#[derive(Parser)]
|
|
26
|
+
#[command(name = "skillctl")]
|
|
27
|
+
#[command(about = "Gestor de Skills para Agentes de IA", long_about = None)]
|
|
28
|
+
struct Cli {
|
|
29
|
+
#[command(subcommand)]
|
|
30
|
+
command: Commands,
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
#[derive(Subcommand)]
|
|
34
|
+
enum Commands {
|
|
35
|
+
/// Inicializa un nuevo proyecto de skills
|
|
36
|
+
Init,
|
|
37
|
+
/// Añade una nueva skill al proyecto
|
|
38
|
+
Add { url: String, skill: String },
|
|
39
|
+
/// Re-descarga todas las skills desde sus URLs originales
|
|
40
|
+
Update,
|
|
41
|
+
/// Genera los archivos de configuración para los editores detectados
|
|
42
|
+
Sync {
|
|
43
|
+
#[arg(short, long)]
|
|
44
|
+
editors: Vec<String>, // ej: --editors cursor,antigravity
|
|
45
|
+
},
|
|
46
|
+
/// Lista todas las skills instaladas
|
|
47
|
+
List,
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// --- LÓGICA DE UPDATE ---
|
|
51
|
+
fn update_skills() -> Result<()> {
|
|
52
|
+
let manifest_path = Path::new("skills.toml");
|
|
53
|
+
if !manifest_path.exists() {
|
|
54
|
+
println!("❌ No se encontró skills.toml. Usa 'add' primero.");
|
|
55
|
+
return Ok(());
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
let content = fs::read_to_string(manifest_path)?;
|
|
59
|
+
let mut manifest: SkillManifest = toml::from_str(&content)?;
|
|
60
|
+
|
|
61
|
+
println!("🔄 Buscando actualizaciones para {} skills...", manifest.skills.len());
|
|
62
|
+
|
|
63
|
+
for (name, entry) in &manifest.skills {
|
|
64
|
+
println!(" ⬇️ Actualizando {}...", name);
|
|
65
|
+
// Reutilizamos la lógica de descarga (download_file)
|
|
66
|
+
// Aquí podrías comprobar hashes git si quisieras ser muy preciso,
|
|
67
|
+
// pero re-descargar el RAW file es rápido y efectivo.
|
|
68
|
+
download_skill_file(&entry.url, &entry.branch, name)?;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Actualizamos timestamp en el toml (opcional)
|
|
72
|
+
fs::write(manifest_path, toml::to_string(&manifest)?)?;
|
|
73
|
+
|
|
74
|
+
println!("✅ Todas las skills están al día.");
|
|
75
|
+
// Auto-ejecutamos sync para reflejar cambios
|
|
76
|
+
sync_editors(vec!["cursor".to_string(), "antigravity".to_string()])?;
|
|
77
|
+
|
|
78
|
+
Ok(())
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// --- LÓGICA DE SYNC MULTI-EDITOR ---
|
|
82
|
+
fn sync_editors(targets: Vec<String>) -> Result<()> {
|
|
83
|
+
let manifest = load_manifest()?; // Función helper que lee skills.toml
|
|
84
|
+
|
|
85
|
+
for editor in targets {
|
|
86
|
+
match editor.as_str() {
|
|
87
|
+
"cursor" => generate_cursor_config(&manifest)?,
|
|
88
|
+
"antigravity" => generate_antigravity_config(&manifest)?,
|
|
89
|
+
"vscode" => generate_vscode_config(&manifest)?, // Copilot instructions
|
|
90
|
+
_ => println!("⚠️ Editor desconocido: {}", editor),
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
Ok(())
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Generador para Cursor (.cursorrules)
|
|
97
|
+
fn generate_cursor_config(manifest: &SkillManifest) -> Result<()> {
|
|
98
|
+
let mut instructions = String::from("# Rules generadas por Skill-CLI\n\n");
|
|
99
|
+
|
|
100
|
+
for (name, entry) in &manifest.skills {
|
|
101
|
+
// Opción A: Referencia al archivo (si el editor sabe leer paths)
|
|
102
|
+
instructions.push_str(&format!("## Skill: {}\n", name));
|
|
103
|
+
instructions.push_str(&format!("Reference: .cursor/skills/{}/SKILL.md\n\n", name));
|
|
104
|
+
|
|
105
|
+
// Opción B (Más robusta): Leer el contenido e inyectarlo si es pequeño
|
|
106
|
+
// let content = fs::read_to_string(&entry.local_path)?;
|
|
107
|
+
// instructions.push_str(&content);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
fs::write(".cursorrules", instructions)?;
|
|
111
|
+
println!("✅ .cursorrules actualizado.");
|
|
112
|
+
Ok(())
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Generador para Antigravity (.antigravity)
|
|
116
|
+
fn generate_antigravity_config(manifest: &SkillManifest) -> Result<()> {
|
|
117
|
+
// Supongamos que Antigravity usa JSON o un formato diferente
|
|
118
|
+
// O tal vez soporta "Symlinks" virtuales.
|
|
119
|
+
|
|
120
|
+
let mut config_lines = Vec::new();
|
|
121
|
+
config_lines.push("PROJECT_CONTEXT:".to_string());
|
|
122
|
+
|
|
123
|
+
for (name, entry) in &manifest.skills {
|
|
124
|
+
// Imaginemos que Antigravity necesita path absoluto
|
|
125
|
+
let abs_path = fs::canonicalize(&entry.local_path)?;
|
|
126
|
+
config_lines.push(format!(" - IMPORT_SKILL: {}", abs_path.display()));
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
fs::write(".antigravity", config_lines.join("\n"))?;
|
|
130
|
+
println!("✅ .antigravity actualizado.");
|
|
131
|
+
Ok(())
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Generador para VSCode (.github/copilot-instructions.md)
|
|
135
|
+
fn generate_vscode_config(manifest: &SkillManifest) -> Result<()> {
|
|
136
|
+
let mut instructions = String::from("# GitHub Copilot Instructions\n\n");
|
|
137
|
+
|
|
138
|
+
for (name, entry) in &manifest.skills {
|
|
139
|
+
instructions.push_str(&format!("## Skill: {}\n", name));
|
|
140
|
+
instructions.push_str(&format!("Path: {}\n\n", entry.local_path));
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
fs::create_dir_all(".github")?;
|
|
144
|
+
fs::write(".github/copilot-instructions.md", instructions)?;
|
|
145
|
+
println!("✅ .github/copilot-instructions.md actualizado.");
|
|
146
|
+
Ok(())
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// --- LÓGICA DE INIT ---
|
|
150
|
+
fn init_project() -> Result<()> {
|
|
151
|
+
let manifest_path = Path::new("skills.toml");
|
|
152
|
+
if manifest_path.exists() {
|
|
153
|
+
println!("⚠️ El archivo skills.toml ya existe.");
|
|
154
|
+
return Ok(());
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
let default_content = r#"# Manifiesto de Skills
|
|
158
|
+
version = "1.0"
|
|
159
|
+
|
|
160
|
+
[skills]
|
|
161
|
+
# Las skills se añadirán aquí automáticamente al usar 'add'
|
|
162
|
+
"#;
|
|
163
|
+
|
|
164
|
+
fs::write(manifest_path, default_content)?;
|
|
165
|
+
|
|
166
|
+
// Crear carpetas necesarias
|
|
167
|
+
fs::create_dir_all(".cursor/skills")?;
|
|
168
|
+
|
|
169
|
+
println!("✅ Proyecto inicializado. Se ha creado 'skills.toml'.");
|
|
170
|
+
println!("🚀 Prueba ahora: npx skillctl add <url> --skill <nombre>");
|
|
171
|
+
|
|
172
|
+
Ok(())
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// --- LÓGICA DE LIST ---
|
|
176
|
+
fn list_skills() -> Result<()> {
|
|
177
|
+
let manifest_path = Path::new("skills.toml");
|
|
178
|
+
if !manifest_path.exists() {
|
|
179
|
+
println!("❌ No se encontró skills.toml. Ejecuta 'skillctl init' primero.");
|
|
180
|
+
return Ok(());
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
let content = fs::read_to_string(manifest_path)?;
|
|
184
|
+
let manifest: SkillManifest = toml::from_str(&content)?;
|
|
185
|
+
|
|
186
|
+
if manifest.skills.is_empty() {
|
|
187
|
+
println!("📦 No hay skills instaladas.");
|
|
188
|
+
println!("💡 Usa 'skillctl add <url> --skill <nombre>' para añadir una.");
|
|
189
|
+
} else {
|
|
190
|
+
println!("📦 Skills instaladas ({}):", manifest.skills.len());
|
|
191
|
+
for (name, entry) in &manifest.skills {
|
|
192
|
+
println!(" • {} ({})", name, entry.url);
|
|
193
|
+
println!(" └─ Branch: {} | Path: {}", entry.branch, entry.local_path);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
Ok(())
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// --- HELPER: Cargar manifiesto ---
|
|
201
|
+
fn load_manifest() -> Result<SkillManifest> {
|
|
202
|
+
let manifest_path = Path::new("skills.toml");
|
|
203
|
+
if !manifest_path.exists() {
|
|
204
|
+
anyhow::bail!("No se encontró skills.toml. Ejecuta 'skillctl init' primero.");
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
let content = fs::read_to_string(manifest_path)?;
|
|
208
|
+
let manifest: SkillManifest = toml::from_str(&content)?;
|
|
209
|
+
Ok(manifest)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// --- HELPER: Descargar archivo de skill ---
|
|
213
|
+
fn download_skill_file(url: &str, branch: &str, name: &str) -> Result<()> {
|
|
214
|
+
// Implementación simplificada - aquí iría la lógica real de descarga
|
|
215
|
+
println!(" ⬇️ Descargando {} desde {} (branch: {})", name, url, branch);
|
|
216
|
+
// TODO: Implementar descarga real usando reqwest o similar
|
|
217
|
+
Ok(())
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// --- FUNCIÓN PRINCIPAL ---
|
|
221
|
+
fn main() -> Result<()> {
|
|
222
|
+
let cli = Cli::parse();
|
|
223
|
+
|
|
224
|
+
match &cli.command {
|
|
225
|
+
Commands::Init => init_project()?,
|
|
226
|
+
Commands::Add { url, skill } => {
|
|
227
|
+
println!("🔧 Añadiendo skill '{}' desde {}...", skill, url);
|
|
228
|
+
// Aquí iría la lógica de add_skill(url, skill)
|
|
229
|
+
println!("⚠️ Comando 'add' aún no implementado completamente.");
|
|
230
|
+
}
|
|
231
|
+
Commands::Update => update_skills()?,
|
|
232
|
+
Commands::Sync { editors } => sync_editors(editors.clone())?,
|
|
233
|
+
Commands::List => list_skills()?,
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
Ok(())
|
|
237
|
+
}
|