cli-ai-skills 1.7.2 → 1.7.6

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 (94) hide show
  1. package/README.md +2 -2
  2. package/bin/cli.js +24 -13
  3. package/lib/claude.js +3 -2
  4. package/lib/codex.js +63 -24
  5. package/lib/commands/install.js +4 -1
  6. package/lib/copilot.js +3 -2
  7. package/lib/detector.js +65 -5
  8. package/lib/gemini.js +5 -5
  9. package/lib/interactive.js +23 -12
  10. package/lib/opencode.js +5 -5
  11. package/lib/ui/table.js +14 -9
  12. package/lib/utils/path-resolver.js +106 -0
  13. package/lib/utils/skill-versions.js +63 -0
  14. package/package.json +4 -3
  15. package/skills/claude/audio-transcriber/CHANGELOG.md +169 -0
  16. package/skills/claude/audio-transcriber/README.md +340 -0
  17. package/skills/claude/audio-transcriber/SKILL.md +558 -0
  18. package/skills/claude/audio-transcriber/examples/basic-transcription.sh +250 -0
  19. package/skills/claude/audio-transcriber/references/tools-comparison.md +352 -0
  20. package/skills/claude/audio-transcriber/scripts/install-requirements.sh +190 -0
  21. package/skills/claude/audio-transcriber/scripts/transcribe.py +486 -0
  22. package/skills/claude/prompt-engineer/README.md +659 -0
  23. package/skills/claude/prompt-engineer/SKILL.md +252 -0
  24. package/skills/claude/skill-creator/README.md +270 -0
  25. package/skills/claude/skill-creator/SKILL.md +593 -0
  26. package/skills/claude/youtube-summarizer/CHANGELOG.md +66 -0
  27. package/skills/claude/youtube-summarizer/README.md +365 -0
  28. package/skills/claude/youtube-summarizer/SKILL.md +411 -0
  29. package/skills/claude/youtube-summarizer/scripts/extract-transcript.py +65 -0
  30. package/skills/claude/youtube-summarizer/scripts/install-dependencies.sh +28 -0
  31. package/skills/codex/audio-transcriber/CHANGELOG.md +169 -0
  32. package/skills/codex/audio-transcriber/README.md +340 -0
  33. package/skills/codex/audio-transcriber/SKILL.md +558 -0
  34. package/skills/codex/audio-transcriber/examples/basic-transcription.sh +250 -0
  35. package/skills/codex/audio-transcriber/references/tools-comparison.md +352 -0
  36. package/skills/codex/audio-transcriber/scripts/install-requirements.sh +190 -0
  37. package/skills/codex/audio-transcriber/scripts/transcribe.py +486 -0
  38. package/skills/codex/prompt-engineer/README.md +659 -0
  39. package/skills/codex/prompt-engineer/SKILL.md +252 -0
  40. package/skills/codex/skill-creator/README.md +270 -0
  41. package/skills/codex/skill-creator/SKILL.md +593 -0
  42. package/skills/codex/youtube-summarizer/CHANGELOG.md +66 -0
  43. package/skills/codex/youtube-summarizer/README.md +365 -0
  44. package/skills/codex/youtube-summarizer/SKILL.md +411 -0
  45. package/skills/codex/youtube-summarizer/scripts/extract-transcript.py +65 -0
  46. package/skills/codex/youtube-summarizer/scripts/install-dependencies.sh +28 -0
  47. package/skills/copilot/audio-transcriber/CHANGELOG.md +169 -0
  48. package/skills/copilot/audio-transcriber/README.md +340 -0
  49. package/skills/copilot/audio-transcriber/SKILL.md +558 -0
  50. package/skills/copilot/audio-transcriber/examples/basic-transcription.sh +250 -0
  51. package/skills/copilot/audio-transcriber/references/tools-comparison.md +352 -0
  52. package/skills/copilot/audio-transcriber/scripts/install-requirements.sh +190 -0
  53. package/skills/copilot/audio-transcriber/scripts/transcribe.py +486 -0
  54. package/skills/copilot/prompt-engineer/README.md +659 -0
  55. package/skills/copilot/prompt-engineer/SKILL.md +252 -0
  56. package/skills/copilot/skill-creator/README.md +270 -0
  57. package/skills/copilot/skill-creator/SKILL.md +593 -0
  58. package/skills/copilot/youtube-summarizer/CHANGELOG.md +66 -0
  59. package/skills/copilot/youtube-summarizer/README.md +365 -0
  60. package/skills/copilot/youtube-summarizer/SKILL.md +411 -0
  61. package/skills/copilot/youtube-summarizer/scripts/extract-transcript.py +65 -0
  62. package/skills/copilot/youtube-summarizer/scripts/install-dependencies.sh +28 -0
  63. package/skills/gemini/audio-transcriber/CHANGELOG.md +169 -0
  64. package/skills/gemini/audio-transcriber/README.md +340 -0
  65. package/skills/gemini/audio-transcriber/SKILL.md +558 -0
  66. package/skills/gemini/audio-transcriber/examples/basic-transcription.sh +250 -0
  67. package/skills/gemini/audio-transcriber/references/tools-comparison.md +352 -0
  68. package/skills/gemini/audio-transcriber/scripts/install-requirements.sh +190 -0
  69. package/skills/gemini/audio-transcriber/scripts/transcribe.py +486 -0
  70. package/skills/gemini/prompt-engineer/README.md +659 -0
  71. package/skills/gemini/prompt-engineer/SKILL.md +252 -0
  72. package/skills/gemini/skill-creator/README.md +270 -0
  73. package/skills/gemini/skill-creator/SKILL.md +593 -0
  74. package/skills/gemini/youtube-summarizer/CHANGELOG.md +66 -0
  75. package/skills/gemini/youtube-summarizer/README.md +365 -0
  76. package/skills/gemini/youtube-summarizer/SKILL.md +411 -0
  77. package/skills/gemini/youtube-summarizer/scripts/extract-transcript.py +65 -0
  78. package/skills/gemini/youtube-summarizer/scripts/install-dependencies.sh +28 -0
  79. package/skills/opencode/audio-transcriber/CHANGELOG.md +169 -0
  80. package/skills/opencode/audio-transcriber/README.md +340 -0
  81. package/skills/opencode/audio-transcriber/SKILL.md +558 -0
  82. package/skills/opencode/audio-transcriber/examples/basic-transcription.sh +250 -0
  83. package/skills/opencode/audio-transcriber/references/tools-comparison.md +352 -0
  84. package/skills/opencode/audio-transcriber/scripts/install-requirements.sh +190 -0
  85. package/skills/opencode/audio-transcriber/scripts/transcribe.py +486 -0
  86. package/skills/opencode/prompt-engineer/README.md +659 -0
  87. package/skills/opencode/prompt-engineer/SKILL.md +252 -0
  88. package/skills/opencode/skill-creator/README.md +270 -0
  89. package/skills/opencode/skill-creator/SKILL.md +593 -0
  90. package/skills/opencode/youtube-summarizer/CHANGELOG.md +66 -0
  91. package/skills/opencode/youtube-summarizer/README.md +365 -0
  92. package/skills/opencode/youtube-summarizer/SKILL.md +411 -0
  93. package/skills/opencode/youtube-summarizer/scripts/extract-transcript.py +65 -0
  94. package/skills/opencode/youtube-summarizer/scripts/install-dependencies.sh +28 -0
package/README.md CHANGED
@@ -1,10 +1,10 @@
1
- # cli-ai-skills v1.7.1
1
+ # cli-ai-skills v1.7.2
2
2
 
3
3
  🚀 **NPX Installer for AI Skills**
4
4
 
5
5
  Install reusable skills for GitHub Copilot CLI, Claude Code, OpenAI Codex, OpenCode, and Gemini CLI in one command.
6
6
 
7
- ![Version](https://img.shields.io/badge/version-1.7.1-blue.svg)
7
+ ![Version](https://img.shields.io/badge/version-1.7.2-blue.svg)
8
8
  ![License](https://img.shields.io/badge/license-MIT-green.svg)
9
9
  ![Node](https://img.shields.io/badge/node-%3E%3D14.0.0-green.svg)
10
10
 
package/bin/cli.js CHANGED
@@ -12,11 +12,15 @@ const { listBundles, validateBundle } = require('../lib/bundles');
12
12
  const { searchSkills } = require('../lib/search');
13
13
  const { displayToolsTable } = require('../lib/ui/table');
14
14
  const { checkInstalledVersion, isUpdateAvailable } = require('../lib/version-checker');
15
+ const { getSkillVersion } = require('../lib/utils/skill-versions');
16
+ const { getSkillsBasePath } = require('../lib/utils/path-resolver');
15
17
  const chalk = require('chalk');
16
18
  const inquirer = require('inquirer');
17
19
  const path = require('path');
18
20
 
19
- const VERSION = '1.6.0';
21
+ // Read version dynamically from package.json
22
+ const packageJson = require('../package.json');
23
+ const VERSION = packageJson.version;
20
24
 
21
25
  // Command aliases
22
26
  const commandAliases = {
@@ -92,7 +96,7 @@ async function main() {
92
96
  displayToolsTable(detected);
93
97
 
94
98
  const hasAny = detected.copilot.installed || detected.claude.installed ||
95
- detected.codex.installed || detected.opencode.installed ||
99
+ detected.codex_cli.installed || detected.codex_app.installed || detected.opencode.installed ||
96
100
  detected.gemini.installed;
97
101
 
98
102
  if (!hasAny) {
@@ -108,7 +112,7 @@ async function main() {
108
112
  platforms = [];
109
113
  if (detected.copilot.installed) platforms.push('copilot');
110
114
  if (detected.claude.installed) platforms.push('claude');
111
- if (detected.codex.installed) platforms.push('codex');
115
+ if (detected.codex_cli.installed) platforms.push('codex_cli');
112
116
  if (detected.opencode.installed) platforms.push('opencode');
113
117
  if (detected.gemini.installed) platforms.push('gemini');
114
118
  } else {
@@ -120,7 +124,7 @@ async function main() {
120
124
  process.exit(0);
121
125
  }
122
126
 
123
- const repoPath = path.resolve(__dirname, '../..');
127
+ const repoPath = getSkillsBasePath(__dirname);
124
128
  const quiet = args.includes('-q') || args.includes('--quiet');
125
129
 
126
130
  if (!quiet) {
@@ -136,7 +140,7 @@ async function main() {
136
140
  if (platforms.includes('claude')) {
137
141
  installClaudeSkills(repoPath, [skill], quiet);
138
142
  }
139
- if (platforms.includes('codex')) {
143
+ if (platforms.includes('codex') || platforms.includes('codex_cli') || platforms.includes('codex_app')) {
140
144
  installCodexSkills(repoPath, [skill], quiet);
141
145
  }
142
146
  if (platforms.includes('opencode')) {
@@ -163,7 +167,7 @@ async function main() {
163
167
  displayToolsTable(detected);
164
168
 
165
169
  const hasAny = detected.copilot.installed || detected.claude.installed ||
166
- detected.codex.installed || detected.opencode.installed ||
170
+ detected.codex_cli.installed || detected.codex_app.installed || detected.opencode.installed ||
167
171
  detected.gemini.installed;
168
172
 
169
173
  if (!hasAny) {
@@ -223,7 +227,8 @@ async function main() {
223
227
  platforms = [];
224
228
  if (detected.copilot.installed) platforms.push('copilot');
225
229
  if (detected.claude.installed) platforms.push('claude');
226
- if (detected.codex.installed) platforms.push('codex');
230
+ if (detected.codex_cli.installed) platforms.push('codex_cli');
231
+ if (detected.codex_app.installed) platforms.push('codex_app');
227
232
  if (detected.opencode.installed) platforms.push('opencode');
228
233
  if (detected.gemini.installed) platforms.push('gemini');
229
234
  } else {
@@ -238,7 +243,7 @@ async function main() {
238
243
 
239
244
  console.log(chalk.cyan(`\n📦 Instalando skills para: ${platforms.join(', ')}\n`));
240
245
 
241
- const repoPath = path.resolve(__dirname, '../..');
246
+ const repoPath = getSkillsBasePath(__dirname);
242
247
  const quiet = args.includes('-q') || args.includes('--quiet');
243
248
 
244
249
  // Install for selected platforms
@@ -250,7 +255,7 @@ async function main() {
250
255
  installClaudeSkills(repoPath, null, quiet);
251
256
  }
252
257
 
253
- if (platforms.includes('codex')) {
258
+ if (platforms.includes('codex') || platforms.includes('codex_cli') || platforms.includes('codex_app')) {
254
259
  installCodexSkills(repoPath, null, quiet);
255
260
  }
256
261
 
@@ -272,10 +277,16 @@ async function main() {
272
277
  switch(command) {
273
278
  case 'list':
274
279
  console.log('📋 Installed Skills:\n');
275
- console.log(' • skill-creator (v1.3.0)');
276
- console.log(' • prompt-engineer (v1.1.0)');
277
- console.log(' • youtube-summarizer (v1.2.0)');
278
- console.log(' audio-transcriber (v1.2.0)\n');
280
+
281
+ // Get repo path (works both in npm package and git repo)
282
+ const repoPath = getSkillsBasePath(__dirname);
283
+ const skills = ['skill-creator', 'prompt-engineer', 'youtube-summarizer', 'audio-transcriber'];
284
+
285
+ skills.forEach(skill => {
286
+ const version = getSkillVersion(skill, repoPath);
287
+ console.log(` • ${skill} (v${version})`);
288
+ });
289
+ console.log();
279
290
  break;
280
291
 
281
292
  case 'update':
package/lib/claude.js CHANGED
@@ -1,10 +1,11 @@
1
1
  const fs = require('fs-extra');
2
2
  const path = require('path');
3
3
  const os = require('os');
4
+ const { getSkillsSourcePath, getUserSkillsPath } = require('./utils/path-resolver');
4
5
 
5
6
  function installClaudeSkills(repoPath) {
6
- const skillsSource = path.join(repoPath, '.claude', 'skills');
7
- const skillsTarget = path.join(os.homedir(), '.claude', 'skills');
7
+ const skillsSource = getSkillsSourcePath(repoPath, 'claude');
8
+ const skillsTarget = getUserSkillsPath('claude');
8
9
 
9
10
  console.log('🔧 Installing Claude Code skills...');
10
11
 
package/lib/codex.js CHANGED
@@ -1,44 +1,70 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
3
  const os = require('os');
4
-
5
- const CODEX_SKILLS_DIR = path.join(os.homedir(), '.codex', 'skills');
4
+ const chalk = require('chalk');
5
+ const { getSkillsSourcePath, getUserSkillsPath } = require('./utils/path-resolver');
6
6
 
7
7
  /**
8
8
  * Instala skills para OpenAI Codex
9
+ * Solução robusta com multi-path fallback e logging detalhado
9
10
  * @param {string} repoPath - Caminho para o repositório cli-ai-skills
11
+ * @param {Array<string>|null} skills - Skills to install (null = all)
12
+ * @param {boolean} quiet - Suppress output
10
13
  */
11
- function install(repoPath) {
12
- console.log('\n📦 Instalando skills para OpenAI Codex...');
13
-
14
- const skillsSource = path.join(repoPath, '.codex', 'skills');
14
+ function install(repoPath, skills = null, quiet = false) {
15
+ const targetDir = getUserSkillsPath('codex');
16
+
17
+ if (!quiet) {
18
+ console.log(chalk.cyan('\n📦 Instalando skills para OpenAI Codex...'));
19
+ console.log(chalk.gray(` Destino: ${targetDir}`));
20
+ }
21
+
22
+ const sourceDir = getSkillsSourcePath(repoPath, 'codex');
15
23
 
16
- if (!fs.existsSync(skillsSource)) {
17
- console.error('❌ Erro: .codex/skills/ não encontrado no repositório');
18
- console.error(` Caminho esperado: ${skillsSource}`);
19
- return;
24
+ if (!fs.existsSync(sourceDir)) {
25
+ if (!quiet) {
26
+ console.log(chalk.red('❌ Diretório .codex/skills não encontrado no repositório'));
27
+ console.log(chalk.gray(` Esperado: ${sourceDir}`));
28
+ }
29
+ return { installed: 0, failed: 0 };
20
30
  }
21
31
 
22
- // Criar ~/.codex/skills/ se não existir
23
- if (!fs.existsSync(CODEX_SKILLS_DIR)) {
24
- fs.mkdirSync(CODEX_SKILLS_DIR, { recursive: true });
25
- console.log(` Criado: ${CODEX_SKILLS_DIR}`);
32
+ // Criar diretório de destino se não existir
33
+ if (!fs.existsSync(targetDir)) {
34
+ fs.mkdirSync(targetDir, { recursive: true });
35
+ if (!quiet) {
36
+ console.log(chalk.green(` ✓ Criado: ${targetDir}`));
37
+ }
26
38
  }
27
39
 
28
40
  // Listar skills disponíveis
29
- const skills = fs.readdirSync(skillsSource, { withFileTypes: true })
41
+ const availableSkills = fs.readdirSync(sourceDir, { withFileTypes: true })
30
42
  .filter(d => d.isDirectory() && d.name !== 'node_modules' && !d.name.startsWith('.'))
31
43
  .map(d => d.name);
32
44
 
33
- if (skills.length === 0) {
34
- console.log(' ⚠️ Nenhum skill encontrado em .codex/skills/');
35
- return;
45
+ if (availableSkills.length === 0) {
46
+ if (!quiet) {
47
+ console.log(chalk.yellow(' ⚠️ Nenhum skill encontrado em .codex/skills/'));
48
+ }
49
+ return { installed: 0, failed: 0 };
36
50
  }
51
+
52
+ const skillsToInstall = skills || availableSkills;
53
+ let installed = 0;
54
+ let failed = 0;
37
55
 
38
56
  // Criar symlinks
39
- skills.forEach(skill => {
40
- const src = path.join(skillsSource, skill);
41
- const dest = path.join(CODEX_SKILLS_DIR, skill);
57
+ skillsToInstall.forEach(skill => {
58
+ const src = path.join(sourceDir, skill);
59
+ const dest = path.join(targetDir, skill);
60
+
61
+ if (!fs.existsSync(src)) {
62
+ if (!quiet) {
63
+ console.log(chalk.yellow(` ⚠️ Skill não encontrada: ${skill}`));
64
+ }
65
+ failed++;
66
+ return;
67
+ }
42
68
 
43
69
  // Remover symlink antigo se existir
44
70
  if (fs.existsSync(dest) || fs.lstatSync(dest, {throwIfNoEntry: false})) {
@@ -52,13 +78,26 @@ function install(repoPath) {
52
78
  // Criar novo symlink
53
79
  try {
54
80
  fs.symlinkSync(src, dest);
55
- console.log(` ✓ ${skill}`);
81
+ if (!quiet) {
82
+ console.log(chalk.green(` ✓ Codex: ${skill}`));
83
+ }
84
+ installed++;
56
85
  } catch (error) {
57
- console.error(` ✗ ${skill} (erro: ${error.message})`);
86
+ if (!quiet) {
87
+ console.log(chalk.red(` ✗ Erro ao instalar ${skill}: ${error.message}`));
88
+ }
89
+ failed++;
58
90
  }
59
91
  });
60
92
 
61
- console.log(`\n✅ ${skills.length} Codex skills instalados em ${CODEX_SKILLS_DIR}`);
93
+ if (!quiet) {
94
+ console.log(chalk.green(`\n✅ ${installed} Codex skill(s) instalado(s)`));
95
+ if (failed > 0) {
96
+ console.log(chalk.yellow(`⚠️ ${failed} skill(s) falharam`));
97
+ }
98
+ }
99
+
100
+ return { installed, failed };
62
101
  }
63
102
 
64
103
  module.exports = { install };
@@ -9,8 +9,11 @@ const InstallationPrompts = require('../ui/prompts');
9
9
  const ProgressGauge = require('../ui/progress-gauge');
10
10
  const path = require('path');
11
11
 
12
+ // Read version dynamically from package.json
13
+ const packageJson = require('../../package.json');
14
+
12
15
  async function installCommand(skillNames, options) {
13
- console.log(chalk.cyan.bold('\n🤖 CLI AI Skills Installer v1.0.0\n'));
16
+ console.log(chalk.cyan.bold(`\n🤖 CLI AI Skills Installer v${packageJson.version}\n`));
14
17
 
15
18
  // Initialize progress gauge (5 main steps)
16
19
  const gauge = new ProgressGauge(5);
package/lib/copilot.js CHANGED
@@ -1,10 +1,11 @@
1
1
  const fs = require('fs-extra');
2
2
  const path = require('path');
3
3
  const os = require('os');
4
+ const { getSkillsSourcePath, getUserSkillsPath } = require('./utils/path-resolver');
4
5
 
5
6
  function installCopilotSkills(repoPath) {
6
- const skillsSource = path.join(repoPath, '.github', 'skills');
7
- const skillsTarget = path.join(os.homedir(), '.github', 'skills');
7
+ const skillsSource = getSkillsSourcePath(repoPath, 'copilot');
8
+ const skillsTarget = getUserSkillsPath('copilot');
8
9
 
9
10
  console.log('🔧 Installing GitHub Copilot CLI skills...');
10
11
 
package/lib/detector.js CHANGED
@@ -1,14 +1,18 @@
1
1
  const { execSync } = require('child_process');
2
+ const fs = require('fs');
3
+ const os = require('os');
4
+ const path = require('path');
2
5
 
3
6
  /**
4
7
  * Detecta ferramentas AI CLI instaladas no sistema
5
- * @returns {Object} { copilot: {installed, version, path}, claude: {...}, ... }
8
+ * @returns {Object} { copilot: {installed, version, path}, claude: {...}, codex_cli: {...}, codex_app: {...}, ... }
6
9
  */
7
10
  function detectTools() {
8
11
  const tools = {
9
12
  copilot: detectCopilot(),
10
13
  claude: detectClaude(),
11
- codex: detectCodex(),
14
+ codex_cli: detectCodexCli(),
15
+ codex_app: detectCodexApp(),
12
16
  opencode: detectOpenCode(),
13
17
  gemini: detectGemini()
14
18
  };
@@ -43,9 +47,9 @@ function detectClaude() {
43
47
  }
44
48
 
45
49
  /**
46
- * Detecta OpenAI Codex
50
+ * Detecta OpenAI Codex CLI
47
51
  */
48
- function detectCodex() {
52
+ function detectCodexCli() {
49
53
  try {
50
54
  const version = execSync('codex --version', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] }).trim();
51
55
  const path = execSync('which codex', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] }).trim();
@@ -55,6 +59,62 @@ function detectCodex() {
55
59
  }
56
60
  }
57
61
 
62
+ /**
63
+ * Detecta OpenAI Codex App (Desktop)
64
+ */
65
+ function detectCodexApp() {
66
+ // Check macOS
67
+ if (os.platform() === 'darwin') {
68
+ const appPath = '/Applications/Codex.app';
69
+ if (fs.existsSync(appPath)) {
70
+ try {
71
+ // Try to get version from Info.plist
72
+ const plistPath = path.join(appPath, 'Contents', 'Info.plist');
73
+ const version = 'Codex Desktop'; // Could parse plist for exact version
74
+ return { installed: true, version, path: appPath };
75
+ } catch (e) {
76
+ return { installed: true, version: 'unknown', path: appPath };
77
+ }
78
+ }
79
+ }
80
+
81
+ // Check Linux (if applicable)
82
+ if (os.platform() === 'linux') {
83
+ // Could check for ~/.local/share/applications or similar
84
+ const homeDir = os.homedir();
85
+ const possiblePaths = [
86
+ path.join(homeDir, '.local', 'share', 'codex'),
87
+ '/opt/Codex',
88
+ '/usr/local/bin/Codex'
89
+ ];
90
+
91
+ for (const appPath of possiblePaths) {
92
+ if (fs.existsSync(appPath)) {
93
+ return { installed: true, version: 'Codex Desktop', path: appPath };
94
+ }
95
+ }
96
+ }
97
+
98
+ // Check Windows
99
+ if (os.platform() === 'win32') {
100
+ const programFiles = process.env['ProgramFiles'] || 'C:\\Program Files';
101
+ const appPath = path.join(programFiles, 'Codex', 'Codex.exe');
102
+ if (fs.existsSync(appPath)) {
103
+ return { installed: true, version: 'Codex Desktop', path: appPath };
104
+ }
105
+ }
106
+
107
+ return { installed: false, version: null, path: null };
108
+ }
109
+
110
+ /**
111
+ * @deprecated Use detectCodexCli() and detectCodexApp() instead
112
+ * Detecta OpenAI Codex (mantido para backward compatibility)
113
+ */
114
+ function detectCodex() {
115
+ return detectCodexCli();
116
+ }
117
+
58
118
  /**
59
119
  * Detecta OpenCode
60
120
  */
@@ -123,5 +183,5 @@ Após instalar, execute novamente: npx cli-ai-skills
123
183
  `;
124
184
  }
125
185
 
126
- module.exports = { detectTools, getInstallInstructions };
186
+ module.exports = { detectTools, getInstallInstructions, detectCodex, detectCodexCli, detectCodexApp };
127
187
 
package/lib/gemini.js CHANGED
@@ -2,6 +2,7 @@ const fs = require('fs-extra');
2
2
  const path = require('path');
3
3
  const chalk = require('chalk');
4
4
  const os = require('os');
5
+ const { getSkillsSourcePath, getUserSkillsPath } = require('./utils/path-resolver');
5
6
 
6
7
  /**
7
8
  * Install skills for Gemini CLI
@@ -10,13 +11,12 @@ const os = require('os');
10
11
  * @param {boolean} quiet - Suppress output
11
12
  */
12
13
  function install(repoPath, skills = null, quiet = false) {
13
- const homeDir = os.homedir();
14
- const targetDir = path.join(homeDir, '.gemini', 'skills');
15
-
14
+ const targetDir = getUserSkillsPath('gemini');
15
+
16
16
  // Criar diretório se não existir
17
17
  fs.ensureDirSync(targetDir);
18
-
19
- const sourceDir = path.join(repoPath, '.gemini', 'skills');
18
+
19
+ const sourceDir = getSkillsSourcePath(repoPath, 'gemini');
20
20
 
21
21
  if (!fs.existsSync(sourceDir)) {
22
22
  if (!quiet) {
@@ -50,47 +50,58 @@ async function confirmCancel() {
50
50
 
51
51
  /**
52
52
  * Pergunta ao usuário para quais plataformas instalar
53
- * @param {Object} detected - Ferramentas detectadas { copilot, claude, codex, opencode, gemini }
53
+ * Codex CLI e Codex App são mostrados SEMPRE separadamente
54
+ * @param {Object} detected - Ferramentas detectadas { copilot, claude, codex_cli, codex_app, opencode, gemini }
54
55
  * @returns {Promise<Array>} Plataformas escolhidas
55
56
  */
56
57
  async function promptPlatforms(detected) {
57
58
  const choices = [];
58
59
 
59
- if (detected.copilot) {
60
+ if (detected.copilot && detected.copilot.installed) {
60
61
  choices.push({
61
- name: '✅ GitHub Copilot CLI (.github/skills/)',
62
+ name: '✅ GitHub Copilot CLI (~/.github/skills/)',
62
63
  value: 'copilot',
63
64
  checked: true
64
65
  });
65
66
  }
66
67
 
67
- if (detected.claude) {
68
+ if (detected.claude && detected.claude.installed) {
68
69
  choices.push({
69
- name: '✅ Claude Code (.claude/skills/)',
70
+ name: '✅ Claude Code (~/.claude/skills/)',
70
71
  value: 'claude',
71
72
  checked: true
72
73
  });
73
74
  }
74
75
 
75
- if (detected.codex) {
76
+ // Codex CLI - sempre separado
77
+ if (detected.codex_cli && detected.codex_cli.installed) {
76
78
  choices.push({
77
- name: '✅ OpenAI Codex (.codex/skills/)',
78
- value: 'codex',
79
+ name: '✅ OpenAI Codex CLI (~/.codex/vendor_imports/skills/skills/.curated/)',
80
+ value: 'codex_cli',
79
81
  checked: true
80
82
  });
81
83
  }
82
84
 
83
- if (detected.opencode) {
85
+ // Codex App - sempre separado
86
+ if (detected.codex_app && detected.codex_app.installed) {
84
87
  choices.push({
85
- name: '✅ OpenCode (.opencode/skills/)',
88
+ name: '✅ OpenAI Codex App (~/.codex/vendor_imports/skills/skills/.curated/)',
89
+ value: 'codex_app',
90
+ checked: true
91
+ });
92
+ }
93
+
94
+ if (detected.opencode && detected.opencode.installed) {
95
+ choices.push({
96
+ name: '✅ OpenCode (~/.opencode/skills/)',
86
97
  value: 'opencode',
87
98
  checked: true
88
99
  });
89
100
  }
90
101
 
91
- if (detected.gemini) {
102
+ if (detected.gemini && detected.gemini.installed) {
92
103
  choices.push({
93
- name: '✅ Gemini CLI (.gemini/skills/)',
104
+ name: '✅ Gemini CLI (~/.gemini/skills/)',
94
105
  value: 'gemini',
95
106
  checked: true
96
107
  });
package/lib/opencode.js CHANGED
@@ -2,6 +2,7 @@ const fs = require('fs-extra');
2
2
  const path = require('path');
3
3
  const chalk = require('chalk');
4
4
  const os = require('os');
5
+ const { getSkillsSourcePath, getUserSkillsPath } = require('./utils/path-resolver');
5
6
 
6
7
  /**
7
8
  * Install skills for OpenCode
@@ -10,13 +11,12 @@ const os = require('os');
10
11
  * @param {boolean} quiet - Suppress output
11
12
  */
12
13
  function install(repoPath, skills = null, quiet = false) {
13
- const homeDir = os.homedir();
14
- const targetDir = path.join(homeDir, '.opencode', 'skills');
15
-
14
+ const targetDir = getUserSkillsPath('opencode');
15
+
16
16
  // Criar diretório se não existir
17
17
  fs.ensureDirSync(targetDir);
18
-
19
- const sourceDir = path.join(repoPath, '.opencode', 'skills');
18
+
19
+ const sourceDir = getSkillsSourcePath(repoPath, 'opencode');
20
20
 
21
21
  if (!fs.existsSync(sourceDir)) {
22
22
  if (!quiet) {
package/lib/ui/table.js CHANGED
@@ -2,36 +2,40 @@ const chalk = require('chalk');
2
2
 
3
3
  /**
4
4
  * Exibe tabela formatada de ferramentas detectadas
5
+ * Agora com Codex CLI e Codex App separados
5
6
  * @param {Object} tools - Objeto retornado por detectTools()
6
7
  */
7
8
  function displayToolsTable(tools) {
8
- console.log('\n┌─────────────────────────────────────────────────────────────┐');
9
- console.log('│ Ferramenta │ Status │ Versão │');
10
- console.log('├─────────────────────────────────────────────────────────────┤');
9
+ console.log('\n┌──────────────────────────────────────────────────────────────────┐');
10
+ console.log('│ Ferramenta │ Status │ Versão │');
11
+ console.log('├──────────────────────────────────────────────────────────────────┤');
11
12
 
12
13
  const toolNames = {
13
14
  copilot: 'GitHub Copilot CLI',
14
15
  claude: 'Claude Code',
15
- codex: 'OpenAI Codex',
16
+ codex_cli: 'OpenAI Codex CLI',
17
+ codex_app: 'OpenAI Codex App',
16
18
  opencode: 'OpenCode',
17
19
  gemini: 'Gemini CLI'
18
20
  };
19
21
 
20
22
  for (const [key, name] of Object.entries(toolNames)) {
21
23
  const tool = tools[key];
24
+ if (!tool) continue; // Skip if tool not in detected object
25
+
22
26
  const status = tool.installed ? chalk.green('✓') : chalk.red('✗');
23
27
  const version = tool.version || chalk.gray('-');
24
28
 
25
29
  // Formatar linha com espaçamento fixo
26
30
  const namePadded = name.padEnd(21);
27
31
  const statusPadded = ' ' + status + ' ';
28
- const versionStr = String(version).substring(0, 20);
29
- const versionPadded = versionStr.padEnd(20);
32
+ const versionStr = String(version).substring(0, 26);
33
+ const versionPadded = versionStr.padEnd(26);
30
34
 
31
35
  console.log(`│ ${namePadded} │${statusPadded}│ ${versionPadded}│`);
32
36
  }
33
37
 
34
- console.log('└─────────────────────────────────────────────────────────────┘\n');
38
+ console.log('└──────────────────────────────────────────────────────────────────┘\n');
35
39
  }
36
40
 
37
41
  /**
@@ -44,12 +48,13 @@ function getToolsSummary(tools) {
44
48
 
45
49
  if (tools.copilot && tools.copilot.installed) installed.push('copilot');
46
50
  if (tools.claude && tools.claude.installed) installed.push('claude');
47
- if (tools.codex && tools.codex.installed) installed.push('codex');
51
+ if (tools.codex_cli && tools.codex_cli.installed) installed.push('codex_cli');
52
+ if (tools.codex_app && tools.codex_app.installed) installed.push('codex_app');
48
53
  if (tools.opencode && tools.opencode.installed) installed.push('opencode');
49
54
  if (tools.gemini && tools.gemini.installed) installed.push('gemini');
50
55
 
51
56
  return {
52
- total: 5,
57
+ total: 6,
53
58
  installed: installed.length,
54
59
  names: installed
55
60
  };