@sysvv/ai-skill 1.0.0 → 1.1.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 +141 -11
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -2,23 +2,93 @@
2
2
  import inquirer from "inquirer";
3
3
  import fs from "fs-extra";
4
4
  import path from "node:path";
5
+ import { readFileSync } from "node:fs";
6
+ import { fileURLToPath } from "node:url";
5
7
  import { findSkillFiles } from "./core/registry.js";
6
8
  import { parseSkillFile } from "./core/frontmatter.js";
7
9
  import { loadSkill } from "./core/skill.js";
10
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
11
+ // ── ANSI ────────────────────────────────────────────────────────────────
12
+ const ANSI = {
13
+ bold: '\x1b[1m',
14
+ dim: '\x1b[2m',
15
+ reset: '\x1b[0m',
16
+ };
17
+ const PINK = '\x1b[38;2;238;54;141m';
18
+ const BLUE = '\x1b[38;2;14;93;171m';
19
+ const RED = '\x1b[38;2;255;70;70m';
20
+ const GREEN = '\x1b[38;2;80;200;120m';
21
+ // ── ASCII Art Letters (5 lines) ─────────────────────────────────────────
22
+ const LETTERS = {
23
+ A: [' █████ ', '██ ██', '███████', '██ ██', '██ ██'],
24
+ I: ['██', '██', '██', '██', '██'],
25
+ K: ['██ ██', '██ ██ ', '████ ', '██ ██ ', '██ ██'],
26
+ L: ['██ ', '██ ', '██ ', '██ ', '███████'],
27
+ S: ['███████', '██ ', '███████', ' ██', '███████'],
28
+ Y: ['██ ██', ' ██ ██ ', ' ███ ', ' ███ ', ' ███ '],
29
+ };
30
+ function joinLetters(keys, gap = ' ') {
31
+ const letters = keys.map(k => LETTERS[k]);
32
+ return Array.from({ length: 5 }, (_, i) => letters.map(l => l[i]).join(gap));
33
+ }
34
+ function centerPad(line, totalWidth) {
35
+ const spaces = Math.max(0, Math.floor((totalWidth - line.length) / 2));
36
+ return ' '.repeat(spaces) + line;
37
+ }
38
+ function showBanner() {
39
+ let version = '0.0.0';
40
+ try {
41
+ const pkg = JSON.parse(readFileSync(path.join(__dirname, '../package.json'), 'utf8'));
42
+ version = pkg.version;
43
+ }
44
+ catch { /* ignore */ }
45
+ const sysLines = joinLetters(['S', 'Y', 'S']);
46
+ const aiLines = joinLetters(['A', 'I']);
47
+ const skillsLines = joinLetters(['S', 'K', 'I', 'L', 'L', 'S']);
48
+ const maxWidth = Math.max(sysLines[0].length, aiLines[0].length, skillsLines[0].length);
49
+ const indent = ' ';
50
+ console.log('');
51
+ for (const line of sysLines) {
52
+ console.log(indent + PINK + ANSI.bold + centerPad(line, maxWidth) + ANSI.reset);
53
+ }
54
+ console.log('');
55
+ for (const line of aiLines) {
56
+ console.log(indent + BLUE + centerPad(line, maxWidth) + ANSI.reset);
57
+ }
58
+ for (const line of skillsLines) {
59
+ console.log(indent + BLUE + centerPad(line, maxWidth) + ANSI.reset);
60
+ }
61
+ console.log('');
62
+ console.log(indent + ANSI.dim + centerPad(`VERSION ${version}`, maxWidth) + ANSI.reset);
63
+ console.log('');
64
+ const desc = 'Skills para turbinar seus agentes de codigo';
65
+ const boxInner = desc.length + 2;
66
+ console.log(indent + ANSI.dim + centerPad('┌' + '─'.repeat(boxInner) + '┐', maxWidth) + ANSI.reset);
67
+ console.log(indent + ANSI.dim + centerPad('│ ' + desc + ' │', maxWidth) + ANSI.reset);
68
+ console.log(indent + ANSI.dim + centerPad('└' + '─'.repeat(boxInner) + '┘', maxWidth) + ANSI.reset);
69
+ console.log('');
70
+ console.log(indent + ANSI.dim + ' ℹ Tip: npx @sysvv/ai-skill --claude | --codex | --gemini | --clear' + ANSI.reset);
71
+ console.log('');
72
+ }
73
+ // ── Config ──────────────────────────────────────────────────────────────
8
74
  const AGENT_DIRS = {
9
75
  claude: ".claude/skills",
10
76
  codex: ".codex/skills",
11
77
  gemini: ".gemini/skills",
12
78
  };
13
- async function main() {
14
- const { agent } = await inquirer.prompt([
15
- {
16
- type: "list",
17
- name: "agent",
18
- message: "Qual IA você usa?",
19
- choices: Object.keys(AGENT_DIRS)
20
- }
21
- ]);
79
+ // ── Parse args ──────────────────────────────────────────────────────────
80
+ function parseArgs() {
81
+ const args = process.argv.slice(2);
82
+ if (args.includes("--clear"))
83
+ return { clear: true };
84
+ for (const key of Object.keys(AGENT_DIRS)) {
85
+ if (args.includes(`--${key}`))
86
+ return { agent: key };
87
+ }
88
+ return {};
89
+ }
90
+ // ── Install skills for agent ────────────────────────────────────────────
91
+ async function installSkills(agent) {
22
92
  const skillFiles = await findSkillFiles();
23
93
  const available = [];
24
94
  for (const file of skillFiles) {
@@ -53,9 +123,69 @@ async function main() {
53
123
  const skillDir = path.join(destBase, skill.metadata.name);
54
124
  await fs.ensureDir(skillDir);
55
125
  await fs.writeFile(path.join(skillDir, "SKILL.md"), skill.renderedBody, "utf8");
56
- console.log(` ${skill.metadata.name}`);
126
+ console.log(` ${GREEN}✔${ANSI.reset} ${skill.metadata.name}`);
127
+ }
128
+ console.log(`\n Skills instaladas em ${ANSI.bold}${destBase}/${ANSI.reset}\n`);
129
+ }
130
+ // ── Clear all skills ────────────────────────────────────────────────────
131
+ async function clearSkills() {
132
+ const existing = [];
133
+ for (const [agent, dir] of Object.entries(AGENT_DIRS)) {
134
+ const full = path.resolve(dir);
135
+ if (await fs.pathExists(full)) {
136
+ existing.push(agent);
137
+ }
138
+ }
139
+ if (existing.length === 0) {
140
+ console.log(" Nenhuma pasta de skills encontrada.\n");
141
+ return;
142
+ }
143
+ console.log(` ${RED}⚠${ANSI.reset} Pastas encontradas:\n`);
144
+ for (const agent of existing) {
145
+ console.log(` ${ANSI.dim}${path.resolve(AGENT_DIRS[agent])}${ANSI.reset}`);
146
+ }
147
+ console.log('');
148
+ const { confirm } = await inquirer.prompt([
149
+ {
150
+ type: "confirm",
151
+ name: "confirm",
152
+ message: "Tem certeza que deseja apagar TODAS as pastas de skills?",
153
+ default: false
154
+ }
155
+ ]);
156
+ if (!confirm) {
157
+ console.log("\n Operação cancelada.\n");
158
+ return;
57
159
  }
58
- console.log(`\nSkills instaladas em ${destBase}/\n`);
160
+ for (const agent of existing) {
161
+ const full = path.resolve(AGENT_DIRS[agent]);
162
+ await fs.remove(full);
163
+ console.log(` ${RED}✖${ANSI.reset} ${full} removida`);
164
+ }
165
+ console.log("\n Todas as skills foram removidas.\n");
166
+ }
167
+ // ── Main ────────────────────────────────────────────────────────────────
168
+ async function main() {
169
+ showBanner();
170
+ const { agent, clear } = parseArgs();
171
+ if (clear) {
172
+ await clearSkills();
173
+ return;
174
+ }
175
+ if (agent) {
176
+ await installSkills(agent);
177
+ return;
178
+ }
179
+ // Modo interativo
180
+ const { chosenAgent } = await inquirer.prompt([
181
+ {
182
+ type: "list",
183
+ name: "chosenAgent",
184
+ message: "Qual IA você usa?",
185
+ choices: Object.keys(AGENT_DIRS)
186
+ }
187
+ ]);
188
+ await installSkills(chosenAgent);
59
189
  }
60
190
  main().catch((err) => {
61
191
  console.error("Erro:", err.message);
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@sysvv/ai-skill",
3
- "version": "1.0.0",
3
+ "version": "1.1.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": {
7
- "ai-skill": "./dist/index.js"
7
+ "ai-skill": "dist/index.js"
8
8
  },
9
9
  "files": [
10
10
  "dist",