@sysvv/ai-skill 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +71 -33
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -24,9 +24,9 @@ const WHITE = '\x1b[97m';
24
24
  // ── Inquirer Theme ──────────────────────────────────────────────────────
25
25
  const sysTheme = {
26
26
  icon: {
27
- cursor: PINK + '❯' + ANSI.reset,
28
- checked: PINK + '' + ANSI.reset,
29
- unchecked: ANSI.dim + '○' + ANSI.reset,
27
+ cursor: PINK + ' ❯' + ANSI.reset,
28
+ checked: GREEN + '' + ANSI.reset,
29
+ unchecked: ANSI.dim + ' ○' + ANSI.reset,
30
30
  },
31
31
  style: {
32
32
  highlight: (text) => PINK + ANSI.bold + text + ANSI.reset,
@@ -146,7 +146,6 @@ async function installSkills(agent) {
146
146
  ]);
147
147
  const destBase = path.resolve(AGENT_DIRS[agent]);
148
148
  const mcpsToInstall = new Set();
149
- // Instala skills
150
149
  console.log('');
151
150
  for (const file of selected) {
152
151
  const skill = await loadSkill(file, agent);
@@ -154,19 +153,16 @@ async function installSkills(agent) {
154
153
  await fs.ensureDir(skillDir);
155
154
  await fs.writeFile(path.join(skillDir, "SKILL.md"), skill.renderedBody, "utf8");
156
155
  console.log(` ${GREEN}✔${ANSI.reset} ${skill.metadata.name}`);
157
- // Coleta MCPs necessários
158
156
  for (const mcpName of skill.metadata.mcps ?? []) {
159
157
  mcpsToInstall.add(mcpName);
160
158
  }
161
159
  }
162
- // Instala MCPs automaticamente
163
160
  if (mcpsToInstall.size > 0) {
164
161
  console.log('');
165
- let mcpTarget = '';
166
162
  for (const mcpName of mcpsToInstall) {
167
163
  try {
168
164
  const mcp = await loadMcp(mcpName);
169
- mcpTarget = await writeMcp(agent, mcp);
165
+ const mcpTarget = await writeMcp(agent, mcp);
170
166
  console.log(` ${GREEN}✔${ANSI.reset} MCP ${ANSI.bold}${mcpName}${ANSI.reset} ${ANSI.dim}→ ${mcpTarget}${ANSI.reset}`);
171
167
  }
172
168
  catch (err) {
@@ -176,36 +172,75 @@ async function installSkills(agent) {
176
172
  }
177
173
  console.log(`\n Skills instaladas em ${ANSI.bold}${destBase}/${ANSI.reset}\n`);
178
174
  }
179
- // ── Clear all skills + MCPs ─────────────────────────────────────────────
180
- async function clearSkills() {
181
- const found = [];
175
+ // ── Clear ───────────────────────────────────────────────────────────────
176
+ async function clearFlow() {
177
+ // Descobre o que existe
178
+ const foundSkills = [];
179
+ const foundMcps = [];
182
180
  for (const [agent, dir] of Object.entries(AGENT_DIRS)) {
183
181
  const skillsFull = path.resolve(dir);
182
+ if (await fs.pathExists(skillsFull)) {
183
+ foundSkills.push({ agent, dir: skillsFull });
184
+ }
184
185
  const mcpTarget = getMcpTargetPath(agent);
185
- const mcpFull = mcpTarget ? path.resolve(mcpTarget) : "";
186
- const hasSkills = await fs.pathExists(skillsFull);
187
- const hasMcp = mcpFull ? await fs.pathExists(mcpFull) : false;
188
- if (hasSkills || hasMcp) {
189
- found.push({ agent, skillsDir: skillsFull, mcpFile: mcpFull, hasSkills, hasMcp });
186
+ if (mcpTarget) {
187
+ const mcpFull = path.resolve(mcpTarget);
188
+ if (await fs.pathExists(mcpFull)) {
189
+ foundMcps.push({ agent, file: mcpFull });
190
+ }
190
191
  }
191
192
  }
192
- if (found.length === 0) {
193
- console.log(" Nenhuma pasta de skills ou MCP encontrada.\n");
193
+ const hasSkills = foundSkills.length > 0;
194
+ const hasMcps = foundMcps.length > 0;
195
+ if (!hasSkills && !hasMcps) {
196
+ console.log(" Nenhuma skill ou MCP instalado.\n");
194
197
  return;
195
198
  }
199
+ // Mostra o que encontrou
196
200
  console.log(` ${RED}⚠${ANSI.reset} Encontrado:\n`);
197
- for (const f of found) {
198
- if (f.hasSkills)
199
- console.log(` ${ANSI.dim}${f.skillsDir}${ANSI.reset}`);
200
- if (f.hasMcp)
201
- console.log(` ${ANSI.dim}${f.mcpFile}${ANSI.reset}`);
201
+ if (hasSkills) {
202
+ console.log(` ${ANSI.bold}Skills${ANSI.reset}`);
203
+ for (const s of foundSkills) {
204
+ console.log(` ${ANSI.dim}${s.dir}${ANSI.reset}`);
205
+ }
206
+ }
207
+ if (hasMcps) {
208
+ if (hasSkills)
209
+ console.log('');
210
+ console.log(` ${ANSI.bold}MCPs${ANSI.reset}`);
211
+ for (const m of foundMcps) {
212
+ console.log(` ${ANSI.dim}${m.file}${ANSI.reset}`);
213
+ }
202
214
  }
203
215
  console.log('');
216
+ const choices = [];
217
+ if (hasSkills && hasMcps) {
218
+ choices.push({ name: `${RED}Tudo${ANSI.reset} ${ANSI.dim}(skills + MCPs)${ANSI.reset}`, value: "all" }, { name: `Apenas Skills`, value: "skills" }, { name: `Apenas MCPs`, value: "mcps" });
219
+ }
220
+ else if (hasSkills) {
221
+ choices.push({ name: `Apagar Skills`, value: "skills" });
222
+ }
223
+ else {
224
+ choices.push({ name: `Apagar MCPs`, value: "mcps" });
225
+ }
226
+ const { action } = await inquirer.prompt([
227
+ {
228
+ type: "list",
229
+ name: "action",
230
+ message: "O que deseja remover?",
231
+ choices,
232
+ theme: sysTheme
233
+ }
234
+ ]);
235
+ const removeSkills = action === "all" || action === "skills";
236
+ const removeMcps = action === "all" || action === "mcps";
237
+ // Confirmação
238
+ const target = action === "all" ? "skills e MCPs" : action === "skills" ? "skills" : "MCPs";
204
239
  const { confirm } = await inquirer.prompt([
205
240
  {
206
241
  type: "confirm",
207
242
  name: "confirm",
208
- message: "Tem certeza que deseja apagar TUDO (skills + MCPs)?",
243
+ message: `Confirma a remoção de ${target}?`,
209
244
  default: false,
210
245
  theme: sysTheme
211
246
  }
@@ -214,24 +249,27 @@ async function clearSkills() {
214
249
  console.log("\n Operação cancelada.\n");
215
250
  return;
216
251
  }
217
- for (const f of found) {
218
- if (f.hasSkills) {
219
- await fs.remove(f.skillsDir);
220
- console.log(` ${RED}✖${ANSI.reset} ${f.skillsDir}`);
252
+ console.log('');
253
+ if (removeSkills) {
254
+ for (const s of foundSkills) {
255
+ await fs.remove(s.dir);
256
+ console.log(` ${RED}✖${ANSI.reset} ${ANSI.dim}${s.dir}${ANSI.reset}`);
221
257
  }
222
- if (f.hasMcp) {
223
- await fs.remove(f.mcpFile);
224
- console.log(` ${RED}✖${ANSI.reset} ${f.mcpFile}`);
258
+ }
259
+ if (removeMcps) {
260
+ for (const m of foundMcps) {
261
+ await fs.remove(m.file);
262
+ console.log(` ${RED}✖${ANSI.reset} ${ANSI.dim}${m.file}${ANSI.reset}`);
225
263
  }
226
264
  }
227
- console.log("\n Tudo removido.\n");
265
+ console.log("\n Removido com sucesso.\n");
228
266
  }
229
267
  // ── Main ────────────────────────────────────────────────────────────────
230
268
  async function main() {
231
269
  showBanner();
232
270
  const { agent, clear } = parseArgs();
233
271
  if (clear) {
234
- await clearSkills();
272
+ await clearFlow();
235
273
  return;
236
274
  }
237
275
  if (agent) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sysvv/ai-skill",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "description": "Instale skills de IA direto no seu projeto. Escolha o agent, escolha as skills.",
5
5
  "type": "module",
6
6
  "bin": {